summaryrefslogtreecommitdiff
path: root/chromium/content/browser
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-01-25 11:39:07 +0100
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2016-01-25 15:20:42 +0000
commit6c91641271e536ffaa88a1dff5127e42ee99a91e (patch)
tree703d9dd49602377ddc90cbf886aad37913f2496b /chromium/content/browser
parentb145b7fafd36f0c260d6a768c81fc14e32578099 (diff)
downloadqtwebengine-chromium-6c91641271e536ffaa88a1dff5127e42ee99a91e.tar.gz
BASELINE: Update Chromium to 49.0.2623.23
Also adds missing printing sources. Change-Id: I3726b8f0c7d6751c9fc846096c571fadca7108cd Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/content/browser')
-rw-r--r--chromium/content/browser/BUILD.gn88
-rw-r--r--chromium/content/browser/DEPS14
-rw-r--r--chromium/content/browser/accessibility/BUILD.gn5
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm77
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder_win.cc3
-rw-r--r--chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc12
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter.cc94
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter.h80
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc50
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc55
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc213
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h35
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm73
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc69
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc33
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.h19
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc62
-rw-r--r--chromium/content/browser/accessibility/accessibility_ui.cc40
-rw-r--r--chromium/content/browser/accessibility/accessibility_ui.h2
-rw-r--r--chromium/content/browser/accessibility/accessibility_win_browsertest.cc270
-rw-r--r--chromium/content/browser/accessibility/ax_tree_id_registry.h2
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.cc263
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.h75
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_android.cc131
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_android.h18
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_auralinux.cc26
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_auralinux.h1
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.h7
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.mm329
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac.h1
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac.mm31
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm12
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.cc133
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.h41
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_android.cc140
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_android.h128
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc8
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h5
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_mac.h8
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm272
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc115
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_win.cc120
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_win.h13
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_state_impl.cc3
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_state_impl.h2
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc1
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_win.cc777
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_win.h88
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc621
-rw-r--r--chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc27
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc111
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h18
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc8
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc53
-rw-r--r--chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc8
-rw-r--r--chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h2
-rw-r--r--chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc3
-rw-r--r--chromium/content/browser/accessibility/site_per_process_accessibility_browsertest.cc166
-rw-r--r--chromium/content/browser/accessibility/snapshot_ax_tree_browsertest.cc7
-rw-r--r--chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc7
-rw-r--r--chromium/content/browser/android/DEPS3
-rw-r--r--chromium/content/browser/android/OWNERS4
-rw-r--r--chromium/content/browser/android/animation_utils.h33
-rw-r--r--chromium/content/browser/android/background_sync_launcher_android.cc74
-rw-r--r--chromium/content/browser/android/background_sync_launcher_android.h57
-rw-r--r--chromium/content/browser/android/background_sync_network_observer_android.cc3
-rw-r--r--chromium/content/browser/android/background_sync_network_observer_android.h8
-rw-r--r--chromium/content/browser/android/browser_surface_texture_manager.h1
-rw-r--r--chromium/content/browser/android/child_process_launcher_android.cc24
-rw-r--r--chromium/content/browser/android/composited_touch_handle_drawable.cc72
-rw-r--r--chromium/content/browser/android/composited_touch_handle_drawable.h12
-rw-r--r--chromium/content/browser/android/content_protocol_handler_impl.h2
-rw-r--r--chromium/content/browser/android/content_readback_handler.cc124
-rw-r--r--chromium/content/browser/android/content_readback_handler.h63
-rw-r--r--chromium/content/browser/android/content_startup_flags.cc36
-rw-r--r--chromium/content/browser/android/content_video_view.cc49
-rw-r--r--chromium/content/browser/android/content_video_view.h26
-rw-r--r--chromium/content/browser/android/content_view_core_impl.cc341
-rw-r--r--chromium/content/browser/android/content_view_core_impl.h293
-rw-r--r--chromium/content/browser/android/content_view_render_view.cc42
-rw-r--r--chromium/content/browser/android/content_view_render_view.h35
-rw-r--r--chromium/content/browser/android/content_view_statics.cc1
-rw-r--r--chromium/content/browser/android/date_time_chooser_android.cc10
-rw-r--r--chromium/content/browser/android/date_time_chooser_android.h7
-rw-r--r--chromium/content/browser/android/deferred_download_observer.h1
-rw-r--r--chromium/content/browser/android/download_controller_android_impl.cc36
-rw-r--r--chromium/content/browser/android/download_controller_android_impl.h8
-rw-r--r--chromium/content/browser/android/edge_effect.cc360
-rw-r--r--chromium/content/browser/android/edge_effect.h84
-rw-r--r--chromium/content/browser/android/edge_effect_base.cc49
-rw-r--r--chromium/content/browser/android/edge_effect_base.h67
-rw-r--r--chromium/content/browser/android/edge_effect_l.cc301
-rw-r--r--chromium/content/browser/android/edge_effect_l.h83
-rw-r--r--chromium/content/browser/android/in_process/DEPS4
-rw-r--r--chromium/content/browser/android/in_process/context_provider_in_process.cc84
-rw-r--r--chromium/content/browser/android/in_process/context_provider_in_process.h17
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_context_provider.cc21
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_context_provider.h31
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.cc74
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h44
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.cc210
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.h32
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_impl.cc230
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_impl.h84
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc292
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h122
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_registry_in_proc.cc (renamed from chromium/content/browser/android/in_process/synchronous_compositor_registry.cc)42
-rw-r--r--chromium/content/browser/android/in_process/synchronous_compositor_registry_in_proc.h (renamed from chromium/content/browser/android/in_process/synchronous_compositor_registry.h)54
-rw-r--r--chromium/content/browser/android/in_process/synchronous_input_event_filter.cc9
-rw-r--r--chromium/content/browser/android/in_process/synchronous_input_event_filter.h8
-rw-r--r--chromium/content/browser/android/in_process_surface_texture_manager.h1
-rw-r--r--chromium/content/browser/android/interstitial_page_delegate_android.cc9
-rw-r--r--chromium/content/browser/android/interstitial_page_delegate_android.h7
-rw-r--r--chromium/content/browser/android/java/gin_java_bound_object.cc9
-rw-r--r--chromium/content/browser/android/java/gin_java_bound_object.h15
-rw-r--r--chromium/content/browser/android/java/gin_java_bound_object_delegate.h3
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc19
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h10
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_message_filter.cc27
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_message_filter.h11
-rw-r--r--chromium/content/browser/android/java/gin_java_method_invocation_helper.cc9
-rw-r--r--chromium/content/browser/android/java/gin_java_method_invocation_helper.h5
-rw-r--r--chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc5
-rw-r--r--chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc23
-rw-r--r--chromium/content/browser/android/java/java_bridge_thread.cc1
-rw-r--r--chromium/content/browser/android/java/java_method.h2
-rw-r--r--chromium/content/browser/android/java/java_type.cc2
-rw-r--r--chromium/content/browser/android/java/java_type_unittest.cc2
-rw-r--r--chromium/content/browser/android/overscroll_controller_android.cc12
-rw-r--r--chromium/content/browser/android/overscroll_controller_android.h13
-rw-r--r--chromium/content/browser/android/overscroll_glow.cc279
-rw-r--r--chromium/content/browser/android/overscroll_glow.h110
-rw-r--r--chromium/content/browser/android/overscroll_refresh.cc104
-rw-r--r--chromium/content/browser/android/overscroll_refresh.h104
-rw-r--r--chromium/content/browser/android/overscroll_refresh_unittest.cc241
-rw-r--r--chromium/content/browser/android/popup_touch_handle_drawable.cc35
-rw-r--r--chromium/content/browser/android/popup_touch_handle_drawable.h9
-rw-r--r--chromium/content/browser/android/synchronous_compositor_base.cc77
-rw-r--r--chromium/content/browser/android/synchronous_compositor_base.h47
-rw-r--r--chromium/content/browser/android/synchronous_compositor_host.cc388
-rw-r--r--chromium/content/browser/android/synchronous_compositor_host.h105
-rw-r--r--chromium/content/browser/android/tracing_controller_android.cc30
-rw-r--r--chromium/content/browser/android/tracing_controller_android.h17
-rw-r--r--chromium/content/browser/android/url_request_content_job.cc83
-rw-r--r--chromium/content/browser/android/url_request_content_job.h15
-rw-r--r--chromium/content/browser/android/url_request_content_job_unittest.cc35
-rw-r--r--chromium/content/browser/android/web_contents_observer_proxy.cc22
-rw-r--r--chromium/content/browser/android/web_contents_observer_proxy.h5
-rw-r--r--chromium/content/browser/appcache/appcache.cc12
-rw-r--r--chromium/content/browser/appcache/appcache.h26
-rw-r--r--chromium/content/browser/appcache/appcache_backend_impl.cc8
-rw-r--r--chromium/content/browser/appcache/appcache_backend_impl.h11
-rw-r--r--chromium/content/browser/appcache/appcache_database.cc97
-rw-r--r--chromium/content/browser/appcache/appcache_database.h111
-rw-r--r--chromium/content/browser/appcache/appcache_database_unittest.cc30
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache.cc43
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache.h16
-rw-r--r--chromium/content/browser/appcache/appcache_dispatcher_host.cc16
-rw-r--r--chromium/content/browser/appcache/appcache_dispatcher_host.h17
-rw-r--r--chromium/content/browser/appcache/appcache_entry.h24
-rw-r--r--chromium/content/browser/appcache/appcache_group.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_group.h16
-rw-r--r--chromium/content/browser/appcache/appcache_group_unittest.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_histograms.h2
-rw-r--r--chromium/content/browser/appcache/appcache_host.cc12
-rw-r--r--chromium/content/browser/appcache/appcache_host.h19
-rw-r--r--chromium/content/browser/appcache/appcache_host_unittest.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_interceptor.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_interceptor.h6
-rw-r--r--chromium/content/browser/appcache/appcache_internals_ui.cc12
-rw-r--r--chromium/content/browser/appcache/appcache_internals_ui.h9
-rw-r--r--chromium/content/browser/appcache/appcache_manifest_parser.cc3
-rw-r--r--chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc3
-rw-r--r--chromium/content/browser/appcache/appcache_quota_client.h1
-rw-r--r--chromium/content/browser/appcache/appcache_quota_client_unittest.cc14
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.cc162
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.h64
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler_unittest.cc248
-rw-r--r--chromium/content/browser/appcache/appcache_response.cc56
-rw-r--r--chromium/content/browser/appcache/appcache_response.h74
-rw-r--r--chromium/content/browser/appcache/appcache_response_unittest.cc10
-rw-r--r--chromium/content/browser/appcache/appcache_service_impl.cc85
-rw-r--r--chromium/content/browser/appcache/appcache_service_impl.h13
-rw-r--r--chromium/content/browser/appcache/appcache_service_unittest.cc28
-rw-r--r--chromium/content/browser/appcache/appcache_storage.cc18
-rw-r--r--chromium/content/browser/appcache/appcache_storage.h97
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl.cc186
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl.h51
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl_unittest.cc60
-rw-r--r--chromium/content/browser/appcache/appcache_unittest.cc31
-rw-r--r--chromium/content/browser/appcache/appcache_update_job.cc14
-rw-r--r--chromium/content/browser/appcache/appcache_update_job.h12
-rw-r--r--chromium/content/browser/appcache/appcache_update_job_unittest.cc91
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job.cc58
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job.h50
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job_unittest.cc126
-rw-r--r--chromium/content/browser/appcache/appcache_working_set.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_working_set.h10
-rw-r--r--chromium/content/browser/appcache/chrome_appcache_service.h1
-rw-r--r--chromium/content/browser/appcache/mock_appcache_storage.cc36
-rw-r--r--chromium/content/browser/appcache/mock_appcache_storage.h48
-rw-r--r--chromium/content/browser/appcache/mock_appcache_storage_unittest.cc51
-rw-r--r--chromium/content/browser/background_sync/OWNERS1
-rw-r--r--chromium/content/browser/background_sync/background_sync.proto2
-rw-r--r--chromium/content/browser/background_sync/background_sync_browsertest.cc449
-rw-r--r--chromium/content/browser/background_sync/background_sync_context_impl.cc4
-rw-r--r--chromium/content/browser/background_sync/background_sync_context_impl.h1
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager.cc694
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager.h164
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager_unittest.cc919
-rw-r--r--chromium/content/browser/background_sync/background_sync_metrics.cc83
-rw-r--r--chromium/content/browser/background_sync/background_sync_metrics.h26
-rw-r--r--chromium/content/browser/background_sync/background_sync_network_observer.cc5
-rw-r--r--chromium/content/browser/background_sync/background_sync_network_observer.h8
-rw-r--r--chromium/content/browser/background_sync/background_sync_power_observer.h1
-rw-r--r--chromium/content/browser/background_sync/background_sync_power_observer_unittest.cc1
-rw-r--r--chromium/content/browser/background_sync/background_sync_registration.cc43
-rw-r--r--chromium/content/browser/background_sync/background_sync_registration.h26
-rw-r--r--chromium/content/browser/background_sync/background_sync_registration_handle.cc4
-rw-r--r--chromium/content/browser/background_sync/background_sync_registration_handle.h7
-rw-r--r--chromium/content/browser/background_sync/background_sync_registration_options.h3
-rw-r--r--chromium/content/browser/background_sync/background_sync_service_impl.cc33
-rw-r--r--chromium/content/browser/background_sync/background_sync_service_impl.h15
-rw-r--r--chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc116
-rw-r--r--chromium/content/browser/bad_message.h10
-rw-r--r--chromium/content/browser/battery_status/battery_monitor_impl_browsertest.cc5
-rw-r--r--chromium/content/browser/battery_status/battery_monitor_integration_browsertest.cc11
-rw-r--r--chromium/content/browser/blob_storage/blob_async_builder_host_unittest.cc327
-rw-r--r--chromium/content/browser/blob_storage/blob_async_transport_strategy_unittest.cc458
-rw-r--r--chromium/content/browser/blob_storage/blob_storage_registry_unittest.cc87
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc155
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.h84
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_allowed_devices_map_unittest.cc167
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_dispatcher_host.cc922
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_dispatcher_host.h154
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_metrics.cc76
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_metrics.h44
-rw-r--r--chromium/content/browser/bootstrap_sandbox_manager_mac.cc6
-rw-r--r--chromium/content/browser/bootstrap_sandbox_manager_mac.h1
-rw-r--r--chromium/content/browser/browser_child_process_host_impl.cc95
-rw-r--r--chromium/content/browser/browser_child_process_host_impl.h15
-rw-r--r--chromium/content/browser/browser_context.cc14
-rw-r--r--chromium/content/browser/browser_io_surface_manager_mac.cc320
-rw-r--r--chromium/content/browser/browser_io_surface_manager_mac.h128
-rw-r--r--chromium/content/browser/browser_io_surface_manager_mac_unittest.cc288
-rw-r--r--chromium/content/browser/browser_main.cc22
-rw-r--r--chromium/content/browser/browser_main.h1
-rw-r--r--chromium/content/browser/browser_main_loop.cc227
-rw-r--r--chromium/content/browser/browser_main_loop.h8
-rw-r--r--chromium/content/browser/browser_main_runner.cc6
-rw-r--r--chromium/content/browser/browser_plugin/OWNERS1
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.cc19
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.h1
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.cc112
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.h22
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_message_filter.h1
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h9
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm11
-rw-r--r--chromium/content/browser/browser_process_sub_thread.h3
-rw-r--r--chromium/content/browser/browser_shutdown_profile_dumper.h4
-rw-r--r--chromium/content/browser/browser_side_navigation_browsertest.cc7
-rw-r--r--chromium/content/browser/browser_thread_impl.cc4
-rw-r--r--chromium/content/browser/browser_thread_unittest.cc17
-rw-r--r--chromium/content/browser/browser_url_handler_impl.cc3
-rw-r--r--chromium/content/browser/browser_url_handler_impl.h3
-rw-r--r--chromium/content/browser/browsing_instance.h3
-rw-r--r--chromium/content/browser/byte_stream.cc5
-rw-r--r--chromium/content/browser/byte_stream.h2
-rw-r--r--chromium/content/browser/byte_stream_unittest.cc2
-rw-r--r--chromium/content/browser/cache_storage/cache_storage.cc90
-rw-r--r--chromium/content/browser/cache_storage/cache_storage.h18
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc12
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h1
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc7
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache.cc136
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache.h5
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc28
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_context_impl.cc2
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc19
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h3
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager.cc34
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager.h10
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc85
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_quota_client.h1
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_scheduler.h1
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_unittest.cc121
-rw-r--r--chromium/content/browser/cert_store_impl.h1
-rw-r--r--chromium/content/browser/child_process_launcher.cc49
-rw-r--r--chromium/content/browser/child_process_launcher.h12
-rw-r--r--chromium/content/browser/child_process_security_policy_browsertest.cc2
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.cc2
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.h1
-rw-r--r--chromium/content/browser/child_process_security_policy_unittest.cc1
-rw-r--r--chromium/content/browser/cocoa/system_hotkey_helper_mac.h1
-rw-r--r--chromium/content/browser/compositor/DEPS3
-rw-r--r--chromium/content/browser/compositor/browser_compositor_output_surface.cc12
-rw-r--r--chromium/content/browser/compositor/browser_compositor_output_surface.h12
-rw-r--r--chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator.h1
-rw-r--r--chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.cc50
-rw-r--r--chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h40
-rw-r--r--chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h2
-rw-r--r--chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm10
-rw-r--r--chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.cc19
-rw-r--r--chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h2
-rw-r--r--chromium/content/browser/compositor/browser_compositor_view_mac.h1
-rw-r--r--chromium/content/browser/compositor/browser_compositor_view_mac.mm12
-rw-r--r--chromium/content/browser/compositor/buffer_queue.cc169
-rw-r--r--chromium/content/browser/compositor/buffer_queue.h52
-rw-r--r--chromium/content/browser/compositor/buffer_queue_unittest.cc208
-rw-r--r--chromium/content/browser/compositor/delegated_frame_host.cc206
-rw-r--r--chromium/content/browser/compositor/delegated_frame_host.h41
-rw-r--r--chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc27
-rw-r--r--chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h9
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.cc112
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.h17
-rw-r--r--chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc25
-rw-r--r--chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h11
-rw-r--r--chromium/content/browser/compositor/image_transport_factory.h9
-rw-r--r--chromium/content/browser/compositor/image_transport_factory_browsertest.cc1
-rw-r--r--chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc21
-rw-r--r--chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h12
-rw-r--r--chromium/content/browser/compositor/owned_mailbox.cc8
-rw-r--r--chromium/content/browser/compositor/owned_mailbox.h14
-rw-r--r--chromium/content/browser/compositor/reflector_impl.cc5
-rw-r--r--chromium/content/browser/compositor/reflector_impl_unittest.cc25
-rw-r--r--chromium/content/browser/compositor/reflector_texture.cc4
-rw-r--r--chromium/content/browser/compositor/reflector_texture.h7
-rw-r--r--chromium/content/browser/compositor/resize_lock.h2
-rw-r--r--chromium/content/browser/compositor/software_browser_compositor_output_surface.cc18
-rw-r--r--chromium/content/browser/compositor/software_browser_compositor_output_surface.h6
-rw-r--r--chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc16
-rw-r--r--chromium/content/browser/compositor/software_output_device_mac.h42
-rw-r--r--chromium/content/browser/compositor/software_output_device_mac.mm157
-rw-r--r--chromium/content/browser/compositor/software_output_device_mus.cc66
-rw-r--r--chromium/content/browser/compositor/software_output_device_mus.h36
-rw-r--r--chromium/content/browser/compositor/software_output_device_ozone.cc17
-rw-r--r--chromium/content/browser/compositor/software_output_device_ozone.h5
-rw-r--r--chromium/content/browser/compositor/software_output_device_ozone_unittest.cc29
-rw-r--r--chromium/content/browser/compositor/software_output_device_win.cc55
-rw-r--r--chromium/content/browser/compositor/software_output_device_win.h8
-rw-r--r--chromium/content/browser/compositor/software_output_device_x11.cc25
-rw-r--r--chromium/content/browser/compositor/software_output_device_x11.h1
-rw-r--r--chromium/content/browser/compositor/surface_utils.cc7
-rw-r--r--chromium/content/browser/cross_site_transfer_browsertest.cc75
-rw-r--r--chromium/content/browser/database_quota_client_unittest.cc14
-rw-r--r--chromium/content/browser/database_tracker_unittest.cc34
-rw-r--r--chromium/content/browser/databases_table_unittest.cc2
-rw-r--r--chromium/content/browser/device_monitor_mac.h2
-rw-r--r--chromium/content/browser/device_monitor_mac.mm7
-rw-r--r--chromium/content/browser/device_monitor_udev.cc3
-rw-r--r--chromium/content/browser/device_monitor_udev.h2
-rw-r--r--chromium/content/browser/device_sensors/OWNERS2
-rw-r--r--chromium/content/browser/device_sensors/ambient_light_mac.cc4
-rw-r--r--chromium/content/browser/device_sensors/ambient_light_mac.h2
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory.h3
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_android.cc22
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.cc8
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.h3
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc93
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.cc2
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_default.cc7
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_mac.cc9
-rw-r--r--chromium/content/browser/device_sensors/data_fetcher_shared_memory_win.cc10
-rw-r--r--chromium/content/browser/device_sensors/device_inertial_sensor_browsertest.cc1
-rw-r--r--chromium/content/browser/device_sensors/device_inertial_sensor_service.cc7
-rw-r--r--chromium/content/browser/device_sensors/device_inertial_sensor_service.h8
-rw-r--r--chromium/content/browser/device_sensors/device_light_message_filter.h1
-rw-r--r--chromium/content/browser/device_sensors/device_motion_message_filter.h1
-rw-r--r--chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.cc66
-rw-r--r--chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.h34
-rw-r--r--chromium/content/browser/device_sensors/device_orientation_message_filter.h1
-rw-r--r--chromium/content/browser/device_sensors/device_sensors_consts.h (renamed from chromium/content/browser/device_sensors/inertial_sensor_consts.h)13
-rw-r--r--chromium/content/browser/device_sensors/sensor_manager_android.cc226
-rw-r--r--chromium/content/browser/device_sensors/sensor_manager_android.h91
-rw-r--r--chromium/content/browser/device_sensors/sensor_manager_android_unittest.cc61
-rw-r--r--chromium/content/browser/device_sensors/sensor_manager_chromeos.cc2
-rw-r--r--chromium/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc1
-rw-r--r--chromium/content/browser/devtools/browser_devtools_agent_host.cc7
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.cc25
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.h20
-rw-r--r--chromium/content/browser/devtools/devtools_frame_trace_recorder.cc17
-rw-r--r--chromium/content/browser/devtools/devtools_frame_trace_recorder.h1
-rw-r--r--chromium/content/browser/devtools/devtools_frontend_host_impl.cc20
-rw-r--r--chromium/content/browser/devtools/devtools_frontend_host_impl.h9
-rw-r--r--chromium/content/browser/devtools/devtools_io_context.h2
-rw-r--r--chromium/content/browser/devtools/devtools_manager.h1
-rw-r--r--chromium/content/browser/devtools/devtools_manager_unittest.cc12
-rw-r--r--chromium/content/browser/devtools/devtools_netlog_observer.cc8
-rw-r--r--chromium/content/browser/devtools/devtools_netlog_observer.h8
-rw-r--r--chromium/content/browser/devtools/devtools_protocol_handler.cc82
-rw-r--r--chromium/content/browser/devtools/devtools_protocol_handler.h22
-rw-r--r--chromium/content/browser/devtools/forwarding_agent_host.cc2
-rw-r--r--chromium/content/browser/devtools/protocol/color_picker.cc1
-rw-r--r--chromium/content/browser/devtools/protocol/color_picker.h1
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc138
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_client.cc31
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_client.h32
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_delegate.h22
-rwxr-xr-xchromium/content/browser/devtools/protocol/devtools_protocol_handler_generator.py24
-rw-r--r--chromium/content/browser/devtools/protocol/dom_handler.cc1
-rw-r--r--chromium/content/browser/devtools/protocol/dom_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/emulation_handler.cc19
-rw-r--r--chromium/content/browser/devtools/protocol/emulation_handler.h12
-rw-r--r--chromium/content/browser/devtools/protocol/input_handler.cc40
-rw-r--r--chromium/content/browser/devtools/protocol/input_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/inspector_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/io_handler.cc1
-rw-r--r--chromium/content/browser/devtools/protocol/io_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/memory_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/network_handler.cc4
-rw-r--r--chromium/content/browser/devtools/protocol/network_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.cc65
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.h25
-rw-r--r--chromium/content/browser/devtools/protocol/power_handler.cc84
-rw-r--r--chromium/content/browser/devtools/protocol/power_handler.h45
-rw-r--r--chromium/content/browser/devtools/protocol/security_handler.cc4
-rw-r--r--chromium/content/browser/devtools/protocol/security_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/service_worker_handler.cc16
-rw-r--r--chromium/content/browser/devtools/protocol/service_worker_handler.h7
-rw-r--r--chromium/content/browser/devtools/protocol/system_info_handler.cc16
-rw-r--r--chromium/content/browser/devtools/protocol/system_info_handler.h1
-rw-r--r--chromium/content/browser/devtools/protocol/tethering_handler.cc29
-rw-r--r--chromium/content/browser/devtools/protocol/tethering_handler.h5
-rw-r--r--chromium/content/browser/devtools/protocol/tracing_handler.cc28
-rw-r--r--chromium/content/browser/devtools/protocol/tracing_handler.h10
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.cc218
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.h38
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.cc8
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.h5
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_manager.cc14
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_manager.h10
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_agent_host.h1
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_manager.cc2
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_manager.h2
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc47
-rw-r--r--chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc47
-rw-r--r--chromium/content/browser/devtools/worker_devtools_agent_host.cc28
-rw-r--r--chromium/content/browser/devtools/worker_devtools_agent_host.h1
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_area.cc4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_area.h12
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_area_unittest.cc6
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_impl.cc18
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_impl.h18
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc1
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_wrapper.h1
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_database.cc4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_host.h1
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_message_filter.cc2
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_message_filter.h6
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_namespace.cc5
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_namespace.h11
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_session.cc6
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_session.h12
-rw-r--r--chromium/content/browser/dom_storage/local_storage_database_adapter.h1
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database.cc12
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database.h5
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database_adapter.h1
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database_unittest.cc36
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl.cc8
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl.h8
-rw-r--r--chromium/content/browser/download/OWNERS1
-rw-r--r--chromium/content/browser/download/base_file.cc9
-rw-r--r--chromium/content/browser/download/base_file.h12
-rw-r--r--chromium/content/browser/download/base_file_posix.cc2
-rw-r--r--chromium/content/browser/download/base_file_unittest.cc22
-rw-r--r--chromium/content/browser/download/base_file_win.cc1
-rw-r--r--chromium/content/browser/download/download_browsertest.cc1422
-rw-r--r--chromium/content/browser/download/download_create_info.cc42
-rw-r--r--chromium/content/browser/download/download_create_info.h14
-rw-r--r--chromium/content/browser/download/download_file.h5
-rw-r--r--chromium/content/browser/download/download_file_factory.cc8
-rw-r--r--chromium/content/browser/download/download_file_impl.cc10
-rw-r--r--chromium/content/browser/download/download_file_impl.h6
-rw-r--r--chromium/content/browser/download/download_file_unittest.cc47
-rw-r--r--chromium/content/browser/download/download_item_factory.h12
-rw-r--r--chromium/content/browser/download/download_item_impl.cc97
-rw-r--r--chromium/content/browser/download/download_item_impl.h36
-rw-r--r--chromium/content/browser/download/download_item_impl_delegate.cc3
-rw-r--r--chromium/content/browser/download/download_item_impl_delegate.h5
-rw-r--r--chromium/content/browser/download/download_item_impl_unittest.cc435
-rw-r--r--chromium/content/browser/download/download_manager_impl.cc218
-rw-r--r--chromium/content/browser/download/download_manager_impl.h34
-rw-r--r--chromium/content/browser/download/download_manager_impl_unittest.cc73
-rw-r--r--chromium/content/browser/download/download_net_log_parameters.cc40
-rw-r--r--chromium/content/browser/download/download_net_log_parameters.h13
-rw-r--r--chromium/content/browser/download/download_request_core.cc366
-rw-r--r--chromium/content/browser/download/download_request_core.h137
-rw-r--r--chromium/content/browser/download/download_request_handle.cc18
-rw-r--r--chromium/content/browser/download/download_request_handle.h2
-rw-r--r--chromium/content/browser/download/download_resource_handler.cc404
-rw-r--r--chromium/content/browser/download/download_resource_handler.h46
-rw-r--r--chromium/content/browser/download/download_stats.cc22
-rw-r--r--chromium/content/browser/download/download_stats.h13
-rw-r--r--chromium/content/browser/download/drag_download_file.cc10
-rw-r--r--chromium/content/browser/download/drag_download_file.h1
-rw-r--r--chromium/content/browser/download/drag_download_file_browsertest.cc13
-rw-r--r--chromium/content/browser/download/drag_download_util.cc5
-rw-r--r--chromium/content/browser/download/drag_download_util.h2
-rw-r--r--chromium/content/browser/download/file_metadata_linux.cc1
-rw-r--r--chromium/content/browser/download/file_metadata_unittest_linux.cc1
-rw-r--r--chromium/content/browser/download/mhtml_generation_browsertest.cc130
-rw-r--r--chromium/content/browser/download/mhtml_generation_manager.cc429
-rw-r--r--chromium/content/browser/download/mhtml_generation_manager.h62
-rw-r--r--chromium/content/browser/download/mock_download_file.h7
-rw-r--r--chromium/content/browser/download/rate_estimator.cc18
-rw-r--r--chromium/content/browser/download/rate_estimator.h14
-rw-r--r--chromium/content/browser/download/save_file.cc2
-rw-r--r--chromium/content/browser/download/save_file.h9
-rw-r--r--chromium/content/browser/download/save_file_manager.cc341
-rw-r--r--chromium/content/browser/download/save_file_manager.h132
-rw-r--r--chromium/content/browser/download/save_file_resource_handler.cc36
-rw-r--r--chromium/content/browser/download/save_file_resource_handler.h15
-rw-r--r--chromium/content/browser/download/save_item.cc55
-rw-r--r--chromium/content/browser/download/save_item.h28
-rw-r--r--chromium/content/browser/download/save_package.cc625
-rw-r--r--chromium/content/browser/download/save_package.h159
-rw-r--r--chromium/content/browser/download/save_package_browsertest.cc13
-rw-r--r--chromium/content/browser/download/save_package_unittest.cc31
-rw-r--r--chromium/content/browser/download/save_types.cc46
-rw-r--r--chromium/content/browser/download/save_types.h46
-rw-r--r--chromium/content/browser/download/url_downloader.cc291
-rw-r--r--chromium/content/browser/download/url_downloader.h75
-rw-r--r--chromium/content/browser/file_descriptor_info_impl.cc20
-rw-r--r--chromium/content/browser/file_descriptor_info_impl.h7
-rw-r--r--chromium/content/browser/file_descriptor_info_impl_unittest.cc4
-rw-r--r--chromium/content/browser/fileapi/blob_reader_unittest.cc34
-rw-r--r--chromium/content/browser/fileapi/blob_storage_context_unittest.cc6
-rw-r--r--chromium/content/browser/fileapi/blob_storage_host.h1
-rw-r--r--chromium/content/browser/fileapi/blob_url_request_job_unittest.cc51
-rw-r--r--chromium/content/browser/fileapi/browser_file_system_helper.cc11
-rw-r--r--chromium/content/browser/fileapi/chrome_blob_storage_context.cc12
-rw-r--r--chromium/content/browser/fileapi/chrome_blob_storage_context.h3
-rw-r--r--chromium/content/browser/fileapi/copy_or_move_file_validator_unittest.cc20
-rw-r--r--chromium/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc104
-rw-r--r--chromium/content/browser/fileapi/dragged_file_util_unittest.cc13
-rw-r--r--chromium/content/browser/fileapi/external_mount_points_unittest.cc3
-rw-r--r--chromium/content/browser/fileapi/file_system_browsertest.cc4
-rw-r--r--chromium/content/browser/fileapi/file_system_context_unittest.cc4
-rw-r--r--chromium/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc12
-rw-r--r--chromium/content/browser/fileapi/file_system_file_stream_reader_unittest.cc14
-rw-r--r--chromium/content/browser/fileapi/file_system_operation_impl_unittest.cc73
-rw-r--r--chromium/content/browser/fileapi/file_system_operation_impl_write_unittest.cc19
-rw-r--r--chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc14
-rw-r--r--chromium/content/browser/fileapi/file_system_quota_client_unittest.cc92
-rw-r--r--chromium/content/browser/fileapi/file_system_url_request_job_unittest.cc14
-rw-r--r--chromium/content/browser/fileapi/file_system_url_unittest.cc3
-rw-r--r--chromium/content/browser/fileapi/file_system_usage_cache_unittest.cc40
-rw-r--r--chromium/content/browser/fileapi/file_writer_delegate_unittest.cc96
-rw-r--r--chromium/content/browser/fileapi/fileapi_message_filter.cc43
-rw-r--r--chromium/content/browser/fileapi/fileapi_message_filter.h12
-rw-r--r--chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc2
-rw-r--r--chromium/content/browser/fileapi/isolated_context_unittest.cc4
-rw-r--r--chromium/content/browser/fileapi/local_file_stream_reader_unittest.cc18
-rw-r--r--chromium/content/browser/fileapi/local_file_stream_writer_unittest.cc4
-rw-r--r--chromium/content/browser/fileapi/local_file_util_unittest.cc6
-rw-r--r--chromium/content/browser/fileapi/mock_file_change_observer.h2
-rw-r--r--chromium/content/browser/fileapi/mock_file_update_observer.cc2
-rw-r--r--chromium/content/browser/fileapi/mock_file_update_observer.h6
-rw-r--r--chromium/content/browser/fileapi/mock_url_request_delegate.cc4
-rw-r--r--chromium/content/browser/fileapi/native_file_util_unittest.cc5
-rw-r--r--chromium/content/browser/fileapi/obfuscated_file_util_unittest.cc87
-rw-r--r--chromium/content/browser/fileapi/plugin_private_file_system_backend_unittest.cc1
-rw-r--r--chromium/content/browser/fileapi/recursive_operation_delegate_unittest.cc4
-rw-r--r--chromium/content/browser/fileapi/sandbox_database_test_helper.cc19
-rw-r--r--chromium/content/browser/fileapi/sandbox_database_test_helper.h2
-rw-r--r--chromium/content/browser/fileapi/sandbox_directory_database_unittest.cc7
-rw-r--r--chromium/content/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc1
-rw-r--r--chromium/content/browser/fileapi/sandbox_file_system_backend_unittest.cc4
-rw-r--r--chromium/content/browser/fileapi/sandbox_isolated_origin_database_unittest.cc1
-rw-r--r--chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc3
-rw-r--r--chromium/content/browser/fileapi/sandbox_prioritized_origin_database_unittest.cc1
-rw-r--r--chromium/content/browser/fileapi/timed_task_helper_unittest.cc1
-rw-r--r--chromium/content/browser/fileapi/transient_file_util_unittest.cc2
-rw-r--r--chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc29
-rw-r--r--chromium/content/browser/fileapi/upload_file_system_file_element_reader.h21
-rw-r--r--chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc31
-rw-r--r--chromium/content/browser/font_list_async.cc4
-rw-r--r--chromium/content/browser/frame_host/DEPS2
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.cc56
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.h18
-rw-r--r--chromium/content/browser/frame_host/cross_site_transferring_request.h2
-rw-r--r--chromium/content/browser/frame_host/debug_urls.cc26
-rw-r--r--chromium/content/browser/frame_host/frame_mojo_shell.cc28
-rw-r--r--chromium/content/browser/frame_host/frame_mojo_shell.h4
-rw-r--r--chromium/content/browser/frame_host/frame_navigation_entry.cc36
-rw-r--r--chromium/content/browser/frame_host/frame_navigation_entry.h65
-rw-r--r--chromium/content/browser/frame_host/frame_tree.cc153
-rw-r--r--chromium/content/browser/frame_host/frame_tree.h58
-rw-r--r--chromium/content/browser/frame_host/frame_tree_browsertest.cc275
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.cc114
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.h61
-rw-r--r--chromium/content/browser/frame_host/frame_tree_unittest.cc194
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl.cc79
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl.h20
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc5
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_navigator_impl.h1
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_android.cc170
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_android.h159
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_delegate.h10
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.cc154
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.h31
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc875
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc232
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.cc227
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.h49
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc1
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc14
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_screenshot_manager.h1
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.cc249
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.h117
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc490
-rw-r--r--chromium/content/browser/frame_host/navigation_request.cc204
-rw-r--r--chromium/content/browser/frame_host/navigation_request.h28
-rw-r--r--chromium/content/browser/frame_host/navigation_request_info.cc6
-rw-r--r--chromium/content/browser/frame_host/navigation_request_info.h8
-rw-r--r--chromium/content/browser/frame_host/navigator.cc5
-rw-r--r--chromium/content/browser/frame_host/navigator.h19
-rw-r--r--chromium/content/browser/frame_host/navigator_delegate.cc4
-rw-r--r--chromium/content/browser/frame_host/navigator_delegate.h9
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.cc264
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.h22
-rw-r--r--chromium/content/browser/frame_host/navigator_impl_unittest.cc24
-rw-r--r--chromium/content/browser/frame_host/popup_menu_helper_mac.h1
-rw-r--r--chromium/content/browser/frame_host/popup_menu_helper_mac.mm16
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.cc14
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.h24
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_factory.cc4
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_factory.h12
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.cc615
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.h149
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc19
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.cc1144
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.h226
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc455
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc968
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.cc60
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.h23
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc (renamed from chromium/content/browser/renderer_host/render_message_filter_browsertest.cc)63
-rw-r--r--chromium/content/browser/frame_host/render_frame_proxy_host.cc52
-rw-r--r--chromium/content/browser/frame_host/render_frame_proxy_host.h13
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_child_frame.cc61
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_child_frame.h25
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc3
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc12
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.cc140
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.h26
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc14
-rw-r--r--chromium/content/browser/gamepad/gamepad_consumer.h1
-rw-r--r--chromium/content/browser/gamepad/gamepad_data_fetcher.cc85
-rw-r--r--chromium/content/browser/gamepad/gamepad_data_fetcher.h41
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher.h3
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.cc2
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.h1
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc44
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h17
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h13
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm89
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc126
-rw-r--r--chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.h9
-rw-r--r--chromium/content/browser/gamepad/gamepad_provider.cc11
-rw-r--r--chromium/content/browser/gamepad/gamepad_provider.h1
-rw-r--r--chromium/content/browser/gamepad/gamepad_provider_unittest.cc6
-rw-r--r--chromium/content/browser/gamepad/gamepad_service.cc4
-rw-r--r--chromium/content/browser/gamepad/gamepad_service.h2
-rw-r--r--chromium/content/browser/gamepad/gamepad_service_unittest.cc3
-rw-r--r--chromium/content/browser/gamepad/gamepad_standard_mappings_linux.cc10
-rw-r--r--chromium/content/browser/gamepad/gamepad_standard_mappings_mac.mm8
-rw-r--r--chromium/content/browser/gamepad/gamepad_standard_mappings_win.cc3
-rw-r--r--chromium/content/browser/gamepad/gamepad_test_helpers.h1
-rw-r--r--chromium/content/browser/gamepad/raw_input_data_fetcher_win.cc21
-rw-r--r--chromium/content/browser/gamepad/raw_input_data_fetcher_win.h4
-rw-r--r--chromium/content/browser/gamepad/xbox_data_fetcher_mac.cc86
-rw-r--r--chromium/content/browser/gamepad/xbox_data_fetcher_mac.h10
-rw-r--r--chromium/content/browser/geofencing/geofencing_dispatcher_host.cc6
-rw-r--r--chromium/content/browser/geofencing/geofencing_dispatcher_host.h9
-rw-r--r--chromium/content/browser/geofencing/geofencing_manager.cc99
-rw-r--r--chromium/content/browser/geofencing/geofencing_manager.h59
-rw-r--r--chromium/content/browser/geofencing/geofencing_manager_unittest.cc41
-rw-r--r--chromium/content/browser/geofencing/geofencing_provider.h7
-rw-r--r--chromium/content/browser/geofencing/geofencing_registration_delegate.h9
-rw-r--r--chromium/content/browser/geofencing/geofencing_service.cc24
-rw-r--r--chromium/content/browser/geofencing/geofencing_service.h26
-rw-r--r--chromium/content/browser/geofencing/geofencing_service_unittest.cc25
-rw-r--r--chromium/content/browser/geofencing/mock_geofencing_service.cc9
-rw-r--r--chromium/content/browser/geofencing/mock_geofencing_service.h12
-rw-r--r--chromium/content/browser/geolocation/empty_wifi_data_provider.h1
-rw-r--r--chromium/content/browser/geolocation/fake_access_token_store.h1
-rw-r--r--chromium/content/browser/geolocation/geolocation_provider_impl.cc2
-rw-r--r--chromium/content/browser/geolocation/geolocation_provider_impl.h2
-rw-r--r--chromium/content/browser/geolocation/geolocation_provider_impl_unittest.cc5
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_context.cc4
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_context.h1
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl.cc4
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl.h3
-rw-r--r--chromium/content/browser/geolocation/location_api_adapter_android.cc1
-rw-r--r--chromium/content/browser/geolocation/location_arbitrator_impl.cc3
-rw-r--r--chromium/content/browser/geolocation/location_arbitrator_impl.h5
-rw-r--r--chromium/content/browser/geolocation/location_provider_base.h1
-rw-r--r--chromium/content/browser/geolocation/mock_location_arbitrator.cc2
-rw-r--r--chromium/content/browser/geolocation/mock_location_arbitrator.h2
-rw-r--r--chromium/content/browser/geolocation/mock_location_provider.h1
-rw-r--r--chromium/content/browser/geolocation/network_location_provider.h4
-rw-r--r--chromium/content/browser/geolocation/network_location_provider_unittest.cc5
-rw-r--r--chromium/content/browser/geolocation/network_location_request.cc12
-rw-r--r--chromium/content/browser/geolocation/network_location_request.h2
-rw-r--r--chromium/content/browser/geolocation/osx_wifi.h102
-rw-r--r--chromium/content/browser/geolocation/wifi_data.cc11
-rw-r--r--chromium/content/browser/geolocation/wifi_data.h1
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider.h2
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_chromeos.cc4
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_chromeos.h1
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_common.cc2
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_common.h6
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_common_unittest.cc2
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_common_win.cc8
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm8
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_linux.cc18
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_linux.h1
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_linux_unittest.cc9
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_mac.cc150
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_mac.h1
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_manager.h2
-rw-r--r--chromium/content/browser/geolocation/wifi_data_provider_win.h1
-rw-r--r--chromium/content/browser/geolocation/wifi_polling_policy.h2
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc15
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.h11
-rw-r--r--chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc450
-rw-r--r--chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h123
-rw-r--r--chromium/content/browser/gpu/compositor_util.cc39
-rw-r--r--chromium/content/browser/gpu/compositor_util.h8
-rw-r--r--chromium/content/browser/gpu/gpu_arc_video_service_host.cc76
-rw-r--r--chromium/content/browser/gpu/gpu_arc_video_service_host.h54
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.cc3
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.h6
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.cc72
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.h9
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc4
-rw-r--r--chromium/content/browser/gpu/gpu_internals_ui.cc101
-rw-r--r--chromium/content/browser/gpu/gpu_internals_ui.h1
-rw-r--r--chromium/content/browser/gpu/gpu_ipc_browsertests.cc50
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.cc215
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.h80
-rw-r--r--chromium/content/browser/gpu/gpu_process_host_ui_shim.cc44
-rw-r--r--chromium/content/browser/gpu/gpu_process_host_ui_shim.h7
-rw-r--r--chromium/content/browser/gpu/gpu_surface_tracker.cc5
-rw-r--r--chromium/content/browser/gpu/gpu_surface_tracker.h4
-rw-r--r--chromium/content/browser/gpu/shader_disk_cache.cc9
-rw-r--r--chromium/content/browser/gpu/shader_disk_cache.h13
-rw-r--r--chromium/content/browser/gpu/shader_disk_cache_unittest.cc1
-rw-r--r--chromium/content/browser/gpu/test_support_gpu.gypi7
-rw-r--r--chromium/content/browser/histogram_controller.h1
-rw-r--r--chromium/content/browser/histogram_internals_request_job.h2
-rw-r--r--chromium/content/browser/histogram_message_filter.cc1
-rw-r--r--chromium/content/browser/histogram_message_filter.h1
-rw-r--r--chromium/content/browser/histogram_synchronizer.h2
-rw-r--r--chromium/content/browser/host_zoom_level_context.cc4
-rw-r--r--chromium/content/browser/host_zoom_map_impl.cc2
-rw-r--r--chromium/content/browser/host_zoom_map_impl.h7
-rw-r--r--chromium/content/browser/host_zoom_map_impl_unittest.cc3
-rw-r--r--chromium/content/browser/in_process_io_surface_manager_mac.cc52
-rw-r--r--chromium/content/browser/in_process_io_surface_manager_mac.h47
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc24
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_active_blob_registry.h26
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc17
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store.cc475
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store.h171
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc63
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_blob_info.cc25
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_blob_info.h20
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_browsertest.cc88
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_callbacks.cc47
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_callbacks.h40
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_class_factory.cc9
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_class_factory.h6
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc1
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_connection.h1
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_context_impl.cc27
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_context_impl.h18
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_cursor.cc8
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_cursor.h8
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database.cc266
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database.h162
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc11
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database_callbacks.h10
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database_error.cc14
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database_error.h13
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database_unittest.cc47
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc141
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h112
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory.h4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.cc6
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.h3
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc20
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc86
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_fake_backing_store.h90
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_index_writer.cc25
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_index_writer.h22
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_internals_ui.cc4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_internals_ui.h3
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc273
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h251
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc29
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_metadata.cc15
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_metadata.h35
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_pending_connection.cc4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_pending_connection.h11
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_quota_client.cc6
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_quota_client.h1
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc13
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction.cc6
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction.h16
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc5
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.h5
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc27
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_unittest.cc8
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_value.h2
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_database.cc23
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_database.h1
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc8
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h1
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc4
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_transaction.h1
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc2
-rw-r--r--chromium/content/browser/indexed_db/list_set.h2
-rw-r--r--chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc24
-rw-r--r--chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h6
-rw-r--r--chromium/content/browser/indexed_db/mock_indexed_db_callbacks.cc7
-rw-r--r--chromium/content/browser/indexed_db/mock_indexed_db_callbacks.h5
-rw-r--r--chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.cc2
-rw-r--r--chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.h9
-rw-r--r--chromium/content/browser/indexed_db/mock_indexed_db_factory.h3
-rw-r--r--chromium/content/browser/loader/async_resource_handler.cc12
-rw-r--r--chromium/content/browser/loader/async_resource_handler.h5
-rw-r--r--chromium/content/browser/loader/async_resource_handler_browsertest.cc27
-rw-r--r--chromium/content/browser/loader/async_revalidation_driver.cc274
-rw-r--r--chromium/content/browser/loader/async_revalidation_driver.h104
-rw-r--r--chromium/content/browser/loader/async_revalidation_driver_unittest.cc397
-rw-r--r--chromium/content/browser/loader/async_revalidation_manager.cc191
-rw-r--r--chromium/content/browser/loader/async_revalidation_manager.h107
-rw-r--r--chromium/content/browser/loader/async_revalidation_manager_browsertest.cc220
-rw-r--r--chromium/content/browser/loader/async_revalidation_manager_unittest.cc554
-rw-r--r--chromium/content/browser/loader/certificate_resource_handler.cc111
-rw-r--r--chromium/content/browser/loader/certificate_resource_handler.h72
-rw-r--r--chromium/content/browser/loader/cross_site_resource_handler.cc72
-rw-r--r--chromium/content/browser/loader/cross_site_resource_handler.h9
-rw-r--r--chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc278
-rw-r--r--chromium/content/browser/loader/detachable_resource_handler.cc4
-rw-r--r--chromium/content/browser/loader/detachable_resource_handler.h2
-rw-r--r--chromium/content/browser/loader/global_routing_id.h7
-rw-r--r--chromium/content/browser/loader/layered_resource_handler.cc6
-rw-r--r--chromium/content/browser/loader/mime_type_resource_handler.cc27
-rw-r--r--chromium/content/browser/loader/mime_type_resource_handler.h1
-rw-r--r--chromium/content/browser/loader/mime_type_resource_handler_unittest.cc26
-rw-r--r--chromium/content/browser/loader/navigation_resource_throttle.cc141
-rw-r--r--chromium/content/browser/loader/navigation_resource_throttle.h3
-rw-r--r--chromium/content/browser/loader/navigation_url_loader.cc12
-rw-r--r--chromium/content/browser/loader/navigation_url_loader.h3
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_factory.h1
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl.cc23
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl.h2
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl_core.cc25
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl_core.h3
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_unittest.cc20
-rw-r--r--chromium/content/browser/loader/power_save_block_resource_throttle.cc7
-rw-r--r--chromium/content/browser/loader/power_save_block_resource_throttle.h7
-rw-r--r--chromium/content/browser/loader/redirect_to_file_resource_handler.cc12
-rw-r--r--chromium/content/browser/loader/redirect_to_file_resource_handler.h2
-rw-r--r--chromium/content/browser/loader/resource_buffer.h2
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc305
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.cc321
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.h33
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_unittest.cc159
-rw-r--r--chromium/content/browser/loader/resource_loader.cc43
-rw-r--r--chromium/content/browser/loader/resource_loader.h1
-rw-r--r--chromium/content/browser/loader/resource_loader_unittest.cc60
-rw-r--r--chromium/content/browser/loader/resource_message_delegate.h2
-rw-r--r--chromium/content/browser/loader/resource_message_filter.cc6
-rw-r--r--chromium/content/browser/loader/resource_message_filter.h14
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.cc79
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.h18
-rw-r--r--chromium/content/browser/loader/resource_scheduler.cc90
-rw-r--r--chromium/content/browser/loader/resource_scheduler.h7
-rw-r--r--chromium/content/browser/loader/resource_scheduler_filter.cc8
-rw-r--r--chromium/content/browser/loader/resource_scheduler_unittest.cc135
-rw-r--r--chromium/content/browser/loader/stream_resource_handler.h1
-rw-r--r--chromium/content/browser/loader/sync_resource_handler.h4
-rw-r--r--chromium/content/browser/loader/temporary_file_stream.cc4
-rw-r--r--chromium/content/browser/loader/temporary_file_stream_unittest.cc6
-rw-r--r--chromium/content/browser/loader/throttling_resource_handler.cc6
-rw-r--r--chromium/content/browser/loader/throttling_resource_handler.h2
-rw-r--r--chromium/content/browser/loader/upload_data_stream_builder.cc32
-rw-r--r--chromium/content/browser/loader/upload_data_stream_builder_unittest.cc13
-rw-r--r--chromium/content/browser/mach_broker_mac.h1
-rw-r--r--chromium/content/browser/mach_broker_mac.mm2
-rw-r--r--chromium/content/browser/manifest/manifest_browsertest.cc143
-rw-r--r--chromium/content/browser/manifest/manifest_manager_host.cc116
-rw-r--r--chromium/content/browser/manifest/manifest_manager_host.h22
-rw-r--r--chromium/content/browser/media/android/browser_demuxer_android.cc1
-rw-r--r--chromium/content/browser/media/android/browser_demuxer_android.h1
-rw-r--r--chromium/content/browser/media/android/browser_media_player_manager.cc126
-rw-r--r--chromium/content/browser/media/android/browser_media_player_manager.h22
-rw-r--r--chromium/content/browser/media/android/browser_media_session_manager.cc34
-rw-r--r--chromium/content/browser/media/android/browser_media_session_manager.h38
-rw-r--r--chromium/content/browser/media/android/media_drm_credential_manager.cc119
-rw-r--r--chromium/content/browser/media/android/media_drm_credential_manager.h65
-rw-r--r--chromium/content/browser/media/android/media_resource_getter_impl.cc22
-rw-r--r--chromium/content/browser/media/android/media_resource_getter_impl.h6
-rw-r--r--chromium/content/browser/media/android/media_session.cc98
-rw-r--r--chromium/content/browser/media/android/media_session.h17
-rw-r--r--chromium/content/browser/media/android/media_session_browsertest.cc84
-rw-r--r--chromium/content/browser/media/android/media_session_uma_helper.cc8
-rw-r--r--chromium/content/browser/media/android/media_session_uma_helper.h4
-rw-r--r--chromium/content/browser/media/android/media_throttler.cc1
-rw-r--r--chromium/content/browser/media/android/media_throttler.h1
-rw-r--r--chromium/content/browser/media/android/media_web_contents_observer_android.cc200
-rw-r--r--chromium/content/browser/media/android/media_web_contents_observer_android.h78
-rw-r--r--chromium/content/browser/media/android/provision_fetcher_impl.cc56
-rw-r--r--chromium/content/browser/media/android/provision_fetcher_impl.h53
-rw-r--r--chromium/content/browser/media/android/url_provision_fetcher.cc77
-rw-r--r--chromium/content/browser/media/android/url_provision_fetcher.h41
-rw-r--r--chromium/content/browser/media/audible_metrics.cc79
-rw-r--r--chromium/content/browser/media/audible_metrics.h49
-rw-r--r--chromium/content/browser/media/audible_metrics_unittest.cc397
-rw-r--r--chromium/content/browser/media/audio_stream_monitor.cc16
-rw-r--r--chromium/content/browser/media/audio_stream_monitor.h9
-rw-r--r--chromium/content/browser/media/audio_stream_monitor_unittest.cc88
-rw-r--r--chromium/content/browser/media/capture/DEPS8
-rw-r--r--chromium/content/browser/media/capture/audio_mirroring_manager.h2
-rw-r--r--chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc1
-rw-r--r--chromium/content/browser/media/capture/aura_window_capture_machine.cc216
-rw-r--r--chromium/content/browser/media/capture/aura_window_capture_machine.h25
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer.h55
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer_aura.cc226
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer_aura.h78
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer_aura_unittest.cc203
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device.cc30
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device.h1
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_aura.cc4
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_aura.h1
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc40
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_unittest.cc67
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream.cc5
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream.h1
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc5
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_muter.cc3
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_muter.h1
-rw-r--r--chromium/content/browser/media/capture/web_contents_capture_util.cc64
-rw-r--r--chromium/content/browser/media/capture/web_contents_capture_util.h32
-rw-r--r--chromium/content/browser/media/capture/web_contents_tracker.h1
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device.cc212
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device.h1
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc154
-rw-r--r--chromium/content/browser/media/capture/window_activity_tracker.h32
-rw-r--r--chromium/content/browser/media/capture/window_activity_tracker_aura.cc71
-rw-r--r--chromium/content/browser/media/capture/window_activity_tracker_aura.h56
-rw-r--r--chromium/content/browser/media/cdm/browser_cdm_manager.cc201
-rw-r--r--chromium/content/browser/media/cdm/browser_cdm_manager.h49
-rw-r--r--chromium/content/browser/media/encrypted_media_browsertest.cc1
-rw-r--r--chromium/content/browser/media/media_browsertest.cc13
-rw-r--r--chromium/content/browser/media/media_browsertest.h4
-rw-r--r--chromium/content/browser/media/media_canplaytype_browsertest.cc265
-rw-r--r--chromium/content/browser/media/media_internals.cc18
-rw-r--r--chromium/content/browser/media/media_internals.h1
-rw-r--r--chromium/content/browser/media/media_internals_handler.h1
-rw-r--r--chromium/content/browser/media/media_internals_proxy.cc3
-rw-r--r--chromium/content/browser/media/media_internals_proxy.h1
-rw-r--r--chromium/content/browser/media/media_internals_ui.h1
-rw-r--r--chromium/content/browser/media/media_internals_unittest.cc5
-rw-r--r--chromium/content/browser/media/media_source_browsertest.cc10
-rw-r--r--chromium/content/browser/media/media_web_contents_observer.cc316
-rw-r--r--chromium/content/browser/media/media_web_contents_observer.h90
-rw-r--r--chromium/content/browser/media/midi_host.cc57
-rw-r--r--chromium/content/browser/media/midi_host.h26
-rw-r--r--chromium/content/browser/media/midi_host_unittest.cc70
-rw-r--r--chromium/content/browser/media/webrtc_audio_debug_recordings_browsertest.cc21
-rw-r--r--chromium/content/browser/media/webrtc_browsertest.cc35
-rw-r--r--chromium/content/browser/media/webrtc_getusermedia_browsertest.cc92
-rw-r--r--chromium/content/browser/media/webrtc_identity_store.cc9
-rw-r--r--chromium/content/browser/media/webrtc_identity_store.h1
-rw-r--r--chromium/content/browser/media/webrtc_identity_store_backend.cc16
-rw-r--r--chromium/content/browser/media/webrtc_identity_store_backend.h1
-rw-r--r--chromium/content/browser/media/webrtc_identity_store_unittest.cc7
-rw-r--r--chromium/content/browser/media/webrtc_internals.cc92
-rw-r--r--chromium/content/browser/media/webrtc_internals.h15
-rw-r--r--chromium/content/browser/media/webrtc_internals_browsertest.cc15
-rw-r--r--chromium/content/browser/media/webrtc_internals_message_handler.cc54
-rw-r--r--chromium/content/browser/media/webrtc_internals_message_handler.h8
-rw-r--r--chromium/content/browser/media/webrtc_internals_ui.h1
-rw-r--r--chromium/content/browser/media/webrtc_ip_permissions_browsertest.cc180
-rw-r--r--chromium/content/browser/media/webrtc_media_recorder_browsertest.cc153
-rw-r--r--chromium/content/browser/media/webrtc_webcam_browsertest.cc5
-rw-r--r--chromium/content/browser/memory/memory_message_filter.cc21
-rw-r--r--chromium/content/browser/memory/memory_message_filter.h23
-rw-r--r--chromium/content/browser/memory/memory_pressure_controller.cc61
-rw-r--r--chromium/content/browser/memory/memory_pressure_controller.h25
-rw-r--r--chromium/content/browser/memory/memory_pressure_controller_browsertest.cc79
-rw-r--r--chromium/content/browser/message_port_message_filter.cc2
-rw-r--r--chromium/content/browser/message_port_message_filter.h1
-rw-r--r--chromium/content/browser/message_port_provider.cc1
-rw-r--r--chromium/content/browser/message_port_provider_browsertest.cc1
-rw-r--r--chromium/content/browser/message_port_service.cc2
-rw-r--r--chromium/content/browser/message_port_service.h2
-rw-r--r--chromium/content/browser/mime_registry_message_filter.cc7
-rw-r--r--chromium/content/browser/mojo/OWNERS13
-rw-r--r--chromium/content/browser/mojo/mojo_app_connection_impl.cc5
-rw-r--r--chromium/content/browser/mojo/mojo_app_connection_impl.h2
-rw-r--r--chromium/content/browser/mojo/mojo_application_host.cc21
-rw-r--r--chromium/content/browser/mojo/mojo_application_host.h5
-rw-r--r--chromium/content/browser/mojo/mojo_shell_client_host.cc219
-rw-r--r--chromium/content/browser/mojo/mojo_shell_client_host.h48
-rw-r--r--chromium/content/browser/mojo/mojo_shell_context.cc102
-rw-r--r--chromium/content/browser/mojo/mojo_shell_context.h2
-rw-r--r--chromium/content/browser/mojo/renderer_capability_filter.cc22
-rw-r--r--chromium/content/browser/mojo/service_registrar_android.cc1
-rw-r--r--chromium/content/browser/mojo/service_registry_android.cc31
-rw-r--r--chromium/content/browser/mojo/service_registry_android.h25
-rw-r--r--chromium/content/browser/navigator_connect/navigator_connect_context_impl.cc100
-rw-r--r--chromium/content/browser/navigator_connect/navigator_connect_context_impl.h26
-rw-r--r--chromium/content/browser/navigator_connect/service_port_service_impl.cc12
-rw-r--r--chromium/content/browser/navigator_connect/service_port_service_impl.h11
-rw-r--r--chromium/content/browser/net/browser_online_state_observer.cc20
-rw-r--r--chromium/content/browser/net/browser_online_state_observer.h16
-rw-r--r--chromium/content/browser/net/network_errors_listing_ui.cc94
-rw-r--r--chromium/content/browser/net/network_errors_listing_ui.h25
-rw-r--r--chromium/content/browser/net/quota_policy_cookie_store.cc3
-rw-r--r--chromium/content/browser/net/quota_policy_cookie_store.h3
-rw-r--r--chromium/content/browser/net/quota_policy_cookie_store_unittest.cc2
-rw-r--r--chromium/content/browser/net/view_http_cache_job_factory.cc23
-rw-r--r--chromium/content/browser/net_info_browsertest.cc34
-rw-r--r--chromium/content/browser/notification_service_impl.h1
-rw-r--r--chromium/content/browser/notifications/PRESUBMIT.py12
-rw-r--r--chromium/content/browser/notifications/notification_database.cc44
-rw-r--r--chromium/content/browser/notifications/notification_database.h9
-rw-r--r--chromium/content/browser/notifications/notification_database_data_conversions.cc5
-rw-r--r--chromium/content/browser/notifications/notification_database_data_unittest.cc33
-rw-r--r--chromium/content/browser/notifications/notification_database_unittest.cc129
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl.cc70
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl.h3
-rw-r--r--chromium/content/browser/notifications/notification_id_generator.cc1
-rw-r--r--chromium/content/browser/notifications/notification_id_generator_unittest.cc236
-rw-r--r--chromium/content/browser/notifications/notification_message_filter.cc68
-rw-r--r--chromium/content/browser/notifications/notification_message_filter.h19
-rw-r--r--chromium/content/browser/notifications/page_notification_delegate.cc3
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_impl.cc137
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_impl.h1
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_unittest.cc82
-rw-r--r--chromium/content/browser/pepper_flash_settings_helper_impl.h2
-rw-r--r--chromium/content/browser/permissions/permission_service_context.cc4
-rw-r--r--chromium/content/browser/permissions/permission_service_context.h2
-rw-r--r--chromium/content/browser/permissions/permission_service_impl.cc128
-rw-r--r--chromium/content/browser/permissions/permission_service_impl.h18
-rw-r--r--chromium/content/browser/plugin_content_origin_whitelist.h1
-rw-r--r--chromium/content/browser/plugin_data_remover_impl.cc17
-rw-r--r--chromium/content/browser/plugin_data_remover_impl.h1
-rw-r--r--chromium/content/browser/plugin_loader_posix.cc4
-rw-r--r--chromium/content/browser/plugin_loader_posix.h9
-rw-r--r--chromium/content/browser/plugin_loader_posix_unittest.cc7
-rw-r--r--chromium/content/browser/plugin_process_host.cc22
-rw-r--r--chromium/content/browser/plugin_process_host.h20
-rw-r--r--chromium/content/browser/plugin_process_host_mac.cc5
-rw-r--r--chromium/content/browser/plugin_service_impl.cc5
-rw-r--r--chromium/content/browser/plugin_service_impl.h2
-rw-r--r--chromium/content/browser/power_monitor_message_broadcaster.h2
-rw-r--r--chromium/content/browser/power_monitor_message_broadcaster_unittest.cc1
-rw-r--r--chromium/content/browser/power_profiler/power_data_provider.h47
-rw-r--r--chromium/content/browser/power_profiler/power_data_provider_dummy.cc13
-rw-r--r--chromium/content/browser/power_profiler/power_data_provider_ia_win.cc104
-rw-r--r--chromium/content/browser/power_profiler/power_data_provider_ia_win.h38
-rw-r--r--chromium/content/browser/power_profiler/power_event.cc17
-rw-r--r--chromium/content/browser/power_profiler/power_event.h42
-rw-r--r--chromium/content/browser/power_profiler/power_profiler_observer.h33
-rw-r--r--chromium/content/browser/power_profiler/power_profiler_service.cc122
-rw-r--r--chromium/content/browser/power_profiler/power_profiler_service.h78
-rw-r--r--chromium/content/browser/power_profiler/power_profiler_service_unittest.cc143
-rw-r--r--chromium/content/browser/power_save_blocker_android.cc1
-rw-r--r--chromium/content/browser/power_save_blocker_chromeos.cc2
-rw-r--r--chromium/content/browser/power_save_blocker_impl.cc5
-rw-r--r--chromium/content/browser/power_save_blocker_impl.h9
-rw-r--r--chromium/content/browser/power_save_blocker_ozone.cc1
-rw-r--r--chromium/content/browser/power_save_blocker_win.cc1
-rw-r--r--chromium/content/browser/power_save_blocker_x11.cc119
-rw-r--r--chromium/content/browser/power_usage_monitor_impl.cc8
-rw-r--r--chromium/content/browser/power_usage_monitor_impl.h2
-rw-r--r--chromium/content/browser/power_usage_monitor_impl_unittest.cc4
-rw-r--r--chromium/content/browser/ppapi_plugin_process_host.cc53
-rw-r--r--chromium/content/browser/ppapi_plugin_process_host.h12
-rw-r--r--chromium/content/browser/presentation/presentation_service_impl.cc198
-rw-r--r--chromium/content/browser/presentation/presentation_service_impl.h68
-rw-r--r--chromium/content/browser/presentation/presentation_service_impl_unittest.cc280
-rw-r--r--chromium/content/browser/presentation/presentation_type_converters.cc25
-rw-r--r--chromium/content/browser/presentation/presentation_type_converters.h8
-rw-r--r--chromium/content/browser/profiler_controller_impl.h1
-rw-r--r--chromium/content/browser/profiler_message_filter.cc13
-rw-r--r--chromium/content/browser/profiler_message_filter.h9
-rw-r--r--chromium/content/browser/push_messaging/OWNERS6
-rw-r--r--chromium/content/browser/push_messaging/PRESUBMIT.py12
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_message_filter.cc265
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_message_filter.h47
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_router.cc42
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_router.h10
-rw-r--r--chromium/content/browser/quota/mock_quota_manager.cc15
-rw-r--r--chromium/content/browser/quota/mock_quota_manager.h11
-rw-r--r--chromium/content/browser/quota/mock_quota_manager_proxy.cc7
-rw-r--r--chromium/content/browser/quota/mock_quota_manager_proxy.h9
-rw-r--r--chromium/content/browser/quota/mock_quota_manager_unittest.cc1
-rw-r--r--chromium/content/browser/quota/quota_backend_impl_unittest.cc45
-rw-r--r--chromium/content/browser/quota/quota_database_unittest.cc144
-rw-r--r--chromium/content/browser/quota/quota_manager_unittest.cc317
-rw-r--r--chromium/content/browser/quota/quota_reservation_manager_unittest.cc58
-rw-r--r--chromium/content/browser/quota/quota_temporary_storage_evictor_unittest.cc76
-rw-r--r--chromium/content/browser/quota/storage_monitor_unittest.cc40
-rw-r--r--chromium/content/browser/quota/usage_tracker_unittest.cc53
-rw-r--r--chromium/content/browser/quota_dispatcher_host.cc48
-rw-r--r--chromium/content/browser/quota_dispatcher_host.h2
-rw-r--r--chromium/content/browser/renderer_host/DEPS3
-rw-r--r--chromium/content/browser/renderer_host/OWNERS2
-rw-r--r--chromium/content/browser/renderer_host/begin_frame_observer_proxy.h1
-rw-r--r--chromium/content/browser/renderer_host/begin_frame_observer_proxy_unittest.cc4
-rw-r--r--chromium/content/browser/renderer_host/clipboard_message_filter.cc12
-rw-r--r--chromium/content/browser/renderer_host/clipboard_message_filter.h11
-rw-r--r--chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm3
-rw-r--r--chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.cc354
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.h72
-rw-r--r--chromium/content/browser/renderer_host/compositor_resize_lock_aura.h1
-rw-r--r--chromium/content/browser/renderer_host/database_message_filter.cc34
-rw-r--r--chromium/content/browser/renderer_host/database_message_filter.h16
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_evictor.h1
-rw-r--r--chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc347
-rw-r--r--chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h65
-rw-r--r--chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc145
-rw-r--r--chromium/content/browser/renderer_host/file_utilities_message_filter.h2
-rw-r--r--chromium/content/browser/renderer_host/font_utils_linux.cc6
-rw-r--r--chromium/content/browser/renderer_host/font_utils_linux.h6
-rw-r--r--chromium/content/browser/renderer_host/gamepad_browser_message_filter.h1
-rw-r--r--chromium/content/browser/renderer_host/gpu_message_filter.cc65
-rw-r--r--chromium/content/browser/renderer_host/gpu_message_filter.h28
-rw-r--r--chromium/content/browser/renderer_host/ime_adapter_android.cc72
-rw-r--r--chromium/content/browser/renderer_host/ime_adapter_android.h53
-rw-r--r--chromium/content/browser/renderer_host/input/OWNERS1
-rw-r--r--chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc171
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue.h4
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc12
-rw-r--r--chromium/content/browser/renderer_host/input/input_ack_handler.h1
-rw-r--r--chromium/content/browser/renderer_host/input/input_router.h8
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_config_helper.cc1
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.cc68
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.h28
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl_perftest.cc15
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc593
-rw-r--r--chromium/content/browser/renderer_host/input/mock_input_ack_handler.h7
-rw-r--r--chromium/content/browser/renderer_host/input/mock_input_router_client.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/mock_input_router_client.h7
-rw-r--r--chromium/content/browser/renderer_host/input/motion_event_android.cc348
-rw-r--r--chromium/content/browser/renderer_host/input/motion_event_android.h134
-rw-r--r--chromium/content/browser/renderer_host/input/motion_event_android_unittest.cc222
-rw-r--r--chromium/content/browser/renderer_host/input/motion_event_web.cc65
-rw-r--r--chromium/content/browser/renderer_host/input/motion_event_web.h12
-rw-r--r--chromium/content/browser/renderer_host/input/motion_event_web_unittest.cc80
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc30
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h10
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc3
-rw-r--r--chromium/content/browser/renderer_host/input/stylus_text_selector.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture.cc6
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture.h5
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc9
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc196
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc12
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h5
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc16
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_mac.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.cc49
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.h44
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer.cc35
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer.h51
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc58
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action.h45
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc118
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h29
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc54
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h9
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touch_pointer.cc46
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touch_pointer.h45
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc8
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc35
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h7
-rw-r--r--chromium/content/browser/renderer_host/input/tap_suppression_controller.h1
-rw-r--r--chromium/content/browser/renderer_host/input/tap_suppression_controller_client.h2
-rw-r--r--chromium/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/timeout_monitor.h2
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_browsertest.cc12
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter.cc29
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter.h2
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc36
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator.cc23
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator.h1
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator_client.h3
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator_unittest.cc6
-rw-r--r--chromium/content/browser/renderer_host/input/touch_event_queue.cc14
-rw-r--r--chromium/content/browser/renderer_host/input/touch_event_queue.h9
-rw-r--r--chromium/content/browser/renderer_host/input/touch_event_queue_unittest.cc15
-rw-r--r--chromium/content/browser/renderer_host/input/touch_input_browsertest.cc10
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc37
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h14
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc111
-rw-r--r--chromium/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h1
-rw-r--r--chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc6
-rw-r--r--chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h1
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_android.h6
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm34
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm4
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc59
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_win.h6
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_util.cc117
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_util.h5
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc78
-rw-r--r--chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc2
-rw-r--r--chromium/content/browser/renderer_host/legacy_render_widget_host_win.h2
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_debug_writer.cc9
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_debug_writer.h4
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_device_manager.cc1
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_device_manager.h3
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc4
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc37
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_renderer_host.h9
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc39
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_sync_writer.h26
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc20
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_device_enumerator.cc28
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_device_enumerator.h24
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc115
-rw-r--r--chromium/content/browser/renderer_host/media/audio_renderer_host.cc303
-rw-r--r--chromium/content/browser/renderer_host/media/audio_renderer_host.h60
-rw-r--r--chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc154
-rw-r--r--chromium/content/browser/renderer_host/media/audio_sync_reader.cc29
-rw-r--r--chromium/content/browser/renderer_host/media/audio_sync_reader.h9
-rw-r--r--chromium/content/browser/renderer_host/media/media_capture_devices_impl.h1
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc26
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h3
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc179
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager.cc482
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager.h65
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc126
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.h8
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc1
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc5
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy.h2
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc32
-rw-r--r--chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h5
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_buffer_pool.cc160
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_buffer_pool.h12
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc49
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller.cc190
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller.h16
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc196
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_device_client.cc465
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_device_client.h31
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_device_client_unittest.cc8
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc11
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h6
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_host.cc13
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_host.h3
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_host_unittest.cc11
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_manager.cc228
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_manager.h36
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc21
-rw-r--r--chromium/content/browser/renderer_host/media/webrtc_identity_service_host.h2
-rw-r--r--chromium/content/browser/renderer_host/memory_benchmark_message_filter.cc1
-rw-r--r--chromium/content/browser/renderer_host/memory_benchmark_message_filter.h1
-rw-r--r--chromium/content/browser/renderer_host/native_web_keyboard_event_aura.cc36
-rw-r--r--chromium/content/browser/renderer_host/overscroll_configuration.cc36
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller.h2
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller_delegate.h2
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc78
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h20
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host.cc73
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host.h24
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc28
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp.h5
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.cc2
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.h5
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc7
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc61
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_test_utils.cc30
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_test_utils.h13
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_throttler.cc5
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_throttler.h3
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_udp.cc57
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_udp.h21
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc48
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h5
-rw-r--r--chromium/content/browser/renderer_host/pepper/browser_ppapi_host_test.h2
-rw-r--r--chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc9
-rw-r--r--chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h1
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc8
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_io_host.h4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc8
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_lookup_request.h1
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_message_filter.h2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h1
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_printing_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_printing_host.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_printing_host_unittest.cc13
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc18
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.h2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc11
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_socket_utils.h1
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc10
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc543
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc23
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font.h2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.h3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm1
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc1
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_mac.mm3
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_win.cc46
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc15
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h7
-rw-r--r--chromium/content/browser/renderer_host/pepper/quota_reservation.h2
-rw-r--r--chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc45
-rw-r--r--chromium/content/browser/renderer_host/pepper/ssl_context_helper.h2
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.cc154
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.h55
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_browsertest.cc7
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.cc874
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.h83
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_unittest.cc3
-rw-r--r--chromium/content/browser/renderer_host/render_sandbox_host_linux.h1
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_browsertest.cc20
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate.cc8
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate.h68
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate_view.h2
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_factory.cc19
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_factory.h12
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_impl.cc310
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_impl.h156
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_unittest.cc5
-rw-r--r--chromium/content/browser/renderer_host/render_widget_helper.cc34
-rw-r--r--chromium/content/browser/renderer_host/render_widget_helper.h33
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.cc25
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.h83
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.cc319
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.h212
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc63
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.h22
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h63
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_unittest.cc210
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.cc290
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.h45
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.cc344
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.h30
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc145
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.cc16
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.h48
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc108
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.h25
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.mm238
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h2
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm4
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h2
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm2
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm6
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm106
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mus.cc334
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mus.h142
-rw-r--r--chromium/content/browser/renderer_host/renderer_frame_manager.cc1
-rw-r--r--chromium/content/browser/renderer_host/renderer_frame_manager.h4
-rw-r--r--chromium/content/browser/renderer_host/sandbox_ipc_linux.cc43
-rw-r--r--chromium/content/browser/renderer_host/sandbox_ipc_linux.h19
-rw-r--r--chromium/content/browser/renderer_host/text_input_client_mac.h4
-rw-r--r--chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm11
-rw-r--r--chromium/content/browser/renderer_host/text_input_client_message_filter.h3
-rw-r--r--chromium/content/browser/renderer_host/ui_events_helper.cc18
-rw-r--r--chromium/content/browser/renderer_host/web_input_event_aura.cc69
-rw-r--r--chromium/content/browser/renderer_host/web_input_event_aura_unittest.cc79
-rw-r--r--chromium/content/browser/renderer_host/web_input_event_aurawin.cc37
-rw-r--r--chromium/content/browser/renderer_host/webmenurunner_mac.mm2
-rw-r--r--chromium/content/browser/renderer_host/websocket_dispatcher_host.cc10
-rw-r--r--chromium/content/browser/renderer_host/websocket_dispatcher_host.h13
-rw-r--r--chromium/content/browser/renderer_host/websocket_host.cc38
-rw-r--r--chromium/content/browser/renderer_host/websocket_host.h7
-rw-r--r--chromium/content/browser/resource_context_impl.cc4
-rw-r--r--chromium/content/browser/resource_loading_browsertest.cc7
-rw-r--r--chromium/content/browser/resources/accessibility/accessibility.html3
-rw-r--r--chromium/content/browser/resources/accessibility/accessibility.js16
-rw-r--r--chromium/content/browser/resources/gpu/browser_bridge.js28
-rw-r--r--chromium/content/browser/resources/gpu/browser_bridge_tests.js1
-rw-r--r--chromium/content/browser/resources/gpu/info_view.html5
-rw-r--r--chromium/content/browser/resources/gpu/info_view.js9
-rw-r--r--chromium/content/browser/resources/media/dump_creator.js46
-rw-r--r--chromium/content/browser/resources/media/manager.js27
-rw-r--r--chromium/content/browser/resources/media/webrtc_internals.js8
-rw-r--r--chromium/content/browser/resources/net/network_errors_listing.css16
-rw-r--r--chromium/content/browser/resources/net/network_errors_listing.html27
-rw-r--r--chromium/content/browser/resources/net/network_errors_listing.js50
-rw-r--r--chromium/content/browser/safe_util_win.cc1
-rw-r--r--chromium/content/browser/safe_util_win.h2
-rw-r--r--chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc33
-rw-r--r--chromium/content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h1
-rw-r--r--chromium/content/browser/screen_orientation/screen_orientation_message_filter_android.h1
-rw-r--r--chromium/content/browser/security_exploit_browsertest.cc28
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.cc383
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.h61
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc330
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_registry.cc2
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_registry.h5
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.cc83
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.h44
-rw-r--r--chromium/content/browser/service_worker/foreign_fetch_request_handler.cc227
-rw-r--r--chromium/content/browser/service_worker/foreign_fetch_request_handler.h142
-rw-r--r--chromium/content/browser/service_worker/service_worker_browsertest.cc64
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer.cc506
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer.h232
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc809
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_utils.cc397
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_utils.h60
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.cc173
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.h78
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_observer.h29
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler.cc25
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler.h5
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc30
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_unittest.cc71
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.cc40
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.h40
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.cc121
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.h44
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc200
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.h60
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc68
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.cc732
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.h232
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.proto2
-rw-r--r--chromium/content/browser/service_worker/service_worker_database_task_manager.h1
-rw-r--r--chromium/content/browser/service_worker/service_worker_database_unittest.cc470
-rw-r--r--chromium/content/browser/service_worker/service_worker_disk_cache.cc34
-rw-r--r--chromium/content/browser/service_worker/service_worker_disk_cache.h28
-rw-r--r--chromium/content/browser/service_worker/service_worker_disk_cache_migrator.cc504
-rw-r--r--chromium/content/browser/service_worker/service_worker_disk_cache_migrator.h123
-rw-r--r--chromium/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc539
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host.cc88
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host.h22
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc129
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc7
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_handle.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_handle_unittest.cc16
-rw-r--r--chromium/content/browser/service_worker/service_worker_info.cc24
-rw-r--r--chromium/content/browser/service_worker/service_worker_info.h16
-rw-r--r--chromium/content/browser/service_worker/service_worker_internals_ui.cc25
-rw-r--r--chromium/content/browser/service_worker/service_worker_job_coordinator.cc10
-rw-r--r--chromium/content/browser/service_worker/service_worker_job_coordinator.h1
-rw-r--r--chromium/content/browser/service_worker/service_worker_job_unittest.cc81
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.cc50
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.h32
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_handle.cc35
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_handle.h78
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc65
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_handle_core.h57
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager.cc116
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager.h20
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc203
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.cc99
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.h27
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc17
-rw-r--r--chromium/content/browser/service_worker/service_worker_quota_client.h1
-rw-r--r--chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc91
-rw-r--r--chromium/content/browser/service_worker/service_worker_read_from_cache_job.h19
-rw-r--r--chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc234
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.cc24
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.h3
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.cc94
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.h26
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_handle.h1
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_unittest.cc53
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.cc127
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.h18
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc12
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_cache_map.cc29
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_cache_map.h14
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.cc423
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.h162
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_unittest.cc395
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_unregister_job.cc6
-rw-r--r--chromium/content/browser/service_worker/service_worker_unregister_job.h12
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.cc242
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.h81
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc358
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.cc906
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.h396
-rw-r--r--chromium/content/browser/service_worker/service_worker_version_unittest.cc506
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc687
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job.h67
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc93
-rw-r--r--chromium/content/browser/session_history_browsertest.cc6
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host.cc27
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host.h4
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_instance.cc10
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_instance.h20
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc24
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_message_filter.cc26
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_message_filter.h8
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.cc76
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.h15
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc37
-rw-r--r--chromium/content/browser/shared_worker/worker_browsertest.cc39
-rw-r--r--chromium/content/browser/shared_worker/worker_document_set.h1
-rw-r--r--chromium/content/browser/signed_certificate_timestamp_store_impl.h1
-rw-r--r--chromium/content/browser/site_instance_impl.cc67
-rw-r--r--chromium/content/browser/site_instance_impl.h46
-rw-r--r--chromium/content/browser/site_instance_impl_unittest.cc2
-rw-r--r--chromium/content/browser/site_per_process_browsertest.cc1631
-rw-r--r--chromium/content/browser/speech/audio_buffer.cc14
-rw-r--r--chromium/content/browser/speech/audio_buffer.h17
-rw-r--r--chromium/content/browser/speech/audio_encoder.cc2
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer.cc32
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer.h13
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer_unittest.cc20
-rw-r--r--chromium/content/browser/speech/endpointer/endpointer.cc12
-rw-r--r--chromium/content/browser/speech/endpointer/endpointer.h31
-rw-r--r--chromium/content/browser/speech/endpointer/endpointer_unittest.cc34
-rw-r--r--chromium/content/browser/speech/endpointer/energy_endpointer.cc39
-rw-r--r--chromium/content/browser/speech/endpointer/energy_endpointer.h22
-rw-r--r--chromium/content/browser/speech/endpointer/energy_endpointer_params.h1
-rw-r--r--chromium/content/browser/speech/google_one_shot_remote_engine.cc5
-rw-r--r--chromium/content/browser/speech/google_one_shot_remote_engine.h2
-rw-r--r--chromium/content/browser/speech/google_streaming_remote_engine.cc23
-rw-r--r--chromium/content/browser/speech/google_streaming_remote_engine.h11
-rw-r--r--chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc5
-rw-r--r--chromium/content/browser/speech/speech_recognition_browsertest.cc10
-rw-r--r--chromium/content/browser/speech/speech_recognition_dispatcher_host.h1
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine.cc2
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine.h5
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.cc12
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.h4
-rw-r--r--chromium/content/browser/speech/speech_recognizer.h1
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.cc14
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.h2
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_android.cc76
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_android.h26
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_unittest.cc7
-rw-r--r--chromium/content/browser/ssl/ssl_cert_error_handler.cc11
-rw-r--r--chromium/content/browser/ssl/ssl_cert_error_handler.h3
-rw-r--r--chromium/content/browser/ssl/ssl_client_auth_handler.cc9
-rw-r--r--chromium/content/browser/ssl/ssl_client_auth_handler.h1
-rw-r--r--chromium/content/browser/ssl/ssl_error_handler.cc19
-rw-r--r--chromium/content/browser/ssl/ssl_error_handler.h19
-rw-r--r--chromium/content/browser/ssl/ssl_manager.cc38
-rw-r--r--chromium/content/browser/ssl/ssl_manager.h16
-rw-r--r--chromium/content/browser/ssl/ssl_policy.cc32
-rw-r--r--chromium/content/browser/ssl/ssl_policy.h3
-rw-r--r--chromium/content/browser/ssl/ssl_policy_backend.h2
-rw-r--r--chromium/content/browser/ssl/ssl_request_info.cc2
-rw-r--r--chromium/content/browser/ssl/ssl_request_info.h6
-rw-r--r--chromium/content/browser/startup_task_runner.h1
-rw-r--r--chromium/content/browser/storage_partition_impl.cc44
-rw-r--r--chromium/content/browser/storage_partition_impl.h19
-rw-r--r--chromium/content/browser/storage_partition_impl_map.cc32
-rw-r--r--chromium/content/browser/storage_partition_impl_map_unittest.cc10
-rw-r--r--chromium/content/browser/storage_partition_impl_unittest.cc31
-rw-r--r--chromium/content/browser/streams/stream.cc2
-rw-r--r--chromium/content/browser/streams/stream.h4
-rw-r--r--chromium/content/browser/streams/stream_handle_impl.cc2
-rw-r--r--chromium/content/browser/streams/stream_registry.h4
-rw-r--r--chromium/content/browser/streams/stream_unittest.cc2
-rw-r--r--chromium/content/browser/streams/stream_url_request_job.cc65
-rw-r--r--chromium/content/browser/streams/stream_url_request_job.h7
-rw-r--r--chromium/content/browser/system_message_window_win.cc8
-rw-r--r--chromium/content/browser/system_message_window_win.h2
-rw-r--r--chromium/content/browser/tcmalloc_internals_request_job.cc121
-rw-r--r--chromium/content/browser/tcmalloc_internals_request_job.h67
-rw-r--r--chromium/content/browser/theme_helper_mac.h1
-rw-r--r--chromium/content/browser/theme_helper_mac.mm10
-rw-r--r--chromium/content/browser/time_zone_monitor.cc1
-rw-r--r--chromium/content/browser/time_zone_monitor.h2
-rw-r--r--chromium/content/browser/time_zone_monitor_android.cc6
-rw-r--r--chromium/content/browser/time_zone_monitor_android.h6
-rw-r--r--chromium/content/browser/time_zone_monitor_chromeos.cc1
-rw-r--r--chromium/content/browser/time_zone_monitor_linux.cc4
-rw-r--r--chromium/content/browser/time_zone_monitor_mac.mm5
-rw-r--r--chromium/content/browser/time_zone_monitor_win.cc2
-rw-r--r--chromium/content/browser/tracing/OWNERS3
-rw-r--r--chromium/content/browser/tracing/background_tracing_config_impl.cc46
-rw-r--r--chromium/content/browser/tracing/background_tracing_config_impl.h16
-rw-r--r--chromium/content/browser/tracing/background_tracing_config_unittest.cc132
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_browsertest.cc388
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_impl.cc319
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_impl.h33
-rw-r--r--chromium/content/browser/tracing/background_tracing_rule.cc238
-rw-r--r--chromium/content/browser/tracing/background_tracing_rule.h12
-rw-r--r--chromium/content/browser/tracing/battor_power_trace_provider.cc2
-rw-r--r--chromium/content/browser/tracing/battor_power_trace_provider.h3
-rw-r--r--chromium/content/browser/tracing/etw_system_event_consumer_win.cc49
-rw-r--r--chromium/content/browser/tracing/etw_system_event_consumer_win.h24
-rw-r--r--chromium/content/browser/tracing/file_tracing_provider_impl.cc2
-rw-r--r--chromium/content/browser/tracing/file_tracing_provider_impl.h4
-rw-r--r--chromium/content/browser/tracing/memory_tracing_browsertest.cc24
-rw-r--r--chromium/content/browser/tracing/power_tracing_agent.cc128
-rw-r--r--chromium/content/browser/tracing/power_tracing_agent.h35
-rw-r--r--chromium/content/browser/tracing/trace_message_filter.cc24
-rw-r--r--chromium/content/browser/tracing/trace_message_filter.h14
-rw-r--r--chromium/content/browser/tracing/tracing_controller_browsertest.cc304
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl.cc538
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl.h106
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl_data_sinks.cc150
-rw-r--r--chromium/content/browser/tracing/tracing_resources.gyp3
-rw-r--r--chromium/content/browser/tracing/tracing_ui.cc47
-rw-r--r--chromium/content/browser/tracing/tracing_ui.h5
-rw-r--r--chromium/content/browser/udev_linux.cc2
-rw-r--r--chromium/content/browser/udev_linux.h2
-rw-r--r--chromium/content/browser/utility_process_host_impl.cc88
-rw-r--r--chromium/content/browser/utility_process_host_impl.h8
-rw-r--r--chromium/content/browser/vibration_manager_integration_browsertest.cc140
-rw-r--r--chromium/content/browser/vr/OWNERS1
-rw-r--r--chromium/content/browser/vr/android/cardboard/cardboard_vr_device.cc5
-rw-r--r--chromium/content/browser/vr/android/cardboard/cardboard_vr_device.h2
-rw-r--r--chromium/content/browser/vr/android/cardboard/cardboard_vr_device_provider.h2
-rw-r--r--chromium/content/browser/vr/vr_device_manager.cc11
-rw-r--r--chromium/content/browser/vr/vr_device_manager.h4
-rw-r--r--chromium/content/browser/vr/vr_device_manager_unittest.cc1
-rw-r--r--chromium/content/browser/wake_lock/wake_lock_browsertest.cc376
-rw-r--r--chromium/content/browser/wake_lock/wake_lock_service_context.cc92
-rw-r--r--chromium/content/browser/wake_lock/wake_lock_service_context.h68
-rw-r--r--chromium/content/browser/wake_lock/wake_lock_service_context_unittest.cc96
-rw-r--r--chromium/content/browser/wake_lock/wake_lock_service_impl.cc35
-rw-r--r--chromium/content/browser/wake_lock/wake_lock_service_impl.h41
-rw-r--r--chromium/content/browser/web_contents/aura/gesture_nav_simple.cc12
-rw-r--r--chromium/content/browser/web_contents/aura/gesture_nav_simple.h1
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc10
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc30
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_animation.cc3
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_animation.h1
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_animation_unittest.cc3
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_delegate.h1
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc7
-rw-r--r--chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc1
-rw-r--r--chromium/content/browser/web_contents/aura/shadow_layer_delegate.h1
-rw-r--r--chromium/content/browser/web_contents/opened_by_dom_browsertest.cc23
-rw-r--r--chromium/content/browser/web_contents/web_contents_android.cc335
-rw-r--r--chromium/content/browser/web_contents/web_contents_android.h235
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.cc850
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.h202
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_browsertest.cc105
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_unittest.cc175
-rw-r--r--chromium/content/browser/web_contents/web_contents_view.h2
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.cc6
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.h1
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.cc77
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.h1
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc122
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.cc9
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.h4
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.h10
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.mm31
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mus.cc266
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mus.h119
-rw-r--r--chromium/content/browser/web_contents/web_drag_source_mac.h4
-rw-r--r--chromium/content/browser/web_contents/web_drag_source_mac.mm25
-rw-r--r--chromium/content/browser/webkit_browsertest.cc27
-rw-r--r--chromium/content/browser/webui/OWNERS1
-rw-r--r--chromium/content/browser/webui/content_web_ui_controller_factory.cc7
-rw-r--r--chromium/content/browser/webui/content_web_ui_controller_factory.h2
-rw-r--r--chromium/content/browser/webui/generic_handler.h1
-rw-r--r--chromium/content/browser/webui/shared_resources_data_source.cc5
-rw-r--r--chromium/content/browser/webui/shared_resources_data_source.h2
-rw-r--r--chromium/content/browser/webui/url_data_manager.cc2
-rw-r--r--chromium/content/browser/webui/url_data_manager.h1
-rw-r--r--chromium/content/browser/webui/url_data_manager_backend.cc100
-rw-r--r--chromium/content/browser/webui/url_data_manager_backend.h4
-rw-r--r--chromium/content/browser/webui/url_data_manager_backend_unittest.cc27
-rw-r--r--chromium/content/browser/webui/url_data_source_impl.cc11
-rw-r--r--chromium/content/browser/webui/url_data_source_impl.h3
-rw-r--r--chromium/content/browser/webui/web_ui_controller_factory_registry.cc2
-rw-r--r--chromium/content/browser/webui/web_ui_controller_factory_registry.h1
-rw-r--r--chromium/content/browser/webui/web_ui_data_source_impl.cc65
-rw-r--r--chromium/content/browser/webui/web_ui_data_source_impl.h3
-rw-r--r--chromium/content/browser/webui/web_ui_data_source_unittest.cc136
-rw-r--r--chromium/content/browser/webui/web_ui_impl.cc7
-rw-r--r--chromium/content/browser/webui/web_ui_impl.h11
-rw-r--r--chromium/content/browser/webui/web_ui_mojo_browsertest.cc52
-rw-r--r--chromium/content/browser/zygote_host/zygote_host_impl_linux.cc11
-rw-r--r--chromium/content/browser/zygote_host/zygote_host_impl_linux.h2
1718 files changed, 61681 insertions, 36318 deletions
diff --git a/chromium/content/browser/BUILD.gn b/chromium/content/browser/BUILD.gn
index 23dca61865d..4d66f86c09f 100644
--- a/chromium/content/browser/BUILD.gn
+++ b/chromium/content/browser/BUILD.gn
@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//build/config/crypto.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
import("//content/browser/browser.gni")
@@ -13,7 +12,10 @@ source_set("browser") {
# internal content ones) should depend on the public one.
visibility = [ "//content/public/browser:browser_sources" ]
- configs += [ "//build/config:precompiled_headers" ]
+ configs += [
+ "//build/config:precompiled_headers",
+ "//content/public/common:mojo_shell_client",
+ ]
defines = []
libs = []
ldflags = []
@@ -36,19 +38,20 @@ source_set("browser") {
"//device/battery",
"//device/vibration",
"//google_apis",
- "//mojo/application/public/cpp:cpp_for_chromium",
- "//mojo/application/public/interfaces",
"//mojo/common",
- "//mojo/package_manager",
+ "//mojo/public/cpp/bindings",
"//mojo/shell",
+ "//mojo/shell/package_manager",
+ "//mojo/shell/public/cpp:cpp_for_chromium",
+ "//mojo/shell/public/interfaces",
"//net",
"//net:extras",
"//skia",
"//sql",
- "//third_party/mojo/src/mojo/public/cpp/bindings",
+ "//third_party/WebKit/public:blink_headers",
+ "//third_party/kasko:kasko_features",
"//third_party/npapi",
"//third_party/re2",
- "//third_party/WebKit/public:blink_headers",
"//third_party/zlib",
"//third_party/zlib:zip",
"//ui/accessibility",
@@ -105,10 +108,17 @@ source_set("browser") {
],
".")
+ sources += [
+ "mojo/mojo_shell_client_host.cc",
+ "mojo/mojo_shell_client_host.h",
+ "mojo/renderer_capability_filter.cc",
+ ]
+
# Non-iOS deps.
deps += [
"//cc",
"//cc/surfaces",
+ "//components/scheduler:common",
"//content/app/resources",
"//content/app/strings",
"//content/browser/devtools:gen_devtools_protocol_handler",
@@ -117,9 +127,11 @@ source_set("browser") {
"//content/public/common:mojo_bindings",
"//device/bluetooth",
"//gin",
- "//mojo/application/public/interfaces",
"//mojo/common:url_type_converters",
"//mojo/converters/geometry",
+ "//mojo/public/cpp/bindings",
+ "//mojo/public/js",
+ "//mojo/shell/public/interfaces",
"//skia/public",
"//storage/browser",
"//storage/common",
@@ -129,13 +141,13 @@ source_set("browser") {
"//third_party/icu",
"//third_party/leveldatabase",
"//third_party/libyuv",
- "//third_party/mojo/src/mojo/public/cpp/bindings",
- "//third_party/mojo/src/mojo/public/js",
"//ui/events/blink",
"//ui/resources",
"//ui/surface",
"//ui/touch_selection",
]
+
+ configs += [ "//v8:external_startup_data" ]
}
configs += [
@@ -147,17 +159,10 @@ source_set("browser") {
deps += [ "//ui/events" ]
}
- if (is_win) {
- sources += [
- "power_profiler/power_data_provider_ia_win.cc",
- "power_profiler/power_data_provider_ia_win.h",
- ]
- deps += [ "//third_party/power_gadget" ]
- } else {
+ if (!is_win) {
sources += [
"file_descriptor_info_impl.cc",
"file_descriptor_info_impl.h",
- "power_profiler/power_data_provider_dummy.cc",
]
sources -= [ "renderer_host/web_input_event_aurawin.cc" ]
}
@@ -342,7 +347,6 @@ source_set("browser") {
"geolocation/network_location_request.h",
"power_usage_monitor_impl.cc",
"power_usage_monitor_impl.h",
- "renderer_host/begin_frame_observer_proxy.cc",
"tracing/tracing_ui.cc",
"tracing/tracing_ui.h",
@@ -368,13 +372,28 @@ source_set("browser") {
"speech/speech_recognizer_impl.cc",
"speech/speech_recognizer_impl.h",
]
+
+ if (!use_aura) {
+ sources += rebase_path(
+ content_browser_gypi_values.android_non_aura_browser_sources,
+ ".",
+ "//content")
+ sources += rebase_path(
+ content_browser_gypi_values.android_in_process_browser_sources,
+ ".",
+ "//content")
+ sources -= [ "renderer_host/begin_frame_observer_proxy.cc" ]
+ deps += [ "//ui/android" ]
+ }
+
deps -= [ "//device/battery" ]
deps += [
"//content/public/android:jni",
"//media",
+ "//media/mojo/interfaces",
"//mojo/android:libsystem_java",
- "//ui/android",
]
+ defines += [ "APPCACHE_USE_SIMPLE_CACHE" ]
libs += [ "jnigraphics" ]
}
@@ -398,6 +417,10 @@ source_set("browser") {
if (is_chromeos) {
sources -= [ "device_sensors/data_fetcher_shared_memory_default.cc" ]
+ sources += [
+ "gpu/gpu_arc_video_service_host.cc",
+ "gpu/gpu_arc_video_service_host.h",
+ ]
deps += [
"//chromeos",
"//chromeos:power_manager_proto",
@@ -406,13 +429,32 @@ source_set("browser") {
if (use_aura) {
deps += [
+ "//components/bitmap_uploader",
+ "//components/mus/public/cpp",
+ "//components/mus/public/interfaces",
"//ui/aura",
"//ui/aura_extra",
"//ui/strings",
+ "//ui/views/mus:for_component",
"//ui/wm",
]
+ sources += [
+ "compositor/software_output_device_mus.cc",
+ "compositor/software_output_device_mus.h",
+ "renderer_host/render_widget_host_view_mus.cc",
+ "renderer_host/render_widget_host_view_mus.h",
+ "web_contents/web_contents_view_mus.cc",
+ "web_contents/web_contents_view_mus.h",
+ ]
+ if (toolkit_views) {
+ defines += [ "MOJO_RUNNER_CLIENT" ]
+ }
} else { # Not aura.
sources -= [
+ "media/capture/cursor_renderer_aura.cc",
+ "media/capture/cursor_renderer_aura.h",
+ "media/capture/window_activity_tracker_aura.cc",
+ "media/capture/window_activity_tracker_aura.h",
"renderer_host/compositor_resize_lock_aura.cc",
"renderer_host/compositor_resize_lock_aura.h",
"renderer_host/input/synthetic_gesture_target_aura.cc",
@@ -483,8 +525,6 @@ source_set("browser") {
sources += [
"media/cdm/browser_cdm_manager.cc",
"media/cdm/browser_cdm_manager.h",
- "media/media_web_contents_observer.cc",
- "media/media_web_contents_observer.h",
]
}
@@ -492,6 +532,10 @@ source_set("browser") {
deps += [ "//third_party/boringssl" ]
}
+ if (enable_mojo_media != "none") {
+ configs += [ "//media/mojo/services:enable_mojo_media_config" ]
+ }
+
if (enable_mojo_media == "browser") {
deps += [ "//media/mojo/services:application" ]
}
diff --git a/chromium/content/browser/DEPS b/chromium/content/browser/DEPS
index 401e216fdac..5e33c93e2de 100644
--- a/chromium/content/browser/DEPS
+++ b/chromium/content/browser/DEPS
@@ -1,7 +1,10 @@
include_rules = [
# Allow inclusion of specific components that we depend on. We may only
# depend on components which we share with the mojo html_viewer.
+ "+components/arc",
"+components/mime_util",
+ "+components/mus/public/interfaces",
+ "+components/mus/public",
"+components/scheduler/common",
"+components/tracing",
"+components/url_formatter",
@@ -11,6 +14,7 @@ include_rules = [
"+device/battery", # For battery status service.
"+device/vibration", # For Vibration API
"+gin/v8_initializer.h",
+ "+media/media_features.h",
"+media/audio", # For audio input for speech input feature.
"+media/base", # For Android JNI registration.
"+media/filters", # For reporting GPU decoding UMA.
@@ -20,6 +24,7 @@ include_rules = [
"+mojo",
"+sql",
"+ui/aura_extra",
+ "+ui/views/mus", # http://crbug.com/555767
"+ui/webui",
"+win8/util",
@@ -27,11 +32,14 @@ include_rules = [
# This is the an exception.
"+device/udev_linux", # For udev utility and wrapper library.
+ # Explicitly disallow using SyncMessageFilter to prevent browser from
+ # sending synchronous IPC messages on non-UI threads.
+ "-ipc/ipc_sync_message_filter.h",
+
# Other libraries.
"+third_party/iaccessible2",
"+third_party/isimpledom",
"+third_party/khronos", # For enum definitions only
- "+third_party/power_gadget",
"+third_party/re2",
# Allow non-browser Chrome OS code to be used.
@@ -74,13 +82,15 @@ include_rules = [
"+third_party/WebKit/public/web/WebDragOperation.h",
"+third_party/WebKit/public/web/WebDragStatus.h",
"+third_party/WebKit/public/web/WebFindOptions.h",
+ "+third_party/WebKit/public/web/WebFrameOwnerProperties.h",
"+third_party/WebKit/public/web/WebInputEvent.h",
"+third_party/WebKit/public/web/WebMediaPlayerAction.h",
- "+third_party/WebKit/public/web/WebPageSerializerClient.h",
"+third_party/WebKit/public/web/WebPluginAction.h",
"+third_party/WebKit/public/web/WebPopupType.h",
"+third_party/WebKit/public/web/WebSandboxFlags.h",
"+third_party/WebKit/public/web/WebSerializedScriptValueVersion.h",
+ "+third_party/WebKit/public/web/WebSharedWorkerCreationContextType.h",
+ "+third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h",
"+third_party/WebKit/public/web/WebTextDirection.h",
"+third_party/WebKit/public/web/WebTextInputType.h",
"+third_party/WebKit/public/web/WebTreeScopeType.h",
diff --git a/chromium/content/browser/accessibility/BUILD.gn b/chromium/content/browser/accessibility/BUILD.gn
index f76c0e34808..1f3d9395563 100644
--- a/chromium/content/browser/accessibility/BUILD.gn
+++ b/chromium/content/browser/accessibility/BUILD.gn
@@ -1,5 +1,5 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
+# Copyright 2015 The Chromium Authors. All rights reserved.
# found in the LICENSE file.
import("//build/config/android/config.gni")
@@ -9,7 +9,4 @@ java_cpp_enum("content_browser_accessibility_java_enums_srcjar") {
sources = [
"//content/browser/accessibility/browser_accessibility_manager_android.h",
]
- outputs = [
- "org/chromium/content/browser/accessibility/ScrollDirection.java",
- ]
}
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm b/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm
index 95967f43b64..cf307013967 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm
@@ -9,11 +9,9 @@
#import <Cocoa/Cocoa.h>
#include "base/mac/foundation_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
+#include "base/mac/scoped_cftyperef.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
namespace content {
@@ -39,10 +37,11 @@ class AccessibilityEventRecorderMac : public AccessibilityEventRecorder {
AXUIElementRef element, NSString* attribute_name);
// The AXUIElement for the Chrome application.
- AXUIElementRef application_;
+ base::ScopedCFTypeRef<AXUIElementRef> application_;
// The AXObserver we use to monitor AX notifications.
- AXObserverRef observer_ref_;
+ base::ScopedCFTypeRef<AXObserverRef> observer_ref_;
+ CFRunLoopSourceRef observer_run_loop_source_;
};
// Callback function registered using AXObserverCreate.
@@ -64,18 +63,17 @@ AccessibilityEventRecorder* AccessibilityEventRecorder::Create(
AccessibilityEventRecorderMac::AccessibilityEventRecorderMac(
BrowserAccessibilityManager* manager)
- : AccessibilityEventRecorder(manager),
- observer_ref_(0) {
+ : AccessibilityEventRecorder(manager), observer_run_loop_source_(NULL) {
// Get Chrome's process id.
int pid = [[NSProcessInfo processInfo] processIdentifier];
- if (kAXErrorSuccess != AXObserverCreate(
- pid, EventReceivedThunk, &observer_ref_)) {
+ if (kAXErrorSuccess != AXObserverCreate(pid, EventReceivedThunk,
+ observer_ref_.InitializeInto())) {
LOG(FATAL) << "Failed to create AXObserverRef";
}
// Get an AXUIElement for the Chrome application.
- application_ = AXUIElementCreateApplication(pid);
- if (!application_)
+ application_.reset(AXUIElementCreateApplication(pid));
+ if (!application_.get())
LOG(FATAL) << "Failed to create AXUIElement for application.";
// Add the notifications we care about to the observer.
@@ -92,58 +90,59 @@ AccessibilityEventRecorderMac::AccessibilityEventRecorderMac(
AddNotification(@"AXRowExpanded");
// Add the observer to the current message loop.
- CFRunLoopAddSource(
- [[NSRunLoop currentRunLoop] getCFRunLoop],
- AXObserverGetRunLoopSource(observer_ref_),
- kCFRunLoopDefaultMode);
+ observer_run_loop_source_ = AXObserverGetRunLoopSource(observer_ref_.get());
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), observer_run_loop_source_,
+ kCFRunLoopDefaultMode);
}
AccessibilityEventRecorderMac::~AccessibilityEventRecorderMac() {
- CFRelease(application_);
- CFRelease(observer_ref_);
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), observer_run_loop_source_,
+ kCFRunLoopDefaultMode);
}
void AccessibilityEventRecorderMac::AddNotification(NSString* notification) {
- AXObserverAddNotification(observer_ref_,
- application_,
- static_cast<CFStringRef>(notification),
- this);
+ AXObserverAddNotification(observer_ref_, application_,
+ base::mac::NSToCFCast(notification), this);
}
std::string AccessibilityEventRecorderMac::GetAXAttributeValue(
- AXUIElementRef element, NSString* attribute_name) {
- CFTypeRef value;
+ AXUIElementRef element,
+ NSString* attribute_name) {
+ base::ScopedCFTypeRef<CFTypeRef> value;
AXError err = AXUIElementCopyAttributeValue(
- element, static_cast<CFStringRef>(attribute_name), &value);
+ element, base::mac::NSToCFCast(attribute_name), value.InitializeInto());
if (err != kAXErrorSuccess)
return std::string();
- return base::SysNSStringToUTF8(
- base::mac::CFToNSCast(static_cast<CFStringRef>(value)));
+
+ CFStringRef value_string = base::mac::CFCast<CFStringRef>(value.get());
+ if (value_string)
+ return base::SysCFStringRefToUTF8(value_string);
+
+ // TODO(dmazzoni): And if it's not a string, can we return something better?
+ return std::string();
}
-void AccessibilityEventRecorderMac::EventReceived(
- AXUIElementRef element,
- CFStringRef notification) {
- std::string notification_str = base::SysNSStringToUTF8(
- base::mac::CFToNSCast(notification));
+void AccessibilityEventRecorderMac::EventReceived(AXUIElementRef element,
+ CFStringRef notification) {
+ std::string notification_str = base::SysCFStringRefToUTF8(notification);
std::string role = GetAXAttributeValue(element, NSAccessibilityRoleAttribute);
if (role.empty())
return;
- std::string log = base::StringPrintf("%s on %s",
- notification_str.c_str(), role.c_str());
+ std::string log =
+ base::StringPrintf("%s on %s", notification_str.c_str(), role.c_str());
- std::string title = GetAXAttributeValue(element,
- NSAccessibilityTitleAttribute);
+ std::string title =
+ GetAXAttributeValue(element, NSAccessibilityTitleAttribute);
if (!title.empty())
log += base::StringPrintf(" AXTitle=\"%s\"", title.c_str());
- std::string description = GetAXAttributeValue(element,
- NSAccessibilityDescriptionAttribute);
+ std::string description =
+ GetAXAttributeValue(element, NSAccessibilityDescriptionAttribute);
if (!description.empty())
log += base::StringPrintf(" AXDescription=\"%s\"", description.c_str());
- std::string value = GetAXAttributeValue(element,
- NSAccessibilityValueAttribute);
+ std::string value =
+ GetAXAttributeValue(element, NSAccessibilityValueAttribute);
if (!value.empty())
log += base::StringPrintf(" AXValue=\"%s\"", value.c_str());
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
index b90fc8c23ea..fa767494fb4 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
@@ -5,6 +5,7 @@
#include "content/browser/accessibility/accessibility_event_recorder.h"
#include <oleacc.h>
+#include <stdint.h>
#include <string>
@@ -65,7 +66,7 @@ std::string BstrToUTF8(BSTR bstr) {
return base::UTF16ToUTF8(str16);
}
-std::string AccessibilityEventToStringUTF8(int32 event_id) {
+std::string AccessibilityEventToStringUTF8(int32_t event_id) {
return base::UTF16ToUTF8(AccessibilityEventToString(event_id));
}
diff --git a/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc b/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
index 6c47f9470c0..a8bd5412df5 100644
--- a/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/ax_event_notification_details.h"
@@ -131,8 +135,14 @@ IN_PROC_BROWSER_TEST_F(AccessibilityIpcErrorBrowserTest,
EXPECT_TRUE(button->data().state >> ui::AX_STATE_FOCUSED & 1);
}
+#if defined(OS_ANDROID)
+// http://crbug.com/542704
+#define MAYBE_MultipleBadAccessibilityIPCsKillsRenderer DISABLED_MultipleBadAccessibilityIPCsKillsRenderer
+#else
+#define MAYBE_MultipleBadAccessibilityIPCsKillsRenderer MultipleBadAccessibilityIPCsKillsRenderer
+#endif
IN_PROC_BROWSER_TEST_F(AccessibilityIpcErrorBrowserTest,
- MultipleBadAccessibilityIPCsKillsRenderer) {
+ MAYBE_MultipleBadAccessibilityIPCsKillsRenderer) {
// Create a data url and load it.
const char url_str[] =
"data:text/html,"
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
index 9d786338f3f..70a00f4f5cf 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
@@ -4,6 +4,8 @@
#include "content/browser/accessibility/accessibility_tree_formatter.h"
+#include <stddef.h>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/pattern.h"
@@ -25,40 +27,25 @@ const char* kSkipChildren = "@NO_CHILDREN_DUMP";
const char* kChildrenDictAttr = "children";
}
-AccessibilityTreeFormatter::AccessibilityTreeFormatter(
- BrowserAccessibility* root)
- : root_(root),
- show_ids_(false) {
- Initialize();
-}
-
-// static
-AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create(
- WebContents* web_contents) {
- BrowserAccessibilityManager* manager =
- static_cast<WebContentsImpl*>(web_contents)->
- GetRootBrowserAccessibilityManager();
- if (!manager)
- return NULL;
-
- BrowserAccessibility* root = manager->GetRoot();
- return new AccessibilityTreeFormatter(root);
+AccessibilityTreeFormatter::AccessibilityTreeFormatter()
+ : show_ids_(false) {
}
-
AccessibilityTreeFormatter::~AccessibilityTreeFormatter() {
}
scoped_ptr<base::DictionaryValue>
-AccessibilityTreeFormatter::BuildAccessibilityTree() {
+AccessibilityTreeFormatter::BuildAccessibilityTree(
+ BrowserAccessibility* root) {
+ CHECK(root);
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
- RecursiveBuildAccessibilityTree(*root_, dict.get());
- return dict.Pass();
+ RecursiveBuildAccessibilityTree(*root, dict.get());
+ return dict;
}
void AccessibilityTreeFormatter::FormatAccessibilityTree(
- base::string16* contents) {
- scoped_ptr<base::DictionaryValue> dict = BuildAccessibilityTree();
+ BrowserAccessibility* root, base::string16* contents) {
+ scoped_ptr<base::DictionaryValue> dict = BuildAccessibilityTree(root);
RecursiveFormatAccessibilityTree(*(dict.get()), contents);
}
@@ -69,8 +56,8 @@ void AccessibilityTreeFormatter::RecursiveBuildAccessibilityTree(
base::ListValue* children = new base::ListValue;
dict->Set(kChildrenDictAttr, children);
- for (size_t i = 0; i < node.PlatformChildCount(); ++i) {
- BrowserAccessibility* child_node = node.PlatformGetChild(i);
+ for (size_t i = 0; i < ChildCount(node); ++i) {
+ BrowserAccessibility* child_node = GetChild(node, i);
base::DictionaryValue* child_dict = new base::DictionaryValue;
children->Append(child_dict);
RecursiveBuildAccessibilityTree(*child_node, child_dict);
@@ -98,55 +85,20 @@ void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
}
}
-#if !defined(OS_WIN) && \
- !defined(OS_MACOSX) && \
- !defined(OS_ANDROID) && \
- !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11))
-void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
- base::DictionaryValue* dict) {
- dict->SetInteger("id", node.GetId());
-}
-
-base::string16 AccessibilityTreeFormatter::ToString(
- const base::DictionaryValue& node) {
- int id_value;
- node.GetInteger("id", &id_value);
- return base::IntToString16(id_value);
-}
-
-void AccessibilityTreeFormatter::Initialize() {}
-
-// static
-const base::FilePath::StringType
-AccessibilityTreeFormatter::GetActualFileSuffix() {
- return base::FilePath::StringType();
-}
-
-// static
-const base::FilePath::StringType
-AccessibilityTreeFormatter::GetExpectedFileSuffix() {
- return base::FilePath::StringType();
-}
-
-// static
-const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
- return std::string();
-}
-
-// static
-const std::string AccessibilityTreeFormatter::GetAllowString() {
- return std::string();
+void AccessibilityTreeFormatter::SetFilters(
+ const std::vector<Filter>& filters) {
+ filters_ = filters;
}
-// static
-const std::string AccessibilityTreeFormatter::GetDenyString() {
- return std::string();
+uint32_t AccessibilityTreeFormatter::ChildCount(
+ const BrowserAccessibility& node) const {
+ return node.PlatformChildCount();
}
-#endif
-void AccessibilityTreeFormatter::SetFilters(
- const std::vector<Filter>& filters) {
- filters_ = filters;
+BrowserAccessibility* AccessibilityTreeFormatter::GetChild(
+ const BrowserAccessibility& node,
+ uint32_t i) const {
+ return node.PlatformGetChild(i);
}
// static
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter.h b/chromium/content/browser/accessibility/accessibility_tree_formatter.h
index 8db914a9fa5..fd86f91aeee 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter.h
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_H_
#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_H_
+#include <stdint.h>
+
#include <vector>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
@@ -24,7 +27,7 @@ class WebContents;
// implemented.
class CONTENT_EXPORT AccessibilityTreeFormatter {
public:
- explicit AccessibilityTreeFormatter(BrowserAccessibility* root);
+ explicit AccessibilityTreeFormatter();
virtual ~AccessibilityTreeFormatter();
// A single filter specification. See GetAllowString() and GetDenyString()
@@ -42,7 +45,8 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
: match_str(match_str), type(type) {}
};
- static AccessibilityTreeFormatter* Create(WebContents* wc);
+ // Create the appropriate native subclass of AccessibilityTreeFormatter.
+ static AccessibilityTreeFormatter* Create();
static bool MatchesFilters(
const std::vector<Filter>& filters,
@@ -69,10 +73,12 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
// "children": [ ]
// } ]
// }
- scoped_ptr<base::DictionaryValue> BuildAccessibilityTree();
+ scoped_ptr<base::DictionaryValue> BuildAccessibilityTree(
+ BrowserAccessibility* root);
// Dumps a BrowserAccessibility tree into a string.
- void FormatAccessibilityTree(base::string16* contents);
+ void FormatAccessibilityTree(
+ BrowserAccessibility* root, base::string16* contents);
// Set regular expression filters that apply to each component of every
// line before it's output.
@@ -83,15 +89,14 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
void set_show_ids(bool show_ids) { show_ids_ = show_ids; }
// Suffix of the expectation file corresponding to html file.
+ // Overridden by each platform subclass.
// Example:
// HTML test: test-file.html
// Expected: test-file-expected-mac.txt.
- // Auto-generated: test-file-actual-mac.txt
- static const base::FilePath::StringType GetActualFileSuffix();
- static const base::FilePath::StringType GetExpectedFileSuffix();
+ virtual const base::FilePath::StringType GetExpectedFileSuffix() = 0;
- // A platform-specific string that indicates a given line in a file
- // is an allow-empty, allow or deny filter. Example:
+ // A string that indicates a given line in a file is an allow-empty,
+ // allow or deny filter. Overridden by each platform subclass. Example:
// Mac values:
// GetAllowEmptyString() -> "@MAC-ALLOW-EMPTY:"
// GetAllowString() -> "@MAC-ALLOW:"
@@ -103,36 +108,35 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
// @MAC-DENY:subrole*
// -->
// <p>Text</p>
- static const std::string GetAllowEmptyString();
- static const std::string GetAllowString();
- static const std::string GetDenyString();
+ virtual const std::string GetAllowEmptyString() = 0;
+ virtual const std::string GetAllowString() = 0;
+ virtual const std::string GetDenyString() = 0;
protected:
- void RecursiveFormatAccessibilityTree(const BrowserAccessibility& node,
- base::string16* contents,
- int indent);
- void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
- base::DictionaryValue* tree_node);
- void RecursiveFormatAccessibilityTree(const base::DictionaryValue& tree_node,
- base::string16* contents,
- int depth = 0);
+ //
+ // Overridden by platform subclasses.
+ //
- // Overridden by each platform to add the required attributes for each node
- // into the given dict.
- void AddProperties(const BrowserAccessibility& node,
- base::DictionaryValue* dict);
+ virtual uint32_t ChildCount(const BrowserAccessibility& node) const;
- base::string16 FormatCoordinates(const char* name,
- const char* x_name,
- const char* y_name,
- const base::DictionaryValue& value);
+ virtual BrowserAccessibility* GetChild(const BrowserAccessibility& node,
+ uint32_t i) const;
+
+ // Add the attributes for each node into the given dict.
+ virtual void AddProperties(const BrowserAccessibility& node,
+ base::DictionaryValue* dict) = 0;
// Returns a platform specific representation of a BrowserAccessibility.
- base::string16 ToString(const base::DictionaryValue& node);
+ virtual base::string16 ToString(const base::DictionaryValue& node) = 0;
- void Initialize();
+ //
+ // Utility functions to be used by each platform.
+ //
- bool MatchesFilters(const base::string16& text, bool default_result) const;
+ base::string16 FormatCoordinates(const char* name,
+ const char* x_name,
+ const char* y_name,
+ const base::DictionaryValue& value);
// Writes the given attribute string out to |line| if it matches the filters.
void WriteAttribute(bool include_by_default,
@@ -142,7 +146,19 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
const std::string& attr,
base::string16* line);
- BrowserAccessibility* root_;
+ bool show_ids() { return show_ids_; }
+
+ private:
+ void RecursiveFormatAccessibilityTree(const BrowserAccessibility& node,
+ base::string16* contents,
+ int indent);
+ void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
+ base::DictionaryValue* tree_node);
+ void RecursiveFormatAccessibilityTree(const base::DictionaryValue& tree_node,
+ base::string16* contents,
+ int depth = 0);
+
+ bool MatchesFilters(const base::string16& text, bool default_result) const;
// Filters used when formatting the accessibility tree as text.
std::vector<Filter> filters_;
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc
index 9e47007a9e5..12321df619d 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -10,6 +10,7 @@
#include "base/android/jni_string.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -67,10 +68,33 @@ const char* INT_ATTRIBUTES[] = {
};
}
-void AccessibilityTreeFormatter::Initialize() {
+class AccessibilityTreeFormatterAndroid : public AccessibilityTreeFormatter {
+ public:
+ explicit AccessibilityTreeFormatterAndroid();
+ ~AccessibilityTreeFormatterAndroid() override;
+
+ private:
+ const base::FilePath::StringType GetExpectedFileSuffix() override;
+ const std::string GetAllowEmptyString() override;
+ const std::string GetAllowString() override;
+ const std::string GetDenyString() override;
+ void AddProperties(const BrowserAccessibility& node,
+ base::DictionaryValue* dict) override;
+ base::string16 ToString(const base::DictionaryValue& node) override;
+};
+
+// static
+AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create() {
+ return new AccessibilityTreeFormatterAndroid();
+}
+
+AccessibilityTreeFormatterAndroid::AccessibilityTreeFormatterAndroid() {
+}
+
+AccessibilityTreeFormatterAndroid::~AccessibilityTreeFormatterAndroid() {
}
-void AccessibilityTreeFormatter::AddProperties(
+void AccessibilityTreeFormatterAndroid::AddProperties(
const BrowserAccessibility& node, base::DictionaryValue* dict) {
dict->SetInteger("id", node.GetId());
@@ -133,11 +157,11 @@ void AccessibilityTreeFormatter::AddProperties(
dict->SetBoolean("action_scroll_right", android_node->CanScrollRight());
}
-base::string16 AccessibilityTreeFormatter::ToString(
+base::string16 AccessibilityTreeFormatterAndroid::ToString(
const base::DictionaryValue& dict) {
base::string16 line;
- if (show_ids_) {
+ if (show_ids()) {
int id_value;
dict.GetInteger("id", &id_value);
WriteAttribute(true, base::IntToString16(id_value), &line);
@@ -177,30 +201,20 @@ base::string16 AccessibilityTreeFormatter::ToString(
return line;
}
-// static
const base::FilePath::StringType
-AccessibilityTreeFormatter::GetActualFileSuffix() {
- return FILE_PATH_LITERAL("-actual-android.txt");
-}
-
-// static
-const base::FilePath::StringType
-AccessibilityTreeFormatter::GetExpectedFileSuffix() {
+AccessibilityTreeFormatterAndroid::GetExpectedFileSuffix() {
return FILE_PATH_LITERAL("-expected-android.txt");
}
-// static
-const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
+const std::string AccessibilityTreeFormatterAndroid::GetAllowEmptyString() {
return "@ANDROID-ALLOW-EMPTY:";
}
-// static
-const std::string AccessibilityTreeFormatter::GetAllowString() {
+const std::string AccessibilityTreeFormatterAndroid::GetAllowString() {
return "@ANDROID-ALLOW:";
}
-// static
-const std::string AccessibilityTreeFormatter::GetDenyString() {
+const std::string AccessibilityTreeFormatterAndroid::GetDenyString() {
return "@ANDROID-DENY:";
}
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
index 8ceefe86993..4ebb1c0e46d 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -15,8 +15,35 @@
namespace content {
-void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
- base::DictionaryValue* dict) {
+class AccessibilityTreeFormatterAuraLinux : public AccessibilityTreeFormatter {
+ public:
+ explicit AccessibilityTreeFormatterAuraLinux();
+ ~AccessibilityTreeFormatterAuraLinux() override;
+
+ private:
+ const base::FilePath::StringType GetExpectedFileSuffix() override;
+ const std::string GetAllowEmptyString() override;
+ const std::string GetAllowString() override;
+ const std::string GetDenyString() override;
+ void AddProperties(const BrowserAccessibility& node,
+ base::DictionaryValue* dict) override;
+ base::string16 ToString(const base::DictionaryValue& node) override;
+};
+
+// static
+AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create() {
+ return new AccessibilityTreeFormatterAuraLinux();
+}
+
+AccessibilityTreeFormatterAuraLinux::AccessibilityTreeFormatterAuraLinux() {
+}
+
+AccessibilityTreeFormatterAuraLinux::~AccessibilityTreeFormatterAuraLinux() {
+}
+
+void AccessibilityTreeFormatterAuraLinux::AddProperties(
+ const BrowserAccessibility& node,
+ base::DictionaryValue* dict) {
dict->SetInteger("id", node.GetId());
BrowserAccessibilityAuraLinux* acc_obj =
const_cast<BrowserAccessibility*>(&node)
@@ -38,7 +65,7 @@ void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
dict->Set("states", states);
}
-base::string16 AccessibilityTreeFormatter::ToString(
+base::string16 AccessibilityTreeFormatterAuraLinux::ToString(
const base::DictionaryValue& node) {
base::string16 line;
std::string role_value;
@@ -74,33 +101,21 @@ base::string16 AccessibilityTreeFormatter::ToString(
return line + base::ASCIIToUTF16("\n");
}
-void AccessibilityTreeFormatter::Initialize() {
-}
-
-// static
-const base::FilePath::StringType
-AccessibilityTreeFormatter::GetActualFileSuffix() {
- return FILE_PATH_LITERAL("-actual-auralinux.txt");
-}
-
-// static
const base::FilePath::StringType
-AccessibilityTreeFormatter::GetExpectedFileSuffix() {
+AccessibilityTreeFormatterAuraLinux::GetExpectedFileSuffix() {
return FILE_PATH_LITERAL("-expected-auralinux.txt");
}
-// static
-const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
+const std::string AccessibilityTreeFormatterAuraLinux::GetAllowEmptyString() {
return "@AURALINUX-ALLOW-EMPTY:";
}
-// static
-const std::string AccessibilityTreeFormatter::GetAllowString() {
+const std::string AccessibilityTreeFormatterAuraLinux::GetAllowString() {
return "@AURALINUX-ALLOW:";
}
-// static
-const std::string AccessibilityTreeFormatter::GetDenyString() {
+const std::string AccessibilityTreeFormatterAuraLinux::GetDenyString() {
return "@AURALINUX-DENY:";
}
+
}
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
new file mode 100644
index 00000000000..27b9c9fa1cd
--- /dev/null
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -0,0 +1,213 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
+
+namespace content {
+
+AccessibilityTreeFormatterBlink::AccessibilityTreeFormatterBlink()
+ : AccessibilityTreeFormatter() {
+}
+
+AccessibilityTreeFormatterBlink::~AccessibilityTreeFormatterBlink() {
+}
+
+uint32_t AccessibilityTreeFormatterBlink::ChildCount(
+ const BrowserAccessibility& node) const {
+ return node.InternalChildCount();
+}
+
+BrowserAccessibility* AccessibilityTreeFormatterBlink::GetChild(
+ const BrowserAccessibility& node,
+ uint32_t i) const {
+ return node.InternalGetChild(i);
+}
+
+void AccessibilityTreeFormatterBlink::AddProperties(
+ const BrowserAccessibility& node,
+ base::DictionaryValue* dict) {
+ dict->SetInteger("id", node.GetId());
+
+ dict->SetString("role", ui::ToString(node.GetData().role));
+
+ dict->SetInteger("boundsX", node.GetData().location.x());
+ dict->SetInteger("boundsY", node.GetData().location.y());
+ dict->SetInteger("boundsWidth", node.GetData().location.width());
+ dict->SetInteger("boundsHeight", node.GetData().location.height());
+
+ for (int state_index = ui::AX_STATE_NONE;
+ state_index <= ui::AX_STATE_LAST;
+ ++state_index) {
+ auto state = static_cast<ui::AXState>(state_index);
+ if (node.HasState(state))
+ dict->SetBoolean(ui::ToString(state), true);
+ }
+
+ for (int attr_index = ui::AX_STRING_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_STRING_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXStringAttribute>(attr_index);
+ if (node.HasStringAttribute(attr))
+ dict->SetString(ui::ToString(attr), node.GetStringAttribute(attr));
+ }
+
+ for (int attr_index = ui::AX_INT_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_INT_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXIntAttribute>(attr_index);
+ if (node.HasIntAttribute(attr))
+ dict->SetInteger(ui::ToString(attr), node.GetIntAttribute(attr));
+ }
+
+ for (int attr_index = ui::AX_FLOAT_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_FLOAT_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXFloatAttribute>(attr_index);
+ if (node.HasFloatAttribute(attr))
+ dict->SetDouble(ui::ToString(attr), node.GetFloatAttribute(attr));
+ }
+
+ for (int attr_index = ui::AX_BOOL_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_BOOL_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXBoolAttribute>(attr_index);
+ if (node.HasBoolAttribute(attr))
+ dict->SetBoolean(ui::ToString(attr), node.GetBoolAttribute(attr));
+ }
+
+ for (int attr_index = ui::AX_INT_LIST_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_INT_LIST_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXIntListAttribute>(attr_index);
+ if (node.HasIntListAttribute(attr)) {
+ std::vector<int32_t> values;
+ node.GetIntListAttribute(attr, &values);
+ base::ListValue* value_list = new base::ListValue;
+ for (size_t i = 0; i < values.size(); ++i)
+ value_list->AppendInteger(values[i]);
+ dict->Set(ui::ToString(attr), value_list);
+ }
+ }
+}
+
+base::string16 AccessibilityTreeFormatterBlink::ToString(
+ const base::DictionaryValue& dict) {
+ base::string16 line;
+
+ if (show_ids()) {
+ int id_value;
+ dict.GetInteger("id", &id_value);
+ WriteAttribute(true, base::IntToString16(id_value), &line);
+ }
+
+ base::string16 role_value;
+ dict.GetString("role", &role_value);
+ WriteAttribute(true, base::UTF16ToUTF8(role_value), &line);
+
+ for (int state_index = ui::AX_STATE_NONE;
+ state_index <= ui::AX_STATE_LAST;
+ ++state_index) {
+ auto state = static_cast<ui::AXState>(state_index);
+ const base::Value* value;
+ if (!dict.Get(ui::ToString(state), &value))
+ continue;
+
+ WriteAttribute(false, ui::ToString(state), &line);
+ }
+
+ WriteAttribute(false,
+ FormatCoordinates("location", "boundsX", "boundsY", dict),
+ &line);
+ WriteAttribute(false,
+ FormatCoordinates("size", "boundsWidth", "boundsHeight", dict),
+ &line);
+
+ for (int attr_index = ui::AX_STRING_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_STRING_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXStringAttribute>(attr_index);
+ std::string string_value;
+ if (!dict.GetString(ui::ToString(attr), &string_value))
+ continue;
+ WriteAttribute(false,
+ base::StringPrintf(
+ "%s='%s'",
+ ui::ToString(attr).c_str(),
+ string_value.c_str()),
+ &line);
+ }
+
+ for (int attr_index = ui::AX_INT_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_INT_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXIntAttribute>(attr_index);
+ int int_value;
+ if (!dict.GetInteger(ui::ToString(attr), &int_value))
+ continue;
+ WriteAttribute(false,
+ base::StringPrintf(
+ "%s=%d",
+ ui::ToString(attr).c_str(),
+ int_value),
+ &line);
+ }
+
+ for (int attr_index = ui::AX_BOOL_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_BOOL_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXBoolAttribute>(attr_index);
+ bool bool_value;
+ if (!dict.GetBoolean(ui::ToString(attr), &bool_value))
+ continue;
+ WriteAttribute(false,
+ base::StringPrintf(
+ "%s=%s",
+ ui::ToString(attr).c_str(),
+ bool_value ? "true" : "false"),
+ &line);
+ }
+
+ for (int attr_index = ui::AX_INT_LIST_ATTRIBUTE_NONE;
+ attr_index <= ui::AX_INT_LIST_ATTRIBUTE_LAST;
+ ++attr_index) {
+ auto attr = static_cast<ui::AXIntListAttribute>(attr_index);
+ const base::ListValue* value;
+ if (!dict.GetList(ui::ToString(attr), &value))
+ continue;
+ std::string attr_string = ui::ToString(attr) + "=";
+ for (size_t i = 0; i < value->GetSize(); ++i) {
+ int int_value;
+ value->GetInteger(i, &int_value);
+ if (i > 0)
+ attr_string += ",";
+ attr_string += base::IntToString(int_value);
+ }
+ WriteAttribute(false, attr_string, &line);
+ }
+
+ return line;
+}
+
+const base::FilePath::StringType
+AccessibilityTreeFormatterBlink::GetExpectedFileSuffix() {
+ return FILE_PATH_LITERAL("-expected-blink.txt");
+}
+
+const std::string AccessibilityTreeFormatterBlink::GetAllowEmptyString() {
+ return "@BLINK-ALLOW-EMPTY:";
+}
+
+const std::string AccessibilityTreeFormatterBlink::GetAllowString() {
+ return "@BLINK-ALLOW:";
+}
+
+const std::string AccessibilityTreeFormatterBlink::GetDenyString() {
+ return "@BLINK-DENY:";
+}
+
+} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h
new file mode 100644
index 00000000000..bbb5c68d97c
--- /dev/null
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BLINK_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BLINK_H_
+
+#include <stdint.h>
+
+#include "content/browser/accessibility/accessibility_tree_formatter.h"
+
+namespace content {
+
+class CONTENT_EXPORT AccessibilityTreeFormatterBlink
+ : public AccessibilityTreeFormatter {
+ public:
+ explicit AccessibilityTreeFormatterBlink();
+ ~AccessibilityTreeFormatterBlink() override;
+
+ private:
+ const base::FilePath::StringType GetExpectedFileSuffix() override;
+ const std::string GetAllowEmptyString() override;
+ const std::string GetAllowString() override;
+ const std::string GetDenyString() override;
+ uint32_t ChildCount(const BrowserAccessibility& node) const override;
+ BrowserAccessibility* GetChild(const BrowserAccessibility& node,
+ uint32_t i) const override;
+ void AddProperties(const BrowserAccessibility& node,
+ base::DictionaryValue* dict) override;
+ base::string16 ToString(const base::DictionaryValue& node) override;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_BLINK_H_
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index 62462428ec0..0721a9e991f 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -6,7 +6,6 @@
#import <Cocoa/Cocoa.h>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
@@ -58,7 +57,7 @@ scoped_ptr<base::DictionaryValue> PopulatePosition(
static_cast<int>(node_position.x - root_left));
position->SetInteger(kYCoordDictAttr,
static_cast<int>(-node_position.y - node_size.height - root_top));
- return position.Pass();
+ return position;
}
scoped_ptr<base::DictionaryValue>
@@ -67,14 +66,14 @@ PopulateSize(const BrowserAccessibilityCocoa* cocoa_node) {
NSSize node_size = [[cocoa_node size] sizeValue];
size->SetInteger(kHeightDictAttr, static_cast<int>(node_size.height));
size->SetInteger(kWidthDictAttr, static_cast<int>(node_size.width));
- return size.Pass();
+ return size;
}
scoped_ptr<base::DictionaryValue> PopulateRange(NSRange range) {
scoped_ptr<base::DictionaryValue> rangeDict(new base::DictionaryValue);
rangeDict->SetInteger(kRangeLocDictAttr, static_cast<int>(range.location));
rangeDict->SetInteger(kRangeLenDictAttr, static_cast<int>(range.length));
- return rangeDict.Pass();
+ return rangeDict;
}
// Returns true if |value| is an NSValue containing a NSRange.
@@ -90,7 +89,7 @@ scoped_ptr<base::ListValue> PopulateArray(NSArray* array) {
scoped_ptr<base::ListValue> list(new base::ListValue);
for (NSUInteger i = 0; i < [array count]; i++)
list->Append(PopulateObject([array objectAtIndex:i]).release());
- return list.Pass();
+ return list;
}
scoped_ptr<base::StringValue> StringForBrowserAccessibility(
@@ -105,7 +104,8 @@ scoped_ptr<base::StringValue> StringForBrowserAccessibility(
id roleDescription = [obj roleDescription];
if ([role isEqualToString:NSAccessibilityGroupRole] &&
roleDescription != nil &&
- ![roleDescription isEqualToString:@""]) {
+ ![roleDescription isEqualToString:@""] &&
+ ![roleDescription isEqualToString:@"group"]) {
[tokens addObject:roleDescription];
}
@@ -123,7 +123,7 @@ scoped_ptr<base::StringValue> StringForBrowserAccessibility(
NSString* result = [tokens componentsJoinedByString:@" "];
return scoped_ptr<base::StringValue>(
- new base::StringValue(SysNSStringToUTF16(result))).Pass();
+ new base::StringValue(SysNSStringToUTF16(result)));
}
scoped_ptr<base::Value> PopulateObject(id value) {
@@ -138,9 +138,8 @@ scoped_ptr<base::Value> PopulateObject(id value) {
(BrowserAccessibilityCocoa*) value));
}
- return scoped_ptr<base::Value>(
- new base::StringValue(
- SysNSStringToUTF16([NSString stringWithFormat:@"%@", value]))).Pass();
+ return scoped_ptr<base::Value>(new base::StringValue(
+ SysNSStringToUTF16([NSString stringWithFormat:@"%@", value])));
}
NSArray* BuildAllAttributesArray() {
@@ -191,12 +190,35 @@ NSArray* BuildAllAttributesArray() {
} // namespace
-void AccessibilityTreeFormatter::Initialize() {
+class AccessibilityTreeFormatterMac : public AccessibilityTreeFormatter {
+ public:
+ explicit AccessibilityTreeFormatterMac();
+ ~AccessibilityTreeFormatterMac() override;
+
+ private:
+ const base::FilePath::StringType GetExpectedFileSuffix() override;
+ const std::string GetAllowEmptyString() override;
+ const std::string GetAllowString() override;
+ const std::string GetDenyString() override;
+ void AddProperties(const BrowserAccessibility& node,
+ base::DictionaryValue* dict) override;
+ base::string16 ToString(const base::DictionaryValue& node) override;
+};
+
+// static
+AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create() {
+ return new AccessibilityTreeFormatterMac();
}
+AccessibilityTreeFormatterMac::AccessibilityTreeFormatterMac() {
+}
-void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
- base::DictionaryValue* dict) {
+AccessibilityTreeFormatterMac::~AccessibilityTreeFormatterMac() {
+}
+
+void AccessibilityTreeFormatterMac::AddProperties(
+ const BrowserAccessibility& node,
+ base::DictionaryValue* dict) {
dict->SetInteger("id", node.GetId());
BrowserAccessibilityCocoa* cocoa_node =
const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityCocoa();
@@ -228,10 +250,10 @@ void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
dict->Set(kSizeDictAttr, PopulateSize(cocoa_node).release());
}
-base::string16 AccessibilityTreeFormatter::ToString(
+base::string16 AccessibilityTreeFormatterMac::ToString(
const base::DictionaryValue& dict) {
base::string16 line;
- if (show_ids_) {
+ if (show_ids()) {
int id_value;
dict.GetInteger("id", &id_value);
WriteAttribute(true, base::IntToString16(id_value), &line);
@@ -239,6 +261,9 @@ base::string16 AccessibilityTreeFormatter::ToString(
NSArray* defaultAttributes =
[NSArray arrayWithObjects:NSAccessibilityTitleAttribute,
+ NSAccessibilityTitleUIElementAttribute,
+ NSAccessibilityDescriptionAttribute,
+ NSAccessibilityHelpAttribute,
NSAccessibilityValueAttribute,
nil];
string s_value;
@@ -294,30 +319,20 @@ base::string16 AccessibilityTreeFormatter::ToString(
return line;
}
-// static
const base::FilePath::StringType
-AccessibilityTreeFormatter::GetActualFileSuffix() {
- return FILE_PATH_LITERAL("-actual-mac.txt");
-}
-
-// static
-const base::FilePath::StringType
-AccessibilityTreeFormatter::GetExpectedFileSuffix() {
+AccessibilityTreeFormatterMac::GetExpectedFileSuffix() {
return FILE_PATH_LITERAL("-expected-mac.txt");
}
-// static
-const string AccessibilityTreeFormatter::GetAllowEmptyString() {
+const string AccessibilityTreeFormatterMac::GetAllowEmptyString() {
return "@MAC-ALLOW-EMPTY:";
}
-// static
-const string AccessibilityTreeFormatter::GetAllowString() {
+const string AccessibilityTreeFormatterMac::GetAllowString() {
return "@MAC-ALLOW:";
}
-// static
-const string AccessibilityTreeFormatter::GetDenyString() {
+const string AccessibilityTreeFormatterMac::GetDenyString() {
return "@MAC-DENY:";
}
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc
new file mode 100644
index 00000000000..4fae96ed5c4
--- /dev/null
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/strings/string_number_conversions.h"
+#include "content/browser/accessibility/accessibility_tree_formatter.h"
+
+namespace content {
+
+class AccessibilityTreeFormatterStub : public AccessibilityTreeFormatter {
+ public:
+ explicit AccessibilityTreeFormatterStub();
+ ~AccessibilityTreeFormatterStub() override;
+
+ private:
+ const base::FilePath::StringType GetExpectedFileSuffix() override;
+ const std::string GetAllowEmptyString() override;
+ const std::string GetAllowString() override;
+ const std::string GetDenyString() override;
+ void AddProperties(const BrowserAccessibility& node,
+ base::DictionaryValue* dict) override;
+ base::string16 ToString(const base::DictionaryValue& node) override;
+};
+
+#if !defined(PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL)
+// static
+AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create() {
+ return new AccessibilityTreeFormatterStub();
+}
+#endif
+
+AccessibilityTreeFormatterStub::AccessibilityTreeFormatterStub()
+ : AccessibilityTreeFormatter() {
+}
+
+AccessibilityTreeFormatterStub::~AccessibilityTreeFormatterStub() {
+}
+
+void AccessibilityTreeFormatterStub::AddProperties(
+ const BrowserAccessibility& node,
+ base::DictionaryValue* dict) {
+ dict->SetInteger("id", node.GetId());
+}
+
+base::string16 AccessibilityTreeFormatterStub::ToString(
+ const base::DictionaryValue& node) {
+ int id_value;
+ node.GetInteger("id", &id_value);
+ return base::IntToString16(id_value);
+}
+
+const base::FilePath::StringType
+AccessibilityTreeFormatterStub::GetExpectedFileSuffix() {
+ return base::FilePath::StringType();
+}
+
+const std::string AccessibilityTreeFormatterStub::GetAllowEmptyString() {
+ return std::string();
+}
+
+const std::string AccessibilityTreeFormatterStub::GetAllowString() {
+ return std::string();
+}
+
+const std::string AccessibilityTreeFormatterStub::GetDenyString() {
+ return std::string();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
index 9dd9e196c93..19e58a9a3c9 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
@@ -9,6 +9,7 @@
#include <map>
#include <string>
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -21,11 +22,11 @@ class AccessibilityEnumMap {
public:
static AccessibilityEnumMap* GetInstance();
- 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;
- std::map<int32, base::string16> event_string_map;
+ std::map<int32_t, base::string16> ia_role_string_map;
+ std::map<int32_t, base::string16> ia2_role_string_map;
+ std::map<int32_t, base::string16> ia_state_string_map;
+ std::map<int32_t, base::string16> ia2_state_string_map;
+ std::map<int32_t, base::string16> event_string_map;
private:
AccessibilityEnumMap();
@@ -294,49 +295,49 @@ AccessibilityEnumMap::AccessibilityEnumMap() {
} // namespace.
-base::string16 IAccessibleRoleToString(int32 ia_role) {
+base::string16 IAccessibleRoleToString(int32_t ia_role) {
return AccessibilityEnumMap::GetInstance()->ia_role_string_map[ia_role];
}
-base::string16 IAccessible2RoleToString(int32 ia_role) {
+base::string16 IAccessible2RoleToString(int32_t ia_role) {
return AccessibilityEnumMap::GetInstance()->ia2_role_string_map[ia_role];
}
-void IAccessibleStateToStringVector(int32 ia_state,
+void IAccessibleStateToStringVector(int32_t ia_state,
std::vector<base::string16>* result) {
- const std::map<int32, base::string16>& state_string_map =
+ const std::map<int32_t, base::string16>& state_string_map =
AccessibilityEnumMap::GetInstance()->ia_state_string_map;
- std::map<int32, base::string16>::const_iterator it;
+ std::map<int32_t, 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);
}
}
-base::string16 IAccessibleStateToString(int32 ia_state) {
+base::string16 IAccessibleStateToString(int32_t ia_state) {
std::vector<base::string16> strings;
IAccessibleStateToStringVector(ia_state, &strings);
return base::JoinString(strings, base::ASCIIToUTF16(","));
}
-void IAccessible2StateToStringVector(int32 ia2_state,
+void IAccessible2StateToStringVector(int32_t ia2_state,
std::vector<base::string16>* result) {
- const std::map<int32, base::string16>& state_string_map =
+ const std::map<int32_t, base::string16>& state_string_map =
AccessibilityEnumMap::GetInstance()->ia2_state_string_map;
- std::map<int32, base::string16>::const_iterator it;
+ std::map<int32_t, 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);
}
}
-base::string16 IAccessible2StateToString(int32 ia2_state) {
+base::string16 IAccessible2StateToString(int32_t ia2_state) {
std::vector<base::string16> strings;
IAccessible2StateToStringVector(ia2_state, &strings);
return base::JoinString(strings, base::ASCIIToUTF16(","));
}
-base::string16 AccessibilityEventToString(int32 event_id) {
+base::string16 AccessibilityEventToString(int32_t event_id) {
return AccessibilityEnumMap::GetInstance()->event_string_map[event_id];
}
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.h b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
index 37d93b5095b..8312282f347 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
@@ -5,25 +5,28 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UTILS_WIN_H_
#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UTILS_WIN_H_
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "content/common/content_export.h"
namespace content {
-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 base::string16 IAccessibleRoleToString(int32_t ia_role);
+CONTENT_EXPORT base::string16 IAccessible2RoleToString(int32_t ia_role);
+CONTENT_EXPORT base::string16 IAccessibleStateToString(int32_t ia_state);
CONTENT_EXPORT void IAccessibleStateToStringVector(
- int32 ia_state, std::vector<base::string16>* result);
-CONTENT_EXPORT base::string16 IAccessible2StateToString(int32 ia2_state);
+ int32_t ia_state,
+ std::vector<base::string16>* result);
+CONTENT_EXPORT base::string16 IAccessible2StateToString(int32_t ia2_state);
CONTENT_EXPORT void IAccessible2StateToStringVector(
- int32 ia_state, std::vector<base::string16>* result);
+ int32_t ia_state,
+ std::vector<base::string16>* result);
// Handles both IAccessible/MSAA events and IAccessible2 events.
-CONTENT_EXPORT base::string16 AccessibilityEventToString(int32 event_id);
+CONTENT_EXPORT base::string16 AccessibilityEventToString(int32_t event_id);
} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
index c7ef471a616..cbece3a2553 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -5,6 +5,8 @@
#include "content/browser/accessibility/accessibility_tree_formatter.h"
#include <oleacc.h>
+#include <stddef.h>
+#include <stdint.h>
#include <string>
@@ -25,6 +27,33 @@
namespace content {
+class AccessibilityTreeFormatterWin : public AccessibilityTreeFormatter {
+ public:
+ explicit AccessibilityTreeFormatterWin();
+ ~AccessibilityTreeFormatterWin() override;
+
+ private:
+ const base::FilePath::StringType GetExpectedFileSuffix() override;
+ const std::string GetAllowEmptyString() override;
+ const std::string GetAllowString() override;
+ const std::string GetDenyString() override;
+ void AddProperties(const BrowserAccessibility& node,
+ base::DictionaryValue* dict) override;
+ base::string16 ToString(const base::DictionaryValue& node) override;
+};
+
+// static
+AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create() {
+ return new AccessibilityTreeFormatterWin();
+}
+
+AccessibilityTreeFormatterWin::AccessibilityTreeFormatterWin() {
+ ui::win::CreateATLModuleIfNeeded();
+}
+
+AccessibilityTreeFormatterWin::~AccessibilityTreeFormatterWin() {
+}
+
const char* ALL_ATTRIBUTES[] = {
"name",
"value",
@@ -124,11 +153,7 @@ base::string16 GetIA2Hypertext(BrowserAccessibilityWin& ax_object) {
} // Namespace
-void AccessibilityTreeFormatter::Initialize() {
- ui::win::CreateATLModuleIfNeeded();
-}
-
-void AccessibilityTreeFormatter::AddProperties(
+void AccessibilityTreeFormatterWin::AddProperties(
const BrowserAccessibility& node, base::DictionaryValue* dict) {
dict->SetInteger("id", node.GetId());
BrowserAccessibilityWin* ax_object =
@@ -151,7 +176,7 @@ void AccessibilityTreeFormatter::AddProperties(
temp_bstr.Reset();
std::vector<base::string16> state_strings;
- int32 ia_state = ax_object->ia_state();
+ int32_t ia_state = ax_object->ia_state();
// Avoid flakiness: these states depend on whether the window is focused
// and the position of the mouse cursor.
@@ -284,11 +309,11 @@ void AccessibilityTreeFormatter::AddProperties(
}
}
-base::string16 AccessibilityTreeFormatter::ToString(
+base::string16 AccessibilityTreeFormatterWin::ToString(
const base::DictionaryValue& dict) {
base::string16 line;
- if (show_ids_) {
+ if (show_ids()) {
int id_value;
dict.GetInteger("id", &id_value);
WriteAttribute(true, base::IntToString16(id_value), &line);
@@ -298,8 +323,7 @@ base::string16 AccessibilityTreeFormatter::ToString(
dict.GetString("role", &role_value);
WriteAttribute(true, base::UTF16ToUTF8(role_value), &line);
- for (int i = 0; i < arraysize(ALL_ATTRIBUTES); i++) {
- const char* attribute_name = ALL_ATTRIBUTES[i];
+ for (const char* attribute_name : ALL_ATTRIBUTES) {
const base::Value* value;
if (!dict.Get(attribute_name, &value))
continue;
@@ -377,30 +401,20 @@ base::string16 AccessibilityTreeFormatter::ToString(
return line;
}
-// static
-const base::FilePath::StringType
-AccessibilityTreeFormatter::GetActualFileSuffix() {
- return FILE_PATH_LITERAL("-actual-win.txt");
-}
-
-// static
const base::FilePath::StringType
-AccessibilityTreeFormatter::GetExpectedFileSuffix() {
+AccessibilityTreeFormatterWin::GetExpectedFileSuffix() {
return FILE_PATH_LITERAL("-expected-win.txt");
}
-// static
-const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
+const std::string AccessibilityTreeFormatterWin::GetAllowEmptyString() {
return "@WIN-ALLOW-EMPTY:";
}
-// static
-const std::string AccessibilityTreeFormatter::GetAllowString() {
+const std::string AccessibilityTreeFormatterWin::GetAllowString() {
return "@WIN-ALLOW:";
}
-// static
-const std::string AccessibilityTreeFormatter::GetDenyString() {
+const std::string AccessibilityTreeFormatterWin::GetDenyString() {
return "@WIN-DENY:";
}
diff --git a/chromium/content/browser/accessibility/accessibility_ui.cc b/chromium/content/browser/accessibility/accessibility_ui.cc
index 1a466469951..dd23bc12b97 100644
--- a/chromium/content/browser/accessibility/accessibility_ui.cc
+++ b/chromium/content/browser/accessibility/accessibility_ui.cc
@@ -11,6 +11,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -43,6 +44,8 @@ namespace content {
namespace {
+bool g_show_internal_accessibility_tree = false;
+
base::DictionaryValue* BuildTargetDescriptor(
const GURL& url,
const std::string& name,
@@ -105,14 +108,13 @@ bool HandleRequestCallback(BrowserContext* current_context,
// Ignore processes that don't have a connection, such as crashed tabs.
if (!widget->GetProcess()->HasConnection())
continue;
- if (!widget->IsRenderView())
- continue;
- RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
- BrowserContext* context = rwhi->GetProcess()->GetBrowserContext();
+ RenderViewHost* rvh = RenderViewHost::From(widget);
+ if (!rvh)
+ continue;
+ BrowserContext* context = rvh->GetProcess()->GetBrowserContext();
if (context != current_context)
continue;
- RenderViewHost* rvh = RenderViewHost::From(widget);
rvh_list->Append(BuildTargetDescriptor(rvh));
}
@@ -121,6 +123,9 @@ bool HandleRequestCallback(BrowserContext* current_context,
data.SetInteger(
"global_a11y_mode",
BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode());
+ data.SetBoolean(
+ "global_internal_tree_mode",
+ g_show_internal_accessibility_tree);
std::string json_string;
base::JSONWriter::Write(data, &json_string);
@@ -145,6 +150,10 @@ AccessibilityUI::AccessibilityUI(WebUI* web_ui) : WebUIController(web_ui) {
base::Bind(&AccessibilityUI::ToggleGlobalAccessibility,
base::Unretained(this)));
web_ui->RegisterMessageCallback(
+ "toggleInternalTree",
+ base::Bind(&AccessibilityUI::ToggleInternalTree,
+ base::Unretained(this)));
+ web_ui->RegisterMessageCallback(
"requestAccessibilityTree",
base::Bind(&AccessibilityUI::RequestAccessibilityTree,
base::Unretained(this)));
@@ -179,7 +188,7 @@ void AccessibilityUI::ToggleAccessibility(const base::ListValue* args) {
RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id);
if (!rvh)
return;
- WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
+ auto web_contents = static_cast<WebContentsImpl*>(
WebContents::FromRenderViewHost(rvh));
AccessibilityMode mode = web_contents->GetAccessibilityMode();
if ((mode & AccessibilityModeComplete) != AccessibilityModeComplete) {
@@ -200,6 +209,10 @@ void AccessibilityUI::ToggleGlobalAccessibility(const base::ListValue* args) {
state->DisableAccessibility();
}
+void AccessibilityUI::ToggleInternalTree(const base::ListValue* args) {
+ g_show_internal_accessibility_tree = !g_show_internal_accessibility_tree;
+}
+
void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
std::string process_id_str;
std::string route_id_str;
@@ -222,17 +235,22 @@ void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
}
scoped_ptr<base::DictionaryValue> result(BuildTargetDescriptor(rvh));
- WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
- scoped_ptr<AccessibilityTreeFormatter> formatter(
- AccessibilityTreeFormatter::Create(web_contents));
+ auto web_contents = static_cast<WebContentsImpl*>(
+ WebContents::FromRenderViewHost(rvh));
+ scoped_ptr<AccessibilityTreeFormatter> formatter;
+ if (g_show_internal_accessibility_tree)
+ formatter.reset(new AccessibilityTreeFormatterBlink());
+ else
+ formatter.reset(AccessibilityTreeFormatter::Create());
base::string16 accessibility_contents_utf16;
std::vector<AccessibilityTreeFormatter::Filter> filters;
filters.push_back(AccessibilityTreeFormatter::Filter(
base::ASCIIToUTF16("*"),
AccessibilityTreeFormatter::Filter::ALLOW));
formatter->SetFilters(filters);
- formatter->FormatAccessibilityTree(&accessibility_contents_utf16);
-
+ formatter->FormatAccessibilityTree(
+ web_contents->GetRootBrowserAccessibilityManager()->GetRoot(),
+ &accessibility_contents_utf16);
result->Set("tree",
new base::StringValue(
base::UTF16ToUTF8(accessibility_contents_utf16)));
diff --git a/chromium/content/browser/accessibility/accessibility_ui.h b/chromium/content/browser/accessibility/accessibility_ui.h
index bdab0c628c8..67799cbee4b 100644
--- a/chromium/content/browser/accessibility/accessibility_ui.h
+++ b/chromium/content/browser/accessibility/accessibility_ui.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_UI_H_
#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_UI_H_
+#include "base/macros.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/web_ui_data_source.h"
@@ -22,6 +23,7 @@ class AccessibilityUI : public WebUIController {
private:
void ToggleAccessibility(const base::ListValue* args);
void ToggleGlobalAccessibility(const base::ListValue* args);
+ void ToggleInternalTree(const base::ListValue* args);
void RequestAccessibilityTree(const base::ListValue* args);
DISALLOW_COPY_AND_ASSIGN(AccessibilityUI);
diff --git a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
index 373ef0ed45e..f6805bc8ba7 100644
--- a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
@@ -13,6 +17,7 @@
#include "content/browser/accessibility/accessibility_mode_helper.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
+#include "content/browser/accessibility/browser_accessibility_win.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
@@ -59,6 +64,8 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest {
base::win::ScopedComPtr<IAccessibleText>* input_text);
void SetUpTextareaField(
base::win::ScopedComPtr<IAccessibleText>* textarea_text);
+ void SetUpSampleParagraph(
+ base::win::ScopedComPtr<IAccessibleText>* paragraph_text);
static base::win::ScopedComPtr<IAccessible> GetAccessibleFromVariant(
IAccessible* parent,
@@ -66,12 +73,12 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest {
static HRESULT QueryIAccessible2(IAccessible* accessible,
IAccessible2** accessible2);
static void FindNodeInAccessibilityTree(IAccessible* node,
- int32 expected_role,
+ int32_t expected_role,
const std::wstring& expected_name,
- int32 depth,
+ int32_t depth,
bool* found);
static void CheckTextAtOffset(
- base::win::ScopedComPtr<IAccessibleText>& element,
+ base::win::ScopedComPtr<IAccessibleText>& object,
LONG offset,
IA2TextBoundaryType boundary_type,
LONG expected_start_offset,
@@ -126,29 +133,28 @@ void AccessibilityWinBrowserTest::SetUpInputField(
base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.get());
- ASSERT_EQ(1, document_children.size());
+ ASSERT_EQ(1u, document_children.size());
base::win::ScopedComPtr<IAccessible2> form;
- HRESULT hr = QueryIAccessible2(GetAccessibleFromVariant(
- document.get(), document_children[0].AsInput()).get(), form.Receive());
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
+ GetAccessibleFromVariant(document.get(), document_children[0].AsInput())
+ .get(),
+ form.Receive()));
std::vector<base::win::ScopedVariant> form_children =
GetAllAccessibleChildren(form.get());
- ASSERT_EQ(2, form_children.size());
+ ASSERT_EQ(2u, form_children.size());
// Find the input text field.
base::win::ScopedComPtr<IAccessible2> input;
- hr = QueryIAccessible2(GetAccessibleFromVariant(
- form.get(), form_children[1].AsInput()).get(), input.Receive());
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
+ GetAccessibleFromVariant(form.get(), form_children[1].AsInput()).get(),
+ input.Receive()));
LONG input_role = 0;
- hr = input->role(&input_role);
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(input->role(&input_role));
ASSERT_EQ(ROLE_SYSTEM_TEXT, input_role);
// Retrieve the IAccessibleText interface for the field.
- hr = input.QueryInterface(input_text->Receive());
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(input.QueryInterface(input_text->Receive()));
// Set the caret on the last character.
AccessibilityNotificationWaiter waiter(
@@ -178,29 +184,29 @@ void AccessibilityWinBrowserTest::SetUpTextareaField(
base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.get());
- ASSERT_EQ(1, document_children.size());
+ ASSERT_EQ(1u, document_children.size());
base::win::ScopedComPtr<IAccessible2> section;
- HRESULT hr = QueryIAccessible2(GetAccessibleFromVariant(
- document.get(), document_children[0].AsInput()).get(), section.Receive());
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
+ GetAccessibleFromVariant(document.get(), document_children[0].AsInput())
+ .get(),
+ section.Receive()));
std::vector<base::win::ScopedVariant> section_children =
GetAllAccessibleChildren(section.get());
- ASSERT_EQ(1, section_children.size());
+ ASSERT_EQ(1u, section_children.size());
// Find the textarea text field.
base::win::ScopedComPtr<IAccessible2> textarea;
- hr = QueryIAccessible2(GetAccessibleFromVariant(
- section.get(), section_children[0].AsInput()).get(), textarea.Receive());
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
+ GetAccessibleFromVariant(section.get(), section_children[0].AsInput())
+ .get(),
+ textarea.Receive()));
LONG textarea_role = 0;
- hr = textarea->role(&textarea_role);
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(textarea->role(&textarea_role));
ASSERT_EQ(ROLE_SYSTEM_TEXT, textarea_role);
// Retrieve the IAccessibleText interface for the field.
- hr = textarea.QueryInterface(textarea_text->Receive());
- ASSERT_EQ(S_OK, hr);
+ ASSERT_HRESULT_SUCCEEDED(textarea.QueryInterface(textarea_text->Receive()));
// Set the caret on the last character.
AccessibilityNotificationWaiter waiter(
@@ -216,6 +222,33 @@ void AccessibilityWinBrowserTest::SetUpTextareaField(
waiter.WaitForNotification();
}
+// Loads a page with a paragraph of sample text.
+void AccessibilityWinBrowserTest::SetUpSampleParagraph(
+ base::win::ScopedComPtr<IAccessibleText>* paragraph_text) {
+ ASSERT_NE(nullptr, paragraph_text);
+ LoadInitialAccessibilityTreeFromHtml(std::string(
+ "<!DOCTYPE html><html><body>"
+ "<p><b>Game theory</b> is \"the study of "
+ "<a href=\"#\" title=\"Mathematical model\">mathematical models</a> "
+ "of conflict and<br>cooperation between intelligent rational "
+ "decision-makers.\"</p></body></html>"));
+
+ // Retrieve the IAccessible interface for the web page.
+ base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
+ std::vector<base::win::ScopedVariant> document_children =
+ GetAllAccessibleChildren(document.get());
+ ASSERT_EQ(1u, document_children.size());
+
+ base::win::ScopedComPtr<IAccessible2> paragraph;
+ ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
+ GetAccessibleFromVariant(document.get(), document_children[0].AsInput())
+ .get(),
+ paragraph.Receive()));
+ LONG paragraph_role = 0;
+ ASSERT_HRESULT_SUCCEEDED(paragraph->role(&paragraph_role));
+ ASSERT_EQ(IA2_ROLE_PARAGRAPH, paragraph_role);
+ ASSERT_HRESULT_SUCCEEDED(paragraph.QueryInterface(paragraph_text->Receive()));
+}
// Static helpers ------------------------------------------------
@@ -260,9 +293,9 @@ HRESULT AccessibilityWinBrowserTest::QueryIAccessible2(
// and name.
void AccessibilityWinBrowserTest::FindNodeInAccessibilityTree(
IAccessible* node,
- int32 expected_role,
+ int32_t expected_role,
const std::wstring& expected_name,
- int32 depth,
+ int32_t depth,
bool* found) {
base::win::ScopedBstr name_bstr;
base::win::ScopedVariant childid_self(CHILDID_SELF);
@@ -303,7 +336,7 @@ void AccessibilityWinBrowserTest::FindNodeInAccessibilityTree(
// Ensures that the text and the start and end offsets retrieved using
// get_textAtOffset match the expected values.
void AccessibilityWinBrowserTest::CheckTextAtOffset(
- base::win::ScopedComPtr<IAccessibleText>& element,
+ base::win::ScopedComPtr<IAccessibleText>& object,
LONG offset,
IA2TextBoundaryType boundary_type,
LONG expected_start_offset,
@@ -317,9 +350,8 @@ void AccessibilityWinBrowserTest::CheckTextAtOffset(
LONG start_offset = 0;
LONG end_offset = 0;
base::win::ScopedBstr text;
- HRESULT hr = element->get_textAtOffset(
- offset, boundary_type,
- &start_offset, &end_offset, text.Receive());
+ HRESULT hr = object->get_textAtOffset(offset, boundary_type, &start_offset,
+ &end_offset, text.Receive());
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(expected_start_offset, start_offset);
EXPECT_EQ(expected_end_offset, end_offset);
@@ -358,15 +390,15 @@ class AccessibilityWinBrowserTest::AccessibleChecker {
// This constructor can be used if the IA2 role will be the same as the MSAA
// role.
AccessibleChecker(const std::wstring& expected_name,
- int32 expected_role,
+ int32_t expected_role,
const std::wstring& expected_value);
AccessibleChecker(const std::wstring& expected_name,
- int32 expected_role,
- int32 expected_ia2_role,
+ int32_t expected_role,
+ int32_t expected_ia2_role,
const std::wstring& expected_value);
AccessibleChecker(const std::wstring& expected_name,
const std::wstring& expected_role,
- int32 expected_ia2_role,
+ int32_t expected_ia2_role,
const std::wstring& expected_value);
// Append an AccessibleChecker that verifies accessibility information for
@@ -402,7 +434,7 @@ class AccessibilityWinBrowserTest::AccessibleChecker {
base::win::ScopedVariant role_;
// Expected IAccessible2 role. Checked against IAccessible2::role.
- int32 ia2_role_;
+ int32_t ia2_role_;
// Expected accessible value. Checked against IAccessible::get_accValue.
std::wstring value_;
@@ -417,38 +449,35 @@ class AccessibilityWinBrowserTest::AccessibleChecker {
AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
const std::wstring& expected_name,
- int32 expected_role,
+ int32_t expected_role,
const std::wstring& expected_value)
: name_(expected_name),
role_(expected_role),
ia2_role_(expected_role),
value_(expected_value),
- state_(-1) {
-}
+ state_(-1) {}
AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
const std::wstring& expected_name,
- int32 expected_role,
- int32 expected_ia2_role,
+ int32_t expected_role,
+ int32_t expected_ia2_role,
const std::wstring& expected_value)
: name_(expected_name),
role_(expected_role),
ia2_role_(expected_ia2_role),
value_(expected_value),
- state_(-1) {
-}
+ state_(-1) {}
AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
const std::wstring& expected_name,
const std::wstring& expected_role,
- int32 expected_ia2_role,
+ int32_t expected_ia2_role,
const std::wstring& expected_value)
: name_(expected_name),
role_(expected_role.c_str()),
ia2_role_(expected_ia2_role),
value_(expected_value),
- state_(-1) {
-}
+ state_(-1) {}
void AccessibilityWinBrowserTest::AccessibleChecker::AppendExpectedChild(
AccessibleChecker* expected_child) {
@@ -905,7 +934,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
&unique_id, &node_type);
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(NODETYPE_DOCUMENT, node_type);
- EXPECT_EQ(1, num_children);
+ EXPECT_EQ(1u, num_children);
node_name.Reset();
node_value.Reset();
@@ -919,7 +948,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(L"body", std::wstring(node_name, node_name.Length()));
EXPECT_EQ(NODETYPE_ELEMENT, node_type);
- EXPECT_EQ(1, num_children);
+ EXPECT_EQ(1u, num_children);
node_name.Reset();
node_value.Reset();
@@ -933,7 +962,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(L"input", std::wstring(node_name, node_name.Length()));
EXPECT_EQ(NODETYPE_ELEMENT, node_type);
- EXPECT_EQ(0, num_children);
+ EXPECT_EQ(0u, num_children);
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestRoleGroup) {
@@ -953,7 +982,107 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestRoleGroup) {
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
- TestSetCaretOffset) {
+ TestCharacterExtentsWithInvalidArguments) {
+ base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ SetUpSampleParagraph(&paragraph_text);
+
+ LONG invalid_offset = -3;
+ LONG x = -1, y = -1;
+ LONG width = -1, height = -1;
+
+ HRESULT hr = paragraph_text->get_characterExtents(
+ invalid_offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height);
+ EXPECT_EQ(E_INVALIDARG, hr);
+ EXPECT_EQ(-1, x);
+ EXPECT_EQ(-1, y);
+ EXPECT_EQ(-1, width);
+ EXPECT_EQ(-1, height);
+ hr = paragraph_text->get_characterExtents(
+ invalid_offset, IA2_COORDTYPE_PARENT_RELATIVE, &x, &y, &width, &height);
+ EXPECT_EQ(E_INVALIDARG, hr);
+ EXPECT_EQ(-1, x);
+ EXPECT_EQ(-1, y);
+ EXPECT_EQ(-1, width);
+ EXPECT_EQ(-1, height);
+
+ LONG n_characters;
+ ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_nCharacters(&n_characters));
+ ASSERT_LT(0, n_characters);
+
+ invalid_offset = n_characters + 1;
+ hr = paragraph_text->get_characterExtents(
+ invalid_offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height);
+ EXPECT_EQ(E_INVALIDARG, hr);
+ EXPECT_EQ(-1, x);
+ EXPECT_EQ(-1, y);
+ EXPECT_EQ(-1, width);
+ EXPECT_EQ(-1, height);
+ hr = paragraph_text->get_characterExtents(
+ invalid_offset, IA2_COORDTYPE_PARENT_RELATIVE, &x, &y, &width, &height);
+ EXPECT_EQ(E_INVALIDARG, hr);
+ EXPECT_EQ(-1, x);
+ EXPECT_EQ(-1, y);
+ EXPECT_EQ(-1, width);
+ EXPECT_EQ(-1, height);
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestCharacterExtents) {
+ base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ SetUpSampleParagraph(&paragraph_text);
+
+ const LONG newline_offset = 46;
+ LONG n_characters;
+ ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_nCharacters(&n_characters));
+ ASSERT_LT(0, n_characters);
+
+ LONG x, y, width, height;
+ LONG previous_x, previous_y;
+
+ for (int coordinate = IA2_COORDTYPE_SCREEN_RELATIVE;
+ coordinate <= IA2_COORDTYPE_PARENT_RELATIVE; ++coordinate) {
+ auto coordinate_type = static_cast<IA2CoordinateType>(coordinate);
+ EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
+ 0, coordinate_type, &x, &y, &width, &height));
+ EXPECT_LE(0, x) << "at offset 0";
+ EXPECT_LE(0, y) << "at offset 0";
+ EXPECT_LT(0, width) << "at offset 0";
+ EXPECT_LT(0, height) << "at offset 0";
+
+ for (LONG offset = 1; offset < newline_offset; ++offset) {
+ previous_x = x;
+ previous_y = y;
+
+ EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
+ offset, coordinate_type, &x, &y, &width, &height));
+ EXPECT_LT(previous_x, x) << "at offset " << offset;
+ EXPECT_EQ(previous_y, y) << "at offset " << offset;
+ EXPECT_LT(0, width) << "at offset " << offset;
+ EXPECT_LT(0, height) << "at offset " << offset;
+ }
+
+ EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
+ newline_offset + 1, coordinate_type, &x, &y, &width, &height));
+ EXPECT_LE(0, x) << "at offset " << newline_offset + 1;
+ EXPECT_GT(previous_x, x) << "at offset " << newline_offset + 1;
+ EXPECT_LT(previous_y, y) << "at offset " << newline_offset + 1;
+ EXPECT_LT(0, width) << "at offset " << newline_offset + 1;
+ EXPECT_LT(0, height) << "at offset " << newline_offset + 1;
+
+ for (LONG offset = newline_offset + 2; offset < n_characters; ++offset) {
+ previous_x = x;
+ previous_y = y;
+
+ EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
+ offset, coordinate_type, &x, &y, &width, &height));
+ EXPECT_LT(previous_x, x) << "at offset " << offset;
+ EXPECT_EQ(previous_y, y) << "at offset " << offset;
+ EXPECT_LT(0, width) << "at offset " << offset;
+ EXPECT_LT(0, height) << "at offset " << offset;
+ }
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetCaretOffset) {
base::win::ScopedComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
@@ -999,7 +1128,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
- TestTextAtOffsetWithInvalidArgs) {
+ TestTextAtOffsetWithInvalidArguments) {
base::win::ScopedComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
HRESULT hr = input_text->get_textAtOffset(
@@ -1092,7 +1221,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
- TestMultiLineTextAtOffsetWithInvalidArgs) {
+ TestMultiLineTextAtOffsetWithInvalidArguments) {
base::win::ScopedComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
HRESULT hr = textarea_text->get_textAtOffset(
@@ -1377,6 +1506,39 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ TestStaticTextAtOffsetWithBoundaryWord) {
+ base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ SetUpSampleParagraph(&paragraph_text);
+ base::string16 embedded_character(
+ 1, BrowserAccessibilityWin::kEmbeddedCharacter);
+ std::vector<std::wstring> words;
+ words.push_back(L"Game ");
+ words.push_back(L"theory ");
+ words.push_back(L"is \"");
+ words.push_back(L"the ");
+ words.push_back(L"study ");
+ words.push_back(L"of " + embedded_character + L' ');
+ words.push_back(L"of ");
+ words.push_back(L"conflict ");
+ words.push_back(L"and\n");
+ words.push_back(L"cooperation ");
+ words.push_back(L"between ");
+ words.push_back(L"intelligent ");
+ words.push_back(L"rational ");
+ words.push_back(L"decision-");
+ words.push_back(L"makers.\"");
+
+ // Try to retrieve one word after another.
+ LONG word_start_offset = 0;
+ for (auto& word : words) {
+ LONG word_end_offset = word_start_offset + word.size();
+ CheckTextAtOffset(paragraph_text, word_start_offset, IA2_TEXT_BOUNDARY_WORD,
+ word_start_offset, word_end_offset, word);
+ word_start_offset = word_end_offset;
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestTextAtOffsetWithBoundarySentence) {
base::win::ScopedComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
diff --git a/chromium/content/browser/accessibility/ax_tree_id_registry.h b/chromium/content/browser/accessibility/ax_tree_id_registry.h
index 7784683395f..fcb22e6f12f 100644
--- a/chromium/content/browser/accessibility/ax_tree_id_registry.h
+++ b/chromium/content/browser/accessibility/ax_tree_id_registry.h
@@ -7,7 +7,9 @@
#include <map>
+#include "base/macros.h"
#include "base/stl_util.h"
+
namespace base {
template <typename T>
struct DefaultSingletonTraits;
diff --git a/chromium/content/browser/accessibility/browser_accessibility.cc b/chromium/content/browser/accessibility/browser_accessibility.cc
index e0827da7792..3501f5c90db 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility.cc
@@ -4,6 +4,8 @@
#include "content/browser/accessibility/browser_accessibility.h"
+#include <stddef.h>
+
#include <algorithm>
#include "base/logging.h"
@@ -16,12 +18,7 @@
namespace content {
-#if !defined(OS_WIN) && \
- !defined(OS_MACOSX) && \
- !defined(OS_ANDROID) && \
- !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11))
-// We have subclassess of BrowserAccessibility on some platforms.
-// On other platforms, instantiate the base class.
+#if !defined(PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL)
// static
BrowserAccessibility* BrowserAccessibility::Create() {
return new BrowserAccessibility();
@@ -46,22 +43,32 @@ bool BrowserAccessibility::PlatformIsLeaf() const {
if (InternalChildCount() == 0)
return true;
- // All of these roles may have children that we use as internal
- // implementation details, but we want to expose them as leaves
- // to platform accessibility APIs.
+ // These types of objects may have children that we use as internal
+ // implementation details, but we want to expose them as leaves to platform
+ // accessibility APIs because screen readers might be confused if they find
+ // any children.
+ if (IsSimpleTextControl() || IsTextOnlyObject())
+ return true;
+
+ // Roles whose children are only presentational according to the ARIA and
+ // HTML5 Specs should be hidden from screen readers.
+ // (Note that whilst ARIA buttons can have only presentational children, HTML5
+ // buttons are allowed to have content.)
switch (GetRole()) {
- case ui::AX_ROLE_COMBO_BOX:
- case ui::AX_ROLE_LINE_BREAK:
+ case ui::AX_ROLE_IMAGE:
+ case ui::AX_ROLE_MATH:
+ case ui::AX_ROLE_METER:
+ case ui::AX_ROLE_SCROLL_BAR:
case ui::AX_ROLE_SLIDER:
- case ui::AX_ROLE_STATIC_TEXT:
- case ui::AX_ROLE_TEXT_FIELD:
+ case ui::AX_ROLE_SPLITTER:
+ case ui::AX_ROLE_PROGRESS_INDICATOR:
return true;
default:
return false;
}
}
-uint32 BrowserAccessibility::PlatformChildCount() const {
+uint32_t BrowserAccessibility::PlatformChildCount() const {
if (HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
BrowserAccessibilityManager* child_manager =
BrowserAccessibilityManager::FromID(
@@ -92,12 +99,13 @@ bool BrowserAccessibility::IsDescendantOf(
bool BrowserAccessibility::IsTextOnlyObject() const {
return GetRole() == ui::AX_ROLE_STATIC_TEXT ||
- GetRole() == ui::AX_ROLE_LINE_BREAK;
+ GetRole() == ui::AX_ROLE_LINE_BREAK ||
+ GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX;
}
BrowserAccessibility* BrowserAccessibility::PlatformGetChild(
- uint32 child_index) const {
- DCHECK(child_index < PlatformChildCount());
+ uint32_t child_index) const {
+ DCHECK_LT(child_index, PlatformChildCount());
BrowserAccessibility* result = nullptr;
if (HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
@@ -114,11 +122,11 @@ BrowserAccessibility* BrowserAccessibility::PlatformGetChild(
}
bool BrowserAccessibility::PlatformIsChildOfLeaf() const {
- BrowserAccessibility* ancestor = GetParent();
+ BrowserAccessibility* ancestor = InternalGetParent();
while (ancestor) {
if (ancestor->PlatformIsLeaf())
return true;
- ancestor = ancestor->GetParent();
+ ancestor = ancestor->InternalGetParent();
}
return false;
@@ -166,17 +174,20 @@ BrowserAccessibility* BrowserAccessibility::PlatformDeepestLastChild() const {
return deepest_child;
}
-uint32 BrowserAccessibility::InternalChildCount() const {
+uint32_t BrowserAccessibility::InternalChildCount() const {
if (!node_ || !manager_)
return 0;
- return static_cast<uint32>(node_->child_count());
+ return static_cast<uint32_t>(node_->child_count());
}
BrowserAccessibility* BrowserAccessibility::InternalGetChild(
- uint32 child_index) const {
- if (!node_ || !manager_)
- return NULL;
- return manager_->GetFromAXNode(node_->ChildAtIndex(child_index));
+ uint32_t child_index) const {
+ if (!node_ || !manager_ || child_index >= InternalChildCount())
+ return nullptr;
+
+ const auto child_node = node_->ChildAtIndex(child_index);
+ DCHECK(child_node);
+ return manager_->GetFromAXNode(child_node);
}
BrowserAccessibility* BrowserAccessibility::GetParent() const {
@@ -189,11 +200,21 @@ BrowserAccessibility* BrowserAccessibility::GetParent() const {
return manager_->GetParentNodeFromParentTree();
}
-int32 BrowserAccessibility::GetIndexInParent() const {
+BrowserAccessibility* BrowserAccessibility::InternalGetParent() const {
+ if (!node_ || !manager_)
+ return nullptr;
+ ui::AXNode* parent = node_->parent();
+ if (parent)
+ return manager_->GetFromAXNode(parent);
+
+ return nullptr;
+}
+
+int32_t BrowserAccessibility::GetIndexInParent() const {
return node_ ? node_->index_in_parent() : -1;
}
-int32 BrowserAccessibility::GetId() const {
+int32_t BrowserAccessibility::GetId() const {
return node_ ? node_->id() : -1;
}
@@ -209,11 +230,11 @@ gfx::Rect BrowserAccessibility::GetLocation() const {
return GetData().location;
}
-int32 BrowserAccessibility::GetRole() const {
+int32_t BrowserAccessibility::GetRole() const {
return GetData().role;
}
-int32 BrowserAccessibility::GetState() const {
+int32_t BrowserAccessibility::GetState() const {
return GetData().state;
}
@@ -240,20 +261,38 @@ gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const {
gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
const {
+ DCHECK_GE(start, 0);
+ DCHECK_GE(len, 0);
+
+ // Standard text fields such as textarea have an embedded div inside them that
+ // holds all the text.
+ if (IsSimpleTextControl() && InternalChildCount() == 1)
+ return InternalGetChild(0)->GetLocalBoundsForRange(start, len);
+
if (GetRole() != ui::AX_ROLE_STATIC_TEXT) {
- // Apply recursively to all static text descendants. For example, if
- // you call it on a div with two text node children, it just calls
- // GetLocalBoundsForRange on each of the two children (adjusting
- // |start| for each one) and unions the resulting rects.
gfx::Rect bounds;
- for (size_t i = 0; i < InternalChildCount(); ++i) {
+ for (size_t i = 0; i < InternalChildCount() && len > 0; ++i) {
BrowserAccessibility* child = InternalGetChild(i);
- int child_len = child->GetStaticTextLenRecursive();
- if (start < child_len && start + len > 0) {
- gfx::Rect child_rect = child->GetLocalBoundsForRange(start, len);
+ // Child objects are of length one, since they are represented by a single
+ // embedded object character. The exception is text-only objects.
+ int child_length_in_parent = 1;
+ if (child->IsTextOnlyObject())
+ child_length_in_parent = static_cast<int>(child->GetText().size());
+ if (start < child_length_in_parent) {
+ gfx::Rect child_rect;
+ if (child->IsTextOnlyObject()) {
+ child_rect = child->GetLocalBoundsForRange(start, len);
+ } else {
+ child_rect = child->GetLocalBoundsForRange(
+ 0, static_cast<int>(child->GetText().size()));
+ }
bounds.Union(child_rect);
+ len -= (child_length_in_parent - start);
}
- start -= child_len;
+ if (start > child_length_in_parent)
+ start -= child_length_in_parent;
+ else
+ start = 0;
}
return ElementBoundsToLocalBounds(bounds);
}
@@ -261,7 +300,6 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
int end = start + len;
int child_start = 0;
int child_end = 0;
-
gfx::Rect bounds;
for (size_t i = 0; i < InternalChildCount() && child_end < start + len; ++i) {
BrowserAccessibility* child = InternalGetChild(i);
@@ -271,11 +309,9 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
continue;
}
- std::string child_text;
- child->GetStringAttribute(ui::AX_ATTR_VALUE, &child_text);
- int child_len = static_cast<int>(child_text.size());
+ int child_length = static_cast<int>(child->GetText().size());
child_start = child_end;
- child_end += child_len;
+ child_end += child_length;
if (child_end < start)
continue;
@@ -289,8 +325,8 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
gfx::Rect child_rect = child->GetLocation();
int text_direction = child->GetIntAttribute(
ui::AX_ATTR_TEXT_DIRECTION);
- const std::vector<int32>& character_offsets = child->GetIntListAttribute(
- ui::AX_ATTR_CHARACTER_OFFSETS);
+ const std::vector<int32_t>& character_offsets =
+ child->GetIntListAttribute(ui::AX_ATTR_CHARACTER_OFFSETS);
int start_pixel_offset =
local_start > 0 ? character_offsets[local_start - 1] : 0;
int end_pixel_offset =
@@ -351,11 +387,18 @@ gfx::Rect BrowserAccessibility::GetGlobalBoundsForRange(int start, int len)
return bounds;
}
+base::string16 BrowserAccessibility::GetValue() const {
+ base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
+ if (value.empty() && IsSimpleTextControl())
+ value = GetInnerText();
+ return value;
+}
+
int BrowserAccessibility::GetWordStartBoundary(
int start, ui::TextBoundaryDirection direction) const {
DCHECK_GE(start, -1);
// Special offset that indicates that a word boundary has not been found.
- int word_start_not_found = GetStaticTextLenRecursive();
+ int word_start_not_found = static_cast<int>(GetText().size());
int word_start = word_start_not_found;
switch (GetRole()) {
@@ -370,20 +413,18 @@ int BrowserAccessibility::GetWordStartBoundary(
child_start = child_end;
BrowserAccessibility* child = InternalGetChild(i);
DCHECK_EQ(child->GetRole(), ui::AX_ROLE_INLINE_TEXT_BOX);
- const std::string& child_text = child->GetStringAttribute(
- ui::AX_ATTR_VALUE);
- int child_len = static_cast<int>(child_text.size());
+ int child_len = static_cast<int>(GetText().size());
child_end += child_len; // End is one past the last character.
- const std::vector<int32>& word_starts = child->GetIntListAttribute(
- ui::AX_ATTR_WORD_STARTS);
+ const std::vector<int32_t>& word_starts =
+ child->GetIntListAttribute(ui::AX_ATTR_WORD_STARTS);
if (word_starts.empty()) {
word_start = child_end;
continue;
}
int local_start = start - child_start;
- std::vector<int32>::const_iterator iter = std::upper_bound(
+ std::vector<int32_t>::const_iterator iter = std::upper_bound(
word_starts.begin(), word_starts.end(), local_start);
if (iter != word_starts.end()) {
if (direction == ui::FORWARDS_DIRECTION) {
@@ -425,22 +466,32 @@ int BrowserAccessibility::GetWordStartBoundary(
if (!InternalChildCount())
return word_start_not_found;
+ const BrowserAccessibility* this_object = this;
+ // Standard text fields such as textarea have an embedded div inside them
+ // that should be skipped.
+ if (IsSimpleTextControl() && InternalChildCount() == 1) {
+ this_object = InternalGetChild(0);
+ }
int child_start = 0;
- for (size_t i = 0; i < InternalChildCount(); ++i) {
- BrowserAccessibility* child = InternalGetChild(i);
- int child_len = child->GetStaticTextLenRecursive();
- int child_word_start = child->GetWordStartBoundary(start, direction);
- if (child_word_start < child_len) {
- // We have found a possible word boundary.
- word_start = child_start + child_word_start;
- }
+ for (size_t i = 0; i < this_object->InternalChildCount(); ++i) {
+ BrowserAccessibility* child = this_object->InternalGetChild(i);
+ // Child objects are of length one, since they are represented by a
+ // single embedded object character. The exception is text-only objects.
+ int child_len = 1;
+ if (child->IsTextOnlyObject()) {
+ child_len = static_cast<int>(child->GetText().size());
+ int child_word_start = child->GetWordStartBoundary(start, direction);
+ if (child_word_start < child_len) {
+ // We have found a possible word boundary.
+ word_start = child_start + child_word_start;
+ }
- // Decide when to stop searching.
- if ((word_start != word_start_not_found &&
- direction == ui::FORWARDS_DIRECTION) ||
- (start < child_len &&
- direction == ui::BACKWARDS_DIRECTION)) {
- break;
+ // Decide when to stop searching.
+ if ((word_start != word_start_not_found &&
+ direction == ui::FORWARDS_DIRECTION) ||
+ (start < child_len && direction == ui::BACKWARDS_DIRECTION)) {
+ break;
+ }
}
child_start += child_len;
@@ -586,14 +637,14 @@ bool BrowserAccessibility::HasIntListAttribute(
return GetData().HasIntListAttribute(attribute);
}
-const std::vector<int32>& BrowserAccessibility::GetIntListAttribute(
+const std::vector<int32_t>& BrowserAccessibility::GetIntListAttribute(
ui::AXIntListAttribute attribute) const {
return GetData().GetIntListAttribute(attribute);
}
bool BrowserAccessibility::GetIntListAttribute(
ui::AXIntListAttribute attribute,
- std::vector<int32>* value) const {
+ std::vector<int32_t>* value) const {
return GetData().GetIntListAttribute(attribute, value);
}
@@ -629,7 +680,11 @@ bool BrowserAccessibility::GetAriaTristate(
if (base::EqualsASCII(value, "mixed"))
*is_mixed = true;
- return false; // Not set
+ return false; // Not set.
+}
+
+base::string16 BrowserAccessibility::GetText() const {
+ return GetInnerText();
}
bool BrowserAccessibility::HasState(ui::AXState state_enum) const {
@@ -642,8 +697,21 @@ bool BrowserAccessibility::IsCellOrTableHeaderRole() const {
GetRole() == ui::AX_ROLE_ROW_HEADER);
}
-bool BrowserAccessibility::IsEditableText() const {
- return HasState(ui::AX_STATE_EDITABLE);
+bool BrowserAccessibility::HasCaret() const {
+ if (HasState(ui::AX_STATE_EDITABLE) &&
+ !HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
+ HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) &&
+ HasIntAttribute(ui::AX_ATTR_TEXT_SEL_END)) {
+ return true;
+ }
+
+ // The caret is always at the focus of the selection.
+ int32_t focus_id = manager()->GetTreeData().sel_focus_object_id;
+ BrowserAccessibility* focus_object = manager()->GetFromID(focus_id);
+ if (!focus_object)
+ return false;
+
+ return focus_object->IsDescendantOf(this);
}
bool BrowserAccessibility::IsWebAreaForPresentationalIframe() const {
@@ -695,16 +763,55 @@ bool BrowserAccessibility::IsControl() const {
}
}
-int BrowserAccessibility::GetStaticTextLenRecursive() const {
- if (GetRole() == ui::AX_ROLE_STATIC_TEXT ||
- GetRole() == ui::AX_ROLE_LINE_BREAK) {
- return static_cast<int>(GetStringAttribute(ui::AX_ATTR_VALUE).size());
+bool BrowserAccessibility::IsSimpleTextControl() const {
+ // Time fields, color wells and spinner buttons might also use text fields as
+ // constituent parts, but they are not considered text fields as a whole.
+ switch (GetRole()) {
+ case ui::AX_ROLE_COMBO_BOX:
+ case ui::AX_ROLE_SEARCH_BOX:
+ case ui::AX_ROLE_TEXT_FIELD:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Indicates if this object is at the root of a rich edit text control.
+bool BrowserAccessibility::IsRichTextControl() const {
+ return HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
+ (!GetParent() || !GetParent()->HasState(ui::AX_STATE_RICHLY_EDITABLE));
+}
+
+std::string BrowserAccessibility::ComputeAccessibleNameFromDescendants() {
+ std::string name;
+ for (size_t i = 0; i < InternalChildCount(); ++i) {
+ BrowserAccessibility* child = InternalGetChild(i);
+ std::string child_name;
+ if (child->GetStringAttribute(ui::AX_ATTR_NAME, &child_name)) {
+ if (!name.empty())
+ name += " ";
+ name += child_name;
+ } else if (!child->HasState(ui::AX_STATE_FOCUSABLE)) {
+ child_name = child->ComputeAccessibleNameFromDescendants();
+ if (!child_name.empty()) {
+ if (!name.empty())
+ name += " ";
+ name += child_name;
+ }
+ }
}
- int len = 0;
+ return name;
+}
+
+base::string16 BrowserAccessibility::GetInnerText() const {
+ if (IsTextOnlyObject())
+ return GetString16Attribute(ui::AX_ATTR_NAME);
+
+ base::string16 text;
for (size_t i = 0; i < InternalChildCount(); ++i)
- len += InternalGetChild(i)->GetStaticTextLenRecursive();
- return len;
+ text += InternalGetChild(i)->GetInnerText();
+ return text;
}
void BrowserAccessibility::FixEmptyBounds(gfx::Rect* bounds) const
diff --git a/chromium/content/browser/accessibility/browser_accessibility.h b/chromium/content/browser/accessibility/browser_accessibility.h
index d330b613fcd..9b1a3feb411 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.h
+++ b/chromium/content/browser/accessibility/browser_accessibility.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_H_
+#include <stdint.h>
+
#include <map>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
#include "build/build_config.h"
@@ -19,6 +21,27 @@
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_text_utils.h"
+// Set PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL if this platform has
+// a platform-specific subclass of BrowserAccessibility and
+// BrowserAccessibilityManager.
+#undef PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL
+
+#if defined(OS_WIN)
+#define PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL 1
+#endif
+
+#if defined(OS_MACOSX)
+#define PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL 1
+#endif
+
+#if defined(OS_ANDROID) && !defined(USE_AURA)
+#define PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL 1
+#endif
+
+#if defined(OS_LINUX) && defined(USE_X11) && !defined(OS_CHROMEOS)
+#define PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL 1
+#endif
+
#if defined(OS_MACOSX) && __OBJC__
@class BrowserAccessibilityCocoa;
#endif
@@ -82,11 +105,11 @@ class CONTENT_EXPORT BrowserAccessibility {
// Returns the number of children of this object, or 0 if PlatformIsLeaf()
// returns true.
- uint32 PlatformChildCount() const;
+ uint32_t PlatformChildCount() const;
// Return a pointer to the child at the given index, or NULL for an
// invalid index. Returns NULL if PlatformIsLeaf() returns true.
- BrowserAccessibility* PlatformGetChild(uint32 child_index) const;
+ BrowserAccessibility* PlatformGetChild(uint32_t child_index) const;
// Returns true if an ancestor of this node (not including itself) is a
// leaf node, meaning that this node is not actually exposed to the
@@ -117,6 +140,10 @@ class CONTENT_EXPORT BrowserAccessibility {
// the role is WebAXRoleStaticText.
gfx::Rect GetGlobalBoundsForRange(int start, int len) const;
+ // This is to handle the cases such as ARIA textbox, where the value should
+ // be calculated from the object's inner text.
+ base::string16 GetValue() const;
+
// Searches in the given text and from the given offset until the start of
// the next or previous word is found and returns its position.
// In case there is no word boundary before or after the given offset, it
@@ -163,17 +190,18 @@ class CONTENT_EXPORT BrowserAccessibility {
// reflect the accessibility tree that should be exposed on each platform.
// Use PlatformChildCount and PlatformGetChild to implement platform
// accessibility APIs.
- uint32 InternalChildCount() const;
- BrowserAccessibility* InternalGetChild(uint32 child_index) const;
+ uint32_t InternalChildCount() const;
+ BrowserAccessibility* InternalGetChild(uint32_t child_index) const;
+ BrowserAccessibility* InternalGetParent() const;
BrowserAccessibility* GetParent() const;
- int32 GetIndexInParent() const;
+ int32_t GetIndexInParent() const;
- int32 GetId() const;
+ int32_t GetId() const;
const ui::AXNodeData& GetData() const;
gfx::Rect GetLocation() const;
- int32 GetRole() const;
- int32 GetState() const;
+ int32_t GetRole() const;
+ int32_t GetState() const;
typedef base::StringPairs HtmlAttributes;
const HtmlAttributes& GetHtmlAttributes() const;
@@ -184,10 +212,13 @@ class CONTENT_EXPORT BrowserAccessibility {
virtual bool IsNative() const;
#if defined(OS_MACOSX) && __OBJC__
+ const BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa() const;
BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa();
#elif defined(OS_WIN)
+ const BrowserAccessibilityWin* ToBrowserAccessibilityWin() const;
BrowserAccessibilityWin* ToBrowserAccessibilityWin();
#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11)
+ const BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux() const;
BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux();
#endif
@@ -230,10 +261,10 @@ class CONTENT_EXPORT BrowserAccessibility {
ui::AXStringAttribute attribute) const;
bool HasIntListAttribute(ui::AXIntListAttribute attribute) const;
- const std::vector<int32>& GetIntListAttribute(
+ const std::vector<int32_t>& GetIntListAttribute(
ui::AXIntListAttribute attribute) const;
bool GetIntListAttribute(ui::AXIntListAttribute attribute,
- std::vector<int32>* value) const;
+ std::vector<int32_t>* value) const;
// Retrieve the value of a html attribute from the attribute map and
// returns true if found.
@@ -256,20 +287,28 @@ class CONTENT_EXPORT BrowserAccessibility {
bool* is_defined,
bool* is_mixed) const;
+ virtual base::string16 GetText() const;
+
// Returns true if the bit corresponding to the given state enum is 1.
bool HasState(ui::AXState state_enum) const;
// Returns true if this node is an cell or an table header.
bool IsCellOrTableHeaderRole() const;
- // Returns true if this node is an editable text field of any kind.
- bool IsEditableText() const;
+ // Returns true if the caret is active on this object.
+ bool HasCaret() const;
// True if this is a web area, and its grandparent is a presentational iframe.
bool IsWebAreaForPresentationalIframe() const;
- // Is any control, like a button, text field, etc.
bool IsControl() const;
+ bool IsSimpleTextControl() const;
+ // Indicates if this object is at the root of a rich edit text control.
+ bool IsRichTextControl() const;
+
+ // If an object is focusable but has no accessible name, use this
+ // to compute a name from its descendants.
+ std::string ComputeAccessibleNameFromDescendants();
protected:
BrowserAccessibility();
@@ -281,9 +320,11 @@ class CONTENT_EXPORT BrowserAccessibility {
ui::AXNode* node_;
private:
- // Return the sum of the lengths of all static text descendants,
- // including this object if it's static text.
- int GetStaticTextLenRecursive() const;
+ // |GetInnerText| recursively includes all the text from descendants such as
+ // text found in any embedded object. In contrast, |GetText| might include a
+ // special character in the place of every embedded object instead of its
+ // text, depending on the platform.
+ base::string16 GetInnerText() const;
// If a bounding rectangle is empty, compute it based on the union of its
// children, since most accessibility APIs don't like elements with no
diff --git a/chromium/content/browser/accessibility/browser_accessibility_android.cc b/chromium/content/browser/accessibility/browser_accessibility_android.cc
index c16eb8d7a13..79a1f18a369 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_android.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_android.cc
@@ -63,7 +63,7 @@ void BrowserAccessibilityAndroid::OnLocationChanged() {
}
bool BrowserAccessibilityAndroid::PlatformIsLeaf() const {
- if (InternalChildCount() == 0)
+ if (BrowserAccessibility::PlatformIsLeaf())
return true;
// Iframes are always allowed to contain children.
@@ -78,8 +78,14 @@ bool BrowserAccessibilityAndroid::PlatformIsLeaf() const {
return false;
// Date and time controls should drop their children.
- if (GetRole() == ui::AX_ROLE_DATE || GetRole() == ui::AX_ROLE_INPUT_TIME)
- return true;
+ switch (GetRole()) {
+ case ui::AX_ROLE_DATE:
+ case ui::AX_ROLE_DATE_TIME:
+ case ui::AX_ROLE_INPUT_TIME:
+ return true;
+ default:
+ break;
+ }
BrowserAccessibilityManagerAndroid* manager_android =
static_cast<BrowserAccessibilityManagerAndroid*>(manager());
@@ -98,7 +104,7 @@ bool BrowserAccessibilityAndroid::PlatformIsLeaf() const {
return true;
}
- return BrowserAccessibility::PlatformIsLeaf();
+ return false;
}
bool BrowserAccessibilityAndroid::IsCheckable() const {
@@ -315,13 +321,24 @@ base::string16 BrowserAccessibilityAndroid::GetText() const {
return base::string16();
}
- // See comment in browser_accessibility_win.cc for details.
- // The difference here is that we can only expose one accessible
- // name on Android, not 2 or 3 like on Windows or Mac.
+ // In accordance with ARIA, some elements use their contents as an
+ // accessibility name, so some elements will have the same name as their
+ // child. While most platforms expect this, it causes Android to speak the
+ // name twice. So in this case we should remove the name from the parent.
+ if (GetRole() == ui::AX_ROLE_LIST_ITEM &&
+ GetIntAttribute(ui::AX_ATTR_NAME_FROM) == ui::AX_NAME_FROM_CONTENTS) {
+ // This is an approximation of "PlatformChildCount() > 0" because we can't
+ // call PlatformChildCount from here.
+ if (InternalChildCount() > 0 && !HasOnlyStaticTextChildren())
+ return base::string16();
+ }
+
+ // We can only expose one accessible name on Android,
+ // not 2 or 3 like on Windows or Mac.
// First, always return the |value| attribute if this is an
// input field.
- base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
+ base::string16 value = GetValue();
if (!value.empty()) {
if (HasState(ui::AX_STATE_EDITABLE))
return value;
@@ -345,63 +362,23 @@ base::string16 BrowserAccessibilityAndroid::GetText() const {
base::StringPrintf("#%02X%02X%02X", red, green, blue));
}
- // Always prefer visible text if this is a link. Sites sometimes add
- // a "title" attribute to a link with more information, but we can't
- // lose the link text.
- base::string16 name = GetString16Attribute(ui::AX_ATTR_NAME);
- if (!name.empty() && GetRole() == ui::AX_ROLE_LINK)
- return name;
-
- // If there's no text value, the basic rule is: prefer description
- // (aria-labelledby or aria-label), then help (title), then name
- // (inner text), then value (control value). However, if
- // title_elem_id is set, that means there's a label element
- // supplying the name and then name takes precedence over help.
- // TODO(dmazzoni): clean this up by providing more granular labels in
- // Blink, making the platform-specific mapping to accessible text simpler.
+ base::string16 text = GetString16Attribute(ui::AX_ATTR_NAME);
base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
- base::string16 help = GetString16Attribute(ui::AX_ATTR_HELP);
-
- base::string16 placeholder;
- switch (GetRole()) {
- case ui::AX_ROLE_DATE:
- case ui::AX_ROLE_INPUT_TIME:
- case ui::AX_ROLE_TEXT_FIELD:
- GetHtmlAttribute("placeholder", &placeholder);
- }
-
- int title_elem_id = GetIntAttribute(
- ui::AX_ATTR_TITLE_UI_ELEMENT);
- base::string16 text;
- if (!description.empty())
- text = description;
- else if (!name.empty()) {
- text = name;
- if (!help.empty()) {
- // TODO(vkuzkokov): This is not the best way to pass 2 texts but this is
- // how Blink seems to be doing it.
+ if (!description.empty()) {
+ if (!text.empty())
text += base::ASCIIToUTF16(" ");
- text += help;
- }
- } else if (!help.empty())
- text = help;
- else if (!placeholder.empty())
- text = placeholder;
- else if (!value.empty())
- text = value;
- else if (title_elem_id) {
- BrowserAccessibility* title_elem =
- manager()->GetFromID(title_elem_id);
- if (title_elem)
- text = static_cast<BrowserAccessibilityAndroid*>(title_elem)->GetText();
+ text += description;
}
+ if (text.empty())
+ text = value;
+
// This is called from PlatformIsLeaf, so don't call PlatformChildCount
// from within this!
if (text.empty() &&
(HasOnlyStaticTextChildren() ||
(IsFocusable() && HasOnlyTextAndImageChildren()))) {
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibility* child = InternalGetChild(i);
text += static_cast<BrowserAccessibilityAndroid*>(child)->GetText();
}
@@ -410,7 +387,7 @@ base::string16 BrowserAccessibilityAndroid::GetText() const {
if (text.empty() && (IsLink() || GetRole() == ui::AX_ROLE_IMAGE)) {
base::string16 url = GetString16Attribute(ui::AX_ATTR_URL);
// Given a url like http://foo.com/bar/baz.png, just return the
- // base name, e.g., "baz".
+ // base text, e.g., "baz".
int trailing_slashes = 0;
while (url.size() - trailing_slashes > 0 &&
url[url.size() - trailing_slashes - 1] == '/') {
@@ -687,7 +664,7 @@ int BrowserAccessibilityAndroid::GetSelectionEnd() const {
}
int BrowserAccessibilityAndroid::GetEditableTextLength() const {
- base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
+ base::string16 value = GetValue();
return value.length();
}
@@ -801,8 +778,8 @@ float BrowserAccessibilityAndroid::RangeCurrentValue() const {
void BrowserAccessibilityAndroid::GetGranularityBoundaries(
int granularity,
- std::vector<int32>* starts,
- std::vector<int32>* ends,
+ std::vector<int32_t>* starts,
+ std::vector<int32_t>* ends,
int offset) {
switch (granularity) {
case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_LINE:
@@ -817,8 +794,8 @@ void BrowserAccessibilityAndroid::GetGranularityBoundaries(
}
void BrowserAccessibilityAndroid::GetLineBoundaries(
- std::vector<int32>* line_starts,
- std::vector<int32>* line_ends,
+ std::vector<int32_t>* line_starts,
+ std::vector<int32_t>* line_ends,
int offset) {
// If this node has no children, treat it as all one line.
if (GetText().size() > 0 && !InternalChildCount()) {
@@ -830,7 +807,7 @@ void BrowserAccessibilityAndroid::GetLineBoundaries(
// inline text boxes if possible.
if (GetRole() == ui::AX_ROLE_STATIC_TEXT) {
int last_y = 0;
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibilityAndroid* child =
static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i));
CHECK_EQ(ui::AX_ROLE_INLINE_TEXT_BOX, child->GetRole());
@@ -851,7 +828,7 @@ void BrowserAccessibilityAndroid::GetLineBoundaries(
}
// Otherwise, call GetLineBoundaries recursively on the children.
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibilityAndroid* child =
static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i));
child->GetLineBoundaries(line_starts, line_ends, offset);
@@ -860,14 +837,14 @@ void BrowserAccessibilityAndroid::GetLineBoundaries(
}
void BrowserAccessibilityAndroid::GetWordBoundaries(
- std::vector<int32>* word_starts,
- std::vector<int32>* word_ends,
+ std::vector<int32_t>* word_starts,
+ std::vector<int32_t>* word_ends,
int offset) {
if (GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) {
- const std::vector<int32>& starts = GetIntListAttribute(
- ui::AX_ATTR_WORD_STARTS);
- const std::vector<int32>& ends = GetIntListAttribute(
- ui::AX_ATTR_WORD_ENDS);
+ const std::vector<int32_t>& starts =
+ GetIntListAttribute(ui::AX_ATTR_WORD_STARTS);
+ const std::vector<int32_t>& ends =
+ GetIntListAttribute(ui::AX_ATTR_WORD_ENDS);
for (size_t i = 0; i < starts.size(); ++i) {
word_starts->push_back(offset + starts[i]);
word_ends->push_back(offset + ends[i]);
@@ -876,7 +853,7 @@ void BrowserAccessibilityAndroid::GetWordBoundaries(
}
base::string16 concatenated_text;
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibilityAndroid* child =
static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i));
base::string16 child_text = child->GetText();
@@ -887,7 +864,7 @@ void BrowserAccessibilityAndroid::GetWordBoundaries(
if (text.empty() || concatenated_text == text) {
// Great - this node is just the concatenation of its children, so
// we can get the word boundaries recursively.
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibilityAndroid* child =
static_cast<BrowserAccessibilityAndroid*>(InternalGetChild(i));
child->GetWordBoundaries(word_starts, word_ends, offset);
@@ -912,7 +889,7 @@ void BrowserAccessibilityAndroid::GetWordBoundaries(
bool BrowserAccessibilityAndroid::HasFocusableChild() const {
// This is called from PlatformIsLeaf, so don't call PlatformChildCount
// from within this!
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibility* child = InternalGetChild(i);
if (child->HasState(ui::AX_STATE_FOCUSABLE))
return true;
@@ -925,7 +902,7 @@ bool BrowserAccessibilityAndroid::HasFocusableChild() const {
bool BrowserAccessibilityAndroid::HasOnlyStaticTextChildren() const {
// This is called from PlatformIsLeaf, so don't call PlatformChildCount
// from within this!
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibility* child = InternalGetChild(i);
if (child->GetRole() != ui::AX_ROLE_STATIC_TEXT)
return false;
@@ -936,7 +913,7 @@ bool BrowserAccessibilityAndroid::HasOnlyStaticTextChildren() const {
bool BrowserAccessibilityAndroid::HasOnlyTextAndImageChildren() const {
// This is called from PlatformIsLeaf, so don't call PlatformChildCount
// from within this!
- for (uint32 i = 0; i < InternalChildCount(); i++) {
+ for (uint32_t i = 0; i < InternalChildCount(); i++) {
BrowserAccessibility* child = InternalGetChild(i);
if (child->GetRole() != ui::AX_ROLE_STATIC_TEXT &&
child->GetRole() != ui::AX_ROLE_IMAGE) {
@@ -956,7 +933,7 @@ void BrowserAccessibilityAndroid::OnDataChanged() {
BrowserAccessibility::OnDataChanged();
if (IsEditableText()) {
- base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
+ base::string16 value = GetValue();
if (value != new_value_) {
old_value_ = new_value_;
new_value_ = value;
@@ -993,7 +970,7 @@ void BrowserAccessibilityAndroid::NotifyLiveRegionUpdate(
int BrowserAccessibilityAndroid::CountChildrenWithRole(ui::AXRole role) const {
int count = 0;
- for (uint32 i = 0; i < PlatformChildCount(); i++) {
+ for (uint32_t i = 0; i < PlatformChildCount(); i++) {
if (PlatformGetChild(i)->GetRole() == role)
count++;
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_android.h b/chromium/content/browser/accessibility/browser_accessibility_android.h
index bcf421095a9..66055538087 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_android.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_android.h
@@ -5,7 +5,11 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_ANDROID_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_ANDROID_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility.h"
namespace content {
@@ -46,7 +50,7 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
bool HasFocusableChild() const;
const char* GetClassName() const;
- base::string16 GetText() const;
+ base::string16 GetText() const override;
int GetItemIndex() const;
int GetItemCount() const;
@@ -93,21 +97,21 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
// Calls GetLineBoundaries or GetWordBoundaries depending on the value
// of |granularity|, or fails if anything else is passed in |granularity|.
void GetGranularityBoundaries(int granularity,
- std::vector<int32>* starts,
- std::vector<int32>* ends,
+ std::vector<int32_t>* starts,
+ std::vector<int32_t>* ends,
int offset);
// Append line start and end indices for the text of this node
// (as returned by GetText()), adding |offset| to each one.
- void GetLineBoundaries(std::vector<int32>* line_starts,
- std::vector<int32>* line_ends,
+ void GetLineBoundaries(std::vector<int32_t>* line_starts,
+ std::vector<int32_t>* line_ends,
int offset);
// Append word start and end indices for the text of this node
// (as returned by GetText()) to |word_starts| and |word_ends|,
// adding |offset| to each one.
- void GetWordBoundaries(std::vector<int32>* word_starts,
- std::vector<int32>* word_ends,
+ void GetWordBoundaries(std::vector<int32_t>* word_starts,
+ std::vector<int32_t>* word_ends,
int offset);
private:
diff --git a/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc b/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc
index 9fb8e4b3e93..880839e047a 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc
@@ -4,6 +4,9 @@
#include "content/browser/accessibility/browser_accessibility_auralinux.h"
+#include <stdint.h>
+#include <string.h>
+
#include "base/strings/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager_auralinux.h"
#include "content/common/accessibility_messages.h"
@@ -205,13 +208,13 @@ static const gchar* GetDocumentAttributeValue(
BrowserAccessibilityAuraLinux* obj,
const gchar* attribute) {
if (!g_ascii_strcasecmp(attribute, "DocType"))
- return obj->GetStringAttribute(ui::AX_ATTR_DOC_DOCTYPE).c_str();
+ return obj->manager()->GetTreeData().doctype.c_str();
else if (!g_ascii_strcasecmp(attribute, "MimeType"))
- return obj->GetStringAttribute(ui::AX_ATTR_DOC_MIMETYPE).c_str();
+ return obj->manager()->GetTreeData().mimetype.c_str();
else if (!g_ascii_strcasecmp(attribute, "Title"))
- return obj->GetStringAttribute(ui::AX_ATTR_DOC_TITLE).c_str();
+ return obj->manager()->GetTreeData().title.c_str();
else if (!g_ascii_strcasecmp(attribute, "URI"))
- return obj->GetStringAttribute(ui::AX_ATTR_DOC_URL).c_str();
+ return obj->manager()->GetTreeData().url.c_str();
return 0;
}
@@ -532,7 +535,7 @@ static AtkStateSet* browser_accessibility_ref_state_set(AtkObject* atk_object) {
return NULL;
AtkStateSet* state_set = ATK_OBJECT_CLASS(browser_accessibility_parent_class)
->ref_state_set(atk_object);
- int32 state = obj->GetState();
+ int32_t state = obj->GetState();
if (state & (1 << ui::AX_STATE_FOCUSABLE))
atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE);
@@ -707,6 +710,14 @@ static GType GetAccessibilityTypeFromObject(
BrowserAccessibilityAtk* browser_accessibility_new(
BrowserAccessibilityAuraLinux* obj) {
+ #if !GLIB_CHECK_VERSION(2, 36, 0)
+ static bool first_time = true;
+ if (first_time) {
+ g_type_init();
+ first_time = false;
+ }
+ #endif
+
GType type = GetAccessibilityTypeFromObject(obj);
AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0));
@@ -724,6 +735,11 @@ BrowserAccessibility* BrowserAccessibility::Create() {
return new BrowserAccessibilityAuraLinux();
}
+const BrowserAccessibilityAuraLinux*
+BrowserAccessibility::ToBrowserAccessibilityAuraLinux() const {
+ return static_cast<const BrowserAccessibilityAuraLinux*>(this);
+}
+
BrowserAccessibilityAuraLinux*
BrowserAccessibility::ToBrowserAccessibilityAuraLinux() {
return static_cast<BrowserAccessibilityAuraLinux*>(this);
diff --git a/chromium/content/browser/accessibility/browser_accessibility_auralinux.h b/chromium/content/browser/accessibility/browser_accessibility_auralinux.h
index e1154418bbf..43a9c3f16b0 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_auralinux.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_auralinux.h
@@ -8,6 +8,7 @@
#include <atk/atk.h>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility.h"
namespace content {
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.h b/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
index bdfe9227d1e..6c5a3e6f0c1 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -37,6 +37,10 @@
// from browserAccessibility_.
- (ui::AXRole)internalRole;
+// Convenience method to determine if this object should expose its
+// accessible name in AXValue (as opposed to AXTitle/AXDescription).
+- (bool)shouldExposeNameInAXValue;
+
// Convenience method to get the BrowserAccessibilityDelegate from
// the manager.
- (content::BrowserAccessibilityDelegate*)delegate;
@@ -54,6 +58,9 @@
// Swap the children array with the given scoped_nsobject.
- (void)swapChildren:(base::scoped_nsobject<NSMutableArray>*)other;
+// Returns the requested text range from this object's value attribute.
+- (NSString*)valueForRange:(NSRange)range;
+
// Internally-used method.
@property(nonatomic, readonly) NSPoint origin;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
index ea4db4a33c3..78c8c0150fb 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -3,12 +3,13 @@
// found in the LICENSE file.
#include <execinfo.h>
+#include <stddef.h>
+#include <stdint.h>
#import "content/browser/accessibility/browser_accessibility_cocoa.h"
#include <map>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
@@ -210,7 +211,7 @@ AccessibilityMatchPredicate PredicateForSearchKey(NSString* searchKey) {
};
} else if ([searchKey isEqualToString:@"AXStaticTextSearchKey"]) {
return [](BrowserAccessibility* start, BrowserAccessibility* current) {
- return current->GetRole() == ui::AX_ROLE_STATIC_TEXT;
+ return current->IsTextOnlyObject();
};
} else if ([searchKey isEqualToString:@"AXStyleChangeSearchKey"]) {
// TODO(dmazzoni): implement this.
@@ -228,7 +229,7 @@ AccessibilityMatchPredicate PredicateForSearchKey(NSString* searchKey) {
};
} else if ([searchKey isEqualToString:@"AXTextFieldSearchKey"]) {
return [](BrowserAccessibility* start, BrowserAccessibility* current) {
- return current->GetRole() == ui::AX_ROLE_TEXT_FIELD;
+ return current->IsSimpleTextControl() || current->IsRichTextControl();
};
} else if ([searchKey isEqualToString:@"AXUnderlineSearchKey"]) {
// TODO(dmazzoni): implement this.
@@ -465,9 +466,9 @@ bool InitializeAccessibilityTreeSearch(
// accessibility children of this object.
- (NSArray*)children {
if (!children_) {
- uint32 childCount = browserAccessibility_->PlatformChildCount();
+ uint32_t childCount = browserAccessibility_->PlatformChildCount();
children_.reset([[NSMutableArray alloc] initWithCapacity:childCount]);
- for (uint32 index = 0; index < childCount; ++index) {
+ for (uint32_t index = 0; index < childCount; ++index) {
BrowserAccessibilityCocoa* child =
browserAccessibility_->PlatformGetChild(index)->
ToBrowserAccessibilityCocoa();
@@ -478,11 +479,11 @@ bool InitializeAccessibilityTreeSearch(
}
// Also, add indirect children (if any).
- const std::vector<int32>& indirectChildIds =
+ const std::vector<int32_t>& indirectChildIds =
browserAccessibility_->GetIntListAttribute(
ui::AX_ATTR_INDIRECT_CHILD_IDS);
- for (uint32 i = 0; i < indirectChildIds.size(); ++i) {
- int32 child_id = indirectChildIds[i];
+ for (uint32_t i = 0; i < indirectChildIds.size(); ++i) {
+ int32_t child_id = indirectChildIds[i];
BrowserAccessibility* child =
browserAccessibility_->manager()->GetFromID(child_id);
@@ -514,9 +515,8 @@ bool InitializeAccessibilityTreeSearch(
}
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- const std::vector<int32>& uniqueCellIds =
- browserAccessibility_->GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& uniqueCellIds =
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
for (size_t i = 0; i < uniqueCellIds.size(); ++i) {
int id = uniqueCellIds[i];
BrowserAccessibility* cell =
@@ -552,34 +552,68 @@ bool InitializeAccessibilityTreeSearch(
}
- (NSString*)description {
- std::string description;
- if (browserAccessibility_->GetStringAttribute(
- ui::AX_ATTR_DESCRIPTION, &description)) {
- return base::SysUTF8ToNSString(description);
- }
-
- // If the role is anything other than an image, or if there's
- // a title or title UI element, just return an empty string.
- if (![[self role] isEqualToString:NSAccessibilityImageRole])
+ // Mac OS X wants static text exposed in AXValue.
+ if ([self shouldExposeNameInAXValue])
return @"";
- if (browserAccessibility_->HasStringAttribute(
- ui::AX_ATTR_NAME)) {
+
+ // If the name came from a single related element and it's present in the
+ // tree, it will be exposed in AXTitleUIElement.
+ std::vector<int32_t> labelledby_ids =
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS);
+ ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>(
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM));
+ if (nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT &&
+ labelledby_ids.size() == 1 &&
+ browserAccessibility_->manager()->GetFromID(labelledby_ids[0])) {
return @"";
}
- if ([self titleUIElement])
- return @"";
- // The remaining case is an image where there's no other title.
- // Return the base part of the filename as the description.
- std::string url;
- if (browserAccessibility_->GetStringAttribute(
- ui::AX_ATTR_URL, &url)) {
- // Given a url like http://foo.com/bar/baz.png, just return the
- // base name, e.g., "baz.png".
- size_t leftIndex = url.rfind('/');
- std::string basename =
- leftIndex != std::string::npos ? url.substr(leftIndex) : url;
- return base::SysUTF8ToNSString(basename);
+ std::string name = browserAccessibility_->GetStringAttribute(
+ ui::AX_ATTR_NAME);
+ if (!name.empty()) {
+ // On Mac OS X, the accessible name of an object is exposed as its
+ // title if it comes from visible text, and as its description
+ // otherwise, but never both.
+ if (nameFrom == ui::AX_NAME_FROM_CONTENTS ||
+ nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT ||
+ nameFrom == ui::AX_NAME_FROM_VALUE) {
+ return @"";
+ } else {
+ return base::SysUTF8ToNSString(name);
+ }
+ }
+
+ // Given an image where there's no other title, return the base part
+ // of the filename as the description.
+ if ([[self role] isEqualToString:NSAccessibilityImageRole]) {
+ if (browserAccessibility_->HasStringAttribute(ui::AX_ATTR_NAME))
+ return @"";
+ if ([self titleUIElement])
+ return @"";
+
+ std::string url;
+ if (browserAccessibility_->GetStringAttribute(
+ ui::AX_ATTR_URL, &url)) {
+ // Given a url like http://foo.com/bar/baz.png, just return the
+ // base name, e.g., "baz.png".
+ size_t leftIndex = url.rfind('/');
+ std::string basename =
+ leftIndex != std::string::npos ? url.substr(leftIndex) : url;
+ return base::SysUTF8ToNSString(basename);
+ }
+ }
+
+ // If it's focusable but didn't have any other name or value, compute a name
+ // from its descendants.
+ base::string16 value = browserAccessibility_->GetValue();
+ if (browserAccessibility_->HasState(ui::AX_STATE_FOCUSABLE) &&
+ !browserAccessibility_->IsControl() &&
+ value.empty() &&
+ [self internalRole] != ui::AX_ROLE_DATE_TIME &&
+ [self internalRole] != ui::AX_ROLE_WEB_AREA &&
+ [self internalRole] != ui::AX_ROLE_ROOT_WEB_AREA) {
+ return base::SysUTF8ToNSString(
+ browserAccessibility_->ComputeAccessibleNameFromDescendants());
}
return @"";
@@ -679,7 +713,7 @@ bool InitializeAccessibilityTreeSearch(
- (NSString*)help {
return NSStringForStringAttribute(
- browserAccessibility_, ui::AX_ATTR_HELP);
+ browserAccessibility_, ui::AX_ATTR_DESCRIPTION);
}
- (NSNumber*)index {
@@ -735,13 +769,27 @@ bool InitializeAccessibilityTreeSearch(
}
- (NSString*)placeholderValue {
+ ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>(
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM));
+ if (nameFrom == ui::AX_NAME_FROM_PLACEHOLDER) {
+ return NSStringForStringAttribute(
+ browserAccessibility_, ui::AX_ATTR_NAME);
+ }
+
+ ui::AXDescriptionFrom descriptionFrom = static_cast<ui::AXDescriptionFrom>(
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_DESCRIPTION_FROM));
+ if (descriptionFrom == ui::AX_DESCRIPTION_FROM_PLACEHOLDER) {
+ return NSStringForStringAttribute(
+ browserAccessibility_, ui::AX_ATTR_DESCRIPTION);
+ }
+
return NSStringForStringAttribute(
browserAccessibility_, ui::AX_ATTR_PLACEHOLDER);
}
- (void)addLinkedUIElementsFromAttribute:(ui::AXIntListAttribute)attribute
addTo:(NSMutableArray*)outArray {
- const std::vector<int32>& attributeValues =
+ const std::vector<int32_t>& attributeValues =
browserAccessibility_->GetIntListAttribute(attribute);
for (size_t i = 0; i < attributeValues.size(); ++i) {
BrowserAccessibility* element =
@@ -753,7 +801,6 @@ bool InitializeAccessibilityTreeSearch(
- (NSArray*)linkedUIElements {
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- [self addLinkedUIElementsFromAttribute:ui::AX_ATTR_OWNS_IDS addTo:ret];
[self addLinkedUIElementsFromAttribute:ui::AX_ATTR_CONTROLS_IDS addTo:ret];
[self addLinkedUIElementsFromAttribute:ui::AX_ATTR_FLOWTO_IDS addTo:ret];
if ([ret count] == 0)
@@ -766,8 +813,8 @@ bool InitializeAccessibilityTreeSearch(
}
- (NSNumber*)loadingProgress {
- float floatValue = browserAccessibility_->GetFloatAttribute(
- ui::AX_ATTR_DOC_LOADING_PROGRESS);
+ BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ float floatValue = manager->GetTreeData().loading_progress;
return [NSNumber numberWithFloat:floatValue];
}
@@ -793,8 +840,7 @@ bool InitializeAccessibilityTreeSearch(
}
- (NSNumber*)numberOfCharacters {
- std::string value = browserAccessibility_->GetStringAttribute(
- ui::AX_ATTR_VALUE);
+ base::string16 value = browserAccessibility_->GetValue();
return [NSNumber numberWithInt:value.size()];
}
@@ -837,6 +883,19 @@ bool InitializeAccessibilityTreeSearch(
return static_cast<ui::AXRole>(browserAccessibility_->GetRole());
}
+// Returns true if this should expose its accessible name in AXValue.
+- (bool)shouldExposeNameInAXValue {
+ switch ([self internalRole]) {
+ case ui::AX_ROLE_LIST_BOX_OPTION:
+ case ui::AX_ROLE_LIST_MARKER:
+ case ui::AX_ROLE_MENU_LIST_OPTION:
+ case ui::AX_ROLE_STATIC_TEXT:
+ return true;
+ default:
+ return false;
+ }
+}
+
- (content::BrowserAccessibilityDelegate*)delegate {
return browserAccessibility_->manager() ?
browserAccessibility_->manager()->delegate() :
@@ -867,6 +926,9 @@ bool InitializeAccessibilityTreeSearch(
// Returns a string indicating the NSAccessibility role of this object.
- (NSString*)role {
+ if (!browserAccessibility_)
+ return nil;
+
ui::AXRole role = [self internalRole];
if (role == ui::AX_ROLE_CANVAS &&
browserAccessibility_->GetBoolAttribute(
@@ -884,8 +946,9 @@ bool InitializeAccessibilityTreeSearch(
else
return NSAccessibilityButtonRole;
}
- if (role == ui::AX_ROLE_TEXT_FIELD &&
- browserAccessibility_->HasState(ui::AX_STATE_MULTILINE)) {
+ if ((browserAccessibility_->IsSimpleTextControl() &&
+ browserAccessibility_->HasState(ui::AX_STATE_MULTILINE)) ||
+ browserAccessibility_->IsRichTextControl()) {
return NSAccessibilityTextAreaRole;
}
@@ -1014,9 +1077,8 @@ bool InitializeAccessibilityTreeSearch(
}
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- const std::vector<int32>& uniqueCellIds =
- browserAccessibility_->GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& uniqueCellIds =
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
for (size_t i = 0; i < uniqueCellIds.size(); ++i) {
int id = uniqueCellIds[i];
BrowserAccessibility* cell =
@@ -1052,10 +1114,10 @@ bool InitializeAccessibilityTreeSearch(
[ret addObject:child];
}
} else if ([self internalRole] == ui::AX_ROLE_COLUMN) {
- const std::vector<int32>& indirectChildIds =
+ const std::vector<int32_t>& indirectChildIds =
browserAccessibility_->GetIntListAttribute(
ui::AX_ATTR_INDIRECT_CHILD_IDS);
- for (uint32 i = 0; i < indirectChildIds.size(); ++i) {
+ for (uint32_t i = 0; i < indirectChildIds.size(); ++i) {
int id = indirectChildIds[i];
BrowserAccessibility* rowElement =
browserAccessibility_->manager()->GetFromID(id);
@@ -1097,8 +1159,8 @@ bool InitializeAccessibilityTreeSearch(
// If it's multiselectable or if the previous attempts failed,
// return any children with the "selected" state, which may
// come from aria-selected.
- uint32 childCount = browserAccessibility_->PlatformChildCount();
- for (uint32 index = 0; index < childCount; ++index) {
+ uint32_t childCount = browserAccessibility_->PlatformChildCount();
+ for (uint32_t index = 0; index < childCount; ++index) {
BrowserAccessibility* child =
browserAccessibility_->PlatformGetChild(index);
if (child->HasState(ui::AX_STATE_SELECTED))
@@ -1177,22 +1239,42 @@ bool InitializeAccessibilityTreeSearch(
}
- (NSString*)title {
- return NSStringForStringAttribute(
- browserAccessibility_, ui::AX_ATTR_NAME);
+ // Mac OS X wants static text exposed in AXValue.
+ if ([self shouldExposeNameInAXValue])
+ return @"";
+
+ // If the name came from a single related element and it's present in the
+ // tree, it will be exposed in AXTitleUIElement.
+ std::vector<int32_t> labelledby_ids =
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS);
+ ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>(
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM));
+ if (nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT &&
+ labelledby_ids.size() == 1 &&
+ browserAccessibility_->manager()->GetFromID(labelledby_ids[0])) {
+ return @"";
+ }
+
+ // On Mac OS X, the accessible name of an object is exposed as its
+ // title if it comes from visible text, and as its description
+ // otherwise, but never both.
+ if (nameFrom == ui::AX_NAME_FROM_CONTENTS ||
+ nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT ||
+ nameFrom == ui::AX_NAME_FROM_VALUE) {
+ return NSStringForStringAttribute(
+ browserAccessibility_, ui::AX_ATTR_NAME);
+ }
+
+ return nil;
}
- (id)titleUIElement {
- int titleElementId;
- if (browserAccessibility_->GetIntAttribute(
- ui::AX_ATTR_TITLE_UI_ELEMENT, &titleElementId)) {
- BrowserAccessibility* titleElement =
- browserAccessibility_->manager()->GetFromID(titleElementId);
- if (titleElement)
- return titleElement->ToBrowserAccessibilityCocoa();
- }
- std::vector<int32> labelledby_ids =
+ std::vector<int32_t> labelledby_ids =
browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS);
- if (labelledby_ids.size() == 1) {
+ ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>(
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM));
+ if (nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT &&
+ labelledby_ids.size() == 1) {
BrowserAccessibility* titleElement =
browserAccessibility_->manager()->GetFromID(labelledby_ids[0]);
if (titleElement)
@@ -1203,24 +1285,24 @@ bool InitializeAccessibilityTreeSearch(
}
- (NSURL*)url {
- StringAttribute urlAttribute =
- [[self role] isEqualToString:@"AXWebArea"] ?
- ui::AX_ATTR_DOC_URL :
- ui::AX_ATTR_URL;
+ std::string url;
+ if ([[self role] isEqualToString:@"AXWebArea"])
+ url = browserAccessibility_->manager()->GetTreeData().url;
+ else
+ url = browserAccessibility_->GetStringAttribute(ui::AX_ATTR_URL);
- std::string urlStr = browserAccessibility_->GetStringAttribute(urlAttribute);
- if (urlStr.empty())
+ if (url.empty())
return nil;
- return [NSURL URLWithString:(base::SysUTF8ToNSString(urlStr))];
+ return [NSURL URLWithString:(base::SysUTF8ToNSString(url))];
}
- (id)value {
- // WebCore uses an attachmentView to get the below behavior.
- // We do not have any native views backing this object, so need
- // to approximate Cocoa ax behavior best as we can.
NSString* role = [self role];
- if ([role isEqualToString:@"AXHeading"]) {
+ if ([self shouldExposeNameInAXValue]) {
+ return NSStringForStringAttribute(
+ browserAccessibility_, ui::AX_ATTR_NAME);
+ } else if ([role isEqualToString:@"AXHeading"]) {
int level = 0;
if (browserAccessibility_->GetIntAttribute(
ui::AX_ATTR_HIERARCHICAL_LEVEL, &level)) {
@@ -1251,8 +1333,7 @@ bool InitializeAccessibilityTreeSearch(
1 :
value;
- if (browserAccessibility_->GetBoolAttribute(
- ui::AX_ATTR_BUTTON_MIXED)) {
+ if (browserAccessibility_->GetBoolAttribute(ui::AX_ATTR_STATE_MIXED)) {
value = 2;
}
return [NSNumber numberWithInt:value];
@@ -1276,26 +1357,24 @@ bool InitializeAccessibilityTreeSearch(
red / 255., green / 255., blue / 255.];
}
- return NSStringForStringAttribute(
- browserAccessibility_, ui::AX_ATTR_VALUE);
+ return base::SysUTF16ToNSString(browserAccessibility_->GetValue());
}
- (NSString*)valueDescription {
- return NSStringForStringAttribute(
- browserAccessibility_, ui::AX_ATTR_VALUE);
+ if (browserAccessibility_)
+ return base::SysUTF16ToNSString(browserAccessibility_->GetValue());
+ return nil;
}
- (NSValue*)visibleCharacterRange {
- std::string value = browserAccessibility_->GetStringAttribute(
- ui::AX_ATTR_VALUE);
+ base::string16 value = browserAccessibility_->GetValue();
return [NSValue valueWithRange:NSMakeRange(0, value.size())];
}
- (NSArray*)visibleCells {
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- const std::vector<int32>& uniqueCellIds =
- browserAccessibility_->GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& uniqueCellIds =
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
for (size_t i = 0; i < uniqueCellIds.size(); ++i) {
int id = uniqueCellIds[i];
BrowserAccessibility* cell =
@@ -1308,8 +1387,8 @@ bool InitializeAccessibilityTreeSearch(
- (NSArray*)visibleChildren {
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- uint32 childCount = browserAccessibility_->PlatformChildCount();
- for (uint32 index = 0; index < childCount; ++index) {
+ uint32_t childCount = browserAccessibility_->PlatformChildCount();
+ for (uint32_t index = 0; index < childCount; ++index) {
BrowserAccessibilityCocoa* child =
browserAccessibility_->PlatformGetChild(index)->
ToBrowserAccessibilityCocoa();
@@ -1352,6 +1431,18 @@ bool InitializeAccessibilityTreeSearch(
children_.swap(*other);
}
+// Returns the requested text range from this object's value attribute.
+- (NSString*)valueForRange:(NSRange)range {
+ if (!browserAccessibility_)
+ return nil;
+
+ base::string16 value = browserAccessibility_->GetValue();
+ if (NSMaxRange(range) > value.size())
+ return nil;
+
+ return base::SysUTF16ToNSString(value.substr(range.location, range.length));
+}
+
// Returns the accessibility value for the given attribute. If the value isn't
// supported this will return nil.
- (id)accessibilityAttributeValue:(NSString*)attribute {
@@ -1374,9 +1465,8 @@ bool InitializeAccessibilityTreeSearch(
int selLength = selEnd - selStart;
if ([attribute isEqualToString:
NSAccessibilityInsertionPointLineNumberAttribute]) {
- const std::vector<int32>& line_breaks =
- browserAccessibility_->GetIntListAttribute(
- ui::AX_ATTR_LINE_BREAKS);
+ const std::vector<int32_t>& line_breaks =
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LINE_BREAKS);
for (int i = 0; i < static_cast<int>(line_breaks.size()); ++i) {
if (line_breaks[i] > selStart)
return [NSNumber numberWithInt:i];
@@ -1384,8 +1474,7 @@ bool InitializeAccessibilityTreeSearch(
return [NSNumber numberWithInt:static_cast<int>(line_breaks.size())];
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
- base::string16 value = browserAccessibility_->GetString16Attribute(
- ui::AX_ATTR_VALUE);
+ base::string16 value = browserAccessibility_->GetValue();
return base::SysUTF16ToNSString(value.substr(selStart, selLength));
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
@@ -1402,19 +1491,21 @@ bool InitializeAccessibilityTreeSearch(
if (!browserAccessibility_)
return nil;
- const std::vector<int32>& line_breaks =
- browserAccessibility_->GetIntListAttribute(
- ui::AX_ATTR_LINE_BREAKS);
- std::string value = browserAccessibility_->GetStringAttribute(
- ui::AX_ATTR_VALUE);
+ const std::vector<int32_t>& line_breaks =
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LINE_BREAKS);
+ base::string16 value = browserAccessibility_->GetValue();
int len = static_cast<int>(value.size());
if ([attribute isEqualToString:
NSAccessibilityStringForRangeParameterizedAttribute]) {
- NSRange range = [(NSValue*)parameter rangeValue];
- base::string16 value = browserAccessibility_->GetString16Attribute(
- ui::AX_ATTR_VALUE);
- return base::SysUTF16ToNSString(value.substr(range.location, range.length));
+ return [self valueForRange:[(NSValue*)parameter rangeValue]];
+ }
+
+ if ([attribute
+ isEqualToString:
+ NSAccessibilityAttributedStringForRangeParameterizedAttribute]) {
+ NSString* value = [self valueForRange:[(NSValue*)parameter rangeValue]];
+ return [[[NSAttributedString alloc] initWithString:value] autorelease];
}
if ([attribute isEqualToString:
@@ -1560,7 +1651,8 @@ bool InitializeAccessibilityTreeSearch(
NSAccessibilityCellForColumnAndRowParameterizedAttribute,
nil]];
}
- if (browserAccessibility_->IsEditableText()) {
+
+ if (browserAccessibility_->HasState(ui::AX_STATE_EDITABLE)) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityLineForIndexParameterizedAttribute,
NSAccessibilityRangeForLineParameterizedAttribute,
@@ -1573,11 +1665,13 @@ bool InitializeAccessibilityTreeSearch(
NSAccessibilityStyleRangeForIndexParameterizedAttribute,
nil]];
}
+
if ([self internalRole] == ui::AX_ROLE_STATIC_TEXT) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityBoundsForRangeParameterizedAttribute,
nil]];
}
+
return ret;
}
@@ -1741,7 +1835,7 @@ bool InitializeAccessibilityTreeSearch(
}
// Caret navigation and text selection attributes.
- if (browserAccessibility_->IsEditableText()) {
+ if (browserAccessibility_->HasState(ui::AX_STATE_EDITABLE)) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityInsertionPointLineNumberAttribute,
NSAccessibilityNumberOfCharactersAttribute,
@@ -1835,10 +1929,9 @@ bool InitializeAccessibilityTreeSearch(
}
// Title UI Element.
- if (browserAccessibility_->HasIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT) ||
- (browserAccessibility_->HasIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS) &&
- browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS)
- .size() == 1)) {
+ if (browserAccessibility_->HasIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS) &&
+ browserAccessibility_->GetIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS)
+ .size() > 0) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityTitleUIElementAttribute,
nil]];
@@ -1869,16 +1962,22 @@ bool InitializeAccessibilityTreeSearch(
if (!browserAccessibility_)
return NO;
- if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
- return GetState(browserAccessibility_,
- ui::AX_STATE_FOCUSABLE);
+ if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
+ if ([self internalRole] == ui::AX_ROLE_DATE_TIME)
+ return NO;
+
+ return GetState(browserAccessibility_, ui::AX_STATE_FOCUSABLE);
+ }
+
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
return browserAccessibility_->GetBoolAttribute(
ui::AX_ATTR_CAN_SET_VALUE);
}
+
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute] &&
- browserAccessibility_->IsEditableText())
+ browserAccessibility_->HasState(ui::AX_STATE_EDITABLE)) {
return YES;
+ }
return NO;
}
@@ -1887,7 +1986,7 @@ bool InitializeAccessibilityTreeSearch(
// tree.
- (BOOL)accessibilityIsIgnored {
if (!browserAccessibility_)
- return true;
+ return YES;
return [self isIgnored];
}
@@ -1937,9 +2036,9 @@ bool InitializeAccessibilityTreeSearch(
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
NSRange range = [(NSValue*)value rangeValue];
- [self delegate]->AccessibilitySetTextSelection(
- browserAccessibility_->GetId(),
- range.location, range.location + range.length);
+ [self delegate]->AccessibilitySetSelection(
+ browserAccessibility_->GetId(), range.location,
+ browserAccessibility_->GetId(), range.location + range.length);
}
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac.h b/chromium/content/browser/accessibility/browser_accessibility_mac.h
index a574086d597..aed8fd49e08 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac.h
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility.h"
@class BrowserAccessibilityCocoa;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_mac.mm
index 1d4c2f92a7f..da1f55e9673 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac.mm
@@ -20,17 +20,8 @@ BrowserAccessibilityMac::BrowserAccessibilityMac()
: browser_accessibility_cocoa_(NULL) {
}
-void BrowserAccessibilityMac::OnDataChanged() {
- BrowserAccessibility::OnDataChanged();
-
- if (browser_accessibility_cocoa_) {
- [browser_accessibility_cocoa_ childrenChanged];
- return;
- }
-
- // We take ownership of the cocoa obj here.
- browser_accessibility_cocoa_ = [[BrowserAccessibilityCocoa alloc]
- initWithObject:this];
+bool BrowserAccessibilityMac::IsNative() const {
+ return true;
}
void BrowserAccessibilityMac::NativeReleaseReference() {
@@ -44,8 +35,17 @@ void BrowserAccessibilityMac::NativeReleaseReference() {
delete this;
}
-bool BrowserAccessibilityMac::IsNative() const {
- return true;
+void BrowserAccessibilityMac::OnDataChanged() {
+ BrowserAccessibility::OnDataChanged();
+
+ if (browser_accessibility_cocoa_) {
+ [browser_accessibility_cocoa_ childrenChanged];
+ return;
+ }
+
+ // We take ownership of the Cocoa object here.
+ browser_accessibility_cocoa_ =
+ [[BrowserAccessibilityCocoa alloc] initWithObject:this];
}
void BrowserAccessibilityMac::RecreateNativeObject() {
@@ -63,6 +63,11 @@ void BrowserAccessibilityMac::RecreateNativeObject() {
[browser_accessibility_cocoa_ swapChildren:&children];
}
+const BrowserAccessibilityCocoa*
+BrowserAccessibility::ToBrowserAccessibilityCocoa() const {
+ return static_cast<const BrowserAccessibilityMac*>(this)->native_view();
+}
+
BrowserAccessibilityCocoa* BrowserAccessibility::ToBrowserAccessibilityCocoa() {
return static_cast<BrowserAccessibilityMac*>(this)->
native_view();
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm b/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm
index 34874e3e49a..c85957fab59 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm
@@ -30,7 +30,7 @@ class BrowserAccessibilityTest : public ui::CocoaTest {
root.location.set_width(500);
root.location.set_height(100);
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
- root.AddStringAttribute(ui::AX_ATTR_HELP, "HelpText");
+ root.AddStringAttribute(ui::AX_ATTR_DESCRIPTION, "HelpText");
root.child_ids.push_back(1001);
root.child_ids.push_back(1002);
@@ -66,7 +66,8 @@ TEST_F(BrowserAccessibilityTest, HitTestTest) {
BrowserAccessibilityCocoa* firstChild =
[accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
EXPECT_NSEQ(@"Child1",
- [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
+ [firstChild
+ accessibilityAttributeValue:NSAccessibilityDescriptionAttribute]);
}
// Test doing a hit test on the edge of a child.
@@ -74,7 +75,8 @@ TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
BrowserAccessibilityCocoa* firstChild =
[accessibility_ accessibilityHitTest:NSZeroPoint];
EXPECT_NSEQ(@"Child1",
- [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
+ [firstChild
+ accessibilityAttributeValue:NSAccessibilityDescriptionAttribute]);
}
// This will test a hit test with invalid coordinates. It is assumed that
@@ -105,7 +107,7 @@ TEST_F(BrowserAccessibilityTest, RetainedDetachedObjectsReturnNil) {
BrowserAccessibilityCocoa* retainedFirstChild =
[accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
EXPECT_NSEQ(@"Child1", [retainedFirstChild
- accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
+ accessibilityAttributeValue:NSAccessibilityDescriptionAttribute]);
// Retain it. This simulates what the system might do with an
// accessibility object.
@@ -116,7 +118,7 @@ TEST_F(BrowserAccessibilityTest, RetainedDetachedObjectsReturnNil) {
// Now any attributes we query should return nil.
EXPECT_EQ(nil, [retainedFirstChild
- accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
+ accessibilityAttributeValue:NSAccessibilityDescriptionAttribute]);
// Don't leak memory in the test.
[retainedFirstChild release];
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.cc b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
index 2fc7e44b310..8979f10f0f0 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
@@ -4,7 +4,10 @@
#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include <stddef.h>
+
#include "base/logging.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/common/accessibility_messages.h"
#include "ui/accessibility/ax_tree_serializer.h"
@@ -40,7 +43,7 @@ using AXTreeIDMap =
base::hash_map<AXTreeIDRegistry::AXTreeID, BrowserAccessibilityManager*>;
base::LazyInstance<AXTreeIDMap> g_ax_tree_id_map = LAZY_INSTANCE_INITIALIZER;
-SimpleAXTreeUpdate MakeAXTreeUpdate(
+ui::AXTreeUpdate MakeAXTreeUpdate(
const ui::AXNodeData& node1,
const ui::AXNodeData& node2 /* = ui::AXNodeData() */,
const ui::AXNodeData& node3 /* = ui::AXNodeData() */,
@@ -49,11 +52,14 @@ SimpleAXTreeUpdate MakeAXTreeUpdate(
const ui::AXNodeData& node6 /* = ui::AXNodeData() */,
const ui::AXNodeData& node7 /* = ui::AXNodeData() */,
const ui::AXNodeData& node8 /* = ui::AXNodeData() */,
- const ui::AXNodeData& node9 /* = ui::AXNodeData() */) {
+ const ui::AXNodeData& node9 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node10 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node11 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node12 /* = ui::AXNodeData() */) {
CR_DEFINE_STATIC_LOCAL(ui::AXNodeData, empty_data, ());
- int32 no_id = empty_data.id;
+ int32_t no_id = empty_data.id;
- SimpleAXTreeUpdate update;
+ ui::AXTreeUpdate update;
update.nodes.push_back(node1);
if (node2.id != no_id)
update.nodes.push_back(node2);
@@ -71,11 +77,21 @@ SimpleAXTreeUpdate MakeAXTreeUpdate(
update.nodes.push_back(node8);
if (node9.id != no_id)
update.nodes.push_back(node9);
+ if (node10.id != no_id)
+ update.nodes.push_back(node10);
+ if (node11.id != no_id)
+ update.nodes.push_back(node11);
+ if (node12.id != no_id)
+ update.nodes.push_back(node12);
return update;
}
BrowserAccessibility* BrowserAccessibilityFactory::Create() {
+#if defined(OS_ANDROID) && defined(USE_AURA)
+ return nullptr;
+#else
return BrowserAccessibility::Create();
+#endif
}
BrowserAccessibilityFindInPageInfo::BrowserAccessibilityFindInPageInfo()
@@ -87,15 +103,10 @@ BrowserAccessibilityFindInPageInfo::BrowserAccessibilityFindInPageInfo()
end_offset(-1),
active_request_id(-1) {}
-#if !defined(OS_WIN) && \
- !defined(OS_MACOSX) && \
- !defined(OS_ANDROID) && \
- !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11))
-// We have subclassess of BrowserAccessibility on some platforms.
-// For other platforms, instantiate the base class.
+#if !defined(PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL)
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory) {
return new BrowserAccessibilityManager(initial_tree, delegate, factory);
@@ -125,7 +136,7 @@ BrowserAccessibilityManager::BrowserAccessibilityManager(
}
BrowserAccessibilityManager::BrowserAccessibilityManager(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
: delegate_(delegate),
@@ -146,7 +157,7 @@ BrowserAccessibilityManager::~BrowserAccessibilityManager() {
}
void BrowserAccessibilityManager::Initialize(
- const SimpleAXTreeUpdate& initial_tree) {
+ const ui::AXTreeUpdate& initial_tree) {
if (!tree_->Unserialize(initial_tree)) {
if (delegate_) {
LOG(ERROR) << tree_->error();
@@ -161,33 +172,39 @@ void BrowserAccessibilityManager::Initialize(
}
// static
-SimpleAXTreeUpdate
+ui::AXTreeUpdate
BrowserAccessibilityManager::GetEmptyDocument() {
ui::AXNodeData empty_document;
empty_document.id = 0;
empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
- SimpleAXTreeUpdate update;
+ ui::AXTreeUpdate update;
update.nodes.push_back(empty_document);
return update;
}
BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
+ // tree_ can be null during destruction.
+ if (!tree_)
+ return nullptr;
+
// tree_->root() can be null during AXTreeDelegate callbacks.
ui::AXNode* root = tree_->root();
return root ? GetFromAXNode(root) : nullptr;
}
BrowserAccessibility* BrowserAccessibilityManager::GetFromAXNode(
- ui::AXNode* node) {
+ const ui::AXNode* node) const {
+ if (!node)
+ return nullptr;
return GetFromID(node->id());
}
-BrowserAccessibility* BrowserAccessibilityManager::GetFromID(int32 id) {
- base::hash_map<int32, BrowserAccessibility*>::iterator iter =
- id_wrapper_map_.find(id);
+BrowserAccessibility* BrowserAccessibilityManager::GetFromID(int32_t id) const {
+ const auto iter = id_wrapper_map_.find(id);
if (iter != id_wrapper_map_.end())
return iter->second;
- return NULL;
+
+ return nullptr;
}
BrowserAccessibility*
@@ -195,7 +212,7 @@ BrowserAccessibilityManager::GetParentNodeFromParentTree() {
if (!GetRoot())
return nullptr;
- int parent_tree_id = GetRoot()->GetIntAttribute(ui::AX_ATTR_PARENT_TREE_ID);
+ int parent_tree_id = GetTreeData().parent_tree_id;
BrowserAccessibilityManager* parent_manager =
BrowserAccessibilityManager::FromID(parent_tree_id);
if (!parent_manager)
@@ -225,6 +242,10 @@ BrowserAccessibilityManager::GetParentNodeFromParentTree() {
return nullptr;
}
+const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() {
+ return tree_->data();
+}
+
void BrowserAccessibilityManager::OnWindowFocused() {
if (focus_)
NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
@@ -252,6 +273,9 @@ void BrowserAccessibilityManager::NavigationFailed() {
}
void BrowserAccessibilityManager::GotMouseDown() {
+ if (!focus_)
+ return;
+
osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
}
@@ -265,7 +289,7 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
bool should_send_initial_focus = false;
// Process all changes to the accessibility tree first.
- for (uint32 index = 0; index < details.size(); ++index) {
+ for (uint32_t index = 0; index < details.size(); ++index) {
const AXEventNotificationDetails& detail = details[index];
if (!tree_->Unserialize(detail.update)) {
if (delegate_) {
@@ -284,13 +308,11 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
}
}
- if (should_send_initial_focus &&
- (!delegate_ || delegate_->AccessibilityViewHasFocus())) {
+ if (should_send_initial_focus && NativeViewHasFocus())
NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
- }
// Now iterate over the events again and fire the events.
- for (uint32 index = 0; index < details.size(); index++) {
+ for (uint32_t index = 0; index < details.size(); index++) {
const AXEventNotificationDetails& detail = details[index];
// Find the node corresponding to the id that's the target of the
@@ -310,7 +332,7 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
// Don't send a native focus event if the window itself doesn't
// have focus.
- if (delegate_ && !delegate_->AccessibilityViewHasFocus())
+ if (!NativeViewHasFocus())
continue;
}
@@ -385,15 +407,23 @@ BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus(
return node;
}
+bool BrowserAccessibilityManager::NativeViewHasFocus() {
+ BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
+ if (delegate)
+ return delegate->AccessibilityViewHasFocus();
+ return false;
+}
+
BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
BrowserAccessibility* root) {
if (!focus_)
- return NULL;
+ return nullptr;
if (root && !focus_->IsDescendantOf(root->node()))
- return NULL;
+ return nullptr;
BrowserAccessibility* obj = GetFromAXNode(focus_);
+ DCHECK(obj);
if (obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
BrowserAccessibilityManager* child_manager =
BrowserAccessibilityManager::FromID(
@@ -458,8 +488,8 @@ void BrowserAccessibilityManager::SetTextSelection(
int start_offset,
int end_offset) {
if (delegate_) {
- delegate_->AccessibilitySetTextSelection(
- node.GetId(), start_offset, end_offset);
+ delegate_->AccessibilitySetSelection(node.GetId(), start_offset,
+ node.GetId(), end_offset);
}
}
@@ -479,7 +509,7 @@ BrowserAccessibility* BrowserAccessibilityManager::NextInTreeOrder(
return node->PlatformGetChild(0);
while (node) {
- auto sibling = node->GetNextSibling();
+ const auto sibling = node->GetNextSibling();
if (sibling)
return sibling;
@@ -494,7 +524,7 @@ BrowserAccessibility* BrowserAccessibilityManager::PreviousInTreeOrder(
if (!node)
return nullptr;
- auto sibling = node->GetPreviousSibling();
+ const auto sibling = node->GetPreviousSibling();
if (!sibling)
return node->GetParent();
@@ -522,8 +552,12 @@ BrowserAccessibility* BrowserAccessibilityManager::NextTextOnlyObject(
return next_node;
}
+void BrowserAccessibilityManager::OnTreeDataChanged(ui::AXTree* tree) {
+}
+
void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXTree* tree,
ui::AXNode* node) {
+ DCHECK(node);
if (node == focus_ && tree_) {
if (node != tree_->root())
SetFocus(tree_->root(), false);
@@ -538,6 +572,7 @@ void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXTree* tree,
void BrowserAccessibilityManager::OnSubtreeWillBeDeleted(ui::AXTree* tree,
ui::AXNode* node) {
+ DCHECK(node);
BrowserAccessibility* obj = GetFromAXNode(node);
if (obj)
obj->OnSubtreeWillBeDeleted();
@@ -553,6 +588,7 @@ void BrowserAccessibilityManager::OnNodeCreated(ui::AXTree* tree,
void BrowserAccessibilityManager::OnNodeChanged(ui::AXTree* tree,
ui::AXNode* node) {
+ DCHECK(node);
GetFromAXNode(node)->OnDataChanged();
}
@@ -560,11 +596,21 @@ void BrowserAccessibilityManager::OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
const std::vector<ui::AXTreeDelegate::Change>& changes) {
- if (GetRoot()->HasIntAttribute(ui::AX_ATTR_TREE_ID) &&
- GetRoot()->GetIntAttribute(ui::AX_ATTR_TREE_ID) != ax_tree_id_) {
+ bool ax_tree_id_changed = false;
+ if (GetTreeData().tree_id != -1 && GetTreeData().tree_id != ax_tree_id_) {
g_ax_tree_id_map.Get().erase(ax_tree_id_);
- ax_tree_id_ = GetRoot()->GetIntAttribute(ui::AX_ATTR_TREE_ID);
+ ax_tree_id_ = GetTreeData().tree_id;
g_ax_tree_id_map.Get().insert(std::make_pair(ax_tree_id_, this));
+ ax_tree_id_changed = true;
+ }
+
+ if (ax_tree_id_changed || root_changed) {
+ BrowserAccessibility* parent = GetParentNodeFromParentTree();
+ if (parent) {
+ parent->OnDataChanged();
+ parent->manager()->NotifyAccessibilityEvent(
+ ui::AX_EVENT_CHILDREN_CHANGED, parent);
+ }
}
}
@@ -572,7 +618,7 @@ BrowserAccessibilityDelegate*
BrowserAccessibilityManager::GetDelegateFromRootManager() {
if (!GetRoot())
return nullptr;
- int parent_tree_id = GetRoot()->GetIntAttribute(ui::AX_ATTR_PARENT_TREE_ID);
+ int parent_tree_id = GetTreeData().parent_tree_id;
BrowserAccessibilityManager* parent_manager =
BrowserAccessibilityManager::FromID(parent_tree_id);
if (parent_manager)
@@ -580,13 +626,16 @@ BrowserAccessibilityDelegate*
return delegate();
}
-SimpleAXTreeUpdate
+ui::AXTreeUpdate
BrowserAccessibilityManager::SnapshotAXTreeForTesting() {
- scoped_ptr<ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData> > tree_source(
+ scoped_ptr<ui::AXTreeSource<const ui::AXNode*,
+ ui::AXNodeData,
+ ui::AXTreeData> > tree_source(
tree_->CreateTreeSource());
- ui::AXTreeSerializer<const ui::AXNode*, ui::AXNodeData> serializer(
- tree_source.get());
- SimpleAXTreeUpdate update;
+ ui::AXTreeSerializer<const ui::AXNode*,
+ ui::AXNodeData,
+ ui::AXTreeData> serializer(tree_source.get());
+ ui::AXTreeUpdate update;
serializer.SerializeChanges(tree_->root(), &update);
return update;
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.h b/chromium/content/browser/accessibility/browser_accessibility_manager.h
index 4d9c35ce1d7..e2e17564680 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_
+#include <stdint.h>
+
#include <vector>
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "content/browser/accessibility/ax_tree_id_registry.h"
@@ -32,10 +35,8 @@ class BrowserAccessibilityManagerWin;
class BrowserAccessibilityManagerAuraLinux;
#endif
-using SimpleAXTreeUpdate = ui::AXTreeUpdate<ui::AXNodeData>;
-
// For testing.
-CONTENT_EXPORT SimpleAXTreeUpdate MakeAXTreeUpdate(
+CONTENT_EXPORT ui::AXTreeUpdate MakeAXTreeUpdate(
const ui::AXNodeData& node,
const ui::AXNodeData& node2 = ui::AXNodeData(),
const ui::AXNodeData& node3 = ui::AXNodeData(),
@@ -44,7 +45,10 @@ CONTENT_EXPORT SimpleAXTreeUpdate MakeAXTreeUpdate(
const ui::AXNodeData& node6 = ui::AXNodeData(),
const ui::AXNodeData& node7 = ui::AXNodeData(),
const ui::AXNodeData& node8 = ui::AXNodeData(),
- const ui::AXNodeData& node9 = ui::AXNodeData());
+ const ui::AXNodeData& node9 = ui::AXNodeData(),
+ const ui::AXNodeData& node10 = ui::AXNodeData(),
+ const ui::AXNodeData& node11 = ui::AXNodeData(),
+ const ui::AXNodeData& node12 = ui::AXNodeData());
// Class that can perform actions on behalf of the BrowserAccessibilityManager.
// Note: BrowserAccessibilityManager should never cache any of the return
@@ -65,8 +69,10 @@ class CONTENT_EXPORT BrowserAccessibilityDelegate {
int acc_obj_id, const gfx::Point& point) = 0;
virtual void AccessibilitySetScrollOffset(
int acc_obj_id, const gfx::Point& offset) = 0;
- virtual void AccessibilitySetTextSelection(
- int acc_obj_id, int start_offset, int end_offset) = 0;
+ virtual void AccessibilitySetSelection(int anchor_obj_id,
+ int anchor_offset,
+ int focus_obj_id,
+ int focus_offset) = 0;
virtual void AccessibilitySetValue(
int acc_obj_id, const base::string16& value) = 0;
virtual bool AccessibilityViewHasFocus() const = 0;
@@ -116,7 +122,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
// Creates the platform-specific BrowserAccessibilityManager, but
// with no parent window pointer. Only useful for unit tests.
static BrowserAccessibilityManager* Create(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
@@ -125,9 +131,9 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
~BrowserAccessibilityManager() override;
- void Initialize(const SimpleAXTreeUpdate& initial_tree);
+ void Initialize(const ui::AXTreeUpdate& initial_tree);
- static SimpleAXTreeUpdate GetEmptyDocument();
+ static ui::AXTreeUpdate GetEmptyDocument();
virtual void NotifyAccessibilityEvent(
ui::AXEvent event_type, BrowserAccessibility* node) { }
@@ -136,15 +142,18 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
BrowserAccessibility* GetRoot();
// Returns a pointer to the BrowserAccessibility object for a given AXNode.
- BrowserAccessibility* GetFromAXNode(ui::AXNode* node);
+ BrowserAccessibility* GetFromAXNode(const ui::AXNode* node) const;
// Return a pointer to the object corresponding to the given id,
// does not make a new reference.
- BrowserAccessibility* GetFromID(int32 id);
+ BrowserAccessibility* GetFromID(int32_t id) const;
// If this tree has a parent tree, return the parent node in that tree.
BrowserAccessibility* GetParentNodeFromParentTree();
+ // Get the AXTreeData for this frame.
+ const ui::AXTreeData& GetTreeData();
+
// Called to notify the accessibility manager that its associated native
// view got focused.
virtual void OnWindowFocused();
@@ -247,6 +256,9 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
// active descendant if it has one.
BrowserAccessibility* GetActiveDescendantFocus(BrowserAccessibility* root);
+ // Returns true if native focus is anywhere in this WebContents or not.
+ bool NativeViewHasFocus();
+
// True by default, but some platforms want to treat the root
// scroll offsets separately.
virtual bool UseRootScrollOffsetsWhenComputingBounds();
@@ -259,6 +271,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
BrowserAccessibility* node) const;
// AXTreeDelegate implementation.
+ void OnTreeDataChanged(ui::AXTree* tree) override;
void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
void OnNodeCreated(ui::AXTree* tree, ui::AXNode* node) override;
@@ -279,7 +292,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
BrowserAccessibilityDelegate* GetDelegateFromRootManager();
// Get a snapshot of the current tree as an AXTreeUpdate.
- SimpleAXTreeUpdate SnapshotAXTreeForTesting();
+ ui::AXTreeUpdate SnapshotAXTreeForTesting();
protected:
BrowserAccessibilityManager(
@@ -287,7 +300,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
BrowserAccessibilityFactory* factory);
BrowserAccessibilityManager(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory);
@@ -328,7 +341,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
ui::AXNode* focus_;
// A mapping from a node id to its wrapper of type BrowserAccessibility.
- base::hash_map<int32, BrowserAccessibility*> id_wrapper_map_;
+ base::hash_map<int32_t, BrowserAccessibility*> id_wrapper_map_;
// True if the user has initiated a navigation to another page.
bool user_is_navigating_away_;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
index 28dd40f0525..57dd100c571 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
+#include <stddef.h>
+
#include <cmath>
#include "base/android/jni_android.h"
@@ -53,7 +55,7 @@ namespace aria_strings {
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory) {
return new BrowserAccessibilityManagerAndroid(
@@ -67,7 +69,7 @@ BrowserAccessibilityManager::ToBrowserAccessibilityManagerAndroid() {
BrowserAccessibilityManagerAndroid::BrowserAccessibilityManagerAndroid(
ScopedJavaLocalRef<jobject> content_view_core,
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
: BrowserAccessibilityManager(delegate, factory),
@@ -86,14 +88,14 @@ BrowserAccessibilityManagerAndroid::~BrowserAccessibilityManagerAndroid() {
}
// static
-SimpleAXTreeUpdate
+ui::AXTreeUpdate
BrowserAccessibilityManagerAndroid::GetEmptyDocument() {
ui::AXNodeData empty_document;
empty_document.id = 0;
empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
empty_document.state = 1 << ui::AX_STATE_READ_ONLY;
- SimpleAXTreeUpdate update;
+ ui::AXTreeUpdate update;
update.nodes.push_back(empty_document);
return update;
}
@@ -177,7 +179,7 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
break;
case ui::AX_EVENT_TEXT_CHANGED:
case ui::AX_EVENT_VALUE_CHANGED:
- if (node->IsEditableText() && GetFocus(GetRoot()) == node) {
+ if (android_node->IsEditableText() && GetFocus(GetRoot()) == node) {
Java_BrowserAccessibilityManager_handleEditableTextChanged(
env, obj.obj(), node->GetId());
} else if (android_node->IsSlider()) {
@@ -192,7 +194,9 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
}
}
-jint BrowserAccessibilityManagerAndroid::GetRootId(JNIEnv* env, jobject obj) {
+jint BrowserAccessibilityManagerAndroid::GetRootId(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (GetRoot())
return static_cast<jint>(GetRoot()->GetId());
else
@@ -200,18 +204,25 @@ jint BrowserAccessibilityManagerAndroid::GetRootId(JNIEnv* env, jobject obj) {
}
jboolean BrowserAccessibilityManagerAndroid::IsNodeValid(
- JNIEnv* env, jobject obj, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
return GetFromID(id) != NULL;
}
void BrowserAccessibilityManagerAndroid::HitTest(
- JNIEnv* env, jobject obj, jint x, jint y) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint x,
+ jint y) {
if (delegate())
delegate()->AccessibilityHitTest(gfx::Point(x, y));
}
jboolean BrowserAccessibilityManagerAndroid::IsEditableText(
- JNIEnv* env, jobject obj, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -221,7 +232,9 @@ jboolean BrowserAccessibilityManagerAndroid::IsEditableText(
}
jint BrowserAccessibilityManagerAndroid::GetEditableTextSelectionStart(
- JNIEnv* env, jobject obj, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -231,7 +244,9 @@ jint BrowserAccessibilityManagerAndroid::GetEditableTextSelectionStart(
}
jint BrowserAccessibilityManagerAndroid::GetEditableTextSelectionEnd(
- JNIEnv* env, jobject obj, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -241,7 +256,10 @@ jint BrowserAccessibilityManagerAndroid::GetEditableTextSelectionEnd(
}
jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo(
- JNIEnv* env, jobject obj, jobject info, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& info,
+ jint id) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -351,7 +369,11 @@ jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo(
}
jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityEvent(
- JNIEnv* env, jobject obj, jobject event, jint id, jint event_type) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& event,
+ jint id,
+ jint event_type) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -452,33 +474,42 @@ jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityEvent(
return true;
}
-void BrowserAccessibilityManagerAndroid::Click(
- JNIEnv* env, jobject obj, jint id) {
+void BrowserAccessibilityManagerAndroid::Click(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
BrowserAccessibility* node = GetFromID(id);
if (node)
DoDefaultAction(*node);
}
-void BrowserAccessibilityManagerAndroid::Focus(
- JNIEnv* env, jobject obj, jint id) {
+void BrowserAccessibilityManagerAndroid::Focus(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
BrowserAccessibility* node = GetFromID(id);
if (node)
SetFocus(node, true);
}
-void BrowserAccessibilityManagerAndroid::Blur(JNIEnv* env, jobject obj) {
+void BrowserAccessibilityManagerAndroid::Blur(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
SetFocus(GetRoot(), true);
}
void BrowserAccessibilityManagerAndroid::ScrollToMakeNodeVisible(
- JNIEnv* env, jobject obj, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
BrowserAccessibility* node = GetFromID(id);
if (node)
ScrollToMakeVisible(*node, gfx::Rect(node->GetLocation().size()));
}
void BrowserAccessibilityManagerAndroid::SetTextFieldValue(
- JNIEnv* env, jobject obj, jint id, jstring value) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id,
+ const JavaParamRef<jstring>& value) {
BrowserAccessibility* node = GetFromID(id);
if (node) {
BrowserAccessibilityManager::SetValue(
@@ -487,14 +518,21 @@ void BrowserAccessibilityManagerAndroid::SetTextFieldValue(
}
void BrowserAccessibilityManagerAndroid::SetSelection(
- JNIEnv* env, jobject obj, jint id, jint start, jint end) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id,
+ jint start,
+ jint end) {
BrowserAccessibility* node = GetFromID(id);
if (node)
SetTextSelection(*node, start, end);
}
jboolean BrowserAccessibilityManagerAndroid::AdjustSlider(
- JNIEnv* env, jobject obj, jint id, jboolean increment) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id,
+ jboolean increment) {
BrowserAccessibility* node = GetFromID(id);
if (!node)
return false;
@@ -549,7 +587,10 @@ void BrowserAccessibilityManagerAndroid::HandleHoverEvent(
}
jint BrowserAccessibilityManagerAndroid::FindElementType(
- JNIEnv* env, jobject obj, jint start_id, jstring element_type_str,
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint start_id,
+ const JavaParamRef<jstring>& element_type_str,
jboolean forwards) {
BrowserAccessibility* node = GetFromID(start_id);
if (!node)
@@ -606,8 +647,12 @@ jint BrowserAccessibilityManagerAndroid::FindElementType(
}
jboolean BrowserAccessibilityManagerAndroid::NextAtGranularity(
- JNIEnv* env, jobject obj, jint granularity, jboolean extend_selection,
- jint id, jint cursor_index) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint granularity,
+ jboolean extend_selection,
+ jint id,
+ jint cursor_index) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -632,8 +677,12 @@ jboolean BrowserAccessibilityManagerAndroid::NextAtGranularity(
}
jboolean BrowserAccessibilityManagerAndroid::PreviousAtGranularity(
- JNIEnv* env, jobject obj, jint granularity, jboolean extend_selection,
- jint id, jint cursor_index) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint granularity,
+ jboolean extend_selection,
+ jint id,
+ jint cursor_index) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -653,12 +702,15 @@ jboolean BrowserAccessibilityManagerAndroid::PreviousAtGranularity(
}
bool BrowserAccessibilityManagerAndroid::NextAtGranularity(
- int32 granularity, int32 cursor_index,
- BrowserAccessibilityAndroid* node, int32* start_index, int32* end_index) {
+ int32_t granularity,
+ int32_t cursor_index,
+ BrowserAccessibilityAndroid* node,
+ int32_t* start_index,
+ int32_t* end_index) {
switch (granularity) {
case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_CHARACTER: {
base::string16 text = node->GetText();
- if (cursor_index >= static_cast<int32>(text.length()))
+ if (cursor_index >= static_cast<int32_t>(text.length()))
return false;
base::i18n::UTF16CharIterator iter(text.data(), text.size());
while (!iter.end() && iter.array_pos() <= cursor_index)
@@ -669,8 +721,8 @@ bool BrowserAccessibilityManagerAndroid::NextAtGranularity(
}
case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_WORD:
case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_LINE: {
- std::vector<int32> starts;
- std::vector<int32> ends;
+ std::vector<int32_t> starts;
+ std::vector<int32_t> ends;
node->GetGranularityBoundaries(granularity, &starts, &ends, 0);
if (starts.size() == 0)
return false;
@@ -694,8 +746,11 @@ bool BrowserAccessibilityManagerAndroid::NextAtGranularity(
}
bool BrowserAccessibilityManagerAndroid::PreviousAtGranularity(
- int32 granularity, int32 cursor_index,
- BrowserAccessibilityAndroid* node, int32* start_index, int32* end_index) {
+ int32_t granularity,
+ int32_t cursor_index,
+ BrowserAccessibilityAndroid* node,
+ int32_t* start_index,
+ int32_t* end_index) {
switch (granularity) {
case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_CHARACTER: {
if (cursor_index <= 0)
@@ -713,8 +768,8 @@ bool BrowserAccessibilityManagerAndroid::PreviousAtGranularity(
}
case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_WORD:
case ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_LINE: {
- std::vector<int32> starts;
- std::vector<int32> ends;
+ std::vector<int32_t> starts;
+ std::vector<int32_t> ends;
node->GetGranularityBoundaries(granularity, &starts, &ends, 0);
if (starts.size() == 0)
return false;
@@ -738,13 +793,17 @@ bool BrowserAccessibilityManagerAndroid::PreviousAtGranularity(
}
void BrowserAccessibilityManagerAndroid::SetAccessibilityFocus(
- JNIEnv* env, jobject obj, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
if (delegate_)
delegate_->AccessibilitySetAccessibilityFocus(id);
}
bool BrowserAccessibilityManagerAndroid::IsSlider(
- JNIEnv* env, jobject obj, jint id) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
@@ -754,7 +813,10 @@ bool BrowserAccessibilityManagerAndroid::IsSlider(
}
bool BrowserAccessibilityManagerAndroid::Scroll(
- JNIEnv* env, jobject obj, jint id, int direction) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint id,
+ int direction) {
BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
GetFromID(id));
if (!node)
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_android.h b/chromium/content/browser/accessibility/browser_accessibility_manager_android.h
index aeffa745953..404676bbe06 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -5,7 +5,10 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
+#include <stdint.h>
+
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/android/content_view_core_impl.h"
@@ -48,13 +51,13 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
public:
BrowserAccessibilityManagerAndroid(
base::android::ScopedJavaLocalRef<jobject> content_view_core,
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
~BrowserAccessibilityManagerAndroid() override;
- static SimpleAXTreeUpdate GetEmptyDocument();
+ static ui::AXTreeUpdate GetEmptyDocument();
void SetContentViewCore(
base::android::ScopedJavaLocalRef<jobject> content_view_core);
@@ -80,37 +83,76 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
// --------------------------------------------------------------------------
// Tree methods.
- jint GetRootId(JNIEnv* env, jobject obj);
- jboolean IsNodeValid(JNIEnv* env, jobject obj, jint id);
- void HitTest(JNIEnv* env, jobject obj, jint x, jint y);
+ jint GetRootId(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ jboolean IsNodeValid(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
+ void HitTest(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint x,
+ jint y);
// Methods to get information about a specific node.
- jboolean IsEditableText(JNIEnv* env, jobject obj, jint id);
- jint GetEditableTextSelectionStart(JNIEnv* env, jobject obj, jint id);
- jint GetEditableTextSelectionEnd(JNIEnv* env, jobject obj, jint id);
+ jboolean IsEditableText(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
+ jint GetEditableTextSelectionStart(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
+ jint GetEditableTextSelectionEnd(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
// Populate Java accessibility data structures with info about a node.
jboolean PopulateAccessibilityNodeInfo(
- JNIEnv* env, jobject obj, jobject info, jint id);
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& info,
+ jint id);
jboolean PopulateAccessibilityEvent(
- JNIEnv* env, jobject obj, jobject event, jint id, jint event_type);
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& event,
+ jint id,
+ jint event_type);
// Perform actions.
- void Click(JNIEnv* env, jobject obj, jint id);
- void Focus(JNIEnv* env, jobject obj, jint id);
- void Blur(JNIEnv* env, jobject obj);
- void ScrollToMakeNodeVisible(JNIEnv* env, jobject obj, jint id);
- void SetTextFieldValue(JNIEnv* env, jobject obj, jint id, jstring value);
- void SetSelection(JNIEnv* env, jobject obj, jint id, jint start, jint end);
- jboolean AdjustSlider(JNIEnv* env, jobject obj, jint id, jboolean increment);
+ void Click(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
+ void Focus(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
+ void Blur(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void ScrollToMakeNodeVisible(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
+ void SetTextFieldValue(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id,
+ const base::android::JavaParamRef<jstring>& value);
+ void SetSelection(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id,
+ jint start,
+ jint end);
+ jboolean AdjustSlider(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id,
+ jboolean increment);
// Return the id of the next node in tree order in the direction given by
// |forwards|, starting with |start_id|, that matches |element_type|,
// where |element_type| is a special uppercase string from TalkBack or
// BrailleBack indicating general categories of web content like
// "SECTION" or "CONTROL". Return 0 if not found.
- jint FindElementType(JNIEnv* env, jobject obj, jint start_id,
- jstring element_type, jboolean forwards);
+ jint FindElementType(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint start_id,
+ const base::android::JavaParamRef<jstring>& element_type,
+ jboolean forwards);
// Respond to a ACTION_[NEXT/PREVIOUS]_AT_MOVEMENT_GRANULARITY action
// and move the cursor/selection within the given node id. We keep track
@@ -119,12 +161,19 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
// in Blink, too, and either way calls
// Java_BrowserAccessibilityManager_finishGranularityMove with the
// result.
- jboolean NextAtGranularity(JNIEnv* env, jobject obj,
- jint granularity, jboolean extend_selection,
- jint id, jint cursor_index);
- jboolean PreviousAtGranularity(JNIEnv* env, jobject obj,
- jint granularity, jboolean extend_selection,
- jint id, jint cursor_index);
+ jboolean NextAtGranularity(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint granularity,
+ jboolean extend_selection,
+ jint id,
+ jint cursor_index);
+ jboolean PreviousAtGranularity(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint granularity,
+ jboolean extend_selection,
+ jint id,
+ jint cursor_index);
// Helper functions to compute the next start and end index when moving
// forwards or backwards by character, word, or line. This part is
@@ -132,24 +181,35 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
// take a single cursor index as input and return the boundaries surrounding
// the next word or line. If moving by character, the output start and
// end index will be the same.
- bool NextAtGranularity(
- int32 granularity, int cursor_index,
- BrowserAccessibilityAndroid* node, int32* start_index, int32* end_index);
- bool PreviousAtGranularity(
- int32 granularity, int cursor_index,
- BrowserAccessibilityAndroid* node, int32* start_index, int32* end_index);
+ bool NextAtGranularity(int32_t granularity,
+ int cursor_index,
+ BrowserAccessibilityAndroid* node,
+ int32_t* start_index,
+ int32_t* end_index);
+ bool PreviousAtGranularity(int32_t granularity,
+ int cursor_index,
+ BrowserAccessibilityAndroid* node,
+ int32_t* start_index,
+ int32_t* end_index);
// Set accessibility focus. This sends a message to the renderer to
// asynchronously load inline text boxes for this node only, enabling more
// accurate movement by granularities on this node.
- void SetAccessibilityFocus(JNIEnv* env, jobject obj, jint id);
+ void SetAccessibilityFocus(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
// Returns true if the object is a slider.
- bool IsSlider(JNIEnv* env, jobject obj, jint id);
+ bool IsSlider(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
// Scrolls any scrollable container by about 80% of one page in the
// given direction.
- bool Scroll(JNIEnv* env, jobject obj, jint id, int direction);
+ bool Scroll(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id,
+ int direction);
protected:
// AXTreeDelegate overrides.
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index 45645f5a6ce..ffded43e881 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -11,7 +11,7 @@ namespace content {
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory) {
return new BrowserAccessibilityManagerAuraLinux(nullptr, initial_tree,
@@ -25,7 +25,7 @@ BrowserAccessibilityManager::ToBrowserAccessibilityManagerAuraLinux() {
BrowserAccessibilityManagerAuraLinux::BrowserAccessibilityManagerAuraLinux(
AtkObject* parent_object,
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
: BrowserAccessibilityManager(delegate, factory),
@@ -37,13 +37,13 @@ BrowserAccessibilityManagerAuraLinux::~BrowserAccessibilityManagerAuraLinux() {
}
// static
-SimpleAXTreeUpdate
+ui::AXTreeUpdate
BrowserAccessibilityManagerAuraLinux::GetEmptyDocument() {
ui::AXNodeData empty_document;
empty_document.id = 0;
empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
empty_document.state = 1 << ui::AX_STATE_READ_ONLY;
- SimpleAXTreeUpdate update;
+ ui::AXTreeUpdate update;
update.nodes.push_back(empty_document);
return update;
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
index bcbcbdcaa97..4ccd31faa88 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_AURALINUX_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_AURALINUX_H_
+#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
struct ViewHostMsg_AccessibilityNotification_Params;
@@ -18,13 +19,13 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAuraLinux
public:
BrowserAccessibilityManagerAuraLinux(
AtkObject* parent_object,
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
~BrowserAccessibilityManagerAuraLinux() override;
- static SimpleAXTreeUpdate GetEmptyDocument();
+ static ui::AXTreeUpdate GetEmptyDocument();
// Implementation BrowserAccessibilityManager methods
void NotifyAccessibilityEvent(ui::AXEvent event_type,
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
index e6b2ab48d7f..0cda76d2e93 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -7,6 +7,7 @@
#import <Cocoa/Cocoa.h>
+#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
namespace content {
@@ -16,11 +17,11 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
public:
BrowserAccessibilityManagerMac(
NSView* parent_view,
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
- static SimpleAXTreeUpdate GetEmptyDocument();
+ static ui::AXTreeUpdate GetEmptyDocument();
BrowserAccessibility* GetFocus(BrowserAccessibility* root) override;
@@ -36,6 +37,9 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
bool root_changed,
const std::vector<ui::AXTreeDelegate::Change>& changes) override;
+ // Returns an autoreleased object.
+ NSDictionary* GetUserInfoForSelectedTextChangedNotification();
+
// This gives BrowserAccessibilityManager::Create access to the class
// constructor.
friend class BrowserAccessibilityManager;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 3c24f0632a8..0937229b2aa 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -4,16 +4,79 @@
#include "content/browser/accessibility/browser_accessibility_manager_mac.h"
-#import "base/logging.h"
+#include <stddef.h>
+
+#import "base/mac/mac_util.h"
+#import "base/mac/sdk_forward_declarations.h"
+#include "base/logging.h"
#import "content/browser/accessibility/browser_accessibility_cocoa.h"
#import "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/common/accessibility_messages.h"
+
+namespace {
+
+// Declare accessibility constants and enums only present in WebKit.
+
+enum AXTextStateChangeType {
+ AXTextStateChangeTypeUnknown,
+ AXTextStateChangeTypeEdit,
+ AXTextStateChangeTypeSelectionMove,
+ AXTextStateChangeTypeSelectionExtend
+};
+
+enum AXTextSelectionDirection {
+ AXTextSelectionDirectionUnknown,
+ AXTextSelectionDirectionBeginning,
+ AXTextSelectionDirectionEnd,
+ AXTextSelectionDirectionPrevious,
+ AXTextSelectionDirectionNext,
+ AXTextSelectionDirectionDiscontiguous
+};
+
+enum AXTextSelectionGranularity {
+ AXTextSelectionGranularityUnknown,
+ AXTextSelectionGranularityCharacter,
+ AXTextSelectionGranularityWord,
+ AXTextSelectionGranularityLine,
+ AXTextSelectionGranularitySentence,
+ AXTextSelectionGranularityParagraph,
+ AXTextSelectionGranularityPage,
+ AXTextSelectionGranularityDocument,
+ AXTextSelectionGranularityAll
+};
+
+NSString* const NSAccessibilityAutocorrectionOccurredNotification =
+ @"AXAutocorrectionOccurred";
+NSString* const NSAccessibilityLayoutCompleteNotification =
+ @"AXLayoutComplete";
+NSString* const NSAccessibilityLoadCompleteNotification =
+ @"AXLoadComplete";
+NSString* const NSAccessibilityInvalidStatusChangedNotification =
+ @"AXInvalidStatusChanged";
+NSString* const NSAccessibilityLiveRegionChangedNotification =
+ @"AXLiveRegionChanged";
+NSString* const NSAccessibilityMenuItemSelectedNotification =
+ @"AXMenuItemSelected";
+NSString* const NSAccessibilityTextStateChangeTypeKey =
+ @"AXTextStateChangeType";
+NSString* const NSAccessibilityTextStateSyncKey = @"AXTextStateSync";
+NSString* const NSAccessibilityTextSelectionDirection =
+ @"AXTextSelectionDirection";
+NSString* const NSAccessibilityTextSelectionGranularity =
+ @"AXTextSelectionGranularity";
+NSString* const NSAccessibilityTextSelectionChangedFocus =
+ @"AXTextSelectionChangedFocus";
+NSString* const NSAccessibilityTextChangeElement =
+ @"AXAccessibilityTextChangeElement";
+
+} // namespace
+
namespace content {
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory) {
return new BrowserAccessibilityManagerMac(
@@ -22,7 +85,7 @@ BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
BrowserAccessibilityManagerMac::BrowserAccessibilityManagerMac(
NSView* parent_view,
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
: BrowserAccessibilityManager(delegate, factory),
@@ -31,14 +94,14 @@ BrowserAccessibilityManagerMac::BrowserAccessibilityManagerMac(
}
// static
-SimpleAXTreeUpdate
+ui::AXTreeUpdate
BrowserAccessibilityManagerMac::GetEmptyDocument() {
ui::AXNodeData empty_document;
empty_document.id = 0;
empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
empty_document.state =
1 << ui::AX_STATE_READ_ONLY;
- SimpleAXTreeUpdate update;
+ ui::AXTreeUpdate update;
update.nodes.push_back(empty_document);
return update;
}
@@ -61,107 +124,124 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
if (!node->IsNative())
return;
- if (event_type == ui::AX_EVENT_FOCUS &&
- node->GetRole() == ui::AX_ROLE_LIST_BOX_OPTION &&
- node->HasState(ui::AX_STATE_SELECTED) &&
- node->GetParent() &&
- node->GetParent()->GetRole() == ui::AX_ROLE_LIST_BOX) {
- node = node->GetParent();
- SetFocus(node, false);
+ if (event_type == ui::AX_EVENT_FOCUS) {
+ BrowserAccessibility* active_descendant = GetActiveDescendantFocus(
+ GetRoot());
+ if (active_descendant)
+ node = active_descendant;
+
+ if (node->GetRole() == ui::AX_ROLE_LIST_BOX_OPTION &&
+ node->HasState(ui::AX_STATE_SELECTED) &&
+ node->GetParent() &&
+ node->GetParent()->GetRole() == ui::AX_ROLE_LIST_BOX) {
+ node = node->GetParent();
+ SetFocus(node, false);
+ }
}
- // Refer to AXObjectCache.mm (webkit).
- NSString* event_id = @"";
+ auto native_node = node->ToBrowserAccessibilityCocoa();
+ DCHECK(native_node);
+
+ // Refer to |AXObjectCache::postPlatformNotification| in WebKit source code.
+ NSString* mac_notification;
switch (event_type) {
case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
if (node->GetRole() == ui::AX_ROLE_TREE) {
- event_id = NSAccessibilitySelectedRowsChangedNotification;
+ mac_notification = NSAccessibilitySelectedRowsChangedNotification;
+ } else if (node->GetRole() == ui::AX_ROLE_COMBO_BOX) {
+ // Even though the selected item in the combo box has changed, we don't
+ // want to post a focus change because this will take the focus out of
+ // the combo box where the user might be typing.
+ mac_notification = NSAccessibilitySelectedChildrenChangedNotification;
} else {
- event_id = NSAccessibilityFocusedUIElementChangedNotification;
- BrowserAccessibility* active_descendant_focus =
- GetActiveDescendantFocus(GetRoot());
- if (active_descendant_focus)
- node = active_descendant_focus;
+ mac_notification = NSAccessibilityFocusedUIElementChangedNotification;
}
-
break;
- case ui::AX_EVENT_ALERT:
- // Not used on Mac.
- return;
- case ui::AX_EVENT_BLUR:
- // A no-op on Mac.
- return;
- case ui::AX_EVENT_CHECKED_STATE_CHANGED:
- // Not used on Mac.
- return;
- case ui::AX_EVENT_CHILDREN_CHANGED:
- // TODO(dtseng): no clear equivalent on Mac.
- return;
- case ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED:
- // Not used on Mac.
- return;
+ case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
+ mac_notification = NSAccessibilityAutocorrectionOccurredNotification;
+ break;
case ui::AX_EVENT_FOCUS:
- event_id = NSAccessibilityFocusedUIElementChangedNotification;
+ mac_notification = NSAccessibilityFocusedUIElementChangedNotification;
break;
case ui::AX_EVENT_LAYOUT_COMPLETE:
- event_id = @"AXLayoutComplete";
- break;
- case ui::AX_EVENT_LIVE_REGION_CHANGED:
- event_id = @"AXLiveRegionChanged";
+ mac_notification = NSAccessibilityLayoutCompleteNotification;
break;
case ui::AX_EVENT_LOAD_COMPLETE:
- event_id = @"AXLoadComplete";
+ mac_notification = NSAccessibilityLoadCompleteNotification;
break;
- case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED:
- // Not used on Mac.
- return;
- case ui::AX_EVENT_ROW_COUNT_CHANGED:
- event_id = NSAccessibilityRowCountChangedNotification;
- break;
- case ui::AX_EVENT_ROW_COLLAPSED:
- event_id = @"AXRowCollapsed";
- break;
- case ui::AX_EVENT_ROW_EXPANDED:
- event_id = @"AXRowExpanded";
+ case ui::AX_EVENT_INVALID_STATUS_CHANGED:
+ mac_notification = NSAccessibilityInvalidStatusChangedNotification;
break;
- case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
- // Not used on Mac.
- return;
case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
- event_id = NSAccessibilitySelectedChildrenChangedNotification;
+ if (node->GetRole() == ui::AX_ROLE_GRID ||
+ node->GetRole() == ui::AX_ROLE_TABLE) {
+ mac_notification = NSAccessibilitySelectedRowsChangedNotification;
+ } else {
+ mac_notification = NSAccessibilitySelectedChildrenChangedNotification;
+ }
break;
- case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
- event_id = NSAccessibilitySelectedTextChangedNotification;
+ case ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED: {
+ mac_notification = NSAccessibilitySelectedTextChangedNotification;
+ if (base::mac::IsOSElCapitanOrLater()) {
+ // |NSAccessibilityPostNotificationWithUserInfo| should be used on OS X
+ // 10.11 or later to notify Voiceover about text selection changes. This
+ // API has been present on versions of OS X since 10.7 but doesn't
+ // appear to be needed by Voiceover before version 10.11.
+ NSDictionary* user_info =
+ GetUserInfoForSelectedTextChangedNotification();
+ NSAccessibilityPostNotificationWithUserInfo(
+ native_node, mac_notification, user_info);
+ return;
+ }
break;
+ }
+ case ui::AX_EVENT_CHECKED_STATE_CHANGED:
case ui::AX_EVENT_VALUE_CHANGED:
- event_id = NSAccessibilityValueChangedNotification;
+ mac_notification = NSAccessibilityValueChangedNotification;
+ break;
+ // TODO(nektar): Need to add an event for live region created.
+ case ui::AX_EVENT_LIVE_REGION_CHANGED:
+ mac_notification = NSAccessibilityLiveRegionChangedNotification;
+ break;
+ case ui::AX_EVENT_ROW_COUNT_CHANGED:
+ mac_notification = NSAccessibilityRowCountChangedNotification;
+ break;
+ case ui::AX_EVENT_ROW_EXPANDED:
+ mac_notification = NSAccessibilityRowExpandedNotification;
break;
+ case ui::AX_EVENT_ROW_COLLAPSED:
+ mac_notification = NSAccessibilityRowCollapsedNotification;
+ break;
+ // TODO(nektar): Add events for busy and expanded changed.
+ // TODO(nektar): Support menu open/close notifications.
+ case ui::AX_EVENT_MENU_LIST_ITEM_SELECTED:
+ mac_notification = NSAccessibilityMenuItemSelectedNotification;
+ break;
+
+ // These events are not used on Mac for now.
+ case ui::AX_EVENT_ALERT:
+ case ui::AX_EVENT_TEXT_CHANGED:
+ case ui::AX_EVENT_CHILDREN_CHANGED:
+ case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED:
+ case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
+ case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
case ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED:
- // Not used on Mac.
- return;
- case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
- // Not used on Mac.
- return;
- case ui::AX_EVENT_INVALID_STATUS_CHANGED:
- // Not used on Mac.
- return;
case ui::AX_EVENT_LOCATION_CHANGED:
- // Not used on Mac.
- return;
- case ui::AX_EVENT_MENU_LIST_ITEM_SELECTED:
- // Not used on Mac.
return;
- case ui::AX_EVENT_TEXT_CHANGED:
- // Not used on Mac.
+
+ // Deprecated events.
+ case ui::AX_EVENT_BLUR:
+ case ui::AX_EVENT_HIDE:
+ case ui::AX_EVENT_HOVER:
+ case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
+ case ui::AX_EVENT_SHOW:
return;
default:
- LOG(WARNING) << "Unknown accessibility event: " << event_type;
+ DLOG(WARNING) << "Unknown accessibility event: " << event_type;
return;
}
- BrowserAccessibilityCocoa* native_node = node->ToBrowserAccessibilityCocoa();
- DCHECK(native_node);
- NSAccessibilityPostNotification(native_node, event_id);
+ NSAccessibilityPostNotification(native_node, mac_notification);
}
void BrowserAccessibilityManagerMac::OnAtomicUpdateFinished(
@@ -175,7 +255,10 @@ void BrowserAccessibilityManagerMac::OnAtomicUpdateFinished(
for (size_t i = 0; i < changes.size(); ++i) {
if (changes[i].type != NODE_CREATED && changes[i].type != SUBTREE_CREATED)
continue;
- BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
+
+ const ui::AXNode* changed_node = changes[i].node;
+ DCHECK(changed_node);
+ BrowserAccessibility* obj = GetFromAXNode(changed_node);
if (obj && obj->HasStringAttribute(ui::AX_ATTR_LIVE_STATUS)) {
created_live_region = true;
break;
@@ -198,4 +281,35 @@ void BrowserAccessibilityManagerMac::OnAtomicUpdateFinished(
}
}
+// Returns an autoreleased object.
+NSDictionary* BrowserAccessibilityManagerMac::
+ GetUserInfoForSelectedTextChangedNotification() {
+ NSMutableDictionary* user_info = [[[NSMutableDictionary alloc] init]
+ autorelease];
+ [user_info setObject:[NSNumber numberWithBool:YES]
+ forKey:NSAccessibilityTextStateSyncKey];
+ [user_info setObject:[NSNumber numberWithInt:AXTextStateChangeTypeUnknown]
+ forKey:NSAccessibilityTextStateChangeTypeKey];
+ [user_info
+ setObject:[NSNumber numberWithInt:AXTextSelectionDirectionUnknown]
+ forKey:NSAccessibilityTextSelectionDirection];
+ [user_info
+ setObject:[NSNumber numberWithInt:AXTextSelectionGranularityUnknown]
+ forKey:NSAccessibilityTextSelectionGranularity];
+ [user_info setObject:[NSNumber numberWithBool:YES]
+ forKey:NSAccessibilityTextSelectionChangedFocus];
+ // TODO(nektar): Set selected text marker range.
+
+ int32_t focus_id = GetTreeData().sel_focus_object_id;
+ BrowserAccessibility* focus_object = GetFromID(focus_id);
+ if (focus_object) {
+ auto native_focus_object = focus_object->ToBrowserAccessibilityCocoa();
+ if (native_focus_object)
+ [user_info setObject:native_focus_object
+ forKey:NSAccessibilityTextChangeElement];
+ }
+
+ return user_info;
+}
+
} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
index ca5b28501ed..c3a059652df 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#if defined(OS_WIN)
@@ -41,7 +45,7 @@ class CountedBrowserAccessibility : public BrowserAccessibility {
// http://crbug.com/235508
// TODO(dmazzoni): Fix this properly.
static const size_t kDataSize = sizeof(int) + sizeof(BrowserAccessibility);
- uint8 padding_[sizeof(BrowserAccessibilityWin) - kDataSize];
+ uint8_t padding_[sizeof(BrowserAccessibilityWin) - kDataSize];
#endif
};
@@ -72,9 +76,10 @@ class TestBrowserAccessibilityDelegate
const gfx::Point& point) override {}
void AccessibilitySetScrollOffset(int acc_obj_id,
const gfx::Point& offset) override {}
- void AccessibilitySetTextSelection(int acc_obj_id,
- int start_offset,
- int end_offset) override {}
+ void AccessibilitySetSelection(int acc_anchor_obj_id,
+ int start_offset,
+ int acc_focus_obj_id,
+ int end_offset) override {}
void AccessibilitySetValue(int acc_obj_id, const base::string16& value)
override {}
bool AccessibilityViewHasFocus() const override { return false; }
@@ -632,19 +637,19 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRange) {
ui::AXNodeData static_text;
static_text.id = 2;
- static_text.SetValue("Hello, world.");
+ static_text.SetName("Hello, world.");
static_text.role = ui::AX_ROLE_STATIC_TEXT;
static_text.location = gfx::Rect(100, 100, 29, 18);
root.child_ids.push_back(2);
ui::AXNodeData inline_text1;
inline_text1.id = 3;
- inline_text1.SetValue("Hello, ");
+ inline_text1.SetName("Hello, ");
inline_text1.role = ui::AX_ROLE_INLINE_TEXT_BOX;
inline_text1.location = gfx::Rect(100, 100, 29, 9);
inline_text1.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
ui::AX_TEXT_DIRECTION_LTR);
- std::vector<int32> character_offsets1;
+ std::vector<int32_t> character_offsets1;
character_offsets1.push_back(6); // 0
character_offsets1.push_back(11); // 1
character_offsets1.push_back(16); // 2
@@ -658,12 +663,12 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRange) {
ui::AXNodeData inline_text2;
inline_text2.id = 4;
- inline_text2.SetValue("world.");
+ inline_text2.SetName("world.");
inline_text2.role = ui::AX_ROLE_INLINE_TEXT_BOX;
inline_text2.location = gfx::Rect(100, 109, 28, 9);
inline_text2.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
ui::AX_TEXT_DIRECTION_LTR);
- std::vector<int32> character_offsets2;
+ std::vector<int32_t> character_offsets2;
character_offsets2.push_back(5);
character_offsets2.push_back(10);
character_offsets2.push_back(15);
@@ -681,8 +686,10 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRange) {
new CountedBrowserAccessibilityFactory()));
BrowserAccessibility* root_accessible = manager->GetRoot();
+ ASSERT_NE(nullptr, root_accessible);
BrowserAccessibility* static_text_accessible =
root_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, static_text_accessible);
EXPECT_EQ(gfx::Rect(100, 100, 6, 9).ToString(),
static_text_accessible->GetLocalBoundsForRange(0, 1).ToString());
@@ -702,12 +709,9 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRange) {
EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(),
static_text_accessible->GetLocalBoundsForRange(0, 13).ToString());
- // Test range that's beyond the text.
- EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(),
- static_text_accessible->GetLocalBoundsForRange(-1, 999).ToString());
-
- // Test that we can call bounds for range on the parent element, too,
- // and it still works.
+ // Note that each child in the parent element is represented by a single
+ // embedded object character and not by its text.
+ // TODO(nektar): Investigate failure on Linux.
EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(),
root_accessible->GetLocalBoundsForRange(0, 13).ToString());
}
@@ -716,7 +720,7 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeBiDi) {
// In this example, we assume that the string "123abc" is rendered with
// "123" going left-to-right and "abc" going right-to-left. In other
// words, on-screen it would look like "123cba". This is possible to
- // acheive if the source string had unicode control characters
+ // achieve if the source string had unicode control characters
// to switch directions. This test doesn't worry about how, though - it just
// tests that if something like that were to occur, GetLocalBoundsForRange
// returns the correct bounds for different ranges.
@@ -727,19 +731,19 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeBiDi) {
ui::AXNodeData static_text;
static_text.id = 2;
- static_text.SetValue("123abc");
+ static_text.SetName("123abc");
static_text.role = ui::AX_ROLE_STATIC_TEXT;
static_text.location = gfx::Rect(100, 100, 60, 20);
root.child_ids.push_back(2);
ui::AXNodeData inline_text1;
inline_text1.id = 3;
- inline_text1.SetValue("123");
+ inline_text1.SetName("123");
inline_text1.role = ui::AX_ROLE_INLINE_TEXT_BOX;
inline_text1.location = gfx::Rect(100, 100, 30, 20);
inline_text1.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
ui::AX_TEXT_DIRECTION_LTR);
- std::vector<int32> character_offsets1;
+ std::vector<int32_t> character_offsets1;
character_offsets1.push_back(10); // 0
character_offsets1.push_back(20); // 1
character_offsets1.push_back(30); // 2
@@ -749,12 +753,12 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeBiDi) {
ui::AXNodeData inline_text2;
inline_text2.id = 4;
- inline_text2.SetValue("abc");
+ inline_text2.SetName("abc");
inline_text2.role = ui::AX_ROLE_INLINE_TEXT_BOX;
inline_text2.location = gfx::Rect(130, 100, 30, 20);
inline_text2.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
ui::AX_TEXT_DIRECTION_RTL);
- std::vector<int32> character_offsets2;
+ std::vector<int32_t> character_offsets2;
character_offsets2.push_back(10);
character_offsets2.push_back(20);
character_offsets2.push_back(30);
@@ -769,8 +773,10 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeBiDi) {
new CountedBrowserAccessibilityFactory()));
BrowserAccessibility* root_accessible = manager->GetRoot();
+ ASSERT_NE(nullptr, root_accessible);
BrowserAccessibility* static_text_accessible =
root_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, static_text_accessible);
EXPECT_EQ(gfx::Rect(100, 100, 60, 20).ToString(),
static_text_accessible->GetLocalBoundsForRange(0, 6).ToString());
@@ -802,19 +808,19 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeScrolledWindow) {
ui::AXNodeData static_text;
static_text.id = 2;
- static_text.SetValue("ABC");
+ static_text.SetName("ABC");
static_text.role = ui::AX_ROLE_STATIC_TEXT;
static_text.location = gfx::Rect(100, 100, 16, 9);
root.child_ids.push_back(2);
ui::AXNodeData inline_text;
inline_text.id = 3;
- inline_text.SetValue("ABC");
+ inline_text.SetName("ABC");
inline_text.role = ui::AX_ROLE_INLINE_TEXT_BOX;
inline_text.location = gfx::Rect(100, 100, 16, 9);
inline_text.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
ui::AX_TEXT_DIRECTION_LTR);
- std::vector<int32> character_offsets1;
+ std::vector<int32_t> character_offsets1;
character_offsets1.push_back(6); // 0
character_offsets1.push_back(11); // 1
character_offsets1.push_back(16); // 2
@@ -829,8 +835,10 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeScrolledWindow) {
new CountedBrowserAccessibilityFactory()));
BrowserAccessibility* root_accessible = manager->GetRoot();
+ ASSERT_NE(nullptr, root_accessible);
BrowserAccessibility* static_text_accessible =
root_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, static_text_accessible);
if (manager->UseRootScrollOffsetsWhenComputingBounds()) {
EXPECT_EQ(gfx::Rect(75, 50, 16, 9).ToString(),
@@ -841,13 +849,7 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeScrolledWindow) {
}
}
-#if defined(OS_WIN)
-#define MAYBE_BoundsForRangeOnParentElement \
- DISABLED_BoundsForRangeOnParentElement
-#else
-#define MAYBE_BoundsForRangeOnParentElement BoundsForRangeOnParentElement
-#endif
-TEST(BrowserAccessibilityManagerTest, MAYBE_BoundsForRangeOnParentElement) {
+TEST(BrowserAccessibilityManagerTest, BoundsForRangeOnParentElement) {
ui::AXNodeData root;
root.id = 1;
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
@@ -863,31 +865,32 @@ TEST(BrowserAccessibilityManagerTest, MAYBE_BoundsForRangeOnParentElement) {
ui::AXNodeData static_text1;
static_text1.id = 3;
- static_text1.SetValue("AB");
+ static_text1.SetName("AB");
static_text1.role = ui::AX_ROLE_STATIC_TEXT;
static_text1.location = gfx::Rect(100, 100, 40, 20);
static_text1.child_ids.push_back(6);
ui::AXNodeData img;
img.id = 4;
+ img.SetName("Test image");
img.role = ui::AX_ROLE_IMAGE;
img.location = gfx::Rect(140, 100, 20, 20);
ui::AXNodeData static_text2;
static_text2.id = 5;
- static_text2.SetValue("CD");
+ static_text2.SetName("CD");
static_text2.role = ui::AX_ROLE_STATIC_TEXT;
static_text2.location = gfx::Rect(160, 100, 40, 20);
static_text2.child_ids.push_back(7);
ui::AXNodeData inline_text1;
inline_text1.id = 6;
- inline_text1.SetValue("AB");
+ inline_text1.SetName("AB");
inline_text1.role = ui::AX_ROLE_INLINE_TEXT_BOX;
inline_text1.location = gfx::Rect(100, 100, 40, 20);
inline_text1.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
ui::AX_TEXT_DIRECTION_LTR);
- std::vector<int32> character_offsets1;
+ std::vector<int32_t> character_offsets1;
character_offsets1.push_back(20); // 0
character_offsets1.push_back(40); // 1
inline_text1.AddIntListAttribute(
@@ -895,12 +898,12 @@ TEST(BrowserAccessibilityManagerTest, MAYBE_BoundsForRangeOnParentElement) {
ui::AXNodeData inline_text2;
inline_text2.id = 7;
- inline_text2.SetValue("CD");
+ inline_text2.SetName("CD");
inline_text2.role = ui::AX_ROLE_INLINE_TEXT_BOX;
inline_text2.location = gfx::Rect(160, 100, 40, 20);
inline_text2.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
ui::AX_TEXT_DIRECTION_LTR);
- std::vector<int32> character_offsets2;
+ std::vector<int32_t> character_offsets2;
character_offsets2.push_back(20); // 0
character_offsets2.push_back(40); // 1
inline_text2.AddIntListAttribute(
@@ -914,27 +917,30 @@ TEST(BrowserAccessibilityManagerTest, MAYBE_BoundsForRangeOnParentElement) {
nullptr,
new CountedBrowserAccessibilityFactory()));
BrowserAccessibility* root_accessible = manager->GetRoot();
+ ASSERT_NE(nullptr, root_accessible);
+ BrowserAccessibility* div_accessible = root_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, div_accessible);
EXPECT_EQ(gfx::Rect(100, 100, 20, 20).ToString(),
- root_accessible->GetLocalBoundsForRange(0, 1).ToString());
+ div_accessible->GetLocalBoundsForRange(0, 1).ToString());
EXPECT_EQ(gfx::Rect(100, 100, 40, 20).ToString(),
- root_accessible->GetLocalBoundsForRange(0, 2).ToString());
+ div_accessible->GetLocalBoundsForRange(0, 2).ToString());
EXPECT_EQ(gfx::Rect(100, 100, 80, 20).ToString(),
- root_accessible->GetLocalBoundsForRange(0, 3).ToString());
+ div_accessible->GetLocalBoundsForRange(0, 4).ToString());
EXPECT_EQ(gfx::Rect(120, 100, 60, 20).ToString(),
- root_accessible->GetLocalBoundsForRange(1, 2).ToString());
+ div_accessible->GetLocalBoundsForRange(1, 3).ToString());
EXPECT_EQ(gfx::Rect(120, 100, 80, 20).ToString(),
- root_accessible->GetLocalBoundsForRange(1, 3).ToString());
+ div_accessible->GetLocalBoundsForRange(1, 4).ToString());
EXPECT_EQ(gfx::Rect(100, 100, 100, 20).ToString(),
- root_accessible->GetLocalBoundsForRange(0, 4).ToString());
+ div_accessible->GetLocalBoundsForRange(0, 5).ToString());
}
-TEST(BrowserAccessibilityManagerTest, NextPreviousInTreeOrder) {
+TEST(BrowserAccessibilityManagerTest, TestNextPreviousInTreeOrder) {
ui::AXNodeData root;
root.id = 1;
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
@@ -962,10 +968,17 @@ TEST(BrowserAccessibilityManagerTest, NextPreviousInTreeOrder) {
new CountedBrowserAccessibilityFactory()));
auto root_accessible = manager->GetRoot();
+ ASSERT_NE(nullptr, root_accessible);
+ ASSERT_EQ(3U, root_accessible->PlatformChildCount());
auto node2_accessible = root_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, node2_accessible);
auto node3_accessible = root_accessible->PlatformGetChild(1);
+ ASSERT_NE(nullptr, node3_accessible);
+ ASSERT_EQ(1U, node3_accessible->PlatformChildCount());
auto node4_accessible = node3_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, node4_accessible);
auto node5_accessible = root_accessible->PlatformGetChild(2);
+ ASSERT_NE(nullptr, node5_accessible);
EXPECT_EQ(nullptr, manager->NextInTreeOrder(nullptr));
EXPECT_EQ(node2_accessible, manager->NextInTreeOrder(root_accessible));
@@ -981,7 +994,7 @@ TEST(BrowserAccessibilityManagerTest, NextPreviousInTreeOrder) {
EXPECT_EQ(root_accessible, manager->PreviousInTreeOrder(node2_accessible));
}
-TEST(BrowserAccessibilityManagerTest, NextPreviousTextOnlyObject) {
+TEST(BrowserAccessibilityManagerTest, TestNextPreviousTextOnlyObject) {
ui::AXNodeData root;
root.id = 1;
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
@@ -1030,14 +1043,26 @@ TEST(BrowserAccessibilityManagerTest, NextPreviousTextOnlyObject) {
new CountedBrowserAccessibilityFactory()));
auto root_accessible = manager->GetRoot();
+ ASSERT_NE(nullptr, root_accessible);
+ ASSERT_EQ(4U, root_accessible->PlatformChildCount());
auto node2_accessible = root_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, node2_accessible);
auto text1_accessible = root_accessible->PlatformGetChild(1);
+ ASSERT_NE(nullptr, text1_accessible);
auto node3_accessible = root_accessible->PlatformGetChild(2);
+ ASSERT_NE(nullptr, node3_accessible);
+ ASSERT_EQ(3U, node3_accessible->PlatformChildCount());
auto text2_accessible = node3_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, text2_accessible);
auto node4_accessible = node3_accessible->PlatformGetChild(1);
+ ASSERT_NE(nullptr, node4_accessible);
auto text3_accessible = node3_accessible->PlatformGetChild(2);
+ ASSERT_NE(nullptr, text3_accessible);
auto node5_accessible = root_accessible->PlatformGetChild(3);
+ ASSERT_NE(nullptr, node5_accessible);
+ ASSERT_EQ(1U, node5_accessible->PlatformChildCount());
auto text4_accessible = node5_accessible->PlatformGetChild(0);
+ ASSERT_NE(nullptr, text4_accessible);
EXPECT_EQ(nullptr, manager->NextTextOnlyObject(nullptr));
EXPECT_EQ(text1_accessible, manager->NextTextOnlyObject(root_accessible));
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
index d28423b70e4..4f963ebcb02 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -4,6 +4,9 @@
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
#include "base/command_line.h"
@@ -17,9 +20,13 @@
namespace content {
+// Map from unique_id_win to BrowserAccessibility
+using UniqueIDWinMap = base::hash_map<LONG, BrowserAccessibility*>;
+base::LazyInstance<UniqueIDWinMap> g_unique_id_map = LAZY_INSTANCE_INITIALIZER;
+
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory) {
return new BrowserAccessibilityManagerWin(initial_tree, delegate, factory);
@@ -31,7 +38,7 @@ BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() {
}
BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
: BrowserAccessibilityManager(delegate, factory),
@@ -43,6 +50,11 @@ BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
}
BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
+ // Destroy the tree in the subclass, rather than in the inherited
+ // destructor, otherwise our overrides of functions like
+ // OnNodeWillBeDeleted won't be called.
+ tree_.reset(NULL);
+
if (tracked_scroll_object_) {
tracked_scroll_object_->Release();
tracked_scroll_object_ = NULL;
@@ -50,7 +62,7 @@ BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
}
// static
-SimpleAXTreeUpdate
+ui::AXTreeUpdate
BrowserAccessibilityManagerWin::GetEmptyDocument() {
ui::AXNodeData empty_document;
empty_document.id = 0;
@@ -60,21 +72,23 @@ SimpleAXTreeUpdate
(1 << ui::AX_STATE_READ_ONLY) |
(1 << ui::AX_STATE_BUSY);
- SimpleAXTreeUpdate update;
+ ui::AXTreeUpdate update;
update.nodes.push_back(empty_document);
return update;
}
HWND BrowserAccessibilityManagerWin::GetParentHWND() {
- if (!delegate_)
+ BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
+ if (!delegate)
return NULL;
- return delegate_->AccessibilityGetAcceleratedWidget();
+ return delegate->AccessibilityGetAcceleratedWidget();
}
IAccessible* BrowserAccessibilityManagerWin::GetParentIAccessible() {
- if (!delegate_)
+ BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
+ if (!delegate)
return NULL;
- return delegate_->AccessibilityGetNativeViewAccessible();
+ return delegate->AccessibilityGetNativeViewAccessible();
}
void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
@@ -84,7 +98,7 @@ void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
// This line and other LOG(WARNING) lines are temporary, to debug
// flaky failures in DumpAccessibilityEvent* tests.
// http://crbug.com/440579
- LOG(WARNING) << "Not firing AX event because of no delegate";
+ DLOG(WARNING) << "Not firing AX event because of no delegate";
return;
}
@@ -93,7 +107,7 @@ void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
HWND hwnd = delegate->AccessibilityGetAcceleratedWidget();
if (!hwnd) {
- LOG(WARNING) << "Not firing AX event because of no hwnd";
+ DLOG(WARNING) << "Not firing AX event because of no hwnd";
return;
}
@@ -112,7 +126,7 @@ void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
// entering their "browse" mode.
if ((event == EVENT_OBJECT_FOCUS ||
event == IA2_EVENT_DOCUMENT_LOAD_COMPLETE) &&
- (!delegate_->AccessibilityViewHasFocus())) {
+ !NativeViewHasFocus()) {
return;
}
@@ -122,7 +136,7 @@ void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(
node == GetRoot() &&
node->PlatformChildCount() == 0 &&
!node->HasState(ui::AX_STATE_BUSY) &&
- !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) {
+ !node->manager()->GetTreeData().loaded) {
return;
}
@@ -152,7 +166,7 @@ void BrowserAccessibilityManagerWin::OnWindowFocused() {
// if they're not successful this time.
focus_event_on_root_needed_ = true;
- if (!delegate_ || !delegate_->AccessibilityViewHasFocus()) {
+ if (!NativeViewHasFocus()) {
inside_on_window_focused_ = false;
return;
}
@@ -175,7 +189,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
BrowserAccessibility* node) {
BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
if (!root_delegate || !root_delegate->AccessibilityGetAcceleratedWidget()) {
- LOG(WARNING) << "Not firing AX event because of no root_delegate or hwnd";
+ DLOG(WARNING) << "Not firing AX event because of no root_delegate or hwnd";
return;
}
@@ -195,7 +209,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
if ((event_type == ui::AX_EVENT_FOCUS ||
event_type == ui::AX_EVENT_BLUR ||
event_type == ui::AX_EVENT_LOAD_COMPLETE) &&
- !root_delegate->AccessibilityViewHasFocus()) {
+ !NativeViewHasFocus()) {
return;
}
@@ -205,7 +219,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
node == GetRoot() &&
node->PlatformChildCount() == 0 &&
!node->HasState(ui::AX_STATE_BUSY) &&
- !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) {
+ !node->manager()->GetTreeData().loaded) {
return;
}
@@ -255,9 +269,15 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
event_id = EVENT_OBJECT_SELECTIONWITHIN;
break;
- case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
+ case ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED: {
+ // Fire the event on the object where the focus of the selection is.
+ int32_t focus_id = GetTreeData().sel_focus_object_id;
+ BrowserAccessibility* focus_object = GetFromID(focus_id);
+ if (focus_object)
+ node = focus_object;
event_id = IA2_EVENT_TEXT_CARET_MOVED;
break;
+ }
default:
// Not all WebKit accessibility events result in a Windows
// accessibility notification.
@@ -290,6 +310,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXTree* tree,
ui::AXNode* node) {
+ DCHECK(node);
BrowserAccessibilityManager::OnNodeCreated(tree, node);
BrowserAccessibility* obj = GetFromAXNode(node);
if (!obj)
@@ -297,26 +318,25 @@ void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXTree* tree,
if (!obj->IsNative())
return;
LONG unique_id_win = obj->ToBrowserAccessibilityWin()->unique_id_win();
- unique_id_to_ax_id_map_[unique_id_win] = obj->GetId();
- unique_id_to_ax_tree_id_map_[unique_id_win] = ax_tree_id_;
+ g_unique_id_map.Get()[unique_id_win] = obj;
}
void BrowserAccessibilityManagerWin::OnNodeWillBeDeleted(ui::AXTree* tree,
ui::AXNode* node) {
- BrowserAccessibilityManager::OnNodeWillBeDeleted(tree, node);
+ DCHECK(node);
BrowserAccessibility* obj = GetFromAXNode(node);
- if (!obj)
- return;
- if (!obj->IsNative())
- return;
- unique_id_to_ax_id_map_.erase(
- obj->ToBrowserAccessibilityWin()->unique_id_win());
- unique_id_to_ax_tree_id_map_.erase(
- obj->ToBrowserAccessibilityWin()->unique_id_win());
- if (obj == tracked_scroll_object_) {
- tracked_scroll_object_->Release();
- tracked_scroll_object_ = NULL;
+ if (obj && obj->IsNative()) {
+ g_unique_id_map.Get().erase(
+ obj->ToBrowserAccessibilityWin()->unique_id_win());
+ if (obj == tracked_scroll_object_) {
+ tracked_scroll_object_->Release();
+ tracked_scroll_object_ = NULL;
+ }
}
+
+ // Call the inherited function at the bottom, otherwise our call to
+ // |GetFromAXNode|, above, will fail!
+ BrowserAccessibilityManager::OnNodeWillBeDeleted(tree, node);
}
void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
@@ -337,7 +357,9 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
// The first step moves win_attributes_ to old_win_attributes_ and then
// recomputes all of win_attributes_ other than IAccessibleText.
for (size_t i = 0; i < changes.size(); ++i) {
- BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
+ const ui::AXNode* changed_node = changes[i].node;
+ DCHECK(changed_node);
+ BrowserAccessibility* obj = GetFromAXNode(changed_node);
if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf())
obj->ToBrowserAccessibilityWin()->UpdateStep1ComputeWinAttributes();
}
@@ -346,7 +368,9 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
// concatenation of all of its child text nodes, so it can't run until
// the text of all of the nodes was computed in the previous step.
for (size_t i = 0; i < changes.size(); ++i) {
- BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
+ const ui::AXNode* changed_node = changes[i].node;
+ DCHECK(changed_node);
+ BrowserAccessibility* obj = GetFromAXNode(changed_node);
if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf())
obj->ToBrowserAccessibilityWin()->UpdateStep2ComputeHypertext();
}
@@ -360,7 +384,9 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
// At the end, it deletes old_win_attributes_ since they're not needed
// anymore.
for (size_t i = 0; i < changes.size(); ++i) {
- BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
+ const ui::AXNode* changed_node = changes[i].node;
+ DCHECK(changed_node);
+ BrowserAccessibility* obj = GetFromAXNode(changed_node);
if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf()) {
obj->ToBrowserAccessibilityWin()->UpdateStep3FireEvents(
changes[i].type == AXTreeDelegate::SUBTREE_CREATED);
@@ -378,31 +404,11 @@ void BrowserAccessibilityManagerWin::TrackScrollingObject(
BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin(
LONG unique_id_win) {
- auto tree_iter = unique_id_to_ax_tree_id_map_.find(unique_id_win);
- if (tree_iter == unique_id_to_ax_tree_id_map_.end())
+ auto iter = g_unique_id_map.Get().find(unique_id_win);
+ if (iter == g_unique_id_map.Get().end())
return nullptr;
- int tree_id = tree_iter->second;
- if (tree_id != ax_tree_id_) {
- BrowserAccessibilityManagerWin* manager =
- BrowserAccessibilityManager::FromID(tree_id)
- ->ToBrowserAccessibilityManagerWin();
- if (!manager)
- return nullptr;
- if (manager != this)
- return manager->GetFromUniqueIdWin(unique_id_win);
- return nullptr;
- }
-
- auto iter = unique_id_to_ax_id_map_.find(unique_id_win);
- if (iter == unique_id_to_ax_id_map_.end())
- return nullptr;
-
- BrowserAccessibility* result = GetFromID(iter->second);
- if (result && result->IsNative())
- return result->ToBrowserAccessibilityWin();
-
- return nullptr;
+ return iter->second->ToBrowserAccessibilityWin();
}
} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_win.h b/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
index f1cb688b659..b9da9a12c6a 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -7,6 +7,7 @@
#include <oleacc.h>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/scoped_comptr.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -19,13 +20,13 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
: public BrowserAccessibilityManager {
public:
BrowserAccessibilityManagerWin(
- const SimpleAXTreeUpdate& initial_tree,
+ const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
~BrowserAccessibilityManagerWin() override;
- static SimpleAXTreeUpdate GetEmptyDocument();
+ static ui::AXTreeUpdate GetEmptyDocument();
// Get the closest containing HWND.
HWND GetParentHWND();
@@ -72,14 +73,6 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
// TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
BrowserAccessibilityWin* tracked_scroll_object_;
- // A mapping from the Windows-specific unique IDs (unique within the
- // browser process) to accessibility ids within this page.
- base::hash_map<long, int32> unique_id_to_ax_id_map_;
-
- // A mapping from the Windows-specific unique IDs (unique within the
- // browser process) to the AXTreeID that contains this unique ID.
- base::hash_map<long, AXTreeIDRegistry::AXTreeID> unique_id_to_ax_tree_id_map_;
-
// Set to true if we need to fire a focus event on the root as soon as
// possible.
bool focus_event_on_root_needed_;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc b/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc
index 31b9aebc034..8fb3442d422 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc
@@ -4,8 +4,11 @@
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
+#include <stddef.h>
+
#include "base/command_line.h"
#include "base/metrics/histogram.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_mode_helper.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
diff --git a/chromium/content/browser/accessibility/browser_accessibility_state_impl.h b/chromium/content/browser/accessibility/browser_accessibility_state_impl.h
index e3da7f7dad2..5beb762551f 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_state_impl.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -7,8 +7,8 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/common/accessibility_mode_enums.h"
#include "content/public/browser/browser_accessibility_state.h"
diff --git a/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc b/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc
index 058e3a7c148..1409b0f1ab5 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc
@@ -6,6 +6,7 @@
#include <windows.h>
#include <psapi.h>
+#include <stddef.h>
#include "base/files/file_path.h"
#include "base/macros.h"
diff --git a/chromium/content/browser/accessibility/browser_accessibility_win.cc b/chromium/content/browser/accessibility/browser_accessibility_win.cc
index 40f0a1f2428..54165ed7323 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_win.cc
@@ -207,6 +207,11 @@ BrowserAccessibility* BrowserAccessibility::Create() {
return instance->NewReference();
}
+const BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin()
+ const {
+ return static_cast<const BrowserAccessibilityWin*>(this);
+}
+
BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin() {
return static_cast<BrowserAccessibilityWin*>(this);
}
@@ -318,7 +323,7 @@ STDMETHODIMP BrowserAccessibilityWin::accNavigate(LONG nav_dir,
return E_INVALIDARG;
}
- uint32 child_count = target->PlatformChildCount();
+ uint32_t child_count = target->PlatformChildCount();
BrowserAccessibility* result = NULL;
switch (nav_dir) {
@@ -451,18 +456,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accHelp(VARIANT var_id, BSTR* help) {
if (!help)
return E_INVALIDARG;
- BrowserAccessibilityWin* target = GetTargetFromChildID(var_id);
- if (!target)
- return E_INVALIDARG;
-
- base::string16 help_str = target->help();
- if (help_str.empty())
- return S_FALSE;
-
- *help = SysAllocString(help_str.c_str());
-
- DCHECK(*help);
- return S_OK;
+ return S_FALSE;
}
STDMETHODIMP BrowserAccessibilityWin::get_accKeyboardShortcut(VARIANT var_id,
@@ -493,19 +487,6 @@ STDMETHODIMP BrowserAccessibilityWin::get_accName(VARIANT var_id, BSTR* name) {
return E_INVALIDARG;
base::string16 name_str = target->name();
-
- // If the name is empty, see if it's labeled by another element.
- if (name_str.empty()) {
- int title_elem_id;
- if (target->GetIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT,
- &title_elem_id)) {
- BrowserAccessibilityWin* title_elem =
- manager()->GetFromID(title_elem_id)->ToBrowserAccessibilityWin();
- if (title_elem)
- name_str = title_elem->GetNameRecursive();
- }
- }
-
if (name_str.empty())
return S_FALSE;
@@ -845,7 +826,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_relations(
return S_OK;
}
-STDMETHODIMP BrowserAccessibilityWin::scrollTo(enum IA2ScrollType scroll_type) {
+STDMETHODIMP BrowserAccessibilityWin::scrollTo(IA2ScrollType scroll_type) {
if (!instance_active())
return E_FAIL;
@@ -886,7 +867,7 @@ STDMETHODIMP BrowserAccessibilityWin::scrollTo(enum IA2ScrollType scroll_type) {
}
STDMETHODIMP BrowserAccessibilityWin::scrollToPoint(
- enum IA2CoordinateType coordinate_type,
+ IA2CoordinateType coordinate_type,
LONG x,
LONG y) {
if (!instance_active())
@@ -1053,7 +1034,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_description(BSTR* desc) {
}
STDMETHODIMP BrowserAccessibilityWin::get_imagePosition(
- enum IA2CoordinateType coordinate_type,
+ IA2CoordinateType coordinate_type,
LONG* x,
LONG* y) {
if (!instance_active())
@@ -1125,8 +1106,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_accessibleAt(
if (row < 0 || row >= rows || column < 0 || column >= columns)
return E_INVALIDARG;
- const std::vector<int32>& cell_ids = GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
DCHECK_EQ(columns * rows, static_cast<int>(cell_ids.size()));
int cell_id = cell_ids[row * columns + column];
@@ -1174,10 +1155,10 @@ STDMETHODIMP BrowserAccessibilityWin::get_childIndex(long row,
if (row < 0 || row >= rows || column < 0 || column >= columns)
return E_INVALIDARG;
- const std::vector<int32>& cell_ids = GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
- const std::vector<int32>& unique_cell_ids = GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& unique_cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
DCHECK_EQ(columns * rows, static_cast<int>(cell_ids.size()));
int cell_id = cell_ids[row * columns + column];
for (size_t i = 0; i < unique_cell_ids.size(); ++i) {
@@ -1211,8 +1192,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnDescription(long column,
if (column < 0 || column >= columns)
return E_INVALIDARG;
- const std::vector<int32>& cell_ids = GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
for (int i = 0; i < rows; ++i) {
int cell_id = cell_ids[i * columns + column];
BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
@@ -1258,8 +1239,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnExtentAt(
if (row < 0 || row >= rows || column < 0 || column >= columns)
return E_INVALIDARG;
- const std::vector<int32>& cell_ids = GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
int cell_id = cell_ids[row * columns + column];
BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
manager()->GetFromID(cell_id));
@@ -1290,8 +1271,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnIndex(long cell_index,
if (!column_index)
return E_INVALIDARG;
- const std::vector<int32>& unique_cell_ids = GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& unique_cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
int cell_id_count = static_cast<int>(unique_cell_ids.size());
if (cell_index < 0)
return E_INVALIDARG;
@@ -1400,8 +1381,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowDescription(long row,
if (row < 0 || row >= rows)
return E_INVALIDARG;
- const std::vector<int32>& cell_ids = GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
for (int i = 0; i < columns; ++i) {
int cell_id = cell_ids[row * columns + i];
BrowserAccessibilityWin* cell =
@@ -1446,8 +1427,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowExtentAt(long row,
if (row < 0 || row >= rows || column < 0 || column >= columns)
return E_INVALIDARG;
- const std::vector<int32>& cell_ids = GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
int cell_id = cell_ids[row * columns + column];
BrowserAccessibilityWin* cell =
manager()->GetFromID(cell_id)->ToBrowserAccessibilityWin();
@@ -1478,8 +1459,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowIndex(long cell_index,
if (!row_index)
return E_INVALIDARG;
- const std::vector<int32>& unique_cell_ids = GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& unique_cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
int cell_id_count = static_cast<int>(unique_cell_ids.size());
if (cell_index < 0)
return E_INVALIDARG;
@@ -1607,8 +1588,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowColumnExtentsAtIndex(
if (!row || !column || !row_extents || !column_extents || !is_selected)
return E_INVALIDARG;
- const std::vector<int32>& unique_cell_ids = GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& unique_cell_ids =
+ GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
int cell_id_count = static_cast<int>(unique_cell_ids.size());
if (index < 0)
return E_INVALIDARG;
@@ -1770,8 +1751,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells(
if (columns <= 0 || rows <= 0 || column < 0 || column >= columns)
return S_FALSE;
- const std::vector<int32>& cell_ids = table->GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ table->GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
for (int i = 0; i < rows; ++i) {
int cell_id = cell_ids[i * columns + column];
@@ -1868,8 +1849,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells(
if (columns <= 0 || rows <= 0 || row < 0 || row >= rows)
return S_FALSE;
- const std::vector<int32>& cell_ids = table->GetIntListAttribute(
- ui::AX_ATTR_CELL_IDS);
+ const std::vector<int32_t>& cell_ids =
+ table->GetIntListAttribute(ui::AX_ATTR_CELL_IDS);
for (int i = 0; i < columns; ++i) {
int cell_id = cell_ids[row * columns + i];
@@ -1997,7 +1978,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nCharacters(LONG* n_characters) {
if (!n_characters)
return E_INVALIDARG;
- *n_characters = TextForIAccessibleText().length();
+ *n_characters = static_cast<LONG>(GetText().size());
return S_OK;
}
@@ -2008,10 +1989,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
if (!offset)
return E_INVALIDARG;
+ if (!HasCaret())
+ return S_FALSE;
+
int selection_start, selection_end;
GetSelectionOffsets(&selection_start, &selection_end);
- *offset = selection_start;
- if (selection_start < 0)
+ // The caret is always at the end of the selection.
+ *offset = selection_end;
+ if (*offset < 0)
return S_FALSE;
return S_OK;
@@ -2019,7 +2004,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
STDMETHODIMP BrowserAccessibilityWin::get_characterExtents(
LONG offset,
- enum IA2CoordinateType coordinate_type,
+ IA2CoordinateType coordinate_type,
LONG* out_x,
LONG* out_y,
LONG* out_width,
@@ -2030,7 +2015,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_characterExtents(
if (!out_x || !out_y || !out_width || !out_height)
return E_INVALIDARG;
- const base::string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = GetText();
HandleSpecialTextOffset(text_str, &offset);
if (offset < 0 || offset > static_cast<LONG>(text_str.size()))
@@ -2065,8 +2050,9 @@ STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) {
int selection_start, selection_end;
GetSelectionOffsets(&selection_start, &selection_end);
if (selection_start >= 0 && selection_end >= 0 &&
- selection_start != selection_end)
+ selection_start != selection_end) {
*n_selections = 1;
+ }
return S_OK;
}
@@ -2089,6 +2075,13 @@ STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index,
int selection_start, selection_end;
GetSelectionOffsets(&selection_start, &selection_end);
if (selection_start >= 0 && selection_end >= 0) {
+ // We should ignore the direction of the selection when exposing start and
+ // end offsets. According to the IA2 Spec the end offset is always increased
+ // by one past the end of the selection. This wouldn't make sense if
+ // end < start.
+ if (selection_end < selection_start)
+ std::swap(selection_start, selection_end);
+
*start_offset = selection_start;
*end_offset = selection_end;
}
@@ -2105,9 +2098,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset,
if (!text)
return E_INVALIDARG;
- const base::string16& text_str = TextForIAccessibleText();
-
- // Handle special text offsets.
+ const base::string16& text_str = GetText();
HandleSpecialTextOffset(text_str, &start_offset);
HandleSpecialTextOffset(text_str, &end_offset);
@@ -2128,6 +2119,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset,
base::string16 substr = text_str.substr(start_offset,
end_offset - start_offset);
+
if (substr.empty())
return S_FALSE;
@@ -2138,7 +2130,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset,
STDMETHODIMP BrowserAccessibilityWin::get_textAtOffset(
LONG offset,
- enum IA2TextBoundaryType boundary_type,
+ IA2TextBoundaryType boundary_type,
LONG* start_offset,
LONG* end_offset,
BSTR* text) {
@@ -2148,7 +2140,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAtOffset(
if (!start_offset || !end_offset || !text)
return E_INVALIDARG;
- const base::string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = GetText();
HandleSpecialTextOffset(text_str, &offset);
if (offset < 0)
return E_INVALIDARG;
@@ -2184,7 +2176,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAtOffset(
STDMETHODIMP BrowserAccessibilityWin::get_textBeforeOffset(
LONG offset,
- enum IA2TextBoundaryType boundary_type,
+ IA2TextBoundaryType boundary_type,
LONG* start_offset,
LONG* end_offset,
BSTR* text) {
@@ -2203,7 +2195,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textBeforeOffset(
return S_FALSE;
}
- const base::string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = GetText();
*start_offset = FindBoundary(
text_str, boundary_type, offset, ui::BACKWARDS_DIRECTION);
@@ -2213,7 +2205,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textBeforeOffset(
STDMETHODIMP BrowserAccessibilityWin::get_textAfterOffset(
LONG offset,
- enum IA2TextBoundaryType boundary_type,
+ IA2TextBoundaryType boundary_type,
LONG* start_offset,
LONG* end_offset,
BSTR* text) {
@@ -2232,7 +2224,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAfterOffset(
return S_FALSE;
}
- const base::string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = GetText();
*start_offset = offset;
*end_offset = FindBoundary(
@@ -2255,7 +2247,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_newText(IA2TextSegment* new_text) {
if (new_len == 0)
return E_FAIL;
- base::string16 substr = hypertext().substr(start, new_len);
+ base::string16 substr = GetText().substr(start, new_len);
new_text->text = SysAllocString(substr.c_str());
new_text->start = static_cast<long>(start);
new_text->end = static_cast<long>(start + new_len);
@@ -2288,7 +2280,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_oldText(IA2TextSegment* old_text) {
STDMETHODIMP BrowserAccessibilityWin::get_offsetAtPoint(
LONG x,
LONG y,
- enum IA2CoordinateType coord_type,
+ IA2CoordinateType coord_type,
LONG* offset) {
if (!instance_active())
return E_FAIL;
@@ -2306,7 +2298,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_offsetAtPoint(
STDMETHODIMP BrowserAccessibilityWin::scrollSubstringTo(
LONG start_index,
LONG end_index,
- enum IA2ScrollType scroll_type) {
+ IA2ScrollType scroll_type) {
// TODO(dmazzoni): adjust this for the start and end index, too.
return scrollTo(scroll_type);
}
@@ -2314,8 +2306,9 @@ STDMETHODIMP BrowserAccessibilityWin::scrollSubstringTo(
STDMETHODIMP BrowserAccessibilityWin::scrollSubstringToPoint(
LONG start_index,
LONG end_index,
- enum IA2CoordinateType coordinate_type,
- LONG x, LONG y) {
+ IA2CoordinateType coordinate_type,
+ LONG x,
+ LONG y) {
// TODO(dmazzoni): adjust this for the start and end index, too.
return scrollToPoint(coordinate_type, x, y);
}
@@ -2325,7 +2318,7 @@ STDMETHODIMP BrowserAccessibilityWin::addSelection(LONG start_offset,
if (!instance_active())
return E_FAIL;
- const base::string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = GetText();
HandleSpecialTextOffset(text_str, &start_offset);
HandleSpecialTextOffset(text_str, &end_offset);
@@ -2348,7 +2341,7 @@ STDMETHODIMP BrowserAccessibilityWin::setCaretOffset(LONG offset) {
if (!instance_active())
return E_FAIL;
- const base::string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = GetText();
HandleSpecialTextOffset(text_str, &offset);
manager()->SetTextSelection(*this, offset, offset);
return S_OK;
@@ -2363,7 +2356,7 @@ STDMETHODIMP BrowserAccessibilityWin::setSelection(LONG selection_index,
if (selection_index != 0)
return E_INVALIDARG;
- const base::string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = GetText();
HandleSpecialTextOffset(text_str, &start_offset);
HandleSpecialTextOffset(text_str, &end_offset);
@@ -2409,7 +2402,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlink(
return E_INVALIDARG;
}
- int32 id = hyperlinks()[index];
+ int32_t id = hyperlinks()[index];
BrowserAccessibilityWin* child =
manager()->GetFromID(id)->ToBrowserAccessibilityWin();
if (child) {
@@ -2429,17 +2422,16 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex(
if (!hyperlink_index)
return E_INVALIDARG;
- *hyperlink_index = -1;
-
- if (char_index < 0 ||
- char_index >= static_cast<long>(hypertext().size())) {
+ if (char_index < 0 || char_index >= static_cast<long>(GetText().size())) {
return E_INVALIDARG;
}
- std::map<int32, int32>::iterator it =
+ std::map<int32_t, int32_t>::iterator it =
hyperlink_offset_to_index().find(char_index);
- if (it == hyperlink_offset_to_index().end())
- return E_FAIL;
+ if (it == hyperlink_offset_to_index().end()) {
+ *hyperlink_index = -1;
+ return S_FALSE;
+ }
*hyperlink_index = it->second;
return S_OK;
@@ -2458,14 +2450,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_anchor(long index, VARIANT* anchor) {
if (index != 0 || !anchor)
return E_INVALIDARG;
- BSTR hypertext = SysAllocString(TextForIAccessibleText().c_str());
- DCHECK(hypertext);
+ BSTR ia2_hypertext = SysAllocString(GetText().c_str());
+ DCHECK(ia2_hypertext);
anchor->vt = VT_BSTR;
- anchor->bstrVal = hypertext;
+ anchor->bstrVal = ia2_hypertext;
// Returning S_FALSE is not mentioned in the IA2 Spec, but it might have been
// an oversight.
- if (!SysStringLen(hypertext))
+ if (!SysStringLen(ia2_hypertext))
return S_FALSE;
return S_OK;
@@ -2506,7 +2498,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_startIndex(long* index) {
if (!index)
return E_INVALIDARG;
- int32 hypertext_offset = 0;
+ int32_t hypertext_offset = 0;
const auto parent = GetParent();
if (parent) {
hypertext_offset =
@@ -2648,7 +2640,17 @@ STDMETHODIMP BrowserAccessibilityWin::get_URL(BSTR* url) {
if (!url)
return E_INVALIDARG;
- return GetStringAttributeAsBstr(ui::AX_ATTR_DOC_URL, url);
+ if (this != manager()->GetRoot())
+ return E_FAIL;
+
+ std::string str = manager()->GetTreeData().url;
+ if (str.empty())
+ return S_FALSE;
+
+ *url = SysAllocString(base::UTF8ToUTF16(str).c_str());
+ DCHECK(*url);
+
+ return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_title(BSTR* title) {
@@ -2658,7 +2660,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_title(BSTR* title) {
if (!title)
return E_INVALIDARG;
- return GetStringAttributeAsBstr(ui::AX_ATTR_DOC_TITLE, title);
+ std::string str = manager()->GetTreeData().title;
+ if (str.empty())
+ return S_FALSE;
+
+ *title = SysAllocString(base::UTF8ToUTF16(str).c_str());
+ DCHECK(*title);
+
+ return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_mimeType(BSTR* mime_type) {
@@ -2668,8 +2677,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_mimeType(BSTR* mime_type) {
if (!mime_type)
return E_INVALIDARG;
- return GetStringAttributeAsBstr(
- ui::AX_ATTR_DOC_MIMETYPE, mime_type);
+ std::string str = manager()->GetTreeData().mimetype;
+ if (str.empty())
+ return S_FALSE;
+
+ *mime_type = SysAllocString(base::UTF8ToUTF16(str).c_str());
+ DCHECK(*mime_type);
+
+ return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_docType(BSTR* doc_type) {
@@ -2679,8 +2694,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_docType(BSTR* doc_type) {
if (!doc_type)
return E_INVALIDARG;
- return GetStringAttributeAsBstr(
- ui::AX_ATTR_DOC_DOCTYPE, doc_type);
+ std::string str = manager()->GetTreeData().doctype;
+ if (str.empty())
+ return S_FALSE;
+
+ *doc_type = SysAllocString(base::UTF8ToUTF16(str).c_str());
+ DCHECK(*doc_type);
+
+ return S_OK;
}
STDMETHODIMP
@@ -3011,9 +3032,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_unclippedSubstringBounds(
if (!out_x || !out_y || !out_width || !out_height)
return E_INVALIDARG;
- const base::string16& text_str = TextForIAccessibleText();
- if (start_index > text_str.size() ||
- end_index > text_str.size() ||
+ unsigned int text_length = static_cast<unsigned int>(GetText().size());
+ if (start_index > text_length || end_index > text_length ||
start_index > end_index) {
return E_INVALIDARG;
}
@@ -3033,9 +3053,8 @@ STDMETHODIMP BrowserAccessibilityWin::scrollToSubstring(
if (!instance_active())
return E_FAIL;
- const base::string16& text_str = TextForIAccessibleText();
- if (start_index > text_str.size() ||
- end_index > text_str.size() ||
+ unsigned int text_length = static_cast<unsigned int>(GetText().size());
+ if (start_index > text_length || end_index > text_length ||
start_index > end_index) {
return E_INVALIDARG;
}
@@ -3071,7 +3090,10 @@ STDMETHODIMP BrowserAccessibilityWin::QueryService(REFGUID guid_service,
// 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(
+ BrowserAccessibility* node = this;
+ while (node->GetParent())
+ node = node->GetParent()->manager()->GetRoot();
+ return node->ToBrowserAccessibilityWin()->QueryInterface(
IID_IAccessible2, object);
}
@@ -3135,7 +3157,7 @@ STDMETHODIMP BrowserAccessibilityWin::GetPatternProvider(PATTERNID id,
<< " for pattern id: "
<< id;
if (id == UIA_ValuePatternId || id == UIA_TextPatternId) {
- if (IsEditableText()) {
+ if (HasState(ui::AX_STATE_EDITABLE)) {
DVLOG(1) << "Returning UIA text provider";
base::win::UIATextProvider::CreateTextProvider(
GetValueText(), true, provider);
@@ -3153,7 +3175,7 @@ STDMETHODIMP BrowserAccessibilityWin::GetPropertyValue(PROPERTYID id,
<< id;
V_VT(ret) = VT_EMPTY;
if (id == UIA_ControlTypePropertyId) {
- if (IsEditableText()) {
+ if (HasState(ui::AX_STATE_EDITABLE)) {
V_VT(ret) = VT_I4;
ret->lVal = UIA_EditControlTypeId;
DVLOG(1) << "Returning Edit control type";
@@ -3165,7 +3187,7 @@ STDMETHODIMP BrowserAccessibilityWin::GetPropertyValue(PROPERTYID id,
}
STDMETHODIMP BrowserAccessibilityWin::get_ProviderOptions(
- enum ProviderOptions* ret) {
+ ProviderOptions* ret) {
return E_NOTIMPL;
}
@@ -3186,7 +3208,7 @@ HRESULT WINAPI BrowserAccessibilityWin::InternalQueryInterface(
void** object) {
BrowserAccessibilityWin* accessibility =
reinterpret_cast<BrowserAccessibilityWin*>(this_ptr);
- int32 ia_role = accessibility->ia_role();
+ int32_t ia_role = accessibility->ia_role();
if (iid == IID_IAccessibleImage) {
if (ia_role != ROLE_SYSTEM_GRAPHIC) {
*object = NULL;
@@ -3226,6 +3248,12 @@ HRESULT WINAPI BrowserAccessibilityWin::InternalQueryInterface(
this_ptr, entries, iid, object);
}
+base::string16 BrowserAccessibilityWin::GetText() const {
+ if (PlatformIsChildOfLeaf())
+ return BrowserAccessibility::GetText();
+ return win_attributes_->hypertext;
+}
+
//
// Private methods.
//
@@ -3286,8 +3314,8 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
while (table && table->GetRole() != ui::AX_ROLE_TABLE)
table = table->GetParent();
if (table) {
- const std::vector<int32>& unique_cell_ids = table->GetIntListAttribute(
- ui::AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& unique_cell_ids =
+ table->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
for (size_t i = 0; i < unique_cell_ids.size(); ++i) {
if (unique_cell_ids[i] == GetId()) {
win_attributes_->ia2_attributes.push_back(
@@ -3320,6 +3348,8 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
base::string16 aria_invalid_value;
if (GetString16Attribute(ui::AX_ATTR_ARIA_INVALID_VALUE,
&aria_invalid_value)) {
+ SanitizeStringAttributeForIA2(aria_invalid_value,
+ &aria_invalid_value);
win_attributes_->ia2_attributes.push_back(
L"invalid:" + aria_invalid_value);
} else {
@@ -3334,7 +3364,7 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
}
// Expose row or column header sort direction.
- int32 sort_direction;
+ int32_t sort_direction;
if ((ia_role() == ROLE_SYSTEM_COLUMNHEADER ||
ia_role() == ROLE_SYSTEM_ROWHEADER) &&
GetIntAttribute(ui::AX_ATTR_SORT_DIRECTION, &sort_direction)) {
@@ -3356,88 +3386,15 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
}
}
- // The calculation of the accessible name of an element has been
- // standardized in the HTML to Platform Accessibility APIs Implementation
- // Guide (http://www.w3.org/TR/html-aapi/). In order to return the
- // appropriate accessible name on Windows, we need to apply some logic
- // to the fields we get from WebKit.
- //
- // TODO(dmazzoni): move most of this logic into WebKit.
- //
- // WebKit gives us:
- //
- // name: the default name, e.g. inner text
- // title ui element: a reference to a <label> element on the same
- // page that labels this node.
- // description: accessible labels that override the default name:
- // aria-label or aria-labelledby or aria-describedby
- // help: the value of the "title" attribute
- //
- // On Windows, the logic we apply lets some fields take precedence and
- // always returns the primary name in "name" and the secondary name,
- // if any, in "description".
-
- int title_elem_id = GetIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT);
- base::string16 name = GetString16Attribute(ui::AX_ATTR_NAME);
- base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
- base::string16 help = GetString16Attribute(ui::AX_ATTR_HELP);
- base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
-
- // WebKit annoyingly puts the title in the description if there's no other
- // description, which just confuses the rest of the logic. Put it back.
- // Now "help" is always the value of the "title" attribute, if present.
- base::string16 title_attr;
- if (GetHtmlAttribute("title", &title_attr) &&
- description == title_attr &&
- help.empty()) {
- help = description;
- description.clear();
- }
-
- // Now implement the main logic: the descripion should become the name if
- // 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;
- description.clear();
- }
- if (!help.empty() && description.empty()) {
- description = help;
- help.clear();
- }
- if (!description.empty() && name.empty() && !title_elem_id) {
- name = description;
- description.clear();
- }
-
- // If it's a text field, also consider the placeholder.
- base::string16 placeholder;
- if (GetRole() == ui::AX_ROLE_TEXT_FIELD &&
- HasState(ui::AX_STATE_FOCUSABLE) &&
- GetHtmlAttribute("placeholder", &placeholder)) {
- if (name.empty() && !title_elem_id) {
- name = placeholder;
- } else if (description.empty()) {
- description = placeholder;
- }
- }
+ win_attributes_->name = GetString16Attribute(ui::AX_ATTR_NAME);
+ win_attributes_->description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
+
+ base::string16 value = GetValue();
// On Windows, the value of a document should be its url.
if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA ||
GetRole() == ui::AX_ROLE_WEB_AREA) {
- value = GetString16Attribute(ui::AX_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() &&
- (GetRole() == ui::AX_ROLE_STATIC_TEXT ||
- GetRole() == ui::AX_ROLE_LIST_MARKER ||
- IsListBoxOptionOrMenuListOption())) {
- base::string16 tmp = value;
- value = name;
- name = tmp;
+ value = base::UTF8ToUTF16(manager()->GetTreeData().url);
}
// If this doesn't have a value and is linked then set its value to the url
@@ -3445,9 +3402,6 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED))
value = GetString16Attribute(ui::AX_ATTR_URL);
- win_attributes_->name = name;
- win_attributes_->description = description;
- win_attributes_->help = help;
win_attributes_->value = value;
// Clear any old relationships between this node and other nodes.
@@ -3456,47 +3410,12 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
relations_.clear();
// Handle title UI element.
- if (title_elem_id) {
- // Add a labelled by relationship.
- CComObject<BrowserAccessibilityRelation>* relation;
- HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance(
- &relation);
- DCHECK(SUCCEEDED(hr));
- relation->AddRef();
- relation->Initialize(this, IA2_RELATION_LABELLED_BY);
- relation->AddTarget(title_elem_id);
- relations_.push_back(relation);
- }
-
- // Expose slider value.
- if (ia_role() == ROLE_SYSTEM_PROGRESSBAR ||
- ia_role() == ROLE_SYSTEM_SCROLLBAR ||
- ia_role() == ROLE_SYSTEM_SLIDER) {
- win_attributes_->ia2_attributes.push_back(L"valuetext:" + GetValueText());
- }
-
- // Expose dropeffect attribute.
- base::string16 dropEffect;
- if (GetHtmlAttribute("aria-dropeffect", &dropEffect))
- win_attributes_->ia2_attributes.push_back(L"dropeffect:" + dropEffect);
-
- // Expose grabbed attribute.
- base::string16 grabbed;
- if (GetHtmlAttribute("aria-grabbed", &grabbed))
- win_attributes_->ia2_attributes.push_back(L"grabbed:" + grabbed);
-
- // Expose datetime attribute.
- base::string16 datetime;
- if (GetRole() == ui::AX_ROLE_TIME &&
- GetHtmlAttribute("datetime", &datetime))
- win_attributes_->ia2_attributes.push_back(L"datetime:" + datetime);
-
- // Expose input-text type attribute.
- base::string16 type;
- if (GetRole() == ui::AX_ROLE_TEXT_FIELD &&
- GetHtmlAttribute("type", &type))
- win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type);
+ AddRelations(ui::AX_ATTR_CONTROLS_IDS, IA2_RELATION_CONTROLLER_FOR);
+ AddRelations(ui::AX_ATTR_DESCRIBEDBY_IDS, IA2_RELATION_DESCRIBED_BY);
+ AddRelations(ui::AX_ATTR_FLOWTO_IDS, IA2_RELATION_FLOWS_TO);
+ AddRelations(ui::AX_ATTR_LABELLEDBY_IDS, IA2_RELATION_LABELLED_BY);
+ UpdateRequiredAttributes();
// If this is a web area for a presentational iframe, give it a role of
// something other than DOCUMENT so that the fact that it's a separate doc
// is not exposed to AT.
@@ -3507,8 +3426,13 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
}
void BrowserAccessibilityWin::UpdateStep2ComputeHypertext() {
- if (!PlatformChildCount()) {
- win_attributes_->hypertext += name();
+ if (PlatformIsLeaf()) {
+ if (IsSimpleTextControl())
+ win_attributes_->hypertext = value();
+ else {
+ win_attributes_->hypertext = name();
+ }
+
return;
}
@@ -3521,12 +3445,13 @@ void BrowserAccessibilityWin::UpdateStep2ComputeHypertext() {
BrowserAccessibilityWin* child =
PlatformGetChild(i)->ToBrowserAccessibilityWin();
DCHECK(child);
+ // Similar to Firefox, we don't expose text-only objects in IA2 hypertext.
if (child->IsTextOnlyObject()) {
win_attributes_->hypertext += child->name();
} else {
- int32 char_offset = hypertext().size();
- int32 child_id = child->GetId();
- int32 index = hyperlinks().size();
+ int32_t char_offset = static_cast<int32_t>(GetText().size());
+ int32_t child_id = child->GetId();
+ int32_t index = hyperlinks().size();
win_attributes_->hyperlink_offset_to_index[char_offset] = index;
win_attributes_->hyperlinks.push_back(child_id);
win_attributes_->hypertext += kEmbeddedCharacter;
@@ -3556,8 +3481,6 @@ void BrowserAccessibilityWin::UpdateStep3FireEvents(bool is_subtree_creation) {
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, this);
if (description() != old_win_attributes_->description)
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_DESCRIPTIONCHANGE, this);
- if (help() != old_win_attributes_->help)
- manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_HELPCHANGE, this);
if (value() != old_win_attributes_->value)
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_VALUECHANGE, this);
if (ia_state() != old_win_attributes_->ia_state)
@@ -3696,11 +3619,27 @@ HRESULT BrowserAccessibilityWin::GetStringAttributeAsBstr(
return S_OK;
}
+// Static
+void BrowserAccessibilityWin::SanitizeStringAttributeForIA2(
+ const base::string16& input,
+ base::string16* output) {
+ DCHECK(output);
+ // According to the IA2 Spec, these characters need to be escaped with a
+ // backslash: backslash, colon, comma, equals and semicolon.
+ // Note that backslash must be replaced first.
+ base::ReplaceChars(input, L"\\", L"\\\\", output);
+ base::ReplaceChars(*output, L":", L"\\:", output);
+ base::ReplaceChars(*output, L",", L"\\,", output);
+ base::ReplaceChars(*output, L"=", L"\\=", output);
+ base::ReplaceChars(*output, L";", L"\\;", output);
+}
+
void BrowserAccessibilityWin::StringAttributeToIA2(
ui::AXStringAttribute attribute,
const char* ia2_attr) {
base::string16 value;
if (GetString16Attribute(attribute, &value)) {
+ SanitizeStringAttributeForIA2(value, &value);
win_attributes_->ia2_attributes.push_back(
base::ASCIIToUTF16(ia2_attr) + L":" + value);
}
@@ -3729,7 +3668,7 @@ void BrowserAccessibilityWin::IntAttributeToIA2(
}
bool BrowserAccessibilityWin::IsHyperlink() const {
- int32 hyperlink_index = -1;
+ int32_t hyperlink_index = -1;
const auto parent = GetParent();
if (parent) {
hyperlink_index =
@@ -3741,20 +3680,22 @@ bool BrowserAccessibilityWin::IsHyperlink() const {
return false;
}
-int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild(
+int32_t BrowserAccessibilityWin::GetHyperlinkIndexFromChild(
const BrowserAccessibilityWin& child) const {
+ if (hyperlinks().empty())
+ return -1;
+
auto iterator = std::find(
hyperlinks().begin(), hyperlinks().end(), child.GetId());
if (iterator == hyperlinks().end())
return -1;
- return static_cast<int32>(iterator - hyperlinks().begin());
+ return static_cast<int32_t>(iterator - hyperlinks().begin());
}
-int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex(
- int32 hyperlink_index) const {
- auto& offsets_map = hyperlink_offset_to_index();
- for (auto& offset_index : offsets_map) {
+int32_t BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex(
+ int32_t hyperlink_index) const {
+ for (auto& offset_index : hyperlink_offset_to_index()) {
if (offset_index.second == hyperlink_index)
return offset_index.first;
}
@@ -3762,16 +3703,40 @@ int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex(
return -1;
}
-int32 BrowserAccessibilityWin::GetHypertextOffsetFromChild(
+int32_t BrowserAccessibilityWin::GetHypertextOffsetFromChild(
const BrowserAccessibilityWin& child) const {
- int32 hyperlink_index = GetHyperlinkIndexFromChild(child);
+ DCHECK(child.GetParent() == this);
+
+ // Handle the case when we are dealing with a direct text-only child.
+ // (Note that this object might be a platform leaf, e.g. an ARIA searchbox,
+ // and so |InternalChild...| functions need to be used. Also, direct text-only
+ // children should not be present at tree roots and so no cross-tree traversal
+ // is necessary.)
+ if (child.IsTextOnlyObject()) {
+ int32_t hypertextOffset = 0;
+ int32_t index_in_parent = child.GetIndexInParent();
+ DCHECK_GE(index_in_parent, 0);
+ DCHECK_LT(index_in_parent, static_cast<int32_t>(InternalChildCount()));
+ for (uint32_t i = 0; i < static_cast<uint32_t>(index_in_parent); ++i) {
+ const BrowserAccessibilityWin* sibling =
+ InternalGetChild(i)->ToBrowserAccessibilityWin();
+ DCHECK(sibling);
+ if (sibling->IsTextOnlyObject())
+ hypertextOffset += sibling->GetText().size();
+ else
+ ++hypertextOffset;
+ }
+ return hypertextOffset;
+ }
+
+ int32_t hyperlink_index = GetHyperlinkIndexFromChild(child);
if (hyperlink_index < 0)
return -1;
return GetHypertextOffsetFromHyperlinkIndex(hyperlink_index);
}
-int32 BrowserAccessibilityWin::GetHypertextOffsetFromDescendant(
+int32_t BrowserAccessibilityWin::GetHypertextOffsetFromDescendant(
const BrowserAccessibilityWin& descendant) const {
auto parent_object = descendant.GetParent()->ToBrowserAccessibilityWin();
auto current_object = const_cast<BrowserAccessibilityWin*>(&descendant);
@@ -3785,70 +3750,105 @@ int32 BrowserAccessibilityWin::GetHypertextOffsetFromDescendant(
return parent_object->GetHypertextOffsetFromChild(*current_object);
}
-int BrowserAccessibilityWin::GetSelectionAnchor() const {
- BrowserAccessibility* root = manager()->GetRoot();
- int32 anchor_id;
- if (!root || !root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, &anchor_id))
- return -1;
+int BrowserAccessibilityWin::GetHypertextOffsetFromEndpoint(
+ const BrowserAccessibilityWin& endpoint_object,
+ int endpoint_offset) const {
+ // There are three cases:
+ // 1. Either the selection endpoint is inside this object or is an ancestor of
+ // of this object. endpoint_offset should be returned.
+ // 2. The selection endpoint is a pure descendant of this object. The offset
+ // of the character corresponding to the subtree in which the endpoint is
+ // located should be returned.
+ // 3. The selection endpoint is in a completely different part of the tree.
+ // Either 0 or text_length should be returned depending on the direction that
+ // one needs to travel to find the endpoint.
+
+ // Case 1.
+ //
+ // IsDescendantOf includes the case when endpoint_object == this.
+ if (IsDescendantOf(&endpoint_object))
+ return endpoint_offset;
- BrowserAccessibilityWin* anchor_object = manager()->GetFromID(
- anchor_id)->ToBrowserAccessibilityWin();
- if (!anchor_object)
+ const BrowserAccessibility* common_parent = this;
+ int32_t index_in_common_parent = GetIndexInParent();
+ while (common_parent && !endpoint_object.IsDescendantOf(common_parent)) {
+ index_in_common_parent = common_parent->GetIndexInParent();
+ common_parent = common_parent->GetParent();
+ }
+ if (!common_parent)
return -1;
- // Includes the case when anchor_object == this.
- if (IsDescendantOf(anchor_object) ||
- // Text only objects that are direct descendants should behave as if they
- // are part of this object when computing hypertext.
- (anchor_object->GetParent() == this &&
- anchor_object->IsTextOnlyObject())) {
- int anchor_offset;
- if (!root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, &anchor_offset))
- return -1;
+ DCHECK_GE(index_in_common_parent, 0);
+ DCHECK(!(common_parent->IsTextOnlyObject()));
- return anchor_offset;
+ // Case 2.
+ //
+ // We already checked in case 1 if our endpoint is inside this object.
+ // We can safely assume that it is a descendant or in a completely different
+ // part of the tree.
+ if (common_parent == this) {
+ int32_t hypertext_offset =
+ GetHypertextOffsetFromDescendant(endpoint_object);
+ if (endpoint_object.GetParent() == this &&
+ endpoint_object.IsTextOnlyObject()) {
+ hypertext_offset += endpoint_offset;
+ }
+
+ return hypertext_offset;
+ }
+
+ // Case 3.
+ //
+ // We can safely assume that the endpoint is in another part of the tree or
+ // at common parent, and that this object is a descendant of common parent.
+ int32_t endpoint_index_in_common_parent = -1;
+ for (uint32_t i = 0; i < common_parent->InternalChildCount(); ++i) {
+ const BrowserAccessibility* child = common_parent->InternalGetChild(i);
+ DCHECK(child);
+ if (endpoint_object.IsDescendantOf(child)) {
+ endpoint_index_in_common_parent = child->GetIndexInParent();
+ break;
+ }
}
+ DCHECK_GE(endpoint_index_in_common_parent, 0);
- if (anchor_object->IsDescendantOf(this))
- return GetHypertextOffsetFromDescendant(*anchor_object);
+ if (endpoint_index_in_common_parent < index_in_common_parent)
+ return 0;
+ if (endpoint_index_in_common_parent > index_in_common_parent)
+ return GetText().size();
+ NOTREACHED();
return -1;
}
-int BrowserAccessibilityWin::GetSelectionFocus() const {
- BrowserAccessibility* root = manager()->GetRoot();
- int32 focus_id;
- if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id))
+int BrowserAccessibilityWin::GetSelectionAnchor() const {
+ int32_t anchor_id = manager()->GetTreeData().sel_anchor_object_id;
+ const auto anchor_object =
+ manager()->GetFromID(anchor_id)->ToBrowserAccessibilityWin();
+ if (!anchor_object)
return -1;
- BrowserAccessibilityWin* focus_object = manager()->GetFromID(
- focus_id)->ToBrowserAccessibilityWin();
+ int anchor_offset = manager()->GetTreeData().sel_anchor_offset;
+ return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset);
+}
+
+int BrowserAccessibilityWin::GetSelectionFocus() const {
+ int32_t focus_id = manager()->GetTreeData().sel_focus_object_id;
+ const auto focus_object =
+ manager()->GetFromID(focus_id)->ToBrowserAccessibilityWin();
if (!focus_object)
return -1;
- // Includes the case when focus_object == this.
- if (IsDescendantOf(focus_object) ||
- // Text only objects that are direct descendants should behave as if they
- // are part of this object when computing hypertext.
- (focus_object->GetParent() == this && focus_object->IsTextOnlyObject())) {
- int focus_offset;
- if (!root->GetIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, &focus_offset))
- return -1;
-
- return focus_offset;
- }
-
- if (focus_object->IsDescendantOf(this))
- return GetHypertextOffsetFromDescendant(*focus_object);
-
- return -1;
+ int focus_offset = manager()->GetTreeData().sel_focus_offset;
+ return GetHypertextOffsetFromEndpoint(*focus_object, focus_offset);
}
void BrowserAccessibilityWin::GetSelectionOffsets(
int* selection_start, int* selection_end) const {
DCHECK(selection_start && selection_end);
- if (IsEditableText() && !HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
+ if (HasState(ui::AX_STATE_EDITABLE) &&
+ !HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, selection_start) &&
GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, selection_end)) {
return;
@@ -3859,28 +3859,51 @@ void BrowserAccessibilityWin::GetSelectionOffsets(
if (*selection_start < 0 || *selection_end < 0)
return;
- if (*selection_end < *selection_start)
- std::swap(*selection_start, *selection_end);
-
- // IA2 Spec says that the end of the selection should be after the last
- // embedded object character that is part of the selection, if there is one.
- if (hyperlink_offset_to_index().find(*selection_end) !=
- hyperlink_offset_to_index().end()) {
- ++(*selection_end);
+ // There are three cases when a selection would start and end on the same
+ // character:
+ // 1. Anchor and focus are both in a subtree that is to the right of this
+ // object.
+ // 2. Anchor and focus are both in a subtree that is to the left of this
+ // object.
+ // 3. Anchor and focus are in a subtree represented by a single embedded
+ // object character.
+ // Only case 3 refers to a valid selection because cases 1 and 2 fall
+ // outside this object in their entirety.
+ // Selections that span more than one character are by definition inside this
+ // object, so checking them is not necessary.
+ if (*selection_start == *selection_end && !HasCaret()) {
+ *selection_start = -1;
+ *selection_end = -1;
+ return;
}
-}
-base::string16 BrowserAccessibilityWin::GetNameRecursive() const {
- if (!name().empty()) {
- return name();
- }
+ // The IA2 Spec says that if the largest of the two offsets falls on an
+ // embedded object character and if there is a selection in that embedded
+ // object, it should be incremented by one so that it points after the
+ // embedded object character.
+ // This is a signal to AT software that the embedded object is also part of
+ // the selection.
+ int* largest_offset =
+ (*selection_start <= *selection_end) ? selection_end : selection_start;
+ auto current_object = const_cast<BrowserAccessibilityWin*>(this);
+ LONG hyperlink_index;
+ HRESULT hr =
+ current_object->get_hyperlinkIndex(*largest_offset, &hyperlink_index);
+ if (hr != S_OK)
+ return;
- base::string16 result;
- for (uint32 i = 0; i < PlatformChildCount(); ++i) {
- result += PlatformGetChild(i)->ToBrowserAccessibilityWin()->
- GetNameRecursive();
- }
- return result;
+ DCHECK_GE(hyperlink_index, 0);
+ base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink;
+ hr = current_object->get_hyperlink(hyperlink_index, hyperlink.Receive());
+ DCHECK(SUCCEEDED(hr));
+ base::win::ScopedComPtr<IAccessibleText> hyperlink_text;
+ hr = hyperlink.QueryInterface(hyperlink_text.Receive());
+ DCHECK(SUCCEEDED(hr));
+ LONG n_selections = 0;
+ hr = hyperlink_text->get_nSelections(&n_selections);
+ DCHECK(SUCCEEDED(hr));
+ if (n_selections > 0)
+ ++(*largest_offset);
}
base::string16 BrowserAccessibilityWin::GetValueText() {
@@ -3894,16 +3917,6 @@ base::string16 BrowserAccessibilityWin::GetValueText() {
return value;
}
-base::string16 BrowserAccessibilityWin::TextForIAccessibleText() {
- switch (GetRole()) {
- case ui::AX_ROLE_TEXT_FIELD:
- case ui::AX_ROLE_MENU_LIST_OPTION:
- return value();
- default:
- return hypertext();
- }
-}
-
bool BrowserAccessibilityWin::IsSameHypertextCharacter(size_t old_char_index,
size_t new_char_index) {
CHECK(old_win_attributes_);
@@ -3919,20 +3932,20 @@ bool BrowserAccessibilityWin::IsSameHypertextCharacter(size_t old_char_index,
// If it's an embedded character, they're only identical if the child id
// the hyperlink points to is the same.
- std::map<int32, int32>& old_offset_to_index =
+ std::map<int32_t, int32_t>& old_offset_to_index =
old_win_attributes_->hyperlink_offset_to_index;
- std::vector<int32>& old_hyperlinks = old_win_attributes_->hyperlinks;
- int32 old_hyperlinks_count = static_cast<int32>(old_hyperlinks.size());
- std::map<int32, int32>::iterator iter;
+ std::vector<int32_t>& old_hyperlinks = old_win_attributes_->hyperlinks;
+ int32_t old_hyperlinks_count = static_cast<int32_t>(old_hyperlinks.size());
+ std::map<int32_t, int32_t>::iterator iter;
iter = old_offset_to_index.find(old_char_index);
int old_index = (iter != old_offset_to_index.end()) ? iter->second : -1;
int old_child_id = (old_index >= 0 && old_index < old_hyperlinks_count) ?
old_hyperlinks[old_index] : -1;
- std::map<int32, int32>& new_offset_to_index =
+ std::map<int32_t, int32_t>& new_offset_to_index =
win_attributes_->hyperlink_offset_to_index;
- std::vector<int32>& new_hyperlinks = win_attributes_->hyperlinks;
- int32 new_hyperlinks_count = static_cast<int32>(new_hyperlinks.size());
+ std::vector<int32_t>& new_hyperlinks = win_attributes_->hyperlinks;
+ int32_t new_hyperlinks_count = static_cast<int32_t>(new_hyperlinks.size());
iter = new_offset_to_index.find(new_char_index);
int new_index = (iter != new_offset_to_index.end()) ? iter->second : -1;
int new_child_id = (new_index >= 0 && new_index < new_hyperlinks_count) ?
@@ -3950,7 +3963,7 @@ void BrowserAccessibilityWin::ComputeHypertextRemovedAndInserted(
*new_len = 0;
const base::string16& old_text = old_win_attributes_->hypertext;
- const base::string16& new_text = hypertext();
+ const base::string16& new_text = GetText();
size_t common_prefix = 0;
while (common_prefix < old_text.size() &&
@@ -4009,19 +4022,17 @@ LONG BrowserAccessibilityWin::FindBoundary(
LONG start_offset,
ui::TextBoundaryDirection direction) {
HandleSpecialTextOffset(text, &start_offset);
- if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD &&
- GetRole() == ui::AX_ROLE_TEXT_FIELD) {
+ if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD)
return GetWordStartBoundary(static_cast<int>(start_offset), direction);
- }
ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary);
- const std::vector<int32>& line_breaks = GetIntListAttribute(
- ui::AX_ATTR_LINE_BREAKS);
+ const std::vector<int32_t>& line_breaks =
+ GetIntListAttribute(ui::AX_ATTR_LINE_BREAKS);
return ui::FindAccessibleTextBoundary(
text, line_breaks, boundary, start_offset, direction);
}
-BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32 id) {
+BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32_t id) {
return manager()->GetFromID(id)->ToBrowserAccessibilityWin();
}
@@ -4029,8 +4040,8 @@ bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() {
if (!GetParent())
return false;
- int32 role = GetRole();
- int32 parent_role = GetParent()->GetRole();
+ int32_t role = GetRole();
+ int32_t parent_role = GetParent()->GetRole();
if (role == ui::AX_ROLE_LIST_BOX_OPTION &&
parent_role == ui::AX_ROLE_LIST_BOX) {
@@ -4045,12 +4056,94 @@ bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() {
return false;
}
+void BrowserAccessibilityWin::UpdateRequiredAttributes() {
+ // Expose slider value.
+ if (ia_role() == ROLE_SYSTEM_PROGRESSBAR ||
+ ia_role() == ROLE_SYSTEM_SCROLLBAR ||
+ ia_role() == ROLE_SYSTEM_SLIDER) {
+ base::string16 value_text = GetValueText();
+ SanitizeStringAttributeForIA2(value_text, &value_text);
+ win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text);
+ }
+
+ // Expose dropeffect attribute.
+ base::string16 drop_effect;
+ if (GetHtmlAttribute("aria-dropeffect", &drop_effect)) {
+ SanitizeStringAttributeForIA2(drop_effect, &drop_effect);
+ win_attributes_->ia2_attributes.push_back(L"dropeffect:" + drop_effect);
+ }
+
+ // Expose grabbed attribute.
+ base::string16 grabbed;
+ if (GetHtmlAttribute("aria-grabbed", &grabbed)) {
+ SanitizeStringAttributeForIA2(grabbed, &grabbed);
+ win_attributes_->ia2_attributes.push_back(L"grabbed:" + grabbed);
+ }
+
+ // Expose class attribute.
+ base::string16 class_attr;
+ if (GetHtmlAttribute("class", &class_attr)) {
+ SanitizeStringAttributeForIA2(class_attr, &class_attr);
+ win_attributes_->ia2_attributes.push_back(L"class:" + class_attr);
+ }
+
+ // Expose datetime attribute.
+ base::string16 datetime;
+ if (GetRole() == ui::AX_ROLE_TIME &&
+ GetHtmlAttribute("datetime", &datetime)) {
+ SanitizeStringAttributeForIA2(datetime, &datetime);
+ win_attributes_->ia2_attributes.push_back(L"datetime:" + datetime);
+ }
+
+ // Expose id attribute.
+ base::string16 id;
+ if (GetHtmlAttribute("id", &id)) {
+ SanitizeStringAttributeForIA2(id, &id);
+ win_attributes_->ia2_attributes.push_back(L"id:" + id);
+ }
+
+ // Expose src attribute.
+ base::string16 src;
+ if (GetRole() == ui::AX_ROLE_IMAGE && GetHtmlAttribute("src", &src)) {
+ SanitizeStringAttributeForIA2(src, &src);
+ win_attributes_->ia2_attributes.push_back(L"src:" + src);
+ }
+
+ // Expose input-text type attribute.
+ base::string16 type;
+ base::string16 html_tag = GetString16Attribute(ui::AX_ATTR_HTML_TAG);
+ if (IsSimpleTextControl() && html_tag == L"input" &&
+ GetHtmlAttribute("type", &type)) {
+ SanitizeStringAttributeForIA2(type, &type);
+ win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type);
+ }
+}
+
+void BrowserAccessibilityWin::AddRelations(
+ ui::AXIntListAttribute src_attr,
+ const base::string16& iaccessiblerelation_type) {
+ if (!HasIntListAttribute(src_attr))
+ return;
+
+ const std::vector<int32_t>& ids = GetIntListAttribute(src_attr);
+ for (size_t i = 0; i < ids.size(); ++i) {
+ CComObject<BrowserAccessibilityRelation>* relation;
+ HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance(
+ &relation);
+ DCHECK(SUCCEEDED(hr));
+ relation->AddRef();
+ relation->Initialize(this, iaccessiblerelation_type);
+ relation->AddTarget(ids[i]);
+ relations_.push_back(relation);
+ }
+}
+
void BrowserAccessibilityWin::InitRoleAndState() {
- int32 ia_role = 0;
- int32 ia_state = 0;
+ int32_t ia_role = 0;
+ int32_t ia_state = 0;
base::string16 role_name;
- int32 ia2_role = 0;
- int32 ia2_state = IA2_STATE_OPAQUE;
+ int32_t ia2_role = 0;
+ int32_t ia2_state = IA2_STATE_OPAQUE;
if (HasState(ui::AX_STATE_BUSY))
ia_state |= STATE_SYSTEM_BUSY;
@@ -4064,8 +4157,6 @@ void BrowserAccessibilityWin::InitRoleAndState() {
ia_state |= STATE_SYSTEM_FOCUSABLE;
if (HasState(ui::AX_STATE_HASPOPUP))
ia_state |= STATE_SYSTEM_HASPOPUP;
- if (HasState(ui::AX_STATE_INDETERMINATE))
- ia_state |= STATE_SYSTEM_INDETERMINATE;
if (HasIntAttribute(ui::AX_ATTR_INVALID_STATE) &&
GetIntAttribute(ui::AX_ATTR_INVALID_STATE) != ui::AX_INVALID_STATE_FALSE)
ia2_state |= IA2_STATE_INVALID_ENTRY;
@@ -4111,10 +4202,10 @@ void BrowserAccessibilityWin::InitRoleAndState() {
ia_state |= STATE_SYSTEM_HOTTRACKED;
}
- if (IsEditableText())
+ if (HasState(ui::AX_STATE_EDITABLE))
ia2_state |= IA2_STATE_EDITABLE;
- if (GetBoolAttribute(ui::AX_ATTR_BUTTON_MIXED))
+ if (GetBoolAttribute(ui::AX_ATTR_STATE_MIXED))
ia_state |= STATE_SYSTEM_MIXED;
if (GetBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE))
diff --git a/chromium/content/browser/accessibility/browser_accessibility_win.h b/chromium/content/browser/accessibility/browser_accessibility_win.h
index e7acbb8416c..adeb16b494b 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_win.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_win.h
@@ -8,11 +8,15 @@
#include <atlbase.h>
#include <atlcom.h>
#include <oleacc.h>
+#include <stddef.h>
+#include <stdint.h>
#include <UIAutomationCore.h>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/common/content_export.h"
#include "third_party/iaccessible2/ia2_api_all.h"
@@ -86,8 +90,8 @@ BrowserAccessibilityWin
// Mappings from roles and states to human readable strings. Initialize
// with |InitializeStringMaps|.
- static std::map<int32, base::string16> role_string_map;
- static std::map<int32, base::string16> state_string_map;
+ static std::map<int32_t, base::string16> role_string_map;
+ static std::map<int32_t, base::string16> state_string_map;
CONTENT_EXPORT BrowserAccessibilityWin();
@@ -709,24 +713,26 @@ BrowserAccessibilityWin
REFIID iid,
void** object);
+ CONTENT_EXPORT base::string16 GetText() const override;
+
// Accessors.
- int32 ia_role() const { return win_attributes_->ia_role; }
- int32 ia_state() const { return win_attributes_->ia_state; }
+ int32_t ia_role() const { return win_attributes_->ia_role; }
+ int32_t ia_state() const { return win_attributes_->ia_state; }
const base::string16& role_name() const { return win_attributes_->role_name; }
- int32 ia2_role() const { return win_attributes_->ia2_role; }
- int32 ia2_state() const { return win_attributes_->ia2_state; }
+ int32_t ia2_role() const { return win_attributes_->ia2_role; }
+ int32_t ia2_state() const { return win_attributes_->ia2_state; }
const std::vector<base::string16>& ia2_attributes() const {
return win_attributes_->ia2_attributes;
}
base::string16 name() const { return win_attributes_->name; }
base::string16 description() const { return win_attributes_->description; }
- base::string16 help() const { return win_attributes_->help; }
base::string16 value() const { return win_attributes_->value; }
- base::string16 hypertext() const { return win_attributes_->hypertext; }
- std::map<int32, int32>& hyperlink_offset_to_index() const {
+ std::map<int32_t, int32_t>& hyperlink_offset_to_index() const {
return win_attributes_->hyperlink_offset_to_index;
}
- std::vector<int32>& hyperlinks() const { return win_attributes_->hyperlinks; }
+ std::vector<int32_t>& hyperlinks() const {
+ return win_attributes_->hyperlinks;
+ }
private:
// Add one to the reference count and return the same object. Always
@@ -752,6 +758,14 @@ BrowserAccessibilityWin
ui::AXStringAttribute attribute,
BSTR* value_bstr);
+ // Escapes characters in string attributes as required by the IA2 Spec.
+ // It's okay for input to be the same as output.
+ CONTENT_EXPORT static void SanitizeStringAttributeForIA2(
+ const base::string16& input,
+ base::string16* output);
+ FRIEND_TEST_ALL_PREFIXES(BrowserAccessibilityTest,
+ TestSanitizeStringAttributeForIA2);
+
// If the string attribute |attribute| is present, add its value as an
// IAccessible2 attribute with the name |ia2_attr|.
void StringAttributeToIA2(ui::AXStringAttribute attribute,
@@ -779,12 +793,25 @@ BrowserAccessibilityWin
// Functions for retrieving offsets for hyperlinks and hypertext.
// Return -1 in case of failure.
- int32 GetHyperlinkIndexFromChild(const BrowserAccessibilityWin& child) const;
- int32 GetHypertextOffsetFromHyperlinkIndex(int32 hyperlink_index) const;
- int32 GetHypertextOffsetFromChild(const BrowserAccessibilityWin& child) const;
- int32 GetHypertextOffsetFromDescendant(
+ int32_t GetHyperlinkIndexFromChild(
+ const BrowserAccessibilityWin& child) const;
+ int32_t GetHypertextOffsetFromHyperlinkIndex(int32_t hyperlink_index) const;
+ int32_t GetHypertextOffsetFromChild(
+ const BrowserAccessibilityWin& child) const;
+ int32_t GetHypertextOffsetFromDescendant(
const BrowserAccessibilityWin& descendant) const;
+ // If the selection endpoint is either equal to or an ancestor of this object,
+ // returns endpoint_offset.
+ // If the selection endpoint is a descendant of this object, returns its
+ // offset. Otherwise, returns either 0 or the length of the hypertext
+ // depending on the direction of the selection.
+ // Returns -1 in case of unexpected failure, e.g. the selection endpoint
+ // cannot be found in the accessibility tree.
+ int GetHypertextOffsetFromEndpoint(
+ const BrowserAccessibilityWin& endpoint_object,
+ int endpoint_offset) const;
+
//
// Selection helper functions.
//
@@ -798,20 +825,13 @@ BrowserAccessibilityWin
// selection_start and selection_end are -1 when there is no selection active
// on this object.
// The greatest of the two offsets is one past the last character of the
- // selection.
+ // selection.)
void GetSelectionOffsets(int* selection_start, int* selection_end) const;
- // Append the accessible name from this node and its children.
- base::string16 GetNameRecursive() const;
-
// Get the value text, which might come from the floating-point
// value for some roles.
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.
- base::string16 TextForIAccessibleText();
-
bool IsSameHypertextCharacter(size_t old_char_index, size_t new_char_index);
void ComputeHypertextRemovedAndInserted(
int* start, int* old_len, int* new_len);
@@ -833,12 +853,20 @@ BrowserAccessibilityWin
// Return a pointer to the object corresponding to the given id,
// does not make a new reference.
- BrowserAccessibilityWin* GetFromID(int32 id);
+ BrowserAccessibilityWin* GetFromID(int32_t id);
// Returns true if this is a list box option with a parent of type list box,
// or a menu list option with a parent of type menu list popup.
bool IsListBoxOptionOrMenuListOption();
+ // Updates object attributes of IA2 with html attributes.
+ void UpdateRequiredAttributes();
+
+ // Given an int list attribute containing the ids of related elements,
+ // add a new IAccessibleRelation for this object with the given type name.
+ void AddRelations(ui::AXIntListAttribute src_attr,
+ const base::string16& iaccessiblerelation_type);
+
// Windows-specific unique ID (unique within the browser process),
// used for get_accChild, NotifyWinEvent, and as the unique ID for
// IAccessible2 and ISimpleDOM.
@@ -849,19 +877,18 @@ BrowserAccessibilityWin
~WinAttributes();
// IAccessible role and state.
- int32 ia_role;
- int32 ia_state;
+ int32_t ia_role;
+ int32_t ia_state;
base::string16 role_name;
// IAccessible name, description, help, value.
base::string16 name;
base::string16 description;
- base::string16 help;
base::string16 value;
// IAccessible2 role and state.
- int32 ia2_role;
- int32 ia2_state;
+ int32_t ia2_role;
+ int32_t ia2_state;
// IAccessible2 attributes.
std::vector<base::string16> ia2_attributes;
@@ -871,12 +898,11 @@ BrowserAccessibilityWin
// Maps the |hypertext_| embedded character offset to an index in
// |hyperlinks_|.
- // TODO(nektar): Replace map with vector of offsets.
- std::map<int32, int32> hyperlink_offset_to_index;
+ std::map<int32_t, int32_t> hyperlink_offset_to_index;
// The id of a BrowserAccessibilityWin for each hyperlink.
// TODO(nektar): Replace object IDs with child indices.
- std::vector<int32> hyperlinks;
+ std::vector<int32_t> hyperlinks;
};
scoped_ptr<WinAttributes> win_attributes_;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
index 5c1eff4d7ba..f8d53475e9f 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
@@ -337,7 +340,7 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
text_field.id = 2;
text_field.role = ui::AX_ROLE_TEXT_FIELD;
text_field.AddStringAttribute(ui::AX_ATTR_VALUE, text_value);
- std::vector<int32> line_start_offsets;
+ std::vector<int32_t> line_start_offsets;
line_start_offsets.push_back(15);
text_field.AddIntListAttribute(
ui::AX_ATTR_LINE_BREAKS, line_start_offsets);
@@ -348,14 +351,14 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
ui::AXNodeData static_text1;
static_text1.id = 3;
static_text1.role = ui::AX_ROLE_STATIC_TEXT;
- static_text1.AddStringAttribute(ui::AX_ATTR_VALUE, line1);
+ static_text1.AddStringAttribute(ui::AX_ATTR_NAME, line1);
static_text1.child_ids.push_back(4);
ui::AXNodeData inline_box1;
inline_box1.id = 4;
inline_box1.role = ui::AX_ROLE_INLINE_TEXT_BOX;
- inline_box1.AddStringAttribute(ui::AX_ATTR_VALUE, line1);
- std::vector<int32> word_start_offsets1;
+ inline_box1.AddStringAttribute(ui::AX_ATTR_NAME, line1);
+ std::vector<int32_t> word_start_offsets1;
word_start_offsets1.push_back(0);
word_start_offsets1.push_back(4);
word_start_offsets1.push_back(8);
@@ -365,19 +368,19 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
ui::AXNodeData line_break;
line_break.id = 5;
line_break.role = ui::AX_ROLE_LINE_BREAK;
- line_break.AddStringAttribute(ui::AX_ATTR_VALUE, "\n");
+ line_break.AddStringAttribute(ui::AX_ATTR_NAME, "\n");
ui::AXNodeData static_text2;
static_text2.id = 6;
static_text2.role = ui::AX_ROLE_STATIC_TEXT;
- static_text2.AddStringAttribute(ui::AX_ATTR_VALUE, line2);
+ static_text2.AddStringAttribute(ui::AX_ATTR_NAME, line2);
static_text2.child_ids.push_back(7);
ui::AXNodeData inline_box2;
inline_box2.id = 7;
inline_box2.role = ui::AX_ROLE_INLINE_TEXT_BOX;
- inline_box2.AddStringAttribute(ui::AX_ATTR_VALUE, line2);
- std::vector<int32> word_start_offsets2;
+ inline_box2.AddStringAttribute(ui::AX_ATTR_NAME, line2);
+ std::vector<int32_t> word_start_offsets2;
word_start_offsets2.push_back(0);
word_start_offsets2.push_back(5);
word_start_offsets2.push_back(10);
@@ -395,7 +398,7 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
BrowserAccessibilityWin* root_obj =
manager->GetRoot()->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, root_obj);
- ASSERT_EQ(1, root_obj->PlatformChildCount());
+ ASSERT_EQ(1U, root_obj->PlatformChildCount());
BrowserAccessibilityWin* text_field_obj =
root_obj->PlatformGetChild(0)->ToBrowserAccessibilityWin();
@@ -484,6 +487,7 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) {
const std::string text1_name = "One two three.";
const std::string text2_name = " Four five six.";
+ const long text_name_len = text1_name.length() + text2_name.length();
ui::AXNodeData text1;
text1.id = 11;
@@ -501,164 +505,216 @@ TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) {
root.id = 1;
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
root.state = 1 << ui::AX_STATE_READ_ONLY;
- root.child_ids.push_back(11);
- root.child_ids.push_back(12);
+ root.child_ids.push_back(text1.id);
+ root.child_ids.push_back(text2.id);
CountedBrowserAccessibility::reset();
scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- MakeAXTreeUpdate(root, text1, text2),
- NULL, new CountedBrowserAccessibilityFactory()));
+ MakeAXTreeUpdate(root, text1, text2), nullptr,
+ new CountedBrowserAccessibilityFactory()));
ASSERT_EQ(3, CountedBrowserAccessibility::num_instances());
BrowserAccessibilityWin* root_obj =
manager->GetRoot()->ToBrowserAccessibilityWin();
long text_len;
- ASSERT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
+ EXPECT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
+ EXPECT_EQ(text_name_len, text_len);
base::win::ScopedBstr text;
- ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, text.Receive()));
+ EXPECT_EQ(S_OK, root_obj->get_text(0, text_name_len, text.Receive()));
EXPECT_EQ(text1_name + text2_name, base::UTF16ToUTF8(base::string16(text)));
long hyperlink_count;
- ASSERT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
+ EXPECT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
EXPECT_EQ(0, hyperlink_count);
base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink;
EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(-1, hyperlink.Receive()));
EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(0, hyperlink.Receive()));
- EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(28, hyperlink.Receive()));
- EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(29, hyperlink.Receive()));
+ EXPECT_EQ(E_INVALIDARG,
+ root_obj->get_hyperlink(text_name_len, hyperlink.Receive()));
+ EXPECT_EQ(E_INVALIDARG,
+ root_obj->get_hyperlink(text_name_len + 1, hyperlink.Receive()));
long hyperlink_index;
- EXPECT_EQ(E_FAIL, root_obj->get_hyperlinkIndex(0, &hyperlink_index));
- EXPECT_EQ(-1, hyperlink_index);
- EXPECT_EQ(E_FAIL, root_obj->get_hyperlinkIndex(28, &hyperlink_index));
+ EXPECT_EQ(S_FALSE, root_obj->get_hyperlinkIndex(0, &hyperlink_index));
EXPECT_EQ(-1, hyperlink_index);
+ // Invalid arguments should not be modified.
+ hyperlink_index = -2;
+ EXPECT_EQ(E_INVALIDARG,
+ root_obj->get_hyperlinkIndex(text_name_len, &hyperlink_index));
+ EXPECT_EQ(-2, hyperlink_index);
EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlinkIndex(-1, &hyperlink_index));
- EXPECT_EQ(-1, hyperlink_index);
- EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlinkIndex(29, &hyperlink_index));
- EXPECT_EQ(-1, hyperlink_index);
+ EXPECT_EQ(-2, hyperlink_index);
+ EXPECT_EQ(E_INVALIDARG,
+ root_obj->get_hyperlinkIndex(text_name_len + 1, &hyperlink_index));
+ EXPECT_EQ(-2, hyperlink_index);
- // Delete the manager and test that all BrowserAccessibility instances are
- // deleted.
manager.reset();
ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
- const std::string text1_name = "One two three.";
- const std::string text2_name = " Four five six.";
- const std::string button1_text_name = "red";
- const std::string link1_text_name = "blue";
+ const base::string16 text1_name = L"One two three.";
+ const base::string16 combo_box_name = L"City:";
+ const base::string16 combo_box_value = L"Happyland";
+ const base::string16 text2_name = L" Four five six.";
+ const base::string16 check_box_name = L"I agree";
+ const base::string16 check_box_value = L"Checked";
+ const base::string16 button_text_name = L"Red";
+ const base::string16 link_text_name = L"Blue";
+ // Each control (combo / check box, button and link) will be represented by an
+ // embedded object character.
+ const base::string16 embed(1, BrowserAccessibilityWin::kEmbeddedCharacter);
+ const base::string16 root_hypertext =
+ text1_name + embed + text2_name + embed + embed + embed;
+ const long root_hypertext_len = root_hypertext.length();
ui::AXNodeData text1;
text1.id = 11;
text1.role = ui::AX_ROLE_STATIC_TEXT;
text1.state = 1 << ui::AX_STATE_READ_ONLY;
- text1.SetName(text1_name);
+ text1.SetName(base::UTF16ToUTF8(text1_name));
+
+ ui::AXNodeData combo_box;
+ combo_box.id = 12;
+ combo_box.role = ui::AX_ROLE_COMBO_BOX;
+ combo_box.SetName(base::UTF16ToUTF8(combo_box_name));
+ combo_box.SetValue(base::UTF16ToUTF8(combo_box_value));
ui::AXNodeData text2;
- text2.id = 12;
+ text2.id = 13;
text2.role = ui::AX_ROLE_STATIC_TEXT;
text2.state = 1 << ui::AX_STATE_READ_ONLY;
- text2.SetName(text2_name);
-
- ui::AXNodeData button1, button1_text;
- button1.id = 13;
- button1_text.id = 15;
- button1_text.SetName(button1_text_name);
- button1.role = ui::AX_ROLE_BUTTON;
- button1_text.role = ui::AX_ROLE_STATIC_TEXT;
- button1.state = 1 << ui::AX_STATE_READ_ONLY;
- button1_text.state = 1 << ui::AX_STATE_READ_ONLY;
- button1.child_ids.push_back(15);
-
- ui::AXNodeData link1, link1_text;
- link1.id = 14;
- link1_text.id = 16;
- link1_text.SetName(link1_text_name);
- link1.role = ui::AX_ROLE_LINK;
- link1_text.role = ui::AX_ROLE_STATIC_TEXT;
- link1.state = 1 << ui::AX_STATE_READ_ONLY;
- link1_text.state = 1 << ui::AX_STATE_READ_ONLY;
- link1.child_ids.push_back(16);
+ text2.SetName(base::UTF16ToUTF8(text2_name));
+
+ ui::AXNodeData check_box;
+ check_box.id = 14;
+ check_box.role = ui::AX_ROLE_CHECK_BOX;
+ check_box.state = 1 << ui::AX_STATE_CHECKED;
+ check_box.SetName(base::UTF16ToUTF8(check_box_name));
+ check_box.SetValue(base::UTF16ToUTF8(check_box_value));
+
+ ui::AXNodeData button, button_text;
+ button.id = 15;
+ button_text.id = 17;
+ button_text.SetName(base::UTF16ToUTF8(button_text_name));
+ button.role = ui::AX_ROLE_BUTTON;
+ button_text.role = ui::AX_ROLE_STATIC_TEXT;
+ button.state = 1 << ui::AX_STATE_READ_ONLY;
+ button_text.state = 1 << ui::AX_STATE_READ_ONLY;
+ button.child_ids.push_back(button_text.id);
+
+ ui::AXNodeData link, link_text;
+ link.id = 16;
+ link_text.id = 18;
+ link_text.SetName(base::UTF16ToUTF8(link_text_name));
+ link.role = ui::AX_ROLE_LINK;
+ link_text.role = ui::AX_ROLE_STATIC_TEXT;
+ link.state = 1 << ui::AX_STATE_READ_ONLY;
+ link_text.state = 1 << ui::AX_STATE_READ_ONLY;
+ link.child_ids.push_back(link_text.id);
ui::AXNodeData root;
root.id = 1;
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
root.state = 1 << ui::AX_STATE_READ_ONLY;
- root.child_ids.push_back(11);
- root.child_ids.push_back(13);
- root.child_ids.push_back(12);
- root.child_ids.push_back(14);
+ root.child_ids.push_back(text1.id);
+ root.child_ids.push_back(combo_box.id);
+ root.child_ids.push_back(text2.id);
+ root.child_ids.push_back(check_box.id);
+ root.child_ids.push_back(button.id);
+ root.child_ids.push_back(link.id);
CountedBrowserAccessibility::reset();
scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- MakeAXTreeUpdate(root,
- text1, button1, button1_text,
- text2, link1, link1_text),
- NULL, new CountedBrowserAccessibilityFactory()));
- ASSERT_EQ(7, CountedBrowserAccessibility::num_instances());
+ MakeAXTreeUpdate(root, text1, combo_box, text2, check_box, button,
+ button_text, link, link_text),
+ nullptr, new CountedBrowserAccessibilityFactory()));
+ ASSERT_EQ(9, CountedBrowserAccessibility::num_instances());
BrowserAccessibilityWin* root_obj =
manager->GetRoot()->ToBrowserAccessibilityWin();
long text_len;
- ASSERT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
+ EXPECT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
+ EXPECT_EQ(root_hypertext_len, text_len);
base::win::ScopedBstr text;
- ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, text.Receive()));
- const std::string embed = base::UTF16ToUTF8(
- base::string16(1, BrowserAccessibilityWin::kEmbeddedCharacter));
- EXPECT_EQ(text1_name + embed + text2_name + embed,
- base::UTF16ToUTF8(base::string16(text)));
+ EXPECT_EQ(S_OK, root_obj->get_text(0, root_hypertext_len, text.Receive()));
+ EXPECT_STREQ(root_hypertext.c_str(), text);
text.Reset();
long hyperlink_count;
- ASSERT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
- EXPECT_EQ(2, hyperlink_count);
+ EXPECT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
+ EXPECT_EQ(4, hyperlink_count);
base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink;
base::win::ScopedComPtr<IAccessibleText> hypertext;
EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(-1, hyperlink.Receive()));
- EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(2, hyperlink.Receive()));
- EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(28, hyperlink.Receive()));
+ EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(4, hyperlink.Receive()));
+ // Get the text of the combo box.
+ // It should be its value.
EXPECT_EQ(S_OK, root_obj->get_hyperlink(0, hyperlink.Receive()));
+ EXPECT_EQ(S_OK, hyperlink.QueryInterface(hypertext.Receive()));
EXPECT_EQ(S_OK,
- 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(base::string16(text)).c_str());
+ hypertext->get_text(0, IA2_TEXT_OFFSET_LENGTH, text.Receive()));
+ EXPECT_STREQ(combo_box_value.c_str(), text);
text.Reset();
hyperlink.Release();
hypertext.Release();
+ // Get the text of the check box.
+ // It should be its name.
EXPECT_EQ(S_OK, root_obj->get_hyperlink(1, hyperlink.Receive()));
+ EXPECT_EQ(S_OK, hyperlink.QueryInterface(hypertext.Receive()));
+ EXPECT_EQ(S_OK,
+ hypertext->get_text(0, IA2_TEXT_OFFSET_LENGTH, text.Receive()));
+ EXPECT_STREQ(check_box_name.c_str(), text);
+ text.Reset();
+ hyperlink.Release();
+ hypertext.Release();
+
+ // Get the text of the button.
+ EXPECT_EQ(S_OK, root_obj->get_hyperlink(2, hyperlink.Receive()));
+ EXPECT_EQ(S_OK, hyperlink.QueryInterface(hypertext.Receive()));
EXPECT_EQ(S_OK,
- hyperlink.QueryInterface<IAccessibleText>(hypertext.Receive()));
+ hypertext->get_text(0, IA2_TEXT_OFFSET_LENGTH, text.Receive()));
+ EXPECT_STREQ(button_text_name.c_str(), text);
+ text.Reset();
+ hyperlink.Release();
+ hypertext.Release();
+
+ // Get the text of the link.
+ EXPECT_EQ(S_OK, root_obj->get_hyperlink(3, hyperlink.Receive()));
+ EXPECT_EQ(S_OK, hyperlink.QueryInterface(hypertext.Receive()));
EXPECT_EQ(S_OK, hypertext->get_text(0, 4, text.Receive()));
- EXPECT_STREQ(link1_text_name.c_str(),
- base::UTF16ToUTF8(base::string16(text)).c_str());
+ EXPECT_STREQ(link_text_name.c_str(), text);
text.Reset();
hyperlink.Release();
hypertext.Release();
long hyperlink_index;
- EXPECT_EQ(E_FAIL, root_obj->get_hyperlinkIndex(0, &hyperlink_index));
- EXPECT_EQ(-1, hyperlink_index);
- EXPECT_EQ(E_FAIL, root_obj->get_hyperlinkIndex(28, &hyperlink_index));
+ EXPECT_EQ(S_FALSE, root_obj->get_hyperlinkIndex(0, &hyperlink_index));
EXPECT_EQ(-1, hyperlink_index);
+ // Invalid arguments should not be modified.
+ hyperlink_index = -2;
+ EXPECT_EQ(E_INVALIDARG,
+ root_obj->get_hyperlinkIndex(root_hypertext_len, &hyperlink_index));
+ EXPECT_EQ(-2, hyperlink_index);
EXPECT_EQ(S_OK, root_obj->get_hyperlinkIndex(14, &hyperlink_index));
EXPECT_EQ(0, hyperlink_index);
EXPECT_EQ(S_OK, root_obj->get_hyperlinkIndex(30, &hyperlink_index));
EXPECT_EQ(1, hyperlink_index);
+ EXPECT_EQ(S_OK, root_obj->get_hyperlinkIndex(31, &hyperlink_index));
+ EXPECT_EQ(2, hyperlink_index);
+ EXPECT_EQ(S_OK, root_obj->get_hyperlinkIndex(32, &hyperlink_index));
+ EXPECT_EQ(3, hyperlink_index);
- // Delete the manager and test that all BrowserAccessibility instances are
- // deleted.
manager.reset();
ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
@@ -667,9 +723,9 @@ TEST_F(BrowserAccessibilityTest, TestCreateEmptyDocument) {
// Try creating an empty document with busy state. Readonly is
// set automatically.
CountedBrowserAccessibility::reset();
- const int32 busy_state = 1 << ui::AX_STATE_BUSY;
- const int32 readonly_state = 1 << ui::AX_STATE_READ_ONLY;
- const int32 enabled_state = 1 << ui::AX_STATE_ENABLED;
+ const int32_t busy_state = 1 << ui::AX_STATE_BUSY;
+ const int32_t readonly_state = 1 << ui::AX_STATE_READ_ONLY;
+ const int32_t enabled_state = 1 << ui::AX_STATE_ENABLED;
scoped_ptr<BrowserAccessibilityManager> manager(
new BrowserAccessibilityManagerWin(
BrowserAccessibilityManagerWin::GetEmptyDocument(),
@@ -770,8 +826,14 @@ TEST_F(BrowserAccessibilityTest, EmptyDocHasUniqueIdWin) {
}
TEST_F(BrowserAccessibilityTest, TestIA2Attributes) {
+ ui::AXNodeData pseudo_before;
+ pseudo_before.id = 2;
+ pseudo_before.role = ui::AX_ROLE_DIV;
+ pseudo_before.AddStringAttribute(ui::AX_ATTR_HTML_TAG, "<pseudo:before>");
+ pseudo_before.AddStringAttribute(ui::AX_ATTR_DISPLAY, "none");
+
ui::AXNodeData checkbox;
- checkbox.id = 2;
+ checkbox.id = 3;
checkbox.SetName("Checkbox");
checkbox.role = ui::AX_ROLE_CHECK_BOX;
checkbox.state = 1 << ui::AX_STATE_CHECKED;
@@ -782,38 +844,185 @@ TEST_F(BrowserAccessibilityTest, TestIA2Attributes) {
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE);
root.child_ids.push_back(2);
+ root.child_ids.push_back(3);
CountedBrowserAccessibility::reset();
scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- MakeAXTreeUpdate(root, checkbox),
- nullptr, new CountedBrowserAccessibilityFactory()));
- ASSERT_EQ(2, CountedBrowserAccessibility::num_instances());
+ MakeAXTreeUpdate(root, pseudo_before, checkbox), nullptr,
+ new CountedBrowserAccessibilityFactory()));
+ ASSERT_EQ(3, CountedBrowserAccessibility::num_instances());
ASSERT_NE(nullptr, manager->GetRoot());
BrowserAccessibilityWin* root_accessible =
manager->GetRoot()->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, root_accessible);
- ASSERT_EQ(1, root_accessible->PlatformChildCount());
- BrowserAccessibilityWin* checkbox_accessible =
- root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
- ASSERT_NE(nullptr, checkbox_accessible);
+ ASSERT_EQ(2U, root_accessible->PlatformChildCount());
+
+ BrowserAccessibilityWin* pseudo_accessible =
+ root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, pseudo_accessible);
base::win::ScopedBstr attributes;
- HRESULT hr = checkbox_accessible->get_attributes(attributes.Receive());
+ HRESULT hr = pseudo_accessible->get_attributes(attributes.Receive());
EXPECT_EQ(S_OK, hr);
EXPECT_NE(nullptr, static_cast<BSTR>(attributes));
std::wstring attributes_str(attributes, attributes.Length());
+ EXPECT_EQ(L"display:none;tag:<pseudo\\:before>;", attributes_str);
+
+ BrowserAccessibilityWin* checkbox_accessible =
+ root_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, checkbox_accessible);
+
+ attributes.Reset();
+ hr = checkbox_accessible->get_attributes(attributes.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_NE(nullptr, static_cast<BSTR>(attributes));
+ attributes_str = std::wstring(attributes, attributes.Length());
EXPECT_EQ(L"checkable:true;", attributes_str);
manager.reset();
ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
-/**
- * Ensures that ui::AX_ATTR_TEXT_SEL_START/END attributes are correctly used to
- * determine caret position and text selection in simple form fields.
- */
+TEST_F(BrowserAccessibilityTest, TestValueAttributeInTextControls) {
+ ui::AXNodeData root;
+ root.id = 1;
+ root.role = ui::AX_ROLE_ROOT_WEB_AREA;
+ root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE);
+
+ ui::AXNodeData combo_box, combo_box_text;
+ combo_box.id = 2;
+ combo_box_text.id = 3;
+ combo_box.SetName("Combo box:");
+ combo_box_text.SetName("Combo box text");
+ combo_box.role = ui::AX_ROLE_COMBO_BOX;
+ combo_box_text.role = ui::AX_ROLE_STATIC_TEXT;
+ combo_box.state = (1 << ui::AX_STATE_EDITABLE) |
+ (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_FOCUSED);
+ combo_box_text.state = 1 << ui::AX_STATE_EDITABLE;
+ combo_box.child_ids.push_back(combo_box_text.id);
+
+ ui::AXNodeData search_box, search_box_text, new_line;
+ search_box.id = 4;
+ search_box_text.id = 5;
+ new_line.id = 6;
+ search_box.SetName("Search for:");
+ search_box_text.SetName("Search box text");
+ new_line.SetName("\n");
+ search_box.role = ui::AX_ROLE_SEARCH_BOX;
+ search_box_text.role = ui::AX_ROLE_STATIC_TEXT;
+ new_line.role = ui::AX_ROLE_LINE_BREAK;
+ search_box.state = (1 << ui::AX_STATE_EDITABLE) |
+ (1 << ui::AX_STATE_FOCUSABLE) |
+ (1 << ui::AX_STATE_FOCUSED);
+ search_box_text.state = new_line.state = 1 << ui::AX_STATE_EDITABLE;
+ search_box.child_ids.push_back(search_box_text.id);
+ search_box.child_ids.push_back(new_line.id);
+
+ ui::AXNodeData text_field;
+ text_field.id = 7;
+ text_field.role = ui::AX_ROLE_TEXT_FIELD;
+ text_field.state =
+ (1 << ui::AX_STATE_EDITABLE) | (1 << ui::AX_STATE_FOCUSABLE);
+ text_field.SetValue("Text field text");
+
+ ui::AXNodeData link, link_text;
+ link.id = 8;
+ link_text.id = 9;
+ link_text.SetName("Link text");
+ link.role = ui::AX_ROLE_LINK;
+ link_text.role = ui::AX_ROLE_STATIC_TEXT;
+ link.state = link_text.state = 1 << ui::AX_STATE_READ_ONLY;
+ link.child_ids.push_back(link_text.id);
+
+ ui::AXNodeData slider, slider_text;
+ slider.id = 10;
+ slider_text.id = 11;
+ slider.AddFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, 5.0F);
+ slider_text.SetName("Slider text");
+ slider.role = ui::AX_ROLE_SLIDER;
+ slider_text.role = ui::AX_ROLE_STATIC_TEXT;
+ slider_text.state = 1 << ui::AX_STATE_READ_ONLY;
+ slider.child_ids.push_back(slider_text.id);
+
+ root.child_ids.push_back(2); // Combo box.
+ root.child_ids.push_back(4); // Search box.
+ root.child_ids.push_back(7); // Text field.
+ root.child_ids.push_back(8); // Link.
+ root.child_ids.push_back(10); // Slider.
+
+ CountedBrowserAccessibility::reset();
+ scoped_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(
+ MakeAXTreeUpdate(root, combo_box, combo_box_text, search_box,
+ search_box_text, new_line, text_field, link,
+ link_text, slider, slider_text),
+ nullptr, new CountedBrowserAccessibilityFactory()));
+ ASSERT_EQ(11, CountedBrowserAccessibility::num_instances());
+
+ ASSERT_NE(nullptr, manager->GetRoot());
+ BrowserAccessibilityWin* root_accessible =
+ manager->GetRoot()->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, root_accessible);
+ ASSERT_EQ(5U, root_accessible->PlatformChildCount());
+
+ BrowserAccessibilityWin* combo_box_accessible =
+ root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, combo_box_accessible);
+ manager->SetFocus(combo_box_accessible, false /* notify */);
+ ASSERT_EQ(combo_box_accessible,
+ manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin());
+ BrowserAccessibilityWin* search_box_accessible =
+ root_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, search_box_accessible);
+ BrowserAccessibilityWin* text_field_accessible =
+ root_accessible->PlatformGetChild(2)->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, text_field_accessible);
+ BrowserAccessibilityWin* link_accessible =
+ root_accessible->PlatformGetChild(3)->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, link_accessible);
+ BrowserAccessibilityWin* slider_accessible =
+ root_accessible->PlatformGetChild(4)->ToBrowserAccessibilityWin();
+ ASSERT_NE(nullptr, slider_accessible);
+
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ base::win::ScopedVariant childid_slider(5);
+ base::win::ScopedBstr value;
+
+ HRESULT hr =
+ combo_box_accessible->get_accValue(childid_self, value.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_STREQ(L"Combo box text", value);
+ value.Reset();
+ hr = search_box_accessible->get_accValue(childid_self, value.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_STREQ(L"Search box text\n", value);
+ value.Reset();
+ hr = text_field_accessible->get_accValue(childid_self, value.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_STREQ(L"Text field text", value);
+ value.Reset();
+
+ // Other controls, such as links, should not use their inner text as their
+ // value. Only text entry controls.
+ hr = link_accessible->get_accValue(childid_self, value.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(0u, value.Length());
+ value.Reset();
+
+ // Sliders and other range controls should expose their current value and not
+ // their inner text.
+ // Also, try accessing the slider via its child number instead of directly.
+ hr = root_accessible->get_accValue(childid_slider, value.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_STREQ(L"5", value);
+ value.Reset();
+
+ manager.reset();
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
+}
+
TEST_F(BrowserAccessibilityTest, TestCaretAndSelectionInSimpleFields) {
ui::AXNodeData root;
root.id = 1;
@@ -854,7 +1063,7 @@ TEST_F(BrowserAccessibilityTest, TestCaretAndSelectionInSimpleFields) {
BrowserAccessibilityWin* root_accessible =
manager->GetRoot()->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, root_accessible);
- ASSERT_EQ(2, root_accessible->PlatformChildCount());
+ ASSERT_EQ(2U, root_accessible->PlatformChildCount());
BrowserAccessibilityWin* combo_box_accessible =
root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
@@ -873,13 +1082,13 @@ TEST_F(BrowserAccessibilityTest, TestCaretAndSelectionInSimpleFields) {
LONG selection_end = -2;
// Test get_caretOffset.
- HRESULT hr = combo_box_accessible->get_caretOffset(&caret_offset);;
+ HRESULT hr = combo_box_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, caret_offset);
- // The caret should be at the start of the selection.
- hr = text_field_accessible->get_caretOffset(&caret_offset);;
+ // The caret should be at the end of the selection.
+ hr = text_field_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
- EXPECT_EQ(1L, caret_offset);
+ EXPECT_EQ(2L, caret_offset);
// Move the focus to the text field.
combo_box.state &= ~(1 << ui::AX_STATE_FOCUSED);
@@ -889,27 +1098,27 @@ TEST_F(BrowserAccessibilityTest, TestCaretAndSelectionInSimpleFields) {
manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin());
// The caret should not have moved.
- hr = text_field_accessible->get_caretOffset(&caret_offset);;
+ hr = text_field_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
- EXPECT_EQ(1L, caret_offset);
+ EXPECT_EQ(2L, caret_offset);
// Test get_nSelections.
- hr = combo_box_accessible->get_nSelections(&n_selections);;
+ hr = combo_box_accessible->get_nSelections(&n_selections);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(0L, n_selections);
- hr = text_field_accessible->get_nSelections(&n_selections);;
+ hr = text_field_accessible->get_nSelections(&n_selections);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, n_selections);
// Test get_selection.
hr = combo_box_accessible->get_selection(
- 0L /* selection_index */, &selection_start, &selection_end);;
+ 0L /* selection_index */, &selection_start, &selection_end);
EXPECT_EQ(E_INVALIDARG, hr); // No selections available.
// Invalid in_args should not modify out_args.
EXPECT_EQ(-2L, selection_start);
EXPECT_EQ(-2L, selection_end);
hr = text_field_accessible->get_selection(
- 0L /* selection_index */, &selection_start, &selection_end);;
+ 0L /* selection_index */, &selection_start, &selection_end);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, selection_start);
EXPECT_EQ(2L, selection_end);
@@ -950,21 +1159,25 @@ TEST_F(BrowserAccessibilityTest, TestCaretInContentEditables) {
(1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED);
link_text.SetName("here");
- // Place the caret between 'h' and 'e'.
- root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 4);
- root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1);
- root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 4);
- root.AddIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, 1);
-
root.child_ids.push_back(2);
div_editable.child_ids.push_back(3);
div_editable.child_ids.push_back(4);
link.child_ids.push_back(5);
+ ui::AXTreeUpdate update = MakeAXTreeUpdate(
+ root, div_editable, link, link_text, text);
+
+ // Place the caret between 'h' and 'e'.
+ update.has_tree_data = true;
+ update.tree_data.sel_anchor_object_id = 5;
+ update.tree_data.sel_anchor_offset = 1;
+ update.tree_data.sel_focus_object_id = 5;
+ update.tree_data.sel_focus_offset = 1;
+
CountedBrowserAccessibility::reset();
scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- MakeAXTreeUpdate(root, div_editable, link, link_text, text),
+ update,
nullptr, new CountedBrowserAccessibilityFactory()));
ASSERT_EQ(5, CountedBrowserAccessibility::num_instances());
@@ -972,18 +1185,24 @@ TEST_F(BrowserAccessibilityTest, TestCaretInContentEditables) {
BrowserAccessibilityWin* root_accessible =
manager->GetRoot()->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, root_accessible);
- ASSERT_EQ(1, root_accessible->PlatformChildCount());
+ ASSERT_EQ(1U, root_accessible->PlatformChildCount());
BrowserAccessibilityWin* div_editable_accessible =
root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, div_editable_accessible);
- ASSERT_EQ(2, div_editable_accessible->PlatformChildCount());
+ ASSERT_EQ(2U, div_editable_accessible->PlatformChildCount());
// -2 is never a valid offset.
LONG caret_offset = -2;
+ LONG n_selections = -2;
+
+ // No selection should be present.
+ HRESULT hr = div_editable_accessible->get_nSelections(&n_selections);
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(0L, n_selections);
// The caret should be on the embedded object character.
- HRESULT hr = div_editable_accessible->get_caretOffset(&caret_offset);;
+ hr = div_editable_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(6L, caret_offset);
@@ -999,21 +1218,31 @@ TEST_F(BrowserAccessibilityTest, TestCaretInContentEditables) {
BrowserAccessibilityWin* link_accessible =
div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, link_accessible);
- ASSERT_EQ(1, link_accessible->PlatformChildCount());
+ ASSERT_EQ(1U, link_accessible->PlatformChildCount());
BrowserAccessibilityWin* link_text_accessible =
link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, link_text_accessible);
// The caret should not have moved.
- hr = div_editable_accessible->get_caretOffset(&caret_offset);;
+ hr = div_editable_accessible->get_nSelections(&n_selections);
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(0L, n_selections);
+ hr = div_editable_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(6L, caret_offset);
- hr = link_accessible->get_caretOffset(&caret_offset);;
+ hr = link_accessible->get_nSelections(&n_selections);
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(0L, n_selections);
+ hr = link_text_accessible->get_nSelections(&n_selections);
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(0L, n_selections);
+
+ hr = link_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, caret_offset);
- hr = link_text_accessible->get_caretOffset(&caret_offset);;
+ hr = link_text_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, caret_offset);
@@ -1021,7 +1250,7 @@ TEST_F(BrowserAccessibilityTest, TestCaretInContentEditables) {
ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
-TEST_F(BrowserAccessibilityTest, DISABLED_TestSelectionInContentEditables) {
+TEST_F(BrowserAccessibilityTest, TestSelectionInContentEditables) {
ui::AXNodeData root;
root.id = 1;
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
@@ -1049,21 +1278,25 @@ TEST_F(BrowserAccessibilityTest, DISABLED_TestSelectionInContentEditables) {
link_text.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED);
link_text.SetName("here");
- // Select the part of the text "lick here".
- root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 3);
- root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1);
- root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 5);
- root.AddIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, 4);
-
root.child_ids.push_back(2);
div_editable.child_ids.push_back(3);
div_editable.child_ids.push_back(4);
link.child_ids.push_back(5);
+ ui::AXTreeUpdate update =
+ MakeAXTreeUpdate(root, div_editable, link, link_text, text);
+
+ // Select the following part of the text: "lick here".
+ update.has_tree_data = true;
+ update.tree_data.sel_anchor_object_id = 3;
+ update.tree_data.sel_anchor_offset = 1;
+ update.tree_data.sel_focus_object_id = 5;
+ update.tree_data.sel_focus_offset = 4;
+
CountedBrowserAccessibility::reset();
scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- MakeAXTreeUpdate(root, div_editable, link, link_text, text),
+ update,
nullptr, new CountedBrowserAccessibilityFactory()));
ASSERT_EQ(5, CountedBrowserAccessibility::num_instances());
@@ -1071,12 +1304,12 @@ TEST_F(BrowserAccessibilityTest, DISABLED_TestSelectionInContentEditables) {
BrowserAccessibilityWin* root_accessible =
manager->GetRoot()->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, root_accessible);
- ASSERT_EQ(1, root_accessible->PlatformChildCount());
+ ASSERT_EQ(1U, root_accessible->PlatformChildCount());
BrowserAccessibilityWin* div_editable_accessible =
root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, div_editable_accessible);
- ASSERT_EQ(2, div_editable_accessible->PlatformChildCount());
+ ASSERT_EQ(2U, div_editable_accessible->PlatformChildCount());
// -2 is never a valid offset.
LONG caret_offset = -2;
@@ -1090,55 +1323,55 @@ TEST_F(BrowserAccessibilityTest, DISABLED_TestSelectionInContentEditables) {
BrowserAccessibilityWin* link_accessible =
div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, link_accessible);
- ASSERT_EQ(1, link_accessible->PlatformChildCount());
+ ASSERT_EQ(1U, link_accessible->PlatformChildCount());
BrowserAccessibilityWin* link_text_accessible =
link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
ASSERT_NE(nullptr, link_text_accessible);
// get_nSelections should work on all objects.
- HRESULT hr = div_editable_accessible->get_nSelections(&n_selections);;
+ HRESULT hr = div_editable_accessible->get_nSelections(&n_selections);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, n_selections);
- hr = text_accessible->get_nSelections(&n_selections);;
+ hr = text_accessible->get_nSelections(&n_selections);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, n_selections);
- hr = link_accessible->get_nSelections(&n_selections);;
+ hr = link_accessible->get_nSelections(&n_selections);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, n_selections);
- hr = link_text_accessible->get_nSelections(&n_selections);;
+ hr = link_text_accessible->get_nSelections(&n_selections);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, n_selections);
// get_selection should be unaffected by focus placement.
hr = div_editable_accessible->get_selection(
- 0L /* selection_index */, &selection_start, &selection_end);;
+ 0L /* selection_index */, &selection_start, &selection_end);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, selection_start);
// selection_end should be after embedded object character.
EXPECT_EQ(7L, selection_end);
hr = text_accessible->get_selection(
- 0L /* selection_index */, &selection_start, &selection_end);;
+ 0L /* selection_index */, &selection_start, &selection_end);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, selection_start);
// No embedded character on this object, only the first part of the text.
EXPECT_EQ(6L, selection_end);
hr = link_accessible->get_selection(
- 0L /* selection_index */, &selection_start, &selection_end);;
+ 0L /* selection_index */, &selection_start, &selection_end);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(0L, selection_start);
EXPECT_EQ(4L, selection_end);
hr = link_text_accessible->get_selection(
- 0L /* selection_index */, &selection_start, &selection_end);;
+ 0L /* selection_index */, &selection_start, &selection_end);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(0L, selection_start);
EXPECT_EQ(4L, selection_end);
- // The caret should be at the anchor (the start) of the selection.
- hr = div_editable_accessible->get_caretOffset(&caret_offset);;
+ // The caret should be at the focus (the end) of the selection.
+ hr = div_editable_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
- EXPECT_EQ(1L, caret_offset);
+ EXPECT_EQ(7L, caret_offset);
// Move the focus to the content editable.
div_editable.state |= 1 << ui::AX_STATE_FOCUSED;
@@ -1147,20 +1380,21 @@ TEST_F(BrowserAccessibilityTest, DISABLED_TestSelectionInContentEditables) {
manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin());
// The caret should not have moved.
- hr = div_editable_accessible->get_caretOffset(&caret_offset);;
+ hr = div_editable_accessible->get_caretOffset(&caret_offset);
EXPECT_EQ(S_OK, hr);
- EXPECT_EQ(1L, caret_offset);
+ EXPECT_EQ(7L, caret_offset);
- // The HRESULT should be S_FALSE if the caret is not in the given object.
- hr = link_accessible->get_caretOffset(&caret_offset);;
- EXPECT_EQ(S_FALSE, hr);
- EXPECT_EQ(-1L, caret_offset);
- hr = link_text_accessible->get_caretOffset(&caret_offset);;
- EXPECT_EQ(S_FALSE, hr);
- EXPECT_EQ(-1L, caret_offset);
+ // The caret offset should reflect the position of the selection's focus in
+ // any given object.
+ hr = link_accessible->get_caretOffset(&caret_offset);
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(4L, caret_offset);
+ hr = link_text_accessible->get_caretOffset(&caret_offset);
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(4L, caret_offset);
hr = div_editable_accessible->get_selection(
- 0L /* selection_index */, &selection_start, &selection_end);;
+ 0L /* selection_index */, &selection_start, &selection_end);
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(1L, selection_start);
EXPECT_EQ(7L, selection_end);
@@ -1351,12 +1585,12 @@ TEST_F(BrowserAccessibilityTest, TestPlatformDeepestFirstLastChild) {
auto root_accessible = manager->GetRoot();
ASSERT_NE(nullptr, root_accessible);
- ASSERT_EQ(2, root_accessible->PlatformChildCount());
+ ASSERT_EQ(2U, root_accessible->PlatformChildCount());
auto child1_accessible = root_accessible->PlatformGetChild(0);
ASSERT_NE(nullptr, child1_accessible);
auto child2_accessible = root_accessible->PlatformGetChild(1);
ASSERT_NE(nullptr, child2_accessible);
- ASSERT_EQ(2, child2_accessible->PlatformChildCount());
+ ASSERT_EQ(2U, child2_accessible->PlatformChildCount());
auto child2_child1_accessible = child2_accessible->PlatformGetChild(0);
ASSERT_NE(nullptr, child2_child1_accessible);
auto child2_child2_accessible = child2_accessible->PlatformGetChild(1);
@@ -1377,4 +1611,73 @@ TEST_F(BrowserAccessibilityTest, TestPlatformDeepestFirstLastChild) {
EXPECT_EQ(nullptr, child2_child2_accessible->PlatformDeepestLastChild());
}
+TEST_F(BrowserAccessibilityTest, TestSanitizeStringAttributeForIA2) {
+ base::string16 input(L"\\:=,;");
+ base::string16 output;
+ BrowserAccessibilityWin::SanitizeStringAttributeForIA2(input, &output);
+ EXPECT_EQ(L"\\\\\\:\\=\\,\\;", output);
+}
+
+TEST_F(BrowserAccessibilityTest, UniqueIdWinInvalidAfterDeletingTree) {
+ ui::AXNodeData root_node;
+ root_node.id = 1;
+ root_node.role = ui::AX_ROLE_ROOT_WEB_AREA;
+
+ ui::AXNodeData child_node;
+ child_node.id = 2;
+ root_node.child_ids.push_back(2);
+
+ scoped_ptr<BrowserAccessibilityManagerWin> manager(
+ new BrowserAccessibilityManagerWin(
+ MakeAXTreeUpdate(root_node, child_node),
+ nullptr,
+ new CountedBrowserAccessibilityFactory()));
+
+ BrowserAccessibility* root = manager->GetRoot();
+ LONG root_unique_id = root->ToBrowserAccessibilityWin()->unique_id_win();
+ BrowserAccessibility* child = root->PlatformGetChild(0);
+ LONG child_unique_id = child->ToBrowserAccessibilityWin()->unique_id_win();
+
+ // Now destroy that original tree and create a new tree.
+ manager.reset(
+ new BrowserAccessibilityManagerWin(
+ MakeAXTreeUpdate(root_node, child_node),
+ nullptr,
+ new CountedBrowserAccessibilityFactory()));
+ root = manager->GetRoot();
+ LONG root_unique_id_2 = root->ToBrowserAccessibilityWin()->unique_id_win();
+ child = root->PlatformGetChild(0);
+ LONG child_unique_id_2 = child->ToBrowserAccessibilityWin()->unique_id_win();
+
+ // The nodes in the new tree should not have the same ids.
+ EXPECT_NE(root_unique_id, root_unique_id_2);
+ EXPECT_NE(child_unique_id, child_unique_id_2);
+
+ // Trying to access the unique IDs of the old, deleted objects should fail.
+ base::win::ScopedVariant old_root_variant(root_unique_id);
+ base::win::ScopedComPtr<IDispatch> old_root_dispatch;
+ HRESULT hr = root->ToBrowserAccessibilityWin()->get_accChild(
+ old_root_variant, old_root_dispatch.Receive());
+ EXPECT_EQ(E_INVALIDARG, hr);
+
+ base::win::ScopedVariant old_child_variant(child_unique_id);
+ base::win::ScopedComPtr<IDispatch> old_child_dispatch;
+ hr = root->ToBrowserAccessibilityWin()->get_accChild(
+ old_child_variant, old_child_dispatch.Receive());
+ EXPECT_EQ(E_INVALIDARG, hr);
+
+ // Trying to access the unique IDs of the new objects should succeed.
+ base::win::ScopedVariant new_root_variant(root_unique_id_2);
+ base::win::ScopedComPtr<IDispatch> new_root_dispatch;
+ hr = root->ToBrowserAccessibilityWin()->get_accChild(
+ new_root_variant, new_root_dispatch.Receive());
+ EXPECT_EQ(S_OK, hr);
+
+ base::win::ScopedVariant new_child_variant(child_unique_id_2);
+ base::win::ScopedComPtr<IDispatch> new_child_dispatch;
+ hr = root->ToBrowserAccessibilityWin()->get_accChild(
+ new_child_variant, new_child_dispatch.Receive());
+ EXPECT_EQ(S_OK, hr);
+}
+
} // namespace content
diff --git a/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
index 215a94e5f97..9866b326f99 100644
--- a/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
+++ b/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -2,10 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
@@ -144,17 +149,13 @@ IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
const ui::AXTree& tree = GetAXTree();
const ui::AXNode* root = tree.root();
+ // Check properties of thet tree.
+ EXPECT_STREQ(url_str, tree.data().url.c_str());
+ EXPECT_STREQ("Accessibility Test", tree.data().title.c_str());
+ EXPECT_STREQ("html", tree.data().doctype.c_str());
+ EXPECT_STREQ("text/html", tree.data().mimetype.c_str());
+
// Check properties of the root element of the tree.
- EXPECT_STREQ(url_str,
- GetAttr(root, ui::AX_ATTR_DOC_URL).c_str());
- EXPECT_STREQ(
- "Accessibility Test",
- GetAttr(root, ui::AX_ATTR_DOC_TITLE).c_str());
- EXPECT_STREQ(
- "html", GetAttr(root, ui::AX_ATTR_DOC_DOCTYPE).c_str());
- EXPECT_STREQ(
- "text/html",
- GetAttr(root, ui::AX_ATTR_DOC_MIMETYPE).c_str());
EXPECT_STREQ(
"Accessibility Test",
GetAttr(root, ui::AX_ATTR_NAME).c_str());
@@ -291,7 +292,7 @@ IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
EXPECT_EQ(1U, column1->data().intlist_attributes.size());
EXPECT_EQ(ui::AX_ATTR_INDIRECT_CHILD_IDS,
column1->data().intlist_attributes[0].first);
- const std::vector<int32> column1_indirect_child_ids =
+ const std::vector<int32_t> column1_indirect_child_ids =
column1->data().intlist_attributes[0].second;
EXPECT_EQ(1U, column1_indirect_child_ids.size());
EXPECT_EQ(cell1->id(), column1_indirect_child_ids[0]);
@@ -300,7 +301,7 @@ IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
EXPECT_EQ(0, column2->child_count());
EXPECT_EQ(ui::AX_ATTR_INDIRECT_CHILD_IDS,
column2->data().intlist_attributes[0].first);
- const std::vector<int32> column2_indirect_child_ids =
+ const std::vector<int32_t> column2_indirect_child_ids =
column2->data().intlist_attributes[0].second;
EXPECT_EQ(1U, column2_indirect_child_ids.size());
EXPECT_EQ(cell2->id(), column2_indirect_child_ids[0]);
@@ -445,7 +446,7 @@ IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
ASSERT_EQ(ui::AX_ATTR_CELL_IDS,
table->data().intlist_attributes[0].first);
- const std::vector<int32>& table_cell_ids =
+ const std::vector<int32_t>& table_cell_ids =
table->data().intlist_attributes[0].second;
ASSERT_EQ(6U, table_cell_ids.size());
EXPECT_EQ(cell1->id(), table_cell_ids[0]);
diff --git a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc
index 60c5af63a0c..b5dd3296ef3 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -8,18 +8,23 @@
#include <string>
#include <vector>
+#include "base/command_line.h"
#include "base/path_service.h"
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_paths.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -47,16 +52,18 @@ DumpAccessibilityTestBase::~DumpAccessibilityTestBase() {
base::string16
DumpAccessibilityTestBase::DumpUnfilteredAccessibilityTreeAsString() {
- WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
- shell()->web_contents());
- AccessibilityTreeFormatter formatter(
- web_contents->GetRootBrowserAccessibilityManager()->GetRoot());
+ scoped_ptr<AccessibilityTreeFormatter> formatter(
+ CreateAccessibilityTreeFormatter());
std::vector<Filter> filters;
filters.push_back(Filter(base::ASCIIToUTF16("*"), Filter::ALLOW));
- formatter.SetFilters(filters);
- formatter.set_show_ids(true);
+ formatter->SetFilters(filters);
+ formatter->set_show_ids(true);
+ WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
+ shell()->web_contents());
base::string16 ax_tree_dump;
- formatter.FormatAccessibilityTree(&ax_tree_dump);
+ formatter->FormatAccessibilityTree(
+ web_contents->GetRootBrowserAccessibilityManager()->GetRoot(),
+ &ax_tree_dump);
return ax_tree_dump;
}
@@ -92,12 +99,9 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
for (const std::string& line :
base::SplitString(test_html, "\n", base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL)) {
- const std::string& allow_empty_str =
- AccessibilityTreeFormatter::GetAllowEmptyString();
- const std::string& allow_str =
- AccessibilityTreeFormatter::GetAllowString();
- const std::string& deny_str =
- AccessibilityTreeFormatter::GetDenyString();
+ const std::string& allow_empty_str = formatter_->GetAllowEmptyString();
+ const std::string& allow_str = formatter_->GetAllowString();
+ const std::string& deny_str = formatter_->GetDenyString();
const std::string& wait_str = "@WAIT-FOR:";
if (base::StartsWith(line, allow_empty_str,
base::CompareCase::SENSITIVE)) {
@@ -121,8 +125,30 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
}
}
+AccessibilityTreeFormatter*
+ DumpAccessibilityTestBase::CreateAccessibilityTreeFormatter() {
+ if (is_blink_pass_)
+ return new AccessibilityTreeFormatterBlink();
+ else
+ return AccessibilityTreeFormatter::Create();
+}
+
void DumpAccessibilityTestBase::RunTest(
const base::FilePath file_path, const char* file_dir) {
+#if !defined(OS_ANDROID)
+ // The blink tree is different on Android because we exclude inline
+ // text boxes, for performance.
+ is_blink_pass_ = true;
+ RunTestForPlatform(file_path, file_dir);
+#endif
+ is_blink_pass_ = false;
+ RunTestForPlatform(file_path, file_dir);
+}
+
+void DumpAccessibilityTestBase::RunTestForPlatform(
+ const base::FilePath file_path, const char* file_dir) {
+ formatter_.reset(CreateAccessibilityTreeFormatter());
+
// Disable the "hot tracked" state (set when the mouse is hovering over
// an object) because it makes test output change based on the mouse position.
BrowserAccessibilityStateImpl::GetInstance()->
@@ -132,7 +158,9 @@ void DumpAccessibilityTestBase::RunTest(
// Output the test path to help anyone who encounters a failure and needs
// to know where to look.
- printf("Testing: %s\n", file_path.MaybeAsASCII().c_str());
+ LOG(INFO) << "Testing: " << file_path.LossyDisplayName()
+ << (is_blink_pass_ ? " (internal Blink accessibility tree)"
+ : " (native accessibility tree for this platform)");
std::string html_contents;
base::ReadFileToString(file_path, &html_contents);
@@ -140,8 +168,18 @@ void DumpAccessibilityTestBase::RunTest(
// Read the expected file.
std::string expected_contents_raw;
base::FilePath expected_file =
- base::FilePath(file_path.RemoveExtension().value() +
- AccessibilityTreeFormatter::GetExpectedFileSuffix());
+ base::FilePath(file_path.RemoveExtension().value() +
+ formatter_->GetExpectedFileSuffix());
+ if (!base::PathExists(expected_file)) {
+ LOG(INFO) << "File not found: " << expected_file.LossyDisplayName();
+ LOG(INFO) << "No expectation file present, ignoring test on this platform."
+ << " To run this test anyway, create "
+ << expected_file.LossyDisplayName()
+ << " (it can be empty) and then run content_browsertests "
+ << "with the switch: --"
+ << switches::kGenerateAccessibilityTestExpectations;
+ return;
+ }
base::ReadFileToString(expected_file, &expected_contents_raw);
// Tolerate Windows-style line endings (\r\n) in the expected file:
@@ -150,7 +188,7 @@ void DumpAccessibilityTestBase::RunTest(
base::RemoveChars(expected_contents_raw, "\r", &expected_contents);
if (!expected_contents.compare(0, strlen(kMarkSkipFile), kMarkSkipFile)) {
- printf("Skipping this test on this platform.\n");
+ LOG(INFO) << "Skipping this test on this platform.";
return;
}
@@ -211,9 +249,11 @@ void DumpAccessibilityTestBase::RunTest(
if (is_different) {
OnDiffFailed();
+ std::string diff;
+
// Mark the expected lines which did not match actual output with a *.
- printf("* Line Expected\n");
- printf("- ---- --------\n");
+ diff += "* Line Expected\n";
+ diff += "- ---- --------\n";
for (int line = 0, diff_index = 0;
line < static_cast<int>(expected_lines.size());
++line) {
@@ -223,25 +263,24 @@ void DumpAccessibilityTestBase::RunTest(
is_diff = true;
++diff_index;
}
- printf("%1s %4d %s\n", is_diff? kSignalDiff : "", line + 1,
+ diff += base::StringPrintf(
+ "%1s %4d %s\n", is_diff? kSignalDiff : "", line + 1,
expected_lines[line].c_str());
}
- printf("\nActual\n");
- printf("------\n");
- printf("%s\n", actual_contents.c_str());
- }
-
- if (!base::PathExists(expected_file)) {
- base::FilePath actual_file =
- base::FilePath(file_path.RemoveExtension().value() +
- AccessibilityTreeFormatter::GetActualFileSuffix());
-
- EXPECT_TRUE(base::WriteFile(
- actual_file, actual_contents.c_str(), actual_contents.size()));
-
- ADD_FAILURE() << "No expectation found. Create it by doing:\n"
- << "mv " << actual_file.LossyDisplayName() << " "
- << expected_file.LossyDisplayName();
+ diff += "\nActual\n";
+ diff += "------\n";
+ diff += actual_contents;
+ LOG(ERROR) << "Diff:\n" << diff;
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kGenerateAccessibilityTestExpectations)) {
+ CHECK(base::WriteFile(
+ expected_file, actual_contents.c_str(), actual_contents.size()));
+ LOG(INFO) << "Wrote expectations to: "
+ << expected_file.LossyDisplayName();
+ }
+ } else {
+ LOG(INFO) << "Test output matches expectations.";
}
}
diff --git a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
index 591d5b99f55..21ae32a1faf 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
+++ b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -5,7 +5,9 @@
#include <string>
#include <vector>
+#include "base/debug/leak_annotations.h"
#include "base/strings/string16.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
#include "content/public/test/content_browser_test.h"
@@ -83,8 +85,24 @@ class DumpAccessibilityTestBase : public ContentBrowserTest {
std::vector<AccessibilityTreeFormatter::Filter>* filters,
std::string* wait_for);
+ // Create the right AccessibilityTreeFormatter subclass.
+ AccessibilityTreeFormatter* CreateAccessibilityTreeFormatter();
+
+ void RunTestForPlatform(const base::FilePath file_path, const char* file_dir);
+
// The default filters plus the filters loaded from the test file.
std::vector<AccessibilityTreeFormatter::Filter> filters_;
+
+#if defined(LEAK_SANITIZER) && !defined(OS_NACL)
+ // http://crbug.com/568674
+ ScopedLeakSanitizerDisabler lsan_disabler;
+#endif
+
+ // The current AccessibilityTreeFormatter.
+ scoped_ptr<AccessibilityTreeFormatter> formatter_;
+
+ // Whether we're doing a native pass or internal/blink tree pass.
+ bool is_blink_pass_;
};
} // namespace content
diff --git a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index 304fc071c25..e4d2fc46dd6 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <set>
#include <string>
#include <vector>
@@ -10,6 +12,7 @@
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_event_recorder.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
#include "content/browser/accessibility/browser_accessibility.h"
@@ -213,8 +216,11 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
#if defined(OS_WIN)
#define MAYBE_AccessibilityEventsListboxNext \
DISABLED_AccessibilityEventsListboxNext
+#define MAYBE_AccessibilityEventsMenuListPopup \
+ DISABLED_AccessibilityEventsMenuListPopup
#else
#define MAYBE_AccessibilityEventsListboxNext AccessibilityEventsListboxNext
+#define MAYBE_AccessibilityEventsMenuListPopup AccessibilityEventsMenuListPopup
#endif
IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
@@ -233,7 +239,7 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
- AccessibilityEventsMenuListPopup) {
+ MAYBE_AccessibilityEventsMenuListPopup) {
RunEventTest(FILE_PATH_LITERAL("menulist-popup.html"));
}
diff --git a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index c68ae7b9e3b..87a89ce14eb 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -12,7 +12,9 @@
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/dump_accessibility_browsertest_base.h"
@@ -87,13 +89,15 @@ class DumpAccessibilityTreeTest : public DumpAccessibilityTestBase {
}
std::vector<std::string> Dump() override {
+ scoped_ptr<AccessibilityTreeFormatter> formatter(
+ CreateAccessibilityTreeFormatter());
+ formatter->SetFilters(filters_);
+ base::string16 actual_contents_utf16;
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
shell()->web_contents());
- AccessibilityTreeFormatter formatter(
- web_contents->GetRootBrowserAccessibilityManager()->GetRoot());
- formatter.SetFilters(filters_);
- base::string16 actual_contents_utf16;
- formatter.FormatAccessibilityTree(&actual_contents_utf16);
+ formatter->FormatAccessibilityTree(
+ web_contents->GetRootBrowserAccessibilityManager()->GetRoot(),
+ &actual_contents_utf16);
std::string actual_contents = base::UTF16ToUTF8(actual_contents_utf16);
return base::SplitString(
actual_contents, "\n",
@@ -719,6 +723,41 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunHtmlTest(FILE_PATH_LITERAL("contenteditable-descendants.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityElementClassIdSrcAttr) {
+ RunHtmlTest(FILE_PATH_LITERAL("element-class-id-src-attr.html"));
+}
+
+#if defined(OS_ANDROID)
+// Flaky failures: http://crbug.com/445929.
+#define MAYBE_AccessibilityContenteditableDescendantsWithSelection \
+ DISABLED_AccessibilityContenteditableDescendantsWithSelection
+#else
+#define MAYBE_AccessibilityContenteditableDescendantsWithSelection \
+ AccessibilityContenteditableDescendantsWithSelection
+#endif
+IN_PROC_BROWSER_TEST_F(
+ DumpAccessibilityTreeTest,
+ MAYBE_AccessibilityContenteditableDescendantsWithSelection) {
+ RunHtmlTest(FILE_PATH_LITERAL(
+ "contenteditable-descendants-with-selection.html"));
+}
+
+#if defined(OS_ANDROID)
+// Flaky failures: http://crbug.com/445929.
+#define MAYBE_AccessibilityContenteditableWithEmbeddedContenteditables \
+ DISABLED_AccessibilityContenteditableWithEmbeddedContenteditables
+#else
+#define MAYBE_AccessibilityContenteditableWithEmbeddedContenteditables \
+ AccessibilityContenteditableWithEmbeddedContenteditables
+#endif
+IN_PROC_BROWSER_TEST_F(
+ DumpAccessibilityTreeTest,
+ MAYBE_AccessibilityContenteditableWithEmbeddedContenteditables) {
+ RunHtmlTest(
+ FILE_PATH_LITERAL("contenteditable-with-embedded-contenteditables.html"));
+}
+
#if defined(OS_ANDROID)
// Flaky failures: http://crbug.com/515053.
#define MAYBE_AccessibilityEm DISABLED_AccessibilityEm
@@ -913,7 +952,9 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputTel) {
RunHtmlTest(FILE_PATH_LITERAL("input-tel.html"));
}
-IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputText) {
+// Fails on Android GN bot, see crbug.com/569542.
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ MAYBE(AccessibilityInputText)) {
RunHtmlTest(FILE_PATH_LITERAL("input-text.html"));
}
diff --git a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
index 1757c997657..8b17f2d9fd2 100644
--- a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
+++ b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
@@ -4,6 +4,8 @@
#include "content/browser/accessibility/one_shot_accessibility_tree_search.h"
+#include <stdint.h>
+
#include "base/i18n/case_conversion.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
@@ -20,8 +22,6 @@ void GetNodeStrings(BrowserAccessibility* node,
strings->push_back(node->GetString16Attribute(ui::AX_ATTR_NAME));
if (node->HasStringAttribute(ui::AX_ATTR_DESCRIPTION))
strings->push_back(node->GetString16Attribute(ui::AX_ATTR_DESCRIPTION));
- if (node->HasStringAttribute(ui::AX_ATTR_HELP))
- strings->push_back(node->GetString16Attribute(ui::AX_ATTR_HELP));
if (node->HasStringAttribute(ui::AX_ATTR_VALUE))
strings->push_back(node->GetString16Attribute(ui::AX_ATTR_VALUE));
if (node->HasStringAttribute(ui::AX_ATTR_PLACEHOLDER))
@@ -117,7 +117,7 @@ void OneShotAccessibilityTreeSearch::SearchByIteratingOverChildren() {
// If start_node_ is specified, iterate over the first child past that
// node.
- uint32 count = scope_node_->PlatformChildCount();
+ uint32_t count = scope_node_->PlatformChildCount();
if (count == 0)
return;
@@ -127,7 +127,7 @@ void OneShotAccessibilityTreeSearch::SearchByIteratingOverChildren() {
while (start_node_ && start_node_->GetParent() != scope_node_)
start_node_ = start_node_->GetParent();
- uint32 index = (direction_ == FORWARDS ? 0 : count - 1);
+ uint32_t index = (direction_ == FORWARDS ? 0 : count - 1);
if (start_node_) {
index = start_node_->GetIndexInParent();
if (direction_ == FORWARDS)
diff --git a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h
index 7e55a887857..2538bb8aee0 100644
--- a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h
+++ b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_SEARCH_H_
#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_SEARCH_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
diff --git a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
index 38b82acce4a..be30284fc80 100644
--- a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
+++ b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -15,7 +16,7 @@ namespace {
class TestBrowserAccessibilityManager : public BrowserAccessibilityManager {
public:
TestBrowserAccessibilityManager(
- const SimpleAXTreeUpdate& initial_tree)
+ const ui::AXTreeUpdate& initial_tree)
: BrowserAccessibilityManager(initial_tree,
nullptr,
new BrowserAccessibilityFactory()) {}
diff --git a/chromium/content/browser/accessibility/site_per_process_accessibility_browsertest.cc b/chromium/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
index 192b11c9efa..37107702569 100644
--- a/chromium/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
+++ b/chromium/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
@@ -5,6 +5,7 @@
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
@@ -27,51 +28,103 @@
#include "content/test/accessibility_browser_test_utils.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h"
#include "url/url_constants.h"
+// These tests time out on Android.
+#if defined(OS_ANDROID)
+#define MAYBE_SitePerProcessAccessibilityBrowserTest \
+ DISABLED_SitePerProcessAccessibilityBrowserTest
+#else
+#define MAYBE_SitePerProcessAccessibilityBrowserTest \
+ SitePerProcessAccessibilityBrowserTest
+#endif
+
namespace content {
-class SitePerProcessAccessibilityBrowserTest
- : public SitePerProcessBrowserTest {
- public:
- SitePerProcessAccessibilityBrowserTest() {}
-};
+namespace {
-bool AccessibilityTreeContainsDocTitle(
- BrowserAccessibility* node,
- const std::string& title) {
- if (node->GetStringAttribute(ui::AX_ATTR_DOC_TITLE) == title)
+// Searches recursively and returns true if any node's accessible name
+// is equal to the given text.
+bool AccessibilityTreeContainsText(BrowserAccessibility* node,
+ const std::string& text) {
+ if (node->GetStringAttribute(ui::AX_ATTR_NAME) == text)
return true;
for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
- if (AccessibilityTreeContainsDocTitle(node->PlatformGetChild(i), title))
+ if (AccessibilityTreeContainsText(node->PlatformGetChild(i), text))
return true;
}
return false;
}
-// Utility function to determine if an accessibility tree has finished loading
-// or if the tree represents a page that hasn't finished loading yet.
-bool AccessibilityTreeIsLoaded(BrowserAccessibilityManager* manager) {
- BrowserAccessibility* root = manager->GetRoot();
- return (root->GetFloatAttribute(ui::AX_ATTR_DOC_LOADING_PROGRESS) == 1.0 &&
- root->GetStringAttribute(ui::AX_ATTR_DOC_URL) != url::kAboutBlankURL);
+// Helper function to be used with FrameTree::ForEach, so that
+// AccessibilityNotificationWaiter can listen for accessibility
+// events in all frames.
+bool ListenToFrame(AccessibilityNotificationWaiter* waiter,
+ FrameTreeNode* frame_tree_node) {
+ waiter->ListenToAdditionalFrame(frame_tree_node->current_frame_host());
+ return true;
}
-// Times out on Android, not clear if it's an actual bug or just slow.
-#if defined(OS_ANDROID)
-#define MAYBE_CrossSiteIframeAccessibility DISABLED_CrossSiteIframeAccessibility
-#else
-#define MAYBE_CrossSiteIframeAccessibility CrossSiteIframeAccessibility
-#endif
-IN_PROC_BROWSER_TEST_F(SitePerProcessAccessibilityBrowserTest,
- MAYBE_CrossSiteIframeAccessibility) {
+} // namespace
+
+class MAYBE_SitePerProcessAccessibilityBrowserTest
+ : public SitePerProcessBrowserTest {
+ public:
+ MAYBE_SitePerProcessAccessibilityBrowserTest() {}
+
+ void LoadCrossSitePageIntoFrame(FrameTreeNode* frame_tree_node,
+ const std::string& relative_url,
+ const std::string& host) {
+ // Load cross-site page into iframe.
+ RenderFrameHostImpl* child_rfh =
+ frame_tree_node->render_manager()->current_frame_host();
+ RenderFrameDeletedObserver deleted_observer(child_rfh);
+ GURL cross_site_url(embedded_test_server()->GetURL(host, relative_url));
+ NavigateFrameToURL(frame_tree_node, cross_site_url);
+
+ // Ensure that we have created a new process for the subframe.
+ SiteInstance* site_instance =
+ frame_tree_node->current_frame_host()->GetSiteInstance();
+ EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance);
+
+ // Wait until the iframe completes the swap.
+ deleted_observer.WaitUntilDeleted();
+ }
+
+ // This is intended to be a robust way to assert that the accessibility
+ // tree eventually gets into the correct state, without worrying about
+ // the exact ordering of events received while getting there.
+ //
+ // Searches the accessibility tree to see if any node's accessible name
+ // is equal to the given text. If not, sets up a notification waiter
+ // that listens for any accessibility event in any frame, and checks again
+ // after each event. Keeps looping until the text is found (or the
+ // test times out).
+ void WaitForAccessibilityTreeToContainText(const std::string& text) {
+ RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
+ shell()->web_contents()->GetMainFrame());
+ BrowserAccessibilityManager* main_frame_manager =
+ main_frame->browser_accessibility_manager();
+ FrameTree* frame_tree =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->GetFrameTree();
+ while (!AccessibilityTreeContainsText(
+ main_frame_manager->GetRoot(), text)) {
+ AccessibilityNotificationWaiter accessibility_waiter(main_frame,
+ ui::AX_EVENT_NONE);
+ frame_tree->ForEach(base::Bind(ListenToFrame, &accessibility_waiter));
+ accessibility_waiter.WaitForNotification();
+ }
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(MAYBE_SitePerProcessAccessibilityBrowserTest,
+ CrossSiteIframeAccessibility) {
// Enable full accessibility for all current and future WebContents.
BrowserAccessibilityState::GetInstance()->EnableAccessibility();
- host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(test_server()->Start());
- GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
NavigateToURL(shell(), main_url);
// It is safe to obtain the root frame tree node here, as it doesn't change.
@@ -81,26 +134,13 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessAccessibilityBrowserTest,
// Load same-site page into iframe.
FrameTreeNode* child = root->child_at(0);
- GURL http_url(test_server()->GetURL("files/title1.html"));
+ GURL http_url(embedded_test_server()->GetURL("/title1.html"));
NavigateFrameToURL(child, http_url);
- // Load cross-site page into iframe.
- RenderFrameHostImpl* child_rfh =
- child->render_manager()->current_frame_host();
- RenderFrameDeletedObserver deleted_observer(child_rfh);
- GURL::Replacements replace_host;
- GURL cross_site_url(test_server()->GetURL("files/title2.html"));
- replace_host.SetHostStr("foo.com");
- cross_site_url = cross_site_url.ReplaceComponents(replace_host);
- NavigateFrameToURL(root->child_at(0), cross_site_url);
-
- // Ensure that we have created a new process for the subframe.
- ASSERT_EQ(2U, root->child_count());
- SiteInstance* site_instance = child->current_frame_host()->GetSiteInstance();
- EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance);
-
- // Wait until the iframe completes the swap.
- deleted_observer.WaitUntilDeleted();
+ // Load cross-site page into iframe and wait for text from that
+ // page to appear in the accessibility tree.
+ LoadCrossSitePageIntoFrame(child, "/title2.html", "foo.com");
+ WaitForAccessibilityTreeToContainText("Title Of Awesomeness");
RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
shell()->web_contents()->GetMainFrame());
@@ -109,16 +149,6 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessAccessibilityBrowserTest,
VLOG(1) << "Main frame accessibility tree:\n"
<< main_frame_manager->SnapshotAXTreeForTesting().ToString();
- RenderFrameHostImpl* child_frame = static_cast<RenderFrameHostImpl*>(
- child->current_frame_host());
- while (!AccessibilityTreeContainsDocTitle(main_frame_manager->GetRoot(),
- "Title Of Awesomeness")) {
- AccessibilityNotificationWaiter accessibility_waiter(main_frame,
- ui::AX_EVENT_NONE);
- accessibility_waiter.ListenToAdditionalFrame(child_frame);
- accessibility_waiter.WaitForNotification();
- }
-
// Assert that we can walk from the main frame down into the child frame
// directly, getting correct roles and data along the way.
BrowserAccessibility* ax_root = main_frame_manager->GetRoot();
@@ -153,4 +183,30 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessAccessibilityBrowserTest,
EXPECT_EQ(ax_child_frame_root->GetParent(), ax_iframe);
}
+IN_PROC_BROWSER_TEST_F(MAYBE_SitePerProcessAccessibilityBrowserTest,
+ TwoCrossSiteNavigations) {
+ // Enable full accessibility for all current and future WebContents.
+ BrowserAccessibilityState::GetInstance()->EnableAccessibility();
+
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
+ NavigateToURL(shell(), main_url);
+
+ // It is safe to obtain the root frame tree node here, as it doesn't change.
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+
+ // Load first cross-site page into iframe and wait for text from that
+ // page to appear in the accessibility tree.
+ FrameTreeNode* child = root->child_at(0);
+ LoadCrossSitePageIntoFrame(child, "/title1.html", "foo.com");
+ WaitForAccessibilityTreeToContainText("This page has no title.");
+
+ // Load second cross-site page into iframe and wait for text from that
+ // page to appear in the accessibility tree. If this succeeds and doesn't
+ // time out, the test passes.
+ LoadCrossSitePageIntoFrame(child, "/title2.html", "bar.com");
+ WaitForAccessibilityTreeToContainText("Title Of Awesomeness");
+}
+
} // namespace content
diff --git a/chromium/content/browser/accessibility/snapshot_ax_tree_browsertest.cc b/chromium/content/browser/accessibility/snapshot_ax_tree_browsertest.cc
index 9f47aaf2e54..da6201f5b6b 100644
--- a/chromium/content/browser/accessibility/snapshot_ax_tree_browsertest.cc
+++ b/chromium/content/browser/accessibility/snapshot_ax_tree_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/callback.h"
+#include "base/macros.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -24,15 +25,15 @@ class AXTreeSnapshotWaiter {
loop_runner_->Run();
}
- const SimpleAXTreeUpdate& snapshot() const { return snapshot_; }
+ const ui::AXTreeUpdate& snapshot() const { return snapshot_; }
- void ReceiveSnapshot(const SimpleAXTreeUpdate& snapshot) {
+ void ReceiveSnapshot(const ui::AXTreeUpdate& snapshot) {
snapshot_ = snapshot;
loop_runner_->Quit();
}
private:
- SimpleAXTreeUpdate snapshot_;
+ ui::AXTreeUpdate snapshot_;
scoped_refptr<MessageLoopRunner> loop_runner_;
DISALLOW_COPY_AND_ASSIGN(AXTreeSnapshotWaiter);
diff --git a/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc b/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
index fe92e3bad3e..0e2e0ccbb07 100644
--- a/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
+++ b/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -80,8 +81,8 @@ IN_PROC_BROWSER_TEST_F(TouchAccessibilityBrowserTest,
// cell. A touch exploration event is just a mouse move event with
// the ui::EF_TOUCH_ACCESSIBILITY flag set.
gfx::Rect bounds = window->GetBoundsInRootWindow();
- gfx::PointF location(bounds.x() + 50 * col + 25,
- bounds.y() + 50 * row + 25);
+ gfx::Point location(bounds.x() + 50 * col + 25,
+ bounds.y() + 50 * row + 25);
int flags = ui::EF_TOUCH_ACCESSIBILITY;
scoped_ptr<ui::Event> mouse_move_event(new ui::MouseEvent(
ui::ET_MOUSE_MOVED, location, location, ui::EventTimeForNow(),
@@ -97,7 +98,7 @@ IN_PROC_BROWSER_TEST_F(TouchAccessibilityBrowserTest,
BrowserAccessibility* hit = manager->GetFromID(target_id);
BrowserAccessibility* child = hit->PlatformGetChild(0);
ASSERT_NE(nullptr, child);
- cell_text = child->GetData().GetStringAttribute(ui::AX_ATTR_VALUE);
+ cell_text = child->GetData().GetStringAttribute(ui::AX_ATTR_NAME);
VLOG(1) << "Got hover event in cell with text: " << cell_text;
} while (cell_text != expected_cell_text);
}
diff --git a/chromium/content/browser/android/DEPS b/chromium/content/browser/android/DEPS
new file mode 100644
index 00000000000..6cf1809dc48
--- /dev/null
+++ b/chromium/content/browser/android/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+content/gpu/in_process_gpu_thread.h",
+]
diff --git a/chromium/content/browser/android/OWNERS b/chromium/content/browser/android/OWNERS
index 6ba7da7c389..c6293207b2c 100644
--- a/chromium/content/browser/android/OWNERS
+++ b/chromium/content/browser/android/OWNERS
@@ -2,5 +2,5 @@ skyostil@chromium.org
tedchoc@chromium.org
yfriedman@chromium.org
-# Input handling related
-jdduke@chromium.org
+per-file synchronous_compositor_*.h=boliu@chromium.org
+per-file synchronous_compositor_*.cc=boliu@chromium.org
diff --git a/chromium/content/browser/android/animation_utils.h b/chromium/content/browser/android/animation_utils.h
deleted file mode 100644
index e20d2eb9e50..00000000000
--- a/chromium/content/browser/android/animation_utils.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_ANIMATION_UTILS_H_
-#define CONTENT_BROWSER_ANDROID_ANIMATION_UTILS_H_
-
-namespace content {
-
-template <typename T>
-T Lerp(T a, T b, T t) {
- return a + (b - a) * t;
-}
-
-template <typename T>
-T Clamp(T value, T low, T high) {
- return value < low ? low : (value > high ? high : value);
-}
-
-template <typename T>
-T Damp(T input, T factor) {
- T result;
- if (factor == 1) {
- result = 1 - (1 - input) * (1 - input);
- } else {
- result = 1 - std::pow(1 - input, 2 * factor);
- }
- return result;
-}
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_ANIMATION_UTILS_H_
diff --git a/chromium/content/browser/android/background_sync_launcher_android.cc b/chromium/content/browser/android/background_sync_launcher_android.cc
deleted file mode 100644
index 693817baa8a..00000000000
--- a/chromium/content/browser/android/background_sync_launcher_android.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/background_sync_launcher_android.h"
-
-#include "content/public/browser/browser_thread.h"
-#include "jni/BackgroundSyncLauncher_jni.h"
-
-namespace content {
-
-namespace {
-base::LazyInstance<BackgroundSyncLauncherAndroid> g_background_sync_launcher =
- LAZY_INSTANCE_INITIALIZER;
-}
-
-// static
-BackgroundSyncLauncherAndroid* BackgroundSyncLauncherAndroid::Get() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- return g_background_sync_launcher.Pointer();
-}
-
-// static
-void BackgroundSyncLauncherAndroid::LaunchBrowserWhenNextOnline(
- const BackgroundSyncManager* registrant,
- bool launch_when_next_online) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- Get()->LaunchBrowserWhenNextOnlineImpl(registrant, launch_when_next_online);
-}
-
-void BackgroundSyncLauncherAndroid::LaunchBrowserWhenNextOnlineImpl(
- const BackgroundSyncManager* registrant,
- bool launch_when_next_online) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- bool was_launching = !launch_when_next_online_registrants_.empty();
-
- if (launch_when_next_online)
- launch_when_next_online_registrants_.insert(registrant);
- else
- launch_when_next_online_registrants_.erase(registrant);
-
- bool now_launching = !launch_when_next_online_registrants_.empty();
- if (was_launching != now_launching) {
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_BackgroundSyncLauncher_setLaunchWhenNextOnline(
- env, java_launcher_.obj(), base::android::GetApplicationContext(),
- now_launching);
- }
-}
-
-// static
-bool BackgroundSyncLauncherAndroid::RegisterLauncher(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-BackgroundSyncLauncherAndroid::BackgroundSyncLauncherAndroid() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- JNIEnv* env = base::android::AttachCurrentThread();
- java_launcher_.Reset(Java_BackgroundSyncLauncher_create(
- env, base::android::GetApplicationContext()));
-}
-
-BackgroundSyncLauncherAndroid::~BackgroundSyncLauncherAndroid() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_BackgroundSyncLauncher_destroy(env, java_launcher_.obj());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/background_sync_launcher_android.h b/chromium/content/browser/android/background_sync_launcher_android.h
deleted file mode 100644
index 77018f44c07..00000000000
--- a/chromium/content/browser/android/background_sync_launcher_android.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_BACKGROUND_SYNC_LAUNCHER_ANDROID_H_
-#define CONTENT_BROWSER_ANDROID_BACKGROUND_SYNC_LAUNCHER_ANDROID_H_
-
-#include <set>
-
-#include "base/android/jni_android.h"
-#include "base/lazy_instance.h"
-#include "base/macros.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-class BackgroundSyncManager;
-
-// The BackgroundSyncLauncherAndroid singleton owns the Java
-// BackgroundSyncLauncher object and is used to register interest in starting
-// the browser the next time the device goes online. This class runs on the UI
-// thread.
-class CONTENT_EXPORT BackgroundSyncLauncherAndroid {
- public:
- static BackgroundSyncLauncherAndroid* Get();
-
- // Register the |registrant|'s interest (or disinterest) in starting the
- // browser the next time the device goes online after the browser has closed.
- // |registrant| is used to count the number of interested objects and is not
- // accessed, therefore it is okay for |registrant| to be deleted before this
- // class. Interest is reset the next time the BackgroundSyncLauncherAndroid is
- // created (browser restart). The caller can remove interest in launching the
- // browser by calling with |launch_when_next_online| set to false.
- static void LaunchBrowserWhenNextOnline(
- const BackgroundSyncManager* registrant,
- bool launch_when_next_online);
-
- static bool RegisterLauncher(JNIEnv* env);
-
- private:
- friend struct base::DefaultLazyInstanceTraits<BackgroundSyncLauncherAndroid>;
-
- // Constructor and destructor marked private to enforce singleton
- BackgroundSyncLauncherAndroid();
- ~BackgroundSyncLauncherAndroid();
-
- void LaunchBrowserWhenNextOnlineImpl(const BackgroundSyncManager* registrant,
- bool launch_when_next_online);
-
- std::set<const BackgroundSyncManager*> launch_when_next_online_registrants_;
- base::android::ScopedJavaGlobalRef<jobject> java_launcher_;
- DISALLOW_COPY_AND_ASSIGN(BackgroundSyncLauncherAndroid);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_BACKGROUND_SYNC_LAUNCHER_ANDROID_H_
diff --git a/chromium/content/browser/android/background_sync_network_observer_android.cc b/chromium/content/browser/android/background_sync_network_observer_android.cc
index 533fc363b45..05d46ecdfd7 100644
--- a/chromium/content/browser/android/background_sync_network_observer_android.cc
+++ b/chromium/content/browser/android/background_sync_network_observer_android.cc
@@ -4,6 +4,7 @@
#include "content/browser/android/background_sync_network_observer_android.h"
+#include "base/android/context_utils.h"
#include "jni/BackgroundSyncNetworkObserver_jni.h"
namespace content {
@@ -50,7 +51,7 @@ BackgroundSyncNetworkObserverAndroid::Observer::~Observer() {
void BackgroundSyncNetworkObserverAndroid::Observer::
NotifyConnectionTypeChanged(JNIEnv* env,
- jobject jcaller,
+ const JavaParamRef<jobject>& jcaller,
jint new_connection_type) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
diff --git a/chromium/content/browser/android/background_sync_network_observer_android.h b/chromium/content/browser/android/background_sync_network_observer_android.h
index 49e8b0ac9c8..1c1a46e51ea 100644
--- a/chromium/content/browser/android/background_sync_network_observer_android.h
+++ b/chromium/content/browser/android/background_sync_network_observer_android.h
@@ -7,6 +7,7 @@
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/background_sync/background_sync_network_observer.h"
#include "content/public/browser/browser_thread.h"
@@ -46,9 +47,10 @@ class BackgroundSyncNetworkObserverAndroid
// connection type changes. This updates the current connection type seen by
// this class and calls the |network_changed_callback| provided to the
// constructor, on the IO thread, with the new connection type.
- void NotifyConnectionTypeChanged(JNIEnv* env,
- jobject jcaller,
- jint new_connection_type);
+ void NotifyConnectionTypeChanged(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jcaller,
+ jint new_connection_type);
private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
diff --git a/chromium/content/browser/android/browser_surface_texture_manager.h b/chromium/content/browser/android/browser_surface_texture_manager.h
index 79a814a9396..f9fb74cccb5 100644
--- a/chromium/content/browser/android/browser_surface_texture_manager.h
+++ b/chromium/content/browser/android/browser_surface_texture_manager.h
@@ -7,6 +7,7 @@
#include "content/common/android/surface_texture_manager.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/common/android/surface_texture_peer.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/android/child_process_launcher_android.cc b/chromium/content/browser/android/child_process_launcher_android.cc
index 44e1bd38f6d..471ce31d91c 100644
--- a/chromium/content/browser/android/child_process_launcher_android.cc
+++ b/chromium/content/browser/android/child_process_launcher_android.cc
@@ -4,14 +4,18 @@
#include "content/browser/android/child_process_launcher_android.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/media/android/browser_media_player_manager.h"
-#include "content/browser/media/media_web_contents_observer.h"
-#include "content/browser/renderer_host/compositor_impl_android.h"
+#include "content/browser/media/android/media_web_contents_observer_android.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
@@ -37,6 +41,7 @@ static void SetSurfacePeer(
base::ProcessHandle render_process_handle,
int render_frame_id,
int player_id) {
+#if !defined(USE_AURA)
int render_process_id = 0;
RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
while (!it.IsAtEnd()) {
@@ -59,10 +64,10 @@ static void SetSurfacePeer(
return;
}
- WebContentsImpl* web_contents =
- static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(frame));
BrowserMediaPlayerManager* player_manager =
- web_contents->media_web_contents_observer()->GetMediaPlayerManager(frame);
+ MediaWebContentsObserverAndroid::FromWebContents(
+ WebContents::FromRenderFrameHost(frame))
+ ->GetMediaPlayerManager(frame);
if (!player_manager) {
DVLOG(1) << "Cannot find the media player manager for frame " << frame;
return;
@@ -76,8 +81,11 @@ static void SetSurfacePeer(
if (player != player_manager->GetFullscreenPlayer()) {
gfx::ScopedJavaSurface scoped_surface(surface);
- player->SetVideoSurface(scoped_surface.Pass());
+ player->SetVideoSurface(std::move(scoped_surface));
}
+#else
+ NOTREACHED();
+#endif
}
} // anonymous namespace
@@ -125,8 +133,8 @@ void StartChildProcess(
PCHECK(0 <= fd);
int id = files_to_register->GetIDAt(i);
bool auto_close = files_to_register->OwnsFD(fd);
- int64 offset = 0L;
- int64 size = 0L;
+ int64_t offset = 0L;
+ int64_t size = 0L;
auto found_region_iter = regions.find(id);
if (found_region_iter != regions.end()) {
offset = found_region_iter->second.offset;
diff --git a/chromium/content/browser/android/composited_touch_handle_drawable.cc b/chromium/content/browser/android/composited_touch_handle_drawable.cc
index 502189651e7..235e2eef3b4 100644
--- a/chromium/content/browser/android/composited_touch_handle_drawable.cc
+++ b/chromium/content/browser/android/composited_touch_handle_drawable.cc
@@ -4,8 +4,10 @@
#include "content/browser/android/composited_touch_handle_drawable.h"
+#include "base/android/context_utils.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/trace_event/trace_event.h"
#include "cc/layers/ui_resource_layer.h"
#include "content/public/browser/android/compositor.h"
@@ -49,6 +51,9 @@ class HandleResources {
left_bitmap_.setImmutable();
right_bitmap_.setImmutable();
center_bitmap_.setImmutable();
+
+ drawable_horizontal_padding_ratio_ =
+ Java_HandleViewResources_getHandleHorizontalPaddingRatio(env);
}
const SkBitmap& GetBitmap(ui::TouchHandleOrientation orientation) {
@@ -66,10 +71,16 @@ class HandleResources {
return center_bitmap_;
}
+ float GetDrawableHorizontalPaddingRatio() const {
+ DCHECK(loaded_);
+ return drawable_horizontal_padding_ratio_;
+ }
+
private:
SkBitmap left_bitmap_;
SkBitmap right_bitmap_;
SkBitmap center_bitmap_;
+ float drawable_horizontal_padding_ratio_;
bool loaded_;
DISALLOW_COPY_AND_ASSIGN(HandleResources);
@@ -87,6 +98,8 @@ CompositedTouchHandleDrawable::CompositedTouchHandleDrawable(
orientation_(ui::TouchHandleOrientation::UNDEFINED),
layer_(cc::UIResourceLayer::Create(Compositor::LayerSettings())) {
g_selection_resources.Get().LoadIfNecessary(context);
+ drawable_horizontal_padding_ratio_ =
+ g_selection_resources.Get().GetDrawableHorizontalPaddingRatio();
DCHECK(root_layer);
root_layer->AddChild(layer_.get());
}
@@ -103,29 +116,38 @@ void CompositedTouchHandleDrawable::SetEnabled(bool enabled) {
}
void CompositedTouchHandleDrawable::SetOrientation(
- ui::TouchHandleOrientation orientation) {
+ ui::TouchHandleOrientation orientation,
+ bool mirror_vertical,
+ bool mirror_horizontal) {
DCHECK(layer_->parent());
+ bool orientation_changed = orientation_ != orientation;
+
orientation_ = orientation;
- const SkBitmap& bitmap = g_selection_resources.Get().GetBitmap(orientation);
- layer_->SetBitmap(bitmap);
- layer_->SetBounds(gfx::Size(bitmap.width(), bitmap.height()));
-
- switch (orientation_) {
- case ui::TouchHandleOrientation::LEFT:
- focal_offset_from_origin_ = gfx::Vector2dF(bitmap.width() * 0.75f, 0);
- break;
- case ui::TouchHandleOrientation::RIGHT:
- focal_offset_from_origin_ = gfx::Vector2dF(bitmap.width() * 0.25f, 0);
- break;
- case ui::TouchHandleOrientation::CENTER:
- focal_offset_from_origin_ = gfx::Vector2dF(bitmap.width() * 0.5f, 0);
- break;
- case ui::TouchHandleOrientation::UNDEFINED:
- NOTREACHED() << "Invalid touch handle orientation.";
- break;
- };
+ if (orientation_changed) {
+ const SkBitmap& bitmap = g_selection_resources.Get().GetBitmap(orientation);
+ const int bitmap_height = bitmap.height();
+ const int bitmap_width = bitmap.width();
+ layer_->SetBitmap(bitmap);
+ layer_->SetBounds(gfx::Size(bitmap_width, bitmap_height));
+ }
+
+ const int layer_height = layer_->bounds().height();
+ const int layer_width = layer_->bounds().width();
+
+ // Invert about X and Y axis based on the mirror values
+ gfx::Transform transform;
+ float scale_x = mirror_horizontal ? -1.f : 1.f;
+ float scale_y = mirror_vertical ? -1.f : 1.f;
+ layer_->SetTransformOrigin(
+ gfx::Point3F(layer_width * 0.5f, layer_height * 0.5f, 0));
+ transform.Scale(scale_x, scale_y);
+ layer_->SetTransform(transform);
+}
+
+void CompositedTouchHandleDrawable::SetOrigin(const gfx::PointF& origin) {
+ origin_position_ = gfx::ScalePoint(origin, dpi_scale_);
UpdateLayerPosition();
}
@@ -137,12 +159,6 @@ void CompositedTouchHandleDrawable::SetAlpha(float alpha) {
layer_->SetHideLayerAndSubtree(hidden);
}
-void CompositedTouchHandleDrawable::SetFocus(const gfx::PointF& position) {
- DCHECK(layer_->parent());
- focal_position_ = gfx::ScalePoint(position, dpi_scale_);
- UpdateLayerPosition();
-}
-
gfx::RectF CompositedTouchHandleDrawable::GetVisibleBounds() const {
return gfx::ScaleRect(gfx::RectF(layer_->position().x(),
layer_->position().y(),
@@ -151,12 +167,16 @@ gfx::RectF CompositedTouchHandleDrawable::GetVisibleBounds() const {
1.f / dpi_scale_);
}
+float CompositedTouchHandleDrawable::GetDrawableHorizontalPaddingRatio() const {
+ return drawable_horizontal_padding_ratio_;
+}
+
void CompositedTouchHandleDrawable::DetachLayer() {
layer_->RemoveFromParent();
}
void CompositedTouchHandleDrawable::UpdateLayerPosition() {
- layer_->SetPosition(focal_position_ - focal_offset_from_origin_);
+ layer_->SetPosition(origin_position_);
}
// static
diff --git a/chromium/content/browser/android/composited_touch_handle_drawable.h b/chromium/content/browser/android/composited_touch_handle_drawable.h
index 28c6910b9d4..29324da8a77 100644
--- a/chromium/content/browser/android/composited_touch_handle_drawable.h
+++ b/chromium/content/browser/android/composited_touch_handle_drawable.h
@@ -8,6 +8,7 @@
#include "ui/touch_selection/touch_handle.h"
#include "base/android/jni_android.h"
+#include "base/macros.h"
#include "cc/layers/ui_resource_layer.h"
namespace content {
@@ -22,10 +23,13 @@ class CompositedTouchHandleDrawable : public ui::TouchHandleDrawable {
// ui::TouchHandleDrawable implementation.
void SetEnabled(bool enabled) override;
- void SetOrientation(ui::TouchHandleOrientation orientation) override;
+ void SetOrientation(ui::TouchHandleOrientation orientation,
+ bool mirror_vertical,
+ bool mirror_horizontal) override;
+ void SetOrigin(const gfx::PointF& origin) override;
void SetAlpha(float alpha) override;
- void SetFocus(const gfx::PointF& position) override;
gfx::RectF GetVisibleBounds() const override;
+ float GetDrawableHorizontalPaddingRatio() const override;
static bool RegisterHandleViewResources(JNIEnv* env);
@@ -34,9 +38,9 @@ class CompositedTouchHandleDrawable : public ui::TouchHandleDrawable {
void UpdateLayerPosition();
const float dpi_scale_;
+ float drawable_horizontal_padding_ratio_;
ui::TouchHandleOrientation orientation_;
- gfx::PointF focal_position_;
- gfx::Vector2dF focal_offset_from_origin_;
+ gfx::PointF origin_position_;
scoped_refptr<cc::UIResourceLayer> layer_;
DISALLOW_COPY_AND_ASSIGN(CompositedTouchHandleDrawable);
diff --git a/chromium/content/browser/android/content_protocol_handler_impl.h b/chromium/content/browser/android/content_protocol_handler_impl.h
index f593a84bb88..f5069fd0ce3 100644
--- a/chromium/content/browser/android/content_protocol_handler_impl.h
+++ b/chromium/content/browser/android/content_protocol_handler_impl.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_ANDROID_CONTENT_PROTOCOL_HANDLER_IMPL_H_
#define CONTENT_BROWSER_ANDROID_CONTENT_PROTOCOL_HANDLER_IMPL_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/public/browser/android/content_protocol_handler.h"
diff --git a/chromium/content/browser/android/content_readback_handler.cc b/chromium/content/browser/android/content_readback_handler.cc
deleted file mode 100644
index a7c9b67ed56..00000000000
--- a/chromium/content/browser/android/content_readback_handler.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/content_readback_handler.h"
-
-#include "base/android/jni_android.h"
-#include "base/bind.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/output/copy_output_result.h"
-#include "content/browser/android/content_view_core_impl.h"
-#include "jni/ContentReadbackHandler_jni.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/android/window_android.h"
-#include "ui/android/window_android_compositor.h"
-#include "ui/gfx/android/java_bitmap.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace content {
-
-namespace {
-
-void OnFinishCopyOutputRequest(
- const ReadbackRequestCallback& result_callback,
- scoped_ptr<cc::CopyOutputResult> copy_output_result) {
- if (!copy_output_result->HasBitmap()) {
- result_callback.Run(SkBitmap(), READBACK_FAILED);
- return;
- }
-
- scoped_ptr<SkBitmap> bitmap = copy_output_result->TakeBitmap();
- result_callback.Run(*bitmap, READBACK_SUCCESS);
-}
-
-} // anonymous namespace
-
-// static
-bool ContentReadbackHandler::RegisterContentReadbackHandler(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-ContentReadbackHandler::ContentReadbackHandler(JNIEnv* env, jobject obj)
- : weak_factory_(this) {
- java_obj_.Reset(env, obj);
-}
-
-void ContentReadbackHandler::Destroy(JNIEnv* env, jobject obj) {
- delete this;
-}
-
-void ContentReadbackHandler::GetContentBitmap(JNIEnv* env,
- jobject obj,
- jint readback_id,
- jfloat scale,
- jobject color_type,
- jfloat x,
- jfloat y,
- jfloat width,
- jfloat height,
- jobject content_view_core) {
- ContentViewCore* view =
- ContentViewCore::GetNativeContentViewCore(env, content_view_core);
- DCHECK(view);
-
- const ReadbackRequestCallback result_callback =
- base::Bind(&ContentReadbackHandler::OnFinishReadback,
- weak_factory_.GetWeakPtr(),
- readback_id);
-
- SkColorType sk_color_type = gfx::ConvertToSkiaColorType(color_type);
- view->GetScaledContentBitmap(
- scale, sk_color_type, gfx::Rect(x, y, width, height), result_callback);
-}
-
-void ContentReadbackHandler::GetCompositorBitmap(JNIEnv* env,
- jobject obj,
- jint readback_id,
- jlong native_window_android) {
- ui::WindowAndroid* window_android =
- reinterpret_cast<ui::WindowAndroid*>(native_window_android);
- DCHECK(window_android);
-
- const ReadbackRequestCallback result_callback =
- base::Bind(&ContentReadbackHandler::OnFinishReadback,
- weak_factory_.GetWeakPtr(),
- readback_id);
-
- base::Callback<void(scoped_ptr<cc::CopyOutputResult>)> copy_output_callback =
- base::Bind(&OnFinishCopyOutputRequest,
- result_callback);
-
- ui::WindowAndroidCompositor* compositor = window_android->GetCompositor();
-
- if (!compositor) {
- copy_output_callback.Run(cc::CopyOutputResult::CreateEmptyResult());
- return;
- }
-
- compositor->RequestCopyOfOutputOnRootLayer(
- cc::CopyOutputRequest::CreateBitmapRequest(copy_output_callback));
-}
-
-ContentReadbackHandler::~ContentReadbackHandler() {}
-
-void ContentReadbackHandler::OnFinishReadback(int readback_id,
- const SkBitmap& bitmap,
- ReadbackResponse response) {
- JNIEnv* env = base::android::AttachCurrentThread();
- ScopedJavaLocalRef<jobject> java_bitmap;
- if (response == READBACK_SUCCESS)
- java_bitmap = gfx::ConvertToJavaBitmap(&bitmap);
-
- Java_ContentReadbackHandler_notifyGetBitmapFinished(
- env, java_obj_.obj(), readback_id, java_bitmap.obj(), response);
-}
-
-// static
-static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
- ContentReadbackHandler* content_readback_handler =
- new ContentReadbackHandler(env, obj);
- return reinterpret_cast<intptr_t>(content_readback_handler);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/content_readback_handler.h b/chromium/content/browser/android/content_readback_handler.h
deleted file mode 100644
index 66b2c8588d4..00000000000
--- a/chromium/content/browser/android/content_readback_handler.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_CONTENT_READBACK_HANDLER_H_
-#define CONTENT_BROWSER_ANDROID_CONTENT_READBACK_HANDLER_H_
-
-#include <jni.h>
-
-#include "base/android/jni_weak_ref.h"
-#include "base/callback.h"
-#include "base/memory/weak_ptr.h"
-#include "content/public/browser/readback_types.h"
-
-class SkBitmap;
-
-namespace cc {
-class CopyOutputResult;
-}
-
-namespace content {
-
-// Native side of the ContentReadbackHandler.java, which issues content
-// readbacks from the Java side.
-class ContentReadbackHandler {
- public:
- // Registers the JNI methods for ContentViewRender.
- static bool RegisterContentReadbackHandler(JNIEnv* env);
-
- // Methods called from Java via JNI -----------------------------------------
- ContentReadbackHandler(JNIEnv* env, jobject obj);
- void Destroy(JNIEnv* env, jobject obj);
- void GetContentBitmap(JNIEnv* env,
- jobject obj,
- jint readback_id,
- jfloat scale,
- jobject config,
- jfloat x,
- jfloat y,
- jfloat width,
- jfloat height,
- jobject content_view_core);
- void GetCompositorBitmap(JNIEnv* env,
- jobject obj,
- jint readback_id,
- jlong native_window_android);
-
- private:
- virtual ~ContentReadbackHandler();
-
- void OnFinishReadback(int readback_id,
- const SkBitmap& bitmap,
- ReadbackResponse response);
-
- base::android::ScopedJavaGlobalRef<jobject> java_obj_;
- base::WeakPtrFactory<ContentReadbackHandler> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentReadbackHandler);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_CONTENT_READBACK_HANDLER_H_
diff --git a/chromium/content/browser/android/content_startup_flags.cc b/chromium/content/browser/android/content_startup_flags.cc
index 2f0c632c85e..acda33ee494 100644
--- a/chromium/content/browser/android/content_startup_flags.cc
+++ b/chromium/content/browser/android/content_startup_flags.cc
@@ -8,13 +8,10 @@
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
#include "base/sys_info.h"
#include "cc/base/switches.h"
-#include "cc/trees/layer_tree_settings.h"
+#include "cc/layers/layer_settings.h"
#include "content/public/browser/android/compositor.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "ui/base/ui_base_switches.h"
@@ -33,23 +30,7 @@ void SetContentCommandLineFlags(bool single_process,
base::CommandLine* parsed_command_line =
base::CommandLine::ForCurrentProcess();
- int command_line_renderer_limit = -1;
- if (parsed_command_line->HasSwitch(switches::kRendererProcessLimit)) {
- std::string limit = parsed_command_line->GetSwitchValueASCII(
- switches::kRendererProcessLimit);
- int value;
- if (base::StringToInt(limit, &value)) {
- command_line_renderer_limit = std::max(0, value);
- }
- }
-
- if (command_line_renderer_limit > 0) {
- int limit = std::min(command_line_renderer_limit,
- static_cast<int>(kMaxRendererProcessCount));
- RenderProcessHost::SetMaxRendererProcessCount(limit);
- }
-
- if (single_process || command_line_renderer_limit == 0) {
+ if (single_process) {
// Need to ensure the command line flag is consistent as a lot of chrome
// internal code checks this directly, but it wouldn't normally get set when
// we are implementing an embedded WebView.
@@ -62,9 +43,8 @@ void SetContentCommandLineFlags(bool single_process,
parsed_command_line->AppendSwitch(switches::kEnableOverlayScrollbar);
parsed_command_line->AppendSwitch(switches::kValidateInputEventStream);
- // TODO(jdduke): Use the proper SDK version when available, crbug.com/466749.
- if (base::android::BuildInfo::GetInstance()->sdk_int() >
- base::android::SDK_VERSION_LOLLIPOP_MR1) {
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_MARSHMALLOW) {
parsed_command_line->AppendSwitch(switches::kEnableLongpressDragSelection);
parsed_command_line->AppendSwitchASCII(
switches::kTouchTextSelectionStrategy, "direction");
@@ -100,11 +80,13 @@ void SetContentCommandLineFlags(bool single_process,
switches::kProfilerTiming, switches::kProfilerTimingDisabledValue);
}
+#if !defined(USE_AURA)
cc::LayerSettings layer_settings;
- if (parsed_command_line->HasSwitch(
- switches::kEnableAndroidCompositorAnimationTimelines))
- layer_settings.use_compositor_animation_timelines = true;
+ layer_settings.use_compositor_animation_timelines =
+ !parsed_command_line->HasSwitch(
+ switches::kDisableAndroidCompositorAnimationTimelines);
Compositor::SetLayerSettings(layer_settings);
+#endif
}
} // namespace content
diff --git a/chromium/content/browser/android/content_video_view.cc b/chromium/content/browser/android/content_video_view.cc
index 8a9eb4298b1..b107377c34c 100644
--- a/chromium/content/browser/android/content_video_view.cc
+++ b/chromium/content/browser/android/content_video_view.cc
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
-#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/media/android/browser_media_player_manager.h"
#include "content/browser/power_save_blocker_impl.h"
#include "content/common/android/surface_texture_peer.h"
@@ -16,6 +15,10 @@
#include "content/public/common/content_switches.h"
#include "jni/ContentVideoView_jni.h"
+#if !defined(USE_AURA)
+#include "content/browser/android/content_view_core_impl.h"
+#endif
+
using base::android::AttachCurrentThread;
using base::android::CheckException;
using base::android::ScopedJavaGlobalRef;
@@ -95,15 +98,6 @@ void ContentVideoView::OnVideoSizeChanged(int width, int height) {
}
}
-void ContentVideoView::OnBufferingUpdate(int percent) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
- if (!content_video_view.is_null()) {
- Java_ContentVideoView_onBufferingUpdate(env, content_video_view.obj(),
- percent);
- }
-}
-
void ContentVideoView::OnPlaybackComplete() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
@@ -119,8 +113,10 @@ void ContentVideoView::OnExitFullscreen() {
Java_ContentVideoView_onExitFullscreen(env, content_video_view.obj());
}
-void ContentVideoView::RecordFullscreenPlayback(
- JNIEnv*, jobject, bool is_portrait_video, bool is_orientation_portrait) {
+void ContentVideoView::RecordFullscreenPlayback(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ bool is_portrait_video,
+ bool is_orientation_portrait) {
UMA_HISTOGRAM_BOOLEAN("MobileFullscreenVideo.OrientationPortrait",
is_orientation_portrait);
UMA_HISTOGRAM_BOOLEAN("MobileFullscreenVideo.VideoPortrait",
@@ -128,7 +124,9 @@ void ContentVideoView::RecordFullscreenPlayback(
}
void ContentVideoView::RecordExitFullscreenPlayback(
- JNIEnv*, jobject, bool is_portrait_video,
+ JNIEnv*,
+ const JavaParamRef<jobject>&,
+ bool is_portrait_video,
long playback_duration_in_milliseconds_before_orientation_change,
long playback_duration_in_milliseconds_after_orientation_change) {
bool orientation_changed = (
@@ -169,24 +167,27 @@ void ContentVideoView::UpdateMediaMetadata() {
}
}
-bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) {
+bool ContentVideoView::IsPlaying(JNIEnv*, const JavaParamRef<jobject>& obj) {
media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
return player ? player->IsPlaying() : false;
}
-void ContentVideoView::ExitFullscreen(
- JNIEnv*, jobject, jboolean release_media_player) {
+void ContentVideoView::ExitFullscreen(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ jboolean release_media_player) {
j_content_video_view_.reset();
manager_->ExitFullscreen(release_media_player);
}
-void ContentVideoView::SetSurface(JNIEnv* env, jobject obj,
- jobject surface) {
+void ContentVideoView::SetSurface(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& surface) {
manager_->SetVideoSurface(
gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
}
-void ContentVideoView::RequestMediaMetadata(JNIEnv* env, jobject obj) {
+void ContentVideoView::RequestMediaMetadata(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ContentVideoView::UpdateMediaMetadata,
@@ -198,11 +199,15 @@ ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
}
JavaObjectWeakGlobalRef ContentVideoView::CreateJavaObject() {
- ContentViewCore* content_view_core = manager_->GetContentViewCore();
+
JNIEnv* env = AttachCurrentThread();
+ base::android::ScopedJavaLocalRef<jobject> j_content_view_core;
+
+#if !defined(USE_AURA)
+ ContentViewCore* content_view_core = manager_->GetContentViewCore();
+ j_content_view_core = content_view_core->GetJavaObject();
+#endif
- base::android::ScopedJavaLocalRef<jobject> j_content_view_core =
- content_view_core->GetJavaObject();
if (j_content_view_core.is_null())
return JavaObjectWeakGlobalRef(env, nullptr);
diff --git a/chromium/content/browser/android/content_video_view.h b/chromium/content/browser/android/content_video_view.h
index 37b7f2e8be7..7959cd60880 100644
--- a/chromium/content/browser/android/content_video_view.h
+++ b/chromium/content/browser/android/content_video_view.h
@@ -9,7 +9,7 @@
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -41,31 +41,39 @@ class ContentVideoView {
static ContentVideoView* GetInstance();
// Getter method called by the Java class to get the media information.
- bool IsPlaying(JNIEnv*, jobject obj);
- void RequestMediaMetadata(JNIEnv*, jobject obj);
+ bool IsPlaying(JNIEnv*, const base::android::JavaParamRef<jobject>& obj);
+ void RequestMediaMetadata(JNIEnv*,
+ const base::android::JavaParamRef<jobject>& obj);
// Called when the Java fullscreen view is destroyed. If
// |release_media_player| is true, |manager_| needs to release the player
// as we are quitting the app.
- void ExitFullscreen(JNIEnv*, jobject, jboolean release_media_player);
+ void ExitFullscreen(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ jboolean release_media_player);
// Called by the Java class to pass the surface object to the player.
- void SetSurface(JNIEnv*, jobject obj, jobject surface);
+ void SetSurface(JNIEnv*,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& surface);
// Method called by |manager_| to inform the Java class about player status
// change.
void UpdateMediaMetadata();
void OnMediaPlayerError(int errorType);
void OnVideoSizeChanged(int width, int height);
- void OnBufferingUpdate(int percent);
void OnPlaybackComplete();
void OnExitFullscreen();
// Functions called to record fullscreen playback UMA metrics.
- void RecordFullscreenPlayback(
- JNIEnv*, jobject, bool is_portrait_video, bool is_orientation_portrait);
+ void RecordFullscreenPlayback(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ bool is_portrait_video,
+ bool is_orientation_portrait);
void RecordExitFullscreenPlayback(
- JNIEnv*, jobject, bool is_portrait_video,
+ JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ bool is_portrait_video,
long playback_duration_in_milliseconds_before_orientation_change,
long playback_duration_in_milliseconds_after_orientation_change);
diff --git a/chromium/content/browser/android/content_view_core_impl.cc b/chromium/content/browser/android/content_view_core_impl.cc
index 273d73e6af5..965c21e95f0 100644
--- a/chromium/content/browser/android/content_view_core_impl.cc
+++ b/chromium/content/browser/android/content_view_core_impl.cc
@@ -4,12 +4,15 @@
#include "content/browser/android/content_view_core_impl.h"
+#include <stddef.h>
+
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
@@ -25,7 +28,6 @@
#include "content/browser/geolocation/geolocation_service_context.h"
#include "content/browser/media/media_web_contents_observer.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
-#include "content/browser/renderer_host/input/motion_event_android.h"
#include "content/browser/renderer_host/input/web_input_event_builders_android.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -52,6 +54,7 @@
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/android/view_android.h"
#include "ui/android/window_android.h"
+#include "ui/events/android/motion_event_android.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -211,15 +214,15 @@ ContentViewCoreImpl::ContentViewCoreImpl(
web_contents_(static_cast<WebContentsImpl*>(web_contents)),
root_layer_(cc::SolidColorLayer::Create(Compositor::LayerSettings())),
page_scale_(1),
- view_android_(new ui::ViewAndroid(view_android_delegate, window_android)),
- dpi_scale_(ui::GetScaleFactorForNativeView(view_android_.get())),
+ dpi_scale_(ui::GetScaleFactorForNativeView(this)),
window_android_(window_android),
device_orientation_(0),
accessibility_enabled_(false) {
CHECK(web_contents) <<
"A ContentViewCoreImpl should be created with a valid WebContents.";
DCHECK(window_android_);
-
+ DCHECK(view_android_delegate);
+ view_android_delegate_.Reset(AttachCurrentThread(), view_android_delegate);
root_layer_->SetBackgroundColor(GetBackgroundColor(env, obj));
gfx::Size physical_size(
Java_ContentViewCore_getPhysicalBackingWidthPix(env, obj),
@@ -257,19 +260,22 @@ ContentViewCoreImpl::~ContentViewCoreImpl() {
}
base::android::ScopedJavaLocalRef<jobject>
-ContentViewCoreImpl::GetWebContentsAndroid(JNIEnv* env, jobject obj) {
+ContentViewCoreImpl::GetWebContentsAndroid(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return web_contents_->GetJavaWebContents();
}
base::android::ScopedJavaLocalRef<jobject>
-ContentViewCoreImpl::GetJavaWindowAndroid(JNIEnv* env, jobject obj) {
+ContentViewCoreImpl::GetJavaWindowAndroid(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (!window_android_)
return ScopedJavaLocalRef<jobject>();
return window_android_->GetJavaObject();
}
-void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(JNIEnv* env,
- jobject obj) {
+void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
DCHECK(env->IsSameObject(java_ref_.get(env).obj(), obj));
java_ref_.reset();
// Java peer has gone, ContentViewCore is not functional and waits to
@@ -310,11 +316,13 @@ void ContentViewCoreImpl::RenderViewHostChanged(RenderViewHost* old_host,
old_pid = GetRenderProcessIdFromRenderViewHost(old_host);
RenderWidgetHostViewAndroid* view =
- static_cast<RenderWidgetHostViewAndroid*>(old_host->GetView());
+ static_cast<RenderWidgetHostViewAndroid*>(
+ old_host->GetWidget()->GetView());
if (view)
view->SetContentViewCore(NULL);
- view = static_cast<RenderWidgetHostViewAndroid*>(new_host->GetView());
+ view = static_cast<RenderWidgetHostViewAndroid*>(
+ new_host->GetWidget()->GetView());
if (view)
view->SetContentViewCore(this);
}
@@ -342,6 +350,7 @@ RenderWidgetHostViewAndroid*
rwhv = web_contents_->GetInterstitialPage()
->GetMainFrame()
->GetRenderViewHost()
+ ->GetWidget()
->GetView();
}
}
@@ -561,8 +570,6 @@ bool ContentViewCoreImpl::FilterInputEvent(const blink::WebInputEvent& event) {
gesture_type,
gesture.x * dpi_scale(),
gesture.y * dpi_scale());
-
- // TODO(jdduke): Also report double-tap UMA, crbug/347568.
}
bool ContentViewCoreImpl::HasFocus() {
@@ -606,18 +613,18 @@ void ContentViewCoreImpl::OnSelectionEvent(ui::SelectionEventType event,
selection_rect_pix.right(), selection_rect_pix.bottom());
}
-void ContentViewCoreImpl::ShowPastePopup(int x_dip, int y_dip) {
+bool ContentViewCoreImpl::ShowPastePopup(int x_dip, int y_dip) {
RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
if (!view)
- return;
+ return false;
view->OnShowingPastePopup(gfx::PointF(x_dip, y_dip));
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null())
- return;
- Java_ContentViewCore_showPastePopupWithFeedback(
+ return false;
+ return Java_ContentViewCore_showPastePopupWithFeedback(
env, obj.obj(), static_cast<jint>(x_dip * dpi_scale()),
static_cast<jint>(y_dip * dpi_scale()));
}
@@ -637,7 +644,8 @@ void ContentViewCoreImpl::GetScaledContentBitmap(
result_callback);
}
-void ContentViewCoreImpl::StartContentIntent(const GURL& content_url) {
+void ContentViewCoreImpl::StartContentIntent(const GURL& content_url,
+ bool is_main_frame) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
if (j_obj.is_null())
@@ -646,7 +654,8 @@ void ContentViewCoreImpl::StartContentIntent(const GURL& content_url) {
ConvertUTF8ToJavaString(env, content_url.spec());
Java_ContentViewCore_startContentIntent(env,
j_obj.obj(),
- jcontent_url.obj());
+ jcontent_url.obj(),
+ is_main_frame);
}
void ContentViewCoreImpl::ShowDisambiguationPopup(
@@ -792,8 +801,9 @@ void ContentViewCoreImpl::SelectBetweenCoordinates(const gfx::PointF& base,
web_contents_->SelectRange(base_point, extent_point);
}
-ui::ViewAndroid* ContentViewCoreImpl::GetViewAndroid() const {
- return view_android_.get();
+ScopedJavaLocalRef<jobject> ContentViewCoreImpl::GetViewAndroidDelegate()
+ const {
+ return base::android::ScopedJavaLocalRef<jobject>(view_android_delegate_);
}
ui::WindowAndroid* ContentViewCoreImpl::GetWindowAndroid() const {
@@ -808,10 +818,11 @@ const scoped_refptr<cc::Layer>& ContentViewCoreImpl::GetLayer() const {
// Methods called from Java via JNI
// ----------------------------------------------------------------------------
-void ContentViewCoreImpl::SelectPopupMenuItems(JNIEnv* env,
- jobject obj,
- jlong selectPopupSourceFrame,
- jintArray indices) {
+void ContentViewCoreImpl::SelectPopupMenuItems(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong selectPopupSourceFrame,
+ const JavaParamRef<jintArray>& indices) {
RenderFrameHostImpl* rfhi =
reinterpret_cast<RenderFrameHostImpl*>(selectPopupSourceFrame);
DCHECK(rfhi);
@@ -833,7 +844,9 @@ WebContents* ContentViewCoreImpl::GetWebContents() const {
return web_contents_;
}
-void ContentViewCoreImpl::SetFocus(JNIEnv* env, jobject obj, jboolean focused) {
+void ContentViewCoreImpl::SetFocus(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean focused) {
SetFocusInternal(focused);
}
@@ -847,62 +860,68 @@ void ContentViewCoreImpl::SetFocusInternal(bool focused) {
GetRenderWidgetHostViewAndroid()->Blur();
}
-void ContentViewCoreImpl::SendOrientationChangeEvent(JNIEnv* env,
- jobject obj,
- jint orientation) {
+void ContentViewCoreImpl::SendOrientationChangeEvent(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint orientation) {
if (device_orientation_ != orientation) {
device_orientation_ = orientation;
SendOrientationChangeEventInternal();
}
}
-jboolean ContentViewCoreImpl::OnTouchEvent(JNIEnv* env,
- jobject obj,
- jobject motion_event,
- jlong time_ms,
- jint android_action,
- jint pointer_count,
- jint history_size,
- jint action_index,
- jfloat pos_x_0,
- jfloat pos_y_0,
- jfloat pos_x_1,
- jfloat pos_y_1,
- jint pointer_id_0,
- jint pointer_id_1,
- jfloat touch_major_0,
- jfloat touch_major_1,
- jfloat touch_minor_0,
- jfloat touch_minor_1,
- jfloat orientation_0,
- jfloat orientation_1,
- jfloat raw_pos_x,
- jfloat raw_pos_y,
- jint android_tool_type_0,
- jint android_tool_type_1,
- jint android_button_state,
- jint android_meta_state,
- jboolean is_touch_handle_event) {
+jboolean ContentViewCoreImpl::OnTouchEvent(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& motion_event,
+ jlong time_ms,
+ jint android_action,
+ jint pointer_count,
+ jint history_size,
+ jint action_index,
+ jfloat pos_x_0,
+ jfloat pos_y_0,
+ jfloat pos_x_1,
+ jfloat pos_y_1,
+ jint pointer_id_0,
+ jint pointer_id_1,
+ jfloat touch_major_0,
+ jfloat touch_major_1,
+ jfloat touch_minor_0,
+ jfloat touch_minor_1,
+ jfloat orientation_0,
+ jfloat orientation_1,
+ jfloat tilt_0,
+ jfloat tilt_1,
+ jfloat raw_pos_x,
+ jfloat raw_pos_y,
+ jint android_tool_type_0,
+ jint android_tool_type_1,
+ jint android_button_state,
+ jint android_meta_state,
+ jboolean is_touch_handle_event) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
// Avoid synthesizing a touch event if it cannot be forwarded.
if (!rwhv)
return false;
- MotionEventAndroid::Pointer pointer0(pointer_id_0,
+ ui::MotionEventAndroid::Pointer pointer0(pointer_id_0,
pos_x_0,
pos_y_0,
touch_major_0,
touch_minor_0,
orientation_0,
+ tilt_0,
android_tool_type_0);
- MotionEventAndroid::Pointer pointer1(pointer_id_1,
+ ui::MotionEventAndroid::Pointer pointer1(pointer_id_1,
pos_x_1,
pos_y_1,
touch_major_1,
touch_minor_1,
orientation_1,
+ tilt_1,
android_tool_type_1);
- MotionEventAndroid event(1.f / dpi_scale(),
+ ui::MotionEventAndroid event(1.f / dpi_scale(),
env,
motion_event,
time_ms,
@@ -925,11 +944,12 @@ float ContentViewCoreImpl::GetDpiScale() const {
return dpi_scale_;
}
-jboolean ContentViewCoreImpl::SendMouseMoveEvent(JNIEnv* env,
- jobject obj,
- jlong time_ms,
- jfloat x,
- jfloat y) {
+jboolean ContentViewCoreImpl::SendMouseMoveEvent(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (!rwhv)
return false;
@@ -943,14 +963,15 @@ jboolean ContentViewCoreImpl::SendMouseMoveEvent(JNIEnv* env,
return true;
}
-jboolean ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv* env,
- jobject obj,
- jlong time_ms,
- jfloat x,
- jfloat y,
- jfloat ticks_x,
- jfloat ticks_y,
- jfloat pixels_per_tick) {
+jboolean ContentViewCoreImpl::SendMouseWheelEvent(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y,
+ jfloat ticks_x,
+ jfloat ticks_y,
+ jfloat pixels_per_tick) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (!rwhv)
return false;
@@ -966,8 +987,10 @@ jboolean ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv* env,
return true;
}
-WebGestureEvent ContentViewCoreImpl::MakeGestureEvent(
- WebInputEvent::Type type, int64 time_ms, float x, float y) const {
+WebGestureEvent ContentViewCoreImpl::MakeGestureEvent(WebInputEvent::Type type,
+ int64_t time_ms,
+ float x,
+ float y) const {
return WebGestureEventBuilder::Build(
type, time_ms / 1000.0, x / dpi_scale(), y / dpi_scale());
}
@@ -980,7 +1003,7 @@ void ContentViewCoreImpl::SendGestureEvent(
}
void ContentViewCoreImpl::ScrollBegin(JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
@@ -996,14 +1019,21 @@ void ContentViewCoreImpl::ScrollBegin(JNIEnv* env,
SendGestureEvent(event);
}
-void ContentViewCoreImpl::ScrollEnd(JNIEnv* env, jobject obj, jlong time_ms) {
+void ContentViewCoreImpl::ScrollEnd(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GestureScrollEnd, time_ms, 0, 0);
SendGestureEvent(event);
}
-void ContentViewCoreImpl::ScrollBy(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y, jfloat dx, jfloat dy) {
+void ContentViewCoreImpl::ScrollBy(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y,
+ jfloat dx,
+ jfloat dy) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GestureScrollUpdate, time_ms, x, y);
event.data.scrollUpdate.deltaX = -dx / dpi_scale();
@@ -1013,7 +1043,7 @@ void ContentViewCoreImpl::ScrollBy(JNIEnv* env, jobject obj, jlong time_ms,
}
void ContentViewCoreImpl::FlingStart(JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
@@ -1029,7 +1059,9 @@ void ContentViewCoreImpl::FlingStart(JNIEnv* env,
SendGestureEvent(event);
}
-void ContentViewCoreImpl::FlingCancel(JNIEnv* env, jobject obj, jlong time_ms) {
+void ContentViewCoreImpl::FlingCancel(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GestureFlingCancel, time_ms, 0, 0);
event.data.flingCancel.preventBoosting = true;
@@ -1037,8 +1069,11 @@ void ContentViewCoreImpl::FlingCancel(JNIEnv* env, jobject obj, jlong time_ms) {
SendGestureEvent(event);
}
-void ContentViewCoreImpl::SingleTap(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y) {
+void ContentViewCoreImpl::SingleTap(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y) {
// Tap gestures should always be preceded by a TapDown, ensuring consistency
// with the touch-based gesture detection pipeline.
WebGestureEvent tap_down_event = MakeGestureEvent(
@@ -1052,8 +1087,11 @@ void ContentViewCoreImpl::SingleTap(JNIEnv* env, jobject obj, jlong time_ms,
SendGestureEvent(tap_event);
}
-void ContentViewCoreImpl::DoubleTap(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y) {
+void ContentViewCoreImpl::DoubleTap(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GestureDoubleTap, time_ms, x, y);
// Set the tap count to 1 even for DoubleTap, in order to be consistent with
@@ -1063,29 +1101,40 @@ void ContentViewCoreImpl::DoubleTap(JNIEnv* env, jobject obj, jlong time_ms,
SendGestureEvent(event);
}
-void ContentViewCoreImpl::LongPress(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y) {
+void ContentViewCoreImpl::LongPress(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GestureLongPress, time_ms, x, y);
SendGestureEvent(event);
}
-void ContentViewCoreImpl::PinchBegin(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y) {
+void ContentViewCoreImpl::PinchBegin(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GesturePinchBegin, time_ms, x, y);
SendGestureEvent(event);
}
-void ContentViewCoreImpl::PinchEnd(JNIEnv* env, jobject obj, jlong time_ms) {
+void ContentViewCoreImpl::PinchEnd(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GesturePinchEnd, time_ms, 0, 0);
SendGestureEvent(event);
}
-void ContentViewCoreImpl::PinchBy(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat anchor_x, jfloat anchor_y,
+void ContentViewCoreImpl::PinchBy(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat anchor_x,
+ jfloat anchor_y,
jfloat delta) {
WebGestureEvent event = MakeGestureEvent(
WebInputEvent::GesturePinchUpdate, time_ms, anchor_x, anchor_y);
@@ -1094,51 +1143,63 @@ void ContentViewCoreImpl::PinchBy(JNIEnv* env, jobject obj, jlong time_ms,
SendGestureEvent(event);
}
-void ContentViewCoreImpl::SelectBetweenCoordinates(JNIEnv* env, jobject obj,
- jfloat x1, jfloat y1,
- jfloat x2, jfloat y2) {
+void ContentViewCoreImpl::SelectBetweenCoordinates(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jfloat x1,
+ jfloat y1,
+ jfloat x2,
+ jfloat y2) {
SelectBetweenCoordinates(gfx::PointF(x1 / dpi_scale(), y1 / dpi_scale()),
gfx::PointF(x2 / dpi_scale(), y2 / dpi_scale()));
}
-void ContentViewCoreImpl::MoveCaret(JNIEnv* env, jobject obj,
- jfloat x, jfloat y) {
+void ContentViewCoreImpl::MoveCaret(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jfloat x,
+ jfloat y) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
rwhv->MoveCaret(gfx::Point(x / dpi_scale_, y / dpi_scale_));
}
-void ContentViewCoreImpl::DismissTextHandles(JNIEnv* env, jobject obj) {
+void ContentViewCoreImpl::DismissTextHandles(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
rwhv->DismissTextHandles();
}
-void ContentViewCoreImpl::SetTextHandlesTemporarilyHidden(JNIEnv* env,
- jobject obj,
- jboolean hidden) {
+void ContentViewCoreImpl::SetTextHandlesTemporarilyHidden(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean hidden) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
rwhv->SetTextHandlesTemporarilyHidden(hidden);
}
-void ContentViewCoreImpl::ResetGestureDetection(JNIEnv* env, jobject obj) {
+void ContentViewCoreImpl::ResetGestureDetection(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
rwhv->ResetGestureDetection();
}
-void ContentViewCoreImpl::SetDoubleTapSupportEnabled(JNIEnv* env,
- jobject obj,
- jboolean enabled) {
+void ContentViewCoreImpl::SetDoubleTapSupportEnabled(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean enabled) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
rwhv->SetDoubleTapSupportEnabled(enabled);
}
-void ContentViewCoreImpl::SetMultiTouchZoomSupportEnabled(JNIEnv* env,
- jobject obj,
- jboolean enabled) {
+void ContentViewCoreImpl::SetMultiTouchZoomSupportEnabled(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean enabled) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
rwhv->SetMultiTouchZoomSupportEnabled(enabled);
@@ -1146,31 +1207,31 @@ void ContentViewCoreImpl::SetMultiTouchZoomSupportEnabled(JNIEnv* env,
void ContentViewCoreImpl::SetAllowJavascriptInterfacesInspection(
JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jboolean allow) {
java_bridge_dispatcher_host_->SetAllowObjectContentsInspection(allow);
}
void ContentViewCoreImpl::AddJavascriptInterface(
JNIEnv* env,
- jobject /* obj */,
- jobject object,
- jstring name,
- jclass safe_annotation_clazz) {
- ScopedJavaLocalRef<jobject> scoped_object(env, object);
- ScopedJavaLocalRef<jclass> scoped_clazz(env, safe_annotation_clazz);
+ const JavaParamRef<jobject>& /* obj */,
+ const JavaParamRef<jobject>& object,
+ const JavaParamRef<jstring>& name,
+ const JavaParamRef<jclass>& safe_annotation_clazz) {
java_bridge_dispatcher_host_->AddNamedObject(
- ConvertJavaStringToUTF8(env, name), scoped_object, scoped_clazz);
+ ConvertJavaStringToUTF8(env, name), object, safe_annotation_clazz);
}
-void ContentViewCoreImpl::RemoveJavascriptInterface(JNIEnv* env,
- jobject /* obj */,
- jstring name) {
+void ContentViewCoreImpl::RemoveJavascriptInterface(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& /* obj */,
+ const JavaParamRef<jstring>& name) {
java_bridge_dispatcher_host_->RemoveNamedObject(
ConvertJavaStringToUTF8(env, name));
}
-void ContentViewCoreImpl::WasResized(JNIEnv* env, jobject obj) {
+void ContentViewCoreImpl::WasResized(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
gfx::Size physical_size(
Java_ContentViewCore_getPhysicalBackingWidthPix(env, obj),
@@ -1185,7 +1246,9 @@ void ContentViewCoreImpl::WasResized(JNIEnv* env, jobject obj) {
}
}
-long ContentViewCoreImpl::GetNativeImeAdapter(JNIEnv* env, jobject obj) {
+long ContentViewCoreImpl::GetNativeImeAdapter(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
if (!rwhva)
return 0;
@@ -1231,21 +1294,24 @@ void ContentViewCoreImpl::UpdateImeAdapter(long native_ime_adapter,
is_non_ime_change);
}
-void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv* env, jobject obj,
- bool enabled) {
+void ContentViewCoreImpl::SetAccessibilityEnabled(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ bool enabled) {
SetAccessibilityEnabledInternal(enabled);
}
-void ContentViewCoreImpl::SetTextTrackSettings(JNIEnv* env,
- jobject obj,
- jboolean textTracksEnabled,
- jstring textTrackBackgroundColor,
- jstring textTrackFontFamily,
- jstring textTrackFontStyle,
- jstring textTrackFontVariant,
- jstring textTrackTextColor,
- jstring textTrackTextShadow,
- jstring textTrackTextSize) {
+void ContentViewCoreImpl::SetTextTrackSettings(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean textTracksEnabled,
+ const JavaParamRef<jstring>& textTrackBackgroundColor,
+ const JavaParamRef<jstring>& textTrackFontFamily,
+ const JavaParamRef<jstring>& textTrackFontStyle,
+ const JavaParamRef<jstring>& textTrackFontVariant,
+ const JavaParamRef<jstring>& textTrackTextColor,
+ const JavaParamRef<jstring>& textTrackTextShadow,
+ const JavaParamRef<jstring>& textTrackTextSize) {
FrameMsg_TextTrackSettings_Params params;
params.text_tracks_enabled = textTracksEnabled;
params.text_track_background_color = ConvertJavaStringToUTF8(
@@ -1297,14 +1363,14 @@ void ContentViewCoreImpl::SetAccessibilityEnabledInternal(bool enabled) {
void ContentViewCoreImpl::SendOrientationChangeEventInternal() {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv)
- rwhv->UpdateScreenInfo(GetViewAndroid());
+ rwhv->UpdateScreenInfo(this);
static_cast<WebContentsImpl*>(web_contents())->
screen_orientation_dispatcher_host()->OnOrientationChange();
}
void ContentViewCoreImpl::ExtractSmartClipData(JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jint x,
jint y,
jint width,
@@ -1320,13 +1386,16 @@ void ContentViewCoreImpl::ExtractSmartClipData(JNIEnv* env,
GetWebContents()->GetRoutingID(), rect));
}
-jint ContentViewCoreImpl::GetCurrentRenderProcessId(JNIEnv* env, jobject obj) {
+jint ContentViewCoreImpl::GetCurrentRenderProcessId(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return GetRenderProcessIdFromRenderViewHost(
web_contents_->GetRenderViewHost());
}
-void ContentViewCoreImpl::SetBackgroundOpaque(JNIEnv* env, jobject jobj,
- jboolean opaque) {
+void ContentViewCoreImpl::SetBackgroundOpaque(JNIEnv* env,
+ const JavaParamRef<jobject>& jobj,
+ jboolean opaque) {
if (GetRenderWidgetHostViewAndroid()) {
if (opaque)
GetRenderWidgetHostViewAndroid()->SetBackgroundColorToDefault();
diff --git a/chromium/content/browser/android/content_view_core_impl.h b/chromium/content/browser/android/content_view_core_impl.h
index a953427f35b..2e0b22694ee 100644
--- a/chromium/content/browser/android/content_view_core_impl.h
+++ b/chromium/content/browser/android/content_view_core_impl.h
@@ -5,26 +5,29 @@
#ifndef CONTENT_BROWSER_ANDROID_CONTENT_VIEW_CORE_IMPL_H_
#define CONTENT_BROWSER_ANDROID_CONTENT_VIEW_CORE_IMPL_H_
+#include <stdint.h>
+
#include <vector>
#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
#include "base/compiler_specific.h"
#include "base/i18n/rtl.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process.h"
-#include "content/browser/android/overscroll_refresh.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/android/overscroll_refresh.h"
+#include "ui/android/view_android.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "url/gurl.h"
namespace ui {
-class ViewAndroid;
class WindowAndroid;
}
@@ -36,7 +39,7 @@ class RenderWidgetHostViewAndroid;
struct MenuItem;
class ContentViewCoreImpl : public ContentViewCore,
- public OverscrollRefreshHandler,
+ public ui::OverscrollRefreshHandler,
public WebContentsObserver {
public:
static ContentViewCoreImpl* FromWebContents(WebContents* web_contents);
@@ -50,10 +53,9 @@ class ContentViewCoreImpl : public ContentViewCore,
// ContentViewCore implementation.
base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override;
WebContents* GetWebContents() const override;
- ui::ViewAndroid* GetViewAndroid() const override;
ui::WindowAndroid* GetWindowAndroid() const override;
const scoped_refptr<cc::Layer>& GetLayer() const override;
- void ShowPastePopup(int x, int y) override;
+ bool ShowPastePopup(int x, int y) override;
void GetScaledContentBitmap(
float scale,
SkColorType preferred_color_type,
@@ -67,58 +69,74 @@ class ContentViewCoreImpl : public ContentViewCore,
int start_offset,
int end_offset)>& callback) override;
+ // ViewAndroid implementation
+ base::android::ScopedJavaLocalRef<jobject> GetViewAndroidDelegate()
+ const override;
+
// --------------------------------------------------------------------------
// Methods called from Java via JNI
// --------------------------------------------------------------------------
- base::android::ScopedJavaLocalRef<jobject> GetWebContentsAndroid(JNIEnv* env,
- jobject obj);
- base::android::ScopedJavaLocalRef<jobject> GetJavaWindowAndroid(JNIEnv* env,
- jobject obj);
+ base::android::ScopedJavaLocalRef<jobject> GetWebContentsAndroid(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ base::android::ScopedJavaLocalRef<jobject> GetJavaWindowAndroid(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
- void OnJavaContentViewCoreDestroyed(JNIEnv* env, jobject obj);
+ void OnJavaContentViewCoreDestroyed(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
// Notifies the ContentViewCore that items were selected in the currently
// showing select popup.
- void SelectPopupMenuItems(JNIEnv* env, jobject obj,
- jlong selectPopupSourceFrame,
- jintArray indices);
-
- void SendOrientationChangeEvent(JNIEnv* env, jobject obj, jint orientation);
- jboolean OnTouchEvent(JNIEnv* env,
- jobject obj,
- jobject motion_event,
- jlong time_ms,
- jint android_action,
- jint pointer_count,
- jint history_size,
- jint action_index,
- jfloat pos_x_0,
- jfloat pos_y_0,
- jfloat pos_x_1,
- jfloat pos_y_1,
- jint pointer_id_0,
- jint pointer_id_1,
- jfloat touch_major_0,
- jfloat touch_major_1,
- jfloat touch_minor_0,
- jfloat touch_minor_1,
- jfloat orientation_0,
- jfloat orientation_1,
- jfloat raw_pos_x,
- jfloat raw_pos_y,
- jint android_tool_type_0,
- jint android_tool_type_1,
- jint android_button_state,
- jint android_meta_state,
- jboolean is_touch_handle_event);
+ void SelectPopupMenuItems(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong selectPopupSourceFrame,
+ const base::android::JavaParamRef<jintArray>& indices);
+
+ void SendOrientationChangeEvent(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint orientation);
+ jboolean OnTouchEvent(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& motion_event,
+ jlong time_ms,
+ jint android_action,
+ jint pointer_count,
+ jint history_size,
+ jint action_index,
+ jfloat pos_x_0,
+ jfloat pos_y_0,
+ jfloat pos_x_1,
+ jfloat pos_y_1,
+ jint pointer_id_0,
+ jint pointer_id_1,
+ jfloat touch_major_0,
+ jfloat touch_major_1,
+ jfloat touch_minor_0,
+ jfloat touch_minor_1,
+ jfloat orientation_0,
+ jfloat orientation_1,
+ jfloat tilt_0,
+ jfloat tilt_1,
+ jfloat raw_pos_x,
+ jfloat raw_pos_y,
+ jint android_tool_type_0,
+ jint android_tool_type_1,
+ jint android_button_state,
+ jint android_meta_state,
+ jboolean is_touch_handle_event);
jboolean SendMouseMoveEvent(JNIEnv* env,
- jobject obj,
+ const base::android::JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y);
jboolean SendMouseWheelEvent(JNIEnv* env,
- jobject obj,
+ const base::android::JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
@@ -126,89 +144,145 @@ class ContentViewCoreImpl : public ContentViewCore,
jfloat ticks_y,
jfloat pixels_per_tick);
void ScrollBegin(JNIEnv* env,
- jobject obj,
+ const base::android::JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
jfloat hintx,
jfloat hinty,
jboolean target_viewport);
- void ScrollEnd(JNIEnv* env, jobject obj, jlong time_ms);
- void ScrollBy(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y, jfloat dx, jfloat dy);
+ void ScrollEnd(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms);
+ void ScrollBy(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y,
+ jfloat dx,
+ jfloat dy);
void FlingStart(JNIEnv* env,
- jobject obj,
+ const base::android::JavaParamRef<jobject>& obj,
jlong time_ms,
jfloat x,
jfloat y,
jfloat vx,
jfloat vy,
jboolean target_viewport);
- void FlingCancel(JNIEnv* env, jobject obj, jlong time_ms);
- void SingleTap(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y);
- void DoubleTap(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y);
- void LongPress(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y);
- void PinchBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y);
- void PinchEnd(JNIEnv* env, jobject obj, jlong time_ms);
- void PinchBy(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y, jfloat delta);
- void SelectBetweenCoordinates(JNIEnv* env, jobject obj,
- jfloat x1, jfloat y1,
- jfloat x2, jfloat y2);
- void MoveCaret(JNIEnv* env, jobject obj, jfloat x, jfloat y);
- void DismissTextHandles(JNIEnv* env, jobject obj);
- void SetTextHandlesTemporarilyHidden(JNIEnv* env,
- jobject obj,
- jboolean hidden);
-
- void ResetGestureDetection(JNIEnv* env, jobject obj);
- void SetDoubleTapSupportEnabled(JNIEnv* env, jobject obj, jboolean enabled);
- void SetMultiTouchZoomSupportEnabled(JNIEnv* env,
- jobject obj,
- jboolean enabled);
-
- long GetNativeImeAdapter(JNIEnv* env, jobject obj);
- void SetFocus(JNIEnv* env, jobject obj, jboolean focused);
+ void FlingCancel(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms);
+ void SingleTap(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y);
+ void DoubleTap(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y);
+ void LongPress(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y);
+ void PinchBegin(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y);
+ void PinchEnd(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms);
+ void PinchBy(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong time_ms,
+ jfloat x,
+ jfloat y,
+ jfloat delta);
+ void SelectBetweenCoordinates(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jfloat x1,
+ jfloat y1,
+ jfloat x2,
+ jfloat y2);
+ void MoveCaret(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jfloat x,
+ jfloat y);
+ void DismissTextHandles(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void SetTextHandlesTemporarilyHidden(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean hidden);
+
+ void ResetGestureDetection(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void SetDoubleTapSupportEnabled(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean enabled);
+ void SetMultiTouchZoomSupportEnabled(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean enabled);
+
+ long GetNativeImeAdapter(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void SetFocus(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean focused);
jint GetBackgroundColor(JNIEnv* env, jobject obj);
void SetBackgroundColor(JNIEnv* env, jobject obj, jint color);
- void SetAllowJavascriptInterfacesInspection(JNIEnv* env,
- jobject obj,
- jboolean allow);
- void AddJavascriptInterface(JNIEnv* env,
- jobject obj,
- jobject object,
- jstring name,
- jclass safe_annotation_clazz);
- void RemoveJavascriptInterface(JNIEnv* env, jobject obj, jstring name);
- void WasResized(JNIEnv* env, jobject obj);
-
- void SetAccessibilityEnabled(JNIEnv* env, jobject obj, bool enabled);
-
- void SetTextTrackSettings(JNIEnv* env,
- jobject obj,
- jboolean textTracksEnabled,
- jstring textTrackBackgroundColor,
- jstring textTrackFontFamily,
- jstring textTrackFontStyle,
- jstring textTrackFontVariant,
- jstring textTrackTextColor,
- jstring textTrackTextShadow,
- jstring textTrackTextSize);
+ void SetAllowJavascriptInterfacesInspection(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean allow);
+ void AddJavascriptInterface(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& object,
+ const base::android::JavaParamRef<jstring>& name,
+ const base::android::JavaParamRef<jclass>& safe_annotation_clazz);
+ void RemoveJavascriptInterface(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& name);
+ void WasResized(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+
+ void SetAccessibilityEnabled(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ bool enabled);
+
+ void SetTextTrackSettings(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean textTracksEnabled,
+ const base::android::JavaParamRef<jstring>& textTrackBackgroundColor,
+ const base::android::JavaParamRef<jstring>& textTrackFontFamily,
+ const base::android::JavaParamRef<jstring>& textTrackFontStyle,
+ const base::android::JavaParamRef<jstring>& textTrackFontVariant,
+ const base::android::JavaParamRef<jstring>& textTrackTextColor,
+ const base::android::JavaParamRef<jstring>& textTrackTextShadow,
+ const base::android::JavaParamRef<jstring>& textTrackTextSize);
void ExtractSmartClipData(JNIEnv* env,
- jobject obj,
+ const base::android::JavaParamRef<jobject>& obj,
jint x,
jint y,
jint width,
jint height);
- void SetBackgroundOpaque(JNIEnv* env, jobject jobj, jboolean opaque);
+ void SetBackgroundOpaque(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj,
+ jboolean opaque);
- jint GetCurrentRenderProcessId(JNIEnv* env, jobject obj);
+ jint GetCurrentRenderProcessId(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
// --------------------------------------------------------------------------
// Public methods that call to Java via JNI
@@ -265,7 +339,7 @@ class ContentViewCoreImpl : public ContentViewCore,
const gfx::PointF& selection_anchor,
const gfx::RectF& selection_rect);
- void StartContentIntent(const GURL& content_url);
+ void StartContentIntent(const GURL& content_url, bool is_main_frame);
// Shows the disambiguation popup
// |rect_pixels| --> window coordinates which |zoomed_bitmap| represents
@@ -340,8 +414,10 @@ class ContentViewCoreImpl : public ContentViewCore,
RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid() const;
- blink::WebGestureEvent MakeGestureEvent(
- blink::WebInputEvent::Type type, int64 time_ms, float x, float y) const;
+ blink::WebGestureEvent MakeGestureEvent(blink::WebInputEvent::Type type,
+ int64_t time_ms,
+ float x,
+ float y) const;
gfx::Size GetViewportSizePix() const;
int GetTopControlsHeightPix() const;
@@ -369,9 +445,8 @@ class ContentViewCoreImpl : public ContentViewCore,
// Page scale factor.
float page_scale_;
- // The Android view that can be used to add and remove decoration layers
- // like AutofillPopup.
- scoped_ptr<ui::ViewAndroid> view_android_;
+ // Java delegate to acquire and release anchor views from the NativeView
+ base::android::ScopedJavaGlobalRef<jobject> view_android_delegate_;
// Device scale factor.
const float dpi_scale_;
diff --git a/chromium/content/browser/android/content_view_render_view.cc b/chromium/content/browser/android/content_view_render_view.cc
index 8b1ea2be9c4..24fdbc2f020 100644
--- a/chromium/content/browser/android/content_view_render_view.cc
+++ b/chromium/content/browser/android/content_view_render_view.cc
@@ -52,12 +52,15 @@ static jlong Init(JNIEnv* env,
return reinterpret_cast<intptr_t>(content_view_render_view);
}
-void ContentViewRenderView::Destroy(JNIEnv* env, jobject obj) {
+void ContentViewRenderView::Destroy(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
delete this;
}
void ContentViewRenderView::SetCurrentContentViewCore(
- JNIEnv* env, jobject obj, jlong native_content_view_core) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong native_content_view_core) {
InitCompositor();
ContentViewCoreImpl* content_view_core =
reinterpret_cast<ContentViewCoreImpl*>(native_content_view_core);
@@ -65,19 +68,25 @@ void ContentViewRenderView::SetCurrentContentViewCore(
: scoped_refptr<cc::Layer>());
}
-void ContentViewRenderView::SurfaceCreated(
- JNIEnv* env, jobject obj) {
+void ContentViewRenderView::SurfaceCreated(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
current_surface_format_ = 0;
InitCompositor();
}
-void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env, jobject obj) {
+void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
compositor_->SetSurface(NULL);
current_surface_format_ = 0;
}
-void ContentViewRenderView::SurfaceChanged(JNIEnv* env, jobject obj,
- jint format, jint width, jint height, jobject surface) {
+void ContentViewRenderView::SurfaceChanged(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint format,
+ jint width,
+ jint height,
+ const JavaParamRef<jobject>& surface) {
if (current_surface_format_ != format) {
current_surface_format_ = format;
compositor_->SetSurface(surface);
@@ -86,19 +95,23 @@ void ContentViewRenderView::SurfaceChanged(JNIEnv* env, jobject obj,
}
void ContentViewRenderView::SetOverlayVideoMode(
- JNIEnv* env, jobject obj, bool enabled) {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ bool enabled) {
compositor_->SetHasTransparentBackground(enabled);
SetNeedsComposite(env, obj);
}
-void ContentViewRenderView::SetNeedsComposite(JNIEnv* env, jobject obj) {
+void ContentViewRenderView::SetNeedsComposite(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (compositor_)
compositor_->SetNeedsComposite();
}
-void ContentViewRenderView::Layout() {
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_ContentViewRenderView_onCompositorLayout(env, java_obj_.obj());
+void ContentViewRenderView::UpdateLayerTreeHost() {
+ // TODO(wkorman): Rename Layout to UpdateLayerTreeHost in all Android
+ // Compositor related classes.
}
void ContentViewRenderView::OnSwapBuffersCompleted(int pending_swap_buffers) {
@@ -111,8 +124,9 @@ void ContentViewRenderView::InitCompositor() {
compositor_.reset(Compositor::Create(this, root_window_));
}
-jlong ContentViewRenderView::GetUIResourceProvider(JNIEnv* env,
- jobject obj) {
+jlong ContentViewRenderView::GetUIResourceProvider(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (!compositor_)
return 0;
return reinterpret_cast<intptr_t>(&compositor_->GetUIResourceProvider());
diff --git a/chromium/content/browser/android/content_view_render_view.h b/chromium/content/browser/android/content_view_render_view.h
index a07b7957aef..c571de0fd4e 100644
--- a/chromium/content/browser/android/content_view_render_view.h
+++ b/chromium/content/browser/android/content_view_render_view.h
@@ -7,6 +7,7 @@
#include "base/android/jni_weak_ref.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/android/compositor_client.h"
@@ -29,22 +30,34 @@ class ContentViewRenderView : public CompositorClient {
gfx::NativeWindow root_window);
// Methods called from Java via JNI -----------------------------------------
- void Destroy(JNIEnv* env, jobject obj);
- void SetCurrentContentViewCore(JNIEnv* env, jobject obj,
- jlong native_content_view_core);
- void SurfaceCreated(JNIEnv* env, jobject obj);
- void SurfaceDestroyed(JNIEnv* env, jobject obj);
- void SurfaceChanged(JNIEnv* env, jobject obj,
- jint format, jint width, jint height, jobject surface);
- void SetOverlayVideoMode(JNIEnv* env, jobject obj, bool enabled);
- void SetNeedsComposite(JNIEnv* env, jobject obj);
+ void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void SetCurrentContentViewCore(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong native_content_view_core);
+ void SurfaceCreated(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void SurfaceDestroyed(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void SurfaceChanged(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint format,
+ jint width,
+ jint height,
+ const base::android::JavaParamRef<jobject>& surface);
+ void SetOverlayVideoMode(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ bool enabled);
+ void SetNeedsComposite(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
// TODO(yusufo): Remove this once the compositor code is
// refactored to use a unified system.
- jlong GetUIResourceProvider(JNIEnv* env, jobject obj);
+ jlong GetUIResourceProvider(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
// CompositorClient implementation
- void Layout() override;
+ void UpdateLayerTreeHost() override;
void OnSwapBuffersCompleted(int pending_swap_buffers) override;
private:
diff --git a/chromium/content/browser/android/content_view_statics.cc b/chromium/content/browser/android/content_view_statics.cc
index e34ccf87381..f5e72676f13 100644
--- a/chromium/content/browser/android/content_view_statics.cc
+++ b/chromium/content/browser/android/content_view_statics.cc
@@ -8,7 +8,6 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
-#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "content/browser/android/content_view_statics.h"
diff --git a/chromium/content/browser/android/date_time_chooser_android.cc b/chromium/content/browser/android/date_time_chooser_android.cc
index b555ef6d6b2..35d703855c7 100644
--- a/chromium/content/browser/android/date_time_chooser_android.cc
+++ b/chromium/content/browser/android/date_time_chooser_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/android/date_time_chooser_android.h"
+#include <stddef.h>
+
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/i18n/char_iterator.h"
@@ -19,6 +21,7 @@ using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF8ToJavaString;
using base::android::ConvertUTF16ToJavaString;
+using base::android::JavaRef;
namespace {
@@ -50,12 +53,13 @@ DateTimeChooserAndroid::~DateTimeChooserAndroid() {
}
void DateTimeChooserAndroid::ReplaceDateTime(JNIEnv* env,
- jobject,
+ const JavaRef<jobject>&,
jdouble value) {
host_->Send(new ViewMsg_ReplaceDateTime(host_->GetRoutingID(), value));
}
-void DateTimeChooserAndroid::CancelDialog(JNIEnv* env, jobject) {
+void DateTimeChooserAndroid::CancelDialog(JNIEnv* env,
+ const JavaRef<jobject>&) {
host_->Send(new ViewMsg_CancelDateTimeDialog(host_->GetRoutingID()));
}
@@ -100,7 +104,7 @@ void DateTimeChooserAndroid::ShowDialog(
step,
suggestions_array.obj()));
if (j_date_time_chooser_.is_null())
- ReplaceDateTime(env, j_date_time_chooser_.obj(), dialog_value);
+ ReplaceDateTime(env, j_date_time_chooser_, dialog_value);
}
// ----------------------------------------------------------------------------
diff --git a/chromium/content/browser/android/date_time_chooser_android.h b/chromium/content/browser/android/date_time_chooser_android.h
index 6e6c8954b9c..05a8bdd3dd7 100644
--- a/chromium/content/browser/android/date_time_chooser_android.h
+++ b/chromium/content/browser/android/date_time_chooser_android.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/android/jni_weak_ref.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/gfx/native_widget_types.h"
@@ -38,10 +39,12 @@ class DateTimeChooserAndroid {
const std::vector<DateTimeSuggestion>& suggestions);
// Replaces the current value
- void ReplaceDateTime(JNIEnv* env, jobject, jdouble value);
+ void ReplaceDateTime(JNIEnv* env,
+ const base::android::JavaRef<jobject>&,
+ jdouble value);
// Closes the dialog without propagating any changes.
- void CancelDialog(JNIEnv* env, jobject);
+ void CancelDialog(JNIEnv* env, const base::android::JavaRef<jobject>&);
private:
RenderViewHost* host_;
diff --git a/chromium/content/browser/android/deferred_download_observer.h b/chromium/content/browser/android/deferred_download_observer.h
index f1df3178ba9..0c11db8cee5 100644
--- a/chromium/content/browser/android/deferred_download_observer.h
+++ b/chromium/content/browser/android/deferred_download_observer.h
@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
diff --git a/chromium/content/browser/android/download_controller_android_impl.cc b/chromium/content/browser/android/download_controller_android_impl.cc
index 546438c709d..feb8de30152 100644
--- a/chromium/content/browser/android/download_controller_android_impl.cc
+++ b/chromium/content/browser/android/download_controller_android_impl.cc
@@ -4,6 +4,9 @@
#include "content/browser/android/download_controller_android_impl.h"
+#include <utility>
+
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
@@ -91,7 +94,7 @@ void CreateContextMenuDownload(int render_process_id,
if (!is_link && extra_headers.empty())
dl_params->set_prefer_cache(true);
dl_params->set_prompt(false);
- dlm->DownloadUrl(dl_params.Pass());
+ dlm->DownloadUrl(std::move(dl_params));
}
} // namespace
@@ -181,16 +184,10 @@ void DownloadControllerAndroidImpl::CancelDeferredDownload(
}
void DownloadControllerAndroidImpl::AcquireFileAccessPermission(
- int render_process_id,
- int render_view_id,
+ WebContents* web_contents,
const DownloadControllerAndroid::AcquireFileAccessPermissionCallback& cb) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- WebContents* web_contents = GetWebContents(render_process_id, render_view_id);
- if (!web_contents) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, base::Bind(cb, false));
- return;
- }
+ DCHECK(web_contents);
ScopedJavaLocalRef<jobject> view =
GetContentViewCoreFromWebContents(web_contents);
@@ -259,16 +256,10 @@ void DownloadControllerAndroidImpl::PrepareDownloadInfo(
net::CookieStore* cookie_store = request->context()->cookie_store();
if (cookie_store) {
- net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster();
- if (cookie_monster) {
- cookie_monster->GetAllCookiesForURLAsync(
- request->url(),
- base::Bind(&DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies,
- base::Unretained(this), info_android, callback,
- global_id));
- } else {
- DoLoadCookies(info_android, callback, global_id);
- }
+ cookie_store->GetAllCookiesForURLAsync(
+ request->url(),
+ base::Bind(&DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies,
+ base::Unretained(this), info_android, callback, global_id));
} else {
// Can't get any cookies, start android download.
callback.Run(info_android);
@@ -360,7 +351,7 @@ void DownloadControllerAndroidImpl::StartAndroidDownload(
}
AcquireFileAccessPermission(
- render_process_id, render_view_id,
+ web_contents,
base::Bind(&DownloadControllerAndroidImpl::StartAndroidDownloadInternal,
base::Unretained(this), render_process_id, render_view_id,
info));
@@ -536,9 +527,8 @@ void DownloadControllerAndroidImpl::StartContextMenuDownload(
int process_id = web_contents->GetRenderProcessHost()->GetID();
int routing_id = web_contents->GetRoutingID();
AcquireFileAccessPermission(
- process_id, routing_id,
- base::Bind(&CreateContextMenuDownload, process_id, routing_id, params,
- is_link, extra_headers));
+ web_contents, base::Bind(&CreateContextMenuDownload, process_id,
+ routing_id, params, is_link, extra_headers));
}
void DownloadControllerAndroidImpl::DangerousDownloadValidated(
diff --git a/chromium/content/browser/android/download_controller_android_impl.h b/chromium/content/browser/android/download_controller_android_impl.h
index 112167ddef2..36c108e349d 100644
--- a/chromium/content/browser/android/download_controller_android_impl.h
+++ b/chromium/content/browser/android/download_controller_android_impl.h
@@ -21,9 +21,12 @@
#include <string>
+#include <stdint.h>
+
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/singleton.h"
#include "content/public/browser/android/download_controller_android.h"
@@ -56,8 +59,7 @@ class DownloadControllerAndroidImpl : public DownloadControllerAndroid,
// DownloadControllerAndroid implementation.
void AcquireFileAccessPermission(
- int render_process_id,
- int render_view_id,
+ WebContents* web_contents,
const AcquireFileAccessPermissionCallback& callback) override;
private:
@@ -71,7 +73,7 @@ class DownloadControllerAndroidImpl : public DownloadControllerAndroid,
GURL url;
// The original URL before any redirection by the server for this URL.
GURL original_url;
- int64 total_bytes;
+ int64_t total_bytes;
std::string content_disposition;
std::string original_mime_type;
std::string user_agent;
diff --git a/chromium/content/browser/android/edge_effect.cc b/chromium/content/browser/android/edge_effect.cc
deleted file mode 100644
index df84c3f2775..00000000000
--- a/chromium/content/browser/android/edge_effect.cc
+++ /dev/null
@@ -1,360 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/edge_effect.h"
-
-#include "cc/layers/layer.h"
-#include "cc/layers/ui_resource_layer.h"
-#include "content/browser/android/animation_utils.h"
-#include "content/public/browser/android/compositor.h"
-#include "ui/android/resources/resource_manager.h"
-#include "ui/android/resources/system_ui_resource_type.h"
-
-namespace content {
-
-namespace {
-
-const ui::SystemUIResourceType kEdgeResourceId = ui::OVERSCROLL_EDGE;
-const ui::SystemUIResourceType kGlowResourceId = ui::OVERSCROLL_GLOW;
-
-// Time it will take the effect to fully recede in ms
-const int kRecedeTimeMs = 1000;
-
-// Time it will take before a pulled glow begins receding in ms
-const int kPullTimeMs = 167;
-
-// Time it will take in ms for a pulled glow to decay before release
-const int kPullDecayTimeMs = 1000;
-
-const float kMaxAlpha = 1.f;
-const float kHeldEdgeScaleY = .5f;
-
-const float kMaxGlowHeight = 4.f;
-
-const float kPullGlowBegin = 1.f;
-const float kPullEdgeBegin = 0.6f;
-
-// Min/max velocity that will be absorbed
-const float kMinVelocity = 100.f;
-const float kMaxVelocity = 10000.f;
-
-const float kEpsilon = 0.001f;
-
-const float kGlowHeightWidthRatio = 0.25f;
-
-// How much dragging should effect the height of the edge image.
-// Number determined by user testing.
-const int kPullDistanceEdgeFactor = 7;
-
-// How much dragging should effect the height of the glow image.
-// Number determined by user testing.
-const int kPullDistanceGlowFactor = 7;
-const float kPullDistanceAlphaGlowFactor = 1.1f;
-
-const int kVelocityEdgeFactor = 8;
-const int kVelocityGlowFactor = 12;
-
-const float kEdgeHeightAtMdpi = 12.f;
-const float kGlowHeightAtMdpi = 128.f;
-
-} // namespace
-
-class EdgeEffect::EffectLayer {
- public:
- EffectLayer(ui::SystemUIResourceType resource_type,
- ui::ResourceManager* resource_manager)
- : ui_resource_layer_(
- cc::UIResourceLayer::Create(Compositor::LayerSettings())),
- resource_type_(resource_type),
- resource_manager_(resource_manager) {}
-
- ~EffectLayer() { ui_resource_layer_->RemoveFromParent(); }
-
- void SetParent(cc::Layer* parent) {
- if (ui_resource_layer_->parent() != parent)
- parent->AddChild(ui_resource_layer_);
- }
-
- void Disable() { ui_resource_layer_->SetIsDrawable(false); }
-
- void Update(const gfx::Size& size,
- const gfx::Transform& transform,
- float opacity) {
- ui_resource_layer_->SetUIResourceId(resource_manager_->GetUIResourceId(
- ui::ANDROID_RESOURCE_TYPE_SYSTEM, resource_type_));
- ui_resource_layer_->SetIsDrawable(true);
- ui_resource_layer_->SetTransformOrigin(
- gfx::Point3F(size.width() * 0.5f, 0, 0));
- ui_resource_layer_->SetTransform(transform);
- ui_resource_layer_->SetBounds(size);
- ui_resource_layer_->SetOpacity(Clamp(opacity, 0.f, 1.f));
- }
-
- scoped_refptr<cc::UIResourceLayer> ui_resource_layer_;
- ui::SystemUIResourceType resource_type_;
- ui::ResourceManager* resource_manager_;
-
- DISALLOW_COPY_AND_ASSIGN(EffectLayer);
-};
-
-EdgeEffect::EdgeEffect(ui::ResourceManager* resource_manager,
- float device_scale_factor)
- : edge_(new EffectLayer(kEdgeResourceId, resource_manager)),
- glow_(new EffectLayer(kGlowResourceId, resource_manager)),
- base_edge_height_(kEdgeHeightAtMdpi * device_scale_factor),
- base_glow_height_(kGlowHeightAtMdpi * device_scale_factor),
- edge_alpha_(0),
- edge_scale_y_(0),
- glow_alpha_(0),
- glow_scale_y_(0),
- edge_alpha_start_(0),
- edge_alpha_finish_(0),
- edge_scale_y_start_(0),
- edge_scale_y_finish_(0),
- glow_alpha_start_(0),
- glow_alpha_finish_(0),
- glow_scale_y_start_(0),
- glow_scale_y_finish_(0),
- state_(STATE_IDLE),
- pull_distance_(0) {
-}
-
-EdgeEffect::~EdgeEffect() {
-}
-
-bool EdgeEffect::IsFinished() const {
- return state_ == STATE_IDLE;
-}
-
-void EdgeEffect::Finish() {
- edge_->Disable();
- glow_->Disable();
- pull_distance_ = 0;
- state_ = STATE_IDLE;
-}
-
-void EdgeEffect::Pull(base::TimeTicks current_time,
- float delta_distance,
- float displacement) {
- if (state_ == STATE_PULL_DECAY && current_time - start_time_ < duration_) {
- return;
- }
- if (state_ != STATE_PULL) {
- glow_scale_y_ = kPullGlowBegin;
- }
- state_ = STATE_PULL;
-
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kPullTimeMs);
-
- float abs_delta_distance = std::abs(delta_distance);
- pull_distance_ += delta_distance;
- float distance = std::abs(pull_distance_);
-
- edge_alpha_ = edge_alpha_start_ = Clamp(distance, kPullEdgeBegin, kMaxAlpha);
- edge_scale_y_ = edge_scale_y_start_ =
- Clamp(distance * kPullDistanceEdgeFactor, kHeldEdgeScaleY, 1.f);
-
- glow_alpha_ = glow_alpha_start_ =
- std::min(kMaxAlpha,
- glow_alpha_ + abs_delta_distance * kPullDistanceAlphaGlowFactor);
-
- float glow_change = abs_delta_distance;
- if (delta_distance > 0 && pull_distance_ < 0)
- glow_change = -glow_change;
- if (pull_distance_ == 0)
- glow_scale_y_ = 0;
-
- // Do not allow glow to get larger than kMaxGlowHeight.
- glow_scale_y_ = glow_scale_y_start_ =
- Clamp(glow_scale_y_ + glow_change * kPullDistanceGlowFactor,
- 0.f,
- kMaxGlowHeight);
-
- edge_alpha_finish_ = edge_alpha_;
- edge_scale_y_finish_ = edge_scale_y_;
- glow_alpha_finish_ = glow_alpha_;
- glow_scale_y_finish_ = glow_scale_y_;
-}
-
-void EdgeEffect::Release(base::TimeTicks current_time) {
- pull_distance_ = 0;
-
- if (state_ != STATE_PULL && state_ != STATE_PULL_DECAY)
- return;
-
- state_ = STATE_RECEDE;
- edge_alpha_start_ = edge_alpha_;
- edge_scale_y_start_ = edge_scale_y_;
- glow_alpha_start_ = glow_alpha_;
- glow_scale_y_start_ = glow_scale_y_;
-
- edge_alpha_finish_ = 0.f;
- edge_scale_y_finish_ = 0.f;
- glow_alpha_finish_ = 0.f;
- glow_scale_y_finish_ = 0.f;
-
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kRecedeTimeMs);
-}
-
-void EdgeEffect::Absorb(base::TimeTicks current_time, float velocity) {
- state_ = STATE_ABSORB;
- velocity = Clamp(std::abs(velocity), kMinVelocity, kMaxVelocity);
-
- start_time_ = current_time;
- // This should never be less than 1 millisecond.
- duration_ = base::TimeDelta::FromMilliseconds(0.15f + (velocity * 0.02f));
-
- // The edge should always be at least partially visible, regardless
- // of velocity.
- edge_alpha_start_ = 0.f;
- edge_scale_y_ = edge_scale_y_start_ = 0.f;
- // The glow depends more on the velocity, and therefore starts out
- // nearly invisible.
- glow_alpha_start_ = 0.3f;
- glow_scale_y_start_ = 0.f;
-
- // Factor the velocity by 8. Testing on device shows this works best to
- // reflect the strength of the user's scrolling.
- edge_alpha_finish_ = Clamp(velocity * kVelocityEdgeFactor, 0.f, 1.f);
- // Edge should never get larger than the size of its asset.
- edge_scale_y_finish_ =
- Clamp(velocity * kVelocityEdgeFactor, kHeldEdgeScaleY, 1.f);
-
- // Growth for the size of the glow should be quadratic to properly
- // respond
- // to a user's scrolling speed. The faster the scrolling speed, the more
- // intense the effect should be for both the size and the saturation.
- glow_scale_y_finish_ =
- std::min(0.025f + (velocity * (velocity / 100) * 0.00015f), 1.75f);
- // Alpha should change for the glow as well as size.
- glow_alpha_finish_ = Clamp(
- glow_alpha_start_, velocity * kVelocityGlowFactor * .00001f, kMaxAlpha);
-}
-
-bool EdgeEffect::Update(base::TimeTicks current_time) {
- if (IsFinished())
- return false;
-
- const double dt = (current_time - start_time_).InMilliseconds();
- const double t = std::min(dt / duration_.InMilliseconds(), 1.);
- const float interp = static_cast<float>(Damp(t, 1.));
-
- edge_alpha_ = Lerp(edge_alpha_start_, edge_alpha_finish_, interp);
- edge_scale_y_ = Lerp(edge_scale_y_start_, edge_scale_y_finish_, interp);
- glow_alpha_ = Lerp(glow_alpha_start_, glow_alpha_finish_, interp);
- glow_scale_y_ = Lerp(glow_scale_y_start_, glow_scale_y_finish_, interp);
-
- if (t >= 1.f - kEpsilon) {
- switch (state_) {
- case STATE_ABSORB:
- state_ = STATE_RECEDE;
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kRecedeTimeMs);
-
- edge_alpha_start_ = edge_alpha_;
- edge_scale_y_start_ = edge_scale_y_;
- glow_alpha_start_ = glow_alpha_;
- glow_scale_y_start_ = glow_scale_y_;
-
- // After absorb, the glow and edge should fade to nothing.
- edge_alpha_finish_ = 0.f;
- edge_scale_y_finish_ = 0.f;
- glow_alpha_finish_ = 0.f;
- glow_scale_y_finish_ = 0.f;
- break;
- case STATE_PULL:
- state_ = STATE_PULL_DECAY;
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kPullDecayTimeMs);
-
- edge_alpha_start_ = edge_alpha_;
- edge_scale_y_start_ = edge_scale_y_;
- glow_alpha_start_ = glow_alpha_;
- glow_scale_y_start_ = glow_scale_y_;
-
- // After pull, the glow and edge should fade to nothing.
- edge_alpha_finish_ = 0.f;
- edge_scale_y_finish_ = 0.f;
- glow_alpha_finish_ = 0.f;
- glow_scale_y_finish_ = 0.f;
- break;
- case STATE_PULL_DECAY: {
- // When receding, we want edge to decrease more slowly
- // than the glow.
- const float factor =
- glow_scale_y_finish_
- ? 1 / (glow_scale_y_finish_ * glow_scale_y_finish_)
- : std::numeric_limits<float>::max();
- edge_scale_y_ =
- edge_scale_y_start_ +
- (edge_scale_y_finish_ - edge_scale_y_start_) * interp * factor;
- state_ = STATE_RECEDE;
- } break;
- case STATE_RECEDE:
- Finish();
- break;
- default:
- break;
- }
- }
-
- if (state_ == STATE_RECEDE && glow_scale_y_ <= 0 && edge_scale_y_ <= 0)
- Finish();
-
- return !IsFinished();
-}
-
-float EdgeEffect::GetAlpha() const {
- return IsFinished() ? 0.f : std::max(glow_alpha_, edge_alpha_);
-}
-
-void EdgeEffect::ApplyToLayers(Edge edge,
- const gfx::SizeF& viewport_size,
- float offset) {
- if (IsFinished())
- return;
-
- // An empty window size, while meaningless, is also relatively harmless, and
- // will simply prevent any drawing of the layers.
- if (viewport_size.IsEmpty()) {
- edge_->Disable();
- glow_->Disable();
- return;
- }
-
- gfx::SizeF size = ComputeOrientedSize(edge, viewport_size);
- gfx::Transform transform = ComputeTransform(edge, viewport_size, offset);
-
- // Glow
- const int scaled_glow_height = static_cast<int>(
- std::min(base_glow_height_ * glow_scale_y_ * kGlowHeightWidthRatio * 0.6f,
- base_glow_height_ * kMaxGlowHeight) +
- 0.5f);
- const gfx::Size glow_size(size.width(), scaled_glow_height);
- glow_->Update(glow_size, transform, glow_alpha_);
-
- // Edge
- const int scaled_edge_height =
- static_cast<int>(base_edge_height_ * edge_scale_y_);
- const gfx::Size edge_size(size.width(), scaled_edge_height);
- edge_->Update(edge_size, transform, edge_alpha_);
-}
-
-void EdgeEffect::SetParent(cc::Layer* parent) {
- edge_->SetParent(parent);
- glow_->SetParent(parent);
-}
-
-// static
-void EdgeEffect::PreloadResources(ui::ResourceManager* resource_manager) {
- DCHECK(resource_manager);
- resource_manager->PreloadResource(ui::ANDROID_RESOURCE_TYPE_SYSTEM,
- kEdgeResourceId);
- resource_manager->PreloadResource(ui::ANDROID_RESOURCE_TYPE_SYSTEM,
- kGlowResourceId);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/edge_effect.h b/chromium/content/browser/android/edge_effect.h
deleted file mode 100644
index 587f1898c64..00000000000
--- a/chromium/content/browser/android/edge_effect.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_EDGE_EFFECT_H_
-#define CONTENT_BROWSER_ANDROID_EDGE_EFFECT_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "content/browser/android/edge_effect_base.h"
-
-namespace cc {
-class Layer;
-}
-
-namespace ui {
-class ResourceManager;
-}
-
-namespace content {
-
-// |EdgeEffect| mirrors its Android counterpart, EdgeEffect.java.
-// Conscious tradeoffs were made to align this as closely as possible with the
-// the original Android java version.
-// All coordinates and dimensions are in device pixels.
-class EdgeEffect : public EdgeEffectBase {
- public:
- explicit EdgeEffect(ui::ResourceManager* resource_manager,
- float device_scale_factor);
- ~EdgeEffect() override;
-
- void Pull(base::TimeTicks current_time,
- float delta_distance,
- float displacement) override;
- void Absorb(base::TimeTicks current_time, float velocity) override;
- bool Update(base::TimeTicks current_time) override;
- void Release(base::TimeTicks current_time) override;
-
- void Finish() override;
- bool IsFinished() const override;
- float GetAlpha() const override;
-
- void ApplyToLayers(Edge edge,
- const gfx::SizeF& viewport_size,
- float offset) override;
- void SetParent(cc::Layer* parent) override;
-
- // Thread-safe trigger to load resources.
- static void PreloadResources(ui::ResourceManager* resource_manager);
-
- private:
- class EffectLayer;
- scoped_ptr<EffectLayer> edge_;
- scoped_ptr<EffectLayer> glow_;
-
- float base_edge_height_;
- float base_glow_height_;
-
- float edge_alpha_;
- float edge_scale_y_;
- float glow_alpha_;
- float glow_scale_y_;
-
- float edge_alpha_start_;
- float edge_alpha_finish_;
- float edge_scale_y_start_;
- float edge_scale_y_finish_;
- float glow_alpha_start_;
- float glow_alpha_finish_;
- float glow_scale_y_start_;
- float glow_scale_y_finish_;
-
- base::TimeTicks start_time_;
- base::TimeDelta duration_;
-
- State state_;
-
- float pull_distance_;
-
- DISALLOW_COPY_AND_ASSIGN(EdgeEffect);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_EDGE_EFFECT_H_
diff --git a/chromium/content/browser/android/edge_effect_base.cc b/chromium/content/browser/android/edge_effect_base.cc
deleted file mode 100644
index 9f81f16f56d..00000000000
--- a/chromium/content/browser/android/edge_effect_base.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/edge_effect_base.h"
-
-namespace content {
-
-// static
-gfx::Transform EdgeEffectBase::ComputeTransform(Edge edge,
- const gfx::SizeF& viewport_size,
- float offset) {
- // Transforms assume the edge layers are anchored to their *top center point*.
- switch (edge) {
- case EDGE_TOP:
- return gfx::Transform(1, 0, 0, 1, 0, offset);
- case EDGE_LEFT:
- return gfx::Transform(0, 1, -1, 0, -viewport_size.height() / 2.f + offset,
- viewport_size.height() / 2.f);
- case EDGE_BOTTOM:
- return gfx::Transform(-1, 0, 0, -1, 0, viewport_size.height() + offset);
- case EDGE_RIGHT:
- return gfx::Transform(0, -1, 1, 0, -viewport_size.height() / 2.f +
- viewport_size.width() + offset,
- viewport_size.height() / 2.f);
- default:
- NOTREACHED() << "Invalid edge: " << edge;
- return gfx::Transform();
- };
-}
-
-// static
-gfx::SizeF EdgeEffectBase::ComputeOrientedSize(
- Edge edge,
- const gfx::SizeF& viewport_size) {
- switch (edge) {
- case EDGE_TOP:
- case EDGE_BOTTOM:
- return viewport_size;
- case EDGE_LEFT:
- case EDGE_RIGHT:
- return gfx::SizeF(viewport_size.height(), viewport_size.width());
- default:
- NOTREACHED() << "Invalid edge: " << edge;
- return gfx::SizeF();
- };
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/edge_effect_base.h b/chromium/content/browser/android/edge_effect_base.h
deleted file mode 100644
index a0fa84ed0f3..00000000000
--- a/chromium/content/browser/android/edge_effect_base.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_EDGE_EFFECT_BASE_H_
-#define CONTENT_BROWSER_ANDROID_EDGE_EFFECT_BASE_H_
-
-#include "base/basictypes.h"
-#include "base/time/time.h"
-#include "ui/gfx/geometry/size_f.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-class Layer;
-}
-
-namespace content {
-
-// A base class for overscroll-related Android effects.
-class EdgeEffectBase {
- public:
- enum State {
- STATE_IDLE = 0,
- STATE_PULL,
- STATE_ABSORB,
- STATE_RECEDE,
- STATE_PULL_DECAY
- };
-
- enum Edge { EDGE_TOP, EDGE_LEFT, EDGE_BOTTOM, EDGE_RIGHT, EDGE_COUNT };
-
- virtual ~EdgeEffectBase() {}
-
- virtual void Pull(base::TimeTicks current_time,
- float delta_distance,
- float displacement) = 0;
- virtual void Absorb(base::TimeTicks current_time, float velocity) = 0;
- virtual bool Update(base::TimeTicks current_time) = 0;
- virtual void Release(base::TimeTicks current_time) = 0;
-
- virtual void Finish() = 0;
- virtual bool IsFinished() const = 0;
- virtual float GetAlpha() const = 0;
-
- virtual void ApplyToLayers(Edge edge,
- const gfx::SizeF& viewport_size,
- float offset) = 0;
- virtual void SetParent(cc::Layer* parent) = 0;
-
- protected:
- // Computes the transform for an edge effect given the |edge|, |viewport_size|
- // and edge |offset|. This assumes the the effect transform anchor is at the
- // centered edge of the effect.
- static gfx::Transform ComputeTransform(Edge edge,
- const gfx::SizeF& viewport_size,
- float offset);
-
- // Computes the maximum effect size relative to the screen |edge|. For
- // top/bottom edges, thsi is simply |viewport_size|, while for left/right
- // edges this is |viewport_size| with coordinates swapped.
- static gfx::SizeF ComputeOrientedSize(Edge edge,
- const gfx::SizeF& viewport_size);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_EDGE_EFFECT_BASE_H_
diff --git a/chromium/content/browser/android/edge_effect_l.cc b/chromium/content/browser/android/edge_effect_l.cc
deleted file mode 100644
index 8545b9fb48e..00000000000
--- a/chromium/content/browser/android/edge_effect_l.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/edge_effect_l.h"
-
-#include "cc/layers/ui_resource_layer.h"
-#include "content/browser/android/animation_utils.h"
-#include "content/public/browser/android/compositor.h"
-#include "ui/android/resources/resource_manager.h"
-#include "ui/android/resources/system_ui_resource_type.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/size_conversions.h"
-
-namespace content {
-
-namespace {
-
-// Time it will take the effect to fully recede in ms
-const int kRecedeTimeMs = 600;
-
-// Time it will take before a pulled glow begins receding in ms
-const int kPullTimeMs = 167;
-
-// Time it will take for a pulled glow to decay to partial strength before
-// release
-const int kPullDecayTimeMs = 2000;
-
-const float kMaxAlpha = 0.5f;
-
-const float kPullGlowBegin = 0.f;
-
-// Min/max velocity that will be absorbed
-const float kMinVelocity = 100.f;
-const float kMaxVelocity = 10000.f;
-
-const float kEpsilon = 0.001f;
-
-const float kSin = 0.5f; // sin(PI / 6)
-const float kCos = 0.866f; // cos(PI / 6);
-
-// How much dragging should effect the height of the glow image.
-// Number determined by user testing.
-const float kPullDistanceAlphaGlowFactor = 0.8f;
-
-const int kVelocityGlowFactor = 6;
-
-const ui::SystemUIResourceType kResourceId = ui::OVERSCROLL_GLOW_L;
-
-} // namespace
-
-EdgeEffectL::EdgeEffectL(ui::ResourceManager* resource_manager)
- : resource_manager_(resource_manager),
- glow_(cc::UIResourceLayer::Create(Compositor::LayerSettings())),
- glow_alpha_(0),
- glow_scale_y_(0),
- glow_alpha_start_(0),
- glow_alpha_finish_(0),
- glow_scale_y_start_(0),
- glow_scale_y_finish_(0),
- displacement_(0.5f),
- target_displacement_(0.5f),
- state_(STATE_IDLE),
- pull_distance_(0) {
- // Prevent the provided layers from drawing until the effect is activated.
- glow_->SetIsDrawable(false);
-}
-
-EdgeEffectL::~EdgeEffectL() {
- glow_->RemoveFromParent();
-}
-
-bool EdgeEffectL::IsFinished() const {
- return state_ == STATE_IDLE;
-}
-
-void EdgeEffectL::Finish() {
- glow_->SetIsDrawable(false);
- pull_distance_ = 0;
- state_ = STATE_IDLE;
-}
-
-void EdgeEffectL::Pull(base::TimeTicks current_time,
- float delta_distance,
- float displacement) {
- target_displacement_ = displacement;
- if (state_ == STATE_PULL_DECAY && current_time - start_time_ < duration_) {
- return;
- }
- if (state_ != STATE_PULL) {
- glow_scale_y_ = std::max(kPullGlowBegin, glow_scale_y_);
- }
- state_ = STATE_PULL;
-
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kPullTimeMs);
-
- float abs_delta_distance = std::abs(delta_distance);
- pull_distance_ += delta_distance;
-
- glow_alpha_ = glow_alpha_start_ = std::min(
- kMaxAlpha,
- glow_alpha_ + (abs_delta_distance * kPullDistanceAlphaGlowFactor));
-
- if (pull_distance_ == 0) {
- glow_scale_y_ = glow_scale_y_start_ = 0;
- } else {
- float scale = 1.f -
- 1.f / std::sqrt(std::abs(pull_distance_) * bounds_.height()) -
- 0.3f;
- glow_scale_y_ = glow_scale_y_start_ = std::max(0.f, scale) / 0.7f;
- }
-
- glow_alpha_finish_ = glow_alpha_;
- glow_scale_y_finish_ = glow_scale_y_;
-}
-
-void EdgeEffectL::Release(base::TimeTicks current_time) {
- pull_distance_ = 0;
-
- if (state_ != STATE_PULL && state_ != STATE_PULL_DECAY)
- return;
-
- state_ = STATE_RECEDE;
- glow_alpha_start_ = glow_alpha_;
- glow_scale_y_start_ = glow_scale_y_;
-
- glow_alpha_finish_ = 0.f;
- glow_scale_y_finish_ = 0.f;
-
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kRecedeTimeMs);
-}
-
-void EdgeEffectL::Absorb(base::TimeTicks current_time, float velocity) {
- state_ = STATE_ABSORB;
-
- velocity = Clamp(std::abs(velocity), kMinVelocity, kMaxVelocity);
-
- start_time_ = current_time;
- // This should never be less than 1 millisecond.
- duration_ = base::TimeDelta::FromMilliseconds(0.15f + (velocity * 0.02f));
-
- // The glow depends more on the velocity, and therefore starts out
- // nearly invisible.
- glow_alpha_start_ = 0.3f;
- glow_scale_y_start_ = std::max(glow_scale_y_, 0.f);
-
- // Growth for the size of the glow should be quadratic to properly respond
- // to a user's scrolling speed. The faster the scrolling speed, the more
- // intense the effect should be for both the size and the saturation.
- glow_scale_y_finish_ =
- std::min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2.f, 1.f);
- // Alpha should change for the glow as well as size.
- glow_alpha_finish_ = Clamp(
- glow_alpha_start_, velocity * kVelocityGlowFactor * .00001f, kMaxAlpha);
- target_displacement_ = 0.5;
-}
-
-bool EdgeEffectL::Update(base::TimeTicks current_time) {
- if (IsFinished())
- return false;
-
- const double dt = (current_time - start_time_).InMilliseconds();
- const double t = std::min(dt / duration_.InMilliseconds(), 1.);
- const float interp = static_cast<float>(Damp(t, 1.));
-
- glow_alpha_ = Lerp(glow_alpha_start_, glow_alpha_finish_, interp);
- glow_scale_y_ = Lerp(glow_scale_y_start_, glow_scale_y_finish_, interp);
- displacement_ = (displacement_ + target_displacement_) / 2.f;
-
- if (t >= 1.f - kEpsilon) {
- switch (state_) {
- case STATE_ABSORB:
- state_ = STATE_RECEDE;
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kRecedeTimeMs);
-
- glow_alpha_start_ = glow_alpha_;
- glow_scale_y_start_ = glow_scale_y_;
-
- glow_alpha_finish_ = 0.f;
- glow_scale_y_finish_ = 0.f;
- break;
- case STATE_PULL:
- state_ = STATE_PULL_DECAY;
- start_time_ = current_time;
- duration_ = base::TimeDelta::FromMilliseconds(kPullDecayTimeMs);
-
- glow_alpha_start_ = glow_alpha_;
- glow_scale_y_start_ = glow_scale_y_;
-
- // After pull, the glow should fade to nothing.
- glow_alpha_finish_ = 0.f;
- glow_scale_y_finish_ = 0.f;
- break;
- case STATE_PULL_DECAY:
- state_ = STATE_RECEDE;
- break;
- case STATE_RECEDE:
- Finish();
- break;
- default:
- break;
- }
- }
-
- bool one_last_frame = false;
- if (state_ == STATE_RECEDE && glow_scale_y_ <= 0) {
- Finish();
- one_last_frame = true;
- }
-
- return !IsFinished() || one_last_frame;
-}
-
-float EdgeEffectL::GetAlpha() const {
- return IsFinished() ? 0.f : glow_alpha_;
-}
-
-void EdgeEffectL::ApplyToLayers(Edge edge,
- const gfx::SizeF& viewport_size,
- float offset) {
- if (IsFinished())
- return;
-
- // An empty viewport, while meaningless, is also relatively harmless, and will
- // simply prevent any drawing of the layers.
- if (viewport_size.IsEmpty()) {
- glow_->SetIsDrawable(false);
- return;
- }
-
- gfx::SizeF size = ComputeOrientedSize(edge, viewport_size);
- const float r = size.width() * 0.75f / kSin;
- const float y = kCos * r;
- const float h = r - y;
- const float o_r = size.height() * 0.75f / kSin;
- const float o_y = kCos * o_r;
- const float o_h = o_r - o_y;
- const float base_glow_scale = h > 0.f ? std::min(o_h / h, 1.f) : 1.f;
- bounds_ = gfx::Size(size.width(), (int)std::min(size.height(), h));
- gfx::Size image_bounds(
- r, std::min(1.f, glow_scale_y_) * base_glow_scale * bounds_.height());
-
- // Compute the displaced image rect. This includes both the horizontal
- // offset from the |displacement_| factor, as well as the vertical edge offset
- // provided by the method call.
- const float displacement = Clamp(displacement_, 0.f, 1.f) - 0.5f;
- const float displacement_offset_x = bounds_.width() * displacement * 0.5f;
- const float image_offset_x = (bounds_.width() - image_bounds.width()) * 0.5f;
- gfx::RectF image_rect = gfx::RectF(gfx::SizeF(image_bounds));
- image_rect.Offset(image_offset_x - displacement_offset_x, -std::abs(offset));
-
- // Clip the image rect against the viewport. If either rect is empty there's
- // no need to draw anything further.
- gfx::RectF clipped_rect(size.width(), size.height());
- clipped_rect.Intersect(image_rect);
- if (clipped_rect.IsEmpty() || image_rect.IsEmpty()) {
- glow_->SetIsDrawable(false);
- return;
- }
-
- // Compute the logical UV coordinates of the clipped rect relative to the
- // displaced image rect.
- gfx::PointF clipped_top_left = clipped_rect.origin();
- gfx::PointF clipped_bottom_right = clipped_rect.bottom_right();
- gfx::PointF uv_top_left(
- (clipped_top_left.x() - image_rect.x()) / image_rect.width(),
- (clipped_top_left.y() - image_rect.y()) / image_rect.height());
- gfx::PointF uv_bottom_right(
- (clipped_bottom_right.x() - image_rect.x()) / image_rect.width(),
- (clipped_bottom_right.y() - image_rect.y()) / image_rect.height());
- glow_->SetUV(uv_top_left, uv_bottom_right);
-
- // There's no need to use the provided |offset| when computing the transform;
- // the offset is built in to the computed UV coordinates.
- glow_->SetTransform(ComputeTransform(edge, viewport_size, 0));
-
- glow_->SetIsDrawable(true);
- glow_->SetUIResourceId(resource_manager_->GetUIResourceId(
- ui::ANDROID_RESOURCE_TYPE_SYSTEM, kResourceId));
- glow_->SetTransformOrigin(gfx::Point3F(bounds_.width() * 0.5f, 0, 0));
- glow_->SetBounds(gfx::ToRoundedSize(clipped_rect.size()));
- glow_->SetContentsOpaque(false);
- glow_->SetOpacity(Clamp(glow_alpha_, 0.f, 1.f));
-}
-
-void EdgeEffectL::SetParent(cc::Layer* parent) {
- if (glow_->parent() != parent)
- parent->AddChild(glow_);
-}
-
-// static
-void EdgeEffectL::PreloadResources(ui::ResourceManager* resource_manager) {
- DCHECK(resource_manager);
- resource_manager->PreloadResource(ui::ANDROID_RESOURCE_TYPE_SYSTEM,
- kResourceId);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/edge_effect_l.h b/chromium/content/browser/android/edge_effect_l.h
deleted file mode 100644
index 0e78282a378..00000000000
--- a/chromium/content/browser/android/edge_effect_l.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_EDGE_EFFECT_L_H_
-#define CONTENT_BROWSER_ANDROID_EDGE_EFFECT_L_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "content/browser/android/edge_effect_base.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-class Layer;
-class UIResourceLayer;
-}
-
-namespace ui {
-class ResourceManager;
-}
-
-namespace content {
-
-// |EdgeEffectL| mirrors its Android L counterpart, EdgeEffect.java.
-// Conscious tradeoffs were made to align this as closely as possible with the
-// the original Android java version.
-// All coordinates and dimensions are in device pixels.
-class EdgeEffectL : public EdgeEffectBase {
- public:
- explicit EdgeEffectL(ui::ResourceManager* resource_manager);
- ~EdgeEffectL() override;
-
- void Pull(base::TimeTicks current_time,
- float delta_distance,
- float displacement) override;
- void Absorb(base::TimeTicks current_time, float velocity) override;
- bool Update(base::TimeTicks current_time) override;
- void Release(base::TimeTicks current_time) override;
-
- void Finish() override;
- bool IsFinished() const override;
- float GetAlpha() const override;
-
- void ApplyToLayers(Edge edge,
- const gfx::SizeF& viewport_size,
- float offset) override;
- void SetParent(cc::Layer* parent) override;
-
- // Thread-safe trigger to load resources.
- static void PreloadResources(ui::ResourceManager* resource_manager);
-
- private:
- ui::ResourceManager* const resource_manager_;
-
- scoped_refptr<cc::UIResourceLayer> glow_;
-
- float glow_alpha_;
- float glow_scale_y_;
-
- float glow_alpha_start_;
- float glow_alpha_finish_;
- float glow_scale_y_start_;
- float glow_scale_y_finish_;
-
- gfx::RectF arc_rect_;
- gfx::Size bounds_;
- float displacement_;
- float target_displacement_;
-
- base::TimeTicks start_time_;
- base::TimeDelta duration_;
-
- State state_;
-
- float pull_distance_;
-
- DISALLOW_COPY_AND_ASSIGN(EdgeEffectL);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_EDGE_EFFECT_L_H_
diff --git a/chromium/content/browser/android/in_process/DEPS b/chromium/content/browser/android/in_process/DEPS
index 68b1400faed..e200a5aab38 100644
--- a/chromium/content/browser/android/in_process/DEPS
+++ b/chromium/content/browser/android/in_process/DEPS
@@ -1,8 +1,8 @@
include_rules = [
"+cc/blink",
- "+content/gpu/in_process_gpu_thread.h",
# Required for SynchronousCompositor (in --single-process mode only).
"+content/public/renderer/android",
"+content/renderer",
- # Include joth@chromium.org on the review for any additions to this file.
+ "+ui/events/blink/synchronous_input_handler_proxy.h",
+ # Include boliu@chromium.org on the review for any additions to this file.
]
diff --git a/chromium/content/browser/android/in_process/context_provider_in_process.cc b/chromium/content/browser/android/in_process/context_provider_in_process.cc
index 5fea00f2502..9f4fbc2d827 100644
--- a/chromium/content/browser/android/in_process/context_provider_in_process.cc
+++ b/chromium/content/browser/android/in_process/context_provider_in_process.cc
@@ -4,6 +4,9 @@
#include "content/browser/android/in_process/context_provider_in_process.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/strings/stringprintf.h"
@@ -22,14 +25,14 @@ class ContextProviderInProcess::LostContextCallbackProxy
public:
explicit LostContextCallbackProxy(ContextProviderInProcess* provider)
: provider_(provider) {
- provider_->context3d_->setContextLostCallback(this);
+ provider_->WebContext3DImpl()->setContextLostCallback(this);
}
- virtual ~LostContextCallbackProxy() {
- provider_->context3d_->setContextLostCallback(NULL);
+ ~LostContextCallbackProxy() override {
+ provider_->WebContext3DImpl()->setContextLostCallback(NULL);
}
- virtual void onContextLost() {
+ void onContextLost() override {
provider_->OnLostContext();
}
@@ -43,17 +46,18 @@ scoped_refptr<ContextProviderInProcess> ContextProviderInProcess::Create(
const std::string& debug_name) {
if (!context3d)
return NULL;
- return new ContextProviderInProcess(context3d.Pass(), debug_name);
+ return new ContextProviderInProcess(std::move(context3d), debug_name);
}
ContextProviderInProcess::ContextProviderInProcess(
scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d,
const std::string& debug_name)
- : context3d_(context3d.Pass()),
- destroyed_(false),
- debug_name_(debug_name) {
+ : debug_name_(debug_name) {
DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(context3d_);
+ DCHECK(context3d);
+ gr_interface_ = skia::AdoptRef(
+ new GrGLInterfaceForWebGraphicsContext3D(std::move(context3d)));
+ DCHECK(gr_interface_->WebContext3D());
context_thread_checker_.DetachFromThread();
}
@@ -66,11 +70,20 @@ blink::WebGraphicsContext3D* ContextProviderInProcess::WebContext3D() {
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
DCHECK(context_thread_checker_.CalledOnValidThread());
- return context3d_.get();
+ return WebContext3DImpl();
+}
+
+gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl*
+ ContextProviderInProcess::WebContext3DImpl() {
+ DCHECK(gr_interface_->WebContext3D());
+
+ return
+ static_cast<gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl*>(
+ gr_interface_->WebContext3D());
}
bool ContextProviderInProcess::BindToCurrentThread() {
- DCHECK(context3d_);
+ DCHECK(WebContext3DImpl());
// This is called on the thread the context will be used.
DCHECK(context_thread_checker_.CalledOnValidThread());
@@ -78,14 +91,15 @@ bool ContextProviderInProcess::BindToCurrentThread() {
if (lost_context_callback_proxy_)
return true;
- if (!context3d_->InitializeOnCurrentThread())
+ if (!WebContext3DImpl()->InitializeOnCurrentThread())
return false;
+ gr_interface_->BindToCurrentThread();
InitializeCapabilities();
const std::string unique_context_name =
- base::StringPrintf("%s-%p", debug_name_.c_str(), context3d_.get());
- context3d_->traceBeginCHROMIUM("gpu_toplevel",
+ base::StringPrintf("%s-%p", debug_name_.c_str(), WebContext3DImpl());
+ WebContext3DImpl()->traceBeginCHROMIUM("gpu_toplevel",
unique_context_name.c_str());
lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this));
@@ -97,9 +111,9 @@ void ContextProviderInProcess::DetachFromThread() {
}
void ContextProviderInProcess::InitializeCapabilities() {
- capabilities_.gpu = context3d_->GetImplementation()->capabilities();
+ capabilities_.gpu = WebContext3DImpl()->GetImplementation()->capabilities();
- size_t mapped_memory_limit = context3d_->GetMappedMemoryLimit();
+ size_t mapped_memory_limit = WebContext3DImpl()->GetMappedMemoryLimit();
capabilities_.max_transfer_buffer_usage_bytes =
mapped_memory_limit ==
WebGraphicsContext3DInProcessCommandBufferImpl::kNoLimit
@@ -115,21 +129,21 @@ ContextProviderInProcess::ContextCapabilities() {
}
::gpu::gles2::GLES2Interface* ContextProviderInProcess::ContextGL() {
- DCHECK(context3d_);
+ DCHECK(WebContext3DImpl());
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
DCHECK(context_thread_checker_.CalledOnValidThread());
- return context3d_->GetGLInterface();
+ return WebContext3DImpl()->GetGLInterface();
}
::gpu::ContextSupport* ContextProviderInProcess::ContextSupport() {
- DCHECK(context3d_);
+ DCHECK(WebContext3DImpl());
if (!lost_context_callback_proxy_)
return NULL; // Not bound to anything.
DCHECK(context_thread_checker_.CalledOnValidThread());
- return context3d_->GetContextSupport();
+ return WebContext3DImpl()->GetContextSupport();
}
class GrContext* ContextProviderInProcess::GrContext() {
@@ -139,7 +153,7 @@ class GrContext* ContextProviderInProcess::GrContext() {
if (gr_context_)
return gr_context_->get();
- gr_context_.reset(new GrContextForWebGraphicsContext3D(context3d_.get()));
+ gr_context_.reset(new GrContextForWebGraphicsContext3D(gr_interface_));
return gr_context_->get();
}
@@ -152,21 +166,13 @@ void ContextProviderInProcess::InvalidateGrContext(uint32_t state) {
}
void ContextProviderInProcess::SetupLock() {
- context3d_->SetLock(&context_lock_);
+ WebContext3DImpl()->SetLock(&context_lock_);
}
base::Lock* ContextProviderInProcess::GetLock() {
return &context_lock_;
}
-void ContextProviderInProcess::VerifyContexts() {
- DCHECK(lost_context_callback_proxy_); // Is bound to thread.
- DCHECK(context_thread_checker_.CalledOnValidThread());
-
- if (ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
- OnLostContext();
-}
-
void ContextProviderInProcess::DeleteCachedResources() {
DCHECK(context_thread_checker_.CalledOnValidThread());
@@ -176,25 +182,12 @@ void ContextProviderInProcess::DeleteCachedResources() {
void ContextProviderInProcess::OnLostContext() {
DCHECK(context_thread_checker_.CalledOnValidThread());
- {
- base::AutoLock lock(destroyed_lock_);
- if (destroyed_)
- return;
- destroyed_ = true;
- }
if (!lost_context_callback_.is_null())
base::ResetAndReturn(&lost_context_callback_).Run();
if (gr_context_)
gr_context_->OnLostContext();
}
-bool ContextProviderInProcess::DestroyedOnMainThread() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
-
- base::AutoLock lock(destroyed_lock_);
- return destroyed_;
-}
-
void ContextProviderInProcess::SetLostContextCallback(
const LostContextCallback& lost_context_callback) {
DCHECK(context_thread_checker_.CalledOnValidThread());
@@ -203,9 +196,4 @@ void ContextProviderInProcess::SetLostContextCallback(
lost_context_callback_ = lost_context_callback;
}
-void ContextProviderInProcess::SetMemoryPolicyChangedCallback(
- const MemoryPolicyChangedCallback& memory_policy_changed_callback) {
- // There's no memory manager for the in-process implementation.
-}
-
} // namespace content
diff --git a/chromium/content/browser/android/in_process/context_provider_in_process.h b/chromium/content/browser/android/in_process/context_provider_in_process.h
index b2b2ba8ba62..fe24f945003 100644
--- a/chromium/content/browser/android/in_process/context_provider_in_process.h
+++ b/chromium/content/browser/android/in_process/context_provider_in_process.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_ANDROID_IN_PROCESS_CONTEXT_PROVIDER_IN_PROCESS_H_
#define CONTENT_BROWSER_ANDROID_IN_PROCESS_CONTEXT_PROVIDER_IN_PROCESS_H_
+#include <stdint.h>
+
#include <string>
#include "base/macros.h"
@@ -12,6 +14,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
#include "cc/blink/context_provider_web_context.h"
+#include "skia/ext/refptr.h"
namespace blink { class WebGraphicsContext3D; }
@@ -22,6 +25,7 @@ class WebGraphicsContext3DInProcessCommandBufferImpl;
namespace content {
class GrContextForWebGraphicsContext3D;
+class GrGLInterfaceForWebGraphicsContext3D;
class ContextProviderInProcess
: NON_EXPORTED_BASE(public cc_blink::ContextProviderWebContext) {
@@ -41,6 +45,8 @@ class ContextProviderInProcess
// cc_blink::ContextProviderWebContext:
blink::WebGraphicsContext3D* WebContext3D() override;
+ gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl* WebContext3DImpl();
+
// cc::ContextProvider:
bool BindToCurrentThread() override;
void DetachFromThread() override;
@@ -51,14 +57,9 @@ class ContextProviderInProcess
void InvalidateGrContext(uint32_t state) override;
void SetupLock() override;
base::Lock* GetLock() override;
- void VerifyContexts() override;
void DeleteCachedResources() override;
- bool DestroyedOnMainThread() override;
void SetLostContextCallback(
const LostContextCallback& lost_context_callback) override;
- void SetMemoryPolicyChangedCallback(
- const MemoryPolicyChangedCallback& memory_policy_changed_callback)
- override;
void OnLostContext();
void InitializeCapabilities();
@@ -66,15 +67,11 @@ class ContextProviderInProcess
base::ThreadChecker main_thread_checker_;
base::ThreadChecker context_thread_checker_;
- scoped_ptr<gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl>
- context3d_;
+ skia::RefPtr<GrGLInterfaceForWebGraphicsContext3D> gr_interface_;
scoped_ptr<GrContextForWebGraphicsContext3D> gr_context_;
LostContextCallback lost_context_callback_;
- base::Lock destroyed_lock_;
- bool destroyed_;
-
base::Lock context_lock_;
std::string debug_name_;
class LostContextCallbackProxy;
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_context_provider.cc b/chromium/content/browser/android/in_process/synchronous_compositor_context_provider.cc
deleted file mode 100644
index ccdd993d4b2..00000000000
--- a/chromium/content/browser/android/in_process/synchronous_compositor_context_provider.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/in_process/synchronous_compositor_context_provider.h"
-
-namespace content {
-
-SynchronousCompositorContextProvider::SynchronousCompositorContextProvider(
- scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d,
- CommandBufferContextType type)
- : ContextProviderCommandBuffer(context3d.Pass(), type) {}
-
-SynchronousCompositorContextProvider::~SynchronousCompositorContextProvider() {}
-
-void SynchronousCompositorContextProvider::SetMemoryPolicyChangedCallback(
- const MemoryPolicyChangedCallback& memory_policy_changed_callback) {
- // Intentional no-op.
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_context_provider.h b/chromium/content/browser/android/in_process/synchronous_compositor_context_provider.h
deleted file mode 100644
index 5a692a65597..00000000000
--- a/chromium/content/browser/android/in_process/synchronous_compositor_context_provider.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_CONTEXT_PROVIDER_H_
-#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_CONTEXT_PROVIDER_H_
-
-#include "content/common/gpu/client/context_provider_command_buffer.h"
-
-namespace content {
-
-// This class exists purely to ignore memory signals from the command buffer.
-// Synchronous compositor manages memory by itself.
-class SynchronousCompositorContextProvider
- : public ContextProviderCommandBuffer {
- public:
- SynchronousCompositorContextProvider(
- scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d,
- CommandBufferContextType type);
-
- void SetMemoryPolicyChangedCallback(
- const MemoryPolicyChangedCallback& memory_policy_changed_callback)
- override;
-
- private:
- ~SynchronousCompositorContextProvider() override;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_CONTEXT_PROVIDER_H_
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.cc b/chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.cc
deleted file mode 100644
index fd9513cb89d..00000000000
--- a/chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h"
-
-#include "cc/output/begin_frame_args.h"
-#include "content/browser/android/in_process/synchronous_compositor_impl.h"
-#include "content/browser/android/in_process/synchronous_compositor_registry.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace content {
-
-SynchronousCompositorExternalBeginFrameSource::
- SynchronousCompositorExternalBeginFrameSource(int routing_id)
- : routing_id_(routing_id),
- registered_(false),
- compositor_(nullptr) {
-}
-
-SynchronousCompositorExternalBeginFrameSource::
- ~SynchronousCompositorExternalBeginFrameSource() {
- DCHECK(CalledOnValidThread());
-
- if (registered_) {
- SynchronousCompositorRegistry::GetInstance()->UnregisterBeginFrameSource(
- routing_id_, this);
- }
- DCHECK(!compositor_);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::BeginFrame(
- const cc::BeginFrameArgs& args) {
- DCHECK(CalledOnValidThread());
- CallOnBeginFrame(args);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::SetCompositor(
- SynchronousCompositorImpl* compositor) {
- DCHECK(CalledOnValidThread());
- if (compositor_ == compositor) return;
-
- if (compositor_)
- compositor_->OnNeedsBeginFramesChange(false);
-
- compositor_ = compositor;
-
- if (compositor_)
- compositor_->OnNeedsBeginFramesChange(needs_begin_frames_);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::OnNeedsBeginFramesChange(
- bool needs_begin_frames) {
- DCHECK(CalledOnValidThread());
- if (compositor_)
- compositor_->OnNeedsBeginFramesChange(needs_begin_frames);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::SetClientReady() {
- DCHECK(CalledOnValidThread());
- SynchronousCompositorRegistry::GetInstance()->RegisterBeginFrameSource(
- routing_id_, this);
- registered_ = true;
-}
-
-// Not using base::NonThreadSafe as we want to enforce a more exacting threading
-// requirement: SynchronousCompositorExternalBeginFrameSource() must only be
-// used on the UI thread.
-bool
-SynchronousCompositorExternalBeginFrameSource::CalledOnValidThread() const {
- return BrowserThread::CurrentlyOn(BrowserThread::UI);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h b/chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h
deleted file mode 100644
index eb7e84b87e6..00000000000
--- a/chromium/content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
-#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "cc/scheduler/begin_frame_source.h"
-
-namespace content {
-class SynchronousCompositorImpl;
-
-// Make sure that this is initialized and set to compositor before output
-// surface is bound to compositor.
-class SynchronousCompositorExternalBeginFrameSource
- : public cc::BeginFrameSourceBase {
- public:
- explicit SynchronousCompositorExternalBeginFrameSource(int routing_id);
- ~SynchronousCompositorExternalBeginFrameSource() override;
-
- void BeginFrame(const cc::BeginFrameArgs& args);
- void SetCompositor(SynchronousCompositorImpl* compositor);
-
- // cc::BeginFrameSourceBase implementation.
- void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
- void SetClientReady() override;
-
- private:
- bool CalledOnValidThread() const;
-
- const int routing_id_;
- bool registered_;
-
- // Not owned. This can be null when compositor is gone first than BFS.
- SynchronousCompositorImpl* compositor_;
-
- DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorExternalBeginFrameSource);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
index 70480001010..628bfccf6a2 100644
--- a/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
+++ b/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
@@ -4,22 +4,25 @@
#include "content/browser/android/in_process/synchronous_compositor_factory_impl.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/observer_list.h"
#include "base/sys_info.h"
#include "base/thread_task_runner_handle.h"
#include "content/browser/android/in_process/context_provider_in_process.h"
-#include "content/browser/android/in_process/synchronous_compositor_context_provider.h"
-#include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h"
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
-#include "content/browser/android/in_process/synchronous_compositor_output_surface.h"
+#include "content/browser/android/in_process/synchronous_compositor_registry_in_proc.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
+#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
-#include "content/gpu/in_process_gpu_thread.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/renderer/android/synchronous_compositor_external_begin_frame_source.h"
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
#include "content/renderer/render_thread_impl.h"
#include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h"
@@ -75,30 +78,12 @@ ContextHolder CreateContextHolder(
holder.command_buffer =
scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(
WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
- context.Pass(), attributes));
+ std::move(context), attributes));
holder.gl_in_process_context = context_ptr;
return holder;
}
-scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext3D(
- int surface_id,
- const blink::WebGraphicsContext3D::Attributes& attributes,
- const content::WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits&
- mem_limits) {
- DCHECK(RenderThreadImpl::current());
- CauseForGpuLaunch cause =
- CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
- scoped_refptr<GpuChannelHost> gpu_channel_host(
- RenderThreadImpl::current()->EstablishGpuChannelSync(cause));
- CHECK(gpu_channel_host.get());
-
- bool lose_context_when_out_of_memory = true;
- return make_scoped_ptr(new WebGraphicsContext3DCommandBufferImpl(
- surface_id, GURL(), gpu_channel_host.get(), attributes,
- lose_context_when_out_of_memory, mem_limits, NULL));
-}
-
} // namespace
class SynchronousCompositorFactoryImpl::VideoContextProvider
@@ -113,10 +98,14 @@ class SynchronousCompositorFactoryImpl::VideoContextProvider
}
scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture(
- uint32 stream_id) override {
+ uint32_t stream_id) override {
return gl_in_process_context_->GetSurfaceTexture(stream_id);
}
+ uint32_t CreateStreamTexture(uint32_t texture_id) override {
+ return gl_in_process_context_->CreateStreamTexture(texture_id);
+ }
+
gpu::gles2::GLES2Interface* ContextGL() override {
return context_provider_->ContextGL();
}
@@ -147,8 +136,7 @@ class SynchronousCompositorFactoryImpl::VideoContextProvider
};
SynchronousCompositorFactoryImpl::SynchronousCompositorFactoryImpl()
- : use_ipc_command_buffer_(false),
- num_hardware_compositors_(0) {
+ : num_hardware_compositors_(0) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSingleProcess)) {
// TODO(boliu): Figure out how to deal with this more nicely.
@@ -166,18 +154,13 @@ SynchronousCompositorFactoryImpl::GetCompositorTaskRunner() {
scoped_ptr<cc::OutputSurface>
SynchronousCompositorFactoryImpl::CreateOutputSurface(
int routing_id,
- scoped_refptr<content::FrameSwapMessageQueue> frame_swap_message_queue) {
- // TODO(piman): we still need to create a View command buffer until
- // crbug.com/526196 is fixed. The surface_id doesn't matter, it just needs to
- // be !0.
- const int32 kDummySurfaceId = 1;
- scoped_refptr<cc::ContextProvider> onscreen_context =
- CreateContextProviderForCompositor(kDummySurfaceId,
- RENDER_COMPOSITOR_CONTEXT);
- scoped_refptr<cc::ContextProvider> worker_context =
- GetSharedWorkerContextProvider();
+ const scoped_refptr<FrameSwapMessageQueue>& frame_swap_message_queue,
+ const scoped_refptr<cc::ContextProvider>& onscreen_context,
+ const scoped_refptr<cc::ContextProvider>& worker_context) {
return make_scoped_ptr(new SynchronousCompositorOutputSurface(
- onscreen_context, worker_context, routing_id, frame_swap_message_queue));
+ onscreen_context, worker_context, routing_id,
+ SynchronousCompositorRegistryInProc::GetInstance(),
+ frame_swap_message_queue));
}
InputHandlerManagerClient*
@@ -188,116 +171,8 @@ SynchronousCompositorFactoryImpl::GetInputHandlerManagerClient() {
scoped_ptr<cc::BeginFrameSource>
SynchronousCompositorFactoryImpl::CreateExternalBeginFrameSource(
int routing_id) {
- return make_scoped_ptr(
- new SynchronousCompositorExternalBeginFrameSource(routing_id));
-}
-
-bool SynchronousCompositorFactoryImpl::OverrideWithFactory() {
- return !use_ipc_command_buffer_;
-}
-
-scoped_refptr<ContextProviderWebContext>
-SynchronousCompositorFactoryImpl::CreateOffscreenContextProvider(
- const blink::WebGraphicsContext3D::Attributes& attributes,
- const std::string& debug_name) {
- DCHECK(!use_ipc_command_buffer_);
- ContextHolder holder =
- CreateContextHolder(attributes, GpuThreadService(),
- gpu::GLInProcessContextSharedMemoryLimits(), true);
- return ContextProviderInProcess::Create(holder.command_buffer.Pass(),
- debug_name);
-}
-
-scoped_refptr<cc::ContextProvider>
-SynchronousCompositorFactoryImpl::CreateContextProviderForCompositor(
- int surface_id,
- CommandBufferContextType type) {
- // This is half of what RenderWidget uses because synchronous compositor
- // pipeline is only one frame deep. But twice of half for low end here
- // because 16bit texture is not supported.
- // TODO(reveman): This limit is based on the usage required by async
- // uploads. Determine what a good limit is now that async uploads are
- // no longer used.
- unsigned int mapped_memory_reclaim_limit =
- (base::SysInfo::IsLowEndDevice() ? 2 : 6) * 1024 * 1024;
- blink::WebGraphicsContext3D::Attributes attributes = GetDefaultAttribs();
-
- if (use_ipc_command_buffer_) {
- WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits mem_limits;
- mem_limits.mapped_memory_reclaim_limit = mapped_memory_reclaim_limit;
- scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context =
- CreateContext3D(surface_id, GetDefaultAttribs(), mem_limits);
- return make_scoped_refptr(
- new SynchronousCompositorContextProvider(context.Pass(), type));
- }
-
- gpu::GLInProcessContextSharedMemoryLimits mem_limits;
- mem_limits.mapped_memory_reclaim_limit = mapped_memory_reclaim_limit;
- ContextHolder holder =
- CreateContextHolder(attributes, GpuThreadService(), mem_limits, true);
- return ContextProviderInProcess::Create(holder.command_buffer.Pass(),
- "Child-Compositor");
-}
-
-scoped_refptr<cc::ContextProvider>
-SynchronousCompositorFactoryImpl::GetSharedWorkerContextProvider() {
- // TODO(reveman): This limit is based on the usage required by async
- // uploads. Determine what a good limit is now that async uploads are
- // no longer used.
- unsigned int mapped_memory_reclaim_limit =
- (base::SysInfo::IsLowEndDevice() ? 2 : 6) * 1024 * 1024;
-
- if (use_ipc_command_buffer_) {
- bool shared_worker_context_lost = false;
- if (shared_worker_context_) {
- // Note: If context is lost, we delete reference after releasing the lock.
- base::AutoLock lock(*shared_worker_context_->GetLock());
- if (shared_worker_context_->ContextGL()->GetGraphicsResetStatusKHR() !=
- GL_NO_ERROR) {
- shared_worker_context_lost = true;
- }
- }
- if (!shared_worker_context_ || shared_worker_context_lost) {
- WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits mem_limits;
- mem_limits.mapped_memory_reclaim_limit = mapped_memory_reclaim_limit;
- scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context =
- CreateContext3D(0, GetDefaultAttribs(), mem_limits);
- shared_worker_context_ =
- make_scoped_refptr(new SynchronousCompositorContextProvider(
- context.Pass(), RENDER_WORKER_CONTEXT));
- if (!shared_worker_context_->BindToCurrentThread())
- shared_worker_context_ = nullptr;
- if (shared_worker_context_)
- shared_worker_context_->SetupLock();
- }
-
- return shared_worker_context_;
- }
-
- bool in_process_shared_worker_context_lost = false;
- if (in_process_shared_worker_context_) {
- // Note: If context is lost, we delete reference after releasing the lock.
- base::AutoLock lock(*in_process_shared_worker_context_->GetLock());
- if (in_process_shared_worker_context_->ContextGL()
- ->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
- in_process_shared_worker_context_lost = true;
- }
- }
- if (!in_process_shared_worker_context_ ||
- in_process_shared_worker_context_lost) {
- gpu::GLInProcessContextSharedMemoryLimits mem_limits;
- mem_limits.mapped_memory_reclaim_limit = mapped_memory_reclaim_limit;
- ContextHolder holder = CreateContextHolder(
- GetDefaultAttribs(), GpuThreadService(), mem_limits, true);
- in_process_shared_worker_context_ = ContextProviderInProcess::Create(
- holder.command_buffer.Pass(), "Child-Worker");
- if (!in_process_shared_worker_context_->BindToCurrentThread())
- in_process_shared_worker_context_ = nullptr;
- if (in_process_shared_worker_context_)
- in_process_shared_worker_context_->SetupLock();
- }
-
- return in_process_shared_worker_context_;
+ return make_scoped_ptr(new SynchronousCompositorExternalBeginFrameSource(
+ routing_id, SynchronousCompositorRegistryInProc::GetInstance()));
}
scoped_refptr<StreamTextureFactory>
@@ -311,21 +186,6 @@ SynchronousCompositorFactoryImpl::CreateStreamTextureFactory(int frame_id) {
return factory;
}
-WebGraphicsContext3DInProcessCommandBufferImpl*
-SynchronousCompositorFactoryImpl::CreateOffscreenGraphicsContext3D(
- const blink::WebGraphicsContext3D::Attributes& attributes) {
- DCHECK(!use_ipc_command_buffer_);
- ContextHolder holder =
- CreateContextHolder(attributes, GpuThreadService(),
- gpu::GLInProcessContextSharedMemoryLimits(), true);
- return holder.command_buffer.release();
-}
-
-gpu::GPUInfo SynchronousCompositorFactoryImpl::GetGPUInfo() const {
- DCHECK(!use_ipc_command_buffer_);
- return content::GpuDataManager::GetInstance()->GetGPUInfo();
-}
-
void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw() {
base::AutoLock lock(num_hardware_compositor_lock_);
num_hardware_compositors_++;
@@ -381,7 +241,7 @@ SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory() {
CreateContextHolder(attributes, android_view_service_,
gpu::GLInProcessContextSharedMemoryLimits(), false);
video_context_provider_ = new VideoContextProvider(
- ContextProviderInProcess::Create(holder.command_buffer.Pass(),
+ ContextProviderInProcess::Create(std::move(holder.command_buffer),
"Video-Offscreen-main-thread"),
holder.gl_in_process_context);
}
@@ -394,26 +254,4 @@ void SynchronousCompositorFactoryImpl::SetDeferredGpuService(
android_view_service_ = service;
}
-base::Thread* SynchronousCompositorFactoryImpl::CreateInProcessGpuThread(
- const InProcessChildThreadParams& params) {
- DCHECK(android_view_service_.get());
- return new InProcessGpuThread(params,
- android_view_service_->sync_point_manager());
-}
-
-scoped_refptr<gpu::InProcessCommandBuffer::Service>
-SynchronousCompositorFactoryImpl::GpuThreadService() {
- DCHECK(android_view_service_.get());
- // Create thread lazily on first use.
- if (!gpu_thread_service_.get()) {
- gpu_thread_service_ = new gpu::GpuInProcessThread(
- android_view_service_->sync_point_manager());
- }
- return gpu_thread_service_;
-}
-
-void SynchronousCompositorFactoryImpl::SetUseIpcCommandBuffer() {
- use_ipc_command_buffer_ = true;
-}
-
} // namespace content
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.h b/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.h
index b78d2c81006..03533444a3e 100644
--- a/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.h
+++ b/chromium/content/browser/android/in_process/synchronous_compositor_factory_impl.h
@@ -28,7 +28,7 @@ class WebGraphicsContext3DInProcessCommandBufferImpl;
namespace content {
class InProcessChildThreadParams;
-class SynchronousCompositorContextProvider;
+class ContextProviderCommandBuffer;
class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
public:
@@ -40,22 +40,14 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
override;
scoped_ptr<cc::OutputSurface> CreateOutputSurface(
int routing_id,
- scoped_refptr<content::FrameSwapMessageQueue> frame_swap_message_queue)
- override;
+ const scoped_refptr<FrameSwapMessageQueue>& frame_swap_message_queue,
+ const scoped_refptr<cc::ContextProvider>& onscreen_context,
+ const scoped_refptr<cc::ContextProvider>& worker_context) override;
InputHandlerManagerClient* GetInputHandlerManagerClient() override;
scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
int routing_id) override;
scoped_refptr<StreamTextureFactory> CreateStreamTextureFactory(
- int view_id) override;
- bool OverrideWithFactory() override;
- scoped_refptr<cc_blink::ContextProviderWebContext>
- CreateOffscreenContextProvider(
- const blink::WebGraphicsContext3D::Attributes& attributes,
- const std::string& debug_name) override;
- gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl*
- CreateOffscreenGraphicsContext3D(
- const blink::WebGraphicsContext3D::Attributes& attributes) override;
- gpu::GPUInfo GetGPUInfo() const override;
+ int frame_id) override;
SynchronousInputEventFilter* synchronous_input_event_filter() {
return &synchronous_input_event_filter_;
@@ -63,38 +55,24 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
void SetDeferredGpuService(
scoped_refptr<gpu::InProcessCommandBuffer::Service> service);
- base::Thread* CreateInProcessGpuThread(
- const InProcessChildThreadParams& params);
- void SetUseIpcCommandBuffer();
void CompositorInitializedHardwareDraw();
void CompositorReleasedHardwareDraw();
private:
- scoped_refptr<cc::ContextProvider> CreateContextProviderForCompositor(
- int surface_id,
- CommandBufferContextType type);
scoped_refptr<cc::ContextProvider> GetSharedWorkerContextProvider();
bool CanCreateMainThreadContext();
scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
TryCreateStreamTextureFactory();
void RestoreContextOnMainThread();
- scoped_refptr<gpu::InProcessCommandBuffer::Service> GpuThreadService();
SynchronousInputEventFilter synchronous_input_event_filter_;
scoped_refptr<gpu::InProcessCommandBuffer::Service> android_view_service_;
- scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_thread_service_;
class VideoContextProvider;
scoped_refptr<VideoContextProvider> video_context_provider_;
- scoped_refptr<SynchronousCompositorContextProvider> shared_worker_context_;
- scoped_refptr<cc_blink::ContextProviderWebContext>
- in_process_shared_worker_context_;
-
- bool use_ipc_command_buffer_;
-
// |num_hardware_compositor_lock_| is updated on UI thread only but can be
// read on renderer main thread.
base::Lock num_hardware_compositor_lock_;
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc b/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc
index 98466724ed1..e1791374ed2 100644
--- a/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -4,13 +4,14 @@
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
+#include <utility>
+
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
-#include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h"
#include "content/browser/android/in_process/synchronous_compositor_factory_impl.h"
-#include "content/browser/android/in_process/synchronous_compositor_registry.h"
+#include "content/browser/android/in_process/synchronous_compositor_registry_in_proc.h"
#include "content/browser/android/in_process/synchronous_input_event_filter.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
@@ -20,6 +21,8 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/common/child_process_host.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gl/gl_surface.h"
@@ -27,104 +30,72 @@ namespace content {
namespace {
-int GetInProcessRendererId() {
- content::RenderProcessHost::iterator it =
- content::RenderProcessHost::AllHostsIterator();
- if (it.IsAtEnd()) {
- // There should always be one RPH in single process mode.
- NOTREACHED();
- return 0;
- }
-
- int id = it.GetCurrentValue()->GetID();
- it.Advance();
- DCHECK(it.IsAtEnd()); // Not multiprocess compatible.
- return id;
-}
+int g_process_id = ChildProcessHost::kInvalidUniqueID;
base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
LAZY_INSTANCE_INITIALIZER;
-base::Thread* CreateInProcessGpuThreadForSynchronousCompositor(
- const InProcessChildThreadParams& params) {
- return g_factory.Get().CreateInProcessGpuThread(params);
-}
-
} // namespace
-DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
-
-// static
-SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
- int routing_id) {
+SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
+ int routing_id) {
if (g_factory == nullptr)
return nullptr;
- RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id);
+ if (g_process_id == ChildProcessHost::kInvalidUniqueID)
+ return nullptr;
+ RenderViewHost* rvh = RenderViewHost::FromID(g_process_id, routing_id);
if (!rvh)
return nullptr;
- WebContents* contents = WebContents::FromRenderViewHost(rvh);
- if (!contents)
+ RenderWidgetHostViewAndroid* rwhva =
+ static_cast<RenderWidgetHostViewAndroid*>(rvh->GetWidget()->GetView());
+ if (!rwhva)
return nullptr;
- return FromWebContents(contents);
+ return static_cast<SynchronousCompositorImpl*>(
+ rwhva->GetSynchronousCompositor());
}
-SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
- int routing_id) {
- return FromID(GetInProcessRendererId(), routing_id);
-}
-
-SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents)
- : compositor_client_(nullptr),
+SynchronousCompositorImpl::SynchronousCompositorImpl(
+ RenderWidgetHostViewAndroid* rwhva,
+ SynchronousCompositorClient* client)
+ : rwhva_(rwhva),
+ routing_id_(rwhva_->GetRenderWidgetHost()->GetRoutingID()),
+ compositor_client_(client),
output_surface_(nullptr),
begin_frame_source_(nullptr),
- contents_(contents),
- routing_id_(contents->GetRoutingID()),
synchronous_input_handler_proxy_(nullptr),
registered_with_client_(false),
is_active_(true),
renderer_needs_begin_frames_(false),
need_animate_input_(false),
weak_ptr_factory_(this) {
- DCHECK(contents);
DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
-}
+ g_factory.Get(); // Ensure it's initialized.
-SynchronousCompositorImpl::~SynchronousCompositorImpl() {
- DCHECK(!output_surface_);
- DCHECK(!begin_frame_source_);
- DCHECK(!synchronous_input_handler_proxy_);
-}
-
-void SynchronousCompositorImpl::SetClient(
- SynchronousCompositorClient* compositor_client) {
- DCHECK(CalledOnValidThread());
- DCHECK_IMPLIES(compositor_client, !compositor_client_);
- DCHECK_IMPLIES(!compositor_client, compositor_client_);
-
- if (!compositor_client) {
- SynchronousCompositorRegistry::GetInstance()->UnregisterCompositor(
- routing_id_, this);
+ int process_id = rwhva_->GetRenderWidgetHost()->GetProcess()->GetID();
+ if (g_process_id == ChildProcessHost::kInvalidUniqueID) {
+ g_process_id = process_id;
+ } else {
+ DCHECK_EQ(g_process_id, process_id); // Not multiprocess compatible.
}
- compositor_client_ = compositor_client;
+ SynchronousCompositorRegistryInProc::GetInstance()->RegisterCompositor(
+ routing_id_, this);
+}
- // SetClient is essentially the constructor and destructor of
- // SynchronousCompositorImpl.
- if (compositor_client_) {
- SynchronousCompositorRegistry::GetInstance()->RegisterCompositor(
- routing_id_, this);
- }
+SynchronousCompositorImpl::~SynchronousCompositorImpl() {
+ SynchronousCompositorRegistryInProc::GetInstance()->UnregisterCompositor(
+ routing_id_, this);
}
void SynchronousCompositorImpl::RegisterWithClient() {
DCHECK(CalledOnValidThread());
- DCHECK(compositor_client_);
DCHECK(output_surface_);
DCHECK(synchronous_input_handler_proxy_);
DCHECK(!registered_with_client_);
registered_with_client_ = true;
compositor_client_->DidInitializeCompositor(this);
+ compositor_client_->DidBecomeCurrent(this);
output_surface_->SetTreeActivationCallback(
base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree,
@@ -138,41 +109,33 @@ void SynchronousCompositorImpl::RegisterWithClient() {
}
// static
-void SynchronousCompositor::SetGpuService(
+void SynchronousCompositorImpl::SetGpuServiceInProc(
scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
g_factory.Get().SetDeferredGpuService(service);
- GpuProcessHost::RegisterGpuMainThreadFactory(
- CreateInProcessGpuThreadForSynchronousCompositor);
-}
-
-// static
-void SynchronousCompositor::SetUseIpcCommandBuffer() {
- g_factory.Get().SetUseIpcCommandBuffer();
}
void SynchronousCompositorImpl::DidInitializeRendererObjects(
SynchronousCompositorOutputSurface* output_surface,
SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
+ ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
DCHECK(!output_surface_);
DCHECK(!begin_frame_source_);
DCHECK(output_surface);
DCHECK(begin_frame_source);
- DCHECK(compositor_client_);
DCHECK(synchronous_input_handler_proxy);
output_surface_ = output_surface;
begin_frame_source_ = begin_frame_source;
synchronous_input_handler_proxy_ = synchronous_input_handler_proxy;
- output_surface_->SetCompositor(this);
- begin_frame_source_->SetCompositor(this);
+ output_surface_->SetSyncClient(this);
+ begin_frame_source_->SetClient(this);
+ begin_frame_source_->SetBeginFrameSourcePaused(!is_active_);
}
void SynchronousCompositorImpl::DidDestroyRendererObjects() {
DCHECK(output_surface_);
DCHECK(begin_frame_source_);
- DCHECK(compositor_client_);
if (registered_with_client_) {
output_surface_->SetTreeActivationCallback(base::Closure());
@@ -181,8 +144,8 @@ void SynchronousCompositorImpl::DidDestroyRendererObjects() {
}
// This object is being destroyed, so remove pointers to it.
- begin_frame_source_->SetCompositor(nullptr);
- output_surface_->SetCompositor(nullptr);
+ begin_frame_source_->SetClient(nullptr);
+ output_surface_->SetSyncClient(nullptr);
synchronous_input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(
nullptr);
@@ -194,29 +157,25 @@ void SynchronousCompositorImpl::DidDestroyRendererObjects() {
}
scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw(
- gfx::Size surface_size,
+ const gfx::Size& surface_size,
const gfx::Transform& transform,
- gfx::Rect viewport,
- gfx::Rect clip,
- gfx::Rect viewport_rect_for_tile_priority,
+ const gfx::Rect& viewport,
+ const gfx::Rect& clip,
+ const gfx::Rect& viewport_rect_for_tile_priority,
const gfx::Transform& transform_for_tile_priority) {
DCHECK(CalledOnValidThread());
DCHECK(output_surface_);
- DCHECK(compositor_client_);
DCHECK(begin_frame_source_);
+ DCHECK(!frame_holder_);
- scoped_ptr<cc::CompositorFrame> frame =
- output_surface_->DemandDrawHw(surface_size,
- transform,
- viewport,
- clip,
- viewport_rect_for_tile_priority,
- transform_for_tile_priority);
+ output_surface_->DemandDrawHw(surface_size, transform, viewport, clip,
+ viewport_rect_for_tile_priority,
+ transform_for_tile_priority);
- if (frame.get())
- UpdateFrameMetaData(frame->metadata);
+ if (frame_holder_)
+ UpdateFrameMetaData(frame_holder_->metadata);
- return frame.Pass();
+ return std::move(frame_holder_);
}
void SynchronousCompositorImpl::ReturnResources(
@@ -228,24 +187,29 @@ void SynchronousCompositorImpl::ReturnResources(
bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) {
DCHECK(CalledOnValidThread());
DCHECK(output_surface_);
- DCHECK(compositor_client_);
DCHECK(begin_frame_source_);
+ DCHECK(!frame_holder_);
- scoped_ptr<cc::CompositorFrame> frame =
- output_surface_->DemandDrawSw(canvas);
+ output_surface_->DemandDrawSw(canvas);
- if (frame.get())
- UpdateFrameMetaData(frame->metadata);
+ bool success = !!frame_holder_;
+ if (frame_holder_) {
+ UpdateFrameMetaData(frame_holder_->metadata);
+ frame_holder_.reset();
+ }
- return !!frame.get();
+ return success;
+}
+
+void SynchronousCompositorImpl::SwapBuffers(cc::CompositorFrame* frame) {
+ DCHECK(!frame_holder_);
+ frame_holder_.reset(new cc::CompositorFrame);
+ frame->AssignTo(frame_holder_.get());
}
void SynchronousCompositorImpl::UpdateFrameMetaData(
const cc::CompositorFrameMetadata& frame_metadata) {
- RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
- contents_->GetRenderWidgetHostView());
- if (rwhv)
- rwhv->SynchronousFrameMetadata(frame_metadata);
+ rwhva_->SynchronousFrameMetadata(frame_metadata);
DeliverMessages();
}
@@ -263,9 +227,8 @@ void SynchronousCompositorImpl::SetMemoryPolicy(size_t bytes_limit) {
}
}
-void SynchronousCompositorImpl::PostInvalidate() {
+void SynchronousCompositorImpl::Invalidate() {
DCHECK(CalledOnValidThread());
- DCHECK(compositor_client_);
if (registered_with_client_)
compositor_client_->PostInvalidate();
}
@@ -282,8 +245,13 @@ void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset(
void SynchronousCompositorImpl::SetIsActive(bool is_active) {
TRACE_EVENT1("cc", "SynchronousCompositorImpl::SetIsActive", "is_active",
is_active);
+ if (is_active_ == is_active)
+ return;
+
is_active_ = is_active;
UpdateNeedsBeginFrames();
+ if (begin_frame_source_)
+ begin_frame_source_->SetBeginFrameSourcePaused(!is_active_);
}
void SynchronousCompositorImpl::OnComputeScroll(
@@ -312,15 +280,11 @@ void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) {
}
void SynchronousCompositorImpl::UpdateNeedsBeginFrames() {
- RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
- contents_->GetRenderWidgetHostView());
- if (rwhv)
- rwhv->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_);
+ rwhva_->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_);
}
void SynchronousCompositorImpl::DidOverscroll(
const DidOverscrollParams& params) {
- DCHECK(compositor_client_);
if (registered_with_client_) {
compositor_client_->DidOverscroll(params.accumulated_overscroll,
params.latest_overscroll_delta,
@@ -332,7 +296,7 @@ void SynchronousCompositorImpl::DidStopFlinging() {
// It's important that the fling-end notification follow the same path as it
// takes on other platforms (using an IPC). This ensures consistent
// bookkeeping at all stages of the input pipeline.
- contents_->GetRenderProcessHost()->OnMessageReceived(
+ rwhva_->GetRenderWidgetHost()->GetProcess()->OnMessageReceived(
InputHostMsg_DidStopFlinging(routing_id_));
}
@@ -340,22 +304,31 @@ InputEventAckState SynchronousCompositorImpl::HandleInputEvent(
const blink::WebInputEvent& input_event) {
DCHECK(CalledOnValidThread());
return g_factory.Get().synchronous_input_event_filter()->HandleInputEvent(
- contents_->GetRoutingID(), input_event);
+ routing_id_, input_event);
+}
+
+bool SynchronousCompositorImpl::OnMessageReceived(const IPC::Message& message) {
+ NOTREACHED();
+ return false;
+}
+
+void SynchronousCompositorImpl::DidBecomeCurrent() {
+ // This is single process synchronous compositor. There is only one
+ // RenderViewHost. DidBecomeCurrent could be called before the renderer
+ // objects are initialized. So hold off calling DidBecomeCurrent until
+ // RegisterWithClient. Intentional no-op here.
}
void SynchronousCompositorImpl::DeliverMessages() {
- ScopedVector<IPC::Message> messages;
+ std::vector<scoped_ptr<IPC::Message>> messages;
output_surface_->GetMessagesToDeliver(&messages);
- RenderProcessHost* rph = contents_->GetRenderProcessHost();
- for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
- i != messages.end();
- ++i) {
- rph->OnMessageReceived(**i);
+ RenderProcessHost* rph = rwhva_->GetRenderWidgetHost()->GetProcess();
+ for (const auto& msg : messages) {
+ rph->OnMessageReceived(*msg);
}
}
void SynchronousCompositorImpl::DidActivatePendingTree() {
- DCHECK(compositor_client_);
if (registered_with_client_)
compositor_client_->DidUpdateContent();
DeliverMessages();
@@ -363,7 +336,6 @@ void SynchronousCompositorImpl::DidActivatePendingTree() {
void SynchronousCompositorImpl::SetNeedsSynchronousAnimateInput() {
DCHECK(CalledOnValidThread());
- DCHECK(compositor_client_);
if (!registered_with_client_)
return;
need_animate_input_ = true;
@@ -378,7 +350,6 @@ void SynchronousCompositorImpl::UpdateRootLayerState(
float min_page_scale_factor,
float max_page_scale_factor) {
DCHECK(CalledOnValidThread());
- DCHECK(compositor_client_);
if (registered_with_client_) {
// TODO(miletus): Pass in ScrollOffset. crbug.com/414283.
@@ -398,19 +369,4 @@ bool SynchronousCompositorImpl::CalledOnValidThread() const {
return BrowserThread::CurrentlyOn(BrowserThread::UI);
}
-// static
-void SynchronousCompositor::SetClientForWebContents(
- WebContents* contents,
- SynchronousCompositorClient* client) {
- DCHECK(contents);
- if (client) {
- g_factory.Get(); // Ensure it's initialized.
- SynchronousCompositorImpl::CreateForWebContents(contents);
- }
- SynchronousCompositorImpl* instance =
- SynchronousCompositorImpl::FromWebContents(contents);
- DCHECK(instance);
- instance->SetClient(client);
-}
-
} // namespace content
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_impl.h b/chromium/content/browser/android/in_process/synchronous_compositor_impl.h
index 049fe78ec69..e5a14611d8c 100644
--- a/chromium/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/chromium/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -5,29 +5,26 @@
#ifndef CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_IMPL_H_
#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_IMPL_H_
+#include <stddef.h>
+
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "content/browser/android/in_process/synchronous_compositor_output_surface.h"
-#include "content/common/input/input_event_ack_state.h"
-#include "content/public/browser/android/synchronous_compositor.h"
-#include "content/public/browser/web_contents_user_data.h"
-#include "content/renderer/input/synchronous_input_handler_proxy.h"
+#include "content/browser/android/synchronous_compositor_base.h"
+#include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
#include "ipc/ipc_message.h"
+#include "ui/events/blink/synchronous_input_handler_proxy.h"
namespace cc {
-struct BeginFrameArgs;
class InputHandler;
}
-namespace blink {
-class WebInputEvent;
-}
-
namespace content {
class InputHandlerManager;
+class RenderWidgetHostViewAndroid;
class SynchronousCompositorExternalBeginFrameSource;
struct DidOverscrollParams;
@@ -37,41 +34,41 @@ struct DidOverscrollParams;
// This class is created on the main thread but most of the APIs are called
// from the Compositor thread.
class SynchronousCompositorImpl
- : public SynchronousInputHandler,
- public SynchronousCompositor,
- public WebContentsUserData<SynchronousCompositorImpl> {
+ : public ui::SynchronousInputHandler,
+ public SynchronousCompositorBase,
+ public SynchronousCompositorExternalBeginFrameSourceClient,
+ public SynchronousCompositorOutputSurfaceClient {
public:
- // When used from browser code, use both |process_id| and |routing_id|.
- static SynchronousCompositorImpl* FromID(int process_id, int routing_id);
- // When handling upcalls from renderer code, use this version; the process id
+ // For handling upcalls from renderer code; the process id
// is implicitly that of the in-process renderer.
static SynchronousCompositorImpl* FromRoutingID(int routing_id);
- InputEventAckState HandleInputEvent(const blink::WebInputEvent& input_event);
+ static void SetGpuServiceInProc(
+ scoped_refptr<gpu::InProcessCommandBuffer::Service> service);
+
+ ~SynchronousCompositorImpl() override;
// Called by SynchronousCompositorRegistry.
void DidInitializeRendererObjects(
SynchronousCompositorOutputSurface* output_surface,
SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy);
+ ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy);
void DidDestroyRendererObjects();
- // Called by SynchronousCompositorExternalBeginFrameSource.
- void OnNeedsBeginFramesChange(bool needs_begin_frames);
-
- // Called by SynchronousCompositorOutputSurface.
- void PostInvalidate();
+ // SynchronousCompositorExternalBeginFrameSourceClient overrides.
+ void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
- // Called by RenderWidgetHostViewAndroid.
- void BeginFrame(const cc::BeginFrameArgs& args);
+ // SynchronousCompositorOutputSurfaceClient overrides.
+ void Invalidate() override;
+ void SwapBuffers(cc::CompositorFrame* frame) override;
- // SynchronousCompositor
+ // SynchronousCompositor overrides.
scoped_ptr<cc::CompositorFrame> DemandDrawHw(
- gfx::Size surface_size,
+ const gfx::Size& surface_size,
const gfx::Transform& transform,
- gfx::Rect viewport,
- gfx::Rect clip,
- gfx::Rect viewport_rect_for_tile_priority,
+ const gfx::Rect& viewport,
+ const gfx::Rect& clip,
+ const gfx::Rect& viewport_rect_for_tile_priority,
const gfx::Transform& transform_for_tile_priority) override;
bool DemandDrawSw(SkCanvas* canvas) override;
void ReturnResources(const cc::CompositorFrameAck& frame_ack) override;
@@ -81,6 +78,13 @@ class SynchronousCompositorImpl
void SetIsActive(bool is_active) override;
void OnComputeScroll(base::TimeTicks animation_time) override;
+ // SynchronousCompositorBase overrides.
+ void BeginFrame(const cc::BeginFrameArgs& args) override;
+ InputEventAckState HandleInputEvent(
+ const blink::WebInputEvent& input_event) override;
+ bool OnMessageReceived(const IPC::Message& message) override;
+ void DidBecomeCurrent() override;
+
// SynchronousInputHandler
void SetNeedsSynchronousAnimateInput() override;
void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
@@ -94,12 +98,9 @@ class SynchronousCompositorImpl
void DidStopFlinging();
private:
- friend class WebContentsUserData<SynchronousCompositorImpl>;
- friend class SynchronousCompositor;
- explicit SynchronousCompositorImpl(WebContents* contents);
- ~SynchronousCompositorImpl() override;
-
- void SetClient(SynchronousCompositorClient* compositor_client);
+ friend class SynchronousCompositorBase;
+ SynchronousCompositorImpl(RenderWidgetHostViewAndroid* rwhva,
+ SynchronousCompositorClient* client);
void RegisterWithClient();
void UpdateFrameMetaData(const cc::CompositorFrameMetadata& frame_info);
void DidActivatePendingTree();
@@ -107,16 +108,17 @@ class SynchronousCompositorImpl
bool CalledOnValidThread() const;
void UpdateNeedsBeginFrames();
- SynchronousCompositorClient* compositor_client_;
+ RenderWidgetHostViewAndroid* const rwhva_;
+ const int routing_id_;
+ SynchronousCompositorClient* const compositor_client_;
SynchronousCompositorOutputSurface* output_surface_;
SynchronousCompositorExternalBeginFrameSource* begin_frame_source_;
- WebContents* contents_;
- const int routing_id_;
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy_;
+ ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy_;
bool registered_with_client_;
bool is_active_;
bool renderer_needs_begin_frames_;
bool need_animate_input_;
+ scoped_ptr<cc::CompositorFrame> frame_holder_;
base::WeakPtrFactory<SynchronousCompositorImpl> weak_ptr_factory_;
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc
deleted file mode 100644
index f03f992d83d..00000000000
--- a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ /dev/null
@@ -1,292 +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/android/in_process/synchronous_compositor_output_surface.h"
-
-#include "base/auto_reset.h"
-#include "base/logging.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/context_provider.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/output/software_output_device.h"
-#include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h"
-#include "content/browser/android/in_process/synchronous_compositor_impl.h"
-#include "content/browser/android/in_process/synchronous_compositor_registry.h"
-#include "content/browser/gpu/compositor_util.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/renderer/gpu/frame_swap_message_queue.h"
-#include "gpu/command_buffer/client/context_support.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/gfx/transform.h"
-
-namespace content {
-
-namespace {
-
-// Do not limit number of resources, so use an unrealistically high value.
-const size_t kNumResourcesLimit = 10 * 1000 * 1000;
-
-} // namespace
-
-class SynchronousCompositorOutputSurface::SoftwareDevice
- : public cc::SoftwareOutputDevice {
- public:
- SoftwareDevice(SynchronousCompositorOutputSurface* surface)
- : surface_(surface) {
- }
- void Resize(const gfx::Size& pixel_size, float scale_factor) override {
- // Intentional no-op: canvas size is controlled by the embedder.
- }
- SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override {
- if (!surface_->current_sw_canvas_) {
- NOTREACHED() << "BeginPaint with no canvas set";
- return &null_canvas_;
- }
- LOG_IF(WARNING, surface_->frame_holder_.get())
- << "Mutliple calls to BeginPaint per frame";
- return surface_->current_sw_canvas_;
- }
- void EndPaint() override {}
-
- private:
- SynchronousCompositorOutputSurface* surface_;
- SkCanvas null_canvas_;
-
- DISALLOW_COPY_AND_ASSIGN(SoftwareDevice);
-};
-
-SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
- const scoped_refptr<cc::ContextProvider>& context_provider,
- const scoped_refptr<cc::ContextProvider>& worker_context_provider,
- int routing_id,
- scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue)
- : cc::OutputSurface(
- context_provider,
- worker_context_provider,
- scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareDevice(this))),
- routing_id_(routing_id),
- registered_(false),
- current_sw_canvas_(nullptr),
- memory_policy_(0),
- frame_swap_message_queue_(frame_swap_message_queue) {
- capabilities_.draw_and_swap_full_viewport_every_frame = true;
- capabilities_.adjust_deadline_for_parent = false;
- capabilities_.delegated_rendering = true;
- capabilities_.max_frames_pending = 1;
- memory_policy_.priority_cutoff_when_visible =
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
-}
-
-SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {
-}
-
-bool SynchronousCompositorOutputSurface::BindToClient(
- cc::OutputSurfaceClient* surface_client) {
- DCHECK(CalledOnValidThread());
- if (!cc::OutputSurface::BindToClient(surface_client))
- return false;
-
- client_->SetMemoryPolicy(memory_policy_);
-
- SynchronousCompositorRegistry::GetInstance()->RegisterOutputSurface(
- routing_id_, this);
- registered_ = true;
-
- return true;
-}
-
-void SynchronousCompositorOutputSurface::DetachFromClient() {
- DCHECK(CalledOnValidThread());
- if (registered_) {
- SynchronousCompositorRegistry::GetInstance()->UnregisterOutputSurface(
- routing_id_, this);
- }
- cc::OutputSurface::DetachFromClient();
-}
-
-void SynchronousCompositorOutputSurface::SetCompositor(
- SynchronousCompositorImpl* compositor) {
- DCHECK(CalledOnValidThread());
- compositor_ = compositor;
-}
-
-void SynchronousCompositorOutputSurface::Reshape(
- const gfx::Size& size, float scale_factor) {
- // Intentional no-op: surface size is controlled by the embedder.
-}
-
-void SynchronousCompositorOutputSurface::SwapBuffers(
- cc::CompositorFrame* frame) {
- DCHECK(CalledOnValidThread());
-
- frame_holder_.reset(new cc::CompositorFrame);
- frame->AssignTo(frame_holder_.get());
-
- client_->DidSwapBuffers();
-}
-
-void SynchronousCompositorOutputSurface::Invalidate() {
- DCHECK(CalledOnValidThread());
- compositor_->PostInvalidate();
-}
-
-namespace {
-void AdjustTransform(gfx::Transform* transform, gfx::Rect viewport) {
- // CC's draw origin starts at the viewport.
- transform->matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
-}
-} // namespace
-
-scoped_ptr<cc::CompositorFrame>
-SynchronousCompositorOutputSurface::DemandDrawHw(
- gfx::Size surface_size,
- const gfx::Transform& transform,
- gfx::Rect viewport,
- gfx::Rect clip,
- gfx::Rect viewport_rect_for_tile_priority,
- const gfx::Transform& transform_for_tile_priority) {
- DCHECK(CalledOnValidThread());
- DCHECK(HasClient());
- DCHECK(context_provider_.get());
-
- surface_size_ = surface_size;
- InvokeComposite(transform,
- viewport,
- clip,
- viewport_rect_for_tile_priority,
- transform_for_tile_priority,
- true);
-
- return frame_holder_.Pass();
-}
-
-scoped_ptr<cc::CompositorFrame>
-SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
- DCHECK(CalledOnValidThread());
- DCHECK(canvas);
- DCHECK(!current_sw_canvas_);
-
- base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas);
-
- SkIRect canvas_clip;
- canvas->getClipDeviceBounds(&canvas_clip);
- gfx::Rect clip = gfx::SkIRectToRect(canvas_clip);
-
- gfx::Transform transform(gfx::Transform::kSkipInitialization);
- transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4.
-
- surface_size_ = gfx::Size(canvas->getDeviceSize().width(),
- canvas->getDeviceSize().height());
-
- // Pass in the cached hw viewport and transform for tile priority to avoid
- // tile thrashing when the WebView is alternating between hardware and
- // software draws.
- InvokeComposite(transform,
- clip,
- clip,
- cached_hw_viewport_rect_for_tile_priority_,
- cached_hw_transform_for_tile_priority_,
- false);
-
- return frame_holder_.Pass();
-}
-
-void SynchronousCompositorOutputSurface::InvokeComposite(
- const gfx::Transform& transform,
- gfx::Rect viewport,
- gfx::Rect clip,
- gfx::Rect viewport_rect_for_tile_priority,
- gfx::Transform transform_for_tile_priority,
- bool hardware_draw) {
- DCHECK(!frame_holder_.get());
-
- gfx::Transform adjusted_transform = transform;
- AdjustTransform(&adjusted_transform, viewport);
- SetExternalDrawConstraints(adjusted_transform,
- viewport,
- clip,
- viewport_rect_for_tile_priority,
- transform_for_tile_priority,
- !hardware_draw);
- SetNeedsRedrawRect(gfx::Rect(viewport.size()));
-
- client_->OnDraw();
-
- // After software draws (which might move the viewport arbitrarily), restore
- // the previous hardware viewport to allow CC's tile manager to prioritize
- // properly.
- if (hardware_draw) {
- cached_hw_transform_ = adjusted_transform;
- cached_hw_viewport_ = viewport;
- cached_hw_clip_ = clip;
- cached_hw_viewport_rect_for_tile_priority_ =
- viewport_rect_for_tile_priority;
- cached_hw_transform_for_tile_priority_ = transform_for_tile_priority;
- } else {
- bool resourceless_software_draw = false;
- SetExternalDrawConstraints(cached_hw_transform_,
- cached_hw_viewport_,
- cached_hw_clip_,
- cached_hw_viewport_rect_for_tile_priority_,
- cached_hw_transform_for_tile_priority_,
- resourceless_software_draw);
- }
-
- if (frame_holder_.get())
- client_->DidSwapBuffersComplete();
-}
-
-void SynchronousCompositorOutputSurface::ReturnResources(
- const cc::CompositorFrameAck& frame_ack) {
- ReclaimResources(&frame_ack);
-}
-
-void SynchronousCompositorOutputSurface::SetMemoryPolicy(size_t bytes_limit) {
- DCHECK(CalledOnValidThread());
- bool became_zero = memory_policy_.bytes_limit_when_visible && !bytes_limit;
- bool became_non_zero =
- !memory_policy_.bytes_limit_when_visible && bytes_limit;
- memory_policy_.bytes_limit_when_visible = bytes_limit;
- memory_policy_.num_resources_limit = kNumResourcesLimit;
-
- if (client_)
- client_->SetMemoryPolicy(memory_policy_);
-
- if (became_zero) {
- // This is small hack to drop context resources without destroying it
- // when this compositor is put into the background.
- context_provider()->ContextSupport()->SetAggressivelyFreeResources(
- true /* aggressively_free_resources */);
- } else if (became_non_zero) {
- context_provider()->ContextSupport()->SetAggressivelyFreeResources(
- false /* aggressively_free_resources */);
- }
-}
-
-void SynchronousCompositorOutputSurface::SetTreeActivationCallback(
- const base::Closure& callback) {
- DCHECK(client_);
- client_->SetTreeActivationCallback(callback);
-}
-
-void SynchronousCompositorOutputSurface::GetMessagesToDeliver(
- ScopedVector<IPC::Message>* messages) {
- DCHECK(CalledOnValidThread());
- scoped_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope =
- frame_swap_message_queue_->AcquireSendMessageScope();
- frame_swap_message_queue_->DrainMessages(messages);
-}
-
-// Not using base::NonThreadSafe as we want to enforce a more exacting threading
-// requirement: SynchronousCompositorOutputSurface() must only be used on the UI
-// thread.
-bool SynchronousCompositorOutputSurface::CalledOnValidThread() const {
- return BrowserThread::CurrentlyOn(BrowserThread::UI);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h b/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h
deleted file mode 100644
index b1baa643d98..00000000000
--- a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h
+++ /dev/null
@@ -1,122 +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_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
-#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/managed_memory_policy.h"
-#include "cc/output/output_surface.h"
-#include "content/public/browser/android/synchronous_compositor.h"
-#include "ipc/ipc_message.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-class ContextProvider;
-class CompositorFrameMetadata;
-}
-
-namespace IPC {
-class Message;
-}
-
-namespace content {
-
-class FrameSwapMessageQueue;
-class SynchronousCompositorClient;
-class SynchronousCompositorImpl;
-class SynchronousCompositorOutputSurface;
-class WebGraphicsContext3DCommandBufferImpl;
-
-// Specialization of the output surface that adapts it to implement the
-// content::SynchronousCompositor public API. This class effects an "inversion
-// of control" - enabling drawing to be orchestrated by the embedding
-// layer, instead of driven by the compositor internals - hence it holds two
-// 'client' pointers (|client_| in the OutputSurface baseclass and
-// |delegate_|) which represent the consumers of the two roles in plays.
-// This class can be created only on the main thread, but then becomes pinned
-// to a fixed thread when BindToClient is called.
-class SynchronousCompositorOutputSurface
- : NON_EXPORTED_BASE(public cc::OutputSurface) {
- public:
- SynchronousCompositorOutputSurface(
- const scoped_refptr<cc::ContextProvider>& context_provider,
- const scoped_refptr<cc::ContextProvider>& worker_context_provider,
- int routing_id,
- scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue);
- ~SynchronousCompositorOutputSurface() override;
-
- void SetCompositor(SynchronousCompositorImpl* compositor);
-
- // OutputSurface.
- bool BindToClient(cc::OutputSurfaceClient* surface_client) override;
- void DetachFromClient() override;
- void Reshape(const gfx::Size& size, float scale_factor) override;
- void SwapBuffers(cc::CompositorFrame* frame) override;
- void Invalidate() override;
-
- // Partial SynchronousCompositor API implementation.
- scoped_ptr<cc::CompositorFrame> DemandDrawHw(
- gfx::Size surface_size,
- const gfx::Transform& transform,
- gfx::Rect viewport,
- gfx::Rect clip,
- gfx::Rect viewport_rect_for_tile_priority,
- const gfx::Transform& transform_for_tile_priority);
- void ReturnResources(const cc::CompositorFrameAck& frame_ack);
- scoped_ptr<cc::CompositorFrame> DemandDrawSw(SkCanvas* canvas);
- void SetMemoryPolicy(size_t bytes_limit);
- void SetTreeActivationCallback(const base::Closure& callback);
- void GetMessagesToDeliver(ScopedVector<IPC::Message>* messages);
-
- size_t GetMemoryPolicy() const {
- return memory_policy_.bytes_limit_when_visible;
- }
-
- private:
- class SoftwareDevice;
- friend class SoftwareDevice;
-
- void InvokeComposite(const gfx::Transform& transform,
- gfx::Rect viewport,
- gfx::Rect clip,
- gfx::Rect viewport_rect_for_tile_priority,
- gfx::Transform transform_for_tile_priority,
- bool hardware_draw);
- bool CalledOnValidThread() const;
-
- const int routing_id_;
- bool registered_;
-
- // Not owned.
- SynchronousCompositorImpl* compositor_;
-
- gfx::Transform cached_hw_transform_;
- gfx::Rect cached_hw_viewport_;
- gfx::Rect cached_hw_clip_;
- gfx::Rect cached_hw_viewport_rect_for_tile_priority_;
- gfx::Transform cached_hw_transform_for_tile_priority_;
-
- // Only valid (non-NULL) during a DemandDrawSw() call.
- SkCanvas* current_sw_canvas_;
-
- cc::ManagedMemoryPolicy memory_policy_;
-
- scoped_ptr<cc::CompositorFrame> frame_holder_;
-
- scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue_;
-
- DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorOutputSurface);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_registry.cc b/chromium/content/browser/android/in_process/synchronous_compositor_registry_in_proc.cc
index d1017977ba5..4292a873878 100644
--- a/chromium/content/browser/android/in_process/synchronous_compositor_registry.cc
+++ b/chromium/content/browser/android/in_process/synchronous_compositor_registry_in_proc.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/android/in_process/synchronous_compositor_registry.h"
+#include "content/browser/android/in_process/synchronous_compositor_registry_in_proc.h"
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
#include "content/public/browser/browser_thread.h"
@@ -10,24 +10,25 @@
namespace content {
namespace {
-base::LazyInstance<SynchronousCompositorRegistry> g_compositor_registry =
+base::LazyInstance<SynchronousCompositorRegistryInProc> g_compositor_registry =
LAZY_INSTANCE_INITIALIZER;
}
// static
-SynchronousCompositorRegistry* SynchronousCompositorRegistry::GetInstance() {
+SynchronousCompositorRegistryInProc*
+SynchronousCompositorRegistryInProc::GetInstance() {
return g_compositor_registry.Pointer();
}
-SynchronousCompositorRegistry::SynchronousCompositorRegistry() {
+SynchronousCompositorRegistryInProc::SynchronousCompositorRegistryInProc() {
DCHECK(CalledOnValidThread());
}
-SynchronousCompositorRegistry::~SynchronousCompositorRegistry() {
+SynchronousCompositorRegistryInProc::~SynchronousCompositorRegistryInProc() {
DCHECK(CalledOnValidThread());
}
-void SynchronousCompositorRegistry::RegisterCompositor(
+void SynchronousCompositorRegistryInProc::RegisterCompositor(
int routing_id,
SynchronousCompositorImpl* compositor) {
DCHECK(CalledOnValidThread());
@@ -38,7 +39,7 @@ void SynchronousCompositorRegistry::RegisterCompositor(
CheckIsReady(routing_id);
}
-void SynchronousCompositorRegistry::UnregisterCompositor(
+void SynchronousCompositorRegistryInProc::UnregisterCompositor(
int routing_id,
SynchronousCompositorImpl* compositor) {
DCHECK(CalledOnValidThread());
@@ -53,7 +54,7 @@ void SynchronousCompositorRegistry::UnregisterCompositor(
RemoveEntryIfNeeded(routing_id);
}
-void SynchronousCompositorRegistry::RegisterBeginFrameSource(
+void SynchronousCompositorRegistryInProc::RegisterBeginFrameSource(
int routing_id,
SynchronousCompositorExternalBeginFrameSource* begin_frame_source) {
DCHECK(CalledOnValidThread());
@@ -64,7 +65,7 @@ void SynchronousCompositorRegistry::RegisterBeginFrameSource(
CheckIsReady(routing_id);
}
-void SynchronousCompositorRegistry::UnregisterBeginFrameSource(
+void SynchronousCompositorRegistryInProc::UnregisterBeginFrameSource(
int routing_id,
SynchronousCompositorExternalBeginFrameSource* begin_frame_source) {
DCHECK(CalledOnValidThread());
@@ -79,7 +80,7 @@ void SynchronousCompositorRegistry::UnregisterBeginFrameSource(
RemoveEntryIfNeeded(routing_id);
}
-void SynchronousCompositorRegistry::RegisterOutputSurface(
+void SynchronousCompositorRegistryInProc::RegisterOutputSurface(
int routing_id,
SynchronousCompositorOutputSurface* output_surface) {
DCHECK(CalledOnValidThread());
@@ -90,7 +91,7 @@ void SynchronousCompositorRegistry::RegisterOutputSurface(
CheckIsReady(routing_id);
}
-void SynchronousCompositorRegistry::UnregisterOutputSurface(
+void SynchronousCompositorRegistryInProc::UnregisterOutputSurface(
int routing_id,
SynchronousCompositorOutputSurface* output_surface) {
DCHECK(CalledOnValidThread());
@@ -105,9 +106,9 @@ void SynchronousCompositorRegistry::UnregisterOutputSurface(
RemoveEntryIfNeeded(routing_id);
}
-void SynchronousCompositorRegistry::RegisterInputHandler(
+void SynchronousCompositorRegistryInProc::RegisterInputHandler(
int routing_id,
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
+ ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
DCHECK(CalledOnValidThread());
DCHECK(synchronous_input_handler_proxy);
Entry& entry = entry_map_[routing_id];
@@ -116,7 +117,8 @@ void SynchronousCompositorRegistry::RegisterInputHandler(
CheckIsReady(routing_id);
}
-void SynchronousCompositorRegistry::UnregisterInputHandler(int routing_id) {
+void SynchronousCompositorRegistryInProc::UnregisterInputHandler(
+ int routing_id) {
DCHECK(CalledOnValidThread());
DCHECK(entry_map_.find(routing_id) != entry_map_.end());
Entry& entry = entry_map_[routing_id];
@@ -127,7 +129,7 @@ void SynchronousCompositorRegistry::UnregisterInputHandler(int routing_id) {
RemoveEntryIfNeeded(routing_id);
}
-void SynchronousCompositorRegistry::CheckIsReady(int routing_id) {
+void SynchronousCompositorRegistryInProc::CheckIsReady(int routing_id) {
DCHECK(entry_map_.find(routing_id) != entry_map_.end());
Entry& entry = entry_map_[routing_id];
if (entry.IsReady()) {
@@ -137,14 +139,14 @@ void SynchronousCompositorRegistry::CheckIsReady(int routing_id) {
}
}
-void SynchronousCompositorRegistry::UnregisterObjects(int routing_id) {
+void SynchronousCompositorRegistryInProc::UnregisterObjects(int routing_id) {
DCHECK(entry_map_.find(routing_id) != entry_map_.end());
Entry& entry = entry_map_[routing_id];
DCHECK(entry.IsReady());
entry.compositor->DidDestroyRendererObjects();
}
-void SynchronousCompositorRegistry::RemoveEntryIfNeeded(int routing_id) {
+void SynchronousCompositorRegistryInProc::RemoveEntryIfNeeded(int routing_id) {
DCHECK(entry_map_.find(routing_id) != entry_map_.end());
Entry& entry = entry_map_[routing_id];
if (!entry.compositor && !entry.begin_frame_source && !entry.output_surface &&
@@ -153,17 +155,17 @@ void SynchronousCompositorRegistry::RemoveEntryIfNeeded(int routing_id) {
}
}
-bool SynchronousCompositorRegistry::CalledOnValidThread() const {
+bool SynchronousCompositorRegistryInProc::CalledOnValidThread() const {
return BrowserThread::CurrentlyOn(BrowserThread::UI);
}
-SynchronousCompositorRegistry::Entry::Entry()
+SynchronousCompositorRegistryInProc::Entry::Entry()
: compositor(nullptr),
begin_frame_source(nullptr),
output_surface(nullptr),
synchronous_input_handler_proxy(nullptr) {}
-bool SynchronousCompositorRegistry::Entry::IsReady() {
+bool SynchronousCompositorRegistryInProc::Entry::IsReady() {
return compositor && begin_frame_source && output_surface &&
synchronous_input_handler_proxy;
}
diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_registry.h b/chromium/content/browser/android/in_process/synchronous_compositor_registry_in_proc.h
index f7dc913e646..1de200260d7 100644
--- a/chromium/content/browser/android/in_process/synchronous_compositor_registry.h
+++ b/chromium/content/browser/android/in_process/synchronous_compositor_registry_in_proc.h
@@ -2,14 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_REGISTRY_H_
-#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_REGISTRY_H_
+#ifndef CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_REGISTRY_IN_PROC_H_
+#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_REGISTRY_IN_PROC_H_
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "content/renderer/android/synchronous_compositor_registry.h"
+#include "ui/events/blink/synchronous_input_handler_proxy.h"
-namespace cc {
-class InputHandler;
+namespace ui {
+class SynchronousInputHandlerProxy;
}
namespace content {
@@ -17,43 +20,46 @@ namespace content {
class SynchronousCompositorExternalBeginFrameSource;
class SynchronousCompositorImpl;
class SynchronousCompositorOutputSurface;
-class SynchronousInputHandlerProxy;
-class SynchronousCompositorRegistry {
+class SynchronousCompositorRegistryInProc
+ : public SynchronousCompositorRegistry {
public:
- static SynchronousCompositorRegistry* GetInstance();
+ static SynchronousCompositorRegistryInProc* GetInstance();
void RegisterCompositor(int routing_id,
SynchronousCompositorImpl* compositor);
void UnregisterCompositor(int routing_id,
SynchronousCompositorImpl* compositor);
- void RegisterBeginFrameSource(
- int routing_id,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source);
- void UnregisterBeginFrameSource(
+ void RegisterInputHandler(
int routing_id,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source);
+ ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy);
+ void UnregisterInputHandler(int routing_id);
+
+ // SynchronousCompositorRegistry overrides.
+ void RegisterBeginFrameSource(int routing_id,
+ SynchronousCompositorExternalBeginFrameSource*
+ begin_frame_source) override;
+ void UnregisterBeginFrameSource(int routing_id,
+ SynchronousCompositorExternalBeginFrameSource*
+ begin_frame_source) override;
void RegisterOutputSurface(
int routing_id,
- SynchronousCompositorOutputSurface* output_surface);
+ SynchronousCompositorOutputSurface* output_surface) override;
void UnregisterOutputSurface(
int routing_id,
- SynchronousCompositorOutputSurface* output_surface);
- void RegisterInputHandler(
- int routing_id,
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy);
- void UnregisterInputHandler(int routing_id);
+ SynchronousCompositorOutputSurface* output_surface) override;
private:
- friend struct base::DefaultLazyInstanceTraits<SynchronousCompositorRegistry>;
- SynchronousCompositorRegistry();
- ~SynchronousCompositorRegistry();
+ friend struct base::DefaultLazyInstanceTraits<
+ SynchronousCompositorRegistryInProc>;
+ SynchronousCompositorRegistryInProc();
+ ~SynchronousCompositorRegistryInProc() override;
struct Entry {
SynchronousCompositorImpl* compositor;
SynchronousCompositorExternalBeginFrameSource* begin_frame_source;
SynchronousCompositorOutputSurface* output_surface;
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy;
+ ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy;
Entry();
bool IsReady();
@@ -68,9 +74,9 @@ class SynchronousCompositorRegistry {
EntryMap entry_map_;
- DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorRegistry);
+ DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorRegistryInProc);
};
} // namespace content
-#endif // CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_REGISTRY_H_
+#endif // CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_REGISTRY_IN_PROC_H_
diff --git a/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc b/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc
index 6645607edf0..3ce1c61eb4f 100644
--- a/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc
+++ b/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc
@@ -6,8 +6,9 @@
#include "base/callback.h"
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
-#include "content/browser/android/in_process/synchronous_compositor_registry.h"
+#include "content/browser/android/in_process/synchronous_compositor_registry_in_proc.h"
#include "content/public/browser/browser_thread.h"
+#include "ui/events/blink/synchronous_input_handler_proxy.h"
#include "ui/events/latency_info.h"
using blink::WebInputEvent;
@@ -47,15 +48,15 @@ void SynchronousInputEventFilter::SetBoundHandlerOnUIThread(
void SynchronousInputEventFilter::DidAddInputHandler(
int routing_id,
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
+ ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SynchronousCompositorRegistry::GetInstance()->RegisterInputHandler(
+ SynchronousCompositorRegistryInProc::GetInstance()->RegisterInputHandler(
routing_id, synchronous_input_handler_proxy);
}
void SynchronousInputEventFilter::DidRemoveInputHandler(int routing_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SynchronousCompositorRegistry::GetInstance()->UnregisterInputHandler(
+ SynchronousCompositorRegistryInProc::GetInstance()->UnregisterInputHandler(
routing_id);
}
diff --git a/chromium/content/browser/android/in_process/synchronous_input_event_filter.h b/chromium/content/browser/android/in_process/synchronous_input_event_filter.h
index 89feee1e6e5..98375d73bf8 100644
--- a/chromium/content/browser/android/in_process/synchronous_input_event_filter.h
+++ b/chromium/content/browser/android/in_process/synchronous_input_event_filter.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_INPUT_EVENT_FILTER_H_
#define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_INPUT_EVENT_FILTER_H_
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "content/common/input/input_event_ack_state.h"
@@ -16,6 +15,10 @@ namespace blink {
class WebInputEvent;
}
+namespace ui {
+class SynchronousInputHandlerProxy;
+}
+
namespace content {
// This class perform synchronous, in-process InputEvent handling.
@@ -35,7 +38,8 @@ class SynchronousInputEventFilter : public InputHandlerManagerClient {
void SetBoundHandler(const Handler& handler) override;
void DidAddInputHandler(
int routing_id,
- SynchronousInputHandlerProxy* synchronous_input_handler_proxy) override;
+ ui::SynchronousInputHandlerProxy*
+ synchronous_input_handler_proxy) override;
void DidRemoveInputHandler(int routing_id) override;
void DidOverscroll(int routing_id,
const DidOverscrollParams& params) override;
diff --git a/chromium/content/browser/android/in_process_surface_texture_manager.h b/chromium/content/browser/android/in_process_surface_texture_manager.h
index 6b02c8b76ea..24e951c7b2f 100644
--- a/chromium/content/browser/android/in_process_surface_texture_manager.h
+++ b/chromium/content/browser/android/in_process_surface_texture_manager.h
@@ -8,6 +8,7 @@
#include "content/common/android/surface_texture_manager.h"
#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
diff --git a/chromium/content/browser/android/interstitial_page_delegate_android.cc b/chromium/content/browser/android/interstitial_page_delegate_android.cc
index ce727ef830e..ee4bba840fa 100644
--- a/chromium/content/browser/android/interstitial_page_delegate_android.cc
+++ b/chromium/content/browser/android/interstitial_page_delegate_android.cc
@@ -31,13 +31,16 @@ InterstitialPageDelegateAndroid::~InterstitialPageDelegateAndroid() {
Java_InterstitialPageDelegateAndroid_onNativeDestroyed(env, obj.obj());
}
-void InterstitialPageDelegateAndroid::Proceed(JNIEnv* env, jobject obj) {
+void InterstitialPageDelegateAndroid::Proceed(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (page_)
page_->Proceed();
}
-void InterstitialPageDelegateAndroid::DontProceed(JNIEnv* env,
- jobject obj) {
+void InterstitialPageDelegateAndroid::DontProceed(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (page_)
page_->DontProceed();
}
diff --git a/chromium/content/browser/android/interstitial_page_delegate_android.h b/chromium/content/browser/android/interstitial_page_delegate_android.h
index bd28d381c9d..dcc92ce94d6 100644
--- a/chromium/content/browser/android/interstitial_page_delegate_android.h
+++ b/chromium/content/browser/android/interstitial_page_delegate_android.h
@@ -9,8 +9,8 @@
#include <string>
#include "base/android/jni_weak_ref.h"
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/interstitial_page_delegate.h"
@@ -31,8 +31,9 @@ class InterstitialPageDelegateAndroid : public InterstitialPageDelegate {
void set_interstitial_page(InterstitialPage* page) { page_ = page; }
// Methods called from Java.
- void Proceed(JNIEnv* env, jobject obj);
- void DontProceed(JNIEnv* env, jobject obj);
+ void Proceed(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void DontProceed(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
// Implementation of InterstitialPageDelegate
std::string GetHTMLContents() override;
diff --git a/chromium/content/browser/android/java/gin_java_bound_object.cc b/chromium/content/browser/android/java/gin_java_bound_object.cc
index 527fcef83bd..d281f8902b0 100644
--- a/chromium/content/browser/android/java/gin_java_bound_object.cc
+++ b/chromium/content/browser/android/java/gin_java_bound_object.cc
@@ -42,8 +42,8 @@ GinJavaBoundObject* GinJavaBoundObject::CreateNamed(
GinJavaBoundObject* GinJavaBoundObject::CreateTransient(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- int32 holder) {
- std::set<int32> holders;
+ int32_t holder) {
+ std::set<int32_t> holders;
holders.insert(holder);
return new GinJavaBoundObject(ref, safe_annotation_clazz, holders);
}
@@ -61,14 +61,13 @@ GinJavaBoundObject::GinJavaBoundObject(
GinJavaBoundObject::GinJavaBoundObject(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- const std::set<int32>& holders)
+ const std::set<int32_t>& holders)
: ref_(ref),
names_count_(0),
holders_(holders),
object_get_class_method_id_(NULL),
are_methods_set_up_(false),
- safe_annotation_clazz_(safe_annotation_clazz) {
-}
+ safe_annotation_clazz_(safe_annotation_clazz) {}
GinJavaBoundObject::~GinJavaBoundObject() {
}
diff --git a/chromium/content/browser/android/java/gin_java_bound_object.h b/chromium/content/browser/android/java/gin_java_bound_object.h
index cd3a04de930..735e14a7b71 100644
--- a/chromium/content/browser/android/java/gin_java_bound_object.h
+++ b/chromium/content/browser/android/java/gin_java_bound_object.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BOUND_OBJECT_H_
#define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BOUND_OBJECT_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <set>
@@ -20,7 +23,7 @@ namespace content {
class GinJavaBoundObject
: public base::RefCountedThreadSafe<GinJavaBoundObject> {
public:
- typedef int32 ObjectID;
+ typedef int32_t ObjectID;
static GinJavaBoundObject* CreateNamed(
const JavaObjectWeakGlobalRef& ref,
@@ -28,7 +31,7 @@ class GinJavaBoundObject
static GinJavaBoundObject* CreateTransient(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- int32 holder);
+ int32_t holder);
// The following methods can be called on any thread.
JavaObjectWeakGlobalRef& GetWeakRef() { return ref_; }
@@ -42,8 +45,8 @@ class GinJavaBoundObject
// The following methods are called on the background thread.
bool HasHolders() { return !holders_.empty(); }
- void AddHolder(int32 holder) { holders_.insert(holder); }
- void RemoveHolder(int32 holder) { holders_.erase(holder); }
+ void AddHolder(int32_t holder) { holders_.insert(holder); }
+ void RemoveHolder(int32_t holder) { holders_.erase(holder); }
std::set<std::string> GetMethodNames();
bool HasMethod(const std::string& method_name);
@@ -62,7 +65,7 @@ class GinJavaBoundObject
GinJavaBoundObject(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- const std::set<int32>& holders);
+ const std::set<int32_t>& holders);
~GinJavaBoundObject();
// The following methods are called on the background thread.
@@ -73,7 +76,7 @@ class GinJavaBoundObject
// An object must be kept in retained_object_set_ either if it has
// names or if it has a non-empty holders set.
int names_count_;
- std::set<int32> holders_;
+ std::set<int32_t> holders_;
// The following fields are accessed on the background thread.
typedef std::multimap<std::string, linked_ptr<JavaMethod> > JavaMethodMap;
diff --git a/chromium/content/browser/android/java/gin_java_bound_object_delegate.h b/chromium/content/browser/android/java/gin_java_bound_object_delegate.h
index cdee8a61c6c..f4a9c2aef54 100644
--- a/chromium/content/browser/android/java/gin_java_bound_object_delegate.h
+++ b/chromium/content/browser/android/java/gin_java_bound_object_delegate.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BOUND_OBJECT_DELEGATE_H_
#define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BOUND_OBJECT_DELEGATE_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/android/java/gin_java_bound_object.h"
#include "content/browser/android/java/gin_java_method_invocation_helper.h"
diff --git a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
index 0a08896b092..2de4f9fef0f 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -6,6 +6,7 @@
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
+#include "build/build_config.h"
#include "content/browser/android/java/gin_java_bound_object_delegate.h"
#include "content/browser/android/java/gin_java_bridge_message_filter.h"
#include "content/browser/android/java/java_bridge_thread.h"
@@ -79,11 +80,25 @@ void GinJavaBridgeDispatcherHost::WebContentsDestroyed() {
filter->RemoveHost(this);
}
+void GinJavaBridgeDispatcherHost::RenderProcessGone(
+ base::TerminationStatus status) {
+ GinJavaBridgeMessageFilter::RemoveFilter(this);
+}
+
+void GinJavaBridgeDispatcherHost::RenderViewHostChanged(
+ RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ scoped_refptr<GinJavaBridgeMessageFilter> filter =
+ GinJavaBridgeMessageFilter::FromHost(this, false);
+ if (!filter)
+ InstallFilterAndRegisterAllRoutingIds();
+}
+
GinJavaBoundObject::ObjectID GinJavaBridgeDispatcherHost::AddObject(
const base::android::JavaRef<jobject>& object,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
bool is_named,
- int32 holder) {
+ int32_t holder) {
// Can be called on any thread. Calls come from the UI thread via
// AddNamedObject, and from the background thread, when injected Java
// object's method returns a Java object.
@@ -143,7 +158,7 @@ JavaObjectWeakGlobalRef GinJavaBridgeDispatcherHost::GetObjectWeakRef(
JavaObjectWeakGlobalRef
GinJavaBridgeDispatcherHost::RemoveHolderAndAdvanceLocked(
- int32 holder,
+ int32_t holder,
ObjectMap::iterator* iter_ptr) {
objects_lock_.AssertAcquired();
JavaObjectWeakGlobalRef result;
diff --git a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h
index f17fd50ae06..3bfbd261f4e 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h
+++ b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_DISPATCHER_HOST_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "content/browser/android/java/gin_java_bound_object.h"
@@ -47,6 +50,9 @@ class GinJavaBridgeDispatcherHost
void RenderFrameCreated(RenderFrameHost* render_frame_host) override;
void DocumentAvailableInMainFrame() override;
void WebContentsDestroyed() override;
+ void RenderProcessGone(base::TerminationStatus status) override;
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) override;
// GinJavaMethodInvocationHelper::DispatcherDelegate
JavaObjectWeakGlobalRef GetObjectWeakRef(
@@ -83,14 +89,14 @@ class GinJavaBridgeDispatcherHost
const base::android::JavaRef<jobject>& object,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
bool is_named,
- int32 holder);
+ int32_t holder);
scoped_refptr<GinJavaBoundObject> FindObject(
GinJavaBoundObject::ObjectID object_id);
bool FindObjectId(const base::android::JavaRef<jobject>& object,
GinJavaBoundObject::ObjectID* object_id);
void RemoveFromRetainedObjectSetLocked(const JavaObjectWeakGlobalRef& ref);
JavaObjectWeakGlobalRef RemoveHolderAndAdvanceLocked(
- int32 holder,
+ int32_t holder,
ObjectMap::iterator* iter_ptr);
// The following objects are used only on the UI thread.
diff --git a/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc b/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc
index 698ce5d5b56..dd45d0a5ecb 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc
+++ b/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc
@@ -5,6 +5,7 @@
#include "content/browser/android/java/gin_java_bridge_message_filter.h"
#include "base/auto_reset.h"
+#include "build/build_config.h"
#include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
#include "content/browser/android/java/java_bridge_thread.h"
#include "content/common/gin_java_bridge_messages.h"
@@ -43,7 +44,8 @@ void GinJavaBridgeMessageFilter::OnDestruct() const {
bool GinJavaBridgeMessageFilter::OnMessageReceived(
const IPC::Message& message) {
DCHECK(JavaBridgeThread::CurrentlyOn());
- base::AutoReset<int32> routing_id(&current_routing_id_, message.routing_id());
+ base::AutoReset<int32_t> routing_id(&current_routing_id_,
+ message.routing_id());
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GinJavaBridgeMessageFilter, message)
IPC_MESSAGE_HANDLER(GinJavaBridgeHostMsg_GetMethods, OnGetMethods)
@@ -103,12 +105,16 @@ GinJavaBridgeDispatcherHost* GinJavaBridgeMessageFilter::FindHost() {
auto iter = hosts_.find(current_routing_id_);
if (iter != hosts_.end())
return iter->second;
- // This is usually OK -- we can receive messages from RenderFrames for
- // which the corresponding host part has already been destroyed. That means,
- // any references to Java objects that the host was holding were already
- // released (with the death of ContentViewCore), so we can just drop such
- // messages.
- LOG(WARNING) << "WebView: Unknown frame routing id: " << current_routing_id_;
+ // Not being able to find a host is OK -- we can receive messages from
+ // RenderFrames for which the corresponding host part has already been
+ // destroyed. That means, any references to Java objects that the host was
+ // holding were already released (with the death of ContentViewCore), so we
+ // can just ignore such messages.
+ // RenderProcessHostImpl does the same -- if it can't find a listener
+ // for the message's routing id, it just drops the message silently.
+ // The only action RenderProcessHostImpl does is sending a reply to incoming
+ // synchronous messages, but as we handle all our messages using
+ // IPC_MESSAGE_HANDLER, the reply will be sent automatically.
return nullptr;
}
@@ -162,4 +168,11 @@ void GinJavaBridgeMessageFilter::OnObjectWrapperDeleted(
host->OnObjectWrapperDeleted(current_routing_id_, object_id);
}
+// static
+void GinJavaBridgeMessageFilter::RemoveFilter(
+ GinJavaBridgeDispatcherHost* host) {
+ RenderProcessHost* rph = host->web_contents()->GetRenderProcessHost();
+ rph->RemoveUserData(kGinJavaBridgeMessageFilterKey);
+}
+
} // namespace content
diff --git a/chromium/content/browser/android/java/gin_java_bridge_message_filter.h b/chromium/content/browser/android/java/gin_java_bridge_message_filter.h
index 630963207b6..ee5051af76b 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_message_filter.h
+++ b/chromium/content/browser/android/java/gin_java_bridge_message_filter.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include <map>
#include <set>
@@ -43,6 +45,11 @@ class GinJavaBridgeMessageFilter : public BrowserMessageFilter {
static scoped_refptr<GinJavaBridgeMessageFilter> FromHost(
GinJavaBridgeDispatcherHost* host, bool create_if_not_exists);
+ // Removes the filter, which triggers its deletion. Needs to be called when
+ // the corresponding RenderProcessHost cleans itself up, e.g. on renderer
+ // process exit.
+ static void RemoveFilter(GinJavaBridgeDispatcherHost* host);
+
private:
friend class BrowserThread;
friend class base::DeleteHelper<GinJavaBridgeMessageFilter>;
@@ -59,7 +66,7 @@ class GinJavaBridgeMessageFilter : public BrowserMessageFilter {
// 2. As RenderFrames pass away earlier than JavaScript wrappers,
// messages from the latter can arrive after the RenderFrame has been
// removed from the WebContents' routing table.
- typedef std::map<int32, GinJavaBridgeDispatcherHost*> HostMap;
+ typedef std::map<int32_t, GinJavaBridgeDispatcherHost*> HostMap;
GinJavaBridgeMessageFilter();
~GinJavaBridgeMessageFilter() override;
@@ -84,7 +91,7 @@ class GinJavaBridgeMessageFilter : public BrowserMessageFilter {
// The routing id of the RenderFrameHost whose request we are processing.
// Used on the background thread.
- int32 current_routing_id_;
+ int32_t current_routing_id_;
};
} // namespace content
diff --git a/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc b/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc
index 93ab2e66228..904926f6fbe 100644
--- a/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc
+++ b/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc
@@ -5,8 +5,8 @@
#include "content/browser/android/java/gin_java_method_invocation_helper.h"
#include <unistd.h>
-
#include <cmath>
+#include <utility>
#include "base/android/event_log.h"
#include "base/android/jni_android.h"
@@ -33,11 +33,10 @@ GinJavaMethodInvocationHelper::GinJavaMethodInvocationHelper(
scoped_ptr<ObjectDelegate> object,
const std::string& method_name,
const base::ListValue& arguments)
- : object_(object.Pass()),
+ : object_(std::move(object)),
method_name_(method_name),
arguments_(arguments.DeepCopy()),
- invocation_error_(kGinJavaBridgeNoError) {
-}
+ invocation_error_(kGinJavaBridgeNoError) {}
GinJavaMethodInvocationHelper::~GinJavaMethodInvocationHelper() {}
@@ -210,7 +209,7 @@ GinJavaMethodInvocationHelper::GetSafeAnnotationClass() {
return safe_annotation_clazz_;
}
-const GinJavaBridgeError GinJavaMethodInvocationHelper::GetInvocationError() {
+GinJavaBridgeError GinJavaMethodInvocationHelper::GetInvocationError() {
return invocation_error_;
}
diff --git a/chromium/content/browser/android/java/gin_java_method_invocation_helper.h b/chromium/content/browser/android/java/gin_java_method_invocation_helper.h
index f7bdd57747f..b61fdfd68eb 100644
--- a/chromium/content/browser/android/java/gin_java_method_invocation_helper.h
+++ b/chromium/content/browser/android/java/gin_java_method_invocation_helper.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_METHOD_INVOCATION_HELPER_H_
#define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_METHOD_INVOCATION_HELPER_H_
+#include <stddef.h>
+
#include <map>
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/values.h"
#include "content/browser/android/java/gin_java_bound_object.h"
@@ -63,7 +66,7 @@ class CONTENT_EXPORT GinJavaMethodInvocationHelper
const base::ListValue& GetPrimitiveResult();
const base::android::JavaRef<jobject>& GetObjectResult();
const base::android::JavaRef<jclass>& GetSafeAnnotationClass();
- const GinJavaBridgeError GetInvocationError();
+ GinJavaBridgeError GetInvocationError();
private:
friend class base::RefCountedThreadSafe<GinJavaMethodInvocationHelper>;
diff --git a/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc b/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
index fcda3cda934..395df88f1b9 100644
--- a/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
+++ b/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
@@ -4,7 +4,10 @@
#include "content/browser/android/java/gin_java_method_invocation_helper.h"
+#include <stddef.h>
+
#include "base/android/jni_android.h"
+#include "base/macros.h"
#include "content/browser/android/java/jni_helper.h"
#include "content/common/android/gin_java_bridge_value.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -43,7 +46,7 @@ class NullObjectDelegate
}
private:
- base::android::ScopedJavaLocalRef<jclass> safe_annotation_class_;
+ base::android::ScopedJavaGlobalRef<jclass> safe_annotation_class_;
DISALLOW_COPY_AND_ASSIGN(NullObjectDelegate);
};
diff --git a/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc b/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
index b74775280e6..f65a96aea18 100644
--- a/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
+++ b/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
@@ -7,6 +7,8 @@
#include <stdint.h>
#include <unistd.h>
+#include <limits>
+
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/strings/string_number_conversions.h"
@@ -34,19 +36,19 @@ double RoundDoubleTowardsZero(const double& x) {
// Rounds to jlong using Java's type conversion rules.
jlong RoundDoubleToLong(const double& x) {
double intermediate = RoundDoubleTowardsZero(x);
- // The int64 limits can not be converted exactly to double values, so we
+ // The int64_t limits can not be converted exactly to double values, so we
// compare to custom constants. kint64max is 2^63 - 1, but the spacing
// between double values in the the range 2^62 to 2^63 is 2^10. The cast is
// required to silence a spurious gcc warning for integer overflow.
- const int64 kLimit = (INT64_C(1) << 63) - static_cast<uint64>(1 << 10);
+ const int64_t kLimit = (INT64_C(1) << 63) - static_cast<uint64_t>(1 << 10);
DCHECK(kLimit > 0);
const double kLargestDoubleLessThanInt64Max = kLimit;
const double kSmallestDoubleGreaterThanInt64Min = -kLimit;
if (intermediate > kLargestDoubleLessThanInt64Max) {
- return kint64max;
+ return std::numeric_limits<int64_t>::max();
}
if (intermediate < kSmallestDoubleGreaterThanInt64Min) {
- return kint64min;
+ return std::numeric_limits<int64_t>::min();
}
return static_cast<jlong>(intermediate);
}
@@ -54,9 +56,11 @@ jlong RoundDoubleToLong(const double& x) {
// Rounds to jint using Java's type conversion rules.
jint RoundDoubleToInt(const double& x) {
double intermediate = RoundDoubleTowardsZero(x);
- // The int32 limits cast exactly to double values.
- intermediate = std::min(intermediate, static_cast<double>(kint32max));
- intermediate = std::max(intermediate, static_cast<double>(kint32min));
+ // The int32_t limits cast exactly to double values.
+ intermediate = std::min(
+ intermediate, static_cast<double>(std::numeric_limits<int32_t>::max()));
+ intermediate = std::max(
+ intermediate, static_cast<double>(std::numeric_limits<int32_t>::min()));
return static_cast<jint>(intermediate);
}
@@ -514,13 +518,14 @@ jobject CoerceJavaScriptDictionaryToArray(JNIEnv* env,
if (length_value->IsType(base::Value::TYPE_INTEGER)) {
int int_length;
length_value->GetAsInteger(&int_length);
- if (int_length >= 0 && int_length <= kint32max) {
+ if (int_length >= 0 && int_length <= std::numeric_limits<int32_t>::max()) {
length = static_cast<jsize>(int_length);
}
} else if (length_value->IsType(base::Value::TYPE_DOUBLE)) {
double double_length;
length_value->GetAsDouble(&double_length);
- if (double_length >= 0.0 && double_length <= kint32max) {
+ if (double_length >= 0.0 &&
+ double_length <= std::numeric_limits<int32_t>::max()) {
length = static_cast<jsize>(double_length);
}
}
diff --git a/chromium/content/browser/android/java/java_bridge_thread.cc b/chromium/content/browser/android/java/java_bridge_thread.cc
index a221527b564..6c69bc0d571 100644
--- a/chromium/content/browser/android/java/java_bridge_thread.cc
+++ b/chromium/content/browser/android/java/java_bridge_thread.cc
@@ -7,6 +7,7 @@
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
#include "base/task_runner_util.h"
+#include "build/build_config.h"
#if !defined(OS_ANDROID)
#error "JavaBridge only supports OS_ANDROID"
diff --git a/chromium/content/browser/android/java/java_method.h b/chromium/content/browser/android/java/java_method.h
index b5ba26a6f5f..333d4031e68 100644
--- a/chromium/content/browser/android/java/java_method.h
+++ b/chromium/content/browser/android/java/java_method.h
@@ -6,10 +6,12 @@
#define CONTENT_BROWSER_ANDROID_JAVA_JAVA_METHOD_H_
#include <jni.h>
+#include <stddef.h>
#include <string>
#include <vector>
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "content/browser/android/java/java_type.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/android/java/java_type.cc b/chromium/content/browser/android/java/java_type.cc
index 3c48532e6c1..0ebc4f30c8a 100644
--- a/chromium/content/browser/android/java/java_type.cc
+++ b/chromium/content/browser/android/java/java_type.cc
@@ -61,7 +61,7 @@ scoped_ptr<JavaType> CreateFromArrayComponentTypeName(
// Includes void (V).
NOTREACHED();
}
- return result.Pass();
+ return result;
}
} // namespace
diff --git a/chromium/content/browser/android/java/java_type_unittest.cc b/chromium/content/browser/android/java/java_type_unittest.cc
index 484b3eb43a9..c55d716792e 100644
--- a/chromium/content/browser/android/java/java_type_unittest.cc
+++ b/chromium/content/browser/android/java/java_type_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/android/java/java_type.h"
+#include <stddef.h>
+
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/browser/android/overscroll_controller_android.cc b/chromium/content/browser/android/overscroll_controller_android.cc
index 857d2f64d98..d62f2327b7f 100644
--- a/chromium/content/browser/android/overscroll_controller_android.cc
+++ b/chromium/content/browser/android/overscroll_controller_android.cc
@@ -9,18 +9,26 @@
#include "cc/layers/layer.h"
#include "cc/output/compositor_frame_metadata.h"
#include "content/browser/android/content_view_core_impl.h"
-#include "content/browser/android/edge_effect.h"
-#include "content/browser/android/edge_effect_l.h"
#include "content/common/input/did_overscroll_params.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_switches.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/android/edge_effect.h"
+#include "ui/android/edge_effect_l.h"
#include "ui/android/resources/resource_manager.h"
#include "ui/android/window_android.h"
#include "ui/android/window_android_compositor.h"
#include "ui/base/l10n/l10n_util_android.h"
+using ui::EdgeEffect;
+using ui::EdgeEffectBase;
+using ui::EdgeEffectL;
+using ui::OverscrollGlow;
+using ui::OverscrollGlowClient;
+using ui::OverscrollRefresh;
+using ui::OverscrollRefreshHandler;
+
namespace content {
namespace {
diff --git a/chromium/content/browser/android/overscroll_controller_android.h b/chromium/content/browser/android/overscroll_controller_android.h
index 852f074a40f..73c1b769bc1 100644
--- a/chromium/content/browser/android/overscroll_controller_android.h
+++ b/chromium/content/browser/android/overscroll_controller_android.h
@@ -5,10 +5,11 @@
#ifndef CONTENT_BROWSER_ANDROID_OVERSCROLL_CONTROLLER_ANDROID_H_
#define CONTENT_BROWSER_ANDROID_OVERSCROLL_CONTROLLER_ANDROID_H_
+#include "base/macros.h"
#include "base/time/time.h"
-#include "content/browser/android/overscroll_glow.h"
-#include "content/browser/android/overscroll_refresh.h"
#include "content/common/input/input_event_ack_state.h"
+#include "ui/android/overscroll_glow.h"
+#include "ui/android/overscroll_refresh.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace blink {
@@ -32,7 +33,7 @@ struct DidOverscrollParams;
// Glue class for handling all inputs into Android-specific overscroll effects,
// both the passive overscroll glow and the active overscroll pull-to-refresh.
// Note that all input coordinates (both for events and overscroll) are in DIPs.
-class OverscrollControllerAndroid : public OverscrollGlowClient {
+class OverscrollControllerAndroid : public ui::OverscrollGlowClient {
public:
explicit OverscrollControllerAndroid(ContentViewCoreImpl* content_view_core);
~OverscrollControllerAndroid() override;
@@ -62,7 +63,7 @@ class OverscrollControllerAndroid : public OverscrollGlowClient {
private:
// OverscrollGlowClient implementation.
- scoped_ptr<EdgeEffectBase> CreateEdgeEffect() override;
+ scoped_ptr<ui::EdgeEffectBase> CreateEdgeEffect() override;
void SetNeedsAnimate();
@@ -72,8 +73,8 @@ class OverscrollControllerAndroid : public OverscrollGlowClient {
bool enabled_;
// TODO(jdduke): Factor out a common API from the two overscroll effects.
- scoped_ptr<OverscrollGlow> glow_effect_;
- scoped_ptr<OverscrollRefresh> refresh_effect_;
+ scoped_ptr<ui::OverscrollGlow> glow_effect_;
+ scoped_ptr<ui::OverscrollRefresh> refresh_effect_;
DISALLOW_COPY_AND_ASSIGN(OverscrollControllerAndroid);
};
diff --git a/chromium/content/browser/android/overscroll_glow.cc b/chromium/content/browser/android/overscroll_glow.cc
deleted file mode 100644
index edebea9e9e4..00000000000
--- a/chromium/content/browser/android/overscroll_glow.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/overscroll_glow.h"
-
-#include "cc/layers/layer.h"
-#include "content/browser/android/edge_effect_base.h"
-#include "content/public/browser/android/compositor.h"
-
-using std::max;
-using std::min;
-
-namespace content {
-
-namespace {
-
-const float kEpsilon = 1e-3f;
-
-bool IsApproxZero(float value) {
- return std::abs(value) < kEpsilon;
-}
-
-gfx::Vector2dF ZeroSmallComponents(gfx::Vector2dF vector) {
- if (IsApproxZero(vector.x()))
- vector.set_x(0);
- if (IsApproxZero(vector.y()))
- vector.set_y(0);
- return vector;
-}
-
-} // namespace
-
-OverscrollGlow::OverscrollGlow(OverscrollGlowClient* client)
- : client_(client),
- edge_offsets_(),
- initialized_(false),
- allow_horizontal_overscroll_(true),
- allow_vertical_overscroll_(true) {
- DCHECK(client);
-}
-
-OverscrollGlow::~OverscrollGlow() {
- Detach();
-}
-
-void OverscrollGlow::Reset() {
- if (!initialized_)
- return;
- Detach();
- for (size_t i = 0; i < EDGE_COUNT; ++i)
- edge_effects_[i]->Finish();
-}
-
-bool OverscrollGlow::IsActive() const {
- if (!initialized_)
- return false;
- for (size_t i = 0; i < EDGE_COUNT; ++i) {
- if (!edge_effects_[i]->IsFinished())
- return true;
- }
- return false;
-}
-
-float OverscrollGlow::GetVisibleAlpha() const {
- float max_alpha = 0;
- for (size_t i = 0; i < EDGE_COUNT; ++i) {
- if (!edge_effects_[i]->IsFinished())
- max_alpha = std::max(max_alpha, edge_effects_[i]->GetAlpha());
- }
- return std::min(max_alpha, 1.f);
-}
-
-bool OverscrollGlow::OnOverscrolled(base::TimeTicks current_time,
- const gfx::Vector2dF& accumulated_overscroll,
- gfx::Vector2dF overscroll_delta,
- gfx::Vector2dF velocity,
- const gfx::Vector2dF& overscroll_location) {
- // The size of the glow determines the relative effect of the inputs; an
- // empty-sized effect is effectively disabled.
- if (viewport_size_.IsEmpty())
- return false;
-
- if (!allow_horizontal_overscroll_) {
- overscroll_delta.set_x(0);
- velocity.set_x(0);
- }
- if (!allow_vertical_overscroll_) {
- overscroll_delta.set_y(0);
- velocity.set_y(0);
- }
-
- // Ignore sufficiently small values that won't meaningfuly affect animation.
- overscroll_delta = ZeroSmallComponents(overscroll_delta);
- if (overscroll_delta.IsZero()) {
- if (initialized_)
- Release(current_time);
- return CheckNeedsAnimate();
- }
-
- if (!InitializeIfNecessary())
- return false;
-
- gfx::Vector2dF old_overscroll = accumulated_overscroll - overscroll_delta;
- bool x_overscroll_started =
- !IsApproxZero(overscroll_delta.x()) && IsApproxZero(old_overscroll.x());
- bool y_overscroll_started =
- !IsApproxZero(overscroll_delta.y()) && IsApproxZero(old_overscroll.y());
-
- velocity = ZeroSmallComponents(velocity);
- if (!velocity.IsZero())
- Absorb(current_time, velocity, x_overscroll_started, y_overscroll_started);
- else
- Pull(current_time, overscroll_delta, overscroll_location);
-
- return CheckNeedsAnimate();
-}
-
-bool OverscrollGlow::Animate(base::TimeTicks current_time,
- cc::Layer* parent_layer) {
- DCHECK(parent_layer);
- if (!CheckNeedsAnimate())
- return false;
-
- UpdateLayerAttachment(parent_layer);
-
- for (size_t i = 0; i < EDGE_COUNT; ++i) {
- if (edge_effects_[i]->Update(current_time)) {
- EdgeEffectBase::Edge edge = static_cast<EdgeEffectBase::Edge>(i);
- edge_effects_[i]->ApplyToLayers(edge, viewport_size_, edge_offsets_[i]);
- }
- }
-
- return CheckNeedsAnimate();
-}
-
-void OverscrollGlow::OnFrameUpdated(
- const gfx::SizeF& viewport_size,
- const gfx::SizeF& content_size,
- const gfx::Vector2dF& content_scroll_offset) {
- viewport_size_ = viewport_size;
- edge_offsets_[EdgeEffectBase::EDGE_TOP] = -content_scroll_offset.y();
- edge_offsets_[EdgeEffectBase::EDGE_LEFT] = -content_scroll_offset.x();
- edge_offsets_[EdgeEffectBase::EDGE_BOTTOM] = content_size.height() -
- content_scroll_offset.y() -
- viewport_size.height();
- edge_offsets_[EdgeEffectBase::EDGE_RIGHT] =
- content_size.width() - content_scroll_offset.x() - viewport_size.width();
-
- // Only allow overscroll on scrollable axes, matching platform behavior.
- allow_horizontal_overscroll_ =
- std::ceil(viewport_size_.width()) < std::floor(content_size.width());
- allow_vertical_overscroll_ =
- std::ceil(viewport_size_.height()) < std::floor(content_size.height());
-}
-
-bool OverscrollGlow::CheckNeedsAnimate() {
- if (!initialized_) {
- Detach();
- return false;
- }
-
- if (IsActive())
- return true;
-
- Detach();
- return false;
-}
-
-void OverscrollGlow::UpdateLayerAttachment(cc::Layer* parent) {
- DCHECK(parent);
- if (!root_layer_.get())
- return;
-
- if (!CheckNeedsAnimate())
- return;
-
- if (root_layer_->parent() != parent)
- parent->AddChild(root_layer_);
-
- for (size_t i = 0; i < EDGE_COUNT; ++i)
- edge_effects_[i]->SetParent(root_layer_.get());
-}
-
-void OverscrollGlow::Detach() {
- if (root_layer_.get())
- root_layer_->RemoveFromParent();
-}
-
-bool OverscrollGlow::InitializeIfNecessary() {
- if (initialized_)
- return true;
-
- DCHECK(!root_layer_.get());
- root_layer_ = cc::Layer::Create(Compositor::LayerSettings());
- for (size_t i = 0; i < EDGE_COUNT; ++i) {
- edge_effects_[i] = client_->CreateEdgeEffect();
- DCHECK(edge_effects_[i]);
- }
-
- initialized_ = true;
- return true;
-}
-
-void OverscrollGlow::Pull(base::TimeTicks current_time,
- const gfx::Vector2dF& overscroll_delta,
- const gfx::Vector2dF& overscroll_location) {
- DCHECK(initialized_);
- DCHECK(!overscroll_delta.IsZero());
- DCHECK(!viewport_size_.IsEmpty());
- const float inv_width = 1.f / viewport_size_.width();
- const float inv_height = 1.f / viewport_size_.height();
-
- gfx::Vector2dF overscroll_pull =
- gfx::ScaleVector2d(overscroll_delta, inv_width, inv_height);
- const float edge_pull[EDGE_COUNT] = {
- min(overscroll_pull.y(), 0.f), // Top
- min(overscroll_pull.x(), 0.f), // Left
- max(overscroll_pull.y(), 0.f), // Bottom
- max(overscroll_pull.x(), 0.f) // Right
- };
-
- gfx::Vector2dF displacement =
- gfx::ScaleVector2d(overscroll_location, inv_width, inv_height);
- displacement.set_x(max(0.f, min(1.f, displacement.x())));
- displacement.set_y(max(0.f, min(1.f, displacement.y())));
- const float edge_displacement[EDGE_COUNT] = {
- 1.f - displacement.x(), // Top
- displacement.y(), // Left
- displacement.x(), // Bottom
- 1.f - displacement.y() // Right
- };
-
- for (size_t i = 0; i < EDGE_COUNT; ++i) {
- if (!edge_pull[i])
- continue;
-
- edge_effects_[i]->Pull(
- current_time, std::abs(edge_pull[i]), edge_displacement[i]);
- GetOppositeEdge(i)->Release(current_time);
- }
-}
-
-void OverscrollGlow::Absorb(base::TimeTicks current_time,
- const gfx::Vector2dF& velocity,
- bool x_overscroll_started,
- bool y_overscroll_started) {
- DCHECK(initialized_);
- DCHECK(!velocity.IsZero());
-
- // Only trigger on initial overscroll at a non-zero velocity
- const float overscroll_velocities[EDGE_COUNT] = {
- y_overscroll_started ? min(velocity.y(), 0.f) : 0, // Top
- x_overscroll_started ? min(velocity.x(), 0.f) : 0, // Left
- y_overscroll_started ? max(velocity.y(), 0.f) : 0, // Bottom
- x_overscroll_started ? max(velocity.x(), 0.f) : 0 // Right
- };
-
- for (size_t i = 0; i < EDGE_COUNT; ++i) {
- if (!overscroll_velocities[i])
- continue;
-
- edge_effects_[i]->Absorb(current_time, std::abs(overscroll_velocities[i]));
- GetOppositeEdge(i)->Release(current_time);
- }
-}
-
-void OverscrollGlow::Release(base::TimeTicks current_time) {
- DCHECK(initialized_);
- for (size_t i = 0; i < EDGE_COUNT; ++i)
- edge_effects_[i]->Release(current_time);
-}
-
-EdgeEffectBase* OverscrollGlow::GetOppositeEdge(int edge_index) {
- DCHECK(initialized_);
- return edge_effects_[(edge_index + 2) % EDGE_COUNT].get();
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/overscroll_glow.h b/chromium/content/browser/android/overscroll_glow.h
deleted file mode 100644
index 1736ae7be59..00000000000
--- a/chromium/content/browser/android/overscroll_glow.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_OVERSCROLL_GLOW_H_
-#define CONTENT_BROWSER_ANDROID_OVERSCROLL_GLOW_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "content/browser/android/edge_effect_base.h"
-#include "ui/gfx/geometry/size_f.h"
-#include "ui/gfx/geometry/vector2d_f.h"
-
-namespace cc {
-class Layer;
-}
-
-namespace content {
-
-// Provides lazy, customized EdgeEffect creation.
-class OverscrollGlowClient {
- public:
- virtual ~OverscrollGlowClient() {}
-
- // Called lazily, after the initial overscrolling event.
- virtual scoped_ptr<EdgeEffectBase> CreateEdgeEffect() = 0;
-};
-
-/* |OverscrollGlow| mirrors its Android counterpart, OverscrollGlow.java.
- * Conscious tradeoffs were made to align this as closely as possible with the
- * original Android Java version.
- */
-class OverscrollGlow {
- public:
- // |client| must be valid for the duration of the effect's lifetime.
- // The effect is enabled by default, but will remain dormant until the first
- // overscroll event.
- explicit OverscrollGlow(OverscrollGlowClient* client);
- ~OverscrollGlow();
-
- // Called when the root content layer overscrolls.
- // |accumulated_overscroll| and |overscroll_delta| are in device pixels, while
- // |velocity| is in device pixels / second.
- // |overscroll_location| is the coordinate of the causal overscrolling event.
- // Returns true if the effect still needs animation ticks.
- bool OnOverscrolled(base::TimeTicks current_time,
- const gfx::Vector2dF& accumulated_overscroll,
- gfx::Vector2dF overscroll_delta,
- gfx::Vector2dF velocity,
- const gfx::Vector2dF& overscroll_location);
-
- // Returns true if the effect still needs animation ticks, with effect layers
- // attached to |parent_layer| if necessary.
- // Note: The effect will detach itself when no further animation is required.
- bool Animate(base::TimeTicks current_time, cc::Layer* parent_layer);
-
- // Update the effect according to the most recent display parameters,
- // Note: All dimensions are in device pixels.
- void OnFrameUpdated(const gfx::SizeF& viewport_size,
- const gfx::SizeF& content_size,
- const gfx::Vector2dF& content_scroll_offset);
-
- // Reset the effect to its inactive state, clearing any active effects.
- void Reset();
-
- // Whether the effect is active, either being pulled or receding.
- bool IsActive() const;
-
- // The maximum alpha value (in the range [0,1]) of any animated edge layers.
- // If the effect is inactive, this will be 0.
- float GetVisibleAlpha() const;
-
- private:
- enum Axis { AXIS_X, AXIS_Y };
- enum { EDGE_COUNT = EdgeEffectBase::EDGE_COUNT };
-
- // Returns whether the effect has been properly initialized.
- bool InitializeIfNecessary();
- bool CheckNeedsAnimate();
- void UpdateLayerAttachment(cc::Layer* parent);
- void Detach();
- void Pull(base::TimeTicks current_time,
- const gfx::Vector2dF& overscroll_delta,
- const gfx::Vector2dF& overscroll_location);
- void Absorb(base::TimeTicks current_time,
- const gfx::Vector2dF& velocity,
- bool x_overscroll_started,
- bool y_overscroll_started);
- void Release(base::TimeTicks current_time);
-
- EdgeEffectBase* GetOppositeEdge(int edge_index);
-
- OverscrollGlowClient* const client_;
- scoped_ptr<EdgeEffectBase> edge_effects_[EDGE_COUNT];
-
- gfx::SizeF viewport_size_;
- float edge_offsets_[EDGE_COUNT];
- bool initialized_;
- bool allow_horizontal_overscroll_;
- bool allow_vertical_overscroll_;
-
- scoped_refptr<cc::Layer> root_layer_;
-
- DISALLOW_COPY_AND_ASSIGN(OverscrollGlow);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_OVERSCROLL_GLOW_H_
diff --git a/chromium/content/browser/android/overscroll_refresh.cc b/chromium/content/browser/android/overscroll_refresh.cc
deleted file mode 100644
index c2a1453bc17..00000000000
--- a/chromium/content/browser/android/overscroll_refresh.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/android/overscroll_refresh.h"
-
-#include "base/logging.h"
-
-namespace content {
-namespace {
-
-// Experimentally determined constant used to allow activation even if touch
-// release results in a small upward fling (quite common during a slow scroll).
-const float kMinFlingVelocityForActivation = -500.f;
-
-} // namespace
-
-OverscrollRefresh::OverscrollRefresh(OverscrollRefreshHandler* handler)
- : scrolled_to_top_(true),
- overflow_y_hidden_(false),
- scroll_consumption_state_(DISABLED),
- handler_(handler) {
- DCHECK(handler);
-}
-
-OverscrollRefresh::~OverscrollRefresh() {
-}
-
-void OverscrollRefresh::Reset() {
- scroll_consumption_state_ = DISABLED;
- handler_->PullReset();
-}
-
-void OverscrollRefresh::OnScrollBegin() {
- ReleaseWithoutActivation();
- if (scrolled_to_top_ && !overflow_y_hidden_)
- scroll_consumption_state_ = AWAITING_SCROLL_UPDATE_ACK;
-}
-
-void OverscrollRefresh::OnScrollEnd(const gfx::Vector2dF& scroll_velocity) {
- bool allow_activation = scroll_velocity.y() > kMinFlingVelocityForActivation;
- Release(allow_activation);
-}
-
-void OverscrollRefresh::OnScrollUpdateAck(bool was_consumed) {
- if (scroll_consumption_state_ != AWAITING_SCROLL_UPDATE_ACK)
- return;
-
- if (was_consumed) {
- scroll_consumption_state_ = DISABLED;
- return;
- }
-
- scroll_consumption_state_ = handler_->PullStart() ? ENABLED : DISABLED;
-}
-
-bool OverscrollRefresh::WillHandleScrollUpdate(
- const gfx::Vector2dF& scroll_delta) {
- switch (scroll_consumption_state_) {
- case DISABLED:
- return false;
-
- case AWAITING_SCROLL_UPDATE_ACK:
- // If the initial scroll motion is downward, never allow activation.
- if (scroll_delta.y() <= 0)
- scroll_consumption_state_ = DISABLED;
- return false;
-
- case ENABLED:
- handler_->PullUpdate(scroll_delta.y());
- return true;
- }
-
- NOTREACHED() << "Invalid overscroll state: " << scroll_consumption_state_;
- return false;
-}
-
-void OverscrollRefresh::ReleaseWithoutActivation() {
- bool allow_activation = false;
- Release(allow_activation);
-}
-
-bool OverscrollRefresh::IsActive() const {
- return scroll_consumption_state_ == ENABLED;
-}
-
-bool OverscrollRefresh::IsAwaitingScrollUpdateAck() const {
- return scroll_consumption_state_ == AWAITING_SCROLL_UPDATE_ACK;
-}
-
-void OverscrollRefresh::OnFrameUpdated(
- const gfx::Vector2dF& content_scroll_offset,
- bool root_overflow_y_hidden) {
- scrolled_to_top_ = content_scroll_offset.y() == 0;
- overflow_y_hidden_ = root_overflow_y_hidden;
-}
-
-void OverscrollRefresh::Release(bool allow_refresh) {
- if (scroll_consumption_state_ == ENABLED)
- handler_->PullRelease(allow_refresh);
- scroll_consumption_state_ = DISABLED;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/overscroll_refresh.h b/chromium/content/browser/android/overscroll_refresh.h
deleted file mode 100644
index 43ed0833258..00000000000
--- a/chromium/content/browser/android/overscroll_refresh.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_OVERSCROLL_REFRESH_H_
-#define CONTENT_BROWSER_ANDROID_OVERSCROLL_REFRESH_H_
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "ui/gfx/geometry/size_f.h"
-#include "ui/gfx/geometry/vector2d_f.h"
-
-namespace content {
-
-class CONTENT_EXPORT OverscrollRefreshHandler {
- public:
- // Signals the start of an overscrolling pull. Returns whether the handler
- // will consume the overscroll gesture, in which case it will receive the
- // remaining pull updates.
- virtual bool PullStart() = 0;
-
- // Signals a pull update, where |delta| is in device pixels.
- virtual void PullUpdate(float delta) = 0;
-
- // Signals the release of the pull, and whether the release is allowed to
- // trigger the refresh action.
- virtual void PullRelease(bool allow_refresh) = 0;
-
- // Reset the active pull state.
- virtual void PullReset() = 0;
-
- protected:
- virtual ~OverscrollRefreshHandler() {}
-};
-
-// Simple pull-to-refresh styled effect. Listens to scroll events, conditionally
-// activating when:
-// 1) The scroll begins when the page's root layer 1) has no vertical scroll
-// offset and 2) lacks the overflow-y:hidden property.
-// 2) The page doesn't consume the initial scroll events.
-// 3) The initial scroll direction is upward.
-// The actuall pull response, animation and action are delegated to the
-// provided refresh handler.
-class CONTENT_EXPORT OverscrollRefresh {
- public:
- // Minmum number of overscrolling pull events required to activate the effect.
- // Useful for avoiding accidental triggering when a scroll janks (is delayed),
- // capping the impulse per event.
- enum { kMinPullsToActivate = 3 };
-
- explicit OverscrollRefresh(OverscrollRefreshHandler* handler);
- ~OverscrollRefresh();
-
- // Scroll event stream listening methods.
- void OnScrollBegin();
- // Returns whether the refresh was activated.
- void OnScrollEnd(const gfx::Vector2dF& velocity);
-
- // Scroll ack listener. The effect will only be activated if the initial
- // updates go unconsumed.
- void OnScrollUpdateAck(bool was_consumed);
-
- // Returns true if the effect has consumed the |scroll_delta|.
- bool WillHandleScrollUpdate(const gfx::Vector2dF& scroll_delta);
-
- // Release the effect (if active), preventing any associated refresh action.
- void ReleaseWithoutActivation();
-
- // Notify the effect of the latest scroll offset and overflow properties.
- // The effect will be disabled when the offset is non-zero or overflow is
- // hidden. Note: All dimensions are in device pixels.
- void OnFrameUpdated(const gfx::Vector2dF& content_scroll_offset,
- bool root_overflow_y_hidden);
-
- // Reset the effect to its inactive state, immediately detaching and
- // disabling any active effects.
- void Reset();
-
- // Returns true if the refresh effect is either being manipulated or animated.
- bool IsActive() const;
-
- // Returns true if the effect is waiting for an unconsumed scroll to start.
- bool IsAwaitingScrollUpdateAck() const;
-
- private:
- void Release(bool allow_refresh);
-
- bool scrolled_to_top_;
- bool overflow_y_hidden_;
-
- enum ScrollConsumptionState {
- DISABLED,
- AWAITING_SCROLL_UPDATE_ACK,
- ENABLED,
- } scroll_consumption_state_;
-
- OverscrollRefreshHandler* const handler_;
-
- DISALLOW_COPY_AND_ASSIGN(OverscrollRefresh);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_OVERSCROLL_REFRESH_H_
diff --git a/chromium/content/browser/android/overscroll_refresh_unittest.cc b/chromium/content/browser/android/overscroll_refresh_unittest.cc
deleted file mode 100644
index 70ed0dbd510..00000000000
--- a/chromium/content/browser/android/overscroll_refresh_unittest.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/layer.h"
-#include "content/browser/android/overscroll_refresh.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-class OverscrollRefreshTest : public OverscrollRefreshHandler,
- public testing::Test {
- public:
- OverscrollRefreshTest() {}
-
- // OverscrollRefreshHandler implementation.
- bool PullStart() override {
- started_ = true;
- return true;
- }
-
- void PullUpdate(float delta) override { delta_ += delta; }
-
- void PullRelease(bool allow_refresh) override {
- released_ = true;
- refresh_allowed_ = allow_refresh;
- }
-
- void PullReset() override { reset_ = true; }
-
- bool GetAndResetPullStarted() {
- bool result = started_;
- started_ = false;
- return result;
- }
-
- float GetAndResetPullDelta() {
- float result = delta_;
- delta_ = 0;
- return result;
- }
-
- bool GetAndResetPullReleased() {
- bool result = released_;
- released_ = false;
- return result;
- }
-
- bool GetAndResetRefreshAllowed() {
- bool result = refresh_allowed_;
- refresh_allowed_ = false;
- return result;
- }
-
- bool GetAndResetPullReset() {
- bool result = reset_;
- reset_ = false;
- return result;
- }
-
- private:
- float delta_ = 0;
- bool started_ = false;
- bool released_ = false;
- bool reset_ = false;
- bool refresh_allowed_ = false;
-};
-
-TEST_F(OverscrollRefreshTest, Basic) {
- OverscrollRefresh effect(this);
-
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
-
- effect.OnScrollBegin();
- EXPECT_FALSE(effect.IsActive());
- EXPECT_TRUE(effect.IsAwaitingScrollUpdateAck());
-
- // The initial scroll should not be consumed, as it should first be offered
- // to content.
- gfx::Vector2dF scroll_up(0, 10);
- EXPECT_FALSE(effect.WillHandleScrollUpdate(scroll_up));
- EXPECT_FALSE(effect.IsActive());
- EXPECT_TRUE(effect.IsAwaitingScrollUpdateAck());
-
- // The unconsumed, overscrolling scroll will trigger the effect.
- effect.OnScrollUpdateAck(false);
- EXPECT_TRUE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- EXPECT_TRUE(GetAndResetPullStarted());
-
- // Further scrolls will be consumed.
- EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
- EXPECT_EQ(50.f, GetAndResetPullDelta());
- EXPECT_TRUE(effect.IsActive());
-
- // Even scrolls in the down direction should be consumed.
- EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, -50)));
- EXPECT_EQ(-50.f, GetAndResetPullDelta());
- EXPECT_TRUE(effect.IsActive());
-
- // Ending the scroll while beyond the threshold should trigger a refresh.
- gfx::Vector2dF zero_velocity;
- EXPECT_FALSE(GetAndResetPullReleased());
- effect.OnScrollEnd(zero_velocity);
- EXPECT_FALSE(effect.IsActive());
- EXPECT_TRUE(GetAndResetPullReleased());
- EXPECT_TRUE(GetAndResetRefreshAllowed());
-}
-
-TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialYOffsetIsNotZero) {
- OverscrollRefresh effect(this);
-
- // A positive y scroll offset at the start of scroll will prevent activation,
- // even if the subsequent scroll overscrolls upward.
- gfx::Vector2dF nonzero_offset(0, 10);
- bool overflow_y_hidden = false;
- effect.OnFrameUpdated(nonzero_offset, overflow_y_hidden);
- effect.OnScrollBegin();
-
- effect.OnFrameUpdated(gfx::Vector2dF(), overflow_y_hidden);
- ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- effect.OnScrollUpdateAck(false);
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
- effect.OnScrollEnd(gfx::Vector2dF());
- EXPECT_FALSE(GetAndResetPullStarted());
- EXPECT_FALSE(GetAndResetPullReleased());
-}
-
-TEST_F(OverscrollRefreshTest, NotTriggeredIfOverflowYHidden) {
- OverscrollRefresh effect(this);
-
- // overflow-y:hidden at the start of scroll will prevent activation.
- gfx::Vector2dF zero_offset;
- bool overflow_y_hidden = true;
- effect.OnFrameUpdated(zero_offset, overflow_y_hidden);
- effect.OnScrollBegin();
-
- ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- effect.OnScrollUpdateAck(false);
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
- effect.OnScrollEnd(gfx::Vector2dF());
- EXPECT_FALSE(GetAndResetPullStarted());
- EXPECT_FALSE(GetAndResetPullReleased());
-}
-
-TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialScrollDownward) {
- OverscrollRefresh effect(this);
- effect.OnScrollBegin();
-
- // A downward initial scroll will prevent activation, even if the subsequent
- // scroll overscrolls upward.
- ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, -10)));
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
-
- effect.OnScrollUpdateAck(false);
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
- effect.OnScrollEnd(gfx::Vector2dF());
- EXPECT_FALSE(GetAndResetPullReleased());
-}
-
-TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialScrollOrTouchConsumed) {
- OverscrollRefresh effect(this);
- effect.OnScrollBegin();
- ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
- ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());
-
- // Consumption of the initial touchmove or scroll should prevent future
- // activation.
- effect.OnScrollUpdateAck(true);
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
- effect.OnScrollUpdateAck(false);
- EXPECT_FALSE(effect.IsActive());
- EXPECT_FALSE(effect.IsAwaitingScrollUpdateAck());
- EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
- effect.OnScrollEnd(gfx::Vector2dF());
- EXPECT_FALSE(GetAndResetPullStarted());
- EXPECT_FALSE(GetAndResetPullReleased());
-}
-
-TEST_F(OverscrollRefreshTest, NotTriggeredIfFlungDownward) {
- OverscrollRefresh effect(this);
- effect.OnScrollBegin();
- ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
- ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());
- effect.OnScrollUpdateAck(false);
- ASSERT_TRUE(effect.IsActive());
- EXPECT_TRUE(GetAndResetPullStarted());
-
- // Terminating the pull with a down-directed fling should prevent triggering.
- effect.OnScrollEnd(gfx::Vector2dF(0, -1000));
- EXPECT_TRUE(GetAndResetPullReleased());
- EXPECT_FALSE(GetAndResetRefreshAllowed());
-}
-
-TEST_F(OverscrollRefreshTest, NotTriggeredIfReleasedWithoutActivation) {
- OverscrollRefresh effect(this);
- effect.OnScrollBegin();
- ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
- ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());
- effect.OnScrollUpdateAck(false);
- ASSERT_TRUE(effect.IsActive());
- EXPECT_TRUE(GetAndResetPullStarted());
-
- // An early release should prevent the refresh action from firing.
- effect.ReleaseWithoutActivation();
- effect.OnScrollEnd(gfx::Vector2dF());
- EXPECT_TRUE(GetAndResetPullReleased());
- EXPECT_FALSE(GetAndResetRefreshAllowed());
-}
-
-TEST_F(OverscrollRefreshTest, NotTriggeredIfReset) {
- OverscrollRefresh effect(this);
- effect.OnScrollBegin();
- ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
- ASSERT_TRUE(effect.IsAwaitingScrollUpdateAck());
- effect.OnScrollUpdateAck(false);
- ASSERT_TRUE(effect.IsActive());
- EXPECT_TRUE(GetAndResetPullStarted());
-
- // An early reset should prevent the refresh action from firing.
- effect.Reset();
- EXPECT_TRUE(GetAndResetPullReset());
- effect.OnScrollEnd(gfx::Vector2dF());
- EXPECT_FALSE(GetAndResetPullReleased());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/popup_touch_handle_drawable.cc b/chromium/content/browser/android/popup_touch_handle_drawable.cc
index 7791ddfe452..28b0525361f 100644
--- a/chromium/content/browser/android/popup_touch_handle_drawable.cc
+++ b/chromium/content/browser/android/popup_touch_handle_drawable.cc
@@ -29,6 +29,8 @@ PopupTouchHandleDrawable::PopupTouchHandleDrawable(JNIEnv* env,
float dpi_scale)
: java_ref_(env, obj), dpi_scale_(dpi_scale) {
DCHECK(!java_ref_.is_empty());
+ drawable_horizontal_padding_ratio_ =
+ Java_PopupTouchHandleDrawable_getHandleHorizontalPaddingRatio(env, obj);
}
PopupTouchHandleDrawable::~PopupTouchHandleDrawable() {
@@ -50,31 +52,34 @@ void PopupTouchHandleDrawable::SetEnabled(bool enabled) {
}
void PopupTouchHandleDrawable::SetOrientation(
- ui::TouchHandleOrientation orientation) {
+ ui::TouchHandleOrientation orientation,
+ bool mirror_vertical,
+ bool mirror_horizontal) {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (!obj.is_null()) {
- Java_PopupTouchHandleDrawable_setOrientation(env, obj.obj(),
- static_cast<int>(orientation));
+ Java_PopupTouchHandleDrawable_setOrientation(
+ env, obj.obj(), static_cast<int>(orientation), mirror_vertical,
+ mirror_horizontal);
}
}
-void PopupTouchHandleDrawable::SetAlpha(float alpha) {
+void PopupTouchHandleDrawable::SetOrigin(const gfx::PointF& origin) {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- bool visible = alpha > 0;
- if (!obj.is_null())
- Java_PopupTouchHandleDrawable_setVisible(env, obj.obj(), visible);
+ if (!obj.is_null()) {
+ const gfx::PointF origin_pix = gfx::ScalePoint(origin, dpi_scale_);
+ Java_PopupTouchHandleDrawable_setOrigin(env, obj.obj(), origin_pix.x(),
+ origin_pix.y());
+ }
}
-void PopupTouchHandleDrawable::SetFocus(const gfx::PointF& position) {
- const gfx::PointF position_pix = gfx::ScalePoint(position, dpi_scale_);
+void PopupTouchHandleDrawable::SetAlpha(float alpha) {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj.is_null()) {
- Java_PopupTouchHandleDrawable_setFocus(env, obj.obj(), position_pix.x(),
- position_pix.y());
- }
+ bool visible = alpha > 0;
+ if (!obj.is_null())
+ Java_PopupTouchHandleDrawable_setVisible(env, obj.obj(), visible);
}
gfx::RectF PopupTouchHandleDrawable::GetVisibleBounds() const {
@@ -90,6 +95,10 @@ gfx::RectF PopupTouchHandleDrawable::GetVisibleBounds() const {
return gfx::ScaleRect(unscaled_rect, 1.f / dpi_scale_);
}
+float PopupTouchHandleDrawable::GetDrawableHorizontalPaddingRatio() const {
+ return drawable_horizontal_padding_ratio_;
+}
+
// static
bool PopupTouchHandleDrawable::RegisterPopupTouchHandleDrawable(JNIEnv* env) {
return RegisterNativesImpl(env);
diff --git a/chromium/content/browser/android/popup_touch_handle_drawable.h b/chromium/content/browser/android/popup_touch_handle_drawable.h
index 84d2673d0bb..316de0eb962 100644
--- a/chromium/content/browser/android/popup_touch_handle_drawable.h
+++ b/chromium/content/browser/android/popup_touch_handle_drawable.h
@@ -9,6 +9,7 @@
#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
+#include "base/macros.h"
namespace content {
@@ -23,10 +24,13 @@ class PopupTouchHandleDrawable : public ui::TouchHandleDrawable {
// ui::TouchHandleDrawable implementation.
void SetEnabled(bool enabled) override;
- void SetOrientation(ui::TouchHandleOrientation orientation) override;
+ void SetOrientation(ui::TouchHandleOrientation orientation,
+ bool mirror_vertical,
+ bool mirror_horizontal) override;
+ void SetOrigin(const gfx::PointF& origin) override;
void SetAlpha(float alpha) override;
- void SetFocus(const gfx::PointF& position) override;
gfx::RectF GetVisibleBounds() const override;
+ float GetDrawableHorizontalPaddingRatio() const override;
static bool RegisterPopupTouchHandleDrawable(JNIEnv* env);
@@ -36,6 +40,7 @@ class PopupTouchHandleDrawable : public ui::TouchHandleDrawable {
JavaObjectWeakGlobalRef java_ref_;
const float dpi_scale_;
+ float drawable_horizontal_padding_ratio_;
DISALLOW_COPY_AND_ASSIGN(PopupTouchHandleDrawable);
};
diff --git a/chromium/content/browser/android/synchronous_compositor_base.cc b/chromium/content/browser/android/synchronous_compositor_base.cc
new file mode 100644
index 00000000000..acc5e349f99
--- /dev/null
+++ b/chromium/content/browser/android/synchronous_compositor_base.cc
@@ -0,0 +1,77 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/synchronous_compositor_base.h"
+
+#include "base/command_line.h"
+#include "base/supports_user_data.h"
+#include "content/browser/android/in_process/synchronous_compositor_impl.h"
+#include "content/browser/android/synchronous_compositor_host.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/browser/web_contents/web_contents_android.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/gpu/in_process_gpu_thread.h"
+#include "content/public/common/content_switches.h"
+
+namespace content {
+
+class SynchronousCompositorClient;
+
+namespace {
+
+gpu::SyncPointManager* g_sync_point_manager = nullptr;
+
+base::Thread* CreateInProcessGpuThreadForSynchronousCompositor(
+ const InProcessChildThreadParams& params) {
+ DCHECK(g_sync_point_manager);
+ return new InProcessGpuThread(params, g_sync_point_manager);
+}
+
+} // namespace
+
+void SynchronousCompositor::SetGpuService(
+ scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
+ DCHECK(!g_sync_point_manager);
+ g_sync_point_manager = service->sync_point_manager();
+ GpuProcessHost::RegisterGpuMainThreadFactory(
+ CreateInProcessGpuThreadForSynchronousCompositor);
+
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kIPCSyncCompositing)) {
+ SynchronousCompositorImpl::SetGpuServiceInProc(service);
+ }
+}
+
+// static
+void SynchronousCompositor::SetClientForWebContents(
+ WebContents* contents,
+ SynchronousCompositorClient* client) {
+ DCHECK(contents);
+ DCHECK(client);
+ WebContentsAndroid* web_contents_android =
+ static_cast<WebContentsImpl*>(contents)->GetWebContentsAndroid();
+ DCHECK(!web_contents_android->synchronous_compositor_client());
+ web_contents_android->set_synchronous_compositor_client(client);
+}
+
+// static
+scoped_ptr<SynchronousCompositorBase> SynchronousCompositorBase::Create(
+ RenderWidgetHostViewAndroid* rwhva,
+ WebContents* web_contents) {
+ DCHECK(web_contents);
+ WebContentsAndroid* web_contents_android =
+ static_cast<WebContentsImpl*>(web_contents)->GetWebContentsAndroid();
+ if (!web_contents_android->synchronous_compositor_client())
+ return nullptr; // Not using sync compositing.
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kIPCSyncCompositing)) {
+ return make_scoped_ptr(new SynchronousCompositorHost(
+ rwhva, web_contents_android->synchronous_compositor_client()));
+ }
+ return make_scoped_ptr(new SynchronousCompositorImpl(
+ rwhva, web_contents_android->synchronous_compositor_client()));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/android/synchronous_compositor_base.h b/chromium/content/browser/android/synchronous_compositor_base.h
new file mode 100644
index 00000000000..6bd41bb24d4
--- /dev/null
+++ b/chromium/content/browser/android/synchronous_compositor_base.h
@@ -0,0 +1,47 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BASE_H_
+#define CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BASE_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "content/common/input/input_event_ack_state.h"
+#include "content/public/browser/android/synchronous_compositor.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace blink {
+class WebInputEvent;
+}
+
+namespace cc {
+struct BeginFrameArgs;
+}
+
+namespace content {
+
+class RenderWidgetHostViewAndroid;
+class WebContents;
+
+class SynchronousCompositorBase : public SynchronousCompositor {
+ public:
+ static scoped_ptr<SynchronousCompositorBase> Create(
+ RenderWidgetHostViewAndroid* rwhva,
+ WebContents* web_contents);
+
+ ~SynchronousCompositorBase() override {}
+
+ virtual void BeginFrame(const cc::BeginFrameArgs& args) = 0;
+ virtual InputEventAckState HandleInputEvent(
+ const blink::WebInputEvent& input_event) = 0;
+ virtual bool OnMessageReceived(const IPC::Message& message) = 0;
+
+ virtual void DidBecomeCurrent() = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BASE_H_
diff --git a/chromium/content/browser/android/synchronous_compositor_host.cc b/chromium/content/browser/android/synchronous_compositor_host.cc
new file mode 100644
index 00000000000..83dd85fead4
--- /dev/null
+++ b/chromium/content/browser/android/synchronous_compositor_host.cc
@@ -0,0 +1,388 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/synchronous_compositor_host.h"
+
+#include <utility>
+
+#include "base/containers/hash_tables.h"
+#include "base/memory/shared_memory.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "cc/output/compositor_frame_ack.h"
+#include "content/browser/renderer_host/render_widget_host_view_android.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/android/sync_compositor_messages.h"
+#include "content/public/browser/android/synchronous_compositor_client.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_view_host.h"
+#include "ipc/ipc_sender.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
+#include "third_party/skia/include/core/SkRect.h"
+#include "ui/gfx/skia_util.h"
+
+namespace content {
+
+SynchronousCompositorHost::SynchronousCompositorHost(
+ RenderWidgetHostViewAndroid* rwhva,
+ SynchronousCompositorClient* client)
+ : rwhva_(rwhva),
+ client_(client),
+ ui_task_runner_(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
+ routing_id_(rwhva_->GetRenderWidgetHost()->GetRoutingID()),
+ sender_(rwhva_->GetRenderWidgetHost()),
+ is_active_(false),
+ bytes_limit_(0u),
+ root_scroll_offset_updated_by_browser_(false),
+ renderer_param_version_(0u),
+ need_animate_scroll_(false),
+ need_invalidate_(false),
+ need_begin_frame_(false),
+ did_activate_pending_tree_(false),
+ weak_ptr_factory_(this) {
+ client_->DidInitializeCompositor(this);
+}
+
+SynchronousCompositorHost::~SynchronousCompositorHost() {
+ client_->DidDestroyCompositor(this);
+ if (weak_ptr_factory_.HasWeakPtrs())
+ UpdateStateTask();
+}
+
+bool SynchronousCompositorHost::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorHost, message)
+ IPC_MESSAGE_HANDLER(SyncCompositorHostMsg_UpdateState, ProcessCommonParams)
+ IPC_MESSAGE_HANDLER(SyncCompositorHostMsg_OverScroll, OnOverScroll)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void SynchronousCompositorHost::DidBecomeCurrent() {
+ client_->DidBecomeCurrent(this);
+}
+
+scoped_ptr<cc::CompositorFrame> SynchronousCompositorHost::DemandDrawHw(
+ const gfx::Size& surface_size,
+ const gfx::Transform& transform,
+ const gfx::Rect& viewport,
+ const gfx::Rect& clip,
+ const gfx::Rect& viewport_rect_for_tile_priority,
+ const gfx::Transform& transform_for_tile_priority) {
+ SyncCompositorDemandDrawHwParams params(surface_size, transform, viewport,
+ clip, viewport_rect_for_tile_priority,
+ transform_for_tile_priority);
+ scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
+ SyncCompositorCommonBrowserParams common_browser_params;
+ PopulateCommonParams(&common_browser_params);
+ SyncCompositorCommonRendererParams common_renderer_params;
+ if (!sender_->Send(new SyncCompositorMsg_DemandDrawHw(
+ routing_id_, common_browser_params, params, &common_renderer_params,
+ frame.get()))) {
+ return nullptr;
+ }
+ ProcessCommonParams(common_renderer_params);
+ if (!frame->delegated_frame_data) {
+ // This can happen if compositor did not swap in this draw.
+ frame.reset();
+ }
+ if (frame)
+ UpdateFrameMetaData(frame->metadata);
+ return frame;
+}
+
+void SynchronousCompositorHost::UpdateFrameMetaData(
+ const cc::CompositorFrameMetadata& frame_metadata) {
+ rwhva_->SynchronousFrameMetadata(frame_metadata);
+}
+
+class SynchronousCompositorHost::ScopedSendZeroMemory {
+ public:
+ ScopedSendZeroMemory(SynchronousCompositorHost* host) : host_(host) {}
+ ~ScopedSendZeroMemory() { host_->SendZeroMemory(); }
+
+ private:
+ SynchronousCompositorHost* const host_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSendZeroMemory);
+};
+
+struct SynchronousCompositorHost::SharedMemoryWithSize {
+ base::SharedMemory shm;
+ const size_t stride;
+ const size_t buffer_size;
+
+ SharedMemoryWithSize(size_t stride, size_t buffer_size)
+ : stride(stride), buffer_size(buffer_size) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SharedMemoryWithSize);
+};
+
+bool SynchronousCompositorHost::DemandDrawSw(SkCanvas* canvas) {
+ SyncCompositorDemandDrawSwParams params;
+ params.size = gfx::Size(canvas->getBaseLayerSize().width(),
+ canvas->getBaseLayerSize().height());
+ SkIRect canvas_clip;
+ canvas->getClipDeviceBounds(&canvas_clip);
+ params.clip = gfx::SkIRectToRect(canvas_clip);
+ params.transform.matrix() = canvas->getTotalMatrix();
+ if (params.size.IsEmpty())
+ return true;
+
+ SkImageInfo info =
+ SkImageInfo::MakeN32Premul(params.size.width(), params.size.height());
+ DCHECK_EQ(kRGBA_8888_SkColorType, info.colorType());
+ size_t stride = info.minRowBytes();
+ size_t buffer_size = info.getSafeSize(stride);
+ if (!buffer_size)
+ return false; // Overflow.
+
+ SetSoftwareDrawSharedMemoryIfNeeded(stride, buffer_size);
+ if (!software_draw_shm_)
+ return false;
+
+ scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
+ SyncCompositorCommonBrowserParams common_browser_params;
+ PopulateCommonParams(&common_browser_params);
+ SyncCompositorCommonRendererParams common_renderer_params;
+ bool success = false;
+ if (!sender_->Send(new SyncCompositorMsg_DemandDrawSw(
+ routing_id_, common_browser_params, params, &success,
+ &common_renderer_params, frame.get()))) {
+ return false;
+ }
+ ScopedSendZeroMemory send_zero_memory(this);
+ if (!success)
+ return false;
+
+ ProcessCommonParams(common_renderer_params);
+ UpdateFrameMetaData(frame->metadata);
+
+ SkBitmap bitmap;
+ if (!bitmap.installPixels(info, software_draw_shm_->shm.memory(), stride))
+ return false;
+
+ {
+ TRACE_EVENT0("browser", "DrawBitmap");
+ canvas->save();
+ canvas->resetMatrix();
+ canvas->drawBitmap(bitmap, 0, 0);
+ canvas->restore();
+ }
+
+ return true;
+}
+
+void SynchronousCompositorHost::SetSoftwareDrawSharedMemoryIfNeeded(
+ size_t stride,
+ size_t buffer_size) {
+ if (software_draw_shm_ && software_draw_shm_->stride == stride &&
+ software_draw_shm_->buffer_size == buffer_size)
+ return;
+ software_draw_shm_.reset();
+ scoped_ptr<SharedMemoryWithSize> software_draw_shm(
+ new SharedMemoryWithSize(stride, buffer_size));
+ {
+ TRACE_EVENT1("browser", "AllocateSharedMemory", "buffer_size", buffer_size);
+ if (!software_draw_shm->shm.CreateAndMapAnonymous(buffer_size))
+ return;
+ }
+
+ SyncCompositorSetSharedMemoryParams set_shm_params;
+ set_shm_params.buffer_size = buffer_size;
+ base::ProcessHandle renderer_process_handle =
+ rwhva_->GetRenderWidgetHost()->GetProcess()->GetHandle();
+ if (!software_draw_shm->shm.ShareToProcess(renderer_process_handle,
+ &set_shm_params.shm_handle)) {
+ return;
+ }
+
+ SyncCompositorCommonBrowserParams common_browser_params;
+ PopulateCommonParams(&common_browser_params);
+ bool success = false;
+ SyncCompositorCommonRendererParams common_renderer_params;
+ if (!sender_->Send(new SyncCompositorMsg_SetSharedMemory(
+ routing_id_, common_browser_params, set_shm_params, &success,
+ &common_renderer_params)) ||
+ !success) {
+ return;
+ }
+ software_draw_shm_ = std::move(software_draw_shm);
+ ProcessCommonParams(common_renderer_params);
+}
+
+void SynchronousCompositorHost::SendZeroMemory() {
+ // No need to check return value.
+ sender_->Send(new SyncCompositorMsg_ZeroSharedMemory(routing_id_));
+}
+
+void SynchronousCompositorHost::ReturnResources(
+ const cc::CompositorFrameAck& frame_ack) {
+ returned_resources_.insert(returned_resources_.end(),
+ frame_ack.resources.begin(),
+ frame_ack.resources.end());
+}
+
+void SynchronousCompositorHost::SetMemoryPolicy(size_t bytes_limit) {
+ if (bytes_limit_ == bytes_limit)
+ return;
+ bytes_limit_ = bytes_limit;
+ SendAsyncCompositorStateIfNeeded();
+}
+
+void SynchronousCompositorHost::DidChangeRootLayerScrollOffset(
+ const gfx::ScrollOffset& root_offset) {
+ if (root_scroll_offset_ == root_offset)
+ return;
+ root_scroll_offset_updated_by_browser_ = true;
+ root_scroll_offset_ = root_offset;
+ SendAsyncCompositorStateIfNeeded();
+}
+
+void SynchronousCompositorHost::SendAsyncCompositorStateIfNeeded() {
+ if (weak_ptr_factory_.HasWeakPtrs())
+ return;
+
+ ui_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&SynchronousCompositorHost::UpdateStateTask,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SynchronousCompositorHost::UpdateStateTask() {
+ SyncCompositorCommonBrowserParams common_browser_params;
+ PopulateCommonParams(&common_browser_params);
+ sender_->Send(
+ new SyncCompositorMsg_UpdateState(routing_id_, common_browser_params));
+ DCHECK(!weak_ptr_factory_.HasWeakPtrs());
+}
+
+void SynchronousCompositorHost::SetIsActive(bool is_active) {
+ if (is_active_ == is_active)
+ return;
+ is_active_ = is_active;
+ UpdateNeedsBeginFrames();
+ SendAsyncCompositorStateIfNeeded();
+}
+
+void SynchronousCompositorHost::OnComputeScroll(
+ base::TimeTicks animation_time) {
+ if (!need_animate_scroll_)
+ return;
+ need_animate_scroll_ = false;
+
+ SyncCompositorCommonBrowserParams common_browser_params;
+ PopulateCommonParams(&common_browser_params);
+ SyncCompositorCommonRendererParams common_renderer_params;
+ if (!sender_->Send(new SyncCompositorMsg_ComputeScroll(
+ routing_id_, common_browser_params, animation_time,
+ &common_renderer_params))) {
+ return;
+ }
+ ProcessCommonParams(common_renderer_params);
+}
+
+InputEventAckState SynchronousCompositorHost::HandleInputEvent(
+ const blink::WebInputEvent& input_event) {
+ SyncCompositorCommonBrowserParams common_browser_params;
+ PopulateCommonParams(&common_browser_params);
+ SyncCompositorCommonRendererParams common_renderer_params;
+ InputEventAckState ack = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
+ if (!sender_->Send(new SyncCompositorMsg_HandleInputEvent(
+ routing_id_, common_browser_params, &input_event,
+ &common_renderer_params, &ack))) {
+ return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
+ }
+ ProcessCommonParams(common_renderer_params);
+ return ack;
+}
+
+void SynchronousCompositorHost::BeginFrame(const cc::BeginFrameArgs& args) {
+ if (!is_active_ || !need_begin_frame_)
+ return;
+
+ SyncCompositorCommonBrowserParams common_browser_params;
+ PopulateCommonParams(&common_browser_params);
+ SyncCompositorCommonRendererParams common_renderer_params;
+ if (!sender_->Send(
+ new SyncCompositorMsg_BeginFrame(routing_id_, common_browser_params,
+ args, &common_renderer_params))) {
+ return;
+ }
+ ProcessCommonParams(common_renderer_params);
+}
+
+void SynchronousCompositorHost::OnOverScroll(
+ const SyncCompositorCommonRendererParams& params,
+ const DidOverscrollParams& over_scroll_params) {
+ ProcessCommonParams(params);
+ client_->DidOverscroll(over_scroll_params.accumulated_overscroll,
+ over_scroll_params.latest_overscroll_delta,
+ over_scroll_params.current_fling_velocity);
+}
+
+void SynchronousCompositorHost::PopulateCommonParams(
+ SyncCompositorCommonBrowserParams* params) {
+ DCHECK(params);
+ DCHECK(params->ack.resources.empty());
+ params->bytes_limit = bytes_limit_;
+ params->ack.resources.swap(returned_resources_);
+ if (root_scroll_offset_updated_by_browser_) {
+ params->root_scroll_offset = root_scroll_offset_;
+ params->update_root_scroll_offset = root_scroll_offset_updated_by_browser_;
+ root_scroll_offset_updated_by_browser_ = false;
+ }
+ params->begin_frame_source_paused = !is_active_;
+
+ weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
+void SynchronousCompositorHost::ProcessCommonParams(
+ const SyncCompositorCommonRendererParams& params) {
+ // Ignore if |renderer_param_version_| is newer than |params.version|. This
+ // comparison takes into account when the unsigned int wraps.
+ if ((renderer_param_version_ - params.version) < 0x80000000) {
+ return;
+ }
+ renderer_param_version_ = params.version;
+ need_animate_scroll_ = params.need_animate_scroll;
+ if (need_begin_frame_ != params.need_begin_frame) {
+ need_begin_frame_ = params.need_begin_frame;
+ UpdateNeedsBeginFrames();
+ }
+ need_invalidate_ = need_invalidate_ || params.need_invalidate;
+ did_activate_pending_tree_ =
+ did_activate_pending_tree_ || params.did_activate_pending_tree;
+ root_scroll_offset_ = params.total_scroll_offset;
+
+ if (need_invalidate_) {
+ need_invalidate_ = false;
+ client_->PostInvalidate();
+ }
+
+ if (did_activate_pending_tree_) {
+ did_activate_pending_tree_ = false;
+ client_->DidUpdateContent();
+ }
+
+ // Ensure only valid values from compositor are sent to client.
+ // Compositor has page_scale_factor set to 0 before initialization, so check
+ // for that case here.
+ if (params.page_scale_factor) {
+ client_->UpdateRootLayerState(
+ gfx::ScrollOffsetToVector2dF(params.total_scroll_offset),
+ gfx::ScrollOffsetToVector2dF(params.max_scroll_offset),
+ params.scrollable_size, params.page_scale_factor,
+ params.min_page_scale_factor, params.max_page_scale_factor);
+ }
+}
+
+void SynchronousCompositorHost::UpdateNeedsBeginFrames() {
+ rwhva_->OnSetNeedsBeginFrames(is_active_ && need_begin_frame_);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/android/synchronous_compositor_host.h b/chromium/content/browser/android/synchronous_compositor_host.h
new file mode 100644
index 00000000000..8c60071db59
--- /dev/null
+++ b/chromium/content/browser/android/synchronous_compositor_host.h
@@ -0,0 +1,105 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_HOST_H_
+#define CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_HOST_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "cc/output/compositor_frame.h"
+#include "content/browser/android/synchronous_compositor_base.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/size_f.h"
+
+namespace IPC {
+class Sender;
+}
+
+namespace content {
+
+class RenderWidgetHostViewAndroid;
+class SynchronousCompositorClient;
+struct DidOverscrollParams;
+struct SyncCompositorCommonBrowserParams;
+struct SyncCompositorCommonRendererParams;
+
+class SynchronousCompositorHost : public SynchronousCompositorBase {
+ public:
+ ~SynchronousCompositorHost() override;
+
+ // SynchronousCompositor overrides.
+ scoped_ptr<cc::CompositorFrame> DemandDrawHw(
+ const gfx::Size& surface_size,
+ const gfx::Transform& transform,
+ const gfx::Rect& viewport,
+ const gfx::Rect& clip,
+ const gfx::Rect& viewport_rect_for_tile_priority,
+ const gfx::Transform& transform_for_tile_priority) override;
+ bool DemandDrawSw(SkCanvas* canvas) override;
+ void ReturnResources(const cc::CompositorFrameAck& frame_ack) override;
+ void SetMemoryPolicy(size_t bytes_limit) override;
+ void DidChangeRootLayerScrollOffset(
+ const gfx::ScrollOffset& root_offset) override;
+ void SetIsActive(bool is_active) override;
+ void OnComputeScroll(base::TimeTicks animation_time) override;
+
+ // SynchronousCompositorBase overrides.
+ InputEventAckState HandleInputEvent(
+ const blink::WebInputEvent& input_event) override;
+ void BeginFrame(const cc::BeginFrameArgs& args) override;
+ bool OnMessageReceived(const IPC::Message& message) override;
+ void DidBecomeCurrent() override;
+
+ private:
+ class ScopedSendZeroMemory;
+ struct SharedMemoryWithSize;
+ friend class ScopedSetZeroMemory;
+ friend class SynchronousCompositorBase;
+
+ SynchronousCompositorHost(RenderWidgetHostViewAndroid* rwhva,
+ SynchronousCompositorClient* client);
+ void PopulateCommonParams(SyncCompositorCommonBrowserParams* params);
+ void ProcessCommonParams(const SyncCompositorCommonRendererParams& params);
+ void UpdateNeedsBeginFrames();
+ void UpdateFrameMetaData(const cc::CompositorFrameMetadata& frame_metadata);
+ void OnOverScroll(const SyncCompositorCommonRendererParams& params,
+ const DidOverscrollParams& over_scroll_params);
+ void SendAsyncCompositorStateIfNeeded();
+ void UpdateStateTask();
+ void SetSoftwareDrawSharedMemoryIfNeeded(size_t stride, size_t buffer_size);
+ void SendZeroMemory();
+
+ RenderWidgetHostViewAndroid* const rwhva_;
+ SynchronousCompositorClient* const client_;
+ const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
+ const int routing_id_;
+ IPC::Sender* const sender_;
+
+ bool is_active_;
+ size_t bytes_limit_;
+ cc::ReturnedResourceArray returned_resources_;
+ scoped_ptr<SharedMemoryWithSize> software_draw_shm_;
+
+ // Updated by both renderer and browser.
+ gfx::ScrollOffset root_scroll_offset_;
+ bool root_scroll_offset_updated_by_browser_;
+
+ // From renderer.
+ uint32_t renderer_param_version_;
+ bool need_animate_scroll_;
+ bool need_invalidate_;
+ bool need_begin_frame_;
+ bool did_activate_pending_tree_;
+
+ base::WeakPtrFactory<SynchronousCompositorHost> weak_ptr_factory_;
+ DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_HOST_H_
diff --git a/chromium/content/browser/android/tracing_controller_android.cc b/chromium/content/browser/android/tracing_controller_android.cc
index 0aeeda7be81..35545aad3f8 100644
--- a/chromium/content/browser/android/tracing_controller_android.cc
+++ b/chromium/content/browser/android/tracing_controller_android.cc
@@ -25,14 +25,16 @@ TracingControllerAndroid::TracingControllerAndroid(JNIEnv* env, jobject obj)
TracingControllerAndroid::~TracingControllerAndroid() {}
-void TracingControllerAndroid::Destroy(JNIEnv* env, jobject obj) {
+void TracingControllerAndroid::Destroy(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
delete this;
}
-bool TracingControllerAndroid::StartTracing(JNIEnv* env,
- jobject obj,
- jstring jcategories,
- jstring jtraceoptions) {
+bool TracingControllerAndroid::StartTracing(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& jcategories,
+ const JavaParamRef<jstring>& jtraceoptions) {
std::string categories =
base::android::ConvertJavaStringToUTF8(env, jcategories);
std::string options =
@@ -41,17 +43,18 @@ bool TracingControllerAndroid::StartTracing(JNIEnv* env,
// This log is required by adb_profile_chrome.py.
LOG(WARNING) << "Logging performance trace to file";
- return TracingController::GetInstance()->EnableRecording(
+ return TracingController::GetInstance()->StartTracing(
base::trace_event::TraceConfig(categories, options),
- TracingController::EnableRecordingDoneCallback());
+ TracingController::StartTracingDoneCallback());
}
-void TracingControllerAndroid::StopTracing(JNIEnv* env,
- jobject obj,
- jstring jfilepath) {
+void TracingControllerAndroid::StopTracing(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& jfilepath) {
base::FilePath file_path(
base::android::ConvertJavaStringToUTF8(env, jfilepath));
- if (!TracingController::GetInstance()->DisableRecording(
+ if (!TracingController::GetInstance()->StopTracing(
TracingController::CreateFileSink(
file_path,
base::Bind(&TracingControllerAndroid::OnTracingStopped,
@@ -77,8 +80,9 @@ void TracingControllerAndroid::OnTracingStopped() {
Java_TracingControllerAndroid_onTracingStopped(env, obj.obj());
}
-bool TracingControllerAndroid::GetKnownCategoryGroupsAsync(JNIEnv* env,
- jobject obj) {
+bool TracingControllerAndroid::GetKnownCategoryGroupsAsync(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (!TracingController::GetInstance()->GetCategories(
base::Bind(&TracingControllerAndroid::OnKnownCategoriesReceived,
weak_factory_.GetWeakPtr()))) {
diff --git a/chromium/content/browser/android/tracing_controller_android.h b/chromium/content/browser/android/tracing_controller_android.h
index 58e6b94d36b..77f6144f2e0 100644
--- a/chromium/content/browser/android/tracing_controller_android.h
+++ b/chromium/content/browser/android/tracing_controller_android.h
@@ -9,6 +9,7 @@
#include "base/android/jni_weak_ref.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
namespace content {
@@ -17,14 +18,18 @@ namespace content {
class TracingControllerAndroid {
public:
TracingControllerAndroid(JNIEnv* env, jobject obj);
- void Destroy(JNIEnv* env, jobject obj);
+ void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
bool StartTracing(JNIEnv* env,
- jobject obj,
- jstring categories,
- jstring trace_options);
- void StopTracing(JNIEnv* env, jobject obj, jstring jfilepath);
- bool GetKnownCategoryGroupsAsync(JNIEnv* env, jobject obj);
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& categories,
+ const base::android::JavaParamRef<jstring>& trace_options);
+ void StopTracing(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& jfilepath);
+ bool GetKnownCategoryGroupsAsync(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
static void GenerateTracingFilePath(base::FilePath* file_path);
private:
diff --git a/chromium/content/browser/android/url_request_content_job.cc b/chromium/content/browser/android/url_request_content_job.cc
index 594e89f35e9..baf9483fafe 100644
--- a/chromium/content/browser/android/url_request_content_job.cc
+++ b/chromium/content/browser/android/url_request_content_job.cc
@@ -11,7 +11,6 @@
#include "base/task_runner.h"
#include "net/base/file_stream.h"
#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request_error_job.h"
#include "url/gurl.h"
@@ -34,6 +33,7 @@ URLRequestContentJob::URLRequestContentJob(
content_path_(content_path),
stream_(new net::FileStream(content_task_runner)),
content_task_runner_(content_task_runner),
+ range_parse_result_(net::OK),
remaining_bytes_(0),
io_pending_(false),
weak_ptr_factory_(this) {}
@@ -56,44 +56,28 @@ void URLRequestContentJob::Kill() {
net::URLRequestJob::Kill();
}
-bool URLRequestContentJob::ReadRawData(net::IOBuffer* dest,
- int dest_size,
- int* bytes_read) {
+int URLRequestContentJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
DCHECK_GT(dest_size, 0);
- DCHECK(bytes_read);
DCHECK_GE(remaining_bytes_, 0);
if (remaining_bytes_ < dest_size)
- dest_size = static_cast<int>(remaining_bytes_);
+ dest_size = remaining_bytes_;
// If we should copy zero bytes because |remaining_bytes_| is zero, short
// circuit here.
- if (!dest_size) {
- *bytes_read = 0;
- return true;
- }
+ if (!dest_size)
+ return 0;
- int rv = stream_->Read(dest,
- dest_size,
+ int rv = stream_->Read(dest, dest_size,
base::Bind(&URLRequestContentJob::DidRead,
- weak_ptr_factory_.GetWeakPtr(),
- make_scoped_refptr(dest)));
- if (rv >= 0) {
- // Data is immediately available.
- *bytes_read = rv;
- remaining_bytes_ -= rv;
- DCHECK_GE(remaining_bytes_, 0);
- return true;
- }
-
- // Otherwise, a read error occured. We may just need to wait...
+ weak_ptr_factory_.GetWeakPtr()));
if (rv == net::ERR_IO_PENDING) {
io_pending_ = true;
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
- } else {
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, rv));
+ } else if (rv > 0) {
+ remaining_bytes_ -= rv;
}
- return false;
+ DCHECK_GE(remaining_bytes_, 0);
+ return rv;
}
bool URLRequestContentJob::IsRedirectResponse(GURL* location,
@@ -116,16 +100,16 @@ void URLRequestContentJob::SetExtraRequestHeaders(
if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header))
return;
- // We only care about "Range" header here.
+ // Currently this job only cares about the Range header. Note that validation
+ // is deferred to DidOpen(), because NotifyStartError is not legal to call
+ // since the job has not started.
std::vector<net::HttpByteRange> ranges;
if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
if (ranges.size() == 1) {
byte_range_ = ranges[0];
} else {
// We don't support multiple range requests.
- NotifyDone(net::URLRequestStatus(
- net::URLRequestStatus::FAILED,
- net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ range_parse_result_ = net::ERR_REQUEST_RANGE_NOT_SATISFIABLE;
}
}
}
@@ -162,13 +146,20 @@ void URLRequestContentJob::DidFetchMetaInfo(const ContentMetaInfo* meta_info) {
void URLRequestContentJob::DidOpen(int result) {
if (result != net::OK) {
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
+ NotifyStartError(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
+ return;
+ }
+
+ if (range_parse_result_ != net::OK) {
+ NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ range_parse_result_));
return;
}
if (!byte_range_.ComputeBounds(meta_info_.content_size)) {
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ NotifyStartError(net::URLRequestStatus(
+ net::URLRequestStatus::FAILED, net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
@@ -193,10 +184,10 @@ void URLRequestContentJob::DidOpen(int result) {
}
}
-void URLRequestContentJob::DidSeek(int64 result) {
+void URLRequestContentJob::DidSeek(int64_t result) {
if (result != byte_range_.first_byte_position()) {
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ NotifyStartError(net::URLRequestStatus(
+ net::URLRequestStatus::FAILED, net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
@@ -204,24 +195,16 @@ void URLRequestContentJob::DidSeek(int64 result) {
NotifyHeadersComplete();
}
-void URLRequestContentJob::DidRead(
- scoped_refptr<net::IOBuffer> buf, int result) {
- if (result > 0) {
- SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status
- remaining_bytes_ -= result;
- DCHECK_GE(remaining_bytes_, 0);
- }
-
+void URLRequestContentJob::DidRead(int result) {
DCHECK(io_pending_);
io_pending_ = false;
- if (result == 0) {
- NotifyDone(net::URLRequestStatus());
- } else if (result < 0) {
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
+ if (result > 0) {
+ remaining_bytes_ -= result;
+ DCHECK_GE(remaining_bytes_, 0);
}
- NotifyReadComplete(result);
+ ReadRawDataComplete(result);
}
} // namespace content
diff --git a/chromium/content/browser/android/url_request_content_job.h b/chromium/content/browser/android/url_request_content_job.h
index 5d3d9336acc..9858eba38c8 100644
--- a/chromium/content/browser/android/url_request_content_job.h
+++ b/chromium/content/browser/android/url_request_content_job.h
@@ -5,13 +5,17 @@
#ifndef CONTENT_BROWSER_ANDROID_URL_REQUEST_CONTENT_JOB_H_
#define CONTENT_BROWSER_ANDROID_URL_REQUEST_CONTENT_JOB_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
+#include "net/base/net_errors.h"
#include "net/http/http_byte_range.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
@@ -42,7 +46,7 @@ class CONTENT_EXPORT URLRequestContentJob : public net::URLRequestJob {
// net::URLRequestJob:
void Start() override;
void Kill() override;
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;
bool IsRedirectResponse(GURL* location, int* http_status_code) override;
bool GetMimeType(std::string* mime_type) const override;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
@@ -59,7 +63,7 @@ class CONTENT_EXPORT URLRequestContentJob : public net::URLRequestJob {
// Flag showing whether the content URI exists.
bool content_exists;
// Size of the content URI.
- int64 content_size;
+ int64_t content_size;
// Mime type associated with the content URI.
std::string mime_type;
};
@@ -76,10 +80,10 @@ class CONTENT_EXPORT URLRequestContentJob : public net::URLRequestJob {
// Callback after seeking to the beginning of |byte_range_| in the content URI
// on a background thread.
- void DidSeek(int64 result);
+ void DidSeek(int64_t result);
// Callback after data is asynchronously read from the content URI into |buf|.
- void DidRead(scoped_refptr<net::IOBuffer> buf, int result);
+ void DidRead(int result);
// The full path of the content URI.
base::FilePath content_path_;
@@ -89,7 +93,8 @@ class CONTENT_EXPORT URLRequestContentJob : public net::URLRequestJob {
const scoped_refptr<base::TaskRunner> content_task_runner_;
net::HttpByteRange byte_range_;
- int64 remaining_bytes_;
+ net::Error range_parse_result_;
+ int64_t remaining_bytes_;
bool io_pending_;
diff --git a/chromium/content/browser/android/url_request_content_job_unittest.cc b/chromium/content/browser/android/url_request_content_job_unittest.cc
index 028a864968a..124b24a5e02 100644
--- a/chromium/content/browser/android/url_request_content_job_unittest.cc
+++ b/chromium/content/browser/android/url_request_content_job_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/android/url_request_content_job.h"
+#include <stdint.h>
+
#include <algorithm>
#include "base/files/file_util.h"
@@ -26,7 +28,8 @@ class CallbacksJobFactory : public net::URLRequestJobFactory {
public:
class JobObserver {
public:
- virtual void OnJobCreated(URLRequestContentJob* job) = 0;
+ virtual ~JobObserver() {}
+ virtual void OnJobCreated() = 0;
};
CallbacksJobFactory(const base::FilePath& path, JobObserver* observer)
@@ -45,7 +48,7 @@ class CallbacksJobFactory : public net::URLRequestJobFactory {
network_delegate,
path_,
const_cast<base::MessageLoop*>(&message_loop_)->task_runner());
- observer_->OnJobCreated(job);
+ observer_->OnJobCreated();
return job;
}
@@ -82,16 +85,15 @@ class CallbacksJobFactory : public net::URLRequestJobFactory {
class JobObserverImpl : public CallbacksJobFactory::JobObserver {
public:
- void OnJobCreated(URLRequestContentJob* job) override {
- jobs_.push_back(job);
- }
+ JobObserverImpl() : num_jobs_created_(0) {}
+ ~JobObserverImpl() override {}
- typedef std::vector<scoped_refptr<URLRequestContentJob> > JobList;
+ void OnJobCreated() override { ++num_jobs_created_; }
- const JobList& jobs() { return jobs_; }
+ int num_jobs_created() const { return num_jobs_created_; }
- protected:
- JobList jobs_;
+ private:
+ int num_jobs_created_;
};
// A simple holder for start/end used in http range requests.
@@ -141,7 +143,7 @@ void URLRequestContentJobTest::RunRequest(const Range* range) {
base::FilePath path = base::InsertImageIntoMediaStore(image_file);
EXPECT_TRUE(path.IsContentUri());
EXPECT_TRUE(base::PathExists(path));
- int64 file_size;
+ int64_t file_size;
EXPECT_TRUE(base::GetFileSize(path, &file_size));
EXPECT_LT(0, file_size);
CallbacksJobFactory factory(path, &observer_);
@@ -158,11 +160,12 @@ void URLRequestContentJobTest::RunRequest(const Range* range) {
base::StringPrintf("bytes=%d-%d", range->start, range->end);
request->SetExtraRequestHeaderByName(
net::HttpRequestHeaders::kRange, range_value, true /*overwrite*/);
- if (range->start <= file_size)
- expected_length =
- std::min(range->end, (int) (file_size - 1)) - range->start + 1;
- else
+ if (range->start <= file_size) {
+ expected_length = std::min(range->end, static_cast<int>(file_size - 1)) -
+ range->start + 1;
+ } else {
expected_length = 0;
+ }
}
request->Start();
@@ -170,8 +173,8 @@ void URLRequestContentJobTest::RunRequest(const Range* range) {
loop.Run();
EXPECT_FALSE(delegate_.request_failed());
- ASSERT_EQ(observer_.jobs().size(), 1u);
- EXPECT_EQ(delegate_.bytes_received(), expected_length);
+ ASSERT_EQ(1, observer_.num_jobs_created());
+ EXPECT_EQ(expected_length, delegate_.bytes_received());
}
TEST_F(URLRequestContentJobTest, ContentURIWithoutRange) {
diff --git a/chromium/content/browser/android/web_contents_observer_proxy.cc b/chromium/content/browser/android/web_contents_observer_proxy.cc
index c04f9263b00..22ab07c2ed6 100644
--- a/chromium/content/browser/android/web_contents_observer_proxy.cc
+++ b/chromium/content/browser/android/web_contents_observer_proxy.cc
@@ -48,7 +48,8 @@ jlong Init(JNIEnv* env,
return reinterpret_cast<intptr_t>(native_observer);
}
-void WebContentsObserverProxy::Destroy(JNIEnv* env, jobject obj) {
+void WebContentsObserverProxy::Destroy(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
delete this;
}
@@ -87,8 +88,10 @@ void WebContentsObserverProxy::DidStartLoading() {
void WebContentsObserverProxy::DidStopLoading() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj(java_observer_);
+ std::string url_string = web_contents()->GetLastCommittedURL().spec();
+ SetToBaseURLForDataURLIfNeeded(&url_string);
ScopedJavaLocalRef<jstring> jstring_url(ConvertUTF8ToJavaString(
- env, web_contents()->GetLastCommittedURL().spec()));
+ env, url_string));
Java_WebContentsObserverProxy_didStopLoading(env, obj.obj(),
jstring_url.obj());
}
@@ -205,11 +208,7 @@ void WebContentsObserverProxy::DidFinishLoad(RenderFrameHost* render_frame_host,
ScopedJavaLocalRef<jobject> obj(java_observer_);
std::string url_string = validated_url.spec();
- NavigationEntry* entry =
- web_contents()->GetController().GetLastCommittedEntry();
- // Note that GetBaseURLForDataURL is only used by the Android WebView.
- if (entry && !entry->GetBaseURLForDataURL().is_empty())
- url_string = entry->GetBaseURLForDataURL().possibly_invalid_spec();
+ SetToBaseURLForDataURLIfNeeded(&url_string);
ScopedJavaLocalRef<jstring> jstring_url(
ConvertUTF8ToJavaString(env, url_string));
@@ -300,6 +299,15 @@ void WebContentsObserverProxy::MediaSessionStateChanged(bool is_controllable,
env, obj.obj(), is_controllable, is_suspended);
}
+void WebContentsObserverProxy::SetToBaseURLForDataURLIfNeeded(
+ std::string* url) {
+ NavigationEntry* entry =
+ web_contents()->GetController().GetLastCommittedEntry();
+ // Note that GetBaseURLForDataURL is only used by the Android WebView.
+ if (entry && !entry->GetBaseURLForDataURL().is_empty())
+ *url = entry->GetBaseURLForDataURL().possibly_invalid_spec();
+}
+
bool RegisterWebContentsObserverProxy(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/chromium/content/browser/android/web_contents_observer_proxy.h b/chromium/content/browser/android/web_contents_observer_proxy.h
index bbce0942241..23464053b26 100644
--- a/chromium/content/browser/android/web_contents_observer_proxy.h
+++ b/chromium/content/browser/android/web_contents_observer_proxy.h
@@ -8,7 +8,7 @@
#include <jni.h>
#include "base/android/jni_weak_ref.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/process/kill.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents_observer.h"
@@ -27,7 +27,7 @@ class WebContentsObserverProxy : public WebContentsObserver {
WebContentsObserverProxy(JNIEnv* env, jobject obj, WebContents* web_contents);
~WebContentsObserverProxy() override;
- void Destroy(JNIEnv* env, jobject obj);
+ void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
private:
void RenderViewReady() override;
@@ -73,6 +73,7 @@ class WebContentsObserverProxy : public WebContentsObserver {
NavigationController::ReloadType reload_type) override;
void MediaSessionStateChanged(bool is_controllable,
bool is_suspended) override;
+ void SetToBaseURLForDataURLIfNeeded(std::string* url);
void DidFailLoadInternal(bool is_provisional_load,
bool is_main_frame,
diff --git a/chromium/content/browser/appcache/appcache.cc b/chromium/content/browser/appcache/appcache.cc
index aa0b224bd7e..f97d9cce916 100644
--- a/chromium/content/browser/appcache/appcache.cc
+++ b/chromium/content/browser/appcache/appcache.cc
@@ -4,6 +4,8 @@
#include "content/browser/appcache/appcache.h"
+#include <stddef.h>
+
#include <algorithm>
#include "base/logging.h"
@@ -16,7 +18,7 @@
namespace content {
-AppCache::AppCache(AppCacheStorage* storage, int64 cache_id)
+AppCache::AppCache(AppCacheStorage* storage, int64_t cache_id)
: cache_id_(cache_id),
owning_group_(NULL),
online_whitelist_all_(false),
@@ -73,7 +75,8 @@ AppCacheEntry* AppCache::GetEntry(const GURL& url) {
}
const AppCacheEntry* AppCache::GetEntryAndUrlWithResponseId(
- int64 response_id, GURL* optional_url_out) {
+ int64_t response_id,
+ GURL* optional_url_out) {
for (EntryMap::const_iterator iter = entries_.begin();
iter != entries_.end(); ++iter) {
if (iter->second.response_id() == response_id) {
@@ -85,7 +88,7 @@ const AppCacheEntry* AppCache::GetEntryAndUrlWithResponseId(
return NULL;
}
-AppCacheExecutableHandler* AppCache::GetExecutableHandler(int64 response_id) {
+AppCacheExecutableHandler* AppCache::GetExecutableHandler(int64_t response_id) {
HandlerMap::const_iterator found = executable_handlers_.find(response_id);
if (found != executable_handlers_.end())
return found->second;
@@ -93,7 +96,8 @@ AppCacheExecutableHandler* AppCache::GetExecutableHandler(int64 response_id) {
}
AppCacheExecutableHandler* AppCache::GetOrCreateExecutableHandler(
- int64 response_id, net::IOBuffer* handler_source) {
+ int64_t response_id,
+ net::IOBuffer* handler_source) {
AppCacheExecutableHandler* handler = GetExecutableHandler(response_id);
if (handler)
return handler;
diff --git a/chromium/content/browser/appcache/appcache.h b/chromium/content/browser/appcache/appcache.h
index a444579a64d..f619252ef3a 100644
--- a/chromium/content/browser/appcache/appcache.h
+++ b/chromium/content/browser/appcache/appcache.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "content/browser/appcache/appcache_database.h"
@@ -42,9 +45,9 @@ class CONTENT_EXPORT AppCache
typedef std::map<GURL, AppCacheEntry> EntryMap;
typedef std::set<AppCacheHost*> AppCacheHosts;
- AppCache(AppCacheStorage* storage, int64 cache_id);
+ AppCache(AppCacheStorage* storage, int64_t cache_id);
- int64 cache_id() const { return cache_id_; }
+ int64_t cache_id() const { return cache_id_; }
AppCacheGroup* owning_group() const { return owning_group_.get(); }
@@ -64,11 +67,11 @@ class CONTENT_EXPORT AppCache
// Do not store or delete the returned ptr, they're owned by 'this'.
AppCacheEntry* GetEntry(const GURL& url);
- const AppCacheEntry* GetEntryWithResponseId(int64 response_id) {
+ const AppCacheEntry* GetEntryWithResponseId(int64_t response_id) {
return GetEntryAndUrlWithResponseId(response_id, NULL);
}
- const AppCacheEntry* GetEntryAndUrlWithResponseId(
- int64 response_id, GURL* optional_url);
+ const AppCacheEntry* GetEntryAndUrlWithResponseId(int64_t response_id,
+ GURL* optional_url);
const EntryMap& entries() const { return entries_; }
// The AppCache owns the collection of executable handlers that have
@@ -76,9 +79,10 @@ class CONTENT_EXPORT AppCache
// handler returning null if not found, the GetOrCreate method will
// cons one up if not found.
// Do not store the returned ptrs, they're owned by 'this'.
- AppCacheExecutableHandler* GetExecutableHandler(int64 response_id);
+ AppCacheExecutableHandler* GetExecutableHandler(int64_t response_id);
AppCacheExecutableHandler* GetOrCreateExecutableHandler(
- int64 response_id, net::IOBuffer* handler_source);
+ int64_t response_id,
+ net::IOBuffer* handler_source);
// Returns the URL of the resource used as entry for 'namespace_url'.
GURL GetFallbackEntryUrl(const GURL& namespace_url) const {
@@ -105,7 +109,7 @@ class CONTENT_EXPORT AppCache
base::Time update_time() const { return update_time_; }
- int64 cache_size() const { return cache_size_; }
+ int64_t cache_size() const { return cache_size_; }
void set_update_time(base::Time ticks) { update_time_ = ticks; }
@@ -176,7 +180,7 @@ class CONTENT_EXPORT AppCache
}
void UnassociateHost(AppCacheHost* host);
- const int64 cache_id_;
+ const int64_t cache_id_;
scoped_refptr<AppCacheGroup> owning_group_;
AppCacheHosts associated_hosts_;
@@ -192,9 +196,9 @@ class CONTENT_EXPORT AppCache
// when this cache was last updated
base::Time update_time_;
- int64 cache_size_;
+ int64_t cache_size_;
- typedef std::map<int64, AppCacheExecutableHandler*> HandlerMap;
+ typedef std::map<int64_t, AppCacheExecutableHandler*> HandlerMap;
HandlerMap executable_handlers_;
// to notify storage when cache is deleted
diff --git a/chromium/content/browser/appcache/appcache_backend_impl.cc b/chromium/content/browser/appcache/appcache_backend_impl.cc
index 01eed000ef0..c3bb533f037 100644
--- a/chromium/content/browser/appcache/appcache_backend_impl.cc
+++ b/chromium/content/browser/appcache/appcache_backend_impl.cc
@@ -65,7 +65,7 @@ bool AppCacheBackendImpl::SetSpawningHostId(
bool AppCacheBackendImpl::SelectCache(
int host_id,
const GURL& document_url,
- const int64 cache_document_was_loaded_from,
+ const int64_t cache_document_was_loaded_from,
const GURL& manifest_url) {
AppCacheHost* host = GetHost(host_id);
if (!host)
@@ -84,8 +84,8 @@ bool AppCacheBackendImpl::SelectCacheForWorker(
return host->SelectCacheForWorker(parent_process_id, parent_host_id);
}
-bool AppCacheBackendImpl::SelectCacheForSharedWorker(
- int host_id, int64 appcache_id) {
+bool AppCacheBackendImpl::SelectCacheForSharedWorker(int host_id,
+ int64_t appcache_id) {
AppCacheHost* host = GetHost(host_id);
if (!host)
return false;
@@ -96,7 +96,7 @@ bool AppCacheBackendImpl::SelectCacheForSharedWorker(
bool AppCacheBackendImpl::MarkAsForeignEntry(
int host_id,
const GURL& document_url,
- int64 cache_document_was_loaded_from) {
+ int64_t cache_document_was_loaded_from) {
AppCacheHost* host = GetHost(host_id);
if (!host)
return false;
diff --git a/chromium/content/browser/appcache/appcache_backend_impl.h b/chromium/content/browser/appcache/appcache_backend_impl.h
index bd6f440823e..b0136b4081a 100644
--- a/chromium/content/browser/appcache/appcache_backend_impl.h
+++ b/chromium/content/browser/appcache/appcache_backend_impl.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_BACKEND_IMPL_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_BACKEND_IMPL_H_
+#include <stdint.h>
+
#include "base/containers/hash_tables.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/common/content_export.h"
@@ -32,15 +34,16 @@ class CONTENT_EXPORT AppCacheBackendImpl {
bool SetSpawningHostId(int host_id, int spawning_host_id);
bool SelectCache(int host_id,
const GURL& document_url,
- const int64 cache_document_was_loaded_from,
+ const int64_t cache_document_was_loaded_from,
const GURL& manifest_url);
void GetResourceList(
int host_id, std::vector<AppCacheResourceInfo>* resource_infos);
bool SelectCacheForWorker(int host_id, int parent_process_id,
int parent_host_id);
- bool SelectCacheForSharedWorker(int host_id, int64 appcache_id);
- bool MarkAsForeignEntry(int host_id, const GURL& document_url,
- int64 cache_document_was_loaded_from);
+ bool SelectCacheForSharedWorker(int host_id, int64_t appcache_id);
+ bool MarkAsForeignEntry(int host_id,
+ const GURL& document_url,
+ int64_t cache_document_was_loaded_from);
bool GetStatusWithCallback(int host_id, const GetStatusCallback& callback,
void* callback_param);
bool StartUpdateWithCallback(int host_id, const StartUpdateCallback& callback,
diff --git a/chromium/content/browser/appcache/appcache_database.cc b/chromium/content/browser/appcache/appcache_database.cc
index 8298bfb58bb..f9e83ac91b7 100644
--- a/chromium/content/browser/appcache/appcache_database.cc
+++ b/chromium/content/browser/appcache/appcache_database.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/appcache/appcache_entry.h"
#include "content/browser/appcache/appcache_histograms.h"
@@ -218,12 +219,12 @@ void AppCacheDatabase::Disable() {
ResetConnectionAndTables();
}
-int64 AppCacheDatabase::GetOriginUsage(const GURL& origin) {
+int64_t AppCacheDatabase::GetOriginUsage(const GURL& origin) {
std::vector<CacheRecord> records;
if (!FindCachesForOrigin(origin, &records))
return 0;
- int64 origin_usage = 0;
+ int64_t origin_usage = 0;
std::vector<CacheRecord>::const_iterator iter = records.begin();
while (iter != records.end()) {
origin_usage += iter->cache_size;
@@ -232,7 +233,7 @@ int64 AppCacheDatabase::GetOriginUsage(const GURL& origin) {
return origin_usage;
}
-bool AppCacheDatabase::GetAllOriginUsage(std::map<GURL, int64>* usage_map) {
+bool AppCacheDatabase::GetAllOriginUsage(std::map<GURL, int64_t>* usage_map) {
std::set<GURL> origins;
if (!FindOriginsWithGroups(&origins))
return false;
@@ -260,8 +261,10 @@ bool AppCacheDatabase::FindOriginsWithGroups(std::set<GURL>* origins) {
}
bool AppCacheDatabase::FindLastStorageIds(
- int64* last_group_id, int64* last_cache_id, int64* last_response_id,
- int64* last_deletable_response_rowid) {
+ int64_t* last_group_id,
+ int64_t* last_cache_id,
+ int64_t* last_response_id,
+ int64_t* last_deletable_response_rowid) {
DCHECK(last_group_id && last_cache_id && last_response_id &&
last_deletable_response_rowid);
@@ -281,11 +284,11 @@ bool AppCacheDatabase::FindLastStorageIds(
"SELECT MAX(response_id) FROM DeletableResponseIds";
const char* kMaxDeletableResponseRowIdSql =
"SELECT MAX(rowid) FROM DeletableResponseIds";
- int64 max_group_id;
- int64 max_cache_id;
- int64 max_response_id_from_entries;
- int64 max_response_id_from_deletables;
- int64 max_deletable_response_rowid;
+ int64_t max_group_id;
+ int64_t max_cache_id;
+ int64_t max_response_id_from_entries;
+ int64_t max_response_id_from_deletables;
+ int64_t max_deletable_response_rowid;
if (!RunUniqueStatementWithInt64Result(kMaxGroupIdSql, &max_group_id) ||
!RunUniqueStatementWithInt64Result(kMaxCacheIdSql, &max_cache_id) ||
!RunUniqueStatementWithInt64Result(kMaxResponseIdFromEntriesSql,
@@ -305,7 +308,7 @@ bool AppCacheDatabase::FindLastStorageIds(
return true;
}
-bool AppCacheDatabase::FindGroup(int64 group_id, GroupRecord* record) {
+bool AppCacheDatabase::FindGroup(int64_t group_id, GroupRecord* record) {
DCHECK(record);
if (!LazyOpen(kDontCreate))
return false;
@@ -377,7 +380,8 @@ bool AppCacheDatabase::FindGroupsForOrigin(
return statement.Succeeded();
}
-bool AppCacheDatabase::FindGroupForCache(int64 cache_id, GroupRecord* record) {
+bool AppCacheDatabase::FindGroupForCache(int64_t cache_id,
+ GroupRecord* record) {
DCHECK(record);
if (!LazyOpen(kDontCreate))
return false;
@@ -420,7 +424,7 @@ bool AppCacheDatabase::InsertGroup(const GroupRecord* record) {
return statement.Run();
}
-bool AppCacheDatabase::DeleteGroup(int64 group_id) {
+bool AppCacheDatabase::DeleteGroup(int64_t group_id) {
if (!LazyOpen(kDontCreate))
return false;
@@ -431,15 +435,14 @@ bool AppCacheDatabase::DeleteGroup(int64 group_id) {
return statement.Run();
}
-bool AppCacheDatabase::UpdateLastAccessTime(
- int64 group_id, base::Time time) {
+bool AppCacheDatabase::UpdateLastAccessTime(int64_t group_id, base::Time time) {
if (!LazyUpdateLastAccessTime(group_id, time))
return false;
return CommitLazyLastAccessTimes();
}
-bool AppCacheDatabase::LazyUpdateLastAccessTime(
- int64 group_id, base::Time time) {
+bool AppCacheDatabase::LazyUpdateLastAccessTime(int64_t group_id,
+ base::Time time) {
if (!LazyOpen(kCreateIfNeeded))
return false;
lazy_last_access_times_[group_id] = time;
@@ -468,7 +471,7 @@ bool AppCacheDatabase::CommitLazyLastAccessTimes() {
}
bool AppCacheDatabase::UpdateEvictionTimes(
- int64 group_id,
+ int64_t group_id,
base::Time last_full_update_check_time,
base::Time first_evictable_error_time) {
if (!LazyOpen(kCreateIfNeeded))
@@ -485,7 +488,7 @@ bool AppCacheDatabase::UpdateEvictionTimes(
return statement.Run(); // Will succeed even if group_id is invalid.
}
-bool AppCacheDatabase::FindCache(int64 cache_id, CacheRecord* record) {
+bool AppCacheDatabase::FindCache(int64_t cache_id, CacheRecord* record) {
DCHECK(record);
if (!LazyOpen(kDontCreate))
return false;
@@ -504,7 +507,8 @@ bool AppCacheDatabase::FindCache(int64 cache_id, CacheRecord* record) {
return true;
}
-bool AppCacheDatabase::FindCacheForGroup(int64 group_id, CacheRecord* record) {
+bool AppCacheDatabase::FindCacheForGroup(int64_t group_id,
+ CacheRecord* record) {
DCHECK(record);
if (!LazyOpen(kDontCreate))
return false;
@@ -559,7 +563,7 @@ bool AppCacheDatabase::InsertCache(const CacheRecord* record) {
return statement.Run();
}
-bool AppCacheDatabase::DeleteCache(int64 cache_id) {
+bool AppCacheDatabase::DeleteCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
@@ -572,8 +576,8 @@ bool AppCacheDatabase::DeleteCache(int64 cache_id) {
return statement.Run();
}
-bool AppCacheDatabase::FindEntriesForCache(
- int64 cache_id, std::vector<EntryRecord>* records) {
+bool AppCacheDatabase::FindEntriesForCache(int64_t cache_id,
+ std::vector<EntryRecord>* records) {
DCHECK(records && records->empty());
if (!LazyOpen(kDontCreate))
return false;
@@ -616,8 +620,9 @@ bool AppCacheDatabase::FindEntriesForUrl(
return statement.Succeeded();
}
-bool AppCacheDatabase::FindEntry(
- int64 cache_id, const GURL& url, EntryRecord* record) {
+bool AppCacheDatabase::FindEntry(int64_t cache_id,
+ const GURL& url,
+ EntryRecord* record) {
DCHECK(record);
if (!LazyOpen(kDontCreate))
return false;
@@ -673,7 +678,7 @@ bool AppCacheDatabase::InsertEntryRecords(
return transaction.Commit();
}
-bool AppCacheDatabase::DeleteEntriesForCache(int64 cache_id) {
+bool AppCacheDatabase::DeleteEntriesForCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
@@ -686,8 +691,9 @@ bool AppCacheDatabase::DeleteEntriesForCache(int64 cache_id) {
return statement.Run();
}
-bool AppCacheDatabase::AddEntryFlags(
- const GURL& entry_url, int64 cache_id, int additional_flags) {
+bool AppCacheDatabase::AddEntryFlags(const GURL& entry_url,
+ int64_t cache_id,
+ int additional_flags) {
if (!LazyOpen(kDontCreate))
return false;
@@ -724,7 +730,7 @@ bool AppCacheDatabase::FindNamespacesForOrigin(
}
bool AppCacheDatabase::FindNamespacesForCache(
- int64 cache_id,
+ int64_t cache_id,
std::vector<NamespaceRecord>* intercepts,
std::vector<NamespaceRecord>* fallbacks) {
DCHECK(intercepts && intercepts->empty());
@@ -789,7 +795,7 @@ bool AppCacheDatabase::InsertNamespaceRecords(
return transaction.Commit();
}
-bool AppCacheDatabase::DeleteNamespacesForCache(int64 cache_id) {
+bool AppCacheDatabase::DeleteNamespacesForCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
@@ -803,7 +809,8 @@ bool AppCacheDatabase::DeleteNamespacesForCache(int64 cache_id) {
}
bool AppCacheDatabase::FindOnlineWhiteListForCache(
- int64 cache_id, std::vector<OnlineWhiteListRecord>* records) {
+ int64_t cache_id,
+ std::vector<OnlineWhiteListRecord>* records) {
DCHECK(records && records->empty());
if (!LazyOpen(kDontCreate))
return false;
@@ -856,7 +863,7 @@ bool AppCacheDatabase::InsertOnlineWhiteListRecords(
return transaction.Commit();
}
-bool AppCacheDatabase::DeleteOnlineWhiteListForCache(int64 cache_id) {
+bool AppCacheDatabase::DeleteOnlineWhiteListForCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
@@ -870,7 +877,9 @@ bool AppCacheDatabase::DeleteOnlineWhiteListForCache(int64 cache_id) {
}
bool AppCacheDatabase::GetDeletableResponseIds(
- std::vector<int64>* response_ids, int64 max_rowid, int limit) {
+ std::vector<int64_t>* response_ids,
+ int64_t max_rowid,
+ int limit) {
if (!LazyOpen(kDontCreate))
return false;
@@ -889,22 +898,23 @@ bool AppCacheDatabase::GetDeletableResponseIds(
}
bool AppCacheDatabase::InsertDeletableResponseIds(
- const std::vector<int64>& response_ids) {
+ const std::vector<int64_t>& response_ids) {
const char kSql[] =
"INSERT INTO DeletableResponseIds (response_id) VALUES (?)";
return RunCachedStatementWithIds(SQL_FROM_HERE, kSql, response_ids);
}
bool AppCacheDatabase::DeleteDeletableResponseIds(
- const std::vector<int64>& response_ids) {
+ const std::vector<int64_t>& response_ids) {
const char kSql[] =
"DELETE FROM DeletableResponseIds WHERE response_id = ?";
return RunCachedStatementWithIds(SQL_FROM_HERE, kSql, response_ids);
}
bool AppCacheDatabase::RunCachedStatementWithIds(
- const sql::StatementID& statement_id, const char* sql,
- const std::vector<int64>& ids) {
+ const sql::StatementID& statement_id,
+ const char* sql,
+ const std::vector<int64_t>& ids) {
DCHECK(sql);
if (!LazyOpen(kCreateIfNeeded))
return false;
@@ -915,7 +925,7 @@ bool AppCacheDatabase::RunCachedStatementWithIds(
sql::Statement statement(db_->GetCachedStatement(statement_id, sql));
- std::vector<int64>::const_iterator iter = ids.begin();
+ std::vector<int64_t>::const_iterator iter = ids.begin();
while (iter != ids.end()) {
statement.BindInt64(0, *iter);
if (!statement.Run())
@@ -927,8 +937,8 @@ bool AppCacheDatabase::RunCachedStatementWithIds(
return transaction.Commit();
}
-bool AppCacheDatabase::RunUniqueStatementWithInt64Result(
- const char* sql, int64* result) {
+bool AppCacheDatabase::RunUniqueStatementWithInt64Result(const char* sql,
+ int64_t* result) {
DCHECK(sql);
sql::Statement statement(db_->GetUniqueStatement(sql));
if (!statement.Step()) {
@@ -939,8 +949,9 @@ bool AppCacheDatabase::RunUniqueStatementWithInt64Result(
}
bool AppCacheDatabase::FindResponseIdsForCacheHelper(
- int64 cache_id, std::vector<int64>* ids_vector,
- std::set<int64>* ids_set) {
+ int64_t cache_id,
+ std::vector<int64_t>* ids_vector,
+ std::set<int64_t>* ids_set) {
DCHECK(ids_vector || ids_set);
DCHECK(!(ids_vector && ids_set));
if (!LazyOpen(kDontCreate))
@@ -953,7 +964,7 @@ bool AppCacheDatabase::FindResponseIdsForCacheHelper(
statement.BindInt64(0, cache_id);
while (statement.Step()) {
- int64 id = statement.ColumnInt64(0);
+ int64_t id = statement.ColumnInt64(0);
if (ids_set)
ids_set->insert(id);
else
diff --git a/chromium/content/browser/appcache/appcache_database.h b/chromium/content/browser/appcache/appcache_database.h
index 6addf9030bb..a6f017e48d0 100644
--- a/chromium/content/browser/appcache/appcache_database.h
+++ b/chromium/content/browser/appcache/appcache_database.h
@@ -5,13 +5,15 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_DATABASE_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_DATABASE_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "content/common/appcache_interfaces.h"
@@ -51,7 +53,7 @@ class CONTENT_EXPORT AppCacheDatabase {
GroupRecord();
~GroupRecord();
- int64 group_id;
+ int64_t group_id;
GURL origin;
GURL manifest_url;
base::Time creation_time;
@@ -64,28 +66,28 @@ class CONTENT_EXPORT AppCacheDatabase {
CacheRecord()
: cache_id(0), group_id(0), online_wildcard(false), cache_size(0) {}
- int64 cache_id;
- int64 group_id;
+ int64_t cache_id;
+ int64_t group_id;
bool online_wildcard;
base::Time update_time;
- int64 cache_size; // the sum of all response sizes in this cache
+ int64_t cache_size; // the sum of all response sizes in this cache
};
struct EntryRecord {
EntryRecord() : cache_id(0), flags(0), response_id(0), response_size(0) {}
- int64 cache_id;
+ int64_t cache_id;
GURL url;
int flags;
- int64 response_id;
- int64 response_size;
+ int64_t response_id;
+ int64_t response_size;
};
struct CONTENT_EXPORT NamespaceRecord {
NamespaceRecord();
~NamespaceRecord();
- int64 cache_id;
+ int64_t cache_id;
GURL origin;
AppCacheNamespace namespace_;
};
@@ -95,7 +97,7 @@ class CONTENT_EXPORT AppCacheDatabase {
struct OnlineWhiteListRecord {
OnlineWhiteListRecord() : cache_id(0), is_pattern(false) {}
- int64 cache_id;
+ int64_t cache_id;
GURL namespace_url;
bool is_pattern;
};
@@ -107,58 +109,57 @@ class CONTENT_EXPORT AppCacheDatabase {
bool is_disabled() const { return is_disabled_; }
bool was_corruption_detected() const { return was_corruption_detected_; }
- int64 GetOriginUsage(const GURL& origin);
- bool GetAllOriginUsage(std::map<GURL, int64>* usage_map);
+ int64_t GetOriginUsage(const GURL& origin);
+ bool GetAllOriginUsage(std::map<GURL, int64_t>* usage_map);
bool FindOriginsWithGroups(std::set<GURL>* origins);
- bool FindLastStorageIds(
- int64* last_group_id, int64* last_cache_id, int64* last_response_id,
- int64* last_deletable_response_rowid);
+ bool FindLastStorageIds(int64_t* last_group_id,
+ int64_t* last_cache_id,
+ int64_t* last_response_id,
+ int64_t* last_deletable_response_rowid);
- bool FindGroup(int64 group_id, GroupRecord* record);
+ bool FindGroup(int64_t group_id, GroupRecord* record);
bool FindGroupForManifestUrl(const GURL& manifest_url, GroupRecord* record);
bool FindGroupsForOrigin(
const GURL& origin, std::vector<GroupRecord>* records);
- bool FindGroupForCache(int64 cache_id, GroupRecord* record);
+ bool FindGroupForCache(int64_t cache_id, GroupRecord* record);
bool InsertGroup(const GroupRecord* record);
- bool DeleteGroup(int64 group_id);
+ bool DeleteGroup(int64_t group_id);
// The access and eviction time update methods do not fail when
// given invalid group_ids. The return value only indicates whether
// the database is functioning.
- bool UpdateLastAccessTime(int64 group_id,
- base::Time last_access_time);
- bool LazyUpdateLastAccessTime(int64 group_id,
- base::Time last_access_time);
- bool UpdateEvictionTimes(int64 group_id,
+ bool UpdateLastAccessTime(int64_t group_id, base::Time last_access_time);
+ bool LazyUpdateLastAccessTime(int64_t group_id, base::Time last_access_time);
+ bool UpdateEvictionTimes(int64_t group_id,
base::Time last_full_update_check_time,
base::Time first_evictable_error_time);
bool CommitLazyLastAccessTimes(); // The destructor calls this too.
- bool FindCache(int64 cache_id, CacheRecord* record);
- bool FindCacheForGroup(int64 group_id, CacheRecord* record);
+ bool FindCache(int64_t cache_id, CacheRecord* record);
+ bool FindCacheForGroup(int64_t group_id, CacheRecord* record);
bool FindCachesForOrigin(
const GURL& origin, std::vector<CacheRecord>* records);
bool InsertCache(const CacheRecord* record);
- bool DeleteCache(int64 cache_id);
+ bool DeleteCache(int64_t cache_id);
- bool FindEntriesForCache(
- int64 cache_id, std::vector<EntryRecord>* records);
+ bool FindEntriesForCache(int64_t cache_id, std::vector<EntryRecord>* records);
bool FindEntriesForUrl(
const GURL& url, std::vector<EntryRecord>* records);
- bool FindEntry(int64 cache_id, const GURL& url, EntryRecord* record);
+ bool FindEntry(int64_t cache_id, const GURL& url, EntryRecord* record);
bool InsertEntry(const EntryRecord* record);
bool InsertEntryRecords(
const std::vector<EntryRecord>& records);
- bool DeleteEntriesForCache(int64 cache_id);
- bool AddEntryFlags(const GURL& entry_url, int64 cache_id,
+ bool DeleteEntriesForCache(int64_t cache_id);
+ bool AddEntryFlags(const GURL& entry_url,
+ int64_t cache_id,
int additional_flags);
- bool FindResponseIdsForCacheAsVector(
- int64 cache_id, std::vector<int64>* response_ids) {
+ bool FindResponseIdsForCacheAsVector(int64_t cache_id,
+ std::vector<int64_t>* response_ids) {
return FindResponseIdsForCacheHelper(cache_id, response_ids, NULL);
}
- bool FindResponseIdsForCacheAsSet(
- int64 cache_id, std::set<int64>* response_ids) {
+ bool FindResponseIdsForCacheAsSet(int64_t cache_id,
+ std::set<int64_t>* response_ids) {
return FindResponseIdsForCacheHelper(cache_id, NULL, response_ids);
}
@@ -166,26 +167,26 @@ class CONTENT_EXPORT AppCacheDatabase {
const GURL& origin,
NamespaceRecordVector* intercepts,
NamespaceRecordVector* fallbacks);
- bool FindNamespacesForCache(
- int64 cache_id,
- NamespaceRecordVector* intercepts,
- std::vector<NamespaceRecord>* fallbacks);
+ bool FindNamespacesForCache(int64_t cache_id,
+ NamespaceRecordVector* intercepts,
+ std::vector<NamespaceRecord>* fallbacks);
bool InsertNamespaceRecords(
const NamespaceRecordVector& records);
bool InsertNamespace(const NamespaceRecord* record);
- bool DeleteNamespacesForCache(int64 cache_id);
+ bool DeleteNamespacesForCache(int64_t cache_id);
- bool FindOnlineWhiteListForCache(
- int64 cache_id, std::vector<OnlineWhiteListRecord>* records);
+ bool FindOnlineWhiteListForCache(int64_t cache_id,
+ std::vector<OnlineWhiteListRecord>* records);
bool InsertOnlineWhiteList(const OnlineWhiteListRecord* record);
bool InsertOnlineWhiteListRecords(
const std::vector<OnlineWhiteListRecord>& records);
- bool DeleteOnlineWhiteListForCache(int64 cache_id);
+ bool DeleteOnlineWhiteListForCache(int64_t cache_id);
- bool GetDeletableResponseIds(std::vector<int64>* response_ids,
- int64 max_rowid, int limit);
- bool InsertDeletableResponseIds(const std::vector<int64>& response_ids);
- bool DeleteDeletableResponseIds(const std::vector<int64>& response_ids);
+ bool GetDeletableResponseIds(std::vector<int64_t>* response_ids,
+ int64_t max_rowid,
+ int limit);
+ bool InsertDeletableResponseIds(const std::vector<int64_t>& response_ids);
+ bool DeleteDeletableResponseIds(const std::vector<int64_t>& response_ids);
// So our callers can wrap operations in transactions.
sql::Connection* db_connection() {
@@ -194,14 +195,14 @@ class CONTENT_EXPORT AppCacheDatabase {
}
private:
- bool RunCachedStatementWithIds(
- const sql::StatementID& statement_id, const char* sql,
- const std::vector<int64>& ids);
- bool RunUniqueStatementWithInt64Result(const char* sql, int64* result);
+ bool RunCachedStatementWithIds(const sql::StatementID& statement_id,
+ const char* sql,
+ const std::vector<int64_t>& ids);
+ bool RunUniqueStatementWithInt64Result(const char* sql, int64_t* result);
- bool FindResponseIdsForCacheHelper(
- int64 cache_id, std::vector<int64>* ids_vector,
- std::set<int64>* ids_set);
+ bool FindResponseIdsForCacheHelper(int64_t cache_id,
+ std::vector<int64_t>* ids_vector,
+ std::set<int64_t>* ids_set);
// Record retrieval helpers
void ReadGroupRecord(const sql::Statement& statement, GroupRecord* record);
@@ -234,7 +235,7 @@ class CONTENT_EXPORT AppCacheDatabase {
base::FilePath db_file_path_;
scoped_ptr<sql::Connection> db_;
scoped_ptr<sql::MetaTable> meta_table_;
- std::map<int64, base::Time> lazy_last_access_times_;
+ std::map<int64_t, base::Time> lazy_last_access_times_;
bool is_disabled_;
bool is_recreating_;
bool was_corruption_detected_;
diff --git a/chromium/content/browser/appcache/appcache_database_unittest.cc b/chromium/content/browser/appcache/appcache_database_unittest.cc
index f786df6c560..79751d99e96 100644
--- a/chromium/content/browser/appcache/appcache_database_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_database_unittest.cc
@@ -2,9 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
+#include <limits>
+
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "content/browser/appcache/appcache_database.h"
#include "content/browser/appcache/appcache_entry.h"
@@ -35,7 +40,7 @@ TEST(AppCacheDatabaseTest, LazyOpen) {
EXPECT_FALSE(db.LazyOpen(false));
EXPECT_TRUE(db.LazyOpen(true));
- int64 group_id, cache_id, response_id, deleteable_response_rowid;
+ int64_t group_id, cache_id, response_id, deleteable_response_rowid;
group_id = cache_id = response_id = deleteable_response_rowid = 0;
EXPECT_TRUE(db.FindLastStorageIds(&group_id, &cache_id, &response_id,
&deleteable_response_rowid));
@@ -135,7 +140,7 @@ TEST(AppCacheDatabaseTest, WasCorrutionDetected) {
{
sql::ScopedErrorIgnorer ignore_errors;
ignore_errors.IgnoreError(SQLITE_CORRUPT);
- std::map<GURL, int64> usage_map;
+ std::map<GURL, int64_t> usage_map;
EXPECT_FALSE(db.GetAllOriginUsage(&usage_map));
EXPECT_TRUE(db.was_corruption_detected());
EXPECT_TRUE(base::PathExists(kDbFile));
@@ -680,20 +685,22 @@ TEST(AppCacheDatabaseTest, DeletableResponseIds) {
// TODO(shess): See EntryRecords test.
ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
- std::vector<int64> ids;
+ std::vector<int64_t> ids;
- EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
+ EXPECT_TRUE(db.GetDeletableResponseIds(
+ &ids, std::numeric_limits<int64_t>::max(), 100));
EXPECT_TRUE(ids.empty());
ids.push_back(0);
EXPECT_TRUE(db.DeleteDeletableResponseIds(ids));
EXPECT_TRUE(db.InsertDeletableResponseIds(ids));
ids.clear();
- EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
+ EXPECT_TRUE(db.GetDeletableResponseIds(
+ &ids, std::numeric_limits<int64_t>::max(), 100));
EXPECT_EQ(1U, ids.size());
EXPECT_EQ(0, ids[0]);
- int64 unused, deleteable_response_rowid;
+ int64_t unused, deleteable_response_rowid;
unused = deleteable_response_rowid = 0;
EXPECT_TRUE(db.FindLastStorageIds(&unused, &unused, &unused,
&deleteable_response_rowid));
@@ -715,14 +722,16 @@ TEST(AppCacheDatabaseTest, DeletableResponseIds) {
EXPECT_EQ(10, deleteable_response_rowid);
ids.clear();
- EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
+ EXPECT_TRUE(db.GetDeletableResponseIds(
+ &ids, std::numeric_limits<int64_t>::max(), 100));
EXPECT_EQ(10U, ids.size());
for (int i = 0; i < 10; ++i)
EXPECT_EQ(i, ids[i]);
// Ensure the limit is respected.
ids.clear();
- EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 5));
+ EXPECT_TRUE(
+ db.GetDeletableResponseIds(&ids, std::numeric_limits<int64_t>::max(), 5));
EXPECT_EQ(5U, ids.size());
for (int i = 0; i < static_cast<int>(ids.size()); ++i)
EXPECT_EQ(i, ids[i]);
@@ -737,7 +746,8 @@ TEST(AppCacheDatabaseTest, DeletableResponseIds) {
// Ensure that we can delete from the table.
EXPECT_TRUE(db.DeleteDeletableResponseIds(ids));
ids.clear();
- EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
+ EXPECT_TRUE(db.GetDeletableResponseIds(
+ &ids, std::numeric_limits<int64_t>::max(), 100));
EXPECT_EQ(5U, ids.size());
for (int i = 0; i < static_cast<int>(ids.size()); ++i)
EXPECT_EQ(i + 5, ids[i]);
@@ -808,7 +818,7 @@ TEST(AppCacheDatabaseTest, OriginUsage) {
EXPECT_TRUE(db.FindCachesForOrigin(kOtherOrigin, &cache_records));
EXPECT_EQ(1U, cache_records.size());
- std::map<GURL, int64> usage_map;
+ std::map<GURL, int64_t> usage_map;
EXPECT_TRUE(db.GetAllOriginUsage(&usage_map));
EXPECT_EQ(2U, usage_map.size());
EXPECT_EQ(1100, usage_map[kOrigin]);
diff --git a/chromium/content/browser/appcache/appcache_disk_cache.cc b/chromium/content/browser/appcache/appcache_disk_cache.cc
index 8419e11c510..49030f000a9 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache.cc
+++ b/chromium/content/browser/appcache/appcache_disk_cache.cc
@@ -4,6 +4,9 @@
#include "content/browser/appcache/appcache_disk_cache.h"
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
@@ -61,11 +64,11 @@ class AppCacheDiskCache::EntryImpl : public Entry {
// Entry implementation.
int Read(int index,
- int64 offset,
+ int64_t offset,
net::IOBuffer* buf,
int buf_len,
const net::CompletionCallback& callback) override {
- if (offset < 0 || offset > kint32max)
+ if (offset < 0 || offset > std::numeric_limits<int32_t>::max())
return net::ERR_INVALID_ARGUMENT;
if (!disk_cache_entry_)
return net::ERR_ABORTED;
@@ -74,11 +77,11 @@ class AppCacheDiskCache::EntryImpl : public Entry {
}
int Write(int index,
- int64 offset,
+ int64_t offset,
net::IOBuffer* buf,
int buf_len,
const net::CompletionCallback& callback) override {
- if (offset < 0 || offset > kint32max)
+ if (offset < 0 || offset > std::numeric_limits<int32_t>::max())
return net::ERR_INVALID_ARGUMENT;
if (!disk_cache_entry_)
return net::ERR_ABORTED;
@@ -87,7 +90,7 @@ class AppCacheDiskCache::EntryImpl : public Entry {
index, static_cast<int>(offset), buf, buf_len, callback, kTruncate);
}
- int64 GetSize(int index) override {
+ int64_t GetSize(int index) override {
return disk_cache_entry_ ? disk_cache_entry_->GetDataSize(index) : 0L;
}
@@ -119,7 +122,8 @@ class AppCacheDiskCache::ActiveCall
: public base::RefCounted<AppCacheDiskCache::ActiveCall> {
public:
static int CreateEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
- int64 key, Entry** entry,
+ int64_t key,
+ Entry** entry,
const net::CompletionCallback& callback) {
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, entry, callback));
@@ -130,7 +134,8 @@ class AppCacheDiskCache::ActiveCall
}
static int OpenEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
- int64 key, Entry** entry,
+ int64_t key,
+ Entry** entry,
const net::CompletionCallback& callback) {
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, entry, callback));
@@ -141,7 +146,8 @@ class AppCacheDiskCache::ActiveCall
}
static int DoomEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
- int64 key, const net::CompletionCallback& callback) {
+ int64_t key,
+ const net::CompletionCallback& callback) {
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, nullptr, callback));
int rv = owner->disk_cache()->DoomEntry(
@@ -253,7 +259,8 @@ void AppCacheDiskCache::Disable() {
disk_cache_.reset();
}
-int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry,
+int AppCacheDiskCache::CreateEntry(int64_t key,
+ Entry** entry,
const net::CompletionCallback& callback) {
DCHECK(entry);
DCHECK(!callback.is_null());
@@ -272,7 +279,8 @@ int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry,
weak_factory_.GetWeakPtr(), key, entry, callback);
}
-int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry,
+int AppCacheDiskCache::OpenEntry(int64_t key,
+ Entry** entry,
const net::CompletionCallback& callback) {
DCHECK(entry);
DCHECK(!callback.is_null());
@@ -291,7 +299,7 @@ int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry,
weak_factory_.GetWeakPtr(), key, entry, callback);
}
-int AppCacheDiskCache::DoomEntry(int64 key,
+int AppCacheDiskCache::DoomEntry(int64_t key,
const net::CompletionCallback& callback) {
DCHECK(!callback.is_null());
if (is_disabled_)
@@ -321,15 +329,12 @@ AppCacheDiskCache::PendingCall::PendingCall()
entry(NULL) {
}
-AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type,
- int64 key,
+AppCacheDiskCache::PendingCall::PendingCall(
+ PendingCallType call_type,
+ int64_t key,
Entry** entry,
const net::CompletionCallback& callback)
- : call_type(call_type),
- key(key),
- entry(entry),
- callback(callback) {
-}
+ : call_type(call_type), key(key), entry(entry), callback(callback) {}
AppCacheDiskCache::PendingCall::~PendingCall() {}
@@ -365,7 +370,7 @@ int AppCacheDiskCache::Init(
void AppCacheDiskCache::OnCreateBackendComplete(int rv) {
if (rv == net::OK) {
- disk_cache_ = create_backend_callback_->backend_ptr_.Pass();
+ disk_cache_ = std::move(create_backend_callback_->backend_ptr_);
}
create_backend_callback_ = NULL;
diff --git a/chromium/content/browser/appcache/appcache_disk_cache.h b/chromium/content/browser/appcache/appcache_disk_cache.h
index 98ac3c0a69f..2b8c29993b4 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache.h
+++ b/chromium/content/browser/appcache/appcache_disk_cache.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_DISK_CACHE_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_DISK_CACHE_H_
+#include <stdint.h>
+
#include <set>
#include <vector>
@@ -44,13 +46,13 @@ class CONTENT_EXPORT AppCacheDiskCache
void Disable();
bool is_disabled() const { return is_disabled_; }
- int CreateEntry(int64 key,
+ int CreateEntry(int64_t key,
Entry** entry,
const net::CompletionCallback& callback) override;
- int OpenEntry(int64 key,
+ int OpenEntry(int64_t key,
Entry** entry,
const net::CompletionCallback& callback) override;
- int DoomEntry(int64 key, const net::CompletionCallback& callback) override;
+ int DoomEntry(int64_t key, const net::CompletionCallback& callback) override;
void set_is_waiting_to_initialize(bool is_waiting_to_initialize) {
is_waiting_to_initialize_ = is_waiting_to_initialize;
@@ -76,14 +78,16 @@ class CONTENT_EXPORT AppCacheDiskCache
};
struct PendingCall {
PendingCallType call_type;
- int64 key;
+ int64_t key;
Entry** entry;
net::CompletionCallback callback;
PendingCall();
- PendingCall(PendingCallType call_type, int64 key,
- Entry** entry, const net::CompletionCallback& callback);
+ PendingCall(PendingCallType call_type,
+ int64_t key,
+ Entry** entry,
+ const net::CompletionCallback& callback);
~PendingCall();
};
diff --git a/chromium/content/browser/appcache/appcache_dispatcher_host.cc b/chromium/content/browser/appcache/appcache_dispatcher_host.cc
index 6a864f7dff1..2eb90dd5189 100644
--- a/chromium/content/browser/appcache/appcache_dispatcher_host.cc
+++ b/chromium/content/browser/appcache/appcache_dispatcher_host.cc
@@ -23,7 +23,7 @@ AppCacheDispatcherHost::AppCacheDispatcherHost(
weak_factory_(this) {
}
-void AppCacheDispatcherHost::OnChannelConnected(int32 peer_pid) {
+void AppCacheDispatcherHost::OnChannelConnected(int32_t peer_pid) {
if (appcache_service_.get()) {
backend_impl_.Initialize(
appcache_service_.get(), &frontend_proxy_, process_id_);
@@ -89,8 +89,9 @@ void AppCacheDispatcherHost::OnSetSpawningHostId(
}
void AppCacheDispatcherHost::OnSelectCache(
- int host_id, const GURL& document_url,
- int64 cache_document_was_loaded_from,
+ int host_id,
+ const GURL& document_url,
+ int64_t cache_document_was_loaded_from,
const GURL& opt_manifest_url) {
if (appcache_service_.get()) {
if (!backend_impl_.SelectCache(host_id,
@@ -117,8 +118,8 @@ void AppCacheDispatcherHost::OnSelectCacheForWorker(
}
}
-void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(
- int host_id, int64 appcache_id) {
+void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(int host_id,
+ int64_t appcache_id) {
if (appcache_service_.get()) {
if (!backend_impl_.SelectCacheForSharedWorker(host_id, appcache_id))
bad_message::ReceivedBadMessage(
@@ -129,8 +130,9 @@ void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(
}
void AppCacheDispatcherHost::OnMarkAsForeignEntry(
- int host_id, const GURL& document_url,
- int64 cache_document_was_loaded_from) {
+ int host_id,
+ const GURL& document_url,
+ int64_t cache_document_was_loaded_from) {
if (appcache_service_.get()) {
if (!backend_impl_.MarkAsForeignEntry(
host_id, document_url, cache_document_was_loaded_from)) {
diff --git a/chromium/content/browser/appcache/appcache_dispatcher_host.h b/chromium/content/browser/appcache/appcache_dispatcher_host.h
index f8909a88125..4181b4398eb 100644
--- a/chromium/content/browser/appcache/appcache_dispatcher_host.h
+++ b/chromium/content/browser/appcache/appcache_dispatcher_host.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_DISPATCHER_HOST_H_
+#include <stdint.h>
+
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -28,7 +31,7 @@ class AppCacheDispatcherHost : public BrowserMessageFilter {
int process_id);
// BrowserIOMessageFilter implementation
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
bool OnMessageReceived(const IPC::Message& message) override;
protected:
@@ -39,14 +42,16 @@ class AppCacheDispatcherHost : public BrowserMessageFilter {
void OnRegisterHost(int host_id);
void OnUnregisterHost(int host_id);
void OnSetSpawningHostId(int host_id, int spawning_host_id);
- void OnSelectCache(int host_id, const GURL& document_url,
- int64 cache_document_was_loaded_from,
+ void OnSelectCache(int host_id,
+ const GURL& document_url,
+ int64_t cache_document_was_loaded_from,
const GURL& opt_manifest_url);
void OnSelectCacheForWorker(int host_id, int parent_process_id,
int parent_host_id);
- void OnSelectCacheForSharedWorker(int host_id, int64 appcache_id);
- void OnMarkAsForeignEntry(int host_id, const GURL& document_url,
- int64 cache_document_was_loaded_from);
+ void OnSelectCacheForSharedWorker(int host_id, int64_t appcache_id);
+ void OnMarkAsForeignEntry(int host_id,
+ const GURL& document_url,
+ int64_t cache_document_was_loaded_from);
void OnGetStatus(int host_id, IPC::Message* reply_msg);
void OnStartUpdate(int host_id, IPC::Message* reply_msg);
void OnSwapCache(int host_id, IPC::Message* reply_msg);
diff --git a/chromium/content/browser/appcache/appcache_entry.h b/chromium/content/browser/appcache/appcache_entry.h
index 7aaf42581ea..3c3b89ea772 100644
--- a/chromium/content/browser/appcache/appcache_entry.h
+++ b/chromium/content/browser/appcache/appcache_entry.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_ENTRY_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_ENTRY_H_
+#include <stdint.h>
+
#include "content/common/appcache_interfaces.h"
namespace content {
@@ -33,11 +35,13 @@ class AppCacheEntry {
explicit AppCacheEntry(int type)
: types_(type), response_id_(kAppCacheNoResponseId), response_size_(0) {}
- AppCacheEntry(int type, int64 response_id)
- : types_(type), response_id_(response_id), response_size_(0) {}
+ AppCacheEntry(int type, int64_t response_id)
+ : types_(type), response_id_(response_id), response_size_(0) {}
- AppCacheEntry(int type, int64 response_id, int64 response_size)
- : types_(type), response_id_(response_id), response_size_(response_size) {}
+ AppCacheEntry(int type, int64_t response_id, int64_t response_size)
+ : types_(type),
+ response_id_(response_id),
+ response_size_(response_size) {}
int types() const { return types_; }
void add_types(int added_types) { types_ |= added_types; }
@@ -49,17 +53,17 @@ class AppCacheEntry {
bool IsIntercept() const { return (types_ & INTERCEPT) != 0; }
bool IsExecutable() const { return (types_ & EXECUTABLE) != 0; }
- int64 response_id() const { return response_id_; }
- void set_response_id(int64 id) { response_id_ = id; }
+ int64_t response_id() const { return response_id_; }
+ void set_response_id(int64_t id) { response_id_ = id; }
bool has_response_id() const { return response_id_ != kAppCacheNoResponseId; }
- int64 response_size() const { return response_size_; }
- void set_response_size(int64 size) { response_size_ = size; }
+ int64_t response_size() const { return response_size_; }
+ void set_response_size(int64_t size) { response_size_ = size; }
private:
int types_;
- int64 response_id_;
- int64 response_size_;
+ int64_t response_id_;
+ int64_t response_size_;
};
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_group.cc b/chromium/content/browser/appcache/appcache_group.cc
index 86660c2b113..8efd709cd9b 100644
--- a/chromium/content/browser/appcache/appcache_group.cc
+++ b/chromium/content/browser/appcache/appcache_group.cc
@@ -40,7 +40,7 @@ class AppCacheGroup::HostObserver : public AppCacheHost::Observer {
AppCacheGroup::AppCacheGroup(AppCacheStorage* storage,
const GURL& manifest_url,
- int64 group_id)
+ int64_t group_id)
: group_id_(group_id),
manifest_url_(manifest_url),
update_status_(IDLE),
@@ -137,7 +137,7 @@ void AppCacheGroup::RemoveCache(AppCache* cache) {
}
void AppCacheGroup::AddNewlyDeletableResponseIds(
- std::vector<int64>* response_ids) {
+ std::vector<int64_t>* response_ids) {
if (is_being_deleted() || (!is_obsolete() && old_caches_.empty())) {
storage_->DeleteResponses(manifest_url_, *response_ids);
response_ids->clear();
diff --git a/chromium/content/browser/appcache/appcache_group.h b/chromium/content/browser/appcache/appcache_group.h
index be29635bcaa..626deb7b0c3 100644
--- a/chromium/content/browser/appcache/appcache_group.h
+++ b/chromium/content/browser/appcache/appcache_group.h
@@ -5,12 +5,15 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_GROUP_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_GROUP_H_
+#include <stdint.h>
+
#include <map>
#include <utility>
#include <vector>
#include "base/cancelable_callback.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
@@ -51,15 +54,16 @@ class CONTENT_EXPORT AppCacheGroup
DOWNLOADING,
};
- AppCacheGroup(AppCacheStorage* storage, const GURL& manifest_url,
- int64 group_id);
+ AppCacheGroup(AppCacheStorage* storage,
+ const GURL& manifest_url,
+ int64_t group_id);
// Adds/removes an update observer, the AppCacheGroup does not take
// ownership of the observer.
void AddUpdateObserver(UpdateObserver* observer);
void RemoveUpdateObserver(UpdateObserver* observer);
- int64 group_id() const { return group_id_; }
+ int64_t group_id() const { return group_id_; }
const GURL& manifest_url() const { return manifest_url_; }
base::Time creation_time() const { return creation_time_; }
void set_creation_time(base::Time time) { creation_time_ = time; }
@@ -86,7 +90,7 @@ class CONTENT_EXPORT AppCacheGroup
void RemoveCache(AppCache* cache);
bool HasCache() const { return newest_complete_cache_ != NULL; }
- void AddNewlyDeletableResponseIds(std::vector<int64>* response_ids);
+ void AddNewlyDeletableResponseIds(std::vector<int64_t>* response_ids);
UpdateAppCacheStatus update_status() const { return update_status_; }
@@ -141,13 +145,13 @@ class CONTENT_EXPORT AppCacheGroup
void ScheduleUpdateRestart(int delay_ms);
void HostDestructionImminent(AppCacheHost* host);
- const int64 group_id_;
+ const int64_t group_id_;
const GURL manifest_url_;
base::Time creation_time_;
UpdateAppCacheStatus update_status_;
bool is_obsolete_;
bool is_being_deleted_;
- std::vector<int64> newly_deletable_response_ids_;
+ std::vector<int64_t> newly_deletable_response_ids_;
// Most update checks respect the cache control headers of the manifest
// resource, but we bypass the http cache for a "full" update check after 24
diff --git a/chromium/content/browser/appcache/appcache_group_unittest.cc b/chromium/content/browser/appcache/appcache_group_unittest.cc
index 64e321d5525..180e522c9a4 100644
--- a/chromium/content/browser/appcache/appcache_group_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_group_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <string>
#include "base/message_loop/message_loop.h"
@@ -51,7 +53,7 @@ class TestAppCacheFrontend : public content::AppCacheFrontend {
void OnContentBlocked(int host_id, const GURL& manifest_url) override {}
int last_host_id_;
- int64 last_cache_id_;
+ int64_t last_cache_id_;
content::AppCacheStatus last_status_;
};
diff --git a/chromium/content/browser/appcache/appcache_histograms.h b/chromium/content/browser/appcache/appcache_histograms.h
index 0fcc54cf65f..57ba1f85d02 100644
--- a/chromium/content/browser/appcache/appcache_histograms.h
+++ b/chromium/content/browser/appcache/appcache_histograms.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_HISTOGRAMS_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_HISTOGRAMS_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "content/browser/appcache/appcache_update_job.h"
namespace base {
diff --git a/chromium/content/browser/appcache/appcache_host.cc b/chromium/content/browser/appcache/appcache_host.cc
index 9ec45f6174f..697b2bdf8d0 100644
--- a/chromium/content/browser/appcache/appcache_host.cc
+++ b/chromium/content/browser/appcache/appcache_host.cc
@@ -81,7 +81,7 @@ void AppCacheHost::RemoveObserver(Observer* observer) {
}
bool AppCacheHost::SelectCache(const GURL& document_url,
- const int64 cache_document_was_loaded_from,
+ const int64_t cache_document_was_loaded_from,
const GURL& manifest_url) {
if (was_select_cache_called_)
return false;
@@ -170,7 +170,7 @@ bool AppCacheHost::SelectCacheForWorker(int parent_process_id,
return true;
}
-bool AppCacheHost::SelectCacheForSharedWorker(int64 appcache_id) {
+bool AppCacheHost::SelectCacheForSharedWorker(int64_t appcache_id) {
if (was_select_cache_called_)
return false;
@@ -190,7 +190,7 @@ bool AppCacheHost::SelectCacheForSharedWorker(int64 appcache_id) {
// TODO(michaeln): change method name to MarkEntryAsForeign for consistency
bool AppCacheHost::MarkAsForeignEntry(const GURL& document_url,
- int64 cache_document_was_loaded_from) {
+ int64_t cache_document_was_loaded_from) {
if (was_select_cache_called_)
return false;
@@ -378,13 +378,13 @@ void AppCacheHost::OnGroupLoaded(AppCacheGroup* group,
FinishCacheSelection(NULL, group);
}
-void AppCacheHost::LoadSelectedCache(int64 cache_id) {
+void AppCacheHost::LoadSelectedCache(int64_t cache_id) {
DCHECK(cache_id != kAppCacheNoCacheId);
pending_selected_cache_id_ = cache_id;
storage()->LoadCache(cache_id, this);
}
-void AppCacheHost::OnCacheLoaded(AppCache* cache, int64 cache_id) {
+void AppCacheHost::OnCacheLoaded(AppCache* cache, int64_t cache_id) {
if (cache_id == pending_main_resource_cache_id_) {
pending_main_resource_cache_id_ = kAppCacheNoCacheId;
main_resource_cache_ = cache;
@@ -503,7 +503,7 @@ void AppCacheHost::SetSwappableCache(AppCacheGroup* group) {
}
}
-void AppCacheHost::LoadMainResourceCache(int64 cache_id) {
+void AppCacheHost::LoadMainResourceCache(int64_t cache_id) {
DCHECK(cache_id != kAppCacheNoCacheId);
if (pending_main_resource_cache_id_ == cache_id ||
(main_resource_cache_.get() &&
diff --git a/chromium/content/browser/appcache/appcache_host.h b/chromium/content/browser/appcache/appcache_host.h
index 3818f30683e..c5103c2db7f 100644
--- a/chromium/content/browser/appcache/appcache_host.h
+++ b/chromium/content/browser/appcache/appcache_host.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_HOST_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_HOST_H_
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "content/browser/appcache/appcache_group.h"
@@ -78,13 +81,13 @@ class CONTENT_EXPORT AppCacheHost
// Support for cache selection and scriptable method calls.
bool SelectCache(const GURL& document_url,
- const int64 cache_document_was_loaded_from,
+ const int64_t cache_document_was_loaded_from,
const GURL& manifest_url);
bool SelectCacheForWorker(int parent_process_id,
int parent_host_id);
- bool SelectCacheForSharedWorker(int64 appcache_id);
+ bool SelectCacheForSharedWorker(int64_t appcache_id);
bool MarkAsForeignEntry(const GURL& document_url,
- int64 cache_document_was_loaded_from);
+ int64_t cache_document_was_loaded_from);
void GetStatusWithCallback(const GetStatusCallback& callback,
void* callback_param);
void StartUpdateWithCallback(const StartUpdateCallback& callback,
@@ -143,7 +146,7 @@ class CONTENT_EXPORT AppCacheHost
void SetSwappableCache(AppCacheGroup* group);
// Used to ensure that a loaded appcache survives a frame navigation.
- void LoadMainResourceCache(int64 cache_id);
+ void LoadMainResourceCache(int64_t cache_id);
// Used to notify the host that a namespace resource is being delivered as
// the main resource of the page and to provide its url.
@@ -187,14 +190,14 @@ class CONTENT_EXPORT AppCacheHost
friend class content::AppCacheUpdateJobTest;
AppCacheStatus GetStatus();
- void LoadSelectedCache(int64 cache_id);
+ void LoadSelectedCache(int64_t cache_id);
void LoadOrCreateGroup(const GURL& manifest_url);
// See public Associate*Host() methods above.
void AssociateCacheHelper(AppCache* cache, const GURL& manifest_url);
// AppCacheStorage::Delegate impl
- void OnCacheLoaded(AppCache* cache, int64 cache_id) override;
+ void OnCacheLoaded(AppCache* cache, int64_t cache_id) override;
void OnGroupLoaded(AppCacheGroup* group, const GURL& manifest_url) override;
// AppCacheServiceImpl::Observer impl
void OnServiceReinitialized(
@@ -262,12 +265,12 @@ class CONTENT_EXPORT AppCacheHost
// Keep a reference to the cache of the main resource so it survives frame
// navigations.
scoped_refptr<AppCache> main_resource_cache_;
- int64 pending_main_resource_cache_id_;
+ int64_t pending_main_resource_cache_id_;
// Cache loading is async, if we're loading a specific cache or group
// for the purposes of cache selection, one or the other of these will
// indicate which cache or group is being loaded.
- int64 pending_selected_cache_id_;
+ int64_t pending_selected_cache_id_;
GURL pending_selected_manifest_url_;
// Used to defend against bad IPC messages.
diff --git a/chromium/content/browser/appcache/appcache_host_unittest.cc b/chromium/content/browser/appcache/appcache_host_unittest.cc
index 255bfa9ab5b..ee935c1b508 100644
--- a/chromium/content/browser/appcache/appcache_host_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_host_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/scoped_ptr.h"
@@ -79,7 +81,7 @@ class AppCacheHostTest : public testing::Test {
}
int last_host_id_;
- int64 last_cache_id_;
+ int64_t last_cache_id_;
AppCacheStatus last_status_;
AppCacheStatus last_status_changed_;
AppCacheEventID last_event_id_;
@@ -98,7 +100,7 @@ class AppCacheHostTest : public testing::Test {
void NotifyStorageModified(storage::QuotaClient::ID client_id,
const GURL& origin,
storage::StorageType type,
- int64 delta) override {}
+ int64_t delta) override {}
void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
const GURL& origin,
storage::StorageType type,
diff --git a/chromium/content/browser/appcache/appcache_interceptor.cc b/chromium/content/browser/appcache/appcache_interceptor.cc
index 4ca2c6998e7..81985fe704a 100644
--- a/chromium/content/browser/appcache/appcache_interceptor.cc
+++ b/chromium/content/browser/appcache/appcache_interceptor.cc
@@ -55,7 +55,7 @@ void AppCacheInterceptor::SetExtraRequestInfo(
}
void AppCacheInterceptor::GetExtraResponseInfo(net::URLRequest* request,
- int64* cache_id,
+ int64_t* cache_id,
GURL* manifest_url) {
DCHECK(*cache_id == kAppCacheNoCacheId);
DCHECK(manifest_url->is_empty());
diff --git a/chromium/content/browser/appcache/appcache_interceptor.h b/chromium/content/browser/appcache/appcache_interceptor.h
index be8110daabb..0e50983ba21 100644
--- a/chromium/content/browser/appcache/appcache_interceptor.h
+++ b/chromium/content/browser/appcache/appcache_interceptor.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_INTERCEPTOR_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_INTERCEPTOR_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
#include "net/url_request/url_request_interceptor.h"
@@ -35,7 +37,7 @@ class CONTENT_EXPORT AppCacheInterceptor : public net::URLRequestInterceptor {
// May be called after response headers are complete to retrieve extra
// info about the response.
static void GetExtraResponseInfo(net::URLRequest* request,
- int64* cache_id,
+ int64_t* cache_id,
GURL* manifest_url);
// Methods to support cross site navigations.
diff --git a/chromium/content/browser/appcache/appcache_internals_ui.cc b/chromium/content/browser/appcache/appcache_internals_ui.cc
index dfd06b167bd..3abd692603a 100644
--- a/chromium/content/browser/appcache/appcache_internals_ui.cc
+++ b/chromium/content/browser/appcache/appcache_internals_ui.cc
@@ -4,6 +4,8 @@
#include "content/browser/appcache/appcache_internals_ui.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
@@ -42,8 +44,8 @@ const char kFunctionOnAppCacheDetailsReady[] =
const char kFunctionOnFileDetailsReady[] = "appcache.onFileDetailsReady";
const char kFunctionOnFileDetailsFailed[] = "appcache.onFileDetailsFailed";
-int64 ToInt64(const std::string& str) {
- int64 i = 0;
+int64_t ToInt64(const std::string& str) {
+ int64_t i = 0;
base::StringToInt64(str.c_str(), &i);
return i;
}
@@ -271,7 +273,7 @@ void AppCacheInternalsUI::Proxy::HandleFileDetailsRequest() {
void AppCacheInternalsUI::Proxy::OnResponseInfoLoaded(
AppCacheResponseInfo* response,
- int64 response_id) {
+ int64_t response_id) {
if (shutdown_called_)
return;
if (!appcache_service_)
@@ -280,8 +282,8 @@ void AppCacheInternalsUI::Proxy::OnResponseInfoLoaded(
response_enquiries_.pop_front();
if (response) {
scoped_refptr<AppCacheResponseInfo> response_info = response;
- const int64 kLimit = 100 * 1000;
- int64 amount_to_read =
+ const int64_t kLimit = 100 * 1000;
+ int64_t amount_to_read =
std::min(kLimit, response_info->response_data_size());
scoped_refptr<net::IOBuffer> response_data(new net::IOBuffer(
base::CheckedNumeric<size_t>(amount_to_read).ValueOrDie()));
diff --git a/chromium/content/browser/appcache/appcache_internals_ui.h b/chromium/content/browser/appcache/appcache_internals_ui.h
index 3b2ddfa3f07..f5498dbc285 100644
--- a/chromium/content/browser/appcache/appcache_internals_ui.h
+++ b/chromium/content/browser/appcache/appcache_internals_ui.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_INTERNALS_UI_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_INTERNALS_UI_H_
+#include <stdint.h>
+
#include <list>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/appcache/appcache_group.h"
@@ -40,8 +43,8 @@ class AppCacheInternalsUI : public WebUIController {
struct ResponseEnquiry {
std::string manifest_url;
- int64 group_id;
- int64 response_id;
+ int64_t group_id;
+ int64_t response_id;
};
private:
@@ -64,7 +67,7 @@ class AppCacheInternalsUI : public WebUIController {
void OnGroupLoaded(AppCacheGroup* appcache_group,
const GURL& manifest_gurl) override;
void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
- int64 response_id) override;
+ int64_t response_id) override;
void OnResponseDataReadComplete(
const ResponseEnquiry& response_enquiry,
scoped_refptr<AppCacheResponseInfo> response_info,
diff --git a/chromium/content/browser/appcache/appcache_manifest_parser.cc b/chromium/content/browser/appcache/appcache_manifest_parser.cc
index bf936c23ebc..8189858a1c6 100644
--- a/chromium/content/browser/appcache/appcache_manifest_parser.cc
+++ b/chromium/content/browser/appcache/appcache_manifest_parser.cc
@@ -31,9 +31,12 @@
#include "content/browser/appcache/appcache_manifest_parser.h"
+#include <stddef.h>
+
#include "base/command_line.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "url/gurl.h"
diff --git a/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc b/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc
index 6dd8c279121..4f3d2f4cd2a 100644
--- a/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <string>
+#include "base/macros.h"
#include "content/browser/appcache/appcache_manifest_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
diff --git a/chromium/content/browser/appcache/appcache_quota_client.h b/chromium/content/browser/appcache/appcache_quota_client.h
index e5c12510fc5..d55283180b0 100644
--- a/chromium/content/browser/appcache/appcache_quota_client.h
+++ b/chromium/content/browser/appcache/appcache_quota_client.h
@@ -9,6 +9,7 @@
#include <map>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/appcache/appcache_storage.h"
diff --git a/chromium/content/browser/appcache/appcache_quota_client_unittest.cc b/chromium/content/browser/appcache/appcache_quota_client_unittest.cc
index de17324034f..a9e1be03ef1 100644
--- a/chromium/content/browser/appcache/appcache_quota_client_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_quota_client_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <map>
#include <set>
@@ -36,9 +38,9 @@ class AppCacheQuotaClientTest : public testing::Test {
num_delete_origins_completions_(0),
weak_factory_(this) {}
- int64 GetOriginUsage(storage::QuotaClient* client,
- const GURL& origin,
- storage::StorageType type) {
+ int64_t GetOriginUsage(storage::QuotaClient* client,
+ const GURL& origin,
+ storage::StorageType type) {
usage_ = -1;
AsyncGetOriginUsage(client, origin, type);
base::RunLoop().RunUntilIdle();
@@ -106,7 +108,7 @@ class AppCacheQuotaClientTest : public testing::Test {
weak_factory_.GetWeakPtr()));
}
- void SetUsageMapEntry(const GURL& origin, int64 usage) {
+ void SetUsageMapEntry(const GURL& origin, int64_t usage) {
mock_service_.storage()->usage_map_[origin] = usage;
}
@@ -127,7 +129,7 @@ class AppCacheQuotaClientTest : public testing::Test {
}
protected:
- void OnGetOriginUsageComplete(int64 usage) {
+ void OnGetOriginUsageComplete(int64_t usage) {
++num_get_origin_usage_completions_;
usage_ = usage;
}
@@ -143,7 +145,7 @@ class AppCacheQuotaClientTest : public testing::Test {
}
base::MessageLoop message_loop_;
- int64 usage_;
+ int64_t usage_;
std::set<GURL> origins_;
storage::QuotaStatusCode delete_status_;
int num_get_origin_usage_completions_;
diff --git a/chromium/content/browser/appcache/appcache_request_handler.cc b/chromium/content/browser/appcache/appcache_request_handler.cc
index bcfbe35cfb0..c02223752af 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler.cc
@@ -4,6 +4,9 @@
#include "content/browser/appcache/appcache_request_handler.h"
+#include <utility>
+
+#include "base/bind.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_backend_impl.h"
#include "content/browser/appcache/appcache_policy.h"
@@ -25,9 +28,11 @@ AppCacheRequestHandler::AppCacheRequestHandler(AppCacheHost* host,
found_cache_id_(0),
found_network_namespace_(false),
cache_entry_not_found_(false),
+ is_delivering_network_response_(false),
maybe_load_resource_executed_(false),
old_process_id_(0),
- old_host_id_(kAppCacheNoHostId) {
+ old_host_id_(kAppCacheNoHostId),
+ cache_id_(kAppCacheNoCacheId) {
DCHECK(host_);
host_->AddObserver(this);
}
@@ -45,26 +50,23 @@ AppCacheStorage* AppCacheRequestHandler::storage() const {
}
AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadResource(
- net::URLRequest* request, net::NetworkDelegate* network_delegate) {
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) {
maybe_load_resource_executed_ = true;
if (!host_ || !IsSchemeAndMethodSupportedForAppCache(request) ||
- cache_entry_not_found_)
+ cache_entry_not_found_) {
return NULL;
+ }
// This method can get called multiple times over the life
// of a request. The case we detect here is having scheduled
- // delivery of a "network response" using a job setup on an
- // earlier call thru this method. To send the request thru
+ // delivery of a "network response" using a job set up on an
+ // earlier call through this method. To send the request through
// to the network involves restarting the request altogether,
- // which will call thru to our interception layer again.
- // This time thru, we return NULL so the request hits the wire.
- if (job_.get()) {
- DCHECK(job_->is_delivering_network_response() ||
- job_->cache_entry_not_found());
- if (job_->cache_entry_not_found())
- cache_entry_not_found_ = true;
- job_ = NULL;
- storage()->CancelDelegateCallbacks(this);
+ // which will call through to our interception layer again.
+ // This time through, we return NULL so the request hits the wire.
+ if (is_delivering_network_response_) {
+ is_delivering_network_response_ = false;
return NULL;
}
@@ -76,20 +78,21 @@ AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadResource(
found_manifest_url_ = GURL();
found_network_namespace_ = false;
+ scoped_ptr<AppCacheURLRequestJob> job;
if (is_main_resource())
- MaybeLoadMainResource(request, network_delegate);
+ job = MaybeLoadMainResource(request, network_delegate);
else
- MaybeLoadSubResource(request, network_delegate);
+ job = MaybeLoadSubResource(request, network_delegate);
// If its been setup to deliver a network response, we can just delete
// it now and return NULL instead to achieve that since it couldn't
// have been started yet.
- if (job_.get() && job_->is_delivering_network_response()) {
- DCHECK(!job_->has_been_started());
- job_ = NULL;
+ if (job && job->is_delivering_network_response()) {
+ DCHECK(!job->has_been_started());
+ job.reset();
}
- return job_.get();
+ return job.release();
}
AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect(
@@ -110,28 +113,28 @@ AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect(
DCHECK(!job_.get()); // our jobs never generate redirects
+ scoped_ptr<AppCacheURLRequestJob> job;
if (found_fallback_entry_.has_response_id()) {
// 6.9.6, step 4: If this results in a redirect to another origin,
// get the resource of the fallback entry.
- job_ = new AppCacheURLRequestJob(request, network_delegate,
- storage(), host_, is_main_resource());
+ job = CreateJob(request, network_delegate);
DeliverAppCachedResponse(
found_fallback_entry_, found_cache_id_, found_group_id_,
found_manifest_url_, true, found_namespace_entry_url_);
} else if (!found_network_namespace_) {
// 6.9.6, step 6: Fail the resource load.
- job_ = new AppCacheURLRequestJob(request, network_delegate,
- storage(), host_, is_main_resource());
+ job = CreateJob(request, network_delegate);
DeliverErrorResponse();
} else {
// 6.9.6 step 3 and 5: Fetch the resource normally.
}
- return job_.get();
+ return job.release();
}
AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse(
- net::URLRequest* request, net::NetworkDelegate* network_delegate) {
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) {
if (!host_ || !IsSchemeAndMethodSupportedForAppCache(request) ||
cache_entry_not_found_)
return NULL;
@@ -167,20 +170,17 @@ AppCacheURLRequestJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse(
// 6.9.6, step 4: If this results in a 4xx or 5xx status code
// or there were network errors, get the resource of the fallback entry.
- job_ = new AppCacheURLRequestJob(request, network_delegate,
- storage(), host_, is_main_resource());
+ scoped_ptr<AppCacheURLRequestJob> job = CreateJob(request, network_delegate);
DeliverAppCachedResponse(
found_fallback_entry_, found_cache_id_, found_group_id_,
found_manifest_url_, true, found_namespace_entry_url_);
- return job_.get();
+ return job.release();
}
-void AppCacheRequestHandler::GetExtraResponseInfo(
- int64* cache_id, GURL* manifest_url) {
- if (job_.get() && job_->is_delivering_appcache_response()) {
- *cache_id = job_->cache_id();
- *manifest_url = job_->manifest_url();
- }
+void AppCacheRequestHandler::GetExtraResponseInfo(int64_t* cache_id,
+ GURL* manifest_url) {
+ *cache_id = cache_id_;
+ *manifest_url = manifest_url_;
}
void AppCacheRequestHandler::PrepareForCrossSiteTransfer(int old_process_id) {
@@ -199,7 +199,8 @@ void AppCacheRequestHandler::CompleteCrossSiteTransfer(
return;
DCHECK_EQ(host_, host_for_cross_site_transfer_.get());
AppCacheBackendImpl* backend = host_->service()->GetBackend(new_process_id);
- backend->TransferHostIn(new_host_id, host_for_cross_site_transfer_.Pass());
+ backend->TransferHostIn(new_host_id,
+ std::move(host_for_cross_site_transfer_));
}
void AppCacheRequestHandler::MaybeCompleteCrossSiteTransferInOldProcess(
@@ -219,17 +220,24 @@ void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) {
// that is current running. It's destined for the bit bucket anyway.
if (job_.get()) {
job_->Kill();
- job_ = NULL;
+ job_.reset();
}
}
void AppCacheRequestHandler::DeliverAppCachedResponse(
- const AppCacheEntry& entry, int64 cache_id, int64 group_id,
- const GURL& manifest_url, bool is_fallback,
+ const AppCacheEntry& entry,
+ int64_t cache_id,
+ int64_t group_id,
+ const GURL& manifest_url,
+ bool is_fallback,
const GURL& namespace_entry_url) {
DCHECK(host_ && job_.get() && job_->is_waiting());
DCHECK(entry.has_response_id());
+ // Cache information about the response, for use by GetExtraResponseInfo.
+ cache_id_ = cache_id;
+ manifest_url_ = manifest_url;
+
if (IsResourceTypeFrame(resource_type_) && !namespace_entry_url.is_empty())
host_->NotifyMainResourceIsNamespaceEntry(namespace_entry_url);
@@ -239,18 +247,50 @@ void AppCacheRequestHandler::DeliverAppCachedResponse(
void AppCacheRequestHandler::DeliverErrorResponse() {
DCHECK(job_.get() && job_->is_waiting());
+ DCHECK_EQ(kAppCacheNoCacheId, cache_id_);
+ DCHECK(manifest_url_.is_empty());
job_->DeliverErrorResponse();
}
void AppCacheRequestHandler::DeliverNetworkResponse() {
DCHECK(job_.get() && job_->is_waiting());
+ DCHECK_EQ(kAppCacheNoCacheId, cache_id_);
+ DCHECK(manifest_url_.is_empty());
job_->DeliverNetworkResponse();
}
+void AppCacheRequestHandler::OnPrepareToRestart() {
+ DCHECK(job_->is_delivering_network_response() ||
+ job_->cache_entry_not_found());
+
+ // Any information about the source of the response is no longer relevant.
+ cache_id_ = kAppCacheNoCacheId;
+ manifest_url_ = GURL();
+
+ cache_entry_not_found_ = job_->cache_entry_not_found();
+ is_delivering_network_response_ = job_->is_delivering_network_response();
+
+ storage()->CancelDelegateCallbacks(this);
+
+ job_.reset();
+}
+
+scoped_ptr<AppCacheURLRequestJob> AppCacheRequestHandler::CreateJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) {
+ scoped_ptr<AppCacheURLRequestJob> job(new AppCacheURLRequestJob(
+ request, network_delegate, storage(), host_, is_main_resource(),
+ base::Bind(&AppCacheRequestHandler::OnPrepareToRestart,
+ base::Unretained(this))));
+ job_ = job->GetWeakPtr();
+ return job;
+}
+
// Main-resource handling ----------------------------------------------
-void AppCacheRequestHandler::MaybeLoadMainResource(
- net::URLRequest* request, net::NetworkDelegate* network_delegate) {
+scoped_ptr<AppCacheURLRequestJob> AppCacheRequestHandler::MaybeLoadMainResource(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) {
DCHECK(!job_.get());
DCHECK(host_);
@@ -259,7 +299,7 @@ void AppCacheRequestHandler::MaybeLoadMainResource(
// prior to the AppCache handler.
if (ServiceWorkerRequestHandler::IsControlledByServiceWorker(request)) {
host_->enable_cache_selection(false);
- return;
+ return nullptr;
}
host_->enable_cache_selection(true);
@@ -272,23 +312,28 @@ void AppCacheRequestHandler::MaybeLoadMainResource(
// We may have to wait for our storage query to complete, but
// this query can also complete syncrhonously.
- job_ = new AppCacheURLRequestJob(request, network_delegate,
- storage(), host_, is_main_resource());
+ scoped_ptr<AppCacheURLRequestJob> job = CreateJob(request, network_delegate);
storage()->FindResponseForMainRequest(
request->url(), preferred_manifest_url, this);
+ return job;
}
void AppCacheRequestHandler::OnMainResponseFound(
- const GURL& url, const AppCacheEntry& entry,
- const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry,
- int64 cache_id, int64 group_id, const GURL& manifest_url) {
- DCHECK(job_.get());
+ const GURL& url,
+ const AppCacheEntry& entry,
+ const GURL& namespace_entry_url,
+ const AppCacheEntry& fallback_entry,
+ int64_t cache_id,
+ int64_t group_id,
+ const GURL& manifest_url) {
DCHECK(host_);
DCHECK(is_main_resource());
DCHECK(!entry.IsForeign());
DCHECK(!fallback_entry.IsForeign());
DCHECK(!(entry.has_response_id() && fallback_entry.has_response_id()));
+ // Request may have been canceled, but not yet deleted, while waiting on
+ // the cache.
if (!job_.get())
return;
@@ -345,28 +390,27 @@ void AppCacheRequestHandler::OnMainResponseFound(
// Sub-resource handling ----------------------------------------------
-void AppCacheRequestHandler::MaybeLoadSubResource(
- net::URLRequest* request, net::NetworkDelegate* network_delegate) {
+scoped_ptr<AppCacheURLRequestJob> AppCacheRequestHandler::MaybeLoadSubResource(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) {
DCHECK(!job_.get());
if (host_->is_selection_pending()) {
// We have to wait until cache selection is complete and the
// selected cache is loaded.
is_waiting_for_cache_selection_ = true;
- job_ = new AppCacheURLRequestJob(request, network_delegate,
- storage(), host_, is_main_resource());
- return;
+ return CreateJob(request, network_delegate);
}
if (!host_->associated_cache() ||
!host_->associated_cache()->is_complete() ||
host_->associated_cache()->owning_group()->is_being_deleted()) {
- return;
+ return nullptr;
}
- job_ = new AppCacheURLRequestJob(request, network_delegate,
- storage(), host_, is_main_resource());
+ scoped_ptr<AppCacheURLRequestJob> job = CreateJob(request, network_delegate);
ContinueMaybeLoadSubResource();
+ return job;
}
void AppCacheRequestHandler::ContinueMaybeLoadSubResource() {
@@ -420,6 +464,12 @@ void AppCacheRequestHandler::ContinueMaybeLoadSubResource() {
void AppCacheRequestHandler::OnCacheSelectionComplete(AppCacheHost* host) {
DCHECK(host == host_);
+
+ // Request may have been canceled, but not yet deleted, while waiting on
+ // the cache.
+ if (!job_.get())
+ return;
+
if (is_main_resource())
return;
if (!is_waiting_for_cache_selection_)
diff --git a/chromium/content/browser/appcache/appcache_request_handler.h b/chromium/content/browser/appcache/appcache_request_handler.h
index 81acd85d0d3..d7b55e5a96b 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.h
+++ b/chromium/content/browser/appcache/appcache_request_handler.h
@@ -5,7 +5,12 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_REQUEST_HANDLER_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_REQUEST_HANDLER_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "content/browser/appcache/appcache_entry.h"
#include "content/browser/appcache/appcache_host.h"
@@ -36,15 +41,17 @@ class CONTENT_EXPORT AppCacheRequestHandler
// These are called on each request intercept opportunity.
AppCacheURLRequestJob* MaybeLoadResource(
- net::URLRequest* request, net::NetworkDelegate* network_delegate);
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate);
AppCacheURLRequestJob* MaybeLoadFallbackForRedirect(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const GURL& location);
AppCacheURLRequestJob* MaybeLoadFallbackForResponse(
- net::URLRequest* request, net::NetworkDelegate* network_delegate);
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate);
- void GetExtraResponseInfo(int64* cache_id, GURL* manifest_url);
+ void GetExtraResponseInfo(int64_t* cache_id, GURL* manifest_url);
// Methods to support cross site navigations.
void PrepareForCrossSiteTransfer(int old_process_id);
@@ -68,13 +75,25 @@ class CONTENT_EXPORT AppCacheRequestHandler
// Helpers to instruct a waiting job with what response to
// deliver for the request we're handling.
- void DeliverAppCachedResponse(const AppCacheEntry& entry, int64 cache_id,
- int64 group_id, const GURL& manifest_url,
+ void DeliverAppCachedResponse(const AppCacheEntry& entry,
+ int64_t cache_id,
+ int64_t group_id,
+ const GURL& manifest_url,
bool is_fallback,
const GURL& namespace_entry_url);
void DeliverNetworkResponse();
void DeliverErrorResponse();
+ // Called just before the request is restarted. Grabs the reason for
+ // restarting, so can correctly continue to handle the request.
+ void OnPrepareToRestart();
+
+ // Helper method to create an AppCacheURLRequestJob and populate job_.
+ // Caller takes ownership of returned value.
+ scoped_ptr<AppCacheURLRequestJob> CreateJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate);
+
// Helper to retrieve a pointer to the storage object.
AppCacheStorage* storage() const;
@@ -85,23 +104,25 @@ class CONTENT_EXPORT AppCacheRequestHandler
// Main-resource loading -------------------------------------
// Frame and SharedWorker main resources are handled here.
- void MaybeLoadMainResource(net::URLRequest* request,
- net::NetworkDelegate* network_delegate);
+ scoped_ptr<AppCacheURLRequestJob> MaybeLoadMainResource(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate);
// AppCacheStorage::Delegate methods
void OnMainResponseFound(const GURL& url,
const AppCacheEntry& entry,
const GURL& fallback_url,
const AppCacheEntry& fallback_entry,
- int64 cache_id,
- int64 group_id,
+ int64_t cache_id,
+ int64_t group_id,
const GURL& mainfest_url) override;
// Sub-resource loading -------------------------------------
// Dedicated worker and all manner of sub-resources are handled here.
- void MaybeLoadSubResource(net::URLRequest* request,
- net::NetworkDelegate* network_delegate);
+ scoped_ptr<AppCacheURLRequestJob> MaybeLoadSubResource(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate);
void ContinueMaybeLoadSubResource();
// AppCacheHost::Observer override
@@ -123,8 +144,8 @@ class CONTENT_EXPORT AppCacheRequestHandler
// Info about the type of response we found for delivery.
// These are relevant for both main and subresource requests.
- int64 found_group_id_;
- int64 found_cache_id_;
+ int64_t found_group_id_;
+ int64_t found_cache_id_;
AppCacheEntry found_entry_;
AppCacheEntry found_fallback_entry_;
GURL found_namespace_entry_url_;
@@ -137,11 +158,19 @@ class CONTENT_EXPORT AppCacheRequestHandler
// request and any redirects will be handled by the network library.
bool cache_entry_not_found_;
+ // True if the next time this request is started, the response should be
+ // delivered from the network, bypassing the AppCache. Cleared after the next
+ // intercept opportunity.
+ bool is_delivering_network_response_;
+
// True if this->MaybeLoadResource(...) has been called in the past.
bool maybe_load_resource_executed_;
- // The job we use to deliver a response.
- scoped_refptr<AppCacheURLRequestJob> job_;
+ // The job we use to deliver a response. Only NULL during the following times:
+ // 1) Before request has started a job.
+ // 2) Request is not being handled by appcache.
+ // 3) Request has been cancelled, and the job killed.
+ base::WeakPtr<AppCacheURLRequestJob> job_;
// During a cross site navigation, we transfer ownership the AppcacheHost
// from the old processes structures over to the new structures.
@@ -149,6 +178,11 @@ class CONTENT_EXPORT AppCacheRequestHandler
int old_process_id_;
int old_host_id_;
+ // Cached information about the response being currently served by the
+ // AppCache, if there is one.
+ int cache_id_;
+ GURL manifest_url_;
+
friend class content::AppCacheRequestHandlerTest;
DISALLOW_COPY_AND_ASSIGN(AppCacheRequestHandler);
};
diff --git a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
index 3dbaf8532e7..46ce987cc90 100644
--- a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
@@ -2,21 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/appcache/appcache_request_handler.h"
+
+#include <stdint.h>
#include <stack>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_backend_impl.h"
-#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/appcache/appcache_url_request_job.h"
#include "content/browser/appcache/mock_appcache_policy.h"
#include "content/browser/appcache/mock_appcache_service.h"
@@ -92,8 +97,9 @@ class AppCacheRequestHandlerTest : public testing::Test {
has_response_info_(true),
response_info_(info) {}
- protected:
~MockURLRequestJob() override {}
+
+ protected:
void Start() override { NotifyHeadersComplete(); }
int GetResponseCode() const override { return response_code_; }
void GetResponseInfo(net::HttpResponseInfo* info) override {
@@ -110,30 +116,23 @@ class AppCacheRequestHandlerTest : public testing::Test {
class MockURLRequestJobFactory : public net::URLRequestJobFactory {
public:
- MockURLRequestJobFactory() : job_(NULL) {
- }
+ MockURLRequestJobFactory() {}
~MockURLRequestJobFactory() override { DCHECK(!job_); }
- void SetJob(net::URLRequestJob* job) {
- job_ = job;
- }
+ void SetJob(scoped_ptr<net::URLRequestJob> job) { job_ = std::move(job); }
net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
const std::string& scheme,
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
- if (job_) {
- net::URLRequestJob* temp = job_;
- job_ = NULL;
- return temp;
- } else {
- // Some of these tests trigger UpdateJobs which start URLRequests.
- // We short circuit those be returning error jobs.
- return new net::URLRequestErrorJob(request,
- network_delegate,
- net::ERR_INTERNET_DISCONNECTED);
- }
+ if (job_)
+ return job_.release();
+
+ // Some of these tests trigger UpdateJobs which start URLRequests.
+ // We short circuit those be returning error jobs.
+ return new net::URLRequestErrorJob(request, network_delegate,
+ net::ERR_INTERNET_DISCONNECTED);
}
net::URLRequestJob* MaybeInterceptRedirect(
@@ -162,7 +161,7 @@ class AppCacheRequestHandlerTest : public testing::Test {
}
private:
- mutable net::URLRequestJob* job_;
+ mutable scoped_ptr<net::URLRequestJob> job_;
};
static void SetUpTestCase() {
@@ -261,8 +260,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
@@ -274,21 +273,20 @@ class AppCacheRequestHandlerTest : public testing::Test {
EXPECT_FALSE(job_->is_waiting());
EXPECT_TRUE(job_->is_delivering_network_response());
- int64 cache_id = kAppCacheNoCacheId;
+ int64_t cache_id = kAppCacheNoCacheId;
GURL manifest_url;
handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
EXPECT_EQ(kAppCacheNoCacheId, cache_id);
EXPECT_EQ(GURL(), manifest_url);
EXPECT_EQ(0, handler_->found_group_id_);
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForRedirect(
- request_.get(),
- request_->context()->network_delegate(),
- GURL("http://blah/redirect"));
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForRedirect(
+ request_.get(), request_->context()->network_delegate(),
+ GURL("http://blah/redirect")));
EXPECT_FALSE(fallback_job);
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ fallback_job.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
EXPECT_TRUE(host_->preferred_manifest_url().is_empty());
@@ -315,8 +313,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
GURL(), AppCacheEntry(),
1, 2, GURL("http://blah/manifest/"));
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
@@ -328,16 +326,16 @@ class AppCacheRequestHandlerTest : public testing::Test {
EXPECT_FALSE(job_->is_waiting());
EXPECT_TRUE(job_->is_delivering_appcache_response());
- int64 cache_id = kAppCacheNoCacheId;
+ int64_t cache_id = kAppCacheNoCacheId;
GURL manifest_url;
handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
EXPECT_EQ(1, cache_id);
EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
EXPECT_EQ(2, handler_->found_group_id_);
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
EXPECT_EQ(GURL("http://blah/manifest/"),
@@ -366,8 +364,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
1, 2, GURL("http://blah/manifest/"));
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
@@ -376,11 +374,9 @@ class AppCacheRequestHandlerTest : public testing::Test {
}
void SimulateResponseCode(int response_code) {
- job_factory_->SetJob(
- new MockURLRequestJob(
- request_.get(),
- request_->context()->network_delegate(),
- response_code));
+ job_factory_->SetJob(make_scoped_ptr(new MockURLRequestJob(
+ request_.get(), request_->context()->network_delegate(),
+ response_code)));
request_->Start();
// All our simulation needs to satisfy are the following two DCHECKs
DCHECK(request_->status().is_success());
@@ -388,10 +384,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
}
void SimulateResponseInfo(const net::HttpResponseInfo& info) {
- job_factory_->SetJob(
- new MockURLRequestJob(
- request_.get(),
- request_->context()->network_delegate(), info));
+ job_factory_->SetJob(make_scoped_ptr(new MockURLRequestJob(
+ request_.get(), request_->context()->network_delegate(), info)));
request_->Start();
}
@@ -399,22 +393,26 @@ class AppCacheRequestHandlerTest : public testing::Test {
EXPECT_FALSE(job_->is_waiting());
EXPECT_TRUE(job_->is_delivering_network_response());
+ // The handler expects to the job to tell it that the request is going to
+ // be restarted before it sees the next request.
+ handler_->OnPrepareToRestart();
+
// When the request is restarted, the existing job is dropped so a
// real network job gets created. We expect NULL here which will cause
// the net library to create a real job.
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(job_.get());
// Simulate an http error of the real network job.
SimulateResponseCode(500);
- job_ = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_delivering_appcache_response());
- int64 cache_id = kAppCacheNoCacheId;
+ int64_t cache_id = kAppCacheNoCacheId;
GURL manifest_url;
handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
EXPECT_EQ(1, cache_id);
@@ -449,8 +447,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
1, 2, GURL("http://blah/manifest/"));
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
@@ -462,11 +460,15 @@ class AppCacheRequestHandlerTest : public testing::Test {
EXPECT_FALSE(job_->is_waiting());
EXPECT_TRUE(job_->is_delivering_network_response());
+ // The handler expects to the job to tell it that the request is going to
+ // be restarted before it sees the next request.
+ handler_->OnPrepareToRestart();
+
// When the request is restarted, the existing job is dropped so a
// real network job gets created. We expect NULL here which will cause
// the net library to create a real job.
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(job_.get());
// Simulate an http error of the real network job, but with custom
@@ -480,10 +482,17 @@ class AppCacheRequestHandlerTest : public testing::Test {
std::string(kOverrideHeaders, arraysize(kOverrideHeaders)));
SimulateResponseInfo(info);
- job_ = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(job_.get());
+ // GetExtraResponseInfo should return no information.
+ int64_t cache_id = kAppCacheNoCacheId;
+ GURL manifest_url;
+ handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
+ EXPECT_EQ(kAppCacheNoCacheId, cache_id);
+ EXPECT_TRUE(manifest_url.is_empty());
+
TestFinished();
}
@@ -517,19 +526,18 @@ class AppCacheRequestHandlerTest : public testing::Test {
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_delivering_error_response());
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForRedirect(
- request_.get(),
- request_->context()->network_delegate(),
- GURL("http://blah/redirect"));
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForRedirect(
+ request_.get(), request_->context()->network_delegate(),
+ GURL("http://blah/redirect")));
EXPECT_FALSE(fallback_job);
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ fallback_job.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
TestFinished();
@@ -549,8 +557,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
RESOURCE_TYPE_SUB_RESOURCE,
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
@@ -558,14 +566,13 @@ class AppCacheRequestHandlerTest : public testing::Test {
EXPECT_FALSE(job_->is_waiting());
EXPECT_TRUE(job_->is_delivering_error_response());
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForRedirect(
- request_.get(),
- request_->context()->network_delegate(),
- GURL("http://blah/redirect"));
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForRedirect(
+ request_.get(), request_->context()->network_delegate(),
+ GURL("http://blah/redirect")));
EXPECT_FALSE(fallback_job);
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ fallback_job.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
TestFinished();
@@ -585,19 +592,18 @@ class AppCacheRequestHandlerTest : public testing::Test {
RESOURCE_TYPE_SUB_RESOURCE,
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_delivering_appcache_response());
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForRedirect(
- request_.get(),
- request_->context()->network_delegate(),
- GURL("http://blah/redirect"));
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForRedirect(
+ request_.get(), request_->context()->network_delegate(),
+ GURL("http://blah/redirect")));
EXPECT_FALSE(fallback_job);
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ fallback_job.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
TestFinished();
@@ -619,20 +625,19 @@ class AppCacheRequestHandlerTest : public testing::Test {
RESOURCE_TYPE_SUB_RESOURCE,
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(job_.get());
- job_ = handler_->MaybeLoadFallbackForRedirect(
- request_.get(),
- request_->context()->network_delegate(),
- GURL("http://not_blah/redirect"));
+ job_.reset(handler_->MaybeLoadFallbackForRedirect(
+ request_.get(), request_->context()->network_delegate(),
+ GURL("http://not_blah/redirect")));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_delivering_appcache_response());
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
TestFinished();
@@ -654,20 +659,19 @@ class AppCacheRequestHandlerTest : public testing::Test {
RESOURCE_TYPE_SUB_RESOURCE,
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(job_.get());
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForRedirect(
- request_.get(),
- request_->context()->network_delegate(),
- GURL("http://blah/redirect"));
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForRedirect(
+ request_.get(), request_->context()->network_delegate(),
+ GURL("http://blah/redirect")));
EXPECT_FALSE(fallback_job);
SimulateResponseCode(200);
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ fallback_job.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
TestFinished();
@@ -690,18 +694,17 @@ class AppCacheRequestHandlerTest : public testing::Test {
RESOURCE_TYPE_SUB_RESOURCE,
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(job_.get());
- AppCacheURLRequestJob* fallback_job;
- fallback_job = handler_->MaybeLoadFallbackForRedirect(
- request_.get(),
- request_->context()->network_delegate(),
- GURL("http://blah/redirect"));
+ scoped_ptr<AppCacheURLRequestJob> fallback_job(
+ handler_->MaybeLoadFallbackForRedirect(
+ request_.get(), request_->context()->network_delegate(),
+ GURL("http://blah/redirect")));
EXPECT_FALSE(fallback_job);
- fallback_job = handler_->MaybeLoadFallbackForResponse(
- request_.get(), request_->context()->network_delegate());
+ fallback_job.reset(handler_->MaybeLoadFallbackForResponse(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_FALSE(fallback_job);
TestFinished();
@@ -750,8 +753,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
@@ -806,18 +809,21 @@ class AppCacheRequestHandlerTest : public testing::Test {
false));
EXPECT_TRUE(handler_.get());
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
EXPECT_FALSE(job_->has_been_started());
- job_factory_->SetJob(job_.get());
+ base::WeakPtr<AppCacheURLRequestJob> weak_job = job_->GetWeakPtr();
+
+ job_factory_->SetJob(std::move(job_));
request_->Start();
- EXPECT_TRUE(job_->has_been_started());
+ ASSERT_TRUE(weak_job);
+ EXPECT_TRUE(weak_job->has_been_started());
request_->Cancel();
- EXPECT_TRUE(job_->has_been_killed());
+ ASSERT_FALSE(weak_job);
EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
request_.get(), request_->context()->network_delegate()));
@@ -888,8 +894,8 @@ class AppCacheRequestHandlerTest : public testing::Test {
GURL(), AppCacheEntry(),
1, 2, GURL("http://blah/manifest/"));
- job_ = handler_->MaybeLoadResource(request_.get(),
- request_->context()->network_delegate());
+ job_.reset(handler_->MaybeLoadResource(
+ request_.get(), request_->context()->network_delegate()));
EXPECT_TRUE(job_.get());
EXPECT_TRUE(job_->is_waiting());
@@ -942,7 +948,7 @@ class AppCacheRequestHandlerTest : public testing::Test {
MockURLRequestDelegate delegate_;
scoped_ptr<net::URLRequest> request_;
scoped_ptr<AppCacheRequestHandler> handler_;
- scoped_refptr<AppCacheURLRequestJob> job_;
+ scoped_ptr<AppCacheURLRequestJob> job_;
static scoped_ptr<base::Thread> io_thread_;
};
diff --git a/chromium/content/browser/appcache/appcache_response.cc b/chromium/content/browser/appcache/appcache_response.cc
index f113adf940d..20a8b8a36d0 100644
--- a/chromium/content/browser/appcache/appcache_response.cc
+++ b/chromium/content/browser/appcache/appcache_response.cc
@@ -4,6 +4,8 @@
#include "content/browser/appcache/appcache_response.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
@@ -11,7 +13,6 @@
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/pickle.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
@@ -48,12 +49,15 @@ class WrappedPickleIOBuffer : public net::WrappedIOBuffer {
// AppCacheResponseInfo ----------------------------------------------
-AppCacheResponseInfo::AppCacheResponseInfo(
- AppCacheStorage* storage, const GURL& manifest_url,
- int64 response_id, net::HttpResponseInfo* http_info,
- int64 response_data_size)
- : manifest_url_(manifest_url), response_id_(response_id),
- http_response_info_(http_info), response_data_size_(response_data_size),
+AppCacheResponseInfo::AppCacheResponseInfo(AppCacheStorage* storage,
+ const GURL& manifest_url,
+ int64_t response_id,
+ net::HttpResponseInfo* http_info,
+ int64_t response_data_size)
+ : manifest_url_(manifest_url),
+ response_id_(response_id),
+ http_response_info_(http_info),
+ response_data_size_(response_data_size),
storage_(storage) {
DCHECK(http_info);
DCHECK(response_id != kAppCacheNoResponseId);
@@ -76,15 +80,15 @@ HttpResponseInfoIOBuffer::~HttpResponseInfoIOBuffer() {}
// AppCacheResponseIO ----------------------------------------------
-AppCacheResponseIO::AppCacheResponseIO(
- int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache)
+AppCacheResponseIO::AppCacheResponseIO(int64_t response_id,
+ int64_t group_id,
+ AppCacheDiskCacheInterface* disk_cache)
: response_id_(response_id),
group_id_(group_id),
disk_cache_(disk_cache),
entry_(NULL),
buffer_len_(0),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
AppCacheResponseIO::~AppCacheResponseIO() {
if (entry_)
@@ -130,11 +134,6 @@ void AppCacheResponseIO::WriteRaw(int index, int offset,
}
void AppCacheResponseIO::OnRawIOComplete(int result) {
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "422516 AppCacheResponseIO::OnRawIOComplete"));
-
DCHECK_NE(net::ERR_IO_PENDING, result);
OnIOComplete(result);
}
@@ -176,16 +175,15 @@ void AppCacheResponseIO::OpenEntryCallback(
// AppCacheResponseReader ----------------------------------------------
AppCacheResponseReader::AppCacheResponseReader(
- int64 response_id,
- int64 group_id,
+ int64_t response_id,
+ int64_t group_id,
AppCacheDiskCacheInterface* disk_cache)
: AppCacheResponseIO(response_id, group_id, disk_cache),
range_offset_(0),
- range_length_(kint32max),
+ range_length_(std::numeric_limits<int32_t>::max()),
read_position_(0),
reading_metadata_size_(0),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
AppCacheResponseReader::~AppCacheResponseReader() {
}
@@ -272,7 +270,7 @@ void AppCacheResponseReader::OnIOComplete(int result) {
info_buffer_->response_data_size =
entry_->GetSize(kResponseContentIndex);
- int64 metadata_size = entry_->GetSize(kResponseMetadataIndex);
+ int64_t metadata_size = entry_->GetSize(kResponseMetadataIndex);
if (metadata_size > 0) {
reading_metadata_size_ = metadata_size;
info_buffer_->http_info->metadata = new net::IOBufferWithSize(
@@ -302,14 +300,15 @@ void AppCacheResponseReader::OnOpenEntryComplete() {
// AppCacheResponseWriter ----------------------------------------------
AppCacheResponseWriter::AppCacheResponseWriter(
- int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache)
+ int64_t response_id,
+ int64_t group_id,
+ AppCacheDiskCacheInterface* disk_cache)
: AppCacheResponseIO(response_id, group_id, disk_cache),
info_size_(0),
write_position_(0),
write_amount_(0),
creation_phase_(INITIAL_ATTEMPT),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
AppCacheResponseWriter::~AppCacheResponseWriter() {
}
@@ -443,13 +442,12 @@ void AppCacheResponseWriter::OnCreateEntryComplete(
// AppCacheResponseMetadataWriter ----------------------------------------------
AppCacheResponseMetadataWriter::AppCacheResponseMetadataWriter(
- int64 response_id,
- int64 group_id,
+ int64_t response_id,
+ int64_t group_id,
AppCacheDiskCacheInterface* disk_cache)
: AppCacheResponseIO(response_id, group_id, disk_cache),
write_amount_(0),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
AppCacheResponseMetadataWriter::~AppCacheResponseMetadataWriter() {
}
diff --git a/chromium/content/browser/appcache/appcache_response.h b/chromium/content/browser/appcache/appcache_response.h
index 8d6c79060bd..8543b2b902f 100644
--- a/chromium/content/browser/appcache/appcache_response.h
+++ b/chromium/content/browser/appcache/appcache_response.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -31,25 +33,27 @@ class CONTENT_EXPORT AppCacheResponseInfo
: public base::RefCounted<AppCacheResponseInfo> {
public:
// AppCacheResponseInfo takes ownership of the http_info.
- AppCacheResponseInfo(AppCacheStorage* storage, const GURL& manifest_url,
- int64 response_id, net::HttpResponseInfo* http_info,
- int64 response_data_size);
+ AppCacheResponseInfo(AppCacheStorage* storage,
+ const GURL& manifest_url,
+ int64_t response_id,
+ net::HttpResponseInfo* http_info,
+ int64_t response_data_size);
const GURL& manifest_url() const { return manifest_url_; }
- int64 response_id() const { return response_id_; }
+ int64_t response_id() const { return response_id_; }
const net::HttpResponseInfo* http_response_info() const {
return http_response_info_.get();
}
- int64 response_data_size() const { return response_data_size_; }
+ int64_t response_data_size() const { return response_data_size_; }
private:
friend class base::RefCounted<AppCacheResponseInfo>;
virtual ~AppCacheResponseInfo();
const GURL manifest_url_;
- const int64 response_id_;
+ const int64_t response_id_;
const scoped_ptr<net::HttpResponseInfo> http_response_info_;
- const int64 response_data_size_;
+ const int64_t response_data_size_;
AppCacheStorage* storage_;
};
@@ -73,21 +77,30 @@ class CONTENT_EXPORT AppCacheDiskCacheInterface {
public:
class Entry {
public:
- virtual int Read(int index, int64 offset, net::IOBuffer* buf, int buf_len,
+ virtual int Read(int index,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
const net::CompletionCallback& callback) = 0;
- virtual int Write(int index, int64 offset, net::IOBuffer* buf, int buf_len,
+ virtual int Write(int index,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
const net::CompletionCallback& callback) = 0;
- virtual int64 GetSize(int index) = 0;
+ virtual int64_t GetSize(int index) = 0;
virtual void Close() = 0;
protected:
virtual ~Entry() {}
};
- virtual int CreateEntry(int64 key, Entry** entry,
+ virtual int CreateEntry(int64_t key,
+ Entry** entry,
const net::CompletionCallback& callback) = 0;
- virtual int OpenEntry(int64 key, Entry** entry,
+ virtual int OpenEntry(int64_t key,
+ Entry** entry,
+ const net::CompletionCallback& callback) = 0;
+ virtual int DoomEntry(int64_t key,
const net::CompletionCallback& callback) = 0;
- virtual int DoomEntry(int64 key, const net::CompletionCallback& callback) = 0;
protected:
friend class base::RefCounted<AppCacheDiskCacheInterface>;
@@ -98,11 +111,11 @@ class CONTENT_EXPORT AppCacheDiskCacheInterface {
class CONTENT_EXPORT AppCacheResponseIO {
public:
virtual ~AppCacheResponseIO();
- int64 response_id() const { return response_id_; }
+ int64_t response_id() const { return response_id_; }
protected:
- AppCacheResponseIO(int64 response_id,
- int64 group_id,
+ AppCacheResponseIO(int64_t response_id,
+ int64_t group_id,
AppCacheDiskCacheInterface* disk_cache);
virtual void OnIOComplete(int result) = 0;
@@ -115,8 +128,8 @@ class CONTENT_EXPORT AppCacheResponseIO {
void WriteRaw(int index, int offset, net::IOBuffer* buf, int buf_len);
void OpenEntryIfNeeded();
- const int64 response_id_;
- const int64 group_id_;
+ const int64_t response_id_;
+ const int64_t group_id_;
AppCacheDiskCacheInterface* disk_cache_;
AppCacheDiskCacheInterface::Entry* entry_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
@@ -177,8 +190,8 @@ class CONTENT_EXPORT AppCacheResponseReader
friend class content::MockAppCacheStorage;
// Should only be constructed by the storage class and derivatives.
- AppCacheResponseReader(int64 response_id,
- int64 group_id,
+ AppCacheResponseReader(int64_t response_id,
+ int64_t group_id,
AppCacheDiskCacheInterface* disk_cache);
void OnIOComplete(int result) override;
@@ -209,8 +222,9 @@ class CONTENT_EXPORT AppCacheResponseWriter
// negative error code or the number of bytes written. The 'callback' is a
// required parameter. The contents of 'info_buf' are not modified.
// Should only be called where there is no Write operation in progress.
- void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
- const net::CompletionCallback& callback);
+ // (virtual for testing)
+ virtual void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
+ const net::CompletionCallback& callback);
// Writes data to storage. Always returns the result of the write
// asynchronously through the 'callback'. Returns the number of bytes written
@@ -220,19 +234,21 @@ class CONTENT_EXPORT AppCacheResponseWriter
// the number of bytes written. The 'callback' is a required parameter.
// The contents of 'buf' are not modified.
// Should only be called where there is no Write operation in progress.
- void WriteData(net::IOBuffer* buf, int buf_len,
- const net::CompletionCallback& callback);
+ // (virtual for testing)
+ virtual void WriteData(net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback);
// Returns true if there is a write pending.
bool IsWritePending() { return IsIOPending(); }
// Returns the amount written, info and data.
- int64 amount_written() { return info_size_ + write_position_; }
+ int64_t amount_written() { return info_size_ + write_position_; }
protected:
// Should only be constructed by the storage class and derivatives.
- AppCacheResponseWriter(int64 response_id,
- int64 group_id,
+ AppCacheResponseWriter(int64_t response_id,
+ int64_t group_id,
AppCacheDiskCacheInterface* disk_cache);
private:
@@ -289,8 +305,8 @@ class CONTENT_EXPORT AppCacheResponseMetadataWriter
friend class AppCacheStorageImpl;
friend class content::MockAppCacheStorage;
// Should only be constructed by the storage class and derivatives.
- AppCacheResponseMetadataWriter(int64 response_id,
- int64 group_id,
+ AppCacheResponseMetadataWriter(int64_t response_id,
+ int64_t group_id,
AppCacheDiskCacheInterface* disk_cache);
private:
diff --git a/chromium/content/browser/appcache/appcache_response_unittest.cc b/chromium/content/browser/appcache/appcache_response_unittest.cc
index 743a624556f..54f3a6e2e65 100644
--- a/chromium/content/browser/appcache/appcache_response_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_response_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <string.h>
+
#include <stack>
#include <string>
#include <utility>
@@ -11,6 +14,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/pickle.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
@@ -44,14 +48,14 @@ class AppCacheResponseTest : public testing::Test {
}
void OnResponseInfoLoaded(AppCacheResponseInfo* info,
- int64 response_id) override {
+ int64_t response_id) override {
loaded_info_ = info;
loaded_info_id_ = response_id;
test_->ScheduleNextTask();
}
scoped_refptr<AppCacheResponseInfo> loaded_info_;
- int64 loaded_info_id_;
+ int64_t loaded_info_id_;
AppCacheResponseTest* test_;
};
@@ -766,7 +770,7 @@ class AppCacheResponseTest : public testing::Test {
int reader_deletion_count_down_;
bool read_callback_was_called_;
- int64 written_response_id_;
+ int64_t written_response_id_;
scoped_ptr<AppCacheResponseWriter> writer_;
scoped_ptr<AppCacheResponseMetadataWriter> metadata_writer_;
scoped_refptr<HttpResponseInfoIOBuffer> write_info_buffer_;
diff --git a/chromium/content/browser/appcache/appcache_service_impl.cc b/chromium/content/browser/appcache/appcache_service_impl.cc
index 01cbb46add0..2fc5d949d2e 100644
--- a/chromium/content/browser/appcache/appcache_service_impl.cc
+++ b/chromium/content/browser/appcache/appcache_service_impl.cc
@@ -5,11 +5,13 @@
#include "content/browser/appcache/appcache_service_impl.h"
#include <functional>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/thread_task_runner_handle.h"
@@ -83,54 +85,6 @@ void AppCacheServiceImpl::AsyncHelper::Cancel() {
service_ = NULL;
}
-// CanHandleOfflineHelper -------
-
-class AppCacheServiceImpl::CanHandleOfflineHelper : AsyncHelper {
- public:
- CanHandleOfflineHelper(
- AppCacheServiceImpl* service, const GURL& url,
- const GURL& first_party, const net::CompletionCallback& callback)
- : AsyncHelper(service, callback),
- url_(url),
- first_party_(first_party) {
- }
-
- void Start() override {
- AppCachePolicy* policy = service_->appcache_policy();
- if (policy && !policy->CanLoadAppCache(url_, first_party_)) {
- CallCallback(net::ERR_FAILED);
- delete this;
- return;
- }
-
- service_->storage()->FindResponseForMainRequest(url_, GURL(), this);
- }
-
- private:
- // AppCacheStorage::Delegate implementation.
- void OnMainResponseFound(const GURL& url,
- const AppCacheEntry& entry,
- const GURL& fallback_url,
- const AppCacheEntry& fallback_entry,
- int64 cache_id,
- int64 group_id,
- const GURL& mainfest_url) override;
-
- GURL url_;
- GURL first_party_;
-
- DISALLOW_COPY_AND_ASSIGN(CanHandleOfflineHelper);
-};
-
-void AppCacheServiceImpl::CanHandleOfflineHelper::OnMainResponseFound(
- const GURL& url, const AppCacheEntry& entry,
- const GURL& fallback_url, const AppCacheEntry& fallback_entry,
- int64 cache_id, int64 group_id, const GURL& manifest_url) {
- bool can = (entry.has_response_id() || fallback_entry.has_response_id());
- CallCallback(can ? net::OK : net::ERR_FAILED);
- delete this;
-}
-
// DeleteHelper -------
class AppCacheServiceImpl::DeleteHelper : public AsyncHelper {
@@ -303,9 +257,10 @@ void AppCacheServiceImpl::GetInfoHelper::OnAllInfo(
class AppCacheServiceImpl::CheckResponseHelper : AsyncHelper {
public:
- CheckResponseHelper(
- AppCacheServiceImpl* service, const GURL& manifest_url, int64 cache_id,
- int64 response_id)
+ CheckResponseHelper(AppCacheServiceImpl* service,
+ const GURL& manifest_url,
+ int64_t cache_id,
+ int64_t response_id)
: AsyncHelper(service, net::CompletionCallback()),
manifest_url_(manifest_url),
cache_id_(cache_id),
@@ -313,8 +268,7 @@ class AppCacheServiceImpl::CheckResponseHelper : AsyncHelper {
kIOBufferSize(32 * 1024),
expected_total_size_(0),
amount_headers_read_(0),
- amount_data_read_(0) {
- }
+ amount_data_read_(0) {}
void Start() override {
service_->storage()->LoadOrCreateGroup(manifest_url_, this);
@@ -334,8 +288,8 @@ class AppCacheServiceImpl::CheckResponseHelper : AsyncHelper {
// Inputs describing what to check.
GURL manifest_url_;
- int64 cache_id_;
- int64 response_id_;
+ int64_t cache_id_;
+ int64_t response_id_;
// Internals used to perform the checks.
const int kIOBufferSize;
@@ -343,7 +297,7 @@ class AppCacheServiceImpl::CheckResponseHelper : AsyncHelper {
scoped_ptr<AppCacheResponseReader> response_reader_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
scoped_refptr<net::IOBuffer> data_buffer_;
- int64 expected_total_size_;
+ int64_t expected_total_size_;
int amount_headers_read_;
int amount_data_read_;
DISALLOW_COPY_AND_ASSIGN(CheckResponseHelper);
@@ -436,7 +390,7 @@ void AppCacheServiceImpl::CheckResponseHelper::OnReadDataComplete(int result) {
AppCacheStorageReference::AppCacheStorageReference(
scoped_ptr<AppCacheStorage> storage)
- : storage_(storage.Pass()) {}
+ : storage_(std::move(storage)) {}
AppCacheStorageReference::~AppCacheStorageReference() {}
// AppCacheServiceImpl -------
@@ -516,23 +470,14 @@ void AppCacheServiceImpl::Reinitialize() {
// Inform observers of about this and give them a chance to
// defer deletion of the old storage object.
- scoped_refptr<AppCacheStorageReference>
- old_storage_ref(new AppCacheStorageReference(storage_.Pass()));
+ scoped_refptr<AppCacheStorageReference> old_storage_ref(
+ new AppCacheStorageReference(std::move(storage_)));
FOR_EACH_OBSERVER(Observer, observers_,
OnServiceReinitialized(old_storage_ref.get()));
Initialize(cache_directory_, db_thread_, cache_thread_);
}
-void AppCacheServiceImpl::CanHandleMainResourceOffline(
- const GURL& url,
- const GURL& first_party,
- const net::CompletionCallback& callback) {
- CanHandleOfflineHelper* helper =
- new CanHandleOfflineHelper(this, url, first_party, callback);
- helper->Start();
-}
-
void AppCacheServiceImpl::GetAllAppCacheInfo(
AppCacheInfoCollection* collection,
const net::CompletionCallback& callback) {
@@ -555,8 +500,8 @@ void AppCacheServiceImpl::DeleteAppCachesForOrigin(
}
void AppCacheServiceImpl::CheckAppCacheResponse(const GURL& manifest_url,
- int64 cache_id,
- int64 response_id) {
+ int64_t cache_id,
+ int64_t response_id) {
CheckResponseHelper* helper = new CheckResponseHelper(
this, manifest_url, cache_id, response_id);
helper->Start();
diff --git a/chromium/content/browser/appcache/appcache_service_impl.h b/chromium/content/browser/appcache/appcache_service_impl.h
index 968666636aa..acc660f7ae2 100644
--- a/chromium/content/browser/appcache/appcache_service_impl.h
+++ b/chromium/content/browser/appcache/appcache_service_impl.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_SERVICE_IMPL_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_SERVICE_IMPL_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
@@ -99,10 +102,6 @@ class CONTENT_EXPORT AppCacheServiceImpl
void ScheduleReinitialize();
// AppCacheService implementation:
- void CanHandleMainResourceOffline(
- const GURL& url,
- const GURL& first_party,
- const net::CompletionCallback& callback) override;
void GetAllAppCacheInfo(AppCacheInfoCollection* collection,
const net::CompletionCallback& callback) override;
void DeleteAppCacheGroup(const GURL& manifest_url,
@@ -116,8 +115,9 @@ class CONTENT_EXPORT AppCacheServiceImpl
// Checks the integrity of 'response_id' by reading the headers and data.
// If it cannot be read, the cache group for 'manifest_url' is deleted.
- void CheckAppCacheResponse(const GURL& manifest_url, int64 cache_id,
- int64 response_id);
+ void CheckAppCacheResponse(const GURL& manifest_url,
+ int64_t cache_id,
+ int64_t response_id);
// Context for use during cache updates, should only be accessed
// on the IO thread. We do NOT add a reference to the request context,
@@ -187,7 +187,6 @@ class CONTENT_EXPORT AppCacheServiceImpl
ScheduleReinitialize);
class AsyncHelper;
- class CanHandleOfflineHelper;
class DeleteHelper;
class DeleteOriginHelper;
class GetInfoHelper;
diff --git a/chromium/content/browser/appcache/appcache_service_unittest.cc b/chromium/content/browser/appcache/appcache_service_unittest.cc
index 62e6a4dbe0b..79febf7675a 100644
--- a/chromium/content/browser/appcache/appcache_service_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_service_unittest.cc
@@ -2,11 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/pickle.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -22,11 +25,11 @@
namespace content {
namespace {
-const int64 kMockGroupId = 1;
-const int64 kMockCacheId = 1;
-const int64 kMockResponseId = 1;
-const int64 kMissingCacheId = 5;
-const int64 kMissingResponseId = 5;
+const int64_t kMockGroupId = 1;
+const int64_t kMockCacheId = 1;
+const int64_t kMockResponseId = 1;
+const int64_t kMissingCacheId = 5;
+const int64_t kMissingResponseId = 5;
const char kMockHeaders[] =
"HTTP/1.0 200 OK\0Content-Length: 5\0\0";
const char kMockBody[] = "Hello";
@@ -34,13 +37,16 @@ const int kMockBodySize = 5;
class MockResponseReader : public AppCacheResponseReader {
public:
- MockResponseReader(int64 response_id,
- net::HttpResponseInfo* info, int info_size,
- const char* data, int data_size)
+ MockResponseReader(int64_t response_id,
+ net::HttpResponseInfo* info,
+ int info_size,
+ const char* data,
+ int data_size)
: AppCacheResponseReader(response_id, 0, NULL),
- info_(info), info_size_(info_size),
- data_(data), data_size_(data_size) {
- }
+ info_(info),
+ info_size_(info_size),
+ data_(data),
+ data_size_(data_size) {}
void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
const net::CompletionCallback& callback) override {
info_buffer_ = info_buf;
diff --git a/chromium/content/browser/appcache/appcache_storage.cc b/chromium/content/browser/appcache/appcache_storage.cc
index 077000616ae..7b94bf44965 100644
--- a/chromium/content/browser/appcache/appcache_storage.cc
+++ b/chromium/content/browser/appcache/appcache_storage.cc
@@ -15,7 +15,7 @@
namespace content {
// static
-const int64 AppCacheStorage::kUnitializedId = -1;
+const int64_t AppCacheStorage::kUnitializedId = -1;
AppCacheStorage::AppCacheStorage(AppCacheServiceImpl* service)
: last_cache_id_(kUnitializedId), last_group_id_(kUnitializedId),
@@ -41,8 +41,8 @@ AppCacheStorage::DelegateReference::~DelegateReference() {
AppCacheStorage::ResponseInfoLoadTask::ResponseInfoLoadTask(
const GURL& manifest_url,
- int64 group_id,
- int64 response_id,
+ int64_t group_id,
+ int64_t response_id,
AppCacheStorage* storage)
: storage_(storage),
manifest_url_(manifest_url),
@@ -79,8 +79,10 @@ void AppCacheStorage::ResponseInfoLoadTask::OnReadComplete(int result) {
delete this;
}
-void AppCacheStorage::LoadResponseInfo(
- const GURL& manifest_url, int64 group_id, int64 id, Delegate* delegate) {
+void AppCacheStorage::LoadResponseInfo(const GURL& manifest_url,
+ int64_t group_id,
+ int64_t id,
+ Delegate* delegate) {
AppCacheResponseInfo* info = working_set_.GetResponseInfo(id);
if (info) {
delegate->OnResponseInfoLoaded(info, id);
@@ -95,10 +97,10 @@ void AppCacheStorage::LoadResponseInfo(
info_load->StartIfNeeded();
}
-void AppCacheStorage::UpdateUsageMapAndNotify(
- const GURL& origin, int64 new_usage) {
+void AppCacheStorage::UpdateUsageMapAndNotify(const GURL& origin,
+ int64_t new_usage) {
DCHECK_GE(new_usage, 0);
- int64 old_usage = usage_map_[origin];
+ int64_t old_usage = usage_map_[origin];
if (new_usage > 0)
usage_map_[origin] = new_usage;
else
diff --git a/chromium/content/browser/appcache/appcache_storage.h b/chromium/content/browser/appcache/appcache_storage.h
index 41668cbca4a..42a77cd5477 100644
--- a/chromium/content/browser/appcache/appcache_storage.h
+++ b/chromium/content/browser/appcache/appcache_storage.h
@@ -5,12 +5,14 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_H_
+#include <stdint.h>
+
#include <map>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/appcache/appcache_working_set.h"
@@ -37,7 +39,7 @@ struct HttpResponseInfoIOBuffer;
class CONTENT_EXPORT AppCacheStorage {
public:
- typedef std::map<GURL, int64> UsageMap;
+ typedef std::map<GURL, int64_t> UsageMap;
class CONTENT_EXPORT Delegate {
public:
@@ -45,7 +47,7 @@ class CONTENT_EXPORT AppCacheStorage {
virtual void OnAllInfo(AppCacheInfoCollection* collection) {}
// If a load fails the 'cache' will be NULL.
- virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) {}
+ virtual void OnCacheLoaded(AppCache* cache, int64_t cache_id) {}
// If a load fails the 'group' will be NULL.
virtual void OnGroupLoaded(
@@ -62,8 +64,8 @@ class CONTENT_EXPORT AppCacheStorage {
int response_code) {}
// If a load fails the 'response_info' will be NULL.
- virtual void OnResponseInfoLoaded(
- AppCacheResponseInfo* response_info, int64 response_id) {}
+ virtual void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
+ int64_t response_id) {}
// If no response is found, entry.response_id() and
// fallback_entry.response_id() will be kAppCacheNoResponseId.
@@ -71,10 +73,13 @@ class CONTENT_EXPORT AppCacheStorage {
// namespace, the url of the namespece entry is returned.
// If a response is found, the cache id and manifest url of the
// containing cache and group are also returned.
- virtual void OnMainResponseFound(
- const GURL& url, const AppCacheEntry& entry,
- const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry,
- int64 cache_id, int64 group_id, const GURL& mainfest_url) {}
+ virtual void OnMainResponseFound(const GURL& url,
+ const AppCacheEntry& entry,
+ const GURL& namespace_entry_url,
+ const AppCacheEntry& fallback_entry,
+ int64_t cache_id,
+ int64_t group_id,
+ const GURL& mainfest_url) {}
protected:
virtual ~Delegate() {}
@@ -93,7 +98,7 @@ class CONTENT_EXPORT AppCacheStorage {
// memory, the delegate will be called back immediately without returning
// to the message loop. If the load fails, the delegate will be called
// back with a NULL cache pointer.
- virtual void LoadCache(int64 id, Delegate* delegate) = 0;
+ virtual void LoadCache(int64_t id, Delegate* delegate) = 0;
// Schedules a group and its newest cache, if any, to be loaded from storage.
// Upon load completion the delegate will be called back. If the group
@@ -108,9 +113,10 @@ class CONTENT_EXPORT AppCacheStorage {
// already resides in memory, the delegate will be called back
// immediately without returning to the message loop. If the load fails,
// the delegate will be called back with a NULL pointer.
- virtual void LoadResponseInfo(
- const GURL& manifest_url, int64 group_id, int64 response_id,
- Delegate* delegate);
+ virtual void LoadResponseInfo(const GURL& manifest_url,
+ int64_t group_id,
+ int64_t response_id,
+ Delegate* delegate);
// Schedules a group and its newest complete cache to be initially stored or
// incrementally updated with new changes. Upon completion the delegate
@@ -142,7 +148,7 @@ class CONTENT_EXPORT AppCacheStorage {
// and schedules a task to update persistent storage. If the cache is
// already scheduled to be loaded, upon loading completion the entry
// will be marked. There is no delegate completion callback.
- virtual void MarkEntryAsForeign(const GURL& entry_url, int64 cache_id) = 0;
+ virtual void MarkEntryAsForeign(const GURL& entry_url, int64_t cache_id) = 0;
// Schedules a task to update persistent storage and doom the group and all
// related caches and responses for deletion. Upon completion the in-memory
@@ -166,37 +172,34 @@ class CONTENT_EXPORT AppCacheStorage {
}
// Creates a reader to read a response from storage.
- virtual AppCacheResponseReader* CreateResponseReader(
- const GURL& manifest_url, int64 group_id, int64 response_id) = 0;
+ virtual AppCacheResponseReader* CreateResponseReader(const GURL& manifest_url,
+ int64_t group_id,
+ int64_t response_id) = 0;
// Creates a writer to write a new response to storage. This call
// establishes a new response id.
- virtual AppCacheResponseWriter* CreateResponseWriter(
- const GURL& manifest_url, int64 group_id) = 0;
+ virtual AppCacheResponseWriter* CreateResponseWriter(const GURL& manifest_url,
+ int64_t group_id) = 0;
// Creates a metadata writer to write metadata of response to storage.
virtual AppCacheResponseMetadataWriter* CreateResponseMetadataWriter(
- int64 group_id,
- int64 response_id) = 0;
+ int64_t group_id,
+ int64_t response_id) = 0;
// Schedules the lazy deletion of responses and saves the ids
// persistently such that the responses will be deleted upon restart
// if they aren't deleted prior to shutdown.
- virtual void DoomResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids) = 0;
+ virtual void DoomResponses(const GURL& manifest_url,
+ const std::vector<int64_t>& response_ids) = 0;
// Schedules the lazy deletion of responses without persistently saving
// the response ids.
- virtual void DeleteResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids) = 0;
+ virtual void DeleteResponses(const GURL& manifest_url,
+ const std::vector<int64_t>& response_ids) = 0;
// Generates unique storage ids for different object types.
- int64 NewCacheId() {
- return ++last_cache_id_;
- }
- int64 NewGroupId() {
- return ++last_group_id_;
- }
+ int64_t NewCacheId() { return ++last_cache_id_; }
+ int64_t NewGroupId() { return ++last_group_id_; }
// The working set of object instances currently in memory.
AppCacheWorkingSet* working_set() { return &working_set_; }
@@ -250,13 +253,15 @@ class CONTENT_EXPORT AppCacheStorage {
// multiple callers.
class ResponseInfoLoadTask {
public:
- ResponseInfoLoadTask(const GURL& manifest_url, int64 group_id,
- int64 response_id, AppCacheStorage* storage);
+ ResponseInfoLoadTask(const GURL& manifest_url,
+ int64_t group_id,
+ int64_t response_id,
+ AppCacheStorage* storage);
~ResponseInfoLoadTask();
- int64 response_id() const { return response_id_; }
+ int64_t response_id() const { return response_id_; }
const GURL& manifest_url() const { return manifest_url_; }
- int64 group_id() const { return group_id_; }
+ int64_t group_id() const { return group_id_; }
void AddDelegate(DelegateReference* delegate_reference) {
delegates_.push_back(delegate_reference);
@@ -269,14 +274,14 @@ class CONTENT_EXPORT AppCacheStorage {
AppCacheStorage* storage_;
GURL manifest_url_;
- int64 group_id_;
- int64 response_id_;
+ int64_t group_id_;
+ int64_t response_id_;
scoped_ptr<AppCacheResponseReader> reader_;
DelegateReferenceVector delegates_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
};
- typedef std::map<int64, ResponseInfoLoadTask*> PendingResponseInfoLoads;
+ typedef std::map<int64_t, ResponseInfoLoadTask*> PendingResponseInfoLoads;
DelegateReference* GetDelegateReference(Delegate* delegate) {
DelegateReferenceMap::iterator iter =
@@ -294,7 +299,9 @@ class CONTENT_EXPORT AppCacheStorage {
}
ResponseInfoLoadTask* GetOrCreateResponseInfoLoadTask(
- const GURL& manifest_url, int64 group_id, int64 response_id) {
+ const GURL& manifest_url,
+ int64_t group_id,
+ int64_t response_id) {
PendingResponseInfoLoads::iterator iter =
pending_info_loads_.find(response_id);
if (iter != pending_info_loads_.end())
@@ -303,19 +310,17 @@ class CONTENT_EXPORT AppCacheStorage {
}
// Should only be called when creating a new response writer.
- int64 NewResponseId() {
- return ++last_response_id_;
- }
+ int64_t NewResponseId() { return ++last_response_id_; }
// Helpers to query and notify the QuotaManager.
- void UpdateUsageMapAndNotify(const GURL& origin, int64 new_usage);
+ void UpdateUsageMapAndNotify(const GURL& origin, int64_t new_usage);
void ClearUsageMapAndNotify();
void NotifyStorageAccessed(const GURL& origin);
// The last storage id used for different object types.
- int64 last_cache_id_;
- int64 last_group_id_;
- int64 last_response_id_;
+ int64_t last_cache_id_;
+ int64_t last_group_id_;
+ int64_t last_response_id_;
UsageMap usage_map_; // maps origin to usage
AppCacheWorkingSet working_set_;
@@ -324,7 +329,7 @@ class CONTENT_EXPORT AppCacheStorage {
PendingResponseInfoLoads pending_info_loads_;
// The set of last ids must be retrieved from storage prior to being used.
- static const int64 kUnitializedId;
+ static const int64_t kUnitializedId;
FRIEND_TEST_ALL_PREFIXES(content::AppCacheStorageTest, DelegateReferences);
FRIEND_TEST_ALL_PREFIXES(content::AppCacheStorageTest, UsageMap);
diff --git a/chromium/content/browser/appcache/appcache_storage_impl.cc b/chromium/content/browser/appcache/appcache_storage_impl.cc
index 7f1ee9a3fcb..b144eb69f51 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl.cc
+++ b/chromium/content/browser/appcache/appcache_storage_impl.cc
@@ -4,8 +4,11 @@
#include "content/browser/appcache/appcache_storage_impl.h"
+#include <stddef.h>
+
#include <algorithm>
#include <functional>
+#include <limits>
#include <set>
#include <vector>
@@ -19,6 +22,7 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_database.h"
#include "content/browser/appcache/appcache_entry.h"
@@ -49,9 +53,10 @@ static const base::FilePath::CharType kDiskCacheDirectoryName[] =
namespace {
// Helpers for clearing data from the AppCacheDatabase.
-bool DeleteGroupAndRelatedRecords(AppCacheDatabase* database,
- int64 group_id,
- std::vector<int64>* deletable_response_ids) {
+bool DeleteGroupAndRelatedRecords(
+ AppCacheDatabase* database,
+ int64_t group_id,
+ std::vector<int64_t>* deletable_response_ids) {
AppCacheDatabase::CacheRecord cache_record;
bool success = false;
if (database->FindCacheForGroup(group_id, &cache_record)) {
@@ -119,7 +124,7 @@ void ClearSessionOnlyOrigins(
NOTREACHED() << "Failed to start transaction";
return;
}
- std::vector<int64> deletable_response_ids;
+ std::vector<int64_t> deletable_response_ids;
bool success = DeleteGroupAndRelatedRecords(database,
group->group_id,
&deletable_response_ids);
@@ -280,11 +285,11 @@ class AppCacheStorageImpl::InitTask : public DatabaseTask {
private:
base::FilePath db_file_path_;
base::FilePath disk_cache_directory_;
- int64 last_group_id_;
- int64 last_cache_id_;
- int64 last_response_id_;
- int64 last_deletable_response_rowid_;
- std::map<GURL, int64> usage_map_;
+ int64_t last_group_id_;
+ int64_t last_cache_id_;
+ int64_t last_response_id_;
+ int64_t last_deletable_response_rowid_;
+ std::map<GURL, int64_t> usage_map_;
};
void AppCacheStorageImpl::InitTask::Run() {
@@ -402,7 +407,7 @@ class AppCacheStorageImpl::StoreOrLoadTask : public DatabaseTask {
: DatabaseTask(storage) {}
~StoreOrLoadTask() override {}
- bool FindRelatedCacheRecords(int64 cache_id);
+ bool FindRelatedCacheRecords(int64_t cache_id);
void CreateCacheAndGroupFromRecords(
scoped_refptr<AppCache>* cache, scoped_refptr<AppCacheGroup>* group);
@@ -418,7 +423,7 @@ class AppCacheStorageImpl::StoreOrLoadTask : public DatabaseTask {
};
bool AppCacheStorageImpl::StoreOrLoadTask::FindRelatedCacheRecords(
- int64 cache_id) {
+ int64_t cache_id) {
return database_->FindEntriesForCache(cache_id, &entry_records_) &&
database_->FindNamespacesForCache(
cache_id, &intercept_namespace_records_,
@@ -504,9 +509,8 @@ void AppCacheStorageImpl::StoreOrLoadTask::CreateCacheAndGroupFromRecords(
class AppCacheStorageImpl::CacheLoadTask : public StoreOrLoadTask {
public:
- CacheLoadTask(int64 cache_id, AppCacheStorageImpl* storage)
- : StoreOrLoadTask(storage), cache_id_(cache_id),
- success_(false) {}
+ CacheLoadTask(int64_t cache_id, AppCacheStorageImpl* storage)
+ : StoreOrLoadTask(storage), cache_id_(cache_id), success_(false) {}
// DatabaseTask:
void Run() override;
@@ -516,7 +520,7 @@ class AppCacheStorageImpl::CacheLoadTask : public StoreOrLoadTask {
~CacheLoadTask() override {}
private:
- int64 cache_id_;
+ int64_t cache_id_;
bool success_;
};
@@ -607,8 +611,8 @@ class AppCacheStorageImpl::StoreGroupAndCacheTask : public StoreOrLoadTask {
void GetQuotaThenSchedule();
void OnQuotaCallback(storage::QuotaStatusCode status,
- int64 usage,
- int64 quota);
+ int64_t usage,
+ int64_t quota);
// DatabaseTask:
void Run() override;
@@ -623,9 +627,9 @@ class AppCacheStorageImpl::StoreGroupAndCacheTask : public StoreOrLoadTask {
scoped_refptr<AppCache> cache_;
bool success_;
bool would_exceed_quota_;
- int64 space_available_;
- int64 new_origin_usage_;
- std::vector<int64> newly_deletable_response_ids_;
+ int64_t space_available_;
+ int64_t new_origin_usage_;
+ std::vector<int64_t> newly_deletable_response_ids_;
};
AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
@@ -659,11 +663,16 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::GetQuotaThenSchedule() {
if (storage_->service()->special_storage_policy() &&
storage_->service()->special_storage_policy()->IsStorageUnlimited(
group_record_.origin))
- space_available_ = kint64max;
+ space_available_ = std::numeric_limits<int64_t>::max();
Schedule();
return;
}
+ // crbug.com/349708
+ TRACE_EVENT0(
+ "io",
+ "AppCacheStorageImpl::StoreGroupAndCacheTask::GetQuotaThenSchedule");
+
// We have to ask the quota manager for the value.
storage_->pending_quota_queries_.insert(this);
quota_manager->GetUsageAndQuota(
@@ -674,11 +683,11 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::GetQuotaThenSchedule() {
void AppCacheStorageImpl::StoreGroupAndCacheTask::OnQuotaCallback(
storage::QuotaStatusCode status,
- int64 usage,
- int64 quota) {
+ int64_t usage,
+ int64_t quota) {
if (storage_) {
if (status == storage::kQuotaStatusOk)
- space_available_ = std::max(static_cast<int64>(0), quota - usage);
+ space_available_ = std::max(static_cast<int64_t>(0), quota - usage);
else
space_available_ = 0;
storage_->pending_quota_queries_.erase(this);
@@ -696,7 +705,7 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
if (!transaction.Begin())
return;
- int64 old_origin_usage = database_->GetOriginUsage(group_record_.origin);
+ int64_t old_origin_usage = database_->GetOriginUsage(group_record_.origin);
AppCacheDatabase::GroupRecord existing_group;
success_ = database_->FindGroup(group_record_.group_id, &existing_group);
@@ -720,7 +729,7 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
AppCacheDatabase::CacheRecord cache;
if (database_->FindCacheForGroup(group_record_.group_id, &cache)) {
// Get the set of response ids in the old cache.
- std::set<int64> existing_response_ids;
+ std::set<int64_t> existing_response_ids;
database_->FindResponseIdsForCacheAsSet(cache.cache_id,
&existing_response_ids);
@@ -733,7 +742,7 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
}
// The rest are deletable.
- std::set<int64>::const_iterator id_iter = existing_response_ids.begin();
+ std::set<int64_t>::const_iterator id_iter = existing_response_ids.begin();
while (id_iter != existing_response_ids.end()) {
newly_deletable_response_ids_.push_back(*id_iter);
++id_iter;
@@ -783,7 +792,7 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
// Check limits based on the space availbable given to us via the
// quota system.
- int64 delta = new_origin_usage_ - old_origin_usage;
+ int64_t delta = new_origin_usage_ - old_origin_usage;
if (delta > space_available_) {
would_exceed_quota_ = true;
success_ = false;
@@ -834,9 +843,9 @@ class SortByCachePreference
AppCacheDatabase::EntryRecord,
bool> {
public:
- SortByCachePreference(int64 preferred_id, const std::set<int64>& in_use_ids)
- : preferred_id_(preferred_id), in_use_ids_(in_use_ids) {
- }
+ SortByCachePreference(int64_t preferred_id,
+ const std::set<int64_t>& in_use_ids)
+ : preferred_id_(preferred_id), in_use_ids_(in_use_ids) {}
bool operator()(
const AppCacheDatabase::EntryRecord& lhs,
const AppCacheDatabase::EntryRecord& rhs) {
@@ -850,8 +859,8 @@ class SortByCachePreference
return 50;
return 0;
}
- int64 preferred_id_;
- const std::set<int64>& in_use_ids_;
+ int64_t preferred_id_;
+ const std::set<int64_t>& in_use_ids_;
};
bool SortByLength(
@@ -867,7 +876,7 @@ class NetworkNamespaceHelper {
: database_(database) {
}
- bool IsInNetworkNamespace(const GURL& url, int64 cache_id) {
+ bool IsInNetworkNamespace(const GURL& url, int64_t cache_id) {
typedef std::pair<WhiteListMap::iterator, bool> InsertResult;
InsertResult result = namespaces_map_.insert(
WhiteListMap::value_type(cache_id, AppCacheNamespaceVector()));
@@ -877,8 +886,8 @@ class NetworkNamespaceHelper {
}
private:
- void GetOnlineWhiteListForCache(
- int64 cache_id, AppCacheNamespaceVector* namespaces) {
+ void GetOnlineWhiteListForCache(int64_t cache_id,
+ AppCacheNamespaceVector* namespaces) {
DCHECK(namespaces && namespaces->empty());
typedef std::vector<AppCacheDatabase::OnlineWhiteListRecord>
WhiteListVector;
@@ -895,7 +904,7 @@ class NetworkNamespaceHelper {
}
// Key is cache id
- typedef std::map<int64, AppCacheNamespaceVector> WhiteListMap;
+ typedef std::map<int64_t, AppCacheNamespaceVector> WhiteListMap;
WhiteListMap namespaces_map_;
AppCacheDatabase* database_;
};
@@ -935,22 +944,21 @@ class AppCacheStorageImpl::FindMainResponseTask : public DatabaseTask {
typedef std::vector<AppCacheDatabase::NamespaceRecord*>
NamespaceRecordPtrVector;
- bool FindExactMatch(int64 preferred_id);
- bool FindNamespaceMatch(int64 preferred_id);
- bool FindNamespaceHelper(
- int64 preferred_cache_id,
- AppCacheDatabase::NamespaceRecordVector* namespaces,
- NetworkNamespaceHelper* network_namespace_helper);
+ bool FindExactMatch(int64_t preferred_id);
+ bool FindNamespaceMatch(int64_t preferred_id);
+ bool FindNamespaceHelper(int64_t preferred_cache_id,
+ AppCacheDatabase::NamespaceRecordVector* namespaces,
+ NetworkNamespaceHelper* network_namespace_helper);
bool FindFirstValidNamespace(const NamespaceRecordPtrVector& namespaces);
GURL url_;
GURL preferred_manifest_url_;
- std::set<int64> cache_ids_in_use_;
+ std::set<int64_t> cache_ids_in_use_;
AppCacheEntry entry_;
AppCacheEntry fallback_entry_;
GURL namespace_entry_url_;
- int64 cache_id_;
- int64 group_id_;
+ int64_t cache_id_;
+ int64_t group_id_;
GURL manifest_url_;
};
@@ -970,7 +978,7 @@ void AppCacheStorageImpl::FindMainResponseTask::Run() {
// TODO(michaeln): come up with a 'preferred_manifest_url' in more cases
// - when navigating a frame whose current contents are from an appcache
// - when clicking an href in a frame that is appcached
- int64 preferred_cache_id = kAppCacheNoCacheId;
+ int64_t preferred_cache_id = kAppCacheNoCacheId;
if (!preferred_manifest_url_.is_empty()) {
AppCacheDatabase::GroupRecord preferred_group;
AppCacheDatabase::CacheRecord preferred_cache;
@@ -995,8 +1003,8 @@ void AppCacheStorageImpl::FindMainResponseTask::Run() {
group_id_ == 0);
}
-bool AppCacheStorageImpl::
-FindMainResponseTask::FindExactMatch(int64 preferred_cache_id) {
+bool AppCacheStorageImpl::FindMainResponseTask::FindExactMatch(
+ int64_t preferred_cache_id) {
std::vector<AppCacheDatabase::EntryRecord> entries;
if (database_->FindEntriesForUrl(url_, &entries) && !entries.empty()) {
// Sort them in order of preference, from the preferred_cache first,
@@ -1022,8 +1030,8 @@ FindMainResponseTask::FindExactMatch(int64 preferred_cache_id) {
return false;
}
-bool AppCacheStorageImpl::
-FindMainResponseTask::FindNamespaceMatch(int64 preferred_cache_id) {
+bool AppCacheStorageImpl::FindMainResponseTask::FindNamespaceMatch(
+ int64_t preferred_cache_id) {
AppCacheDatabase::NamespaceRecordVector all_intercepts;
AppCacheDatabase::NamespaceRecordVector all_fallbacks;
if (!database_->FindNamespacesForOrigin(
@@ -1044,9 +1052,8 @@ FindMainResponseTask::FindNamespaceMatch(int64 preferred_cache_id) {
return false;
}
-bool AppCacheStorageImpl::
-FindMainResponseTask::FindNamespaceHelper(
- int64 preferred_cache_id,
+bool AppCacheStorageImpl::FindMainResponseTask::FindNamespaceHelper(
+ int64_t preferred_cache_id,
AppCacheDatabase::NamespaceRecordVector* namespaces,
NetworkNamespaceHelper* network_namespace_helper) {
// Sort them by length, longer matches within the same cache/bucket take
@@ -1124,8 +1131,9 @@ void AppCacheStorageImpl::FindMainResponseTask::RunCompleted() {
class AppCacheStorageImpl::MarkEntryAsForeignTask : public DatabaseTask {
public:
- MarkEntryAsForeignTask(
- AppCacheStorageImpl* storage, const GURL& url, int64 cache_id)
+ MarkEntryAsForeignTask(AppCacheStorageImpl* storage,
+ const GURL& url,
+ int64_t cache_id)
: DatabaseTask(storage), cache_id_(cache_id), entry_url_(url) {}
// DatabaseTask:
@@ -1136,7 +1144,7 @@ class AppCacheStorageImpl::MarkEntryAsForeignTask : public DatabaseTask {
~MarkEntryAsForeignTask() override {}
private:
- int64 cache_id_;
+ int64_t cache_id_;
GURL entry_url_;
};
@@ -1168,12 +1176,12 @@ class AppCacheStorageImpl::MakeGroupObsoleteTask : public DatabaseTask {
private:
scoped_refptr<AppCacheGroup> group_;
- int64 group_id_;
+ int64_t group_id_;
GURL origin_;
bool success_;
int response_code_;
- int64 new_origin_usage_;
- std::vector<int64> newly_deletable_response_ids_;
+ int64_t new_origin_usage_;
+ std::vector<int64_t> newly_deletable_response_ids_;
};
AppCacheStorageImpl::MakeGroupObsoleteTask::MakeGroupObsoleteTask(
@@ -1244,7 +1252,7 @@ void AppCacheStorageImpl::MakeGroupObsoleteTask::CancelCompletion() {
class AppCacheStorageImpl::GetDeletableResponseIdsTask : public DatabaseTask {
public:
- GetDeletableResponseIdsTask(AppCacheStorageImpl* storage, int64 max_rowid)
+ GetDeletableResponseIdsTask(AppCacheStorageImpl* storage, int64_t max_rowid)
: DatabaseTask(storage), max_rowid_(max_rowid) {}
// DatabaseTask:
@@ -1255,8 +1263,8 @@ class AppCacheStorageImpl::GetDeletableResponseIdsTask : public DatabaseTask {
~GetDeletableResponseIdsTask() override {}
private:
- int64 max_rowid_;
- std::vector<int64> response_ids_;
+ int64_t max_rowid_;
+ std::vector<int64_t> response_ids_;
};
void AppCacheStorageImpl::GetDeletableResponseIdsTask::Run() {
@@ -1281,7 +1289,7 @@ class AppCacheStorageImpl::InsertDeletableResponseIdsTask
// DatabaseTask:
void Run() override;
- std::vector<int64> response_ids_;
+ std::vector<int64_t> response_ids_;
protected:
~InsertDeletableResponseIdsTask() override {}
@@ -1303,7 +1311,7 @@ class AppCacheStorageImpl::DeleteDeletableResponseIdsTask
// DatabaseTask:
void Run() override;
- std::vector<int64> response_ids_;
+ std::vector<int64_t> response_ids_;
protected:
~DeleteDeletableResponseIdsTask() override {}
@@ -1333,7 +1341,7 @@ class AppCacheStorageImpl::LazyUpdateLastAccessTimeTask
~LazyUpdateLastAccessTimeTask() override {}
private:
- int64 group_id_;
+ int64_t group_id_;
base::Time last_access_time_;
};
@@ -1387,7 +1395,7 @@ class AppCacheStorageImpl::UpdateEvictionTimesTask
~UpdateEvictionTimesTask() override {}
private:
- int64 group_id_;
+ int64_t group_id_;
base::Time last_full_update_check_time_;
base::Time first_evictable_error_time_;
};
@@ -1475,7 +1483,7 @@ void AppCacheStorageImpl::GetAllInfo(Delegate* delegate) {
task->Schedule();
}
-void AppCacheStorageImpl::LoadCache(int64 id, Delegate* delegate) {
+void AppCacheStorageImpl::LoadCache(int64_t id, Delegate* delegate) {
DCHECK(delegate);
if (is_disabled_) {
delegate->OnCacheLoaded(NULL, id);
@@ -1661,9 +1669,13 @@ void AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse(
void AppCacheStorageImpl::CallOnMainResponseFound(
DelegateReferenceVector* delegates,
- const GURL& url, const AppCacheEntry& entry,
- const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry,
- int64 cache_id, int64 group_id, const GURL& manifest_url) {
+ const GURL& url,
+ const AppCacheEntry& entry,
+ const GURL& namespace_entry_url,
+ const AppCacheEntry& fallback_entry,
+ int64_t cache_id,
+ int64_t group_id,
+ const GURL& manifest_url) {
FOR_EACH_DELEGATE(
(*delegates),
OnMainResponseFound(url, entry,
@@ -1695,8 +1707,8 @@ void AppCacheStorageImpl::FindResponseForSubRequest(
found_network_namespace);
}
-void AppCacheStorageImpl::MarkEntryAsForeign(
- const GURL& entry_url, int64 cache_id) {
+void AppCacheStorageImpl::MarkEntryAsForeign(const GURL& entry_url,
+ int64_t cache_id) {
AppCache* cache = working_set_.GetCache(cache_id);
if (cache) {
AppCacheEntry* entry = cache->GetEntry(entry_url);
@@ -1727,24 +1739,28 @@ void AppCacheStorageImpl::StoreEvictionTimes(AppCacheGroup* group) {
}
AppCacheResponseReader* AppCacheStorageImpl::CreateResponseReader(
- const GURL& manifest_url, int64 group_id, int64 response_id) {
+ const GURL& manifest_url,
+ int64_t group_id,
+ int64_t response_id) {
return new AppCacheResponseReader(response_id, group_id, disk_cache());
}
AppCacheResponseWriter* AppCacheStorageImpl::CreateResponseWriter(
- const GURL& manifest_url, int64 group_id) {
+ const GURL& manifest_url,
+ int64_t group_id) {
return new AppCacheResponseWriter(NewResponseId(), group_id, disk_cache());
}
AppCacheResponseMetadataWriter*
-AppCacheStorageImpl::CreateResponseMetadataWriter(int64 group_id,
- int64 response_id) {
+AppCacheStorageImpl::CreateResponseMetadataWriter(int64_t group_id,
+ int64_t response_id) {
return new AppCacheResponseMetadataWriter(response_id, group_id,
disk_cache());
}
void AppCacheStorageImpl::DoomResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids) {
+ const GURL& manifest_url,
+ const std::vector<int64_t>& response_ids) {
if (response_ids.empty())
return;
@@ -1763,7 +1779,8 @@ void AppCacheStorageImpl::DoomResponses(
}
void AppCacheStorageImpl::DeleteResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids) {
+ const GURL& manifest_url,
+ const std::vector<int64_t>& response_ids) {
if (response_ids.empty())
return;
StartDeletingResponses(response_ids);
@@ -1779,7 +1796,7 @@ void AppCacheStorageImpl::DelayedStartDeletingUnusedResponses() {
}
void AppCacheStorageImpl::StartDeletingResponses(
- const std::vector<int64>& response_ids) {
+ const std::vector<int64_t>& response_ids) {
DCHECK(!response_ids.empty());
did_start_deleting_responses_ = true;
deletable_response_ids_.insert(
@@ -1812,7 +1829,7 @@ void AppCacheStorageImpl::DeleteOneResponse() {
}
// TODO(michaeln): add group_id to DoomEntry args
- int64 id = deletable_response_ids_.front();
+ int64_t id = deletable_response_ids_.front();
int rv = disk_cache_->DoomEntry(
id, base::Bind(&AppCacheStorageImpl::OnDeletedOneResponse,
base::Unretained(this)));
@@ -1825,7 +1842,7 @@ void AppCacheStorageImpl::OnDeletedOneResponse(int rv) {
if (is_disabled_)
return;
- int64 id = deletable_response_ids_.front();
+ int64_t id = deletable_response_ids_.front();
deletable_response_ids_.pop_front();
if (rv != net::ERR_ABORTED)
deleted_response_ids_.push_back(id);
@@ -1850,7 +1867,7 @@ void AppCacheStorageImpl::OnDeletedOneResponse(int rv) {
}
AppCacheStorageImpl::CacheLoadTask*
-AppCacheStorageImpl::GetPendingCacheLoadTask(int64 cache_id) {
+AppCacheStorageImpl::GetPendingCacheLoadTask(int64_t cache_id) {
PendingCacheLoads::iterator found = pending_cache_loads_.find(cache_id);
if (found != pending_cache_loads_.end())
return found->second;
@@ -1866,7 +1883,8 @@ AppCacheStorageImpl::GetPendingGroupLoadTask(const GURL& manifest_url) {
}
void AppCacheStorageImpl::GetPendingForeignMarkingsForCache(
- int64 cache_id, std::vector<GURL>* urls) {
+ int64_t cache_id,
+ std::vector<GURL>* urls) {
PendingForeignMarkings::iterator iter = pending_foreign_markings_.begin();
while (iter != pending_foreign_markings_.end()) {
if (iter->second == cache_id)
diff --git a/chromium/content/browser/appcache/appcache_storage_impl.h b/chromium/content/browser/appcache/appcache_storage_impl.h
index 2d1162ec683..664ba31f97e 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl.h
+++ b/chromium/content/browser/appcache/appcache_storage_impl.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_
+#include <stdint.h>
+
#include <deque>
#include <map>
#include <set>
@@ -43,7 +45,7 @@ class AppCacheStorageImpl : public AppCacheStorage {
// AppCacheStorage methods, see the base class for doc comments.
void GetAllInfo(Delegate* delegate) override;
- void LoadCache(int64 id, Delegate* delegate) override;
+ void LoadCache(int64_t id, Delegate* delegate) override;
void LoadOrCreateGroup(const GURL& manifest_url, Delegate* delegate) override;
void StoreGroupAndNewestCache(AppCacheGroup* group,
AppCache* newest_cache,
@@ -56,23 +58,23 @@ class AppCacheStorageImpl : public AppCacheStorage {
AppCacheEntry* found_entry,
AppCacheEntry* found_fallback_entry,
bool* found_network_namespace) override;
- void MarkEntryAsForeign(const GURL& entry_url, int64 cache_id) override;
+ void MarkEntryAsForeign(const GURL& entry_url, int64_t cache_id) override;
void MakeGroupObsolete(AppCacheGroup* group,
Delegate* delegate,
int response_code) override;
void StoreEvictionTimes(AppCacheGroup* group) override;
AppCacheResponseReader* CreateResponseReader(const GURL& manifest_url,
- int64 group_id,
- int64 response_id) override;
+ int64_t group_id,
+ int64_t response_id) override;
AppCacheResponseWriter* CreateResponseWriter(const GURL& manifest_url,
- int64 group_id) override;
+ int64_t group_id) override;
AppCacheResponseMetadataWriter* CreateResponseMetadataWriter(
- int64 group_id,
- int64 response_id) override;
+ int64_t group_id,
+ int64_t response_id) override;
void DoomResponses(const GURL& manifest_url,
- const std::vector<int64>& response_ids) override;
+ const std::vector<int64_t>& response_ids) override;
void DeleteResponses(const GURL& manifest_url,
- const std::vector<int64>& response_ids) override;
+ const std::vector<int64_t>& response_ids) override;
private:
// The AppCacheStorageImpl class methods and datamembers may only be
@@ -97,25 +99,25 @@ class AppCacheStorageImpl : public AppCacheStorage {
class UpdateEvictionTimesTask;
typedef std::deque<DatabaseTask*> DatabaseTaskQueue;
- typedef std::map<int64, CacheLoadTask*> PendingCacheLoads;
+ typedef std::map<int64_t, CacheLoadTask*> PendingCacheLoads;
typedef std::map<GURL, GroupLoadTask*> PendingGroupLoads;
- typedef std::deque<std::pair<GURL, int64> > PendingForeignMarkings;
+ typedef std::deque<std::pair<GURL, int64_t>> PendingForeignMarkings;
typedef std::set<StoreGroupAndCacheTask*> PendingQuotaQueries;
bool IsInitTaskComplete() {
return last_cache_id_ != AppCacheStorage::kUnitializedId;
}
- CacheLoadTask* GetPendingCacheLoadTask(int64 cache_id);
+ CacheLoadTask* GetPendingCacheLoadTask(int64_t cache_id);
GroupLoadTask* GetPendingGroupLoadTask(const GURL& manifest_url);
- void GetPendingForeignMarkingsForCache(
- int64 cache_id, std::vector<GURL>* urls);
+ void GetPendingForeignMarkingsForCache(int64_t cache_id,
+ std::vector<GURL>* urls);
void ScheduleSimpleTask(const base::Closure& task);
void RunOnePendingSimpleTask();
void DelayedStartDeletingUnusedResponses();
- void StartDeletingResponses(const std::vector<int64>& response_ids);
+ void StartDeletingResponses(const std::vector<int64_t>& response_ids);
void ScheduleDeleteOneResponse();
void DeleteOneResponse();
void OnDeletedOneResponse(int rv);
@@ -136,11 +138,14 @@ class AppCacheStorageImpl : public AppCacheStorage {
scoped_refptr<AppCache> newest_cache,
scoped_refptr<DelegateReference> delegate_ref);
- void CallOnMainResponseFound(
- DelegateReferenceVector* delegates,
- const GURL& url, const AppCacheEntry& entry,
- const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry,
- int64 cache_id, int64 group_id, const GURL& manifest_url);
+ void CallOnMainResponseFound(DelegateReferenceVector* delegates,
+ const GURL& url,
+ const AppCacheEntry& entry,
+ const GURL& namespace_entry_url,
+ const AppCacheEntry& fallback_entry,
+ int64_t cache_id,
+ int64_t group_id,
+ const GURL& manifest_url);
CONTENT_EXPORT AppCacheDiskCache* disk_cache();
@@ -162,11 +167,11 @@ class AppCacheStorageImpl : public AppCacheStorage {
PendingQuotaQueries pending_quota_queries_;
// Structures to keep track of lazy response deletion.
- std::deque<int64> deletable_response_ids_;
- std::vector<int64> deleted_response_ids_;
+ std::deque<int64_t> deletable_response_ids_;
+ std::vector<int64_t> deleted_response_ids_;
bool is_response_deletion_scheduled_;
bool did_start_deleting_responses_;
- int64 last_deletable_response_rowid_;
+ int64_t last_deletable_response_rowid_;
// Created on the IO thread, but only used on the DB thread.
AppCacheDatabase* database_;
diff --git a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
index 669db8c8207..9e4c2c4e6df 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -2,7 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/appcache/appcache_storage_impl.h"
+
+#include <stdint.h>
#include <stack>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -10,6 +14,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
@@ -24,7 +29,6 @@
#include "content/browser/appcache/appcache_interceptor.h"
#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/appcache/appcache_service_impl.h"
-#include "content/browser/appcache/appcache_storage_impl.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
@@ -100,16 +104,16 @@ class MockHttpServer {
std::string* headers,
std::string* body) {
const char manifest_headers[] =
- "HTTP/1.1 200 OK\0"
- "Content-type: text/cache-manifest\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-type: text/cache-manifest\n"
+ "\n";
const char page_headers[] =
- "HTTP/1.1 200 OK\0"
- "Content-type: text/html\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-type: text/html\n"
+ "\n";
const char not_found_headers[] =
- "HTTP/1.1 404 NOT FOUND\0"
- "\0";
+ "HTTP/1.1 404 NOT FOUND\n"
+ "\n";
if (path == "/manifest") {
(*headers) = std::string(manifest_headers, arraysize(manifest_headers));
@@ -129,9 +133,8 @@ class MockHttpServerJobFactory
: public net::URLRequestJobFactory::ProtocolHandler {
public:
MockHttpServerJobFactory(
- scoped_ptr<net::URLRequestInterceptor> appcache_start_interceptor)
- : appcache_start_interceptor_(appcache_start_interceptor.Pass()) {
- }
+ scoped_ptr<net::URLRequestInterceptor> appcache_start_interceptor)
+ : appcache_start_interceptor_(std::move(appcache_start_interceptor)) {}
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
@@ -165,7 +168,7 @@ class IOThread : public base::Thread {
factory->SetProtocolHandler(
"http", make_scoped_ptr(new MockHttpServerJobFactory(
make_scoped_ptr(new AppCacheInterceptor()))));
- job_factory_ = factory.Pass();
+ job_factory_ = std::move(factory);
request_context_.reset(new net::TestURLRequestContext());
request_context_->set_job_factory(job_factory_.get());
}
@@ -195,7 +198,7 @@ class AppCacheStorageImplTest : public testing::Test {
found_cache_id_(kAppCacheNoCacheId), test_(test) {
}
- void OnCacheLoaded(AppCache* cache, int64 cache_id) override {
+ void OnCacheLoaded(AppCache* cache, int64_t cache_id) override {
loaded_cache_ = cache;
loaded_cache_id_ = cache_id;
test_->ScheduleNextTask();
@@ -232,8 +235,8 @@ class AppCacheStorageImplTest : public testing::Test {
const AppCacheEntry& entry,
const GURL& namespace_entry_url,
const AppCacheEntry& fallback_entry,
- int64 cache_id,
- int64 group_id,
+ int64_t cache_id,
+ int64_t group_id,
const GURL& manifest_url) override {
found_url_ = url;
found_entry_ = entry;
@@ -246,7 +249,7 @@ class AppCacheStorageImplTest : public testing::Test {
}
scoped_refptr<AppCache> loaded_cache_;
- int64 loaded_cache_id_;
+ int64_t loaded_cache_id_;
scoped_refptr<AppCacheGroup> loaded_group_;
GURL loaded_manifest_url_;
scoped_refptr<AppCache> loaded_groups_newest_cache_;
@@ -259,8 +262,8 @@ class AppCacheStorageImplTest : public testing::Test {
AppCacheEntry found_entry_;
GURL found_namespace_entry_url_;
AppCacheEntry found_fallback_entry_;
- int64 found_cache_id_;
- int64 found_group_id_;
+ int64_t found_cache_id_;
+ int64_t found_group_id_;
GURL found_manifest_url_;
AppCacheStorageImplTest* test_;
};
@@ -321,7 +324,7 @@ class AppCacheStorageImplTest : public testing::Test {
void NotifyStorageModified(storage::QuotaClient::ID client_id,
const GURL& origin,
storage::StorageType type,
- int64 delta) override {
+ int64_t delta) override {
EXPECT_EQ(storage::QuotaClient::kAppcache, client_id);
EXPECT_EQ(storage::kStorageTypeTemporary, type);
++notify_storage_modified_count_;
@@ -391,8 +394,7 @@ class AppCacheStorageImplTest : public testing::Test {
// Test harness --------------------------------------------------
- AppCacheStorageImplTest() {
- }
+ AppCacheStorageImplTest() { request_delegate_.set_quit_on_complete(false); }
template <class Method>
void RunTestOnIOThread(Method method) {
@@ -493,7 +495,7 @@ class AppCacheStorageImplTest : public testing::Test {
// Setup some preconditions. Make an 'unstored' cache for
// us to load. The ctor should put it in the working set.
- int64 cache_id = storage()->NewCacheId();
+ int64_t cache_id = storage()->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(storage(), cache_id));
// Conduct the test.
@@ -764,7 +766,7 @@ class AppCacheStorageImplTest : public testing::Test {
// Setup some preconditions. Create a group and newest cache that
// appear to be "unstored" and big enough to exceed the 5M limit.
- const int64 kTooBig = 10 * 1024 * 1024; // 10M
+ const int64_t kTooBig = 10 * 1024 * 1024; // 10M
group_ = new AppCacheGroup(
storage(), kManifestUrl, storage()->NewGroupId());
cache_ = new AppCache(storage(), storage()->NewCacheId());
@@ -1765,7 +1767,7 @@ class AppCacheStorageImplTest : public testing::Test {
AppCacheHost* host2 = backend_->GetHost(2);
GURL manifest_url = MockHttpServer::GetMockUrl("manifest");
request_ = service()->request_context()->CreateRequest(
- manifest_url, net::DEFAULT_PRIORITY, NULL);
+ manifest_url, net::DEFAULT_PRIORITY, &request_delegate_);
AppCacheInterceptor::SetExtraRequestInfo(
request_.get(), service_.get(),
backend_->process_id(), host2->host_id(),
@@ -1837,9 +1839,10 @@ class AppCacheStorageImplTest : public testing::Test {
return delegate_.get();
}
- void MakeCacheAndGroup(
- const GURL& manifest_url, int64 group_id, int64 cache_id,
- bool add_to_database) {
+ void MakeCacheAndGroup(const GURL& manifest_url,
+ int64_t group_id,
+ int64_t cache_id,
+ bool add_to_database) {
AppCacheEntry default_entry(
AppCacheEntry::EXPLICIT, cache_id + kDefaultEntryIdOffset,
kDefaultEntrySize);
@@ -1890,6 +1893,7 @@ class AppCacheStorageImplTest : public testing::Test {
scoped_ptr<MockServiceObserver> observer_;
MockAppCacheFrontend frontend_;
scoped_ptr<AppCacheBackendImpl> backend_;
+ net::TestDelegate request_delegate_;
scoped_ptr<net::URLRequest> request_;
};
diff --git a/chromium/content/browser/appcache/appcache_unittest.cc b/chromium/content/browser/appcache/appcache_unittest.cc
index 4062498e95e..6bf5d797741 100644
--- a/chromium/content/browser/appcache/appcache_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/browser/appcache/mock_appcache_service.h"
@@ -62,8 +65,8 @@ TEST(AppCacheTest, AddModifyRemoveEntry) {
EXPECT_EQ(0L, cache->cache_size());
const GURL kFooUrl("http://foo.com");
- const int64 kFooResponseId = 1;
- const int64 kFooSize = 100;
+ const int64_t kFooResponseId = 1;
+ const int64_t kFooSize = 100;
AppCacheEntry entry1(AppCacheEntry::MASTER, kFooResponseId, kFooSize);
cache->AddEntry(kFooUrl, entry1);
EXPECT_EQ(entry1.types(), cache->GetEntry(kFooUrl)->types());
@@ -71,8 +74,8 @@ TEST(AppCacheTest, AddModifyRemoveEntry) {
EXPECT_EQ(kFooSize, cache->cache_size());
const GURL kBarUrl("http://bar.com");
- const int64 kBarResponseId = 2;
- const int64 kBarSize = 200;
+ const int64_t kBarResponseId = 2;
+ const int64_t kBarSize = 200;
AppCacheEntry entry2(AppCacheEntry::FALLBACK, kBarResponseId, kBarSize);
EXPECT_TRUE(cache->AddOrModifyEntry(kBarUrl, entry2));
EXPECT_EQ(entry2.types(), cache->GetEntry(kBarUrl)->types());
@@ -165,12 +168,12 @@ TEST(AppCacheTest, FindResponseForRequest) {
const GURL kOnlineNamespaceWithinOtherNamespaces(
"http://blah/fallback_namespace/intercept_namespace/1/online");
- const int64 kFallbackResponseId1 = 1;
- const int64 kFallbackResponseId2 = 2;
- const int64 kManifestResponseId = 3;
- const int64 kForeignExplicitResponseId = 4;
- const int64 kExplicitInOnlineNamespaceResponseId = 5;
- const int64 kInterceptResponseId = 6;
+ const int64_t kFallbackResponseId1 = 1;
+ const int64_t kFallbackResponseId2 = 2;
+ const int64_t kManifestResponseId = 3;
+ const int64_t kForeignExplicitResponseId = 4;
+ const int64_t kExplicitInOnlineNamespaceResponseId = 5;
+ const int64_t kInterceptResponseId = 6;
AppCacheManifest manifest;
manifest.online_whitelist_namespaces.push_back(
@@ -362,7 +365,7 @@ TEST(AppCacheTest, FindInterceptPatternResponseForRequest) {
const GURL kInterceptPatternNamespace(
kInterceptNamespaceBase.Resolve("*.hit*"));
const GURL kInterceptNamespaceEntry("http://blah/intercept_resource");
- const int64 kInterceptResponseId = 1;
+ const int64_t kInterceptResponseId = 1;
AppCacheManifest manifest;
manifest.intercept_namespaces.push_back(
AppCacheNamespace(APPCACHE_INTERCEPT_NAMESPACE,
@@ -433,7 +436,7 @@ TEST(AppCacheTest, FindFallbackPatternResponseForRequest) {
const GURL kFallbackPatternNamespace(
kFallbackNamespaceBase.Resolve("*.hit*"));
const GURL kFallbackNamespaceEntry("http://blah/fallback_resource");
- const int64 kFallbackResponseId = 1;
+ const int64_t kFallbackResponseId = 1;
AppCacheManifest manifest;
manifest.fallback_namespaces.push_back(
AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE, kFallbackPatternNamespace,
@@ -541,8 +544,8 @@ TEST(AppCacheTest, FindNetworkNamespacePatternResponseForRequest) {
TEST(AppCacheTest, ToFromDatabaseRecords) {
// Setup a cache with some entries.
- const int64 kCacheId = 1234;
- const int64 kGroupId = 4321;
+ const int64_t kCacheId = 1234;
+ const int64_t kGroupId = 4321;
const GURL kManifestUrl("http://foo.com/manifest");
const GURL kInterceptUrl("http://foo.com/intercept.html");
const GURL kFallbackUrl("http://foo.com/fallback.html");
diff --git a/chromium/content/browser/appcache/appcache_update_job.cc b/chromium/content/browser/appcache/appcache_update_job.cc
index 24700465026..b6ab3fb7318 100644
--- a/chromium/content/browser/appcache/appcache_update_job.cc
+++ b/chromium/content/browser/appcache/appcache_update_job.cc
@@ -20,6 +20,7 @@
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_context.h"
+#include "url/origin.h"
namespace content {
@@ -163,6 +164,7 @@ AppCacheUpdateJob::URLFetcher::~URLFetcher() {
void AppCacheUpdateJob::URLFetcher::Start() {
request_->set_first_party_for_cookies(job_->manifest_url_);
+ request_->set_initiator(url::Origin(job_->manifest_url_));
if (fetch_type_ == MANIFEST_FETCH && job_->doing_full_update_check_)
request_->SetLoadFlags(request_->load_flags() | net::LOAD_BYPASS_CACHE);
else if (existing_response_headers_.get())
@@ -174,7 +176,7 @@ void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect(
net::URLRequest* request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) {
- DCHECK(request_ == request);
+ DCHECK_EQ(request_.get(), request);
// Redirect is not allowed by the update process.
job_->MadeProgress();
redirect_response_code_ = request->GetResponseCode();
@@ -185,7 +187,7 @@ void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect(
void AppCacheUpdateJob::URLFetcher::OnResponseStarted(
net::URLRequest *request) {
- DCHECK(request == request_);
+ DCHECK_EQ(request_.get(), request);
int response_code = -1;
if (request->status().is_success()) {
response_code = request->GetResponseCode();
@@ -244,7 +246,7 @@ void AppCacheUpdateJob::URLFetcher::OnResponseStarted(
void AppCacheUpdateJob::URLFetcher::OnReadCompleted(
net::URLRequest* request, int bytes_read) {
- DCHECK(request_ == request);
+ DCHECK_EQ(request_.get(), request);
bool data_consumed = true;
if (request->status().is_success() && bytes_read > 0) {
job_->MadeProgress();
@@ -270,7 +272,8 @@ void AppCacheUpdateJob::URLFetcher::OnReadCompleted(
void AppCacheUpdateJob::URLFetcher::AddConditionalHeaders(
const net::HttpResponseHeaders* headers) {
- DCHECK(request_.get() && headers);
+ DCHECK(request_);
+ DCHECK(headers);
net::HttpRequestHeaders extra_headers;
// Add If-Modified-Since header if response info has Last-Modified header.
@@ -1446,7 +1449,8 @@ bool AppCacheUpdateJob::MaybeLoadFromNewestCache(const GURL& url,
}
void AppCacheUpdateJob::OnResponseInfoLoaded(
- AppCacheResponseInfo* response_info, int64 response_id) {
+ AppCacheResponseInfo* response_info,
+ int64_t response_id) {
const net::HttpResponseInfo* http_info = response_info ?
response_info->http_response_info() : NULL;
diff --git a/chromium/content/browser/appcache/appcache_update_job.h b/chromium/content/browser/appcache/appcache_update_job.h
index eaee83b9e3d..f1c7af03bd5 100644
--- a/chromium/content/browser/appcache/appcache_update_job.h
+++ b/chromium/content/browser/appcache/appcache_update_job.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <map>
#include <set>
@@ -12,6 +15,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
@@ -63,7 +67,7 @@ class CONTENT_EXPORT AppCacheUpdateJob
typedef std::vector<AppCacheHost*> PendingHosts;
typedef std::map<GURL, PendingHosts> PendingMasters;
typedef std::map<GURL, URLFetcher*> PendingUrlFetches;
- typedef std::map<int64, GURL> LoadingResponses;
+ typedef std::map<int64_t, GURL> LoadingResponses;
static const int kRerunDelayMs = 1000;
@@ -166,7 +170,7 @@ class CONTENT_EXPORT AppCacheUpdateJob
// Methods for AppCacheStorage::Delegate.
void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
- int64 response_id) override;
+ int64_t response_id) override;
void OnGroupAndNewestCacheStored(AppCacheGroup* group,
AppCache* newest_cache,
bool success,
@@ -325,14 +329,14 @@ class CONTENT_EXPORT AppCacheUpdateJob
// Response ids stored by this update job, used to cleanup in
// error conditions.
- std::vector<int64> stored_response_ids_;
+ std::vector<int64_t> stored_response_ids_;
// In some cases we fetch the same resource multiple times, and then
// have to delete the duplicates upon successful update. These ids
// are also in the stored_response_ids_ collection so we only schedule
// these for deletion on success.
// TODO(michaeln): Rework when we no longer fetches master entries directly.
- std::vector<int64> duplicate_response_ids_;
+ std::vector<int64_t> duplicate_response_ids_;
// Whether we've stored the resulting group/cache yet.
StoredState stored_state_;
diff --git a/chromium/content/browser/appcache/appcache_update_job_unittest.cc b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
index 569532a2078..9820bc273bf 100644
--- a/chromium/content/browser/appcache/appcache_update_job_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
@@ -2,9 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/appcache/appcache_update_job.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
@@ -13,7 +20,6 @@
#include "content/browser/appcache/appcache_group.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/browser/appcache/appcache_response.h"
-#include "content/browser/appcache/appcache_update_job.h"
#include "content/browser/appcache/mock_appcache_service.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
@@ -78,28 +84,28 @@ class MockHttpServer {
std::string* headers,
std::string* body) {
const char ok_headers[] =
- "HTTP/1.1 200 OK\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "\n";
const char error_headers[] =
- "HTTP/1.1 500 BOO HOO\0"
- "\0";
+ "HTTP/1.1 500 BOO HOO\n"
+ "\n";
const char manifest_headers[] =
- "HTTP/1.1 200 OK\0"
- "Content-type: text/cache-manifest\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-type: text/cache-manifest\n"
+ "\n";
const char not_modified_headers[] =
- "HTTP/1.1 304 NOT MODIFIED\0"
- "\0";
+ "HTTP/1.1 304 NOT MODIFIED\n"
+ "\n";
const char gone_headers[] =
- "HTTP/1.1 410 GONE\0"
- "\0";
+ "HTTP/1.1 410 GONE\n"
+ "\n";
const char not_found_headers[] =
- "HTTP/1.1 404 NOT FOUND\0"
- "\0";
+ "HTTP/1.1 404 NOT FOUND\n"
+ "\n";
const char no_store_headers[] =
- "HTTP/1.1 200 OK\0"
- "Cache-Control: no-store\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Cache-Control: no-store\n"
+ "\n";
if (path == "/files/missing-mime-manifest") {
(*headers) = std::string(ok_headers, arraysize(ok_headers));
@@ -410,16 +416,16 @@ class RetryRequestTestJob : public net::URLRequestTestJob {
static std::string retry_headers() {
const char no_retry_after[] =
- "HTTP/1.1 503 BOO HOO\0"
- "\0";
+ "HTTP/1.1 503 BOO HOO\n"
+ "\n";
const char nonzero[] =
- "HTTP/1.1 503 BOO HOO\0"
- "Retry-After: 60\0"
- "\0";
+ "HTTP/1.1 503 BOO HOO\n"
+ "Retry-After: 60\n"
+ "\n";
const char retry_after_0[] =
- "HTTP/1.1 503 BOO HOO\0"
- "Retry-After: 0\0"
- "\0";
+ "HTTP/1.1 503 BOO HOO\n"
+ "Retry-After: 0\n"
+ "\n";
switch (retry_after_) {
case NO_RETRY_AFTER:
@@ -434,9 +440,9 @@ class RetryRequestTestJob : public net::URLRequestTestJob {
static std::string manifest_headers() {
const char headers[] =
- "HTTP/1.1 200 OK\0"
- "Content-type: text/cache-manifest\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-type: text/cache-manifest\n"
+ "\n";
return std::string(headers, arraysize(headers));
}
@@ -578,7 +584,7 @@ class IOThread : public base::Thread {
make_scoped_ptr(new MockHttpServerJobFactory));
factory->SetProtocolHandler("https",
make_scoped_ptr(new MockHttpServerJobFactory));
- job_factory_ = factory.Pass();
+ job_factory_ = std::move(factory);
request_context_.reset(new net::TestURLRequestContext());
request_context_->set_job_factory(job_factory_.get());
}
@@ -1233,10 +1239,9 @@ class AppCacheUpdateJobTest : public testing::Test,
expect_group_obsolete_ = false;
expect_group_has_cache_ = true;
expect_old_cache_ = cache;
- expect_response_ids_.insert(
- std::map<GURL, int64>::value_type(
- MockHttpServer::GetMockUrl("files/explicit1"),
- response_writer_->response_id()));
+ expect_response_ids_.insert(std::map<GURL, int64_t>::value_type(
+ MockHttpServer::GetMockUrl("files/explicit1"),
+ response_writer_->response_id()));
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids(1, host->host_id());
frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT);
@@ -1570,9 +1575,9 @@ class AppCacheUpdateJobTest : public testing::Test,
expect_extra_entries_.insert(AppCache::EntryMap::value_type(
MockHttpServer::GetMockUrl("files/notmodified"),
AppCacheEntry(AppCacheEntry::EXPLICIT)));
- expect_response_ids_.insert(std::map<GURL, int64>::value_type(
+ expect_response_ids_.insert(std::map<GURL, int64_t>::value_type(
MockHttpServer::GetMockUrl("files/servererror"), 444)); // copied
- expect_response_ids_.insert(std::map<GURL, int64>::value_type(
+ expect_response_ids_.insert(std::map<GURL, int64_t>::value_type(
MockHttpServer::GetMockUrl("files/notmodified"), 555)); // copied
MockFrontend::HostIds ids1(1, host1->host_id());
frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
@@ -1931,7 +1936,7 @@ class AppCacheUpdateJobTest : public testing::Test,
storage->SimulateStoreGroupAndNewestCacheFailure();
const GURL kManifestUrl = MockHttpServer::GetMockUrl("files/notmodified");
- const int64 kManifestResponseId = 11;
+ const int64_t kManifestResponseId = 11;
// Seed the response_info working set with canned data for
// files/servererror and for files/notmodified to test that the
@@ -3058,13 +3063,14 @@ class AppCacheUpdateJobTest : public testing::Test,
service_->set_request_context(io_thread_->request_context());
}
- AppCache* MakeCacheForGroup(int64 cache_id, int64 manifest_response_id) {
+ AppCache* MakeCacheForGroup(int64_t cache_id, int64_t manifest_response_id) {
return MakeCacheForGroup(cache_id, group_->manifest_url(),
manifest_response_id);
}
- AppCache* MakeCacheForGroup(int64 cache_id, const GURL& manifest_entry_url,
- int64 manifest_response_id) {
+ AppCache* MakeCacheForGroup(int64_t cache_id,
+ const GURL& manifest_entry_url,
+ int64_t manifest_response_id) {
AppCache* cache = new AppCache(service_->storage(), cache_id);
cache->set_complete(true);
cache->set_update_time(base::Time::Now() - kOneHour);
@@ -3090,7 +3096,8 @@ class AppCacheUpdateJobTest : public testing::Test,
}
AppCacheResponseInfo* MakeAppCacheResponseInfo(
- const GURL& manifest_url, int64 response_id,
+ const GURL& manifest_url,
+ int64_t response_id,
const std::string& raw_headers) {
net::HttpResponseInfo* http_info = new net::HttpResponseInfo();
http_info->headers = new net::HttpResponseHeaders(raw_headers);
@@ -3172,7 +3179,7 @@ class AppCacheUpdateJobTest : public testing::Test,
// Check that any copied entries have the expected response id
// and that entries that are not copied have a different response id.
- std::map<GURL, int64>::iterator found =
+ std::map<GURL, int64_t>::iterator found =
expect_response_ids_.find(it->first);
if (found != expect_response_ids_.end()) {
EXPECT_EQ(found->second, it->second.response_id());
@@ -3448,7 +3455,7 @@ class AppCacheUpdateJobTest : public testing::Test,
TestedManifest tested_manifest_;
const char* tested_manifest_path_override_;
AppCache::EntryMap expect_extra_entries_;
- std::map<GURL, int64> expect_response_ids_;
+ std::map<GURL, int64_t> expect_response_ids_;
};
TEST_F(AppCacheUpdateJobTest, AlreadyChecking) {
diff --git a/chromium/content/browser/appcache/appcache_url_request_job.cc b/chromium/content/browser/appcache/appcache_url_request_job.cc
index d66c795ce53..05fe008b54e 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job.cc
+++ b/chromium/content/browser/appcache/appcache_url_request_job.cc
@@ -36,7 +36,8 @@ AppCacheURLRequestJob::AppCacheURLRequestJob(
net::NetworkDelegate* network_delegate,
AppCacheStorage* storage,
AppCacheHost* host,
- bool is_main_resource)
+ bool is_main_resource,
+ const OnPrepareToRestartCallback& restart_callback)
: net::URLRequestJob(request, network_delegate),
host_(host),
storage_(storage),
@@ -45,13 +46,21 @@ AppCacheURLRequestJob::AppCacheURLRequestJob(
group_id_(0), cache_id_(kAppCacheNoCacheId), is_fallback_(false),
is_main_resource_(is_main_resource),
cache_entry_not_found_(false),
+ on_prepare_to_restart_callback_(restart_callback),
weak_factory_(this) {
DCHECK(storage_);
}
-void AppCacheURLRequestJob::DeliverAppCachedResponse(
- const GURL& manifest_url, int64 group_id, int64 cache_id,
- const AppCacheEntry& entry, bool is_fallback) {
+AppCacheURLRequestJob::~AppCacheURLRequestJob() {
+ if (storage_)
+ storage_->CancelDelegateCallbacks(this);
+}
+
+void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url,
+ int64_t group_id,
+ int64_t cache_id,
+ const AppCacheEntry& entry,
+ bool is_fallback) {
DCHECK(!has_delivery_orders());
DCHECK(entry.has_response_id());
delivery_type_ = APPCACHED_DELIVERY;
@@ -77,6 +86,10 @@ void AppCacheURLRequestJob::DeliverErrorResponse() {
MaybeBeginDelivery();
}
+base::WeakPtr<AppCacheURLRequestJob> AppCacheURLRequestJob::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
void AppCacheURLRequestJob::MaybeBeginDelivery() {
if (has_been_started() && has_delivery_orders()) {
// Start asynchronously so that all error reporting and data
@@ -156,7 +169,7 @@ void AppCacheURLRequestJob::BeginExecutableHandlerDelivery() {
storage_->LoadCache(cache_id_, this);
}
-void AppCacheURLRequestJob::OnCacheLoaded(AppCache* cache, int64 cache_id) {
+void AppCacheURLRequestJob::OnCacheLoaded(AppCache* cache, int64_t cache_id) {
DCHECK_EQ(cache_id_, cache_id);
DCHECK(!has_been_killed());
@@ -185,7 +198,7 @@ void AppCacheURLRequestJob::OnCacheLoaded(AppCache* cache, int64 cache_id) {
// Read the script data, truncating if its too large.
// NOTE: we just issue one read and don't bother chaining if the resource
// is very (very) large, close enough for now.
- const int64 kLimit = 500 * 1000;
+ const int64_t kLimit = 500 * 1000;
handler_source_buffer_ = new net::GrowableIOBuffer();
handler_source_buffer_->SetCapacity(kLimit);
handler_source_reader_.reset(storage_->CreateResponseReader(
@@ -264,15 +277,10 @@ void AppCacheURLRequestJob::BeginErrorDelivery(const char* message) {
BeginDelivery();
}
-AppCacheURLRequestJob::~AppCacheURLRequestJob() {
- if (storage_)
- storage_->CancelDelegateCallbacks(this);
-}
-
void AppCacheURLRequestJob::OnResponseInfoLoaded(
- AppCacheResponseInfo* response_info, int64 response_id) {
+ AppCacheResponseInfo* response_info,
+ int64_t response_id) {
DCHECK(is_delivering_appcache_response());
- scoped_refptr<AppCacheURLRequestJob> protect(this);
if (response_info) {
info_ = response_info;
reader_.reset(storage_->CreateResponseReader(
@@ -336,7 +344,6 @@ void AppCacheURLRequestJob::SetupRangeResponse() {
void AppCacheURLRequestJob::OnReadComplete(int result) {
DCHECK(is_delivering_appcache_response());
if (result == 0) {
- NotifyDone(net::URLRequestStatus());
AppCacheHistograms::CountResponseRetrieval(
true, is_main_resource_, manifest_url_.GetOrigin());
} else if (result < 0) {
@@ -344,13 +351,10 @@ void AppCacheURLRequestJob::OnReadComplete(int result) {
storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_,
entry_.response_id());
}
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
AppCacheHistograms::CountResponseRetrieval(
false, is_main_resource_, manifest_url_.GetOrigin());
- } else {
- SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status
}
- NotifyReadComplete(result);
+ ReadRawDataComplete(result);
}
// net::URLRequestJob overrides ------------------------------------------------
@@ -419,17 +423,14 @@ int AppCacheURLRequestJob::GetResponseCode() const {
return http_info()->headers->response_code();
}
-bool AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size,
- int *bytes_read) {
+int AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
DCHECK(is_delivering_appcache_response());
DCHECK_NE(buf_size, 0);
- DCHECK(bytes_read);
DCHECK(!reader_->IsReadPending());
- reader_->ReadData(
- buf, buf_size, base::Bind(&AppCacheURLRequestJob::OnReadComplete,
- base::Unretained(this)));
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
- return false;
+ reader_->ReadData(buf, buf_size,
+ base::Bind(&AppCacheURLRequestJob::OnReadComplete,
+ base::Unretained(this)));
+ return net::ERR_IO_PENDING;
}
void AppCacheURLRequestJob::SetExtraRequestHeaders(
@@ -447,4 +448,9 @@ void AppCacheURLRequestJob::SetExtraRequestHeaders(
range_requested_ = ranges[0];
}
+void AppCacheURLRequestJob::NotifyRestartRequired() {
+ on_prepare_to_restart_callback_.Run();
+ URLRequestJob::NotifyRestartRequired();
+}
+
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_url_request_job.h b/chromium/content/browser/appcache/appcache_url_request_job.h
index be30a5fa3c3..057c13b98e4 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job.h
+++ b/chromium/content/browser/appcache/appcache_url_request_job.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_URL_REQUEST_JOB_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_URL_REQUEST_JOB_H_
+#include <stdint.h>
+
#include <string>
+#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/appcache/appcache_entry.h"
#include "content/browser/appcache/appcache_executable_handler.h"
@@ -31,17 +34,27 @@ class CONTENT_EXPORT AppCacheURLRequestJob
: public net::URLRequestJob,
public AppCacheStorage::Delegate {
public:
+ // Callback that will be invoked before the request is restarted. The caller
+ // can use this opportunity to grab state from the AppCacheURLRequestJob to
+ // determine how it should behave when the request is restarted.
+ using OnPrepareToRestartCallback = base::Closure;
+
AppCacheURLRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
AppCacheStorage* storage,
AppCacheHost* host,
- bool is_main_resource);
+ bool is_main_resource,
+ const OnPrepareToRestartCallback& restart_callback_);
+
+ ~AppCacheURLRequestJob() override;
// Informs the job of what response it should deliver. Only one of these
// methods should be called, and only once per job. A job will sit idle and
// wait indefinitely until one of the deliver methods is called.
- void DeliverAppCachedResponse(const GURL& manifest_url, int64 group_id,
- int64 cache_id, const AppCacheEntry& entry,
+ void DeliverAppCachedResponse(const GURL& manifest_url,
+ int64_t group_id,
+ int64_t cache_id,
+ const AppCacheEntry& entry,
bool is_fallback);
void DeliverNetworkResponse();
void DeliverErrorResponse();
@@ -66,8 +79,8 @@ class CONTENT_EXPORT AppCacheURLRequestJob
// that this job has been instructed to deliver. These are only
// valid to call if is_delivering_appcache_response.
const GURL& manifest_url() const { return manifest_url_; }
- int64 group_id() const { return group_id_; }
- int64 cache_id() const { return cache_id_; }
+ int64_t group_id() const { return group_id_; }
+ int64_t cache_id() const { return cache_id_; }
const AppCacheEntry& entry() const { return entry_; }
// net::URLRequestJob's Kill method is made public so the users of this
@@ -89,12 +102,12 @@ class CONTENT_EXPORT AppCacheURLRequestJob
return cache_entry_not_found_;
}
- protected:
- ~AppCacheURLRequestJob() override;
-
private:
- friend class content::AppCacheRequestHandlerTest;
- friend class content::AppCacheURLRequestJobTest;
+ friend class AppCacheRequestHandlerTest;
+ friend class AppCacheURLRequestJobTest;
+
+ // Friend so it can get a weak pointer.
+ friend class AppCacheRequestHandler;
enum DeliveryType {
AWAITING_DELIVERY_ORDERS,
@@ -103,6 +116,8 @@ class CONTENT_EXPORT AppCacheURLRequestJob
ERROR_DELIVERY
};
+ base::WeakPtr<AppCacheURLRequestJob> GetWeakPtr();
+
// Returns true if one of the Deliver methods has been called.
bool has_delivery_orders() const {
return !is_waiting();
@@ -121,8 +136,8 @@ class CONTENT_EXPORT AppCacheURLRequestJob
// AppCacheStorage::Delegate methods
void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
- int64 response_id) override;
- void OnCacheLoaded(AppCache* cache, int64 cache_id) override;
+ int64_t response_id) override;
+ void OnCacheLoaded(AppCache* cache, int64_t cache_id) override;
const net::HttpResponseInfo* http_info() const;
bool is_range_request() const { return range_requested_.IsValid(); }
@@ -136,7 +151,7 @@ class CONTENT_EXPORT AppCacheURLRequestJob
net::LoadState GetLoadState() const override;
bool GetCharset(std::string* charset) override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;
// Sets extra request headers for Job types that support request headers.
// This is how we get informed of range-requests.
@@ -146,6 +161,10 @@ class CONTENT_EXPORT AppCacheURLRequestJob
bool GetMimeType(std::string* mime_type) const override;
int GetResponseCode() const override;
+ // Invokes |prepare_to_restart_callback_| and then calls
+ // net::URLRequestJob::NotifyRestartRequired.
+ void NotifyRestartRequired();
+
AppCacheHost* host_;
AppCacheStorage* storage_;
base::TimeTicks start_time_tick_;
@@ -153,8 +172,8 @@ class CONTENT_EXPORT AppCacheURLRequestJob
bool has_been_killed_;
DeliveryType delivery_type_;
GURL manifest_url_;
- int64 group_id_;
- int64 cache_id_;
+ int64_t group_id_;
+ int64_t cache_id_;
AppCacheEntry entry_;
bool is_fallback_;
bool is_main_resource_; // Used for histogram logging.
@@ -167,6 +186,7 @@ class CONTENT_EXPORT AppCacheURLRequestJob
scoped_ptr<AppCacheResponseReader> reader_;
scoped_refptr<AppCache> cache_;
scoped_refptr<AppCacheGroup> group_;
+ const OnPrepareToRestartCallback on_prepare_to_restart_callback_;
base::WeakPtrFactory<AppCacheURLRequestJob> weak_factory_;
};
diff --git a/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc b/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
index 0e27295a0eb..aa228c879cb 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <string.h>
+
#include <stack>
#include <utility>
@@ -11,7 +14,9 @@
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/pickle.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
@@ -44,20 +49,30 @@ const char kHttpBasicBody[] = "Hello";
const int kNumBlocks = 4;
const int kBlockSize = 1024;
+// Used as an AppCacheURLRequestJob::OnPrepareToRestartCallback for requests
+// that aren't expected to be restarted.
+void ExpectNotRestarted() {
+ ADD_FAILURE() << "Request unexpectedly restarted";
+}
+
+// Used as an AppCacheURLRequestJob::OnPrepareToRestartCallback for requests
+// that are expected to be restarted. Allows tests to verify it was called by
+// setting |*value| to true when invoked.
+void SetIfCalled(bool* value) {
+ // Expected to be called only once.
+ EXPECT_FALSE(*value);
+ *value = true;
+}
+
class MockURLRequestJobFactory : public net::URLRequestJobFactory {
public:
- MockURLRequestJobFactory() : job_(NULL) {
- }
+ MockURLRequestJobFactory() {}
~MockURLRequestJobFactory() override { DCHECK(!job_); }
- void SetJob(net::URLRequestJob* job) {
- job_ = job;
- }
+ void SetJob(scoped_ptr<net::URLRequestJob> job) { job_ = std::move(job); }
- bool has_job() const {
- return job_ != NULL;
- }
+ bool has_job() const { return job_.get() != nullptr; }
// net::URLRequestJobFactory implementation.
net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
@@ -65,9 +80,7 @@ class MockURLRequestJobFactory : public net::URLRequestJobFactory {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
if (job_) {
- net::URLRequestJob* temp = job_;
- job_ = NULL;
- return temp;
+ return job_.release();
} else {
return new net::URLRequestErrorJob(request,
network_delegate,
@@ -101,9 +114,12 @@ class MockURLRequestJobFactory : public net::URLRequestJobFactory {
}
private:
- mutable net::URLRequestJob* job_;
+ // This is mutable because MaybeCreateJobWithProtocolHandler is const.
+ mutable scoped_ptr<net::URLRequestJob> job_;
};
+} // namespace
+
class AppCacheURLRequestJobTest : public testing::Test {
public:
@@ -117,14 +133,14 @@ class AppCacheURLRequestJobTest : public testing::Test {
}
void OnResponseInfoLoaded(AppCacheResponseInfo* info,
- int64 response_id) override {
+ int64_t response_id) override {
loaded_info_ = info;
loaded_info_id_ = response_id;
test_->ScheduleNextTask();
}
scoped_refptr<AppCacheResponseInfo> loaded_info_;
- int64 loaded_info_id_;
+ int64_t loaded_info_id_;
AppCacheURLRequestJobTest* test_;
};
@@ -238,6 +254,8 @@ class AppCacheURLRequestJobTest : public testing::Test {
reader_deletion_count_down_ = 0;
writer_deletion_count_down_ = 0;
+ restart_callback_invoked_ = false;
+
url_request_delegate_.reset(new MockURLRequestDelegate(this));
job_factory_.reset(new MockURLRequestJobFactory());
empty_context_.reset(new net::URLRequestContext());
@@ -432,13 +450,14 @@ class AppCacheURLRequestJobTest : public testing::Test {
// Basic -------------------------------------------------------------------
void Basic() {
AppCacheStorage* storage = service_->storage();
- scoped_ptr<net::URLRequest> request(empty_context_->CreateRequest(
- GURL("http://blah/"), net::DEFAULT_PRIORITY, NULL));
- scoped_refptr<AppCacheURLRequestJob> job;
+ request_ = empty_context_->CreateRequest(GURL("http://blah/"),
+ net::DEFAULT_PRIORITY, nullptr);
// Create an instance and see that it looks as expected.
- job = new AppCacheURLRequestJob(request.get(), NULL, storage, NULL, false);
+ scoped_ptr<AppCacheURLRequestJob> job(
+ new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
+ false, base::Bind(&ExpectNotRestarted)));
EXPECT_TRUE(job->is_waiting());
EXPECT_FALSE(job->is_delivering_appcache_response());
EXPECT_FALSE(job->is_delivering_network_response());
@@ -456,26 +475,31 @@ class AppCacheURLRequestJobTest : public testing::Test {
void DeliveryOrders() {
AppCacheStorage* storage = service_->storage();
scoped_ptr<net::URLRequest> request(empty_context_->CreateRequest(
- GURL("http://blah/"), net::DEFAULT_PRIORITY, NULL));
- scoped_refptr<AppCacheURLRequestJob> job;
+ GURL("http://blah/"), net::DEFAULT_PRIORITY, nullptr));
// Create an instance, give it a delivery order and see that
// it looks as expected.
- job = new AppCacheURLRequestJob(request.get(), NULL, storage, NULL, false);
+ scoped_ptr<AppCacheURLRequestJob> job(
+ new AppCacheURLRequestJob(request.get(), nullptr, storage, nullptr,
+ false, base::Bind(&ExpectNotRestarted)));
job->DeliverErrorResponse();
EXPECT_TRUE(job->is_delivering_error_response());
EXPECT_FALSE(job->has_been_started());
- job = new AppCacheURLRequestJob(request.get(), NULL, storage, NULL, false);
+ job.reset(new AppCacheURLRequestJob(request.get(), nullptr, storage,
+ nullptr, false,
+ base::Bind(&ExpectNotRestarted)));
job->DeliverNetworkResponse();
EXPECT_TRUE(job->is_delivering_network_response());
EXPECT_FALSE(job->has_been_started());
- job = new AppCacheURLRequestJob(request.get(), NULL, storage, NULL, false);
+ job.reset(new AppCacheURLRequestJob(request.get(), nullptr, storage,
+ nullptr, false,
+ base::Bind(&ExpectNotRestarted)));
const GURL kManifestUrl("http://blah/");
- const int64 kCacheId(1);
- const int64 kGroupId(1);
+ const int64_t kCacheId(1);
+ const int64_t kGroupId(1);
const AppCacheEntry kEntry(AppCacheEntry::EXPLICIT, 1);
job->DeliverAppCachedResponse(kManifestUrl, kCacheId, kGroupId,
kEntry, false);
@@ -504,14 +528,15 @@ class AppCacheURLRequestJobTest : public testing::Test {
net::DEFAULT_PRIORITY,
url_request_delegate_.get());
- // Setup to create an AppCacheURLRequestJob with orders to deliver
+ // Set up to create an AppCacheURLRequestJob with orders to deliver
// a network response.
- AppCacheURLRequestJob* mock_job = new AppCacheURLRequestJob(
- request_.get(), NULL, storage, NULL, false);
- job_factory_->SetJob(mock_job);
+ scoped_ptr<AppCacheURLRequestJob> mock_job(new AppCacheURLRequestJob(
+ request_.get(), nullptr, storage, nullptr, false,
+ base::Bind(&SetIfCalled, &restart_callback_invoked_)));
mock_job->DeliverNetworkResponse();
EXPECT_TRUE(mock_job->is_delivering_network_response());
EXPECT_FALSE(mock_job->has_been_started());
+ job_factory_->SetJob(std::move(mock_job));
// Start the request.
request_->Start();
@@ -524,6 +549,7 @@ class AppCacheURLRequestJobTest : public testing::Test {
void VerifyDeliverNetworkResponse() {
EXPECT_EQ(request_->status().error(),
net::ERR_INTERNET_DISCONNECTED);
+ EXPECT_TRUE(restart_callback_invoked_);
TestFinished();
}
@@ -542,12 +568,13 @@ class AppCacheURLRequestJobTest : public testing::Test {
// Setup to create an AppCacheURLRequestJob with orders to deliver
// a network response.
- AppCacheURLRequestJob* mock_job = new AppCacheURLRequestJob(
- request_.get(), NULL, storage, NULL, false);
- job_factory_->SetJob(mock_job);
+ scoped_ptr<AppCacheURLRequestJob> mock_job(
+ new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
+ false, base::Bind(&ExpectNotRestarted)));
mock_job->DeliverErrorResponse();
EXPECT_TRUE(mock_job->is_delivering_error_response());
EXPECT_FALSE(mock_job->has_been_started());
+ job_factory_->SetJob(std::move(mock_job));
// Start the request.
request_->Start();
@@ -593,8 +620,9 @@ class AppCacheURLRequestJobTest : public testing::Test {
// Setup to create an AppCacheURLRequestJob with orders to deliver
// a network response.
- scoped_refptr<AppCacheURLRequestJob> job(new AppCacheURLRequestJob(
- request_.get(), NULL, storage, NULL, false));
+ scoped_ptr<AppCacheURLRequestJob> job(
+ new AppCacheURLRequestJob(request_.get(), NULL, storage, NULL, false,
+ base::Bind(&ExpectNotRestarted)));
if (start_after_delivery_orders) {
job->DeliverAppCachedResponse(
@@ -606,17 +634,19 @@ class AppCacheURLRequestJobTest : public testing::Test {
// Start the request.
EXPECT_FALSE(job->has_been_started());
- job_factory_->SetJob(job.get());
+ base::WeakPtr<AppCacheURLRequestJob> weak_job = job->GetWeakPtr();
+ job_factory_->SetJob(std::move(job));
request_->Start();
EXPECT_FALSE(job_factory_->has_job());
- EXPECT_TRUE(job->has_been_started());
+ ASSERT_TRUE(weak_job);
+ EXPECT_TRUE(weak_job->has_been_started());
if (!start_after_delivery_orders) {
- job->DeliverAppCachedResponse(
+ weak_job->DeliverAppCachedResponse(
GURL(), 0, 111,
- AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_),
- false);
- EXPECT_TRUE(job->is_delivering_appcache_response());
+ AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_), false);
+ ASSERT_TRUE(weak_job);
+ EXPECT_TRUE(weak_job->is_delivering_appcache_response());
}
// Completion is async.
@@ -711,8 +741,9 @@ class AppCacheURLRequestJobTest : public testing::Test {
request_->SetExtraRequestHeaders(extra_headers);
// Create job with orders to deliver an appcached entry.
- scoped_refptr<AppCacheURLRequestJob> job(new AppCacheURLRequestJob(
- request_.get(), NULL, storage, NULL, false));
+ scoped_ptr<AppCacheURLRequestJob> job(
+ new AppCacheURLRequestJob(request_.get(), NULL, storage, NULL, false,
+ base::Bind(&ExpectNotRestarted)));
job->DeliverAppCachedResponse(
GURL(), 0, 111,
AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_),
@@ -721,10 +752,9 @@ class AppCacheURLRequestJobTest : public testing::Test {
// Start the request.
EXPECT_FALSE(job->has_been_started());
- job_factory_->SetJob(job.get());
+ job_factory_->SetJob(std::move(job));
request_->Start();
EXPECT_FALSE(job_factory_->has_job());
- EXPECT_TRUE(job->has_been_started());
// Completion is async.
}
@@ -738,7 +768,7 @@ class AppCacheURLRequestJobTest : public testing::Test {
url_request_delegate_->received_info_.headers.get();
EXPECT_EQ(206, headers->response_code());
EXPECT_EQ(3, headers->GetContentLength());
- int64 range_start, range_end, object_size;
+ int64_t range_start, range_end, object_size;
EXPECT_TRUE(
headers->GetContentRange(&range_start, &range_end, &object_size));
EXPECT_EQ(1, range_start);
@@ -813,13 +843,15 @@ class AppCacheURLRequestJobTest : public testing::Test {
int expected_read_result_;
int reader_deletion_count_down_;
- int64 written_response_id_;
+ int64_t written_response_id_;
scoped_ptr<AppCacheResponseWriter> writer_;
scoped_refptr<HttpResponseInfoIOBuffer> write_info_buffer_;
scoped_refptr<IOBuffer> write_buffer_;
int expected_write_result_;
int writer_deletion_count_down_;
+ bool restart_callback_invoked_;
+
scoped_ptr<MockURLRequestJobFactory> job_factory_;
scoped_ptr<net::URLRequestContext> empty_context_;
scoped_ptr<net::URLRequest> request_;
@@ -867,6 +899,4 @@ TEST_F(AppCacheURLRequestJobTest, CancelRequestWithIOPending) {
RunTestOnIOThread(&AppCacheURLRequestJobTest::CancelRequestWithIOPending);
}
-} // namespace
-
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_working_set.cc b/chromium/content/browser/appcache/appcache_working_set.cc
index 4394097aee0..646068406d2 100644
--- a/chromium/content/browser/appcache/appcache_working_set.cc
+++ b/chromium/content/browser/appcache/appcache_working_set.cc
@@ -33,7 +33,7 @@ void AppCacheWorkingSet::AddCache(AppCache* cache) {
if (is_disabled_)
return;
DCHECK(cache->cache_id() != kAppCacheNoCacheId);
- int64 cache_id = cache->cache_id();
+ int64_t cache_id = cache->cache_id();
DCHECK(caches_.find(cache_id) == caches_.end());
caches_.insert(CacheMap::value_type(cache_id, cache));
}
@@ -68,7 +68,7 @@ void AppCacheWorkingSet::AddResponseInfo(AppCacheResponseInfo* info) {
if (is_disabled_)
return;
DCHECK(info->response_id() != kAppCacheNoResponseId);
- int64 response_id = info->response_id();
+ int64_t response_id = info->response_id();
DCHECK(response_infos_.find(response_id) == response_infos_.end());
response_infos_.insert(ResponseInfoMap::value_type(response_id, info));
}
diff --git a/chromium/content/browser/appcache/appcache_working_set.h b/chromium/content/browser/appcache/appcache_working_set.h
index 5b9d00a1e1c..e9483b6c357 100644
--- a/chromium/content/browser/appcache/appcache_working_set.h
+++ b/chromium/content/browser/appcache/appcache_working_set.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_WORKING_SET_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_WORKING_SET_H_
+#include <stdint.h>
+
#include <map>
#include "base/containers/hash_tables.h"
@@ -31,7 +33,7 @@ class CONTENT_EXPORT AppCacheWorkingSet {
void AddCache(AppCache* cache);
void RemoveCache(AppCache* cache);
- AppCache* GetCache(int64 id) {
+ AppCache* GetCache(int64_t id) {
CacheMap::iterator it = caches_.find(id);
return (it != caches_.end()) ? it->second : NULL;
}
@@ -49,15 +51,15 @@ class CONTENT_EXPORT AppCacheWorkingSet {
void AddResponseInfo(AppCacheResponseInfo* response_info);
void RemoveResponseInfo(AppCacheResponseInfo* response_info);
- AppCacheResponseInfo* GetResponseInfo(int64 id) {
+ AppCacheResponseInfo* GetResponseInfo(int64_t id) {
ResponseInfoMap::iterator it = response_infos_.find(id);
return (it != response_infos_.end()) ? it->second : NULL;
}
private:
- typedef base::hash_map<int64, AppCache*> CacheMap;
+ typedef base::hash_map<int64_t, AppCache*> CacheMap;
typedef std::map<GURL, GroupMap> GroupsByOriginMap;
- typedef base::hash_map<int64, AppCacheResponseInfo*> ResponseInfoMap;
+ typedef base::hash_map<int64_t, AppCacheResponseInfo*> ResponseInfoMap;
GroupMap* GetMutableGroupsInOrigin(const GURL& origin_url) {
GroupsByOriginMap::iterator it = groups_by_origin_.find(origin_url);
diff --git a/chromium/content/browser/appcache/chrome_appcache_service.h b/chromium/content/browser/appcache/chrome_appcache_service.h
index 6976d873007..a34cd084cf4 100644
--- a/chromium/content/browser/appcache/chrome_appcache_service.h
+++ b/chromium/content/browser/appcache/chrome_appcache_service.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_APPCACHE_CHROME_APPCACHE_SERVICE_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner_helpers.h"
#include "content/browser/appcache/appcache_policy.h"
diff --git a/chromium/content/browser/appcache/mock_appcache_storage.cc b/chromium/content/browser/appcache/mock_appcache_storage.cc
index a59fe30c437..09bdf03c2ac 100644
--- a/chromium/content/browser/appcache/mock_appcache_storage.cc
+++ b/chromium/content/browser/appcache/mock_appcache_storage.cc
@@ -4,6 +4,8 @@
#include "content/browser/appcache/mock_appcache_storage.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
@@ -54,7 +56,7 @@ void MockAppCacheStorage::GetAllInfo(Delegate* delegate) {
make_scoped_refptr(GetOrCreateDelegateReference(delegate))));
}
-void MockAppCacheStorage::LoadCache(int64 id, Delegate* delegate) {
+void MockAppCacheStorage::LoadCache(int64_t id, Delegate* delegate) {
DCHECK(delegate);
AppCache* cache = working_set_.GetCache(id);
if (ShouldCacheLoadAppearAsync(cache)) {
@@ -130,8 +132,8 @@ void MockAppCacheStorage::FindResponseForSubRequest(
found_network_namespace);
}
-void MockAppCacheStorage::MarkEntryAsForeign(
- const GURL& entry_url, int64 cache_id) {
+void MockAppCacheStorage::MarkEntryAsForeign(const GURL& entry_url,
+ int64_t cache_id) {
AppCache* cache = working_set_.GetCache(cache_id);
if (cache) {
AppCacheEntry* entry = cache->GetEntry(entry_url);
@@ -162,34 +164,39 @@ void MockAppCacheStorage::StoreEvictionTimes(AppCacheGroup* group) {
}
AppCacheResponseReader* MockAppCacheStorage::CreateResponseReader(
- const GURL& manifest_url, int64 group_id, int64 response_id) {
+ const GURL& manifest_url,
+ int64_t group_id,
+ int64_t response_id) {
if (simulated_reader_)
return simulated_reader_.release();
return new AppCacheResponseReader(response_id, group_id, disk_cache());
}
AppCacheResponseWriter* MockAppCacheStorage::CreateResponseWriter(
- const GURL& manifest_url, int64 group_id) {
+ const GURL& manifest_url,
+ int64_t group_id) {
return new AppCacheResponseWriter(NewResponseId(), group_id, disk_cache());
}
AppCacheResponseMetadataWriter*
-MockAppCacheStorage::CreateResponseMetadataWriter(int64 group_id,
- int64 response_id) {
+MockAppCacheStorage::CreateResponseMetadataWriter(int64_t group_id,
+ int64_t response_id) {
return new AppCacheResponseMetadataWriter(response_id, group_id,
disk_cache());
}
void MockAppCacheStorage::DoomResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids) {
+ const GURL& manifest_url,
+ const std::vector<int64_t>& response_ids) {
DeleteResponses(manifest_url, response_ids);
}
void MockAppCacheStorage::DeleteResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids) {
+ const GURL& manifest_url,
+ const std::vector<int64_t>& response_ids) {
// We don't bother with actually removing responses from the disk-cache,
// just keep track of which ids have been doomed or deleted
- std::vector<int64>::const_iterator it = response_ids.begin();
+ std::vector<int64_t>::const_iterator it = response_ids.begin();
while (it != response_ids.end()) {
doomed_response_ids_.insert(*it);
++it;
@@ -203,7 +210,8 @@ void MockAppCacheStorage::ProcessGetAllInfo(
}
void MockAppCacheStorage::ProcessLoadCache(
- int64 id, scoped_refptr<DelegateReference> delegate_ref) {
+ int64_t id,
+ scoped_refptr<DelegateReference> delegate_ref) {
AppCache* cache = working_set_.GetCache(id);
if (delegate_ref->delegate)
delegate_ref->delegate->OnCacheLoaded(cache, id);
@@ -256,8 +264,8 @@ namespace {
struct FoundCandidate {
GURL namespace_entry_url;
AppCacheEntry entry;
- int64 cache_id;
- int64 group_id;
+ int64_t cache_id;
+ int64_t group_id;
GURL manifest_url;
bool is_cache_in_use;
@@ -479,7 +487,7 @@ void MockAppCacheStorage::RunOnePendingTask() {
}
void MockAppCacheStorage::AddStoredCache(AppCache* cache) {
- int64 cache_id = cache->cache_id();
+ int64_t cache_id = cache->cache_id();
if (stored_caches_.find(cache_id) == stored_caches_.end()) {
stored_caches_.insert(
StoredCacheMap::value_type(cache_id, make_scoped_refptr(cache)));
diff --git a/chromium/content/browser/appcache/mock_appcache_storage.h b/chromium/content/browser/appcache/mock_appcache_storage.h
index 25c95846e45..22d0e8e892b 100644
--- a/chromium/content/browser/appcache/mock_appcache_storage.h
+++ b/chromium/content/browser/appcache/mock_appcache_storage.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_APPCACHE_MOCK_APPCACHE_STORAGE_H_
#define CONTENT_BROWSER_APPCACHE_MOCK_APPCACHE_STORAGE_H_
+#include <stdint.h>
+
#include <deque>
#include <map>
#include <vector>
@@ -12,6 +14,7 @@
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/appcache/appcache.h"
@@ -50,7 +53,7 @@ class MockAppCacheStorage : public AppCacheStorage {
~MockAppCacheStorage() override;
void GetAllInfo(Delegate* delegate) override;
- void LoadCache(int64 id, Delegate* delegate) override;
+ void LoadCache(int64_t id, Delegate* delegate) override;
void LoadOrCreateGroup(const GURL& manifest_url, Delegate* delegate) override;
void StoreGroupAndNewestCache(AppCacheGroup* group,
AppCache* newest_cache,
@@ -63,23 +66,23 @@ class MockAppCacheStorage : public AppCacheStorage {
AppCacheEntry* found_entry,
AppCacheEntry* found_fallback_entry,
bool* found_network_namespace) override;
- void MarkEntryAsForeign(const GURL& entry_url, int64 cache_id) override;
+ void MarkEntryAsForeign(const GURL& entry_url, int64_t cache_id) override;
void MakeGroupObsolete(AppCacheGroup* group,
Delegate* delegate,
int response_code) override;
void StoreEvictionTimes(AppCacheGroup* group) override;
AppCacheResponseReader* CreateResponseReader(const GURL& manifest_url,
- int64 group_id,
- int64 response_id) override;
+ int64_t group_id,
+ int64_t response_id) override;
AppCacheResponseWriter* CreateResponseWriter(const GURL& manifest_url,
- int64 group_id) override;
+ int64_t group_id) override;
AppCacheResponseMetadataWriter* CreateResponseMetadataWriter(
- int64 group_id,
- int64 response_id) override;
+ int64_t group_id,
+ int64_t response_id) override;
void DoomResponses(const GURL& manifest_url,
- const std::vector<int64>& response_ids) override;
+ const std::vector<int64_t>& response_ids) override;
void DeleteResponses(const GURL& manifest_url,
- const std::vector<int64>& response_ids) override;
+ const std::vector<int64_t>& response_ids) override;
private:
friend class AppCacheRequestHandlerTest;
@@ -87,15 +90,15 @@ class MockAppCacheStorage : public AppCacheStorage {
friend class AppCacheUpdateJobTest;
friend class MockAppCacheStorageTest;
- typedef base::hash_map<int64, scoped_refptr<AppCache> > StoredCacheMap;
+ typedef base::hash_map<int64_t, scoped_refptr<AppCache>> StoredCacheMap;
typedef std::map<GURL, scoped_refptr<AppCacheGroup> > StoredGroupMap;
- typedef std::set<int64> DoomedResponseIds;
- typedef std::map<int64, std::pair<base::Time, base::Time>>
+ typedef std::set<int64_t> DoomedResponseIds;
+ typedef std::map<int64_t, std::pair<base::Time, base::Time>>
StoredEvictionTimesMap;
void ProcessGetAllInfo(scoped_refptr<DelegateReference> delegate_ref);
- void ProcessLoadCache(
- int64 id, scoped_refptr<DelegateReference> delegate_ref);
+ void ProcessLoadCache(int64_t id,
+ scoped_refptr<DelegateReference> delegate_ref);
void ProcessLoadOrCreateGroup(
const GURL& manifest_url, scoped_refptr<DelegateReference> delegate_ref);
void ProcessStoreGroupAndNewestCache(
@@ -156,13 +159,12 @@ class MockAppCacheStorage : public AppCacheStorage {
// provided values will be return on the next call to
// the corresponding Find method, subsequent calls are
// unaffected.
- void SimulateFindMainResource(
- const AppCacheEntry& entry,
- const GURL& fallback_url,
- const AppCacheEntry& fallback_entry,
- int64 cache_id,
- int64 group_id,
- const GURL& manifest_url) {
+ void SimulateFindMainResource(const AppCacheEntry& entry,
+ const GURL& fallback_url,
+ const AppCacheEntry& fallback_entry,
+ int64_t cache_id,
+ int64_t group_id,
+ const GURL& manifest_url) {
simulate_find_main_resource_ = true;
simulate_find_sub_resource_ = false;
simulated_found_entry_ = entry;
@@ -209,8 +211,8 @@ class MockAppCacheStorage : public AppCacheStorage {
bool simulate_find_sub_resource_;
AppCacheEntry simulated_found_entry_;
AppCacheEntry simulated_found_fallback_entry_;
- int64 simulated_found_cache_id_;
- int64 simulated_found_group_id_;
+ int64_t simulated_found_cache_id_;
+ int64_t simulated_found_group_id_;
GURL simulated_found_fallback_url_;
GURL simulated_found_manifest_url_;
bool simulated_found_network_namespace_;
diff --git a/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc b/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc
index 8f52912d39f..bee5ff03252 100644
--- a/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc
+++ b/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/run_loop.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_group.h"
@@ -21,7 +24,7 @@ class MockAppCacheStorageTest : public testing::Test {
obsoleted_success_(false), found_cache_id_(kAppCacheNoCacheId) {
}
- void OnCacheLoaded(AppCache* cache, int64 cache_id) override {
+ void OnCacheLoaded(AppCache* cache, int64_t cache_id) override {
loaded_cache_ = cache;
loaded_cache_id_ = cache_id;
}
@@ -51,8 +54,8 @@ class MockAppCacheStorageTest : public testing::Test {
const AppCacheEntry& entry,
const GURL& fallback_url,
const AppCacheEntry& fallback_entry,
- int64 cache_id,
- int64 group_id,
+ int64_t cache_id,
+ int64_t group_id,
const GURL& manifest_url) override {
found_url_ = url;
found_entry_ = entry;
@@ -63,7 +66,7 @@ class MockAppCacheStorageTest : public testing::Test {
}
scoped_refptr<AppCache> loaded_cache_;
- int64 loaded_cache_id_;
+ int64_t loaded_cache_id_;
scoped_refptr<AppCacheGroup> loaded_group_;
GURL loaded_manifest_url_;
scoped_refptr<AppCacheGroup> stored_group_;
@@ -74,7 +77,7 @@ class MockAppCacheStorageTest : public testing::Test {
AppCacheEntry found_entry_;
GURL found_fallback_url_;
AppCacheEntry found_fallback_entry_;
- int64 found_cache_id_;
+ int64_t found_cache_id_;
GURL found_manifest_url_;
};
@@ -102,7 +105,7 @@ TEST_F(MockAppCacheStorageTest, LoadCache_NearHit) {
// Setup some preconditions. Make an 'unstored' cache for
// us to load. The ctor should put it in the working set.
- int64 cache_id = service.storage()->NewCacheId();
+ int64_t cache_id = service.storage()->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
// Conduct the test.
@@ -170,7 +173,7 @@ TEST_F(MockAppCacheStorageTest, LoadGroupAndCache_FarHit) {
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
- int64 cache_id = storage->NewCacheId();
+ int64_t cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->set_complete(true);
group->AddCache(cache.get());
@@ -221,7 +224,7 @@ TEST_F(MockAppCacheStorageTest, StoreNewGroup) {
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
- int64 cache_id = storage->NewCacheId();
+ int64_t cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
// Hold a ref to the cache simulate the UpdateJob holding that ref,
// and hold a ref to the group to simulate the CacheHost holding that ref.
@@ -253,14 +256,14 @@ TEST_F(MockAppCacheStorageTest, StoreExistingGroup) {
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
- int64 old_cache_id = storage->NewCacheId();
+ int64_t old_cache_id = storage->NewCacheId();
scoped_refptr<AppCache> old_cache(
new AppCache(service.storage(), old_cache_id));
old_cache->set_complete(true);
group->AddCache(old_cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(old_cache.get());
- int64 new_cache_id = storage->NewCacheId();
+ int64_t new_cache_id = storage->NewCacheId();
scoped_refptr<AppCache> new_cache(
new AppCache(service.storage(), new_cache_id));
// Hold our refs to simulate the UpdateJob holding these refs.
@@ -298,7 +301,7 @@ TEST_F(MockAppCacheStorageTest, StoreExistingGroupExistingCache) {
GURL manifest_url("http://blah");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
- int64 cache_id = storage->NewCacheId();
+ int64_t cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->set_complete(true);
group->AddCache(cache.get());
@@ -340,7 +343,7 @@ TEST_F(MockAppCacheStorageTest, MakeGroupObsolete) {
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
- int64 cache_id = storage->NewCacheId();
+ int64_t cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->set_complete(true);
group->AddCache(cache.get());
@@ -382,7 +385,7 @@ TEST_F(MockAppCacheStorageTest, MarkEntryAsForeign) {
// Setup some preconditions. Create a cache with an entry.
GURL entry_url("http://blah/entry");
- int64 cache_id = storage->NewCacheId();
+ int64_t cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::EXPLICIT));
@@ -425,10 +428,10 @@ TEST_F(MockAppCacheStorageTest, BasicFindMainResponse) {
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a complete cache with an entry.
- const int64 kCacheId = storage->NewCacheId();
+ const int64_t kCacheId = storage->NewCacheId();
const GURL kEntryUrl("http://blah/entry");
const GURL kManifestUrl("http://blah/manifest");
- const int64 kResponseId = 1;
+ const int64_t kResponseId = 1;
scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
cache->AddEntry(
kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId));
@@ -461,14 +464,14 @@ TEST_F(MockAppCacheStorageTest, BasicFindMainFallbackResponse) {
// Setup some preconditions. Create a complete cache with a
// fallback namespace and entry.
- const int64 kCacheId = storage->NewCacheId();
+ const int64_t kCacheId = storage->NewCacheId();
const GURL kFallbackEntryUrl1("http://blah/fallback_entry1");
const GURL kFallbackNamespaceUrl1("http://blah/fallback_namespace/");
const GURL kFallbackEntryUrl2("http://blah/fallback_entry2");
const GURL kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer");
const GURL kManifestUrl("http://blah/manifest");
- const int64 kResponseId1 = 1;
- const int64 kResponseId2 = 2;
+ const int64_t kResponseId1 = 1;
+ const int64_t kResponseId2 = 2;
AppCacheManifest manifest;
manifest.fallback_namespaces.push_back(
@@ -521,12 +524,12 @@ TEST_F(MockAppCacheStorageTest, FindMainResponseWithMultipleCandidates) {
// for the same url.
const GURL kEntryUrl("http://blah/entry");
- const int64 kCacheId1 = storage->NewCacheId();
- const int64 kCacheId2 = storage->NewCacheId();
+ const int64_t kCacheId1 = storage->NewCacheId();
+ const int64_t kCacheId2 = storage->NewCacheId();
const GURL kManifestUrl1("http://blah/manifest1");
const GURL kManifestUrl2("http://blah/manifest2");
- const int64 kResponseId1 = 1;
- const int64 kResponseId2 = 2;
+ const int64_t kResponseId1 = 1;
+ const int64_t kResponseId2 = 2;
// The first cache.
scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId1));
@@ -576,11 +579,11 @@ TEST_F(MockAppCacheStorageTest, FindMainResponseExclusions) {
// Setup some preconditions. Create a complete cache with a
// foreign entry and an online namespace.
- const int64 kCacheId = storage->NewCacheId();
+ const int64_t kCacheId = storage->NewCacheId();
const GURL kEntryUrl("http://blah/entry");
const GURL kManifestUrl("http://blah/manifest");
const GURL kOnlineNamespaceUrl("http://blah/online_namespace");
- const int64 kResponseId = 1;
+ const int64_t kResponseId = 1;
AppCacheManifest manifest;
manifest.online_whitelist_namespaces.push_back(
diff --git a/chromium/content/browser/background_sync/OWNERS b/chromium/content/browser/background_sync/OWNERS
index 1e6deee91b7..c60b9f98b80 100644
--- a/chromium/content/browser/background_sync/OWNERS
+++ b/chromium/content/browser/background_sync/OWNERS
@@ -1 +1,2 @@
+iclelland@chromium.org
jkarlin@chromium.org
diff --git a/chromium/content/browser/background_sync/background_sync.proto b/chromium/content/browser/background_sync/background_sync.proto
index 895117d463d..11adc3133c3 100644
--- a/chromium/content/browser/background_sync/background_sync.proto
+++ b/chromium/content/browser/background_sync/background_sync.proto
@@ -31,6 +31,8 @@ message BackgroundSyncRegistrationProto {
required int64 min_period = 4;
required SyncNetworkState network_state = 5;
required SyncPowerState power_state = 6;
+ required int32 num_attempts = 7;
+ required int64 delay_until = 8;
}
message BackgroundSyncRegistrationsProto {
diff --git a/chromium/content/browser/background_sync/background_sync_browsertest.cc b/chromium/content/browser/background_sync/background_sync_browsertest.cc
index ae1ccc94223..a5de6ada408 100644
--- a/chromium/content/browser/background_sync/background_sync_browsertest.cc
+++ b/chromium/content/browser/background_sync/background_sync_browsertest.cc
@@ -2,11 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <set>
#include <string>
#include <vector>
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/task_runner_util.h"
@@ -21,12 +24,14 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
+#include "content/public/test/background_sync_test_util.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/base/network_change_notifier.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
using net::NetworkChangeNotifier;
@@ -35,7 +40,9 @@ namespace content {
namespace {
-const char kDefaultTestURL[] = "files/background_sync/test.html";
+const char kDefaultTestURL[] = "/background_sync/test.html";
+const char kEmptyURL[] = "/background_sync/empty.html";
+const char kRegisterSyncURL[] = "/background_sync/register_sync.html";
const char kSuccessfulOperationPrefix[] = "ok - ";
@@ -75,7 +82,7 @@ void OneShotPendingDidGetSWRegistration(
ServiceWorkerStatusCode status,
const scoped_refptr<ServiceWorkerRegistration>& registration) {
ASSERT_EQ(SERVICE_WORKER_OK, status);
- int64 service_worker_id = registration->id();
+ int64_t service_worker_id = registration->id();
BackgroundSyncManager* sync_manager = sync_context->background_sync_manager();
sync_manager->GetRegistration(
service_worker_id, tag, SYNC_ONE_SHOT,
@@ -88,11 +95,19 @@ void OneShotPendingOnIOThread(
const std::string& tag,
const GURL& url,
const base::Callback<void(bool)>& callback) {
- sw_context->FindRegistrationForDocument(
+ sw_context->FindReadyRegistrationForDocument(
url, base::Bind(&OneShotPendingDidGetSWRegistration, sync_context, tag,
callback));
}
+void SetMaxSyncAttemptsOnIOThread(
+ const scoped_refptr<BackgroundSyncContext>& sync_context,
+ int max_sync_attempts) {
+ BackgroundSyncManager* background_sync_manager =
+ sync_context->background_sync_manager();
+ background_sync_manager->SetMaxSyncAttemptsForTesting(max_sync_attempts);
+}
+
} // namespace
class BackgroundSyncBrowserTest : public ContentBrowserTest {
@@ -101,7 +116,8 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
~BackgroundSyncBrowserTest() override {}
void SetUp() override {
- BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(true);
+ background_sync_test_util::SetIgnoreNetworkChangeNotifier(true);
+
ContentBrowserTest::SetUp();
}
@@ -109,12 +125,18 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
shell_ = incognito ? CreateOffTheRecordBrowser() : shell();
}
- BackgroundSyncContext* GetSyncContextFromShell(Shell* shell) {
- StoragePartition* storage = BrowserContext::GetDefaultStoragePartition(
- shell_->web_contents()->GetBrowserContext());
- return storage->GetBackgroundSyncContext();
+ StoragePartition* GetStorage() {
+ WebContents* web_contents = shell_->web_contents();
+ return BrowserContext::GetStoragePartition(
+ web_contents->GetBrowserContext(), web_contents->GetSiteInstance());
}
+ BackgroundSyncContext* GetSyncContext() {
+ return GetStorage()->GetBackgroundSyncContext();
+ }
+
+ WebContents* web_contents() { return shell_->web_contents(); }
+
void SetUpCommandLine(base::CommandLine* command_line) override {
// TODO(jkarlin): Remove this once background sync is no longer
// experimental.
@@ -123,17 +145,14 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
}
void SetUpOnMainThread() override {
- https_server_.reset(new net::SpawnedTestServer(
- net::SpawnedTestServer::TYPE_HTTPS,
- net::BaseTestServer::SSLOptions(
- net::BaseTestServer::SSLOptions::CERT_OK),
- base::FilePath(FILE_PATH_LITERAL("content/test/data/"))));
+ https_server_.reset(
+ new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
+ https_server_->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server_->Start());
SetIncognitoMode(false);
-
- SetOnline(true);
-
+ SetMaxSyncAttempts(1);
+ background_sync_test_util::SetOnline(web_contents(), true);
ASSERT_TRUE(LoadTestPage(kDefaultTestURL));
ContentBrowserTest::SetUpOnMainThread();
@@ -146,73 +165,48 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
}
bool RunScript(const std::string& script, std::string* result) {
- return content::ExecuteScriptAndExtractString(shell_->web_contents(),
- script, result);
+ return content::ExecuteScriptAndExtractString(web_contents(), script,
+ result);
}
- // This runs asynchronously on the IO thread, but we don't need to wait for it
- // to complete before running a background sync operation, since those also
- // run on the IO thread.
- void SetOnline(bool online);
- void SetOnlineOnIOThread(
- const scoped_refptr<BackgroundSyncContext>& sync_context,
- bool online);
-
// Returns true if the one-shot sync with tag is currently pending. Fails
// (assertion failure) if the tag isn't registered.
bool OneShotPending(const std::string& tag);
+ // Sets the BackgroundSyncManager's max sync attempts per registration.
+ void SetMaxSyncAttempts(int max_sync_attempts);
+
+ void ClearStoragePartitionData();
+
+ std::string PopConsoleString();
bool PopConsole(const std::string& expected_msg);
bool RegisterServiceWorker();
bool RegisterOneShot(const std::string& tag);
- bool UnregisterOneShot(const std::string& tag);
- bool UnregisterOneShotTwice(const std::string& tag);
+ bool RegisterOneShotFromServiceWorker(const std::string& tag);
bool GetRegistrationOneShot(const std::string& tag);
+ bool GetRegistrationOneShotFromServiceWorker(const std::string& tag);
+ bool MatchRegistrations(const std::string& script_result,
+ const std::vector<std::string>& expected_tags);
bool GetRegistrationsOneShot(const std::vector<std::string>& expected_tags);
+ bool GetRegistrationsOneShotFromServiceWorker(
+ const std::vector<std::string>& expected_tags);
bool CompleteDelayedOneShot();
bool RejectDelayedOneShot();
- bool NotifyWhenDoneOneShot(const std::string& tag);
- bool NotifyWhenDoneImmediateOneShot(const std::string& expected_msg);
- bool StoreRegistrationOneShot(const std::string& tag);
+
+ net::EmbeddedTestServer* https_server() { return https_server_.get(); }
private:
- scoped_ptr<net::SpawnedTestServer> https_server_;
+ scoped_ptr<net::EmbeddedTestServer> https_server_;
Shell* shell_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(BackgroundSyncBrowserTest);
};
-void BackgroundSyncBrowserTest::SetOnline(bool online) {
- ASSERT_TRUE(shell_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&BackgroundSyncBrowserTest::SetOnlineOnIOThread,
- base::Unretained(this),
- base::Unretained(GetSyncContextFromShell(shell_)), online));
- base::RunLoop().RunUntilIdle();
-}
-
-void BackgroundSyncBrowserTest::SetOnlineOnIOThread(
- const scoped_refptr<BackgroundSyncContext>& sync_context,
- bool online) {
- BackgroundSyncManager* sync_manager = sync_context->background_sync_manager();
- BackgroundSyncNetworkObserver* network_observer =
- sync_manager->GetNetworkObserverForTesting();
- if (online) {
- network_observer->NotifyManagerIfNetworkChanged(
- NetworkChangeNotifier::CONNECTION_WIFI);
- } else {
- network_observer->NotifyManagerIfNetworkChanged(
- NetworkChangeNotifier::CONNECTION_NONE);
- }
-}
-
bool BackgroundSyncBrowserTest::OneShotPending(const std::string& tag) {
bool is_pending;
base::RunLoop run_loop;
- StoragePartition* storage = BrowserContext::GetDefaultStoragePartition(
- shell_->web_contents()->GetBrowserContext());
+ StoragePartition* storage = GetStorage();
BackgroundSyncContext* sync_context = storage->GetBackgroundSyncContext();
ServiceWorkerContextWrapper* service_worker_context =
static_cast<ServiceWorkerContextWrapper*>(
@@ -233,9 +227,51 @@ bool BackgroundSyncBrowserTest::OneShotPending(const std::string& tag) {
return is_pending;
}
-bool BackgroundSyncBrowserTest::PopConsole(const std::string& expected_msg) {
+void BackgroundSyncBrowserTest::SetMaxSyncAttempts(int max_sync_attempts) {
+ base::RunLoop run_loop;
+
+ StoragePartition* storage = GetStorage();
+ BackgroundSyncContext* sync_context = storage->GetBackgroundSyncContext();
+
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SetMaxSyncAttemptsOnIOThread,
+ make_scoped_refptr(sync_context), max_sync_attempts),
+ run_loop.QuitClosure());
+
+ run_loop.Run();
+}
+
+void BackgroundSyncBrowserTest::ClearStoragePartitionData() {
+ // Clear data from the storage partition. Parameters are set to clear data
+ // for service workers, for all origins, for an unbounded time range.
+ StoragePartition* storage = GetStorage();
+
+ uint32_t storage_partition_mask =
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
+ uint32_t quota_storage_mask =
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
+ const GURL& delete_origin = GURL();
+ const base::Time delete_begin = base::Time();
+ base::Time delete_end = base::Time::Max();
+
+ base::RunLoop run_loop;
+
+ storage->ClearData(storage_partition_mask, quota_storage_mask, delete_origin,
+ StoragePartition::OriginMatcherFunction(), delete_begin,
+ delete_end, run_loop.QuitClosure());
+
+ run_loop.Run();
+}
+
+std::string BackgroundSyncBrowserTest::PopConsoleString() {
std::string script_result;
EXPECT_TRUE(RunScript("resultQueue.pop()", &script_result));
+ return script_result;
+}
+
+bool BackgroundSyncBrowserTest::PopConsole(const std::string& expected_msg) {
+ std::string script_result = PopConsoleString();
return script_result == expected_msg;
}
@@ -252,19 +288,13 @@ bool BackgroundSyncBrowserTest::RegisterOneShot(const std::string& tag) {
return script_result == BuildExpectedResult(tag, "registered");
}
-bool BackgroundSyncBrowserTest::UnregisterOneShot(const std::string& tag) {
+bool BackgroundSyncBrowserTest::RegisterOneShotFromServiceWorker(
+ const std::string& tag) {
std::string script_result;
EXPECT_TRUE(
- RunScript(BuildScriptString("unregisterOneShot", tag), &script_result));
- return script_result == BuildExpectedResult(tag, "unregistered");
-}
-
-bool BackgroundSyncBrowserTest::UnregisterOneShotTwice(const std::string& tag) {
- std::string script_result;
- EXPECT_TRUE(RunScript(BuildScriptString("unregisterOneShotTwice", tag),
- &script_result));
- return script_result ==
- BuildExpectedResult(tag, "failed to unregister twice");
+ RunScript(BuildScriptString("registerOneShotFromServiceWorker", tag),
+ &script_result));
+ return script_result == BuildExpectedResult(tag, "register sent to SW");
}
bool BackgroundSyncBrowserTest::GetRegistrationOneShot(const std::string& tag) {
@@ -274,21 +304,49 @@ bool BackgroundSyncBrowserTest::GetRegistrationOneShot(const std::string& tag) {
return script_result == BuildExpectedResult(tag, "found");
}
-bool BackgroundSyncBrowserTest::GetRegistrationsOneShot(
- const std::vector<std::string>& expected_tags) {
+bool BackgroundSyncBrowserTest::GetRegistrationOneShotFromServiceWorker(
+ const std::string& tag) {
std::string script_result;
- EXPECT_TRUE(RunScript("getRegistrationsOneShot()", &script_result));
+ EXPECT_TRUE(RunScript(
+ BuildScriptString("getRegistrationOneShotFromServiceWorker", tag),
+ &script_result));
+ EXPECT_TRUE(script_result == "ok - getRegistration sent to SW");
+ return PopConsole(BuildExpectedResult(tag, "found"));
+}
+
+bool BackgroundSyncBrowserTest::MatchRegistrations(
+ const std::string& script_result,
+ const std::vector<std::string>& expected_tags) {
EXPECT_TRUE(base::StartsWith(script_result, kSuccessfulOperationPrefix,
base::CompareCase::INSENSITIVE_ASCII));
- script_result = script_result.substr(strlen(kSuccessfulOperationPrefix));
+ std::string tag_string =
+ script_result.substr(strlen(kSuccessfulOperationPrefix));
std::vector<std::string> result_tags = base::SplitString(
- script_result, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ tag_string, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
return std::set<std::string>(expected_tags.begin(), expected_tags.end()) ==
std::set<std::string>(result_tags.begin(), result_tags.end());
}
+bool BackgroundSyncBrowserTest::GetRegistrationsOneShot(
+ const std::vector<std::string>& expected_tags) {
+ std::string script_result;
+ EXPECT_TRUE(RunScript("getRegistrationsOneShot()", &script_result));
+
+ return MatchRegistrations(script_result, expected_tags);
+}
+
+bool BackgroundSyncBrowserTest::GetRegistrationsOneShotFromServiceWorker(
+ const std::vector<std::string>& expected_tags) {
+ std::string script_result;
+ EXPECT_TRUE(
+ RunScript("getRegistrationsOneShotFromServiceWorker()", &script_result));
+ EXPECT_TRUE(script_result == "ok - getRegistrations sent to SW");
+
+ return MatchRegistrations(PopConsoleString(), expected_tags);
+}
+
bool BackgroundSyncBrowserTest::CompleteDelayedOneShot() {
std::string script_result;
EXPECT_TRUE(RunScript("completeDelayedOneShot()", &script_result));
@@ -301,48 +359,47 @@ bool BackgroundSyncBrowserTest::RejectDelayedOneShot() {
return script_result == BuildExpectedResult("delay", "rejecting");
}
-bool BackgroundSyncBrowserTest::NotifyWhenDoneOneShot(const std::string& tag) {
- EXPECT_TRUE(content::ExecuteScript(
- shell_->web_contents(), BuildScriptString("notifyWhenDoneOneShot", tag)));
- return PopConsole(BuildExpectedResult(tag, "done"));
-}
-
-bool BackgroundSyncBrowserTest::NotifyWhenDoneImmediateOneShot(
- const std::string& expected_msg) {
- std::string script_result;
- EXPECT_TRUE(RunScript("notifyWhenDoneImmediateOneShot()", &script_result));
- return script_result == expected_msg;
-}
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotFiresControlled) {
+ EXPECT_TRUE(RegisterServiceWorker());
+ EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
-bool BackgroundSyncBrowserTest::StoreRegistrationOneShot(
- const std::string& tag) {
- std::string script_result;
- EXPECT_TRUE(
- RunScript(BuildScriptString("storeRegistration", tag), &script_result));
- return script_result == BuildExpectedResult(tag, "stored");
+ EXPECT_TRUE(RegisterOneShot("foo"));
+ EXPECT_TRUE(PopConsole("foo fired"));
+ EXPECT_FALSE(GetRegistrationOneShot("foo"));
}
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotFires) {
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotFiresUncontrolled) {
EXPECT_TRUE(RegisterServiceWorker());
- EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
EXPECT_TRUE(RegisterOneShot("foo"));
EXPECT_TRUE(PopConsole("foo fired"));
EXPECT_FALSE(GetRegistrationOneShot("foo"));
}
+// Verify that Register works in a service worker
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ OneShotFromServiceWorkerFires) {
+ EXPECT_TRUE(RegisterServiceWorker());
+ EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
+
+ EXPECT_TRUE(RegisterOneShotFromServiceWorker("foo_sw"));
+ EXPECT_TRUE(PopConsole("ok - foo_sw registered in SW"));
+ EXPECT_TRUE(PopConsole("foo_sw fired"));
+ EXPECT_FALSE(GetRegistrationOneShot("foo_sw"));
+}
+
IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotDelaysForNetwork) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
// Prevent firing by going offline.
- SetOnline(false);
+ background_sync_test_util::SetOnline(web_contents(), false);
EXPECT_TRUE(RegisterOneShot("foo"));
EXPECT_TRUE(GetRegistrationOneShot("foo"));
EXPECT_TRUE(OneShotPending("foo"));
// Resume firing by going online.
- SetOnline(true);
+ background_sync_test_util::SetOnline(web_contents(), true);
EXPECT_TRUE(PopConsole("foo fired"));
EXPECT_FALSE(GetRegistrationOneShot("foo"));
}
@@ -351,7 +408,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, WaitUntil) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(true);
+ background_sync_test_util::SetOnline(web_contents(), true);
EXPECT_TRUE(RegisterOneShot("delay"));
// Verify that it is firing.
@@ -363,8 +420,6 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, WaitUntil) {
EXPECT_TRUE(PopConsole("ok - delay completed"));
// Verify that it finished firing.
- // TODO(jkarlin): Use registration.done to verify that the event actually
- // completed successfully.
EXPECT_FALSE(GetRegistrationOneShot("delay"));
}
@@ -372,7 +427,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, WaitUntilReject) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(true);
+ background_sync_test_util::SetOnline(web_contents(), true);
EXPECT_TRUE(RegisterOneShot("delay"));
// Verify that it is firing.
@@ -389,7 +444,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, Incognito) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(false);
+ background_sync_test_util::SetOnline(web_contents(), false);
EXPECT_TRUE(RegisterOneShot("normal"));
EXPECT_TRUE(OneShotPending("normal"));
@@ -399,11 +454,10 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, Incognito) {
// Tell the new network observer that we're offline (it initializes from
// NetworkChangeNotifier::GetCurrentConnectionType() which is not mocked out
// in this test).
- SetOnline(false);
+ background_sync_test_util::SetOnline(web_contents(), false);
EXPECT_TRUE(LoadTestPage(kDefaultTestURL));
EXPECT_TRUE(RegisterServiceWorker());
- EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
EXPECT_FALSE(GetRegistrationOneShot("normal"));
@@ -425,7 +479,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, GetRegistrations) {
std::vector<std::string> registered_tags;
EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
- SetOnline(false);
+ background_sync_test_util::SetOnline(web_contents(), false);
registered_tags.push_back("foo");
registered_tags.push_back("bar");
@@ -435,104 +489,177 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, GetRegistrations) {
EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
}
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, Unregister) {
+// Verify that GetRegistrations works in a service worker
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ GetRegistrationsFromServiceWorker) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(false);
- EXPECT_TRUE(RegisterOneShot("foo"));
- EXPECT_TRUE(UnregisterOneShot("foo"));
- EXPECT_FALSE(GetRegistrationOneShot("foo"));
-}
+ std::vector<std::string> registered_tags;
+ EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, UnregisterTwice) {
- EXPECT_TRUE(RegisterServiceWorker());
- EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
+ background_sync_test_util::SetOnline(web_contents(), false);
+ registered_tags.push_back("foo_sw");
+ registered_tags.push_back("bar_sw");
- SetOnline(false);
- EXPECT_TRUE(RegisterOneShot("foo"));
- EXPECT_TRUE(UnregisterOneShotTwice("foo"));
- EXPECT_FALSE(GetRegistrationOneShot("foo"));
+ for (const std::string& tag : registered_tags) {
+ EXPECT_TRUE(RegisterOneShotFromServiceWorker(tag));
+ EXPECT_TRUE(PopConsole(BuildExpectedResult(tag, "registered in SW")));
+ }
+
+ EXPECT_TRUE(GetRegistrationsOneShotFromServiceWorker(registered_tags));
}
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, UnregisterMidSync) {
+// Verify that GetRegistration works in a service worker
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ GetRegistrationFromServiceWorker) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- EXPECT_TRUE(RegisterOneShot("unregister"));
- EXPECT_TRUE(PopConsole("ok - unregister completed"));
+ std::vector<std::string> registered_tags;
+ EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
+
+ background_sync_test_util::SetOnline(web_contents(), false);
+
+ EXPECT_TRUE(RegisterOneShotFromServiceWorker("foo_sw"));
+ EXPECT_TRUE(PopConsole("ok - foo_sw registered in SW"));
+ EXPECT_TRUE(GetRegistrationOneShotFromServiceWorker("foo_sw"));
}
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallDoneBeforeSyncSucceeds) {
+// Verify that a background sync registration is deleted when site data is
+// cleared.
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ SyncRegistrationDeletedWhenClearingSiteData) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(false);
+ // Prevent firing by going offline.
+ background_sync_test_util::SetOnline(web_contents(), false);
EXPECT_TRUE(RegisterOneShot("foo"));
- EXPECT_TRUE(NotifyWhenDoneOneShot("foo"));
+ EXPECT_TRUE(GetRegistrationOneShot("foo"));
+ EXPECT_TRUE(OneShotPending("foo"));
- SetOnline(true);
- // The ordering of PopConsole messages tells us that the event fired
- // before done resolved.
- EXPECT_TRUE(PopConsole("foo fired"));
- EXPECT_TRUE(PopConsole("foo done result: true"));
+ // Simulate a user clearing site data (including Service Workers, crucially),
+ // by clearing data from the storage partition.
+ ClearStoragePartitionData();
+
+ EXPECT_FALSE(GetRegistrationOneShot("foo"));
}
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallDoneBeforeSyncFails) {
+// Verify that a background sync registration, from a service worker, is deleted
+// when site data is cleared.
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ SyncRegistrationFromSWDeletedWhenClearingSiteData) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(true);
- EXPECT_TRUE(RegisterOneShot("delay"));
- EXPECT_FALSE(OneShotPending("delay"));
- EXPECT_TRUE(NotifyWhenDoneOneShot("delay"));
+ std::vector<std::string> registered_tags;
+ EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
- EXPECT_TRUE(RejectDelayedOneShot());
- // The ordering of PopConsole messages tells us that the event fired
- // before done resolved.
- EXPECT_TRUE(PopConsole("ok - delay rejected"));
- EXPECT_TRUE(PopConsole("delay done result: false"));
+ background_sync_test_util::SetOnline(web_contents(), false);
+
+ EXPECT_TRUE(RegisterOneShotFromServiceWorker("foo_sw"));
+ EXPECT_TRUE(PopConsole("ok - foo_sw registered in SW"));
+ EXPECT_TRUE(GetRegistrationOneShotFromServiceWorker("foo_sw"));
+
+ // Simulate a user clearing site data (including Service Workers, crucially),
+ // by clearing data from the storage partition.
+ ClearStoragePartitionData();
+
+ EXPECT_FALSE(GetRegistrationOneShotFromServiceWorker("foo"));
}
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallDoneAfterSyncSuceeds) {
+// Verify that multiple background sync registrations are deleted when site
+// data is cleared.
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ SyncRegistrationsDeletedWhenClearingSiteData) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(false);
- EXPECT_TRUE(RegisterOneShot("foo"));
- EXPECT_TRUE(StoreRegistrationOneShot("foo"));
+ std::vector<std::string> registered_tags;
+ EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
- SetOnline(true);
- EXPECT_TRUE(PopConsole("foo fired"));
- EXPECT_FALSE(GetRegistrationOneShot("foo"));
- EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - foo result: true"));
+ background_sync_test_util::SetOnline(web_contents(), false);
+ registered_tags.push_back("foo");
+ registered_tags.push_back("bar");
+
+ for (const std::string& tag : registered_tags)
+ EXPECT_TRUE(RegisterOneShot(tag));
+
+ EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
+
+ for (const std::string& tag : registered_tags)
+ EXPECT_TRUE(OneShotPending(tag));
+
+ // Simulate a user clearing site data (including Service Workers, crucially),
+ // by clearing data from the storage partition.
+ ClearStoragePartitionData();
+
+ for (const std::string& tag : registered_tags)
+ EXPECT_FALSE(GetRegistrationOneShot(tag));
}
+// Verify that a sync event that is currently firing is deleted when site
+// data is cleared.
IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
- CallDoneAfterSyncUnregistered) {
+ FiringSyncEventDeletedWhenClearingSiteData) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(false);
- EXPECT_TRUE(RegisterOneShot("foo"));
- EXPECT_TRUE(StoreRegistrationOneShot("foo"));
- EXPECT_TRUE(UnregisterOneShot("foo"));
- EXPECT_FALSE(GetRegistrationOneShot("foo"));
- EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - foo result: false"));
+ background_sync_test_util::SetOnline(web_contents(), true);
+ EXPECT_TRUE(RegisterOneShot("delay"));
+
+ // Verify that it is firing.
+ EXPECT_TRUE(GetRegistrationOneShot("delay"));
+ EXPECT_FALSE(OneShotPending("delay"));
+
+ // Simulate a user clearing site data (including Service Workers, crucially),
+ // by clearing data from the storage partition.
+ ClearStoragePartitionData();
+
+ // Verify that it was deleted.
+ EXPECT_FALSE(GetRegistrationOneShot("delay"));
}
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallDoneAfterSyncFails) {
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, VerifyRetry) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
- SetOnline(true);
- EXPECT_TRUE(RegisterOneShot("delay"));
- EXPECT_FALSE(OneShotPending("delay"));
- EXPECT_TRUE(StoreRegistrationOneShot("delay"));
+ SetMaxSyncAttempts(2);
+ EXPECT_TRUE(RegisterOneShot("delay"));
EXPECT_TRUE(RejectDelayedOneShot());
EXPECT_TRUE(PopConsole("ok - delay rejected"));
- EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - delay result: false"));
+
+ // Verify that the oneshot is still around and waiting to try again.
+ EXPECT_TRUE(OneShotPending("delay"));
+}
+
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, RegisterFromNonMainFrame) {
+ std::string script_result;
+ GURL url = https_server()->GetURL(kEmptyURL);
+ EXPECT_TRUE(
+ RunScript(BuildScriptString("registerOneShotFromLocalFrame", url.spec()),
+ &script_result));
+ EXPECT_EQ(BuildExpectedResult("iframe", "failed to register sync"),
+ script_result);
+}
+
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ RegisterFromServiceWorkerWithoutMainFrameHost) {
+ // Start a second https server to use as a second origin.
+ net::EmbeddedTestServer alt_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ alt_server.ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(alt_server.Start());
+
+ std::string script_result;
+ GURL url = alt_server.GetURL(kRegisterSyncURL);
+ EXPECT_TRUE(
+ RunScript(BuildScriptString("registerOneShotFromCrossOriginServiceWorker",
+ url.spec()),
+ &script_result));
+ EXPECT_EQ(BuildExpectedResult("worker", "failed to register sync"),
+ script_result);
}
} // namespace content
diff --git a/chromium/content/browser/background_sync/background_sync_context_impl.cc b/chromium/content/browser/background_sync/background_sync_context_impl.cc
index 4e55d839bad..009e8864b6f 100644
--- a/chromium/content/browser/background_sync/background_sync_context_impl.cc
+++ b/chromium/content/browser/background_sync/background_sync_context_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/background_sync/background_sync_context_impl.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/stl_util.h"
#include "content/browser/background_sync/background_sync_manager.h"
@@ -78,7 +80,7 @@ void BackgroundSyncContextImpl::CreateServiceOnIOThread(
mojo::InterfaceRequest<BackgroundSyncService> request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(background_sync_manager_);
- services_.insert(new BackgroundSyncServiceImpl(this, request.Pass()));
+ services_.insert(new BackgroundSyncServiceImpl(this, std::move(request)));
}
void BackgroundSyncContextImpl::ShutdownOnIO() {
diff --git a/chromium/content/browser/background_sync/background_sync_context_impl.h b/chromium/content/browser/background_sync/background_sync_context_impl.h
index c5a91039ec4..f30a6392728 100644
--- a/chromium/content/browser/background_sync/background_sync_context_impl.h
+++ b/chromium/content/browser/background_sync/background_sync_context_impl.h
@@ -7,6 +7,7 @@
#include <set>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/background_sync_service.mojom.h"
diff --git a/chromium/content/browser/background_sync/background_sync_manager.cc b/chromium/content/browser/background_sync/background_sync_manager.cc
index 477b31f02d7..926dbca6dc8 100644
--- a/chromium/content/browser/background_sync/background_sync_manager.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager.cc
@@ -4,12 +4,15 @@
#include "content/browser/background_sync/background_sync_manager.h"
+#include <utility>
+
#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/location.h"
-#include "base/metrics/field_trial.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
+#include "base/time/default_clock.h"
+#include "build/build_config.h"
#include "content/browser/background_sync/background_sync_metrics.h"
#include "content/browser/background_sync/background_sync_network_observer.h"
#include "content/browser/background_sync/background_sync_power_observer.h"
@@ -17,10 +20,14 @@
#include "content/browser/background_sync/background_sync_registration_options.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_storage.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/common/service_worker/service_worker_type_converters.h"
+#include "content/public/browser/background_sync_controller.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/common/background_sync.mojom.h"
#if defined(OS_ANDROID)
-#include "content/browser/android/background_sync_launcher_android.h"
#include "content/browser/android/background_sync_network_observer_android.h"
#endif
@@ -41,6 +48,7 @@ class BackgroundSyncManager::RefCountedRegistration
namespace {
+// The key used to index the background sync data in ServiceWorkerStorage.
const char kBackgroundSyncUserDataKey[] = "BackgroundSyncUserData";
void PostErrorResponse(
@@ -48,15 +56,82 @@ void PostErrorResponse(
const BackgroundSyncManager::StatusAndRegistrationCallback& callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(
- callback, status,
- base::Passed(scoped_ptr<BackgroundSyncRegistrationHandle>().Pass())));
+ base::Bind(callback, status,
+ base::Passed(scoped_ptr<BackgroundSyncRegistrationHandle>())));
+}
+
+// Returns nullptr if the controller cannot be accessed for any reason.
+BackgroundSyncController* GetBackgroundSyncControllerOnUIThread(
+ const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (!service_worker_context)
+ return nullptr;
+ StoragePartitionImpl* storage_partition_impl =
+ service_worker_context->storage_partition();
+ if (!storage_partition_impl) // may be null in tests
+ return nullptr;
+
+ return storage_partition_impl->browser_context()
+ ->GetBackgroundSyncController();
+}
+
+void NotifyBackgroundSyncRegisteredOnUIThread(
+ const scoped_refptr<ServiceWorkerContextWrapper>& sw_context_wrapper,
+ const GURL& origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BackgroundSyncController* background_sync_controller =
+ GetBackgroundSyncControllerOnUIThread(sw_context_wrapper);
+
+ if (!background_sync_controller)
+ return;
+
+ background_sync_controller->NotifyBackgroundSyncRegistered(origin);
+}
+
+void RunInBackgroundOnUIThread(
+ const scoped_refptr<ServiceWorkerContextWrapper>& sw_context_wrapper,
+ bool enabled,
+ int64_t min_ms) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BackgroundSyncController* background_sync_controller =
+ GetBackgroundSyncControllerOnUIThread(sw_context_wrapper);
+ if (background_sync_controller) {
+ background_sync_controller->RunInBackground(enabled, min_ms);
+ }
+}
+
+scoped_ptr<BackgroundSyncParameters> GetControllerParameters(
+ const scoped_refptr<ServiceWorkerContextWrapper>& sw_context_wrapper,
+ scoped_ptr<BackgroundSyncParameters> parameters) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BackgroundSyncController* background_sync_controller =
+ GetBackgroundSyncControllerOnUIThread(sw_context_wrapper);
+
+ if (!background_sync_controller) {
+ // If there is no controller then BackgroundSync can't run in the
+ // background, disable it.
+ parameters->disable = true;
+ return parameters;
+ }
+
+ background_sync_controller->GetParameterOverrides(parameters.get());
+ return parameters;
}
-bool ShouldDisableForFieldTrial() {
- std::string experiment = base::FieldTrialList::FindFullName("BackgroundSync");
- return base::StartsWith(experiment, "ExperimentDisable",
- base::CompareCase::INSENSITIVE_ASCII);
+void OnSyncEventFinished(
+ const scoped_refptr<ServiceWorkerVersion>& active_version,
+ int request_id,
+ const ServiceWorkerVersion::StatusCallback& callback,
+ ServiceWorkerEventStatus status) {
+ TRACE_EVENT1("ServiceWorker", "BackgroundSyncManager::OnSyncEventFinished",
+ "Request id", request_id);
+ if (!active_version->FinishRequest(request_id))
+ return;
+ callback.Run(mojo::ConvertTo<ServiceWorkerStatusCode>(status));
}
} // namespace
@@ -105,35 +180,35 @@ BackgroundSyncManager::RegistrationKey::RegistrationKey(
}
void BackgroundSyncManager::Register(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const BackgroundSyncRegistrationOptions& options,
bool requested_from_service_worker,
const StatusAndRegistrationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // For UMA, determine here whether the sync could fire immediately
- BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire =
- AreOptionConditionsMet(options)
- ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
- : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE;
-
if (disabled_) {
- BackgroundSyncMetrics::CountRegister(
- options.periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE,
- BACKGROUND_SYNC_STATUS_STORAGE_ERROR);
+ BackgroundSyncMetrics::CountRegisterFailure(
+ options.periodicity, BACKGROUND_SYNC_STATUS_STORAGE_ERROR);
PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback);
return;
}
- op_scheduler_.ScheduleOperation(base::Bind(
- &BackgroundSyncManager::RegisterImpl, weak_ptr_factory_.GetWeakPtr(),
- sw_registration_id, options, requested_from_service_worker,
- MakeStatusAndRegistrationCompletion(callback)));
+ if (requested_from_service_worker) {
+ op_scheduler_.ScheduleOperation(
+ base::Bind(&BackgroundSyncManager::RegisterCheckIfHasMainFrame,
+ weak_ptr_factory_.GetWeakPtr(), sw_registration_id, options,
+ MakeStatusAndRegistrationCompletion(callback)));
+ return;
+ }
+
+ op_scheduler_.ScheduleOperation(
+ base::Bind(&BackgroundSyncManager::RegisterImpl,
+ weak_ptr_factory_.GetWeakPtr(), sw_registration_id, options,
+ MakeStatusAndRegistrationCompletion(callback)));
}
void BackgroundSyncManager::GetRegistration(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const std::string& sync_registration_tag,
SyncPeriodicity periodicity,
const StatusAndRegistrationCallback& callback) {
@@ -153,7 +228,7 @@ void BackgroundSyncManager::GetRegistration(
}
void BackgroundSyncManager::GetRegistrations(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
SyncPeriodicity periodicity,
const StatusAndRegistrationsCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -164,8 +239,8 @@ void BackgroundSyncManager::GetRegistrations(
base::Bind(
callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR,
base::Passed(
- scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>>()
- .Pass())));
+ scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>>(
+ new ScopedVector<BackgroundSyncRegistrationHandle>()))));
return;
}
@@ -189,7 +264,7 @@ BackgroundSyncManager::DuplicateRegistrationHandle(
return CreateRegistrationHandle(ref_registration->get());
}
-void BackgroundSyncManager::OnRegistrationDeleted(int64 sw_registration_id,
+void BackgroundSyncManager::OnRegistrationDeleted(int64_t sw_registration_id,
const GURL& pattern) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -213,10 +288,20 @@ void BackgroundSyncManager::OnStorageWiped() {
weak_ptr_factory_.GetWeakPtr(), MakeEmptyCompletion()));
}
+void BackgroundSyncManager::SetMaxSyncAttemptsForTesting(int max_attempts) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ op_scheduler_.ScheduleOperation(base::Bind(
+ &BackgroundSyncManager::SetMaxSyncAttemptsImpl,
+ weak_ptr_factory_.GetWeakPtr(), max_attempts, MakeEmptyCompletion()));
+}
+
BackgroundSyncManager::BackgroundSyncManager(
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
: service_worker_context_(service_worker_context),
+ parameters_(new BackgroundSyncParameters()),
disabled_(false),
+ num_firing_registrations_(0),
+ clock_(new base::DefaultClock()),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -254,8 +339,27 @@ void BackgroundSyncManager::InitImpl(const base::Closure& callback) {
return;
}
- if (ShouldDisableForFieldTrial()) {
- DisableAndClearManager(callback);
+ scoped_ptr<BackgroundSyncParameters> parameters_copy(
+ new BackgroundSyncParameters(*parameters_));
+
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&GetControllerParameters, service_worker_context_,
+ base::Passed(std::move(parameters_copy))),
+ base::Bind(&BackgroundSyncManager::InitDidGetControllerParameters,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void BackgroundSyncManager::InitDidGetControllerParameters(
+ const base::Closure& callback,
+ scoped_ptr<BackgroundSyncParameters> updated_parameters) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ parameters_ = std::move(updated_parameters);
+ if (parameters_->disable) {
+ disabled_ = true;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback));
return;
}
@@ -267,7 +371,7 @@ void BackgroundSyncManager::InitImpl(const base::Closure& callback) {
void BackgroundSyncManager::InitDidGetDataFromBackend(
const base::Closure& callback,
- const std::vector<std::pair<int64, std::string>>& user_data,
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -278,7 +382,7 @@ void BackgroundSyncManager::InitDidGetDataFromBackend(
}
bool corruption_detected = false;
- for (const std::pair<int64, std::string>& data : user_data) {
+ for (const std::pair<int64_t, std::string>& data : user_data) {
BackgroundSyncRegistrationsProto registrations_proto;
if (registrations_proto.ParseFromString(data.second)) {
BackgroundSyncRegistrations* registrations =
@@ -312,6 +416,9 @@ void BackgroundSyncManager::InitDidGetDataFromBackend(
options->power_state = registration_proto.power_state();
registration->set_id(registration_proto.id());
+ registration->set_num_attempts(registration_proto.num_attempts());
+ registration->set_delay_until(
+ base::Time::FromInternalValue(registration_proto.delay_until()));
}
}
@@ -331,40 +438,60 @@ void BackgroundSyncManager::InitDidGetDataFromBackend(
base::Bind(callback));
}
-void BackgroundSyncManager::RegisterImpl(
- int64 sw_registration_id,
+void BackgroundSyncManager::RegisterCheckIfHasMainFrame(
+ int64_t sw_registration_id,
const BackgroundSyncRegistrationOptions& options,
- bool requested_from_service_worker,
const StatusAndRegistrationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // For UMA, determine here whether the sync could fire immediately
- BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire =
- AreOptionConditionsMet(options)
- ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
- : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE;
+ ServiceWorkerRegistration* sw_registration =
+ service_worker_context_->GetLiveRegistration(sw_registration_id);
+ if (!sw_registration || !sw_registration->active_version()) {
+ BackgroundSyncMetrics::CountRegisterFailure(
+ options.periodicity, BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER);
+ PostErrorResponse(BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER, callback);
+ return;
+ }
- if (disabled_) {
- BackgroundSyncMetrics::CountRegister(
- options.periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE,
- BACKGROUND_SYNC_STATUS_STORAGE_ERROR);
- PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback);
+ HasMainFrameProviderHost(
+ sw_registration->pattern().GetOrigin(),
+ base::Bind(&BackgroundSyncManager::RegisterDidCheckIfMainFrame,
+ weak_ptr_factory_.GetWeakPtr(), sw_registration_id, options,
+ callback));
+}
+
+void BackgroundSyncManager::RegisterDidCheckIfMainFrame(
+ int64_t sw_registration_id,
+ const BackgroundSyncRegistrationOptions& options,
+ const StatusAndRegistrationCallback& callback,
+ bool has_main_frame_client) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (!has_main_frame_client) {
+ BackgroundSyncMetrics::CountRegisterFailure(
+ options.periodicity, BACKGROUND_SYNC_STATUS_NOT_ALLOWED);
+ PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_ALLOWED, callback);
return;
}
+ RegisterImpl(sw_registration_id, options, callback);
+}
- if (ShouldDisableForFieldTrial()) {
- DisableAndClearManager(base::Bind(
- callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR,
- base::Passed(scoped_ptr<BackgroundSyncRegistrationHandle>().Pass())));
+void BackgroundSyncManager::RegisterImpl(
+ int64_t sw_registration_id,
+ const BackgroundSyncRegistrationOptions& options,
+ const StatusAndRegistrationCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (disabled_) {
+ BackgroundSyncMetrics::CountRegisterFailure(
+ options.periodicity, BACKGROUND_SYNC_STATUS_STORAGE_ERROR);
+ PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback);
return;
}
if (options.tag.length() > kMaxTagLength) {
- BackgroundSyncMetrics::CountRegister(
- options.periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE,
- BACKGROUND_SYNC_STATUS_NOT_ALLOWED);
+ BackgroundSyncMetrics::CountRegisterFailure(
+ options.periodicity, BACKGROUND_SYNC_STATUS_NOT_ALLOWED);
PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_ALLOWED, callback);
return;
}
@@ -372,19 +499,16 @@ void BackgroundSyncManager::RegisterImpl(
ServiceWorkerRegistration* sw_registration =
service_worker_context_->GetLiveRegistration(sw_registration_id);
if (!sw_registration || !sw_registration->active_version()) {
- BackgroundSyncMetrics::CountRegister(
- options.periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE,
- BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER);
+ BackgroundSyncMetrics::CountRegisterFailure(
+ options.periodicity, BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER);
PostErrorResponse(BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER, callback);
return;
}
- if (requested_from_service_worker &&
- !sw_registration->active_version()->HasWindowClients()) {
- PostErrorResponse(BACKGROUND_SYNC_STATUS_NOT_ALLOWED, callback);
- return;
- }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&NotifyBackgroundSyncRegisteredOnUIThread,
+ service_worker_context_,
+ sw_registration->pattern().GetOrigin()));
RefCountedRegistration* existing_registration_ref =
LookupActiveRegistration(sw_registration_id, RegistrationKey(options));
@@ -393,36 +517,28 @@ void BackgroundSyncManager::RegisterImpl(
BackgroundSyncRegistration* existing_registration =
existing_registration_ref->value();
- // Record the duplicated registration
- BackgroundSyncMetrics::CountRegister(
- existing_registration->options()->periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_DUPLICATE,
- BACKGROUND_SYNC_STATUS_OK);
+ BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire =
+ AreOptionConditionsMet(options)
+ ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
+ : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE;
+ BackgroundSyncMetrics::CountRegisterSuccess(
+ existing_registration->options()->periodicity,
+ registration_could_fire,
+ BackgroundSyncMetrics::REGISTRATION_IS_DUPLICATE);
+
+ if (existing_registration->IsFiring()) {
+ existing_registration->set_sync_state(
+ BACKGROUND_SYNC_STATE_REREGISTERED_WHILE_FIRING);
+ }
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(
callback, BACKGROUND_SYNC_STATUS_OK,
- base::Passed(
- CreateRegistrationHandle(existing_registration_ref).Pass())));
+ base::Passed(CreateRegistrationHandle(existing_registration_ref))));
return;
} else {
- DCHECK(!existing_registration_ref->value()->HasCompleted());
- bool firing = existing_registration_ref->value()->sync_state() ==
- BACKGROUND_SYNC_STATE_FIRING ||
- existing_registration_ref->value()->sync_state() ==
- BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING;
-
- existing_registration_ref->value()->set_sync_state(
- firing ? BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING
- : BACKGROUND_SYNC_STATE_UNREGISTERED);
-
- if (!firing) {
- // If the registration is currently firing then wait to run
- // RunDoneCallbacks until after it has finished as it might
- // change state to SUCCESS first.
- existing_registration_ref->value()->RunDoneCallbacks();
- }
+ existing_registration_ref->value()->SetUnregisteredState();
}
}
@@ -458,6 +574,16 @@ void BackgroundSyncManager::DisableAndClearManager(
}
disabled_ = true;
+
+ for (auto& sw_id_and_registrations : active_registrations_) {
+ for (auto& key_and_registration :
+ sw_id_and_registrations.second.registration_map) {
+ BackgroundSyncRegistration* registration =
+ key_and_registration.second->value();
+ registration->SetUnregisteredState();
+ }
+ }
+
active_registrations_.clear();
// Delete all backend entries. The memory representation of registered syncs
@@ -471,7 +597,7 @@ void BackgroundSyncManager::DisableAndClearManager(
void BackgroundSyncManager::DisableAndClearDidGetRegistrations(
const base::Closure& callback,
- const std::vector<std::pair<int64, std::string>>& user_data,
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -504,7 +630,7 @@ void BackgroundSyncManager::DisableAndClearManagerClearedOne(
BackgroundSyncManager::RefCountedRegistration*
BackgroundSyncManager::LookupActiveRegistration(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const RegistrationKey& registration_key) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -526,7 +652,7 @@ BackgroundSyncManager::LookupActiveRegistration(
}
void BackgroundSyncManager::StoreRegistrations(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const ServiceWorkerStorage::StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -549,6 +675,9 @@ void BackgroundSyncManager::StoreRegistrations(
registration_proto->set_network_state(
registration.options()->network_state);
registration_proto->set_power_state(registration.options()->power_state);
+ registration_proto->set_num_attempts(registration.num_attempts());
+ registration_proto->set_delay_until(
+ registration.delay_until().ToInternalValue());
}
std::string serialized;
bool success = registrations_proto.SerializeToString(&serialized);
@@ -559,7 +688,7 @@ void BackgroundSyncManager::StoreRegistrations(
}
void BackgroundSyncManager::RegisterDidStore(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const scoped_refptr<RefCountedRegistration>& new_registration_ref,
const StatusAndRegistrationCallback& callback,
ServiceWorkerStatusCode status) {
@@ -568,17 +697,10 @@ void BackgroundSyncManager::RegisterDidStore(
const BackgroundSyncRegistration* new_registration =
new_registration_ref->value();
- // For UMA, determine here whether the sync could fire immediately
- BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire =
- AreOptionConditionsMet(*new_registration->options())
- ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
- : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE;
-
if (status == SERVICE_WORKER_ERROR_NOT_FOUND) {
// The service worker registration is gone.
- BackgroundSyncMetrics::CountRegister(
- new_registration->options()->periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE,
+ BackgroundSyncMetrics::CountRegisterFailure(
+ new_registration->options()->periodicity,
BACKGROUND_SYNC_STATUS_STORAGE_ERROR);
active_registrations_.erase(sw_registration_id);
PostErrorResponse(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback);
@@ -588,31 +710,33 @@ void BackgroundSyncManager::RegisterDidStore(
if (status != SERVICE_WORKER_OK) {
LOG(ERROR) << "BackgroundSync failed to store registration due to backend "
"failure.";
- BackgroundSyncMetrics::CountRegister(
- new_registration->options()->periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE,
+ BackgroundSyncMetrics::CountRegisterFailure(
+ new_registration->options()->periodicity,
BACKGROUND_SYNC_STATUS_STORAGE_ERROR);
DisableAndClearManager(base::Bind(
callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR,
- base::Passed(scoped_ptr<BackgroundSyncRegistrationHandle>().Pass())));
+ base::Passed(scoped_ptr<BackgroundSyncRegistrationHandle>())));
return;
}
- BackgroundSyncMetrics::CountRegister(
+ BackgroundSyncMetrics::RegistrationCouldFire registration_could_fire =
+ AreOptionConditionsMet(*new_registration->options())
+ ? BackgroundSyncMetrics::REGISTRATION_COULD_FIRE
+ : BackgroundSyncMetrics::REGISTRATION_COULD_NOT_FIRE;
+ BackgroundSyncMetrics::CountRegisterSuccess(
new_registration->options()->periodicity, registration_could_fire,
- BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE,
- BACKGROUND_SYNC_STATUS_OK);
+ BackgroundSyncMetrics::REGISTRATION_IS_NOT_DUPLICATE);
+
FireReadyEvents();
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(
callback, BACKGROUND_SYNC_STATUS_OK,
- base::Passed(
- CreateRegistrationHandle(new_registration_ref.get()).Pass())));
+ base::Passed(CreateRegistrationHandle(new_registration_ref.get()))));
}
void BackgroundSyncManager::RemoveActiveRegistration(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const RegistrationKey& registration_key) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(LookupActiveRegistration(sw_registration_id, registration_key));
@@ -624,7 +748,7 @@ void BackgroundSyncManager::RemoveActiveRegistration(
}
void BackgroundSyncManager::AddActiveRegistration(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const GURL& origin,
const scoped_refptr<RefCountedRegistration>& sync_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -639,7 +763,7 @@ void BackgroundSyncManager::AddActiveRegistration(
}
void BackgroundSyncManager::StoreDataInBackend(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const GURL& origin,
const std::string& backend_key,
const std::string& data,
@@ -663,15 +787,46 @@ void BackgroundSyncManager::GetDataFromBackend(
void BackgroundSyncManager::FireOneShotSync(
BackgroundSyncRegistrationHandle::HandleId handle_id,
const scoped_refptr<ServiceWorkerVersion>& active_version,
+ BackgroundSyncEventLastChance last_chance,
const ServiceWorkerVersion::StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(active_version);
+ if (active_version->running_status() != ServiceWorkerVersion::RUNNING) {
+ active_version->RunAfterStartWorker(
+ callback, base::Bind(&BackgroundSyncManager::FireOneShotSync,
+ weak_ptr_factory_.GetWeakPtr(), handle_id,
+ active_version, last_chance, callback));
+ return;
+ }
+
+ int request_id = active_version->StartRequestWithCustomTimeout(
+ ServiceWorkerMetrics::EventType::SYNC, callback,
+ parameters_->max_sync_event_duration,
+ ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
+ base::WeakPtr<BackgroundSyncServiceClient> client =
+ active_version->GetMojoServiceForRequest<BackgroundSyncServiceClient>(
+ request_id);
+
// The ServiceWorkerVersion doesn't know when the client (javascript) is done
// with the registration so don't give it a BackgroundSyncRegistrationHandle.
// Once the render process gets the handle_id it can create its own handle
// (with a new unique handle id).
- active_version->DispatchSyncEvent(handle_id, callback);
+ client->Sync(
+ handle_id, last_chance,
+ base::Bind(&OnSyncEventFinished, active_version, request_id, callback));
+}
+
+void BackgroundSyncManager::ScheduleDelayedTask(const base::Closure& callback,
+ base::TimeDelta delay) {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, callback,
+ delay);
+}
+
+void BackgroundSyncManager::HasMainFrameProviderHost(
+ const GURL& origin,
+ const BoolCallback& callback) {
+ service_worker_context_->HasMainFrameProviderHost(origin, callback);
}
scoped_ptr<BackgroundSyncRegistrationHandle>
@@ -708,7 +863,7 @@ void BackgroundSyncManager::ReleaseRegistrationHandle(
}
void BackgroundSyncManager::Unregister(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
BackgroundSyncRegistrationHandle::HandleId handle_id,
const StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -733,7 +888,7 @@ void BackgroundSyncManager::Unregister(
}
void BackgroundSyncManager::UnregisterImpl(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const RegistrationKey& registration_key,
BackgroundSyncRegistration::RegistrationId sync_registration_id,
SyncPeriodicity periodicity,
@@ -760,23 +915,7 @@ void BackgroundSyncManager::UnregisterImpl(
return;
}
- DCHECK(!existing_registration->value()->HasCompleted());
-
- bool firing = existing_registration->value()->sync_state() ==
- BACKGROUND_SYNC_STATE_FIRING ||
- existing_registration->value()->sync_state() ==
- BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING;
-
- existing_registration->value()->set_sync_state(
- firing ? BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING
- : BACKGROUND_SYNC_STATE_UNREGISTERED);
-
- if (!firing) {
- // If the registration is currently firing then wait to run
- // RunDoneCallbacks until after it has finished as it might
- // change state to SUCCESS first.
- existing_registration->value()->RunDoneCallbacks();
- }
+ existing_registration->value()->SetUnregisteredState();
RemoveActiveRegistration(sw_registration_id, registration_key);
@@ -786,7 +925,7 @@ void BackgroundSyncManager::UnregisterImpl(
sw_registration_id, periodicity, callback));
}
-void BackgroundSyncManager::UnregisterDidStore(int64 sw_registration_id,
+void BackgroundSyncManager::UnregisterDidStore(int64_t sw_registration_id,
SyncPeriodicity periodicity,
const StatusCallback& callback,
ServiceWorkerStatusCode status) {
@@ -817,7 +956,7 @@ void BackgroundSyncManager::UnregisterDidStore(int64 sw_registration_id,
FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_OK));
}
-void BackgroundSyncManager::NotifyWhenDone(
+void BackgroundSyncManager::NotifyWhenFinished(
BackgroundSyncRegistrationHandle::HandleId handle_id,
const StatusAndStateCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -833,12 +972,12 @@ void BackgroundSyncManager::NotifyWhenDone(
DuplicateRegistrationHandle(handle_id);
op_scheduler_.ScheduleOperation(
- base::Bind(&BackgroundSyncManager::NotifyWhenDoneImpl,
+ base::Bind(&BackgroundSyncManager::NotifyWhenFinishedImpl,
weak_ptr_factory_.GetWeakPtr(),
- base::Passed(registration_handle.Pass()), callback));
+ base::Passed(std::move(registration_handle)), callback));
}
-void BackgroundSyncManager::NotifyWhenDoneImpl(
+void BackgroundSyncManager::NotifyWhenFinishedImpl(
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle,
const StatusAndStateCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -852,8 +991,8 @@ void BackgroundSyncManager::NotifyWhenDoneImpl(
}
if (!registration_handle->registration()->HasCompleted()) {
- registration_handle->registration()->AddDoneCallback(
- base::Bind(&BackgroundSyncManager::NotifyWhenDoneDidFinish,
+ registration_handle->registration()->AddFinishedCallback(
+ base::Bind(&BackgroundSyncManager::NotifyWhenFinishedInvokeCallback,
weak_ptr_factory_.GetWeakPtr(), callback));
op_scheduler_.CompleteOperationAndRunNext();
return;
@@ -865,23 +1004,16 @@ void BackgroundSyncManager::NotifyWhenDoneImpl(
op_scheduler_.CompleteOperationAndRunNext();
}
-void BackgroundSyncManager::NotifyWhenDoneDidFinish(
+void BackgroundSyncManager::NotifyWhenFinishedInvokeCallback(
const StatusAndStateCallback& callback,
BackgroundSyncState sync_state) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (disabled_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR,
- BACKGROUND_SYNC_STATE_FAILED));
- return;
- }
-
callback.Run(BACKGROUND_SYNC_STATUS_OK, sync_state);
}
void BackgroundSyncManager::GetRegistrationImpl(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const RegistrationKey& registration_key,
const StatusAndRegistrationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -901,11 +1033,11 @@ void BackgroundSyncManager::GetRegistrationImpl(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(callback, BACKGROUND_SYNC_STATUS_OK,
- base::Passed(CreateRegistrationHandle(registration).Pass())));
+ base::Passed(CreateRegistrationHandle(registration))));
}
void BackgroundSyncManager::GetRegistrationsImpl(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
SyncPeriodicity periodicity,
const StatusAndRegistrationsCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -916,7 +1048,7 @@ void BackgroundSyncManager::GetRegistrationsImpl(
if (disabled_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_STORAGE_ERROR,
- base::Passed(out_registrations.Pass())));
+ base::Passed(std::move(out_registrations))));
return;
}
@@ -936,7 +1068,7 @@ void BackgroundSyncManager::GetRegistrationsImpl(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(callback, BACKGROUND_SYNC_STATUS_OK,
- base::Passed(out_registrations.Pass())));
+ base::Passed(std::move(out_registrations))));
}
bool BackgroundSyncManager::AreOptionConditionsMet(
@@ -957,14 +1089,17 @@ bool BackgroundSyncManager::IsRegistrationReadyToFire(
if (registration.sync_state() != BACKGROUND_SYNC_STATE_PENDING)
return false;
+ if (clock_->Now() < registration.delay_until())
+ return false;
+
DCHECK_EQ(SYNC_ONE_SHOT, registration.options()->periodicity);
return AreOptionConditionsMet(*registration.options());
}
-void BackgroundSyncManager::SchedulePendingRegistrations() {
-#if defined(OS_ANDROID)
- bool keep_browser_alive_for_one_shot = false;
+void BackgroundSyncManager::RunInBackgroundIfNecessary() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ base::TimeDelta soonest_wakeup_delta = base::TimeDelta::Max();
for (const auto& sw_id_and_registrations : active_registrations_) {
for (const auto& key_and_registration :
@@ -973,7 +1108,14 @@ void BackgroundSyncManager::SchedulePendingRegistrations() {
*key_and_registration.second->value();
if (registration.sync_state() == BACKGROUND_SYNC_STATE_PENDING) {
if (registration.options()->periodicity == SYNC_ONE_SHOT) {
- keep_browser_alive_for_one_shot = true;
+ if (clock_->Now() >= registration.delay_until()) {
+ soonest_wakeup_delta = base::TimeDelta();
+ } else {
+ base::TimeDelta delay_delta =
+ registration.delay_until() - clock_->Now();
+ if (delay_delta < soonest_wakeup_delta)
+ soonest_wakeup_delta = delay_delta;
+ }
} else {
// TODO(jkarlin): Support keeping the browser alive for periodic
// syncs.
@@ -982,15 +1124,29 @@ void BackgroundSyncManager::SchedulePendingRegistrations() {
}
}
- // TODO(jkarlin): Use the context's path instead of the 'this' pointer as an
- // identifier. See crbug.com/489705.
+ // If the browser is closed while firing events, the browser needs a task to
+ // wake it back up and try again.
+ if (num_firing_registrations_ > 0 &&
+ soonest_wakeup_delta > parameters_->min_sync_recovery_time) {
+ soonest_wakeup_delta = parameters_->min_sync_recovery_time;
+ }
+
+ // Try firing again after the wakeup delta.
+ if (!soonest_wakeup_delta.is_max() &&
+ soonest_wakeup_delta != base::TimeDelta()) {
+ delayed_sync_task_.Reset(base::Bind(&BackgroundSyncManager::FireReadyEvents,
+ weak_ptr_factory_.GetWeakPtr()));
+ ScheduleDelayedTask(delayed_sync_task_.callback(), soonest_wakeup_delta);
+ }
+
+ // In case the browser closes (or to prevent it from closing), call
+ // RunInBackground to either wake up the browser at the wakeup delta or to
+ // keep the browser running.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&BackgroundSyncLauncherAndroid::LaunchBrowserWhenNextOnline,
- this, keep_browser_alive_for_one_shot));
-#else
-// TODO(jkarlin): Toggle Chrome's background mode.
-#endif
+ base::Bind(RunInBackgroundOnUIThread, service_worker_context_,
+ !soonest_wakeup_delta.is_max() /* should run in background */,
+ soonest_wakeup_delta.InMilliseconds()));
}
void BackgroundSyncManager::FireReadyEvents() {
@@ -1014,10 +1170,10 @@ void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) {
}
// Find the registrations that are ready to run.
- std::vector<std::pair<int64, RegistrationKey>> sw_id_and_keys_to_fire;
+ std::vector<std::pair<int64_t, RegistrationKey>> sw_id_and_keys_to_fire;
for (auto& sw_id_and_registrations : active_registrations_) {
- const int64 service_worker_id = sw_id_and_registrations.first;
+ const int64_t service_worker_id = sw_id_and_registrations.first;
for (auto& key_and_registration :
sw_id_and_registrations.second.registration_map) {
BackgroundSyncRegistration* registration =
@@ -1033,41 +1189,41 @@ void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) {
}
}
- // If there are no registrations currently ready, then just run |callback|.
- // Otherwise, fire them all, and record the result when done.
- if (sw_id_and_keys_to_fire.size() == 0) {
+ if (sw_id_and_keys_to_fire.empty()) {
+ RunInBackgroundIfNecessary();
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
base::Bind(callback));
- } else {
- base::TimeTicks start_time = base::TimeTicks::Now();
-
- // Fire the sync event of the ready registrations and run |callback| once
- // they're all done.
- base::Closure events_fired_barrier_closure = base::BarrierClosure(
- sw_id_and_keys_to_fire.size(), base::Bind(callback));
-
- // Record the total time taken after all events have run to completion.
- base::Closure events_completed_barrier_closure =
- base::BarrierClosure(sw_id_and_keys_to_fire.size(),
- base::Bind(&OnAllSyncEventsCompleted, start_time,
- sw_id_and_keys_to_fire.size()));
-
- for (const auto& sw_id_and_key : sw_id_and_keys_to_fire) {
- int64 service_worker_id = sw_id_and_key.first;
- const RefCountedRegistration* registration =
- LookupActiveRegistration(service_worker_id, sw_id_and_key.second);
- DCHECK(registration);
-
- service_worker_context_->FindRegistrationForId(
- service_worker_id, active_registrations_[service_worker_id].origin,
- base::Bind(&BackgroundSyncManager::FireReadyEventsDidFindRegistration,
- weak_ptr_factory_.GetWeakPtr(), sw_id_and_key.second,
- registration->value()->id(), events_fired_barrier_closure,
- events_completed_barrier_closure));
- }
+ return;
}
- SchedulePendingRegistrations();
+ base::TimeTicks start_time = base::TimeTicks::Now();
+
+ // Fire the sync event of the ready registrations and run |callback| once
+ // they're all done.
+ base::Closure events_fired_barrier_closure = base::BarrierClosure(
+ sw_id_and_keys_to_fire.size(),
+ base::Bind(&BackgroundSyncManager::FireReadyEventsAllEventsFiring,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+
+ // Record the total time taken after all events have run to completion.
+ base::Closure events_completed_barrier_closure =
+ base::BarrierClosure(sw_id_and_keys_to_fire.size(),
+ base::Bind(&OnAllSyncEventsCompleted, start_time,
+ sw_id_and_keys_to_fire.size()));
+
+ for (const auto& sw_id_and_key : sw_id_and_keys_to_fire) {
+ int64_t service_worker_id = sw_id_and_key.first;
+ const RefCountedRegistration* registration =
+ LookupActiveRegistration(service_worker_id, sw_id_and_key.second);
+ DCHECK(registration);
+
+ service_worker_context_->FindReadyRegistrationForId(
+ service_worker_id, active_registrations_[service_worker_id].origin,
+ base::Bind(&BackgroundSyncManager::FireReadyEventsDidFindRegistration,
+ weak_ptr_factory_.GetWeakPtr(), sw_id_and_key.second,
+ registration->value()->id(), events_fired_barrier_closure,
+ events_completed_barrier_closure));
+ }
}
void BackgroundSyncManager::FireReadyEventsDidFindRegistration(
@@ -1096,85 +1252,139 @@ void BackgroundSyncManager::FireReadyEventsDidFindRegistration(
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle =
CreateRegistrationHandle(registration);
+ num_firing_registrations_ += 1;
+
BackgroundSyncRegistrationHandle::HandleId handle_id =
registration_handle->handle_id();
+
+ BackgroundSyncEventLastChance last_chance =
+ registration->value()->num_attempts() ==
+ parameters_->max_sync_attempts - 1
+ ? BACKGROUND_SYNC_EVENT_LAST_CHANCE_IS_LAST_CHANCE
+ : BACKGROUND_SYNC_EVENT_LAST_CHANCE_IS_NOT_LAST_CHANCE;
+
+ HasMainFrameProviderHost(
+ service_worker_registration->pattern().GetOrigin(),
+ base::Bind(&BackgroundSyncMetrics::RecordEventStarted,
+ registration->value()->options()->periodicity));
+
FireOneShotSync(
- handle_id, service_worker_registration->active_version(),
- base::Bind(
- &BackgroundSyncManager::EventComplete, weak_ptr_factory_.GetWeakPtr(),
- service_worker_registration, service_worker_registration->id(),
- base::Passed(registration_handle.Pass()), event_completed_callback));
+ handle_id, service_worker_registration->active_version(), last_chance,
+ base::Bind(&BackgroundSyncManager::EventComplete,
+ weak_ptr_factory_.GetWeakPtr(), service_worker_registration,
+ service_worker_registration->id(),
+ base::Passed(std::move(registration_handle)),
+ event_completed_callback));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(event_fired_callback));
}
+void BackgroundSyncManager::FireReadyEventsAllEventsFiring(
+ const base::Closure& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ RunInBackgroundIfNecessary();
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback));
+}
+
// |service_worker_registration| is just to keep the registration alive
// while the event is firing.
void BackgroundSyncManager::EventComplete(
const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
- int64 service_worker_id,
+ int64_t service_worker_id,
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle,
const base::Closure& callback,
ServiceWorkerStatusCode status_code) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (disabled_)
- return;
+ // Do not check for disabled as events that were firing when disabled should
+ // be allowed to complete (for NotifyWhenFinished).
op_scheduler_.ScheduleOperation(base::Bind(
&BackgroundSyncManager::EventCompleteImpl, weak_ptr_factory_.GetWeakPtr(),
- service_worker_id, base::Passed(registration_handle.Pass()), status_code,
- MakeClosureCompletion(callback)));
+ service_worker_id, base::Passed(std::move(registration_handle)),
+ status_code, MakeClosureCompletion(callback)));
}
void BackgroundSyncManager::EventCompleteImpl(
- int64 service_worker_id,
+ int64_t service_worker_id,
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle,
ServiceWorkerStatusCode status_code,
const base::Closure& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (disabled_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback));
- return;
- }
-
BackgroundSyncRegistration* registration =
registration_handle->registration();
DCHECK(registration);
+ DCHECK(!registration->HasCompleted());
+
+ registration->set_num_attempts(registration->num_attempts() + 1);
+
+ num_firing_registrations_ -= 1;
// The event ran to completion, we should count it, no matter what happens
// from here.
- BackgroundSyncMetrics::RecordEventResult(registration->options()->periodicity,
- status_code == SERVICE_WORKER_OK);
+ ServiceWorkerRegistration* sw_registration =
+ service_worker_context_->GetLiveRegistration(service_worker_id);
+ if (sw_registration) {
+ HasMainFrameProviderHost(
+ sw_registration->pattern().GetOrigin(),
+ base::Bind(&BackgroundSyncMetrics::RecordEventResult,
+ registration->options()->periodicity,
+ status_code == SERVICE_WORKER_OK));
+ }
if (registration->options()->periodicity == SYNC_ONE_SHOT) {
- if (status_code != SERVICE_WORKER_OK) {
- // TODO(jkarlin): Insert retry logic here. Be sure to check if the state
- // is UNREGISTERED_WHILE_FIRING first. If so then set the state to failed
- // if it was already out of retry attempts otherwise keep the state as
- // unregistered. Then call RunDoneCallbacks(); (crbug.com/501838)
- registration->set_sync_state(BACKGROUND_SYNC_STATE_FAILED);
- registration->RunDoneCallbacks();
- } else {
+ if (registration->sync_state() ==
+ BACKGROUND_SYNC_STATE_REREGISTERED_WHILE_FIRING) {
+ registration->set_sync_state(BACKGROUND_SYNC_STATE_PENDING);
+ registration->set_num_attempts(0);
+ } else if (status_code != SERVICE_WORKER_OK) { // Sync failed
+ bool can_retry =
+ registration->num_attempts() < parameters_->max_sync_attempts;
+ if (registration->sync_state() ==
+ BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING) {
+ registration->set_sync_state(can_retry
+ ? BACKGROUND_SYNC_STATE_UNREGISTERED
+ : BACKGROUND_SYNC_STATE_FAILED);
+ registration->RunFinishedCallbacks();
+ } else if (can_retry) {
+ registration->set_sync_state(BACKGROUND_SYNC_STATE_PENDING);
+ registration->set_delay_until(
+ clock_->Now() +
+ parameters_->initial_retry_delay *
+ pow(parameters_->retry_delay_factor,
+ registration->num_attempts() - 1));
+ } else {
+ registration->set_sync_state(BACKGROUND_SYNC_STATE_FAILED);
+ registration->RunFinishedCallbacks();
+ }
+ } else { // Sync succeeded
registration->set_sync_state(BACKGROUND_SYNC_STATE_SUCCESS);
- registration->RunDoneCallbacks();
+ registration->RunFinishedCallbacks();
}
- RegistrationKey key(*registration);
- // Remove the registration if it's still active.
- RefCountedRegistration* active_registration =
- LookupActiveRegistration(service_worker_id, key);
- if (active_registration &&
- active_registration->value()->id() == registration->id()) {
- RemoveActiveRegistration(service_worker_id, key);
+ if (registration->HasCompleted()) {
+ RegistrationKey key(*registration);
+ RefCountedRegistration* active_registration =
+ LookupActiveRegistration(service_worker_id, key);
+ if (active_registration &&
+ active_registration->value()->id() == registration->id()) {
+ RemoveActiveRegistration(service_worker_id, key);
+ }
}
- } else {
+ } else { // !SYNC_ONE_SHOT
// TODO(jkarlin): Add support for running periodic syncs. (crbug.com/479674)
NOTREACHED();
}
+ if (disabled_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback));
+ return;
+ }
+
StoreRegistrations(
service_worker_id,
base::Bind(&BackgroundSyncManager::EventCompleteDidStore,
@@ -1182,7 +1392,7 @@ void BackgroundSyncManager::EventCompleteImpl(
}
void BackgroundSyncManager::EventCompleteDidStore(
- int64 service_worker_id,
+ int64_t service_worker_id,
const base::Closure& callback,
ServiceWorkerStatusCode status_code) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -1202,6 +1412,9 @@ void BackgroundSyncManager::EventCompleteDidStore(
return;
}
+ // Fire any ready events and call RunInBackground if anything is waiting.
+ FireReadyEvents();
+
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
base::Bind(callback));
}
@@ -1216,7 +1429,7 @@ void BackgroundSyncManager::OnAllSyncEventsCompleted(
}
void BackgroundSyncManager::OnRegistrationDeletedImpl(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const base::Closure& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -1247,6 +1460,15 @@ void BackgroundSyncManager::OnPowerChanged() {
FireReadyEvents();
}
+void BackgroundSyncManager::SetMaxSyncAttemptsImpl(
+ int max_attempts,
+ const base::Closure& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ parameters_->max_sync_attempts = max_attempts;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
+}
+
// TODO(jkarlin): Figure out how to pass scoped_ptrs with this.
template <typename CallbackT, typename... Params>
void BackgroundSyncManager::CompleteOperationCallback(const CallbackT& callback,
@@ -1263,7 +1485,7 @@ void BackgroundSyncManager::CompleteStatusAndRegistrationCallback(
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- callback.Run(status, registration_handle.Pass());
+ callback.Run(status, std::move(registration_handle));
op_scheduler_.CompleteOperationAndRunNext();
}
@@ -1274,7 +1496,7 @@ void BackgroundSyncManager::CompleteStatusAndRegistrationsCallback(
registration_handles) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- callback.Run(status, registration_handles.Pass());
+ callback.Run(status, std::move(registration_handles));
op_scheduler_.CompleteOperationAndRunNext();
}
diff --git a/chromium/content/browser/background_sync/background_sync_manager.h b/chromium/content/browser/background_sync/background_sync_manager.h
index a845dd3a249..42a69ea8989 100644
--- a/chromium/content/browser/background_sync/background_sync_manager.h
+++ b/chromium/content/browser/background_sync/background_sync_manager.h
@@ -5,15 +5,21 @@
#ifndef CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_
#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_MANAGER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/callback_forward.h"
+#include "base/cancelable_callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
+#include "base/time/clock.h"
#include "content/browser/background_sync/background_sync.pb.h"
#include "content/browser/background_sync/background_sync_registration.h"
#include "content/browser/background_sync/background_sync_registration_handle.h"
@@ -24,6 +30,8 @@
#include "content/common/background_sync_service.mojom.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_status_code.h"
+#include "content/public/browser/background_sync_parameters.h"
+#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"
namespace content {
@@ -36,20 +44,12 @@ class ServiceWorkerContextWrapper;
// registrations across all registered service workers for a profile.
// Registrations are stored along with their associated Service Worker
// registration in ServiceWorkerStorage. If the ServiceWorker is unregistered,
-// the sync registrations are removed. This class expects to be run on the IO
+// the sync registrations are removed. This class must be run on the IO
// thread. The asynchronous methods are executed sequentially.
-
-// TODO(jkarlin): Check permissions when registering, scheduling, and firing
-// background sync. In the meantime, --enable-service-worker-sync is required to
-// fire a sync event.
-// TODO(jkarlin): Unregister syncs when permission is revoked.
-// TODO(jkarlin): Create a background sync scheduler to actually run the
-// registered events.
-// TODO(jkarlin): Keep the browser alive if "Let Google Chrome Run in the
-// Background" is true and a sync is registered.
class CONTENT_EXPORT BackgroundSyncManager
: NON_EXPORTED_BASE(public ServiceWorkerContextObserver) {
public:
+ using BoolCallback = base::Callback<void(bool)>;
using StatusCallback = base::Callback<void(BackgroundSyncStatus)>;
using StatusAndRegistrationCallback =
base::Callback<void(BackgroundSyncStatus,
@@ -71,21 +71,27 @@ class CONTENT_EXPORT BackgroundSyncManager
// The accepted registration will have a unique id. It may also have altered
// parameters if the user or UA chose different parameters than those
// supplied.
- void Register(int64 sw_registration_id,
+ void Register(int64_t sw_registration_id,
const BackgroundSyncRegistrationOptions& options,
bool requested_from_service_worker,
const StatusAndRegistrationCallback& callback);
// Finds the background sync registration associated with
- // |sw_registration_id| with periodicity |periodicity|. Calls
- // |callback| with BACKGROUND_SYNC_STATUS_NOT_FOUND if it doesn't exist. Calls
- // |callback| with BACKGROUND_SYNC_STATUS_OK on success.
- void GetRegistration(int64 sw_registration_id,
+ // |sw_registration_id|, periodicity |periodicity|, and tag
+ // |sync_registration_tag|. Calls |callback| with
+ // BACKGROUND_SYNC_STATUS_NOT_FOUND if it doesn't exist. Calls |callback| with
+ // BACKGROUND_SYNC_STATUS_OK on success. If the callback's status
+ // is not BACKGROUND_SYNC_STATUS_OK then the callback's RegistrationHandle
+ // will be nullptr.
+ void GetRegistration(int64_t sw_registration_id,
const std::string& sync_registration_tag,
SyncPeriodicity periodicity,
const StatusAndRegistrationCallback& callback);
- void GetRegistrations(int64 sw_registration_id,
+ // Finds the background sync registrations associated with
+ // |sw_registration_id| and periodicity |periodicity|. Calls
+ // |callback| with BACKGROUND_SYNC_STATUS_OK on success.
+ void GetRegistrations(int64_t sw_registration_id,
SyncPeriodicity periodicity,
const StatusAndRegistrationsCallback& callback);
@@ -95,14 +101,23 @@ class CONTENT_EXPORT BackgroundSyncManager
BackgroundSyncRegistrationHandle::HandleId handle_id);
// ServiceWorkerContextObserver overrides.
- void OnRegistrationDeleted(int64 sw_registration_id,
+ void OnRegistrationDeleted(int64_t sw_registration_id,
const GURL& pattern) override;
void OnStorageWiped() override;
+ // Sets the max number of sync attempts after any pending operations have
+ // completed.
+ void SetMaxSyncAttemptsForTesting(int max_attempts);
+
BackgroundSyncNetworkObserver* GetNetworkObserverForTesting() {
return network_observer_.get();
}
+ void set_clock(scoped_ptr<base::Clock> clock) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ clock_ = std::move(clock);
+ }
+
protected:
// A registration might be referenced by the client longer than
// the BackgroundSyncManager needs to keep track of it (e.g., the event has
@@ -120,7 +135,7 @@ class CONTENT_EXPORT BackgroundSyncManager
// The following methods are virtual for testing.
virtual void StoreDataInBackend(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const GURL& origin,
const std::string& backend_key,
const std::string& data,
@@ -132,9 +147,15 @@ class CONTENT_EXPORT BackgroundSyncManager
virtual void FireOneShotSync(
BackgroundSyncRegistrationHandle::HandleId handle_id,
const scoped_refptr<ServiceWorkerVersion>& active_version,
+ BackgroundSyncEventLastChance last_chance,
const ServiceWorkerVersion::StatusCallback& callback);
+ virtual void ScheduleDelayedTask(const base::Closure& callback,
+ base::TimeDelta delay);
+ virtual void HasMainFrameProviderHost(const GURL& origin,
+ const BoolCallback& callback);
private:
+ friend class TestBackgroundSyncManager;
friend class BackgroundSyncManagerTest;
friend class BackgroundSyncRegistrationHandle;
@@ -167,7 +188,7 @@ class CONTENT_EXPORT BackgroundSyncManager
};
using PermissionStatusCallback = base::Callback<void(bool)>;
- using SWIdToRegistrationsMap = std::map<int64, BackgroundSyncRegistrations>;
+ using SWIdToRegistrationsMap = std::map<int64_t, BackgroundSyncRegistrations>;
static const size_t kMaxTagLength = 10240;
@@ -185,50 +206,63 @@ class CONTENT_EXPORT BackgroundSyncManager
BackgroundSyncRegistrationHandle::HandleId handle_id);
// Disable the manager. Already queued operations will abort once they start
- // to run (in their impl methods). Future operations will not queue. Any
- // registrations are cleared from memory and the backend (if it's still
- // functioning). The manager will reenable itself once it receives the
- // OnStorageWiped message or on browser restart.
+ // to run (in their impl methods). Future operations will not queue. The one
+ // exception is already firing events -- their responses will be processed in
+ // order to notify their final state.
+ // The list of active registrations is cleared and the backend is also cleared
+ // (if it's still functioning). The manager will reenable itself once it
+ // receives the OnStorageWiped message or on browser restart.
void DisableAndClearManager(const base::Closure& callback);
void DisableAndClearDidGetRegistrations(
const base::Closure& callback,
- const std::vector<std::pair<int64, std::string>>& user_data,
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerStatusCode status);
void DisableAndClearManagerClearedOne(const base::Closure& barrier_closure,
ServiceWorkerStatusCode status);
// Returns the existing registration or nullptr if it cannot be found.
RefCountedRegistration* LookupActiveRegistration(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const RegistrationKey& registration_key);
// Write all registrations for a given |sw_registration_id| to persistent
// storage.
- void StoreRegistrations(int64 sw_registration_id,
+ void StoreRegistrations(int64_t sw_registration_id,
const ServiceWorkerStorage::StatusCallback& callback);
// Removes the active registration if it is in the map.
- void RemoveActiveRegistration(int64 sw_registration_id,
+ void RemoveActiveRegistration(int64_t sw_registration_id,
const RegistrationKey& registration_key);
void AddActiveRegistration(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const GURL& origin,
const scoped_refptr<RefCountedRegistration>& sync_registration);
void InitImpl(const base::Closure& callback);
+ void InitDidGetControllerParameters(
+ const base::Closure& callback,
+ scoped_ptr<BackgroundSyncParameters> parameters);
void InitDidGetDataFromBackend(
const base::Closure& callback,
- const std::vector<std::pair<int64, std::string>>& user_data,
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerStatusCode status);
// Register callbacks
- void RegisterImpl(int64 sw_registration_id,
+ void RegisterCheckIfHasMainFrame(
+ int64_t sw_registration_id,
+ const BackgroundSyncRegistrationOptions& options,
+ const StatusAndRegistrationCallback& callback);
+ void RegisterDidCheckIfMainFrame(
+ int64_t sw_registration_id,
+ const BackgroundSyncRegistrationOptions& options,
+ const StatusAndRegistrationCallback& callback,
+ bool has_main_frame_client);
+ void RegisterImpl(int64_t sw_registration_id,
const BackgroundSyncRegistrationOptions& options,
- bool requested_from_service_worker,
const StatusAndRegistrationCallback& callback);
void RegisterDidStore(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const scoped_refptr<RefCountedRegistration>& new_registration_ref,
const StatusAndRegistrationCallback& callback,
ServiceWorkerStatusCode status);
@@ -237,38 +271,38 @@ class CONTENT_EXPORT BackgroundSyncManager
// |sync_registration_id|. Calls |callback| with
// BACKGROUND_SYNC_STATUS_NOT_FOUND if no match is found. Calls |callback|
// with BACKGROUND_SYNC_STATUS_OK on success.
- void Unregister(int64 sw_registration_id,
+ void Unregister(int64_t sw_registration_id,
BackgroundSyncRegistrationHandle::HandleId handle_id,
const StatusCallback& callback);
void UnregisterImpl(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const RegistrationKey& key,
BackgroundSyncRegistration::RegistrationId sync_registration_id,
SyncPeriodicity periodicity,
const StatusCallback& callback);
- void UnregisterDidStore(int64 sw_registration_id,
+ void UnregisterDidStore(int64_t sw_registration_id,
SyncPeriodicity periodicity,
const StatusCallback& callback,
ServiceWorkerStatusCode status);
- // NotifyWhenDone and its callbacks. See
- // BackgroundSyncRegistrationHandle::NotifyWhenDone for detailed
+ // NotifyWhenFinished and its callbacks. See
+ // BackgroundSyncRegistrationHandle::NotifyWhenFinished for detailed
// documentation.
- void NotifyWhenDone(BackgroundSyncRegistrationHandle::HandleId handle_id,
- const StatusAndStateCallback& callback);
- void NotifyWhenDoneImpl(
+ void NotifyWhenFinished(BackgroundSyncRegistrationHandle::HandleId handle_id,
+ const StatusAndStateCallback& callback);
+ void NotifyWhenFinishedImpl(
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle,
const StatusAndStateCallback& callback);
- void NotifyWhenDoneDidFinish(const StatusAndStateCallback& callback,
- BackgroundSyncState status);
+ void NotifyWhenFinishedInvokeCallback(const StatusAndStateCallback& callback,
+ BackgroundSyncState status);
// GetRegistration callbacks
- void GetRegistrationImpl(int64 sw_registration_id,
+ void GetRegistrationImpl(int64_t sw_registration_id,
const RegistrationKey& registration_key,
const StatusAndRegistrationCallback& callback);
// GetRegistrations callbacks
- void GetRegistrationsImpl(int64 sw_registration_id,
+ void GetRegistrationsImpl(int64_t sw_registration_id,
SyncPeriodicity periodicity,
const StatusAndRegistrationsCallback& callback);
@@ -276,13 +310,17 @@ class CONTENT_EXPORT BackgroundSyncManager
bool IsRegistrationReadyToFire(
const BackgroundSyncRegistration& registration);
- // Schedules pending registrations to run in the future. For one-shots this
- // means keeping the browser alive so that network connectivity events can be
- // seen (on Android the browser is instead woken up the next time it goes
- // online). For periodic syncs this means creating an alarm.
- void SchedulePendingRegistrations();
-
- // FireReadyEvents and callbacks
+ // Determines if the browser needs to be able to run in the background (e.g.,
+ // to run a pending registration or verify that a firing registration
+ // completed). If background processing is required it calls out to the
+ // BackgroundSyncController to enable it.
+ // Assumes that all registrations in the pending state are not currently ready
+ // to fire. Therefore this should not be called directly and should only be
+ // called by FireReadyEvents.
+ void RunInBackgroundIfNecessary();
+
+ // FireReadyEvents scans the list of available events and fires those that are
+ // ready to fire. For those that can't yet be fired, wakeup alarms are set.
void FireReadyEvents();
void FireReadyEventsImpl(const base::Closure& callback);
void FireReadyEventsDidFindRegistration(
@@ -293,21 +331,22 @@ class CONTENT_EXPORT BackgroundSyncManager
ServiceWorkerStatusCode service_worker_status,
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration);
+ void FireReadyEventsAllEventsFiring(const base::Closure& callback);
// Called when a sync event has completed.
void EventComplete(
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration,
- int64 service_worker_id,
+ int64_t service_worker_id,
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle,
const base::Closure& callback,
ServiceWorkerStatusCode status_code);
void EventCompleteImpl(
- int64 service_worker_id,
+ int64_t service_worker_id,
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle,
ServiceWorkerStatusCode status_code,
const base::Closure& callback);
- void EventCompleteDidStore(int64 service_worker_id,
+ void EventCompleteDidStore(int64_t service_worker_id,
const base::Closure& callback,
ServiceWorkerStatusCode status_code);
@@ -316,7 +355,7 @@ class CONTENT_EXPORT BackgroundSyncManager
int number_of_batched_sync_events);
// OnRegistrationDeleted callbacks
- void OnRegistrationDeletedImpl(int64 sw_registration_id,
+ void OnRegistrationDeletedImpl(int64_t sw_registration_id,
const base::Closure& callback);
// OnStorageWiped callbacks
@@ -325,6 +364,10 @@ class CONTENT_EXPORT BackgroundSyncManager
void OnNetworkChanged();
void OnPowerChanged();
+ // SetMaxSyncAttempts callback
+ void SetMaxSyncAttemptsImpl(int max_sync_attempts,
+ const base::Closure& callback);
+
// Operation Scheduling callback and convenience functions.
template <typename CallbackT, typename... Params>
void CompleteOperationCallback(const CallbackT& callback,
@@ -349,8 +392,17 @@ class CONTENT_EXPORT BackgroundSyncManager
SWIdToRegistrationsMap active_registrations_;
CacheStorageScheduler op_scheduler_;
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
+
+ scoped_ptr<BackgroundSyncParameters> parameters_;
+
+ // True if the manager is disabled and registrations should fail.
bool disabled_;
+ // The number of registrations currently in the firing state.
+ int num_firing_registrations_;
+
+ base::CancelableCallback<void()> delayed_sync_task_;
+
scoped_ptr<BackgroundSyncNetworkObserver> network_observer_;
scoped_ptr<BackgroundSyncPowerObserver> power_observer_;
@@ -359,6 +411,8 @@ class CONTENT_EXPORT BackgroundSyncManager
IDMapOwnPointer,
BackgroundSyncRegistrationHandle::HandleId> registration_handle_ids_;
+ scoped_ptr<base::Clock> clock_;
+
base::WeakPtrFactory<BackgroundSyncManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BackgroundSyncManager);
diff --git a/chromium/content/browser/background_sync/background_sync_manager_unittest.cc b/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
index 72db49fc0f5..bf0670df243 100644
--- a/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -4,15 +4,20 @@
#include "content/browser/background_sync/background_sync_manager.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/mock_entropy_provider.h"
+#include "base/test/simple_test_clock.h"
#include "base/thread_task_runner_handle.h"
#include "content/browser/background_sync/background_sync_network_observer.h"
#include "content/browser/background_sync/background_sync_registration_handle.h"
@@ -22,6 +27,11 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_storage.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/background_sync_controller.h"
+#include "content/public/browser/background_sync_parameters.h"
+#include "content/public/test/background_sync_test_util.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -34,13 +44,12 @@ const char kPattern1[] = "https://example.com/a";
const char kPattern2[] = "https://example.com/b";
const char kScript1[] = "https://example.com/a/script.js";
const char kScript2[] = "https://example.com/b/script.js";
-const int kRenderProcessId = 99;
void RegisterServiceWorkerCallback(bool* called,
- int64* store_registration_id,
+ int64_t* store_registration_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
@@ -85,11 +94,11 @@ void OneShotDelayedCallback(
*out_callback = callback;
}
-void NotifyWhenDoneCallback(bool* was_called,
- BackgroundSyncStatus* out_status,
- BackgroundSyncState* out_state,
- BackgroundSyncStatus status,
- BackgroundSyncState state) {
+void NotifyWhenFinishedCallback(bool* was_called,
+ BackgroundSyncStatus* out_status,
+ BackgroundSyncState* out_state,
+ BackgroundSyncStatus status,
+ BackgroundSyncState state) {
*was_called = true;
*out_status = status;
*out_state = state;
@@ -107,6 +116,46 @@ class TestPowerSource : public base::PowerMonitorSource {
bool test_on_battery_power_ = false;
};
+class TestBackgroundSyncController : public BackgroundSyncController {
+ public:
+ TestBackgroundSyncController() = default;
+
+ // BackgroundSyncController Overrides
+ void NotifyBackgroundSyncRegistered(const GURL& origin) override {
+ registration_count_ += 1;
+ registration_origin_ = origin;
+ }
+ void RunInBackground(bool enabled, int64_t min_ms) override {
+ run_in_background_count_ += 1;
+ run_in_background_enabled_ = enabled;
+ run_in_background_min_ms_ = min_ms;
+ }
+ void GetParameterOverrides(
+ BackgroundSyncParameters* parameters) const override {
+ *parameters = background_sync_parameters_;
+ }
+
+ int registration_count() const { return registration_count_; }
+ GURL registration_origin() const { return registration_origin_; }
+ int run_in_background_count() const { return run_in_background_count_; }
+ bool run_in_background_enabled() const { return run_in_background_enabled_; }
+ int64_t run_in_background_min_ms() const { return run_in_background_min_ms_; }
+ BackgroundSyncParameters* background_sync_parameters() {
+ return &background_sync_parameters_;
+ }
+
+ private:
+ int registration_count_ = 0;
+ GURL registration_origin_;
+
+ int run_in_background_count_ = 0;
+ bool run_in_background_enabled_ = true;
+ int64_t run_in_background_min_ms_ = 0;
+ BackgroundSyncParameters background_sync_parameters_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestBackgroundSyncController);
+};
+
} // namespace
// A BackgroundSyncManager that can simulate delaying and corrupting the backend
@@ -119,12 +168,13 @@ class TestBackgroundSyncManager : public BackgroundSyncManager {
explicit TestBackgroundSyncManager(
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
- : BackgroundSyncManager(service_worker_context) {}
+ : BackgroundSyncManager(service_worker_context) {
+ }
void DoInit() { Init(); }
void StoreDataInBackendContinue(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const GURL& origin,
const std::string& key,
const std::string& data,
@@ -146,6 +196,8 @@ class TestBackgroundSyncManager : public BackgroundSyncManager {
continuation_.Reset();
}
+ void ClearDelayedTask() { delayed_task_.Reset(); }
+
void set_corrupt_backend(bool corrupt_backend) {
corrupt_backend_ = corrupt_backend;
}
@@ -154,9 +206,22 @@ class TestBackgroundSyncManager : public BackgroundSyncManager {
one_shot_callback_ = callback;
}
+ base::Closure delayed_task() const { return delayed_task_; }
+ base::TimeDelta delayed_task_delta() const { return delayed_task_delta_; }
+
+ BackgroundSyncEventLastChance last_chance() const { return last_chance_; }
+
+ void set_has_main_frame_provider_host(bool value) {
+ has_main_frame_provider_host_ = value;
+ }
+
+ const BackgroundSyncParameters* background_sync_parameters() const {
+ return parameters_.get();
+ }
+
protected:
void StoreDataInBackend(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const GURL& origin,
const std::string& key,
const std::string& data,
@@ -185,7 +250,7 @@ class TestBackgroundSyncManager : public BackgroundSyncManager {
if (corrupt_backend_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(callback, std::vector<std::pair<int64, std::string>>(),
+ base::Bind(callback, std::vector<std::pair<int64_t, std::string>>(),
SERVICE_WORKER_ERROR_FAILED));
return;
}
@@ -201,27 +266,41 @@ class TestBackgroundSyncManager : public BackgroundSyncManager {
void FireOneShotSync(
BackgroundSyncRegistrationHandle::HandleId handle_id,
const scoped_refptr<ServiceWorkerVersion>& active_version,
+ BackgroundSyncEventLastChance last_chance,
const ServiceWorkerVersion::StatusCallback& callback) override {
ASSERT_FALSE(one_shot_callback_.is_null());
+ last_chance_ = last_chance;
one_shot_callback_.Run(active_version, callback);
}
+ void ScheduleDelayedTask(const base::Closure& callback,
+ base::TimeDelta delay) override {
+ delayed_task_ = callback;
+ delayed_task_delta_ = delay;
+ }
+
+ void HasMainFrameProviderHost(const GURL& origin,
+ const BoolCallback& callback) override {
+ callback.Run(has_main_frame_provider_host_);
+ }
+
private:
bool corrupt_backend_ = false;
bool delay_backend_ = false;
+ bool has_main_frame_provider_host_ = true;
+ BackgroundSyncEventLastChance last_chance_ =
+ BACKGROUND_SYNC_EVENT_LAST_CHANCE_IS_NOT_LAST_CHANCE;
base::Closure continuation_;
OneShotCallback one_shot_callback_;
+ base::Closure delayed_task_;
+ base::TimeDelta delayed_task_delta_;
};
class BackgroundSyncManagerTest : public testing::Test {
public:
BackgroundSyncManagerTest()
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- network_change_notifier_(net::NetworkChangeNotifier::CreateMock()),
- test_background_sync_manager_(nullptr),
- callback_status_(BACKGROUND_SYNC_STATUS_OK),
- callback_sw_status_code_(SERVICE_WORKER_OK),
- sync_events_called_(0) {
+ network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
sync_options_1_.tag = "foo";
sync_options_1_.periodicity = SYNC_ONE_SHOT;
sync_options_1_.network_state = NETWORK_STATE_ONLINE;
@@ -235,10 +314,21 @@ class BackgroundSyncManagerTest : public testing::Test {
void SetUp() override {
// Don't let the tests be confused by the real-world device connectivity
- BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(true);
-
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
+ background_sync_test_util::SetIgnoreNetworkChangeNotifier(true);
+
+ // TODO(jkarlin): Create a new object with all of the necessary SW calls
+ // so that we can inject test versions instead of bringing up all of this
+ // extra SW stuff.
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
+
+ // Create a StoragePartition with the correct BrowserContext so that the
+ // BackgroundSyncManager can find the BrowserContext through it.
+ storage_partition_impl_.reset(new StoragePartitionImpl(
+ helper_->browser_context(), base::FilePath(), nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr));
+ helper_->context_wrapper()->set_storage_partition(
+ storage_partition_impl_.get());
power_monitor_source_ = new TestPowerSource();
// power_monitor_ takes ownership of power_monitor_source.
@@ -247,7 +337,13 @@ class BackgroundSyncManagerTest : public testing::Test {
SetOnBatteryPower(false);
- SetupBackgroundSyncManager();
+ scoped_ptr<TestBackgroundSyncController> background_sync_controller(
+ new TestBackgroundSyncController());
+ test_controller_ = background_sync_controller.get();
+ helper_->browser_context()->SetBackgroundSyncController(
+ std::move(background_sync_controller));
+
+ SetMaxSyncAttemptsAndRestartManager(1);
// Wait for storage to finish initializing before registering service
// workers.
@@ -257,8 +353,7 @@ class BackgroundSyncManagerTest : public testing::Test {
void TearDown() override {
// Restore the network observer functionality for subsequent tests
- BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(
- false);
+ background_sync_test_util::SetIgnoreNetworkChangeNotifier(false);
}
void RegisterServiceWorkers() {
@@ -277,38 +372,18 @@ class BackgroundSyncManagerTest : public testing::Test {
EXPECT_TRUE(called_1);
EXPECT_TRUE(called_2);
- // Register window clients for the service workers
- host_1_.reset(new ServiceWorkerProviderHost(
- 34 /* dummy render proces id */, MSG_ROUTING_NONE /* render_frame_id */,
- 1 /* dummy provider id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- helper_->context()->AsWeakPtr(), nullptr));
- host_1_->SetDocumentUrl(GURL(kPattern1));
- host_2_.reset(new ServiceWorkerProviderHost(
- 34 /* dummy render proces id */, MSG_ROUTING_NONE /* render_frame_id */,
- 1 /* dummy provider id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- helper_->context()->AsWeakPtr(), nullptr));
- host_2_->SetDocumentUrl(GURL(kPattern2));
-
// Hang onto the registrations as they need to be "live" when
// calling BackgroundSyncManager::Register.
- helper_->context_wrapper()->FindRegistrationForId(
+ helper_->context_wrapper()->FindReadyRegistrationForId(
sw_registration_id_1_, GURL(kPattern1).GetOrigin(),
base::Bind(FindServiceWorkerRegistrationCallback, &sw_registration_1_));
- helper_->context_wrapper()->FindRegistrationForId(
+ helper_->context_wrapper()->FindReadyRegistrationForId(
sw_registration_id_2_, GURL(kPattern1).GetOrigin(),
base::Bind(FindServiceWorkerRegistrationCallback, &sw_registration_2_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(sw_registration_1_);
EXPECT_TRUE(sw_registration_2_);
-
- sw_registration_1_->active_version()->AddControllee(host_1_.get());
- sw_registration_2_->active_version()->AddControllee(host_2_.get());
- }
-
- void RemoveWindowClients() {
- sw_registration_1_->active_version()->RemoveControllee(host_1_.get());
- sw_registration_2_->active_version()->RemoveControllee(host_2_.get());
}
void SetNetwork(net::NetworkChangeNotifier::ConnectionType connection_type) {
@@ -317,7 +392,8 @@ class BackgroundSyncManagerTest : public testing::Test {
if (test_background_sync_manager_) {
BackgroundSyncNetworkObserver* network_observer =
test_background_sync_manager_->GetNetworkObserverForTesting();
- network_observer->NotifyManagerIfNetworkChanged(connection_type);
+ network_observer->NotifyManagerIfNetworkChangedForTesting(
+ connection_type);
base::RunLoop().RunUntilIdle();
}
}
@@ -333,7 +409,7 @@ class BackgroundSyncManagerTest : public testing::Test {
scoped_ptr<BackgroundSyncRegistrationHandle> registration_handle) {
*was_called = true;
callback_status_ = status;
- callback_registration_handle_ = registration_handle.Pass();
+ callback_registration_handle_ = std::move(registration_handle);
}
void StatusAndRegistrationsCallback(
@@ -343,7 +419,7 @@ class BackgroundSyncManagerTest : public testing::Test {
registration_handles) {
*was_called = true;
callback_status_ = status;
- callback_registration_handles_ = registration_handles.Pass();
+ callback_registration_handles_ = std::move(registration_handles);
}
void StatusCallback(bool* was_called, BackgroundSyncStatus status) {
@@ -358,19 +434,23 @@ class BackgroundSyncManagerTest : public testing::Test {
test_background_sync_manager_ =
new TestBackgroundSyncManager(helper_->context_wrapper());
background_sync_manager_.reset(test_background_sync_manager_);
- }
- void InitBackgroundSyncManager() {
- test_background_sync_manager_->DoInit();
+ test_clock_ = new base::SimpleTestClock();
+ background_sync_manager_->set_clock(make_scoped_ptr(test_clock_));
// Many tests do not expect the sync event to fire immediately after
// register (and cleanup up the sync registrations). Tests can control when
// the sync event fires by manipulating the network state as needed.
// NOTE: The setup of the network connection must happen after the
- // BackgroundSyncManager has been setup.
+ // BackgroundSyncManager has been created.
SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
}
+ void InitBackgroundSyncManager() {
+ test_background_sync_manager_->DoInit();
+ base::RunLoop().RunUntilIdle();
+ }
+
// Clear the registrations so that the BackgroundSyncManager can release them.
void ClearRegistrationHandles() {
callback_registration_handle_.reset();
@@ -398,6 +478,7 @@ class BackgroundSyncManagerTest : public testing::Test {
ClearRegistrationHandles();
background_sync_manager_.reset();
test_background_sync_manager_ = nullptr;
+ test_clock_ = nullptr;
}
bool Register(const BackgroundSyncRegistrationOptions& sync_options) {
@@ -405,7 +486,7 @@ class BackgroundSyncManagerTest : public testing::Test {
}
bool RegisterWithServiceWorkerId(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const BackgroundSyncRegistrationOptions& options) {
bool was_called = false;
background_sync_manager_->Register(
@@ -418,7 +499,7 @@ class BackgroundSyncManagerTest : public testing::Test {
}
bool RegisterFromDocumentWithServiceWorkerId(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const BackgroundSyncRegistrationOptions& options) {
bool was_called = false;
background_sync_manager_->Register(
@@ -436,7 +517,7 @@ class BackgroundSyncManagerTest : public testing::Test {
}
bool UnregisterWithServiceWorkerId(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
BackgroundSyncRegistrationHandle* registration_handle) {
bool was_called = false;
registration_handle->Unregister(
@@ -448,6 +529,29 @@ class BackgroundSyncManagerTest : public testing::Test {
return callback_status_ == BACKGROUND_SYNC_STATUS_OK;
}
+ bool NotifyWhenFinished(
+ BackgroundSyncRegistrationHandle* registration_handle) {
+ callback_finished_called_ = false;
+ callback_finished_status_ = BACKGROUND_SYNC_STATUS_NOT_FOUND;
+ callback_finished_state_ = BACKGROUND_SYNC_STATE_FAILED;
+
+ registration_handle->NotifyWhenFinished(
+ base::Bind(&NotifyWhenFinishedCallback, &callback_finished_called_,
+ &callback_finished_status_, &callback_finished_state_));
+ base::RunLoop().RunUntilIdle();
+
+ if (callback_finished_called_)
+ EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, callback_finished_status_);
+
+ return callback_finished_called_;
+ }
+
+ BackgroundSyncState FinishedState() {
+ EXPECT_TRUE(callback_finished_called_);
+ EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, callback_finished_status_);
+ return callback_finished_state_;
+ }
+
bool GetRegistration(
const BackgroundSyncRegistrationOptions& registration_options) {
return GetRegistrationWithServiceWorkerId(sw_registration_id_1_,
@@ -455,7 +559,7 @@ class BackgroundSyncManagerTest : public testing::Test {
}
bool GetRegistrationWithServiceWorkerId(
- int64 sw_registration_id,
+ int64_t sw_registration_id,
const BackgroundSyncRegistrationOptions& registration_options) {
bool was_called = false;
background_sync_manager_->GetRegistration(
@@ -479,7 +583,7 @@ class BackgroundSyncManagerTest : public testing::Test {
periodicity);
}
- bool GetRegistrationWithServiceWorkerId(int64 sw_registration_id,
+ bool GetRegistrationWithServiceWorkerId(int64_t sw_registration_id,
SyncPeriodicity periodicity) {
bool was_called = false;
background_sync_manager_->GetRegistrations(
@@ -496,7 +600,7 @@ class BackgroundSyncManagerTest : public testing::Test {
callback_sw_status_code_ = result;
}
- void UnregisterServiceWorker(uint64 sw_registration_id) {
+ void UnregisterServiceWorker(uint64_t sw_registration_id) {
bool called = false;
helper_->context()->UnregisterServiceWorker(
PatternForSWId(sw_registration_id),
@@ -505,7 +609,7 @@ class BackgroundSyncManagerTest : public testing::Test {
EXPECT_TRUE(called);
}
- GURL PatternForSWId(int64 sw_id) {
+ GURL PatternForSWId(int64_t sw_id) {
EXPECT_TRUE(sw_id == sw_registration_id_1_ ||
sw_id == sw_registration_id_2_);
return sw_id == sw_registration_id_1_ ? GURL(kPattern1) : GURL(kPattern2);
@@ -543,20 +647,35 @@ class BackgroundSyncManagerTest : public testing::Test {
EXPECT_FALSE(sync_fired_callback_.is_null());
}
+ void DeleteServiceWorkerAndStartOver() {
+ helper_->context()->ScheduleDeleteAndStartOver();
+ base::RunLoop().RunUntilIdle();
+ }
+
int MaxTagLength() const { return BackgroundSyncManager::kMaxTagLength; }
+ void SetMaxSyncAttemptsAndRestartManager(int max_sync_attempts) {
+ BackgroundSyncParameters* parameters =
+ test_controller_->background_sync_parameters();
+ parameters->max_sync_attempts = max_sync_attempts;
+
+ // Restart the BackgroundSyncManager so that it updates its parameters.
+ SetupBackgroundSyncManager();
+ }
+
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
- TestPowerSource* power_monitor_source_; // owned by power_monitor_
+ TestPowerSource* power_monitor_source_ = nullptr; // owned by power_monitor_
scoped_ptr<base::PowerMonitor> power_monitor_;
scoped_ptr<EmbeddedWorkerTestHelper> helper_;
scoped_ptr<BackgroundSyncManager> background_sync_manager_;
- TestBackgroundSyncManager* test_background_sync_manager_;
+ scoped_ptr<StoragePartitionImpl> storage_partition_impl_;
+ TestBackgroundSyncManager* test_background_sync_manager_ = nullptr;
+ TestBackgroundSyncController* test_controller_;
+ base::SimpleTestClock* test_clock_ = nullptr;
- scoped_ptr<ServiceWorkerProviderHost> host_1_;
- scoped_ptr<ServiceWorkerProviderHost> host_2_;
- int64 sw_registration_id_1_;
- int64 sw_registration_id_2_;
+ int64_t sw_registration_id_1_;
+ int64_t sw_registration_id_2_;
scoped_refptr<ServiceWorkerRegistration> sw_registration_1_;
scoped_refptr<ServiceWorkerRegistration> sw_registration_2_;
@@ -564,12 +683,16 @@ class BackgroundSyncManagerTest : public testing::Test {
BackgroundSyncRegistrationOptions sync_options_2_;
// Callback values.
- BackgroundSyncStatus callback_status_;
+ BackgroundSyncStatus callback_status_ = BACKGROUND_SYNC_STATUS_OK;
scoped_ptr<BackgroundSyncRegistrationHandle> callback_registration_handle_;
scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>>
callback_registration_handles_;
- ServiceWorkerStatusCode callback_sw_status_code_;
- int sync_events_called_;
+ ServiceWorkerStatusCode callback_sw_status_code_ = SERVICE_WORKER_OK;
+ bool callback_finished_called_ = false;
+ BackgroundSyncStatus callback_finished_status_ =
+ BACKGROUND_SYNC_STATUS_NOT_FOUND;
+ BackgroundSyncState callback_finished_state_ = BACKGROUND_SYNC_STATE_FAILED;
+ int sync_events_called_ = 0;
ServiceWorkerVersion::StatusCallback sync_fired_callback_;
};
@@ -599,7 +722,7 @@ TEST_F(BackgroundSyncManagerTest, RegisterWithoutActiveSWRegistration) {
TEST_F(BackgroundSyncManagerTest, RegisterOverwrites) {
EXPECT_TRUE(Register(sync_options_1_));
scoped_ptr<BackgroundSyncRegistrationHandle> first_registration_handle =
- callback_registration_handle_.Pass();
+ std::move(callback_registration_handle_);
sync_options_1_.min_period = 100;
EXPECT_TRUE(Register(sync_options_1_));
@@ -773,7 +896,7 @@ TEST_F(BackgroundSyncManagerTest, RegisterMaxTagLength) {
TEST_F(BackgroundSyncManagerTest, RegistrationIncreasesId) {
EXPECT_TRUE(Register(sync_options_1_));
scoped_ptr<BackgroundSyncRegistrationHandle> registered_handle =
- callback_registration_handle_.Pass();
+ std::move(callback_registration_handle_);
BackgroundSyncRegistration::RegistrationId cur_id =
registered_handle->handle_id();
@@ -900,8 +1023,7 @@ TEST_F(BackgroundSyncManagerTest,
TEST_F(BackgroundSyncManagerTest, DeleteAndStartOverServiceWorkerContext) {
EXPECT_TRUE(Register(sync_options_1_));
- helper_->context()->ScheduleDeleteAndStartOver();
- base::RunLoop().RunUntilIdle();
+ DeleteServiceWorkerAndStartOver();
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
@@ -930,8 +1052,7 @@ TEST_F(BackgroundSyncManagerTest, DisabledManagerWorksAfterDeleteAndStartOver) {
// The manager is now disabled and not accepting new requests until browser
// restart or notification that the storage has been wiped.
test_background_sync_manager_->set_corrupt_backend(false);
- helper_->context()->ScheduleDeleteAndStartOver();
- base::RunLoop().RunUntilIdle();
+ DeleteServiceWorkerAndStartOver();
RegisterServiceWorkers();
@@ -1062,60 +1183,38 @@ TEST_F(BackgroundSyncManagerTest, OneShotFiresOnRegistration) {
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
-TEST_F(BackgroundSyncManagerTest, NotifyWhenDoneAfterEventSuccess) {
+TEST_F(BackgroundSyncManagerTest, NotifyWhenFinishedAfterEventSuccess) {
InitSyncEventTest();
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_EQ(1, sync_events_called_);
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, sync_state);
+ EXPECT_TRUE(NotifyWhenFinished(callback_registration_handle_.get()));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
}
-TEST_F(BackgroundSyncManagerTest, NotifyWhenDoneBeforeEventSuccess) {
+TEST_F(BackgroundSyncManagerTest, NotifyWhenFinishedBeforeEventSuccess) {
InitDelayedSyncEventTest();
RegisterAndVerifySyncEventDelayed(sync_options_1_);
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
// Finish firing the event.
sync_fired_callback_.Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, sync_events_called_);
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, sync_state);
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
}
TEST_F(BackgroundSyncManagerTest,
- NotifyWhenDoneBeforeUnregisteredEventSuccess) {
+ NotifyWhenFinishedBeforeUnregisteredEventSuccess) {
InitDelayedSyncEventTest();
RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
-
- // Unregistering should set the state to UNREGISTERED but done shouldn't
+ // Unregistering should set the state to UNREGISTERED but finished shouldn't
// be called until the event finishes firing, at which point its state should
// be SUCCESS.
EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
@@ -1124,27 +1223,17 @@ TEST_F(BackgroundSyncManagerTest,
// Finish firing the event.
sync_fired_callback_.Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, sync_events_called_);
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, sync_state);
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
}
TEST_F(BackgroundSyncManagerTest,
- NotifyWhenDoneBeforeUnregisteredEventFailure) {
+ NotifyWhenFinishedBeforeUnregisteredEventFailure) {
InitDelayedSyncEventTest();
RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
-
- // Unregistering should set the state to UNREGISTERED but done shouldn't
+ // Unregistering should set the state to UNREGISTERED but finished shouldn't
// be called until the event finishes firing, at which point its state should
// be FAILED.
EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
@@ -1154,124 +1243,150 @@ TEST_F(BackgroundSyncManagerTest,
sync_fired_callback_.Run(SERVICE_WORKER_ERROR_FAILED);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, sync_events_called_);
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, sync_state);
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, FinishedState());
}
-TEST_F(BackgroundSyncManagerTest, NotifyWhenDoneBeforeUnregisteredEventFires) {
+TEST_F(BackgroundSyncManagerTest,
+ NotifyWhenFinishedBeforeUnregisteredEventFires) {
InitSyncEventTest();
SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
-
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, sync_state);
+ EXPECT_TRUE(NotifyWhenFinished(callback_registration_handle_.get()));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, FinishedState());
}
TEST_F(BackgroundSyncManagerTest,
- NotifyWhenDoneBeforeEventSuccessDroppedHandle) {
+ NotifyWhenFinishedBeforeEventSuccessDroppedHandle) {
InitDelayedSyncEventTest();
RegisterAndVerifySyncEventDelayed(sync_options_1_);
-
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
-
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
// Drop the client's handle to the registration before the event fires, ensure
- // that the done callback is still run.
+ // that the finished callback is still run.
callback_registration_handle_ = nullptr;
// Finish firing the event.
sync_fired_callback_.Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, sync_events_called_);
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, sync_state);
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
}
-TEST_F(BackgroundSyncManagerTest, NotifyWhenDoneAfterEventFailure) {
+TEST_F(BackgroundSyncManagerTest, NotifyWhenFinishedAfterEventFailure) {
InitFailedSyncEventTest();
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_EQ(1, sync_events_called_);
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, sync_state);
+ EXPECT_TRUE(NotifyWhenFinished(callback_registration_handle_.get()));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, FinishedState());
}
-TEST_F(BackgroundSyncManagerTest, NotifyWhenDoneBeforeEventFailure) {
+TEST_F(BackgroundSyncManagerTest, NotifyWhenFinishedBeforeEventFailure) {
InitDelayedSyncEventTest();
RegisterAndVerifySyncEventDelayed(sync_options_1_);
-
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
// Finish firing the event.
sync_fired_callback_.Run(SERVICE_WORKER_ERROR_FAILED);
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, sync_state);
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, FinishedState());
}
-TEST_F(BackgroundSyncManagerTest, NotifyWhenDoneAfterUnregistered) {
+TEST_F(BackgroundSyncManagerTest, NotifyWhenFinishedAfterUnregistered) {
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, sync_state);
+ EXPECT_TRUE(NotifyWhenFinished(callback_registration_handle_.get()));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, FinishedState());
}
-TEST_F(BackgroundSyncManagerTest, NotifyWhenDoneBeforeUnregistered) {
+TEST_F(BackgroundSyncManagerTest, NotifyWhenFinishedBeforeUnregistered) {
Register(sync_options_1_);
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- callback_registration_handle_->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
+ EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, FinishedState());
+}
+
+TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptFails) {
+ InitDelayedSyncEventTest();
+ RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
+
+ // Reregister the event mid-sync
+ EXPECT_TRUE(Register(sync_options_1_));
+
+ // The first sync attempt fails.
+ sync_fired_callback_.Run(SERVICE_WORKER_ERROR_FAILED);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(callback_finished_called_);
+
+ // It should fire again since it was reregistered mid-sync.
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+ sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
+}
+
+TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptSucceeds) {
+ InitDelayedSyncEventTest();
+ RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
+
+ // Reregister the event mid-sync
+ EXPECT_TRUE(Register(sync_options_1_));
+
+ // The first sync event succeeds.
+ sync_fired_callback_.Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
+ EXPECT_FALSE(callback_finished_called_);
+
+ // It should fire again since it was reregistered mid-sync.
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+ sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
+}
+
+TEST_F(BackgroundSyncManagerTest,
+ NotifyUnregisteredMidSyncNoRetryAttemptsLeft) {
+ InitDelayedSyncEventTest();
+ RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
+
+ // Unregister the event mid-sync.
EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, sync_state);
+
+ // Finish firing the event.
+ sync_fired_callback_.Run(SERVICE_WORKER_ERROR_FAILED);
+ base::RunLoop().RunUntilIdle();
+
+ // Since there were no retry attempts left, the sync ultimately failed.
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, FinishedState());
+}
+
+TEST_F(BackgroundSyncManagerTest,
+ NotifyUnregisteredMidSyncWithRetryAttemptsLeft) {
+ SetMaxSyncAttemptsAndRestartManager(2);
+ InitDelayedSyncEventTest();
+
+ RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
+
+ // Unregister the event mid-sync.
+ EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
+
+ // Finish firing the event.
+ sync_fired_callback_.Run(SERVICE_WORKER_ERROR_FAILED);
+ base::RunLoop().RunUntilIdle();
+ // Since there was one retry attempt left, the sync didn't completely fail
+ // before it was unregistered.
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, FinishedState());
}
TEST_F(BackgroundSyncManagerTest, OverwritePendingRegistration) {
@@ -1283,7 +1398,7 @@ TEST_F(BackgroundSyncManagerTest, OverwritePendingRegistration) {
EXPECT_EQ(POWER_STATE_AVOID_DRAINING,
callback_registration_handle_->options()->power_state);
scoped_ptr<BackgroundSyncRegistrationHandle> original_handle =
- callback_registration_handle_.Pass();
+ std::move(callback_registration_handle_);
// Overwrite the pending registration.
sync_options_1_.power_state = POWER_STATE_AUTO;
@@ -1292,15 +1407,8 @@ TEST_F(BackgroundSyncManagerTest, OverwritePendingRegistration) {
EXPECT_EQ(POWER_STATE_AUTO,
callback_registration_handle_->options()->power_state);
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- original_handle->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, sync_state);
+ EXPECT_TRUE(NotifyWhenFinished(original_handle.get()));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, FinishedState());
EXPECT_EQ(0, sync_events_called_);
}
@@ -1312,7 +1420,7 @@ TEST_F(BackgroundSyncManagerTest, OverwriteFiringRegistrationWhichSucceeds) {
sync_options_1_.power_state = POWER_STATE_AVOID_DRAINING;
RegisterAndVerifySyncEventDelayed(sync_options_1_);
scoped_ptr<BackgroundSyncRegistrationHandle> original_handle =
- callback_registration_handle_.Pass();
+ std::move(callback_registration_handle_);
// The next registration won't block.
InitSyncEventTest();
@@ -1320,22 +1428,12 @@ TEST_F(BackgroundSyncManagerTest, OverwriteFiringRegistrationWhichSucceeds) {
// Overwrite the firing registration.
sync_options_1_.power_state = POWER_STATE_AUTO;
EXPECT_TRUE(Register(sync_options_1_));
-
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- original_handle->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
+ EXPECT_FALSE(NotifyWhenFinished(original_handle.get()));
// Successfully finish the first event.
sync_fired_callback_.Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, sync_state);
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
}
TEST_F(BackgroundSyncManagerTest, OverwriteFiringRegistrationWhichFails) {
@@ -1346,7 +1444,7 @@ TEST_F(BackgroundSyncManagerTest, OverwriteFiringRegistrationWhichFails) {
sync_options_1_.power_state = POWER_STATE_AVOID_DRAINING;
RegisterAndVerifySyncEventDelayed(sync_options_1_);
scoped_ptr<BackgroundSyncRegistrationHandle> original_handle =
- callback_registration_handle_.Pass();
+ std::move(callback_registration_handle_);
// The next registration won't block.
InitSyncEventTest();
@@ -1354,22 +1452,50 @@ TEST_F(BackgroundSyncManagerTest, OverwriteFiringRegistrationWhichFails) {
// Overwrite the firing registration.
sync_options_1_.power_state = POWER_STATE_AUTO;
EXPECT_TRUE(Register(sync_options_1_));
-
- bool notify_done_called = false;
- BackgroundSyncStatus status = BACKGROUND_SYNC_STATUS_OK;
- BackgroundSyncState sync_state = BACKGROUND_SYNC_STATE_SUCCESS;
- original_handle->NotifyWhenDone(base::Bind(
- &NotifyWhenDoneCallback, &notify_done_called, &status, &sync_state));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(notify_done_called);
+ EXPECT_FALSE(NotifyWhenFinished(original_handle.get()));
// Fail the first event.
sync_fired_callback_.Run(SERVICE_WORKER_ERROR_FAILED);
base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, FinishedState());
+}
+
+TEST_F(BackgroundSyncManagerTest, DisableWhilePendingNotifiesFinished) {
+ InitSyncEventTest();
- EXPECT_TRUE(notify_done_called);
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_OK, status);
- EXPECT_EQ(BACKGROUND_SYNC_STATE_FAILED, sync_state);
+ // Register a one-shot that must wait for network connectivity before it
+ // can fire.
+ SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
+
+ // Corrupting the backend should result in the manager disabling itself on the
+ // next operation. While disabling, it should finalize any pending
+ // registrations.
+ test_background_sync_manager_->set_corrupt_backend(true);
+ EXPECT_FALSE(Register(sync_options_2_));
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED, FinishedState());
+}
+
+TEST_F(BackgroundSyncManagerTest, DisableWhileFiringNotifiesFinished) {
+ InitDelayedSyncEventTest();
+
+ // Register a one-shot that pauses mid-fire.
+ RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ EXPECT_FALSE(NotifyWhenFinished(callback_registration_handle_.get()));
+
+ // Corrupting the backend should result in the manager disabling itself on the
+ // next operation. Even though the manager is disabled, the firing sync event
+ // should still be able to complete successfully and notify as much.
+ test_background_sync_manager_->set_corrupt_backend(true);
+ EXPECT_FALSE(Register(sync_options_2_));
+ EXPECT_FALSE(callback_finished_called_);
+ test_background_sync_manager_->set_corrupt_backend(false);
+
+ // Successfully complete the firing event.
+ sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(BACKGROUND_SYNC_STATE_SUCCESS, FinishedState());
}
// TODO(jkarlin): Change this to a periodic test as one-shots can't be power
@@ -1530,26 +1656,6 @@ TEST_F(BackgroundSyncManagerTest, OverwriteRegistrationMidSync) {
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
-TEST_F(BackgroundSyncManagerTest, ReregisterOneShotMidSync) {
- InitDelayedSyncEventTest();
-
- RegisterAndVerifySyncEventDelayed(sync_options_1_);
-
- // Register the same sync, but don't delay it. It shouldn't run as it's
- // already firing.
- test_background_sync_manager_->set_one_shot_callback(
- base::Bind(OneShotSuccessfulCallback, &sync_events_called_));
- EXPECT_TRUE(Register(sync_options_1_));
- EXPECT_EQ(1, sync_events_called_);
- EXPECT_TRUE(GetRegistration(sync_options_1_));
-
- // Finish the original event, note that the second never runs.
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, sync_events_called_);
- EXPECT_FALSE(GetRegistration(sync_options_1_));
-}
-
TEST_F(BackgroundSyncManagerTest, UnregisterOneShotMidSync) {
InitDelayedSyncEventTest();
@@ -1606,50 +1712,327 @@ TEST_F(BackgroundSyncManagerTest, KillManagerMidSync) {
EXPECT_EQ(2, sync_events_called_);
}
-TEST_F(BackgroundSyncManagerTest, RegisterFailsWithoutWindow) {
- RemoveWindowClients();
- EXPECT_FALSE(Register(sync_options_1_));
-}
-
-TEST_F(BackgroundSyncManagerTest, RegisterExistingFailsWithoutWindow) {
- EXPECT_TRUE(Register(sync_options_1_));
- RemoveWindowClients();
+TEST_F(BackgroundSyncManagerTest, RegisterFromServiceWorkerWithoutMainFrame) {
+ test_background_sync_manager_->set_has_main_frame_provider_host(false);
EXPECT_FALSE(Register(sync_options_1_));
}
-TEST_F(BackgroundSyncManagerTest, RegisterSucceedsFromUncontrolledWindow) {
- RemoveWindowClients();
+TEST_F(BackgroundSyncManagerTest,
+ RegisterFromDocumentWithoutMainFrameProviderHost) {
+ test_background_sync_manager_->set_has_main_frame_provider_host(false);
EXPECT_TRUE(RegisterFromDocumentWithServiceWorkerId(sw_registration_id_1_,
sync_options_1_));
}
-TEST_F(BackgroundSyncManagerTest, UnregisterSucceedsWithoutWindow) {
+TEST_F(BackgroundSyncManagerTest,
+ RegisterExistingFromServiceWorkerWithoutMainFrame) {
+ EXPECT_TRUE(Register(sync_options_1_));
+ test_background_sync_manager_->set_has_main_frame_provider_host(false);
+ EXPECT_FALSE(Register(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, UnregisterSucceedsWithoutMainFrame) {
EXPECT_TRUE(Register(sync_options_1_));
- RemoveWindowClients();
+ test_background_sync_manager_->set_has_main_frame_provider_host(false);
EXPECT_TRUE(Unregister(callback_registration_handle_.get()));
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
-TEST_F(BackgroundSyncManagerTest, FieldTrialDisablesManager) {
+TEST_F(BackgroundSyncManagerTest, DefaultParameters) {
+ *test_controller_->background_sync_parameters() = BackgroundSyncParameters();
+ // Restart the BackgroundSyncManager so that it updates its parameters.
+ SetupBackgroundSyncManager();
+
+ EXPECT_EQ(BackgroundSyncParameters(),
+ *test_background_sync_manager_->background_sync_parameters());
+}
+
+TEST_F(BackgroundSyncManagerTest, OverrideParameters) {
+ BackgroundSyncParameters* parameters =
+ test_controller_->background_sync_parameters();
+ parameters->disable = true;
+ parameters->max_sync_attempts = 100;
+ parameters->initial_retry_delay = base::TimeDelta::FromMinutes(200);
+ parameters->retry_delay_factor = 300;
+ parameters->min_sync_recovery_time = base::TimeDelta::FromMinutes(400);
+ parameters->max_sync_event_duration = base::TimeDelta::FromMinutes(500);
+
+ // Restart the BackgroundSyncManager so that it updates its parameters.
+ SetupBackgroundSyncManager();
+
+ // Check that the manager is disabled
+ EXPECT_FALSE(Register(sync_options_1_));
+ EXPECT_EQ(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback_status_);
+
+ const BackgroundSyncParameters* manager_parameters =
+ test_background_sync_manager_->background_sync_parameters();
+ EXPECT_EQ(*parameters, *manager_parameters);
+}
+
+TEST_F(BackgroundSyncManagerTest, DisablingFromControllerKeepsRegistrations) {
EXPECT_TRUE(Register(sync_options_1_));
- base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
- base::FieldTrialList::CreateFieldTrial("BackgroundSync",
- "ExperimentDisabled");
+ BackgroundSyncParameters* parameters =
+ test_controller_->background_sync_parameters();
+ parameters->disable = true;
- EXPECT_FALSE(Register(sync_options_2_));
+ // Restart the BackgroundSyncManager so that it updates its parameters.
+ SetupBackgroundSyncManager();
+ EXPECT_FALSE(GetRegistration(sync_options_1_)); // fails because disabled
+
+ // Reenable the BackgroundSyncManager on next launch
+ parameters->disable = false;
+
+ // Restart the BackgroundSyncManager so that it updates its parameters.
+ SetupBackgroundSyncManager();
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, DisabledPermanently) {
+ BackgroundSyncParameters* parameters =
+ test_controller_->background_sync_parameters();
+ parameters->disable = true;
+
+ // Restart the BackgroundSyncManager so that it updates its parameters.
+ SetupBackgroundSyncManager();
+
+ // Check that the manager is disabled
+ EXPECT_FALSE(Register(sync_options_1_));
EXPECT_EQ(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback_status_);
// If the service worker is wiped and the manager is restarted, the manager
- // should disable itself on init.
- test_background_sync_manager_->set_corrupt_backend(false);
- helper_->context()->ScheduleDeleteAndStartOver();
+ // should stay disabled.
+ DeleteServiceWorkerAndStartOver();
+ RegisterServiceWorkers();
+ EXPECT_FALSE(Register(sync_options_1_));
+ EXPECT_EQ(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback_status_);
+}
+
+TEST_F(BackgroundSyncManagerTest, NotifyBackgroundSyncRegistered) {
+ // Verify that the BackgroundSyncController is informed of registrations.
+ EXPECT_EQ(0, test_controller_->registration_count());
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_EQ(1, test_controller_->registration_count());
+ EXPECT_EQ(GURL(kPattern1).GetOrigin().spec(),
+ test_controller_->registration_origin().spec());
+}
+
+TEST_F(BackgroundSyncManagerTest, WakeBrowserCalled) {
+ InitDelayedSyncEventTest();
+
+ // The BackgroundSyncManager should declare in initialization
+ // that it doesn't need to be woken up since it has no registrations.
+ EXPECT_LT(0, test_controller_->run_in_background_count());
+ EXPECT_FALSE(test_controller_->run_in_background_enabled());
+
+ SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ EXPECT_FALSE(test_controller_->run_in_background_enabled());
+
+ // Register a one-shot but it can't fire due to lack of network, wake up is
+ // required.
+ Register(sync_options_1_);
+ EXPECT_TRUE(test_controller_->run_in_background_enabled());
+
+ // Start the event but it will pause mid-sync due to
+ // InitDelayedSyncEventTest() above.
+ SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ EXPECT_TRUE(test_controller_->run_in_background_enabled());
+ EXPECT_EQ(test_background_sync_manager_->background_sync_parameters()
+ ->min_sync_recovery_time,
+ base::TimeDelta::FromMilliseconds(
+ test_controller_->run_in_background_min_ms()));
+
+ // Finish the sync.
+ sync_fired_callback_.Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(test_controller_->run_in_background_enabled());
+}
- RegisterServiceWorkers();
+TEST_F(BackgroundSyncManagerTest, OneAttempt) {
+ SetMaxSyncAttemptsAndRestartManager(1);
+ InitFailedSyncEventTest();
- EXPECT_FALSE(GetRegistrations(SYNC_ONE_SHOT));
- EXPECT_EQ(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback_status_);
+ // It should permanently fail after failing once.
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, TwoAttempts) {
+ SetMaxSyncAttemptsAndRestartManager(2);
+ InitFailedSyncEventTest();
+
+ // The first run will fail but it will setup a timer to try again.
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+ EXPECT_FALSE(test_background_sync_manager_->delayed_task().is_null());
+
+ // Make sure the delay is reasonable.
+ EXPECT_LT(base::TimeDelta::FromMinutes(1),
+ test_background_sync_manager_->delayed_task_delta());
+ EXPECT_GT(base::TimeDelta::FromHours(1),
+ test_background_sync_manager_->delayed_task_delta());
+
+ // Fire again and this time it should permanently fail.
+ test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_background_sync_manager_->delayed_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, ThreeAttempts) {
+ SetMaxSyncAttemptsAndRestartManager(3);
+ InitFailedSyncEventTest();
+
+ // The first run will fail but it will setup a timer to try again.
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+ EXPECT_FALSE(test_background_sync_manager_->delayed_task().is_null());
+
+ // The second run will fail but it will setup a timer to try again.
+ base::TimeDelta first_delta =
+ test_background_sync_manager_->delayed_task_delta();
+ test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_background_sync_manager_->delayed_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+
+ // Verify that the delta grows for each attempt.
+ EXPECT_LT(first_delta, test_background_sync_manager_->delayed_task_delta());
+
+ // The third run will permanently fail.
+ test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_background_sync_manager_->delayed_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, WaitsFullDelayTime) {
+ SetMaxSyncAttemptsAndRestartManager(2);
+ InitFailedSyncEventTest();
+
+ // The first run will fail but it will setup a timer to try again.
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+ EXPECT_FALSE(test_background_sync_manager_->delayed_task().is_null());
+
+ // Fire again one second before it's ready to retry. Expect it to reschedule
+ // the delay timer for one more second.
+ test_clock_->Advance(test_background_sync_manager_->delayed_task_delta() -
+ base::TimeDelta::FromSeconds(1));
+ test_background_sync_manager_->delayed_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+ EXPECT_EQ(base::TimeDelta::FromSeconds(1),
+ test_background_sync_manager_->delayed_task_delta());
+
+ // Fire one second later and it should fail permanently.
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ test_background_sync_manager_->delayed_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, RetryOnBrowserRestart) {
+ SetMaxSyncAttemptsAndRestartManager(2);
+ InitFailedSyncEventTest();
+
+ // The first run will fail but it will setup a timer to try again.
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+
+ // Simulate restarting the browser after sufficient time has passed.
+ base::TimeDelta delta = test_background_sync_manager_->delayed_task_delta();
+ CreateBackgroundSyncManager();
+ InitFailedSyncEventTest();
+ test_clock_->Advance(delta);
+ InitBackgroundSyncManager();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, RescheduleOnBrowserRestart) {
+ SetMaxSyncAttemptsAndRestartManager(2);
+ InitFailedSyncEventTest();
+
+ // The first run will fail but it will setup a timer to try again.
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+
+ // Simulate restarting the browser before the retry timer has expired.
+ base::TimeDelta delta = test_background_sync_manager_->delayed_task_delta();
+ CreateBackgroundSyncManager();
+ InitFailedSyncEventTest();
+ test_clock_->Advance(delta - base::TimeDelta::FromSeconds(1));
+ InitBackgroundSyncManager();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+ EXPECT_EQ(base::TimeDelta::FromSeconds(1),
+ test_background_sync_manager_->delayed_task_delta());
+}
+
+TEST_F(BackgroundSyncManagerTest, RetryIfClosedMidSync) {
+ InitDelayedSyncEventTest();
+
+ RegisterAndVerifySyncEventDelayed(sync_options_1_);
+ // The time delta is the recovery timer.
+ base::TimeDelta delta = test_background_sync_manager_->delayed_task_delta();
+
+ // Simulate restarting the browser after the recovery time, the event should
+ // fire once and then fail permanently.
+ CreateBackgroundSyncManager();
+ InitFailedSyncEventTest();
+ test_clock_->Advance(delta);
+ InitBackgroundSyncManager();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+}
+
+TEST_F(BackgroundSyncManagerTest, AllTestsEventuallyFire) {
+ SetMaxSyncAttemptsAndRestartManager(3);
+ InitFailedSyncEventTest();
+
+ // The first run will fail but it will setup a timer to try again.
+ EXPECT_TRUE(Register(sync_options_1_));
+
+ // Run it a second time.
+ test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_background_sync_manager_->delayed_task().Run();
+ base::RunLoop().RunUntilIdle();
+
+ base::TimeDelta delay_delta =
+ test_background_sync_manager_->delayed_task_delta();
+
+ // Create a second registration, which will fail and setup a timer.
+ EXPECT_TRUE(Register(sync_options_2_));
+ EXPECT_GT(delay_delta, test_background_sync_manager_->delayed_task_delta());
+
+ while (!test_background_sync_manager_->delayed_task().is_null()) {
+ test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_background_sync_manager_->delayed_task().Run();
+ test_background_sync_manager_->ClearDelayedTask();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+ EXPECT_FALSE(GetRegistration(sync_options_2_));
+}
+
+TEST_F(BackgroundSyncManagerTest, LastChance) {
+ SetMaxSyncAttemptsAndRestartManager(2);
+ InitFailedSyncEventTest();
+
+ EXPECT_TRUE(Register(sync_options_1_));
+ EXPECT_EQ(BACKGROUND_SYNC_EVENT_LAST_CHANCE_IS_NOT_LAST_CHANCE,
+ test_background_sync_manager_->last_chance());
+ EXPECT_TRUE(GetRegistration(sync_options_1_));
+
+ // Run it again.
+ test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_background_sync_manager_->delayed_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(GetRegistration(sync_options_1_));
+ EXPECT_EQ(BACKGROUND_SYNC_EVENT_LAST_CHANCE_IS_LAST_CHANCE,
+ test_background_sync_manager_->last_chance());
}
} // namespace content
diff --git a/chromium/content/browser/background_sync/background_sync_metrics.cc b/chromium/content/browser/background_sync/background_sync_metrics.cc
index d52bf03b018..20b3a6651a3 100644
--- a/chromium/content/browser/background_sync/background_sync_metrics.cc
+++ b/chromium/content/browser/background_sync/background_sync_metrics.cc
@@ -7,21 +7,69 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics_action.h"
+namespace {
+
+// ResultPattern is used by Histograms, append new entries at the end.
+enum ResultPattern {
+ RESULT_PATTERN_SUCCESS_FOREGROUND = 0,
+ RESULT_PATTERN_SUCCESS_BACKGROUND,
+ RESULT_PATTERN_FAILED_FOREGROUND,
+ RESULT_PATTERN_FAILED_BACKGROUND,
+ RESULT_PATTERN_MAX = RESULT_PATTERN_FAILED_BACKGROUND
+};
+
+ResultPattern EventResultToResultPattern(bool success,
+ bool finished_in_foreground) {
+ if (success) {
+ return finished_in_foreground ? RESULT_PATTERN_SUCCESS_FOREGROUND
+ : RESULT_PATTERN_SUCCESS_BACKGROUND;
+ }
+ return finished_in_foreground ? RESULT_PATTERN_FAILED_FOREGROUND
+ : RESULT_PATTERN_FAILED_BACKGROUND;
+}
+
+} // namespace
+
namespace content {
+// static
+void BackgroundSyncMetrics::RecordEventStarted(SyncPeriodicity periodicity,
+ bool started_in_foreground) {
+ switch (periodicity) {
+ case SYNC_ONE_SHOT:
+ UMA_HISTOGRAM_BOOLEAN("BackgroundSync.Event.OneShotStartedInForeground",
+ started_in_foreground);
+ return;
+ case SYNC_PERIODIC:
+ UMA_HISTOGRAM_BOOLEAN("BackgroundSync.Event.PeriodicStartedInForeground",
+ started_in_foreground);
+ return;
+ }
+ NOTREACHED();
+}
+
+// static
void BackgroundSyncMetrics::RecordEventResult(SyncPeriodicity periodicity,
- bool success) {
+ bool success,
+ bool finished_in_foreground) {
switch (periodicity) {
case SYNC_ONE_SHOT:
- UMA_HISTOGRAM_BOOLEAN("BackgroundSync.Event.OneShotResult", success);
+ UMA_HISTOGRAM_ENUMERATION(
+ "BackgroundSync.Event.OneShotResultPattern",
+ EventResultToResultPattern(success, finished_in_foreground),
+ RESULT_PATTERN_MAX + 1);
return;
case SYNC_PERIODIC:
- UMA_HISTOGRAM_BOOLEAN("BackgroundSync.Event.PeriodicResult", success);
+ UMA_HISTOGRAM_ENUMERATION(
+ "BackgroundSync.Event.PeriodicResultPattern",
+ EventResultToResultPattern(success, finished_in_foreground),
+ RESULT_PATTERN_MAX + 1);
return;
}
NOTREACHED();
}
+// static
void BackgroundSyncMetrics::RecordBatchSyncEventComplete(
const base::TimeDelta& time,
int number_of_batched_sync_events) {
@@ -34,14 +82,15 @@ void BackgroundSyncMetrics::RecordBatchSyncEventComplete(
number_of_batched_sync_events);
}
-void BackgroundSyncMetrics::CountRegister(
+// static
+void BackgroundSyncMetrics::CountRegisterSuccess(
SyncPeriodicity periodicity,
RegistrationCouldFire registration_could_fire,
- RegistrationIsDuplicate registration_is_duplicate,
- BackgroundSyncStatus result) {
+ RegistrationIsDuplicate registration_is_duplicate) {
switch (periodicity) {
case SYNC_ONE_SHOT:
- UMA_HISTOGRAM_ENUMERATION("BackgroundSync.Registration.OneShot", result,
+ UMA_HISTOGRAM_ENUMERATION("BackgroundSync.Registration.OneShot",
+ BACKGROUND_SYNC_STATUS_OK,
BACKGROUND_SYNC_STATUS_MAX + 1);
UMA_HISTOGRAM_BOOLEAN("BackgroundSync.Registration.OneShot.CouldFire",
registration_could_fire == REGISTRATION_COULD_FIRE);
@@ -50,7 +99,8 @@ void BackgroundSyncMetrics::CountRegister(
registration_is_duplicate == REGISTRATION_IS_DUPLICATE);
return;
case SYNC_PERIODIC:
- UMA_HISTOGRAM_ENUMERATION("BackgroundSync.Registration.Periodic", result,
+ UMA_HISTOGRAM_ENUMERATION("BackgroundSync.Registration.Periodic",
+ BACKGROUND_SYNC_STATUS_OK,
BACKGROUND_SYNC_STATUS_MAX + 1);
UMA_HISTOGRAM_BOOLEAN(
"BackgroundSync.Registration.Periodic.IsDuplicate",
@@ -60,6 +110,23 @@ void BackgroundSyncMetrics::CountRegister(
NOTREACHED();
}
+// static
+void BackgroundSyncMetrics::CountRegisterFailure(SyncPeriodicity periodicity,
+ BackgroundSyncStatus result) {
+ switch (periodicity) {
+ case SYNC_ONE_SHOT:
+ UMA_HISTOGRAM_ENUMERATION("BackgroundSync.Registration.OneShot", result,
+ BACKGROUND_SYNC_STATUS_MAX + 1);
+ return;
+ case SYNC_PERIODIC:
+ UMA_HISTOGRAM_ENUMERATION("BackgroundSync.Registration.Periodic", result,
+ BACKGROUND_SYNC_STATUS_MAX + 1);
+ return;
+ }
+ NOTREACHED();
+}
+
+// static
void BackgroundSyncMetrics::CountUnregister(SyncPeriodicity periodicity,
BackgroundSyncStatus result) {
switch (periodicity) {
diff --git a/chromium/content/browser/background_sync/background_sync_metrics.h b/chromium/content/browser/background_sync/background_sync_metrics.h
index d8c26da4677..f92a7c5b7a3 100644
--- a/chromium/content/browser/background_sync/background_sync_metrics.h
+++ b/chromium/content/browser/background_sync/background_sync_metrics.h
@@ -28,21 +28,31 @@ class BackgroundSyncMetrics {
REGISTRATION_IS_DUPLICATE
};
+ // Records the start of a sync event.
+ static void RecordEventStarted(SyncPeriodicity periodicity,
+ bool startedin_foreground);
+
// Records the result of a single sync event firing.
- static void RecordEventResult(SyncPeriodicity periodicity, bool result);
+ static void RecordEventResult(SyncPeriodicity periodicity,
+ bool result,
+ bool finished_in_foreground);
// Records the result of running a batch of sync events, including the total
// time spent, and the batch size.
static void RecordBatchSyncEventComplete(const base::TimeDelta& time,
int number_of_batched_sync_events);
- // Records the result of trying to register a sync. |could_fire| indicates
- // whether the conditions were sufficient for the sync to fire immediately at
- // the time it was registered.
- static void CountRegister(SyncPeriodicity periodicity,
- RegistrationCouldFire could_fire,
- RegistrationIsDuplicate registration_is_duplicate,
- BackgroundSyncStatus result);
+ // Records the result of successfully registering a sync. |could_fire|
+ // indicates whether the conditions were sufficient for the sync to fire
+ // immediately at the time it was registered.
+ static void CountRegisterSuccess(
+ SyncPeriodicity periodicity,
+ RegistrationCouldFire could_fire,
+ RegistrationIsDuplicate registration_is_duplicate);
+
+ // Records the status of a failed sync registration.
+ static void CountRegisterFailure(SyncPeriodicity periodicity,
+ BackgroundSyncStatus status);
// Records the result of trying to unregister a sync.
static void CountUnregister(SyncPeriodicity periodicity,
diff --git a/chromium/content/browser/background_sync/background_sync_network_observer.cc b/chromium/content/browser/background_sync/background_sync_network_observer.cc
index a08e7d83718..f8a0e089ec6 100644
--- a/chromium/content/browser/background_sync/background_sync_network_observer.cc
+++ b/chromium/content/browser/background_sync/background_sync_network_observer.cc
@@ -65,6 +65,11 @@ void BackgroundSyncNetworkObserver::OnNetworkChanged(
NotifyManagerIfNetworkChanged(connection_type);
}
+void BackgroundSyncNetworkObserver::NotifyManagerIfNetworkChangedForTesting(
+ net::NetworkChangeNotifier::ConnectionType connection_type) {
+ NotifyManagerIfNetworkChanged(connection_type);
+}
+
void BackgroundSyncNetworkObserver::NotifyManagerIfNetworkChanged(
net::NetworkChangeNotifier::ConnectionType connection_type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/background_sync/background_sync_network_observer.h b/chromium/content/browser/background_sync/background_sync_network_observer.h
index 4d47cc6a6c3..79aee8ffae7 100644
--- a/chromium/content/browser/background_sync/background_sync_network_observer.h
+++ b/chromium/content/browser/background_sync/background_sync_network_observer.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_NETWORK_OBSERVER_H_
#include "base/bind.h"
+#include "base/macros.h"
#include "content/browser/background_sync/background_sync.pb.h"
#include "content/common/content_export.h"
#include "net/base/network_change_notifier.h"
@@ -33,10 +34,11 @@ class CONTENT_EXPORT BackgroundSyncNetworkObserver
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType connection_type) override;
- private:
- friend class BackgroundSyncBrowserTest;
- friend class BackgroundSyncManagerTest;
+ // Allow tests to call NotifyManagerIfNetworkChanged.
+ void NotifyManagerIfNetworkChangedForTesting(
+ net::NetworkChangeNotifier::ConnectionType connection_type);
+ private:
// Calls NotifyNetworkChanged if the connection type has changed.
void NotifyManagerIfNetworkChanged(
net::NetworkChangeNotifier::ConnectionType connection_type);
diff --git a/chromium/content/browser/background_sync/background_sync_power_observer.h b/chromium/content/browser/background_sync/background_sync_power_observer.h
index 80b26f0671b..b0da8f9facc 100644
--- a/chromium/content/browser/background_sync/background_sync_power_observer.h
+++ b/chromium/content/browser/background_sync/background_sync_power_observer.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_POWER_OBSERVER_H_
#include "base/bind.h"
+#include "base/macros.h"
#include "base/power_monitor/power_observer.h"
#include "content/browser/background_sync/background_sync.pb.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/background_sync/background_sync_power_observer_unittest.cc b/chromium/content/browser/background_sync/background_sync_power_observer_unittest.cc
index 8d3ed325853..857ac069192 100644
--- a/chromium/content/browser/background_sync/background_sync_power_observer_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_power_observer_unittest.cc
@@ -4,6 +4,7 @@
#include <content/browser/background_sync/background_sync_power_observer.h>
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/power_monitor_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/browser/background_sync/background_sync_registration.cc b/chromium/content/browser/background_sync/background_sync_registration.cc
index 30bbf9e2afa..b20e2ef744f 100644
--- a/chromium/content/browser/background_sync/background_sync_registration.cc
+++ b/chromium/content/browser/background_sync/background_sync_registration.cc
@@ -30,27 +30,28 @@ bool BackgroundSyncRegistration::IsValid() const {
return id_ != kInvalidRegistrationId;
}
-void BackgroundSyncRegistration::AddDoneCallback(
+void BackgroundSyncRegistration::AddFinishedCallback(
const StateCallback& callback) {
DCHECK(!HasCompleted());
- notify_done_callbacks_.push_back(callback);
+ notify_finished_callbacks_.push_back(callback);
}
-void BackgroundSyncRegistration::RunDoneCallbacks() {
+void BackgroundSyncRegistration::RunFinishedCallbacks() {
DCHECK(HasCompleted());
- for (auto& callback : notify_done_callbacks_) {
+ for (auto& callback : notify_finished_callbacks_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(callback, sync_state_));
}
- notify_done_callbacks_.clear();
+ notify_finished_callbacks_.clear();
}
bool BackgroundSyncRegistration::HasCompleted() const {
switch (sync_state_) {
case BACKGROUND_SYNC_STATE_PENDING:
case BACKGROUND_SYNC_STATE_FIRING:
+ case BACKGROUND_SYNC_STATE_REREGISTERED_WHILE_FIRING:
case BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING:
return false;
case BACKGROUND_SYNC_STATE_FAILED:
@@ -62,4 +63,36 @@ bool BackgroundSyncRegistration::HasCompleted() const {
return false;
}
+bool BackgroundSyncRegistration::IsFiring() const {
+ switch (sync_state_) {
+ case BACKGROUND_SYNC_STATE_FIRING:
+ case BACKGROUND_SYNC_STATE_REREGISTERED_WHILE_FIRING:
+ case BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING:
+ return true;
+ case BACKGROUND_SYNC_STATE_PENDING:
+ case BACKGROUND_SYNC_STATE_FAILED:
+ case BACKGROUND_SYNC_STATE_SUCCESS:
+ case BACKGROUND_SYNC_STATE_UNREGISTERED:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
+void BackgroundSyncRegistration::SetUnregisteredState() {
+ DCHECK(!HasCompleted());
+
+ bool is_firing = IsFiring();
+
+ sync_state_ = is_firing ? BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING
+ : BACKGROUND_SYNC_STATE_UNREGISTERED;
+
+ if (!is_firing) {
+ // If the registration is currently firing then wait to run
+ // RunFinishedCallbacks until after it has finished as it might
+ // change state to SUCCESS first.
+ RunFinishedCallbacks();
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/background_sync/background_sync_registration.h b/chromium/content/browser/background_sync/background_sync_registration.h
index 741c88850e4..4e4f1cd3f33 100644
--- a/chromium/content/browser/background_sync/background_sync_registration.h
+++ b/chromium/content/browser/background_sync/background_sync_registration.h
@@ -5,16 +5,19 @@
#ifndef CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_REGISTRATION_H_
#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_REGISTRATION_H_
+#include <stdint.h>
+
#include <list>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
#include "content/browser/background_sync/background_sync.pb.h"
#include "content/browser/background_sync/background_sync_registration_options.h"
#include "content/common/background_sync_service.mojom.h"
#include "content/common/content_export.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/type_converter.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
namespace content {
@@ -30,9 +33,16 @@ class CONTENT_EXPORT BackgroundSyncRegistration {
bool Equals(const BackgroundSyncRegistration& other) const;
bool IsValid() const;
- void AddDoneCallback(const StateCallback& callback);
- void RunDoneCallbacks();
+ void AddFinishedCallback(const StateCallback& callback);
+ void RunFinishedCallbacks();
bool HasCompleted() const;
+ bool IsFiring() const;
+
+ // If the registration is currently firing, sets its state to
+ // BACKGROUND_SYNC_STATE_UNREGISTERED_WHILE_FIRING. If it is firing, it sets
+ // the state to BACKGROUND_SYNC_STATE_UNREGISTERED and calls
+ // RunFinishedCallbacks.
+ void SetUnregisteredState();
const BackgroundSyncRegistrationOptions* options() const { return &options_; }
BackgroundSyncRegistrationOptions* options() { return &options_; }
@@ -43,14 +53,22 @@ class CONTENT_EXPORT BackgroundSyncRegistration {
BackgroundSyncState sync_state() const { return sync_state_; }
void set_sync_state(BackgroundSyncState state) { sync_state_ = state; }
+ int num_attempts() const { return num_attempts_; }
+ void set_num_attempts(int num_attempts) { num_attempts_ = num_attempts; }
+
+ base::Time delay_until() const { return delay_until_; }
+ void set_delay_until(base::Time delay_until) { delay_until_ = delay_until; }
+
private:
static const RegistrationId kInvalidRegistrationId;
BackgroundSyncRegistrationOptions options_;
RegistrationId id_ = kInvalidRegistrationId;
BackgroundSyncState sync_state_ = BACKGROUND_SYNC_STATE_PENDING;
+ int num_attempts_ = 0;
+ base::Time delay_until_;
- std::list<StateCallback> notify_done_callbacks_;
+ std::list<StateCallback> notify_finished_callbacks_;
DISALLOW_COPY_AND_ASSIGN(BackgroundSyncRegistration);
};
diff --git a/chromium/content/browser/background_sync/background_sync_registration_handle.cc b/chromium/content/browser/background_sync/background_sync_registration_handle.cc
index 7cb2672e3cb..eca0abbb693 100644
--- a/chromium/content/browser/background_sync/background_sync_registration_handle.cc
+++ b/chromium/content/browser/background_sync/background_sync_registration_handle.cc
@@ -26,13 +26,13 @@ void BackgroundSyncRegistrationHandle::Unregister(
callback);
}
-void BackgroundSyncRegistrationHandle::NotifyWhenDone(
+void BackgroundSyncRegistrationHandle::NotifyWhenFinished(
const StatusAndStateCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(IsValid());
DCHECK(background_sync_manager_);
- background_sync_manager_->NotifyWhenDone(handle_id_, callback);
+ background_sync_manager_->NotifyWhenFinished(handle_id_, callback);
}
bool BackgroundSyncRegistrationHandle::IsValid() const {
diff --git a/chromium/content/browser/background_sync/background_sync_registration_handle.h b/chromium/content/browser/background_sync/background_sync_registration_handle.h
index 85f21dff6b6..8b2b5a92bb9 100644
--- a/chromium/content/browser/background_sync/background_sync_registration_handle.h
+++ b/chromium/content/browser/background_sync/background_sync_registration_handle.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_REGISTRATION_HANDLE_H_
#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_REGISTRATION_HANDLE_H_
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/background_sync/background_sync_registration.h"
#include "content/browser/background_sync/background_sync_status.h"
@@ -50,9 +53,9 @@ class CONTENT_EXPORT BackgroundSyncRegistrationHandle {
// succeeded. The provided state is BACKGROUND_SYNC_STATE_SUCCESS on success,
// BACKGRUOND_SYNC_STATE_FAILED on final failure, and
// BACKGROUND_SYNC_STATE_UNREGISTERED if the registration was unregistered
- // before it could complete. NotifyWhenDone should only be called for
+ // before it could complete. NotifyWhenFinished should only be called for
// SYNC_ONE_SHOT registrations.
- void NotifyWhenDone(const StatusAndStateCallback& callback);
+ void NotifyWhenFinished(const StatusAndStateCallback& callback);
// Returns true if the handle is backed by a BackgroundSyncRegistration in the
// BackgroundSyncManager.
diff --git a/chromium/content/browser/background_sync/background_sync_registration_options.h b/chromium/content/browser/background_sync/background_sync_registration_options.h
index 133c9f6b31e..0429f2a90cc 100644
--- a/chromium/content/browser/background_sync/background_sync_registration_options.h
+++ b/chromium/content/browser/background_sync/background_sync_registration_options.h
@@ -5,9 +5,10 @@
#ifndef CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_REGISTRATION_OPTIONS_H_
#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_REGISTRATION_OPTIONS_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "content/browser/background_sync/background_sync.pb.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/background_sync/background_sync_service_impl.cc b/chromium/content/browser/background_sync/background_sync_service_impl.cc
index aef8b45c6c9..ffab6abc995 100644
--- a/chromium/content/browser/background_sync/background_sync_service_impl.cc
+++ b/chromium/content/browser/background_sync/background_sync_service_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/background_sync/background_sync_service_impl.h"
+#include <utility>
+
#include "background_sync_registration_handle.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
@@ -41,15 +43,15 @@ SyncRegistrationPtr ToMojoRegistration(
static_cast<content::BackgroundSyncPowerState>(in.options()->power_state);
out->network_state = static_cast<content::BackgroundSyncNetworkState>(
in.options()->network_state);
- return out.Pass();
+ return out;
}
} // namespace
#define COMPILE_ASSERT_MATCHING_ENUM(mojo_name, manager_name) \
- COMPILE_ASSERT(static_cast<int>(content::mojo_name) == \
- static_cast<int>(content::manager_name), \
- mismatching_enums)
+ static_assert(static_cast<int>(content::mojo_name) == \
+ static_cast<int>(content::manager_name), \
+ "mojo and manager enums must match")
// TODO(iclelland): Move these tests somewhere else
COMPILE_ASSERT_MATCHING_ENUM(BACKGROUND_SYNC_ERROR_NONE,
@@ -97,7 +99,7 @@ BackgroundSyncServiceImpl::BackgroundSyncServiceImpl(
BackgroundSyncContextImpl* background_sync_context,
mojo::InterfaceRequest<BackgroundSyncService> request)
: background_sync_context_(background_sync_context),
- binding_(this, request.Pass()),
+ binding_(this, std::move(request)),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(background_sync_context);
@@ -212,7 +214,7 @@ void BackgroundSyncServiceImpl::DuplicateRegistrationHandle(
active_handles_.AddWithID(registration_handle.release(),
handle_ptr->handle_id());
SyncRegistrationPtr mojoResult = ToMojoRegistration(*handle_ptr);
- callback.Run(BACKGROUND_SYNC_ERROR_NONE, mojoResult.Pass());
+ callback.Run(BACKGROUND_SYNC_ERROR_NONE, std::move(mojoResult));
}
void BackgroundSyncServiceImpl::ReleaseRegistration(
@@ -226,9 +228,9 @@ void BackgroundSyncServiceImpl::ReleaseRegistration(
active_handles_.Remove(handle_id);
}
-void BackgroundSyncServiceImpl::NotifyWhenDone(
+void BackgroundSyncServiceImpl::NotifyWhenFinished(
BackgroundSyncRegistrationHandle::HandleId handle_id,
- const NotifyWhenDoneCallback& callback) {
+ const NotifyWhenFinishedCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BackgroundSyncRegistrationHandle* registration =
active_handles_.Lookup(handle_id);
@@ -238,8 +240,8 @@ void BackgroundSyncServiceImpl::NotifyWhenDone(
return;
}
- registration->NotifyWhenDone(
- base::Bind(&BackgroundSyncServiceImpl::OnNotifyWhenDoneResult,
+ registration->NotifyWhenFinished(
+ base::Bind(&BackgroundSyncServiceImpl::OnNotifyWhenFinishedResult,
weak_ptr_factory_.GetWeakPtr(), callback));
}
@@ -256,10 +258,11 @@ void BackgroundSyncServiceImpl::OnRegisterResult(
return;
}
+ DCHECK(result);
active_handles_.AddWithID(result.release(), result_ptr->handle_id());
SyncRegistrationPtr mojoResult = ToMojoRegistration(*result_ptr);
callback.Run(static_cast<content::BackgroundSyncError>(status),
- mojoResult.Pass());
+ std::move(mojoResult));
}
void BackgroundSyncServiceImpl::OnUnregisterResult(
@@ -275,6 +278,8 @@ void BackgroundSyncServiceImpl::OnGetRegistrationsResult(
scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>>
result_registrations) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(result_registrations);
+
mojo::Array<content::SyncRegistrationPtr> mojo_registrations(0);
for (BackgroundSyncRegistrationHandle* registration : *result_registrations) {
active_handles_.AddWithID(registration, registration->handle_id());
@@ -284,11 +289,11 @@ void BackgroundSyncServiceImpl::OnGetRegistrationsResult(
result_registrations->weak_clear();
callback.Run(static_cast<content::BackgroundSyncError>(status),
- mojo_registrations.Pass());
+ std::move(mojo_registrations));
}
-void BackgroundSyncServiceImpl::OnNotifyWhenDoneResult(
- const NotifyWhenDoneCallback& callback,
+void BackgroundSyncServiceImpl::OnNotifyWhenFinishedResult(
+ const NotifyWhenFinishedCallback& callback,
BackgroundSyncStatus status,
BackgroundSyncState sync_state) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/background_sync/background_sync_service_impl.h b/chromium/content/browser/background_sync/background_sync_service_impl.h
index 828b53bde0a..a5b6d184e06 100644
--- a/chromium/content/browser/background_sync/background_sync_service_impl.h
+++ b/chromium/content/browser/background_sync/background_sync_service_impl.h
@@ -5,12 +5,15 @@
#ifndef CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_SERVICE_IMPL_H_
#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_SERVICE_IMPL_H_
+#include <stdint.h>
+
#include "base/id_map.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "content/browser/background_sync/background_sync_manager.h"
#include "content/common/background_sync_service.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding.h"
namespace content {
@@ -52,8 +55,8 @@ class CONTENT_EXPORT BackgroundSyncServiceImpl
const DuplicateRegistrationHandleCallback& callback) override;
void ReleaseRegistration(
BackgroundSyncRegistrationHandle::HandleId handle_id) override;
- void NotifyWhenDone(BackgroundSyncRegistrationHandle::HandleId handle_id,
- const NotifyWhenDoneCallback& callback) override;
+ void NotifyWhenFinished(BackgroundSyncRegistrationHandle::HandleId handle_id,
+ const NotifyWhenFinishedCallback& callback) override;
void OnRegisterResult(const RegisterCallback& callback,
BackgroundSyncStatus status,
@@ -64,9 +67,9 @@ class CONTENT_EXPORT BackgroundSyncServiceImpl
const GetRegistrationsCallback& callback,
BackgroundSyncStatus status,
scoped_ptr<ScopedVector<BackgroundSyncRegistrationHandle>> result);
- void OnNotifyWhenDoneResult(const NotifyWhenDoneCallback& callback,
- BackgroundSyncStatus status,
- BackgroundSyncState sync_state);
+ void OnNotifyWhenFinishedResult(const NotifyWhenFinishedCallback& callback,
+ BackgroundSyncStatus status,
+ BackgroundSyncState sync_state);
// Called when an error is detected on binding_.
void OnConnectionError();
diff --git a/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc b/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
index 7d9d65b098b..a9f8307c04a 100644
--- a/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/background_sync/background_sync_service_impl.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/scoped_ptr.h"
@@ -11,9 +14,13 @@
#include "base/power_monitor/power_monitor_source.h"
#include "base/run_loop.h"
#include "content/browser/background_sync/background_sync_context_impl.h"
+#include "content/browser/background_sync/background_sync_network_observer.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/test/background_sync_test_util.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "net/base/network_change_notifier.h"
@@ -25,15 +32,13 @@ namespace {
const char kServiceWorkerPattern[] = "https://example.com/a";
const char kServiceWorkerScript[] = "https://example.com/a/script.js";
-const int kRenderProcessId = 99;
// Callbacks from SetUp methods
-
void RegisterServiceWorkerCallback(bool* called,
- int64* store_registration_id,
+ int64_t* store_registration_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
@@ -106,7 +111,11 @@ class BackgroundSyncServiceImplTest : public testing::Test {
}
void SetUp() override {
+ // Don't let the tests be confused by the real-world device connectivity
+ background_sync_test_util::SetIgnoreNetworkChangeNotifier(true);
+
CreateTestHelper();
+ CreateStoragePartition();
CreateBackgroundSyncContext();
CreateServiceWorkerRegistration();
CreateBackgroundSyncServiceImpl();
@@ -119,12 +128,26 @@ class BackgroundSyncServiceImplTest : public testing::Test {
background_sync_context_->Shutdown();
base::RunLoop().RunUntilIdle();
background_sync_context_ = nullptr;
+
+ // Restore the network observer functionality for subsequent tests
+ background_sync_test_util::SetIgnoreNetworkChangeNotifier(false);
}
// SetUp helper methods
void CreateTestHelper() {
embedded_worker_helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
+ new EmbeddedWorkerTestHelper(base::FilePath()));
+ }
+
+ void CreateStoragePartition() {
+ // Creates a StoragePartition so that the BackgroundSyncManager can
+ // use it to access the BrowserContext.
+ storage_partition_impl_.reset(new StoragePartitionImpl(
+ embedded_worker_helper_->browser_context(), base::FilePath(), nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
+ embedded_worker_helper_->context_wrapper()->set_storage_partition(
+ storage_partition_impl_.get());
}
void CreateBackgroundSyncContext() {
@@ -141,7 +164,10 @@ class BackgroundSyncServiceImplTest : public testing::Test {
// BackgroundSyncManager has been setup, including any asynchronous
// initialization.
base::RunLoop().RunUntilIdle();
- net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ BackgroundSyncNetworkObserver* network_observer =
+ background_sync_context_->background_sync_manager()
+ ->GetNetworkObserverForTesting();
+ network_observer->NotifyManagerIfNetworkChangedForTesting(
net::NetworkChangeNotifier::CONNECTION_NONE);
base::RunLoop().RunUntilIdle();
}
@@ -155,24 +181,11 @@ class BackgroundSyncServiceImplTest : public testing::Test {
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
- // Register window client for the service worker
- provider_host_.reset(new ServiceWorkerProviderHost(
- 34 /* dummy render proces id */, MSG_ROUTING_NONE /* render_frame_id */,
- 1 /* dummy provider id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- embedded_worker_helper_->context()->AsWeakPtr(), nullptr));
- provider_host_->SetDocumentUrl(GURL(kServiceWorkerPattern));
-
- embedded_worker_helper_->context_wrapper()->FindRegistrationForId(
+ embedded_worker_helper_->context_wrapper()->FindReadyRegistrationForId(
sw_registration_id_, GURL(kServiceWorkerPattern).GetOrigin(),
base::Bind(FindServiceWorkerRegistrationCallback, &sw_registration_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(sw_registration_);
-
- sw_registration_->active_version()->AddControllee(provider_host_.get());
- }
-
- void RemoveWindowClient() {
- sw_registration_->active_version()->RemoveControllee(provider_host_.get());
}
void CreateBackgroundSyncServiceImpl() {
@@ -181,7 +194,7 @@ class BackgroundSyncServiceImplTest : public testing::Test {
mojo::InterfaceRequest<BackgroundSyncService> service_request =
mojo::GetProxy(&service_ptr_);
// Create a new BackgroundSyncServiceImpl bound to the dummy channel
- background_sync_context_->CreateService(service_request.Pass());
+ background_sync_context_->CreateService(std::move(service_request));
base::RunLoop().RunUntilIdle();
service_impl_ = *background_sync_context_->services_.begin();
@@ -192,22 +205,14 @@ class BackgroundSyncServiceImplTest : public testing::Test {
void RegisterOneShot(
SyncRegistrationPtr sync,
const BackgroundSyncService::RegisterCallback& callback) {
- service_impl_->Register(sync.Pass(), sw_registration_id_,
- true /* requested_from_service_worker */, callback);
- base::RunLoop().RunUntilIdle();
- }
-
- void RegisterOneShotFromDocument(
- SyncRegistrationPtr sync,
- const BackgroundSyncService::RegisterCallback& callback) {
- service_impl_->Register(sync.Pass(), sw_registration_id_,
+ service_impl_->Register(std::move(sync), sw_registration_id_,
false /* requested_from_service_worker */,
callback);
base::RunLoop().RunUntilIdle();
}
void UnregisterOneShot(
- int32 handle_id,
+ int32_t handle_id,
const BackgroundSyncService::UnregisterCallback& callback) {
service_impl_->Unregister(
handle_id, sw_registration_id_, callback);
@@ -232,19 +237,19 @@ class BackgroundSyncServiceImplTest : public testing::Test {
}
void NotifyWhenDone(
- int32 handle_id,
- const BackgroundSyncService::NotifyWhenDoneCallback& callback) {
- service_impl_->NotifyWhenDone(handle_id, callback);
+ int32_t handle_id,
+ const BackgroundSyncService::NotifyWhenFinishedCallback& callback) {
+ service_impl_->NotifyWhenFinished(handle_id, callback);
base::RunLoop().RunUntilIdle();
}
scoped_ptr<TestBrowserThreadBundle> thread_bundle_;
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
scoped_ptr<EmbeddedWorkerTestHelper> embedded_worker_helper_;
+ scoped_ptr<StoragePartitionImpl> storage_partition_impl_;
scoped_ptr<base::PowerMonitor> power_monitor_;
scoped_refptr<BackgroundSyncContextImpl> background_sync_context_;
- scoped_ptr<ServiceWorkerProviderHost> provider_host_;
- int64 sw_registration_id_;
+ int64_t sw_registration_id_;
scoped_refptr<ServiceWorkerRegistration> sw_registration_;
BackgroundSyncServicePtr service_ptr_;
BackgroundSyncServiceImpl*
@@ -266,43 +271,6 @@ TEST_F(BackgroundSyncServiceImplTest, Register) {
EXPECT_EQ("", reg->tag);
}
-TEST_F(BackgroundSyncServiceImplTest, RegisterWithoutWindow) {
- bool called = false;
- BackgroundSyncError error;
- SyncRegistrationPtr reg;
- RemoveWindowClient();
- RegisterOneShot(
- default_sync_registration_.Clone(),
- base::Bind(&ErrorAndRegistrationCallback, &called, &error, &reg));
- EXPECT_TRUE(called);
- EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_ALLOWED, error);
-}
-
-TEST_F(BackgroundSyncServiceImplTest, RegisterFromControlledClient) {
- bool called = false;
- BackgroundSyncError error;
- SyncRegistrationPtr reg;
- RegisterOneShotFromDocument(
- default_sync_registration_.Clone(),
- base::Bind(&ErrorAndRegistrationCallback, &called, &error, &reg));
- EXPECT_TRUE(called);
- EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, error);
- EXPECT_EQ("", reg->tag);
-}
-
-TEST_F(BackgroundSyncServiceImplTest, RegisterFromUncontrolledClient) {
- bool called = false;
- BackgroundSyncError error;
- SyncRegistrationPtr reg;
- RemoveWindowClient();
- RegisterOneShotFromDocument(
- default_sync_registration_.Clone(),
- base::Bind(&ErrorAndRegistrationCallback, &called, &error, &reg));
- EXPECT_TRUE(called);
- EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, error);
- EXPECT_EQ("", reg->tag);
-}
-
TEST_F(BackgroundSyncServiceImplTest, Unregister) {
bool unregister_called = false;
BackgroundSyncError unregister_error;
@@ -396,7 +364,7 @@ TEST_F(BackgroundSyncServiceImplTest, GetRegistrationsWithRegisteredSync) {
EXPECT_EQ(1UL, array_size);
}
-TEST_F(BackgroundSyncServiceImplTest, NotifyWhenDone) {
+TEST_F(BackgroundSyncServiceImplTest, NotifyWhenFinished) {
// Register a sync event.
bool register_called = false;
BackgroundSyncError register_error;
diff --git a/chromium/content/browser/bad_message.h b/chromium/content/browser/bad_message.h
index d9f8d1b169c..1a8c80abb4e 100644
--- a/chromium/content/browser/bad_message.h
+++ b/chromium/content/browser/bad_message.h
@@ -30,7 +30,7 @@ enum BadMessageReason {
RVH_CAN_ACCESS_FILES_OF_PAGE_STATE = 6,
RVH_FILE_CHOOSER_PATH = 7,
RWH_SYNTHETIC_GESTURE = 8,
- RWH_FOCUS = 9,
+ RWH_FOCUS = 9, // obsolete; no longer used
RWH_BLUR = 10,
RWH_SHARED_BITMAP = 11,
RWH_BAD_ACK_MESSAGE = 12,
@@ -119,6 +119,14 @@ enum BadMessageReason {
RDH_ILLEGAL_ORIGIN = 95,
RDH_UNAUTHORIZED_HEADER_REQUEST = 96,
RDH_INVALID_URL = 97,
+ BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED = 98,
+ RFH_OWNER_PROPERTY = 99,
+ BDH_EMPTY_OR_INVALID_FILTERS = 100,
+ WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO = 101,
+ RFMF_RENDERER_FAKED_ITS_OWN_DEATH = 102,
+ DWNLD_INVALID_SAVABLE_RESOURCE_LINKS_RESPONSE = 103,
+ DWNLD_INVALID_SERIALIZE_AS_MHTML_RESPONSE = 104,
+ BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN = 105,
// Please add new elements here. The naming convention is abbreviated class
// name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/chromium/content/browser/battery_status/battery_monitor_impl_browsertest.cc b/chromium/content/browser/battery_status/battery_monitor_impl_browsertest.cc
index 51fe83db8e1..8e4b6bc89d7 100644
--- a/chromium/content/browser/battery_status/battery_monitor_impl_browsertest.cc
+++ b/chromium/content/browser/battery_status/battery_monitor_impl_browsertest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
+#include "base/macros.h"
#include "base/thread_task_runner_handle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/content_browser_test.h"
@@ -76,7 +79,7 @@ class BatteryMonitorImplTest : public ContentBrowserTest {
battery_service_->GetUpdateCallbackForTesting()));
battery_manager_ = battery_manager.get();
- battery_service_->SetBatteryManagerForTesting(battery_manager.Pass());
+ battery_service_->SetBatteryManagerForTesting(std::move(battery_manager));
}
void TearDown() override {
diff --git a/chromium/content/browser/battery_status/battery_monitor_integration_browsertest.cc b/chromium/content/browser/battery_status/battery_monitor_integration_browsertest.cc
index 1f774a0c81b..468126f3d39 100644
--- a/chromium/content/browser/battery_status/battery_monitor_integration_browsertest.cc
+++ b/chromium/content/browser/battery_status/battery_monitor_integration_browsertest.cc
@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/callback_list.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
@@ -16,7 +20,7 @@
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "device/battery/battery_monitor.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
// These tests run against a dummy implementation of the BatteryMonitor service.
// That is, they verify that the service implementation is correctly exposed to
@@ -46,15 +50,14 @@ void UpdateBattery(const device::BatteryStatus& battery_status) {
class FakeBatteryMonitor : public device::BatteryMonitor {
public:
static void Create(mojo::InterfaceRequest<BatteryMonitor> request) {
- new FakeBatteryMonitor(request.Pass());
+ new FakeBatteryMonitor(std::move(request));
}
private:
typedef mojo::Callback<void(device::BatteryStatusPtr)> BatteryStatusCallback;
FakeBatteryMonitor(mojo::InterfaceRequest<BatteryMonitor> request)
- : binding_(this, request.Pass()) {
- }
+ : binding_(this, std::move(request)) {}
~FakeBatteryMonitor() override {}
void QueryNextStatus(const BatteryStatusCallback& callback) override {
diff --git a/chromium/content/browser/blob_storage/blob_async_builder_host_unittest.cc b/chromium/content/browser/blob_storage/blob_async_builder_host_unittest.cc
new file mode 100644
index 00000000000..934e0db887b
--- /dev/null
+++ b/chromium/content/browser/blob_storage/blob_async_builder_host_unittest.cc
@@ -0,0 +1,327 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "storage/browser/blob/blob_async_builder_host.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/shared_memory.h"
+#include "storage/common/blob_storage/blob_storage_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace storage {
+namespace {
+const std::string kBlobUUID = "blobUUIDYAY";
+const std::string kFakeBlobUUID = "fakeBlob";
+const std::string kBlobType = "blobtypeYAY";
+
+const size_t kTestBlobStorageIPCThresholdBytes = 5;
+const size_t kTestBlobStorageMaxSharedMemoryBytes = 20;
+const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
+
+void PopulateBytes(char* bytes, size_t length) {
+ for (size_t i = 0; i < length; i++) {
+ bytes[i] = static_cast<char>(i);
+ }
+}
+
+void AddMemoryItem(size_t length, std::vector<DataElement>* out) {
+ DataElement bytes;
+ bytes.SetToBytesDescription(length);
+ out->push_back(bytes);
+}
+
+void AddShortcutMemoryItem(size_t length, std::vector<DataElement>* out) {
+ DataElement bytes;
+ bytes.SetToAllocatedBytes(length);
+ PopulateBytes(bytes.mutable_bytes(), length);
+ out->push_back(bytes);
+}
+
+void AddShortcutMemoryItem(size_t length, BlobDataBuilder* out) {
+ DataElement bytes;
+ bytes.SetToAllocatedBytes(length);
+ PopulateBytes(bytes.mutable_bytes(), length);
+ out->AppendData(bytes.bytes(), length);
+}
+
+void AddBlobItem(std::vector<DataElement>* out) {
+ DataElement blob;
+ blob.SetToBlob(kFakeBlobUUID);
+ out->push_back(blob);
+}
+
+class BlobAsyncBuilderHostTest : public testing::Test {
+ protected:
+ BlobAsyncBuilderHostTest()
+ : matching_builder_(nullptr),
+ done_called_(false),
+ cancel_called_(false),
+ cancel_code_(IPCBlobCreationCancelCode::UNKNOWN),
+ request_called_(false) {}
+ ~BlobAsyncBuilderHostTest() override {}
+
+ void SetUp() override {
+ matching_builder_ = nullptr;
+ done_called_ = false;
+ cancel_called_ = false;
+ cancel_code_ = IPCBlobCreationCancelCode::UNKNOWN;
+ request_called_ = false;
+ requests_.clear();
+ memory_handles_.clear();
+ file_handles_.clear();
+ host_.SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes,
+ kTestBlobStorageMaxSharedMemoryBytes,
+ kTestBlobStorageMaxFileSizeBytes);
+ }
+
+ void SetMatchingBuilder(BlobDataBuilder* builder) {
+ matching_builder_ = builder;
+ }
+
+ void CancelCallback(IPCBlobCreationCancelCode code) {
+ cancel_called_ = true;
+ cancel_code_ = code;
+ }
+
+ void DoneCallback(const BlobDataBuilder& builder) {
+ // This does a deep comparison, including internal data items.
+ if (matching_builder_)
+ EXPECT_EQ(*matching_builder_, builder);
+ done_called_ = true;
+ }
+
+ void RequestMemoryCallback(
+ const std::vector<storage::BlobItemBytesRequest>& requests,
+ const std::vector<base::SharedMemoryHandle>& shared_memory_handles,
+ const std::vector<uint64_t>& file_sizes) {
+ this->requests_ = requests;
+ memory_handles_ = shared_memory_handles;
+ file_handles_ = file_sizes;
+ request_called_ = true;
+ }
+
+ bool BuildBlobAsync(const std::vector<DataElement>& descriptions,
+ size_t memory_available) {
+ done_called_ = false;
+ cancel_called_ = false;
+ request_called_ = false;
+ return host_.StartBuildingBlob(
+ kBlobUUID, kBlobType, descriptions, memory_available,
+ base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
+ base::Unretained(this)),
+ base::Bind(&BlobAsyncBuilderHostTest::DoneCallback,
+ base::Unretained(this)),
+ base::Bind(&BlobAsyncBuilderHostTest::CancelCallback,
+ base::Unretained(this)));
+ }
+
+ BlobDataBuilder* matching_builder_;
+ BlobAsyncBuilderHost host_;
+ bool done_called_;
+ bool cancel_called_;
+ IPCBlobCreationCancelCode cancel_code_;
+
+ bool request_called_;
+ std::vector<storage::BlobItemBytesRequest> requests_;
+ std::vector<base::SharedMemoryHandle> memory_handles_;
+ std::vector<uint64_t> file_handles_;
+};
+
+TEST_F(BlobAsyncBuilderHostTest, TestShortcut) {
+ std::vector<DataElement> descriptions;
+
+ AddShortcutMemoryItem(10, &descriptions);
+ AddBlobItem(&descriptions);
+ AddShortcutMemoryItem(5000, &descriptions);
+
+ BlobDataBuilder expected(kBlobUUID);
+ expected.set_content_type(kBlobType);
+ AddShortcutMemoryItem(10, &expected);
+ expected.AppendBlob(kFakeBlobUUID);
+ AddShortcutMemoryItem(5000, &expected);
+ SetMatchingBuilder(&expected);
+
+ EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
+
+ EXPECT_TRUE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_FALSE(request_called_);
+ EXPECT_EQ(0u, host_.blob_building_count());
+};
+
+TEST_F(BlobAsyncBuilderHostTest, TestSingleSharedMemRequest) {
+ std::vector<DataElement> descriptions;
+ const size_t kSize = kTestBlobStorageIPCThresholdBytes + 1;
+ AddMemoryItem(kSize, &descriptions);
+
+ EXPECT_TRUE(
+ BuildBlobAsync(descriptions, kTestBlobStorageIPCThresholdBytes + 1));
+
+ EXPECT_FALSE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_TRUE(request_called_);
+ EXPECT_EQ(1u, host_.blob_building_count());
+ ASSERT_EQ(1u, requests_.size());
+ request_called_ = false;
+
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateSharedMemoryRequest(0, 0, 0, kSize, 0, 0),
+ requests_.at(0));
+};
+
+TEST_F(BlobAsyncBuilderHostTest, TestMultipleSharedMemRequests) {
+ std::vector<DataElement> descriptions;
+ const size_t kSize = kTestBlobStorageMaxSharedMemoryBytes + 1;
+ const char kFirstBlockByte = 7;
+ const char kSecondBlockByte = 19;
+ AddMemoryItem(kSize, &descriptions);
+
+ BlobDataBuilder expected(kBlobUUID);
+ expected.set_content_type(kBlobType);
+ char data[kSize];
+ memset(data, kFirstBlockByte, kTestBlobStorageMaxSharedMemoryBytes);
+ expected.AppendData(data, kTestBlobStorageMaxSharedMemoryBytes);
+ expected.AppendData(&kSecondBlockByte, 1);
+ SetMatchingBuilder(&expected);
+
+ EXPECT_TRUE(
+ BuildBlobAsync(descriptions, kTestBlobStorageMaxSharedMemoryBytes + 1));
+
+ EXPECT_FALSE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_TRUE(request_called_);
+ EXPECT_EQ(1u, host_.blob_building_count());
+ ASSERT_EQ(1u, requests_.size());
+ request_called_ = false;
+
+ // We need to grab a duplicate handle so we can have two blocks open at the
+ // same time.
+ base::SharedMemoryHandle handle =
+ base::SharedMemory::DuplicateHandle(memory_handles_.at(0));
+ EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle));
+ base::SharedMemory shared_memory(handle, false);
+ EXPECT_TRUE(shared_memory.Map(kTestBlobStorageMaxSharedMemoryBytes));
+
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
+ 0, 0, 0, kTestBlobStorageMaxSharedMemoryBytes, 0, 0),
+ requests_.at(0));
+
+ memset(shared_memory.memory(), kFirstBlockByte,
+ kTestBlobStorageMaxSharedMemoryBytes);
+
+ BlobItemBytesResponse response(0);
+ std::vector<BlobItemBytesResponse> responses = {response};
+ EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
+
+ EXPECT_FALSE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_TRUE(request_called_);
+ EXPECT_EQ(1u, host_.blob_building_count());
+ ASSERT_EQ(1u, requests_.size());
+ request_called_ = false;
+
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
+ 1, 0, kTestBlobStorageMaxSharedMemoryBytes, 1, 0, 0),
+ requests_.at(0));
+
+ memset(shared_memory.memory(), kSecondBlockByte, 1);
+
+ response.request_number = 1;
+ responses[0] = response;
+ EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
+ EXPECT_TRUE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_FALSE(request_called_);
+ EXPECT_EQ(0u, host_.blob_building_count());
+};
+
+TEST_F(BlobAsyncBuilderHostTest, TestBasicIPCAndStopBuilding) {
+ std::vector<DataElement> descriptions;
+
+ AddMemoryItem(2, &descriptions);
+ AddBlobItem(&descriptions);
+ AddMemoryItem(2, &descriptions);
+
+ BlobDataBuilder expected(kBlobUUID);
+ expected.set_content_type(kBlobType);
+ AddShortcutMemoryItem(2, &expected);
+ expected.AppendBlob(kFakeBlobUUID);
+ AddShortcutMemoryItem(2, &expected);
+ SetMatchingBuilder(&expected);
+
+ EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
+ host_.StopBuildingBlob(kBlobUUID);
+ EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
+
+ EXPECT_FALSE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_TRUE(request_called_);
+ EXPECT_EQ(1u, host_.blob_building_count());
+ request_called_ = false;
+
+ BlobItemBytesResponse response1(0);
+ PopulateBytes(response1.allocate_mutable_data(2), 2);
+ BlobItemBytesResponse response2(1);
+ PopulateBytes(response2.allocate_mutable_data(2), 2);
+ std::vector<BlobItemBytesResponse> responses = {response1, response2};
+ EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
+ EXPECT_TRUE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_FALSE(request_called_);
+ EXPECT_EQ(0u, host_.blob_building_count());
+};
+
+TEST_F(BlobAsyncBuilderHostTest, TestBadIPCs) {
+ std::vector<DataElement> descriptions;
+
+ // Test reusing same blob uuid.
+ SetMatchingBuilder(nullptr);
+ AddMemoryItem(10, &descriptions);
+ AddBlobItem(&descriptions);
+ AddMemoryItem(5000, &descriptions);
+ EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
+ EXPECT_FALSE(BuildBlobAsync(descriptions, 5010));
+ EXPECT_FALSE(done_called_);
+ EXPECT_FALSE(cancel_called_);
+ EXPECT_FALSE(request_called_);
+ host_.StopBuildingBlob(kBlobUUID);
+
+ // Test we're _not_ an error if we get a bad uuid for responses.
+ BlobItemBytesResponse response(0);
+ std::vector<BlobItemBytesResponse> responses = {response};
+ EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
+
+ // Test empty responses.
+ responses.clear();
+ EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses));
+
+ // Test response problems below here.
+ descriptions.clear();
+ AddMemoryItem(2, &descriptions);
+ AddBlobItem(&descriptions);
+ AddMemoryItem(2, &descriptions);
+ EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
+
+ // Invalid request number.
+ BlobItemBytesResponse response1(3);
+ PopulateBytes(response1.allocate_mutable_data(2), 2);
+ responses = {response1};
+ EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses));
+
+ // Duplicate request number responses.
+ EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
+ response1.request_number = 0;
+ BlobItemBytesResponse response2(0);
+ PopulateBytes(response2.allocate_mutable_data(2), 2);
+ responses = {response1, response2};
+ EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses));
+};
+
+} // namespace
+} // namespace storage
diff --git a/chromium/content/browser/blob_storage/blob_async_transport_strategy_unittest.cc b/chromium/content/browser/blob_storage/blob_async_transport_strategy_unittest.cc
new file mode 100644
index 00000000000..6318439e916
--- /dev/null
+++ b/chromium/content/browser/blob_storage/blob_async_transport_strategy_unittest.cc
@@ -0,0 +1,458 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "storage/browser/blob/blob_async_transport_strategy.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+
+#include "base/logging.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace storage {
+namespace {
+
+const char kNewUUID[] = "newUUID";
+const base::FilePath kFuturePopulatingFilePath = base::FilePath::FromUTF8Unsafe(
+ std::string(BlobDataBuilder::kAppendFutureFileTemporaryFileName));
+const char kFakeBlobUUID[] = "fakeBlob";
+
+void AddMemoryItem(size_t length, std::vector<DataElement>* out) {
+ DataElement bytes;
+ bytes.SetToBytesDescription(length);
+ out->push_back(bytes);
+}
+
+void AddShortcutMemoryItem(size_t length, std::vector<DataElement>* out) {
+ DataElement bytes;
+ bytes.SetToAllocatedBytes(length);
+ for (size_t i = 0; i < length; i++) {
+ bytes.mutable_bytes()[i] = static_cast<char>(i);
+ }
+ out->push_back(bytes);
+}
+
+void AddBlobItem(std::vector<DataElement>* out) {
+ DataElement blob;
+ blob.SetToBlob(kFakeBlobUUID);
+ out->push_back(blob);
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestNoMemoryItems) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // Here we test that we don't do any requests when there are no memory items.
+ AddBlobItem(&infos);
+ AddBlobItem(&infos);
+ AddBlobItem(&infos);
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_available
+ kNewUUID, infos);
+
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ EXPECT_EQ(0u, strategy.handle_sizes().size());
+ EXPECT_EQ(0u, strategy.requests().size());
+
+ BlobDataBuilder builder(kNewUUID);
+ builder.AppendBlob(kFakeBlobUUID);
+ builder.AppendBlob(kFakeBlobUUID);
+ builder.AppendBlob(kFakeBlobUUID);
+ EXPECT_EQ(builder, *strategy.blob_builder());
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestLargeBlockToFile) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // Here we test our size > max_blob_in_memory_size (100),
+ // and we save to one file. (size < max_file_size)
+ AddMemoryItem(305, &infos);
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_available
+ kNewUUID, infos);
+
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ EXPECT_EQ(1u, strategy.handle_sizes().size());
+ EXPECT_EQ(305ul, strategy.handle_sizes().at(0));
+ EXPECT_EQ(1u, strategy.requests().size());
+
+ auto& memory_item_request = strategy.requests().at(0);
+ EXPECT_EQ(0u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateFileRequest(0u, 0u, 0ull, 305ull, 0u, 0ull),
+ memory_item_request.message);
+
+ BlobDataBuilder builder(kNewUUID);
+ builder.AppendFile(kFuturePopulatingFilePath, 0, 305,
+ base::Time::FromDoubleT(0));
+ EXPECT_EQ(builder, *strategy.blob_builder());
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestLargeBlockToFiles) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // Here we test our size > max_blob_in_memory_size (300),
+ // and we save 3 files. (size > max_file_size)
+ AddMemoryItem(1000, &infos);
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_available
+ kNewUUID, infos);
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ EXPECT_EQ(3u, strategy.handle_sizes().size());
+ EXPECT_EQ(400ul, strategy.handle_sizes().at(0));
+ EXPECT_EQ(400ul, strategy.handle_sizes().at(1));
+ EXPECT_EQ(200ul, strategy.handle_sizes().at(2));
+ EXPECT_EQ(3u, strategy.requests().size());
+
+ auto memory_item_request = strategy.requests().at(0);
+ EXPECT_EQ(0u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateFileRequest(0u, 0u, 0ull, 400ull, 0u, 0ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(1);
+ EXPECT_EQ(1u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateFileRequest(1u, 0u, 400ull, 400ull, 1u, 0ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(2);
+ EXPECT_EQ(2u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateFileRequest(2u, 0u, 800ull, 200ull, 2u, 0ull),
+ memory_item_request.message);
+
+ BlobDataBuilder builder(kNewUUID);
+ builder.AppendFile(kFuturePopulatingFilePath, 0, 400,
+ base::Time::FromDoubleT(0));
+ builder.AppendFile(kFuturePopulatingFilePath, 0, 400,
+ base::Time::FromDoubleT(0));
+ builder.AppendFile(kFuturePopulatingFilePath, 0, 200,
+ base::Time::FromDoubleT(0));
+ EXPECT_EQ(builder, *strategy.blob_builder());
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestLargeBlocksConsolidatingInFiles) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // We should have 3 storage items for the memory, two files, 400 each.
+ // We end up with storage items:
+ // 1: File A, 300MB
+ // 2: Blob
+ // 3: File A, 100MB (300MB offset)
+ // 4: File B, 400MB
+ AddMemoryItem(300, &infos);
+ AddBlobItem(&infos);
+ AddMemoryItem(500, &infos);
+
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_available
+ kNewUUID, infos);
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ EXPECT_EQ(2u, strategy.handle_sizes().size());
+ EXPECT_EQ(400ul, strategy.handle_sizes().at(0));
+ EXPECT_EQ(400ul, strategy.handle_sizes().at(1));
+ EXPECT_EQ(3u, strategy.requests().size());
+
+ auto memory_item_request = strategy.requests().at(0);
+ EXPECT_EQ(0u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateFileRequest(0u, 0u, 0ull, 300ull, 0u, 0ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(1);
+ EXPECT_EQ(2u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateFileRequest(1u, 2u, 0ull, 100ull, 0u, 300ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(2);
+ EXPECT_EQ(3u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(
+ BlobItemBytesRequest::CreateFileRequest(2u, 2u, 100ull, 400ull, 1u, 0ull),
+ memory_item_request.message);
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestSharedMemorySegmentation) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // For transport we should have 3 shared memories, and then storage in 3
+ // browser items.
+ // (size > max_shared_memory_size and size < max_blob_in_memory_size
+ AddMemoryItem(500, &infos);
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 300, // max_file_size
+ 5000, // disk_space_left
+ 500, // memory_available
+ kNewUUID, infos);
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ EXPECT_EQ(3u, strategy.handle_sizes().size());
+ EXPECT_EQ(200u, strategy.handle_sizes().at(0));
+ EXPECT_EQ(200u, strategy.handle_sizes().at(1));
+ EXPECT_EQ(100u, strategy.handle_sizes().at(2));
+ EXPECT_EQ(3u, strategy.requests().size());
+
+ auto memory_item_request = strategy.requests().at(0);
+ EXPECT_EQ(0u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(0u, 0u, 0ull,
+ 200ull, 0u, 0ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(1);
+ EXPECT_EQ(1u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(1u, 0u, 200ull,
+ 200ull, 1u, 0ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(2);
+ EXPECT_EQ(2u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(2u, 0u, 400ull,
+ 100ull, 2u, 0ull),
+ memory_item_request.message);
+
+ BlobDataBuilder builder(kNewUUID);
+ builder.AppendFutureData(200);
+ builder.AppendFutureData(200);
+ builder.AppendFutureData(100);
+
+ EXPECT_EQ(builder, *strategy.blob_builder());
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestSharedMemorySegmentationAndStorage) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // For transport, we should have 2 shared memories, where the first one
+ // have half 0 and half 3, and then the last one has half 3.
+ //
+ // For storage, we should have 3 browser items that match the pre-transport
+ // version:
+ // 1: Bytes 100MB
+ // 2: Blob
+ // 3: Bytes 200MB
+ AddShortcutMemoryItem(100, &infos); // should have no behavior change
+ AddBlobItem(&infos);
+ AddMemoryItem(200, &infos);
+
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 300, // max_file_size
+ 5000, // disk_space_left
+ 300, // memory_available
+ kNewUUID, infos);
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ EXPECT_EQ(2u, strategy.handle_sizes().size());
+ EXPECT_EQ(200u, strategy.handle_sizes().at(0));
+ EXPECT_EQ(100u, strategy.handle_sizes().at(1));
+ EXPECT_EQ(3u, strategy.requests().size());
+
+ auto memory_item_request = strategy.requests().at(0);
+ EXPECT_EQ(0u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(0u, 0u, 0ull,
+ 100ull, 0u, 0ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(1);
+ EXPECT_EQ(2u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(1u, 2u, 0ull,
+ 100ull, 0u, 100ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(2);
+ EXPECT_EQ(2u, memory_item_request.browser_item_index);
+ EXPECT_EQ(100u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(2u, 2u, 100ull,
+ 100ull, 1u, 0ull),
+ memory_item_request.message);
+
+ BlobDataBuilder builder(kNewUUID);
+ builder.AppendFutureData(100);
+ builder.AppendBlob(kFakeBlobUUID);
+ builder.AppendFutureData(200);
+
+ EXPECT_EQ(builder, *strategy.blob_builder());
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestTooLarge) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // Our item is too large for disk, so error out.
+ AddMemoryItem(5001, &infos);
+
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_left
+ kNewUUID, infos);
+
+ EXPECT_EQ(0u, strategy.handle_sizes().size());
+ EXPECT_EQ(0u, strategy.handle_sizes().size());
+ EXPECT_EQ(0u, strategy.requests().size());
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_TOO_LARGE, strategy.error());
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestNoDisk) {
+ BlobAsyncTransportStrategy strategy;
+ std::vector<DataElement> infos;
+
+ // Our item is too large for memory, and we are in no_disk mode (incognito)
+ AddMemoryItem(301, &infos);
+
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 0, // disk_space_left
+ 300, // memory_available
+ kNewUUID, infos);
+
+ EXPECT_EQ(0u, strategy.handle_sizes().size());
+ EXPECT_EQ(0u, strategy.handle_sizes().size());
+ EXPECT_EQ(0u, strategy.requests().size());
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_TOO_LARGE, strategy.error());
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestSimpleIPC) {
+ // Test simple IPC strategy, where size < max_ipc_memory_size and we have
+ // just one item.
+ std::vector<DataElement> infos;
+ BlobAsyncTransportStrategy strategy;
+ AddMemoryItem(10, &infos);
+ AddBlobItem(&infos);
+
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_left
+ kNewUUID, infos);
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ ASSERT_EQ(1u, strategy.requests().size());
+
+ auto memory_item_request = strategy.requests().at(0);
+ EXPECT_EQ(0u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateIPCRequest(0u, 0u, 0ull, 10ull),
+ memory_item_request.message);
+}
+
+TEST(BlobAsyncTransportStrategyTest, TestMultipleIPC) {
+ // Same as above, but with 2 items and a blob in-between.
+ std::vector<DataElement> infos;
+ BlobAsyncTransportStrategy strategy;
+ infos.clear();
+ AddShortcutMemoryItem(10, &infos); // should have no behavior change
+ AddBlobItem(&infos);
+ AddMemoryItem(80, &infos);
+
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_left
+ kNewUUID, infos);
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
+
+ ASSERT_EQ(2u, strategy.requests().size());
+
+ auto memory_item_request = strategy.requests().at(0);
+ EXPECT_EQ(0u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateIPCRequest(0u, 0u, 0ull, 10ull),
+ memory_item_request.message);
+
+ memory_item_request = strategy.requests().at(1);
+ EXPECT_EQ(2u, memory_item_request.browser_item_index);
+ EXPECT_EQ(0u, memory_item_request.browser_item_offset);
+ EXPECT_EQ(BlobItemBytesRequest::CreateIPCRequest(1u, 2u, 0ull, 80ull),
+ memory_item_request.message);
+
+ // We still populate future data, as the strategy assumes we will be
+ // requesting the data.
+ BlobDataBuilder builder(kNewUUID);
+ builder.AppendFutureData(10);
+ builder.AppendBlob(kFakeBlobUUID);
+ builder.AppendFutureData(80);
+
+ EXPECT_EQ(builder, *strategy.blob_builder());
+}
+
+TEST(BlobAsyncTransportStrategyTest, Shortcut) {
+ std::vector<DataElement> infos;
+ AddMemoryItem(100, &infos);
+ AddBlobItem(&infos);
+ EXPECT_FALSE(BlobAsyncTransportStrategy::ShouldBeShortcut(infos, 200));
+
+ infos.clear();
+ AddShortcutMemoryItem(100, &infos);
+ AddBlobItem(&infos);
+ EXPECT_TRUE(BlobAsyncTransportStrategy::ShouldBeShortcut(infos, 200));
+
+ infos.clear();
+ AddShortcutMemoryItem(100, &infos);
+ EXPECT_FALSE(BlobAsyncTransportStrategy::ShouldBeShortcut(infos, 99));
+}
+} // namespace
+
+TEST(BlobAsyncTransportStrategyTest, TestInvalidParams) {
+ std::vector<DataElement> infos;
+ // In order to test uin64_t overflow, we would need to have an array with more
+ // than size_t entries (for 32 byte stuff). So this would only happen if the
+ // IPC was malformed. We instead have to friend this test from DataElement so
+ // we can modify the length to be > size_t.
+
+ // Test uint64_t overflow.
+ BlobAsyncTransportStrategy strategy;
+ AddMemoryItem(1, &infos);
+ AddMemoryItem(1, &infos);
+ infos.back().length_ = std::numeric_limits<uint64_t>::max();
+ strategy.Initialize(100, // max_ipc_memory_size
+ 200, // max_shared_memory_size
+ 400, // max_file_size
+ 5000, // disk_space_left
+ 100, // memory_left
+ kNewUUID, infos);
+ EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_INVALID_PARAMS,
+ strategy.error());
+}
+} // namespace storage
diff --git a/chromium/content/browser/blob_storage/blob_storage_registry_unittest.cc b/chromium/content/browser/blob_storage/blob_storage_registry_unittest.cc
new file mode 100644
index 00000000000..9ff10d69700
--- /dev/null
+++ b/chromium/content/browser/blob_storage/blob_storage_registry_unittest.cc
@@ -0,0 +1,87 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "storage/browser/blob/blob_storage_registry.h"
+
+#include "base/callback.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace storage {
+namespace {
+using Entry = BlobStorageRegistry::Entry;
+using BlobState = BlobStorageRegistry::BlobState;
+
+TEST(BlobStorageRegistry, UUIDRegistration) {
+ const std::string kBlob1 = "Blob1";
+ BlobStorageRegistry registry;
+
+ EXPECT_FALSE(registry.DeleteEntry(kBlob1));
+ EXPECT_EQ(0u, registry.blob_count());
+
+ Entry* entry = registry.CreateEntry(kBlob1);
+ ASSERT_NE(nullptr, entry);
+ EXPECT_EQ(BlobState::RESERVED, entry->state);
+ EXPECT_EQ(1u, entry->refcount);
+ EXPECT_FALSE(entry->exceeded_memory);
+ EXPECT_FALSE(entry->data.get() || entry->data_builder.get());
+ EXPECT_EQ(0u, entry->construction_complete_callbacks.size());
+
+ EXPECT_EQ(entry, registry.GetEntry(kBlob1));
+ EXPECT_TRUE(registry.DeleteEntry(kBlob1));
+ entry = registry.CreateEntry(kBlob1);
+
+ EXPECT_TRUE(entry->TestAndSetState(BlobState::RESERVED,
+ BlobState::ASYNC_TRANSPORTATION));
+ EXPECT_FALSE(
+ entry->TestAndSetState(BlobState::CONSTRUCTION, BlobState::RESERVED));
+ EXPECT_FALSE(entry->TestAndSetState(BlobState::ACTIVE, BlobState::RESERVED));
+ EXPECT_TRUE(entry->TestAndSetState(BlobState::ASYNC_TRANSPORTATION,
+ BlobState::CONSTRUCTION));
+ EXPECT_EQ(BlobState::CONSTRUCTION, entry->state);
+ EXPECT_EQ(1u, registry.blob_count());
+}
+
+TEST(BlobStorageRegistry, URLRegistration) {
+ const std::string kBlob = "Blob1";
+ const std::string kBlob2 = "Blob2";
+ const GURL kURL = GURL("blob://Blob1");
+ const GURL kURL2 = GURL("blob://Blob2");
+ BlobStorageRegistry registry;
+
+ EXPECT_FALSE(registry.IsURLMapped(kURL));
+ EXPECT_EQ(nullptr, registry.GetEntryFromURL(kURL, nullptr));
+ EXPECT_FALSE(registry.DeleteURLMapping(kURL, nullptr));
+ EXPECT_FALSE(registry.CreateUrlMapping(kURL, kBlob));
+ EXPECT_EQ(0u, registry.url_count());
+ Entry* entry = registry.CreateEntry(kBlob);
+
+ EXPECT_FALSE(registry.IsURLMapped(kURL));
+ EXPECT_TRUE(registry.CreateUrlMapping(kURL, kBlob));
+ EXPECT_FALSE(registry.CreateUrlMapping(kURL, kBlob2));
+
+ EXPECT_TRUE(registry.IsURLMapped(kURL));
+ EXPECT_EQ(entry, registry.GetEntryFromURL(kURL, nullptr));
+ std::string uuid;
+ EXPECT_EQ(entry, registry.GetEntryFromURL(kURL, &uuid));
+ EXPECT_EQ(kBlob, uuid);
+ EXPECT_EQ(1u, registry.url_count());
+
+ registry.CreateEntry(kBlob2);
+ EXPECT_TRUE(registry.CreateUrlMapping(kURL2, kBlob2));
+ EXPECT_EQ(2u, registry.url_count());
+ EXPECT_TRUE(registry.DeleteURLMapping(kURL2, &uuid));
+ EXPECT_EQ(kBlob2, uuid);
+ EXPECT_FALSE(registry.IsURLMapped(kURL2));
+
+ // Both urls point to the same blob.
+ EXPECT_TRUE(registry.CreateUrlMapping(kURL2, kBlob));
+ std::string uuid2;
+ EXPECT_EQ(registry.GetEntryFromURL(kURL, &uuid),
+ registry.GetEntryFromURL(kURL2, &uuid2));
+ EXPECT_EQ(uuid, uuid2);
+}
+
+} // namespace
+} // namespace storage
diff --git a/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc
new file mode 100644
index 00000000000..9075fe82bb3
--- /dev/null
+++ b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc
@@ -0,0 +1,155 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/bluetooth/bluetooth_allowed_devices_map.h"
+
+#include <vector>
+
+#include "base/base64.h"
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/strings/string_util.h"
+#include "content/common/bluetooth/bluetooth_scan_filter.h"
+#include "crypto/random.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+
+using device::BluetoothUUID;
+
+namespace content {
+
+namespace {
+const size_t kIdLength = 16 /* 128bits */;
+
+std::string GetBase64Id() {
+ std::string bytes(
+ kIdLength + 1 /* to avoid bytes being reallocated by WriteInto */, '\0');
+
+ crypto::RandBytes(
+ base::WriteInto(&bytes /* str */, kIdLength + 1 /* length_with_null */),
+ kIdLength);
+
+ base::Base64Encode(bytes, &bytes);
+
+ return bytes;
+}
+} // namespace
+
+BluetoothAllowedDevicesMap::BluetoothAllowedDevicesMap() {}
+BluetoothAllowedDevicesMap::~BluetoothAllowedDevicesMap() {}
+
+const std::string& BluetoothAllowedDevicesMap::AddDevice(
+ const url::Origin& origin,
+ const std::string& device_address,
+ const std::vector<BluetoothScanFilter>& filters,
+ const std::vector<BluetoothUUID>& optional_services) {
+ VLOG(1) << "Adding a device to Map of Allowed Devices.";
+
+ // "Unique" Origins generate the same key in maps. The set of "unique"
+ // Origins that generate the same key does not intersect the set of
+ // potentially trustworthy origins; since Bluetooth is only available for
+ // potntially trustworthy origins we should never receive a request from a
+ // "unique" Origin.
+ // See url::Origin for what constitutes a "unique" Origin and the
+ // Secure Contexts spec for what constitutes a Trusworthy Origin:
+ // https://w3c.github.io/webappsec-secure-contexts/
+ CHECK(!origin.unique());
+
+ if (ContainsKey(origin_to_device_address_to_id_map_[origin],
+ device_address)) {
+ VLOG(1) << "Device already in map of allowed devices.";
+ return origin_to_device_address_to_id_map_[origin][device_address];
+ }
+ const std::string device_id = GenerateDeviceId(origin);
+ VLOG(1) << "Id generated for device: " << device_id;
+
+ origin_to_device_address_to_id_map_[origin][device_address] = device_id;
+ origin_to_device_id_to_address_map_[origin][device_id] = device_address;
+ origin_to_device_id_to_services_map_[origin][device_id] =
+ UnionOfServices(filters, optional_services);
+
+ return origin_to_device_address_to_id_map_[origin][device_address];
+}
+
+void BluetoothAllowedDevicesMap::RemoveDevice(
+ const url::Origin& origin,
+ const std::string& device_address) {
+ const std::string device_id = GetDeviceId(origin, device_address);
+ DCHECK(!device_id.empty());
+
+ // 1. Remove from all three maps.
+ CHECK(origin_to_device_address_to_id_map_[origin].erase(device_address));
+ CHECK(origin_to_device_id_to_address_map_[origin].erase(device_id));
+ CHECK(origin_to_device_id_to_services_map_[origin].erase(device_id));
+
+ // 2. Remove empty map for origin.
+ if (origin_to_device_address_to_id_map_[origin].empty()) {
+ CHECK(origin_to_device_address_to_id_map_.erase(origin));
+ CHECK(origin_to_device_id_to_address_map_.erase(origin));
+ CHECK(origin_to_device_id_to_services_map_.erase(origin));
+ }
+}
+
+const std::string& BluetoothAllowedDevicesMap::GetDeviceId(
+ const url::Origin& origin,
+ const std::string& device_address) {
+ auto address_map_iter = origin_to_device_address_to_id_map_.find(origin);
+ if (address_map_iter == origin_to_device_address_to_id_map_.end()) {
+ return base::EmptyString();
+ }
+
+ const auto& device_address_to_id_map = address_map_iter->second;
+
+ auto id_iter = device_address_to_id_map.find(device_address);
+ if (id_iter == device_address_to_id_map.end()) {
+ return base::EmptyString();
+ }
+ return id_iter->second;
+}
+
+const std::string& BluetoothAllowedDevicesMap::GetDeviceAddress(
+ const url::Origin& origin,
+ const std::string& device_id) {
+ auto id_map_iter = origin_to_device_id_to_address_map_.find(origin);
+ if (id_map_iter == origin_to_device_id_to_address_map_.end()) {
+ return base::EmptyString();
+ }
+
+ const auto& device_id_to_address_map = id_map_iter->second;
+
+ auto id_iter = device_id_to_address_map.find(device_id);
+
+ return id_iter == device_id_to_address_map.end() ? base::EmptyString()
+ : id_iter->second;
+}
+
+std::string BluetoothAllowedDevicesMap::GenerateDeviceId(
+ const url::Origin& origin) {
+ std::string device_id = GetBase64Id();
+ auto id_map_iter = origin_to_device_id_to_address_map_.find(origin);
+ if (id_map_iter == origin_to_device_id_to_address_map_.end()) {
+ return device_id;
+ }
+ while (ContainsKey(id_map_iter->second, device_id)) {
+ LOG(WARNING) << "Generated repeated id.";
+ device_id = GetBase64Id();
+ }
+ return device_id;
+}
+
+std::set<std::string> BluetoothAllowedDevicesMap::UnionOfServices(
+ const std::vector<BluetoothScanFilter>& filters,
+ const std::vector<BluetoothUUID>& optional_services) {
+ std::set<std::string> unionOfServices;
+ for (const auto& filter : filters) {
+ for (const BluetoothUUID& uuid : filter.services) {
+ unionOfServices.insert(uuid.canonical_value());
+ }
+ }
+ for (const BluetoothUUID& uuid : optional_services) {
+ unionOfServices.insert(uuid.canonical_value());
+ }
+ return unionOfServices;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.h b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.h
new file mode 100644
index 00000000000..d8672979eeb
--- /dev/null
+++ b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.h
@@ -0,0 +1,84 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_ALLOWED_DEVICES_MAP_
+#define CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_ALLOWED_DEVICES_MAP_
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "content/common/content_export.h"
+#include "url/origin.h"
+
+namespace device {
+class BluetoothUUID;
+}
+
+namespace content {
+
+struct BluetoothScanFilter;
+
+// Keeps track of which origins are allowed to access which devices and
+// their services.
+//
+// |AddDevice| generates device ids, which are random strings that are unique
+// for each (origin, device address) pair.
+class CONTENT_EXPORT BluetoothAllowedDevicesMap final {
+ public:
+ BluetoothAllowedDevicesMap();
+ ~BluetoothAllowedDevicesMap();
+
+ // Adds the Bluetooth Device with |device_address| to the map of allowed
+ // devices for that origin. Generates and returns a device id for the
+ // (|origin|, |device_address|) pair.
+ const std::string& AddDevice(
+ const url::Origin& origin,
+ const std::string& device_address,
+ const std::vector<BluetoothScanFilter>& filters,
+ const std::vector<device::BluetoothUUID>& optional_services);
+
+ // Removes the Bluetooth Device with |device_address| from the map of allowed
+ // devices for |origin|.
+ void RemoveDevice(const url::Origin& origin,
+ const std::string& device_address);
+
+ // TODO(ortuno): Add function to check if origin is allowed to access
+ // a device's service and add tests for that function.
+ // https://crbug.com/493460
+
+ // Returns the Bluetooth Device's id for |origin|. Returns an empty string
+ // if the origin is not allowed to access the device.
+ const std::string& GetDeviceId(const url::Origin& origin,
+ const std::string& device_address);
+
+ // For |device_id| in |origin|, returns the Bluetooth device's address. If
+ // there is no such |device_id| in |origin|, returns an empty string.
+ const std::string& GetDeviceAddress(const url::Origin& origin,
+ const std::string& device_id);
+
+ private:
+ typedef std::map<std::string, std::string> DeviceAddressToIdMap;
+ typedef std::map<std::string, std::string> DeviceIdToAddressMap;
+ typedef std::map<std::string, std::set<std::string>> DeviceIdToServicesMap;
+
+ // Returns an id guaranteed to be unique for the origin. The id is randomly
+ // generated so that an origin can't guess the id used in another origin.
+ std::string GenerateDeviceId(const url::Origin& origin);
+ std::set<std::string> UnionOfServices(
+ const std::vector<BluetoothScanFilter>& filters,
+ const std::vector<device::BluetoothUUID>& optional_services);
+
+ std::map<url::Origin, DeviceAddressToIdMap>
+ origin_to_device_address_to_id_map_;
+ std::map<url::Origin, DeviceIdToAddressMap>
+ origin_to_device_id_to_address_map_;
+ std::map<url::Origin, DeviceIdToServicesMap>
+ origin_to_device_id_to_services_map_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_ALLOWED_DEVICES_MAP_
diff --git a/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map_unittest.cc b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map_unittest.cc
new file mode 100644
index 00000000000..2d5243a1d5f
--- /dev/null
+++ b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map_unittest.cc
@@ -0,0 +1,167 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/bluetooth/bluetooth_allowed_devices_map.h"
+
+#include "base/strings/string_util.h"
+#include "content/common/bluetooth/bluetooth_scan_filter.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+namespace {
+const url::Origin test_origin1(GURL("https://www.example1.com"));
+const url::Origin test_origin2(GURL("https://www.example2.com"));
+
+const std::string device_address1 = "00:00:00";
+const std::string device_address2 = "11:11:11";
+
+const std::vector<content::BluetoothScanFilter> filters =
+ std::vector<BluetoothScanFilter>();
+const std::vector<device::BluetoothUUID> optional_services =
+ std::vector<device::BluetoothUUID>();
+} // namespace
+
+class BluetoothAllowedDevicesMapTest : public testing::Test {};
+
+TEST_F(BluetoothAllowedDevicesMapTest, AddDeviceToMap) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+
+ const std::string& device_id = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+
+ // Test that we can retrieve the device address/id.
+ EXPECT_EQ(device_id,
+ allowed_devices_map.GetDeviceId(test_origin1, device_address1));
+ EXPECT_EQ(device_address1,
+ allowed_devices_map.GetDeviceAddress(test_origin1, device_id));
+}
+
+TEST_F(BluetoothAllowedDevicesMapTest, AddDeviceToMapTwice) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+ const std::string& device_id1 = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+ const std::string& device_id2 = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+
+ EXPECT_EQ(device_id1, device_id2);
+
+ // Test that we can retrieve the device address/id.
+ EXPECT_EQ(device_id1,
+ allowed_devices_map.GetDeviceId(test_origin1, device_address1));
+ EXPECT_EQ(device_address1,
+ allowed_devices_map.GetDeviceAddress(test_origin1, device_id1));
+}
+
+TEST_F(BluetoothAllowedDevicesMapTest, AddTwoDevicesFromSameOriginToMap) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+ const std::string& device_id1 = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+ const std::string& device_id2 = allowed_devices_map.AddDevice(
+ test_origin1, device_address2, filters, optional_services);
+
+ EXPECT_NE(device_id1, device_id2);
+
+ // Test that we can retrieve the device address/id.
+ EXPECT_EQ(device_id1,
+ allowed_devices_map.GetDeviceId(test_origin1, device_address1));
+ EXPECT_EQ(device_id2,
+ allowed_devices_map.GetDeviceId(test_origin1, device_address2));
+
+ EXPECT_EQ(device_address1,
+ allowed_devices_map.GetDeviceAddress(test_origin1, device_id1));
+ EXPECT_EQ(device_address2,
+ allowed_devices_map.GetDeviceAddress(test_origin1, device_id2));
+}
+
+TEST_F(BluetoothAllowedDevicesMapTest, AddTwoDevicesFromTwoOriginsToMap) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+ const std::string& device_id1 = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+ const std::string& device_id2 = allowed_devices_map.AddDevice(
+ test_origin2, device_address2, filters, optional_services);
+
+ EXPECT_NE(device_id1, device_id2);
+
+ // Test that the wrong origin doesn't have access to the device.
+
+ EXPECT_EQ(base::EmptyString(),
+ allowed_devices_map.GetDeviceId(test_origin1, device_address2));
+ EXPECT_EQ(base::EmptyString(),
+ allowed_devices_map.GetDeviceId(test_origin2, device_address1));
+
+ EXPECT_EQ(base::EmptyString(),
+ allowed_devices_map.GetDeviceAddress(test_origin1, device_id2));
+ EXPECT_EQ(base::EmptyString(),
+ allowed_devices_map.GetDeviceAddress(test_origin2, device_id1));
+
+ // Test that we can retrieve the device address/id.
+ EXPECT_EQ(device_id1,
+ allowed_devices_map.GetDeviceId(test_origin1, device_address1));
+ EXPECT_EQ(device_id2,
+ allowed_devices_map.GetDeviceId(test_origin2, device_address2));
+
+ EXPECT_EQ(device_address1,
+ allowed_devices_map.GetDeviceAddress(test_origin1, device_id1));
+ EXPECT_EQ(device_address2,
+ allowed_devices_map.GetDeviceAddress(test_origin2, device_id2));
+}
+
+TEST_F(BluetoothAllowedDevicesMapTest, AddDeviceFromTwoOriginsToMap) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+ const std::string& device_id1 = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+ const std::string& device_id2 = allowed_devices_map.AddDevice(
+ test_origin2, device_address1, filters, optional_services);
+
+ EXPECT_NE(device_id1, device_id2);
+
+ // Test that the wrong origin doesn't have access to the device.
+ EXPECT_EQ(base::EmptyString(),
+ allowed_devices_map.GetDeviceAddress(test_origin1, device_id2));
+ EXPECT_EQ(base::EmptyString(),
+ allowed_devices_map.GetDeviceAddress(test_origin2, device_id1));
+}
+
+TEST_F(BluetoothAllowedDevicesMapTest, AddRemoveAddDeviceToMap) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+ const std::string device_id_first_time = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+
+ allowed_devices_map.RemoveDevice(test_origin1, device_address1);
+
+ const std::string device_id_second_time = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+
+ EXPECT_NE(device_id_first_time, device_id_second_time);
+}
+
+TEST_F(BluetoothAllowedDevicesMapTest, RemoveDeviceFromMap) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+
+ const std::string& device_id = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+
+ allowed_devices_map.RemoveDevice(test_origin1, device_address1);
+
+ EXPECT_EQ(base::EmptyString(),
+ allowed_devices_map.GetDeviceId(test_origin1, device_id));
+ EXPECT_EQ(base::EmptyString(), allowed_devices_map.GetDeviceAddress(
+ test_origin1, device_address1));
+}
+
+TEST_F(BluetoothAllowedDevicesMapTest, CorrectIdFormat) {
+ BluetoothAllowedDevicesMap allowed_devices_map;
+
+ const std::string& device_id = allowed_devices_map.AddDevice(
+ test_origin1, device_address1, filters, optional_services);
+
+ EXPECT_TRUE(device_id.size() == 24)
+ << "Expected Lenghth of a 128bit string encoded to Base64.";
+ EXPECT_TRUE((device_id[22] == '=') && (device_id[23] == '='))
+ << "Expected padding characters for a 128bit string encoded to Base64.";
+}
+
+} // namespace content
diff --git a/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.cc
index decbede43c1..85bf81e0003 100644
--- a/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.cc
@@ -2,14 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// NETWORK_ERROR Note:
-// When a device can't be found in the BluetoothAdapter, that generally
-// indicates that it's gone out of range. We reject with a NetworkError in that
-// case.
-// https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-connectgatt
+// ID Not In Map Note:
+// A service, characteristic, or descriptor ID not in the corresponding
+// BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_,
+// descriptor_to_characteristic_] implies a hostile renderer because a renderer
+// obtains the corresponding ID from this class and it will be added to the map
+// at that time.
#include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
+#include <stddef.h>
+
+#include <utility>
+
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
@@ -45,28 +50,61 @@ namespace {
// https://crbug.com/436280 and https://crbug.com/484504
const int kDelayTime = 5; // 5 seconds for scanning and discovering
const int kTestingDelayTime = 0; // No need to wait during tests
+const size_t kMaxLengthForDeviceName =
+ 29; // max length of device name in filter.
+
+bool IsEmptyOrInvalidFilter(const content::BluetoothScanFilter& filter) {
+ return filter.name.empty() && filter.namePrefix.empty() &&
+ filter.services.empty() &&
+ filter.name.length() > kMaxLengthForDeviceName &&
+ filter.namePrefix.length() > kMaxLengthForDeviceName;
+}
+
+bool HasEmptyOrInvalidFilter(
+ const std::vector<content::BluetoothScanFilter>& filters) {
+ return filters.empty()
+ ? true
+ : filters.end() != std::find_if(filters.begin(), filters.end(),
+ IsEmptyOrInvalidFilter);
+}
// Defined at
// https://webbluetoothchrome.github.io/web-bluetooth/#dfn-matches-a-filter
-bool MatchesFilter(const std::set<BluetoothUUID>& device_uuids,
+bool MatchesFilter(const device::BluetoothDevice& device,
const content::BluetoothScanFilter& filter) {
- if (filter.services.empty())
- return false;
- for (const BluetoothUUID& service : filter.services) {
- if (!ContainsKey(device_uuids, service)) {
+ DCHECK(!IsEmptyOrInvalidFilter(filter));
+
+ const std::string device_name = base::UTF16ToUTF8(device.GetName());
+
+ if (!filter.name.empty() && (device_name != filter.name)) {
return false;
+ }
+
+ if (!filter.namePrefix.empty() &&
+ (!base::StartsWith(device_name, filter.namePrefix,
+ base::CompareCase::SENSITIVE))) {
+ return false;
+ }
+
+ if (!filter.services.empty()) {
+ const auto& device_uuid_list = device.GetUUIDs();
+ const std::set<BluetoothUUID> device_uuids(device_uuid_list.begin(),
+ device_uuid_list.end());
+ for (const auto& service : filter.services) {
+ if (!ContainsKey(device_uuids, service)) {
+ return false;
+ }
}
}
+
return true;
}
bool MatchesFilters(const device::BluetoothDevice& device,
const std::vector<content::BluetoothScanFilter>& filters) {
- const std::vector<BluetoothUUID>& device_uuid_list = device.GetUUIDs();
- const std::set<BluetoothUUID> device_uuids(device_uuid_list.begin(),
- device_uuid_list.end());
+ DCHECK(!HasEmptyOrInvalidFilter(filters));
for (const content::BluetoothScanFilter& filter : filters) {
- if (MatchesFilter(device_uuids, filter)) {
+ if (MatchesFilter(device, filter)) {
return true;
}
}
@@ -100,6 +138,30 @@ WebBluetoothError TranslateConnectError(
case device::BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
RecordConnectGATTOutcome(UMAConnectGATTOutcome::UNSUPPORTED_DEVICE);
return WebBluetoothError::ConnectUnsupportedDevice;
+ case device::BluetoothDevice::ERROR_ATTRIBUTE_LENGTH_INVALID:
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::ATTRIBUTE_LENGTH_INVALID);
+ return WebBluetoothError::ConnectAttributeLengthInvalid;
+ case device::BluetoothDevice::ERROR_CONNECTION_CONGESTED:
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::CONNECTION_CONGESTED);
+ return WebBluetoothError::ConnectConnectionCongested;
+ case device::BluetoothDevice::ERROR_INSUFFICIENT_ENCRYPTION:
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::INSUFFICIENT_ENCRYPTION);
+ return WebBluetoothError::ConnectInsufficientEncryption;
+ case device::BluetoothDevice::ERROR_OFFSET_INVALID:
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::OFFSET_INVALID);
+ return WebBluetoothError::ConnectOffsetInvalid;
+ case device::BluetoothDevice::ERROR_READ_NOT_PERMITTED:
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::READ_NOT_PERMITTED);
+ return WebBluetoothError::ConnectReadNotPermitted;
+ case device::BluetoothDevice::ERROR_REQUEST_NOT_SUPPORTED:
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::REQUEST_NOT_SUPPORTED);
+ return WebBluetoothError::ConnectRequestNotSupported;
+ case device::BluetoothDevice::ERROR_WRITE_NOT_PERMITTED:
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::WRITE_NOT_PERMITTED);
+ return WebBluetoothError::ConnectWriteNotPermitted;
+ case device::BluetoothDevice::NUM_CONNECT_ERROR_CODES:
+ NOTREACHED();
+ return WebBluetoothError::UntranslatedConnectErrorCode;
}
NOTREACHED();
return WebBluetoothError::UntranslatedConnectErrorCode;
@@ -153,6 +215,23 @@ void StopDiscoverySession(
base::Bind(&base::DoNothing));
}
+// TODO(ortuno): This should really be a BluetoothDevice method.
+// Replace when implemented. http://crbug.com/552022
+std::vector<BluetoothGattService*> GetPrimaryServicesByUUID(
+ device::BluetoothDevice* device,
+ const std::string& service_uuid) {
+ std::vector<BluetoothGattService*> services;
+ VLOG(1) << "Looking for service: " << service_uuid;
+ for (BluetoothGattService* service : device->GetGattServices()) {
+ VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value();
+ if (service->GetUUID().canonical_value() == service_uuid &&
+ service->IsPrimary()) {
+ services.push_back(service);
+ }
+ }
+ return services;
+}
+
} // namespace
BluetoothDispatcherHost::BluetoothDispatcherHost(int render_process_id)
@@ -171,6 +250,11 @@ BluetoothDispatcherHost::BluetoothDispatcherHost(int render_process_id)
/*is_repeating=*/false),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Bind all future weak pointers to the UI thread.
+ weak_ptr_on_ui_thread_ = weak_ptr_factory_.GetWeakPtr();
+ weak_ptr_on_ui_thread_.get(); // Associates with UI thread.
+
if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
BluetoothAdapterFactory::GetAdapter(
base::Bind(&BluetoothDispatcherHost::set_adapter,
@@ -199,6 +283,12 @@ bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic)
IPC_MESSAGE_HANDLER(BluetoothHostMsg_ReadValue, OnReadValue)
IPC_MESSAGE_HANDLER(BluetoothHostMsg_WriteValue, OnWriteValue)
+ IPC_MESSAGE_HANDLER(BluetoothHostMsg_StartNotifications, OnStartNotifications)
+ IPC_MESSAGE_HANDLER(BluetoothHostMsg_StopNotifications, OnStopNotifications)
+ IPC_MESSAGE_HANDLER(BluetoothHostMsg_RegisterCharacteristic,
+ OnRegisterCharacteristicObject);
+ IPC_MESSAGE_HANDLER(BluetoothHostMsg_UnregisterCharacteristic,
+ OnUnregisterCharacteristicObject);
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -207,15 +297,34 @@ bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) {
void BluetoothDispatcherHost::SetBluetoothAdapterForTesting(
scoped_refptr<device::BluetoothAdapter> mock_adapter) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- current_delay_time_ = kTestingDelayTime;
- // Reset the discovery session timer to use the new delay time.
- discovery_session_timer_.Start(
- FROM_HERE, base::TimeDelta::FromSecondsD(current_delay_time_),
- base::Bind(&BluetoothDispatcherHost::StopDeviceDiscovery,
- // base::Timer guarantees it won't call back after its
- // destructor starts.
- base::Unretained(this)));
- set_adapter(mock_adapter.Pass());
+
+ if (mock_adapter.get()) {
+ current_delay_time_ = kTestingDelayTime;
+ // Reset the discovery session timer to use the new delay time.
+ discovery_session_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromSecondsD(current_delay_time_),
+ base::Bind(&BluetoothDispatcherHost::StopDeviceDiscovery,
+ // base::Timer guarantees it won't call back after its
+ // destructor starts.
+ base::Unretained(this)));
+ } else {
+ // The following data structures are used to store pending operations.
+ // They should never contain elements at the end of a test.
+ DCHECK(request_device_sessions_.IsEmpty());
+ DCHECK(pending_primary_services_requests_.empty());
+
+ // The following data structures are cleaned up when a
+ // device/service/characteristic is removed.
+ // Since this can happen after the test is done and the cleanup function is
+ // called, we clean them here.
+ service_to_device_.clear();
+ characteristic_to_service_.clear();
+ characteristic_id_to_notify_session_.clear();
+ active_characteristic_threads_.clear();
+ connections_.clear();
+ }
+
+ set_adapter(std::move(mock_adapter));
}
BluetoothDispatcherHost::~BluetoothDispatcherHost() {
@@ -230,10 +339,12 @@ struct BluetoothDispatcherHost::RequestDeviceSession {
public:
RequestDeviceSession(int thread_id,
int request_id,
+ url::Origin origin,
const std::vector<BluetoothScanFilter>& filters,
const std::vector<BluetoothUUID>& optional_services)
: thread_id(thread_id),
request_id(request_id),
+ origin(origin),
filters(filters),
optional_services(optional_services) {}
@@ -254,20 +365,76 @@ struct BluetoothDispatcherHost::RequestDeviceSession {
for (const BluetoothUUID& service : services) {
discovery_filter->AddUUID(service);
}
- return discovery_filter.Pass();
+ return discovery_filter;
}
const int thread_id;
const int request_id;
+ const url::Origin origin;
const std::vector<BluetoothScanFilter> filters;
const std::vector<BluetoothUUID> optional_services;
scoped_ptr<BluetoothChooser> chooser;
scoped_ptr<device::BluetoothDiscoverySession> discovery_session;
};
+struct BluetoothDispatcherHost::CacheQueryResult {
+ CacheQueryResult()
+ : device(nullptr),
+ service(nullptr),
+ characteristic(nullptr),
+ outcome(CacheQueryOutcome::SUCCESS) {}
+ CacheQueryResult(CacheQueryOutcome outcome)
+ : device(nullptr),
+ service(nullptr),
+ characteristic(nullptr),
+ outcome(outcome) {}
+ ~CacheQueryResult() {}
+ WebBluetoothError GetWebError() const {
+ switch (outcome) {
+ case CacheQueryOutcome::SUCCESS:
+ case CacheQueryOutcome::BAD_RENDERER:
+ NOTREACHED();
+ return WebBluetoothError::DeviceNoLongerInRange;
+ case CacheQueryOutcome::NO_DEVICE:
+ return WebBluetoothError::DeviceNoLongerInRange;
+ case CacheQueryOutcome::NO_SERVICE:
+ return WebBluetoothError::ServiceNoLongerExists;
+ case CacheQueryOutcome::NO_CHARACTERISTIC:
+ return WebBluetoothError::CharacteristicNoLongerExists;
+ }
+ NOTREACHED();
+ return WebBluetoothError::DeviceNoLongerInRange;
+ }
+
+ device::BluetoothDevice* device;
+ device::BluetoothGattService* service;
+ device::BluetoothGattCharacteristic* characteristic;
+ CacheQueryOutcome outcome;
+};
+
+struct BluetoothDispatcherHost::PrimaryServicesRequest {
+ enum CallingFunction { GET_PRIMARY_SERVICE, GET_PRIMARY_SERVICES };
+
+ PrimaryServicesRequest(int thread_id,
+ int request_id,
+ const std::string& service_uuid,
+ PrimaryServicesRequest::CallingFunction func)
+ : thread_id(thread_id),
+ request_id(request_id),
+ service_uuid(service_uuid),
+ func(func) {}
+ ~PrimaryServicesRequest() {}
+
+ int thread_id;
+ int request_id;
+ std::string service_uuid;
+ CallingFunction func;
+};
+
void BluetoothDispatcherHost::set_adapter(
scoped_refptr<device::BluetoothAdapter> adapter) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ connections_.clear();
if (adapter_.get())
adapter_->RemoveObserver(this);
adapter_ = adapter;
@@ -278,6 +445,7 @@ void BluetoothDispatcherHost::set_adapter(
void BluetoothDispatcherHost::StartDeviceDiscovery(
RequestDeviceSession* session,
int chooser_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (session->discovery_session) {
// Already running; just increase the timeout.
discovery_session_timer_.Reset();
@@ -287,19 +455,20 @@ void BluetoothDispatcherHost::StartDeviceDiscovery(
adapter_->StartDiscoverySessionWithFilter(
session->ComputeScanFilter(),
base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted,
- weak_ptr_factory_.GetWeakPtr(), chooser_id),
+ weak_ptr_on_ui_thread_, chooser_id),
base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError,
- weak_ptr_factory_.GetWeakPtr(), chooser_id));
+ weak_ptr_on_ui_thread_, chooser_id));
}
}
void BluetoothDispatcherHost::StopDeviceDiscovery() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter(
&request_device_sessions_);
!iter.IsAtEnd(); iter.Advance()) {
RequestDeviceSession* session = iter.GetCurrentValue();
if (session->discovery_session) {
- StopDiscoverySession(session->discovery_session.Pass());
+ StopDiscoverySession(std::move(session->discovery_session));
}
if (session->chooser) {
session->chooser->ShowDiscoveryState(
@@ -311,6 +480,7 @@ void BluetoothDispatcherHost::StopDeviceDiscovery() {
void BluetoothDispatcherHost::AdapterPoweredChanged(
device::BluetoothAdapter* adapter,
bool powered) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
const BluetoothChooser::AdapterPresence presence =
powered ? BluetoothChooser::AdapterPresence::POWERED_ON
: BluetoothChooser::AdapterPresence::POWERED_OFF;
@@ -325,6 +495,7 @@ void BluetoothDispatcherHost::AdapterPoweredChanged(
void BluetoothDispatcherHost::DeviceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
VLOG(1) << "Adding device to all choosers: " << device->GetAddress();
for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter(
&request_device_sessions_);
@@ -336,6 +507,7 @@ void BluetoothDispatcherHost::DeviceAdded(device::BluetoothAdapter* adapter,
void BluetoothDispatcherHost::DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
VLOG(1) << "Marking device removed on all choosers: " << device->GetAddress();
for (IDMap<RequestDeviceSession, IDMapOwnPointer>::iterator iter(
&request_device_sessions_);
@@ -347,6 +519,83 @@ void BluetoothDispatcherHost::DeviceRemoved(device::BluetoothAdapter* adapter,
}
}
+void BluetoothDispatcherHost::GattServicesDiscovered(
+ device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ const std::string& device_address = device->GetAddress();
+ VLOG(1) << "Services discovered for device: " << device_address;
+
+ auto iter = pending_primary_services_requests_.find(device_address);
+ if (iter == pending_primary_services_requests_.end()) {
+ return;
+ }
+ std::vector<PrimaryServicesRequest> requests;
+ requests.swap(iter->second);
+ pending_primary_services_requests_.erase(iter);
+
+ for (const PrimaryServicesRequest& request : requests) {
+ std::vector<BluetoothGattService*> services =
+ GetPrimaryServicesByUUID(device, request.service_uuid);
+ switch (request.func) {
+ case PrimaryServicesRequest::GET_PRIMARY_SERVICE:
+ if (!services.empty()) {
+ AddToServicesMapAndSendGetPrimaryServiceSuccess(
+ *services[0], request.thread_id, request.request_id);
+ } else {
+ VLOG(1) << "No service found";
+ RecordGetPrimaryServiceOutcome(
+ UMAGetPrimaryServiceOutcome::NOT_FOUND);
+ Send(new BluetoothMsg_GetPrimaryServiceError(
+ request.thread_id, request.request_id,
+ WebBluetoothError::ServiceNotFound));
+ }
+ break;
+ case PrimaryServicesRequest::GET_PRIMARY_SERVICES:
+ NOTIMPLEMENTED();
+ break;
+ }
+ }
+ DCHECK(!ContainsKey(pending_primary_services_requests_, device_address))
+ << "Sending get-service responses unexpectedly queued another request.";
+}
+
+void BluetoothDispatcherHost::GattCharacteristicValueChanged(
+ device::BluetoothAdapter* adapter,
+ device::BluetoothGattCharacteristic* characteristic,
+ const std::vector<uint8_t>& value) {
+ VLOG(1) << "Characteristic updated: " << characteristic->GetIdentifier();
+ auto iter =
+ active_characteristic_threads_.find(characteristic->GetIdentifier());
+
+ if (iter == active_characteristic_threads_.end()) {
+ return;
+ }
+
+ for (int thread_id : iter->second) {
+ // Yield to the event loop so that the event gets dispatched after the
+ // readValue promise resolves.
+ // TODO(ortuno): Make sure the order of fulfulling promises and triggering
+ // events matches the spec and that events don't get lost.
+ // https://crbug.com/543882
+ if (!base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&BluetoothDispatcherHost::NotifyActiveCharacteristic,
+ weak_ptr_on_ui_thread_, thread_id,
+ characteristic->GetIdentifier(), value))) {
+ LOG(WARNING) << "No TaskRunner.";
+ }
+ }
+}
+
+void BluetoothDispatcherHost::NotifyActiveCharacteristic(
+ int thread_id,
+ const std::string& characteristic_instance_id,
+ const std::vector<uint8_t>& value) {
+ Send(new BluetoothMsg_CharacteristicValueChanged(
+ thread_id, characteristic_instance_id, value));
+}
+
void BluetoothDispatcherHost::OnRequestDevice(
int thread_id,
int request_id,
@@ -359,6 +608,9 @@ void BluetoothDispatcherHost::OnRequestDevice(
VLOG(1) << "requestDevice called with the following filters: ";
for (const BluetoothScanFilter& filter : filters) {
+ VLOG(1) << "Name: " << filter.name;
+ VLOG(1) << "Name Prefix: " << filter.namePrefix;
+ VLOG(1) << "Services:";
VLOG(1) << "\t[";
for (const BluetoothUUID& service : filter.services)
VLOG(1) << "\t\t" << service.value();
@@ -399,20 +651,30 @@ void BluetoothDispatcherHost::OnRequestDevice(
return;
}
+ // The renderer should never send empty filters.
+ if (HasEmptyOrInvalidFilter(filters)) {
+ bad_message::ReceivedBadMessage(this,
+ bad_message::BDH_EMPTY_OR_INVALID_FILTERS);
+ return;
+ }
+
// Create storage for the information that backs the chooser, and show the
// chooser.
RequestDeviceSession* const session = new RequestDeviceSession(
- thread_id, request_id, filters, optional_services);
+ thread_id, request_id, render_frame_host->GetLastCommittedOrigin(),
+ filters, optional_services);
int chooser_id = request_device_sessions_.Add(session);
BluetoothChooser::EventHandler chooser_event_handler =
base::Bind(&BluetoothDispatcherHost::OnBluetoothChooserEvent,
- weak_ptr_factory_.GetWeakPtr(), chooser_id);
+ weak_ptr_on_ui_thread_, chooser_id);
if (WebContents* web_contents =
WebContents::FromRenderFrameHost(render_frame_host)) {
if (WebContentsDelegate* delegate = web_contents->GetDelegate()) {
session->chooser = delegate->RunBluetoothChooser(
web_contents, chooser_event_handler,
+ // TODO(ortuno): Replace with GetLastCommittedOrigin.
+ // http://crbug.com/577451
render_frame_host->GetLastCommittedURL().GetOrigin());
}
}
@@ -423,6 +685,13 @@ void BluetoothDispatcherHost::OnRequestDevice(
new FirstDeviceBluetoothChooser(chooser_event_handler));
}
+ if (!session->chooser->CanAskForScanningPermission()) {
+ VLOG(1) << "Closing immediately because Chooser cannot obtain permission.";
+ OnBluetoothChooserEvent(chooser_id,
+ BluetoothChooser::Event::DENIED_PERMISSION, "");
+ return;
+ }
+
// Populate the initial list of devices.
VLOG(1) << "Populating " << adapter_->GetDevices().size()
<< " devices in chooser " << chooser_id;
@@ -445,101 +714,122 @@ void BluetoothDispatcherHost::OnRequestDevice(
StartDeviceDiscovery(session, chooser_id);
}
-void BluetoothDispatcherHost::OnConnectGATT(
- int thread_id,
- int request_id,
- const std::string& device_instance_id) {
+void BluetoothDispatcherHost::OnConnectGATT(int thread_id,
+ int request_id,
+ int frame_routing_id,
+ const std::string& device_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT);
const base::TimeTicks start_time = base::TimeTicks::Now();
- // TODO(ortuno): Right now it's pointless to check if the domain has access to
- // the device, because any domain can connect to any device. But once
- // permissions are implemented we should check that the domain has access to
- // the device. https://crbug.com/484745
- device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id);
- if (device == nullptr) { // See "NETWORK_ERROR Note" above.
- RecordConnectGATTOutcome(UMAConnectGATTOutcome::NO_DEVICE);
- Send(new BluetoothMsg_ConnectGATTError(
- thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
+ const CacheQueryResult query_result =
+ QueryCacheForDevice(GetOrigin(frame_routing_id), device_id);
+
+ if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
+ RecordConnectGATTOutcome(query_result.outcome);
+ Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id,
+ query_result.GetWebError()));
return;
}
- device->CreateGattConnection(
+
+ query_result.device->CreateGattConnection(
base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated,
- weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
- device_instance_id, start_time),
+ weak_ptr_on_ui_thread_, thread_id, request_id, device_id,
+ start_time),
base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError,
- weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
- device_instance_id, start_time));
+ weak_ptr_on_ui_thread_, thread_id, request_id, device_id,
+ start_time));
}
void BluetoothDispatcherHost::OnGetPrimaryService(
int thread_id,
int request_id,
- const std::string& device_instance_id,
+ int frame_routing_id,
+ const std::string& device_id,
const std::string& service_uuid) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE);
RecordGetPrimaryServiceService(BluetoothUUID(service_uuid));
- // TODO(ortuno): Check if device_instance_id is in "allowed devices"
- // https://crbug.com/493459
// TODO(ortuno): Check if service_uuid is in "allowed services"
// https://crbug.com/493460
- // For now just wait a fixed time and call OnServiceDiscovered.
- // TODO(ortuno): Use callback once it's implemented http://crbug.com/484504
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&BluetoothDispatcherHost::OnServicesDiscovered,
- weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
- device_instance_id, service_uuid),
- base::TimeDelta::FromSeconds(current_delay_time_));
+
+ const CacheQueryResult query_result =
+ QueryCacheForDevice(GetOrigin(frame_routing_id), device_id);
+
+ if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
+ RecordGetPrimaryServiceOutcome(query_result.outcome);
+ Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id,
+ query_result.GetWebError()));
+ return;
+ }
+
+ // There are four possibilities here:
+ // 1. Services not discovered and service present in |device|: Send back the
+ // service to the renderer.
+ // 2. Services discovered and service present in |device|: Send back the
+ // service to the renderer.
+ // 3. Services discovered and service not present in |device|: Send back not
+ // found error.
+ // 4. Services not discovered and service not present in |device|: Add request
+ // to map of pending getPrimaryService requests.
+
+ std::vector<BluetoothGattService*> services =
+ GetPrimaryServicesByUUID(query_result.device, service_uuid);
+
+ // 1. & 2.
+ if (!services.empty()) {
+ VLOG(1) << "Service found in device.";
+ const BluetoothGattService& service = *services[0];
+ DCHECK(service.IsPrimary());
+ AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id,
+ request_id);
+ return;
+ }
+
+ // 3.
+ if (query_result.device->IsGattServicesDiscoveryComplete()) {
+ VLOG(1) << "Service not found in device.";
+ RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND);
+ Send(new BluetoothMsg_GetPrimaryServiceError(
+ thread_id, request_id, WebBluetoothError::ServiceNotFound));
+ return;
+ }
+
+ VLOG(1) << "Adding service request to pending requests.";
+ // 4.
+ AddToPendingPrimaryServicesRequest(
+ query_result.device->GetAddress(),
+ PrimaryServicesRequest(thread_id, request_id, service_uuid,
+ PrimaryServicesRequest::GET_PRIMARY_SERVICE));
}
void BluetoothDispatcherHost::OnGetCharacteristic(
int thread_id,
int request_id,
+ int frame_routing_id,
const std::string& service_instance_id,
const std::string& characteristic_uuid) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC);
RecordGetCharacteristicCharacteristic(characteristic_uuid);
- auto device_iter = service_to_device_.find(service_instance_id);
- // A service_instance_id not in the map implies a hostile renderer
- // because a renderer obtains the service id from this class and
- // it will be added to the map at that time.
- if (device_iter == service_to_device_.end()) {
- // Kill the renderer
- bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID);
- return;
- }
-
- // TODO(ortuno): Check if domain has access to device.
- // https://crbug.com/493459
- device::BluetoothDevice* device =
- adapter_->GetDevice(device_iter->second /* device_instance_id */);
+ const CacheQueryResult query_result =
+ QueryCacheForService(GetOrigin(frame_routing_id), service_instance_id);
- if (device == nullptr) { // See "NETWORK_ERROR Note" above.
- RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NO_DEVICE);
- Send(new BluetoothMsg_GetCharacteristicError(
- thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
+ if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
return;
}
- // TODO(ortuno): Check if domain has access to service
- // http://crbug.com/493460
- device::BluetoothGattService* service =
- device->GetGattService(service_instance_id);
- if (!service) {
- RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NO_SERVICE);
- Send(new BluetoothMsg_GetCharacteristicError(
- thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
+ if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
+ RecordGetCharacteristicOutcome(query_result.outcome);
+ Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id,
+ query_result.GetWebError()));
return;
}
for (BluetoothGattCharacteristic* characteristic :
- service->GetCharacteristics()) {
+ query_result.service->GetCharacteristics()) {
if (characteristic->GetUUID().canonical_value() == characteristic_uuid) {
const std::string& characteristic_instance_id =
characteristic->GetIdentifier();
@@ -555,7 +845,8 @@ void BluetoothDispatcherHost::OnGetCharacteristic(
// TODO(ortuno): Use generated instance ID instead.
// https://crbug.com/495379
Send(new BluetoothMsg_GetCharacteristicSuccess(
- thread_id, request_id, characteristic_instance_id));
+ thread_id, request_id, characteristic_instance_id,
+ static_cast<uint32_t>(characteristic->GetProperties())));
return;
}
}
@@ -567,66 +858,37 @@ void BluetoothDispatcherHost::OnGetCharacteristic(
void BluetoothDispatcherHost::OnReadValue(
int thread_id,
int request_id,
+ int frame_routing_id,
const std::string& characteristic_instance_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RecordWebBluetoothFunctionCall(
UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE);
- auto characteristic_iter =
- characteristic_to_service_.find(characteristic_instance_id);
- // A characteristic_instance_id not in the map implies a hostile renderer
- // because a renderer obtains the characteristic id from this class and
- // it will be added to the map at that time.
- if (characteristic_iter == characteristic_to_service_.end()) {
- // Kill the renderer
- bad_message::ReceivedBadMessage(this,
- bad_message::BDH_INVALID_CHARACTERISTIC_ID);
- return;
- }
- const std::string& service_instance_id = characteristic_iter->second;
+ const CacheQueryResult query_result = QueryCacheForCharacteristic(
+ GetOrigin(frame_routing_id), characteristic_instance_id);
- auto device_iter = service_to_device_.find(service_instance_id);
-
- CHECK(device_iter != service_to_device_.end());
-
- device::BluetoothDevice* device =
- adapter_->GetDevice(device_iter->second /* device_instance_id */);
- if (device == nullptr) { // See "NETWORK_ERROR Note" above.
- RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::NO_DEVICE);
- Send(new BluetoothMsg_ReadCharacteristicValueError(
- thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
+ if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
return;
}
- BluetoothGattService* service = device->GetGattService(service_instance_id);
- if (service == nullptr) {
- RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::NO_SERVICE);
+ if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
+ RecordCharacteristicReadValueOutcome(query_result.outcome);
Send(new BluetoothMsg_ReadCharacteristicValueError(
- thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
+ thread_id, request_id, query_result.GetWebError()));
return;
}
- BluetoothGattCharacteristic* characteristic =
- service->GetCharacteristic(characteristic_instance_id);
- if (characteristic == nullptr) {
- RecordCharacteristicReadValueOutcome(
- UMAGATTOperationOutcome::NO_CHARACTERISTIC);
- Send(new BluetoothMsg_ReadCharacteristicValueError(
- thread_id, request_id,
- WebBluetoothError::CharacteristicNoLongerExists));
- return;
- }
-
- characteristic->ReadRemoteCharacteristic(
+ query_result.characteristic->ReadRemoteCharacteristic(
base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead,
- weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
+ weak_ptr_on_ui_thread_, thread_id, request_id),
base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError,
- weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
+ weak_ptr_on_ui_thread_, thread_id, request_id));
}
void BluetoothDispatcherHost::OnWriteValue(
int thread_id,
int request_id,
+ int frame_routing_id,
const std::string& characteristic_instance_id,
const std::vector<uint8_t>& value) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -644,56 +906,128 @@ void BluetoothDispatcherHost::OnWriteValue(
return;
}
- auto characteristic_iter =
- characteristic_to_service_.find(characteristic_instance_id);
- // A characteristic_instance_id not in the map implies a hostile renderer
- // because a renderer obtains the characteristic id from this class and
- // it will be added to the map at that time.
- if (characteristic_iter == characteristic_to_service_.end()) {
- bad_message::ReceivedBadMessage(this,
- bad_message::BDH_INVALID_CHARACTERISTIC_ID);
+ const CacheQueryResult query_result = QueryCacheForCharacteristic(
+ GetOrigin(frame_routing_id), characteristic_instance_id);
+
+ if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
return;
}
- const std::string& service_instance_id = characteristic_iter->second;
- auto device_iter = service_to_device_.find(service_instance_id);
+ if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
+ RecordCharacteristicWriteValueOutcome(query_result.outcome);
+ Send(new BluetoothMsg_WriteCharacteristicValueError(
+ thread_id, request_id, query_result.GetWebError()));
+ return;
+ }
- CHECK(device_iter != service_to_device_.end());
+ query_result.characteristic->WriteRemoteCharacteristic(
+ value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess,
+ weak_ptr_on_ui_thread_, thread_id, request_id),
+ base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed,
+ weak_ptr_on_ui_thread_, thread_id, request_id));
+}
- device::BluetoothDevice* device =
- adapter_->GetDevice(device_iter->second /* device_instance_id */);
- if (device == nullptr) { // See "NETWORK_ERROR Note" above.
- RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::NO_DEVICE);
- Send(new BluetoothMsg_WriteCharacteristicValueError(
- thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
+void BluetoothDispatcherHost::OnStartNotifications(
+ int thread_id,
+ int request_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RecordWebBluetoothFunctionCall(
+ UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS);
+
+ // BluetoothDispatcher will never send a request for a characteristic
+ // already subscribed to notifications.
+ if (characteristic_id_to_notify_session_.find(characteristic_instance_id) !=
+ characteristic_id_to_notify_session_.end()) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED);
return;
}
- BluetoothGattService* service = device->GetGattService(service_instance_id);
- if (service == nullptr) {
- RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::NO_SERVICE);
- Send(new BluetoothMsg_WriteCharacteristicValueError(
- thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
+ // TODO(ortuno): Check if notify/indicate bit is set.
+ // http://crbug.com/538869
+
+ const CacheQueryResult query_result = QueryCacheForCharacteristic(
+ GetOrigin(frame_routing_id), characteristic_instance_id);
+
+ if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
return;
}
- BluetoothGattCharacteristic* characteristic =
- service->GetCharacteristic(characteristic_instance_id);
- if (characteristic == nullptr) {
- RecordCharacteristicWriteValueOutcome(
- UMAGATTOperationOutcome::NO_CHARACTERISTIC);
- Send(new BluetoothMsg_WriteCharacteristicValueError(
- thread_id, request_id,
- WebBluetoothError::CharacteristicNoLongerExists));
+ if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
+ RecordStartNotificationsOutcome(query_result.outcome);
+ Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id,
+ query_result.GetWebError()));
return;
}
- characteristic->WriteRemoteCharacteristic(
- value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess,
- weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
- base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed,
+
+ query_result.characteristic->StartNotifySession(
+ base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess,
+ weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
+ base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed,
weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
}
+void BluetoothDispatcherHost::OnStopNotifications(
+ int thread_id,
+ int request_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RecordWebBluetoothFunctionCall(
+ UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS);
+
+ // Check the origin is allowed to access the device. We perform this check in
+ // case a hostile renderer is trying to stop notifications for a device
+ // that the renderer is not allowed to access.
+ if (!CanFrameAccessCharacteristicInstance(frame_routing_id,
+ characteristic_instance_id)) {
+ return;
+ }
+
+ auto notify_session_iter =
+ characteristic_id_to_notify_session_.find(characteristic_instance_id);
+ if (notify_session_iter == characteristic_id_to_notify_session_.end()) {
+ Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
+ return;
+ }
+ notify_session_iter->second->Stop(
+ base::Bind(&BluetoothDispatcherHost::OnStopNotifySession,
+ weak_ptr_factory_.GetWeakPtr(), thread_id, request_id,
+ characteristic_instance_id));
+}
+
+void BluetoothDispatcherHost::OnRegisterCharacteristicObject(
+ int thread_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Make sure the origin is allowed to access the device.
+ if (!CanFrameAccessCharacteristicInstance(frame_routing_id,
+ characteristic_instance_id)) {
+ return;
+ }
+ active_characteristic_threads_[characteristic_instance_id].insert(thread_id);
+}
+
+void BluetoothDispatcherHost::OnUnregisterCharacteristicObject(
+ int thread_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto active_iter =
+ active_characteristic_threads_.find(characteristic_instance_id);
+ if (active_iter == active_characteristic_threads_.end()) {
+ return;
+ }
+ std::set<int>& thread_ids_set = active_iter->second;
+ thread_ids_set.erase(thread_id);
+ if (thread_ids_set.empty()) {
+ active_characteristic_threads_.erase(active_iter);
+ }
+}
+
void BluetoothDispatcherHost::OnDiscoverySessionStarted(
int chooser_id,
scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
@@ -701,14 +1035,14 @@ void BluetoothDispatcherHost::OnDiscoverySessionStarted(
VLOG(1) << "Started discovery session for " << chooser_id;
if (RequestDeviceSession* session =
request_device_sessions_.Lookup(chooser_id)) {
- session->discovery_session = discovery_session.Pass();
+ session->discovery_session = std::move(discovery_session);
// Arrange to stop discovery later.
discovery_session_timer_.Reset();
} else {
VLOG(1) << "Chooser " << chooser_id
<< " was closed before the session finished starting. Stopping.";
- StopDiscoverySession(discovery_session.Pass());
+ StopDiscoverySession(std::move(discovery_session));
}
}
@@ -730,6 +1064,7 @@ void BluetoothDispatcherHost::OnBluetoothChooserEvent(
int chooser_id,
BluetoothChooser::Event event,
const std::string& device_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
RequestDeviceSession* session = request_device_sessions_.Lookup(chooser_id);
DCHECK(session) << "Shouldn't receive an event (" << static_cast<int>(event)
<< ") from a closed chooser.";
@@ -740,6 +1075,7 @@ void BluetoothDispatcherHost::OnBluetoothChooserEvent(
case BluetoothChooser::Event::RESCAN:
StartDeviceDiscovery(session, chooser_id);
break;
+ case BluetoothChooser::Event::DENIED_PERMISSION:
case BluetoothChooser::Event::CANCELLED:
case BluetoothChooser::Event::SELECTED: {
// Synchronously ensure nothing else calls into the chooser after it has
@@ -751,7 +1087,7 @@ void BluetoothDispatcherHost::OnBluetoothChooserEvent(
if (!base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&BluetoothDispatcherHost::FinishClosingChooser,
- weak_ptr_factory_.GetWeakPtr(), chooser_id, event,
+ weak_ptr_on_ui_thread_, chooser_id, event,
device_id))) {
LOG(WARNING) << "No TaskRunner; not closing requestDevice dialog.";
}
@@ -766,6 +1102,9 @@ void BluetoothDispatcherHost::OnBluetoothChooserEvent(
case BluetoothChooser::Event::SHOW_ADAPTER_OFF_HELP:
ShowBluetoothAdapterOffLink();
break;
+ case BluetoothChooser::Event::SHOW_NEED_LOCATION_HELP:
+ ShowNeedLocationLink();
+ break;
}
}
@@ -773,6 +1112,7 @@ void BluetoothDispatcherHost::FinishClosingChooser(
int chooser_id,
BluetoothChooser::Event event,
const std::string& device_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
RequestDeviceSession* session = request_device_sessions_.Lookup(chooser_id);
DCHECK(session) << "Session removed unexpectedly.";
@@ -786,9 +1126,21 @@ void BluetoothDispatcherHost::FinishClosingChooser(
request_device_sessions_.Remove(chooser_id);
return;
}
+ if (event == BluetoothChooser::Event::DENIED_PERMISSION) {
+ RecordRequestDeviceOutcome(
+ UMARequestDeviceOutcome::BLUETOOTH_CHOOSER_DENIED_PERMISSION);
+ VLOG(1) << "Bluetooth chooser denied permission";
+ Send(new BluetoothMsg_RequestDeviceError(
+ session->thread_id, session->request_id,
+ WebBluetoothError::ChooserDeniedPermission));
+ request_device_sessions_.Remove(chooser_id);
+ return;
+ }
DCHECK_EQ(static_cast<int>(event),
static_cast<int>(BluetoothChooser::Event::SELECTED));
+ // |device_id| is the Device Address that RequestDeviceSession passed to
+ // chooser->AddDevice().
const device::BluetoothDevice* const device = adapter_->GetDevice(device_id);
if (device == nullptr) {
VLOG(1) << "Device " << device_id << " no longer in adapter";
@@ -805,15 +1157,22 @@ void BluetoothDispatcherHost::FinishClosingChooser(
for (BluetoothUUID uuid : device->GetUUIDs())
VLOG(1) << "\t" << uuid.canonical_value();
+ const std::string& device_id_for_origin = allowed_devices_map_.AddDevice(
+ session->origin, device->GetAddress(), session->filters,
+ session->optional_services);
+
content::BluetoothDevice device_ipc(
- device->GetAddress(), // instance_id
- device->GetName(), // name
- device->GetBluetoothClass(), // device_class
- device->GetVendorIDSource(), // vendor_id_source
- device->GetVendorID(), // vendor_id
- device->GetProductID(), // product_id
- device->GetDeviceID(), // product_version
- device->IsPaired(), // paired
+ device_id_for_origin, // id
+ device->GetName(), // name
+ content::BluetoothDevice::ValidatePower(
+ device->GetInquiryTxPower()), // tx_power
+ content::BluetoothDevice::ValidatePower(
+ device->GetInquiryRSSI()), // rssi
+ device->GetBluetoothClass(), // device_class
+ device->GetVendorIDSource(), // vendor_id_source
+ device->GetVendorID(), // vendor_id
+ device->GetProductID(), // product_id
+ device->GetDeviceID(), // product_version
content::BluetoothDevice::UUIDsFromBluetoothUUIDs(
device->GetUUIDs())); // uuids
RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS);
@@ -825,23 +1184,23 @@ void BluetoothDispatcherHost::FinishClosingChooser(
void BluetoothDispatcherHost::OnGATTConnectionCreated(
int thread_id,
int request_id,
- const std::string& device_instance_id,
+ const std::string& device_id,
base::TimeTicks start_time,
scoped_ptr<device::BluetoothGattConnection> connection) {
- // TODO(ortuno): Save the BluetoothGattConnection so we can disconnect
- // from it.
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ connections_.push_back(std::move(connection));
RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time);
RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS);
- Send(new BluetoothMsg_ConnectGATTSuccess(thread_id, request_id,
- device_instance_id));
+ Send(new BluetoothMsg_ConnectGATTSuccess(thread_id, request_id, device_id));
}
void BluetoothDispatcherHost::OnCreateGATTConnectionError(
int thread_id,
int request_id,
- const std::string& device_instance_id,
+ const std::string& device_id,
base::TimeTicks start_time,
device::BluetoothDevice::ConnectErrorCode error_code) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// There was an error creating the ATT Bearer so we reject with
// NetworkError.
// https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-connectgatt
@@ -851,52 +1210,29 @@ void BluetoothDispatcherHost::OnCreateGATTConnectionError(
TranslateConnectError(error_code)));
}
-void BluetoothDispatcherHost::OnServicesDiscovered(
+void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess(
+ const device::BluetoothGattService& service,
int thread_id,
- int request_id,
- const std::string& device_instance_id,
- const std::string& service_uuid) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id);
- if (device == nullptr) { // See "NETWORK_ERROR Note" above.
- RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NO_DEVICE);
- Send(new BluetoothMsg_GetPrimaryServiceError(
- thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
- return;
- }
-
- VLOG(1) << "Looking for service: " << service_uuid;
- for (BluetoothGattService* service : device->GetGattServices()) {
- VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value();
- if (service->GetUUID().canonical_value() == service_uuid) {
- // TODO(ortuno): Use generated instance ID instead.
- // https://crbug.com/495379
- const std::string& service_identifier = service->GetIdentifier();
- auto insert_result = service_to_device_.insert(
- make_pair(service_identifier, device_instance_id));
-
- // If a value is already in map, DCHECK it's valid.
- if (!insert_result.second)
- DCHECK(insert_result.first->second == device_instance_id);
-
- RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS);
- Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id,
- service_identifier));
- return;
- }
- }
-
- VLOG(1) << "No service found";
- RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND);
- Send(new BluetoothMsg_GetPrimaryServiceError(
- thread_id, request_id, WebBluetoothError::ServiceNotFound));
+ int request_id) {
+ const std::string& service_identifier = service.GetIdentifier();
+ const std::string& device_address = service.GetDevice()->GetAddress();
+ auto insert_result =
+ service_to_device_.insert(make_pair(service_identifier, device_address));
+
+ // If a value is already in map, DCHECK it's valid.
+ if (!insert_result.second)
+ DCHECK_EQ(insert_result.first->second, device_address);
+
+ RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS);
+ Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id,
+ service_identifier));
}
void BluetoothDispatcherHost::OnCharacteristicValueRead(
int thread_id,
int request_id,
- const std::vector<uint8>& value) {
+ const std::vector<uint8_t>& value) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::SUCCESS);
Send(new BluetoothMsg_ReadCharacteristicValueSuccess(thread_id, request_id,
value));
@@ -906,6 +1242,7 @@ void BluetoothDispatcherHost::OnCharacteristicReadValueError(
int thread_id,
int request_id,
device::BluetoothGattService::GattErrorCode error_code) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// TranslateGATTError calls RecordGATTOperationOutcome.
Send(new BluetoothMsg_ReadCharacteristicValueError(
thread_id, request_id,
@@ -914,6 +1251,7 @@ void BluetoothDispatcherHost::OnCharacteristicReadValueError(
void BluetoothDispatcherHost::OnWriteValueSuccess(int thread_id,
int request_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::SUCCESS);
Send(new BluetoothMsg_WriteCharacteristicValueSuccess(thread_id, request_id));
}
@@ -922,21 +1260,171 @@ void BluetoothDispatcherHost::OnWriteValueFailed(
int thread_id,
int request_id,
device::BluetoothGattService::GattErrorCode error_code) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// TranslateGATTError calls RecordGATTOperationOutcome.
Send(new BluetoothMsg_WriteCharacteristicValueError(
thread_id, request_id,
TranslateGATTError(error_code, UMAGATTOperation::CHARACTERISTIC_WRITE)));
}
+void BluetoothDispatcherHost::OnStartNotifySessionSuccess(
+ int thread_id,
+ int request_id,
+ scoped_ptr<device::BluetoothGattNotifySession> notify_session) {
+ RecordStartNotificationsOutcome(UMAGATTOperationOutcome::SUCCESS);
+
+ // Copy Characteristic Instance ID before passing scoped pointer because
+ // compilers may evaluate arguments in any order.
+ const std::string characteristic_instance_id =
+ notify_session->GetCharacteristicIdentifier();
+ characteristic_id_to_notify_session_.insert(
+ std::make_pair(characteristic_instance_id, std::move(notify_session)));
+
+ Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id));
+}
+
+void BluetoothDispatcherHost::OnStartNotifySessionFailed(
+ int thread_id,
+ int request_id,
+ device::BluetoothGattService::GattErrorCode error_code) {
+ // TranslateGATTError calls RecordGATTOperationOutcome.
+ Send(new BluetoothMsg_StartNotificationsError(
+ thread_id, request_id,
+ TranslateGATTError(error_code, UMAGATTOperation::START_NOTIFICATIONS)));
+}
+
+void BluetoothDispatcherHost::OnStopNotifySession(
+ int thread_id,
+ int request_id,
+ const std::string& characteristic_instance_id) {
+ characteristic_id_to_notify_session_.erase(characteristic_instance_id);
+ Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
+}
+
+BluetoothDispatcherHost::CacheQueryResult
+BluetoothDispatcherHost::QueryCacheForDevice(const url::Origin& origin,
+ const std::string& device_id) {
+ const std::string& device_address =
+ allowed_devices_map_.GetDeviceAddress(origin, device_id);
+ if (device_address.empty()) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
+ return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
+ }
+
+ CacheQueryResult result;
+ result.device = adapter_->GetDevice(device_address);
+
+ // When a device can't be found in the BluetoothAdapter, that generally
+ // indicates that it's gone out of range. We reject with a NetworkError in
+ // that case.
+ // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-connectgatt
+ if (result.device == nullptr) {
+ result.outcome = CacheQueryOutcome::NO_DEVICE;
+ }
+ return result;
+}
+
+BluetoothDispatcherHost::CacheQueryResult
+BluetoothDispatcherHost::QueryCacheForService(
+ const url::Origin& origin,
+ const std::string& service_instance_id) {
+ auto device_iter = service_to_device_.find(service_instance_id);
+
+ // Kill the renderer, see "ID Not In Map Note" above.
+ if (device_iter == service_to_device_.end()) {
+ bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID);
+ return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
+ }
+
+ const std::string& device_id =
+ allowed_devices_map_.GetDeviceId(origin, device_iter->second);
+ // Kill the renderer if the origin is not allowed to access the device.
+ if (device_id.empty()) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
+ return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
+ }
+
+ CacheQueryResult result = QueryCacheForDevice(origin, device_id);
+
+ if (result.outcome != CacheQueryOutcome::SUCCESS) {
+ return result;
+ }
+
+ result.service = result.device->GetGattService(service_instance_id);
+ if (result.service == nullptr) {
+ result.outcome = CacheQueryOutcome::NO_SERVICE;
+ }
+ return result;
+}
+
+BluetoothDispatcherHost::CacheQueryResult
+BluetoothDispatcherHost::QueryCacheForCharacteristic(
+ const url::Origin& origin,
+ const std::string& characteristic_instance_id) {
+ auto characteristic_iter =
+ characteristic_to_service_.find(characteristic_instance_id);
+
+ // Kill the renderer, see "ID Not In Map Note" above.
+ if (characteristic_iter == characteristic_to_service_.end()) {
+ bad_message::ReceivedBadMessage(this,
+ bad_message::BDH_INVALID_CHARACTERISTIC_ID);
+ return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
+ }
+
+ CacheQueryResult result =
+ QueryCacheForService(origin, characteristic_iter->second);
+ if (result.outcome != CacheQueryOutcome::SUCCESS) {
+ return result;
+ }
+
+ result.characteristic =
+ result.service->GetCharacteristic(characteristic_instance_id);
+
+ if (result.characteristic == nullptr) {
+ result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC;
+ }
+
+ return result;
+}
+
+void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest(
+ const std::string& device_address,
+ const PrimaryServicesRequest& request) {
+ pending_primary_services_requests_[device_address].push_back(request);
+}
+
+url::Origin BluetoothDispatcherHost::GetOrigin(int frame_routing_id) {
+ return RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id)
+ ->GetLastCommittedOrigin();
+}
+
+bool BluetoothDispatcherHost::CanFrameAccessCharacteristicInstance(
+ int frame_routing_id,
+ const std::string& characteristic_instance_id) {
+ return QueryCacheForCharacteristic(GetOrigin(frame_routing_id),
+ characteristic_instance_id)
+ .outcome != CacheQueryOutcome::BAD_RENDERER;
+}
+
void BluetoothDispatcherHost::ShowBluetoothOverviewLink() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
NOTIMPLEMENTED();
}
void BluetoothDispatcherHost::ShowBluetoothPairingLink() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
NOTIMPLEMENTED();
}
void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ NOTIMPLEMENTED();
+}
+
+void BluetoothDispatcherHost::ShowNeedLocationLink() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
NOTIMPLEMENTED();
}
diff --git a/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.h b/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.h
index cc6cd9d5cb2..7bae29ca931 100644
--- a/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.h
+++ b/chromium/content/browser/bluetooth/bluetooth_dispatcher_host.h
@@ -5,13 +5,20 @@
#ifndef CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_DISPATCHER_HOST_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <map>
+
#include "base/id_map.h"
+#include "base/macros.h"
+#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
+#include "content/browser/bluetooth/bluetooth_allowed_devices_map.h"
#include "content/public/browser/bluetooth_chooser.h"
#include "content/public/browser/browser_message_filter.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_gatt_connection.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session.h"
#include "device/bluetooth/bluetooth_gatt_service.h"
namespace device {
@@ -53,7 +60,9 @@ class CONTENT_EXPORT BluetoothDispatcherHost final
friend class base::DeleteHelper<BluetoothDispatcherHost>;
friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
+ struct CacheQueryResult;
struct RequestDeviceSession;
+ struct PrimaryServicesRequest;
// Set |adapter_| to a BluetoothAdapter instance and register observers,
// releasing references to previous |adapter_|.
@@ -74,6 +83,18 @@ class CONTENT_EXPORT BluetoothDispatcherHost final
device::BluetoothDevice* device) override;
void DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
+ void GattServicesDiscovered(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) override;
+ void GattCharacteristicValueChanged(
+ device::BluetoothAdapter* adapter,
+ device::BluetoothGattCharacteristic* characteristic,
+ const std::vector<uint8_t>& value) override;
+
+ // Sends an IPC to the thread informing that a the characteristic's
+ // value changed.
+ void NotifyActiveCharacteristic(int thread_id,
+ const std::string& characteristic_instance_id,
+ const std::vector<uint8_t>& value);
// IPC Handlers, see definitions in bluetooth_messages.h.
void OnRequestDevice(
@@ -82,23 +103,45 @@ class CONTENT_EXPORT BluetoothDispatcherHost final
int frame_routing_id,
const std::vector<content::BluetoothScanFilter>& filters,
const std::vector<device::BluetoothUUID>& optional_services);
- void OnConnectGATT(int thread_id, int request_id,
- const std::string& device_instance_id);
+ void OnConnectGATT(int thread_id,
+ int request_id,
+ int frame_routing_id,
+ const std::string& device_id);
void OnGetPrimaryService(int thread_id,
int request_id,
- const std::string& device_instance_id,
+ int frame_routing_id,
+ const std::string& device_id,
const std::string& service_uuid);
void OnGetCharacteristic(int thread_id,
int request_id,
+ int frame_routing_id,
const std::string& service_instance_id,
const std::string& characteristic_uuid);
void OnReadValue(int thread_id,
int request_id,
+ int frame_routing_id,
const std::string& characteristic_instance_id);
void OnWriteValue(int thread_id,
int request_id,
+ int frame_routing_id,
const std::string& characteristic_instance_id,
const std::vector<uint8_t>& value);
+ void OnStartNotifications(int thread_id,
+ int request_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id);
+ void OnStopNotifications(int thread_id,
+ int request_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id);
+ void OnRegisterCharacteristicObject(
+ int thread_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id);
+ void OnUnregisterCharacteristicObject(
+ int thread_id,
+ int frame_routing_id,
+ const std::string& characteristic_instance_id);
// Callbacks for BluetoothAdapter::StartDiscoverySession.
void OnDiscoverySessionStarted(
@@ -122,28 +165,27 @@ class CONTENT_EXPORT BluetoothDispatcherHost final
void OnGATTConnectionCreated(
int thread_id,
int request_id,
- const std::string& device_instance_id,
+ const std::string& device_id,
base::TimeTicks start_time,
scoped_ptr<device::BluetoothGattConnection> connection);
void OnCreateGATTConnectionError(
int thread_id,
int request_id,
- const std::string& device_instance_id,
+ const std::string& device_id,
base::TimeTicks start_time,
device::BluetoothDevice::ConnectErrorCode error_code);
- // Callback for future BluetoothAdapter::ServicesDiscovered callback:
- // For now we just post a delayed task.
- // See: https://crbug.com/484504
- void OnServicesDiscovered(int thread_id,
- int request_id,
- const std::string& device_instance_id,
- const std::string& service_uuid);
+ // Adds the service to the map of services' instance ids to devices' instance
+ // ids and sends the service to the renderer.
+ void AddToServicesMapAndSendGetPrimaryServiceSuccess(
+ const device::BluetoothGattService& service,
+ int thread_id,
+ int request_id);
// Callbacks for BluetoothGattCharacteristic::ReadRemoteCharacteristic.
void OnCharacteristicValueRead(int thread_id,
int request_id,
- const std::vector<uint8>& value);
+ const std::vector<uint8_t>& value);
void OnCharacteristicReadValueError(
int thread_id,
int request_id,
@@ -155,10 +197,65 @@ class CONTENT_EXPORT BluetoothDispatcherHost final
int request_id,
device::BluetoothGattService::GattErrorCode);
+ // Callbacks for BluetoothGattCharacteristic::StartNotifySession.
+ void OnStartNotifySessionSuccess(
+ int thread_id,
+ int request_id,
+ scoped_ptr<device::BluetoothGattNotifySession> notify_session);
+ void OnStartNotifySessionFailed(
+ int thread_id,
+ int request_id,
+ device::BluetoothGattService::GattErrorCode error_code);
+
+ // Callback for BluetoothGattNotifySession::Stop.
+ void OnStopNotifySession(int thread_id,
+ int request_id,
+ const std::string& characteristic_instance_id);
+
+ // Functions to query the platform cache for the bluetooth object.
+ // result.outcome == CacheQueryOutcome::SUCCESS if the object was found in the
+ // cache. Otherwise result.outcome that can used to record the outcome and
+ // result.error will contain the error that should be send to the renderer.
+ // One of the possible outcomes is BAD_RENDERER. In this case the outcome
+ // was already recorded and since there renderer crashed there is no need to
+ // send a response.
+
+ // Queries the platform cache for a Device with |device_id| for |origin|.
+ // Fills in the |outcome| field and the |device| field if successful.
+ CacheQueryResult QueryCacheForDevice(const url::Origin& origin,
+ const std::string& device_id);
+ // Queries the platform cache for a Service with |service_instance_id|. Fills
+ // in the |outcome| field, and |device| and |service| fields if successful.
+ CacheQueryResult QueryCacheForService(const url::Origin& origin,
+ const std::string& service_instance_id);
+ // Queries the platform cache for a characteristic with
+ // |characteristic_instance_id|. Fills in the |outcome| field, and |device|,
+ // |service| and |characteristic| fields if successful.
+ CacheQueryResult QueryCacheForCharacteristic(
+ const url::Origin& origin,
+ const std::string& characteristic_instance_id);
+
+ // Adds the PrimaryServicesRequest to the vector of pending services requests
+ // for that device.
+ void AddToPendingPrimaryServicesRequest(
+ const std::string& device_address,
+ const PrimaryServicesRequest& request);
+
+ // Returns the origin for the frame with "frame_routing_id" in
+ // render_process_id_.
+ url::Origin GetOrigin(int frame_routing_id);
+
+ // Returns true if the frame has permission to access the characteristic
+ // with |characteristic_instance_id|.
+ bool CanFrameAccessCharacteristicInstance(
+ int frame_routing_id,
+ const std::string& characteristic_instance_id);
+
// Show help pages from the chooser dialog.
void ShowBluetoothOverviewLink();
void ShowBluetoothPairingLink();
void ShowBluetoothAdapterOffLink();
+ void ShowNeedLocationLink();
int render_process_id_;
@@ -168,12 +265,25 @@ class CONTENT_EXPORT BluetoothDispatcherHost final
// again everywhere a requestDevice() reply is sent.
IDMap<RequestDeviceSession, IDMapOwnPointer> request_device_sessions_;
+ BluetoothAllowedDevicesMap allowed_devices_map_;
+
// Maps to get the object's parent based on it's instanceID
- // Map of service_instance_id to device_instance_id.
+ // Map of service_instance_id to device_address.
std::map<std::string, std::string> service_to_device_;
// Map of characteristic_instance_id to service_instance_id.
std::map<std::string, std::string> characteristic_to_service_;
+ // Map that matches characteristic_instance_id to notify session.
+ // TODO(ortuno): Also key by thread_id once support for web workers,
+ // is added: http://crbug.com/537372
+ std::map<std::string, scoped_ptr<device::BluetoothGattNotifySession>>
+ characteristic_id_to_notify_session_;
+
+ // Map of characteristic_instance_id to a set of thread ids.
+ // A thread_id in the set represents a BluetoothDispatcher that
+ // needs to be notified of changes to the characteristic.
+ std::map<std::string, std::set<int>> active_characteristic_threads_;
+
// Defines how long to scan for and how long to discover services for.
int current_delay_time_;
@@ -187,7 +297,19 @@ class CONTENT_EXPORT BluetoothDispatcherHost final
// sessions when other sessions are active.
base::Timer discovery_session_timer_;
- // Must be last member, see base/memory/weak_ptr.h documentation
+ // Retain BluetoothGattConnection objects to keep connections open.
+ // TODO(scheib): Destroy as connections are closed. http://crbug.com/539643
+ ScopedVector<device::BluetoothGattConnection> connections_;
+
+ // Map of device_address's to primary-services requests that need responses
+ // when that device's service discovery completes.
+ std::map<std::string, std::vector<PrimaryServicesRequest>>
+ pending_primary_services_requests_;
+
+ // |weak_ptr_on_ui_thread_| provides weak pointers, e.g. for callbacks, and
+ // because it exists and has been bound to the UI thread enforces that all
+ // copies verify they are also used on the UI thread.
+ base::WeakPtr<BluetoothDispatcherHost> weak_ptr_on_ui_thread_;
base::WeakPtrFactory<BluetoothDispatcherHost> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothDispatcherHost);
diff --git a/chromium/content/browser/bluetooth/bluetooth_metrics.cc b/chromium/content/browser/bluetooth/bluetooth_metrics.cc
index e04a7cab0ea..ef829203bba 100644
--- a/chromium/content/browser/bluetooth/bluetooth_metrics.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_metrics.cc
@@ -4,6 +4,8 @@
#include "content/browser/bluetooth/bluetooth_metrics.h"
+#include <stdint.h>
+
#include <map>
#include <set>
#include "base/hash.h"
@@ -18,7 +20,7 @@ namespace {
// TODO(ortuno): Remove once we have a macro to histogram strings.
// http://crbug.com/520284
int HashUUID(const std::string& uuid) {
- uint32 data = base::SuperFastHash(uuid.data(), uuid.size());
+ uint32_t data = base::SuperFastHash(uuid.data(), uuid.size());
// Strip off the signed bit because UMA doesn't support negative values,
// but takes a signed int as input.
@@ -103,6 +105,11 @@ void RecordConnectGATTOutcome(UMAConnectGATTOutcome outcome) {
static_cast<int>(UMAConnectGATTOutcome::COUNT));
}
+void RecordConnectGATTOutcome(CacheQueryOutcome outcome) {
+ DCHECK(outcome == CacheQueryOutcome::NO_DEVICE);
+ RecordConnectGATTOutcome(UMAConnectGATTOutcome::NO_DEVICE);
+}
+
void RecordConnectGATTTimeSuccess(const base::TimeDelta& duration) {
UMA_HISTOGRAM_MEDIUM_TIMES("Bluetooth.Web.ConnectGATT.TimeSuccess", duration);
}
@@ -126,6 +133,11 @@ void RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome outcome) {
static_cast<int>(UMAGetPrimaryServiceOutcome::COUNT));
}
+void RecordGetPrimaryServiceOutcome(CacheQueryOutcome outcome) {
+ DCHECK(outcome == CacheQueryOutcome::NO_DEVICE);
+ RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NO_DEVICE);
+}
+
// getCharacteristic
void RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome outcome) {
@@ -134,6 +146,24 @@ void RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome outcome) {
static_cast<int>(UMAGetCharacteristicOutcome::COUNT));
}
+void RecordGetCharacteristicOutcome(CacheQueryOutcome outcome) {
+ switch (outcome) {
+ case CacheQueryOutcome::SUCCESS:
+ case CacheQueryOutcome::BAD_RENDERER:
+ NOTREACHED() << "No need to record a success or renderer crash";
+ return;
+ case CacheQueryOutcome::NO_DEVICE:
+ RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NO_DEVICE);
+ return;
+ case CacheQueryOutcome::NO_SERVICE:
+ RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NO_SERVICE);
+ return;
+ case CacheQueryOutcome::NO_CHARACTERISTIC:
+ NOTREACHED();
+ return;
+ }
+}
+
void RecordGetCharacteristicCharacteristic(const std::string& characteristic) {
UMA_HISTOGRAM_SPARSE_SLOWLY("Bluetooth.Web.GetCharacteristic.Characteristic",
HashUUID(characteristic));
@@ -150,6 +180,9 @@ void RecordGATTOperationOutcome(UMAGATTOperation operation,
case UMAGATTOperation::CHARACTERISTIC_WRITE:
RecordCharacteristicWriteValueOutcome(outcome);
return;
+ case UMAGATTOperation::START_NOTIFICATIONS:
+ RecordStartNotificationsOutcome(outcome);
+ return;
case UMAGATTOperation::COUNT:
NOTREACHED();
return;
@@ -157,6 +190,24 @@ void RecordGATTOperationOutcome(UMAGATTOperation operation,
NOTREACHED();
}
+static UMAGATTOperationOutcome TranslateCacheQueryOutcomeToGATTOperationOutcome(
+ CacheQueryOutcome outcome) {
+ switch (outcome) {
+ case CacheQueryOutcome::SUCCESS:
+ case CacheQueryOutcome::BAD_RENDERER:
+ NOTREACHED() << "No need to record success or renderer crash";
+ return UMAGATTOperationOutcome::NOT_SUPPORTED;
+ case CacheQueryOutcome::NO_DEVICE:
+ return UMAGATTOperationOutcome::NO_DEVICE;
+ case CacheQueryOutcome::NO_SERVICE:
+ return UMAGATTOperationOutcome::NO_SERVICE;
+ case CacheQueryOutcome::NO_CHARACTERISTIC:
+ return UMAGATTOperationOutcome::NO_CHARACTERISTIC;
+ }
+ NOTREACHED() << "No need to record success or renderer crash";
+ return UMAGATTOperationOutcome::NOT_SUPPORTED;
+}
+
// Characteristic.readValue
// static
@@ -166,6 +217,11 @@ void RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome outcome) {
static_cast<int>(UMAGATTOperationOutcome::COUNT));
}
+void RecordCharacteristicReadValueOutcome(CacheQueryOutcome outcome) {
+ RecordCharacteristicReadValueOutcome(
+ TranslateCacheQueryOutcomeToGATTOperationOutcome(outcome));
+}
+
// Characteristic.writeValue
void RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome outcome) {
@@ -174,4 +230,22 @@ void RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome outcome) {
static_cast<int>(UMAGATTOperationOutcome::COUNT));
}
+void RecordCharacteristicWriteValueOutcome(CacheQueryOutcome outcome) {
+ RecordCharacteristicWriteValueOutcome(
+ TranslateCacheQueryOutcomeToGATTOperationOutcome(outcome));
+}
+
+// Characteristic.startNotifications
+void RecordStartNotificationsOutcome(UMAGATTOperationOutcome outcome) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Bluetooth.Web.Characteristic.StartNotifications.Outcome",
+ static_cast<int>(outcome),
+ static_cast<int>(UMAGATTOperationOutcome::COUNT));
+}
+
+void RecordStartNotificationsOutcome(CacheQueryOutcome outcome) {
+ RecordStartNotificationsOutcome(
+ TranslateCacheQueryOutcomeToGATTOperationOutcome(outcome));
+}
+
} // namespace content
diff --git a/chromium/content/browser/bluetooth/bluetooth_metrics.h b/chromium/content/browser/bluetooth/bluetooth_metrics.h
index fb1a282d351..fa508590177 100644
--- a/chromium/content/browser/bluetooth/bluetooth_metrics.h
+++ b/chromium/content/browser/bluetooth/bluetooth_metrics.h
@@ -29,6 +29,8 @@ enum class UMAWebBluetoothFunction {
GET_CHARACTERISTIC = 3,
CHARACTERISTIC_READ_VALUE = 4,
CHARACTERISTIC_WRITE_VALUE = 5,
+ CHARACTERISTIC_START_NOTIFICATIONS = 6,
+ CHARACTERISTIC_STOP_NOTIFICATIONS = 7,
// NOTE: Add new actions immediately above this line. Make sure to update
// the enum list in tools/metrics/histograms/histograms.xml accordingly.
COUNT
@@ -38,6 +40,15 @@ enum class UMAWebBluetoothFunction {
// API.
void RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction function);
+// Enumation for outcomes of querying the bluetooth cache.
+enum class CacheQueryOutcome {
+ SUCCESS = 0,
+ BAD_RENDERER = 1,
+ NO_DEVICE = 2,
+ NO_SERVICE = 3,
+ NO_CHARACTERISTIC = 4,
+};
+
// requestDevice() Metrics
enum class UMARequestDeviceOutcome {
SUCCESS = 0,
@@ -50,6 +61,7 @@ enum class UMARequestDeviceOutcome {
OBSOLETE_BLUETOOTH_ADAPTER_OFF = 7,
CHOSEN_DEVICE_VANISHED = 8,
BLUETOOTH_CHOOSER_CANCELLED = 9,
+ BLUETOOTH_CHOOSER_DENIED_PERMISSION = 10,
// NOTE: Add new requestDevice() outcomes immediately above this line. Make
// sure to update the enum list in
// tools/metrics/histograms/histograms.xml accordingly.
@@ -83,6 +95,13 @@ enum class UMAConnectGATTOutcome {
AUTH_REJECTED = 7,
AUTH_TIMEOUT = 8,
UNSUPPORTED_DEVICE = 9,
+ ATTRIBUTE_LENGTH_INVALID = 10,
+ CONNECTION_CONGESTED = 11,
+ INSUFFICIENT_ENCRYPTION = 12,
+ OFFSET_INVALID = 13,
+ READ_NOT_PERMITTED = 14,
+ REQUEST_NOT_SUPPORTED = 15,
+ WRITE_NOT_PERMITTED = 16,
// Note: Add new ConnectGATT outcomes immediately above this line. Make sure
// to update the enum list in tools/metrics/histograms/histograms.xml
// accordingly.
@@ -92,6 +111,9 @@ enum class UMAConnectGATTOutcome {
// Send(BluetoothMsg_ConnectGATTSuccess) and
// Send(BluetoothMsg_ConnectGATTError).
void RecordConnectGATTOutcome(UMAConnectGATTOutcome outcome);
+// Records the outcome of the cache query for connectGATT. Should only be called
+// if QueryCacheForDevice fails.
+void RecordConnectGATTOutcome(CacheQueryOutcome outcome);
// Records how long it took for the connection to succeed.
void RecordConnectGATTTimeSuccess(const base::TimeDelta& duration);
// Records how long it took for the connection to fail.
@@ -113,6 +135,9 @@ void RecordGetPrimaryServiceService(const device::BluetoothUUID& service);
// Send(BluetoothMsg_GetPrimaryServiceSuccess) and
// Send(BluetoothMsg_GetPrimaryServiceError).
void RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome outcome);
+// Records the outcome of the cache query for getPrimaryService. Should only be
+// called if QueryCacheForDevice fails.
+void RecordGetPrimaryServiceOutcome(CacheQueryOutcome outcome);
// getCharacteristic() Metrics
enum class UMAGetCharacteristicOutcome {
@@ -129,6 +154,9 @@ enum class UMAGetCharacteristicOutcome {
// Send(BluetoothMsg_GetCharacteristicSuccess) and
// Send(BluetoothMsg_GetCharacteristicError).
void RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome outcome);
+// Records the outcome of the cache query for getCharacteristic. Should only be
+// called if QueryCacheForService fails.
+void RecordGetCharacteristicOutcome(CacheQueryOutcome outcome);
// Records the UUID of the characteristic used when calling getCharacteristic.
void RecordGetCharacteristicCharacteristic(const std::string& characteristic);
@@ -159,6 +187,7 @@ enum UMAGATTOperationOutcome {
enum class UMAGATTOperation {
CHARACTERISTIC_READ,
CHARACTERISTIC_WRITE,
+ START_NOTIFICATIONS,
// Note: Add new GATT Operations immediately above this line.
COUNT
};
@@ -174,12 +203,27 @@ void RecordGATTOperationOutcome(UMAGATTOperation operation,
// Send(BluetoothMsg_ReadCharacteristicValueSuccess) and
// Send(BluetoothMsg_ReadCharacteristicValueError).
void RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome error);
+// Records the outcome of a cache query for readValue. Should only be called if
+// QueryCacheForCharacteristic fails.
+void RecordCharacteristicReadValueOutcome(CacheQueryOutcome outcome);
// Characteristic.writeValue() Metrics
// There should be a call to this function for every call to
// Send(BluetoothMsg_WriteCharacteristicValueSuccess) and
// Send(BluetoothMsg_WriteCharacteristicValueError).
void RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome error);
+// Records the outcome of a cache query for writeValue. Should only be called if
+// QueryCacheForCharacteristic fails.
+void RecordCharacteristicWriteValueOutcome(CacheQueryOutcome outcome);
+
+// Characteristic.startNotifications() Metrics
+// There should be a call to this function for every call to
+// Send(BluetoothMsg_StartNotificationsSuccess) and
+// Send(BluetoothMsg_StopNotificationsError).
+void RecordStartNotificationsOutcome(UMAGATTOperationOutcome outcome);
+// Records the outcome of a cache query for startNotifications. Should only be
+// called if QueryCacheForCharacteristic fails.
+void RecordStartNotificationsOutcome(CacheQueryOutcome outcome);
} // namespace content
diff --git a/chromium/content/browser/bootstrap_sandbox_manager_mac.cc b/chromium/content/browser/bootstrap_sandbox_manager_mac.cc
index 48d25491429..61d1b1e3b04 100644
--- a/chromium/content/browser/bootstrap_sandbox_manager_mac.cc
+++ b/chromium/content/browser/bootstrap_sandbox_manager_mac.cc
@@ -6,7 +6,6 @@
#include "base/logging.h"
#include "base/mac/mac_util.h"
-#include "content/browser/browser_io_surface_manager_mac.h"
#include "content/browser/mach_broker_mac.h"
#include "content/common/sandbox_init_mac.h"
#include "content/public/browser/browser_thread.h"
@@ -79,11 +78,6 @@ void BootstrapSandboxManager::RegisterRendererPolicy() {
policy.rules["com.apple.windowserver.active"] =
sandbox::Rule(sandbox::POLICY_ALLOW);
- // Allow renderers to contact the IOSurfaceManager in the browser to share
- // accelerated surfaces.
- policy.rules[BrowserIOSurfaceManager::GetMachPortName()] =
- sandbox::Rule(sandbox::POLICY_ALLOW);
-
// Allow access to launchservicesd on 10.10+ otherwise the renderer will crash
// attempting to get its ASN. http://crbug.com/533537
if (base::mac::IsOSYosemiteOrLater()) {
diff --git a/chromium/content/browser/bootstrap_sandbox_manager_mac.h b/chromium/content/browser/bootstrap_sandbox_manager_mac.h
index 72233cbebb0..edddde8b7d7 100644
--- a/chromium/content/browser/bootstrap_sandbox_manager_mac.h
+++ b/chromium/content/browser/bootstrap_sandbox_manager_mac.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_BOOTSTRAP_SANDBOX_MANAGER_MAC_H_
#define CONTENT_BROWSER_BOOTSTRAP_SANDBOX_MANAGER_MAC_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "content/public/browser/browser_child_process_observer.h"
diff --git a/chromium/content/browser/browser_child_process_host_impl.cc b/chromium/content/browser/browser_child_process_host_impl.cc
index 2f9076f0fa4..9461b624195 100644
--- a/chromium/content/browser/browser_child_process_host_impl.cc
+++ b/chromium/content/browser/browser_child_process_host_impl.cc
@@ -11,17 +11,20 @@
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
+#include "build/build_config.h"
+#include "components/tracing/tracing_switches.h"
#include "content/browser/histogram_message_filter.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/memory/memory_message_filter.h"
#include "content/browser/profiler_message_filter.h"
#include "content/browser/tracing/trace_message_filter.h"
#include "content/common/child_process_host_impl.h"
+#include "content/common/child_process_messages.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/browser_thread.h"
@@ -30,11 +33,20 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "content/public/common/result_codes.h"
+#include "ipc/attachment_broker.h"
+#include "ipc/attachment_broker_privileged.h"
+#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
#if defined(OS_MACOSX)
#include "content/browser/mach_broker_mac.h"
#endif
+
+#if defined(MOJO_SHELL_CLIENT)
+#include "content/browser/mojo/mojo_shell_client_host.h"
+#include "content/common/mojo/mojo_shell_connection_impl.h"
+#endif
+
namespace content {
namespace {
@@ -44,6 +56,11 @@ static base::LazyInstance<BrowserChildProcessHostImpl::BrowserChildProcessList>
base::LazyInstance<base::ObserverList<BrowserChildProcessObserver>>
g_observers = LAZY_INSTANCE_INITIALIZER;
+void NotifyProcessLaunchedAndConnected(const ChildProcessData& data) {
+ FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
+ BrowserChildProcessLaunchedAndConnected(data));
+}
+
void NotifyProcessHostConnected(const ChildProcessData& data) {
FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
BrowserChildProcessHostConnected(data));
@@ -114,14 +131,28 @@ BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
BrowserChildProcessHostDelegate* delegate)
: data_(process_type),
delegate_(delegate),
- power_monitor_message_broadcaster_(this) {
+ power_monitor_message_broadcaster_(this),
+ is_channel_connected_(false) {
data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
+#if USE_ATTACHMENT_BROKER
+ // Construct the privileged attachment broker early in the life cycle of a
+ // child process. This ensures that when a test is being run in one of the
+ // single process modes, the global attachment broker is the privileged
+ // attachment broker, rather than an unprivileged attachment broker.
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded(
+ MachBroker::GetInstance());
+#else
+ IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded();
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
+#endif // USE_ATTACHMENT_BROKER
+
child_process_host_.reset(ChildProcessHost::Create(this));
AddFilter(new TraceMessageFilter(data_.id));
AddFilter(new ProfilerMessageFilter(process_type));
AddFilter(new HistogramMessageFilter);
- AddFilter(new MemoryMessageFilter);
+ AddFilter(new MemoryMessageFilter(this, process_type));
g_child_process_list.Get().push_back(this);
GetContentClient()->browser()->BrowserChildProcessHostCreated(this);
@@ -252,18 +283,27 @@ bool BrowserChildProcessHostImpl::OnMessageReceived(
return delegate_->OnMessageReceived(message);
}
-void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) {
+void BrowserChildProcessHostImpl::OnChannelConnected(int32_t peer_pid) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ is_channel_connected_ = true;
+
#if defined(OS_WIN)
// From this point onward, the exit of the child process is detected by an
// error on the IPC channel.
early_exit_watcher_.StopWatching();
#endif
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&NotifyProcessHostConnected, data_));
delegate_->OnChannelConnected(peer_pid);
+
+ if (IsProcessLaunched()) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&NotifyProcessLaunchedAndConnected,
+ data_));
+ }
}
void BrowserChildProcessHostImpl::OnChannelError() {
@@ -272,13 +312,17 @@ void BrowserChildProcessHostImpl::OnChannelError() {
void BrowserChildProcessHostImpl::OnBadMessageReceived(
const IPC::Message& message) {
+ TerminateOnBadMessageReceived(message.type());
+}
+
+void BrowserChildProcessHostImpl::TerminateOnBadMessageReceived(uint32_t type) {
HistogramBadMessageTerminated(data_.process_type);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableKillAfterBadIPC)) {
return;
}
LOG(ERROR) << "Terminating child process for bad IPC message of type "
- << message.type();
+ << type;
// Create a memory dump. This will contain enough stack frames to work out
// what the bad message was.
@@ -365,14 +409,31 @@ void BrowserChildProcessHostImpl::OnProcessLaunchFailed() {
}
void BrowserChildProcessHostImpl::OnProcessLaunched() {
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 BrowserChildProcessHostImpl::OnProcessLaunched"));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
const base::Process& process = child_process_->GetProcess();
DCHECK(process.IsValid());
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) {
+ mojo::embedder::ScopedPlatformHandle client_pipe;
+#if defined(MOJO_SHELL_CLIENT)
+ if (IsRunningInMojoShell()) {
+ client_pipe = RegisterProcessWithBroker(process.Pid());
+ } else
+#endif
+ {
+ client_pipe = mojo::embedder::ChildProcessLaunched(process.Handle());
+ }
+ Send(new ChildProcessMsg_SetMojoParentPipeHandle(
+ IPC::GetFileHandleForProcess(
+#if defined(OS_WIN)
+ client_pipe.release().handle,
+#else
+ client_pipe.release().fd,
+#endif
+ process.Handle(), true)));
+ }
+
#if defined(OS_WIN)
// Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the
// child process exits. This watcher is stopped once the IPC channel is
@@ -385,6 +446,18 @@ void BrowserChildProcessHostImpl::OnProcessLaunched() {
// TODO(rvargas) crbug.com/417532: Don't store a handle.
data_.handle = process.Handle();
delegate_->OnProcessLaunched();
+
+ if (is_channel_connected_) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&NotifyProcessLaunchedAndConnected,
+ data_));
+ }
+}
+
+bool BrowserChildProcessHostImpl::IsProcessLaunched() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ return child_process_.get() && child_process_->GetProcess().IsValid();
}
#if defined(OS_WIN)
diff --git a/chromium/content/browser/browser_child_process_host_impl.h b/chromium/content/browser/browser_child_process_host_impl.h
index 0157db9873f..a5f3b6d528b 100644
--- a/chromium/content/browser/browser_child_process_host_impl.h
+++ b/chromium/content/browser/browser_child_process_host_impl.h
@@ -5,12 +5,15 @@
#ifndef CONTENT_BROWSER_BROWSER_CHILD_PROCESS_HOST_IMPL_H_
#define CONTENT_BROWSER_BROWSER_CHILD_PROCESS_HOST_IMPL_H_
+#include <stdint.h>
+
#include <list>
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process.h"
#include "base/synchronization/waitable_event_watcher.h"
+#include "build/build_config.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/power_monitor_message_broadcaster.h"
#include "content/public/browser/browser_child_process_host.h"
@@ -69,10 +72,14 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
void OnChildDisconnected() override;
const base::Process& GetProcess() const override;
bool OnMessageReceived(const IPC::Message& message) override;
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void OnBadMessageReceived(const IPC::Message& message) override;
+ // Terminates the process and logs an error after a bad message was received
+ // from the child process.
+ void TerminateOnBadMessageReceived(uint32_t type);
+
// Removes this host from the host list. Calls ChildProcessHost::ForceShutdown
void ForceShutdown();
@@ -103,6 +110,10 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
void OnProcessLaunched() override;
void OnProcessLaunchFailed() override;
+ // Returns true if the process has successfully launched. Must only be called
+ // on the IO thread.
+ bool IsProcessLaunched() const;
+
#if defined(OS_WIN)
// ObjectWatcher::Delegate implementation.
void OnObjectSignaled(HANDLE object) override;
@@ -122,6 +133,8 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
// IPC channel.
base::win::ObjectWatcher early_exit_watcher_;
#endif
+
+ bool is_channel_connected_;
};
} // namespace content
diff --git a/chromium/content/browser/browser_context.cc b/chromium/content/browser/browser_context.cc
index be99f67344e..fc3f644fba2 100644
--- a/chromium/content/browser/browser_context.cc
+++ b/chromium/content/browser/browser_context.cc
@@ -4,6 +4,12 @@
#include "content/public/browser/browser_context.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
+#include "build/build_config.h"
+
#if !defined(OS_IOS)
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
@@ -114,16 +120,14 @@ void BrowserContext::GarbageCollectStoragePartitions(
BrowserContext* browser_context,
scoped_ptr<base::hash_set<base::FilePath> > active_paths,
const base::Closure& done) {
- GetStoragePartitionMap(browser_context)->GarbageCollect(
- active_paths.Pass(), done);
+ GetStoragePartitionMap(browser_context)
+ ->GarbageCollect(std::move(active_paths), done);
}
DownloadManager* BrowserContext::GetDownloadManager(
BrowserContext* context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!context->GetUserData(kDownloadManagerKeyName)) {
- ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
- DCHECK(rdh);
DownloadManager* download_manager =
new DownloadManagerImpl(
GetContentClient()->browser()->GetNetLog(), context);
@@ -250,7 +254,7 @@ void BrowserContext::CreateFileBackedBlob(
void BrowserContext::DeliverPushMessage(
BrowserContext* browser_context,
const GURL& origin,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& data,
const base::Callback<void(PushDeliveryStatus)>& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chromium/content/browser/browser_io_surface_manager_mac.cc b/chromium/content/browser/browser_io_surface_manager_mac.cc
deleted file mode 100644
index 898fa4b24f6..00000000000
--- a/chromium/content/browser/browser_io_surface_manager_mac.cc
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/browser_io_surface_manager_mac.h"
-
-#include <servers/bootstrap.h>
-
-#include <string>
-
-#include "base/logging.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/mach_logging.h"
-#include "base/strings/stringprintf.h"
-#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
-
-namespace content {
-namespace {
-
-// Returns the Mach port name to use when sending or receiving messages. |pid|
-// is the process ID of the service.
-std::string GetMachPortNameByPid(pid_t pid) {
- return base::StringPrintf("%s.iosurfacemgr.%d", base::mac::BaseBundleID(),
- pid);
-}
-
-// Amount of time to wait before giving up when sending a reply message.
-const int kSendReplyTimeoutMs = 100;
-
-} // namespace
-
-// static
-BrowserIOSurfaceManager* BrowserIOSurfaceManager::GetInstance() {
- return base::Singleton<
- BrowserIOSurfaceManager,
- base::LeakySingletonTraits<BrowserIOSurfaceManager>>::get();
-}
-
-// static
-base::mac::ScopedMachSendRight BrowserIOSurfaceManager::LookupServicePort(
- pid_t pid) {
- // Look up the named IOSurfaceManager port that's been registered with
- // the bootstrap server.
- mach_port_t port;
- kern_return_t kr =
- bootstrap_look_up(bootstrap_port,
- GetMachPortNameByPid(pid).c_str(),
- &port);
- if (kr != KERN_SUCCESS) {
- BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_look_up";
- return base::mac::ScopedMachSendRight();
- }
-
- return base::mac::ScopedMachSendRight(port);
-}
-
-// static
-std::string BrowserIOSurfaceManager::GetMachPortName() {
- return GetMachPortNameByPid(getpid());
-}
-
-bool BrowserIOSurfaceManager::RegisterIOSurface(IOSurfaceId io_surface_id,
- int client_id,
- IOSurfaceRef io_surface) {
- base::AutoLock lock(lock_);
-
- IOSurfaceMapKey key(io_surface_id, client_id);
- DCHECK(io_surfaces_.find(key) == io_surfaces_.end());
- io_surfaces_.add(key, make_scoped_ptr(new base::mac::ScopedMachSendRight(
- IOSurfaceCreateMachPort(io_surface))));
- return true;
-}
-
-void BrowserIOSurfaceManager::UnregisterIOSurface(IOSurfaceId io_surface_id,
- int client_id) {
- base::AutoLock lock(lock_);
-
- IOSurfaceMapKey key(io_surface_id, client_id);
- DCHECK(io_surfaces_.find(key) != io_surfaces_.end());
- io_surfaces_.erase(key);
-}
-
-IOSurfaceRef BrowserIOSurfaceManager::AcquireIOSurface(
- IOSurfaceId io_surface_id) {
- base::AutoLock lock(lock_);
-
- IOSurfaceMapKey key(
- io_surface_id,
- BrowserGpuChannelHostFactory::instance()->GetGpuChannelId());
- auto it = io_surfaces_.find(key);
- if (it == io_surfaces_.end()) {
- LOG(ERROR) << "Invalid Id for IOSurface " << io_surface_id.id;
- return nullptr;
- }
-
- return IOSurfaceLookupFromMachPort(it->second->get());
-}
-
-void BrowserIOSurfaceManager::EnsureRunning() {
- base::AutoLock lock(lock_);
-
- if (initialized_)
- return;
-
- // Do not attempt to reinitialize in the event of failure.
- initialized_ = true;
-
- if (!Initialize()) {
- LOG(ERROR) << "Failed to initialize the BrowserIOSurfaceManager";
- }
-}
-
-IOSurfaceManagerToken BrowserIOSurfaceManager::GenerateGpuProcessToken() {
- base::AutoLock lock(lock_);
-
- DCHECK(gpu_process_token_.IsZero());
- gpu_process_token_ = IOSurfaceManagerToken::Generate();
- DCHECK(gpu_process_token_.Verify());
- return gpu_process_token_;
-}
-
-void BrowserIOSurfaceManager::InvalidateGpuProcessToken() {
- base::AutoLock lock(lock_);
-
- DCHECK(!gpu_process_token_.IsZero());
- gpu_process_token_.SetZero();
- io_surfaces_.clear();
-}
-
-IOSurfaceManagerToken BrowserIOSurfaceManager::GenerateChildProcessToken(
- int child_process_id) {
- base::AutoLock lock(lock_);
-
- IOSurfaceManagerToken token = IOSurfaceManagerToken::Generate();
- DCHECK(token.Verify());
- child_process_ids_[token] = child_process_id;
- return token;
-}
-
-void BrowserIOSurfaceManager::InvalidateChildProcessToken(
- const IOSurfaceManagerToken& token) {
- base::AutoLock lock(lock_);
-
- DCHECK(child_process_ids_.find(token) != child_process_ids_.end());
- child_process_ids_.erase(token);
-}
-
-BrowserIOSurfaceManager::BrowserIOSurfaceManager() : initialized_(false) {
-}
-
-BrowserIOSurfaceManager::~BrowserIOSurfaceManager() {
-}
-
-bool BrowserIOSurfaceManager::Initialize() {
- lock_.AssertAcquired();
- DCHECK(!server_port_.is_valid());
-
- // Check in with launchd and publish the service name.
- mach_port_t port;
- kern_return_t kr = bootstrap_check_in(
- bootstrap_port, GetMachPortName().c_str(), &port);
- if (kr != KERN_SUCCESS) {
- BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_check_in";
- return false;
- }
- server_port_.reset(port);
-
- // Start the dispatch source.
- std::string queue_name =
- base::StringPrintf("%s.IOSurfaceManager", base::mac::BaseBundleID());
- dispatch_source_.reset(
- new base::DispatchSourceMach(queue_name.c_str(), server_port_.get(), ^{
- HandleRequest();
- }));
- dispatch_source_->Resume();
-
- return true;
-}
-
-void BrowserIOSurfaceManager::HandleRequest() {
- struct {
- union {
- mach_msg_header_t header;
- IOSurfaceManagerHostMsg_RegisterIOSurface register_io_surface;
- IOSurfaceManagerHostMsg_UnregisterIOSurface unregister_io_surface;
- IOSurfaceManagerHostMsg_AcquireIOSurface acquire_io_surface;
- } msg;
- mach_msg_trailer_t trailer;
- } request = {{{0}}};
- request.msg.header.msgh_size = sizeof(request);
- request.msg.header.msgh_local_port = server_port_.get();
-
- kern_return_t kr =
- mach_msg(&request.msg.header, MACH_RCV_MSG, 0, sizeof(request),
- server_port_, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (kr != KERN_SUCCESS) {
- MACH_LOG(ERROR, kr) << "mach_msg";
- return;
- }
-
- union {
- mach_msg_header_t header;
- IOSurfaceManagerMsg_RegisterIOSurfaceReply register_io_surface;
- IOSurfaceManagerMsg_AcquireIOSurfaceReply acquire_io_surface;
- } reply = {{0}};
-
- switch (request.msg.header.msgh_id) {
- case IOSurfaceManagerHostMsg_RegisterIOSurface::ID:
- HandleRegisterIOSurfaceRequest(request.msg.register_io_surface,
- &reply.register_io_surface);
- break;
- case IOSurfaceManagerHostMsg_UnregisterIOSurface::ID:
- HandleUnregisterIOSurfaceRequest(request.msg.unregister_io_surface);
- // Unregister requests are asynchronous and do not require a reply as
- // there is no guarantee for how quickly an IO surface is removed from
- // the IOSurfaceManager instance after it has been deleted by a child
- // process.
- return;
- case IOSurfaceManagerHostMsg_AcquireIOSurface::ID:
- HandleAcquireIOSurfaceRequest(request.msg.acquire_io_surface,
- &reply.acquire_io_surface);
- break;
- default:
- LOG(ERROR) << "Unknown message received!";
- return;
- }
-
- kr = mach_msg(&reply.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
- reply.header.msgh_size, 0, MACH_PORT_NULL, kSendReplyTimeoutMs,
- MACH_PORT_NULL);
- if (kr != KERN_SUCCESS) {
- MACH_LOG(ERROR, kr) << "mach_msg";
- }
-}
-
-void BrowserIOSurfaceManager::HandleRegisterIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_RegisterIOSurface& request,
- IOSurfaceManagerMsg_RegisterIOSurfaceReply* reply) {
- base::AutoLock lock(lock_);
-
- reply->header.msgh_bits = MACH_MSGH_BITS_REMOTE(request.header.msgh_bits);
- reply->header.msgh_remote_port = request.header.msgh_remote_port;
- reply->header.msgh_size = sizeof(*reply);
- reply->body.msgh_descriptor_count = 0;
- reply->result = false;
-
- IOSurfaceManagerToken token;
- static_assert(sizeof(request.token_name) == sizeof(token.name),
- "Mach message token size doesn't match expectation.");
- token.SetName(request.token_name);
- if (token.IsZero() || token != gpu_process_token_) {
- LOG(ERROR) << "Illegal message from non-GPU process!";
- return;
- }
-
- IOSurfaceMapKey key(IOSurfaceId(request.io_surface_id), request.client_id);
- io_surfaces_.add(key, make_scoped_ptr(new base::mac::ScopedMachSendRight(
- request.io_surface_port.name)));
- reply->result = true;
-}
-
-bool BrowserIOSurfaceManager::HandleUnregisterIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_UnregisterIOSurface& request) {
- base::AutoLock lock(lock_);
-
- IOSurfaceManagerToken token;
- static_assert(sizeof(request.token_name) == sizeof(token.name),
- "Mach message token size doesn't match expectation.");
- token.SetName(request.token_name);
- if (token.IsZero() || token != gpu_process_token_) {
- LOG(ERROR) << "Illegal message from non-GPU process!";
- return false;
- }
-
- IOSurfaceMapKey key(IOSurfaceId(request.io_surface_id), request.client_id);
- io_surfaces_.erase(key);
- return true;
-}
-
-void BrowserIOSurfaceManager::HandleAcquireIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_AcquireIOSurface& request,
- IOSurfaceManagerMsg_AcquireIOSurfaceReply* reply) {
- base::AutoLock lock(lock_);
-
- reply->header.msgh_bits =
- MACH_MSGH_BITS_REMOTE(request.header.msgh_bits) | MACH_MSGH_BITS_COMPLEX;
- reply->header.msgh_remote_port = request.header.msgh_remote_port;
- reply->header.msgh_size = sizeof(*reply);
- reply->body.msgh_descriptor_count = 0;
- reply->result = false;
- reply->io_surface_port.name = MACH_PORT_NULL;
- reply->io_surface_port.disposition = 0;
- reply->io_surface_port.type = 0;
-
- IOSurfaceManagerToken token;
- static_assert(sizeof(request.token_name) == sizeof(token.name),
- "Mach message token size doesn't match expectation.");
- token.SetName(request.token_name);
- auto child_process_id_it = child_process_ids_.find(token);
- if (child_process_id_it == child_process_ids_.end()) {
- LOG(ERROR) << "Illegal message from non-child process!";
- return;
- }
-
- reply->result = true;
- IOSurfaceMapKey key(IOSurfaceId(request.io_surface_id),
- child_process_id_it->second);
- auto it = io_surfaces_.find(key);
- if (it == io_surfaces_.end()) {
- LOG(ERROR) << "Invalid Id for IOSurface " << request.io_surface_id;
- return;
- }
-
- reply->body.msgh_descriptor_count = 1;
- reply->io_surface_port.name = it->second->get();
- reply->io_surface_port.disposition = MACH_MSG_TYPE_COPY_SEND;
- reply->io_surface_port.type = MACH_MSG_PORT_DESCRIPTOR;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/browser_io_surface_manager_mac.h b/chromium/content/browser/browser_io_surface_manager_mac.h
deleted file mode 100644
index be78b5f93b3..00000000000
--- a/chromium/content/browser/browser_io_surface_manager_mac.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_BROWSER_IO_SURFACE_MANAGER_MAC_H_
-#define CONTENT_BROWSER_BROWSER_IO_SURFACE_MANAGER_MAC_H_
-
-#include <mach/mach.h>
-
-#include <map>
-#include <utility>
-
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/mac/dispatch_source_mach.h"
-#include "base/mac/scoped_mach_port.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/singleton.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/common/mac/io_surface_manager.h"
-#include "content/common/mac/io_surface_manager_messages.h"
-#include "content/common/mac/io_surface_manager_token.h"
-
-namespace content {
-
-// TODO(ericrk): Use gfx::GenericSharedMemoryId as the |io_surface_id| in
-// this file. Allows for more type-safe usage of GpuMemoryBufferIds as the
-// type of the |io_surface_id|, as it is a typedef of
-// gfx::GenericSharedMemoryId.
-
-// Implementation of IOSurfaceManager that provides a mechanism for child
-// processes to register and acquire IOSurfaces through a Mach service.
-class CONTENT_EXPORT BrowserIOSurfaceManager : public IOSurfaceManager {
- public:
- // Returns the global BrowserIOSurfaceManager.
- static BrowserIOSurfaceManager* GetInstance();
-
- // Look up the IOSurfaceManager service port that's been registered with
- // the bootstrap server. |pid| is the process ID of the service.
- static base::mac::ScopedMachSendRight LookupServicePort(pid_t pid);
-
- // Returns the name of the service registered with the bootstrap server.
- static std::string GetMachPortName();
-
- // Overridden from IOSurfaceManager:
- bool RegisterIOSurface(IOSurfaceId io_surface_id,
- int client_id,
- IOSurfaceRef io_surface) override;
- void UnregisterIOSurface(IOSurfaceId io_surface_id, int client_id) override;
- IOSurfaceRef AcquireIOSurface(IOSurfaceId io_surface_id) override;
-
- // Performs any necessary setup that cannot happen in the constructor.
- void EnsureRunning();
-
- // Generate a unique unguessable token that the GPU process can use to
- // register/unregister IOSurface for use by clients.
- IOSurfaceManagerToken GenerateGpuProcessToken();
-
- // Invalidate the previously generated GPU process token.
- void InvalidateGpuProcessToken();
-
- // Generate a unique unguessable token that the child process associated
- // |child_process_id| can use to acquire IOSurface references.
- IOSurfaceManagerToken GenerateChildProcessToken(int child_process_id);
-
- // Invalidate a previously generated child process token.
- void InvalidateChildProcessToken(const IOSurfaceManagerToken& token);
-
- private:
- friend class BrowserIOSurfaceManagerTest;
- friend struct base::DefaultSingletonTraits<BrowserIOSurfaceManager>;
-
- BrowserIOSurfaceManager();
- ~BrowserIOSurfaceManager() override;
-
- // Performs any initialization work.
- bool Initialize();
-
- // Message handler that is invoked on |dispatch_source_| when an
- // incoming message needs to be received.
- void HandleRequest();
-
- // Message handlers that are invoked from HandleRequest.
- void HandleRegisterIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_RegisterIOSurface& request,
- IOSurfaceManagerMsg_RegisterIOSurfaceReply* reply);
- bool HandleUnregisterIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_UnregisterIOSurface& request);
- void HandleAcquireIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_AcquireIOSurface& request,
- IOSurfaceManagerMsg_AcquireIOSurfaceReply* reply);
-
- // Whether or not the class has been initialized.
- bool initialized_;
-
- // The Mach port on which the server listens.
- base::mac::ScopedMachReceiveRight server_port_;
-
- // The dispatch source and queue on which Mach messages will be received.
- scoped_ptr<base::DispatchSourceMach> dispatch_source_;
-
- // Stores the IOSurfaces for all GPU clients. The key contains the IOSurface
- // id and the Child process unique id of the owner.
- using IOSurfaceMapKey = std::pair<IOSurfaceId, int>;
- using IOSurfaceMap =
- base::ScopedPtrHashMap<IOSurfaceMapKey,
- scoped_ptr<base::mac::ScopedMachSendRight>>;
- IOSurfaceMap io_surfaces_;
-
- // Stores the Child process unique id (RenderProcessHost ID) for every
- // token.
- using ChildProcessIdMap = std::map<IOSurfaceManagerToken, int>;
- ChildProcessIdMap child_process_ids_;
-
- // Stores the GPU process token.
- IOSurfaceManagerToken gpu_process_token_;
-
- // Mutex that guards |initialized_|, |io_surfaces_|, |child_process_ids_|
- // and |gpu_process_token_|.
- base::Lock lock_;
-
- DISALLOW_COPY_AND_ASSIGN(BrowserIOSurfaceManager);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_BROWSER_IO_SURFACE_MANAGER_MAC_H_
diff --git a/chromium/content/browser/browser_io_surface_manager_mac_unittest.cc b/chromium/content/browser/browser_io_surface_manager_mac_unittest.cc
deleted file mode 100644
index b8863e4ad9d..00000000000
--- a/chromium/content/browser/browser_io_surface_manager_mac_unittest.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/browser_io_surface_manager_mac.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-class BrowserIOSurfaceManagerTest : public testing::Test {
- public:
- void EnsureRunning() { io_surface_manager_.EnsureRunning(); }
-
- IOSurfaceManagerToken GenerateGpuProcessToken() {
- return io_surface_manager_.GenerateGpuProcessToken();
- }
-
- void InvalidateGpuProcessToken() {
- io_surface_manager_.InvalidateGpuProcessToken();
- }
-
- IOSurfaceManagerToken GenerateChildProcessToken(int child_process_id) {
- return io_surface_manager_.GenerateChildProcessToken(child_process_id);
- }
-
- void InvalidateChildProcessToken(const IOSurfaceManagerToken& token) {
- io_surface_manager_.InvalidateChildProcessToken(token);
- }
-
- bool HandleRegisterIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_RegisterIOSurface& request,
- IOSurfaceManagerMsg_RegisterIOSurfaceReply* reply) {
- io_surface_manager_.HandleRegisterIOSurfaceRequest(request, reply);
- return reply->result;
- }
-
- bool HandleUnregisterIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_UnregisterIOSurface& request) {
- return io_surface_manager_.HandleUnregisterIOSurfaceRequest(request);
- }
-
- bool HandleAcquireIOSurfaceRequest(
- const IOSurfaceManagerHostMsg_AcquireIOSurface& request,
- IOSurfaceManagerMsg_AcquireIOSurfaceReply* reply) {
- io_surface_manager_.HandleAcquireIOSurfaceRequest(request, reply);
- return reply->result;
- }
-
- // Helper function used to register an IOSurface for testing.
- void RegisterIOSurface(const IOSurfaceManagerToken& gpu_process_token,
- int io_surface_id,
- int client_id,
- mach_port_t io_surface_port) {
- IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
- IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
- request.io_surface_id = io_surface_id;
- request.client_id = client_id;
- request.io_surface_port.name = io_surface_port;
- memcpy(request.token_name, gpu_process_token.name,
- sizeof(gpu_process_token.name));
- ASSERT_TRUE(HandleRegisterIOSurfaceRequest(request, &reply));
- ASSERT_TRUE(reply.result);
- }
-
- private:
- BrowserIOSurfaceManager io_surface_manager_;
-};
-
-TEST_F(BrowserIOSurfaceManagerTest, EnsureRunning) {
- EnsureRunning();
- base::mac::ScopedMachSendRight service_port =
- BrowserIOSurfaceManager::LookupServicePort(getpid());
- EXPECT_TRUE(service_port.is_valid());
-}
-
-TEST_F(BrowserIOSurfaceManagerTest, RegisterIOSurfaceSucceeds) {
- const int kIOSurfaceId = 1;
- const int kClientId = 1;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
-
- IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
- IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
-
- request.io_surface_id = kIOSurfaceId;
- request.client_id = kClientId;
- memcpy(request.token_name, gpu_process_token.name,
- sizeof(gpu_process_token.name));
- EXPECT_TRUE(HandleRegisterIOSurfaceRequest(request, &reply));
- EXPECT_TRUE(reply.result);
-}
-
-TEST_F(BrowserIOSurfaceManagerTest, RegisterIOSurfaceFailsWithInvalidToken) {
- const int kIOSurfaceId = 1;
- const int kClientId = 1;
-
- IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
- IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
- request.io_surface_id = kIOSurfaceId;
- request.client_id = kClientId;
- // Fails as request doesn't contain a valid token.
- EXPECT_FALSE(HandleRegisterIOSurfaceRequest(request, &reply));
-}
-
-TEST_F(BrowserIOSurfaceManagerTest,
- RegisterIOSurfaceFailsWithChildProcessToken) {
- const int kIOSurfaceId = 1;
- const int kClientId = 1;
-
- IOSurfaceManagerToken child_process_token =
- GenerateChildProcessToken(kClientId);
-
- IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
- IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
- request.io_surface_id = kIOSurfaceId;
- request.client_id = kClientId;
- memcpy(request.token_name, child_process_token.name,
- sizeof(child_process_token.name));
- // Fails as child process is not allowed to register IOSurfaces.
- EXPECT_FALSE(HandleRegisterIOSurfaceRequest(request, &reply));
-}
-
-TEST_F(BrowserIOSurfaceManagerTest, UnregisterIOSurfaceSucceeds) {
- const int kIOSurfaceId = 1;
- const int kClientId = 1;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0);
-
- IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}};
- request.io_surface_id = kIOSurfaceId;
- request.client_id = kClientId;
- memcpy(request.token_name, gpu_process_token.name,
- sizeof(gpu_process_token.name));
- EXPECT_TRUE(HandleUnregisterIOSurfaceRequest(request));
-}
-
-TEST_F(BrowserIOSurfaceManagerTest, UnregisterIOSurfaceFailsWithInvalidToken) {
- const int kIOSurfaceId = 1;
- const int kClientId = 1;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0);
-
- IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}};
- request.io_surface_id = kIOSurfaceId;
- request.client_id = kClientId;
- // Fails as request doesn't contain valid GPU token.
- EXPECT_FALSE(HandleUnregisterIOSurfaceRequest(request));
-}
-
-TEST_F(BrowserIOSurfaceManagerTest,
- UnregisterIOSurfaceFailsWithChildProcessToken) {
- const int kIOSurfaceId = 1;
- const int kClientId = 1;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
- IOSurfaceManagerToken child_process_token =
- GenerateChildProcessToken(kClientId);
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0);
-
- IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}};
- request.io_surface_id = kIOSurfaceId;
- request.client_id = kClientId;
- memcpy(request.token_name, child_process_token.name,
- sizeof(child_process_token.name));
- // Fails as child process is not allowed to unregister IOSurfaces.
- EXPECT_FALSE(HandleUnregisterIOSurfaceRequest(request));
-}
-
-TEST_F(BrowserIOSurfaceManagerTest, AcquireIOSurfaceSucceeds) {
- const int kIOSurfaceId = 10;
- const int kClientId = 1;
- const mach_port_t kIOSurfacePortId = 100u;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
- IOSurfaceManagerToken child_process_token =
- GenerateChildProcessToken(kClientId);
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
- kIOSurfacePortId);
-
- IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
- IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
- request.io_surface_id = kIOSurfaceId;
- memcpy(request.token_name, child_process_token.name,
- sizeof(child_process_token.name));
- EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply));
- EXPECT_EQ(kIOSurfacePortId, reply.io_surface_port.name);
-}
-
-TEST_F(BrowserIOSurfaceManagerTest, AcquireIOSurfaceFailsWithInvalidToken) {
- const int kIOSurfaceId = 10;
- const int kClientId = 1;
- const mach_port_t kIOSurfacePortId = 100u;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
- kIOSurfacePortId);
-
- IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
- IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
- request.io_surface_id = kIOSurfaceId;
- // Fails as request doesn't contain valid token.
- EXPECT_FALSE(HandleAcquireIOSurfaceRequest(request, &reply));
-}
-
-TEST_F(BrowserIOSurfaceManagerTest,
- AcquireIOSurfaceFailsWithWrongChildProcessToken) {
- const int kIOSurfaceId = 10;
- const int kClientId1 = 1;
- const int kClientId2 = 2;
- const mach_port_t kIOSurfacePortId = 100u;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
- IOSurfaceManagerToken child_process_token2 =
- GenerateChildProcessToken(kClientId2);
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId1,
- kIOSurfacePortId);
-
- IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
- IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
- request.io_surface_id = kIOSurfaceId;
- memcpy(request.token_name, child_process_token2.name,
- sizeof(child_process_token2.name));
- EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply));
- // Fails as child process 2 is not allowed to acquire this IOSurface.
- EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL),
- reply.io_surface_port.name);
-}
-
-TEST_F(BrowserIOSurfaceManagerTest,
- AcquireIOSurfaceFailsAfterInvalidatingChildProcessToken) {
- const int kIOSurfaceId = 10;
- const int kClientId = 1;
- const mach_port_t kIOSurfacePortId = 100u;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
- IOSurfaceManagerToken child_process_token =
- GenerateChildProcessToken(kClientId);
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
- kIOSurfacePortId);
-
- InvalidateChildProcessToken(child_process_token);
-
- IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
- IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
- request.io_surface_id = kIOSurfaceId;
- memcpy(request.token_name, child_process_token.name,
- sizeof(child_process_token.name));
- // Fails as token is no longer valid.
- EXPECT_FALSE(HandleAcquireIOSurfaceRequest(request, &reply));
-}
-
-TEST_F(BrowserIOSurfaceManagerTest,
- AcquireIOSurfaceAfterInvalidatingGpuProcessToken) {
- const int kIOSurfaceId = 10;
- const int kClientId = 1;
- const mach_port_t kIOSurfacePortId = 100u;
-
- IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
- IOSurfaceManagerToken child_process_token =
- GenerateChildProcessToken(kClientId);
-
- RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
- kIOSurfacePortId);
-
- InvalidateGpuProcessToken();
-
- IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
- IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
- request.io_surface_id = kIOSurfaceId;
- memcpy(request.token_name, child_process_token.name,
- sizeof(child_process_token.name));
- EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply));
- // Should return invalid port.
- EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL),
- reply.io_surface_port.name);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/browser_main.cc b/chromium/content/browser/browser_main.cc
index 4c114b43613..d0897f1d650 100644
--- a/chromium/content/browser/browser_main.cc
+++ b/chromium/content/browser/browser_main.cc
@@ -10,9 +10,27 @@
namespace content {
+namespace {
+
+// Generates a pair of BrowserMain async events. We don't use the TRACE_EVENT0
+// macro because the tracing infrastructure doesn't expect synchronous events
+// around the main loop of a thread.
+class ScopedBrowserMainEvent {
+ public:
+ ScopedBrowserMainEvent() {
+ TRACE_EVENT_ASYNC_BEGIN0("startup", "BrowserMain", 0);
+ }
+ ~ScopedBrowserMainEvent() {
+ TRACE_EVENT_ASYNC_END0("startup", "BrowserMain", 0);
+ }
+};
+
+} // namespace
+
// Main routine for running as the Browser process.
int BrowserMain(const MainFunctionParams& parameters) {
- TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, "");
+ ScopedBrowserMainEvent scoped_browser_main_event;
+
base::trace_event::TraceLog::GetInstance()->SetProcessName("Browser");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventBrowserProcessSortIndex);
@@ -27,8 +45,6 @@ int BrowserMain(const MainFunctionParams& parameters) {
main_runner->Shutdown();
- TRACE_EVENT_END_ETW("BrowserMain", 0, 0);
-
return exit_code;
}
diff --git a/chromium/content/browser/browser_main.h b/chromium/content/browser/browser_main.h
index ff52aefa12b..8fab146352a 100644
--- a/chromium/content/browser/browser_main.h
+++ b/chromium/content/browser/browser_main.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_BROWSER_MAIN_H_
#define CONTENT_BROWSER_BROWSER_MAIN_H_
-#include "base/basictypes.h"
#include "content/common/content_export.h"
namespace content {
diff --git a/chromium/content/browser/browser_main_loop.cc b/chromium/content/browser/browser_main_loop.cc
index 86f4123e620..63ee2cca5d9 100644
--- a/chromium/content/browser/browser_main_loop.cc
+++ b/chromium/content/browser/browser_main_loop.cc
@@ -4,10 +4,15 @@
#include "content/browser/browser_main_loop.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/feature_list.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/memory_pressure_monitor.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
@@ -26,7 +31,9 @@
#include "base/timer/hi_res_timer_manager.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "components/tracing/trace_config_file.h"
+#include "components/tracing/trace_to_console.h"
#include "components/tracing/tracing_switches.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/device_sensors/device_inertial_sensor_service.h"
@@ -60,8 +67,8 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/result_codes.h"
-#include "crypto/nss_util.h"
#include "device/battery/battery_status_service.h"
+#include "ipc/mojo/scoped_ipc_support.h"
#include "media/audio/audio_manager.h"
#include "media/base/media.h"
#include "media/base/user_input_monitor.h"
@@ -69,8 +76,9 @@
#include "net/base/network_change_notifier.h"
#include "net/socket/client_socket_factory.h"
#include "net/ssl/ssl_config_service.h"
-#include "ipc/mojo/scoped_ipc_support.h"
+#include "skia/ext/event_tracer_impl.h"
#include "skia/ext/skia_memory_dump_provider.h"
+#include "sql/sql_memory_dump_provider.h"
#include "ui/base/clipboard/clipboard.h"
#if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
@@ -88,6 +96,7 @@
#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
+#include "components/tracing/graphics_memory_dump_provider_android.h"
#include "content/browser/android/browser_startup_controller.h"
#include "content/browser/android/browser_surface_texture_manager.h"
#include "content/browser/android/in_process_surface_texture_manager.h"
@@ -97,17 +106,11 @@
#include "ui/gl/gl_surface.h"
#endif
-#if defined(OS_MACOSX)
-#include "media/base/mac/avfoundation_glue.h"
-#endif
-
#if defined(OS_MACOSX) && !defined(OS_IOS)
#include "base/memory/memory_pressure_monitor_mac.h"
#include "content/browser/bootstrap_sandbox_manager_mac.h"
-#include "content/browser/browser_io_surface_manager_mac.h"
#include "content/browser/cocoa/system_hotkey_helper_mac.h"
#include "content/browser/compositor/browser_compositor_view_mac.h"
-#include "content/browser/in_process_io_surface_manager_mac.h"
#include "content/browser/theme_helper_mac.h"
#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
#endif
@@ -159,7 +162,9 @@
#endif
#if defined(USE_X11)
+#include "ui/base/x/x11_util_internal.h"
#include "ui/gfx/x/x11_connection.h"
+#include "ui/gfx/x/x11_switches.h"
#include "ui/gfx/x/x11_types.h"
#endif
@@ -167,6 +172,15 @@
#include "crypto/nss_util.h"
#endif
+#if defined(MOJO_SHELL_CLIENT)
+#include "components/mus/public/interfaces/window_manager.mojom.h"
+#include "content/common/mojo/mojo_shell_connection_impl.h"
+#include "mojo/converters/network/network_type_converters.h"
+#include "mojo/shell/public/cpp/application_impl.h"
+#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
+#include "ui/views/mus/window_manager_connection.h"
+#endif
+
// One of the linux specific headers defines this as a macro.
#ifdef DestroyAll
#undef DestroyAll
@@ -190,7 +204,7 @@ void SetupSandbox(const base::CommandLine& parsed_command_line) {
static const char no_suid_error[] =
"Running without the SUID sandbox! See "
- "https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment "
+ "https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md "
"for more information on developing with the sandbox on.";
if (want_setuid_sandbox) {
sandbox_binary = setuid_sandbox_host->GetSandboxBinaryPath();
@@ -242,9 +256,9 @@ static void GLibLogHandler(const gchar* log_domain,
<< "http://crbug.com/179797";
} else if (strstr(message, "Attempting to store changes into") ||
strstr(message, "Attempting to set the permissions of")) {
- LOG(ERROR) << message << " (http://bugs.chromium.org/161366)";
+ LOG(ERROR) << message << " (http://crbug.com/161366)";
} else if (strstr(message, "drawable is not a native X11 window")) {
- LOG(ERROR) << message << " (http://bugs.chromium.org/329991)";
+ LOG(ERROR) << message << " (http://crbug.com/329991)";
} else if (strstr(message, "Cannot do system-bus activation with no user")) {
LOG(ERROR) << message << " (http://crbug.com/431005)";
} else if (strstr(message, "deprecated")) {
@@ -371,12 +385,7 @@ class BrowserMainLoop::MemoryObserver : public base::MessageLoop::TaskObserver {
void DidProcessTask(const base::PendingTask& pending_task) override {
#if !defined(OS_IOS) // No ProcessMetrics on IOS.
scoped_ptr<base::ProcessMetrics> process_metrics(
- base::ProcessMetrics::CreateProcessMetrics(
-#if defined(OS_MACOSX)
- base::GetCurrentProcessHandle(), NULL));
-#else
- base::GetCurrentProcessHandle()));
-#endif
+ base::ProcessMetrics::CreateCurrentProcessMetrics());
size_t private_bytes;
process_metrics->GetMemoryBytes(&private_bytes, NULL);
LOCAL_HISTOGRAM_MEMORY_KB("Memory.BrowserUsed", private_bytes >> 10);
@@ -459,10 +468,10 @@ void BrowserMainLoop::EarlyInitialization() {
// definitely harmless, so retained as a reminder of this
// requirement for gconf.
g_type_init();
-#endif
+#endif // !GLIB_CHECK_VERSION(2, 35, 0)
SetUpGLibLogHandler();
-#endif
+#endif // defined(USE_GLIB)
if (parts_)
parts_->PreEarlyInitialization();
@@ -471,7 +480,13 @@ void BrowserMainLoop::EarlyInitialization() {
// We use quite a few file descriptors for our IPC, and the default limit on
// the Mac is low (256), so bump it up.
base::SetFdLimit(1024);
-#endif
+#elif defined(OS_LINUX)
+ // Same for Linux. The default various per distro, but it is 1024 on Fedora.
+ // Low soft limits combined with liberal use of file descriptors means power
+ // users can easily hit this limit with many open tabs. Bump up the limit to
+ // an arbitrarily high number. See https://crbug.com/539567
+ base::SetFdLimit(8192);
+#endif // default(OS_MACOSX)
#if defined(OS_WIN)
net::EnsureWinsockInit();
@@ -493,13 +508,6 @@ void BrowserMainLoop::EarlyInitialization() {
}
#endif // !defined(OS_IOS)
- // TODO(boliu): kSingleProcess check is a temporary workaround for
- // in-process Android WebView. crbug.com/503724 tracks proper fix.
- if (!parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
- base::DiscardableMemoryAllocator::SetInstance(
- HostDiscardableSharedMemoryManager::current());
- }
-
if (parts_)
parts_->PostEarlyInitialization();
}
@@ -544,7 +552,8 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor");
scoped_ptr<base::PowerMonitorSource> power_monitor_source(
new base::PowerMonitorDeviceSource());
- power_monitor_.reset(new base::PowerMonitor(power_monitor_source.Pass()));
+ power_monitor_.reset(
+ new base::PowerMonitor(std::move(power_monitor_source)));
}
{
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager");
@@ -583,13 +592,41 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
system_message_window_.reset(new SystemMessageWindowWin);
#endif
+ // TODO(boliu): kSingleProcess check is a temporary workaround for
+ // in-process Android WebView. crbug.com/503724 tracks proper fix.
+ if (!parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
+ base::DiscardableMemoryAllocator::SetInstance(
+ HostDiscardableSharedMemoryManager::current());
+ }
+
if (parts_)
parts_->PostMainMessageLoopStart();
+ // Start startup tracing through TracingController's interface. TraceLog has
+ // been enabled in content_main_runner where threads are not available. Now We
+ // need to start tracing for all other tracing agents, which require threads.
+ if (parsed_command_line_.HasSwitch(switches::kTraceStartup)) {
+ base::trace_event::TraceConfig trace_config(
+ parsed_command_line_.GetSwitchValueASCII(switches::kTraceStartup),
+ base::trace_event::RECORD_UNTIL_FULL);
+ TracingController::GetInstance()->StartTracing(
+ trace_config,
+ TracingController::StartTracingDoneCallback());
+ } else if (parsed_command_line_.HasSwitch(switches::kTraceToConsole)) {
+ TracingController::GetInstance()->StartTracing(
+ tracing::GetConfigForTraceToConsole(),
+ TracingController::StartTracingDoneCallback());
+ } else if (tracing::TraceConfigFile::GetInstance()->IsEnabled()) {
+ // This checks kTraceConfigFile switch.
+ TracingController::GetInstance()->StartTracing(
+ tracing::TraceConfigFile::GetInstance()->GetTraceConfig(),
+ TracingController::StartTracingDoneCallback());
+ }
#if !defined(OS_IOS)
- // Start tracing to a file if needed. Only do this after starting the main
- // message loop to avoid calling MessagePumpForUI::ScheduleWork() before
- // MessagePumpForUI::Start() as it will crash the browser.
+ // Start tracing to a file for certain duration if needed. Only do this after
+ // starting the main message loop to avoid calling
+ // MessagePumpForUI::ScheduleWork() before MessagePumpForUI::Start() as it
+ // will crash the browser.
if (is_tracing_startup_for_duration_) {
TRACE_EVENT0("startup", "BrowserMainLoop::InitStartupTracingForDuration");
InitStartupTracingForDuration(parsed_command_line_);
@@ -607,7 +644,7 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
BrowserSurfaceTextureManager::GetInstance());
}
}
-
+#if !defined(USE_AURA)
if (!parsed_command_line_.HasSwitch(
switches::kDisableScreenOrientationLock)) {
TRACE_EVENT0("startup",
@@ -617,17 +654,9 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
ScreenOrientationProvider::SetDelegate(screen_orientation_delegate_.get());
}
#endif
+#endif
#if defined(OS_MACOSX) && !defined(OS_IOS)
- {
- TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:IOSurfaceManager");
- if (parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
- IOSurfaceManager::SetInstance(InProcessIOSurfaceManager::GetInstance());
- } else {
- IOSurfaceManager::SetInstance(BrowserIOSurfaceManager::GetInstance());
- }
- }
-
if (BootstrapSandboxManager::ShouldEnable()) {
TRACE_EVENT0("startup",
"BrowserMainLoop::Subsystem:BootstrapSandbox");
@@ -657,17 +686,13 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
}
// Enable memory-infra dump providers.
+ InitSkiaEventTracer();
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- HostSharedBitmapManager::current());
+ HostSharedBitmapManager::current(), "HostSharedBitmapManager", nullptr);
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- skia::SkiaMemoryDumpProvider::GetInstance());
-
-#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
- trace_memory_controller_.reset(new base::trace_event::TraceMemoryController(
- base::MessageLoop::current()->task_runner(),
- ::HeapProfilerWithPseudoStackStart, ::HeapProfilerStop,
- ::GetHeapProfile));
-#endif
+ skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ sql::SqlMemoryDumpProvider::GetInstance(), "Sql", nullptr);
}
int BrowserMainLoop::PreCreateThreads() {
@@ -679,6 +704,10 @@ int BrowserMainLoop::PreCreateThreads() {
result_code_ = parts_->PreCreateThreads();
}
+ // Initialize an instance of FeatureList. This will be a no-op if an instance
+ // was already set up by the embedder.
+ base::FeatureList::InitializeInstance();
+
// TODO(chrisha): Abstract away this construction mess to a helper function,
// once MemoryPressureMonitor is made a concrete class.
#if defined(OS_CHROMEOS)
@@ -694,8 +723,8 @@ int BrowserMainLoop::PreCreateThreads() {
#endif
#if defined(ENABLE_PLUGINS)
- // Prior to any processing happening on the io thread, we create the
- // plugin service as it is predominantly used from the io thread,
+ // Prior to any processing happening on the IO thread, we create the
+ // plugin service as it is predominantly used from the IO thread,
// but must be created on the main thread. The service ctor is
// inexpensive and does not invoke the io_thread() accessor.
{
@@ -704,15 +733,6 @@ int BrowserMainLoop::PreCreateThreads() {
}
#endif
-#if defined(OS_MACOSX)
- {
- // Initialize AVFoundation if supported, for audio and video.
- TRACE_EVENT0("startup",
- "BrowserMainLoop::CreateThreads:InitializeAVFoundation");
- AVFoundationGlue::InitializeAVFoundation();
- }
-#endif
-
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The WindowResizeHelper allows the UI thread to wait on specific renderer
// and GPU messages from the IO thread. Initializing it before the IO thread
@@ -888,6 +908,18 @@ int BrowserMainLoop::CreateThreads() {
}
int BrowserMainLoop::PreMainMessageLoopRun() {
+#if defined(MOJO_SHELL_CLIENT)
+ if (IsRunningInMojoShell()) {
+ mojo::embedder::PreInitializeChildProcess();
+ MojoShellConnectionImpl::Create();
+ MojoShellConnectionImpl::Get()->BindToCommandLinePlatformChannel();
+#if defined(USE_AURA)
+ views::WindowManagerConnection::Create(
+ MojoShellConnection::Get()->GetApplication());
+#endif
+ }
+#endif
+
if (parts_) {
TRACE_EVENT0("startup",
"BrowserMainLoop::CreateThreads:PreMainMessageLoopRun");
@@ -905,7 +937,9 @@ int BrowserMainLoop::PreMainMessageLoopRun() {
}
void BrowserMainLoop::RunMainMessageLoopParts() {
- TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
+ // Don't use the TRACE_EVENT0 macro because the tracing infrastructure doesn't
+ // expect synchronous events around the main loop of a thread.
+ TRACE_EVENT_ASYNC_BEGIN0("toplevel", "BrowserMain:MESSAGE_LOOP", this);
bool ran_main_loop = false;
if (parts_)
@@ -914,7 +948,7 @@ void BrowserMainLoop::RunMainMessageLoopParts() {
if (!ran_main_loop)
MainMessageLoopRun();
- TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
+ TRACE_EVENT_ASYNC_END0("toplevel", "BrowserMain:MESSAGE_LOOP", this);
}
void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
@@ -932,6 +966,9 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
true));
+#if defined(MOJO_SHELL_CLIENT)
+ MojoShellConnection::Destroy();
+#endif
mojo_ipc_support_.reset();
mojo_shell_context_.reset();
@@ -950,7 +987,6 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
aura::Env::DeleteInstance();
#endif
- trace_memory_controller_.reset();
system_stats_monitor_.reset();
#if !defined(OS_IOS)
@@ -966,7 +1002,12 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
if (resource_dispatcher_host_) {
TRACE_EVENT0("shutdown",
"BrowserMainLoop::Subsystem:ResourceDispatcherHost");
- resource_dispatcher_host_.get()->Shutdown();
+ resource_dispatcher_host_->Shutdown();
+ }
+ // Request shutdown to clean up allocated resources on the IO thread.
+ if (midi_manager_) {
+ TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:MidiManager");
+ midi_manager_->Shutdown();
}
memory_pressure_monitor_.reset();
@@ -983,10 +1024,6 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
}
#endif
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
- ZygoteHostImpl::GetInstance()->TearDownAfterLastChild();
-#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
-
// The device monitors are using |system_monitor_| as dependency, so delete
// them before |system_monitor_| goes away.
// On Mac and windows, the monitor needs to be destroyed on the same thread
@@ -1023,7 +1060,7 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
switch (thread_id) {
case BrowserThread::DB: {
TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:DBThread");
- ResetThread_DB(db_thread_.Pass());
+ ResetThread_DB(std::move(db_thread_));
break;
}
case BrowserThread::FILE: {
@@ -1034,28 +1071,28 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
if (resource_dispatcher_host_)
resource_dispatcher_host_.get()->save_file_manager()->Shutdown();
#endif // !defined(OS_IOS)
- ResetThread_FILE(file_thread_.Pass());
+ ResetThread_FILE(std::move(file_thread_));
break;
}
case BrowserThread::FILE_USER_BLOCKING: {
TRACE_EVENT0("shutdown",
"BrowserMainLoop::Subsystem:FileUserBlockingThread");
- ResetThread_FILE_USER_BLOCKING(file_user_blocking_thread_.Pass());
+ ResetThread_FILE_USER_BLOCKING(std::move(file_user_blocking_thread_));
break;
}
case BrowserThread::PROCESS_LAUNCHER: {
TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:LauncherThread");
- ResetThread_PROCESS_LAUNCHER(process_launcher_thread_.Pass());
+ ResetThread_PROCESS_LAUNCHER(std::move(process_launcher_thread_));
break;
}
case BrowserThread::CACHE: {
TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:CacheThread");
- ResetThread_CACHE(cache_thread_.Pass());
+ ResetThread_CACHE(std::move(cache_thread_));
break;
}
case BrowserThread::IO: {
TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IOThread");
- ResetThread_IO(io_thread_.Pass());
+ ResetThread_IO(std::move(io_thread_));
break;
}
case BrowserThread::UI:
@@ -1069,7 +1106,7 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
#if !defined(OS_IOS)
{
TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IndexedDBThread");
- ResetThread_IndexedDb(indexed_db_thread_.Pass());
+ ResetThread_IndexedDb(std::move(indexed_db_thread_));
}
#endif
@@ -1147,7 +1184,6 @@ int BrowserMainLoop::BrowserThreadsStarted() {
#if !defined(OS_IOS)
HistogramSynchronizer::GetInstance();
-
#if defined(OS_ANDROID)
// Up the priority of the UI thread.
base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY);
@@ -1155,7 +1191,7 @@ int BrowserMainLoop::BrowserThreadsStarted() {
bool always_uses_gpu = true;
bool established_gpu_channel = false;
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
// TODO(crbug.com/439322): This should be set to |true|.
established_gpu_channel = false;
BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
@@ -1168,7 +1204,12 @@ int BrowserMainLoop::BrowserThreadsStarted() {
BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
ImageTransportFactory::Initialize();
#if defined(USE_AURA)
- if (aura::Env::GetInstance()) {
+ bool use_mus_in_renderer = false;
+#if defined (MOJO_SHELL_CLIENT)
+ use_mus_in_renderer = base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseMusInRenderer);
+#endif // defined(MOJO_SHELL_CLIENT);
+ if (aura::Env::GetInstance() && !use_mus_in_renderer) {
aura::Env::GetInstance()->set_context_factory(GetContextFactory());
}
#endif // defined(USE_AURA)
@@ -1178,7 +1219,13 @@ int BrowserMainLoop::BrowserThreadsStarted() {
// unregistration happens on the IO thread (See
// BrowserProcessSubThread::IOThreadPreCleanUp).
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- BrowserGpuMemoryBufferManager::current(), io_thread_->task_runner());
+ BrowserGpuMemoryBufferManager::current(), "BrowserGpuMemoryBufferManager",
+ io_thread_->task_runner());
+#if defined(OS_ANDROID)
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
+ nullptr);
+#endif
{
TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:AudioMan");
@@ -1309,6 +1356,17 @@ bool BrowserMainLoop::InitializeToolkit() {
#if defined(USE_X11)
if (!gfx::GetXDisplay())
return false;
+
+#if !defined(OS_CHROMEOS)
+ // InitializeToolkit is called before CreateStartupTasks which one starts the
+ // gpu process.
+ int depth = 0;
+ ui::ChooseVisualForWindow(NULL, &depth);
+ DCHECK(depth > 0);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kWindowDepth, base::IntToString(depth));
+#endif
+
#endif
// Env creates the compositor. Aura widgets need the compositor to be created
@@ -1351,7 +1409,7 @@ base::FilePath BrowserMainLoop::GetStartupTraceFileName(
return trace_file;
if (trace_file.empty()) {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
#else
// Default to saving the startup trace into the current dir.
@@ -1359,7 +1417,7 @@ base::FilePath BrowserMainLoop::GetStartupTraceFileName(
#endif
}
} else {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
#else
trace_file = tracing::TraceConfigFile::GetInstance()->GetResultFile();
@@ -1373,9 +1431,6 @@ void BrowserMainLoop::InitStartupTracingForDuration(
const base::CommandLine& command_line) {
DCHECK(is_tracing_startup_for_duration_);
- // Initialize the tracing controller, required for memory tracing.
- TracingController::GetInstance();
-
startup_trace_file_ = GetStartupTraceFileName(parsed_command_line_);
int delay_secs = 5;
@@ -1401,7 +1456,7 @@ void BrowserMainLoop::EndStartupTracing() {
DCHECK(is_tracing_startup_for_duration_);
is_tracing_startup_for_duration_ = false;
- TracingController::GetInstance()->DisableRecording(
+ TracingController::GetInstance()->StopTracing(
TracingController::CreateFileSink(
startup_trace_file_,
base::Bind(OnStoppedStartupTracing, startup_trace_file_)));
diff --git a/chromium/content/browser/browser_main_loop.h b/chromium/content/browser/browser_main_loop.h
index ecc418d4c84..ae07f764237 100644
--- a/chromium/content/browser/browser_main_loop.h
+++ b/chromium/content/browser/browser_main_loop.h
@@ -5,11 +5,12 @@
#ifndef CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_
#define CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/public/browser/browser_main_runner.h"
@@ -22,7 +23,6 @@ class PowerMonitor;
class SystemMonitor;
class MemoryPressureMonitor;
namespace trace_event {
-class TraceMemoryController;
class TraceEventSystemStatsMonitor;
} // namespace trace_event
} // namespace base
@@ -52,7 +52,6 @@ class ClientNativePixmapFactory;
namespace content {
class BrowserMainParts;
class BrowserOnlineStateObserver;
-class BrowserShutdownImpl;
class BrowserThreadImpl;
class MediaStreamManager;
class MojoShellContext;
@@ -138,8 +137,6 @@ class CONTENT_EXPORT BrowserMainLoop {
private:
class MemoryObserver;
- // For ShutdownThreadsAndCleanUp.
- friend class BrowserShutdownImpl;
void InitializeMainThread();
@@ -210,7 +207,6 @@ class CONTENT_EXPORT BrowserMainLoop {
#endif
scoped_ptr<MemoryObserver> memory_observer_;
- scoped_ptr<base::trace_event::TraceMemoryController> trace_memory_controller_;
// Members initialized in |InitStartupTracingForDuration()| ------------------
base::FilePath startup_trace_file_;
diff --git a/chromium/content/browser/browser_main_runner.cc b/chromium/content/browser/browser_main_runner.cc
index b19fc6950ba..2585c8dd870 100644
--- a/chromium/content/browser/browser_main_runner.cc
+++ b/chromium/content/browser/browser_main_runner.cc
@@ -8,6 +8,7 @@
#include "base/command_line.h"
#include "base/debug/leak_annotations.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/statistics_recorder.h"
@@ -16,6 +17,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/tracked_objects.h"
+#include "build/build_config.h"
#include "components/tracing/trace_config_file.h"
#include "components/tracing/tracing_switches.h"
#include "content/browser/browser_main_loop.h"
@@ -262,9 +264,9 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
new BrowserShutdownProfileDumper(main_loop_->startup_trace_file()));
}
} else if (tracing::TraceConfigFile::GetInstance()->IsEnabled() &&
- TracingController::GetInstance()->IsRecording()) {
+ TracingController::GetInstance()->IsTracing()) {
base::FilePath result_file;
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
TracingControllerAndroid::GenerateTracingFilePath(&result_file);
#else
result_file = tracing::TraceConfigFile::GetInstance()->GetResultFile();
diff --git a/chromium/content/browser/browser_plugin/OWNERS b/chromium/content/browser/browser_plugin/OWNERS
index 0521a451e0a..e3502a8a750 100644
--- a/chromium/content/browser/browser_plugin/OWNERS
+++ b/chromium/content/browser/browser_plugin/OWNERS
@@ -1,3 +1,4 @@
fsamuel@chromium.org
lazyboy@chromium.org
+lfg@chromium.org
wjmaclean@chromium.org
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
index 4c6fecd362a..68899faf82a 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -50,8 +50,8 @@ void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) {
bool BrowserPluginEmbedder::NotifyScreenInfoChanged(
WebContents* guest_web_contents) {
if (guest_web_contents->GetRenderViewHost()) {
- auto render_widget_host =
- RenderWidgetHostImpl::From(guest_web_contents->GetRenderViewHost());
+ auto render_widget_host = RenderWidgetHostImpl::From(
+ guest_web_contents->GetRenderViewHost()->GetWidget());
render_widget_host->NotifyScreenInfoChanged();
}
@@ -105,8 +105,9 @@ void BrowserPluginEmbedder::ClearGuestDragStateIfApplicable() {
// static
bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
WebContents* guest_web_contents) {
- static_cast<RenderViewHostImpl*>(
- guest_web_contents->GetRenderViewHost())->SendScreenRects();
+ RenderWidgetHostImpl::From(
+ guest_web_contents->GetRenderViewHost()->GetWidget())
+ ->SendScreenRects();
// Not handled => Iterate over all guests.
return false;
}
@@ -236,8 +237,9 @@ bool BrowserPluginEmbedder::FindInGuest(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
WebContents* guest) {
- if (static_cast<WebContentsImpl*>(guest)->GetBrowserPluginGuest()->Find(
- request_id, search_text, options)) {
+ if (static_cast<WebContentsImpl*>(guest)
+ ->GetBrowserPluginGuest()
+ ->HandleFindForEmbedder(request_id, search_text, options)) {
// There can only ever currently be one browser plugin that handles find so
// we can break the iteration at this point.
return true;
@@ -248,8 +250,9 @@ bool BrowserPluginEmbedder::FindInGuest(int request_id,
// static
bool BrowserPluginEmbedder::StopFindingInGuest(StopFindAction action,
WebContents* guest) {
- if (static_cast<WebContentsImpl*>(guest)->GetBrowserPluginGuest()
- ->StopFinding(action)) {
+ if (static_cast<WebContentsImpl*>(guest)
+ ->GetBrowserPluginGuest()
+ ->HandleStopFindingForEmbedder(action)) {
// There can only ever currently be one browser plugin that handles find so
// we can break the iteration at this point.
return true;
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
index 4c3731837ac..7bff6233f2c 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -14,6 +14,7 @@
#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_EMBEDDER_H_
#define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_EMBEDDER_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
index 00529ffab22..33262a832e5 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -4,11 +4,15 @@
#include "content/browser/browser_plugin/browser_plugin_guest.h"
+#include <stddef.h>
+
#include <algorithm>
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/pickle.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_manager.h"
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
@@ -236,10 +240,11 @@ bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>(
web_contents()->GetRenderWidgetHostView());
// Until the guest is attached, it should not be handling input events.
- if (attached() && rwhv && rwhv->OnMessageReceivedFromEmbedder(
+ if (attached() && rwhv &&
+ rwhv->OnMessageReceivedFromEmbedder(
message,
- static_cast<RenderViewHostImpl*>(
- embedder_web_contents()->GetRenderViewHost()))) {
+ RenderWidgetHostImpl::From(
+ embedder_web_contents()->GetRenderViewHost()->GetWidget()))) {
return true;
}
@@ -332,8 +337,8 @@ void BrowserPluginGuest::InitInternal(
DCHECK(GetWebContents()->GetRenderViewHost());
// Initialize the device scale factor by calling |NotifyScreenInfoChanged|.
- auto render_widget_host =
- RenderWidgetHostImpl::From(GetWebContents()->GetRenderViewHost());
+ auto render_widget_host = RenderWidgetHostImpl::From(
+ GetWebContents()->GetRenderViewHost()->GetWidget());
render_widget_host->NotifyScreenInfoChanged();
// TODO(chrishtr): this code is wrong. The navigate_on_drag_drop field will
@@ -395,7 +400,7 @@ void BrowserPluginGuest::PointerLockPermissionResponse(bool allow) {
// TODO(wjmaclean): Remove this once any remaining users of this pathway
// are gone.
void BrowserPluginGuest::SwapCompositorFrame(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
int host_process_id,
int host_routing_id,
scoped_ptr<cc::CompositorFrame> frame) {
@@ -443,20 +448,15 @@ void BrowserPluginGuest::OnRequireSequence(
surface->AddDestructionDependency(sequence);
}
-void BrowserPluginGuest::SetContentsOpaque(bool opaque) {
- SendMessageToEmbedder(
- new BrowserPluginMsg_SetContentsOpaque(
- browser_plugin_instance_id(), opaque));
-}
-
-bool BrowserPluginGuest::Find(int request_id,
- const base::string16& search_text,
- const blink::WebFindOptions& options) {
- return delegate_->Find(request_id, search_text, options);
+bool BrowserPluginGuest::HandleFindForEmbedder(
+ int request_id,
+ const base::string16& search_text,
+ const blink::WebFindOptions& options) {
+ return delegate_->HandleFindForEmbedder(request_id, search_text, options);
}
-bool BrowserPluginGuest::StopFinding(StopFindAction action) {
- return delegate_->StopFinding(action);
+bool BrowserPluginGuest::HandleStopFindingForEmbedder(StopFindAction action) {
+ return delegate_->HandleStopFindingForEmbedder(action);
}
void BrowserPluginGuest::ResendEventToEmbedder(
@@ -564,6 +564,46 @@ void BrowserPluginGuest::EmbedderSystemDragEnded() {
EndSystemDragIfApplicable();
}
+// TODO(wjmaclean): Replace this approach with ones based on std::function
+// as in https://codereview.chromium.org/1404353004/ once all Chrome platforms
+// support this. https://crbug.com/544212
+IPC::Message* BrowserPluginGuest::UpdateInstanceIdIfNecessary(
+ IPC::Message* msg) const {
+ DCHECK(msg);
+
+ int msg_browser_plugin_instance_id = browser_plugin::kInstanceIDNone;
+ base::PickleIterator iter(*msg);
+ if (!iter.ReadInt(&msg_browser_plugin_instance_id) ||
+ msg_browser_plugin_instance_id != browser_plugin::kInstanceIDNone) {
+ return msg;
+ }
+
+ // This method may be called with no browser_plugin_instance_id in tests.
+ if (!browser_plugin_instance_id())
+ return msg;
+
+ scoped_ptr<IPC::Message> new_msg(
+ new IPC::Message(msg->routing_id(), msg->type(), msg->priority()));
+ new_msg->WriteInt(browser_plugin_instance_id());
+
+ // Copy remaining payload from original message.
+ // TODO(wjmaclean): it would be nice if IPC::PickleIterator had a method
+ // like 'RemainingBytes()' so that we don't have to include implementation-
+ // specific details like sizeof() in the next line.
+ DCHECK(msg->payload_size() > sizeof(int));
+ size_t remaining_bytes = msg->payload_size() - sizeof(int);
+ const char* data = nullptr;
+ bool read_success = iter.ReadBytes(&data, remaining_bytes);
+ CHECK(read_success)
+ << "Unexpected failure reading remaining IPC::Message payload.";
+ bool write_success = new_msg->WriteBytes(data, remaining_bytes);
+ CHECK(write_success)
+ << "Unexpected failure writing remaining IPC::Message payload.";
+
+ delete msg;
+ return new_msg.release();
+}
+
void BrowserPluginGuest::SendQueuedMessages() {
if (!attached())
return;
@@ -571,7 +611,8 @@ void BrowserPluginGuest::SendQueuedMessages() {
while (!pending_messages_.empty()) {
linked_ptr<IPC::Message> message_ptr = pending_messages_.front();
pending_messages_.pop_front();
- SendMessageToEmbedder(message_ptr.release());
+ SendMessageToEmbedder(
+ UpdateInstanceIdIfNecessary(message_ptr.release()));
}
}
@@ -610,8 +651,9 @@ void BrowserPluginGuest::RenderViewReady() {
Send(new InputMsg_SetFocus(routing_id(), focused_));
UpdateVisibility();
- RenderWidgetHostImpl::From(rvh)->set_hung_renderer_delay(
- base::TimeDelta::FromMilliseconds(kHungRendererDelayMs));
+ RenderWidgetHostImpl::From(rvh->GetWidget())
+ ->set_hung_renderer_delay(
+ base::TimeDelta::FromMilliseconds(kHungRendererDelayMs));
}
void BrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) {
@@ -746,13 +788,14 @@ void BrowserPluginGuest::OnWillAttachComplete(
// does not create a new RenderView on navigation.
if (!use_cross_process_frames && has_render_view_) {
// This will trigger a callback to RenderViewReady after a round-trip IPC.
- static_cast<RenderViewHostImpl*>(
- GetWebContents()->GetRenderViewHost())->Init();
+ static_cast<RenderViewHostImpl*>(GetWebContents()->GetRenderViewHost())
+ ->GetWidget()
+ ->Init();
WebContentsViewGuest* web_contents_view =
static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
- if (!web_contents()->GetRenderViewHost()->GetView()) {
+ if (!web_contents()->GetRenderViewHost()->GetWidget()->GetView()) {
web_contents_view->CreateViewForWidget(
- web_contents()->GetRenderViewHost(), true);
+ web_contents()->GetRenderViewHost()->GetWidget(), true);
}
}
@@ -763,6 +806,9 @@ void BrowserPluginGuest::OnWillAttachComplete(
SendQueuedMessages();
delegate_->DidAttach(GetGuestProxyRoutingID());
+ RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>(
+ web_contents()->GetRenderWidgetHostView());
+ rwhv->RegisterSurfaceNamespaceId();
if (!use_cross_process_frames)
has_render_view_ = true;
@@ -788,6 +834,12 @@ void BrowserPluginGuest::OnDetach(int browser_plugin_instance_id) {
// it's attached again.
attached_ = false;
+ RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>(
+ web_contents()->GetRenderWidgetHostView());
+ // If the guest is terminated, our host may already be gone.
+ if (rwhv)
+ rwhv->UnregisterSurfaceNamespaceId();
+
delegate_->DidDetach();
}
@@ -947,10 +999,10 @@ void BrowserPluginGuest::OnUpdateGeometry(int browser_plugin_instance_id,
// The plugin has moved within the embedder without resizing or the
// embedder/container's view rect changing.
guest_window_rect_ = view_rect;
- RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
- GetWebContents()->GetRenderViewHost());
- if (rvh)
- rvh->SendScreenRects();
+ RenderWidgetHostImpl* rwh = RenderWidgetHostImpl::From(
+ GetWebContents()->GetRenderViewHost()->GetWidget());
+ if (rwh)
+ rwh->SendScreenRects();
}
void BrowserPluginGuest::OnHasTouchEventHandlers(bool accept) {
@@ -966,7 +1018,7 @@ void BrowserPluginGuest::OnShowPopup(
gfx::Rect translated_bounds(params.bounds);
translated_bounds.Offset(guest_window_rect_.OffsetFromOrigin());
BrowserPluginPopupMenuHelper popup_menu_helper(
- owner_web_contents_->GetRenderViewHost(), render_frame_host);
+ owner_web_contents_->GetMainFrame(), render_frame_host);
popup_menu_helper.ShowPopupMenu(translated_bounds,
params.item_height,
params.item_font_size,
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.h b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
index f302c6d9d09..9cdc85e96d2 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
@@ -18,13 +18,17 @@
#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
#define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_
+#include <stdint.h>
+
#include <map>
#include <queue>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/common/edit_command.h"
#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/browser_plugin_guest_delegate.h"
@@ -238,7 +242,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
void PointerLockPermissionResponse(bool allow);
// The next two functions are virtual for test purposes.
- virtual void SwapCompositorFrame(uint32 output_surface_id,
+ virtual void SwapCompositorFrame(uint32_t output_surface_id,
int host_process_id,
int host_routing_id,
scoped_ptr<cc::CompositorFrame> frame);
@@ -247,14 +251,12 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
float scale_factor,
const cc::SurfaceSequence& sequence);
- void SetContentsOpaque(bool opaque);
-
// Find the given |search_text| in the page. Returns true if the find request
// is handled by this browser plugin guest.
- bool Find(int request_id,
- const base::string16& search_text,
- const blink::WebFindOptions& options);
- bool StopFinding(StopFindAction action);
+ bool HandleFindForEmbedder(int request_id,
+ const base::string16& search_text,
+ const blink::WebFindOptions& options);
+ bool HandleStopFindingForEmbedder(StopFindAction action);
void ResendEventToEmbedder(const blink::WebInputEvent& event);
@@ -386,6 +388,12 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
void OnWillAttachComplete(WebContentsImpl* embedder_web_contents,
const BrowserPluginHostMsg_Attach_Params& params);
+ // Returns identical message with current browser_plugin_instance_id() if
+ // the input was created with browser_plugin::kInstanceIdNone, else it returns
+ // the input message unmodified. If no current browser_plugin_instance_id()
+ // is set, or anything goes wrong, the input message is returned.
+ IPC::Message* UpdateInstanceIdIfNecessary(IPC::Message* msg) const;
+
// Forwards all messages from the |pending_messages_| queue to the embedder.
void SendQueuedMessages();
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_message_filter.h b/chromium/content/browser/browser_plugin/browser_plugin_message_filter.h
index 9c89f8170d8..ff17d6f5e69 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_message_filter.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_message_filter.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_MESSAGE_FILTER_H_
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
namespace content {
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h b/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h
index 31c198031b1..7dc9b6582a2 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h
@@ -5,12 +5,11 @@
#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_POPUP_MENU_HELPER_MAC_H_
#define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_POPUP_MENU_HELPER_MAC_H_
+#include "base/macros.h"
#include "content/browser/frame_host/popup_menu_helper_mac.h"
namespace content {
-class RenderViewHost;
-class RenderViewHostImpl;
class RenderFrameHost;
class RenderFrameHostImpl;
@@ -19,15 +18,15 @@ class RenderFrameHostImpl;
class BrowserPluginPopupMenuHelper : public PopupMenuHelper {
public:
// Creates a BrowserPluginPopupMenuHelper that positions popups relative to
- // |embedder_rvh| and will notify |guest_rfh| when a user selects or cancels
+ // |embedder_rfh| and will notify |guest_rfh| when a user selects or cancels
// the popup.
- BrowserPluginPopupMenuHelper(RenderViewHost* embedder_rvh,
+ BrowserPluginPopupMenuHelper(RenderFrameHostImpl* embedder_rfh,
RenderFrameHost* guest_rfh);
private:
RenderWidgetHostViewMac* GetRenderWidgetHostView() const override;
- RenderViewHostImpl* embedder_rvh_;
+ RenderFrameHostImpl* embedder_rfh_;
DISALLOW_COPY_AND_ASSIGN(BrowserPluginPopupMenuHelper);
};
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm b/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm
index 413c96fd16b..1874747f97f 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm
+++ b/chromium/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm
@@ -5,20 +5,19 @@
#include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
+#include "content/public/browser/render_widget_host.h"
namespace content {
BrowserPluginPopupMenuHelper::BrowserPluginPopupMenuHelper(
- RenderViewHost* embedder_rvh, RenderFrameHost* guest_rfh)
- : PopupMenuHelper(guest_rfh),
- embedder_rvh_(static_cast<RenderViewHostImpl*>(embedder_rvh)) {
-}
+ RenderFrameHostImpl* embedder_rfh,
+ RenderFrameHost* guest_rfh)
+ : PopupMenuHelper(guest_rfh), embedder_rfh_(embedder_rfh) {}
RenderWidgetHostViewMac*
BrowserPluginPopupMenuHelper::GetRenderWidgetHostView() const {
- return static_cast<RenderWidgetHostViewMac*>(embedder_rvh_->GetView());
+ return static_cast<RenderWidgetHostViewMac*>(embedder_rfh_->GetView());
}
} // namespace content
diff --git a/chromium/content/browser/browser_process_sub_thread.h b/chromium/content/browser/browser_process_sub_thread.h
index 5899fa31906..2276d6dca46 100644
--- a/chromium/content/browser/browser_process_sub_thread.h
+++ b/chromium/content/browser/browser_process_sub_thread.h
@@ -5,7 +5,8 @@
#ifndef CONTENT_BROWSER_BROWSER_PROCESS_SUB_THREAD_H_
#define CONTENT_BROWSER_BROWSER_PROCESS_SUB_THREAD_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/browser_shutdown_profile_dumper.h b/chromium/content/browser/browser_shutdown_profile_dumper.h
index cc8666ef69d..859811a6501 100644
--- a/chromium/content/browser/browser_shutdown_profile_dumper.h
+++ b/chromium/content/browser/browser_shutdown_profile_dumper.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_BROWSER_SHUTDOWN_PROFILE_DUMPER_H_
#define CONTENT_BROWSER_BROWSER_SHUTDOWN_PROFILE_DUMPER_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/browser_side_navigation_browsertest.cc b/chromium/content/browser/browser_side_navigation_browsertest.cc
index 98a265e8e48..3ffef7d88d2 100644
--- a/chromium/content/browser/browser_side_navigation_browsertest.cc
+++ b/chromium/content/browser/browser_side_navigation_browsertest.cc
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -31,7 +32,7 @@ class BrowserSideNavigationBrowserTest : public ContentBrowserTest {
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
}
};
@@ -137,7 +138,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
TestNavigationObserver observer(shell()->web_contents());
const char kReplacePortNumber[] =
"window.domAutomationController.send(setPortNumber(%d));";
- uint16 port_number = embedded_test_server()->port();
+ uint16_t port_number = embedded_test_server()->port();
GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
bool success = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
diff --git a/chromium/content/browser/browser_thread_impl.cc b/chromium/content/browser/browser_thread_impl.cc
index b0a24ae06c0..b86643970e5 100644
--- a/chromium/content/browser/browser_thread_impl.cc
+++ b/chromium/content/browser/browser_thread_impl.cc
@@ -4,15 +4,19 @@
#include "content/browser/browser_thread_impl.h"
+#include <string.h>
+
#include <string>
#include "base/atomicops.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread_delegate.h"
#include "content/public/browser/content_browser_client.h"
#include "net/disk_cache/simple/simple_backend_impl.h"
diff --git a/chromium/content/browser/browser_thread_unittest.cc b/chromium/content/browser/browser_thread_unittest.cc
index 9b23057f623..1c622c2793c 100644
--- a/chromium/content/browser/browser_thread_unittest.cc
+++ b/chromium/content/browser/browser_thread_unittest.cc
@@ -19,7 +19,8 @@ class BrowserThreadTest : public testing::Test {
public:
void Release() const {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- loop_.task_runner()->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
+ loop_.task_runner()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitWhenIdleClosure());
}
protected:
@@ -37,8 +38,8 @@ class BrowserThreadTest : public testing::Test {
static void BasicFunction(base::MessageLoop* message_loop) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- message_loop->task_runner()->PostTask(FROM_HERE,
- base::MessageLoop::QuitClosure());
+ message_loop->task_runner()->PostTask(
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
class DeletedOnFile
@@ -54,8 +55,8 @@ class BrowserThreadTest : public testing::Test {
~DeletedOnFile() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- message_loop_->task_runner()->PostTask(FROM_HERE,
- base::MessageLoop::QuitClosure());
+ message_loop_->task_runner()->PostTask(
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
base::MessageLoop* message_loop_;
@@ -109,10 +110,8 @@ TEST_F(BrowserThreadTest, PostTaskAndReply) {
// Most of the heavy testing for PostTaskAndReply() is done inside the
// task runner test. This just makes sure we get piped through at all.
ASSERT_TRUE(BrowserThread::PostTaskAndReply(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&base::DoNothing),
- base::Bind(&base::MessageLoop::Quit,
+ BrowserThread::FILE, FROM_HERE, base::Bind(&base::DoNothing),
+ base::Bind(&base::MessageLoop::QuitWhenIdle,
base::Unretained(base::MessageLoop::current()->current()))));
base::MessageLoop::current()->Run();
}
diff --git a/chromium/content/browser/browser_url_handler_impl.cc b/chromium/content/browser/browser_url_handler_impl.cc
index 4f1ed350da6..a79b89dda4c 100644
--- a/chromium/content/browser/browser_url_handler_impl.cc
+++ b/chromium/content/browser/browser_url_handler_impl.cc
@@ -4,6 +4,9 @@
#include "content/browser/browser_url_handler_impl.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/browser/webui/web_ui_impl.h"
diff --git a/chromium/content/browser/browser_url_handler_impl.h b/chromium/content/browser/browser_url_handler_impl.h
index c5ba416742f..6e76431d986 100644
--- a/chromium/content/browser/browser_url_handler_impl.h
+++ b/chromium/content/browser/browser_url_handler_impl.h
@@ -5,10 +5,11 @@
#ifndef CONTENT_BROWSER_BROWSER_URL_HANDLER_IMPL_H_
#define CONTENT_BROWSER_BROWSER_URL_HANDLER_IMPL_H_
-#include <vector>
#include <utility>
+#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/browser_url_handler.h"
diff --git a/chromium/content/browser/browsing_instance.h b/chromium/content/browser/browsing_instance.h
index 60518b07c4d..0cb80ac80a9 100644
--- a/chromium/content/browser/browsing_instance.h
+++ b/chromium/content/browser/browsing_instance.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_BROWSING_INSTANCE_H_
#define CONTENT_BROWSER_BROWSING_INSTANCE_H_
+#include <stddef.h>
+
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_context.h"
diff --git a/chromium/content/browser/byte_stream.cc b/chromium/content/browser/byte_stream.cc
index 5c836bd6a0a..0a8939ed349 100644
--- a/chromium/content/browser/byte_stream.cc
+++ b/chromium/content/browser/byte_stream.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
@@ -383,8 +384,8 @@ void ByteStreamReaderImpl::TransferData(
// If our target is no longer alive, do nothing.
if (!object_lifetime_flag->is_alive) return;
- target->TransferDataInternal(
- transfer_buffer.Pass(), buffer_size, source_complete, status);
+ target->TransferDataInternal(std::move(transfer_buffer), buffer_size,
+ source_complete, status);
}
void ByteStreamReaderImpl::TransferDataInternal(
diff --git a/chromium/content/browser/byte_stream.h b/chromium/content/browser/byte_stream.h
index 60b01634c5c..85906458b37 100644
--- a/chromium/content/browser/byte_stream.h
+++ b/chromium/content/browser/byte_stream.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_BYTE_STREAM_H_
#define CONTENT_BROWSER_BYTE_STREAM_H_
+#include <stddef.h>
+
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
diff --git a/chromium/content/browser/byte_stream_unittest.cc b/chromium/content/browser/byte_stream_unittest.cc
index f750cf2cdfd..4c348b72df3 100644
--- a/chromium/content/browser/byte_stream_unittest.cc
+++ b/chromium/content/browser/byte_stream_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/byte_stream.h"
+#include <stddef.h>
+
#include <deque>
#include <limits>
diff --git a/chromium/content/browser/cache_storage/cache_storage.cc b/chromium/content/browser/cache_storage/cache_storage.cc
index e385480624a..362af37e58c 100644
--- a/chromium/content/browser/cache_storage/cache_storage.cc
+++ b/chromium/content/browser/cache_storage/cache_storage.cc
@@ -4,7 +4,10 @@
#include "content/browser/cache_storage/cache_storage.h"
+#include <stddef.h>
+#include <set>
#include <string>
+#include <utility>
#include "base/barrier_closure.h"
#include "base/files/file_util.h"
@@ -34,6 +37,8 @@ namespace content {
namespace {
+const int kCachePreservationInSecs = 30;
+
std::string HexedHash(const std::string& value) {
std::string value_hash = base::SHA1HashString(value);
std::string valued_hexed_hash = base::ToLowerASCII(
@@ -151,7 +156,7 @@ class CacheStorage::MemoryLoader : public CacheStorage::CacheLoader {
void LoadIndex(scoped_ptr<std::vector<std::string>> cache_names,
const StringVectorCallback& callback) override {
- callback.Run(cache_names.Pass());
+ callback.Run(std::move(cache_names));
}
private:
@@ -325,6 +330,8 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader {
const std::string& serialized) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ scoped_ptr<std::set<std::string>> cache_dirs(new std::set<std::string>);
+
CacheStorageIndex index;
if (index.ParseFromString(serialized)) {
for (int i = 0, max = index.cache_size(); i < max; ++i) {
@@ -332,18 +339,38 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader {
DCHECK(cache.has_cache_dir());
names->push_back(cache.name());
cache_name_to_cache_dir_[cache.name()] = cache.cache_dir();
+ cache_dirs->insert(cache.cache_dir());
}
}
- // TODO(jkarlin): Delete caches that are in the directory and not returned
- // in LoadIndex.
- callback.Run(names.Pass());
+ cache_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_,
+ base::Passed(&cache_dirs)));
+ callback.Run(std::move(names));
}
private:
friend class MigratedLegacyCacheDirectoryNameTest;
~SimpleCacheLoader() override {}
+ // Iterates over the caches and deletes any directory not found in
+ // |cache_dirs|. Runs on cache_task_runner_
+ static void DeleteUnreferencedCachesInPool(
+ const base::FilePath& cache_base_dir,
+ scoped_ptr<std::set<std::string>> cache_dirs) {
+ base::FileEnumerator file_enum(cache_base_dir, false /* recursive */,
+ base::FileEnumerator::DIRECTORIES);
+ std::vector<base::FilePath> dirs_to_delete;
+ base::FilePath cache_path;
+ while (!(cache_path = file_enum.Next()).empty()) {
+ if (!ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe()))
+ dirs_to_delete.push_back(cache_path);
+ }
+
+ for (const base::FilePath& cache_path : dirs_to_delete)
+ base::DeleteFile(cache_path, true /* recursive */);
+ }
+
// Runs on cache_task_runner_
static std::string MigrateCachesIfNecessaryInPool(
const std::string& body,
@@ -510,9 +537,9 @@ void CacheStorage::MatchCache(
CacheStorageCache::ResponseCallback pending_callback =
base::Bind(&CacheStorage::PendingResponseCallback,
weak_factory_.GetWeakPtr(), callback);
- scheduler_->ScheduleOperation(
- base::Bind(&CacheStorage::MatchCacheImpl, weak_factory_.GetWeakPtr(),
- cache_name, base::Passed(request.Pass()), pending_callback));
+ scheduler_->ScheduleOperation(base::Bind(
+ &CacheStorage::MatchCacheImpl, weak_factory_.GetWeakPtr(), cache_name,
+ base::Passed(std::move(request)), pending_callback));
}
void CacheStorage::MatchAllCaches(
@@ -528,7 +555,7 @@ void CacheStorage::MatchAllCaches(
weak_factory_.GetWeakPtr(), callback);
scheduler_->ScheduleOperation(
base::Bind(&CacheStorage::MatchAllCachesImpl, weak_factory_.GetWeakPtr(),
- base::Passed(request.Pass()), pending_callback));
+ base::Passed(std::move(request)), pending_callback));
}
void CacheStorage::CloseAllCaches(const base::Closure& callback) {
@@ -546,13 +573,13 @@ void CacheStorage::CloseAllCaches(const base::Closure& callback) {
pending_callback));
}
-int64 CacheStorage::MemoryBackedSize() const {
+int64_t CacheStorage::MemoryBackedSize() const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!initialized_ || !memory_only_)
return 0;
- int64 sum = 0;
+ int64_t sum = 0;
for (auto& key_value : cache_map_) {
if (key_value.second)
sum += key_value.second->MemoryBackedSize();
@@ -596,7 +623,7 @@ void CacheStorage::LazyInitImpl() {
scoped_ptr<std::vector<std::string>> indexed_cache_names(
new std::vector<std::string>());
- cache_loader_->LoadIndex(indexed_cache_names.Pass(),
+ cache_loader_->LoadIndex(std::move(indexed_cache_names),
base::Bind(&CacheStorage::LazyInitDidLoadIndex,
weak_factory_.GetWeakPtr()));
}
@@ -648,6 +675,8 @@ void CacheStorage::CreateCacheDidCreateCache(
cache_map_.insert(std::make_pair(cache_name, cache->AsWeakPtr()));
ordered_cache_names_.push_back(cache_name);
+ TemporarilyPreserveCache(cache);
+
cache_loader_->WriteIndex(
ordered_cache_names_,
base::Bind(&CacheStorage::CreateCacheDidWriteIndex,
@@ -751,7 +780,7 @@ void CacheStorage::MatchCacheImpl(
// Pass the cache along to the callback to keep the cache open until match is
// done.
- cache->Match(request.Pass(),
+ cache->Match(std::move(request),
base::Bind(&CacheStorage::MatchCacheDidMatch,
weak_factory_.GetWeakPtr(), cache, callback));
}
@@ -762,7 +791,7 @@ void CacheStorage::MatchCacheDidMatch(
CacheStorageError error,
scoped_ptr<ServiceWorkerResponse> response,
scoped_ptr<storage::BlobDataHandle> handle) {
- callback.Run(error, response.Pass(), handle.Pass());
+ callback.Run(error, std::move(response), std::move(handle));
}
void CacheStorage::MatchAllCachesImpl(
@@ -776,7 +805,7 @@ void CacheStorage::MatchAllCachesImpl(
base::BarrierClosure(ordered_cache_names_.size(),
base::Bind(&CacheStorage::MatchAllCachesDidMatchAll,
weak_factory_.GetWeakPtr(),
- base::Passed(callback_copy.Pass())));
+ base::Passed(std::move(callback_copy))));
for (const std::string& cache_name : ordered_cache_names_) {
scoped_refptr<CacheStorageCache> cache = GetLoadedCache(cache_name);
@@ -800,7 +829,7 @@ void CacheStorage::MatchAllCachesDidMatch(
barrier_closure.Run();
return;
}
- callback->Run(error, response.Pass(), handle.Pass());
+ callback->Run(error, std::move(response), std::move(handle));
callback->Reset(); // Only call the callback once.
barrier_closure.Run();
@@ -830,12 +859,41 @@ scoped_refptr<CacheStorageCache> CacheStorage::GetLoadedCache(
scoped_refptr<CacheStorageCache> new_cache =
cache_loader_->CreateCache(cache_name);
map_iter->second = new_cache->AsWeakPtr();
+
+ TemporarilyPreserveCache(new_cache);
return new_cache;
}
return make_scoped_refptr(cache.get());
}
+void CacheStorage::TemporarilyPreserveCache(
+ const scoped_refptr<CacheStorageCache>& cache) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(!ContainsKey(preserved_caches_, cache.get()));
+
+ preserved_caches_[cache.get()] = cache;
+ SchedulePreservedCacheRemoval(base::Bind(&CacheStorage::RemovePreservedCache,
+ weak_factory_.GetWeakPtr(),
+ base::Unretained(cache.get())));
+}
+
+void CacheStorage::SchedulePreservedCacheRemoval(
+ const base::Closure& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, callback,
+ base::TimeDelta::FromSeconds(kCachePreservationInSecs));
+}
+
+void CacheStorage::RemovePreservedCache(const CacheStorageCache* cache) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(ContainsKey(preserved_caches_, cache));
+
+ preserved_caches_.erase(cache);
+}
+
void CacheStorage::CloseAllCachesImpl(const base::Closure& callback) {
int live_cache_count = 0;
for (const auto& key_value : cache_map_) {
@@ -912,7 +970,7 @@ void CacheStorage::PendingResponseCallback(
scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
base::WeakPtr<CacheStorage> cache_storage = weak_factory_.GetWeakPtr();
- callback.Run(error, response.Pass(), blob_data_handle.Pass());
+ callback.Run(error, std::move(response), std::move(blob_data_handle));
if (cache_storage)
scheduler_->CompleteOperationAndRunNext();
}
diff --git a/chromium/content/browser/cache_storage/cache_storage.h b/chromium/content/browser/cache_storage/cache_storage.h
index 6ec3e238dd0..b1bf67e75d6 100644
--- a/chromium/content/browser/cache_storage/cache_storage.h
+++ b/chromium/content/browser/cache_storage/cache_storage.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_H_
#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include "base/callback.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/cache_storage/cache_storage_cache.h"
@@ -94,7 +97,7 @@ class CONTENT_EXPORT CacheStorage {
// The size of all of the origin's contents in memory. Returns 0 if the cache
// backend is not a memory backend. Runs synchronously.
- int64 MemoryBackedSize() const;
+ int64_t MemoryBackedSize() const;
// The functions below are for tests to verify that the operations run
// serially.
@@ -102,6 +105,8 @@ class CONTENT_EXPORT CacheStorage {
void CompleteAsyncOperationForTesting();
private:
+ friend class TestCacheStorage;
+
class MemoryLoader;
class SimpleCacheLoader;
class CacheLoader;
@@ -113,6 +118,12 @@ class CONTENT_EXPORT CacheStorage {
scoped_refptr<CacheStorageCache> GetLoadedCache(
const std::string& cache_name);
+ // Holds a reference to a cache for thirty seconds.
+ void TemporarilyPreserveCache(const scoped_refptr<CacheStorageCache>& cache);
+ virtual void SchedulePreservedCacheRemoval(
+ const base::Closure& callback); // Virtual for testing.
+ void RemovePreservedCache(const CacheStorageCache* cache);
+
// Initializer and its callback are below.
void LazyInit();
void LazyInitImpl();
@@ -217,6 +228,11 @@ class CONTENT_EXPORT CacheStorage {
// Performs backend specific operations (memory vs disk).
scoped_ptr<CacheLoader> cache_loader_;
+ // Holds ref pointers to recently opened caches so that they can be reused
+ // without having the open the cache again.
+ std::map<const CacheStorageCache*, scoped_refptr<CacheStorageCache>>
+ preserved_caches_;
+
base::WeakPtrFactory<CacheStorage> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CacheStorage);
diff --git a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
index 80a666cfd04..08dffc32323 100644
--- a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
@@ -4,6 +4,8 @@
#include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
+#include <utility>
+
#include "base/logging.h"
#include "net/base/io_buffer.h"
#include "net/url_request/url_request_context.h"
@@ -39,19 +41,19 @@ void CacheStorageBlobToDiskCache::StreamBlobToCache(
DCHECK(!blob_request_);
if (!request_context_getter->GetURLRequestContext()) {
- callback.Run(entry.Pass(), false /* success */);
+ callback.Run(std::move(entry), false /* success */);
return;
}
disk_cache_body_index_ = disk_cache_body_index;
- entry_ = entry.Pass();
+ entry_ = std::move(entry);
callback_ = callback;
request_context_getter_ = request_context_getter;
blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
- blob_data_handle.Pass(), request_context_getter->GetURLRequestContext(),
- this);
+ std::move(blob_data_handle),
+ request_context_getter->GetURLRequestContext(), this);
request_context_getter_->AddObserver(this);
blob_request_->Start();
}
@@ -144,7 +146,7 @@ void CacheStorageBlobToDiskCache::RunCallbackAndRemoveObserver(bool success) {
request_context_getter_->RemoveObserver(this);
blob_request_.reset();
- callback_.Run(entry_.Pass(), success);
+ callback_.Run(std::move(entry_), success);
}
} // namespace content
diff --git a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h
index 226ebf1696f..18e6fd9730f 100644
--- a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h
+++ b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_BLOB_TO_DISK_CACHE_H_
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc
index b4e88a8c891..28e6c0c18b4 100644
--- a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc
@@ -5,6 +5,7 @@
#include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
#include <string>
+#include <utility>
#include "base/files/file_path.h"
#include "base/macros.h"
@@ -170,8 +171,8 @@ class CacheStorageBlobToDiskCacheTest : public testing::Test {
blob_storage_context_->GetBlobDataFromUUID(blob_handle_->uuid()));
cache_storage_blob_to_disk_cache_->StreamBlobToCache(
- disk_cache_entry_.Pass(), kCacheEntryIndex, url_request_context_getter_,
- new_data_handle.Pass(),
+ std::move(disk_cache_entry_), kCacheEntryIndex,
+ url_request_context_getter_, std::move(new_data_handle),
base::Bind(&CacheStorageBlobToDiskCacheTest::StreamCallback,
base::Unretained(this)));
@@ -181,7 +182,7 @@ class CacheStorageBlobToDiskCacheTest : public testing::Test {
}
void StreamCallback(disk_cache::ScopedEntryPtr entry_ptr, bool success) {
- disk_cache_entry_ = entry_ptr.Pass();
+ disk_cache_entry_ = std::move(entry_ptr);
callback_success_ = success;
callback_called_ = true;
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.cc b/chromium/content/browser/cache_storage/cache_storage_cache.cc
index 687f6908c04..2fc74110e7e 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.cc
@@ -4,11 +4,14 @@
#include "content/browser/cache_storage/cache_storage_cache.h"
+#include <stddef.h>
#include <string>
+#include <utility>
#include "base/barrier_closure.h"
#include "base/files/file_path.h"
#include "base/guid.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -40,7 +43,7 @@ class CacheStorageCacheDataHandle
public:
CacheStorageCacheDataHandle(const scoped_refptr<CacheStorageCache>& cache,
disk_cache::ScopedEntryPtr entry)
- : cache_(cache), entry_(entry.Pass()) {}
+ : cache_(cache), entry_(std::move(entry)) {}
private:
~CacheStorageCacheDataHandle() override {}
@@ -177,7 +180,7 @@ void ReadMetadataDidReadMetadata(
return;
}
- callback.Run(metadata.Pass());
+ callback.Run(std::move(metadata));
}
} // namespace
@@ -257,9 +260,9 @@ struct CacheStorageCache::PutContext {
const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
: origin(origin),
- request(request.Pass()),
- response(response.Pass()),
- blob_data_handle(blob_data_handle.Pass()),
+ request(std::move(request)),
+ response(std::move(response)),
+ blob_data_handle(std::move(blob_data_handle)),
callback(callback),
request_context_getter(request_context_getter),
quota_manager_proxy(quota_manager_proxy) {}
@@ -321,7 +324,7 @@ void CacheStorageCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
weak_ptr_factory_.GetWeakPtr(), callback);
scheduler_->ScheduleOperation(
base::Bind(&CacheStorageCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(request.Pass()), pending_callback));
+ base::Passed(std::move(request)), pending_callback));
}
void CacheStorageCache::MatchAll(const ResponsesCallback& callback) {
@@ -350,8 +353,9 @@ void CacheStorageCache::BatchOperation(
scoped_ptr<ErrorCallback> callback_copy(new ErrorCallback(callback));
ErrorCallback* callback_ptr = callback_copy.get();
base::Closure barrier_closure = base::BarrierClosure(
- operations.size(), base::Bind(&CacheStorageCache::BatchDidAllOperations,
- this, base::Passed(callback_copy.Pass())));
+ operations.size(),
+ base::Bind(&CacheStorageCache::BatchDidAllOperations, this,
+ base::Passed(std::move(callback_copy))));
ErrorCallback completion_callback =
base::Bind(&CacheStorageCache::BatchDidOneOperation, this,
barrier_closure, callback_ptr);
@@ -423,7 +427,7 @@ void CacheStorageCache::Close(const base::Closure& callback) {
pending_callback));
}
-int64 CacheStorageCache::MemoryBackedSize() const {
+int64_t CacheStorageCache::MemoryBackedSize() const {
if (backend_state_ != BACKEND_OPEN || !memory_only_)
return 0;
@@ -431,7 +435,7 @@ int64 CacheStorageCache::MemoryBackedSize() const {
backend_->CreateIterator();
disk_cache::Entry* entry = nullptr;
- int64 sum = 0;
+ int64_t sum = 0;
std::vector<disk_cache::Entry*> entries;
int rv = net::OK;
@@ -492,7 +496,7 @@ void CacheStorageCache::OpenAllEntries(const OpenAllEntriesCallback& callback) {
net::CompletionCallback open_entry_callback = base::Bind(
&CacheStorageCache::DidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(entries_context.Pass()), callback);
+ base::Passed(std::move(entries_context)), callback);
int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
@@ -507,17 +511,17 @@ void CacheStorageCache::DidOpenNextEntry(
if (rv == net::ERR_FAILED) {
DCHECK(!entries_context->enumerated_entry);
// Enumeration is complete, extract the requests from the entries.
- callback.Run(entries_context.Pass(), CACHE_STORAGE_OK);
+ callback.Run(std::move(entries_context), CACHE_STORAGE_OK);
return;
}
if (rv < 0) {
- callback.Run(entries_context.Pass(), CACHE_STORAGE_ERROR_STORAGE);
+ callback.Run(std::move(entries_context), CACHE_STORAGE_ERROR_STORAGE);
return;
}
if (backend_state_ != BACKEND_OPEN) {
- callback.Run(entries_context.Pass(), CACHE_STORAGE_ERROR_NOT_FOUND);
+ callback.Run(std::move(entries_context), CACHE_STORAGE_ERROR_NOT_FOUND);
return;
}
@@ -530,7 +534,7 @@ void CacheStorageCache::DidOpenNextEntry(
disk_cache::Entry** enumerated_entry = &entries_context->enumerated_entry;
net::CompletionCallback open_entry_callback = base::Bind(
&CacheStorageCache::DidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(entries_context.Pass()), callback);
+ base::Passed(std::move(entries_context)), callback);
rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
@@ -552,10 +556,10 @@ void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request,
disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
ServiceWorkerFetchRequest* request_ptr = request.get();
- net::CompletionCallback open_entry_callback =
- base::Bind(&CacheStorageCache::MatchDidOpenEntry,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(request.Pass()),
- callback, base::Passed(scoped_entry_ptr.Pass()));
+ net::CompletionCallback open_entry_callback = base::Bind(
+ &CacheStorageCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(std::move(request)), callback,
+ base::Passed(std::move(scoped_entry_ptr)));
int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr,
open_entry_callback);
@@ -578,7 +582,8 @@ void CacheStorageCache::MatchDidOpenEntry(
MetadataCallback headers_callback = base::Bind(
&CacheStorageCache::MatchDidReadMetadata, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(request.Pass()), callback, base::Passed(entry.Pass()));
+ base::Passed(std::move(request)), callback,
+ base::Passed(std::move(entry)));
ReadMetadata(*entry_ptr, headers_callback);
}
@@ -615,7 +620,7 @@ void CacheStorageCache::MatchDidReadMetadata(
}
if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
- callback.Run(CACHE_STORAGE_OK, response.Pass(),
+ callback.Run(CACHE_STORAGE_OK, std::move(response),
scoped_ptr<storage::BlobDataHandle>());
return;
}
@@ -628,8 +633,9 @@ void CacheStorageCache::MatchDidReadMetadata(
}
scoped_ptr<storage::BlobDataHandle> blob_data_handle =
- PopulateResponseBody(entry.Pass(), response.get());
- callback.Run(CACHE_STORAGE_OK, response.Pass(), blob_data_handle.Pass());
+ PopulateResponseBody(std::move(entry), response.get());
+ callback.Run(CACHE_STORAGE_OK, std::move(response),
+ std::move(blob_data_handle));
}
void CacheStorageCache::MatchAllImpl(const ResponsesCallback& callback) {
@@ -656,7 +662,7 @@ void CacheStorageCache::MatchAllDidOpenAllEntries(
scoped_ptr<MatchAllContext> context(new MatchAllContext(callback));
context->entries_context.swap(entries_context);
Entries::iterator iter = context->entries_context->entries.begin();
- MatchAllProcessNextEntry(context.Pass(), iter);
+ MatchAllProcessNextEntry(std::move(context), iter);
}
void CacheStorageCache::MatchAllProcessNextEntry(
@@ -665,14 +671,14 @@ void CacheStorageCache::MatchAllProcessNextEntry(
if (iter == context->entries_context->entries.end()) {
// All done. Return all of the responses.
context->original_callback.Run(CACHE_STORAGE_OK,
- context->out_responses.Pass(),
- context->out_blob_data_handles.Pass());
+ std::move(context->out_responses),
+ std::move(context->out_blob_data_handles));
return;
}
ReadMetadata(*iter, base::Bind(&CacheStorageCache::MatchAllDidReadMetadata,
weak_ptr_factory_.GetWeakPtr(),
- base::Passed(context.Pass()), iter));
+ base::Passed(std::move(context)), iter));
}
void CacheStorageCache::MatchAllDidReadMetadata(
@@ -685,7 +691,7 @@ void CacheStorageCache::MatchAllDidReadMetadata(
if (!metadata) {
entry->Doom();
- MatchAllProcessNextEntry(context.Pass(), iter + 1);
+ MatchAllProcessNextEntry(std::move(context), iter + 1);
return;
}
@@ -694,7 +700,7 @@ void CacheStorageCache::MatchAllDidReadMetadata(
if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
context->out_responses->push_back(response);
- MatchAllProcessNextEntry(context.Pass(), iter + 1);
+ MatchAllProcessNextEntry(std::move(context), iter + 1);
return;
}
@@ -706,11 +712,11 @@ void CacheStorageCache::MatchAllDidReadMetadata(
}
scoped_ptr<storage::BlobDataHandle> blob_data_handle =
- PopulateResponseBody(entry.Pass(), &response);
+ PopulateResponseBody(std::move(entry), &response);
context->out_responses->push_back(response);
context->out_blob_data_handles->push_back(*blob_data_handle);
- MatchAllProcessNextEntry(context.Pass(), iter + 1);
+ MatchAllProcessNextEntry(std::move(context), iter + 1);
}
void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
@@ -755,13 +761,14 @@ void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
base::Bind(&CacheStorageCache::PendingErrorCallback,
weak_ptr_factory_.GetWeakPtr(), callback);
- scoped_ptr<PutContext> put_context(new PutContext(
- origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(),
- pending_callback, request_context_getter_, quota_manager_proxy_));
+ scoped_ptr<PutContext> put_context(
+ new PutContext(origin_, std::move(request), std::move(response),
+ std::move(blob_data_handle), pending_callback,
+ request_context_getter_, quota_manager_proxy_));
- scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::PutImpl,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(put_context.Pass())));
+ scheduler_->ScheduleOperation(
+ base::Bind(&CacheStorageCache::PutImpl, weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(std::move(put_context))));
}
void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) {
@@ -774,9 +781,10 @@ void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) {
scoped_ptr<ServiceWorkerFetchRequest> request_copy(
new ServiceWorkerFetchRequest(*put_context->request));
- DeleteImpl(request_copy.Pass(), base::Bind(&CacheStorageCache::PutDidDelete,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(put_context.Pass())));
+ DeleteImpl(std::move(request_copy),
+ base::Bind(&CacheStorageCache::PutDidDelete,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(std::move(put_context))));
}
void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context,
@@ -793,7 +801,8 @@ void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context,
net::CompletionCallback create_entry_callback = base::Bind(
&CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(scoped_entry_ptr.Pass()), base::Passed(put_context.Pass()));
+ base::Passed(std::move(scoped_entry_ptr)),
+ base::Passed(std::move(put_context)));
int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr,
create_entry_callback);
@@ -806,11 +815,12 @@ void CacheStorageCache::PutDidCreateEntry(
scoped_ptr<disk_cache::Entry*> entry_ptr,
scoped_ptr<PutContext> put_context,
int rv) {
+ put_context->cache_entry.reset(*entry_ptr);
+
if (rv != net::OK) {
put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS);
return;
}
- put_context->cache_entry.reset(*entry_ptr);
CacheMetadata metadata;
CacheRequest* request_metadata = metadata.mutable_request();
@@ -848,14 +858,14 @@ void CacheStorageCache::PutDidCreateEntry(
}
scoped_refptr<net::StringIOBuffer> buffer(
- new net::StringIOBuffer(serialized.Pass()));
+ new net::StringIOBuffer(std::move(serialized)));
// Get a temporary copy of the entry pointer before passing it in base::Bind.
disk_cache::Entry* temp_entry_ptr = put_context->cache_entry.get();
net::CompletionCallback write_headers_callback = base::Bind(
&CacheStorageCache::PutDidWriteHeaders, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(put_context.Pass()), buffer->size());
+ base::Passed(std::move(put_context)), buffer->size());
rv = temp_entry_ptr->WriteData(INDEX_HEADERS, 0 /* offset */, buffer.get(),
buffer->size(), write_headers_callback,
@@ -891,7 +901,7 @@ void CacheStorageCache::PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
DCHECK(put_context->blob_data_handle);
- disk_cache::ScopedEntryPtr entry(put_context->cache_entry.Pass());
+ disk_cache::ScopedEntryPtr entry(std::move(put_context->cache_entry));
put_context->cache_entry = NULL;
CacheStorageBlobToDiskCache* blob_to_cache =
@@ -903,14 +913,14 @@ void CacheStorageCache::PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
scoped_refptr<net::URLRequestContextGetter> request_context_getter =
put_context->request_context_getter;
scoped_ptr<storage::BlobDataHandle> blob_data_handle =
- put_context->blob_data_handle.Pass();
+ std::move(put_context->blob_data_handle);
blob_to_cache->StreamBlobToCache(
- entry.Pass(), INDEX_RESPONSE_BODY, request_context_getter,
- blob_data_handle.Pass(),
+ std::move(entry), INDEX_RESPONSE_BODY, request_context_getter,
+ std::move(blob_data_handle),
base::Bind(&CacheStorageCache::PutDidWriteBlobToCache,
weak_ptr_factory_.GetWeakPtr(),
- base::Passed(put_context.Pass()), blob_to_cache_key));
+ base::Passed(std::move(put_context)), blob_to_cache_key));
}
void CacheStorageCache::PutDidWriteBlobToCache(
@@ -919,7 +929,7 @@ void CacheStorageCache::PutDidWriteBlobToCache(
disk_cache::ScopedEntryPtr entry,
bool success) {
DCHECK(entry);
- put_context->cache_entry = entry.Pass();
+ put_context->cache_entry = std::move(entry);
active_blob_to_disk_cache_writers_.Remove(blob_to_cache_key);
@@ -956,7 +966,7 @@ void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation,
weak_ptr_factory_.GetWeakPtr(), callback);
scheduler_->ScheduleOperation(
base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(request.Pass()), pending_callback));
+ base::Passed(std::move(request)), pending_callback));
}
void CacheStorageCache::DeleteImpl(
@@ -975,8 +985,8 @@ void CacheStorageCache::DeleteImpl(
net::CompletionCallback open_entry_callback = base::Bind(
&CacheStorageCache::DeleteDidOpenEntry, weak_ptr_factory_.GetWeakPtr(),
- origin_, base::Passed(request.Pass()), callback,
- base::Passed(entry.Pass()), quota_manager_proxy_);
+ origin_, base::Passed(std::move(request)), callback,
+ base::Passed(std::move(entry)), quota_manager_proxy_);
int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr,
open_entry_callback);
@@ -1044,7 +1054,7 @@ void CacheStorageCache::KeysDidOpenAllEntries(
scoped_ptr<KeysContext> keys_context(new KeysContext(callback));
keys_context->entries_context.swap(entries_context);
Entries::iterator iter = keys_context->entries_context->entries.begin();
- KeysProcessNextEntry(keys_context.Pass(), iter);
+ KeysProcessNextEntry(std::move(keys_context), iter);
}
void CacheStorageCache::KeysProcessNextEntry(
@@ -1053,13 +1063,13 @@ void CacheStorageCache::KeysProcessNextEntry(
if (iter == keys_context->entries_context->entries.end()) {
// All done. Return all of the keys.
keys_context->original_callback.Run(CACHE_STORAGE_OK,
- keys_context->out_keys.Pass());
+ std::move(keys_context->out_keys));
return;
}
ReadMetadata(*iter, base::Bind(&CacheStorageCache::KeysDidReadMetadata,
weak_ptr_factory_.GetWeakPtr(),
- base::Passed(keys_context.Pass()), iter));
+ base::Passed(std::move(keys_context)), iter));
}
void CacheStorageCache::KeysDidReadMetadata(
@@ -1086,7 +1096,7 @@ void CacheStorageCache::KeysDidReadMetadata(
entry->Doom();
}
- KeysProcessNextEntry(keys_context.Pass(), iter + 1);
+ KeysProcessNextEntry(std::move(keys_context), iter + 1);
}
void CacheStorageCache::CloseImpl(const base::Closure& callback) {
@@ -1111,7 +1121,7 @@ void CacheStorageCache::CreateBackend(const ErrorCallback& callback) {
net::CompletionCallback create_cache_callback =
base::Bind(&CacheStorageCache::CreateBackendDidCreate,
weak_ptr_factory_.GetWeakPtr(), callback,
- base::Passed(backend_ptr.Pass()));
+ base::Passed(std::move(backend_ptr)));
// TODO(jkarlin): Use the cache task runner that ServiceWorkerCacheCore
// has for disk caches.
@@ -1133,7 +1143,7 @@ void CacheStorageCache::CreateBackendDidCreate(
return;
}
- backend_ = backend_ptr->Pass();
+ backend_ = std::move(*backend_ptr);
callback.Run(CACHE_STORAGE_OK);
}
@@ -1189,7 +1199,7 @@ void CacheStorageCache::PendingResponseCallback(
scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
- callback.Run(error, response.Pass(), blob_data_handle.Pass());
+ callback.Run(error, std::move(response), std::move(blob_data_handle));
if (cache)
scheduler_->CompleteOperationAndRunNext();
}
@@ -1201,7 +1211,7 @@ void CacheStorageCache::PendingResponsesCallback(
scoped_ptr<BlobDataHandles> blob_data_handles) {
base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
- callback.Run(error, responses.Pass(), blob_data_handles.Pass());
+ callback.Run(error, std::move(responses), std::move(blob_data_handles));
if (cache)
scheduler_->CompleteOperationAndRunNext();
}
@@ -1212,7 +1222,7 @@ void CacheStorageCache::PendingRequestsCallback(
scoped_ptr<Requests> requests) {
base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
- callback.Run(error, requests.Pass());
+ callback.Run(error, std::move(requests));
if (cache)
scheduler_->CompleteOperationAndRunNext();
}
@@ -1247,7 +1257,7 @@ scoped_ptr<storage::BlobDataHandle> CacheStorageCache::PopulateResponseBody(
disk_cache::Entry* temp_entry = entry.get();
blob_data.AppendDiskCacheEntry(
- new CacheStorageCacheDataHandle(this, entry.Pass()), temp_entry,
+ new CacheStorageCacheDataHandle(this, std::move(entry)), temp_entry,
INDEX_RESPONSE_BODY);
return blob_storage_context_->AddFinishedBlob(&blob_data);
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.h b/chromium/content/browser/cache_storage/cache_storage_cache.h
index 75d0c86fc92..a9dcd4cccaf 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.h
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_CACHE_H_
#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_CACHE_H_
+#include <stdint.h>
+
#include <vector>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/id_map.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/cache_storage/cache_storage_types.h"
@@ -105,7 +108,7 @@ class CONTENT_EXPORT CacheStorageCache
// The size of the cache contents in memory. Returns 0 if the cache backend is
// not a memory cache backend.
- int64 MemoryBackedSize() const;
+ int64_t MemoryBackedSize() const;
base::FilePath path() const { return path_; }
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
index 88363a7c4d9..b440758990e 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -4,8 +4,13 @@
#include "content/browser/cache_storage/cache_storage_cache.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
@@ -51,13 +56,13 @@ scoped_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler(
class DelayableBackend : public disk_cache::Backend {
public:
DelayableBackend(scoped_ptr<disk_cache::Backend> backend)
- : backend_(backend.Pass()), delay_open_(false) {}
+ : backend_(std::move(backend)), delay_open_(false) {}
// disk_cache::Backend overrides
net::CacheType GetCacheType() const override {
return backend_->GetCacheType();
}
- int32 GetEntryCount() const override { return backend_->GetEntryCount(); }
+ int32_t GetEntryCount() const override { return backend_->GetEntryCount(); }
int OpenEntry(const std::string& key,
disk_cache::Entry** entry,
const CompletionCallback& callback) override {
@@ -91,6 +96,10 @@ class DelayableBackend : public disk_cache::Backend {
const CompletionCallback& callback) override {
return backend_->DoomEntriesSince(initial_time, callback);
}
+ int CalculateSizeOfAllEntries(
+ const CompletionCallback& callback) override {
+ return backend_->CalculateSizeOfAllEntries(callback);
+ }
scoped_ptr<Iterator> CreateIterator() override {
return backend_->CreateIterator();
}
@@ -135,7 +144,7 @@ void CopyBody(const storage::BlobDataHandle& blob_handle, std::string* output) {
}
case storage::DataElement::TYPE_DISK_CACHE_ENTRY: {
disk_cache::Entry* entry = item->disk_cache_entry();
- int32 body_size = entry->GetDataSize(item->disk_cache_stream_index());
+ int32_t body_size = entry->GetDataSize(item->disk_cache_stream_index());
scoped_refptr<net::IOBuffer> io_buffer = new net::IOBuffer(body_size);
net::TestCompletionCallback callback;
@@ -226,7 +235,8 @@ class TestCacheStorageCache : public CacheStorageCache {
// created before calling this.
DelayableBackend* UseDelayableBackend() {
EXPECT_TRUE(backend_);
- DelayableBackend* delayable_backend = new DelayableBackend(backend_.Pass());
+ DelayableBackend* delayable_backend =
+ new DelayableBackend(std::move(backend_));
backend_.reset(delayable_backend);
return delayable_backend;
}
@@ -438,10 +448,10 @@ class CacheStorageCacheTest : public testing::Test {
scoped_ptr<ServiceWorkerResponse> response,
scoped_ptr<storage::BlobDataHandle> body_handle) {
callback_error_ = error;
- callback_response_ = response.Pass();
+ callback_response_ = std::move(response);
callback_response_data_.reset();
if (error == CACHE_STORAGE_OK && !callback_response_->blob_uuid.empty())
- callback_response_data_ = body_handle.Pass();
+ callback_response_data_ = std::move(body_handle);
if (run_loop)
run_loop->Quit();
@@ -500,13 +510,13 @@ class CacheStorageCacheTest : public testing::Test {
virtual bool MemoryOnly() { return false; }
protected:
+ base::ScopedTempDir temp_dir_;
TestBrowserContext browser_context_;
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
storage::BlobStorageContext* blob_storage_context_;
- base::ScopedTempDir temp_dir_;
scoped_refptr<TestCacheStorageCache> cache_;
ServiceWorkerFetchRequest body_request_;
@@ -908,7 +918,7 @@ TEST_P(CacheStorageCacheTestP, QuotaManagerModified) {
EXPECT_TRUE(Put(no_body_request_, no_body_response_));
EXPECT_EQ(1, quota_manager_proxy_->notify_storage_modified_count());
EXPECT_LT(0, quota_manager_proxy_->last_notified_delta());
- int64 sum_delta = quota_manager_proxy_->last_notified_delta();
+ int64_t sum_delta = quota_manager_proxy_->last_notified_delta();
EXPECT_TRUE(Put(body_request_, body_response_));
EXPECT_EQ(2, quota_manager_proxy_->notify_storage_modified_count());
@@ -930,7 +940,7 @@ TEST_F(CacheStorageCacheMemoryOnlyTest, MemoryBackedSize) {
EXPECT_EQ(0, cache_->MemoryBackedSize());
EXPECT_TRUE(Put(no_body_request_, no_body_response_));
EXPECT_LT(0, cache_->MemoryBackedSize());
- int64 no_body_size = cache_->MemoryBackedSize();
+ int64_t no_body_size = cache_->MemoryBackedSize();
EXPECT_TRUE(Delete(no_body_request_));
EXPECT_EQ(0, cache_->MemoryBackedSize());
diff --git a/chromium/content/browser/cache_storage/cache_storage_context_impl.cc b/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
index 29bb50ccb4c..83aa12d6cdc 100644
--- a/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
@@ -36,7 +36,7 @@ void CacheStorageContextImpl::Init(
base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
scoped_refptr<base::SequencedTaskRunner> cache_task_runner =
pool->GetSequencedTaskRunnerWithShutdownBehavior(
- BrowserThread::GetBlockingPool()->GetSequenceToken(),
+ base::SequencedWorkerPool::GetSequenceToken(),
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
// This thread-hopping antipattern is needed here for some unit tests, where
diff --git a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
index 3dd8d45ec15..073f57d8027 100644
--- a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -4,8 +4,12 @@
#include "content/browser/cache_storage/cache_storage_dispatcher_host.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
@@ -23,7 +27,7 @@ namespace content {
namespace {
-const uint32 kFilteredMessageClasses[] = {CacheStorageMsgStart};
+const uint32_t kFilteredMessageClasses[] = {CacheStorageMsgStart};
blink::WebServiceWorkerCacheError ToWebServiceWorkerCacheError(
CacheStorageError err) {
@@ -187,13 +191,14 @@ void CacheStorageDispatcherHost::OnCacheStorageMatch(
if (match_params.cache_name.empty()) {
context_->cache_manager()->MatchAllCaches(
- origin, scoped_request.Pass(),
+ origin, std::move(scoped_request),
base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback,
this, thread_id, request_id));
return;
}
context_->cache_manager()->MatchCache(
- origin, base::UTF16ToUTF8(match_params.cache_name), scoped_request.Pass(),
+ origin, base::UTF16ToUTF8(match_params.cache_name),
+ std::move(scoped_request),
base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback, this,
thread_id, request_id));
}
@@ -216,7 +221,7 @@ void CacheStorageDispatcherHost::OnCacheMatch(
new ServiceWorkerFetchRequest(request.url, request.method,
request.headers, request.referrer,
request.is_reload));
- cache->Match(scoped_request.Pass(),
+ cache->Match(std::move(scoped_request),
base::Bind(&CacheStorageDispatcherHost::OnCacheMatchCallback,
this, thread_id, request_id, cache));
}
@@ -247,7 +252,7 @@ void CacheStorageDispatcherHost::OnCacheMatchAll(
request.headers, request.referrer,
request.is_reload));
cache->Match(
- scoped_request.Pass(),
+ std::move(scoped_request),
base::Bind(&CacheStorageDispatcherHost::OnCacheMatchAllCallbackAdapter,
this, thread_id, request_id, cache));
}
@@ -416,8 +421,8 @@ void CacheStorageDispatcherHost::OnCacheMatchAllCallbackAdapter(
if (blob_data_handle)
blob_data_handles->push_back(*blob_data_handle);
}
- OnCacheMatchAllCallback(thread_id, request_id, cache, error, responses.Pass(),
- blob_data_handles.Pass());
+ OnCacheMatchAllCallback(thread_id, request_id, cache, error,
+ std::move(responses), std::move(blob_data_handles));
}
void CacheStorageDispatcherHost::OnCacheMatchAllCallback(
diff --git a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h
index 966d4612577..77435096db2 100644
--- a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h
+++ b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_DISPATCHER_HOST_H_
+#include <stdint.h>
+
#include <list>
+#include "base/macros.h"
#include "content/browser/cache_storage/cache_storage.h"
#include "content/public/browser/browser_message_filter.h"
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager.cc b/chromium/content/browser/cache_storage/cache_storage_manager.cc
index 939797d71e8..cd02deb0a0f 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager.cc
@@ -4,8 +4,10 @@
#include "content/browser/cache_storage/cache_storage_manager.h"
+#include <stdint.h>
#include <map>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/files/file_enumerator.h"
@@ -72,7 +74,7 @@ std::vector<CacheStorageUsageInfo> GetAllOriginsUsageOnTaskRunner(
for (const GURL& origin : origins) {
base::FilePath path =
CacheStorageManager::ConstructOriginPath(root_path, origin);
- int64 size = base::ComputeDirectorySize(path);
+ int64_t size = base::ComputeDirectorySize(path);
base::File::Info file_info;
base::Time last_modified;
if (base::GetFileInfo(path, &file_info))
@@ -123,16 +125,10 @@ scoped_ptr<CacheStorageManager> CacheStorageManager::Create(
// the dispatcher host per usual.
manager->SetBlobParametersForCache(old_manager->url_request_context_getter(),
old_manager->blob_storage_context());
- return manager.Pass();
+ return manager;
}
-CacheStorageManager::~CacheStorageManager() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- for (CacheStorageMap::iterator it = cache_storage_map_.begin();
- it != cache_storage_map_.end(); ++it) {
- delete it->second;
- }
-}
+CacheStorageManager::~CacheStorageManager() = default;
void CacheStorageManager::OpenCache(
const GURL& origin,
@@ -182,7 +178,7 @@ void CacheStorageManager::MatchCache(
const CacheStorageCache::ResponseCallback& callback) {
CacheStorage* cache_storage = FindOrCreateCacheStorage(origin);
- cache_storage->MatchCache(cache_name, request.Pass(), callback);
+ cache_storage->MatchCache(cache_name, std::move(request), callback);
}
void CacheStorageManager::MatchAllCaches(
@@ -191,7 +187,7 @@ void CacheStorageManager::MatchAllCaches(
const CacheStorageCache::ResponseCallback& callback) {
CacheStorage* cache_storage = FindOrCreateCacheStorage(origin);
- cache_storage->MatchAllCaches(request.Pass(), callback);
+ cache_storage->MatchAllCaches(std::move(request), callback);
}
void CacheStorageManager::SetBlobParametersForCache(
@@ -235,7 +231,7 @@ void CacheStorageManager::GetOriginUsage(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (IsMemoryBacked()) {
- int64 usage = 0;
+ int64_t usage = 0;
if (ContainsKey(cache_storage_map_, origin_url))
usage = cache_storage_map_[origin_url]->MemoryBackedSize();
callback.Run(usage);
@@ -294,7 +290,13 @@ void CacheStorageManager::DeleteOriginData(
const storage::QuotaClient::DeletionCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- CacheStorage* cache_storage = FindOrCreateCacheStorage(origin);
+ CacheStorageMap::iterator it = cache_storage_map_.find(origin);
+ if (it == cache_storage_map_.end()) {
+ callback.Run(storage::kQuotaStatusOk);
+ return;
+ }
+
+ CacheStorage* cache_storage = it->second.release();
cache_storage_map_.erase(origin);
cache_storage->CloseAllCaches(
base::Bind(&CacheStorageManager::DeleteOriginDidClose, origin, callback,
@@ -361,11 +363,11 @@ CacheStorage* CacheStorageManager::FindOrCreateCacheStorage(
ConstructOriginPath(root_path_, origin), IsMemoryBacked(),
cache_task_runner_.get(), request_context_getter_, quota_manager_proxy_,
blob_context_, origin);
- // The map owns fetch_stores.
- cache_storage_map_.insert(std::make_pair(origin, cache_storage));
+ cache_storage_map_.insert(
+ std::make_pair(origin, make_scoped_ptr(cache_storage)));
return cache_storage;
}
- return it->second;
+ return it->second.get();
}
// static
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager.h b/chromium/content/browser/cache_storage/cache_storage_manager.h
index 0499f95524d..121a25228d3 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager.h
+++ b/chromium/content/browser/cache_storage/cache_storage_manager.h
@@ -8,8 +8,8 @@
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/cache_storage/cache_storage.h"
#include "content/common/content_export.h"
@@ -83,14 +83,15 @@ class CONTENT_EXPORT CacheStorageManager {
return weak_ptr_factory_.GetWeakPtr();
}
+ base::FilePath root_path() const { return root_path_; }
+
private:
friend class CacheStorageContextImpl;
friend class CacheStorageManagerTest;
friend class CacheStorageMigrationTest;
friend class CacheStorageQuotaClient;
- friend class MigratedLegacyCacheDirectoryNameTest;
- typedef std::map<GURL, CacheStorage*> CacheStorageMap;
+ typedef std::map<GURL, scoped_ptr<CacheStorage>> CacheStorageMap;
CacheStorageManager(
const base::FilePath& path,
@@ -122,10 +123,11 @@ class CONTENT_EXPORT CacheStorageManager {
const {
return request_context_getter_;
}
+
base::WeakPtr<storage::BlobStorageContext> blob_storage_context() const {
return blob_context_;
}
- base::FilePath root_path() const { return root_path_; }
+
const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner() const {
return cache_task_runner_;
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
index 04c6a6a87a7..f8d94976e2b 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -4,10 +4,15 @@
#include "content/browser/cache_storage/cache_storage_manager.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/sha1.h"
#include "base/stl_util.h"
@@ -131,8 +136,8 @@ class CacheStorageManagerTest : public testing::Test {
scoped_ptr<ServiceWorkerResponse> response,
scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
callback_error_ = error;
- callback_cache_response_ = response.Pass();
- callback_data_handle_ = blob_data_handle.Pass();
+ callback_cache_response_ = std::move(response);
+ callback_data_handle_ = std::move(blob_data_handle);
run_loop->Quit();
}
@@ -192,7 +197,7 @@ class CacheStorageManagerTest : public testing::Test {
request->url = url;
base::RunLoop loop;
cache_manager_->MatchCache(
- origin, cache_name, request.Pass(),
+ origin, cache_name, std::move(request),
base::Bind(&CacheStorageManagerTest::CacheMatchCallback,
base::Unretained(this), base::Unretained(&loop)));
loop.Run();
@@ -206,7 +211,7 @@ class CacheStorageManagerTest : public testing::Test {
request->url = url;
base::RunLoop loop;
cache_manager_->MatchAllCaches(
- origin, request.Pass(),
+ origin, std::move(request),
base::Bind(&CacheStorageManagerTest::CacheMatchCallback,
base::Unretained(this), base::Unretained(&loop)));
loop.Run();
@@ -251,7 +256,7 @@ class CacheStorageManagerTest : public testing::Test {
new ServiceWorkerFetchRequest());
request->url = url;
base::RunLoop loop;
- cache->Match(request.Pass(),
+ cache->Match(std::move(request),
base::Bind(&CacheStorageManagerTest::CacheMatchCallback,
base::Unretained(this), base::Unretained(&loop)));
loop.Run();
@@ -263,7 +268,7 @@ class CacheStorageManagerTest : public testing::Test {
return cache_manager_->FindOrCreateCacheStorage(origin);
}
- int64 GetOriginUsage(const GURL& origin) {
+ int64_t GetOriginUsage(const GURL& origin) {
base::RunLoop loop;
cache_manager_->GetOriginUsage(
origin, base::Bind(&CacheStorageManagerTest::UsageCallback,
@@ -272,7 +277,7 @@ class CacheStorageManagerTest : public testing::Test {
return callback_usage_;
}
- void UsageCallback(base::RunLoop* run_loop, int64 usage) {
+ void UsageCallback(base::RunLoop* run_loop, int64_t usage) {
callback_usage_ = usage;
run_loop->Quit();
}
@@ -294,12 +299,14 @@ class CacheStorageManagerTest : public testing::Test {
}
protected:
+ // Temporary directory must be allocated first so as to be destroyed last.
+ base::ScopedTempDir temp_dir_;
+
TestBrowserContext browser_context_;
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
storage::BlobStorageContext* blob_storage_context_;
- base::ScopedTempDir temp_dir_;
scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
scoped_ptr<CacheStorageManager> cache_manager_;
@@ -313,7 +320,7 @@ class CacheStorageManagerTest : public testing::Test {
const GURL origin1_;
const GURL origin2_;
- int64 callback_usage_;
+ int64_t callback_usage_;
std::vector<CacheStorageUsageInfo> callback_all_origins_usage_;
private:
@@ -464,7 +471,7 @@ TEST_F(CacheStorageManagerTest, StorageReuseCacheName) {
EXPECT_TRUE(CachePut(callback_cache_, kTestURL));
EXPECT_TRUE(CacheMatch(callback_cache_, kTestURL));
scoped_ptr<storage::BlobDataHandle> data_handle =
- callback_data_handle_.Pass();
+ std::move(callback_data_handle_);
EXPECT_TRUE(Delete(origin1_, "foo"));
// The cache is deleted but the handle to one of its entries is still
@@ -560,27 +567,6 @@ TEST_F(CacheStorageManagerTest, BadOriginName) {
EXPECT_STREQ("foo", callback_strings_[0].c_str());
}
-// With a persistent cache if the client drops its reference to a
-// CacheStorageCache
-// it should be deleted.
-TEST_F(CacheStorageManagerTest, DropReference) {
- EXPECT_TRUE(Open(origin1_, "foo"));
- base::WeakPtr<CacheStorageCache> cache = callback_cache_->AsWeakPtr();
- callback_cache_ = NULL;
- EXPECT_TRUE(!cache);
-}
-
-// With a memory cache the cache can't be freed from memory until the client
-// calls delete.
-TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) {
- EXPECT_TRUE(Open(origin1_, "foo"));
- base::WeakPtr<CacheStorageCache> cache = callback_cache_->AsWeakPtr();
- callback_cache_ = NULL;
- EXPECT_TRUE(cache);
- EXPECT_TRUE(Delete(origin1_, "foo"));
- EXPECT_FALSE(cache);
-}
-
TEST_P(CacheStorageManagerTestP, DeleteBeforeRelease) {
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_TRUE(Delete(origin1_, "foo"));
@@ -641,7 +627,7 @@ TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryBackedSize) {
EXPECT_TRUE(CachePut(foo_cache, GURL("http://example.com/foo")));
EXPECT_LT(0, cache_storage->MemoryBackedSize());
- int64 foo_size = cache_storage->MemoryBackedSize();
+ int64_t foo_size = cache_storage->MemoryBackedSize();
EXPECT_TRUE(CachePut(bar_cache, GURL("http://example.com/foo")));
EXPECT_EQ(foo_size * 2, cache_storage->MemoryBackedSize());
@@ -655,6 +641,31 @@ TEST_F(CacheStorageManagerTest, MemoryBackedSizePersistent) {
EXPECT_EQ(0, cache_storage->MemoryBackedSize());
}
+TEST_F(CacheStorageManagerTest, DeleteUnreferencedCacheDirectories) {
+ // Create a referenced cache.
+ EXPECT_TRUE(Open(origin1_, "foo"));
+ EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo")));
+
+ // Create an unreferenced directory next to the referenced one.
+ base::FilePath origin_path = CacheStorageManager::ConstructOriginPath(
+ cache_manager_->root_path(), origin1_);
+ base::FilePath unreferenced_path = origin_path.AppendASCII("bar");
+ EXPECT_TRUE(CreateDirectory(unreferenced_path));
+ EXPECT_TRUE(base::DirectoryExists(unreferenced_path));
+
+ // Create a new StorageManager so that the next time the cache is opened
+ // the unreferenced directory can be deleted.
+ quota_manager_proxy_->SimulateQuotaManagerDestroyed();
+ cache_manager_ = CacheStorageManager::Create(cache_manager_.get());
+
+ // Verify that the referenced cache still works.
+ EXPECT_TRUE(Open(origin1_, "foo"));
+ EXPECT_TRUE(CacheMatch(callback_cache_, GURL("http://example.com/foo")));
+
+ // Verify that the unreferenced cache is gone.
+ EXPECT_FALSE(base::DirectoryExists(unreferenced_path));
+}
+
class CacheStorageMigrationTest : public CacheStorageManagerTest {
protected:
CacheStorageMigrationTest() : cache1_("foo"), cache2_("bar") {}
@@ -766,8 +777,8 @@ class MigratedLegacyCacheDirectoryNameTest : public CacheStorageManagerTest {
EXPECT_TRUE(CachePut(callback_cache_, stored_url_));
base::FilePath new_path = callback_cache_->path();
- // Close the cache.
- callback_cache_ = nullptr;
+ // Close the cache's backend so that the files can be moved.
+ callback_cache_->Close(base::Bind(&base::DoNothing));
base::RunLoop().RunUntilIdle();
// Legacy index files didn't have the cache directory, so remove it from the
@@ -849,7 +860,7 @@ class CacheStorageQuotaClientTest : public CacheStorageManagerTest {
new CacheStorageQuotaClient(cache_manager_->AsWeakPtr()));
}
- void QuotaUsageCallback(base::RunLoop* run_loop, int64 usage) {
+ void QuotaUsageCallback(base::RunLoop* run_loop, int64_t usage) {
callback_quota_usage_ = usage;
run_loop->Quit();
}
@@ -865,7 +876,7 @@ class CacheStorageQuotaClientTest : public CacheStorageManagerTest {
run_loop->Quit();
}
- int64 QuotaGetOriginUsage(const GURL& origin) {
+ int64_t QuotaGetOriginUsage(const GURL& origin) {
base::RunLoop loop;
quota_client_->GetOriginUsage(
origin, storage::kStorageTypeTemporary,
@@ -912,7 +923,7 @@ class CacheStorageQuotaClientTest : public CacheStorageManagerTest {
scoped_ptr<CacheStorageQuotaClient> quota_client_;
storage::QuotaStatusCode callback_status_;
- int64 callback_quota_usage_ = 0;
+ int64_t callback_quota_usage_ = 0;
std::set<GURL> callback_origins_;
DISALLOW_COPY_AND_ASSIGN(CacheStorageQuotaClientTest);
diff --git a/chromium/content/browser/cache_storage/cache_storage_quota_client.h b/chromium/content/browser/cache_storage/cache_storage_quota_client.h
index 94df1d9f1a4..941bf8ba98d 100644
--- a/chromium/content/browser/cache_storage/cache_storage_quota_client.h
+++ b/chromium/content/browser/cache_storage/cache_storage_quota_client.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_QUOTA_CLIENT_H_
#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_QUOTA_CLIENT_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "storage/browser/quota/quota_client.h"
diff --git a/chromium/content/browser/cache_storage/cache_storage_scheduler.h b/chromium/content/browser/cache_storage/cache_storage_scheduler.h
index dec6cbe7295..d5a48778dac 100644
--- a/chromium/content/browser/cache_storage/cache_storage_scheduler.h
+++ b/chromium/content/browser/cache_storage/cache_storage_scheduler.h
@@ -8,6 +8,7 @@
#include <list>
#include "base/callback.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
namespace content {
diff --git a/chromium/content/browser/cache_storage/cache_storage_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_unittest.cc
new file mode 100644
index 00000000000..faf0eb10635
--- /dev/null
+++ b/chromium/content/browser/cache_storage/cache_storage_unittest.cc
@@ -0,0 +1,121 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/cache_storage/cache_storage.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/run_loop.h"
+#include "base/stl_util.h"
+#include "base/thread_task_runner_handle.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+const char kOrigin[] = "http://example.com/";
+}
+
+class TestCacheStorage : public CacheStorage {
+ public:
+ explicit TestCacheStorage(const base::FilePath& file_path)
+ : CacheStorage(file_path,
+ false /* memory_only */,
+ base::ThreadTaskRunnerHandle::Get().get(),
+ scoped_refptr<net::URLRequestContextGetter>(),
+ scoped_refptr<storage::QuotaManagerProxy>(),
+ base::WeakPtr<storage::BlobStorageContext>(),
+ GURL(kOrigin)),
+ delay_preserved_cache_callback_(false) {}
+
+ void RunPreservedCacheCallback() {
+ ASSERT_FALSE(preserved_cache_callback_.is_null());
+ preserved_cache_callback_.Run();
+ preserved_cache_callback_.Reset();
+ }
+
+ void set_delay_preserved_cache_callback(bool should_delay) {
+ delay_preserved_cache_callback_ = should_delay;
+ }
+
+ bool IsPreservingCache(const CacheStorageCache* cache) {
+ return ContainsKey(preserved_caches_, cache);
+ }
+
+ private:
+ void SchedulePreservedCacheRemoval(const base::Closure& callback) override {
+ if (!delay_preserved_cache_callback_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
+ return;
+ }
+ preserved_cache_callback_ = callback;
+ }
+
+ bool delay_preserved_cache_callback_;
+ base::Closure preserved_cache_callback_;
+};
+
+class CacheStorageTest : public testing::Test {
+ protected:
+ CacheStorageTest()
+ : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
+
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ test_cache_storage_.reset(new TestCacheStorage(temp_dir_.path()));
+ }
+
+ bool OpenCache(const std::string& cache_name) {
+ bool callback_called = false;
+ test_cache_storage_->OpenCache(
+ cache_name, base::Bind(&CacheStorageTest::OpenCacheCallback,
+ base::Unretained(this), &callback_called));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(callback_called);
+ return callback_error_ == CACHE_STORAGE_OK;
+ }
+
+ void OpenCacheCallback(bool* callback_called,
+ const scoped_refptr<CacheStorageCache>& cache,
+ CacheStorageError error) {
+ *callback_called = true;
+ callback_cache_ = cache;
+ callback_error_ = error;
+ }
+
+ base::ScopedTempDir temp_dir_;
+ TestBrowserThreadBundle browser_thread_bundle_;
+ scoped_ptr<TestCacheStorage> test_cache_storage_;
+
+ scoped_refptr<CacheStorageCache> callback_cache_;
+ CacheStorageError callback_error_;
+};
+
+TEST_F(CacheStorageTest, PreserveCache) {
+ test_cache_storage_->set_delay_preserved_cache_callback(true);
+ EXPECT_TRUE(OpenCache("foo"));
+ EXPECT_TRUE(test_cache_storage_->IsPreservingCache(callback_cache_.get()));
+ test_cache_storage_->RunPreservedCacheCallback();
+ EXPECT_FALSE(test_cache_storage_->IsPreservingCache(callback_cache_.get()));
+
+ // Try opening it again, since the cache is already open (callback_cache_ is
+ // referencing it) the cache shouldn't be preserved again.
+ EXPECT_TRUE(OpenCache("foo"));
+ EXPECT_FALSE(test_cache_storage_->IsPreservingCache(callback_cache_.get()));
+
+ // Remove the reference to the cache so that it's deleted. After that, the
+ // next time it's opened will require the cache to be created again and
+ // preserved.
+ callback_cache_ = nullptr;
+ EXPECT_TRUE(OpenCache("foo"));
+ EXPECT_TRUE(test_cache_storage_->IsPreservingCache(callback_cache_.get()));
+ test_cache_storage_->RunPreservedCacheCallback();
+ EXPECT_FALSE(test_cache_storage_->IsPreservingCache(callback_cache_.get()));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/cert_store_impl.h b/chromium/content/browser/cert_store_impl.h
index f5afe83db69..2b08c52c802 100644
--- a/chromium/content/browser/cert_store_impl.h
+++ b/chromium/content/browser/cert_store_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_CERT_STORE_IMPL_H_
#define CONTENT_BROWSER_CERT_STORE_IMPL_H_
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/browser/renderer_data_memoizing_store.h"
#include "content/public/browser/cert_store.h"
diff --git a/chromium/content/browser/child_process_launcher.cc b/chromium/content/browser/child_process_launcher.cc
index 53d21fdb289..57a6368cb7d 100644
--- a/chromium/content/browser/child_process_launcher.cc
+++ b/chromium/content/browser/child_process_launcher.cc
@@ -4,6 +4,8 @@
#include "content/browser/child_process_launcher.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
@@ -12,9 +14,10 @@
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/process/process.h"
-#include "base/profiler/scoped_tracker.h"
+#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
+#include "build/build_config.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
@@ -27,7 +30,6 @@
#include "content/public/common/sandbox_init.h"
#elif defined(OS_MACOSX)
#include "content/browser/bootstrap_sandbox_manager_mac.h"
-#include "content/browser/browser_io_surface_manager_mac.h"
#include "content/browser/mach_broker_mac.h"
#include "sandbox/mac/bootstrap_sandbox.h"
#include "sandbox/mac/pre_exec_delegate.h"
@@ -139,7 +141,7 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
#if defined(OS_ANDROID)
files_to_register->Share(kPrimaryIPCChannel, ipcfd.get());
#else
- files_to_register->Transfer(kPrimaryIPCChannel, ipcfd.Pass());
+ files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd));
#endif
#endif
@@ -188,7 +190,7 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
CHECK(!cmd_line->HasSwitch(switches::kSingleProcess));
StartChildProcess(
- cmd_line->argv(), child_process_id, files_to_register.Pass(), regions,
+ cmd_line->argv(), child_process_id, std::move(files_to_register), regions,
base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id,
begin_launch_time, base::Passed(&ipcfd)));
@@ -199,7 +201,7 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
#if !defined(OS_MACOSX)
if (use_zygote) {
base::ProcessHandle handle = ZygoteHostImpl::GetInstance()->ForkRequest(
- cmd_line->argv(), files_to_register.Pass(), process_type);
+ cmd_line->argv(), std::move(files_to_register), process_type);
process = base::Process(handle);
} else
// Fall through to the normal posix case below when we're not zygoting.
@@ -240,17 +242,13 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
// check-in from the new process.
broker->EnsureRunning();
- // Make sure the IOSurfaceManager service is running.
- BrowserIOSurfaceManager::GetInstance()->EnsureRunning();
-
const SandboxType sandbox_type = delegate->GetSandboxType();
scoped_ptr<sandbox::PreExecDelegate> pre_exec_delegate;
if (BootstrapSandboxManager::ShouldEnable()) {
BootstrapSandboxManager* sandbox_manager =
BootstrapSandboxManager::GetInstance();
if (sandbox_manager->EnabledForSandbox(sandbox_type)) {
- pre_exec_delegate =
- sandbox_manager->sandbox()->NewClient(sandbox_type).Pass();
+ pre_exec_delegate = sandbox_manager->sandbox()->NewClient(sandbox_type);
}
}
options.pre_exec_delegate = pre_exec_delegate.get();
@@ -305,7 +303,7 @@ void TerminateOnLauncherThread(bool zygote, base::Process process) {
ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(process.Handle());
} else
#endif // !OS_MACOSX
- base::EnsureProcessTerminated(process.Pass());
+ base::EnsureProcessTerminated(std::move(process));
#endif // OS_POSIX
#endif // defined(OS_ANDROID)
}
@@ -321,7 +319,7 @@ void SetProcessBackgroundedOnLauncherThread(base::Process process,
#endif
}
-} // anonymous namespace
+} // namespace
ChildProcessLauncher::ChildProcessLauncher(
SandboxedProcessLauncherDelegate* delegate,
@@ -444,24 +442,13 @@ void ChildProcessLauncher::DidLaunch(
if (!process.IsValid())
LOG(ERROR) << "Failed to launch child process";
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile1(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 ChildProcessLauncher::Context::Notify::Start"));
-
if (instance.get()) {
instance->Notify(zygote,
#if defined(OS_ANDROID)
- ipcfd.Pass(),
+ std::move(ipcfd),
#endif
- process.Pass());
+ std::move(process));
} else {
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile4(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 ChildProcessLauncher::Context::Notify::ProcessTerminate"));
if (process.IsValid() && terminate_on_shutdown) {
// On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So
// don't this on the UI/IO threads.
@@ -480,24 +467,14 @@ void ChildProcessLauncher::Notify(
base::Process process) {
DCHECK(CalledOnValidThread());
starting_ = false;
- process_ = process.Pass();
+ process_ = std::move(process);
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
zygote_ = zygote;
#endif
if (process_.IsValid()) {
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile2(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 ChildProcessLauncher::Context::Notify::ProcessLaunched"));
client_->OnProcessLaunched();
} else {
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile3(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 ChildProcessLauncher::Context::Notify::ProcessFailed"));
termination_status_ = base::TERMINATION_STATUS_LAUNCH_FAILED;
client_->OnProcessLaunchFailed();
}
diff --git a/chromium/content/browser/child_process_launcher.h b/chromium/content/browser/child_process_launcher.h
index 2d647f40877..c4f63210af1 100644
--- a/chromium/content/browser/child_process_launcher.h
+++ b/chromium/content/browser/child_process_launcher.h
@@ -5,13 +5,14 @@
#ifndef CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_
#define CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_
-#include "base/basictypes.h"
#include "base/files/scoped_file.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/threading/non_thread_safe.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
@@ -107,6 +108,15 @@ class CONTENT_EXPORT ChildProcessLauncher : public base::NonThreadSafe {
#endif
base::Process process);
+#if defined(MOJO_SHELL_CLIENT)
+ // When this process is run from an external Mojo shell, this function will
+ // create a channel and pass one end to the spawned process and register the
+ // other end with the external shell, allowing the spawned process to bind an
+ // Application request from the shell.
+ void CreateMojoShellChannel(base::CommandLine* command_line,
+ int child_process_id);
+#endif
+
Client* client_;
BrowserThread::ID client_thread_id_;
base::Process process_;
diff --git a/chromium/content/browser/child_process_security_policy_browsertest.cc b/chromium/content/browser/child_process_security_policy_browsertest.cc
index c1e3c3959e9..30d85db73b3 100644
--- a/chromium/content/browser/child_process_security_policy_browsertest.cc
+++ b/chromium/content/browser/child_process_security_policy_browsertest.cc
@@ -4,8 +4,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_process_host.h"
diff --git a/chromium/content/browser/child_process_security_policy_impl.cc b/chromium/content/browser/child_process_security_policy_impl.cc
index 9e94f34602d..639401fc731 100644
--- a/chromium/content/browser/child_process_security_policy_impl.cc
+++ b/chromium/content/browser/child_process_security_policy_impl.cc
@@ -9,9 +9,11 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
+#include "build/build_config.h"
#include "content/browser/plugin_process_host.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/site_isolation_policy.h"
diff --git a/chromium/content/browser/child_process_security_policy_impl.h b/chromium/content/browser/child_process_security_policy_impl.h
index cc5a69948ee..46d2d7a6e96 100644
--- a/chromium/content/browser/child_process_security_policy_impl.h
+++ b/chromium/content/browser/child_process_security_policy_impl.h
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/child_process_security_policy.h"
diff --git a/chromium/content/browser/child_process_security_policy_unittest.cc b/chromium/content/browser/child_process_security_policy_unittest.cc
index 6cba102e288..23604683ad3 100644
--- a/chromium/content/browser/child_process_security_policy_unittest.cc
+++ b/chromium/content/browser/child_process_security_policy_unittest.cc
@@ -5,7 +5,6 @@
#include <set>
#include <string>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/public/common/url_constants.h"
diff --git a/chromium/content/browser/cocoa/system_hotkey_helper_mac.h b/chromium/content/browser/cocoa/system_hotkey_helper_mac.h
index 7cfe1658ef5..d8e0153fd63 100644
--- a/chromium/content/browser/cocoa/system_hotkey_helper_mac.h
+++ b/chromium/content/browser/cocoa/system_hotkey_helper_mac.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_COCOA_SYSTEM_HOTKEY_HELPER_MAC_H_
#define CONTENT_BROWSER_COCOA_SYSTEM_HOTKEY_HELPER_MAC_H_
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/content/browser/compositor/DEPS b/chromium/content/browser/compositor/DEPS
index 1701f72a861..70240ed5c1d 100644
--- a/chromium/content/browser/compositor/DEPS
+++ b/chromium/content/browser/compositor/DEPS
@@ -1,3 +1,4 @@
include_rules = [
- "+ui/platform_window",
+ "+components/bitmap_uploader",
+ "+ui/platform_window",
]
diff --git a/chromium/content/browser/compositor/browser_compositor_output_surface.cc b/chromium/content/browser/compositor/browser_compositor_output_surface.cc
index bdf3a1b2de6..f865702effe 100644
--- a/chromium/content/browser/compositor/browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/browser_compositor_output_surface.cc
@@ -4,6 +4,8 @@
#include "content/browser/compositor/browser_compositor_output_surface.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
@@ -27,18 +29,19 @@ BrowserCompositorOutputSurface::BrowserCompositorOutputSurface(
use_begin_frame_scheduling_(
base::CommandLine::ForCurrentProcess()
->HasSwitch(cc::switches::kEnableBeginFrameScheduling)) {
- overlay_candidate_validator_ = overlay_candidate_validator.Pass();
+ overlay_candidate_validator_ = std::move(overlay_candidate_validator);
Initialize();
}
BrowserCompositorOutputSurface::BrowserCompositorOutputSurface(
scoped_ptr<cc::SoftwareOutputDevice> software_device,
const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager)
- : OutputSurface(software_device.Pass()),
+ : OutputSurface(std::move(software_device)),
vsync_manager_(vsync_manager),
reflector_(nullptr),
- use_begin_frame_scheduling_(base::CommandLine::ForCurrentProcess()->
- HasSwitch(cc::switches::kEnableBeginFrameScheduling)) {
+ use_begin_frame_scheduling_(
+ base::CommandLine::ForCurrentProcess()
+ ->HasSwitch(cc::switches::kEnableBeginFrameScheduling)) {
Initialize();
}
@@ -56,7 +59,6 @@ BrowserCompositorOutputSurface::~BrowserCompositorOutputSurface() {
}
void BrowserCompositorOutputSurface::Initialize() {
- capabilities_.max_frames_pending = 1;
capabilities_.adjust_deadline_for_parent = false;
}
diff --git a/chromium/content/browser/compositor/browser_compositor_output_surface.h b/chromium/content/browser/compositor/browser_compositor_output_surface.h
index f5da02d5695..6e5ac7796b2 100644
--- a/chromium/content/browser/compositor/browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/browser_compositor_output_surface.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
#define CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
+#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
+#include "build/build_config.h"
#include "cc/output/output_surface.h"
#include "content/common/content_export.h"
#include "ui/compositor/compositor_vsync_manager.h"
@@ -14,6 +16,10 @@ namespace cc {
class SoftwareOutputDevice;
}
+namespace gfx {
+enum class SwapResult;
+}
+
namespace content {
class BrowserCompositorOverlayCandidateValidator;
class ContextProviderCommandBuffer;
@@ -46,8 +52,12 @@ class CONTENT_EXPORT BrowserCompositorOutputSurface
// compositors have started composition.
virtual base::Closure CreateCompositionStartedCallback();
+ // Called when a swap completion is sent from the GPU process.
+ virtual void OnGpuSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) = 0;
+
#if defined(OS_MACOSX)
- virtual void OnSurfaceDisplayed() = 0;
virtual void SetSurfaceSuspendedForRecycle(bool suspended) = 0;
virtual bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const = 0;
#endif
diff --git a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator.h b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator.h
index 0c62e2bb14d..933e7bf34d2 100644
--- a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator.h
+++ b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator.h
@@ -7,6 +7,7 @@
#include "cc/output/overlay_candidate_validator.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
namespace content {
diff --git a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.cc b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.cc
new file mode 100644
index 00000000000..12e4a76826f
--- /dev/null
+++ b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.cc
@@ -0,0 +1,50 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h"
+
+#include "cc/output/overlay_processor.h"
+#include "cc/output/overlay_strategy_underlay.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+
+namespace content {
+
+BrowserCompositorOverlayCandidateValidatorAndroid::
+ BrowserCompositorOverlayCandidateValidatorAndroid() {}
+
+BrowserCompositorOverlayCandidateValidatorAndroid::
+ ~BrowserCompositorOverlayCandidateValidatorAndroid() {}
+
+void BrowserCompositorOverlayCandidateValidatorAndroid::GetStrategies(
+ cc::OverlayProcessor::StrategyList* strategies) {
+ strategies->push_back(make_scoped_ptr(new cc::OverlayStrategyUnderlay(this)));
+}
+
+void BrowserCompositorOverlayCandidateValidatorAndroid::CheckOverlaySupport(
+ cc::OverlayCandidateList* candidates) {
+ // There should only be at most a single overlay candidate: the video quad.
+ // There's no check that the presented candidate is really a video frame for
+ // a fullscreen video. Instead it's assumed that if a quad is marked as
+ // overlayable, it's a fullscreen video quad.
+ DCHECK_LE(candidates->size(), 1u);
+
+ if (!candidates->empty()) {
+ cc::OverlayCandidate& candidate = candidates->front();
+ candidate.display_rect =
+ gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect));
+ candidate.overlay_handled = true;
+ candidate.plane_z_order = -1;
+ }
+}
+
+bool BrowserCompositorOverlayCandidateValidatorAndroid::AllowCALayerOverlays() {
+ return false;
+}
+
+// Overlays will still be allowed when software mirroring is enabled, even
+// though they won't appear in the mirror.
+void BrowserCompositorOverlayCandidateValidatorAndroid::SetSoftwareMirrorMode(
+ bool enabled) {}
+
+} // namespace content
diff --git a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h
new file mode 100644
index 00000000000..6cbb1a96270
--- /dev/null
+++ b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h
@@ -0,0 +1,40 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
+#define CONTENT_BROWSER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
+
+#include "base/macros.h"
+#include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// An overlay validator for supporting fullscreen video underlays on Android.
+// Things are a bit different on Android compared with other platforms. By the
+// time a video frame is marked as overlayable it means the video decoder was
+// outputting to a Surface that we can't read back from. As a result, the
+// overlay must always succeed, or the video won't be visible. This is one of of
+// the reasons that only fullscreen is supported: we have to be sure that
+// nothing will cause the overlay to be rejected, because there's no fallback to
+// gl compositing.
+class CONTENT_EXPORT BrowserCompositorOverlayCandidateValidatorAndroid
+ : public BrowserCompositorOverlayCandidateValidator {
+ public:
+ BrowserCompositorOverlayCandidateValidatorAndroid();
+ ~BrowserCompositorOverlayCandidateValidatorAndroid() override;
+
+ void GetStrategies(cc::OverlayProcessor::StrategyList* strategies) override;
+ void CheckOverlaySupport(cc::OverlayCandidateList* surfaces) override;
+ bool AllowCALayerOverlays() override;
+
+ void SetSoftwareMirrorMode(bool enabled) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BrowserCompositorOverlayCandidateValidatorAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
diff --git a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h
index c2ccf65d6e8..d3b1bd11d2d 100644
--- a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h
+++ b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
#define CONTENT_BROWSER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
#include "ui/gfx/native_widget_types.h"
@@ -20,6 +21,7 @@ class CONTENT_EXPORT BrowserCompositorOverlayCandidateValidatorMac
// cc::OverlayCandidateValidator implementation.
void GetStrategies(cc::OverlayProcessor::StrategyList* strategies) override;
+ bool AllowCALayerOverlays() override;
void CheckOverlaySupport(cc::OverlayCandidateList* surfaces) override;
// BrowserCompositorOverlayCandidateValidator implementation.
diff --git a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
index 492fcacf0c0..2b1c3eca645 100644
--- a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
+++ b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
@@ -4,6 +4,8 @@
#include "content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h"
+#include <stddef.h>
+
#include "cc/output/overlay_strategy_sandwich.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
@@ -26,8 +28,12 @@ BrowserCompositorOverlayCandidateValidatorMac::
void BrowserCompositorOverlayCandidateValidatorMac::GetStrategies(
cc::OverlayProcessor::StrategyList* strategies) {
- strategies->push_back(scoped_ptr<cc::OverlayProcessor::Strategy>(
- new cc::OverlayStrategyCommon(this, new cc::OverlayStrategySandwich)));
+}
+
+bool BrowserCompositorOverlayCandidateValidatorMac::AllowCALayerOverlays() {
+ if (software_mirror_active_ || ca_layers_disabled_)
+ return false;
+ return true;
}
void BrowserCompositorOverlayCandidateValidatorMac::CheckOverlaySupport(
diff --git a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.cc b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.cc
index 818a0b97c0f..dae75cf5d86 100644
--- a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.cc
+++ b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.cc
@@ -4,6 +4,9 @@
#include "content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h"
+#include <stddef.h>
+#include <utility>
+
#include "cc/output/overlay_strategy_single_on_top.h"
#include "cc/output/overlay_strategy_underlay.h"
#include "ui/ozone/public/overlay_candidates_ozone.h"
@@ -27,9 +30,8 @@ BrowserCompositorOverlayCandidateValidatorOzone::
gfx::AcceleratedWidget widget,
scoped_ptr<ui::OverlayCandidatesOzone> overlay_candidates)
: widget_(widget),
- overlay_candidates_(overlay_candidates.Pass()),
- software_mirror_active_(false) {
-}
+ overlay_candidates_(std::move(overlay_candidates)),
+ software_mirror_active_(false) {}
BrowserCompositorOverlayCandidateValidatorOzone::
~BrowserCompositorOverlayCandidateValidatorOzone() {
@@ -37,10 +39,13 @@ BrowserCompositorOverlayCandidateValidatorOzone::
void BrowserCompositorOverlayCandidateValidatorOzone::GetStrategies(
cc::OverlayProcessor::StrategyList* strategies) {
- strategies->push_back(scoped_ptr<cc::OverlayProcessor::Strategy>(
- new cc::OverlayStrategyCommon(this, new cc::OverlayStrategySingleOnTop)));
- strategies->push_back(scoped_ptr<cc::OverlayProcessor::Strategy>(
- new cc::OverlayStrategyCommon(this, new cc::OverlayStrategyUnderlay)));
+ strategies->push_back(
+ make_scoped_ptr(new cc::OverlayStrategySingleOnTop(this)));
+ strategies->push_back(make_scoped_ptr(new cc::OverlayStrategyUnderlay(this)));
+}
+
+bool BrowserCompositorOverlayCandidateValidatorOzone::AllowCALayerOverlays() {
+ return false;
}
void BrowserCompositorOverlayCandidateValidatorOzone::CheckOverlaySupport(
diff --git a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h
index 42942299f93..0ad48559f23 100644
--- a/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h
+++ b/chromium/content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
#define CONTENT_BROWSER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
#include "ui/gfx/native_widget_types.h"
@@ -25,6 +26,7 @@ class CONTENT_EXPORT BrowserCompositorOverlayCandidateValidatorOzone
// cc::OverlayCandidateValidator implementation.
void GetStrategies(cc::OverlayProcessor::StrategyList* strategies) override;
+ bool AllowCALayerOverlays() override;
void CheckOverlaySupport(cc::OverlayCandidateList* surfaces) override;
// BrowserCompositorOverlayCandidateValidator implementation.
diff --git a/chromium/content/browser/compositor/browser_compositor_view_mac.h b/chromium/content/browser/compositor/browser_compositor_view_mac.h
index 28b824eedc9..c6ee6ffe345 100644
--- a/chromium/content/browser/compositor/browser_compositor_view_mac.h
+++ b/chromium/content/browser/compositor/browser_compositor_view_mac.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_VIEW_MAC_H_
#define CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_VIEW_MAC_H_
+#include "base/macros.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_observer.h"
diff --git a/chromium/content/browser/compositor/browser_compositor_view_mac.mm b/chromium/content/browser/compositor/browser_compositor_view_mac.mm
index ab0133d7ca0..4670ed02ced 100644
--- a/chromium/content/browser/compositor/browser_compositor_view_mac.mm
+++ b/chromium/content/browser/compositor/browser_compositor_view_mac.mm
@@ -4,6 +4,10 @@
#include "content/browser/compositor/browser_compositor_view_mac.h"
+#include <stdint.h>
+
+#include <utility>
+
#include "base/lazy_instance.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/compositor/image_transport_factory.h"
@@ -26,7 +30,7 @@ bool g_has_shut_down = false;
// The number of placeholder objects allocated. If this reaches zero, then
// the BrowserCompositorMac being held on to for recycling,
// |g_recyclable_browser_compositor|, will be freed.
-uint32 g_placeholder_count = 0;
+uint32_t g_placeholder_count = 0;
// A spare BrowserCompositorMac kept around for recycling.
base::LazyInstance<scoped_ptr<BrowserCompositorMac>>
@@ -44,7 +48,7 @@ BrowserCompositorMac::BrowserCompositorMac()
new ui::AcceleratedWidgetMac(WidgetNeedsGLFinishWorkaround())),
compositor_(content::GetContextFactory(),
ui::WindowResizeHelperMac::Get()->task_runner()) {
- compositor_.SetAcceleratedWidgetAndStartCompositor(
+ compositor_.SetAcceleratedWidget(
accelerated_widget_mac_->accelerated_widget());
compositor_.SetLocksWillTimeOut(false);
Suspend();
@@ -74,8 +78,8 @@ void BrowserCompositorMac::OnCompositingDidCommit(
scoped_ptr<BrowserCompositorMac> BrowserCompositorMac::Create() {
DCHECK(ui::WindowResizeHelperMac::Get()->task_runner());
if (g_recyclable_browser_compositor.Get())
- return g_recyclable_browser_compositor.Get().Pass();
- return scoped_ptr<BrowserCompositorMac>(new BrowserCompositorMac).Pass();
+ return std::move(g_recyclable_browser_compositor.Get());
+ return scoped_ptr<BrowserCompositorMac>(new BrowserCompositorMac);
}
// static
diff --git a/chromium/content/browser/compositor/buffer_queue.cc b/chromium/content/browser/compositor/buffer_queue.cc
index e22ec38d586..cb6bd7933ab 100644
--- a/chromium/content/browser/compositor/buffer_queue.cc
+++ b/chromium/content/browser/compositor/buffer_queue.cc
@@ -4,6 +4,8 @@
#include "content/browser/compositor/buffer_queue.h"
+#include "base/containers/adapters.h"
+#include "build/build_config.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
@@ -51,10 +53,12 @@ void BufferQueue::BindFramebuffer() {
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
- if (!current_surface_.texture) {
+ if (!current_surface_)
current_surface_ = GetNextSurface();
+
+ if (current_surface_) {
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- texture_target_, current_surface_.texture, 0);
+ texture_target_, current_surface_->texture, 0);
}
}
@@ -69,33 +73,41 @@ void BufferQueue::CopyBufferDamage(int texture,
}
void BufferQueue::UpdateBufferDamage(const gfx::Rect& damage) {
- displayed_surface_.damage.Union(damage);
- for (size_t i = 0; i < available_surfaces_.size(); i++)
- available_surfaces_[i].damage.Union(damage);
-
- for (std::deque<AllocatedSurface>::iterator it =
- in_flight_surfaces_.begin();
- it != in_flight_surfaces_.end();
- ++it)
- it->damage.Union(damage);
+ if (displayed_surface_)
+ displayed_surface_->damage.Union(damage);
+ for (auto& surface : available_surfaces_)
+ surface->damage.Union(damage);
+ for (auto& surface : in_flight_surfaces_) {
+ if (surface)
+ surface->damage.Union(damage);
+ }
}
void BufferQueue::SwapBuffers(const gfx::Rect& damage) {
- if (damage != gfx::Rect(size_)) {
- // We must have a frame available to copy from.
- DCHECK(!in_flight_surfaces_.empty() || displayed_surface_.texture);
- unsigned int texture_id = !in_flight_surfaces_.empty()
- ? in_flight_surfaces_.back().texture
- : displayed_surface_.texture;
-
- CopyBufferDamage(current_surface_.texture, texture_id, damage,
- current_surface_.damage);
+ if (current_surface_) {
+ if (!damage.IsEmpty() && damage != gfx::Rect(size_)) {
+ // Copy damage from the most recently swapped buffer. In the event that
+ // the buffer was destroyed and failed to recreate, pick from the most
+ // recently available buffer.
+ unsigned int texture_id = 0;
+ for (auto& surface : base::Reversed(in_flight_surfaces_)) {
+ if (surface) {
+ texture_id = surface->texture;
+ break;
+ }
+ }
+ if (!texture_id && displayed_surface_)
+ texture_id = displayed_surface_->texture;
+
+ if (texture_id) {
+ CopyBufferDamage(current_surface_->texture, texture_id, damage,
+ current_surface_->damage);
+ }
+ }
+ current_surface_->damage = gfx::Rect();
}
UpdateBufferDamage(damage);
- current_surface_.damage = gfx::Rect();
- in_flight_surfaces_.push_back(current_surface_);
- current_surface_.texture = 0;
- current_surface_.image = 0;
+ in_flight_surfaces_.push_back(std::move(current_surface_));
// Some things reset the framebuffer (CopySubBufferDamage, some GLRenderer
// paths), so ensure we restore it here.
context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
@@ -108,7 +120,7 @@ void BufferQueue::Reshape(const gfx::Size& size, float scale_factor) {
// is cause for concern or if it is benign.
// http://crbug.com/524624
#if !defined(OS_MACOSX)
- DCHECK(!current_surface_.texture);
+ DCHECK(!current_surface_);
#endif
size_ = size;
@@ -126,80 +138,76 @@ void BufferQueue::RecreateBuffers() {
// presentable on the device anymore.
// Unused buffers can be freed directly, they will be re-allocated as needed.
// Any in flight, current or displayed surface must be replaced.
- for (size_t i = 0; i < available_surfaces_.size(); i++)
- FreeSurface(&available_surfaces_[i]);
available_surfaces_.clear();
+ // Recreate all in-flight surfaces and put the recreated copies in the queue.
for (auto& surface : in_flight_surfaces_)
- surface = RecreateBuffer(&surface);
+ surface = RecreateBuffer(std::move(surface));
- current_surface_ = RecreateBuffer(&current_surface_);
- displayed_surface_ = RecreateBuffer(&displayed_surface_);
+ current_surface_ = RecreateBuffer(std::move(current_surface_));
+ displayed_surface_ = RecreateBuffer(std::move(displayed_surface_));
- if (current_surface_.texture) {
+ if (current_surface_) {
// If we have a texture bound, we will need to re-bind it.
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- texture_target_, current_surface_.texture, 0);
+ texture_target_, current_surface_->texture, 0);
}
}
-BufferQueue::AllocatedSurface BufferQueue::RecreateBuffer(
- AllocatedSurface* surface) {
- if (!surface->texture)
- return *surface;
- AllocatedSurface new_surface = GetNextSurface();
- new_surface.damage = surface->damage;
+scoped_ptr<BufferQueue::AllocatedSurface> BufferQueue::RecreateBuffer(
+ scoped_ptr<AllocatedSurface> surface) {
+ if (!surface)
+ return nullptr;
+
+ scoped_ptr<AllocatedSurface> new_surface(GetNextSurface());
+ if (!new_surface)
+ return nullptr;
+
+ new_surface->damage = surface->damage;
// Copy the entire texture.
- CopyBufferDamage(new_surface.texture, surface->texture, gfx::Rect(),
+ CopyBufferDamage(new_surface->texture, surface->texture, gfx::Rect(),
gfx::Rect(size_));
-
- FreeSurface(surface);
return new_surface;
}
void BufferQueue::PageFlipComplete() {
DCHECK(!in_flight_surfaces_.empty());
-
- if (displayed_surface_.texture)
- available_surfaces_.push_back(displayed_surface_);
-
- displayed_surface_ = in_flight_surfaces_.front();
+ if (displayed_surface_)
+ available_surfaces_.push_back(std::move(displayed_surface_));
+ displayed_surface_ = std::move(in_flight_surfaces_.front());
in_flight_surfaces_.pop_front();
}
void BufferQueue::FreeAllSurfaces() {
- FreeSurface(&displayed_surface_);
- FreeSurface(&current_surface_);
+ displayed_surface_.reset();
+ current_surface_.reset();
// This is intentionally not emptied since the swap buffers acks are still
// expected to arrive.
for (auto& surface : in_flight_surfaces_)
- FreeSurface(&surface);
-
- for (size_t i = 0; i < available_surfaces_.size(); i++)
- FreeSurface(&available_surfaces_[i]);
-
+ surface = nullptr;
available_surfaces_.clear();
}
-void BufferQueue::FreeSurface(AllocatedSurface* surface) {
- if (surface->texture) {
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
- gl->BindTexture(texture_target_, surface->texture);
- gl->ReleaseTexImage2DCHROMIUM(texture_target_, surface->image);
- gl->DeleteTextures(1, &surface->texture);
- gl->DestroyImageCHROMIUM(surface->image);
- surface->image = 0;
- surface->texture = 0;
- allocated_count_--;
- }
+void BufferQueue::FreeSurfaceResources(AllocatedSurface* surface) {
+ if (!surface->texture)
+ return;
+
+ gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+ gl->BindTexture(texture_target_, surface->texture);
+ gl->ReleaseTexImage2DCHROMIUM(texture_target_, surface->image);
+ gl->DeleteTextures(1, &surface->texture);
+ gl->DestroyImageCHROMIUM(surface->image);
+ surface->buffer.reset();
+ allocated_count_--;
}
-BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() {
+scoped_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface() {
if (!available_surfaces_.empty()) {
- AllocatedSurface surface = available_surfaces_.back();
+ scoped_ptr<AllocatedSurface> surface =
+ std::move(available_surfaces_.back());
available_surfaces_.pop_back();
return surface;
}
@@ -208,7 +216,7 @@ BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() {
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
gl->GenTextures(1, &texture);
if (!texture)
- return AllocatedSurface();
+ return nullptr;
// We don't want to allow anything more than triple buffering.
DCHECK_LT(allocated_count_, 4U);
@@ -218,25 +226,42 @@ BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() {
size_, gpu::ImageFactory::DefaultBufferFormatForImageFormat(
internal_format_),
surface_id_));
- if (!buffer) {
+ if (!buffer.get()) {
gl->DeleteTextures(1, &texture);
DLOG(ERROR) << "Failed to allocate GPU memory buffer";
- return AllocatedSurface();
+ return nullptr;
}
unsigned int id = gl->CreateImageCHROMIUM(
buffer->AsClientBuffer(), size_.width(), size_.height(),
internal_format_);
-
if (!id) {
LOG(ERROR) << "Failed to allocate backing image surface";
gl->DeleteTextures(1, &texture);
- return AllocatedSurface();
+ return nullptr;
}
+
allocated_count_++;
gl->BindTexture(texture_target_, texture);
gl->BindTexImage2DCHROMIUM(texture_target_, id);
- return AllocatedSurface(texture, id, gfx::Rect(size_));
+ return make_scoped_ptr(new AllocatedSurface(this, std::move(buffer), texture,
+ id, gfx::Rect(size_)));
+}
+
+BufferQueue::AllocatedSurface::AllocatedSurface(
+ BufferQueue* buffer_queue,
+ scoped_ptr<gfx::GpuMemoryBuffer> buffer,
+ unsigned int texture,
+ unsigned int image,
+ const gfx::Rect& rect)
+ : buffer_queue(buffer_queue),
+ buffer(buffer.release()),
+ texture(texture),
+ image(image),
+ damage(rect) {}
+
+BufferQueue::AllocatedSurface::~AllocatedSurface() {
+ buffer_queue->FreeSurfaceResources(this);
}
} // namespace content
diff --git a/chromium/content/browser/compositor/buffer_queue.h b/chromium/content/browser/compositor/buffer_queue.h
index 170b7bd3232..4c7d9439f9d 100644
--- a/chromium/content/browser/compositor/buffer_queue.h
+++ b/chromium/content/browser/compositor/buffer_queue.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_BUFFER_QUEUE_H_
#define CONTENT_BROWSER_COMPOSITOR_BUFFER_QUEUE_H_
-#include <queue>
+#include <stddef.h>
+
+#include <deque>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
@@ -18,6 +21,10 @@ namespace cc {
class ContextProvider;
}
+namespace gfx {
+class GpuMemoryBuffer;
+}
+
namespace content {
class BrowserGpuMemoryBufferManager;
@@ -46,26 +53,32 @@ class CONTENT_EXPORT BufferQueue {
void RecreateBuffers();
- unsigned int current_texture_id() const { return current_surface_.texture; }
+ unsigned int current_texture_id() const {
+ return current_surface_ ? current_surface_->texture : 0;
+ }
unsigned int fbo() const { return fbo_; }
private:
friend class BufferQueueTest;
+ friend class AllocatedSurface;
- struct AllocatedSurface {
- AllocatedSurface() : texture(0), image(0) {}
- AllocatedSurface(unsigned int texture,
+ struct CONTENT_EXPORT AllocatedSurface {
+ AllocatedSurface(BufferQueue* buffer_queue,
+ scoped_ptr<gfx::GpuMemoryBuffer> buffer,
+ unsigned int texture,
unsigned int image,
- const gfx::Rect& rect)
- : texture(texture), image(image), damage(rect) {}
- unsigned int texture;
- unsigned int image;
+ const gfx::Rect& rect);
+ ~AllocatedSurface();
+ BufferQueue* const buffer_queue;
+ scoped_ptr<gfx::GpuMemoryBuffer> buffer;
+ const unsigned int texture;
+ const unsigned int image;
gfx::Rect damage; // This is the damage for this frame from the previous.
};
void FreeAllSurfaces();
- void FreeSurface(AllocatedSurface* surface);
+ void FreeSurfaceResources(AllocatedSurface* surface);
// Copy everything that is in |copy_rect|, except for what is in
// |exclude_rect| from |source_texture| to |texture|.
@@ -77,9 +90,10 @@ class CONTENT_EXPORT BufferQueue {
void UpdateBufferDamage(const gfx::Rect& damage);
// Return a surface, available to be drawn into.
- AllocatedSurface GetNextSurface();
+ scoped_ptr<AllocatedSurface> GetNextSurface();
- AllocatedSurface RecreateBuffer(AllocatedSurface* surface);
+ scoped_ptr<AllocatedSurface> RecreateBuffer(
+ scoped_ptr<AllocatedSurface> surface);
gfx::Size size_;
scoped_refptr<cc::ContextProvider> context_provider_;
@@ -87,10 +101,16 @@ class CONTENT_EXPORT BufferQueue {
size_t allocated_count_;
unsigned int texture_target_;
unsigned int internal_format_;
- AllocatedSurface current_surface_; // This surface is currently bound.
- AllocatedSurface displayed_surface_; // The surface currently on the screen.
- std::vector<AllocatedSurface> available_surfaces_; // These are free for use.
- std::deque<AllocatedSurface> in_flight_surfaces_;
+ // This surface is currently bound. This may be nullptr if no surface has
+ // been bound, or if allocation failed at bind.
+ scoped_ptr<AllocatedSurface> current_surface_;
+ // The surface currently on the screen, if any.
+ scoped_ptr<AllocatedSurface> displayed_surface_;
+ // These are free for use, and are not nullptr.
+ std::vector<scoped_ptr<AllocatedSurface>> available_surfaces_;
+ // These have been swapped but are not displayed yet. Entries of this deque
+ // may be nullptr, if they represent frames that have been destroyed.
+ std::deque<scoped_ptr<AllocatedSurface>> in_flight_surfaces_;
GLHelper* gl_helper_;
BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager_;
int surface_id_;
diff --git a/chromium/content/browser/compositor/buffer_queue_unittest.cc b/chromium/content/browser/compositor/buffer_queue_unittest.cc
index 5d5d538aea4..323d7ae8fd2 100644
--- a/chromium/content/browser/compositor/buffer_queue_unittest.cc
+++ b/chromium/content/browser/compositor/buffer_queue_unittest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/compositor/buffer_queue.h"
+
+#include <stddef.h>
+#include <stdint.h>
#include <set>
+#include <utility>
#include "cc/test/test_context_provider.h"
#include "cc/test/test_web_graphics_context_3d.h"
-#include "content/browser/compositor/buffer_queue.h"
#include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/common/gpu/client/gl_helper.h"
@@ -27,13 +31,14 @@ class StubGpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
StubGpuMemoryBufferImpl() {}
// Overridden from gfx::GpuMemoryBuffer:
- bool Map(void** data) override { return false; }
+ bool Map() override { return false; }
+ void* memory(size_t plane) override { return nullptr; }
void Unmap() override {}
- bool IsMapped() const override { return false; }
+ gfx::Size GetSize() const override { return gfx::Size(); }
gfx::BufferFormat GetFormat() const override {
return gfx::BufferFormat::BGRX_8888;
}
- void GetStride(int* stride) const override {}
+ int stride(size_t plane) const override { return 0; }
gfx::GpuMemoryBufferId GetId() const override {
return gfx::GpuMemoryBufferId(0);
}
@@ -47,14 +52,22 @@ class StubGpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
class StubBrowserGpuMemoryBufferManager : public BrowserGpuMemoryBufferManager {
public:
- StubBrowserGpuMemoryBufferManager() : BrowserGpuMemoryBufferManager(1, 1) {}
+ StubBrowserGpuMemoryBufferManager()
+ : BrowserGpuMemoryBufferManager(1, 1), allocate_succeeds_(true) {}
+
+ void set_allocate_succeeds(bool value) { allocate_succeeds_ = value; }
scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferForScanout(
const gfx::Size& size,
gfx::BufferFormat format,
- int32 surface_id) override {
- return make_scoped_ptr<gfx::GpuMemoryBuffer>(new StubGpuMemoryBufferImpl);
+ int32_t surface_id) override {
+ if (allocate_succeeds_)
+ return make_scoped_ptr<gfx::GpuMemoryBuffer>(new StubGpuMemoryBufferImpl);
+ return nullptr;
}
+
+ private:
+ bool allocate_succeeds_;
};
class MockBufferQueue : public BufferQueue {
@@ -83,7 +96,7 @@ class BufferQueueTest : public ::testing::Test {
void InitWithContext(scoped_ptr<cc::TestWebGraphicsContext3D> context) {
scoped_refptr<cc::TestContextProvider> context_provider =
- cc::TestContextProvider::Create(context.Pass());
+ cc::TestContextProvider::Create(std::move(context));
context_provider->BindToCurrentThread();
gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager);
mock_output_surface_ =
@@ -93,31 +106,33 @@ class BufferQueueTest : public ::testing::Test {
output_surface_->Initialize();
}
- unsigned current_surface() { return output_surface_->current_surface_.image; }
- const std::vector<BufferQueue::AllocatedSurface>& available_surfaces() {
+ unsigned current_surface() {
+ return output_surface_->current_surface_
+ ? output_surface_->current_surface_->image
+ : 0;
+ }
+ const std::vector<scoped_ptr<BufferQueue::AllocatedSurface>>&
+ available_surfaces() {
return output_surface_->available_surfaces_;
}
- const std::deque<BufferQueue::AllocatedSurface>& in_flight_surfaces() {
+ std::deque<scoped_ptr<BufferQueue::AllocatedSurface>>& in_flight_surfaces() {
return output_surface_->in_flight_surfaces_;
}
- const BufferQueue::AllocatedSurface& displayed_frame() {
- return output_surface_->displayed_surface_;
- }
- const BufferQueue::AllocatedSurface& current_frame() {
- return output_surface_->current_surface_;
+ const BufferQueue::AllocatedSurface* displayed_frame() {
+ return output_surface_->displayed_surface_.get();
}
- const BufferQueue::AllocatedSurface& last_frame() {
- return output_surface_->in_flight_surfaces_.back();
+ const BufferQueue::AllocatedSurface* current_frame() {
+ return output_surface_->current_surface_.get();
}
- const BufferQueue::AllocatedSurface& next_frame() {
- return output_surface_->available_surfaces_.back();
+ const BufferQueue::AllocatedSurface* next_frame() {
+ return output_surface_->available_surfaces_.back().get();
}
const gfx::Size size() { return output_surface_->size_; }
int CountBuffers() {
int n = available_surfaces().size() + in_flight_surfaces().size() +
- (displayed_frame().texture ? 1 : 0);
+ (displayed_frame() ? 1 : 0);
if (current_surface())
n++;
return n;
@@ -127,14 +142,14 @@ class BufferQueueTest : public ::testing::Test {
void CheckUnique() {
std::set<unsigned> buffers;
EXPECT_TRUE(InsertUnique(&buffers, current_surface()));
- EXPECT_TRUE(InsertUnique(&buffers, displayed_frame().image));
- for (size_t i = 0; i < available_surfaces().size(); i++)
- EXPECT_TRUE(InsertUnique(&buffers, available_surfaces()[i].image));
- for (std::deque<BufferQueue::AllocatedSurface>::const_iterator it =
- in_flight_surfaces().begin();
- it != in_flight_surfaces().end();
- ++it)
- EXPECT_TRUE(InsertUnique(&buffers, it->image));
+ if (displayed_frame())
+ EXPECT_TRUE(InsertUnique(&buffers, displayed_frame()->image));
+ for (auto& surface : available_surfaces())
+ EXPECT_TRUE(InsertUnique(&buffers, surface->image));
+ for (auto& surface : in_flight_surfaces()) {
+ if (surface)
+ EXPECT_TRUE(InsertUnique(&buffers, surface->image));
+ }
}
void SwapBuffers() {
@@ -163,7 +178,7 @@ class BufferQueueTest : public ::testing::Test {
return true;
}
- scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_;
+ scoped_ptr<StubBrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_;
scoped_ptr<BufferQueue> output_surface_;
MockBufferQueue* mock_output_surface_;
bool doublebuffering_;
@@ -222,7 +237,7 @@ scoped_ptr<BufferQueue> CreateOutputSurfaceWithMock(
new BufferQueue(context_provider, target, GL_RGBA, nullptr,
gpu_memory_buffer_manager, 1));
buffer_queue->Initialize();
- return buffer_queue.Pass();
+ return buffer_queue;
}
TEST(BufferQueueStandaloneTest, FboInitialization) {
@@ -313,7 +328,7 @@ TEST_F(BufferQueueTest, PartialSwapReuse) {
SendDamagedFrame(small_damage);
SendDamagedFrame(large_damage);
// Verify that the damage has propagated.
- EXPECT_EQ(next_frame().damage, large_damage);
+ EXPECT_EQ(next_frame()->damage, large_damage);
}
TEST_F(BufferQueueTest, PartialSwapFullFrame) {
@@ -325,7 +340,7 @@ TEST_F(BufferQueueTest, PartialSwapFullFrame) {
SendDamagedFrame(small_damage);
SendFullFrame();
SendFullFrame();
- EXPECT_EQ(next_frame().damage, screen_rect);
+ EXPECT_EQ(next_frame()->damage, screen_rect);
}
TEST_F(BufferQueueTest, PartialSwapOverlapping) {
@@ -339,7 +354,7 @@ TEST_F(BufferQueueTest, PartialSwapOverlapping) {
SendFullFrame();
SendDamagedFrame(small_damage);
SendDamagedFrame(overlapping_damage);
- EXPECT_EQ(next_frame().damage, overlapping_damage);
+ EXPECT_EQ(next_frame()->damage, overlapping_damage);
}
TEST_F(BufferQueueTest, MultipleBindCalls) {
@@ -358,27 +373,27 @@ TEST_F(BufferQueueTest, CheckDoubleBuffering) {
output_surface_->BindFramebuffer();
EXPECT_EQ(1, CountBuffers());
EXPECT_NE(0U, current_surface());
- EXPECT_FALSE(displayed_frame().texture);
+ EXPECT_FALSE(displayed_frame());
SwapBuffers();
EXPECT_EQ(1U, in_flight_surfaces().size());
output_surface_->PageFlipComplete();
EXPECT_EQ(0U, in_flight_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
+ EXPECT_TRUE(displayed_frame()->texture);
output_surface_->BindFramebuffer();
EXPECT_EQ(2, CountBuffers());
CheckUnique();
EXPECT_NE(0U, current_surface());
EXPECT_EQ(0U, in_flight_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
+ EXPECT_TRUE(displayed_frame()->texture);
SwapBuffers();
CheckUnique();
EXPECT_EQ(1U, in_flight_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
+ EXPECT_TRUE(displayed_frame()->texture);
output_surface_->PageFlipComplete();
CheckUnique();
EXPECT_EQ(0U, in_flight_surfaces().size());
EXPECT_EQ(1U, available_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
+ EXPECT_TRUE(displayed_frame()->texture);
output_surface_->BindFramebuffer();
EXPECT_EQ(2, CountBuffers());
CheckUnique();
@@ -390,7 +405,7 @@ TEST_F(BufferQueueTest, CheckTripleBuffering) {
// This bit is the same sequence tested in the doublebuffering case.
output_surface_->BindFramebuffer();
- EXPECT_FALSE(displayed_frame().texture);
+ EXPECT_FALSE(displayed_frame());
SwapBuffers();
output_surface_->PageFlipComplete();
output_surface_->BindFramebuffer();
@@ -399,19 +414,19 @@ TEST_F(BufferQueueTest, CheckTripleBuffering) {
EXPECT_EQ(2, CountBuffers());
CheckUnique();
EXPECT_EQ(1U, in_flight_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
+ EXPECT_TRUE(displayed_frame()->texture);
output_surface_->BindFramebuffer();
EXPECT_EQ(3, CountBuffers());
CheckUnique();
EXPECT_NE(0U, current_surface());
EXPECT_EQ(1U, in_flight_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
+ EXPECT_TRUE(displayed_frame()->texture);
output_surface_->PageFlipComplete();
EXPECT_EQ(3, CountBuffers());
CheckUnique();
EXPECT_NE(0U, current_surface());
EXPECT_EQ(0U, in_flight_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
+ EXPECT_TRUE(displayed_frame()->texture);
EXPECT_EQ(1U, available_surfaces().size());
}
@@ -424,9 +439,9 @@ TEST_F(BufferQueueTest, CheckCorrectBufferOrdering) {
EXPECT_EQ(kSwapCount, in_flight_surfaces().size());
for (size_t i = 0; i < kSwapCount; ++i) {
- unsigned int next_texture_id = in_flight_surfaces().front().texture;
+ unsigned int next_texture_id = in_flight_surfaces().front()->texture;
output_surface_->PageFlipComplete();
- EXPECT_EQ(displayed_frame().texture, next_texture_id);
+ EXPECT_EQ(displayed_frame()->texture, next_texture_id);
}
}
@@ -442,7 +457,7 @@ TEST_F(BufferQueueTest, ReshapeWithInFlightSurfaces) {
for (size_t i = 0; i < kSwapCount; ++i) {
output_surface_->PageFlipComplete();
- EXPECT_EQ(0u, displayed_frame().texture);
+ EXPECT_FALSE(displayed_frame());
}
// The dummy surfacess left should be discarded.
@@ -467,16 +482,16 @@ TEST_F(BufferQueueTest, SwapAfterReshape) {
for (size_t i = 0; i < kSwapCount; ++i) {
output_surface_->PageFlipComplete();
- EXPECT_EQ(0u, displayed_frame().texture);
+ EXPECT_FALSE(displayed_frame());
}
CheckUnique();
for (size_t i = 0; i < kSwapCount; ++i) {
- unsigned int next_texture_id = in_flight_surfaces().front().texture;
+ unsigned int next_texture_id = in_flight_surfaces().front()->texture;
output_surface_->PageFlipComplete();
- EXPECT_EQ(displayed_frame().texture, next_texture_id);
- EXPECT_NE(0u, displayed_frame().texture);
+ EXPECT_EQ(displayed_frame()->texture, next_texture_id);
+ EXPECT_TRUE(displayed_frame());
}
}
@@ -502,37 +517,37 @@ TEST_F(BufferQueueMockedContextTest, RecreateBuffers) {
// being drawn to.
ASSERT_EQ(1U, in_flight_surfaces().size());
ASSERT_EQ(1U, available_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
- EXPECT_TRUE(current_frame().texture);
+ EXPECT_TRUE(displayed_frame());
+ EXPECT_TRUE(current_frame());
- auto current = current_frame();
- auto displayed = displayed_frame();
- auto in_flight = in_flight_surfaces().front();
- auto available = available_surfaces().front();
+ auto* current = current_frame();
+ auto* displayed = displayed_frame();
+ auto* in_flight = in_flight_surfaces().front().get();
+ auto* available = available_surfaces().front().get();
// Expect all 4 images to be destroyed, 3 of the existing textures to be
// copied from and 3 new images to be created.
EXPECT_CALL(*context_, createImageCHROMIUM(_, 0, 0, GL_RGBA)).Times(3);
- Expectation copy1 =
- EXPECT_CALL(*mock_output_surface_,
- CopyBufferDamage(_, displayed.texture, _, _)).Times(1);
- Expectation copy2 =
- EXPECT_CALL(*mock_output_surface_,
- CopyBufferDamage(_, current.texture, _, _)).Times(1);
- Expectation copy3 =
- EXPECT_CALL(*mock_output_surface_,
- CopyBufferDamage(_, in_flight.texture, _, _)).Times(1);
-
- EXPECT_CALL(*context_, destroyImageCHROMIUM(displayed.image))
+ Expectation copy1 = EXPECT_CALL(*mock_output_surface_,
+ CopyBufferDamage(_, displayed->texture, _, _))
+ .Times(1);
+ Expectation copy2 = EXPECT_CALL(*mock_output_surface_,
+ CopyBufferDamage(_, current->texture, _, _))
+ .Times(1);
+ Expectation copy3 = EXPECT_CALL(*mock_output_surface_,
+ CopyBufferDamage(_, in_flight->texture, _, _))
+ .Times(1);
+
+ EXPECT_CALL(*context_, destroyImageCHROMIUM(displayed->image))
.Times(1)
.After(copy1);
- EXPECT_CALL(*context_, destroyImageCHROMIUM(current.image))
+ EXPECT_CALL(*context_, destroyImageCHROMIUM(current->image))
.Times(1)
.After(copy2);
- EXPECT_CALL(*context_, destroyImageCHROMIUM(in_flight.image))
+ EXPECT_CALL(*context_, destroyImageCHROMIUM(in_flight->image))
.Times(1)
.After(copy3);
- EXPECT_CALL(*context_, destroyImageCHROMIUM(available.image)).Times(1);
+ EXPECT_CALL(*context_, destroyImageCHROMIUM(available->image)).Times(1);
// After copying, we expect the framebuffer binding to be updated.
EXPECT_CALL(*context_, bindFramebuffer(_, _))
.After(copy1)
@@ -551,8 +566,57 @@ TEST_F(BufferQueueMockedContextTest, RecreateBuffers) {
// be replaced but still valid.
EXPECT_EQ(1U, in_flight_surfaces().size());
EXPECT_EQ(0U, available_surfaces().size());
- EXPECT_TRUE(displayed_frame().texture);
- EXPECT_TRUE(current_frame().texture);
+ EXPECT_TRUE(displayed_frame());
+ EXPECT_TRUE(current_frame());
+}
+
+TEST_F(BufferQueueTest, AllocateFails) {
+ output_surface_->Reshape(screen_size, 1.0f);
+
+ // Succeed in the two swaps.
+ output_surface_->BindFramebuffer();
+ EXPECT_TRUE(current_frame());
+ output_surface_->SwapBuffers(screen_rect);
+
+ // Fail the next surface allocation.
+ gpu_memory_buffer_manager_->set_allocate_succeeds(false);
+ output_surface_->BindFramebuffer();
+ EXPECT_FALSE(current_frame());
+ output_surface_->SwapBuffers(screen_rect);
+ EXPECT_FALSE(current_frame());
+
+ // Try another swap. It should copy the buffer damage from the back
+ // surface.
+ gpu_memory_buffer_manager_->set_allocate_succeeds(true);
+ output_surface_->BindFramebuffer();
+ unsigned int source_texture = in_flight_surfaces().front()->texture;
+ unsigned int target_texture = current_frame()->texture;
+ testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
+ EXPECT_CALL(*mock_output_surface_,
+ CopyBufferDamage(target_texture, source_texture, small_damage, _))
+ .Times(1);
+ output_surface_->SwapBuffers(small_damage);
+ testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
+
+ // Destroy the just-created buffer, and try another swap. The copy should
+ // come from the displayed surface (because both in-flight surfaces are
+ // gone now).
+ output_surface_->PageFlipComplete();
+ in_flight_surfaces().back().reset();
+ EXPECT_EQ(2u, in_flight_surfaces().size());
+ for (auto& surface : in_flight_surfaces())
+ EXPECT_FALSE(surface);
+ output_surface_->BindFramebuffer();
+ source_texture = displayed_frame()->texture;
+ EXPECT_TRUE(current_frame());
+ EXPECT_TRUE(displayed_frame());
+ target_texture = current_frame()->texture;
+ testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
+ EXPECT_CALL(*mock_output_surface_,
+ CopyBufferDamage(target_texture, source_texture, small_damage, _))
+ .Times(1);
+ output_surface_->SwapBuffers(small_damage);
+ testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
}
} // namespace
diff --git a/chromium/content/browser/compositor/delegated_frame_host.cc b/chromium/content/browser/compositor/delegated_frame_host.cc
index abc001e2f95..f381da0eadd 100644
--- a/chromium/content/browser/compositor/delegated_frame_host.cc
+++ b/chromium/content/browser/compositor/delegated_frame_host.cc
@@ -4,6 +4,11 @@
#include "content/browser/compositor/delegated_frame_host.h"
+#include <algorithm>
+#include <string>
+#include <utility>
+#include <vector>
+
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/time/default_tick_clock.h"
@@ -150,15 +155,15 @@ void DelegatedFrameHost::CopyFromCompositingSurface(
output_size, preferred_color_type, callback));
if (!src_subrect.IsEmpty())
request->set_area(src_subrect);
- RequestCopyOfOutput(request.Pass());
+ RequestCopyOfOutput(std::move(request));
}
void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame(
- const gfx::Rect& src_subrect,
- const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) {
+ const gfx::Rect& src_subrect,
+ const scoped_refptr<media::VideoFrame>& target,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) {
if (!CanCopyToVideoFrame()) {
- callback.Run(false);
+ callback.Run(gfx::Rect(), false);
return;
}
@@ -171,7 +176,7 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame(
target,
callback));
request->set_area(src_subrect);
- RequestCopyOfOutput(request.Pass());
+ RequestCopyOfOutput(std::move(request));
}
bool DelegatedFrameHost::CanCopyToBitmap() const {
@@ -186,7 +191,7 @@ bool DelegatedFrameHost::CanCopyToVideoFrame() const {
void DelegatedFrameHost::BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
- frame_subscriber_ = subscriber.Pass();
+ frame_subscriber_ = std::move(subscriber);
}
void DelegatedFrameHost::EndFrameSubscription() {
@@ -206,7 +211,7 @@ cc::SurfaceId DelegatedFrameHost::SurfaceIdAtPoint(
gfx::Point* transformed_point) {
if (surface_id_.is_null())
return surface_id_;
- cc::SurfaceHittest hittest(GetSurfaceManager());
+ cc::SurfaceHittest hittest(nullptr, GetSurfaceManager());
gfx::Transform target_transform;
cc::SurfaceId target_surface_id =
hittest.GetTargetSurfaceAtPoint(surface_id_, point, &target_transform);
@@ -216,6 +221,23 @@ cc::SurfaceId DelegatedFrameHost::SurfaceIdAtPoint(
return target_surface_id;
}
+void DelegatedFrameHost::TransformPointToLocalCoordSpace(
+ const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point) {
+ *transformed_point = point;
+ if (surface_id_.is_null() || original_surface == surface_id_)
+ return;
+
+ gfx::Transform transform;
+ cc::SurfaceHittest hittest(nullptr, GetSurfaceManager());
+ if (hittest.GetTransformToTargetSurface(surface_id_, original_surface,
+ &transform) &&
+ transform.GetInverse(&transform)) {
+ transform.TransformPoint(transformed_point);
+ }
+}
+
bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const {
// Should skip a frame only when another frame from the renderer is guaranteed
// to replace it. Otherwise may cause hangs when the renderer is waiting for
@@ -254,7 +276,7 @@ void DelegatedFrameHost::CheckResizeLock() {
resize_lock_->UnlockCompositor();
}
-void DelegatedFrameHost::DidReceiveFrameFromRenderer(
+void DelegatedFrameHost::AttemptFrameSubscriberCapture(
const gfx::Rect& damage_rect) {
if (!frame_subscriber() || !CanCopyToVideoFrame())
return;
@@ -264,7 +286,7 @@ void DelegatedFrameHost::DidReceiveFrameFromRenderer(
if (vsync_interval_ <= base::TimeDelta()) {
present_time = now;
} else {
- const int64 intervals_elapsed = (now - vsync_timebase_) / vsync_interval_;
+ const int64_t intervals_elapsed = (now - vsync_timebase_) / vsync_interval_;
present_time = vsync_timebase_ + (intervals_elapsed + 1) * vsync_interval_;
}
@@ -298,25 +320,36 @@ void DelegatedFrameHost::DidReceiveFrameFromRenderer(
// screenshots) since those copy requests do not specify |frame_subscriber()|
// as a source.
request->set_source(frame_subscriber());
- request->set_area(gfx::Rect(current_frame_size_in_dip_));
if (subscriber_texture.get()) {
- request->SetTextureMailbox(
- cc::TextureMailbox(subscriber_texture->mailbox(),
- subscriber_texture->target(),
- subscriber_texture->sync_point()));
+ request->SetTextureMailbox(cc::TextureMailbox(
+ subscriber_texture->mailbox(), subscriber_texture->sync_token(),
+ subscriber_texture->target()));
+ }
+
+ if (surface_factory_.get()) {
+ // To avoid unnecessary composites, go directly to the Surface rather than
+ // through RequestCopyOfOutput (which goes through the browser
+ // compositor).
+ if (!request_copy_of_output_callback_for_testing_.is_null())
+ request_copy_of_output_callback_for_testing_.Run(std::move(request));
+ else
+ surface_factory_->RequestCopyOfSurface(surface_id_, std::move(request));
+ } else {
+ request->set_area(gfx::Rect(current_frame_size_in_dip_));
+ RequestCopyOfOutput(std::move(request));
}
- RequestCopyOfOutput(request.Pass());
}
void DelegatedFrameHost::SwapDelegatedFrame(
- uint32 output_surface_id,
- scoped_ptr<cc::DelegatedFrameData> frame_data,
- float frame_device_scale_factor,
- const std::vector<ui::LatencyInfo>& latency_info,
- std::vector<uint32_t>* satisfies_sequences) {
+ uint32_t output_surface_id,
+ scoped_ptr<cc::CompositorFrame> frame) {
+ DCHECK(frame->delegated_frame_data.get());
+ cc::DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
+ float frame_device_scale_factor = frame->metadata.device_scale_factor;
+
DCHECK(!frame_data->render_pass_list.empty());
- cc::RenderPass* root_pass = frame_data->render_pass_list.back();
+ cc::RenderPass* root_pass = frame_data->render_pass_list.back().get();
gfx::Size frame_size = root_pass->output_rect.size();
gfx::Size frame_size_in_dip =
@@ -333,7 +366,8 @@ void DelegatedFrameHost::SwapDelegatedFrame(
&ack.resources);
skipped_latency_info_list_.insert(skipped_latency_info_list_.end(),
- latency_info.begin(), latency_info.end());
+ frame->metadata.latency_info.begin(),
+ frame->metadata.latency_info.end());
client_->DelegatedFrameHostSendCompositorSwapAck(output_surface_id, ack);
skipped_frames_ = true;
@@ -346,7 +380,7 @@ void DelegatedFrameHost::SwapDelegatedFrame(
damage_rect_in_dip = gfx::Rect(frame_size_in_dip);
// Give the same damage rect to the compositor.
- cc::RenderPass* root_pass = frame_data->render_pass_list.back();
+ cc::RenderPass* root_pass = frame_data->render_pass_list.back().get();
root_pass->damage_rect = damage_rect;
}
@@ -405,16 +439,11 @@ void DelegatedFrameHost::SwapDelegatedFrame(
current_surface_size_ = frame_size;
current_scale_factor_ = frame_device_scale_factor;
}
- scoped_ptr<cc::CompositorFrame> compositor_frame =
- make_scoped_ptr(new cc::CompositorFrame());
- compositor_frame->delegated_frame_data = frame_data.Pass();
- compositor_frame->metadata.latency_info.swap(skipped_latency_info_list_);
- compositor_frame->metadata.latency_info.insert(
- compositor_frame->metadata.latency_info.end(),
- latency_info.begin(),
- latency_info.end());
- compositor_frame->metadata.satisfies_sequences.swap(*satisfies_sequences);
+ frame->metadata.latency_info.insert(frame->metadata.latency_info.end(),
+ skipped_latency_info_list_.begin(),
+ skipped_latency_info_list_.end());
+ skipped_latency_info_list_.clear();
gfx::Size desired_size = client_->DelegatedFrameHostDesiredSizeInDIP();
if (desired_size != frame_size_in_dip && !desired_size.IsEmpty())
@@ -425,8 +454,8 @@ void DelegatedFrameHost::SwapDelegatedFrame(
ack_callback = base::Bind(&DelegatedFrameHost::SurfaceDrawn,
AsWeakPtr(), output_surface_id);
}
- surface_factory_->SubmitCompositorFrame(
- surface_id_, compositor_frame.Pass(), ack_callback);
+ surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame),
+ ack_callback);
} else {
if (!resource_collection_.get()) {
resource_collection_ = new cc::DelegatedFrameResourceCollection;
@@ -441,11 +470,11 @@ void DelegatedFrameHost::SwapDelegatedFrame(
frame_size != frame_provider_->frame_size() ||
frame_size_in_dip != current_frame_size_in_dip_) {
frame_provider_ = new cc::DelegatedFrameProvider(
- resource_collection_.get(), frame_data.Pass());
+ resource_collection_.get(), std::move(frame->delegated_frame_data));
client_->DelegatedFrameHostGetLayer()->SetShowDelegatedContent(
frame_provider_.get(), frame_size_in_dip);
} else {
- frame_provider_->SetFrameData(frame_data.Pass());
+ frame_provider_->SetFrameData(std::move(frame->delegated_frame_data));
}
}
}
@@ -461,7 +490,8 @@ void DelegatedFrameHost::SwapDelegatedFrame(
SendDelegatedFrameAck(output_surface_id);
} else if (!use_surfaces_) {
std::vector<ui::LatencyInfo>::const_iterator it;
- for (it = latency_info.begin(); it != latency_info.end(); ++it)
+ for (it = frame->metadata.latency_info.begin();
+ it != frame->metadata.latency_info.end(); ++it)
compositor_->SetLatencyInfo(*it);
// If we've previously skipped any latency infos add them.
for (it = skipped_latency_info_list_.begin();
@@ -475,7 +505,10 @@ void DelegatedFrameHost::SwapDelegatedFrame(
} else {
AddOnCommitCallbackAndDisableLocks(base::Closure());
}
- DidReceiveFrameFromRenderer(damage_rect);
+ // With Surfaces, WillDrawSurface() will be called as the trigger to attempt
+ // a frame subscriber capture instead.
+ if (!use_surfaces_)
+ AttemptFrameSubscriberCapture(damage_rect);
if (frame_provider_.get() || !surface_id_.is_null())
delegated_frame_evictor_->SwappedFrame(
client_->DelegatedFrameHostIsVisible());
@@ -487,7 +520,7 @@ void DelegatedFrameHost::ClearDelegatedFrame() {
EvictDelegatedFrame();
}
-void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) {
+void DelegatedFrameHost::SendDelegatedFrameAck(uint32_t output_surface_id) {
cc::CompositorFrameAck ack;
if (!surface_returned_resources_.empty())
ack.resources.swap(surface_returned_resources_);
@@ -498,7 +531,7 @@ void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) {
pending_delegated_ack_count_--;
}
-void DelegatedFrameHost::SurfaceDrawn(uint32 output_surface_id,
+void DelegatedFrameHost::SurfaceDrawn(uint32_t output_surface_id,
cc::SurfaceDrawStatus drawn) {
SendDelegatedFrameAck(output_surface_id);
}
@@ -511,7 +544,7 @@ void DelegatedFrameHost::UnusedResourcesAreAvailable() {
}
void DelegatedFrameHost::SendReturnedDelegatedResources(
- uint32 output_surface_id) {
+ uint32_t output_surface_id) {
cc::CompositorFrameAck ack;
if (!surface_returned_resources_.empty()) {
ack.resources.swap(surface_returned_resources_);
@@ -536,6 +569,19 @@ void DelegatedFrameHost::ReturnResources(
SendReturnedDelegatedResources(last_output_surface_id_);
}
+void DelegatedFrameHost::WillDrawSurface(cc::SurfaceId id,
+ const gfx::Rect& damage_rect) {
+ if (id != surface_id_)
+ return;
+ AttemptFrameSubscriberCapture(damage_rect);
+}
+
+void DelegatedFrameHost::SetBeginFrameSource(
+ cc::SurfaceId surface_id,
+ cc::BeginFrameSource* begin_frame_source) {
+ // TODO(tansell): Hook this up.
+}
+
void DelegatedFrameHost::EvictDelegatedFrame() {
client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent();
frame_provider_ = NULL;
@@ -565,16 +611,15 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult(
if (result->HasTexture()) {
// GPU-accelerated path
- PrepareTextureCopyOutputResult(output_size_in_pixel, color_type,
- callback,
- result.Pass());
+ PrepareTextureCopyOutputResult(output_size_in_pixel, color_type, callback,
+ std::move(result));
return;
}
DCHECK(result->HasBitmap());
// Software path
PrepareBitmapCopyOutputResult(output_size_in_pixel, color_type, callback,
- result.Pass());
+ std::move(result));
}
static void CopyFromCompositingSurfaceFinished(
@@ -585,14 +630,14 @@ static void CopyFromCompositingSurfaceFinished(
bool result) {
bitmap_pixels_lock.reset();
- uint32 sync_point = 0;
+ gpu::SyncToken sync_token;
if (result) {
GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
if (gl_helper)
- sync_point = gl_helper->InsertSyncPoint();
+ gl_helper->GenerateSyncToken(&sync_token);
}
- bool lost_resource = sync_point == 0;
- release_callback->Run(sync_point, lost_resource);
+ const bool lost_resource = !sync_token.HasData();
+ release_callback->Run(sync_token, lost_resource);
callback.Run(*bitmap,
result ? content::READBACK_SUCCESS : content::READBACK_FAILED);
@@ -627,7 +672,7 @@ void DelegatedFrameHost::PrepareTextureCopyOutputResult(
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
new SkAutoLockPixels(*bitmap));
- uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
+ uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels());
cc::TextureMailbox texture_mailbox;
scoped_ptr<cc::SingleReleaseCallback> release_callback;
@@ -637,17 +682,10 @@ void DelegatedFrameHost::PrepareTextureCopyOutputResult(
ignore_result(scoped_callback_runner.Release());
gl_helper->CropScaleReadbackAndCleanMailbox(
- texture_mailbox.mailbox(),
- texture_mailbox.sync_point(),
- result->size(),
- gfx::Rect(result->size()),
- dst_size_in_pixel,
- pixels,
- color_type,
- base::Bind(&CopyFromCompositingSurfaceFinished,
- callback,
- base::Passed(&release_callback),
- base::Passed(&bitmap),
+ texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
+ gfx::Rect(result->size()), dst_size_in_pixel, pixels, color_type,
+ base::Bind(&CopyFromCompositingSurfaceFinished, callback,
+ base::Passed(&release_callback), base::Passed(&bitmap),
base::Passed(&bitmap_pixels_lock)),
GLHelper::SCALER_QUALITY_GOOD);
}
@@ -707,13 +745,13 @@ void DelegatedFrameHost::PrepareBitmapCopyOutputResult(
void DelegatedFrameHost::ReturnSubscriberTexture(
base::WeakPtr<DelegatedFrameHost> dfh,
scoped_refptr<OwnedMailbox> subscriber_texture,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
if (!subscriber_texture.get())
return;
if (!dfh)
return;
- subscriber_texture->UpdateSyncPoint(sync_point);
+ subscriber_texture->UpdateSyncToken(sync_token);
if (dfh->frame_subscriber_ && subscriber_texture->texture_id())
dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture);
@@ -728,19 +766,19 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo(
bool result) {
callback.Run(result);
- uint32 sync_point = 0;
+ gpu::SyncToken sync_token;
if (result) {
GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
- sync_point = gl_helper->InsertSyncPoint();
+ gl_helper->GenerateSyncToken(&sync_token);
}
if (release_callback) {
// A release callback means the texture came from the compositor, so there
// should be no |subscriber_texture|.
DCHECK(!subscriber_texture.get());
- bool lost_resource = sync_point == 0;
- release_callback->Run(sync_point, lost_resource);
+ const bool lost_resource = !sync_token.HasData();
+ release_callback->Run(sync_token, lost_resource);
}
- ReturnSubscriberTexture(dfh, subscriber_texture, sync_point);
+ ReturnSubscriberTexture(dfh, subscriber_texture, sync_token);
}
// static
@@ -748,11 +786,13 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
base::WeakPtr<DelegatedFrameHost> dfh,
scoped_refptr<OwnedMailbox> subscriber_texture,
scoped_refptr<media::VideoFrame> video_frame,
- const base::Callback<void(bool)>& callback,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback,
scoped_ptr<cc::CopyOutputResult> result) {
- base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
+ base::ScopedClosureRunner scoped_callback_runner(
+ base::Bind(callback, gfx::Rect(), false));
base::ScopedClosureRunner scoped_return_subscriber_texture(
- base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture, 0));
+ base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture,
+ gpu::SyncToken()));
if (!dfh)
return;
@@ -795,13 +835,11 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
media::CopyRGBToVideoFrame(
- reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
- scaled_bitmap.rowBytes(),
- region_in_frame,
- video_frame.get());
+ reinterpret_cast<uint8_t*>(scaled_bitmap.getPixels()),
+ scaled_bitmap.rowBytes(), region_in_frame, video_frame.get());
}
ignore_result(scoped_callback_runner.Release());
- callback.Run(true);
+ callback.Run(region_in_frame, true);
return;
}
@@ -854,14 +892,13 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
ignore_result(scoped_callback_runner.Release());
ignore_result(scoped_return_subscriber_texture.Release());
+
base::Callback<void(bool result)> finished_callback = base::Bind(
&DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo,
- dfh->AsWeakPtr(),
- callback,
- subscriber_texture,
- base::Passed(&release_callback));
+ dfh->AsWeakPtr(), base::Bind(callback, region_in_frame),
+ subscriber_texture, base::Passed(&release_callback));
yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(),
- texture_mailbox.sync_point(),
+ texture_mailbox.sync_token(),
video_frame.get(),
region_in_frame.origin(),
finished_callback);
@@ -1011,9 +1048,10 @@ void DelegatedFrameHost::LockResources() {
void DelegatedFrameHost::RequestCopyOfOutput(
scoped_ptr<cc::CopyOutputRequest> request) {
if (!request_copy_of_output_callback_for_testing_.is_null())
- request_copy_of_output_callback_for_testing_.Run(request.Pass());
+ request_copy_of_output_callback_for_testing_.Run(std::move(request));
else
- client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput(request.Pass());
+ client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput(
+ std::move(request));
}
void DelegatedFrameHost::UnlockResources() {
diff --git a/chromium/content/browser/compositor/delegated_frame_host.h b/chromium/content/browser/compositor/delegated_frame_host.h
index aa3ce5b1d38..21dc4e0c8f9 100644
--- a/chromium/content/browser/compositor/delegated_frame_host.h
+++ b/chromium/content/browser/compositor/delegated_frame_host.h
@@ -5,6 +5,10 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
#define CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
+#include <stdint.h>
+
+#include <vector>
+
#include "base/gtest_prod_util.h"
#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_frame_resource_collection.h"
@@ -22,6 +26,7 @@
#include "ui/compositor/compositor_vsync_manager.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_owner_delegate.h"
+#include "ui/events/event.h"
#include "ui/gfx/geometry/rect_conversions.h"
namespace base {
@@ -116,18 +121,16 @@ class CONTENT_EXPORT DelegatedFrameHost
// cc::SurfaceFactoryClient implementation.
void ReturnResources(const cc::ReturnedResourceArray& resources) override;
+ void WillDrawSurface(cc::SurfaceId id, const gfx::Rect& damage_rect) override;
+ void SetBeginFrameSource(cc::SurfaceId surface_id,
+ cc::BeginFrameSource* begin_frame_source) override;
bool CanCopyToBitmap() const;
// Public interface exposed to RenderWidgetHostView.
- // Note: |satisfies_sequences| is cleared in calls to this function.
- void SwapDelegatedFrame(
- uint32 output_surface_id,
- scoped_ptr<cc::DelegatedFrameData> frame_data,
- float frame_device_scale_factor,
- const std::vector<ui::LatencyInfo>& latency_info,
- std::vector<uint32_t>* satisfies_sequences);
+ void SwapDelegatedFrame(uint32_t output_surface_id,
+ scoped_ptr<cc::CompositorFrame> frame);
void ClearDelegatedFrame();
void WasHidden();
void WasShown(const ui::LatencyInfo& latency_info);
@@ -147,7 +150,7 @@ class CONTENT_EXPORT DelegatedFrameHost
void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback);
+ const base::Callback<void(const gfx::Rect&, bool)>& callback);
bool CanCopyToVideoFrame() const;
void BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber);
@@ -159,6 +162,14 @@ class CONTENT_EXPORT DelegatedFrameHost
cc::SurfaceId SurfaceIdAtPoint(const gfx::Point& point,
gfx::Point* transformed_point);
+ // Given the SurfaceID of a Surface that is contained within this class'
+ // Surface, find the relative transform between the Surfaces and apply it
+ // to a point. If a Surface has not yet been created this returns the
+ // same point with no transform applied.
+ void TransformPointToLocalCoordSpace(const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point);
+
// Exposed for tests.
cc::DelegatedFrameProvider* FrameProviderForTesting() const {
return frame_provider_.get();
@@ -227,7 +238,7 @@ class CONTENT_EXPORT DelegatedFrameHost
base::WeakPtr<DelegatedFrameHost> rwhva,
scoped_refptr<OwnedMailbox> subscriber_texture,
scoped_refptr<media::VideoFrame> video_frame,
- const base::Callback<void(bool)>& callback,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback,
scoped_ptr<cc::CopyOutputResult> result);
static void CopyFromCompositingSurfaceFinishedForVideo(
base::WeakPtr<DelegatedFrameHost> rwhva,
@@ -238,15 +249,15 @@ class CONTENT_EXPORT DelegatedFrameHost
static void ReturnSubscriberTexture(
base::WeakPtr<DelegatedFrameHost> rwhva,
scoped_refptr<OwnedMailbox> subscriber_texture,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
- void SendDelegatedFrameAck(uint32 output_surface_id);
- void SurfaceDrawn(uint32 output_surface_id, cc::SurfaceDrawStatus drawn);
- void SendReturnedDelegatedResources(uint32 output_surface_id);
+ void SendDelegatedFrameAck(uint32_t output_surface_id);
+ void SurfaceDrawn(uint32_t output_surface_id, cc::SurfaceDrawStatus drawn);
+ void SendReturnedDelegatedResources(uint32_t output_surface_id);
// Called to consult the current |frame_subscriber_|, to determine and maybe
// initiate a copy-into-video-frame request.
- void DidReceiveFrameFromRenderer(const gfx::Rect& damage_rect);
+ void AttemptFrameSubscriberCapture(const gfx::Rect& damage_rect);
DelegatedFrameHostClient* const client_;
ui::Compositor* compositor_;
@@ -271,7 +282,7 @@ class CONTENT_EXPORT DelegatedFrameHost
// With delegated renderer, this is the last output surface, used to
// disambiguate resources with the same id coming from different output
// surfaces.
- uint32 last_output_surface_id_;
+ uint32_t last_output_surface_id_;
// The number of delegated frame acks that are pending, to delay resource
// returns until the acks are sent.
diff --git a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
index 70725a2a8b0..adf0764c65a 100644
--- a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
@@ -4,6 +4,9 @@
#include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
+#include <utility>
+
+#include "build/build_config.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/output_surface_client.h"
#include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
@@ -24,13 +27,13 @@ GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface(
: BrowserCompositorOutputSurface(context,
worker_context,
vsync_manager,
- overlay_candidate_validator.Pass()),
+ std::move(overlay_candidate_validator)),
#if defined(OS_MACOSX)
should_show_frames_state_(SHOULD_SHOW_FRAMES),
#endif
- swap_buffers_completion_callback_(
- base::Bind(&GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted,
- base::Unretained(this))),
+ swap_buffers_completion_callback_(base::Bind(
+ &GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted,
+ base::Unretained(this))),
update_vsync_parameters_callback_(base::Bind(
&BrowserCompositorOutputSurface::OnUpdateVSyncParametersFromGpu,
base::Unretained(this))) {
@@ -58,6 +61,10 @@ bool GpuBrowserCompositorOutputSurface::BindToClient(
swap_buffers_completion_callback_.callback());
GetCommandBufferProxy()->SetUpdateVSyncParametersCallback(
update_vsync_parameters_callback_.callback());
+ if (capabilities_.uses_default_gl_framebuffer) {
+ capabilities_.flipped_output_surface =
+ context_provider()->ContextCapabilities().gpu.flips_vertically;
+ }
return true;
}
@@ -106,24 +113,14 @@ void GpuBrowserCompositorOutputSurface::SwapBuffers(
#endif
}
-void GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted(
+void GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
const std::vector<ui::LatencyInfo>& latency_info,
gfx::SwapResult result) {
-#if defined(OS_MACOSX)
- // On Mac, delay acknowledging the swap to the output surface client until
- // it has been drawn, see OnSurfaceDisplayed();
- NOTREACHED();
-#else
RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
OnSwapBuffersComplete();
-#endif
}
#if defined(OS_MACOSX)
-void GpuBrowserCompositorOutputSurface::OnSurfaceDisplayed() {
- cc::OutputSurface::OnSwapBuffersComplete();
-}
-
void GpuBrowserCompositorOutputSurface::SetSurfaceSuspendedForRecycle(
bool suspended) {
if (suspended) {
diff --git a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
index 7b4f2428122..ae08e8d1a2d 100644
--- a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
@@ -6,6 +6,8 @@
#define CONTENT_BROWSER_COMPOSITOR_GPU_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
#include "base/cancelable_callback.h"
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "ui/gfx/swap_result.h"
@@ -36,6 +38,9 @@ class GpuBrowserCompositorOutputSurface
protected:
// BrowserCompositorOutputSurface:
void OnReflectorChanged() override;
+ void OnGpuSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) override;
// cc::OutputSurface implementation.
void SwapBuffers(cc::CompositorFrame* frame) override;
@@ -43,7 +48,6 @@ class GpuBrowserCompositorOutputSurface
bool SurfaceIsSuspendForRecycle() const override;
#if defined(OS_MACOSX)
- void OnSurfaceDisplayed() override;
void SetSurfaceSuspendedForRecycle(bool suspended) override;
bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override;
enum ShouldShowFramesState {
@@ -61,9 +65,6 @@ class GpuBrowserCompositorOutputSurface
#endif
CommandBufferProxyImpl* GetCommandBufferProxy();
- virtual void OnSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result);
base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&,
gfx::SwapResult)>
diff --git a/chromium/content/browser/compositor/gpu_process_transport_factory.cc b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
index b7ed84406a3..874debf5f1e 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
@@ -5,6 +5,7 @@
#include "content/browser/compositor/gpu_process_transport_factory.h"
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
@@ -14,9 +15,11 @@
#include "base/thread_task_runner_handle.h"
#include "base/threading/simple_thread.h"
#include "base/threading/thread.h"
+#include "build/build_config.h"
#include "cc/base/histograms.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/output_surface.h"
+#include "cc/raster/single_thread_task_graph_runner.h"
#include "cc/raster/task_graph_runner.h"
#include "cc/surfaces/onscreen_display_client.h"
#include "cc/surfaces/surface_display_output_surface.h"
@@ -28,6 +31,7 @@
#include "content/browser/compositor/offscreen_browser_compositor_output_surface.h"
#include "content/browser/compositor/reflector_impl.h"
#include "content/browser/compositor/software_browser_compositor_output_surface.h"
+#include "content/browser/compositor/software_output_device_mus.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/compositor_util.h"
@@ -52,6 +56,10 @@
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_widget_types.h"
+#if defined(MOJO_RUNNER_CLIENT)
+#include "content/common/mojo/mojo_shell_connection_impl.h"
+#endif
+
#if defined(OS_WIN)
#include "content/browser/compositor/software_output_device_win.h"
#elif defined(USE_OZONE)
@@ -66,6 +74,9 @@
#elif defined(OS_MACOSX)
#include "content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h"
#include "content/browser/compositor/software_output_device_mac.h"
+#include "ui/base/cocoa/remote_layer_api.h"
+#elif defined(OS_ANDROID)
+#include "content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h"
#endif
using cc::ContextProvider;
@@ -74,24 +85,6 @@ using gpu::gles2::GLES2Interface;
static const int kNumRetriesBeforeSoftwareFallback = 4;
namespace content {
-namespace {
-
-class RasterThread : public base::SimpleThread {
- public:
- RasterThread(cc::TaskGraphRunner* task_graph_runner)
- : base::SimpleThread("CompositorTileWorker1"),
- task_graph_runner_(task_graph_runner) {}
-
- // Overridden from base::SimpleThread:
- void Run() override { task_graph_runner_->Run(); }
-
- private:
- cc::TaskGraphRunner* task_graph_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(RasterThread);
-};
-
-} // namespace
struct GpuProcessTransportFactory::PerCompositorData {
int surface_id;
@@ -104,7 +97,7 @@ struct GpuProcessTransportFactory::PerCompositorData {
GpuProcessTransportFactory::GpuProcessTransportFactory()
: next_surface_id_namespace_(1u),
- task_graph_runner_(new cc::TaskGraphRunner),
+ task_graph_runner_(new cc::SingleThreadTaskGraphRunner),
callback_factory_(this) {
ui::Layer::InitializeUILayerSettings();
cc::SetClientNameForMetrics("Browser");
@@ -112,8 +105,8 @@ GpuProcessTransportFactory::GpuProcessTransportFactory()
if (UseSurfacesEnabled())
surface_manager_ = make_scoped_ptr(new cc::SurfaceManager);
- raster_thread_.reset(new RasterThread(task_graph_runner_.get()));
- raster_thread_->Start();
+ task_graph_runner_->Start("CompositorTileWorker1",
+ base::SimpleThread::Options());
#if defined(OS_WIN)
software_backing_.reset(new OutputDeviceBacking);
#endif
@@ -126,28 +119,36 @@ GpuProcessTransportFactory::~GpuProcessTransportFactory() {
callback_factory_.InvalidateWeakPtrs();
task_graph_runner_->Shutdown();
- if (raster_thread_)
- raster_thread_->Join();
}
scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() {
+#if defined(OS_ANDROID)
+ return CreateContextCommon(scoped_refptr<GpuChannelHost>(nullptr), 0);
+#else
CauseForGpuLaunch cause =
CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
scoped_refptr<GpuChannelHost> gpu_channel_host(
BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause));
return CreateContextCommon(gpu_channel_host, 0);
+#endif // OS_ANDROID
}
scoped_ptr<cc::SoftwareOutputDevice>
GpuProcessTransportFactory::CreateSoftwareOutputDevice(
ui::Compositor* compositor) {
+#if defined(MOJO_RUNNER_CLIENT)
+ if (IsRunningInMojoShell()) {
+ return scoped_ptr<cc::SoftwareOutputDevice>(
+ new SoftwareOutputDeviceMus(compositor));
+ }
+#endif
+
#if defined(OS_WIN)
return scoped_ptr<cc::SoftwareOutputDevice>(
new SoftwareOutputDeviceWin(software_backing_.get(), compositor));
#elif defined(USE_OZONE)
- return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceOzone(
- compositor));
+ return SoftwareOutputDeviceOzone::Create(compositor);
#elif defined(USE_X11)
return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceX11(
compositor));
@@ -162,6 +163,7 @@ GpuProcessTransportFactory::CreateSoftwareOutputDevice(
scoped_ptr<BrowserCompositorOverlayCandidateValidator>
CreateOverlayCandidateValidator(gfx::AcceleratedWidget widget) {
+ scoped_ptr<BrowserCompositorOverlayCandidateValidator> validator;
#if defined(USE_OZONE)
scoped_ptr<ui::OverlayCandidatesOzone> overlay_candidates =
ui::OzonePlatform::GetInstance()
@@ -171,18 +173,30 @@ CreateOverlayCandidateValidator(gfx::AcceleratedWidget widget) {
if (overlay_candidates &&
(command_line->HasSwitch(switches::kEnableHardwareOverlays) ||
command_line->HasSwitch(switches::kOzoneTestSingleOverlaySupport))) {
- return scoped_ptr<BrowserCompositorOverlayCandidateValidator>(
- new BrowserCompositorOverlayCandidateValidatorOzone(
- widget, overlay_candidates.Pass()));
+ validator.reset(new BrowserCompositorOverlayCandidateValidatorOzone(
+ widget, std::move(overlay_candidates)));
}
#elif defined(OS_MACOSX)
- return make_scoped_ptr(
- new BrowserCompositorOverlayCandidateValidatorMac(widget));
+ // Overlays are only supported through the remote layer API.
+ if (ui::RemoteLayerAPISupported()) {
+ validator.reset(new BrowserCompositorOverlayCandidateValidatorMac(widget));
+ }
+#elif defined(OS_ANDROID)
+ validator.reset(new BrowserCompositorOverlayCandidateValidatorAndroid());
#endif
- return scoped_ptr<BrowserCompositorOverlayCandidateValidator>();
+
+ return validator;
}
static bool ShouldCreateGpuOutputSurface(ui::Compositor* compositor) {
+#if defined(MOJO_RUNNER_CLIENT)
+ // Chrome running as a mojo app currently can only use software compositing.
+ // TODO(rjkroege): http://crbug.com/548451
+ if (IsRunningInMojoShell()) {
+ return false;
+ }
+#endif
+
#if defined(OS_CHROMEOS)
// Software fallback does not happen on Chrome OS.
return true;
@@ -230,7 +244,14 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
int num_attempts) {
if (!compositor)
return;
- PerCompositorData* data = per_compositor_data_[compositor.get()];
+
+ // The widget might have been released in the meantime.
+ PerCompositorDataMap::iterator it =
+ per_compositor_data_.find(compositor.get());
+ if (it == per_compositor_data_.end())
+ return;
+
+ PerCompositorData* data = it->second;
DCHECK(data);
if (num_attempts > kNumRetriesBeforeSoftwareFallback) {
@@ -329,7 +350,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
#endif
surface = make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
context_provider, shared_worker_context_provider_,
- compositor->vsync_manager(), validator.Pass()));
+ compositor->vsync_manager(), std::move(validator)));
}
}
@@ -341,7 +362,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
data->reflector->OnSourceSurfaceReady(data->surface);
if (!UseSurfacesEnabled()) {
- compositor->SetOutputSurface(surface.Pass());
+ compositor->SetOutputSurface(std::move(surface));
return;
}
@@ -352,7 +373,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
cc::SurfaceManager* manager = surface_manager_.get();
scoped_ptr<cc::OnscreenDisplayClient> display_client(
new cc::OnscreenDisplayClient(
- surface.Pass(), manager, HostSharedBitmapManager::current(),
+ std::move(surface), manager, HostSharedBitmapManager::current(),
BrowserGpuMemoryBufferManager::current(),
compositor->GetRendererSettings(), compositor->task_runner()));
@@ -363,8 +384,8 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
display_client->set_surface_output_surface(output_surface.get());
output_surface->set_display_client(display_client.get());
display_client->display()->Resize(compositor->size());
- data->display_client = display_client.Pass();
- compositor->SetOutputSurface(output_surface.Pass());
+ data->display_client = std::move(display_client);
+ compositor->SetOutputSurface(std::move(output_surface));
}
scoped_ptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
@@ -378,7 +399,7 @@ scoped_ptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
source_data->reflector = reflector.get();
if (BrowserCompositorOutputSurface* source_surface = source_data->surface)
reflector->OnSourceSurfaceReady(source_surface);
- return reflector.Pass();
+ return std::move(reflector);
}
void GpuProcessTransportFactory::RemoveReflector(ui::Reflector* reflector) {
@@ -410,7 +431,7 @@ void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
// GLHelper created in this case would be lost/leaked if we just reset()
// on the |gl_helper_| variable directly. So instead we call reset() on a
// local scoped_ptr.
- scoped_ptr<GLHelper> helper = gl_helper_.Pass();
+ scoped_ptr<GLHelper> helper = std::move(gl_helper_);
// If there are any observer left at this point, make sure they clean up
// before we destroy the GLHelper.
@@ -425,7 +446,7 @@ void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
-uint32 GpuProcessTransportFactory::GetImageTextureTarget(
+uint32_t GpuProcessTransportFactory::GetImageTextureTarget(
gfx::BufferFormat format,
gfx::BufferUsage usage) {
return BrowserGpuMemoryBufferManager::GetImageTextureTarget(format, usage);
@@ -494,11 +515,14 @@ void GpuProcessTransportFactory::RemoveObserver(
}
#if defined(OS_MACOSX)
-void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id) {
+void GpuProcessTransportFactory::OnGpuSwapBuffersCompleted(
+ int surface_id,
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) {
BrowserCompositorOutputSurface* surface = output_surface_map_.Lookup(
surface_id);
if (surface)
- surface->OnSurfaceDisplayed();
+ surface->OnGpuSwapBuffersCompleted(latency_info, result);
}
void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
@@ -607,7 +631,7 @@ GpuProcessTransportFactory::CreateContextCommon(
lose_context_when_out_of_memory,
WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
NULL));
- return context.Pass();
+ return context;
}
void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
@@ -628,7 +652,7 @@ void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
shared_main_thread_contexts_;
shared_main_thread_contexts_ = NULL;
- scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass();
+ scoped_ptr<GLHelper> lost_gl_helper = std::move(gl_helper_);
FOR_EACH_OBSERVER(ImageTransportFactoryObserver,
observer_list_,
diff --git a/chromium/content/browser/compositor/gpu_process_transport_factory.h b/chromium/content/browser/compositor/gpu_process_transport_factory.h
index 195bf15f22f..ee8d60e9ac9 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.h
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.h
@@ -5,13 +5,17 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_GPU_PROCESS_TRANSPORT_FACTORY_H_
#define CONTENT_BROWSER_COMPOSITOR_GPU_PROCESS_TRANSPORT_FACTORY_H_
+#include <stdint.h>
+
#include <map>
#include "base/id_map.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
+#include "build/build_config.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "ui/compositor/compositor.h"
@@ -22,6 +26,7 @@ class Thread;
}
namespace cc {
+class SingleThreadTaskGraphRunner;
class SoftwareOutputDevice;
class SurfaceManager;
}
@@ -53,8 +58,8 @@ class GpuProcessTransportFactory
void RemoveCompositor(ui::Compositor* compositor) override;
scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override;
bool DoesCreateTestContexts() override;
- uint32 GetImageTextureTarget(gfx::BufferFormat format,
- gfx::BufferUsage usage) override;
+ uint32_t GetImageTextureTarget(gfx::BufferFormat format,
+ gfx::BufferUsage usage) override;
cc::SharedBitmapManager* GetSharedBitmapManager() override;
gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
cc::TaskGraphRunner* GetTaskGraphRunner() override;
@@ -69,7 +74,10 @@ class GpuProcessTransportFactory
void AddObserver(ImageTransportFactoryObserver* observer) override;
void RemoveObserver(ImageTransportFactoryObserver* observer) override;
#if defined(OS_MACOSX)
- void OnSurfaceDisplayed(int surface_id) override;
+ void OnGpuSwapBuffersCompleted(
+ int surface_id,
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) override;
void SetCompositorSuspendedForRecycle(ui::Compositor* compositor,
bool suspended) override;
bool SurfaceShouldNotShowFramesAfterSuspendForRecycle(
@@ -99,8 +107,7 @@ class GpuProcessTransportFactory
base::ObserverList<ImageTransportFactoryObserver> observer_list_;
scoped_ptr<cc::SurfaceManager> surface_manager_;
uint32_t next_surface_id_namespace_;
- scoped_ptr<cc::TaskGraphRunner> task_graph_runner_;
- scoped_ptr<base::SimpleThread> raster_thread_;
+ scoped_ptr<cc::SingleThreadTaskGraphRunner> task_graph_runner_;
scoped_refptr<ContextProviderCommandBuffer> shared_worker_context_provider_;
#if defined(OS_WIN)
diff --git a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
index 0ce27732e49..0913548f2fa 100644
--- a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
@@ -4,6 +4,8 @@
#include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
+#include <utility>
+
#include "cc/output/compositor_frame.h"
#include "cc/output/output_surface_client.h"
#include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
@@ -31,7 +33,7 @@ GpuSurfacelessBrowserCompositorOutputSurface::
: GpuBrowserCompositorOutputSurface(context,
worker_context,
vsync_manager,
- overlay_candidate_validator.Pass()),
+ std::move(overlay_candidate_validator)),
internalformat_(internalformat),
gpu_memory_buffer_manager_(gpu_memory_buffer_manager) {
capabilities_.uses_default_gl_framebuffer = false;
@@ -87,18 +89,16 @@ void GpuSurfacelessBrowserCompositorOutputSurface::BindFramebuffer() {
void GpuSurfacelessBrowserCompositorOutputSurface::Reshape(
const gfx::Size& size,
- float scale_factor) {
- GpuBrowserCompositorOutputSurface::Reshape(size, scale_factor);
+ float scale_factor,
+ bool alpha) {
+ GpuBrowserCompositorOutputSurface::Reshape(size, scale_factor, alpha);
DCHECK(output_surface_);
output_surface_->Reshape(SurfaceSize(), scale_factor);
}
-void GpuSurfacelessBrowserCompositorOutputSurface::OnSwapBuffersCompleted(
+void GpuSurfacelessBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
const std::vector<ui::LatencyInfo>& latency_info,
gfx::SwapResult result) {
-#if defined(OS_MACOSX)
- NOTREACHED();
-#else
bool force_swap = false;
if (result == gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS) {
// Even through the swap failed, this is a fixable error so we can pretend
@@ -107,17 +107,10 @@ void GpuSurfacelessBrowserCompositorOutputSurface::OnSwapBuffersCompleted(
output_surface_->RecreateBuffers();
force_swap = true;
}
- GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted(latency_info,
- result);
+ GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(latency_info,
+ result);
if (force_swap)
client_->SetNeedsRedrawRect(gfx::Rect(SurfaceSize()));
-#endif
-}
-
-#if defined(OS_MACOSX)
-void GpuSurfacelessBrowserCompositorOutputSurface::OnSurfaceDisplayed() {
- OnSwapBuffersComplete();
}
-#endif
} // namespace content
diff --git a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h
index d7337721c74..a869fccd8cf 100644
--- a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h
@@ -33,15 +33,14 @@ class GpuSurfacelessBrowserCompositorOutputSurface
void SwapBuffers(cc::CompositorFrame* frame) override;
void OnSwapBuffersComplete() override;
void BindFramebuffer() override;
- void Reshape(const gfx::Size& size, float scale_factor) override;
+ void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override;
bool IsDisplayedAsOverlayPlane() const override;
unsigned GetOverlayTextureId() const override;
- void OnSwapBuffersCompleted(const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result) override;
-#if defined(OS_MACOSX)
- void OnSurfaceDisplayed() override;
-#endif
+ // BrowserCompositorOutputSurface implementation.
+ void OnGpuSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) override;
unsigned int internalformat_;
scoped_ptr<GLHelper> gl_helper_;
diff --git a/chromium/content/browser/compositor/image_transport_factory.h b/chromium/content/browser/compositor/image_transport_factory.h
index a5cd0898b5a..744d2c050e7 100644
--- a/chromium/content/browser/compositor/image_transport_factory.h
+++ b/chromium/content/browser/compositor/image_transport_factory.h
@@ -9,8 +9,10 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "cc/surfaces/surface_id_allocator.h"
#include "content/common/content_export.h"
+#include "ui/events/latency_info.h"
#include "ui/gfx/native_widget_types.h"
namespace cc {
@@ -19,6 +21,7 @@ class SurfaceManager;
namespace gfx {
class Size;
+enum class SwapResult;
}
namespace ui {
@@ -83,7 +86,11 @@ class CONTENT_EXPORT ImageTransportFactory {
virtual void RemoveObserver(ImageTransportFactoryObserver* observer) = 0;
#if defined(OS_MACOSX)
- virtual void OnSurfaceDisplayed(int surface_id) = 0;
+ virtual void OnGpuSwapBuffersCompleted(
+ int surface_id,
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) = 0;
+
// Called with |suspended| as true when the ui::Compositor has been
// disconnected from an NSView and may be attached to another one. Called
// with |suspended| as false after the ui::Compositor has been connected to
diff --git a/chromium/content/browser/compositor/image_transport_factory_browsertest.cc b/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
index 327db05f62f..bd2f2c1b6e4 100644
--- a/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
+++ b/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
@@ -5,6 +5,7 @@
#include "content/browser/compositor/image_transport_factory.h"
#include "base/run_loop.h"
+#include "build/build_config.h"
#include "cc/output/context_provider.h"
#include "content/browser/compositor/owned_mailbox.h"
#include "content/public/browser/gpu_data_manager.h"
diff --git a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
index da972c767d4..eaadce55499 100644
--- a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
@@ -4,7 +4,10 @@
#include "content/browser/compositor/offscreen_browser_compositor_output_surface.h"
+#include <utility>
+
#include "base/logging.h"
+#include "build/build_config.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/output/gl_frame_data.h"
@@ -37,11 +40,10 @@ OffscreenBrowserCompositorOutputSurface::
: BrowserCompositorOutputSurface(context,
worker_context,
vsync_manager,
- overlay_candidate_validator.Pass()),
+ std::move(overlay_candidate_validator)),
fbo_(0),
is_backbuffer_discarded_(false),
weak_ptr_factory_(this) {
- capabilities_.max_frames_pending = 1;
capabilities_.uses_default_gl_framebuffer = false;
}
@@ -103,7 +105,8 @@ void OffscreenBrowserCompositorOutputSurface::DiscardBackbuffer() {
}
void OffscreenBrowserCompositorOutputSurface::Reshape(const gfx::Size& size,
- float scale_factor) {
+ float scale_factor,
+ bool alpha) {
if (size == surface_size_)
return;
@@ -139,10 +142,14 @@ void OffscreenBrowserCompositorOutputSurface::SwapBuffers(
// TODO(oshima): sync with the reflector's SwapBuffersComplete
// (crbug.com/520567).
// The original implementation had a flickering issue (crbug.com/515332).
- uint32_t sync_point =
- context_provider_->ContextGL()->InsertSyncPointCHROMIUM();
- context_provider_->ContextSupport()->SignalSyncPoint(
- sync_point, base::Bind(&OutputSurface::OnSwapBuffersComplete,
+ gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+ const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
+ gl->ShallowFlushCHROMIUM();
+
+ gpu::SyncToken sync_token;
+ gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
+ context_provider_->ContextSupport()->SignalSyncToken(
+ sync_token, base::Bind(&OutputSurface::OnSwapBuffersComplete,
weak_ptr_factory_.GetWeakPtr()));
}
diff --git a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h
index c9e32e7876d..abbb20c065d 100644
--- a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_OFFSCREEN_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
#define CONTENT_BROWSER_COMPOSITOR_OFFSCREEN_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
+#include <stdint.h>
+
#include "base/cancelable_callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
namespace ui {
@@ -34,20 +38,22 @@ class OffscreenBrowserCompositorOutputSurface
// cc::OutputSurface:
void EnsureBackbuffer() override;
void DiscardBackbuffer() override;
- void Reshape(const gfx::Size& size, float scale_factor) override;
+ void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override;
void BindFramebuffer() override;
void SwapBuffers(cc::CompositorFrame* frame) override;
// BrowserCompositorOutputSurface
void OnReflectorChanged() override;
base::Closure CreateCompositionStartedCallback() override;
+ void OnGpuSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) override{};
#if defined(OS_MACOSX)
- void OnSurfaceDisplayed() override {};
void SetSurfaceSuspendedForRecycle(bool suspended) override {};
bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override;
#endif
- uint32 fbo_;
+ uint32_t fbo_;
bool is_backbuffer_discarded_;
scoped_ptr<ReflectorTexture> reflector_texture_;
diff --git a/chromium/content/browser/compositor/owned_mailbox.cc b/chromium/content/browser/compositor/owned_mailbox.cc
index 9c7b37861f4..912d4d569b7 100644
--- a/chromium/content/browser/compositor/owned_mailbox.cc
+++ b/chromium/content/browser/compositor/owned_mailbox.cc
@@ -22,14 +22,14 @@ OwnedMailbox::~OwnedMailbox() {
Destroy();
}
-void OwnedMailbox::UpdateSyncPoint(uint32 sync_point) {
- if (sync_point)
- mailbox_holder_.sync_point = sync_point;
+void OwnedMailbox::UpdateSyncToken(const gpu::SyncToken& sync_token) {
+ if (sync_token.HasData())
+ mailbox_holder_.sync_token = sync_token;
}
void OwnedMailbox::Destroy() {
ImageTransportFactory::GetInstance()->RemoveObserver(this);
- gl_helper_->WaitSyncPoint(mailbox_holder_.sync_point);
+ gl_helper_->WaitSyncToken(mailbox_holder_.sync_token);
gl_helper_->DeleteTexture(texture_id_);
texture_id_ = 0;
mailbox_holder_ = gpu::MailboxHolder();
diff --git a/chromium/content/browser/compositor/owned_mailbox.h b/chromium/content/browser/compositor/owned_mailbox.h
index c8868148f4d..796e02edf91 100644
--- a/chromium/content/browser/compositor/owned_mailbox.h
+++ b/chromium/content/browser/compositor/owned_mailbox.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_OWNED_MAILBOX_H_
#define CONTENT_BROWSER_COMPOSITOR_OWNED_MAILBOX_H_
+#include <stdint.h>
+
#include "base/memory/ref_counted.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/common/content_export.h"
@@ -24,10 +26,12 @@ class CONTENT_EXPORT OwnedMailbox : public base::RefCounted<OwnedMailbox>,
const gpu::MailboxHolder& holder() const { return mailbox_holder_; }
const gpu::Mailbox& mailbox() const { return mailbox_holder_.mailbox; }
- uint32 texture_id() const { return texture_id_; }
- uint32 target() const { return mailbox_holder_.texture_target; }
- uint32 sync_point() const { return mailbox_holder_.sync_point; }
- void UpdateSyncPoint(uint32 sync_point);
+ const gpu::SyncToken& sync_token() const {
+ return mailbox_holder_.sync_token;
+ }
+ uint32_t texture_id() const { return texture_id_; }
+ uint32_t target() const { return mailbox_holder_.texture_target; }
+ void UpdateSyncToken(const gpu::SyncToken& sync_token);
void Destroy();
protected:
@@ -39,7 +43,7 @@ class CONTENT_EXPORT OwnedMailbox : public base::RefCounted<OwnedMailbox>,
private:
friend class base::RefCounted<OwnedMailbox>;
- uint32 texture_id_;
+ uint32_t texture_id_;
gpu::MailboxHolder mailbox_holder_;
GLHelper* gl_helper_;
};
diff --git a/chromium/content/browser/compositor/reflector_impl.cc b/chromium/content/browser/compositor/reflector_impl.cc
index dcc0dc2bbe6..c7259dc08d9 100644
--- a/chromium/content/browser/compositor/reflector_impl.cc
+++ b/chromium/content/browser/compositor/reflector_impl.cc
@@ -8,7 +8,6 @@
#include "base/location.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/browser/compositor/owned_mailbox.h"
-//#include "content/common/gpu/client/gl_helper.h"
#include "ui/compositor/layer.h"
namespace content {
@@ -170,9 +169,9 @@ void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& rect) {
}
static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox,
- unsigned int sync_point,
+ const gpu::SyncToken& sync_token,
bool is_lost) {
- mailbox->UpdateSyncPoint(sync_point);
+ mailbox->UpdateSyncToken(sync_token);
}
ScopedVector<ReflectorImpl::LayerData>::iterator ReflectorImpl::FindLayerData(
diff --git a/chromium/content/browser/compositor/reflector_impl_unittest.cc b/chromium/content/browser/compositor/reflector_impl_unittest.cc
index 228a596151f..cebaf514dda 100644
--- a/chromium/content/browser/compositor/reflector_impl_unittest.cc
+++ b/chromium/content/browser/compositor/reflector_impl_unittest.cc
@@ -4,6 +4,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "build/build_config.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/test_context_provider.h"
#include "cc/test/test_web_graphics_context_3d.h"
@@ -76,7 +77,7 @@ class TestOutputSurface : public BrowserCompositorOutputSurface {
: BrowserCompositorOutputSurface(context_provider,
nullptr,
vsync_manager,
- CreateTestValidatorOzone().Pass()) {
+ CreateTestValidatorOzone()) {
surface_size_ = gfx::Size(256, 256);
device_scale_factor_ = 1.f;
}
@@ -94,8 +95,13 @@ class TestOutputSurface : public BrowserCompositorOutputSurface {
}
}
+ void OnGpuSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) override {
+ NOTREACHED();
+ }
+
#if defined(OS_MACOSX)
- void OnSurfaceDisplayed() override {}
void SetSurfaceSuspendedForRecycle(bool suspended) override {}
bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override {
return false;
@@ -124,14 +130,11 @@ class ReflectorImplTest : public testing::Test {
compositor_task_runner_ = new FakeTaskRunner();
compositor_.reset(
new ui::Compositor(context_factory, compositor_task_runner_.get()));
- compositor_->SetAcceleratedWidgetAndStartCompositor(
- gfx::kNullAcceleratedWidget);
- context_provider_ = cc::TestContextProvider::Create(
- cc::TestWebGraphicsContext3D::Create().Pass());
- output_surface_ =
- scoped_ptr<TestOutputSurface>(
- new TestOutputSurface(context_provider_,
- compositor_->vsync_manager())).Pass();
+ compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
+ context_provider_ =
+ cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create());
+ output_surface_ = scoped_ptr<TestOutputSurface>(
+ new TestOutputSurface(context_provider_, compositor_->vsync_manager()));
CHECK(output_surface_->BindToClient(&output_surface_client_));
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
@@ -154,7 +157,7 @@ class ReflectorImplTest : public testing::Test {
cc::TextureMailbox mailbox;
scoped_ptr<cc::SingleReleaseCallback> release;
if (mirroring_layer_->PrepareTextureMailbox(&mailbox, &release, false)) {
- release->Run(0, false);
+ release->Run(gpu::SyncToken(), false);
}
compositor_.reset();
ui::TerminateContextFactoryForTests();
diff --git a/chromium/content/browser/compositor/reflector_texture.cc b/chromium/content/browser/compositor/reflector_texture.cc
index ed6a3bd86db..231066275d9 100644
--- a/chromium/content/browser/compositor/reflector_texture.cc
+++ b/chromium/content/browser/compositor/reflector_texture.cc
@@ -21,8 +21,8 @@ ReflectorTexture::ReflectorTexture(cc::ContextProvider* context_provider)
gl_helper_.reset(new GLHelper(gl, context_provider->ContextSupport()));
- texture_id_ = gl_helper_->ConsumeMailboxToTexture(
- mailbox_->mailbox(), mailbox_->sync_point());
+ texture_id_ = gl_helper_->ConsumeMailboxToTexture(mailbox_->mailbox(),
+ mailbox_->sync_token());
}
ReflectorTexture::~ReflectorTexture() {
diff --git a/chromium/content/browser/compositor/reflector_texture.h b/chromium/content/browser/compositor/reflector_texture.h
index cacabd39c15..cc8f98ce19f 100644
--- a/chromium/content/browser/compositor/reflector_texture.h
+++ b/chromium/content/browser/compositor/reflector_texture.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_REFLECTOR_TEXTURE_H_
#define CONTENT_BROWSER_COMPOSITOR_REFLECTOR_TEXTURE_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/compositor/owned_mailbox.h"
@@ -31,13 +34,13 @@ class CONTENT_EXPORT ReflectorTexture {
void CopyTextureFullImage(const gfx::Size& size);
void CopyTextureSubImage(const gfx::Rect& size);
- uint32 texture_id() const { return texture_id_; }
+ uint32_t texture_id() const { return texture_id_; }
scoped_refptr<OwnedMailbox> mailbox() { return mailbox_; }
private:
scoped_refptr<OwnedMailbox> mailbox_;
scoped_ptr<GLHelper> gl_helper_;
- uint32 texture_id_;
+ uint32_t texture_id_;
DISALLOW_COPY_AND_ASSIGN(ReflectorTexture);
};
diff --git a/chromium/content/browser/compositor/resize_lock.h b/chromium/content/browser/compositor/resize_lock.h
index 306a19d39f1..8b4829785eb 100644
--- a/chromium/content/browser/compositor/resize_lock.h
+++ b/chromium/content/browser/compositor/resize_lock.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_RESIZE_LOCK_H_
#define CONTENT_BROWSER_COMPOSITOR_RESIZE_LOCK_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/size.h"
diff --git a/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
index 866853c6972..151ed5fc406 100644
--- a/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -4,11 +4,14 @@
#include "content/browser/compositor/software_browser_compositor_output_surface.h"
+#include <utility>
+
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/output_surface_client.h"
#include "cc/output/software_output_device.h"
@@ -21,10 +24,8 @@ namespace content {
SoftwareBrowserCompositorOutputSurface::SoftwareBrowserCompositorOutputSurface(
scoped_ptr<cc::SoftwareOutputDevice> software_device,
const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager)
- : BrowserCompositorOutputSurface(software_device.Pass(),
- vsync_manager),
- weak_factory_(this) {
-}
+ : BrowserCompositorOutputSurface(std::move(software_device), vsync_manager),
+ weak_factory_(this) {}
SoftwareBrowserCompositorOutputSurface::
~SoftwareBrowserCompositorOutputSurface() {
@@ -54,12 +55,13 @@ void SoftwareBrowserCompositorOutputSurface::SwapBuffers(
client_->DidSwapBuffers();
}
-#if defined(OS_MACOSX)
-void SoftwareBrowserCompositorOutputSurface::OnSurfaceDisplayed() {
- // See GpuBrowserCompositorOutputSurface for when and how this is used.
- NOTREACHED() << "Not expected for software surfaces.";
+void SoftwareBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) {
+ NOTREACHED();
}
+#if defined(OS_MACOSX)
void SoftwareBrowserCompositorOutputSurface::SetSurfaceSuspendedForRecycle(
bool suspended) {
}
diff --git a/chromium/content/browser/compositor/software_browser_compositor_output_surface.h b/chromium/content/browser/compositor/software_browser_compositor_output_surface.h
index 68776ca7aa6..9e8bbcf1e1a 100644
--- a/chromium/content/browser/compositor/software_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/software_browser_compositor_output_surface.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_SOFTWARE_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_BROWSER_COMPOSITOR_OUTPUT_SURFACE_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/common/content_export.h"
@@ -30,9 +32,11 @@ class CONTENT_EXPORT SoftwareBrowserCompositorOutputSurface
private:
void SwapBuffers(cc::CompositorFrame* frame) override;
+ void OnGpuSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) override;
#if defined(OS_MACOSX)
- void OnSurfaceDisplayed() override;
void SetSurfaceSuspendedForRecycle(bool suspended) override;
bool SurfaceShouldNotShowFramesAfterSuspendForRecycle() const override;
#endif
diff --git a/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc b/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
index 3b9f8b01730..51a2c777910 100644
--- a/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
+++ b/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
@@ -2,10 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/compositor/software_browser_compositor_output_surface.h"
+
+#include <utility>
+
+#include "base/macros.h"
#include "base/thread_task_runner_handle.h"
#include "cc/output/compositor_frame.h"
#include "cc/test/fake_output_surface_client.h"
-#include "content/browser/compositor/software_browser_compositor_output_surface.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/test/context_factories_for_test.h"
@@ -91,8 +95,7 @@ void SoftwareBrowserCompositorOutputSurfaceTest::SetUp() {
compositor_.reset(
new ui::Compositor(context_factory, base::ThreadTaskRunnerHandle::Get()));
- compositor_->SetAcceleratedWidgetAndStartCompositor(
- gfx::kNullAcceleratedWidget);
+ compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
}
void SoftwareBrowserCompositorOutputSurfaceTest::TearDown() {
@@ -106,15 +109,14 @@ SoftwareBrowserCompositorOutputSurfaceTest::CreateSurface(
scoped_ptr<cc::SoftwareOutputDevice> device) {
return scoped_ptr<content::BrowserCompositorOutputSurface>(
new content::SoftwareBrowserCompositorOutputSurface(
- device.Pass(),
- compositor_->vsync_manager()));
+ std::move(device), compositor_->vsync_manager()));
}
TEST_F(SoftwareBrowserCompositorOutputSurfaceTest, NoVSyncProvider) {
cc::FakeOutputSurfaceClient output_surface_client;
scoped_ptr<cc::SoftwareOutputDevice> software_device(
new cc::SoftwareOutputDevice());
- output_surface_ = CreateSurface(software_device.Pass());
+ output_surface_ = CreateSurface(std::move(software_device));
CHECK(output_surface_->BindToClient(&output_surface_client));
cc::CompositorFrame frame;
@@ -128,7 +130,7 @@ TEST_F(SoftwareBrowserCompositorOutputSurfaceTest, VSyncProviderUpdates) {
cc::FakeOutputSurfaceClient output_surface_client;
scoped_ptr<cc::SoftwareOutputDevice> software_device(
new FakeSoftwareOutputDevice());
- output_surface_ = CreateSurface(software_device.Pass());
+ output_surface_ = CreateSurface(std::move(software_device));
CHECK(output_surface_->BindToClient(&output_surface_client));
FakeVSyncProvider* vsync_provider = static_cast<FakeVSyncProvider*>(
diff --git a/chromium/content/browser/compositor/software_output_device_mac.h b/chromium/content/browser/compositor/software_output_device_mac.h
index 5b6ac86b77d..a613ab4b1d8 100644
--- a/chromium/content/browser/compositor/software_output_device_mac.h
+++ b/chromium/content/browser/compositor/software_output_device_mac.h
@@ -5,7 +5,13 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MAC_H_
#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MAC_H_
+#include <IOSurface/IOSurface.h>
+
+#include "base/mac/scoped_cftyperef.h"
+#include "base/macros.h"
#include "cc/output/software_output_device.h"
+#include "third_party/skia/include/core/SkRegion.h"
+#include "ui/gfx/vsync_provider.h"
namespace gfx {
class Canvas;
@@ -17,15 +23,49 @@ class Compositor;
namespace content {
-class SoftwareOutputDeviceMac : public cc::SoftwareOutputDevice {
+class SoftwareOutputDeviceMac :
+ public cc::SoftwareOutputDevice,
+ public gfx::VSyncProvider {
public:
explicit SoftwareOutputDeviceMac(ui::Compositor* compositor);
~SoftwareOutputDeviceMac() override;
+ // cc::SoftwareOutputDevice implementation.
+ void Resize(const gfx::Size& pixel_size, float scale_factor) override;
+ SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
void EndPaint() override;
+ void DiscardBackbuffer() override;
+ void EnsureBackbuffer() override;
+ gfx::VSyncProvider* GetVSyncProvider() override;
+
+ // gfx::VSyncProvider implementation.
+ void GetVSyncParameters(
+ const gfx::VSyncProvider::UpdateVSyncCallback& callback) override;
private:
+ bool EnsureBuffersExist();
+
+ // Copy the pixels from the previous buffer to the new buffer.
+ void CopyPreviousBufferDamage(const SkRegion& new_damage_rect);
+
ui::Compositor* compositor_;
+ gfx::Size pixel_size_;
+ float scale_factor_;
+
+ // This surface is double-buffered. The two buffers are in |io_surfaces_|,
+ // and the index of the current buffer is |current_buffer_|.
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surfaces_[2];
+ int current_index_;
+
+ // The previous frame's damage rectangle. Used to copy unchanged content
+ // between buffers in CopyPreviousBufferDamage.
+ SkRegion previous_buffer_damage_region_;
+
+ // The SkCanvas wrapps the mapped current IOSurface. It is valid only between
+ // BeginPaint and EndPaint.
+ skia::RefPtr<SkCanvas> canvas_;
+
+ gfx::VSyncProvider::UpdateVSyncCallback update_vsync_callback_;
DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceMac);
};
diff --git a/chromium/content/browser/compositor/software_output_device_mac.mm b/chromium/content/browser/compositor/software_output_device_mac.mm
index 5dacbae755c..e71f6782878 100644
--- a/chromium/content/browser/compositor/software_output_device_mac.mm
+++ b/chromium/content/browser/compositor/software_output_device_mac.mm
@@ -2,26 +2,171 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#import <Cocoa/Cocoa.h>
-
#include "content/browser/compositor/software_output_device_mac.h"
+#import <Cocoa/Cocoa.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/mac/foundation_util.h"
+#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/compositor/compositor.h"
+#include "ui/gfx/skia_util.h"
namespace content {
SoftwareOutputDeviceMac::SoftwareOutputDeviceMac(ui::Compositor* compositor)
- : compositor_(compositor) {
-}
+ : compositor_(compositor), scale_factor_(1), current_index_(0) {}
SoftwareOutputDeviceMac::~SoftwareOutputDeviceMac() {
}
+void SoftwareOutputDeviceMac::Resize(const gfx::Size& pixel_size,
+ float scale_factor) {
+ if (pixel_size_ == pixel_size && scale_factor_ == scale_factor)
+ return;
+
+ pixel_size_ = pixel_size;
+ scale_factor_ = scale_factor;
+
+ DiscardBackbuffer();
+}
+
+void SoftwareOutputDeviceMac::CopyPreviousBufferDamage(
+ const SkRegion& new_damage_region) {
+ TRACE_EVENT0("browser", "CopyPreviousBufferDamage");
+
+ // The region to copy is the region drawn last frame, minus the region that
+ // is drawn this frame.
+ SkRegion copy_region = previous_buffer_damage_region_;
+ bool copy_region_nonempty =
+ copy_region.op(new_damage_region, SkRegion::kDifference_Op);
+ previous_buffer_damage_region_ = new_damage_region;
+
+ if (!copy_region_nonempty)
+ return;
+
+ IOSurfaceRef previous_io_surface = io_surfaces_[!current_index_].get();
+
+ {
+ TRACE_EVENT0("browser", "IOSurfaceLock for software copy");
+ IOReturn io_result = IOSurfaceLock(
+ previous_io_surface, kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync,
+ nullptr);
+ if (io_result) {
+ DLOG(ERROR) << "Failed to lock previous IOSurface " << io_result;
+ return;
+ }
+ }
+
+ uint8_t* pixels =
+ static_cast<uint8_t*>(IOSurfaceGetBaseAddress(previous_io_surface));
+ size_t stride = IOSurfaceGetBytesPerRow(previous_io_surface);
+ size_t bytes_per_element = 4;
+ for (SkRegion::Iterator it(copy_region); !it.done(); it.next()) {
+ const SkIRect& rect = it.rect();
+ canvas_->writePixels(
+ SkImageInfo::MakeN32Premul(rect.width(), rect.height()),
+ pixels + bytes_per_element * rect.x() + stride * rect.y(), stride,
+ rect.x(), rect.y());
+ }
+
+ {
+ TRACE_EVENT0("browser", "IOSurfaceUnlock");
+ IOReturn io_result = IOSurfaceUnlock(
+ previous_io_surface, kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync,
+ nullptr);
+ if (io_result)
+ DLOG(ERROR) << "Failed to unlock previous IOSurface " << io_result;
+ }
+}
+
+bool SoftwareOutputDeviceMac::EnsureBuffersExist() {
+ for (int i = 0; i < 2; ++i) {
+ if (!io_surfaces_[i]) {
+ TRACE_EVENT0("browser", "IOSurfaceCreate");
+ unsigned pixel_format = 'BGRA';
+ unsigned bytes_per_element = 4;
+ NSDictionary* options = @{
+ static_cast<id>(kIOSurfaceWidth) : @(pixel_size_.width()),
+ static_cast<id>(kIOSurfaceHeight) : @(pixel_size_.height()),
+ static_cast<id>(kIOSurfacePixelFormat) : @(pixel_format),
+ static_cast<id>(kIOSurfaceBytesPerElement) : @(bytes_per_element),
+ };
+ io_surfaces_[i].reset(IOSurfaceCreate(base::mac::NSToCFCast(options)));
+ }
+ if (!io_surfaces_[i]) {
+ DLOG(ERROR) << "Failed to allocate IOSurface";
+ return false;
+ }
+ }
+ return true;
+}
+
+SkCanvas* SoftwareOutputDeviceMac::BeginPaint(
+ const gfx::Rect& new_damage_rect) {
+ if (!EnsureBuffersExist())
+ return nullptr;
+
+ {
+ TRACE_EVENT0("browser", "IOSurfaceLock for software paint");
+ IOReturn io_result = IOSurfaceLock(io_surfaces_[current_index_],
+ kIOSurfaceLockAvoidSync, nullptr);
+ if (io_result) {
+ DLOG(ERROR) << "Failed to lock IOSurface " << io_result;
+ return nullptr;
+ }
+ }
+
+ SkPMColor* pixels = static_cast<SkPMColor*>(
+ IOSurfaceGetBaseAddress(io_surfaces_[current_index_]));
+ size_t stride = IOSurfaceGetBytesPerRow(io_surfaces_[current_index_]);
+
+ canvas_ = skia::AdoptRef(SkCanvas::NewRasterDirectN32(
+ pixel_size_.width(), pixel_size_.height(), pixels, stride));
+
+ CopyPreviousBufferDamage(SkRegion(gfx::RectToSkIRect(new_damage_rect)));
+
+ return canvas_.get();
+}
+
void SoftwareOutputDeviceMac::EndPaint() {
SoftwareOutputDevice::EndPaint();
- ui::AcceleratedWidgetMacGotSoftwareFrame(
- compositor_->widget(), scale_factor_, surface_->getCanvas());
+ {
+ TRACE_EVENT0("browser", "IOSurfaceUnlock");
+ IOReturn io_result = IOSurfaceUnlock(io_surfaces_[current_index_],
+ kIOSurfaceLockAvoidSync, nullptr);
+ if (io_result)
+ DLOG(ERROR) << "Failed to unlock IOSurface " << io_result;
+ }
+
+ canvas_ = nullptr;
+ base::TimeTicks vsync_timebase;
+ base::TimeDelta vsync_interval;
+ ui::AcceleratedWidgetMacGotFrame(
+ compositor_->widget(), 0, io_surfaces_[current_index_], pixel_size_,
+ scale_factor_, &vsync_timebase, &vsync_interval);
+ if (!update_vsync_callback_.is_null())
+ update_vsync_callback_.Run(vsync_timebase, vsync_interval);
+
+ current_index_ = !current_index_;
+}
+
+void SoftwareOutputDeviceMac::DiscardBackbuffer() {
+ for (int i = 0; i < 2; ++i)
+ io_surfaces_[i].reset();
+}
+
+void SoftwareOutputDeviceMac::EnsureBackbuffer() {}
+
+gfx::VSyncProvider* SoftwareOutputDeviceMac::GetVSyncProvider() {
+ return this;
+}
+
+void SoftwareOutputDeviceMac::GetVSyncParameters(
+ const gfx::VSyncProvider::UpdateVSyncCallback& callback) {
+ update_vsync_callback_ = callback;
}
} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_mus.cc b/chromium/content/browser/compositor/software_output_device_mus.cc
new file mode 100644
index 00000000000..ca5fb95df6a
--- /dev/null
+++ b/chromium/content/browser/compositor/software_output_device_mus.cc
@@ -0,0 +1,66 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/compositor/software_output_device_mus.h"
+
+#include <stddef.h>
+#include <utility>
+
+#include "components/bitmap_uploader/bitmap_uploader.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
+#include "ui/base/view_prop.h"
+#include "ui/compositor/compositor.h"
+#include "ui/gfx/skia_util.h"
+
+#if !defined(OFFICIAL_BUILD)
+#include "base/threading/thread_restrictions.h"
+#endif
+
+namespace content {
+
+SoftwareOutputDeviceMus::SoftwareOutputDeviceMus(ui::Compositor* compositor)
+ : compositor_(compositor) {}
+
+void SoftwareOutputDeviceMus::EndPaint() {
+ SoftwareOutputDevice::EndPaint();
+#if !defined(OFFICIAL_BUILD)
+ base::ThreadRestrictions::ScopedAllowWait wait;
+#endif
+
+ if (!surface_)
+ return;
+
+ gfx::Rect rect = damage_rect_;
+ rect.Intersect(gfx::Rect(viewport_pixel_size_));
+ if (rect.IsEmpty())
+ return;
+
+ gfx::AcceleratedWidget widget = compositor_->widget();
+ bitmap_uploader::BitmapUploader* uploader =
+ reinterpret_cast<bitmap_uploader::BitmapUploader*>(ui::ViewProp::GetValue(
+ widget, bitmap_uploader::kBitmapUploaderForAcceleratedWidget));
+ DCHECK(uploader);
+
+ SkImageInfo info;
+ size_t rowBytes;
+ const void* addr = surface_->peekPixels(&info, &rowBytes);
+
+ if (!addr) {
+ LOG(WARNING) << "SoftwareOutputDeviceMus: skia surface did not provide us "
+ "with pixels";
+ return;
+ }
+
+ const unsigned char* pixels = static_cast<const unsigned char*>(addr);
+
+ // TODO(rjkroege): This makes an additional copy. Improve the
+ // bitmap_uploader API to remove.
+ scoped_ptr<std::vector<unsigned char>> data(new std::vector<unsigned char>(
+ pixels, pixels + rowBytes * viewport_pixel_size_.height()));
+ uploader->SetBitmap(viewport_pixel_size_.width(),
+ viewport_pixel_size_.height(), std::move(data),
+ bitmap_uploader::BitmapUploader::BGRA);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_mus.h b/chromium/content/browser/compositor/software_output_device_mus.h
new file mode 100644
index 00000000000..d4a2e4500b4
--- /dev/null
+++ b/chromium/content/browser/compositor/software_output_device_mus.h
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MUS_H_
+#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MUS_H_
+
+#include "base/macros.h"
+#include "cc/output/software_output_device.h"
+#include "content/common/content_export.h"
+
+namespace ui {
+class Compositor;
+}
+
+namespace content {
+
+// Mus implementation of software compositing: Chrome will do a software
+// composite and ship the resultant bitmap to an instance of the mus
+// window server. Remove this upon completion of http://crbug.com/548451
+class SoftwareOutputDeviceMus : public cc::SoftwareOutputDevice {
+ public:
+ explicit SoftwareOutputDeviceMus(ui::Compositor* compositor);
+
+ private:
+ // cc::SoftwareOutputDevice
+ void EndPaint() override;
+
+ ui::Compositor* compositor_;
+
+ DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceMus);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MUS_H_
diff --git a/chromium/content/browser/compositor/software_output_device_ozone.cc b/chromium/content/browser/compositor/software_output_device_ozone.cc
index 0476ccb0fcc..28e0d415667 100644
--- a/chromium/content/browser/compositor/software_output_device_ozone.cc
+++ b/chromium/content/browser/compositor/software_output_device_ozone.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "content/browser/compositor/software_output_device_ozone.h"
-#include "third_party/skia/include/core/SkDevice.h"
#include "ui/compositor/compositor.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/vsync_provider.h"
@@ -13,6 +12,16 @@
namespace content {
+// static
+scoped_ptr<SoftwareOutputDeviceOzone> SoftwareOutputDeviceOzone::Create(
+ ui::Compositor* compositor) {
+ scoped_ptr<SoftwareOutputDeviceOzone> result(
+ new SoftwareOutputDeviceOzone(compositor));
+ if (!result->surface_ozone_)
+ return nullptr;
+ return result;
+}
+
SoftwareOutputDeviceOzone::SoftwareOutputDeviceOzone(ui::Compositor* compositor)
: compositor_(compositor) {
ui::SurfaceFactoryOzone* factory =
@@ -20,8 +29,10 @@ SoftwareOutputDeviceOzone::SoftwareOutputDeviceOzone(ui::Compositor* compositor)
surface_ozone_ = factory->CreateCanvasForWidget(compositor_->widget());
- if (!surface_ozone_)
- LOG(FATAL) << "Failed to initialize canvas";
+ if (!surface_ozone_) {
+ LOG(ERROR) << "Failed to initialize canvas";
+ return;
+ }
vsync_provider_ = surface_ozone_->CreateVSyncProvider();
}
diff --git a/chromium/content/browser/compositor/software_output_device_ozone.h b/chromium/content/browser/compositor/software_output_device_ozone.h
index 3a7684dc016..3b2a295bee2 100644
--- a/chromium/content/browser/compositor/software_output_device_ozone.h
+++ b/chromium/content/browser/compositor/software_output_device_ozone.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_OZONE_H_
#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_OZONE_H_
+#include "base/macros.h"
#include "cc/output/software_output_device.h"
#include "content/common/content_export.h"
#include "ui/gfx/native_widget_types.h"
@@ -22,7 +23,8 @@ namespace content {
class CONTENT_EXPORT SoftwareOutputDeviceOzone
: public cc::SoftwareOutputDevice {
public:
- explicit SoftwareOutputDeviceOzone(ui::Compositor* compositor);
+ static scoped_ptr<SoftwareOutputDeviceOzone> Create(
+ ui::Compositor* compositor);
~SoftwareOutputDeviceOzone() override;
void Resize(const gfx::Size& viewport_pixel_size,
@@ -31,6 +33,7 @@ class CONTENT_EXPORT SoftwareOutputDeviceOzone
void EndPaint() override;
private:
+ explicit SoftwareOutputDeviceOzone(ui::Compositor* compositor);
ui::Compositor* compositor_;
scoped_ptr<ui::SurfaceOzoneCanvas> surface_ozone_;
diff --git a/chromium/content/browser/compositor/software_output_device_ozone_unittest.cc b/chromium/content/browser/compositor/software_output_device_ozone_unittest.cc
index 8f3febf7d9f..71c8bd941e5 100644
--- a/chromium/content/browser/compositor/software_output_device_ozone_unittest.cc
+++ b/chromium/content/browser/compositor/software_output_device_ozone_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/thread_task_runner_handle.h"
#include "content/browser/compositor/software_output_device_ozone.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkDevice.h"
-#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/test/context_factories_for_test.h"
#include "ui/gfx/geometry/size.h"
@@ -41,6 +41,9 @@ class TestPlatformWindowDelegate : public ui::PlatformWindowDelegate {
float device_pixel_ratio) override {
widget_ = widget;
}
+ void OnAcceleratedWidgetDestroyed() override {
+ NOTREACHED();
+ }
void OnActivationChanged(bool active) override {}
private:
@@ -89,13 +92,13 @@ void SoftwareOutputDeviceOzoneTest::SetUp() {
&window_delegate_, gfx::Rect(size));
compositor_.reset(
new ui::Compositor(context_factory, base::ThreadTaskRunnerHandle::Get()));
- compositor_->SetAcceleratedWidgetAndStartCompositor(
- window_delegate_.GetAcceleratedWidget());
+ compositor_->SetAcceleratedWidget(window_delegate_.GetAcceleratedWidget());
compositor_->SetScaleAndSize(1.0f, size);
- output_device_.reset(new content::SoftwareOutputDeviceOzone(
- compositor_.get()));
- output_device_->Resize(size, 1.f);
+ output_device_ =
+ content::SoftwareOutputDeviceOzone::Create(compositor_.get());
+ if (output_device_)
+ output_device_->Resize(size, 1.f);
}
void SoftwareOutputDeviceOzoneTest::TearDown() {
@@ -117,14 +120,18 @@ void SoftwareOutputDeviceOzonePixelTest::SetUp() {
}
TEST_F(SoftwareOutputDeviceOzoneTest, CheckCorrectResizeBehavior) {
+ // Check if software rendering mode is not supported.
+ if (!output_device_)
+ return;
+
gfx::Rect damage(0, 0, 100, 100);
gfx::Size size(200, 100);
// Reduce size.
output_device_->Resize(size, 1.f);
SkCanvas* canvas = output_device_->BeginPaint(damage);
- gfx::Size canvas_size(canvas->getDeviceSize().width(),
- canvas->getDeviceSize().height());
+ gfx::Size canvas_size(canvas->getBaseLayerSize().width(),
+ canvas->getBaseLayerSize().height());
EXPECT_EQ(size.ToString(), canvas_size.ToString());
size.SetSize(1000, 500);
@@ -132,8 +139,8 @@ TEST_F(SoftwareOutputDeviceOzoneTest, CheckCorrectResizeBehavior) {
output_device_->Resize(size, 1.f);
canvas = output_device_->BeginPaint(damage);
- canvas_size.SetSize(canvas->getDeviceSize().width(),
- canvas->getDeviceSize().height());
+ canvas_size.SetSize(canvas->getBaseLayerSize().width(),
+ canvas->getBaseLayerSize().height());
EXPECT_EQ(size.ToString(), canvas_size.ToString());
}
diff --git a/chromium/content/browser/compositor/software_output_device_win.cc b/chromium/content/browser/compositor/software_output_device_win.cc
index 7f3df8799bf..a712def1911 100644
--- a/chromium/content/browser/compositor/software_output_device_win.cc
+++ b/chromium/content/browser/compositor/software_output_device_win.cc
@@ -4,17 +4,21 @@
#include "content/browser/compositor/software_output_device_win.h"
+#include "base/debug/alias.h"
#include "base/memory/shared_memory.h"
+#include "cc/resources/shared_bitmap.h"
#include "content/public/browser/browser_thread.h"
#include "skia/ext/platform_canvas.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkDevice.h"
#include "ui/compositor/compositor.h"
#include "ui/gfx/gdi_util.h"
#include "ui/gfx/skia_util.h"
namespace content {
+// If a window is larger than this in bytes, don't even try to create a
+// backing bitmap for it.
+static const size_t kMaxBitmapSizeBytes = 4 * (16384 * 8192);
+
OutputDeviceBacking::OutputDeviceBacking() : created_byte_size_(0) {
}
@@ -46,12 +50,21 @@ void OutputDeviceBacking::UnregisterOutputDevice(
Resized();
}
-base::SharedMemory* OutputDeviceBacking::GetSharedMemory() {
+base::SharedMemory* OutputDeviceBacking::GetSharedMemory(
+ const gfx::Size& size) {
if (backing_)
return backing_.get();
- created_byte_size_ = GetMaxByteSize();
+ size_t expected_byte_size = GetMaxByteSize();
+ size_t required_size;
+ if (!cc::SharedBitmap::SizeInBytes(size, &required_size))
+ return nullptr;
+ if (required_size > expected_byte_size)
+ return nullptr;
+
+ created_byte_size_ = expected_byte_size;
backing_.reset(new base::SharedMemory);
+ base::debug::Alias(&expected_byte_size);
CHECK(backing_->CreateAnonymous(created_byte_size_));
return backing_.get();
}
@@ -60,9 +73,13 @@ size_t OutputDeviceBacking::GetMaxByteSize() {
// Minimum byte size is 1 because creating a 0-byte-long SharedMemory fails.
size_t max_size = 1;
for (const SoftwareOutputDeviceWin* device : devices_) {
- max_size = std::max(
- max_size,
- static_cast<size_t>(device->viewport_pixel_size().GetArea() * 4));
+ size_t current_size;
+ if (!cc::SharedBitmap::SizeInBytes(device->viewport_pixel_size(),
+ &current_size))
+ continue;
+ if (current_size > kMaxBitmapSizeBytes)
+ continue;
+ max_size = std::max(max_size, current_size);
}
return max_size;
}
@@ -113,11 +130,21 @@ SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
DCHECK(!in_paint_);
if (!contents_) {
HANDLE shared_section = NULL;
- if (backing_)
- shared_section = backing_->GetSharedMemory()->handle().GetHandle();
- contents_ = skia::AdoptRef(skia::CreatePlatformCanvas(
- viewport_pixel_size_.width(), viewport_pixel_size_.height(), true,
- shared_section, skia::CRASH_ON_FAILURE));
+ bool can_create_contents = true;
+ if (backing_) {
+ base::SharedMemory* memory =
+ backing_->GetSharedMemory(viewport_pixel_size_);
+ if (memory) {
+ shared_section = memory->handle().GetHandle();
+ } else {
+ can_create_contents = false;
+ }
+ }
+ if (can_create_contents) {
+ contents_ = skia::AdoptRef(skia::CreatePlatformCanvas(
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(), true,
+ shared_section, skia::CRASH_ON_FAILURE));
+ }
}
damage_rect_ = damage_rect;
@@ -127,12 +154,14 @@ SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
void SoftwareOutputDeviceWin::EndPaint() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(contents_);
DCHECK(in_paint_);
in_paint_ = false;
SoftwareOutputDevice::EndPaint();
+ if (!contents_)
+ return;
+
gfx::Rect rect = damage_rect_;
rect.Intersect(gfx::Rect(viewport_pixel_size_));
if (rect.IsEmpty())
diff --git a/chromium/content/browser/compositor/software_output_device_win.h b/chromium/content/browser/compositor/software_output_device_win.h
index 3f444ae96e0..1cc267dd55b 100644
--- a/chromium/content/browser/compositor/software_output_device_win.h
+++ b/chromium/content/browser/compositor/software_output_device_win.h
@@ -5,13 +5,15 @@
#ifndef CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_WIN_H_
#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_WIN_H_
+#include <windows.h>
+#include <stddef.h>
+
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "cc/output/software_output_device.h"
-#include <windows.h>
-
namespace base {
class SharedMemory;
}
@@ -31,7 +33,7 @@ class OutputDeviceBacking {
void Resized();
void RegisterOutputDevice(SoftwareOutputDeviceWin* device);
void UnregisterOutputDevice(SoftwareOutputDeviceWin* device);
- base::SharedMemory* GetSharedMemory();
+ base::SharedMemory* GetSharedMemory(const gfx::Size& size);
private:
size_t GetMaxByteSize();
diff --git a/chromium/content/browser/compositor/software_output_device_x11.cc b/chromium/content/browser/compositor/software_output_device_x11.cc
index f0719781f98..7bf743f5aae 100644
--- a/chromium/content/browser/compositor/software_output_device_x11.cc
+++ b/chromium/content/browser/compositor/software_output_device_x11.cc
@@ -4,12 +4,14 @@
#include "content/browser/compositor/software_output_device_x11.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "content/public/browser/browser_thread.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkDevice.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/base/x/x11_util.h"
#include "ui/base/x/x11_util_internal.h"
#include "ui/compositor/compositor.h"
@@ -117,20 +119,11 @@ void SoftwareOutputDeviceX11::EndPaint() {
SkImageInfo info;
size_t rowBytes;
const void* addr = surface_->peekPixels(&info, &rowBytes);
- gfx::PutARGBImage(display_,
- attributes_.visual,
- attributes_.depth,
- compositor_->widget(),
- gc_,
- static_cast<const uint8*>(addr),
- viewport_pixel_size_.width(),
- viewport_pixel_size_.height(),
- rect.x(),
- rect.y(),
- rect.x(),
- rect.y(),
- rect.width(),
- rect.height());
+ gfx::PutARGBImage(
+ display_, attributes_.visual, attributes_.depth, compositor_->widget(),
+ gc_, static_cast<const uint8_t*>(addr), viewport_pixel_size_.width(),
+ viewport_pixel_size_.height(), rect.x(), rect.y(), rect.x(), rect.y(),
+ rect.width(), rect.height());
}
} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_x11.h b/chromium/content/browser/compositor/software_output_device_x11.h
index c6d87a35ffe..9fe571d9814 100644
--- a/chromium/content/browser/compositor/software_output_device_x11.h
+++ b/chromium/content/browser/compositor/software_output_device_x11.h
@@ -7,6 +7,7 @@
#include <X11/Xlib.h>
+#include "base/macros.h"
#include "cc/output/software_output_device.h"
#include "ui/gfx/x/x11_types.h"
diff --git a/chromium/content/browser/compositor/surface_utils.cc b/chromium/content/browser/compositor/surface_utils.cc
index 78f63a0d647..7ae05912a65 100644
--- a/chromium/content/browser/compositor/surface_utils.cc
+++ b/chromium/content/browser/compositor/surface_utils.cc
@@ -4,9 +4,10 @@
#include "content/browser/compositor/surface_utils.h"
+#include "build/build_config.h"
#include "cc/surfaces/surface_id_allocator.h"
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
#include "content/browser/renderer_host/compositor_impl_android.h"
#else
#include "content/browser/compositor/image_transport_factory.h"
@@ -16,7 +17,7 @@
namespace content {
scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
return CompositorImpl::CreateSurfaceIdAllocator();
#else
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
@@ -25,7 +26,7 @@ scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() {
}
cc::SurfaceManager* GetSurfaceManager() {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
return CompositorImpl::GetSurfaceManager();
#else
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
diff --git a/chromium/content/browser/cross_site_transfer_browsertest.cc b/chromium/content/browser/cross_site_transfer_browsertest.cc
index 0ce755c21b0..fbe720d9e11 100644
--- a/chromium/content/browser/cross_site_transfer_browsertest.cc
+++ b/chromium/content/browser/cross_site_transfer_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/public/browser/navigation_entry.h"
@@ -64,11 +65,10 @@ class TrackingResourceDispatcherHostDelegate
BrowserThread::IO, FROM_HERE,
base::Bind(
&TrackingResourceDispatcherHostDelegate::SetTrackedURLOnIOThread,
- base::Unretained(this),
- tracked_url));
+ base::Unretained(this), tracked_url, run_loop_->QuitClosure()));
}
- // Waits until the tracked URL has been requests, and the request for it has
+ // Waits until the tracked URL has been requested, and the request for it has
// been destroyed.
bool WaitForTrackedURLAndGetCompleted() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -107,10 +107,12 @@ class TrackingResourceDispatcherHostDelegate
DISALLOW_COPY_AND_ASSIGN(TrackingThrottle);
};
- void SetTrackedURLOnIOThread(const GURL& tracked_url) {
+ void SetTrackedURLOnIOThread(const GURL& tracked_url,
+ const base::Closure& run_loop_quit_closure) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
throttle_created_ = false;
tracked_url_ = tracked_url;
+ run_loop_quit_closure_ = run_loop_quit_closure;
}
void OnTrackedRequestDestroyed(bool completed) {
@@ -118,20 +120,20 @@ class TrackingResourceDispatcherHostDelegate
tracked_request_completed_ = completed;
tracked_url_ = GURL();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, run_loop_->QuitClosure());
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ run_loop_quit_closure_);
}
// These live on the IO thread.
GURL tracked_url_;
bool throttle_created_;
+ base::Closure run_loop_quit_closure_;
- // This is created and destroyed on the UI thread, but stopped on the IO
- // thread.
+ // This lives on the UI thread.
scoped_ptr<base::RunLoop> run_loop_;
- // Set on the IO thread while |run_loop_| is non-NULL, read on the UI thread
- // after deleting run_loop_.
+ // Set on the IO thread while |run_loop_| is non-nullptr, read on the UI
+ // thread after deleting run_loop_.
bool tracked_request_completed_;
DISALLOW_COPY_AND_ASSIGN(TrackingResourceDispatcherHostDelegate);
@@ -143,22 +145,9 @@ class NoTransferRequestDelegate : public WebContentsDelegate {
public:
NoTransferRequestDelegate() {}
- WebContents* OpenURLFromTab(WebContents* source,
- const OpenURLParams& params) override {
- bool is_transfer =
- (params.transferred_global_request_id != GlobalRequestID());
- if (is_transfer)
- return NULL;
- NavigationController::LoadURLParams load_url_params(params.url);
- load_url_params.referrer = params.referrer;
- load_url_params.frame_tree_node_id = params.frame_tree_node_id;
- load_url_params.transition_type = params.transition;
- load_url_params.extra_headers = params.extra_headers;
- load_url_params.should_replace_current_entry =
- params.should_replace_current_entry;
- load_url_params.is_renderer_initiated = true;
- source->GetController().LoadURLWithParams(load_url_params);
- return source;
+ bool ShouldTransferNavigation() override {
+ // Intentionally cancel the transfer.
+ return false;
}
private:
@@ -167,18 +156,16 @@ class NoTransferRequestDelegate : public WebContentsDelegate {
class CrossSiteTransferTest : public ContentBrowserTest {
public:
- CrossSiteTransferTest() : old_delegate_(NULL) {
- }
+ CrossSiteTransferTest() : old_delegate_(nullptr) {}
// ContentBrowserTest implementation:
void SetUpOnMainThread() override {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(
- &CrossSiteTransferTest::InjectResourceDisptcherHostDelegate,
- base::Unretained(this)));
+ base::Bind(&CrossSiteTransferTest::InjectResourceDispatcherHostDelegate,
+ base::Unretained(this)));
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
content::SetupCrossSiteRedirector(embedded_test_server());
}
@@ -211,7 +198,7 @@ class CrossSiteTransferTest : public ContentBrowserTest {
IsolateAllSitesForTesting(command_line);
}
- void InjectResourceDisptcherHostDelegate() {
+ void InjectResourceDispatcherHostDelegate() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate();
ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_);
@@ -220,7 +207,7 @@ class CrossSiteTransferTest : public ContentBrowserTest {
void RestoreResourceDisptcherHostDelegate() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_);
- old_delegate_ = NULL;
+ old_delegate_ = nullptr;
}
TrackingResourceDispatcherHostDelegate& tracking_delegate() {
@@ -253,7 +240,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
// Navigate to a starting URL, so there is a history entry to replace.
GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
- NavigateToURL(shell(), url1);
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
// Force all future navigations to transfer. Note that this includes same-site
// navigiations which may cause double process swaps (via OpenURL and then via
@@ -272,7 +259,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
NavigateToURLContentInitiated(shell(), url2, true, true);
// There should be one history entry. url2 should have replaced url1.
- EXPECT_TRUE(controller.GetPendingEntry() == NULL);
+ EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
EXPECT_EQ(1, controller.GetEntryCount());
EXPECT_EQ(0, controller.GetCurrentEntryIndex());
EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
@@ -291,7 +278,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
// There should be two history entries. url2 should have replaced url1. url2
// should not have replaced url3.
- EXPECT_TRUE(controller.GetPendingEntry() == NULL);
+ EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
EXPECT_EQ(2, controller.GetEntryCount());
EXPECT_EQ(1, controller.GetCurrentEntryIndex());
EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
@@ -312,7 +299,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
// Navigate to a starting URL, so there is a history entry to replace.
GURL url = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
- NavigateToURL(shell(), url);
+ EXPECT_TRUE(NavigateToURL(shell(), url));
// Force all future navigations to transfer. Note that this includes same-site
// navigiations which may cause double process swaps (via OpenURL and then via
@@ -326,7 +313,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
NavigateToURLContentInitiated(shell(), url2, true, true);
// There should be one history entry. url2 should have replaced url1.
- EXPECT_TRUE(controller.GetPendingEntry() == NULL);
+ EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
EXPECT_EQ(1, controller.GetEntryCount());
EXPECT_EQ(0, controller.GetCurrentEntryIndex());
EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
@@ -337,7 +324,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
// There should be two history entries. url2 should have replaced url1. url2
// should not have replaced url3.
- EXPECT_TRUE(controller.GetPendingEntry() == NULL);
+ EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
EXPECT_EQ(2, controller.GetEntryCount());
EXPECT_EQ(1, controller.GetCurrentEntryIndex());
EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
@@ -353,7 +340,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
// Navigate to a starting URL, so there is a history entry to replace.
GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
- NavigateToURL(shell(), url1);
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
// Navigate to a page on A.com which redirects to B.com with entry
// replacement. This will switch processes via OpenURL twice. First to A.com,
@@ -368,7 +355,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
NavigateToURLContentInitiated(shell(), url2a, true, true);
// There should be one history entry. url2b should have replaced url1.
- EXPECT_TRUE(controller.GetPendingEntry() == NULL);
+ EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
EXPECT_EQ(1, controller.GetEntryCount());
EXPECT_EQ(0, controller.GetCurrentEntryIndex());
EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
@@ -382,7 +369,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest,
// There should be two history entries. url2b should have replaced url1. url2b
// should not have replaced url3b.
- EXPECT_TRUE(controller.GetPendingEntry() == NULL);
+ EXPECT_TRUE(controller.GetPendingEntry() == nullptr);
EXPECT_EQ(2, controller.GetEntryCount());
EXPECT_EQ(1, controller.GetCurrentEntryIndex());
EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
@@ -397,7 +384,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, NoLeakOnCrossSiteCancel) {
// Navigate to a starting URL, so there is a history entry to replace.
GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
- NavigateToURL(shell(), url1);
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
// Force all future navigations to transfer.
ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
diff --git a/chromium/content/browser/database_quota_client_unittest.cc b/chromium/content/browser/database_quota_client_unittest.cc
index 3c2c6f31470..908d4182d4a 100644
--- a/chromium/content/browser/database_quota_client_unittest.cc
+++ b/chromium/content/browser/database_quota_client_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <map>
#include "base/bind.h"
@@ -135,9 +137,9 @@ class DatabaseQuotaClientTest : public testing::Test {
weak_factory_(this) {
}
- int64 GetOriginUsage(storage::QuotaClient* client,
- const GURL& origin,
- storage::StorageType type) {
+ int64_t GetOriginUsage(storage::QuotaClient* client,
+ const GURL& origin,
+ storage::StorageType type) {
usage_ = 0;
client->GetOriginUsage(
origin, type,
@@ -186,9 +188,7 @@ class DatabaseQuotaClientTest : public testing::Test {
private:
- void OnGetOriginUsageComplete(int64 usage) {
- usage_ = usage;
- }
+ void OnGetOriginUsageComplete(int64_t usage) { usage_ = usage; }
void OnGetOriginsComplete(const std::set<GURL>& origins) {
origins_ = origins;
@@ -199,7 +199,7 @@ class DatabaseQuotaClientTest : public testing::Test {
}
base::MessageLoop message_loop_;
- int64 usage_;
+ int64_t usage_;
std::set<GURL> origins_;
storage::QuotaStatusCode delete_status_;
scoped_refptr<MockDatabaseTracker> mock_tracker_;
diff --git a/chromium/content/browser/database_tracker_unittest.cc b/chromium/content/browser/database_tracker_unittest.cc
index a068b4d5d27..189257f1a19 100644
--- a/chromium/content/browser/database_tracker_unittest.cc
+++ b/chromium/content/browser/database_tracker_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -46,7 +49,7 @@ class TestObserver : public storage::DatabaseTracker::Observer {
~TestObserver() override {}
void OnDatabaseSizeChanged(const std::string& origin_identifier,
const base::string16& database_name,
- int64 database_size) override {
+ int64_t database_size) override {
if (!observe_size_changes_)
return;
new_notification_received_ = true;
@@ -72,7 +75,7 @@ class TestObserver : public storage::DatabaseTracker::Observer {
return origin_identifier_;
}
base::string16 GetNotificationDatabaseName() { return database_name_; }
- int64 GetNotificationDatabaseSize() { return database_size_; }
+ int64_t GetNotificationDatabaseSize() { return database_size_; }
private:
bool new_notification_received_;
@@ -80,13 +83,13 @@ class TestObserver : public storage::DatabaseTracker::Observer {
bool observe_scheduled_deletions_;
std::string origin_identifier_;
base::string16 database_name_;
- int64 database_size_;
+ int64_t database_size_;
};
void CheckNotificationReceived(TestObserver* observer,
const std::string& expected_origin_identifier,
const base::string16& expected_database_name,
- int64 expected_database_size) {
+ int64_t expected_database_size) {
EXPECT_TRUE(observer->DidReceiveNewNotification());
EXPECT_EQ(expected_origin_identifier,
observer->GetNotificationOriginIdentifier());
@@ -119,7 +122,7 @@ class TestQuotaManagerProxy : public storage::QuotaManagerProxy {
void NotifyStorageModified(storage::QuotaClient::ID client_id,
const GURL& origin,
storage::StorageType type,
- int64 delta) override {
+ int64_t delta) override {
EXPECT_EQ(storage::QuotaClient::kDatabase, client_id);
EXPECT_EQ(storage::kStorageTypeTemporary, type);
modifications_[origin].first += 1;
@@ -149,7 +152,7 @@ class TestQuotaManagerProxy : public storage::QuotaManagerProxy {
return accesses_[origin] != 0;
}
- bool WasModificationNotified(const GURL& origin, int64 amount) {
+ bool WasModificationNotified(const GURL& origin, int64_t amount) {
return modifications_[origin].first != 0 &&
modifications_[origin].second == amount;
}
@@ -165,14 +168,13 @@ class TestQuotaManagerProxy : public storage::QuotaManagerProxy {
std::map<GURL, int> accesses_;
// Map from origin to <count, sum of deltas>
- std::map<GURL, std::pair<int, int64> > modifications_;
+ std::map<GURL, std::pair<int, int64_t>> modifications_;
protected:
~TestQuotaManagerProxy() override { EXPECT_FALSE(registered_client_); }
};
-
-bool EnsureFileOfSize(const base::FilePath& file_path, int64 length) {
+bool EnsureFileOfSize(const base::FilePath& file_path, int64_t length) {
base::File file(file_path,
base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
if (!file.IsValid())
@@ -206,7 +208,7 @@ class DatabaseTracker_TestHelper_Test {
NULL));
// Create and open three databases.
- int64 database_size = 0;
+ int64_t database_size = 0;
const std::string kOrigin1 =
storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
@@ -320,7 +322,7 @@ class DatabaseTracker_TestHelper_Test {
tracker->AddObserver(&observer2);
// Open three new databases.
- int64 database_size = 0;
+ int64_t database_size = 0;
const std::string kOrigin1 =
storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
@@ -470,7 +472,7 @@ class DatabaseTracker_TestHelper_Test {
// Create a database and modify it a couple of times, close it,
// then delete it. Observe the tracker notifies accordingly.
- int64 database_size = 0;
+ int64_t database_size = 0;
tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
&database_size);
EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
@@ -545,7 +547,7 @@ class DatabaseTracker_TestHelper_Test {
}
static void DatabaseTrackerClearSessionOnlyDatabasesOnExit() {
- int64 database_size = 0;
+ int64_t database_size = 0;
const std::string kOrigin1 =
storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
@@ -622,7 +624,7 @@ class DatabaseTracker_TestHelper_Test {
}
static void DatabaseTrackerSetForceKeepSessionState() {
- int64 database_size = 0;
+ int64_t database_size = 0;
const std::string kOrigin1 =
storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
@@ -718,7 +720,7 @@ class DatabaseTracker_TestHelper_Test {
EXPECT_TRUE(infos.empty());
// Create a db with an empty name.
- int64 database_size = -1;
+ int64_t database_size = -1;
tracker->DatabaseOpened(kOriginId, kEmptyName, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
@@ -770,7 +772,7 @@ class DatabaseTracker_TestHelper_Test {
// --------------------------------------------------------
// Create a record of a database in the tracker db and create
// a spoof_db_file on disk in the expected location.
- int64 database_size = 0;
+ int64_t database_size = 0;
tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
&database_size);
base::FilePath spoof_db_file = tracker->GetFullDBFilePath(kOriginId, kName);
diff --git a/chromium/content/browser/databases_table_unittest.cc b/chromium/content/browser/databases_table_unittest.cc
index ee864cd3a8e..9353ad45557 100644
--- a/chromium/content/browser/databases_table_unittest.cc
+++ b/chromium/content/browser/databases_table_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chromium/content/browser/device_monitor_mac.h b/chromium/content/browser/device_monitor_mac.h
index b3d3f9f6dc3..05eab158db8 100644
--- a/chromium/content/browser/device_monitor_mac.h
+++ b/chromium/content/browser/device_monitor_mac.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_DEVICE_MONITOR_MAC_H_
#define CONTENT_BROWSER_DEVICE_MONITOR_MAC_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/system_monitor/system_monitor.h"
#include "base/threading/thread_checker.h"
diff --git a/chromium/content/browser/device_monitor_mac.mm b/chromium/content/browser/device_monitor_mac.mm
index 36e9a5714b7..248b99dceda 100644
--- a/chromium/content/browser/device_monitor_mac.mm
+++ b/chromium/content/browser/device_monitor_mac.mm
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/mac/bind_objc_block.h"
#include "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/threading/thread_checker.h"
#include "content/public/browser/browser_thread.h"
@@ -531,6 +532,12 @@ DeviceMonitorMac::~DeviceMonitorMac() {}
void DeviceMonitorMac::StartMonitoring(
const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner) {
DCHECK(thread_checker_.CalledOnValidThread());
+
+ // We're on the UI thread so let's try to initialize AVFoundation and then
+ // see if it's supported. IsAVFoundationSupported can't implicitly initialize
+ // the library since it can be called on different threads.
+ AVFoundationGlue::InitializeAVFoundation();
+
if (AVFoundationGlue::IsAVFoundationSupported()) {
// TODO(erikchen): Remove ScopedTracker below once http://crbug.com/458404
// is fixed.
diff --git a/chromium/content/browser/device_monitor_udev.cc b/chromium/content/browser/device_monitor_udev.cc
index 82529e17908..822e995f47c 100644
--- a/chromium/content/browser/device_monitor_udev.cc
+++ b/chromium/content/browser/device_monitor_udev.cc
@@ -6,8 +6,11 @@
#include "content/browser/device_monitor_udev.h"
+#include <stddef.h>
+
#include <string>
+#include "base/macros.h"
#include "base/system_monitor/system_monitor.h"
#include "content/browser/udev_linux.h"
#include "content/public/browser/browser_thread.h"
diff --git a/chromium/content/browser/device_monitor_udev.h b/chromium/content/browser/device_monitor_udev.h
index 4a879ef5d4d..965055d93b2 100644
--- a/chromium/content/browser/device_monitor_udev.h
+++ b/chromium/content/browser/device_monitor_udev.h
@@ -8,7 +8,7 @@
#ifndef CONTENT_BROWSER_DEVICE_MONITOR_UDEV_H_
#define CONTENT_BROWSER_DEVICE_MONITOR_UDEV_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
diff --git a/chromium/content/browser/device_sensors/OWNERS b/chromium/content/browser/device_sensors/OWNERS
index 9bf80a3a416..1fd89e0e2eb 100644
--- a/chromium/content/browser/device_sensors/OWNERS
+++ b/chromium/content/browser/device_sensors/OWNERS
@@ -1,3 +1 @@
-hans@chromium.org
-leandrogracia@chromium.org
timvolodine@chromium.org
diff --git a/chromium/content/browser/device_sensors/ambient_light_mac.cc b/chromium/content/browser/device_sensors/ambient_light_mac.cc
index 187f6a0697d..6f8d3d99d4c 100644
--- a/chromium/content/browser/device_sensors/ambient_light_mac.cc
+++ b/chromium/content/browser/device_sensors/ambient_light_mac.cc
@@ -6,6 +6,8 @@
#include "content/browser/device_sensors/ambient_light_mac.h"
+#include <utility>
+
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_ioobject.h"
@@ -23,7 +25,7 @@ enum LmuFunctionIndex {
// static
scoped_ptr<AmbientLightSensor> AmbientLightSensor::Create() {
scoped_ptr<AmbientLightSensor> light_sensor(new AmbientLightSensor);
- return light_sensor->Init() ? light_sensor.Pass() : nullptr;
+ return light_sensor->Init() ? std::move(light_sensor) : nullptr;
}
AmbientLightSensor::~AmbientLightSensor() {
diff --git a/chromium/content/browser/device_sensors/ambient_light_mac.h b/chromium/content/browser/device_sensors/ambient_light_mac.h
index 8d34e165b80..36eff8b76f1 100644
--- a/chromium/content/browser/device_sensors/ambient_light_mac.h
+++ b/chromium/content/browser/device_sensors/ambient_light_mac.h
@@ -6,7 +6,9 @@
#define CONTENT_BROWSER_DEVICE_SENSORS_AMBIENT_LIGHT_MAC_H_
#include <IOKit/IOKitLib.h>
+#include <stdint.h>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
namespace content {
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory.h b/chromium/content/browser/device_sensors/data_fetcher_shared_memory.h
index ea56b003fd7..e1e97e3073f 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory.h
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DATA_FETCHER_SHARED_MEMORY_H_
#define CONTENT_BROWSER_DEVICE_SENSORS_DATA_FETCHER_SHARED_MEMORY_H_
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/device_sensors/data_fetcher_shared_memory_base.h"
#if !defined(OS_ANDROID)
@@ -46,6 +48,7 @@ class CONTENT_EXPORT DataFetcherSharedMemory
#if !defined(OS_ANDROID)
DeviceMotionHardwareBuffer* motion_buffer_;
DeviceOrientationHardwareBuffer* orientation_buffer_;
+ DeviceOrientationHardwareBuffer* orientation_absolute_buffer_;
DeviceLightHardwareBuffer* light_buffer_;
#endif
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_android.cc b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_android.cc
index e2676a14d72..d746b4d3285 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_android.cc
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_android.cc
@@ -23,16 +23,22 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
switch (consumer_type) {
case CONSUMER_TYPE_MOTION:
- return SensorManagerAndroid::GetInstance()->
- StartFetchingDeviceMotionData(
- static_cast<DeviceMotionHardwareBuffer*>(buffer));
+ SensorManagerAndroid::GetInstance()->StartFetchingDeviceMotionData(
+ static_cast<DeviceMotionHardwareBuffer*>(buffer));
+ return true;
case CONSUMER_TYPE_ORIENTATION:
- return SensorManagerAndroid::GetInstance()->
- StartFetchingDeviceOrientationData(
+ SensorManagerAndroid::GetInstance()->StartFetchingDeviceOrientationData(
+ static_cast<DeviceOrientationHardwareBuffer*>(buffer));
+ return true;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ SensorManagerAndroid::GetInstance()->
+ StartFetchingDeviceOrientationAbsoluteData(
static_cast<DeviceOrientationHardwareBuffer*>(buffer));
+ return true;
case CONSUMER_TYPE_LIGHT:
- return SensorManagerAndroid::GetInstance()->StartFetchingDeviceLightData(
+ SensorManagerAndroid::GetInstance()->StartFetchingDeviceLightData(
static_cast<DeviceLightHardwareBuffer*>(buffer));
+ return true;
default:
NOTREACHED();
}
@@ -47,6 +53,10 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
case CONSUMER_TYPE_ORIENTATION:
SensorManagerAndroid::GetInstance()->StopFetchingDeviceOrientationData();
return true;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ SensorManagerAndroid::GetInstance()
+ ->StopFetchingDeviceOrientationAbsoluteData();
+ return true;
case CONSUMER_TYPE_LIGHT:
SensorManagerAndroid::GetInstance()->StopFetchingDeviceLightData();
return true;
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.cc b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.cc
index 13c2135e854..be3780ea39e 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.cc
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.cc
@@ -4,9 +4,13 @@
#include "content/browser/device_sensors/data_fetcher_shared_memory_base.h"
+#include <stddef.h>
+#include <string.h>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/threading/thread.h"
@@ -24,6 +28,7 @@ size_t GetConsumerSharedMemoryBufferSize(ConsumerType consumer_type) {
case CONSUMER_TYPE_MOTION:
return sizeof(DeviceMotionHardwareBuffer);
case CONSUMER_TYPE_ORIENTATION:
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
return sizeof(DeviceOrientationHardwareBuffer);
case CONSUMER_TYPE_LIGHT:
return sizeof(DeviceLightHardwareBuffer);
@@ -90,7 +95,7 @@ void DataFetcherSharedMemoryBase::PollingThread::RemoveConsumer(
if (!fetcher_->Stop(consumer_type))
return;
- consumers_bitmask_ ^= consumer_type;
+ consumers_bitmask_ &= ~consumer_type;
if (!consumers_bitmask_)
timer_.reset(); // will also stop the timer.
@@ -168,6 +173,7 @@ bool DataFetcherSharedMemoryBase::StopFetchingDeviceData(
void DataFetcherSharedMemoryBase::Shutdown() {
StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
+ StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
}
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.h b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.h
index c13c37800aa..f36ad7c4570 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.h
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base.h
@@ -7,10 +7,11 @@
#include <map>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
-#include "content/browser/device_sensors/inertial_sensor_consts.h"
+#include "content/browser/device_sensors/device_sensors_consts.h"
#include "content/common/content_export.h"
namespace content {
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc
index e13cd8986c6..ea44220dce0 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc
@@ -5,6 +5,7 @@
#include "content/browser/device_sensors/data_fetcher_shared_memory_base.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/process/process_handle.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
@@ -23,15 +24,19 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
: start_light_(false, false),
start_motion_(false, false),
start_orientation_(false, false),
+ start_orientation_absolute_(false, false),
stop_light_(false, false),
stop_motion_(false, false),
stop_orientation_(false, false),
+ stop_orientation_absolute_(false, false),
updated_light_(false, false),
updated_motion_(false, false),
updated_orientation_(false, false),
+ updated_orientation_absolute_(false, false),
light_buffer_(nullptr),
motion_buffer_(nullptr),
- orientation_buffer_(nullptr) {}
+ orientation_buffer_(nullptr),
+ orientation_absolute_buffer_(nullptr) {}
~FakeDataFetcher() override {}
bool Init(ConsumerType consumer_type, void* buffer) {
@@ -45,6 +50,10 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
orientation_buffer_ =
static_cast<DeviceOrientationHardwareBuffer*>(buffer);
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ orientation_absolute_buffer_ =
+ static_cast<DeviceOrientationHardwareBuffer*>(buffer);
+ break;
case CONSUMER_TYPE_LIGHT:
light_buffer_ = static_cast<DeviceLightHardwareBuffer*>(buffer);
break;
@@ -81,6 +90,16 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
updated_orientation_.Signal();
}
+ void UpdateOrientationAbsolute() {
+ DeviceOrientationHardwareBuffer* buffer = GetOrientationAbsoluteBuffer();
+ ASSERT_TRUE(buffer);
+ buffer->seqlock.WriteBegin();
+ buffer->data.alpha = 1;
+ buffer->data.absolute = true;
+ buffer->seqlock.WriteEnd();
+ updated_orientation_absolute_.Signal();
+ }
+
DeviceLightHardwareBuffer* GetLightBuffer() const { return light_buffer_; }
DeviceMotionHardwareBuffer* GetMotionBuffer() const {
@@ -91,6 +110,10 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
return orientation_buffer_;
}
+ DeviceOrientationHardwareBuffer* GetOrientationAbsoluteBuffer() const {
+ return orientation_absolute_buffer_;
+ }
+
void WaitForStart(ConsumerType consumer_type) {
switch (consumer_type) {
case CONSUMER_TYPE_MOTION:
@@ -99,6 +122,9 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
case CONSUMER_TYPE_ORIENTATION:
start_orientation_.Wait();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ start_orientation_absolute_.Wait();
+ break;
case CONSUMER_TYPE_LIGHT:
start_light_.Wait();
break;
@@ -113,6 +139,9 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Wait();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ stop_orientation_absolute_.Wait();
+ break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Wait();
break;
@@ -127,6 +156,9 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
case CONSUMER_TYPE_ORIENTATION:
updated_orientation_.Wait();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ updated_orientation_absolute_.Wait();
+ break;
case CONSUMER_TYPE_LIGHT:
updated_light_.Wait();
break;
@@ -137,17 +169,21 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
base::WaitableEvent start_light_;
base::WaitableEvent start_motion_;
base::WaitableEvent start_orientation_;
+ base::WaitableEvent start_orientation_absolute_;
base::WaitableEvent stop_light_;
base::WaitableEvent stop_motion_;
base::WaitableEvent stop_orientation_;
+ base::WaitableEvent stop_orientation_absolute_;
base::WaitableEvent updated_light_;
base::WaitableEvent updated_motion_;
base::WaitableEvent updated_orientation_;
+ base::WaitableEvent updated_orientation_absolute_;
private:
DeviceLightHardwareBuffer* light_buffer_;
DeviceMotionHardwareBuffer* motion_buffer_;
DeviceOrientationHardwareBuffer* orientation_buffer_;
+ DeviceOrientationHardwareBuffer* orientation_absolute_buffer_;
DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher);
};
@@ -168,6 +204,10 @@ class FakeNonPollingDataFetcher : public FakeDataFetcher {
UpdateOrientation();
start_orientation_.Signal();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ UpdateOrientationAbsolute();
+ start_orientation_absolute_.Signal();
+ break;
case CONSUMER_TYPE_LIGHT:
UpdateLight();
start_light_.Signal();
@@ -186,6 +226,9 @@ class FakeNonPollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Signal();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ stop_orientation_absolute_.Signal();
+ break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Signal();
break;
@@ -222,6 +265,9 @@ class FakePollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION:
start_orientation_.Signal();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ start_orientation_absolute_.Signal();
+ break;
case CONSUMER_TYPE_LIGHT:
start_light_.Signal();
break;
@@ -241,6 +287,9 @@ class FakePollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Signal();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ stop_orientation_absolute_.Signal();
+ break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Signal();
break;
@@ -253,11 +302,14 @@ class FakePollingDataFetcher : public FakeDataFetcher {
void Fetch(unsigned consumer_bitmask) override {
EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
EXPECT_TRUE(consumer_bitmask & CONSUMER_TYPE_ORIENTATION ||
+ consumer_bitmask & CONSUMER_TYPE_ORIENTATION_ABSOLUTE ||
consumer_bitmask & CONSUMER_TYPE_MOTION ||
consumer_bitmask & CONSUMER_TYPE_LIGHT);
if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION)
UpdateOrientation();
+ if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION_ABSOLUTE)
+ UpdateOrientationAbsolute();
if (consumer_bitmask & CONSUMER_TYPE_MOTION)
UpdateMotion();
if (consumer_bitmask & CONSUMER_TYPE_LIGHT)
@@ -286,6 +338,9 @@ class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION:
start_orientation_.Signal();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ start_orientation_absolute_.Signal();
+ break;
case CONSUMER_TYPE_LIGHT:
start_light_.Signal();
break;
@@ -305,6 +360,9 @@ class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Signal();
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ stop_orientation_absolute_.Signal();
+ break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Signal();
break;
@@ -359,6 +417,22 @@ TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientation) {
fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
}
+TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientationAbsolute) {
+ FakeNonPollingDataFetcher fake_data_fetcher;
+ EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
+ fake_data_fetcher.GetType());
+
+ EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
+ CONSUMER_TYPE_ORIENTATION_ABSOLUTE));
+ fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+
+ EXPECT_EQ(1, fake_data_fetcher.GetOrientationAbsoluteBuffer()->data.alpha);
+ EXPECT_TRUE(fake_data_fetcher.GetOrientationAbsoluteBuffer()->data.absolute);
+
+ fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+ fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+}
+
TEST(DataFetcherSharedMemoryBaseTest, DoesStartLight) {
FakeNonPollingDataFetcher fake_data_fetcher;
EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
@@ -405,6 +479,23 @@ TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientation) {
fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
}
+TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientationAbsolute) {
+ FakePollingDataFetcher fake_data_fetcher;
+ EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
+ fake_data_fetcher.GetType());
+
+ EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
+ CONSUMER_TYPE_ORIENTATION_ABSOLUTE));
+ fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+ fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+
+ EXPECT_EQ(1, fake_data_fetcher.GetOrientationAbsoluteBuffer()->data.alpha);
+ EXPECT_TRUE(fake_data_fetcher.GetOrientationAbsoluteBuffer()->data.absolute);
+
+ fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+ fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+}
+
TEST(DataFetcherSharedMemoryBaseTest, DoesPollLight) {
FakePollingDataFetcher fake_data_fetcher;
EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.cc b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.cc
index 76349d2a37d..16abd5ebf8a 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.cc
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.cc
@@ -28,6 +28,7 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
sensor_manager_->StartFetchingDeviceOrientationData(
static_cast<DeviceOrientationHardwareBuffer*>(buffer));
return true;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
case CONSUMER_TYPE_LIGHT:
NOTIMPLEMENTED();
return false;
@@ -42,6 +43,7 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
return sensor_manager_->StopFetchingDeviceMotionData();
case CONSUMER_TYPE_ORIENTATION:
return sensor_manager_->StopFetchingDeviceOrientationData();
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
case CONSUMER_TYPE_LIGHT:
NOTIMPLEMENTED();
return false;
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_default.cc b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_default.cc
index 9b3a60babe8..7287b702d70 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_default.cc
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_default.cc
@@ -46,6 +46,7 @@ namespace content {
DataFetcherSharedMemory::DataFetcherSharedMemory()
: motion_buffer_(nullptr),
orientation_buffer_(nullptr),
+ orientation_absolute_buffer_(nullptr),
light_buffer_(nullptr) {
}
@@ -66,6 +67,10 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
UMA_HISTOGRAM_BOOLEAN("InertialSensor.OrientationDefaultAvailable",
false);
return SetOrientationBuffer(orientation_buffer_, true);
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ orientation_absolute_buffer_ =
+ static_cast<DeviceOrientationHardwareBuffer*>(buffer);
+ return SetOrientationBuffer(orientation_absolute_buffer_, true);
case CONSUMER_TYPE_LIGHT:
light_buffer_ = static_cast<DeviceLightHardwareBuffer*>(buffer);
return SetLightBuffer(light_buffer_,
@@ -82,6 +87,8 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
return SetMotionBuffer(motion_buffer_, false);
case CONSUMER_TYPE_ORIENTATION:
return SetOrientationBuffer(orientation_buffer_, false);
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ return SetOrientationBuffer(orientation_absolute_buffer_, false);
case CONSUMER_TYPE_LIGHT:
return SetLightBuffer(light_buffer_, -1);
default:
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_mac.cc b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_mac.cc
index 4a1644ffb68..a9ab2ff1dc2 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_mac.cc
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_mac.cc
@@ -4,6 +4,8 @@
#include "content/browser/device_sensors/data_fetcher_shared_memory.h"
+#include <stdint.h>
+
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "content/browser/device_sensors/ambient_light_mac.h"
@@ -202,6 +204,10 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
}
return sudden_motion_sensor_available;
}
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE: {
+ NOTIMPLEMENTED();
+ break;
+ }
case CONSUMER_TYPE_LIGHT: {
if (!ambient_light_sensor_)
ambient_light_sensor_ = AmbientLightSensor::Create();
@@ -242,6 +248,9 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
orientation_buffer_ = nullptr;
}
return true;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ NOTIMPLEMENTED();
+ break;
case CONSUMER_TYPE_LIGHT:
if (light_buffer_) {
light_buffer_->seqlock.WriteBegin();
diff --git a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_win.cc b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_win.cc
index 6bb79cb6d67..709c25b595c 100644
--- a/chromium/content/browser/device_sensors/data_fetcher_shared_memory_win.cc
+++ b/chromium/content/browser/device_sensors/data_fetcher_shared_memory_win.cc
@@ -10,6 +10,7 @@
#include <Sensors.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/win/iunknown_impl.h"
#include "base/win/windows_version.h"
@@ -293,6 +294,9 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
SetBufferAvailableState(consumer_type, true);
}
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ NOTIMPLEMENTED();
+ break;
case CONSUMER_TYPE_MOTION:
{
motion_buffer_ = static_cast<DeviceMotionHardwareBuffer*>(buffer);
@@ -346,6 +350,9 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
SetBufferAvailableState(consumer_type, false);
orientation_buffer_ = nullptr;
return true;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ NOTIMPLEMENTED();
+ break;
case CONSUMER_TYPE_MOTION:
SetBufferAvailableState(consumer_type, false);
motion_buffer_ = nullptr;
@@ -419,6 +426,9 @@ void DataFetcherSharedMemory::DisableSensors(ConsumerType consumer_type) {
sensor_inclinometer_.Release();
}
break;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ NOTIMPLEMENTED();
+ break;
case CONSUMER_TYPE_MOTION:
if (sensor_accelerometer_.get()) {
sensor_accelerometer_->SetEventSink(nullptr);
diff --git a/chromium/content/browser/device_sensors/device_inertial_sensor_browsertest.cc b/chromium/content/browser/device_sensors/device_inertial_sensor_browsertest.cc
index 665b0122708..b5d09c5739d 100644
--- a/chromium/content/browser/device_sensors/device_inertial_sensor_browsertest.cc
+++ b/chromium/content/browser/device_sensors/device_inertial_sensor_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "content/browser/device_sensors/data_fetcher_shared_memory.h"
diff --git a/chromium/content/browser/device_sensors/device_inertial_sensor_service.cc b/chromium/content/browser/device_sensors/device_inertial_sensor_service.cc
index 8970cd68e3f..33f083d11fd 100644
--- a/chromium/content/browser/device_sensors/device_inertial_sensor_service.cc
+++ b/chromium/content/browser/device_sensors/device_inertial_sensor_service.cc
@@ -15,6 +15,7 @@ DeviceInertialSensorService::DeviceInertialSensorService()
: num_light_readers_(0),
num_motion_readers_(0),
num_orientation_readers_(0),
+ num_orientation_absolute_readers_(0),
is_shutdown_(false) {
}
@@ -61,6 +62,10 @@ bool DeviceInertialSensorService::ChangeNumberConsumers(
num_orientation_readers_ += delta;
DCHECK_GE(num_orientation_readers_ , 0);
return true;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ num_orientation_absolute_readers_ += delta;
+ DCHECK_GE(num_orientation_absolute_readers_ , 0);
+ return true;
case CONSUMER_TYPE_LIGHT:
num_light_readers_ += delta;
DCHECK_GE(num_light_readers_, 0);
@@ -78,6 +83,8 @@ int DeviceInertialSensorService::GetNumberConsumers(
return num_motion_readers_;
case CONSUMER_TYPE_ORIENTATION:
return num_orientation_readers_;
+ case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
+ return num_orientation_absolute_readers_;
case CONSUMER_TYPE_LIGHT:
return num_light_readers_;
default:
diff --git a/chromium/content/browser/device_sensors/device_inertial_sensor_service.h b/chromium/content/browser/device_sensors/device_inertial_sensor_service.h
index a95f0557d98..f25abc6de08 100644
--- a/chromium/content/browser/device_sensors/device_inertial_sensor_service.h
+++ b/chromium/content/browser/device_sensors/device_inertial_sensor_service.h
@@ -5,13 +5,13 @@
#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_INERTIAL_SENSOR_SERVICE_H_
#define CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_INERTIAL_SENSOR_SERVICE_H_
-#include "base/basictypes.h"
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/memory/singleton.h"
#include "base/threading/thread_checker.h"
-#include "content/browser/device_sensors/inertial_sensor_consts.h"
+#include "content/browser/device_sensors/device_sensors_consts.h"
#include "content/common/content_export.h"
namespace content {
@@ -53,13 +53,13 @@ class CONTENT_EXPORT DeviceInertialSensorService {
DeviceInertialSensorService();
virtual ~DeviceInertialSensorService();
- bool ChangeNumberConsumers(ConsumerType consumer_type,
- int delta);
+ bool ChangeNumberConsumers(ConsumerType consumer_type, int delta);
int GetNumberConsumers(ConsumerType consumer_type) const;
int num_light_readers_;
int num_motion_readers_;
int num_orientation_readers_;
+ int num_orientation_absolute_readers_;
bool is_shutdown_;
scoped_ptr<DataFetcherSharedMemory> data_fetcher_;
base::ThreadChecker thread_checker_;
diff --git a/chromium/content/browser/device_sensors/device_light_message_filter.h b/chromium/content/browser/device_sensors/device_light_message_filter.h
index eb10bbfab24..58246935a7e 100644
--- a/chromium/content/browser/device_sensors/device_light_message_filter.h
+++ b/chromium/content/browser/device_sensors/device_light_message_filter.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_LIGHT_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_LIGHT_MESSAGE_FILTER_H_
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
namespace content {
diff --git a/chromium/content/browser/device_sensors/device_motion_message_filter.h b/chromium/content/browser/device_sensors/device_motion_message_filter.h
index ffe9ff76c9b..36eb42aa127 100644
--- a/chromium/content/browser/device_sensors/device_motion_message_filter.h
+++ b/chromium/content/browser/device_sensors/device_motion_message_filter.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_MOTION_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_MOTION_MESSAGE_FILTER_H_
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
namespace content {
diff --git a/chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.cc b/chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.cc
new file mode 100644
index 00000000000..572952cea11
--- /dev/null
+++ b/chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.cc
@@ -0,0 +1,66 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/device_sensors/device_orientation_absolute_message_filter.h"
+
+#include "content/browser/device_sensors/device_inertial_sensor_service.h"
+#include "content/common/device_sensors/device_orientation_messages.h"
+
+namespace content {
+
+DeviceOrientationAbsoluteMessageFilter::DeviceOrientationAbsoluteMessageFilter()
+ : BrowserMessageFilter(DeviceOrientationMsgStart),
+ is_started_(false) {
+}
+
+DeviceOrientationAbsoluteMessageFilter::
+ ~DeviceOrientationAbsoluteMessageFilter() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (is_started_) {
+ DeviceInertialSensorService::GetInstance()->RemoveConsumer(
+ CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+ }
+}
+
+bool DeviceOrientationAbsoluteMessageFilter::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(DeviceOrientationAbsoluteMessageFilter, message)
+ IPC_MESSAGE_HANDLER(DeviceOrientationAbsoluteHostMsg_StartPolling,
+ OnStartPolling)
+ IPC_MESSAGE_HANDLER(DeviceOrientationAbsoluteHostMsg_StopPolling,
+ OnStopPolling)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void DeviceOrientationAbsoluteMessageFilter::OnStartPolling() {
+ DCHECK(!is_started_);
+ if (is_started_)
+ return;
+ is_started_ = true;
+ DeviceInertialSensorService::GetInstance()->AddConsumer(
+ CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+ DidStartPolling();
+}
+
+void DeviceOrientationAbsoluteMessageFilter::OnStopPolling() {
+ DCHECK(is_started_);
+ if (!is_started_)
+ return;
+ is_started_ = false;
+ DeviceInertialSensorService::GetInstance()->RemoveConsumer(
+ CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+}
+
+void DeviceOrientationAbsoluteMessageFilter::DidStartPolling() {
+ Send(new DeviceOrientationAbsoluteMsg_DidStartPolling(
+ DeviceInertialSensorService::GetInstance()->
+ GetSharedMemoryHandleForProcess(
+ CONSUMER_TYPE_ORIENTATION_ABSOLUTE,
+ PeerHandle())));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.h b/chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.h
new file mode 100644
index 00000000000..5ed5ac5467e
--- /dev/null
+++ b/chromium/content/browser/device_sensors/device_orientation_absolute_message_filter.h
@@ -0,0 +1,34 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_ORIENTATION_ABSOLUTE_MESSAGE_FILTER_H_
+#define CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_ORIENTATION_ABSOLUTE_MESSAGE_FILTER_H_
+
+#include "base/macros.h"
+#include "content/public/browser/browser_message_filter.h"
+
+namespace content {
+
+class DeviceOrientationAbsoluteMessageFilter : public BrowserMessageFilter {
+ public:
+ DeviceOrientationAbsoluteMessageFilter();
+
+ // BrowserMessageFilter implementation.
+ bool OnMessageReceived(const IPC::Message& message) override;
+
+ private:
+ ~DeviceOrientationAbsoluteMessageFilter() override;
+
+ void OnStartPolling();
+ void OnStopPolling();
+ void DidStartPolling();
+
+ bool is_started_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceOrientationAbsoluteMessageFilter);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_ORIENTATION_ABSOLUTE_MESSAGE_FILTER_H_
diff --git a/chromium/content/browser/device_sensors/device_orientation_message_filter.h b/chromium/content/browser/device_sensors/device_orientation_message_filter.h
index acc772d48e5..fb375d99439 100644
--- a/chromium/content/browser/device_sensors/device_orientation_message_filter.h
+++ b/chromium/content/browser/device_sensors/device_orientation_message_filter.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_ORIENTATION_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_ORIENTATION_MESSAGE_FILTER_H_
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
namespace content {
diff --git a/chromium/content/browser/device_sensors/inertial_sensor_consts.h b/chromium/content/browser/device_sensors/device_sensors_consts.h
index 1f665bdbb5d..2ef774e1e87 100644
--- a/chromium/content/browser/device_sensors/inertial_sensor_consts.h
+++ b/chromium/content/browser/device_sensors/device_sensors_consts.h
@@ -1,9 +1,9 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_DEVICE_SENSORS_INERTIAL_SENSOR_CONSTS_H_
-#define CONTENT_BROWSER_DEVICE_SENSORS_INERTIAL_SENSOR_CONSTS_H_
+#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_SENSORS_CONSTS_H_
+#define CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_SENSORS_CONSTS_H_
#include "base/time/time.h"
@@ -11,10 +11,13 @@ namespace content {
// Constants related to the Device {Motion|Orientation|Light} APIs.
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser
enum ConsumerType {
CONSUMER_TYPE_MOTION = 1 << 0,
CONSUMER_TYPE_ORIENTATION = 1 << 1,
- CONSUMER_TYPE_LIGHT = 1 << 2,
+ CONSUMER_TYPE_ORIENTATION_ABSOLUTE = 1 << 2,
+ CONSUMER_TYPE_LIGHT = 1 << 3,
};
// Specifies the sampling rate for sensor data updates.
@@ -33,4 +36,4 @@ const int kLightSensorIntervalMicroseconds =
} // namespace content
-#endif // CONTENT_BROWSER_DEVICE_SENSORS_INERTIAL_SENSOR_CONSTS_H_
+#endif // CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_SENSORS_CONSTS_H_
diff --git a/chromium/content/browser/device_sensors/sensor_manager_android.cc b/chromium/content/browser/device_sensors/sensor_manager_android.cc
index c31a98864c0..e821fb445a4 100644
--- a/chromium/content/browser/device_sensors/sensor_manager_android.cc
+++ b/chromium/content/browser/device_sensors/sensor_manager_android.cc
@@ -6,11 +6,11 @@
#include <string.h>
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/bind.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram.h"
-#include "content/browser/device_sensors/inertial_sensor_consts.h"
#include "content/public/browser/browser_thread.h"
#include "jni/DeviceSensors_jni.h"
@@ -18,21 +18,32 @@ using base::android::AttachCurrentThread;
namespace {
-// These constants should match ORIENTATION_* constants in content/public/
-// android/java/src/org/chromium/content/browser/DeviceSensors.java.
-// When adding new constants don't modify the order as they are used for UMA.
-// TODO(timvolodine): make this a shared enum, crbug.com/522571.
-enum OrientationSensorType {
- NOT_AVAILABLE = 0,
- ROTATION_VECTOR = 1,
- ACCELEROMETER_MAGNETIC = 2,
- GAME_ROTATION_VECTOR = 3,
- ORIENTATION_SENSOR_MAX = 4,
-};
-
-void UpdateDeviceOrientationHistogram(OrientationSensorType type) {
+void UpdateDeviceOrientationHistogram(
+ content::SensorManagerAndroid::OrientationSensorType type) {
UMA_HISTOGRAM_ENUMERATION("InertialSensor.DeviceOrientationSensorAndroid",
- type, ORIENTATION_SENSOR_MAX);
+ type, content::SensorManagerAndroid::ORIENTATION_SENSOR_MAX);
+}
+
+void SetOrientation(content::DeviceOrientationHardwareBuffer* buffer,
+ double alpha, double beta, double gamma) {
+ buffer->seqlock.WriteBegin();
+ buffer->data.alpha = alpha;
+ buffer->data.hasAlpha = true;
+ buffer->data.beta = beta;
+ buffer->data.hasBeta = true;
+ buffer->data.gamma = gamma;
+ buffer->data.hasGamma = true;
+ buffer->seqlock.WriteEnd();
+}
+
+void SetOrientationBufferStatus(
+ content::DeviceOrientationHardwareBuffer* buffer,
+ bool ready, bool absolute) {
+ buffer->seqlock.WriteBegin();
+ buffer->data.absolute = absolute;
+ buffer->data.hasAbsolute = ready;
+ buffer->data.allAvailableSensorsAreActive = ready;
+ buffer->seqlock.WriteEnd();
}
} // namespace
@@ -65,32 +76,52 @@ SensorManagerAndroid* SensorManagerAndroid::GetInstance() {
base::LeakySingletonTraits<SensorManagerAndroid>>::get();
}
-void SensorManagerAndroid::GotOrientation(
- JNIEnv*, jobject, double alpha, double beta, double gamma) {
+void SensorManagerAndroid::GotOrientation(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ double alpha,
+ double beta,
+ double gamma) {
base::AutoLock autolock(orientation_buffer_lock_);
if (!device_orientation_buffer_)
return;
- device_orientation_buffer_->seqlock.WriteBegin();
- device_orientation_buffer_->data.alpha = alpha;
- device_orientation_buffer_->data.hasAlpha = true;
- device_orientation_buffer_->data.beta = beta;
- device_orientation_buffer_->data.hasBeta = true;
- device_orientation_buffer_->data.gamma = gamma;
- device_orientation_buffer_->data.hasGamma = true;
- device_orientation_buffer_->seqlock.WriteEnd();
+ SetOrientation(device_orientation_buffer_, alpha, beta, gamma);
if (!orientation_buffer_initialized_) {
OrientationSensorType type =
static_cast<OrientationSensorType>(GetOrientationSensorTypeUsed());
- SetOrientationBufferStatus(true, type != GAME_ROTATION_VECTOR);
+ SetOrientationBufferStatus(device_orientation_buffer_, true,
+ type != GAME_ROTATION_VECTOR);
+ orientation_buffer_initialized_ = true;
UpdateDeviceOrientationHistogram(type);
}
}
-void SensorManagerAndroid::GotAcceleration(
- JNIEnv*, jobject, double x, double y, double z) {
+void SensorManagerAndroid::GotOrientationAbsolute(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ double alpha,
+ double beta,
+ double gamma) {
+ base::AutoLock autolock(orientation_absolute_buffer_lock_);
+
+ if (!device_orientation_absolute_buffer_)
+ return;
+
+ SetOrientation(device_orientation_absolute_buffer_, alpha, beta, gamma);
+
+ if (!orientation_absolute_buffer_initialized_) {
+ SetOrientationBufferStatus(device_orientation_absolute_buffer_, true, true);
+ orientation_absolute_buffer_initialized_ = true;
+ // TODO(timvolodine): Add UMA.
+ }
+}
+
+void SensorManagerAndroid::GotAcceleration(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ double x,
+ double y,
+ double z) {
base::AutoLock autolock(motion_buffer_lock_);
if (!device_motion_buffer_)
@@ -112,7 +143,11 @@ void SensorManagerAndroid::GotAcceleration(
}
void SensorManagerAndroid::GotAccelerationIncludingGravity(
- JNIEnv*, jobject, double x, double y, double z) {
+ JNIEnv*,
+ const JavaParamRef<jobject>&,
+ double x,
+ double y,
+ double z) {
base::AutoLock autolock(motion_buffer_lock_);
if (!device_motion_buffer_)
@@ -133,8 +168,11 @@ void SensorManagerAndroid::GotAccelerationIncludingGravity(
}
}
-void SensorManagerAndroid::GotRotationRate(
- JNIEnv*, jobject, double alpha, double beta, double gamma) {
+void SensorManagerAndroid::GotRotationRate(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ double alpha,
+ double beta,
+ double gamma) {
base::AutoLock autolock(motion_buffer_lock_);
if (!device_motion_buffer_)
@@ -155,7 +193,9 @@ void SensorManagerAndroid::GotRotationRate(
}
}
-void SensorManagerAndroid::GotLight(JNIEnv*, jobject, double value) {
+void SensorManagerAndroid::GotLight(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ double value) {
base::AutoLock autolock(light_buffer_lock_);
if (!device_light_buffer_)
@@ -166,23 +206,23 @@ void SensorManagerAndroid::GotLight(JNIEnv*, jobject, double value) {
device_light_buffer_->seqlock.WriteEnd();
}
-bool SensorManagerAndroid::Start(EventType event_type) {
+bool SensorManagerAndroid::Start(ConsumerType consumer_type) {
DCHECK(!device_sensors_.is_null());
- int rate_in_microseconds = (event_type == kTypeLight)
+ int rate_in_microseconds = (consumer_type == CONSUMER_TYPE_LIGHT)
? kLightSensorIntervalMicroseconds
: kInertialSensorIntervalMicroseconds;
return Java_DeviceSensors_start(AttachCurrentThread(),
device_sensors_.obj(),
reinterpret_cast<intptr_t>(this),
- static_cast<jint>(event_type),
+ static_cast<jint>(consumer_type),
rate_in_microseconds);
}
-void SensorManagerAndroid::Stop(EventType event_type) {
+void SensorManagerAndroid::Stop(ConsumerType consumer_type) {
DCHECK(!device_sensors_.is_null());
Java_DeviceSensors_stop(AttachCurrentThread(),
device_sensors_.obj(),
- static_cast<jint>(event_type));
+ static_cast<jint>(consumer_type));
}
int SensorManagerAndroid::GetNumberActiveDeviceMotionSensors() {
@@ -191,17 +231,19 @@ int SensorManagerAndroid::GetNumberActiveDeviceMotionSensors() {
AttachCurrentThread(), device_sensors_.obj());
}
-int SensorManagerAndroid::GetOrientationSensorTypeUsed() {
+SensorManagerAndroid::OrientationSensorType
+SensorManagerAndroid::GetOrientationSensorTypeUsed() {
DCHECK(!device_sensors_.is_null());
- return Java_DeviceSensors_getOrientationSensorTypeUsed(
- AttachCurrentThread(), device_sensors_.obj());
+ return static_cast<SensorManagerAndroid::OrientationSensorType>(
+ Java_DeviceSensors_getOrientationSensorTypeUsed(
+ AttachCurrentThread(), device_sensors_.obj()));
}
// ----- Shared memory API methods
// --- Device Light
-bool SensorManagerAndroid::StartFetchingDeviceLightData(
+void SensorManagerAndroid::StartFetchingDeviceLightData(
DeviceLightHardwareBuffer* buffer) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
StartFetchingLightDataOnUI(buffer);
@@ -212,7 +254,6 @@ bool SensorManagerAndroid::StartFetchingDeviceLightData(
base::Unretained(this),
buffer));
}
- return true;
}
void SensorManagerAndroid::StartFetchingLightDataOnUI(
@@ -227,7 +268,7 @@ void SensorManagerAndroid::StartFetchingLightDataOnUI(
device_light_buffer_ = buffer;
SetLightBufferValue(-1);
}
- bool success = Start(kTypeLight);
+ bool success = Start(CONSUMER_TYPE_LIGHT);
if (!success) {
base::AutoLock autolock(light_buffer_lock_);
SetLightBufferValue(std::numeric_limits<double>::infinity());
@@ -251,7 +292,7 @@ void SensorManagerAndroid::StopFetchingLightDataOnUI() {
if (is_shutdown_)
return;
- Stop(kTypeLight);
+ Stop(CONSUMER_TYPE_LIGHT);
{
base::AutoLock autolock(light_buffer_lock_);
if (device_light_buffer_) {
@@ -269,7 +310,7 @@ void SensorManagerAndroid::SetLightBufferValue(double lux) {
// --- Device Motion
-bool SensorManagerAndroid::StartFetchingDeviceMotionData(
+void SensorManagerAndroid::StartFetchingDeviceMotionData(
DeviceMotionHardwareBuffer* buffer) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
StartFetchingMotionDataOnUI(buffer);
@@ -280,7 +321,6 @@ bool SensorManagerAndroid::StartFetchingDeviceMotionData(
base::Unretained(this),
buffer));
}
- return true;
}
void SensorManagerAndroid::StartFetchingMotionDataOnUI(
@@ -295,7 +335,7 @@ void SensorManagerAndroid::StartFetchingMotionDataOnUI(
device_motion_buffer_ = buffer;
ClearInternalMotionBuffers();
}
- Start(kTypeMotion);
+ Start(CONSUMER_TYPE_MOTION);
// If no motion data can ever be provided, the number of active device motion
// sensors will be zero. In that case flag the shared memory buffer
@@ -324,7 +364,7 @@ void SensorManagerAndroid::StopFetchingMotionDataOnUI() {
if (is_shutdown_)
return;
- Stop(kTypeMotion);
+ Stop(CONSUMER_TYPE_MOTION);
{
base::AutoLock autolock(motion_buffer_lock_);
if (device_motion_buffer_) {
@@ -371,17 +411,7 @@ void SensorManagerAndroid::ClearInternalMotionBuffers() {
// --- Device Orientation
-void SensorManagerAndroid::SetOrientationBufferStatus(bool ready,
- bool absolute) {
- device_orientation_buffer_->seqlock.WriteBegin();
- device_orientation_buffer_->data.absolute = absolute;
- device_orientation_buffer_->data.hasAbsolute = ready;
- device_orientation_buffer_->data.allAvailableSensorsAreActive = ready;
- device_orientation_buffer_->seqlock.WriteEnd();
- orientation_buffer_initialized_ = ready;
-}
-
-bool SensorManagerAndroid::StartFetchingDeviceOrientationData(
+void SensorManagerAndroid::StartFetchingDeviceOrientationData(
DeviceOrientationHardwareBuffer* buffer) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
StartFetchingOrientationDataOnUI(buffer);
@@ -392,7 +422,6 @@ bool SensorManagerAndroid::StartFetchingDeviceOrientationData(
base::Unretained(this),
buffer));
}
- return true;
}
void SensorManagerAndroid::StartFetchingOrientationDataOnUI(
@@ -406,13 +435,15 @@ void SensorManagerAndroid::StartFetchingOrientationDataOnUI(
base::AutoLock autolock(orientation_buffer_lock_);
device_orientation_buffer_ = buffer;
}
- bool success = Start(kTypeOrientation);
+ bool success = Start(CONSUMER_TYPE_ORIENTATION);
{
base::AutoLock autolock(orientation_buffer_lock_);
// If Start() was unsuccessful then set the buffer ready flag to true
// to start firing all-null events.
- SetOrientationBufferStatus(!success /* ready */, false /* absolute */);
+ SetOrientationBufferStatus(buffer, !success /* ready */,
+ false /* absolute */);
+ orientation_buffer_initialized_ = !success;
}
if (!success)
@@ -436,16 +467,83 @@ void SensorManagerAndroid::StopFetchingOrientationDataOnUI() {
if (is_shutdown_)
return;
- Stop(kTypeOrientation);
+ Stop(CONSUMER_TYPE_ORIENTATION);
{
base::AutoLock autolock(orientation_buffer_lock_);
if (device_orientation_buffer_) {
- SetOrientationBufferStatus(false, false);
+ SetOrientationBufferStatus(device_orientation_buffer_, false, false);
+ orientation_buffer_initialized_ = false;
device_orientation_buffer_ = nullptr;
}
}
}
+void SensorManagerAndroid::StartFetchingDeviceOrientationAbsoluteData(
+ DeviceOrientationHardwareBuffer* buffer) {
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ StartFetchingOrientationAbsoluteDataOnUI(buffer);
+ } else {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &SensorManagerAndroid::StartFetchingOrientationAbsoluteDataOnUI,
+ base::Unretained(this),
+ buffer));
+ }
+}
+
+void SensorManagerAndroid::StopFetchingDeviceOrientationAbsoluteData() {
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ StopFetchingOrientationAbsoluteDataOnUI();
+ return;
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&SensorManagerAndroid::StopFetchingOrientationAbsoluteDataOnUI,
+ base::Unretained(this)));
+}
+
+void SensorManagerAndroid::StartFetchingOrientationAbsoluteDataOnUI(
+ DeviceOrientationHardwareBuffer* buffer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(buffer);
+ if (is_shutdown_)
+ return;
+
+ {
+ base::AutoLock autolock(orientation_absolute_buffer_lock_);
+ device_orientation_absolute_buffer_ = buffer;
+ }
+ bool success = Start(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+
+ {
+ base::AutoLock autolock(orientation_absolute_buffer_lock_);
+ // If Start() was unsuccessful then set the buffer ready flag to true
+ // to start firing all-null events.
+ SetOrientationBufferStatus(buffer, !success /* ready */,
+ false /* absolute */);
+ orientation_absolute_buffer_initialized_ = !success;
+ }
+}
+
+void SensorManagerAndroid::StopFetchingOrientationAbsoluteDataOnUI() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (is_shutdown_)
+ return;
+
+ Stop(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
+ {
+ base::AutoLock autolock(orientation_absolute_buffer_lock_);
+ if (device_orientation_absolute_buffer_) {
+ SetOrientationBufferStatus(device_orientation_absolute_buffer_, false,
+ false);
+ orientation_absolute_buffer_initialized_ = false;
+ device_orientation_absolute_buffer_ = nullptr;
+ }
+ }
+}
+
void SensorManagerAndroid::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
is_shutdown_ = true;
diff --git a/chromium/content/browser/device_sensors/sensor_manager_android.h b/chromium/content/browser/device_sensors/sensor_manager_android.h
index 53e5f3dc530..0eb2f6c854f 100644
--- a/chromium/content/browser/device_sensors/sensor_manager_android.h
+++ b/chromium/content/browser/device_sensors/sensor_manager_android.h
@@ -6,8 +6,10 @@
#define CONTENT_BROWSER_DEVICE_SENSORS_SENSOR_MANAGER_ANDROID_H_
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
+#include "content/browser/device_sensors/device_sensors_consts.h"
#include "content/common/content_export.h"
#include "content/common/device_sensors/device_light_hardware_buffer.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h"
@@ -34,45 +36,77 @@ class CONTENT_EXPORT SensorManagerAndroid {
static SensorManagerAndroid* GetInstance();
// Called from Java via JNI.
- void GotLight(JNIEnv*, jobject, double value);
- void GotOrientation(JNIEnv*, jobject,
- double alpha, double beta, double gamma);
- void GotAcceleration(JNIEnv*, jobject,
- double x, double y, double z);
- void GotAccelerationIncludingGravity(JNIEnv*, jobject,
- double x, double y, double z);
- void GotRotationRate(JNIEnv*, jobject,
- double alpha, double beta, double gamma);
+ void GotLight(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ double value);
+ void GotOrientation(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ double alpha,
+ double beta,
+ double gamma);
+ void GotOrientationAbsolute(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ double alpha,
+ double beta,
+ double gamma);
+ void GotAcceleration(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ double x,
+ double y,
+ double z);
+ void GotAccelerationIncludingGravity(
+ JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ double x,
+ double y,
+ double z);
+ void GotRotationRate(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ double alpha,
+ double beta,
+ double gamma);
// Shared memory related methods.
- bool StartFetchingDeviceLightData(DeviceLightHardwareBuffer* buffer);
+ void StartFetchingDeviceLightData(DeviceLightHardwareBuffer* buffer);
void StopFetchingDeviceLightData();
- bool StartFetchingDeviceMotionData(DeviceMotionHardwareBuffer* buffer);
+ void StartFetchingDeviceMotionData(DeviceMotionHardwareBuffer* buffer);
void StopFetchingDeviceMotionData();
- bool StartFetchingDeviceOrientationData(
+ void StartFetchingDeviceOrientationData(
DeviceOrientationHardwareBuffer* buffer);
void StopFetchingDeviceOrientationData();
+ void StartFetchingDeviceOrientationAbsoluteData(
+ DeviceOrientationHardwareBuffer* buffer);
+ void StopFetchingDeviceOrientationAbsoluteData();
+
void Shutdown();
- protected:
- enum EventType {
- // These constants should match DEVICE_ORIENTATION, DEVICE_MOTION and
- // DEVICE_LIGHT constants in content/public/android/java/src/org/
- // chromium/content/browser/DeviceSensors.java
- kTypeOrientation = 0,
- kTypeMotion = 1,
- kTypeLight = 2
+ // A Java counterpart will be generated for this enum.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser
+ // When adding new constants don't modify the order as they are used for UMA.
+ enum OrientationSensorType {
+ NOT_AVAILABLE = 0,
+ ROTATION_VECTOR = 1,
+ ACCELEROMETER_MAGNETIC = 2,
+ GAME_ROTATION_VECTOR = 3,
+ ORIENTATION_SENSOR_MAX = 4,
};
+ protected:
SensorManagerAndroid();
virtual ~SensorManagerAndroid();
- virtual bool Start(EventType event_type);
- virtual void Stop(EventType event_type);
- virtual int GetOrientationSensorTypeUsed();
+ // Starts listening to the sensors corresponding to the consumer_type.
+ // Returns true if the registration with sensors was successful.
+ virtual bool Start(ConsumerType consumer_type);
+ // Stops listening to the sensors corresponding to the consumer_type.
+ virtual void Stop(ConsumerType consumer_type);
+ // Returns currently used sensor type for device orientation.
+ virtual OrientationSensorType GetOrientationSensorTypeUsed();
+ // Returns the number of active sensors corresponding to
+ // ConsumerType.DEVICE_MOTION.
virtual int GetNumberActiveDeviceMotionSensors();
void StartFetchingLightDataOnUI(DeviceLightHardwareBuffer* buffer);
@@ -85,6 +119,10 @@ class CONTENT_EXPORT SensorManagerAndroid {
DeviceOrientationHardwareBuffer* buffer);
void StopFetchingOrientationDataOnUI();
+ void StartFetchingOrientationAbsoluteDataOnUI(
+ DeviceOrientationHardwareBuffer* buffer);
+ void StopFetchingOrientationAbsoluteDataOnUI();
+
private:
friend struct base::DefaultSingletonTraits<SensorManagerAndroid>;
@@ -101,22 +139,25 @@ class CONTENT_EXPORT SensorManagerAndroid {
void SetMotionBufferReadyStatus(bool ready);
void ClearInternalMotionBuffers();
- void SetOrientationBufferStatus(bool ready, bool absolute);
-
// The Java provider of sensors info.
base::android::ScopedJavaGlobalRef<jobject> device_sensors_;
int number_active_device_motion_sensors_;
int received_motion_data_[RECEIVED_MOTION_DATA_MAX];
+
+ // Cached pointers to buffers, owned by DataFetcherSharedMemoryBase.
DeviceLightHardwareBuffer* device_light_buffer_;
DeviceMotionHardwareBuffer* device_motion_buffer_;
DeviceOrientationHardwareBuffer* device_orientation_buffer_;
+ DeviceOrientationHardwareBuffer* device_orientation_absolute_buffer_;
bool motion_buffer_initialized_;
bool orientation_buffer_initialized_;
+ bool orientation_absolute_buffer_initialized_;
base::Lock light_buffer_lock_;
base::Lock motion_buffer_lock_;
base::Lock orientation_buffer_lock_;
+ base::Lock orientation_absolute_buffer_lock_;
bool is_shutdown_;
diff --git a/chromium/content/browser/device_sensors/sensor_manager_android_unittest.cc b/chromium/content/browser/device_sensors/sensor_manager_android_unittest.cc
index dd91c4bcb1c..133b1b5a5f4 100644
--- a/chromium/content/browser/device_sensors/sensor_manager_android_unittest.cc
+++ b/chromium/content/browser/device_sensors/sensor_manager_android_unittest.cc
@@ -7,7 +7,7 @@
#include "base/android/jni_android.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "content/browser/device_sensors/inertial_sensor_consts.h"
+#include "content/browser/device_sensors/device_sensors_consts.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -20,8 +20,8 @@ class FakeSensorManagerAndroid : public SensorManagerAndroid {
FakeSensorManagerAndroid() {}
~FakeSensorManagerAndroid() override {}
- int GetOrientationSensorTypeUsed() override {
- return 1; // ROTATION_VECTOR
+ OrientationSensorType GetOrientationSensorTypeUsed() override {
+ return SensorManagerAndroid::ROTATION_VECTOR;
}
int GetNumberActiveDeviceMotionSensors() override {
@@ -33,8 +33,8 @@ class FakeSensorManagerAndroid : public SensorManagerAndroid {
}
protected:
- bool Start(EventType event_type) override { return true; }
- void Stop(EventType event_type) override {}
+ bool Start(ConsumerType event_type) override { return true; }
+ void Stop(ConsumerType event_type) override {}
private:
int number_active_sensors_;
@@ -46,11 +46,25 @@ class AndroidSensorManagerTest : public testing::Test {
light_buffer_.reset(new DeviceLightHardwareBuffer);
motion_buffer_.reset(new DeviceMotionHardwareBuffer);
orientation_buffer_.reset(new DeviceOrientationHardwareBuffer);
+ orientation_absolute_buffer_.reset(new DeviceOrientationHardwareBuffer);
+ }
+
+ void VerifyOrientationBufferValues(
+ const DeviceOrientationHardwareBuffer* buffer,
+ double alpha, double beta, double gamma) {
+ ASSERT_TRUE(buffer->data.allAvailableSensorsAreActive);
+ ASSERT_EQ(alpha, buffer->data.alpha);
+ ASSERT_TRUE(buffer->data.hasAlpha);
+ ASSERT_EQ(beta, buffer->data.beta);
+ ASSERT_TRUE(buffer->data.hasBeta);
+ ASSERT_EQ(gamma, buffer->data.gamma);
+ ASSERT_TRUE(buffer->data.hasGamma);
}
scoped_ptr<DeviceLightHardwareBuffer> light_buffer_;
scoped_ptr<DeviceMotionHardwareBuffer> motion_buffer_;
scoped_ptr<DeviceOrientationHardwareBuffer> orientation_buffer_;
+ scoped_ptr<DeviceOrientationHardwareBuffer> orientation_absolute_buffer_;
content::TestBrowserThreadBundle thread_bundle_;
};
@@ -62,7 +76,7 @@ TEST_F(AndroidSensorManagerTest, ThreeDeviceMotionSensorsActive) {
sensorManager.StartFetchingDeviceMotionData(motion_buffer_.get());
ASSERT_FALSE(motion_buffer_->data.allAvailableSensorsAreActive);
- sensorManager.GotAcceleration(0, 0, 1, 2, 3);
+ sensorManager.GotAcceleration(nullptr, nullptr, 1, 2, 3);
ASSERT_FALSE(motion_buffer_->data.allAvailableSensorsAreActive);
ASSERT_EQ(1, motion_buffer_->data.accelerationX);
ASSERT_TRUE(motion_buffer_->data.hasAccelerationX);
@@ -71,7 +85,7 @@ TEST_F(AndroidSensorManagerTest, ThreeDeviceMotionSensorsActive) {
ASSERT_EQ(3, motion_buffer_->data.accelerationZ);
ASSERT_TRUE(motion_buffer_->data.hasAccelerationZ);
- sensorManager.GotAccelerationIncludingGravity(0, 0, 4, 5, 6);
+ sensorManager.GotAccelerationIncludingGravity(nullptr, nullptr, 4, 5, 6);
ASSERT_FALSE(motion_buffer_->data.allAvailableSensorsAreActive);
ASSERT_EQ(4, motion_buffer_->data.accelerationIncludingGravityX);
ASSERT_TRUE(motion_buffer_->data.hasAccelerationIncludingGravityX);
@@ -80,7 +94,7 @@ TEST_F(AndroidSensorManagerTest, ThreeDeviceMotionSensorsActive) {
ASSERT_EQ(6, motion_buffer_->data.accelerationIncludingGravityZ);
ASSERT_TRUE(motion_buffer_->data.hasAccelerationIncludingGravityZ);
- sensorManager.GotRotationRate(0, 0, 7, 8, 9);
+ sensorManager.GotRotationRate(nullptr, nullptr, 7, 8, 9);
ASSERT_TRUE(motion_buffer_->data.allAvailableSensorsAreActive);
ASSERT_EQ(7, motion_buffer_->data.rotationRateAlpha);
ASSERT_TRUE(motion_buffer_->data.hasRotationRateAlpha);
@@ -103,10 +117,10 @@ TEST_F(AndroidSensorManagerTest, TwoDeviceMotionSensorsActive) {
sensorManager.StartFetchingDeviceMotionData(motion_buffer_.get());
ASSERT_FALSE(motion_buffer_->data.allAvailableSensorsAreActive);
- sensorManager.GotAcceleration(0, 0, 1, 2, 3);
+ sensorManager.GotAcceleration(nullptr, nullptr, 1, 2, 3);
ASSERT_FALSE(motion_buffer_->data.allAvailableSensorsAreActive);
- sensorManager.GotAccelerationIncludingGravity(0, 0, 1, 2, 3);
+ sensorManager.GotAccelerationIncludingGravity(nullptr, nullptr, 1, 2, 3);
ASSERT_TRUE(motion_buffer_->data.allAvailableSensorsAreActive);
ASSERT_EQ(kInertialSensorIntervalMicroseconds / 1000.,
motion_buffer_->data.interval);
@@ -136,14 +150,23 @@ TEST_F(AndroidSensorManagerTest, DeviceOrientationSensorsActive) {
sensorManager.StartFetchingDeviceOrientationData(orientation_buffer_.get());
ASSERT_FALSE(orientation_buffer_->data.allAvailableSensorsAreActive);
- sensorManager.GotOrientation(0, 0, 1, 2, 3);
- ASSERT_TRUE(orientation_buffer_->data.allAvailableSensorsAreActive);
- ASSERT_EQ(1, orientation_buffer_->data.alpha);
- ASSERT_TRUE(orientation_buffer_->data.hasAlpha);
- ASSERT_EQ(2, orientation_buffer_->data.beta);
- ASSERT_TRUE(orientation_buffer_->data.hasBeta);
- ASSERT_EQ(3, orientation_buffer_->data.gamma);
- ASSERT_TRUE(orientation_buffer_->data.hasGamma);
+ sensorManager.GotOrientation(nullptr, nullptr, 1, 2, 3);
+ VerifyOrientationBufferValues(orientation_buffer_.get(), 1, 2, 3);
+
+ sensorManager.StopFetchingDeviceOrientationData();
+ ASSERT_FALSE(orientation_buffer_->data.allAvailableSensorsAreActive);
+}
+
+TEST_F(AndroidSensorManagerTest, DeviceOrientationAbsoluteSensorsActive) {
+ FakeSensorManagerAndroid::Register(base::android::AttachCurrentThread());
+ FakeSensorManagerAndroid sensorManager;
+
+ sensorManager.StartFetchingDeviceOrientationAbsoluteData(
+ orientation_absolute_buffer_.get());
+ ASSERT_FALSE(orientation_buffer_->data.allAvailableSensorsAreActive);
+
+ sensorManager.GotOrientationAbsolute(nullptr, nullptr, 4, 5, 6);
+ VerifyOrientationBufferValues(orientation_absolute_buffer_.get(), 4, 5, 6);
sensorManager.StopFetchingDeviceOrientationData();
ASSERT_FALSE(orientation_buffer_->data.allAvailableSensorsAreActive);
@@ -156,7 +179,7 @@ TEST_F(AndroidSensorManagerTest, DeviceLightSensorsActive) {
sensorManager.StartFetchingDeviceLightData(light_buffer_.get());
- sensorManager.GotLight(0, 0, 100);
+ sensorManager.GotLight(nullptr, nullptr, 100);
ASSERT_EQ(100, light_buffer_->data.value);
sensorManager.StopFetchingDeviceLightData();
diff --git a/chromium/content/browser/device_sensors/sensor_manager_chromeos.cc b/chromium/content/browser/device_sensors/sensor_manager_chromeos.cc
index 12878cc561e..97dc8fbcbc6 100644
--- a/chromium/content/browser/device_sensors/sensor_manager_chromeos.cc
+++ b/chromium/content/browser/device_sensors/sensor_manager_chromeos.cc
@@ -8,7 +8,7 @@
#include "chromeos/accelerometer/accelerometer_reader.h"
#include "chromeos/accelerometer/accelerometer_types.h"
-#include "content/browser/device_sensors/inertial_sensor_consts.h"
+#include "content/browser/device_sensors/device_sensors_consts.h"
#include "ui/gfx/geometry/vector3d_f.h"
namespace {
diff --git a/chromium/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc b/chromium/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc
index 184a315615d..6d9f77644f7 100644
--- a/chromium/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc
+++ b/chromium/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc
@@ -4,6 +4,7 @@
#include "content/browser/device_sensors/sensor_manager_chromeos.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "chromeos/accelerometer/accelerometer_types.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h"
diff --git a/chromium/content/browser/devtools/browser_devtools_agent_host.cc b/chromium/content/browser/devtools/browser_devtools_agent_host.cc
index d045571b737..d7c342307db 100644
--- a/chromium/content/browser/devtools/browser_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/browser_devtools_agent_host.cc
@@ -31,10 +31,7 @@ BrowserDevToolsAgentHost::BrowserDevToolsAgentHost(
tethering_task_runner)),
tracing_handler_(new devtools::tracing::TracingHandler(
devtools::tracing::TracingHandler::Browser, GetIOContext())),
- protocol_handler_(new DevToolsProtocolHandler(
- this,
- base::Bind(&BrowserDevToolsAgentHost::SendMessageToClient,
- base::Unretained(this)))) {
+ protocol_handler_(new DevToolsProtocolHandler(this)) {
DevToolsProtocolDispatcher* dispatcher = protocol_handler_->dispatcher();
dispatcher->SetIOHandler(io_handler_.get());
dispatcher->SetMemoryHandler(memory_handler_.get());
@@ -74,7 +71,7 @@ bool BrowserDevToolsAgentHost::Close() {
bool BrowserDevToolsAgentHost::DispatchProtocolMessage(
const std::string& message) {
- protocol_handler_->HandleMessage(message);
+ protocol_handler_->HandleMessage(session_id(), message);
return true;
}
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.cc b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
index 4d935519c07..df27d124201 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
@@ -7,7 +7,6 @@
#include <map>
#include <vector>
-#include "base/basictypes.h"
#include "base/guid.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
@@ -76,8 +75,7 @@ scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForWorker(
}
DevToolsAgentHostImpl::DevToolsAgentHostImpl()
- : id_(base::GenerateGUID()),
- client_(NULL) {
+ : id_(base::GenerateGUID()), session_id_(0), client_(NULL) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
g_instances.Get()[id_] = this;
}
@@ -106,6 +104,7 @@ scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::Create(
void DevToolsAgentHostImpl::AttachClient(DevToolsAgentHostClient* client) {
scoped_refptr<DevToolsAgentHostImpl> protect(this);
+ ++session_id_;
if (client_) {
client_->AgentHostClosed(this, true);
InnerDetach();
@@ -153,6 +152,16 @@ void DevToolsAgentHostImpl::DisconnectWebContents() {
void DevToolsAgentHostImpl::ConnectWebContents(WebContents* wc) {
}
+void DevToolsAgentHostImpl::SendProtocolResponse(int session_id,
+ const std::string& message) {
+ SendMessageToClient(session_id, message);
+}
+
+void DevToolsAgentHostImpl::SendProtocolNotification(
+ const std::string& message) {
+ SendMessageToClient(session_id_, message);
+}
+
void DevToolsAgentHostImpl::HostClosed() {
if (!client_)
return;
@@ -164,9 +173,13 @@ void DevToolsAgentHostImpl::HostClosed() {
client->AgentHostClosed(this, false);
}
-void DevToolsAgentHostImpl::SendMessageToClient(const std::string& message) {
+void DevToolsAgentHostImpl::SendMessageToClient(int session_id,
+ const std::string& message) {
if (!client_)
return;
+ // Filter any messages from previous sessions.
+ if (session_id != session_id_)
+ return;
client_->DispatchProtocolMessage(this, message);
}
@@ -249,7 +262,7 @@ void DevToolsMessageChunkProcessor::ProcessChunkedMessageFromAgent(
if (chunk.is_first && chunk.is_last) {
CHECK(message_buffer_size_ == 0);
- callback_.Run(chunk.data);
+ callback_.Run(chunk.session_id, chunk.data);
return;
}
@@ -265,7 +278,7 @@ void DevToolsMessageChunkProcessor::ProcessChunkedMessageFromAgent(
if (chunk.is_last) {
CHECK(message_buffer_.size() == message_buffer_size_);
- callback_.Run(message_buffer_);
+ callback_.Run(chunk.session_id, message_buffer_);
message_buffer_ = std::string();
message_buffer_size_ = 0;
}
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.h b/chromium/content/browser/devtools/devtools_agent_host_impl.h
index 8474c0a658f..f3b06246816 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.h
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_AGENT_HOST_IMPL_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_AGENT_HOST_IMPL_H_
+#include <stdint.h>
+
#include <string>
#include "base/compiler_specific.h"
#include "content/browser/devtools/devtools_io_context.h"
+#include "content/browser/devtools/protocol/devtools_protocol_delegate.h"
#include "content/common/content_export.h"
#include "content/common/devtools_messages.h"
#include "content/public/browser/devtools_agent_host.h"
@@ -22,7 +25,8 @@ namespace content {
class BrowserContext;
// Describes interface for managing devtools agents from the browser process.
-class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
+class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost,
+ public DevToolsProtocolDelegate {
public:
// Informs the hosted agent that a client host has attached.
virtual void Attach() = 0;
@@ -44,14 +48,21 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
void DisconnectWebContents() override;
void ConnectWebContents(WebContents* wc) override;
+ // DevToolsProtocolDelegate implementation.
+ void SendProtocolResponse(int session_id,
+ const std::string& message) override;
+ void SendProtocolNotification(const std::string& message) override;
+
protected:
DevToolsAgentHostImpl();
~DevToolsAgentHostImpl() override;
void HostClosed();
- void SendMessageToClient(const std::string& message);
+ void SendMessageToClient(int session_id, const std::string& message);
devtools::DevToolsIOContext* GetIOContext() { return &io_context_; }
+ int session_id() { DCHECK(client_); return session_id_; }
+
static void NotifyCallbacks(DevToolsAgentHostImpl* agent_host, bool attached);
private:
@@ -59,13 +70,14 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
void InnerDetach();
const std::string id_;
+ int session_id_;
DevToolsAgentHostClient* client_;
devtools::DevToolsIOContext io_context_;
};
class DevToolsMessageChunkProcessor {
public:
- using SendMessageCallback = base::Callback<void(const std::string&)>;
+ using SendMessageCallback = base::Callback<void(int, const std::string&)>;
explicit DevToolsMessageChunkProcessor(const SendMessageCallback& callback);
~DevToolsMessageChunkProcessor();
@@ -77,7 +89,7 @@ class DevToolsMessageChunkProcessor {
private:
SendMessageCallback callback_;
std::string message_buffer_;
- uint32 message_buffer_size_;
+ uint32_t message_buffer_size_;
std::string state_cookie_;
int last_call_id_;
};
diff --git a/chromium/content/browser/devtools/devtools_frame_trace_recorder.cc b/chromium/content/browser/devtools/devtools_frame_trace_recorder.cc
index b024a080247..618bbf8517c 100644
--- a/chromium/content/browser/devtools/devtools_frame_trace_recorder.cc
+++ b/chromium/content/browser/devtools/devtools_frame_trace_recorder.cc
@@ -4,6 +4,8 @@
#include "content/browser/devtools/devtools_frame_trace_recorder.h"
+#include <stddef.h>
+
#include <string>
#include <vector>
@@ -17,7 +19,7 @@
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/public/browser/readback_types.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -39,12 +41,11 @@ class TraceableDevToolsScreenshot
if (!frame_.drawsNothing()) {
std::vector<unsigned char> data;
SkAutoLockPixels lock_image(frame_);
- bool encoded = gfx::PNGCodec::Encode(
+ bool encoded = gfx::JPEGCodec::Encode(
reinterpret_cast<unsigned char*>(frame_.getAddr32(0, 0)),
- gfx::PNGCodec::FORMAT_SkBitmap,
- gfx::Size(frame_.width(), frame_.height()),
- frame_.width() * frame_.bytesPerPixel(), false,
- std::vector<gfx::PNGCodec::Comment>(), &data);
+ gfx::JPEGCodec::FORMAT_SkBitmap,
+ frame_.width(), frame_.height(),
+ frame_.width() * frame_.bytesPerPixel(), 80, &data);
if (encoded) {
std::string encoded_data;
base::Base64Encode(
@@ -64,7 +65,7 @@ class TraceableDevToolsScreenshot
SkBitmap frame_;
};
-void FrameCaptured(base::TraceTicks timestamp, const SkBitmap& bitmap,
+void FrameCaptured(base::TimeTicks timestamp, const SkBitmap& bitmap,
ReadbackResponse response) {
if (response != READBACK_SUCCESS)
return;
@@ -98,7 +99,7 @@ void CaptureFrame(RenderFrameHostImpl* host,
metadata.scrollable_viewport_size, scale)));
view->CopyFromCompositingSurface(
gfx::Rect(), snapshot_size,
- base::Bind(FrameCaptured, base::TraceTicks::Now()),
+ base::Bind(FrameCaptured, base::TimeTicks::Now()),
kN32_SkColorType);
}
diff --git a/chromium/content/browser/devtools/devtools_frame_trace_recorder.h b/chromium/content/browser/devtools/devtools_frame_trace_recorder.h
index 97d133a0fdf..1d026676cf8 100644
--- a/chromium/content/browser/devtools/devtools_frame_trace_recorder.h
+++ b/chromium/content/browser/devtools/devtools_frame_trace_recorder.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_FRAME_TRACE_RECORDER_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
namespace cc {
diff --git a/chromium/content/browser/devtools/devtools_frontend_host_impl.cc b/chromium/content/browser/devtools/devtools_frontend_host_impl.cc
index 67981c594ed..37613b36483 100644
--- a/chromium/content/browser/devtools/devtools_frontend_host_impl.cc
+++ b/chromium/content/browser/devtools/devtools_frontend_host_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/devtools/devtools_frontend_host_impl.h"
+#include <stddef.h>
+
#include "content/browser/bad_message.h"
#include "content/common/devtools_messages.h"
#include "content/public/browser/navigation_entry.h"
@@ -21,8 +23,9 @@ const char kCompatibilityScript[] = "devtools.js";
// static
DevToolsFrontendHost* DevToolsFrontendHost::Create(
RenderFrameHost* frontend_main_frame,
- DevToolsFrontendHost::Delegate* delegate) {
- return new DevToolsFrontendHostImpl(frontend_main_frame, delegate);
+ const HandleMessageCallback& handle_message_callback) {
+ return new DevToolsFrontendHostImpl(frontend_main_frame,
+ handle_message_callback);
}
// static
@@ -39,10 +42,10 @@ base::StringPiece DevToolsFrontendHost::GetFrontendResource(
DevToolsFrontendHostImpl::DevToolsFrontendHostImpl(
RenderFrameHost* frontend_main_frame,
- DevToolsFrontendHost::Delegate* delegate)
+ const HandleMessageCallback& handle_message_callback)
: WebContentsObserver(
WebContents::FromRenderFrameHost(frontend_main_frame)),
- delegate_(delegate) {
+ handle_message_callback_(handle_message_callback) {
frontend_main_frame->Send(new DevToolsMsg_SetupDevToolsClient(
frontend_main_frame->GetRoutingID(),
DevToolsFrontendHost::GetFrontendResource(
@@ -64,8 +67,6 @@ bool DevToolsFrontendHostImpl::OnMessageReceived(
return false;
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(DevToolsFrontendHostImpl, message)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DispatchOnInspectorBackend,
- OnDispatchOnInspectorBackend)
IPC_MESSAGE_HANDLER(DevToolsHostMsg_DispatchOnEmbedder,
OnDispatchOnEmbedder)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -73,14 +74,9 @@ bool DevToolsFrontendHostImpl::OnMessageReceived(
return handled;
}
-void DevToolsFrontendHostImpl::OnDispatchOnInspectorBackend(
- const std::string& message) {
- delegate_->HandleMessageFromDevToolsFrontendToBackend(message);
-}
-
void DevToolsFrontendHostImpl::OnDispatchOnEmbedder(
const std::string& message) {
- delegate_->HandleMessageFromDevToolsFrontend(message);
+ handle_message_callback_.Run(message);
}
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_frontend_host_impl.h b/chromium/content/browser/devtools/devtools_frontend_host_impl.h
index 148bc2f6e73..b2e3dba4f5a 100644
--- a/chromium/content/browser/devtools/devtools_frontend_host_impl.h
+++ b/chromium/content/browser/devtools/devtools_frontend_host_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_FRONTEND_HOST_IMPL_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_FRONTEND_HOST_IMPL_H_
+#include "base/macros.h"
#include "content/public/browser/devtools_frontend_host.h"
#include "content/public/browser/web_contents_observer.h"
@@ -13,8 +14,9 @@ namespace content {
class DevToolsFrontendHostImpl : public DevToolsFrontendHost,
public WebContentsObserver {
public:
- DevToolsFrontendHostImpl(RenderFrameHost* frontend_main_frame,
- DevToolsFrontendHost::Delegate* delegate);
+ DevToolsFrontendHostImpl(
+ RenderFrameHost* frontend_main_frame,
+ const HandleMessageCallback& handle_message_callback);
~DevToolsFrontendHostImpl() override;
void BadMessageRecieved() override;
@@ -24,10 +26,9 @@ class DevToolsFrontendHostImpl : public DevToolsFrontendHost,
bool OnMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host) override;
- void OnDispatchOnInspectorBackend(const std::string& message);
void OnDispatchOnEmbedder(const std::string& message);
- DevToolsFrontendHost::Delegate* delegate_;
+ HandleMessageCallback handle_message_callback_;
DISALLOW_COPY_AND_ASSIGN(DevToolsFrontendHostImpl);
};
diff --git a/chromium/content/browser/devtools/devtools_io_context.h b/chromium/content/browser/devtools/devtools_io_context.h
index 7e43233464e..54b4a72938b 100644
--- a/chromium/content/browser/devtools/devtools_io_context.h
+++ b/chromium/content/browser/devtools/devtools_io_context.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <map>
#include "base/callback.h"
diff --git a/chromium/content/browser/devtools/devtools_manager.h b/chromium/content/browser/devtools/devtools_manager.h
index f8b1b45087a..57b9ea022b3 100644
--- a/chromium/content/browser/devtools/devtools_manager.h
+++ b/chromium/content/browser/devtools/devtools_manager.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_MANAGER_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/common/content_export.h"
#include "content/public/browser/devtools_manager_delegate.h"
diff --git a/chromium/content/browser/devtools/devtools_manager_unittest.cc b/chromium/content/browser/devtools/devtools_manager_unittest.cc
index e2870c8ee03..24d8dc0d5f4 100644
--- a/chromium/content/browser/devtools/devtools_manager_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_manager_unittest.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -141,10 +141,11 @@ TEST_F(DevToolsManagerTest, NoUnresponsiveDialogInInspectedContents) {
client_host.InspectAgentHost(agent_host.get());
// Start with a short timeout.
- inspected_rvh->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
+ inspected_rvh->GetWidget()->StartHangMonitorTimeout(
+ TimeDelta::FromMilliseconds(10));
// Wait long enough for first timeout and see if it fired.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMilliseconds(10));
base::MessageLoop::current()->Run();
EXPECT_FALSE(delegate.renderer_unresponsive_received());
@@ -152,10 +153,11 @@ TEST_F(DevToolsManagerTest, NoUnresponsiveDialogInInspectedContents) {
// Now close devtools and check that the notification is delivered.
client_host.Close();
// Start with a short timeout.
- inspected_rvh->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
+ inspected_rvh->GetWidget()->StartHangMonitorTimeout(
+ TimeDelta::FromMilliseconds(10));
// Wait long enough for first timeout and see if it fired.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMilliseconds(10));
base::MessageLoop::current()->Run();
EXPECT_TRUE(delegate.renderer_unresponsive_received());
diff --git a/chromium/content/browser/devtools/devtools_netlog_observer.cc b/chromium/content/browser/devtools/devtools_netlog_observer.cc
index 6b1c1ba0baf..24448e330cf 100644
--- a/chromium/content/browser/devtools/devtools_netlog_observer.cc
+++ b/chromium/content/browser/devtools/devtools_netlog_observer.cc
@@ -4,6 +4,8 @@
#include "content/browser/devtools/devtools_netlog_observer.h"
+#include <stddef.h>
+
#include "base/strings/string_util.h"
#include "base/values.h"
#include "content/browser/loader/resource_request_info_impl.h"
@@ -28,8 +30,8 @@ DevToolsNetLogObserver::DevToolsNetLogObserver() {
DevToolsNetLogObserver::~DevToolsNetLogObserver() {
}
-DevToolsNetLogObserver::ResourceInfo*
-DevToolsNetLogObserver::GetResourceInfo(uint32 id) {
+DevToolsNetLogObserver::ResourceInfo* DevToolsNetLogObserver::GetResourceInfo(
+ uint32_t id) {
RequestToInfoMap::iterator it = request_to_info_.find(id);
if (it != request_to_info_.end())
return it->second.get();
@@ -193,7 +195,7 @@ void DevToolsNetLogObserver::PopulateResponseInfo(
if (!request_info || !request_info->ShouldReportRawHeaders())
return;
- uint32 source_id = request->net_log().source().id;
+ uint32_t source_id = request->net_log().source().id;
DevToolsNetLogObserver* dev_tools_net_log_observer =
DevToolsNetLogObserver::GetInstance();
if (dev_tools_net_log_observer == NULL)
diff --git a/chromium/content/browser/devtools/devtools_netlog_observer.h b/chromium/content/browser/devtools/devtools_netlog_observer.h
index da58589b301..cde0133bc29 100644
--- a/chromium/content/browser/devtools/devtools_netlog_observer.h
+++ b/chromium/content/browser/devtools/devtools_netlog_observer.h
@@ -5,7 +5,10 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_NETLOG_OBSERVER_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_NETLOG_OBSERVER_H_
+#include <stdint.h>
+
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/public/common/resource_devtools_info.h"
#include "net/log/net_log.h"
@@ -48,9 +51,10 @@ class DevToolsNetLogObserver : public net::NetLog::ThreadSafeObserver {
DevToolsNetLogObserver();
~DevToolsNetLogObserver() override;
- ResourceInfo* GetResourceInfo(uint32 id);
+ ResourceInfo* GetResourceInfo(uint32_t id);
- typedef base::hash_map<uint32, scoped_refptr<ResourceInfo> > RequestToInfoMap;
+ typedef base::hash_map<uint32_t, scoped_refptr<ResourceInfo>>
+ RequestToInfoMap;
RequestToInfoMap request_to_info_;
DISALLOW_COPY_AND_ASSIGN(DevToolsNetLogObserver);
diff --git a/chromium/content/browser/devtools/devtools_protocol_handler.cc b/chromium/content/browser/devtools/devtools_protocol_handler.cc
index 86ccd8e5d2d..e92ef84f389 100644
--- a/chromium/content/browser/devtools/devtools_protocol_handler.cc
+++ b/chromium/content/browser/devtools/devtools_protocol_handler.cc
@@ -4,9 +4,12 @@
#include "content/browser/devtools/devtools_protocol_handler.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_manager.h"
#include "content/public/browser/devtools_manager_delegate.h"
@@ -36,35 +39,35 @@ scoped_ptr<base::DictionaryValue> TakeDictionary(base::DictionaryValue* dict,
} // namespace
DevToolsProtocolHandler::DevToolsProtocolHandler(
- DevToolsAgentHost* agent_host, const Notifier& notifier)
- : agent_host_(agent_host),
- client_(notifier),
- dispatcher_(notifier) {
-}
+ DevToolsAgentHostImpl* agent_host)
+ : agent_host_(agent_host), client_(agent_host), dispatcher_(agent_host) {}
DevToolsProtocolHandler::~DevToolsProtocolHandler() {
}
-void DevToolsProtocolHandler::HandleMessage(const std::string& message) {
- scoped_ptr<base::DictionaryValue> command = ParseCommand(message);
+void DevToolsProtocolHandler::HandleMessage(int session_id,
+ const std::string& message) {
+ scoped_ptr<base::DictionaryValue> command = ParseCommand(session_id, message);
if (!command)
return;
- if (PassCommandToDelegate(command.get()))
+ if (PassCommandToDelegate(session_id, command.get()))
return;
- HandleCommand(command.Pass());
+ HandleCommand(session_id, std::move(command));
}
-bool DevToolsProtocolHandler::HandleOptionalMessage(
- const std::string& message, int* call_id) {
- scoped_ptr<base::DictionaryValue> command = ParseCommand(message);
+bool DevToolsProtocolHandler::HandleOptionalMessage(int session_id,
+ const std::string& message,
+ int* call_id) {
+ scoped_ptr<base::DictionaryValue> command = ParseCommand(session_id, message);
if (!command)
return true;
- if (PassCommandToDelegate(command.get()))
+ if (PassCommandToDelegate(session_id, command.get()))
return true;
- return HandleOptionalCommand(command.Pass(), call_id);
+ return HandleOptionalCommand(session_id, std::move(command), call_id);
}
bool DevToolsProtocolHandler::PassCommandToDelegate(
+ int session_id,
base::DictionaryValue* command) {
DevToolsManagerDelegate* delegate =
DevToolsManager::GetInstance()->delegate();
@@ -74,41 +77,41 @@ bool DevToolsProtocolHandler::PassCommandToDelegate(
scoped_ptr<base::DictionaryValue> response(
delegate->HandleCommand(agent_host_, command));
if (response) {
- std::string json_response;
- base::JSONWriter::Write(*response, &json_response);
- client_.SendRawMessage(json_response);
+ client_.SendMessage(session_id, *response);
return true;
}
return false;
}
-scoped_ptr<base::DictionaryValue>
-DevToolsProtocolHandler::ParseCommand(const std::string& message) {
+scoped_ptr<base::DictionaryValue> DevToolsProtocolHandler::ParseCommand(
+ int session_id,
+ const std::string& message) {
scoped_ptr<base::Value> value = base::JSONReader::Read(message);
if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) {
- client_.SendError(DevToolsProtocolClient::kNoId,
- Response(kStatusParseError,
- "Message must be in JSON format"));
+ client_.SendError(
+ DevToolsCommandId(DevToolsCommandId::kNoId, session_id),
+ Response(kStatusParseError, "Message must be in JSON format"));
return nullptr;
}
scoped_ptr<base::DictionaryValue> command =
make_scoped_ptr(static_cast<base::DictionaryValue*>(value.release()));
- int id = DevToolsProtocolClient::kNoId;
- bool ok = command->GetInteger(kIdParam, &id) && id >= 0;
+ int call_id = DevToolsCommandId::kNoId;
+ bool ok = command->GetInteger(kIdParam, &call_id) && call_id >= 0;
if (!ok) {
- client_.SendError(id, Response(kStatusInvalidRequest,
- "The type of 'id' property must be number"));
+ client_.SendError(DevToolsCommandId(call_id, session_id),
+ Response(kStatusInvalidRequest,
+ "The type of 'id' property must be number"));
return nullptr;
}
std::string method;
ok = command->GetString(kMethodParam, &method);
if (!ok) {
- client_.SendError(id,
- Response(kStatusInvalidRequest,
- "The type of 'method' property must be string"));
+ client_.SendError(DevToolsCommandId(call_id, session_id),
+ Response(kStatusInvalidRequest,
+ "The type of 'method' property must be string"));
return nullptr;
}
@@ -116,34 +119,39 @@ DevToolsProtocolHandler::ParseCommand(const std::string& message) {
}
void DevToolsProtocolHandler::HandleCommand(
+ int session_id,
scoped_ptr<base::DictionaryValue> command) {
- int id = DevToolsProtocolClient::kNoId;
+ int call_id = DevToolsCommandId::kNoId;
std::string method;
- command->GetInteger(kIdParam, &id);
+ command->GetInteger(kIdParam, &call_id);
command->GetString(kMethodParam, &method);
DevToolsProtocolDispatcher::CommandHandler command_handler(
dispatcher_.FindCommandHandler(method));
if (command_handler.is_null()) {
- client_.SendError(id, Response(kStatusNoSuchMethod, "No such method"));
+ client_.SendError(DevToolsCommandId(call_id, session_id),
+ Response(kStatusNoSuchMethod, "No such method"));
return;
}
bool result =
- command_handler.Run(id, TakeDictionary(command.get(), kParamsParam));
+ command_handler.Run(DevToolsCommandId(call_id, session_id),
+ TakeDictionary(command.get(), kParamsParam));
DCHECK(result);
}
bool DevToolsProtocolHandler::HandleOptionalCommand(
- scoped_ptr<base::DictionaryValue> command, int* call_id) {
- *call_id = DevToolsProtocolClient::kNoId;
+ int session_id,
+ scoped_ptr<base::DictionaryValue> command,
+ int* call_id) {
+ *call_id = DevToolsCommandId::kNoId;
std::string method;
command->GetInteger(kIdParam, call_id);
command->GetString(kMethodParam, &method);
DevToolsProtocolDispatcher::CommandHandler command_handler(
dispatcher_.FindCommandHandler(method));
if (!command_handler.is_null()) {
- return command_handler.Run(
- *call_id, TakeDictionary(command.get(), kParamsParam));
+ return command_handler.Run(DevToolsCommandId(*call_id, session_id),
+ TakeDictionary(command.get(), kParamsParam));
}
return false;
}
diff --git a/chromium/content/browser/devtools/devtools_protocol_handler.h b/chromium/content/browser/devtools/devtools_protocol_handler.h
index 299b3423088..32f49287d84 100644
--- a/chromium/content/browser/devtools/devtools_protocol_handler.h
+++ b/chromium/content/browser/devtools/devtools_protocol_handler.h
@@ -10,26 +10,30 @@
namespace content {
class DevToolsAgentHost;
+class DevToolsAgentHostImpl;
+class DevToolsProtocolDelegate;
class DevToolsProtocolHandler {
public:
using Response = DevToolsProtocolClient::Response;
- using Notifier = base::Callback<void(const std::string& message)>;
- DevToolsProtocolHandler(DevToolsAgentHost* agent_host,
- const Notifier& notifier);
+ explicit DevToolsProtocolHandler(DevToolsAgentHostImpl* agent_host);
virtual ~DevToolsProtocolHandler();
- void HandleMessage(const std::string& message);
- bool HandleOptionalMessage(const std::string& message, int* call_id);
+ void HandleMessage(int session_id, const std::string& message);
+ bool HandleOptionalMessage(int session_id,
+ const std::string& message,
+ int* call_id);
DevToolsProtocolDispatcher* dispatcher() { return &dispatcher_; }
private:
- scoped_ptr<base::DictionaryValue> ParseCommand(const std::string& message);
- bool PassCommandToDelegate(base::DictionaryValue* command);
- void HandleCommand(scoped_ptr<base::DictionaryValue> command);
- bool HandleOptionalCommand(scoped_ptr<base::DictionaryValue> command,
+ scoped_ptr<base::DictionaryValue> ParseCommand(int session_id,
+ const std::string& message);
+ bool PassCommandToDelegate(int session_id, base::DictionaryValue* command);
+ void HandleCommand(int session_id, scoped_ptr<base::DictionaryValue> command);
+ bool HandleOptionalCommand(int session_id,
+ scoped_ptr<base::DictionaryValue> command,
int* call_id);
DevToolsAgentHost* agent_host_;
diff --git a/chromium/content/browser/devtools/forwarding_agent_host.cc b/chromium/content/browser/devtools/forwarding_agent_host.cc
index ef7f82c30f1..b8b8c2f826b 100644
--- a/chromium/content/browser/devtools/forwarding_agent_host.cc
+++ b/chromium/content/browser/devtools/forwarding_agent_host.cc
@@ -18,7 +18,7 @@ ForwardingAgentHost::~ForwardingAgentHost() {
}
void ForwardingAgentHost::DispatchOnClientHost(const std::string& message) {
- SendMessageToClient(message);
+ SendMessageToClient(session_id(), message);
}
void ForwardingAgentHost::ConnectionClosed() {
diff --git a/chromium/content/browser/devtools/protocol/color_picker.cc b/chromium/content/browser/devtools/protocol/color_picker.cc
index d298927acda..b87c303edc5 100644
--- a/chromium/content/browser/devtools/protocol/color_picker.cc
+++ b/chromium/content/browser/devtools/protocol/color_picker.cc
@@ -5,6 +5,7 @@
#include "content/browser/devtools/protocol/color_picker.h"
#include "base/bind.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/common/cursors/webcursor.h"
diff --git a/chromium/content/browser/devtools/protocol/color_picker.h b/chromium/content/browser/devtools/protocol/color_picker.h
index e4de5257516..297500f4911 100644
--- a/chromium/content/browser/devtools/protocol/color_picker.h
+++ b/chromium/content/browser/devtools/protocol/color_picker.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_COLOR_PICKER_H_
#include "base/callback.h"
+#include "base/macros.h"
#include "content/public/browser/render_widget_host.h"
#include "third_party/skia/include/core/SkBitmap.h"
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 12c17d9d921..62f7a35aade 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <utility>
+
#include "base/base64.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
@@ -37,14 +41,14 @@ class DevToolsProtocolTest : public ContentBrowserTest,
public:
DevToolsProtocolTest()
: last_sent_id_(0),
- waiting_for_notifications_count_(0),
+ waiting_for_command_result_id_(0),
in_dispatch_(false) {
}
protected:
void SendCommand(const std::string& method,
scoped_ptr<base::DictionaryValue> params) {
- SendCommand(method, params.Pass(), true);
+ SendCommand(method, std::move(params), true);
}
void SendCommand(const std::string& method,
@@ -62,8 +66,10 @@ class DevToolsProtocolTest : public ContentBrowserTest,
agent_host_->DispatchProtocolMessage(json_command);
// Some messages are dispatched synchronously.
// Only run loop if we are not finished yet.
- if (in_dispatch_ && wait)
+ if (in_dispatch_ && wait) {
+ waiting_for_command_result_id_ = last_sent_id_;
base::MessageLoop::current()->Run();
+ }
in_dispatch_ = false;
}
@@ -104,8 +110,8 @@ class DevToolsProtocolTest : public ContentBrowserTest,
}
}
- void WaitForNotifications(int count) {
- waiting_for_notifications_count_ = count;
+ void WaitForNotification(const std::string& notification) {
+ waiting_for_notification_ = notification;
RunMessageLoop();
}
@@ -124,19 +130,20 @@ class DevToolsProtocolTest : public ContentBrowserTest,
if (root->GetInteger("id", &id)) {
result_ids_.push_back(id);
base::DictionaryValue* result;
- EXPECT_TRUE(root->GetDictionary("result", &result));
+ ASSERT_TRUE(root->GetDictionary("result", &result));
result_.reset(result->DeepCopy());
in_dispatch_ = false;
- if (base::MessageLoop::current()->is_running())
+ if (id && id == waiting_for_command_result_id_) {
+ waiting_for_command_result_id_ = 0;
base::MessageLoop::current()->QuitNow();
+ }
} else {
std::string notification;
EXPECT_TRUE(root->GetString("method", &notification));
notifications_.push_back(notification);
- if (waiting_for_notifications_count_) {
- waiting_for_notifications_count_--;
- if (!waiting_for_notifications_count_)
- base::MessageLoop::current()->QuitNow();
+ if (waiting_for_notification_ == notification) {
+ waiting_for_notification_ = std::string();
+ base::MessageLoop::current()->QuitNow();
}
}
}
@@ -145,7 +152,8 @@ class DevToolsProtocolTest : public ContentBrowserTest,
EXPECT_TRUE(false);
}
- int waiting_for_notifications_count_;
+ std::string waiting_for_notification_;
+ int waiting_for_command_result_id_;
bool in_dispatch_;
};
@@ -160,7 +168,7 @@ class SyntheticKeyEventTest : public DevToolsProtocolTest {
params->SetInteger("modifiers", modifier);
params->SetInteger("windowsVirtualKeyCode", windowsKeyCode);
params->SetInteger("nativeVirtualKeyCode", nativeKeyCode);
- SendCommand("Input.dispatchKeyEvent", params.Pass());
+ SendCommand("Input.dispatchKeyEvent", std::move(params));
}
};
@@ -259,7 +267,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, DISABLED_SynthesizePinchGesture) {
params->SetInteger("x", old_width / 2);
params->SetInteger("y", old_height / 2);
params->SetDouble("scaleFactor", 2.0);
- SendCommand("Input.synthesizePinchGesture", params.Pass());
+ SendCommand("Input.synthesizePinchGesture", std::move(params));
int new_width;
ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
@@ -290,7 +298,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, SynthesizeScrollGesture) {
params->SetInteger("y", 0);
params->SetInteger("xDistance", 0);
params->SetInteger("yDistance", -100);
- SendCommand("Input.synthesizeScrollGesture", params.Pass());
+ SendCommand("Input.synthesizeScrollGesture", std::move(params));
ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
shell()->web_contents(),
@@ -313,7 +321,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, SynthesizeTapGesture) {
params->SetInteger("x", 16);
params->SetInteger("y", 16);
params->SetString("gestureSourceType", "touch");
- SendCommand("Input.synthesizeTapGesture", params.Pass());
+ SendCommand("Input.synthesizeTapGesture", std::move(params));
// The link that we just tapped should take us to the bottom of the page. The
// new value of |document.body.scrollTop| will depend on the screen dimensions
@@ -327,8 +335,8 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, SynthesizeTapGesture) {
#endif // defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, NavigationPreservesMessages) {
- ASSERT_TRUE(test_server()->Start());
- GURL test_url = test_server()->GetURL("files/devtools/navigation.html");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
Attach();
SendCommand("Page.enable", nullptr, false);
@@ -336,7 +344,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, NavigationPreservesMessages) {
scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
test_url = GetTestUrl("devtools", "navigation.html");
params->SetString("url", test_url.spec());
- SendCommand("Page.navigate", params.Pass(), true);
+ SendCommand("Page.navigate", std::move(params), true);
bool enough_results = result_ids_.size() >= 2u;
EXPECT_TRUE(enough_results);
@@ -357,7 +365,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, NavigationPreservesMessages) {
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CrossSiteNoDetach) {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
content::SetupCrossSiteRedirector(embedded_test_server());
GURL test_url1 = embedded_test_server()->GetURL(
@@ -373,8 +381,8 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CrossSiteNoDetach) {
}
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ReconnectPreservesState) {
- ASSERT_TRUE(test_server()->Start());
- GURL test_url = test_server()->GetURL("files/devtools/navigation.html");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
Shell* second = CreateBrowser();
@@ -383,17 +391,87 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ReconnectPreservesState) {
Attach();
SendCommand("Runtime.enable", nullptr);
- size_t notification_count = notifications_.size();
agent_host_->DisconnectWebContents();
agent_host_->ConnectWebContents(second->web_contents());
- WaitForNotifications(1);
+ WaitForNotification("Runtime.executionContextsCleared");
+}
- bool found_notification = false;
- for (size_t i = notification_count; i < notifications_.size(); ++i) {
- if (notifications_[i] == "Runtime.executionContextsCleared")
- found_notification = true;
- }
- EXPECT_TRUE(found_notification);
+IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CrossSitePauseInBeforeUnload) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ content::SetupCrossSiteRedirector(embedded_test_server());
+
+ NavigateToURLBlockUntilNavigationsComplete(shell(),
+ embedded_test_server()->GetURL("A.com", "/devtools/navigation.html"), 1);
+ Attach();
+ SendCommand("Debugger.enable", nullptr);
+
+ ASSERT_TRUE(content::ExecuteScript(
+ shell()->web_contents(),
+ "window.onbeforeunload = function() { debugger; return null; }"));
+
+ shell()->LoadURL(
+ embedded_test_server()->GetURL("B.com", "/devtools/navigation.html"));
+ WaitForNotification("Debugger.paused");
+ TestNavigationObserver observer(shell()->web_contents(), 1);
+ SendCommand("Debugger.resume", nullptr);
+ observer.Wait();
+}
+
+IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, InspectDuringFrameSwap) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ content::SetupCrossSiteRedirector(embedded_test_server());
+
+ GURL test_url1 =
+ embedded_test_server()->GetURL("A.com", "/devtools/navigation.html");
+ NavigateToURLBlockUntilNavigationsComplete(shell(), test_url1, 1);
+
+ ShellAddedObserver new_shell_observer;
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
+ "window.open('about:blank','foo');"));
+ Shell* new_shell = new_shell_observer.GetShell();
+ EXPECT_TRUE(new_shell->web_contents()->HasOpener());
+
+ agent_host_ = DevToolsAgentHost::GetOrCreateFor(new_shell->web_contents());
+ agent_host_->AttachClient(this);
+
+ GURL test_url2 =
+ embedded_test_server()->GetURL("B.com", "/devtools/navigation.html");
+
+ // After this navigation, if the bug exists, the process will crash.
+ NavigateToURLBlockUntilNavigationsComplete(new_shell, test_url2, 1);
+
+ // Ensure that the A.com process is still alive by executing a script in the
+ // original tab.
+ //
+ // TODO(alexmos, nasko): A better way to do this is to navigate the original
+ // tab to another site, watch for process exit, and check whether there was a
+ // crash. However, currently there's no way to wait for process exit
+ // regardless of whether it's a crash or not. RenderProcessHostWatcher
+ // should be fixed to support waiting on both WATCH_FOR_PROCESS_EXIT and
+ // WATCH_FOR_HOST_DESTRUCTION, and then used here.
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(),
+ "window.domAutomationController.send("
+ " !!window.open('', 'foo'));",
+ &success));
+ EXPECT_TRUE(success);
+
+ GURL test_url3 =
+ embedded_test_server()->GetURL("A.com", "/devtools/navigation.html");
+
+ // After this navigation, if the bug exists, the process will crash.
+ NavigateToURLBlockUntilNavigationsComplete(new_shell, test_url3, 1);
+
+ // Ensure that the A.com process is still alive by executing a script in the
+ // original tab.
+ success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(),
+ "window.domAutomationController.send("
+ " !!window.open('', 'foo'));",
+ &success));
+ EXPECT_TRUE(success);
}
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ReloadBlankPage) {
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_client.cc b/chromium/content/browser/devtools/protocol/devtools_protocol_client.cc
index 4b7c25d6fe3..9ca03f9d1ab 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_client.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_client.cc
@@ -6,6 +6,7 @@
#include "base/json/json_writer.h"
#include "base/strings/stringprintf.h"
+#include "content/browser/devtools/protocol/devtools_protocol_delegate.h"
namespace content {
@@ -30,24 +31,24 @@ const int kStatusServerError = -32000;
} // namespace
// static
-const DevToolsCommandId DevToolsProtocolClient::kNoId = -1;
+const int DevToolsCommandId::kNoId = -1;
DevToolsProtocolClient::DevToolsProtocolClient(
- const RawMessageCallback& raw_message_callback)
- : raw_message_callback_(raw_message_callback) {
-}
+ DevToolsProtocolDelegate* notifier)
+ : notifier_(notifier) {}
DevToolsProtocolClient::~DevToolsProtocolClient() {
}
-void DevToolsProtocolClient::SendRawMessage(const std::string& message) {
- raw_message_callback_.Run(message);
+void DevToolsProtocolClient::SendRawNotification(const std::string& message) {
+ notifier_->SendProtocolNotification(message);
}
-void DevToolsProtocolClient::SendMessage(const base::DictionaryValue& message) {
+void DevToolsProtocolClient::SendMessage(int session_id,
+ const base::DictionaryValue& message) {
std::string json_message;
base::JSONWriter::Write(message, &json_message);
- SendRawMessage(json_message);
+ notifier_->SendProtocolResponse(session_id, json_message);
}
void DevToolsProtocolClient::SendNotification(
@@ -58,19 +59,21 @@ void DevToolsProtocolClient::SendNotification(
if (params)
notification.Set(kParamsParam, params.release());
- SendMessage(notification);
+ std::string json_message;
+ base::JSONWriter::Write(notification, &json_message);
+ SendRawNotification(json_message);
}
void DevToolsProtocolClient::SendSuccess(
DevToolsCommandId command_id,
scoped_ptr<base::DictionaryValue> params) {
base::DictionaryValue response;
- response.SetInteger(kIdParam, command_id);
+ response.SetInteger(kIdParam, command_id.call_id);
response.Set(kResultParam,
params ? params.release() : new base::DictionaryValue());
- SendMessage(response);
+ SendMessage(command_id.session_id, response);
}
bool DevToolsProtocolClient::SendError(DevToolsCommandId command_id,
@@ -80,10 +83,10 @@ bool DevToolsProtocolClient::SendError(DevToolsCommandId command_id,
return false;
}
base::DictionaryValue dict;
- if (command_id == kNoId)
+ if (command_id.call_id == DevToolsCommandId::kNoId)
dict.Set(kIdParam, base::Value::CreateNullValue());
else
- dict.SetInteger(kIdParam, command_id);
+ dict.SetInteger(kIdParam, command_id.call_id);
base::DictionaryValue* error_object = new base::DictionaryValue();
error_object->SetInteger(kErrorCodeParam, response.status());
@@ -91,7 +94,7 @@ bool DevToolsProtocolClient::SendError(DevToolsCommandId command_id,
error_object->SetString(kErrorMessageParam, response.message());
dict.Set(kErrorParam, error_object);
- SendMessage(dict);
+ SendMessage(command_id.session_id, dict);
return true;
}
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_client.h b/chromium/content/browser/devtools/protocol/devtools_protocol_client.h
index 9297187f21c..fe17c995f77 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_client.h
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_client.h
@@ -6,20 +6,27 @@
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_CLIENT_H_
#include "base/callback.h"
+#include "base/macros.h"
#include "base/values.h"
namespace content {
-using DevToolsCommandId = int;
-class DevToolsProtocolHandler;
+struct DevToolsCommandId {
+ static const int kNoId;
+
+ DevToolsCommandId(int call_id, int session_id)
+ : call_id(call_id), session_id(session_id) {}
+
+ int call_id;
+ int session_id;
+};
+
+class DevToolsProtocolDelegate;
class DevToolsProtocolDispatcher;
+class DevToolsProtocolHandler;
class DevToolsProtocolClient {
public:
- typedef base::Callback<void(const std::string& message)>
- RawMessageCallback;
- static const DevToolsCommandId kNoId;
-
struct Response {
public:
static Response FallThrough();
@@ -46,12 +53,13 @@ class DevToolsProtocolClient {
bool SendError(DevToolsCommandId command_id,
const Response& response);
- // Sends message to client, the caller is presumed to properly
+ // Sends notification to client, the caller is presumed to properly
// format the message. Do not use unless you must.
- void SendRawMessage(const std::string& message);
+ void SendRawNotification(const std::string& message);
- explicit DevToolsProtocolClient(
- const RawMessageCallback& raw_message_callback);
+ void SendMessage(int session_id, const base::DictionaryValue& message);
+
+ explicit DevToolsProtocolClient(DevToolsProtocolDelegate* notifier);
virtual ~DevToolsProtocolClient();
protected:
@@ -63,9 +71,7 @@ class DevToolsProtocolClient {
private:
friend class DevToolsProtocolDispatcher;
- void SendMessage(const base::DictionaryValue& message);
-
- RawMessageCallback raw_message_callback_;
+ DevToolsProtocolDelegate* notifier_;
DISALLOW_COPY_AND_ASSIGN(DevToolsProtocolClient);
};
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_delegate.h b/chromium/content/browser/devtools/protocol/devtools_protocol_delegate.h
new file mode 100644
index 00000000000..489020b7704
--- /dev/null
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_delegate.h
@@ -0,0 +1,22 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DELEGATE_H_
+#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DELEGATE_H_
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+class CONTENT_EXPORT DevToolsProtocolDelegate {
+public:
+ virtual ~DevToolsProtocolDelegate() { }
+ virtual void SendProtocolResponse(int session_id,
+ const std::string& message) = 0;
+ virtual void SendProtocolNotification(const std::string& message) = 0;
+};
+
+} // content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DELEGATE_H_
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_handler_generator.py b/chromium/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
index 6bce71e6047..df56ffe8a5c 100755
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
@@ -29,6 +29,8 @@ template_h = string.Template(header + """\
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_
+#include <utility>
+
#include "content/browser/devtools/protocol/devtools_protocol_client.h"
namespace content {
@@ -74,11 +76,11 @@ ${types}\
class DevToolsProtocolDispatcher {
public:
- using Notifier = DevToolsProtocolClient::RawMessageCallback;
using CommandHandler =
- base::Callback<bool(int, scoped_ptr<base::DictionaryValue>)>;
+ base::Callback<bool(DevToolsCommandId,
+ scoped_ptr<base::DictionaryValue>)>;
- explicit DevToolsProtocolDispatcher(const Notifier& notifier);
+ explicit DevToolsProtocolDispatcher(DevToolsProtocolDelegate* notifier);
~DevToolsProtocolDispatcher();
CommandHandler FindCommandHandler(const std::string& method);
@@ -91,7 +93,7 @@ ${setters}\
${methods}\
- Notifier notifier_;
+ DevToolsProtocolDelegate* notifier_;
DevToolsProtocolClient client_;
CommandHandlers command_handlers_;
${fields}\
@@ -208,7 +210,7 @@ tmpl_client = string.Template("""\
namespace ${domain} {
class Client : public DevToolsProtocolClient {
public:
- explicit Client(const RawMessageCallback& raw_message_callback);
+ explicit Client(DevToolsProtocolDelegate* notifier);
~Client() override;
${methods}\
@@ -252,7 +254,7 @@ ${includes}\
namespace content {
DevToolsProtocolDispatcher::DevToolsProtocolDispatcher(
- const Notifier& notifier)
+ DevToolsProtocolDelegate* notifier)
: notifier_(notifier),
client_(notifier),
${fields_init} {
@@ -334,7 +336,7 @@ ${prep}\
return false;
scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
${wrap}\
- client_.SendSuccess(command_id, result.Pass());
+ client_.SendSuccess(command_id, std::move(result));
return true;
}
""")
@@ -405,8 +407,8 @@ tmpl_object_pass = string.Template(
tmpl_client_impl = string.Template("""\
namespace ${domain} {
-Client::Client(const RawMessageCallback& raw_message_callback)
- : DevToolsProtocolClient(raw_message_callback) {
+Client::Client(DevToolsProtocolDelegate* notifier)
+ : DevToolsProtocolClient(notifier) {
}
Client::~Client() {
@@ -421,7 +423,7 @@ tmpl_event_impl = string.Template("""\
void Client::${Command}(
scoped_refptr<${Command}Params> params) {
SendNotification("${Domain}.${command}",
- params->ToValue().Pass());
+ params->ToValue());
}
""")
@@ -429,7 +431,7 @@ tmpl_response_impl = string.Template("""\
void Client::Send${Command}Response(
DevToolsCommandId command_id,
scoped_refptr<${Command}Response> params) {
- SendSuccess(command_id, params->ToValue().Pass());
+ SendSuccess(command_id, params->ToValue());
}
""")
diff --git a/chromium/content/browser/devtools/protocol/dom_handler.cc b/chromium/content/browser/devtools/protocol/dom_handler.cc
index 0022c2ec800..83962556677 100644
--- a/chromium/content/browser/devtools/protocol/dom_handler.cc
+++ b/chromium/content/browser/devtools/protocol/dom_handler.cc
@@ -5,6 +5,7 @@
#include "content/browser/devtools/protocol/dom_handler.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
diff --git a/chromium/content/browser/devtools/protocol/dom_handler.h b/chromium/content/browser/devtools/protocol/dom_handler.h
index 375cf2ba2a9..56f80e2162e 100644
--- a/chromium/content/browser/devtools/protocol/dom_handler.h
+++ b/chromium/content/browser/devtools/protocol/dom_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DOM_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DOM_HANDLER_H_
+#include "base/macros.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
namespace content {
diff --git a/chromium/content/browser/devtools/protocol/emulation_handler.cc b/chromium/content/browser/devtools/protocol/emulation_handler.cc
index cae9f00fc49..f5945d71321 100644
--- a/chromium/content/browser/devtools/protocol/emulation_handler.cc
+++ b/chromium/content/browser/devtools/protocol/emulation_handler.cc
@@ -4,7 +4,10 @@
#include "content/browser/devtools/protocol/emulation_handler.h"
+#include <utility>
+
#include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/geolocation/geolocation_service_context.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -37,22 +40,15 @@ ui::GestureProviderConfigType TouchEmulationConfigurationToType(
} // namespace
-EmulationHandler::EmulationHandler(page::PageHandler* page_handler)
+EmulationHandler::EmulationHandler()
: touch_emulation_enabled_(false),
device_emulation_enabled_(false),
- page_handler_(page_handler),
- host_(nullptr)
-{
- page_handler->SetScreencastListener(this);
+ host_(nullptr) {
}
EmulationHandler::~EmulationHandler() {
}
-void EmulationHandler::ScreencastEnabledChanged() {
- UpdateTouchEventEmulationState();
-}
-
void EmulationHandler::SetRenderFrameHost(RenderFrameHostImpl* host) {
if (host_ == host)
return;
@@ -88,7 +84,7 @@ Response EmulationHandler::SetGeolocationOverride(
} else {
geoposition->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
}
- geolocation_context->SetOverride(geoposition.Pass());
+ geolocation_context->SetOverride(std::move(geoposition));
return Response::OK();
}
@@ -216,8 +212,7 @@ void EmulationHandler::UpdateTouchEventEmulationState() {
host_ ? host_->GetRenderWidgetHost() : nullptr;
if (!widget_host)
return;
- bool enabled = touch_emulation_enabled_ ||
- page_handler_->screencast_enabled();
+ bool enabled = touch_emulation_enabled_;
ui::GestureProviderConfigType config_type =
TouchEmulationConfigurationToType(touch_emulation_configuration_);
widget_host->SetTouchEventEmulationEnabled(enabled, config_type);
diff --git a/chromium/content/browser/devtools/protocol/emulation_handler.h b/chromium/content/browser/devtools/protocol/emulation_handler.h
index c2a4bd38fbd..bcaeb0d0410 100644
--- a/chromium/content/browser/devtools/protocol/emulation_handler.h
+++ b/chromium/content/browser/devtools/protocol/emulation_handler.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_EMULATION_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_EMULATION_HANDLER_H_
+#include "base/macros.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
-#include "content/browser/devtools/protocol/page_handler.h"
#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
namespace content {
@@ -20,15 +20,12 @@ namespace page { class PageHandler; }
namespace emulation {
-class EmulationHandler : public page::PageHandler::ScreencastListener {
+class EmulationHandler {
public:
using Response = DevToolsProtocolClient::Response;
- explicit EmulationHandler(page::PageHandler* page_handler);
- ~EmulationHandler() override;
-
- // page::PageHandler::ScreencastListener implementation.
- void ScreencastEnabledChanged() override;
+ EmulationHandler();
+ ~EmulationHandler();
void SetRenderFrameHost(RenderFrameHostImpl* host);
void Detached();
@@ -67,7 +64,6 @@ class EmulationHandler : public page::PageHandler::ScreencastListener {
bool device_emulation_enabled_;
blink::WebDeviceEmulationParams device_emulation_params_;
- page::PageHandler* page_handler_;
RenderFrameHostImpl* host_;
DISALLOW_COPY_AND_ASSIGN(EmulationHandler);
diff --git a/chromium/content/browser/devtools/protocol/input_handler.cc b/chromium/content/browser/devtools/protocol/input_handler.cc
index eaa72bdd19e..d9c17f3ee0e 100644
--- a/chromium/content/browser/devtools/protocol/input_handler.cc
+++ b/chromium/content/browser/devtools/protocol/input_handler.cc
@@ -4,6 +4,8 @@
#include "content/browser/devtools/protocol/input_handler.h"
+#include <stddef.h>
+
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -23,12 +25,12 @@ namespace input {
namespace {
-gfx::Point CssPixelsToPoint(int x, int y, float page_scale_factor) {
- return gfx::Point(x * page_scale_factor, y * page_scale_factor);
+gfx::PointF CssPixelsToPointF(int x, int y, float page_scale_factor) {
+ return gfx::PointF(x * page_scale_factor, y * page_scale_factor);
}
-gfx::Vector2d CssPixelsToVector2d(int x, int y, float page_scale_factor) {
- return gfx::Vector2d(x * page_scale_factor, y * page_scale_factor);
+gfx::Vector2dF CssPixelsToVector2dF(int x, int y, float page_scale_factor) {
+ return gfx::Vector2dF(x * page_scale_factor, y * page_scale_factor);
}
bool StringToGestureSourceType(const std::string& in,
@@ -204,12 +206,12 @@ Response InputHandler::DispatchKeyEvent(
if (code) {
event.domCode = static_cast<int>(
- ui::KeycodeConverter::CodeStringToDomCode(code->c_str()));
+ ui::KeycodeConverter::CodeStringToDomCode(*code));
}
if (key) {
event.domKey = static_cast<int>(
- ui::KeycodeConverter::KeyStringToDomKey(key->c_str()));
+ ui::KeycodeConverter::KeyStringToDomKey(*key));
}
if (!host_)
@@ -319,7 +321,7 @@ Response InputHandler::SynthesizePinchGesture(
const int kDefaultRelativeSpeed = 800;
gesture_params.scale_factor = scale_factor;
- gesture_params.anchor = CssPixelsToPoint(x, y, page_scale_factor_);
+ gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_);
gesture_params.relative_pointer_speed_in_pixels_s =
relative_speed ? *relative_speed : kDefaultRelativeSpeed;
@@ -358,23 +360,21 @@ Response InputHandler::SynthesizeScrollGesture(
const bool kDefaultPreventFling = true;
const int kDefaultSpeed = 800;
- gesture_params.anchor = CssPixelsToPoint(x, y, page_scale_factor_);
+ gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_);
gesture_params.prevent_fling =
prevent_fling ? *prevent_fling : kDefaultPreventFling;
gesture_params.speed_in_pixels_s = speed ? *speed : kDefaultSpeed;
if (x_distance || y_distance) {
gesture_params.distances.push_back(
- CssPixelsToVector2d(x_distance ? *x_distance : 0,
- y_distance ? *y_distance : 0,
- page_scale_factor_));
+ CssPixelsToVector2dF(x_distance ? *x_distance : 0,
+ y_distance ? *y_distance : 0, page_scale_factor_));
}
if (x_overscroll || y_overscroll) {
- gesture_params.distances.push_back(
- CssPixelsToVector2d(x_overscroll ? -*x_overscroll : 0,
- y_overscroll ? -*y_overscroll : 0,
- page_scale_factor_));
+ gesture_params.distances.push_back(CssPixelsToVector2dF(
+ x_overscroll ? -*x_overscroll : 0, y_overscroll ? -*y_overscroll : 0,
+ page_scale_factor_));
}
if (!StringToGestureSourceType(
@@ -400,8 +400,8 @@ void InputHandler::SynthesizeRepeatingScroll(
DevToolsCommandId command_id) {
if (!interaction_marker_name.empty()) {
// TODO(alexclarke): Can we move this elsewhere? It doesn't really fit here.
- TRACE_EVENT_COPY_ASYNC_BEGIN0("benchmark",
- interaction_marker_name.c_str(), command_id);
+ TRACE_EVENT_COPY_ASYNC_BEGIN0("benchmark", interaction_marker_name.c_str(),
+ command_id.call_id);
}
host_->QueueSyntheticGesture(
@@ -419,8 +419,8 @@ void InputHandler::OnScrollFinished(
DevToolsCommandId command_id,
SyntheticGesture::Result result) {
if (!interaction_marker_name.empty()) {
- TRACE_EVENT_COPY_ASYNC_END0("benchmark",
- interaction_marker_name.c_str(), command_id);
+ TRACE_EVENT_COPY_ASYNC_END0("benchmark", interaction_marker_name.c_str(),
+ command_id.call_id);
}
if (repeat_count > 0) {
@@ -449,7 +449,7 @@ Response InputHandler::SynthesizeTapGesture(
const int kDefaultDuration = 50;
const int kDefaultTapCount = 1;
- gesture_params.position = CssPixelsToPoint(x, y, page_scale_factor_);
+ gesture_params.position = CssPixelsToPointF(x, y, page_scale_factor_);
gesture_params.duration_ms = duration ? *duration : kDefaultDuration;
if (!StringToGestureSourceType(
diff --git a/chromium/content/browser/devtools/protocol/input_handler.h b/chromium/content/browser/devtools/protocol/input_handler.h
index cb6a5fcf713..1bb7be96c74 100644
--- a/chromium/content/browser/devtools/protocol/input_handler.h
+++ b/chromium/content/browser/devtools/protocol/input_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INPUT_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INPUT_HANDLER_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
diff --git a/chromium/content/browser/devtools/protocol/inspector_handler.h b/chromium/content/browser/devtools/protocol/inspector_handler.h
index c533a253543..08c1e5e3efb 100644
--- a/chromium/content/browser/devtools/protocol/inspector_handler.h
+++ b/chromium/content/browser/devtools/protocol/inspector_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INSPECTOR_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INSPECTOR_HANDLER_H_
+#include "base/macros.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
namespace content {
diff --git a/chromium/content/browser/devtools/protocol/io_handler.cc b/chromium/content/browser/devtools/protocol/io_handler.cc
index 1cc1354cda7..59bef41456f 100644
--- a/chromium/content/browser/devtools/protocol/io_handler.cc
+++ b/chromium/content/browser/devtools/protocol/io_handler.cc
@@ -4,6 +4,7 @@
#include "content/browser/devtools/protocol/io_handler.h"
+#include <stddef.h>
#include <stdint.h>
#include "base/bind.h"
diff --git a/chromium/content/browser/devtools/protocol/io_handler.h b/chromium/content/browser/devtools/protocol/io_handler.h
index d6ae25baaa4..951df505dfa 100644
--- a/chromium/content/browser/devtools/protocol/io_handler.h
+++ b/chromium/content/browser/devtools/protocol/io_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_IO_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_IO_HANDLER_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
diff --git a/chromium/content/browser/devtools/protocol/memory_handler.h b/chromium/content/browser/devtools/protocol/memory_handler.h
index 0d668550802..b080f50ea6b 100644
--- a/chromium/content/browser/devtools/protocol/memory_handler.h
+++ b/chromium/content/browser/devtools/protocol/memory_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_MEMORY_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_MEMORY_HANDLER_H_
+#include "base/macros.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
namespace content {
diff --git a/chromium/content/browser/devtools/protocol/network_handler.cc b/chromium/content/browser/devtools/protocol/network_handler.cc
index 27f82f45c8b..d18d87a6b96 100644
--- a/chromium/content/browser/devtools/protocol/network_handler.cc
+++ b/chromium/content/browser/devtools/protocol/network_handler.cc
@@ -4,6 +4,8 @@
#include "content/browser/devtools/protocol/network_handler.h"
+#include <stddef.h>
+
#include "base/containers/hash_tables.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
@@ -322,6 +324,6 @@ Response NetworkHandler::ShowCertificateViewer(int certificate_id) {
return Response::OK();
}
-} // namespace dom
+} // namespace network
} // namespace devtools
} // namespace content
diff --git a/chromium/content/browser/devtools/protocol/network_handler.h b/chromium/content/browser/devtools/protocol/network_handler.h
index 0c8a9890ce7..3b1456bcacf 100644
--- a/chromium/content/browser/devtools/protocol/network_handler.h
+++ b/chromium/content/browser/devtools/protocol/network_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_NETWORK_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_NETWORK_HANDLER_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
#include "net/cookies/canonical_cookie.h"
diff --git a/chromium/content/browser/devtools/protocol/page_handler.cc b/chromium/content/browser/devtools/protocol/page_handler.cc
index 73c4c8ea965..7e79a7200cf 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.cc
+++ b/chromium/content/browser/devtools/protocol/page_handler.cc
@@ -96,15 +96,15 @@ PageHandler::PageHandler()
screencast_quality_(kDefaultScreenshotQuality),
screencast_max_width_(-1),
screencast_max_height_(-1),
+ capture_every_nth_frame_(1),
capture_retry_count_(0),
has_compositor_frame_metadata_(false),
- screencast_frame_sent_(0),
- screencast_frame_acked_(0),
- processing_screencast_frame_(false),
+ session_id_(0),
+ frame_counter_(0),
+ frames_in_flight_(0),
color_picker_(new ColorPicker(base::Bind(
&PageHandler::OnColorPicked, base::Unretained(this)))),
host_(nullptr),
- screencast_listener_(nullptr),
weak_factory_(this) {
}
@@ -188,10 +188,6 @@ void PageHandler::DidDetachInterstitialPage() {
client_->InterstitialHidden(InterstitialHiddenParams::Create());
}
-void PageHandler::SetScreencastListener(ScreencastListener* listener) {
- screencast_listener_ = listener;
-}
-
Response PageHandler::Enable() {
enabled_ = true;
return Response::FallThrough();
@@ -201,8 +197,6 @@ Response PageHandler::Disable() {
enabled_ = false;
screencast_enabled_ = false;
color_picker_->SetEnabled(false);
- if (screencast_listener_)
- screencast_listener_->ScreencastEnabledChanged();
return Response::FallThrough();
}
@@ -283,19 +277,11 @@ Response PageHandler::CaptureScreenshot(DevToolsCommandId command_id) {
return Response::OK();
}
-Response PageHandler::CanScreencast(bool* result) {
-#if defined(OS_ANDROID)
- *result = true;
-#else
- *result = false;
-#endif // defined(OS_ANDROID)
- return Response::OK();
-}
-
Response PageHandler::StartScreencast(const std::string* format,
const int* quality,
const int* max_width,
- const int* max_height) {
+ const int* max_height,
+ const int* every_nth_frame) {
RenderWidgetHostImpl* widget_host =
host_ ? host_->GetRenderWidgetHost() : nullptr;
if (!widget_host)
@@ -308,6 +294,11 @@ Response PageHandler::StartScreencast(const std::string* format,
screencast_quality_ = kDefaultScreenshotQuality;
screencast_max_width_ = max_width ? *max_width : -1;
screencast_max_height_ = max_height ? *max_height : -1;
+ ++session_id_;
+ frame_counter_ = 0;
+ frames_in_flight_ = 0;
+ capture_every_nth_frame_ =
+ every_nth_frame && *every_nth_frame ? *every_nth_frame : 1;
bool visible = !widget_host->is_hidden();
NotifyScreencastVisibility(visible);
@@ -319,20 +310,17 @@ Response PageHandler::StartScreencast(const std::string* format,
new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0));
}
}
- if (screencast_listener_)
- screencast_listener_->ScreencastEnabledChanged();
return Response::FallThrough();
}
Response PageHandler::StopScreencast() {
screencast_enabled_ = false;
- if (screencast_listener_)
- screencast_listener_->ScreencastEnabledChanged();
return Response::FallThrough();
}
-Response PageHandler::ScreencastFrameAck(int frame_number) {
- screencast_frame_acked_ = frame_number;
+Response PageHandler::ScreencastFrameAck(int session_id) {
+ if (session_id == session_id_)
+ --frames_in_flight_;
return Response::OK();
}
@@ -383,12 +371,13 @@ void PageHandler::NotifyScreencastVisibility(bool visible) {
}
void PageHandler::InnerSwapCompositorFrame() {
- if (screencast_frame_sent_ - screencast_frame_acked_ >
- kMaxScreencastFramesInFlight || processing_screencast_frame_) {
+ if (!host_ || !host_->GetView())
return;
- }
- if (!host_ || !host_->GetView())
+ if (frames_in_flight_ > kMaxScreencastFramesInFlight)
+ return;
+
+ if (++frame_counter_ % capture_every_nth_frame_)
return;
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
@@ -423,7 +412,6 @@ void PageHandler::InnerSwapCompositorFrame() {
gfx::ScaleSize(viewport_size_dip, scale)));
if (snapshot_size_dip.width() > 0 && snapshot_size_dip.height() > 0) {
- processing_screencast_frame_ = true;
gfx::Rect viewport_bounds_dip(gfx::ToRoundedSize(viewport_size_dip));
view->CopyFromCompositingSurface(
viewport_bounds_dip,
@@ -432,6 +420,7 @@ void PageHandler::InnerSwapCompositorFrame() {
weak_factory_.GetWeakPtr(),
last_compositor_frame_metadata_),
kN32_SkColorType);
+ frames_in_flight_++;
}
}
@@ -440,7 +429,6 @@ void PageHandler::ScreencastFrameCaptured(
const SkBitmap& bitmap,
ReadbackResponse response) {
if (response != READBACK_SUCCESS) {
- processing_screencast_frame_ = false;
if (capture_retry_count_) {
--capture_retry_count_;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
@@ -448,6 +436,7 @@ void PageHandler::ScreencastFrameCaptured(
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kFrameRetryDelayMs));
}
+ --frames_in_flight_;
return;
}
base::PostTaskAndReplyWithResult(
@@ -463,16 +452,18 @@ void PageHandler::ScreencastFrameEncoded(
const cc::CompositorFrameMetadata& metadata,
const base::Time& timestamp,
const std::string& data) {
- processing_screencast_frame_ = false;
-
// Consider metadata empty in case it has no device scale factor.
- if (metadata.device_scale_factor == 0 || !host_ || data.empty())
+ if (metadata.device_scale_factor == 0 || !host_ || data.empty()) {
+ --frames_in_flight_;
return;
+ }
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
host_->GetView());
- if (!view)
+ if (!view) {
+ --frames_in_flight_;
return;
+ }
gfx::SizeF screen_size_dip =
gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
@@ -489,7 +480,7 @@ void PageHandler::ScreencastFrameEncoded(
client_->ScreencastFrame(ScreencastFrameParams::Create()
->set_data(data)
->set_metadata(param_metadata)
- ->set_frame_number(++screencast_frame_sent_));
+ ->set_session_id(session_id_));
}
void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id,
diff --git a/chromium/content/browser/devtools/protocol/page_handler.h b/chromium/content/browser/devtools/protocol/page_handler.h
index f2c2ded4dba..02b685a50d1 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.h
+++ b/chromium/content/browser/devtools/protocol/page_handler.h
@@ -5,8 +5,10 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_PAGE_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_PAGE_HANDLER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "cc/output/compositor_frame_metadata.h"
@@ -31,12 +33,6 @@ class PageHandler : public NotificationObserver {
public:
typedef DevToolsProtocolClient::Response Response;
- class ScreencastListener {
- public:
- virtual ~ScreencastListener() { }
- virtual void ScreencastEnabledChanged() = 0;
- };
-
PageHandler();
~PageHandler() override;
@@ -48,7 +44,6 @@ class PageHandler : public NotificationObserver {
frame_metadata);
void DidAttachInterstitialPage();
void DidDetachInterstitialPage();
- void SetScreencastListener(ScreencastListener* listener);
bool screencast_enabled() const { return enabled_ && screencast_enabled_; }
Response Enable();
@@ -68,13 +63,13 @@ class PageHandler : public NotificationObserver {
Response CaptureScreenshot(DevToolsCommandId command_id);
- Response CanScreencast(bool* result);
Response StartScreencast(const std::string* format,
const int* quality,
const int* max_width,
- const int* max_height);
+ const int* max_height,
+ const int* every_nth_frame);
Response StopScreencast();
- Response ScreencastFrameAck(int frame_number);
+ Response ScreencastFrameAck(int session_id);
Response HandleJavaScriptDialog(bool accept, const std::string* prompt_text);
@@ -113,19 +108,19 @@ class PageHandler : public NotificationObserver {
int screencast_quality_;
int screencast_max_width_;
int screencast_max_height_;
+ int capture_every_nth_frame_;
int capture_retry_count_;
bool has_compositor_frame_metadata_;
cc::CompositorFrameMetadata next_compositor_frame_metadata_;
cc::CompositorFrameMetadata last_compositor_frame_metadata_;
- int screencast_frame_sent_;
- int screencast_frame_acked_;
- bool processing_screencast_frame_;
+ int session_id_;
+ int frame_counter_;
+ int frames_in_flight_;
scoped_ptr<ColorPicker> color_picker_;
RenderFrameHostImpl* host_;
scoped_ptr<Client> client_;
- ScreencastListener* screencast_listener_;
NotificationRegistrar registrar_;
base::WeakPtrFactory<PageHandler> weak_factory_;
diff --git a/chromium/content/browser/devtools/protocol/power_handler.cc b/chromium/content/browser/devtools/protocol/power_handler.cc
deleted file mode 100644
index c88097b86d7..00000000000
--- a/chromium/content/browser/devtools/protocol/power_handler.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/devtools/protocol/power_handler.h"
-
-#include "content/browser/power_profiler/power_profiler_service.h"
-
-namespace content {
-namespace devtools {
-namespace power {
-
-typedef DevToolsProtocolClient::Response Response;
-
-PowerHandler::PowerHandler() : enabled_(false) {
-}
-
-PowerHandler::~PowerHandler() {
- if (enabled_)
- PowerProfilerService::GetInstance()->RemoveObserver(this);
-}
-
-void PowerHandler::SetClient(scoped_ptr<Client> client) {
- client_.swap(client);
-}
-
-void PowerHandler::OnPowerEvent(const PowerEventVector& events) {
- std::vector<scoped_refptr<PowerEvent>> event_list;
- for (const auto& event : events) {
- DCHECK(event.type < content::PowerEvent::ID_COUNT);
- // Use internal value to be consistent with Blink's
- // monotonicallyIncreasingTime.
- double timestamp = event.time.ToInternalValue() /
- static_cast<double>(base::Time::kMicrosecondsPerMillisecond);
- event_list.push_back(PowerEvent::Create()
- ->set_type(kPowerTypeNames[event.type])
- ->set_timestamp(timestamp)
- ->set_value(event.value));
- }
- client_->DataAvailable(DataAvailableParams::Create()->set_value(event_list));
-}
-
-void PowerHandler::Detached() {
- if (enabled_) {
- PowerProfilerService::GetInstance()->RemoveObserver(this);
- enabled_ = false;
- }
-}
-
-Response PowerHandler::Start() {
- if (!PowerProfilerService::GetInstance()->IsAvailable())
- return Response::InternalError("Power profiler service unavailable");
- if (!enabled_) {
- PowerProfilerService::GetInstance()->AddObserver(this);
- enabled_ = true;
- }
- return Response::OK();
-}
-
-Response PowerHandler::End() {
- if (!PowerProfilerService::GetInstance()->IsAvailable())
- return Response::InternalError("Power profiler service unavailable");
- if (enabled_) {
- PowerProfilerService::GetInstance()->RemoveObserver(this);
- enabled_ = false;
- }
- return Response::OK();
-}
-
-Response PowerHandler::CanProfilePower(bool* result) {
- *result = PowerProfilerService::GetInstance()->IsAvailable();
- return Response::OK();
-}
-
-Response PowerHandler::GetAccuracyLevel(std::string* result) {
- if (!PowerProfilerService::GetInstance()->IsAvailable())
- return Response::InternalError("Power profiler service unavailable");
- *result = PowerProfilerService::GetInstance()->GetAccuracyLevel();
- return Response::OK();
-}
-
-} // namespace power
-} // namespace devtools
-} // namespace content
diff --git a/chromium/content/browser/devtools/protocol/power_handler.h b/chromium/content/browser/devtools/protocol/power_handler.h
deleted file mode 100644
index 1219b1f24a0..00000000000
--- a/chromium/content/browser/devtools/protocol/power_handler.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_POWER_HANDLER_H_
-#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_POWER_HANDLER_H_
-
-#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
-#include "content/browser/power_profiler/power_profiler_observer.h"
-
-namespace content {
-namespace devtools {
-namespace power {
-
-class PowerHandler : public PowerProfilerObserver {
- public:
- typedef DevToolsProtocolClient::Response Response;
-
- PowerHandler();
- ~PowerHandler() override;
-
- void SetClient(scoped_ptr<Client> client);
-
- // PowerProfilerObserver override.
- void OnPowerEvent(const PowerEventVector& events) override;
-
- void Detached();
-
- Response Start();
- Response End();
- Response CanProfilePower(bool* result);
- Response GetAccuracyLevel(std::string* result);
-
- private:
- scoped_ptr<Client> client_;
- bool enabled_;
-
- DISALLOW_COPY_AND_ASSIGN(PowerHandler);
-};
-
-} // namespace power
-} // namespace devtools
-} // namespace content
-
-#endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_POWER_HANDLER_H_
diff --git a/chromium/content/browser/devtools/protocol/security_handler.cc b/chromium/content/browser/devtools/protocol/security_handler.cc
index 50cf64f659b..7784651f7b2 100644
--- a/chromium/content/browser/devtools/protocol/security_handler.cc
+++ b/chromium/content/browser/devtools/protocol/security_handler.cc
@@ -99,8 +99,8 @@ void SecurityHandler::SecurityStyleChanged(
AddExplanations(kSecurityStateInsecure,
security_style_explanations.broken_explanations,
&explanations);
- AddExplanations(kSecurityStateWarning,
- security_style_explanations.warning_explanations,
+ AddExplanations(kSecurityStateNeutral,
+ security_style_explanations.unauthenticated_explanations,
&explanations);
AddExplanations(kSecurityStateSecure,
security_style_explanations.secure_explanations,
diff --git a/chromium/content/browser/devtools/protocol/security_handler.h b/chromium/content/browser/devtools/protocol/security_handler.h
index 407d93c4ec9..3f9ce2b139d 100644
--- a/chromium/content/browser/devtools/protocol/security_handler.h
+++ b/chromium/content/browser/devtools/protocol/security_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_SECURITY_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_SECURITY_HANDLER_H_
+#include "base/macros.h"
#include "content/browser/devtools/devtools_protocol_handler.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
#include "content/public/browser/web_contents_observer.h"
diff --git a/chromium/content/browser/devtools/protocol/service_worker_handler.cc b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
index fcac2734c2b..a84091c276b 100644
--- a/chromium/content/browser/devtools/protocol/service_worker_handler.cc
+++ b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
@@ -182,7 +182,7 @@ bool CollectURLs(std::set<GURL>* urls, FrameTreeNode* tree_node) {
}
void StopServiceWorkerOnIO(scoped_refptr<ServiceWorkerContextWrapper> context,
- int64 version_id) {
+ int64_t version_id) {
if (content::ServiceWorkerVersion* version =
context->GetLiveVersion(version_id)) {
version->StopWorker(base::Bind(&StatusNoOp));
@@ -191,7 +191,7 @@ void StopServiceWorkerOnIO(scoped_refptr<ServiceWorkerContextWrapper> context,
void GetDevToolsRouteInfoOnIO(
scoped_refptr<ServiceWorkerContextWrapper> context,
- int64 version_id,
+ int64_t version_id,
const base::Callback<void(int, int)>& callback) {
if (content::ServiceWorkerVersion* version =
context->GetLiveVersion(version_id)) {
@@ -376,7 +376,7 @@ Response ServiceWorkerHandler::StopWorker(const std::string& version_id) {
return Response::OK();
if (!context_)
return CreateContextErrorResponse();
- int64 id = 0;
+ int64_t id = 0;
if (!base::StringToInt64(version_id, &id))
return CreateInvalidVersionIdErrorResponse();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
@@ -400,7 +400,7 @@ Response ServiceWorkerHandler::InspectWorker(const std::string& version_id) {
if (!context_)
return CreateContextErrorResponse();
- int64 id = kInvalidServiceWorkerVersionId;
+ int64_t id = kInvalidServiceWorkerVersionId;
if (!base::StringToInt64(version_id, &id))
return CreateInvalidVersionIdErrorResponse();
BrowserThread::PostTask(
@@ -422,7 +422,7 @@ Response ServiceWorkerHandler::SetForceUpdateOnPageLoad(
bool force_update_on_page_load) {
if (!context_)
return CreateContextErrorResponse();
- int64 id = kInvalidServiceWorkerRegistrationId;
+ int64_t id = kInvalidServiceWorkerRegistrationId;
if (!base::StringToInt64(registration_id, &id))
return CreateInvalidVersionIdErrorResponse();
context_->SetForceUpdateOnPageLoad(id, force_update_on_page_load);
@@ -437,7 +437,7 @@ Response ServiceWorkerHandler::DeliverPushMessage(
return Response::OK();
if (!render_frame_host_)
return CreateContextErrorResponse();
- int64 id = 0;
+ int64_t id = 0;
if (!base::StringToInt64(registration_id, &id))
return CreateInvalidVersionIdErrorResponse();
BrowserContext::DeliverPushMessage(
@@ -504,8 +504,8 @@ void ServiceWorkerHandler::OnWorkerVersionUpdated(
}
void ServiceWorkerHandler::OnErrorReported(
- int64 registration_id,
- int64 version_id,
+ int64_t registration_id,
+ int64_t version_id,
const ServiceWorkerContextObserver::ErrorInfo& info) {
client_->WorkerErrorReported(
WorkerErrorReportedParams::Create()->set_error_message(
diff --git a/chromium/content/browser/devtools/protocol/service_worker_handler.h b/chromium/content/browser/devtools/protocol/service_worker_handler.h
index a67c37fde8c..1508f5d375f 100644
--- a/chromium/content/browser/devtools/protocol/service_worker_handler.h
+++ b/chromium/content/browser/devtools/protocol/service_worker_handler.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_SERVICE_WORKER_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_SERVICE_WORKER_HANDLER_H_
+#include <stdint.h>
+
#include <set>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
@@ -84,8 +87,8 @@ class ServiceWorkerHandler : public DevToolsAgentHostClient,
const std::vector<ServiceWorkerRegistrationInfo>& registrations);
void OnWorkerVersionUpdated(
const std::vector<ServiceWorkerVersionInfo>& registrations);
- void OnErrorReported(int64 registration_id,
- int64 version_id,
+ void OnErrorReported(int64_t registration_id,
+ int64_t version_id,
const ServiceWorkerContextObserver::ErrorInfo& info);
void OpenNewDevToolsWindow(int process_id, int devtools_agent_route_id);
diff --git a/chromium/content/browser/devtools/protocol/system_info_handler.cc b/chromium/content/browser/devtools/protocol/system_info_handler.cc
index aa32e58e928..27877b0bd98 100644
--- a/chromium/content/browser/devtools/protocol/system_info_handler.cc
+++ b/chromium/content/browser/devtools/protocol/system_info_handler.cc
@@ -4,6 +4,9 @@
#include "content/browser/devtools/protocol/system_info_handler.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/public/browser/gpu_data_manager.h"
@@ -26,7 +29,7 @@ class AuxGPUInfoEnumerator : public gpu::GPUInfo::Enumerator {
: dictionary_(dictionary),
in_aux_attributes_(false) { }
- void AddInt64(const char* name, int64 value) override {
+ void AddInt64(const char* name, int64_t value) override {
if (in_aux_attributes_)
dictionary_->SetDouble(name, value);
}
@@ -193,11 +196,12 @@ void SystemInfoHandler::SendGetInfoResponse(DevToolsCommandId command_id) {
AuxGPUInfoEnumerator enumerator(aux_attributes.get());
gpu_info.EnumerateFields(&enumerator);
- scoped_refptr<GPUInfo> gpu = GPUInfo::Create()
- ->set_devices(devices)
- ->set_aux_attributes(aux_attributes.Pass())
- ->set_feature_status(make_scoped_ptr(GetFeatureStatus()))
- ->set_driver_bug_workarounds(GetDriverBugWorkarounds());
+ scoped_refptr<GPUInfo> gpu =
+ GPUInfo::Create()
+ ->set_devices(devices)
+ ->set_aux_attributes(std::move(aux_attributes))
+ ->set_feature_status(make_scoped_ptr(GetFeatureStatus()))
+ ->set_driver_bug_workarounds(GetDriverBugWorkarounds());
client_->SendGetInfoResponse(
command_id,
diff --git a/chromium/content/browser/devtools/protocol/system_info_handler.h b/chromium/content/browser/devtools/protocol/system_info_handler.h
index 8131c9e2d08..40b14e8e3c4 100644
--- a/chromium/content/browser/devtools/protocol/system_info_handler.h
+++ b/chromium/content/browser/devtools/protocol/system_info_handler.h
@@ -7,6 +7,7 @@
#include <set>
+#include "base/macros.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_data_manager_observer.h"
diff --git a/chromium/content/browser/devtools/protocol/tethering_handler.cc b/chromium/content/browser/devtools/protocol/tethering_handler.cc
index 9b964f49d38..a58b534c368 100644
--- a/chromium/content/browser/devtools/protocol/tethering_handler.cc
+++ b/chromium/content/browser/devtools/protocol/tethering_handler.cc
@@ -156,7 +156,7 @@ class SocketPump {
class BoundSocket {
public:
- typedef base::Callback<void(uint16, const std::string&)> AcceptedCallback;
+ typedef base::Callback<void(uint16_t, const std::string&)> AcceptedCallback;
BoundSocket(AcceptedCallback accepted_callback,
const CreateServerSocketCallback& socket_callback)
@@ -169,7 +169,7 @@ class BoundSocket {
virtual ~BoundSocket() {
}
- bool Listen(uint16 port) {
+ bool Listen(uint16_t port) {
port_ = port;
net::IPAddressNumber ip_number;
if (!net::ParseIPLiteralToNumber(kLocalhost, &ip_number))
@@ -224,7 +224,7 @@ class BoundSocket {
CreateServerSocketCallback socket_callback_;
scoped_ptr<net::ServerSocket> socket_;
scoped_ptr<net::StreamSocket> accept_socket_;
- uint16 port_;
+ uint16_t port_;
};
} // namespace
@@ -238,9 +238,9 @@ class TetheringHandler::TetheringImpl {
const CreateServerSocketCallback& socket_callback);
~TetheringImpl();
- void Bind(DevToolsCommandId command_id, uint16 port);
- void Unbind(DevToolsCommandId command_id, uint16 port);
- void Accepted(uint16 port, const std::string& name);
+ void Bind(DevToolsCommandId command_id, uint16_t port);
+ void Unbind(DevToolsCommandId command_id, uint16_t port);
+ void Accepted(uint16_t port, const std::string& name);
private:
void SendInternalError(DevToolsCommandId command_id,
@@ -249,7 +249,7 @@ class TetheringHandler::TetheringImpl {
base::WeakPtr<TetheringHandler> handler_;
CreateServerSocketCallback socket_callback_;
- typedef std::map<uint16, BoundSocket*> BoundSockets;
+ typedef std::map<uint16_t, BoundSocket*> BoundSockets;
BoundSockets bound_sockets_;
};
@@ -264,8 +264,8 @@ TetheringHandler::TetheringImpl::~TetheringImpl() {
STLDeleteValues(&bound_sockets_);
}
-void TetheringHandler::TetheringImpl::Bind(
- DevToolsCommandId command_id, uint16 port) {
+void TetheringHandler::TetheringImpl::Bind(DevToolsCommandId command_id,
+ uint16_t port) {
if (bound_sockets_.find(port) != bound_sockets_.end()) {
SendInternalError(command_id, "Port already bound");
return;
@@ -287,9 +287,8 @@ void TetheringHandler::TetheringImpl::Bind(
base::Bind(&TetheringHandler::SendBindSuccess, handler_, command_id));
}
-void TetheringHandler::TetheringImpl::Unbind(
- DevToolsCommandId command_id, uint16 port) {
-
+void TetheringHandler::TetheringImpl::Unbind(DevToolsCommandId command_id,
+ uint16_t port) {
BoundSockets::iterator it = bound_sockets_.find(port);
if (it == bound_sockets_.end()) {
SendInternalError(command_id, "Port is not bound");
@@ -304,8 +303,8 @@ void TetheringHandler::TetheringImpl::Unbind(
base::Bind(&TetheringHandler::SendUnbindSuccess, handler_, command_id));
}
-void TetheringHandler::TetheringImpl::Accepted(
- uint16 port, const std::string& name) {
+void TetheringHandler::TetheringImpl::Accepted(uint16_t port,
+ const std::string& name) {
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -348,7 +347,7 @@ void TetheringHandler::SetClient(scoped_ptr<Client> client) {
client_.swap(client);
}
-void TetheringHandler::Accepted(uint16 port, const std::string& name) {
+void TetheringHandler::Accepted(uint16_t port, const std::string& name) {
client_->Accepted(AcceptedParams::Create()->set_port(port)
->set_connection_id(name));
}
diff --git a/chromium/content/browser/devtools/protocol/tethering_handler.h b/chromium/content/browser/devtools/protocol/tethering_handler.h
index 21f1a9a27a6..fc6b8e50673 100644
--- a/chromium/content/browser/devtools/protocol/tethering_handler.h
+++ b/chromium/content/browser/devtools/protocol/tethering_handler.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TETHERING_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TETHERING_HANDLER_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
@@ -35,7 +38,7 @@ class TetheringHandler {
private:
class TetheringImpl;
- void Accepted(uint16 port, const std::string& name);
+ void Accepted(uint16_t port, const std::string& name);
bool Activate();
void SendBindSuccess(DevToolsCommandId command_id);
diff --git a/chromium/content/browser/devtools/protocol/tracing_handler.cc b/chromium/content/browser/devtools/protocol/tracing_handler.cc
index 3518ed5e996..11cc18844ae 100644
--- a/chromium/content/browser/devtools/protocol/tracing_handler.cc
+++ b/chromium/content/browser/devtools/protocol/tracing_handler.cc
@@ -101,7 +101,7 @@ void TracingHandler::SetClient(scoped_ptr<Client> client) {
void TracingHandler::Detached() {
if (did_initiate_recording_)
- DisableRecording(scoped_refptr<TracingController::TraceDataSink>());
+ StopTracing(scoped_refptr<TracingController::TraceDataSink>());
}
void TracingHandler::OnTraceDataCollected(const std::string& trace_fragment) {
@@ -113,7 +113,7 @@ void TracingHandler::OnTraceDataCollected(const std::string& trace_fragment) {
message.reserve(message.size() + trace_fragment.size() + messageSuffixSize);
message += trace_fragment;
message += "] } }";
- client_->SendRawMessage(message);
+ client_->SendRawNotification(message);
}
void TracingHandler::OnTraceComplete() {
@@ -130,7 +130,7 @@ Response TracingHandler::Start(DevToolsCommandId command_id,
const std::string* options,
const double* buffer_usage_reporting_interval,
const std::string* transfer_mode) {
- if (IsRecording())
+ if (IsTracing())
return Response::InternalError("Tracing is already started");
did_initiate_recording_ = true;
@@ -145,13 +145,13 @@ Response TracingHandler::Start(DevToolsCommandId command_id,
// If inspected target is a render process Tracing.start will be handled by
// tracing agent in the renderer.
if (target_ == Renderer) {
- TracingController::GetInstance()->EnableRecording(
+ TracingController::GetInstance()->StartTracing(
trace_config,
- TracingController::EnableRecordingDoneCallback());
+ TracingController::StartTracingDoneCallback());
return Response::FallThrough();
}
- TracingController::GetInstance()->EnableRecording(
+ TracingController::GetInstance()->StartTracing(
trace_config,
base::Bind(&TracingHandler::OnRecordingEnabled,
weak_factory_.GetWeakPtr(),
@@ -173,7 +173,7 @@ Response TracingHandler::End(DevToolsCommandId command_id) {
} else {
proxy = new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr());
}
- DisableRecording(proxy);
+ StopTracing(proxy);
// If inspected target is a render process Tracing.end will be handled by
// tracing agent in the renderer.
return target_ == Renderer ? Response::FallThrough() : Response::OK();
@@ -212,7 +212,7 @@ void TracingHandler::OnCategoriesReceived(
}
Response TracingHandler::RequestMemoryDump(DevToolsCommandId command_id) {
- if (!IsRecording())
+ if (!IsTracing())
return Response::InternalError("Tracing is not started");
base::trace_event::MemoryDumpManager::GetInstance()->RequestGlobalDump(
@@ -224,7 +224,7 @@ Response TracingHandler::RequestMemoryDump(DevToolsCommandId command_id) {
}
void TracingHandler::OnMemoryDumpFinished(DevToolsCommandId command_id,
- uint64 dump_guid,
+ uint64_t dump_guid,
bool success) {
client_->SendRequestMemoryDumpResponse(
command_id,
@@ -251,20 +251,20 @@ void TracingHandler::SetupTimer(double usage_reporting_interval) {
buffer_usage_poll_timer_->Reset();
}
-void TracingHandler::DisableRecording(
+void TracingHandler::StopTracing(
const scoped_refptr<TracingController::TraceDataSink>& trace_data_sink) {
buffer_usage_poll_timer_.reset();
- TracingController::GetInstance()->DisableRecording(trace_data_sink);
+ TracingController::GetInstance()->StopTracing(trace_data_sink);
did_initiate_recording_ = false;
}
-bool TracingHandler::IsRecording() const {
- return TracingController::GetInstance()->IsRecording();
+bool TracingHandler::IsTracing() const {
+ return TracingController::GetInstance()->IsTracing();
}
bool TracingHandler::IsStartupTracingActive() {
return ::tracing::TraceConfigFile::GetInstance()->IsEnabled() &&
- TracingController::GetInstance()->IsRecording();
+ TracingController::GetInstance()->IsTracing();
}
} // namespace tracing
diff --git a/chromium/content/browser/devtools/protocol/tracing_handler.h b/chromium/content/browser/devtools/protocol/tracing_handler.h
index 886067030fd..f45d7e97c2e 100644
--- a/chromium/content/browser/devtools/protocol/tracing_handler.h
+++ b/chromium/content/browser/devtools/protocol/tracing_handler.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <set>
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
@@ -58,13 +62,13 @@ class TracingHandler {
void OnCategoriesReceived(DevToolsCommandId command_id,
const std::set<std::string>& category_set);
void OnMemoryDumpFinished(DevToolsCommandId command_id,
- uint64 dump_guid,
+ uint64_t dump_guid,
bool success);
void SetupTimer(double usage_reporting_interval);
- void DisableRecording(
+ void StopTracing(
const scoped_refptr<TracingController::TraceDataSink>& trace_data_sink);
- bool IsRecording() const;
+ bool IsTracing() const;
static bool IsStartupTracingActive();
scoped_ptr<base::Timer> buffer_usage_poll_timer_;
diff --git a/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc b/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
index 19c991d4a46..cb1be38ea98 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -4,9 +4,11 @@
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/lazy_instance.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/devtools_frame_trace_recorder.h"
#include "content/browser/devtools/devtools_protocol_handler.h"
@@ -17,10 +19,10 @@
#include "content/browser/devtools/protocol/io_handler.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/devtools/protocol/page_handler.h"
-#include "content/browser/devtools/protocol/power_handler.h"
#include "content/browser/devtools/protocol/security_handler.h"
#include "content/browser/devtools/protocol/service_worker_handler.h"
#include "content/browser/devtools/protocol/tracing_handler.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -31,6 +33,7 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#if defined(OS_ANDROID)
#include "content/browser/power_save_blocker_impl.h"
@@ -44,6 +47,8 @@ typedef std::vector<RenderFrameDevToolsAgentHost*> Instances;
namespace {
base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER;
+bool browser_side_navigation = false;
+
static RenderFrameDevToolsAgentHost* FindAgentHost(RenderFrameHost* host) {
if (g_instances == NULL)
return NULL;
@@ -87,7 +92,9 @@ class RenderFrameDevToolsAgentHost::FrameHostHolder {
void Attach();
void Reattach(FrameHostHolder* old);
void Detach();
- void DispatchProtocolMessage(int call_id, const std::string& message);
+ void DispatchProtocolMessage(int session_id,
+ int call_id,
+ const std::string& message);
void InspectElement(int x, int y);
void ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
void Suspend();
@@ -96,15 +103,17 @@ class RenderFrameDevToolsAgentHost::FrameHostHolder {
private:
void GrantPolicy();
void RevokePolicy();
- void SendMessageToClient(const std::string& message);
+ void SendMessageToClient(int session_id, const std::string& message);
RenderFrameDevToolsAgentHost* agent_;
RenderFrameHostImpl* host_;
bool attached_;
bool suspended_;
DevToolsMessageChunkProcessor chunk_processor_;
- std::vector<std::string> pending_messages_;
- std::map<int, std::string> sent_messages_;
+ // <session_id, message>
+ std::vector<std::pair<int, std::string>> pending_messages_;
+ // <call_id> -> <session_id, message>
+ std::map<int, std::pair<int, std::string>> sent_messages_;
};
RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder(
@@ -127,7 +136,7 @@ RenderFrameDevToolsAgentHost::FrameHostHolder::~FrameHostHolder() {
void RenderFrameDevToolsAgentHost::FrameHostHolder::Attach() {
host_->Send(new DevToolsAgentMsg_Attach(
- host_->GetRoutingID(), agent_->GetId()));
+ host_->GetRoutingID(), agent_->GetId(), agent_->session_id()));
GrantPolicy();
attached_ = true;
}
@@ -137,10 +146,13 @@ void RenderFrameDevToolsAgentHost::FrameHostHolder::Reattach(
if (old)
chunk_processor_.set_state_cookie(old->chunk_processor_.state_cookie());
host_->Send(new DevToolsAgentMsg_Reattach(
- host_->GetRoutingID(), agent_->GetId(), chunk_processor_.state_cookie()));
+ host_->GetRoutingID(), agent_->GetId(), agent_->session_id(),
+ chunk_processor_.state_cookie()));
if (old) {
- for (const auto& pair : old->sent_messages_)
- DispatchProtocolMessage(pair.first, pair.second);
+ for (const auto& pair : old->sent_messages_) {
+ DispatchProtocolMessage(pair.second.first, pair.first,
+ pair.second.second);
+ }
}
GrantPolicy();
attached_ = true;
@@ -180,16 +192,19 @@ void RenderFrameDevToolsAgentHost::FrameHostHolder::RevokePolicy() {
}
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage(
- int call_id, const std::string& message) {
+ int session_id,
+ int call_id,
+ const std::string& message) {
host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
- host_->GetRoutingID(), message));
- sent_messages_[call_id] = message;
+ host_->GetRoutingID(), session_id, message));
+ sent_messages_[call_id] = std::make_pair(session_id, message);
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::InspectElement(
int x, int y) {
+ DCHECK(attached_);
host_->Send(new DevToolsAgentMsg_InspectElement(
- host_->GetRoutingID(), agent_->GetId(), x, y));
+ host_->GetRoutingID(), x, y));
}
void
@@ -199,12 +214,13 @@ RenderFrameDevToolsAgentHost::FrameHostHolder::ProcessChunkedMessageFromAgent(
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient(
+ int session_id,
const std::string& message) {
sent_messages_.erase(chunk_processor_.last_call_id());
if (suspended_)
- pending_messages_.push_back(message);
+ pending_messages_.push_back(std::make_pair(session_id, message));
else
- agent_->SendMessageToClient(message);
+ agent_->SendMessageToClient(session_id, message);
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::Suspend() {
@@ -213,14 +229,29 @@ void RenderFrameDevToolsAgentHost::FrameHostHolder::Suspend() {
void RenderFrameDevToolsAgentHost::FrameHostHolder::Resume() {
suspended_ = false;
- for (const std::string& message : pending_messages_)
- agent_->SendMessageToClient(message);
- std::vector<std::string> empty;
+ for (const auto& pair : pending_messages_)
+ agent_->SendMessageToClient(pair.first, pair.second);
+ std::vector<std::pair<int, std::string>> empty;
pending_messages_.swap(empty);
}
// RenderFrameDevToolsAgentHost ------------------------------------------------
+// static
+scoped_refptr<DevToolsAgentHost>
+DevToolsAgentHost::GetOrCreateFor(RenderFrameHost* frame_host) {
+ while (frame_host && !ShouldCreateDevToolsFor(frame_host))
+ frame_host = frame_host->GetParent();
+ DCHECK(frame_host);
+ RenderFrameDevToolsAgentHost* result = FindAgentHost(frame_host);
+ if (!result) {
+ result = new RenderFrameDevToolsAgentHost(
+ static_cast<RenderFrameHostImpl*>(frame_host));
+ }
+ return result;
+}
+
+// static
scoped_refptr<DevToolsAgentHost>
DevToolsAgentHost::GetOrCreateFor(WebContents* web_contents) {
RenderFrameDevToolsAgentHost* result = FindAgentHost(web_contents);
@@ -280,6 +311,9 @@ void RenderFrameDevToolsAgentHost::AddAllAgentHosts(
void RenderFrameDevToolsAgentHost::OnCancelPendingNavigation(
RenderFrameHost* pending,
RenderFrameHost* current) {
+ if (browser_side_navigation)
+ return;
+
RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(pending);
if (!agent_host)
return;
@@ -289,6 +323,14 @@ void RenderFrameDevToolsAgentHost::OnCancelPendingNavigation(
}
}
+// static
+void RenderFrameDevToolsAgentHost::OnBeforeNavigation(
+ RenderFrameHost* current, RenderFrameHost* pending) {
+ RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(current);
+ if (agent_host)
+ agent_host->AboutToNavigateRenderFrame(current, pending);
+}
+
RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
RenderFrameHostImpl* host)
: dom_handler_(new devtools::dom::DOMHandler()),
@@ -297,7 +339,6 @@ RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
io_handler_(new devtools::io::IOHandler(GetIOContext())),
network_handler_(new devtools::network::NetworkHandler()),
page_handler_(nullptr),
- power_handler_(new devtools::power::PowerHandler()),
security_handler_(nullptr),
service_worker_handler_(
new devtools::service_worker::ServiceWorkerHandler()),
@@ -306,18 +347,18 @@ RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
GetIOContext())),
emulation_handler_(nullptr),
frame_trace_recorder_(nullptr),
- protocol_handler_(new DevToolsProtocolHandler(
- this,
- base::Bind(&RenderFrameDevToolsAgentHost::SendMessageToClient,
- base::Unretained(this)))),
- current_frame_crashed_(false) {
+ protocol_handler_(new DevToolsProtocolHandler(this)),
+ current_frame_crashed_(false),
+ pending_handle_(nullptr),
+ in_navigation_(0),
+ frame_tree_node_(host->frame_tree_node()) {
+ browser_side_navigation = IsBrowserSideNavigationEnabled();
DevToolsProtocolDispatcher* dispatcher = protocol_handler_->dispatcher();
dispatcher->SetDOMHandler(dom_handler_.get());
dispatcher->SetInputHandler(input_handler_.get());
dispatcher->SetInspectorHandler(inspector_handler_.get());
dispatcher->SetIOHandler(io_handler_.get());
dispatcher->SetNetworkHandler(network_handler_.get());
- dispatcher->SetPowerHandler(power_handler_.get());
dispatcher->SetServiceWorkerHandler(service_worker_handler_.get());
dispatcher->SetTracingHandler(tracing_handler_.get());
@@ -325,7 +366,7 @@ RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
security_handler_.reset(new devtools::security::SecurityHandler());
page_handler_.reset(new devtools::page::PageHandler());
emulation_handler_.reset(
- new devtools::emulation::EmulationHandler(page_handler_.get()));
+ new devtools::emulation::EmulationHandler());
dispatcher->SetSecurityHandler(security_handler_.get());
dispatcher->SetPageHandler(page_handler_.get());
dispatcher->SetEmulationHandler(emulation_handler_.get());
@@ -335,6 +376,11 @@ RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
CommitPending();
WebContentsObserver::Observe(WebContents::FromRenderFrameHost(host));
+ if (web_contents() && web_contents()->GetCrashedStatus() !=
+ base::TERMINATION_STATUS_STILL_RUNNING) {
+ current_frame_crashed_ = true;
+ }
+
g_instances.Get().push_back(this);
AddRef(); // Balanced in RenderFrameHostDestroyed.
}
@@ -364,7 +410,7 @@ void RenderFrameDevToolsAgentHost::CommitPending() {
return;
}
- current_ = pending_.Pass();
+ current_ = std::move(pending_);
UpdateProtocolHandlers(current_->host());
current_->Resume();
}
@@ -405,13 +451,20 @@ void RenderFrameDevToolsAgentHost::Detach() {
bool RenderFrameDevToolsAgentHost::DispatchProtocolMessage(
const std::string& message) {
int call_id = 0;
- if (protocol_handler_->HandleOptionalMessage(message, &call_id))
+ if (protocol_handler_->HandleOptionalMessage(session_id(), message, &call_id))
return true;
+ if (in_navigation_ > 0) {
+ DCHECK(browser_side_navigation);
+ in_navigation_protocol_message_buffer_[call_id] =
+ std::make_pair(session_id(), message);
+ return true;
+ }
+
if (current_)
- current_->DispatchProtocolMessage(call_id, message);
+ current_->DispatchProtocolMessage(session_id(), call_id, message);
if (pending_)
- pending_->DispatchProtocolMessage(call_id, message);
+ pending_->DispatchProtocolMessage(session_id(), call_id, message);
return true;
}
@@ -428,7 +481,7 @@ void RenderFrameDevToolsAgentHost::OnClientAttached() {
frame_trace_recorder_.reset(new DevToolsFrameTraceRecorder());
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
power_save_blocker_.reset(static_cast<PowerSaveBlockerImpl*>(
PowerSaveBlocker::Create(
PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
@@ -449,10 +502,10 @@ void RenderFrameDevToolsAgentHost::OnClientDetached() {
emulation_handler_->Detached();
if (page_handler_)
page_handler_->Detached();
- power_handler_->Detached();
service_worker_handler_->Detached();
tracing_handler_->Detached();
frame_trace_recorder_.reset();
+ in_navigation_protocol_message_buffer_.clear();
// TODO(kaznacheev): Move this call back to DevToolsManager when
// extensions::ProcessManager no longer relies on this notification.
@@ -467,10 +520,65 @@ RenderFrameDevToolsAgentHost::~RenderFrameDevToolsAgentHost() {
g_instances.Get().erase(it);
}
-// TODO(creis): Consider removing this in favor of RenderFrameHostChanged.
+void RenderFrameDevToolsAgentHost::DidStartNavigation(
+ NavigationHandle* navigation_handle) {
+ if (!browser_side_navigation)
+ return;
+ if (!MatchesMyTreeNode(navigation_handle))
+ return;
+ DCHECK(current_);
+ DCHECK(in_navigation_ >= 0);
+ ++in_navigation_;
+}
+
+void RenderFrameDevToolsAgentHost::ReadyToCommitNavigation(
+ NavigationHandle* navigation_handle) {
+ // ReadyToCommitNavigation should only be called in PlzNavigate.
+ DCHECK(browser_side_navigation);
+
+ if (MatchesMyTreeNode(navigation_handle) && in_navigation_ != 0) {
+ RenderFrameHostImpl* render_frame_host_impl =
+ static_cast<RenderFrameHostImpl*>(
+ navigation_handle->GetRenderFrameHost());
+ if (current_->host() != render_frame_host_impl || current_frame_crashed_) {
+ SetPending(render_frame_host_impl);
+ pending_handle_ = navigation_handle;
+ }
+ }
+}
+
+void RenderFrameDevToolsAgentHost::DidFinishNavigation(
+ NavigationHandle* navigation_handle) {
+ if (!browser_side_navigation)
+ return;
+
+ if (MatchesMyTreeNode(navigation_handle) && in_navigation_ != 0) {
+ --in_navigation_;
+ DCHECK(in_navigation_ >= 0);
+ if (pending_handle_ == navigation_handle) {
+ // This navigation handle did set the pending FrameHostHolder.
+ DCHECK(pending_);
+ if (navigation_handle->HasCommitted()) {
+ DCHECK(pending_->host() == navigation_handle->GetRenderFrameHost());
+ CommitPending();
+ } else {
+ DiscardPending();
+ }
+ pending_handle_ = nullptr;
+ }
+ DispatchBufferedProtocolMessagesIfNecessary();
+ }
+
+ if (navigation_handle->HasCommitted())
+ service_worker_handler_->UpdateHosts();
+}
+
void RenderFrameDevToolsAgentHost::AboutToNavigateRenderFrame(
RenderFrameHost* old_host,
RenderFrameHost* new_host) {
+ if (browser_side_navigation)
+ return;
+
DCHECK(!pending_ || pending_->host() != old_host);
if (!current_ || current_->host() != old_host)
return;
@@ -483,6 +591,9 @@ void RenderFrameDevToolsAgentHost::AboutToNavigateRenderFrame(
void RenderFrameDevToolsAgentHost::RenderFrameHostChanged(
RenderFrameHost* old_host,
RenderFrameHost* new_host) {
+ if (browser_side_navigation)
+ return;
+
DCHECK(!pending_ || pending_->host() != old_host);
if (!current_ || current_->host() != old_host)
return;
@@ -497,7 +608,8 @@ void RenderFrameDevToolsAgentHost::RenderFrameHostChanged(
void RenderFrameDevToolsAgentHost::FrameDeleted(RenderFrameHost* rfh) {
if (pending_ && pending_->host() == rfh) {
- DiscardPending();
+ if (!browser_side_navigation)
+ DiscardPending();
return;
}
@@ -519,6 +631,9 @@ void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() {
HostClosed();
pending_.reset();
current_.reset();
+ frame_tree_node_ = nullptr;
+ pending_handle_ = nullptr;
+ WebContentsObserver::Observe(nullptr);
Release();
}
@@ -586,6 +701,7 @@ void RenderFrameDevToolsAgentHost::DidAttachInterstitialPage() {
// Pending set in AboutToNavigateRenderFrame turned out to be interstitial.
// Connect back to the real one.
DiscardPending();
+ pending_handle_ = nullptr;
}
void RenderFrameDevToolsAgentHost::DidDetachInterstitialPage() {
@@ -597,6 +713,8 @@ void RenderFrameDevToolsAgentHost::DidCommitProvisionalLoadForFrame(
RenderFrameHost* render_frame_host,
const GURL& url,
ui::PageTransition transition_type) {
+ if (browser_side_navigation)
+ return;
if (pending_ && pending_->host() == render_frame_host)
CommitPending();
service_worker_handler_->UpdateHosts();
@@ -608,10 +726,24 @@ void RenderFrameDevToolsAgentHost::DidFailProvisionalLoad(
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) {
+ if (browser_side_navigation)
+ return;
if (pending_ && pending_->host() == render_frame_host)
DiscardPending();
}
+void RenderFrameDevToolsAgentHost::
+ DispatchBufferedProtocolMessagesIfNecessary() {
+ if (in_navigation_ == 0 && in_navigation_protocol_message_buffer_.size()) {
+ DCHECK(current_);
+ for (const auto& pair : in_navigation_protocol_message_buffer_) {
+ current_->DispatchProtocolMessage(pair.second.first, pair.first,
+ pair.second.second);
+ }
+ in_navigation_protocol_message_buffer_.clear();
+ }
+}
+
void RenderFrameDevToolsAgentHost::UpdateProtocolHandlers(
RenderFrameHostImpl* host) {
dom_handler_->SetRenderFrameHost(host);
@@ -632,8 +764,12 @@ void RenderFrameDevToolsAgentHost::DisconnectWebContents() {
if (pending_)
DiscardPending();
UpdateProtocolHandlers(nullptr);
- disconnected_ = current_.Pass();
+ disconnected_ = std::move(current_);
disconnected_->Detach();
+ frame_tree_node_ = nullptr;
+ in_navigation_protocol_message_buffer_.clear();
+ in_navigation_ = 0;
+ pending_handle_ = nullptr;
WebContentsObserver::Observe(nullptr);
}
@@ -643,7 +779,8 @@ void RenderFrameDevToolsAgentHost::ConnectWebContents(WebContents* wc) {
RenderFrameHostImpl* host =
static_cast<RenderFrameHostImpl*>(wc->GetMainFrame());
DCHECK(host);
- current_ = disconnected_.Pass();
+ frame_tree_node_ = host->frame_tree_node();
+ current_ = std::move(disconnected_);
SetPending(host);
CommitPending();
WebContentsObserver::Observe(WebContents::FromRenderFrameHost(host));
@@ -729,4 +866,11 @@ bool RenderFrameDevToolsAgentHost::IsChildFrame() {
return current_ && current_->host()->GetParent();
}
+bool RenderFrameDevToolsAgentHost::MatchesMyTreeNode(
+ NavigationHandle* navigation_handle) {
+ return frame_tree_node_ ==
+ static_cast<NavigationHandleImpl*>(navigation_handle)
+ ->frame_tree_node();
+}
+
} // namespace content
diff --git a/chromium/content/browser/devtools/render_frame_devtools_agent_host.h b/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
index bc4b436b9fe..68409344de8 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -7,9 +7,10 @@
#include <map>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/web_contents_observer.h"
@@ -23,6 +24,8 @@ namespace content {
class BrowserContext;
class DevToolsFrameTraceRecorder;
class DevToolsProtocolHandler;
+class FrameTreeNode;
+class NavigationHandle;
class RenderFrameHostImpl;
#if defined(OS_ANDROID)
@@ -37,7 +40,6 @@ namespace inspector { class InspectorHandler; }
namespace io { class IOHandler; }
namespace network { class NetworkHandler; }
namespace page { class PageHandler; }
-namespace power { class PowerHandler; }
namespace security { class SecurityHandler; }
namespace service_worker { class ServiceWorkerHandler; }
namespace tracing { class TracingHandler; }
@@ -51,6 +53,8 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
static void OnCancelPendingNavigation(RenderFrameHost* pending,
RenderFrameHost* current);
+ static void OnBeforeNavigation(RenderFrameHost* current,
+ RenderFrameHost* pending);
void SynchronousSwapCompositorFrame(
const cc::CompositorFrameMetadata& frame_metadata);
@@ -86,8 +90,9 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void InspectElement(int x, int y) override;
// WebContentsObserver overrides.
- void AboutToNavigateRenderFrame(RenderFrameHost* old_host,
- RenderFrameHost* new_host) override;
+ void DidStartNavigation(NavigationHandle* navigation_handle) override;
+ void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override;
+ void DidFinishNavigation(NavigationHandle* navigation_handle) override;
void RenderFrameHostChanged(RenderFrameHost* old_host,
RenderFrameHost* new_host) override;
void FrameDeleted(RenderFrameHost* rfh) override;
@@ -109,6 +114,11 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
const base::string16& error_description,
bool was_ignored_by_handler) override;
+ void AboutToNavigateRenderFrame(RenderFrameHost* old_host,
+ RenderFrameHost* new_host);
+
+ void DispatchBufferedProtocolMessagesIfNecessary();
+
void SetPending(RenderFrameHostImpl* host);
void CommitPending();
void DiscardPending();
@@ -123,10 +133,13 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void OnSwapCompositorFrame(const IPC::Message& message);
void DestroyOnRenderFrameGone();
+ bool MatchesMyTreeNode(NavigationHandle* navigation_handle);
+
class FrameHostHolder;
scoped_ptr<FrameHostHolder> current_;
scoped_ptr<FrameHostHolder> pending_;
+
// Stores per-host state between DisconnectWebContents and ConnectWebContents.
scoped_ptr<FrameHostHolder> disconnected_;
@@ -136,7 +149,6 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
scoped_ptr<devtools::io::IOHandler> io_handler_;
scoped_ptr<devtools::network::NetworkHandler> network_handler_;
scoped_ptr<devtools::page::PageHandler> page_handler_;
- scoped_ptr<devtools::power::PowerHandler> power_handler_;
scoped_ptr<devtools::security::SecurityHandler> security_handler_;
scoped_ptr<devtools::service_worker::ServiceWorkerHandler>
service_worker_handler_;
@@ -149,6 +161,22 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
scoped_ptr<DevToolsProtocolHandler> protocol_handler_;
bool current_frame_crashed_;
+ // PlzNavigate
+
+ // Handle that caused the setting of pending_.
+ NavigationHandle* pending_handle_;
+
+ // Navigation counter and queue for buffering protocol messages during a
+ // navigation.
+ int in_navigation_;
+
+ // <call_id> -> <session_id, message>
+ std::map<int, std::pair<int, std::string>>
+ in_navigation_protocol_message_buffer_;
+
+ // The FrameTreeNode associated with this agent.
+ FrameTreeNode* frame_tree_node_;
+
DISALLOW_COPY_AND_ASSIGN(RenderFrameDevToolsAgentHost);
};
diff --git a/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc b/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
index 5d65a22c698..3755d15c51e 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -21,7 +21,7 @@ void StatusNoOp(ServiceWorkerStatusCode status) {}
void TerminateServiceWorkerOnIO(
base::WeakPtr<ServiceWorkerContextCore> context_weak,
- int64 version_id) {
+ int64_t version_id) {
if (ServiceWorkerContextCore* context = context_weak.get()) {
if (ServiceWorkerVersion* version = context->GetLiveVersion(version_id))
version->StopWorker(base::Bind(&StatusNoOp));
@@ -30,7 +30,7 @@ void TerminateServiceWorkerOnIO(
void UnregisterServiceWorkerOnIO(
base::WeakPtr<ServiceWorkerContextCore> context_weak,
- int64 version_id) {
+ int64_t version_id) {
if (ServiceWorkerContextCore* context = context_weak.get()) {
if (ServiceWorkerVersion* version = context->GetLiveVersion(version_id)) {
version->StopWorker(base::Bind(&StatusNoOp));
@@ -42,7 +42,7 @@ void UnregisterServiceWorkerOnIO(
void SetDevToolsAttachedOnIO(
base::WeakPtr<ServiceWorkerContextCore> context_weak,
- int64 version_id,
+ int64_t version_id,
bool attached) {
if (ServiceWorkerContextCore* context = context_weak.get()) {
if (ServiceWorkerVersion* version = context->GetLiveVersion(version_id))
@@ -105,7 +105,7 @@ void ServiceWorkerDevToolsAgentHost::OnAttachedStateChanged(bool attached) {
attached));
}
-int64 ServiceWorkerDevToolsAgentHost::service_worker_version_id() const {
+int64_t ServiceWorkerDevToolsAgentHost::service_worker_version_id() const {
return service_worker_->version_id();
}
diff --git a/chromium/content/browser/devtools/service_worker_devtools_agent_host.h b/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
index 04857f81c55..89b48b13b1f 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_SERVICE_WORKER_DEVTOOLS_AGENT_HOST_H_
#define CONTENT_BROWSER_DEVTOOLS_SERVICE_WORKER_DEVTOOLS_AGENT_HOST_H_
+#include <stdint.h>
+
#include <map>
+#include "base/macros.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/devtools/service_worker_devtools_manager.h"
#include "content/browser/devtools/worker_devtools_agent_host.h"
@@ -36,7 +39,7 @@ class ServiceWorkerDevToolsAgentHost : public WorkerDevToolsAgentHost {
// WorkerDevToolsAgentHost overrides.
void OnAttachedStateChanged(bool attached) override;
- int64 service_worker_version_id() const;
+ int64_t service_worker_version_id() const;
bool Matches(const ServiceWorkerIdentifier& other);
diff --git a/chromium/content/browser/devtools/service_worker_devtools_manager.cc b/chromium/content/browser/devtools/service_worker_devtools_manager.cc
index 025203929b8..b94f1a9e3c2 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_manager.cc
+++ b/chromium/content/browser/devtools/service_worker_devtools_manager.cc
@@ -15,13 +15,12 @@ namespace content {
ServiceWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier(
const ServiceWorkerContextCore* context,
base::WeakPtr<ServiceWorkerContextCore> context_weak,
- int64 version_id,
+ int64_t version_id,
const GURL& url)
: context_(context),
context_weak_(context_weak),
version_id_(version_id),
- url_(url) {
-}
+ url_(url) {}
ServiceWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier(
const ServiceWorkerIdentifier& other)
@@ -107,7 +106,8 @@ void ServiceWorkerDevToolsManager::WorkerReadyForInspection(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const WorkerId id(worker_process_id, worker_route_id);
AgentHostMap::iterator it = workers_.find(id);
- DCHECK(it != workers_.end());
+ if (it == workers_.end())
+ return;
scoped_refptr<ServiceWorkerDevToolsAgentHost> host = it->second;
host->WorkerReadyForInspection();
FOR_EACH_OBSERVER(Observer, observer_list_,
@@ -132,7 +132,8 @@ void ServiceWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const WorkerId id(worker_process_id, worker_route_id);
AgentHostMap::iterator it = workers_.find(id);
- DCHECK(it != workers_.end());
+ if (it == workers_.end())
+ return;
scoped_refptr<WorkerDevToolsAgentHost> agent_host(it->second);
agent_host->WorkerDestroyed();
FOR_EACH_OBSERVER(Observer, observer_list_, WorkerDestroyed(it->second));
@@ -170,8 +171,7 @@ ServiceWorkerDevToolsManager::FindExistingWorkerAgentHost(
const ServiceWorkerIdentifier& service_worker_id) {
AgentHostMap::iterator it = workers_.begin();
for (; it != workers_.end(); ++it) {
- if (static_cast<ServiceWorkerDevToolsAgentHost*>(
- it->second)->Matches(service_worker_id))
+ if (it->second->Matches(service_worker_id))
break;
}
return it;
diff --git a/chromium/content/browser/devtools/service_worker_devtools_manager.h b/chromium/content/browser/devtools/service_worker_devtools_manager.h
index 2c8e997ea9f..306edd7d3f5 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_manager.h
+++ b/chromium/content/browser/devtools/service_worker_devtools_manager.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_SERVICE_WORKER_DEVTOOLS_MANAGER_H_
#define CONTENT_BROWSER_DEVTOOLS_SERVICE_WORKER_DEVTOOLS_MANAGER_H_
+#include <stdint.h>
+
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
@@ -44,7 +46,7 @@ class CONTENT_EXPORT ServiceWorkerDevToolsManager {
ServiceWorkerIdentifier(
const ServiceWorkerContextCore* context,
base::WeakPtr<ServiceWorkerContextCore> context_weak,
- int64 version_id,
+ int64_t version_id,
const GURL& url);
ServiceWorkerIdentifier(const ServiceWorkerIdentifier& other);
~ServiceWorkerIdentifier();
@@ -55,13 +57,13 @@ class CONTENT_EXPORT ServiceWorkerDevToolsManager {
base::WeakPtr<ServiceWorkerContextCore> context_weak() const {
return context_weak_;
}
- int64 version_id() const { return version_id_; }
+ int64_t version_id() const { return version_id_; }
GURL url() const { return url_; }
private:
const ServiceWorkerContextCore* const context_;
const base::WeakPtr<ServiceWorkerContextCore> context_weak_;
- const int64 version_id_;
+ const int64_t version_id_;
const GURL url_;
};
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
index 21f8a38de4a..5ac6d6bae1f 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_SHARED_WORKER_DEVTOOLS_AGENT_HOST_H_
#define CONTENT_BROWSER_DEVTOOLS_SHARED_WORKER_DEVTOOLS_AGENT_HOST_H_
+#include "base/macros.h"
#include "content/browser/devtools/worker_devtools_agent_host.h"
namespace content {
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_manager.cc b/chromium/content/browser/devtools/shared_worker_devtools_manager.cc
index 328960498e8..31569a518b7 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_manager.cc
+++ b/chromium/content/browser/devtools/shared_worker_devtools_manager.cc
@@ -51,7 +51,7 @@ bool SharedWorkerDevToolsManager::WorkerCreated(
agent_host->WorkerRestarted(id);
workers_.erase(it);
workers_[id] = agent_host;
- return true;
+ return agent_host->IsAttached();
}
void SharedWorkerDevToolsManager::WorkerReadyForInspection(
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_manager.h b/chromium/content/browser/devtools/shared_worker_devtools_manager.h
index 22842f53038..40d1ffcfccd 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_manager.h
+++ b/chromium/content/browser/devtools/shared_worker_devtools_manager.h
@@ -7,8 +7,8 @@
#include <map>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/devtools_agent_host.h"
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc b/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
index b56c07bab3e..98a715220b0 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
+++ b/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/devtools/shared_worker_devtools_manager.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
@@ -97,12 +100,11 @@ class SharedWorkerDevToolsManagerTest : public testing::Test {
TEST_F(SharedWorkerDevToolsManagerTest, BasicTest) {
scoped_refptr<DevToolsAgentHostImpl> agent_host;
- SharedWorkerInstance instance1(GURL("http://example.com/w.js"),
- base::string16(),
- base::string16(),
- blink::WebContentSecurityPolicyTypeReport,
- browser_context_->GetResourceContext(),
- partition_id_);
+ SharedWorkerInstance instance1(
+ GURL("http://example.com/w.js"), base::string16(), base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(), partition_id_,
+ blink::WebSharedWorkerCreationContextTypeNonsecure);
agent_host = manager_->GetDevToolsAgentHostForWorker(1, 1);
EXPECT_FALSE(agent_host.get());
@@ -180,18 +182,16 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
scoped_refptr<DevToolsAgentHostImpl> agent_host1;
scoped_refptr<DevToolsAgentHostImpl> agent_host2;
- SharedWorkerInstance instance1(GURL("http://example.com/w1.js"),
- base::string16(),
- base::string16(),
- blink::WebContentSecurityPolicyTypeReport,
- browser_context_->GetResourceContext(),
- partition_id_);
- SharedWorkerInstance instance2(GURL("http://example.com/w2.js"),
- base::string16(),
- base::string16(),
- blink::WebContentSecurityPolicyTypeReport,
- browser_context_->GetResourceContext(),
- partition_id_);
+ SharedWorkerInstance instance1(
+ GURL("http://example.com/w1.js"), base::string16(), base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(), partition_id_,
+ blink::WebSharedWorkerCreationContextTypeNonsecure);
+ SharedWorkerInstance instance2(
+ GURL("http://example.com/w2.js"), base::string16(), base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(), partition_id_,
+ blink::WebSharedWorkerCreationContextTypeNonsecure);
// Created -> GetDevToolsAgentHost -> Register -> Started -> Destroyed
scoped_ptr<TestDevToolsClientHost> client_host1(new TestDevToolsClientHost());
@@ -265,12 +265,11 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
}
TEST_F(SharedWorkerDevToolsManagerTest, ReattachTest) {
- SharedWorkerInstance instance(GURL("http://example.com/w3.js"),
- base::string16(),
- base::string16(),
- blink::WebContentSecurityPolicyTypeReport,
- browser_context_->GetResourceContext(),
- partition_id_);
+ SharedWorkerInstance instance(
+ GURL("http://example.com/w3.js"), base::string16(), base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(), partition_id_,
+ blink::WebSharedWorkerCreationContextTypeNonsecure);
scoped_ptr<TestDevToolsClientHost> client_host(new TestDevToolsClientHost());
// Created -> GetDevToolsAgentHost -> Register -> Destroyed
manager_->WorkerCreated(3, 1, instance);
diff --git a/chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc b/chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc
index 1ec78c603c5..cfa2b4a1042 100644
--- a/chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc
+++ b/chromium/content/browser/devtools/site_per_process_devtools_browsertest.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 "build/build_config.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/site_per_process_browsertest.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -53,8 +53,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsBrowserTest,
MAYBE_CrossSiteIframeAgentHost) {
DevToolsAgentHost::List list;
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(test_server()->Start());
- GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
NavigateToURL(shell(), main_url);
// It is safe to obtain the root frame tree node here, as it doesn't change.
@@ -69,7 +68,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsBrowserTest,
// Load same-site page into iframe.
FrameTreeNode* child = root->child_at(0);
- GURL http_url(test_server()->GetURL("files/title1.html"));
+ GURL http_url(embedded_test_server()->GetURL("/title1.html"));
NavigateFrameToURL(child, http_url);
list = DevToolsAgentHost::GetOrCreateAll();
@@ -79,7 +78,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsBrowserTest,
// Load cross-site page into iframe.
GURL::Replacements replace_host;
- GURL cross_site_url(test_server()->GetURL("files/title2.html"));
+ GURL cross_site_url(embedded_test_server()->GetURL("/title2.html"));
replace_host.SetHostStr("foo.com");
cross_site_url = cross_site_url.ReplaceComponents(replace_host);
NavigateFrameToURL(root->child_at(0), cross_site_url);
@@ -108,4 +107,42 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsBrowserTest,
child_host = nullptr;
}
+IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsBrowserTest, AgentHostForFrames) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
+ NavigateToURL(shell(), main_url);
+
+ scoped_refptr<DevToolsAgentHost> page_agent =
+ DevToolsAgentHost::GetOrCreateFor(shell()->web_contents());
+
+ // It is safe to obtain the root frame tree node here, as it doesn't change.
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+
+ scoped_refptr<DevToolsAgentHost> main_frame_agent =
+ DevToolsAgentHost::GetOrCreateFor(root->current_frame_host());
+ EXPECT_EQ(page_agent.get(), main_frame_agent.get());
+
+ // Load same-site page into iframe.
+ FrameTreeNode* child = root->child_at(0);
+ GURL http_url(embedded_test_server()->GetURL("/title1.html"));
+ NavigateFrameToURL(child, http_url);
+
+ scoped_refptr<DevToolsAgentHost> child_frame_agent =
+ DevToolsAgentHost::GetOrCreateFor(child->current_frame_host());
+ EXPECT_EQ(page_agent.get(), child_frame_agent.get());
+
+ // Load cross-site page into iframe.
+ GURL::Replacements replace_host;
+ GURL cross_site_url(embedded_test_server()->GetURL("/title2.html"));
+ replace_host.SetHostStr("foo.com");
+ cross_site_url = cross_site_url.ReplaceComponents(replace_host);
+ NavigateFrameToURL(root->child_at(0), cross_site_url);
+
+ child_frame_agent =
+ DevToolsAgentHost::GetOrCreateFor(child->current_frame_host());
+ EXPECT_NE(page_agent.get(), child_frame_agent.get());
+}
+
} // namespace content
diff --git a/chromium/content/browser/devtools/worker_devtools_agent_host.cc b/chromium/content/browser/devtools/worker_devtools_agent_host.cc
index 32cd668e3d6..d7be60a80c5 100644
--- a/chromium/content/browser/devtools/worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/worker_devtools_agent_host.cc
@@ -21,7 +21,8 @@ void WorkerDevToolsAgentHost::Attach() {
AttachToWorker();
}
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
- host->Send(new DevToolsAgentMsg_Attach(worker_id_.second, GetId()));
+ host->Send(
+ new DevToolsAgentMsg_Attach(worker_id_.second, GetId(), session_id()));
OnAttachedStateChanged(true);
DevToolsAgentHostImpl::NotifyCallbacks(this, true);
}
@@ -45,12 +46,12 @@ bool WorkerDevToolsAgentHost::DispatchProtocolMessage(
return true;
int call_id;
- if (protocol_handler_->HandleOptionalMessage(message, &call_id))
+ if (protocol_handler_->HandleOptionalMessage(session_id(), message, &call_id))
return true;
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
host->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
- worker_id_.second, message));
+ worker_id_.second, session_id(), message));
}
return true;
}
@@ -83,7 +84,8 @@ void WorkerDevToolsAgentHost::WorkerReadyForInspection() {
AttachToWorker();
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
host->Send(new DevToolsAgentMsg_Reattach(
- worker_id_.second, GetId(), chunk_processor_.state_cookie()));
+ worker_id_.second, GetId(), session_id(),
+ chunk_processor_.state_cookie()));
}
OnAttachedStateChanged(true);
}
@@ -101,10 +103,7 @@ void WorkerDevToolsAgentHost::WorkerDestroyed() {
if (state_ == WORKER_INSPECTED) {
DCHECK(IsAttached());
// Client host is debugging this worker agent host.
- base::Callback<void(const std::string&)> raw_message_callback(
- base::Bind(&WorkerDevToolsAgentHost::SendMessageToClient,
- base::Unretained(this)));
- devtools::inspector::Client inspector(raw_message_callback);
+ devtools::inspector::Client inspector(this);
inspector.TargetCrashed(
devtools::inspector::TargetCrashedParams::Create());
DetachFromWorker();
@@ -117,15 +116,10 @@ bool WorkerDevToolsAgentHost::IsTerminated() {
return state_ == WORKER_TERMINATED;
}
-WorkerDevToolsAgentHost::WorkerDevToolsAgentHost(
- WorkerId worker_id)
- : protocol_handler_(new DevToolsProtocolHandler(
- this,
- base::Bind(&WorkerDevToolsAgentHost::SendMessageToClient,
- base::Unretained(this)))),
- chunk_processor_(
- base::Bind(&WorkerDevToolsAgentHost::SendMessageToClient,
- base::Unretained(this))),
+WorkerDevToolsAgentHost::WorkerDevToolsAgentHost(WorkerId worker_id)
+ : protocol_handler_(new DevToolsProtocolHandler(this)),
+ chunk_processor_(base::Bind(&WorkerDevToolsAgentHost::SendMessageToClient,
+ base::Unretained(this))),
state_(WORKER_UNINSPECTED),
worker_id_(worker_id) {
WorkerCreated();
diff --git a/chromium/content/browser/devtools/worker_devtools_agent_host.h b/chromium/content/browser/devtools/worker_devtools_agent_host.h
index 668f0296df2..4f21257a129 100644
--- a/chromium/content/browser/devtools/worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/worker_devtools_agent_host.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_WORKER_DEVTOOLS_AGENT_HOST_H_
#define CONTENT_BROWSER_DEVTOOLS_WORKER_DEVTOOLS_AGENT_HOST_H_
+#include "base/macros.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "ipc/ipc_listener.h"
diff --git a/chromium/content/browser/dom_storage/dom_storage_area.cc b/chromium/content/browser/dom_storage/dom_storage_area.cc
index e76f5c94d5e..50ef7ff05f9 100644
--- a/chromium/content/browser/dom_storage/dom_storage_area.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_area.cc
@@ -118,7 +118,7 @@ DOMStorageArea::DOMStorageArea(const GURL& origin,
}
}
-DOMStorageArea::DOMStorageArea(int64 namespace_id,
+DOMStorageArea::DOMStorageArea(int64_t namespace_id,
const std::string& persistent_namespace_id,
const GURL& origin,
SessionStorageDatabase* session_storage_backing,
@@ -247,7 +247,7 @@ void DOMStorageArea::FastClear() {
}
DOMStorageArea* DOMStorageArea::ShallowCopy(
- int64 destination_namespace_id,
+ int64_t destination_namespace_id,
const std::string& destination_persistent_namespace_id) {
DCHECK_NE(kLocalStorageNamespaceId, namespace_id_);
DCHECK_NE(kLocalStorageNamespaceId, destination_namespace_id);
diff --git a/chromium/content/browser/dom_storage/dom_storage_area.h b/chromium/content/browser/dom_storage/dom_storage_area.h
index dd0df52bdc2..50082fdebc0 100644
--- a/chromium/content/browser/dom_storage/dom_storage_area.h
+++ b/chromium/content/browser/dom_storage/dom_storage_area.h
@@ -5,10 +5,14 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_
#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/nullable_string16.h"
@@ -47,14 +51,14 @@ class CONTENT_EXPORT DOMStorageArea
DOMStorageTaskRunner* task_runner);
// Session storage. Backed on disk if |session_storage_backing| is not NULL.
- DOMStorageArea(int64 namespace_id,
+ DOMStorageArea(int64_t namespace_id,
const std::string& persistent_namespace_id,
const GURL& origin,
SessionStorageDatabase* session_storage_backing,
DOMStorageTaskRunner* task_runner);
const GURL& origin() const { return origin_; }
- int64 namespace_id() const { return namespace_id_; }
+ int64_t namespace_id() const { return namespace_id_; }
// Writes a copy of the current set of values in the area to the |map|.
void ExtractValues(DOMStorageValuesMap* map);
@@ -69,7 +73,7 @@ class CONTENT_EXPORT DOMStorageArea
void FastClear();
DOMStorageArea* ShallowCopy(
- int64 destination_namespace_id,
+ int64_t destination_namespace_id,
const std::string& destination_persistent_namespace_id);
bool HasUncommittedChanges() const;
@@ -161,7 +165,7 @@ class CONTENT_EXPORT DOMStorageArea
static bool s_aggressive_flushing_enabled_;
- int64 namespace_id_;
+ int64_t namespace_id_;
std::string persistent_namespace_id_;
GURL origin_;
base::FilePath directory_;
diff --git a/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc b/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
index ba91f2697dd..e4de22ee206 100644
--- a/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
@@ -2,10 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
@@ -139,7 +143,7 @@ TEST_F(DOMStorageAreaTest, DOMStorageAreaBasics) {
}
TEST_F(DOMStorageAreaTest, BackingDatabaseOpened) {
- const int64 kSessionStorageNamespaceId = kLocalStorageNamespaceId + 1;
+ const int64_t kSessionStorageNamespaceId = kLocalStorageNamespaceId + 1;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const base::FilePath kExpectedOriginFilePath = temp_dir.path().Append(
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_impl.cc b/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
index cef7b573dd0..7fee39c34ab 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
@@ -4,6 +4,7 @@
#include "content/browser/dom_storage/dom_storage_context_impl.h"
+#include <stddef.h>
#include <stdlib.h>
#include "base/bind.h"
@@ -68,7 +69,7 @@ DOMStorageContextImpl::~DOMStorageContextImpl() {
}
DOMStorageNamespace* DOMStorageContextImpl::GetStorageNamespace(
- int64 namespace_id) {
+ int64_t namespace_id) {
if (is_shutdown_)
return NULL;
StorageNamespaceMap::iterator found = namespaces_.find(namespace_id);
@@ -148,13 +149,13 @@ void DOMStorageContextImpl::DeleteSessionStorage(
const SessionStorageUsageInfo& usage_info) {
DCHECK(!is_shutdown_);
DOMStorageNamespace* dom_storage_namespace = NULL;
- std::map<std::string, int64>::const_iterator it =
+ std::map<std::string, int64_t>::const_iterator it =
persistent_namespace_id_to_namespace_id_.find(
usage_info.persistent_namespace_id);
if (it != persistent_namespace_id_to_namespace_id_.end()) {
dom_storage_namespace = GetStorageNamespace(it->second);
} else {
- int64 namespace_id = AllocateSessionId();
+ int64_t namespace_id = AllocateSessionId();
CreateSessionNamespace(namespace_id, usage_info.persistent_namespace_id);
dom_storage_namespace = GetStorageNamespace(namespace_id);
}
@@ -239,7 +240,7 @@ void DOMStorageContextImpl::NotifyAreaCleared(
OnDOMStorageAreaCleared(area, page_url));
}
-int64 DOMStorageContextImpl::AllocateSessionId() {
+int64_t DOMStorageContextImpl::AllocateSessionId() {
return session_id_sequence_.GetNext() + session_id_offset_;
}
@@ -250,7 +251,7 @@ std::string DOMStorageContextImpl::AllocatePersistentSessionId() {
}
void DOMStorageContextImpl::CreateSessionNamespace(
- int64 namespace_id,
+ int64_t namespace_id,
const std::string& persistent_namespace_id) {
if (is_shutdown_)
return;
@@ -263,8 +264,8 @@ void DOMStorageContextImpl::CreateSessionNamespace(
namespace_id;
}
-void DOMStorageContextImpl::DeleteSessionNamespace(
- int64 namespace_id, bool should_persist_data) {
+void DOMStorageContextImpl::DeleteSessionNamespace(int64_t namespace_id,
+ bool should_persist_data) {
DCHECK_NE(kLocalStorageNamespaceId, namespace_id);
StorageNamespaceMap::const_iterator it = namespaces_.find(namespace_id);
if (it == namespaces_.end())
@@ -293,7 +294,8 @@ void DOMStorageContextImpl::DeleteSessionNamespace(
}
void DOMStorageContextImpl::CloneSessionNamespace(
- int64 existing_id, int64 new_id,
+ int64_t existing_id,
+ int64_t new_id,
const std::string& new_persistent_id) {
if (is_shutdown_)
return;
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_impl.h b/chromium/content/browser/dom_storage/dom_storage_context_impl.h
index c2b72bed536..e38e4387c13 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_impl.h
+++ b/chromium/content/browser/dom_storage/dom_storage_context_impl.h
@@ -5,13 +5,14 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_CONTEXT_IMPL_H_
#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_CONTEXT_IMPL_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/atomic_sequence_num.h"
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
@@ -106,7 +107,7 @@ class CONTENT_EXPORT DOMStorageContextImpl
}
DOMStorageTaskRunner* task_runner() const { return task_runner_.get(); }
- DOMStorageNamespace* GetStorageNamespace(int64 namespace_id);
+ DOMStorageNamespace* GetStorageNamespace(int64_t namespace_id);
void GetLocalStorageUsage(std::vector<LocalStorageUsageInfo>* infos,
bool include_file_info);
@@ -152,14 +153,15 @@ class CONTENT_EXPORT DOMStorageContextImpl
const GURL& page_url);
// May be called on any thread.
- int64 AllocateSessionId();
+ int64_t AllocateSessionId();
std::string AllocatePersistentSessionId();
// Must be called on the background thread.
- void CreateSessionNamespace(int64 namespace_id,
+ void CreateSessionNamespace(int64_t namespace_id,
const std::string& persistent_namespace_id);
- void DeleteSessionNamespace(int64 namespace_id, bool should_persist_data);
- void CloneSessionNamespace(int64 existing_id, int64 new_id,
+ void DeleteSessionNamespace(int64_t namespace_id, bool should_persist_data);
+ void CloneSessionNamespace(int64_t existing_id,
+ int64_t new_id,
const std::string& new_persistent_id);
// Starts backing sessionStorage on disk. This function must be called right
@@ -175,7 +177,7 @@ class CONTENT_EXPORT DOMStorageContextImpl
friend class DOMStorageContextImplTest;
FRIEND_TEST_ALL_PREFIXES(DOMStorageContextImplTest, Basics);
friend class base::RefCountedThreadSafe<DOMStorageContextImpl>;
- typedef std::map<int64, scoped_refptr<DOMStorageNamespace> >
+ typedef std::map<int64_t, scoped_refptr<DOMStorageNamespace>>
StorageNamespaceMap;
~DOMStorageContextImpl();
@@ -229,7 +231,7 @@ class CONTENT_EXPORT DOMStorageContextImpl
// Mapping between persistent namespace IDs and namespace IDs for
// sessionStorage.
- std::map<std::string, int64> persistent_namespace_id_to_namespace_id_;
+ std::map<std::string, int64_t> persistent_namespace_id_to_namespace_id_;
};
} // namespace content
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc b/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
index fe99fbfaf4e..5173ac17c30 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
@@ -5,6 +5,7 @@
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
index 6ef2abf84f0..53033447ca1 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/dom_storage_context.h"
diff --git a/chromium/content/browser/dom_storage/dom_storage_database.cc b/chromium/content/browser/dom_storage/dom_storage_database.cc
index 1e0166f68f8..b19dffa6c2f 100644
--- a/chromium/content/browser/dom_storage/dom_storage_database.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_database.cc
@@ -151,6 +151,10 @@ bool DOMStorageDatabase::LazyOpen(bool create_if_needed) {
db_.reset(new sql::Connection());
db_->set_histogram_tag("DOMStorageDatabase");
+ // TODO(shess): The current mitigation for http://crbug.com/537742 stores
+ // state in the meta table, which this database does not use.
+ db_->set_mmap_disabled();
+
if (file_path_.empty()) {
// This code path should only be triggered by unit tests.
if (!db_->OpenInMemory()) {
diff --git a/chromium/content/browser/dom_storage/dom_storage_host.h b/chromium/content/browser/dom_storage/dom_storage_host.h
index a6289076f87..9b79406cbd2 100644
--- a/chromium/content/browser/dom_storage/dom_storage_host.h
+++ b/chromium/content/browser/dom_storage/dom_storage_host.h
@@ -7,6 +7,7 @@
#include <map>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/nullable_string16.h"
#include "base/strings/string16.h"
diff --git a/chromium/content/browser/dom_storage/dom_storage_message_filter.cc b/chromium/content/browser/dom_storage/dom_storage_message_filter.cc
index e792c2921ff..6c591754085 100644
--- a/chromium/content/browser/dom_storage/dom_storage_message_filter.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_message_filter.cc
@@ -88,7 +88,7 @@ bool DOMStorageMessageFilter::OnMessageReceived(const IPC::Message& message) {
}
void DOMStorageMessageFilter::OnOpenStorageArea(int connection_id,
- int64 namespace_id,
+ int64_t namespace_id,
const GURL& origin) {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
if (!host_->OpenStorageArea(connection_id, namespace_id, origin)) {
diff --git a/chromium/content/browser/dom_storage/dom_storage_message_filter.h b/chromium/content/browser/dom_storage/dom_storage_message_filter.h
index 8ac75233007..791ddf16344 100644
--- a/chromium/content/browser/dom_storage/dom_storage_message_filter.h
+++ b/chromium/content/browser/dom_storage/dom_storage_message_filter.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_MESSAGE_FILTER_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
@@ -46,7 +49,8 @@ class DOMStorageMessageFilter
bool OnMessageReceived(const IPC::Message& message) override;
// Message Handlers.
- void OnOpenStorageArea(int connection_id, int64 namespace_id,
+ void OnOpenStorageArea(int connection_id,
+ int64_t namespace_id,
const GURL& origin);
void OnCloseStorageArea(int connection_id);
void OnLoadStorageArea(int connection_id, DOMStorageValuesMap* map);
diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.cc b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
index f554ac58814..25e44e53e3f 100644
--- a/chromium/content/browser/dom_storage/dom_storage_namespace.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
@@ -4,7 +4,6 @@
#include "content/browser/dom_storage/dom_storage_namespace.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
@@ -24,7 +23,7 @@ DOMStorageNamespace::DOMStorageNamespace(
}
DOMStorageNamespace::DOMStorageNamespace(
- int64 namespace_id,
+ int64_t namespace_id,
const std::string& persistent_namespace_id,
SessionStorageDatabase* session_storage_database,
DOMStorageTaskRunner* task_runner)
@@ -72,7 +71,7 @@ DOMStorageArea* DOMStorageNamespace::GetOpenStorageArea(const GURL& origin) {
}
DOMStorageNamespace* DOMStorageNamespace::Clone(
- int64 clone_namespace_id,
+ int64_t clone_namespace_id,
const std::string& clone_persistent_namespace_id) {
DCHECK_NE(kLocalStorageNamespaceId, namespace_id_);
DCHECK_NE(kLocalStorageNamespaceId, clone_namespace_id);
diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.h b/chromium/content/browser/dom_storage/dom_storage_namespace.h
index 48f449a615d..a9f65693fe8 100644
--- a/chromium/content/browser/dom_storage/dom_storage_namespace.h
+++ b/chromium/content/browser/dom_storage/dom_storage_namespace.h
@@ -5,10 +5,11 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
+#include <stdint.h>
+
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
@@ -42,12 +43,12 @@ class CONTENT_EXPORT DOMStorageNamespace
// Constructor for a SessionStorage namespace with a non-zero id and an
// optional backing on disk via |session_storage_database| (may be NULL).
- DOMStorageNamespace(int64 namespace_id,
+ DOMStorageNamespace(int64_t namespace_id,
const std::string& persistent_namespace_id,
SessionStorageDatabase* session_storage_database,
DOMStorageTaskRunner* task_runner);
- int64 namespace_id() const { return namespace_id_; }
+ int64_t namespace_id() const { return namespace_id_; }
const std::string& persistent_namespace_id() const {
return persistent_namespace_id_;
}
@@ -64,7 +65,7 @@ class CONTENT_EXPORT DOMStorageNamespace
// Creates a clone of |this| namespace including
// shallow copies of all contained areas.
// Should only be called for session storage namespaces.
- DOMStorageNamespace* Clone(int64 clone_namespace_id,
+ DOMStorageNamespace* Clone(int64_t clone_namespace_id,
const std::string& clone_persistent_namespace_id);
void DeleteLocalStorageOrigin(const GURL& origin);
@@ -94,7 +95,7 @@ class CONTENT_EXPORT DOMStorageNamespace
// Returns a pointer to the area holder in our map or NULL.
AreaHolder* GetAreaHolder(const GURL& origin);
- int64 namespace_id_;
+ int64_t namespace_id_;
std::string persistent_namespace_id_;
base::FilePath directory_;
AreaMap areas_;
diff --git a/chromium/content/browser/dom_storage/dom_storage_session.cc b/chromium/content/browser/dom_storage/dom_storage_session.cc
index 7706ec85064..338b6cc25c6 100644
--- a/chromium/content/browser/dom_storage/dom_storage_session.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_session.cc
@@ -54,8 +54,8 @@ DOMStorageSession* DOMStorageSession::Clone() {
// static
DOMStorageSession* DOMStorageSession::CloneFrom(DOMStorageContextImpl* context,
- int64 namepace_id_to_clone) {
- int64 clone_id = context->AllocateSessionId();
+ int64_t namepace_id_to_clone) {
+ int64_t clone_id = context->AllocateSessionId();
std::string persistent_clone_id = context->AllocatePersistentSessionId();
context->task_runner()->PostTask(
FROM_HERE,
@@ -65,7 +65,7 @@ DOMStorageSession* DOMStorageSession::CloneFrom(DOMStorageContextImpl* context,
}
DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context,
- int64 namespace_id,
+ int64_t namespace_id,
const std::string& persistent_namespace_id)
: context_(context),
namespace_id_(namespace_id),
diff --git a/chromium/content/browser/dom_storage/dom_storage_session.h b/chromium/content/browser/dom_storage/dom_storage_session.h
index 62c6d97252c..08e54f35c1b 100644
--- a/chromium/content/browser/dom_storage/dom_storage_session.h
+++ b/chromium/content/browser/dom_storage/dom_storage_session.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_SESSION_H_
#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_SESSION_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
@@ -30,7 +32,7 @@ class CONTENT_EXPORT DOMStorageSession
DOMStorageSession(DOMStorageContextImpl* context,
const std::string& persistent_namespace_id);
- int64 namespace_id() const { return namespace_id_; }
+ int64_t namespace_id() const { return namespace_id_; }
const std::string& persistent_namespace_id() const {
return persistent_namespace_id_;
}
@@ -42,18 +44,18 @@ class CONTENT_EXPORT DOMStorageSession
// Constructs a |DOMStorageSession| by cloning
// |namespace_id_to_clone|. Allocates new IDs for it.
static DOMStorageSession* CloneFrom(DOMStorageContextImpl* context,
- int64 namepace_id_to_clone);
+ int64_t namepace_id_to_clone);
private:
friend class base::RefCountedThreadSafe<DOMStorageSession>;
DOMStorageSession(DOMStorageContextImpl* context,
- int64 namespace_id,
+ int64_t namespace_id,
const std::string& persistent_namespace_id);
~DOMStorageSession();
scoped_refptr<DOMStorageContextImpl> context_;
- int64 namespace_id_;
+ int64_t namespace_id_;
std::string persistent_namespace_id_;
bool should_persist_;
diff --git a/chromium/content/browser/dom_storage/local_storage_database_adapter.h b/chromium/content/browser/dom_storage/local_storage_database_adapter.h
index fca55d0c4e0..a8db4a3d530 100644
--- a/chromium/content/browser/dom_storage/local_storage_database_adapter.h
+++ b/chromium/content/browser/dom_storage/local_storage_database_adapter.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_DOM_STORAGE_LOCAL_STORAGE_DATABASE_ADAPTER_H_
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/dom_storage/dom_storage_database_adapter.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/dom_storage/session_storage_database.cc b/chromium/content/browser/dom_storage/session_storage_database.cc
index d0ab442238b..ec246164e34 100644
--- a/chromium/content/browser/dom_storage/session_storage_database.cc
+++ b/chromium/content/browser/dom_storage/session_storage_database.cc
@@ -4,6 +4,8 @@
#include "content/browser/dom_storage/session_storage_database.h"
+#include <stddef.h>
+
#include <vector>
#include "base/files/file_util.h"
@@ -148,7 +150,7 @@ bool SessionStorageDatabase::CommitAreaChanges(
&exists, &map_id))
return false;
if (exists) {
- int64 ref_count;
+ int64_t ref_count;
if (!GetMapRefCount(map_id, &ref_count))
return false;
if (ref_count > 1) {
@@ -535,7 +537,7 @@ bool SessionStorageDatabase::CreateMapForArea(const std::string& namespace_id,
leveldb::Status s = db_->Get(leveldb::ReadOptions(), next_map_id_key, map_id);
if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
return false;
- int64 next_map_id = 0;
+ int64_t next_map_id = 0;
if (s.IsNotFound()) {
*map_id = "0";
} else {
@@ -610,7 +612,7 @@ void SessionStorageDatabase::WriteValuesToMap(const std::string& map_id,
}
bool SessionStorageDatabase::GetMapRefCount(const std::string& map_id,
- int64* ref_count) {
+ int64_t* ref_count) {
std::string ref_count_string;
leveldb::Status s = db_->Get(leveldb::ReadOptions(),
MapRefCountKey(map_id), &ref_count_string);
@@ -623,7 +625,7 @@ bool SessionStorageDatabase::GetMapRefCount(const std::string& map_id,
bool SessionStorageDatabase::IncreaseMapRefCount(const std::string& map_id,
leveldb::WriteBatch* batch) {
// Increase the ref count for the map.
- int64 old_ref_count;
+ int64_t old_ref_count;
if (!GetMapRefCount(map_id, &old_ref_count))
return false;
batch->Put(MapRefCountKey(map_id), base::Int64ToString(++old_ref_count));
@@ -634,7 +636,7 @@ bool SessionStorageDatabase::DecreaseMapRefCount(const std::string& map_id,
int decrease,
leveldb::WriteBatch* batch) {
// Decrease the ref count for the map.
- int64 ref_count;
+ int64_t ref_count;
if (!GetMapRefCount(map_id, &ref_count))
return false;
if (!ConsistencyCheck(decrease <= ref_count))
diff --git a/chromium/content/browser/dom_storage/session_storage_database.h b/chromium/content/browser/dom_storage/session_storage_database.h
index 4260e4adb56..d4e80e4353e 100644
--- a/chromium/content/browser/dom_storage/session_storage_database.h
+++ b/chromium/content/browser/dom_storage/session_storage_database.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_DATABASE_H_
#define CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_DATABASE_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
@@ -158,7 +161,7 @@ class CONTENT_EXPORT SessionStorageDatabase :
const DOMStorageValuesMap& values,
leveldb::WriteBatch* batch);
- bool GetMapRefCount(const std::string& map_id, int64* ref_count);
+ bool GetMapRefCount(const std::string& map_id, int64_t* ref_count);
bool IncreaseMapRefCount(const std::string& map_id,
leveldb::WriteBatch* batch);
// Decreases the ref count of a map by |decrease|. If the ref count goes to 0,
diff --git a/chromium/content/browser/dom_storage/session_storage_database_adapter.h b/chromium/content/browser/dom_storage/session_storage_database_adapter.h
index 1b5a91dd7da..de929842cce 100644
--- a/chromium/content/browser/dom_storage/session_storage_database_adapter.h
+++ b/chromium/content/browser/dom_storage/session_storage_database_adapter.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_DATABASE_ADAPTER_H_
#define CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_DATABASE_ADAPTER_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/dom_storage/dom_storage_database_adapter.h"
#include "url/gurl.h"
diff --git a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
index f8397ace3ea..8ca4b083597 100644
--- a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
@@ -5,6 +5,9 @@
#include "content/browser/dom_storage/session_storage_database.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <algorithm>
#include <map>
#include <string>
@@ -12,6 +15,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/dom_storage/dom_storage_types.h"
@@ -37,10 +41,8 @@ class SessionStorageDatabaseTest : public testing::Test {
std::string* namespace_id);
static bool IsNamespaceOriginKey(const std::string& key,
std::string* namespace_id);
- static bool IsMapRefCountKey(const std::string& key,
- int64* map_id);
- static bool IsMapValueKey(const std::string& key,
- int64* map_id);
+ static bool IsMapRefCountKey(const std::string& key, int64_t* map_id);
+ static bool IsMapValueKey(const std::string& key, int64_t* map_id);
void ResetDatabase();
void ReadData(DataMap* data) const;
void CheckDatabaseConsistency() const;
@@ -58,7 +60,7 @@ class SessionStorageDatabaseTest : public testing::Test {
const std::set<GURL>& expected_origins) const;
std::string GetMapForArea(const std::string& namespace_id,
const GURL& origin) const;
- int64 GetMapRefCount(const std::string& map_id) const;
+ int64_t GetMapRefCount(const std::string& map_id) const;
base::ScopedTempDir temp_dir_;
scoped_refptr<SessionStorageDatabase> db_;
@@ -148,7 +150,7 @@ bool SessionStorageDatabaseTest::IsNamespaceOriginKey(
// static
bool SessionStorageDatabaseTest::IsMapRefCountKey(const std::string& key,
- int64* map_id) {
+ int64_t* map_id) {
std::string map_prefix = "map-";
if (key.find(map_prefix) != 0)
return false;
@@ -165,7 +167,7 @@ bool SessionStorageDatabaseTest::IsMapRefCountKey(const std::string& key,
// static
bool SessionStorageDatabaseTest::IsMapValueKey(const std::string& key,
- int64* map_id) {
+ int64_t* map_id) {
std::string map_prefix = "map-";
if (key.find(map_prefix) != 0)
return false;
@@ -214,8 +216,8 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
// Iterate the "namespace-" keys.
std::set<std::string> found_namespace_ids;
std::set<std::string> namespaces_with_areas;
- std::map<int64, int64> expected_map_refcounts;
- int64 max_map_id = -1;
+ std::map<int64_t, int64_t> expected_map_refcounts;
+ int64_t max_map_id = -1;
for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) {
std::string namespace_id;
@@ -229,7 +231,7 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
ASSERT_TRUE(found_namespace_ids.find(namespace_id) !=
found_namespace_ids.end());
namespaces_with_areas.insert(namespace_id);
- int64 map_id;
+ int64_t map_id;
bool conversion_ok = base::StringToInt64(it->second, &map_id);
ASSERT_TRUE(conversion_ok);
ASSERT_GE(map_id, 0);
@@ -245,7 +247,7 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
if (max_map_id != -1) {
// The database contains maps.
ASSERT_TRUE(data.find(next_map_id_key) != data.end());
- int64 next_map_id;
+ int64_t next_map_id;
bool conversion_ok =
base::StringToInt64(data[next_map_id_key], &next_map_id);
ASSERT_TRUE(conversion_ok);
@@ -253,11 +255,11 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
}
// Iterate the "map-" keys.
- std::set<int64> found_map_ids;
+ std::set<int64_t> found_map_ids;
for (DataMap::const_iterator it = data.begin(); it != data.end(); ++it) {
- int64 map_id;
+ int64_t map_id;
if (IsMapRefCountKey(it->first, &map_id)) {
- int64 ref_count;
+ int64_t ref_count;
bool conversion_ok = base::StringToInt64(it->second, &ref_count);
ASSERT_TRUE(conversion_ok);
// Check that the map is not stale.
@@ -299,7 +301,7 @@ void SessionStorageDatabaseTest::DumpData() const {
scoped_ptr<leveldb::Iterator> it(
db_->db_->NewIterator(leveldb::ReadOptions()));
for (it->SeekToFirst(); it->Valid(); it->Next()) {
- int64 dummy_map_id;
+ int64_t dummy_map_id;
if (IsMapValueKey(it->key().ToString(), &dummy_map_id)) {
// Convert the value back to base::string16.
base::string16 value;
@@ -374,9 +376,9 @@ std::string SessionStorageDatabaseTest::GetMapForArea(
return map_id;
}
-int64 SessionStorageDatabaseTest::GetMapRefCount(
+int64_t SessionStorageDatabaseTest::GetMapRefCount(
const std::string& map_id) const {
- int64 ref_count;
+ int64_t ref_count;
EXPECT_TRUE(db_->GetMapRefCount(map_id, &ref_count));
return ref_count;
}
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc b/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
index a1f7f2dd7f7..0811fab4da8 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
@@ -15,17 +15,17 @@ SessionStorageNamespaceImpl::SessionStorageNamespaceImpl(
}
SessionStorageNamespaceImpl::SessionStorageNamespaceImpl(
- DOMStorageContextWrapper* context, int64 namepace_id_to_clone)
+ DOMStorageContextWrapper* context,
+ int64_t namepace_id_to_clone)
: session_(DOMStorageSession::CloneFrom(context->context(),
- namepace_id_to_clone)) {
-}
+ namepace_id_to_clone)) {}
SessionStorageNamespaceImpl::SessionStorageNamespaceImpl(
DOMStorageContextWrapper* context, const std::string& persistent_id)
: session_(new DOMStorageSession(context->context(), persistent_id)) {
}
-int64 SessionStorageNamespaceImpl::id() const {
+int64_t SessionStorageNamespaceImpl::id() const {
return session_->namespace_id();
}
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl.h b/chromium/content/browser/dom_storage/session_storage_namespace_impl.h
index 83a9866241e..4823efb6c06 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl.h
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_NAMESPACE_IMPL_H_
#define CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_NAMESPACE_IMPL_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/session_storage_namespace.h"
@@ -27,7 +29,7 @@ class SessionStorageNamespaceImpl
// Constructs a |SessionStorageNamespaceImpl| by cloning
// |namespace_to_clone|. Allocates new IDs for it.
SessionStorageNamespaceImpl(DOMStorageContextWrapper* context,
- int64 namepace_id_to_clone);
+ int64_t namepace_id_to_clone);
// Constructs a |SessionStorageNamespaceImpl| and assigns |persistent_id|
// to it. Allocates a new non-persistent ID.
@@ -35,7 +37,7 @@ class SessionStorageNamespaceImpl
const std::string& persistent_id);
// SessionStorageNamespace implementation.
- int64 id() const override;
+ int64_t id() const override;
const std::string& persistent_id() const override;
void SetShouldPersist(bool should_persist) override;
bool should_persist() const override;
diff --git a/chromium/content/browser/download/OWNERS b/chromium/content/browser/download/OWNERS
index 7b50c05bfba..9e1fc0676f3 100644
--- a/chromium/content/browser/download/OWNERS
+++ b/chromium/content/browser/download/OWNERS
@@ -1,5 +1,4 @@
ahendrickson@chromium.org
asanka@chromium.org
-benjhayden@chromium.org
phajdan.jr@chromium.org
rdsmith@chromium.org
diff --git a/chromium/content/browser/download/base_file.cc b/chromium/content/browser/download/base_file.cc
index f9b80155018..7bd2b0bcabf 100644
--- a/chromium/content/browser/download/base_file.cc
+++ b/chromium/content/browser/download/base_file.cc
@@ -4,6 +4,8 @@
#include "content/browser/download/base_file.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
@@ -12,6 +14,7 @@
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
#include "content/browser/download/download_interrupt_reasons_impl.h"
#include "content/browser/download/download_net_log_parameters.h"
#include "content/browser/download/download_stats.h"
@@ -28,7 +31,7 @@ const unsigned char BaseFile::kEmptySha256Hash[] = { 0 };
BaseFile::BaseFile(const base::FilePath& full_path,
const GURL& source_url,
const GURL& referrer_url,
- int64 received_bytes,
+ int64_t received_bytes,
bool calculate_hash,
const std::string& hash_state_bytes,
base::File file,
@@ -36,7 +39,7 @@ BaseFile::BaseFile(const base::FilePath& full_path,
: full_path_(full_path),
source_url_(source_url),
referrer_url_(referrer_url),
- file_(file.Pass()),
+ file_(std::move(file)),
bytes_so_far_(received_bytes),
start_tick_(base::TimeTicks::Now()),
calculate_hash_(calculate_hash),
@@ -272,7 +275,7 @@ DownloadInterruptReason BaseFile::Open() {
// We may be re-opening the file after rename. Always make sure we're
// writing at the end of the file.
- int64 file_size = file_.Seek(base::File::FROM_END, 0);
+ int64_t file_size = file_.Seek(base::File::FROM_END, 0);
if (file_size < 0) {
logging::SystemErrorCode error = logging::GetLastSystemErrorCode();
ClearFile();
diff --git a/chromium/content/browser/download/base_file.h b/chromium/content/browser/download/base_file.h
index 9016755ebc6..9a98d0943f1 100644
--- a/chromium/content/browser/download/base_file.h
+++ b/chromium/content/browser/download/base_file.h
@@ -5,12 +5,16 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_
#define CONTENT_BROWSER_DOWNLOAD_BASE_FILE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
@@ -36,7 +40,7 @@ class CONTENT_EXPORT BaseFile {
BaseFile(const base::FilePath& full_path,
const GURL& source_url,
const GURL& referrer_url,
- int64 received_bytes,
+ int64_t received_bytes,
bool calculate_hash,
const std::string& hash_state,
base::File file,
@@ -91,7 +95,7 @@ class CONTENT_EXPORT BaseFile {
bool in_progress() const { return file_.IsValid(); }
// Returns the number of bytes in the file pointed to by full_path().
- int64 bytes_so_far() const { return bytes_so_far_; }
+ int64_t bytes_so_far() const { return bytes_so_far_; }
// Fills |hash| with the hash digest for the file.
// Returns true if digest is successfully calculated.
@@ -127,7 +131,7 @@ class CONTENT_EXPORT BaseFile {
const base::FilePath& new_path);
// Split out from CurrentSpeed to enable testing.
- int64 CurrentSpeedAtTime(base::TimeTicks current_time) const;
+ int64_t CurrentSpeedAtTime(base::TimeTicks current_time) const;
// Log a TYPE_DOWNLOAD_FILE_ERROR NetLog event with |error| and passes error
// on through, converting to a |DownloadInterruptReason|.
@@ -161,7 +165,7 @@ class CONTENT_EXPORT BaseFile {
base::File file_;
// Amount of data received up so far, in bytes.
- int64 bytes_so_far_;
+ int64_t bytes_so_far_;
// Start time for calculating speed.
base::TimeTicks start_tick_;
diff --git a/chromium/content/browser/download/base_file_posix.cc b/chromium/content/browser/download/base_file_posix.cc
index b5d8e014422..471fb93d77c 100644
--- a/chromium/content/browser/download/base_file_posix.cc
+++ b/chromium/content/browser/download/base_file_posix.cc
@@ -4,6 +4,8 @@
#include "content/browser/download/base_file.h"
+#include <errno.h>
+
#include "base/files/file_util.h"
#include "content/public/browser/download_interrupt_reasons.h"
diff --git a/chromium/content/browser/download/base_file_unittest.cc b/chromium/content/browser/download/base_file_unittest.cc
index 7e27ffe0969..a6ce347c189 100644
--- a/chromium/content/browser/download/base_file_unittest.cc
+++ b/chromium/content/browser/download/base_file_unittest.cc
@@ -4,13 +4,19 @@
#include "content/browser/download/base_file.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/test_file_util.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "crypto/secure_hash.h"
@@ -61,7 +67,7 @@ class BaseFileTest : public testing::Test {
void TearDown() override {
EXPECT_FALSE(base_file_->in_progress());
if (!expected_error_) {
- EXPECT_EQ(static_cast<int64>(expected_data_.size()),
+ EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
base_file_->bytes_so_far());
}
@@ -126,7 +132,7 @@ class BaseFileTest : public testing::Test {
if (base_file_->in_progress()) {
expected_data_ += data;
if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) {
- EXPECT_EQ(static_cast<int64>(expected_data_.size()),
+ EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
base_file_->bytes_so_far());
}
}
@@ -181,7 +187,7 @@ class BaseFileTest : public testing::Test {
duplicate_file.Detach();
}
- int64 CurrentSpeedAtTime(base::TimeTicks current_time) {
+ int64_t CurrentSpeedAtTime(base::TimeTicks current_time) {
EXPECT_TRUE(base_file_.get());
return base_file_->CurrentSpeedAtTime(current_time);
}
@@ -538,14 +544,8 @@ TEST_F(BaseFileTest, WriteWithError) {
// Pass a file handle which was opened without the WRITE flag.
// This should result in an error when writing.
base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ);
- base_file_.reset(new BaseFile(path,
- GURL(),
- GURL(),
- 0,
- false,
- std::string(),
- file.Pass(),
- net::BoundNetLog()));
+ base_file_.reset(new BaseFile(path, GURL(), GURL(), 0, false, std::string(),
+ std::move(file), net::BoundNetLog()));
ASSERT_TRUE(InitializeFile());
#if defined(OS_WIN)
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
diff --git a/chromium/content/browser/download/base_file_win.cc b/chromium/content/browser/download/base_file_win.cc
index 870feb613d3..bfdf3aa9da6 100644
--- a/chromium/content/browser/download/base_file_win.cc
+++ b/chromium/content/browser/download/base_file_win.cc
@@ -12,6 +12,7 @@
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/guid.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc
index fea996e5d65..794e8327bf8 100644
--- a/chromium/content/browser/download/download_browsertest.cc
+++ b/chromium/content/browser/download/download_browsertest.cc
@@ -5,15 +5,24 @@
// This file contains download browser tests that are known to be runnable
// in a pure content context. Over time tests should be migrated here.
-#include "base/command_line.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+#include <vector>
+
+#include "base/callback_helpers.h"
+#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/format_macros.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_file_factory.h"
#include "content/browser/download/download_file_impl.h"
@@ -22,12 +31,13 @@
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/power_save_blocker.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
+#include "content/public/test/test_download_request_handler.h"
#include "content/public/test/test_file_error_injector.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
@@ -37,7 +47,6 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/test/url_request/url_request_slow_download_job.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -48,7 +57,6 @@
#include "content/browser/plugin_service_impl.h"
#endif
-using ::net::test_server::EmbeddedTestServer;
using ::testing::AllOf;
using ::testing::Field;
using ::testing::InSequence;
@@ -191,9 +199,14 @@ DownloadFileWithDelay::DownloadFileWithDelay(
scoped_ptr<PowerSaveBlocker> power_save_blocker,
base::WeakPtr<DownloadDestinationObserver> observer,
base::WeakPtr<DownloadFileWithDelayFactory> owner)
- : DownloadFileImpl(
- save_info.Pass(), default_download_directory, url, referrer_url,
- calculate_hash, stream.Pass(), bound_net_log, observer),
+ : DownloadFileImpl(std::move(save_info),
+ default_download_directory,
+ url,
+ referrer_url,
+ calculate_hash,
+ std::move(stream),
+ bound_net_log,
+ observer),
owner_(owner) {}
DownloadFileWithDelay::~DownloadFileWithDelay() {}
@@ -246,16 +259,16 @@ DownloadFile* DownloadFileWithDelayFactory::CreateFile(
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
PowerSaveBlocker::kReasonOther, "Download in progress"));
return new DownloadFileWithDelay(
- save_info.Pass(), default_download_directory, url, referrer_url,
- calculate_hash, stream.Pass(), bound_net_log,
- psb.Pass(), observer, weak_ptr_factory_.GetWeakPtr());
+ std::move(save_info), default_download_directory, url, referrer_url,
+ calculate_hash, std::move(stream), bound_net_log, std::move(psb),
+ observer, weak_ptr_factory_.GetWeakPtr());
}
void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
rename_callbacks_.push_back(callback);
if (waiting_)
- base::MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->QuitWhenIdle();
}
void DownloadFileWithDelayFactory::GetAllRenameCallbacks(
@@ -276,19 +289,23 @@ void DownloadFileWithDelayFactory::WaitForSomeCallback() {
class CountingDownloadFile : public DownloadFileImpl {
public:
- CountingDownloadFile(
- scoped_ptr<DownloadSaveInfo> save_info,
- const base::FilePath& default_downloads_directory,
- const GURL& url,
- const GURL& referrer_url,
- bool calculate_hash,
- scoped_ptr<ByteStreamReader> stream,
- const net::BoundNetLog& bound_net_log,
- scoped_ptr<PowerSaveBlocker> power_save_blocker,
- base::WeakPtr<DownloadDestinationObserver> observer)
- : DownloadFileImpl(save_info.Pass(), default_downloads_directory,
- url, referrer_url, calculate_hash,
- stream.Pass(), bound_net_log, observer) {}
+ CountingDownloadFile(scoped_ptr<DownloadSaveInfo> save_info,
+ const base::FilePath& default_downloads_directory,
+ const GURL& url,
+ const GURL& referrer_url,
+ bool calculate_hash,
+ scoped_ptr<ByteStreamReader> stream,
+ const net::BoundNetLog& bound_net_log,
+ scoped_ptr<PowerSaveBlocker> power_save_blocker,
+ base::WeakPtr<DownloadDestinationObserver> observer)
+ : DownloadFileImpl(std::move(save_info),
+ default_downloads_directory,
+ url,
+ referrer_url,
+ calculate_hash,
+ std::move(stream),
+ bound_net_log,
+ observer) {}
~CountingDownloadFile() override {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
@@ -311,10 +328,9 @@ class CountingDownloadFile : public DownloadFileImpl {
static int GetNumberActiveFilesFromFileThread() {
int result = -1;
BrowserThread::PostTaskAndReply(
- BrowserThread::FILE,
- FROM_HERE,
+ BrowserThread::FILE, FROM_HERE,
base::Bind(&CountingDownloadFile::GetNumberActiveFiles, &result),
- base::MessageLoop::current()->QuitClosure());
+ base::MessageLoop::current()->QuitWhenIdleClosure());
base::MessageLoop::current()->Run();
DCHECK_NE(-1, result);
return result;
@@ -345,9 +361,9 @@ class CountingDownloadFileFactory : public DownloadFileFactory {
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
PowerSaveBlocker::kReasonOther, "Download in progress"));
return new CountingDownloadFile(
- save_info.Pass(), default_downloads_directory, url, referrer_url,
- calculate_hash, stream.Pass(), bound_net_log,
- psb.Pass(), observer);
+ std::move(save_info), default_downloads_directory, url, referrer_url,
+ calculate_hash, std::move(stream), bound_net_log, std::move(psb),
+ observer);
}
};
@@ -380,71 +396,11 @@ class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate {
std::vector<DownloadOpenDelayedCallback> delayed_callbacks_;
};
-// Record all state transitions and byte counts on the observed download.
-class RecordingDownloadObserver : DownloadItem::Observer {
- public:
- struct RecordStruct {
- DownloadItem::DownloadState state;
- int bytes_received;
- };
-
- typedef std::vector<RecordStruct> RecordVector;
-
- RecordingDownloadObserver(DownloadItem* download)
- : download_(download) {
- last_state_.state = download->GetState();
- last_state_.bytes_received = download->GetReceivedBytes();
- download_->AddObserver(this);
- }
-
- ~RecordingDownloadObserver() override { RemoveObserver(); }
-
- void CompareToExpectedRecord(const RecordStruct expected[], size_t size) {
- EXPECT_EQ(size, record_.size());
- int min = size > record_.size() ? record_.size() : size;
- for (int i = 0; i < min; ++i) {
- EXPECT_EQ(expected[i].state, record_[i].state) << "Iteration " << i;
- EXPECT_EQ(expected[i].bytes_received, record_[i].bytes_received)
- << "Iteration " << i;
- }
- }
-
- private:
- void OnDownloadUpdated(DownloadItem* download) override {
- DCHECK_EQ(download_, download);
- DownloadItem::DownloadState state = download->GetState();
- int bytes = download->GetReceivedBytes();
- if (last_state_.state != state || last_state_.bytes_received > bytes) {
- last_state_.state = state;
- last_state_.bytes_received = bytes;
- record_.push_back(last_state_);
- }
- }
-
- void OnDownloadDestroyed(DownloadItem* download) override {
- DCHECK_EQ(download_, download);
- RemoveObserver();
- }
-
- void RemoveObserver() {
- if (download_) {
- download_->RemoveObserver(this);
- download_ = NULL;
- }
- }
-
- DownloadItem* download_;
- RecordStruct last_state_;
- RecordVector record_;
-};
-
// Get the next created download.
class DownloadCreateObserver : DownloadManager::Observer {
public:
DownloadCreateObserver(DownloadManager* manager)
- : manager_(manager),
- item_(NULL),
- waiting_(false) {
+ : manager_(manager), item_(NULL) {
manager_->AddObserver(this);
}
@@ -465,16 +421,16 @@ class DownloadCreateObserver : DownloadManager::Observer {
if (!item_)
item_ = download;
- if (waiting_)
- base::MessageLoopForUI::current()->Quit();
+ if (!completion_closure_.is_null())
+ base::ResetAndReturn(&completion_closure_).Run();
}
DownloadItem* WaitForFinished() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!item_) {
- waiting_ = true;
- RunMessageLoop();
- waiting_ = false;
+ base::RunLoop run_loop;
+ completion_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
}
return item_;
}
@@ -482,28 +438,11 @@ class DownloadCreateObserver : DownloadManager::Observer {
private:
DownloadManager* manager_;
DownloadItem* item_;
- bool waiting_;
+ base::Closure completion_closure_;
};
-
-// Filter for waiting for a certain number of bytes.
-bool DataReceivedFilter(int number_of_bytes, DownloadItem* download) {
- return download->GetReceivedBytes() >= number_of_bytes;
-}
-
-// Filter for download completion.
-bool DownloadCompleteFilter(DownloadItem* download) {
- return download->GetState() == DownloadItem::COMPLETE;
-}
-
-// Filter for saving the size of the download when the first IN_PROGRESS
-// is hit.
-bool InitialSizeFilter(int* download_size, DownloadItem* download) {
- if (download->GetState() != DownloadItem::IN_PROGRESS)
- return false;
-
- *download_size = download->GetReceivedBytes();
- return true;
+bool IsDownloadInState(DownloadItem::DownloadState state, DownloadItem* item) {
+ return item->GetState() == state;
}
// Request handler to be used with CreateRedirectHandler().
@@ -517,12 +456,12 @@ scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendRedirectResponse(
response->set_code(net::HTTP_FOUND);
response->AddCustomHeader("Location", target_url.spec());
}
- return response.Pass();
+ return std::move(response);
}
// Creates a request handler for EmbeddedTestServer that responds with a HTTP
// 302 redirect if the request URL matches |relative_url|.
-EmbeddedTestServer::HandleRequestCallback CreateRedirectHandler(
+net::EmbeddedTestServer::HandleRequestCallback CreateRedirectHandler(
const std::string& relative_url,
const GURL& target_url) {
return base::Bind(
@@ -532,43 +471,83 @@ EmbeddedTestServer::HandleRequestCallback CreateRedirectHandler(
// Request handler to be used with CreateBasicResponseHandler().
scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse(
const std::string& relative_url,
+ const base::StringPairs& headers,
const std::string& content_type,
const std::string& body,
const net::test_server::HttpRequest& request) {
scoped_ptr<net::test_server::BasicHttpResponse> response;
if (request.relative_url == relative_url) {
response.reset(new net::test_server::BasicHttpResponse);
+ for (const auto& pair : headers)
+ response->AddCustomHeader(pair.first, pair.second);
response->set_content_type(content_type);
response->set_content(body);
}
- return response.Pass();
+ return std::move(response);
}
// Creates a request handler for an EmbeddedTestServer that response with an
// HTTP 200 status code, a Content-Type header and a body.
-EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler(
+net::EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler(
const std::string& relative_url,
+ const base::StringPairs& headers,
const std::string& content_type,
const std::string& body) {
- return base::Bind(
- &HandleRequestAndSendBasicResponse, relative_url, content_type, body);
+ return base::Bind(&HandleRequestAndSendBasicResponse, relative_url, headers,
+ content_type, body);
}
-} // namespace
+// Helper class to "flatten" handling of
+// TestDownloadRequestHandler::OnStartHandler.
+class TestRequestStartHandler {
+ public:
+ // Construct an OnStartHandler that can be set as the on_start_handler for
+ // TestDownloadRequestHandler::Parameters.
+ TestDownloadRequestHandler::OnStartHandler GetOnStartHandler() {
+ EXPECT_FALSE(used_) << "GetOnStartHandler() should only be called once for "
+ "an instance of TestRequestStartHandler.";
+ used_ = true;
+ return base::Bind(&TestRequestStartHandler::OnStartHandler,
+ base::Unretained(this));
+ }
-class DownloadContentTest : public ContentBrowserTest {
- protected:
- // An initial send from a website of at least this size will not be
- // help up by buffering in the underlying downloads ByteStream data
- // transfer. This is important because on resumption tests we wait
- // until we've gotten the data we expect before allowing the test server
- // to send its reset, to get around hard close semantics on the Windows
- // socket layer implementation.
- int GetSafeBufferChunk() const {
- return (DownloadResourceHandler::kDownloadByteStreamSize /
- ByteStreamWriter::kFractionBufferBeforeSending) + 1;
+ // Wait until the OnStartHandlers returned in a prior call to
+ // GetOnStartHandler() is invoked.
+ void WaitForCallback() {
+ if (response_callback_.is_null())
+ run_loop_.Run();
}
+ // Respond to the OnStartHandler() invocation using |headers| and |error|.
+ void RespondWith(const std::string& headers, net::Error error) {
+ ASSERT_FALSE(response_callback_.is_null());
+ response_callback_.Run(headers, error);
+ }
+
+ // Return the headers returned from the invocation of OnStartHandler.
+ const net::HttpRequestHeaders& headers() const {
+ EXPECT_FALSE(response_callback_.is_null());
+ return request_headers_;
+ }
+
+ private:
+ void OnStartHandler(const net::HttpRequestHeaders& headers,
+ const TestDownloadRequestHandler::OnStartResponseCallback&
+ response_callback) {
+ request_headers_ = headers;
+ response_callback_ = response_callback;
+ if (run_loop_.running())
+ run_loop_.Quit();
+ }
+
+ bool used_ = false;
+ base::RunLoop run_loop_;
+ net::HttpRequestHeaders request_headers_;
+ TestDownloadRequestHandler::OnStartResponseCallback response_callback_;
+};
+
+class DownloadContentTest : public ContentBrowserTest {
+ protected:
void SetUpOnMainThread() override {
ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
@@ -603,26 +582,28 @@ class DownloadContentTest : public ContentBrowserTest {
DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
}
- // Create a DownloadTestObserverInProgress that will wait for the
- // specified number of downloads to start.
- DownloadCreateObserver* CreateInProgressWaiter(
- Shell* shell, int num_downloads) {
- DownloadManager* download_manager = DownloadManagerForShell(shell);
- return new DownloadCreateObserver(download_manager);
+ void WaitForInterrupt(DownloadItem* download) {
+ DownloadUpdatedObserver(
+ download, base::Bind(&IsDownloadInState, DownloadItem::INTERRUPTED))
+ .WaitForEvent();
}
- DownloadTestObserver* CreateInterruptedWaiter(
- Shell* shell, int num_downloads) {
- DownloadManager* download_manager = DownloadManagerForShell(shell);
- return new DownloadTestObserverInterrupted(download_manager, num_downloads,
- DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
+ void WaitForInProgress(DownloadItem* download) {
+ DownloadUpdatedObserver(
+ download, base::Bind(&IsDownloadInState, DownloadItem::IN_PROGRESS))
+ .WaitForEvent();
+ }
+
+ void WaitForCompletion(DownloadItem* download) {
+ DownloadUpdatedObserver(
+ download, base::Bind(&IsDownloadInState, DownloadItem::COMPLETE))
+ .WaitForEvent();
}
// Note: Cannot be used with other alternative DownloadFileFactorys
void SetupEnsureNoPendingDownloads() {
DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting(
- scoped_ptr<DownloadFileFactory>(
- new CountingDownloadFileFactory()).Pass());
+ scoped_ptr<DownloadFileFactory>(new CountingDownloadFileFactory()));
}
bool EnsureNoPendingDownloads() {
@@ -649,7 +630,7 @@ class DownloadContentTest : public ContentBrowserTest {
// string.
bool VerifyFile(const base::FilePath& path,
const std::string& value,
- const int64 file_size) {
+ const int64_t file_size) {
std::string file_contents;
bool read = base::ReadFileToString(path, &file_contents);
@@ -675,69 +656,37 @@ class DownloadContentTest : public ContentBrowserTest {
}
// Start a download and return the item.
- DownloadItem* StartDownloadAndReturnItem(GURL url) {
+ DownloadItem* StartDownloadAndReturnItem(Shell* shell, GURL url) {
scoped_ptr<DownloadCreateObserver> observer(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), url);
- observer->WaitForFinished();
- std::vector<DownloadItem*> downloads;
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- EXPECT_EQ(1u, downloads.size());
- if (1u != downloads.size())
- return NULL;
- return downloads[0];
- }
-
- // Wait for data
- void WaitForData(DownloadItem* download, int size) {
- DownloadUpdatedObserver data_observer(
- download, base::Bind(&DataReceivedFilter, size));
- data_observer.WaitForEvent();
- ASSERT_EQ(size, download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
- }
-
- // Tell the test server to release a pending RST and confirm
- // that the interrupt is received properly (for download resumption
- // testing).
- void ReleaseRSTAndConfirmInterruptForResume(DownloadItem* download) {
- scoped_ptr<DownloadTestObserver> rst_observer(
- CreateInterruptedWaiter(shell(), 1));
- NavigateToURL(shell(), test_server()->GetURL("download-finish"));
- rst_observer->WaitForFinished();
- EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
+ new DownloadCreateObserver(DownloadManagerForShell(shell)));
+ shell->LoadURL(url);
+ return observer->WaitForFinished();
}
- // Confirm file status expected for the given location in a stream
- // provided by the resume test server.
- void ConfirmFileStatusForResume(
- DownloadItem* download, bool file_exists,
- int received_bytes, int total_bytes,
- const base::FilePath& expected_filename) {
- // expected_filename is only known if the file exists.
- ASSERT_EQ(file_exists, !expected_filename.empty());
- EXPECT_EQ(received_bytes, download->GetReceivedBytes());
- EXPECT_EQ(total_bytes, download->GetTotalBytes());
- EXPECT_EQ(expected_filename.value(),
- download->GetFullPath().BaseName().value());
- EXPECT_EQ(file_exists,
- (!download->GetFullPath().empty() &&
- base::PathExists(download->GetFullPath())));
-
- if (file_exists) {
- std::string file_contents;
- EXPECT_TRUE(base::ReadFileToString(
- download->GetFullPath(), &file_contents));
-
- ASSERT_EQ(static_cast<size_t>(received_bytes), file_contents.size());
- for (int i = 0; i < received_bytes; ++i) {
- EXPECT_EQ(static_cast<char>((i * 2 + 15) % 256), file_contents[i])
- << "File contents diverged at position " << i
- << " for " << expected_filename.value();
-
- if (static_cast<char>((i * 2 + 15) % 256) != file_contents[i])
- return;
- }
+ static void ReadAndVerifyFileContents(int seed,
+ int64_t expected_size,
+ const base::FilePath& path) {
+ base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ ASSERT_TRUE(file.IsValid());
+ int64_t file_length = file.GetLength();
+ ASSERT_EQ(expected_size, file_length);
+
+ const int64_t kBufferSize = 64 * 1024;
+ std::vector<char> pattern;
+ std::vector<char> data;
+ pattern.resize(kBufferSize);
+ data.resize(kBufferSize);
+ for (int64_t offset = 0; offset < file_length;) {
+ int bytes_read = file.Read(offset, &data.front(), kBufferSize);
+ ASSERT_LT(0, bytes_read);
+ ASSERT_GE(kBufferSize, bytes_read);
+
+ TestDownloadRequestHandler::GetPatternBytes(seed, offset, bytes_read,
+ &pattern.front());
+ ASSERT_EQ(0, memcmp(&pattern.front(), &data.front(), bytes_read))
+ << "Comparing block at offset " << offset << " and length "
+ << bytes_read;
+ offset += bytes_read;
}
}
@@ -745,8 +694,8 @@ class DownloadContentTest : public ContentBrowserTest {
static void EnsureNoPendingDownloadJobsOnIO(bool* result) {
if (net::URLRequestSlowDownloadJob::NumberOutstandingRequests())
*result = false;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::MessageLoop::QuitWhenIdleClosure());
}
// Location of the downloads directory for these tests
@@ -754,23 +703,84 @@ class DownloadContentTest : public ContentBrowserTest {
scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_;
};
+// Parameters for DownloadResumptionContentTest.
+enum class DownloadResumptionTestType {
+ RESUME_WITH_RENDERER, // Resume() is called while the originating WebContents
+ // is still alive.
+ RESUME_WITHOUT_RENDERER // Resume() is called after the originating
+ // WebContents has been deleted.
+};
+
+// Parameterized test for download resumption. Tests using this fixure will be
+// run once with RESUME_WITH_RENDERER and once with RESUME_WITHOUT_RENDERER.
+// Use initiator_shell_for_resumption() to retrieve the Shell object that should
+// be used as the originator for the initial download. Prior to calling
+// Resume(), call PrepareToResume() which will cause the originating Shell to be
+// deleted if the test parameter is RESUME_WITHOUT_RENDERER.
+class DownloadResumptionContentTest
+ : public DownloadContentTest,
+ public ::testing::WithParamInterface<DownloadResumptionTestType> {
+ public:
+ void SetUpOnMainThread() override {
+ base::FeatureList::ClearInstanceForTesting();
+ scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
+ feature_list->InitializeFromCommandLine(
+ features::kDownloadResumption.name, std::string());
+ base::FeatureList::SetInstance(std::move(feature_list));
+
+ DownloadContentTest::SetUpOnMainThread();
+
+ if (GetParam() == DownloadResumptionTestType::RESUME_WITHOUT_RENDERER)
+ initiator_shell_for_resumption_ = CreateBrowser();
+ else
+ initiator_shell_for_resumption_ = shell();
+
+ ASSERT_EQ(DownloadManagerForShell(shell()),
+ DownloadManagerForShell(initiator_shell_for_resumption()));
+ }
+
+ // Shell to use for initiating a download. Only valid *before*
+ // PrepareToResume() is called.
+ Shell* initiator_shell_for_resumption() const {
+ DCHECK(initiator_shell_for_resumption_);
+ return initiator_shell_for_resumption_;
+ }
+
+ // Should be called once before calling DownloadItem::Resume() on an
+ // interrupted download. This may cause initiator_shell_for_resumption() to
+ // become invalidated.
+ void PrepareToResume() {
+ if (GetParam() == DownloadResumptionTestType::RESUME_WITH_RENDERER)
+ return;
+ DCHECK_NE(initiator_shell_for_resumption(), shell());
+ DCHECK(initiator_shell_for_resumption());
+ initiator_shell_for_resumption_->Close();
+ initiator_shell_for_resumption_ = nullptr;
+ }
+
+ private:
+ Shell* initiator_shell_for_resumption_ = nullptr;
+};
+
+INSTANTIATE_TEST_CASE_P(
+ _,
+ DownloadResumptionContentTest,
+ ::testing::Values(DownloadResumptionTestType::RESUME_WITH_RENDERER,
+ DownloadResumptionTestType::RESUME_WITHOUT_RENDERER));
+
+} // namespace
+
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) {
SetupEnsureNoPendingDownloads();
// Create a download, wait until it's started, and confirm
// we're in the expected state.
- scoped_ptr<DownloadCreateObserver> observer(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- observer->WaitForFinished();
-
- std::vector<DownloadItem*> downloads;
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- ASSERT_EQ(1u, downloads.size());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState());
+ DownloadItem* download = StartDownloadAndReturnItem(
+ shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
+ ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
// Cancel the download and wait for download system quiesce.
- downloads[0]->Cancel(true);
+ download->Cancel(true);
scoped_refptr<DownloadTestFlushObserver> flush_observer(
new DownloadTestFlushObserver(DownloadManagerForShell(shell())));
flush_observer->WaitForFlush();
@@ -786,29 +796,14 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) {
// Create a download, wait until it's started, and confirm
// we're in the expected state.
- scoped_ptr<DownloadCreateObserver> observer1(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- observer1->WaitForFinished();
-
- std::vector<DownloadItem*> downloads;
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- ASSERT_EQ(1u, downloads.size());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState());
- DownloadItem* download1 = downloads[0]; // The only download.
+ DownloadItem* download1 = StartDownloadAndReturnItem(
+ shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
+ ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
// Start the second download and wait until it's done.
- base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file));
- // Download the file and wait.
- NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE);
-
- // Should now have 2 items on the manager.
- downloads.clear();
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- ASSERT_EQ(2u, downloads.size());
- // We don't know the order of the downloads.
- DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0];
+ GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
+ DownloadItem* download2 = StartDownloadAndReturnItem(shell(), url);
+ WaitForCompletion(download2);
ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState());
@@ -842,8 +837,6 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) {
// Content served with a MIME type of application/octet-stream should be
// downloaded even when a plugin can be found that handles the file type.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) {
- const base::FilePath::CharType kTestFilePath[] =
- FILE_PATH_LITERAL("octet-stream.abc");
const char kTestPluginName[] = "TestPlugin";
const char kTestMimeType[] = "application/x-test-mime-type";
const char kTestFileType[] = "abc";
@@ -857,7 +850,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) {
// The following is served with a Content-Type of application/octet-stream.
GURL url(
- net::URLRequestMockHTTPJob::GetMockUrl(base::FilePath(kTestFilePath)));
+ net::URLRequestMockHTTPJob::GetMockUrl("octet-stream.abc"));
NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE);
}
#endif
@@ -870,11 +863,11 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtFinalRename) {
new DownloadFileWithDelayFactory();
DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
download_manager->SetDownloadFileFactoryForTesting(
- scoped_ptr<DownloadFileFactory>(file_factory).Pass());
+ scoped_ptr<DownloadFileFactory>(file_factory));
// Create a download
- base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
- NavigateToURL(shell(), net::URLRequestMockHTTPJob::GetMockUrl(file));
+ NavigateToURL(shell(),
+ net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
// Wait until the first (intermediate file) rename and execute the callback.
file_factory->WaitForSomeCallback();
@@ -919,11 +912,11 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) {
DownloadFileWithDelayFactory* file_factory =
new DownloadFileWithDelayFactory();
download_manager->SetDownloadFileFactoryForTesting(
- scoped_ptr<DownloadFileFactory>(file_factory).Pass());
+ scoped_ptr<DownloadFileFactory>(file_factory));
// Create a download
- base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
- NavigateToURL(shell(), net::URLRequestMockHTTPJob::GetMockUrl(file));
+ NavigateToURL(shell(),
+ net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
// Wait until the first (intermediate file) rename and execute the callback.
file_factory->WaitForSomeCallback();
@@ -963,25 +956,26 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) {
EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState());
}
+#if defined(OS_ANDROID)
+// Flaky on android: https://crbug.com/324525
+#define MAYBE_ShutdownInProgress DISABLED_ShutdownInProgress
+#else
+#define MAYBE_ShutdownInProgress ShutdownInProgress
+#endif
+
// Try to shutdown with a download in progress to make sure shutdown path
// works properly.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, MAYBE_ShutdownInProgress) {
// Create a download that won't complete.
- scoped_ptr<DownloadCreateObserver> observer(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- observer->WaitForFinished();
+ DownloadItem* download = StartDownloadAndReturnItem(
+ shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- // Get the item.
- std::vector<DownloadItem*> items;
- DownloadManagerForShell(shell())->GetAllDownloads(&items);
- ASSERT_EQ(1u, items.size());
- EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
+ EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
// Shutdown the download manager and make sure we get the right
// notifications in the right order.
StrictMock<MockDownloadItemObserver> item_observer;
- items[0]->AddObserver(&item_observer);
+ download->AddObserver(&item_observer);
MockDownloadManagerObserver manager_observer(
DownloadManagerForShell(shell()));
// Don't care about ModelChanged() events.
@@ -993,11 +987,12 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
EXPECT_CALL(manager_observer, MockManagerGoingDown(
DownloadManagerForShell(shell())))
.WillOnce(Return());
- EXPECT_CALL(item_observer, OnDownloadUpdated(
- AllOf(items[0],
- Property(&DownloadItem::GetState, DownloadItem::CANCELLED))))
+ EXPECT_CALL(
+ item_observer,
+ OnDownloadUpdated(AllOf(download, Property(&DownloadItem::GetState,
+ DownloadItem::CANCELLED))))
.WillOnce(Return());
- EXPECT_CALL(item_observer, OnDownloadDestroyed(items[0]))
+ EXPECT_CALL(item_observer, OnDownloadDestroyed(download))
.WillOnce(Return());
}
@@ -1014,7 +1009,6 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
- items.clear();
}
// Try to shutdown just after we release the download file, by delaying
@@ -1029,11 +1023,11 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
DownloadFileWithDelayFactory* file_factory =
new DownloadFileWithDelayFactory();
download_manager->SetDownloadFileFactoryForTesting(
- scoped_ptr<DownloadFileFactory>(file_factory).Pass());
+ scoped_ptr<DownloadFileFactory>(file_factory));
// Create a download
- base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
- NavigateToURL(shell(), net::URLRequestMockHTTPJob::GetMockUrl(file));
+ NavigateToURL(shell(),
+ net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
// Wait until the first (intermediate file) rename and execute the callback.
file_factory->WaitForSomeCallback();
@@ -1073,293 +1067,221 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
DownloadManagerForShell(shell())->Shutdown();
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
-
- GURL url = test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+// Test resumption with a response that contains strong validators.
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, StrongValidators) {
+ TestDownloadRequestHandler request_handler;
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ const TestDownloadRequestHandler::InjectedError interruption =
+ parameters.injected_errors.front();
+ request_handler.StartServing(parameters);
- MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
+ ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
- // Confirm resumption while in progress doesn't do anything.
+ PrepareToResume();
download->Resume();
- ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
-
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- // Resume, confirming received bytes on resumption is correct.
- // Make sure no creation calls are included.
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(0);
- int initial_size = 0;
- DownloadUpdatedObserver initial_size_observer(
- download, base::Bind(&InitialSizeFilter, &initial_size));
- download->Resume();
- initial_size_observer.WaitForEvent();
- EXPECT_EQ(GetSafeBufferChunk(), initial_size);
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
-
- // and wait for expected data.
- WaitForData(download, GetSafeBufferChunk() * 2);
-
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 2, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- // Resume and wait for completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
- download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- // Confirm resumption while complete doesn't do anything.
- download->Resume();
- ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::COMPLETE, download->GetState());
- RunAllPendingInMessageLoop();
- ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::COMPLETE, download->GetState());
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
+ parameters.pattern_generator_seed, parameters.size,
+ download->GetTargetFilePath()));
+
+ // Characterization risk: The next portion of the test examines the requests
+ // that were sent out while downloading our resource. These requests
+ // correspond to the requests that were generated by the browser and the
+ // downloads system and may change as implementation details change.
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+
+ ASSERT_EQ(2u, requests.size());
+
+ // The first request only transferrs bytes up until the interruption point.
+ EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count);
+
+ // The next request should only have transferred the remainder of the
+ // resource.
+ EXPECT_EQ(parameters.size - interruption.offset,
+ requests[1].transferred_byte_count);
+
+ std::string value;
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kIfRange, &value));
+ EXPECT_EQ(parameters.etag, value);
+
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &value));
+ EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
+ value);
}
-// Confirm restart fallback happens if a range request is bounced.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownloadNoRange) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
-
- // Auto-restart if server doesn't handle ranges.
- GURL url = test_server()->GetURL(
- base::StringPrintf(
- // First download hits an RST, rest don't, no ranges.
- "rangereset?size=%d&rst_boundary=%d&"
- "token=NoRange&rst_limit=1&bounce_range",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
-
- RecordingDownloadObserver recorder(download);
-
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
+// A partial resumption results in an HTTP 200 response. I.e. the server ignored
+// the range request and sent the entire resource instead. For If-Range requests
+// (as opposed to If-Match), the behavior for a precondition failure is also to
+// respond with a 200. So this test case covers both validation failure and
+// ignoring the range request.
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
+ RestartIfNotPartialResponse) {
+ const int kOriginalPatternGeneratorSeed = 1;
+ const int kNewPatternGeneratorSeed = 2;
+
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
+ const TestDownloadRequestHandler::InjectedError interruption =
+ parameters.injected_errors.front();
+
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
+
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
+
+ ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+
+ parameters = TestDownloadRequestHandler::Parameters();
+ parameters.support_byte_ranges = false;
+ parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
+ request_handler.StartServing(parameters);
+
+ PrepareToResume();
download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Starting continuation
- {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
- // Notification of receiving whole file.
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(
+ ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size,
+ download->GetTargetFilePath()));
+
+ // When the downloads system sees the full response, it should accept the
+ // response without restarting. On the network, we should deterministically
+ // see two requests:
+ // * The original request which transfers upto our interruption point.
+ // * The resumption attempt, which receives the entire entity.
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+
+ ASSERT_EQ(2u, requests.size());
+
+ // The first request only transfers data up to the interruption point.
+ EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count);
+
+ // The second request transfers the entire response.
+ EXPECT_EQ(parameters.size, requests[1].transferred_byte_count);
+
+ std::string value;
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kIfRange, &value));
+ EXPECT_EQ(parameters.etag, value);
+
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &value));
+ EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
+ value);
}
-// Confirm restart fallback happens if a precondition is failed.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- ResumeInterruptedDownloadBadPrecondition) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
-
- GURL url = test_server()->GetURL(base::StringPrintf(
- // First download hits an RST, rest don't, precondition fail.
- "rangereset?size=%d&rst_boundary=%d&"
- "token=BadPrecondition&rst_limit=1&fail_precondition=2",
- GetSafeBufferChunk() * 3,
- GetSafeBufferChunk()));
-
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
-
- RecordingDownloadObserver recorder(download);
-
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
- EXPECT_EQ("BadPrecondition2", download->GetETag());
-
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
- download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
- EXPECT_EQ("BadPrecondition0", download->GetETag());
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Starting continuation
- {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
- // Server precondition fail.
- {DownloadItem::INTERRUPTED, 0},
- // Notification of successful restart.
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
-}
+// Confirm we restart if we don't have a verifier.
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RestartIfNoETag) {
+ const int kOriginalPatternGeneratorSeed = 1;
+ const int kNewPatternGeneratorSeed = 2;
-// Confirm we don't try to resume if we don't have a verifier.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- ResumeInterruptedDownloadNoVerifiers) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
-
- GURL url = test_server()->GetURL(
- base::StringPrintf(
- // First download hits an RST, rest don't, no verifiers.
- "rangereset?size=%d&rst_boundary=%d&"
- "token=NoRange&rst_limit=1&no_verifiers",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
-
- RecordingDownloadObserver recorder(download);
-
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, false, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath());
-
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
- download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Restart for lack of verifiers
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
-}
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ ASSERT_EQ(1u, parameters.injected_errors.size());
+ parameters.etag.clear();
+ parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithDeletedFile) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
- GURL url = test_server()->GetURL(
- base::StringPrintf(
- // First download hits an RST, rest don't
- "rangereset?size=%d&rst_boundary=%d&"
- "token=NoRange&rst_limit=1",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
+ parameters.ClearInjectedErrors();
+ request_handler.StartServing(parameters);
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
+ PrepareToResume();
+ download->Resume();
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(
+ ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size,
+ download->GetTargetFilePath()));
+
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+
+ // Neither If-Range nor Range headers should be present in the second request.
+ ASSERT_EQ(2u, requests.size());
+ std::string value;
+ EXPECT_FALSE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kIfRange, &value));
+ EXPECT_FALSE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &value));
+}
- RecordingDownloadObserver recorder(download);
+// Partial file goes missing before the download is resumed. The download should
+// restart.
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RestartIfNoPartialFile) {
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
// Delete the intermediate file.
- base::DeleteFile(download->GetFullPath(), false);
+ ASSERT_TRUE(base::PathExists(download->GetFullPath()));
+ ASSERT_TRUE(base::DeleteFile(download->GetFullPath(), false));
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
+ parameters.ClearInjectedErrors();
+ request_handler.StartServing(parameters);
+
+ PrepareToResume();
download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Starting continuation
- {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
- // Error because file isn't there.
- {DownloadItem::INTERRUPTED, 0},
- // Restart.
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
+ parameters.pattern_generator_seed, parameters.size,
+ download->GetTargetFilePath()));
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file));
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
+ RecoverFromInitFileError) {
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
// Setup the error injector.
- scoped_refptr<TestFileErrorInjector> injector(
- TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
+ scoped_refptr<TestFileErrorInjector> injector(TestFileErrorInjector::Create(
+ DownloadManagerForShell(initiator_shell_for_resumption())));
- TestFileErrorInjector::FileErrorInfo err = {
- url.spec(),
- TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
- 0,
- DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
- };
+ const TestFileErrorInjector::FileErrorInfo err = {
+ request_handler.url().spec(),
+ TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 0,
+ DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
injector->AddError(err);
injector->InjectErrors();
// Start and watch for interrupt.
- scoped_ptr<DownloadTestObserver> int_observer(
- CreateInterruptedWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url));
- int_observer->WaitForFinished();
+ DownloadItem* download(StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url()));
+ WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
@@ -1379,38 +1301,32 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) {
injector->InjectErrors();
// Resume and watch completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
+ PrepareToResume();
download->Resume();
- completion_observer.WaitForEvent();
+ WaitForCompletion(download);
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- ResumeWithFileIntermediateRenameError) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file));
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
+ RecoverFromIntermediateFileRenameError) {
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
// Setup the error injector.
- scoped_refptr<TestFileErrorInjector> injector(
- TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
+ scoped_refptr<TestFileErrorInjector> injector(TestFileErrorInjector::Create(
+ DownloadManagerForShell(initiator_shell_for_resumption())));
- TestFileErrorInjector::FileErrorInfo err = {
- url.spec(),
- TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY,
- 0,
- DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
- };
+ const TestFileErrorInjector::FileErrorInfo err = {
+ request_handler.url().spec(),
+ TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, 0,
+ DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
injector->AddError(err);
injector->InjectErrors();
// Start and watch for interrupt.
- scoped_ptr<DownloadTestObserver> int_observer(
- CreateInterruptedWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url));
- int_observer->WaitForFinished();
+ DownloadItem* download(StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url()));
+ WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
@@ -1431,39 +1347,34 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
injector->ClearErrors();
injector->InjectErrors();
- // Resume and watch completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
+ PrepareToResume();
download->Resume();
- completion_observer.WaitForEvent();
+ WaitForCompletion(download);
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file));
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
+ RecoverFromFinalRenameError) {
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
// Setup the error injector.
- scoped_refptr<TestFileErrorInjector> injector(
- TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
+ scoped_refptr<TestFileErrorInjector> injector(TestFileErrorInjector::Create(
+ DownloadManagerForShell(initiator_shell_for_resumption())));
- DownloadManagerForShell(shell())->RemoveAllDownloads();
+ DownloadManagerForShell(initiator_shell_for_resumption())
+ ->RemoveAllDownloads();
TestFileErrorInjector::FileErrorInfo err = {
- url.spec(),
- TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE,
- 0,
- DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
- };
+ request_handler.url().spec(),
+ TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, 0,
+ DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
injector->AddError(err);
injector->InjectErrors();
// Start and watch for interrupt.
- scoped_ptr<DownloadTestObserver> int_observer(
- CreateInterruptedWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url));
- int_observer->WaitForFinished();
+ DownloadItem* download(StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url()));
+ WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
@@ -1482,36 +1393,27 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
injector->ClearErrors();
injector->InjectErrors();
- // Resume and watch completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
+ PrepareToResume();
download->Resume();
- completion_observer.WaitForEvent();
+ WaitForCompletion(download);
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
// An interrupted download should remove the intermediate file when it is
// cancelled.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
-
- GURL url1 = test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
+ CancelInterruptedDownload) {
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption());
- DownloadItem* download(StartDownloadAndReturnItem(url1));
- WaitForData(download, GetSafeBufferChunk());
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- base::FilePath intermediate_path(download->GetFullPath());
+ base::FilePath intermediate_path = download->GetFullPath();
ASSERT_FALSE(intermediate_path.empty());
- EXPECT_TRUE(base::PathExists(intermediate_path));
+ ASSERT_TRUE(base::PathExists(intermediate_path));
download->Cancel(true /* user_cancel */);
RunAllPendingInMessageLoop(BrowserThread::FILE);
@@ -1522,82 +1424,59 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
EXPECT_TRUE(download->GetFullPath().empty());
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest,
+ RemoveInterruptedDownload) {
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption());
- // An interrupted download should remove the intermediate file when it is
- // removed.
- {
- GURL url1 = test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- DownloadItem* download(StartDownloadAndReturnItem(url1));
- WaitForData(download, GetSafeBufferChunk());
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- base::FilePath intermediate_path(download->GetFullPath());
- ASSERT_FALSE(intermediate_path.empty());
- EXPECT_TRUE(base::PathExists(intermediate_path));
-
- download->Remove();
- RunAllPendingInMessageLoop(BrowserThread::FILE);
- RunAllPendingInMessageLoop();
-
- // The intermediate file should now be gone.
- EXPECT_FALSE(base::PathExists(intermediate_path));
- }
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
- // A completed download shouldn't delete the downloaded file when it is
- // removed.
- {
- // Start the second download and wait until it's done.
- base::FilePath file2(FILE_PATH_LITERAL("download-test.lib"));
- GURL url2(net::URLRequestMockHTTPJob::GetMockUrl(file2));
- scoped_ptr<DownloadTestObserver> completion_observer(
- CreateWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url2));
- completion_observer->WaitForFinished();
-
- // The target path should exist.
- base::FilePath target_path(download->GetTargetFilePath());
- EXPECT_TRUE(base::PathExists(target_path));
- download->Remove();
- RunAllPendingInMessageLoop(BrowserThread::FILE);
- RunAllPendingInMessageLoop();
-
- // The file should still exist.
- EXPECT_TRUE(base::PathExists(target_path));
- }
-}
+ base::FilePath intermediate_path = download->GetFullPath();
+ ASSERT_FALSE(intermediate_path.empty());
+ ASSERT_TRUE(base::PathExists(intermediate_path));
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
- SetupEnsureNoPendingDownloads();
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
+ download->Remove();
+ RunAllPendingInMessageLoop(BrowserThread::FILE);
+ RunAllPendingInMessageLoop();
- GURL url = test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ // The intermediate file should now be gone.
+ EXPECT_FALSE(base::PathExists(intermediate_path));
+}
- MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveCompletedDownload) {
+ // A completed download shouldn't delete the downloaded file when it is
+ // removed.
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
+ scoped_ptr<DownloadTestObserver> completion_observer(
+ CreateWaiter(shell(), 1));
+ DownloadItem* download(
+ StartDownloadAndReturnItem(shell(), request_handler.url()));
+ completion_observer->WaitForFinished();
+
+ // The target path should exist.
+ base::FilePath target_path(download->GetTargetFilePath());
+ EXPECT_TRUE(base::PathExists(target_path));
+ download->Remove();
+ RunAllPendingInMessageLoop(BrowserThread::FILE);
+ RunAllPendingInMessageLoop();
+
+ // The file should still exist.
+ EXPECT_TRUE(base::PathExists(target_path));
+}
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RemoveResumingDownload) {
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
ASSERT_FALSE(intermediate_path.empty());
@@ -1605,94 +1484,193 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
// Resume and remove download. We expect only a single OnDownloadCreated()
// call, and that's for the second download created below.
+ MockDownloadManagerObserver dm_observer(
+ DownloadManagerForShell(initiator_shell_for_resumption()));
EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+
+ TestRequestStartHandler request_start_handler;
+ parameters.on_start_handler = request_start_handler.GetOnStartHandler();
+ request_handler.StartServing(parameters);
+
+ PrepareToResume();
download->Resume();
+ request_start_handler.WaitForCallback();
+
+ // At this point, the download resumption request has been sent out, but the
+ // reponse hasn't been received yet.
download->Remove();
+ request_start_handler.RespondWith(std::string(), net::OK);
+
// The intermediate file should now be gone.
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(base::PathExists(intermediate_path));
- // Start the second download and wait until it's done. The test server is
- // single threaded. The response to this download request should follow the
- // response to the previous resumption request.
- GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
- NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE);
+ parameters.ClearInjectedErrors();
+ parameters.on_start_handler.Reset();
+ request_handler.StartServing(parameters);
+ // Start the second download and wait until it's done. This exercises the
+ // entire downloads stack and effectively flushes all of our worker threads.
+ // We are testing whether the URL request created in the previous
+ // DownloadItem::Resume() call reulted in a new download or not.
+ NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
+ DownloadItem::COMPLETE);
EXPECT_TRUE(EnsureNoPendingDownloads());
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) {
- SetupEnsureNoPendingDownloads();
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(test_server()->Start());
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, CancelResumingDownload) {
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- GURL url = test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
- MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
+ base::FilePath intermediate_path(download->GetFullPath());
+ ASSERT_FALSE(intermediate_path.empty());
+ EXPECT_TRUE(base::PathExists(intermediate_path));
+
+ // Resume and cancel download. We expect only a single OnDownloadCreated()
+ // call, and that's for the second download created below.
+ MockDownloadManagerObserver dm_observer(
+ DownloadManagerForShell(initiator_shell_for_resumption()));
EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
+ TestRequestStartHandler request_start_handler;
+ parameters.on_start_handler = request_start_handler.GetOnStartHandler();
+ request_handler.StartServing(parameters);
+
+ PrepareToResume();
+ download->Resume();
+ request_start_handler.WaitForCallback();
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ // At this point, the download item has initiated a network request for the
+ // resumption attempt, but hasn't received a response yet.
+ download->Cancel(true /* user_cancel */);
+
+ request_start_handler.RespondWith(std::string(), net::OK);
+
+ // The intermediate file should now be gone.
+ RunAllPendingInMessageLoop(BrowserThread::IO);
+ RunAllPendingInMessageLoop(BrowserThread::FILE);
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(base::PathExists(intermediate_path));
+
+ parameters.ClearInjectedErrors();
+ parameters.on_start_handler.Reset();
+ request_handler.StartServing(parameters);
+
+ // Start the second download and wait until it's done. This exercises the
+ // entire downloads stack and effectively flushes all of our worker threads.
+ // We are testing whether the URL request created in the previous
+ // DownloadItem::Resume() call reulted in a new download or not.
+ NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
+ DownloadItem::COMPLETE);
+ EXPECT_TRUE(EnsureNoPendingDownloads());
+}
+
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, RemoveResumedDownload) {
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
+
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
+ base::FilePath target_path(download->GetTargetFilePath());
ASSERT_FALSE(intermediate_path.empty());
EXPECT_TRUE(base::PathExists(intermediate_path));
+ EXPECT_FALSE(base::PathExists(target_path));
- // Resume and cancel download. We expect only a single OnDownloadCreated()
- // call, and that's for the second download created below.
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+ // Resume and remove download. We don't expect OnDownloadCreated() calls.
+ MockDownloadManagerObserver dm_observer(
+ DownloadManagerForShell(initiator_shell_for_resumption()));
+ EXPECT_CALL(dm_observer, OnDownloadCreated(_, _)).Times(0);
+
+ PrepareToResume();
download->Resume();
- download->Cancel(true);
+ WaitForInProgress(download);
+
+ download->Remove();
// The intermediate file should now be gone.
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(base::PathExists(intermediate_path));
- EXPECT_TRUE(download->GetFullPath().empty());
+ EXPECT_FALSE(base::PathExists(target_path));
+ EXPECT_TRUE(EnsureNoPendingDownloads());
+}
+
+IN_PROC_BROWSER_TEST_P(DownloadResumptionContentTest, CancelResumedDownload) {
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- // Start the second download and wait until it's done. The test server is
- // single threaded. The response to this download request should follow the
- // response to the previous resumption request.
- GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
- NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE);
+ DownloadItem* download = StartDownloadAndReturnItem(
+ initiator_shell_for_resumption(), request_handler.url());
+ WaitForInterrupt(download);
+
+ base::FilePath intermediate_path(download->GetFullPath());
+ base::FilePath target_path(download->GetTargetFilePath());
+ ASSERT_FALSE(intermediate_path.empty());
+ EXPECT_TRUE(base::PathExists(intermediate_path));
+ EXPECT_FALSE(base::PathExists(target_path));
+
+ // Resume and remove download. We don't expect OnDownloadCreated() calls.
+ MockDownloadManagerObserver dm_observer(
+ DownloadManagerForShell(initiator_shell_for_resumption()));
+ EXPECT_CALL(dm_observer, OnDownloadCreated(_, _)).Times(0);
+
+ PrepareToResume();
+ download->Resume();
+ WaitForInProgress(download);
+ download->Cancel(true);
+
+ // The intermediate file should now be gone.
+ RunAllPendingInMessageLoop(BrowserThread::FILE);
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(base::PathExists(intermediate_path));
+ EXPECT_FALSE(base::PathExists(target_path));
EXPECT_TRUE(EnsureNoPendingDownloads());
}
// Check that the cookie policy is correctly updated when downloading a file
// that redirects cross origin.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
- ASSERT_TRUE(test_server()->Start());
- net::HostPortPair host_port = test_server()->host_port_pair();
- DCHECK_EQ(host_port.host(), std::string("127.0.0.1"));
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.Start());
+ ASSERT_TRUE(origin_two.Start());
// Block third-party cookies.
ShellNetworkDelegate::SetAcceptAllCookies(false);
// |url| redirects to a different origin |download| which tries to set a
// cookie.
- std::string download(base::StringPrintf(
- "http://localhost:%d/set-cookie?A=B", host_port.port()));
- GURL url(test_server()->GetURL("server-redirect?" + download));
+ base::StringPairs cookie_header;
+ cookie_header.push_back(
+ std::make_pair(std::string("Set-Cookie"), std::string("A=B")));
+ origin_one.RegisterRequestHandler(CreateBasicResponseHandler(
+ "/foo", cookie_header, "application/octet-stream", "abcd"));
+ origin_two.RegisterRequestHandler(
+ CreateRedirectHandler("/bar", origin_one.GetURL("/foo")));
// Download the file.
SetupEnsureNoPendingDownloads();
- scoped_ptr<DownloadUrlParameters> dl_params(
- DownloadUrlParameters::FromWebContents(shell()->web_contents(), url));
+ scoped_ptr<DownloadUrlParameters> download_parameters(
+ DownloadUrlParameters::FromWebContents(shell()->web_contents(),
+ origin_two.GetURL("/bar")));
scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
- DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass());
+ DownloadManagerForShell(shell())->DownloadUrl(std::move(download_parameters));
observer->WaitForFinished();
// Get the important info from other threads and check it.
@@ -1706,7 +1684,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
// Check that the cookies were correctly set.
EXPECT_EQ("A=B",
content::GetCookies(shell()->web_contents()->GetBrowserContext(),
- GURL(download)));
+ origin_one.GetURL("/")));
}
// A filename suggestion specified via a @download attribute should not be
@@ -1714,10 +1692,10 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
// download URL.
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
DownloadAttributeCrossOriginRedirect) {
- EmbeddedTestServer origin_one;
- EmbeddedTestServer origin_two;
- ASSERT_TRUE(origin_one.InitializeAndWaitUntilReady());
- ASSERT_TRUE(origin_two.InitializeAndWaitUntilReady());
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.Start());
+ ASSERT_TRUE(origin_two.Start());
// The download-attribute.html page contains an anchor element whose href is
// set to the value of the query parameter (specified as |target| in the URL
@@ -1738,7 +1716,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
origin_one.RegisterRequestHandler(
CreateRedirectHandler("/ping", origin_two.GetURL("/download")));
origin_two.RegisterRequestHandler(CreateBasicResponseHandler(
- "/download", "application/octet-stream", "Hello"));
+ "/download", base::StringPairs(), "application/octet-stream", "Hello"));
NavigateToURLAndWaitForDownload(
shell(), referrer_url, DownloadItem::COMPLETE);
@@ -1759,10 +1737,10 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
// of the redirect chain.
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
DownloadAttributeSameOriginRedirect) {
- EmbeddedTestServer origin_one;
- EmbeddedTestServer origin_two;
- ASSERT_TRUE(origin_one.InitializeAndWaitUntilReady());
- ASSERT_TRUE(origin_two.InitializeAndWaitUntilReady());
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.Start());
+ ASSERT_TRUE(origin_two.Start());
// The download-attribute.html page contains an anchor element whose href is
// set to the value of the query parameter (specified as |target| in the URL
@@ -1786,7 +1764,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
origin_two.RegisterRequestHandler(
CreateRedirectHandler("/pong", origin_one.GetURL("/download")));
origin_one.RegisterRequestHandler(CreateBasicResponseHandler(
- "/download", "application/octet-stream", "Hello"));
+ "/download", base::StringPairs(), "application/octet-stream", "Hello"));
NavigateToURLAndWaitForDownload(
shell(), referrer_url, DownloadItem::COMPLETE);
@@ -1805,18 +1783,24 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
// The content body is empty. Make sure this case is handled properly and we
// don't regress on http://crbug.com/320394.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadGZipWithNoContent) {
- EmbeddedTestServer test_server;
- ASSERT_TRUE(test_server.InitializeAndWaitUntilReady());
-
- GURL url = test_server.GetURL("/empty.bin");
- test_server.ServeFilesFromDirectory(GetTestFilePath("download", ""));
-
+ GURL url = net::URLRequestMockHTTPJob::GetMockUrl("empty.bin");
NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE);
// That's it. This should work without crashing.
}
+// Make sure that sniffed MIME types are correctly passed through to the
+// download item.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, SniffedMimeType) {
+ GURL url = net::URLRequestMockHTTPJob::GetMockUrl("gzip-content.gz");
+ DownloadItem* item = StartDownloadAndReturnItem(shell(), url);
+ WaitForCompletion(item);
+
+ EXPECT_STREQ("application/x-gzip", item->GetMimeType().c_str());
+ EXPECT_TRUE(item->GetOriginalMimeType().empty());
+}
+
IN_PROC_BROWSER_TEST_F(DownloadContentTest, Spam) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
NavigateToURLAndWaitForDownload(
shell(),
diff --git a/chromium/content/browser/download/download_create_info.cc b/chromium/content/browser/download/download_create_info.cc
index 05b0992a26d..c09d713aa97 100644
--- a/chromium/content/browser/download/download_create_info.cc
+++ b/chromium/content/browser/download/download_create_info.cc
@@ -5,6 +5,7 @@
#include "content/browser/download/download_create_info.h"
#include <string>
+#include <utility>
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
@@ -12,41 +13,34 @@
namespace content {
DownloadCreateInfo::DownloadCreateInfo(const base::Time& start_time,
- int64 total_bytes,
+ int64_t total_bytes,
const net::BoundNetLog& bound_net_log,
- bool has_user_gesture,
- ui::PageTransition transition_type,
scoped_ptr<DownloadSaveInfo> save_info)
: start_time(start_time),
total_bytes(total_bytes),
download_id(DownloadItem::kInvalidId),
- has_user_gesture(has_user_gesture),
- transition_type(transition_type),
- save_info(save_info.Pass()),
+ has_user_gesture(false),
+ transition_type(ui::PAGE_TRANSITION_LINK),
+ save_info(std::move(save_info)),
request_bound_net_log(bound_net_log) {}
DownloadCreateInfo::DownloadCreateInfo()
- : total_bytes(0),
- download_id(DownloadItem::kInvalidId),
- has_user_gesture(false),
- transition_type(ui::PAGE_TRANSITION_LINK),
- save_info(new DownloadSaveInfo()) {
-}
+ : DownloadCreateInfo(base::Time(),
+ 0,
+ net::BoundNetLog(),
+ make_scoped_ptr(new DownloadSaveInfo)) {}
-DownloadCreateInfo::~DownloadCreateInfo() {
-}
+DownloadCreateInfo::~DownloadCreateInfo() {}
std::string DownloadCreateInfo::DebugString() const {
- return base::StringPrintf("{"
- " download_id = %u"
- " url = \"%s\""
- " request_handle = %s"
- " total_bytes = %" PRId64
- " }",
- download_id,
- url().spec().c_str(),
- request_handle.DebugString().c_str(),
- total_bytes);
+ return base::StringPrintf(
+ "{"
+ " download_id = %u"
+ " url = \"%s\""
+ " request_handle = %s"
+ " total_bytes = %" PRId64 " }",
+ download_id, url().spec().c_str(), request_handle->DebugString().c_str(),
+ total_bytes);
}
const GURL& DownloadCreateInfo::url() const {
diff --git a/chromium/content/browser/download/download_create_info.h b/chromium/content/browser/download/download_create_info.h
index 7bf03ab1d2a..1767e45eebc 100644
--- a/chromium/content/browser/download/download_create_info.h
+++ b/chromium/content/browser/download/download_create_info.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_CREATE_INFO_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_CREATE_INFO_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/browser/download/download_file.h"
#include "content/browser/download/download_request_handle.h"
@@ -25,10 +27,8 @@ namespace content {
// want to pass |DownloadItem|s between threads.
struct CONTENT_EXPORT DownloadCreateInfo {
DownloadCreateInfo(const base::Time& start_time,
- int64 total_bytes,
+ int64_t total_bytes,
const net::BoundNetLog& bound_net_log,
- bool has_user_gesture,
- ui::PageTransition transition_type,
scoped_ptr<DownloadSaveInfo> save_info);
DownloadCreateInfo();
~DownloadCreateInfo();
@@ -55,10 +55,10 @@ struct CONTENT_EXPORT DownloadCreateInfo {
base::Time start_time;
// The total download size.
- int64 total_bytes;
+ int64_t total_bytes;
// The ID of the download.
- uint32 download_id;
+ uint32_t download_id;
// True if the download was initiated by user action.
bool has_user_gesture;
@@ -92,7 +92,7 @@ struct CONTENT_EXPORT DownloadCreateInfo {
std::string remote_address;
// The handle to the URLRequest sourcing this download.
- DownloadRequestHandle request_handle;
+ scoped_ptr<DownloadRequestHandleInterface> request_handle;
// The request's |BoundNetLog|, for "source_dependency" linking with the
// download item's.
diff --git a/chromium/content/browser/download/download_file.h b/chromium/content/browser/download/download_file.h
index 568e7ee091c..2514df15519 100644
--- a/chromium/content/browser/download/download_file.h
+++ b/chromium/content/browser/download/download_file.h
@@ -5,9 +5,10 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_FILE_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_FILE_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "content/common/content_export.h"
@@ -64,7 +65,7 @@ class CONTENT_EXPORT DownloadFile {
virtual base::FilePath FullPath() const = 0;
virtual bool InProgress() const = 0;
- virtual int64 CurrentSpeed() const = 0;
+ virtual int64_t CurrentSpeed() const = 0;
// Set |hash| with sha256 digest for the file.
// Returns true if digest is successfully calculated.
diff --git a/chromium/content/browser/download/download_file_factory.cc b/chromium/content/browser/download/download_file_factory.cc
index 817bee11180..bae88bef34e 100644
--- a/chromium/content/browser/download/download_file_factory.cc
+++ b/chromium/content/browser/download/download_file_factory.cc
@@ -4,6 +4,8 @@
#include "content/browser/download/download_file_factory.h"
+#include <utility>
+
#include "content/browser/download/download_file_impl.h"
namespace content {
@@ -19,9 +21,9 @@ DownloadFile* DownloadFileFactory::CreateFile(
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
base::WeakPtr<DownloadDestinationObserver> observer) {
- return new DownloadFileImpl(
- save_info.Pass(), default_downloads_directory, url, referrer_url,
- calculate_hash, stream.Pass(), bound_net_log, observer);
+ return new DownloadFileImpl(std::move(save_info), default_downloads_directory,
+ url, referrer_url, calculate_hash,
+ std::move(stream), bound_net_log, observer);
}
} // namespace content
diff --git a/chromium/content/browser/download/download_file_impl.cc b/chromium/content/browser/download/download_file_impl.cc
index c5bed5405ba..0a1f3980152 100644
--- a/chromium/content/browser/download/download_file_impl.cc
+++ b/chromium/content/browser/download/download_file_impl.cc
@@ -5,6 +5,7 @@
#include "content/browser/download/download_file_impl.h"
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/files/file_util.h"
@@ -48,15 +49,14 @@ DownloadFileImpl::DownloadFileImpl(
save_info->offset,
calculate_hash,
save_info->hash_state,
- save_info->file.Pass(),
+ std::move(save_info->file),
bound_net_log),
default_download_directory_(default_download_directory),
- stream_reader_(stream.Pass()),
+ stream_reader_(std::move(stream)),
bytes_seen_(0),
bound_net_log_(bound_net_log),
observer_(observer),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
DownloadFileImpl::~DownloadFileImpl() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
@@ -228,7 +228,7 @@ bool DownloadFileImpl::InProgress() const {
return file_.in_progress();
}
-int64 DownloadFileImpl::CurrentSpeed() const {
+int64_t DownloadFileImpl::CurrentSpeed() const {
return rate_estimator_.GetCountPerSecond();
}
diff --git a/chromium/content/browser/download/download_file_impl.h b/chromium/content/browser/download/download_file_impl.h
index 2a8edb3ddd8..98381128505 100644
--- a/chromium/content/browser/download/download_file_impl.h
+++ b/chromium/content/browser/download/download_file_impl.h
@@ -7,6 +7,10 @@
#include "content/browser/download/download_file.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -56,7 +60,7 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
void Cancel() override;
base::FilePath FullPath() const override;
bool InProgress() const override;
- int64 CurrentSpeed() const override;
+ int64_t CurrentSpeed() const override;
bool GetHash(std::string* hash) override;
std::string GetHashState() override;
void SetClientGuid(const std::string& guid) override;
diff --git a/chromium/content/browser/download/download_file_unittest.cc b/chromium/content/browser/download/download_file_unittest.cc
index 59cc4a766de..9630a49b066 100644
--- a/chromium/content/browser/download/download_file_unittest.cc
+++ b/chromium/content/browser/download/download_file_unittest.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/location.h"
@@ -10,6 +14,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/test/test_file_util.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_create_info.h"
@@ -50,15 +55,14 @@ class MockByteStreamReader : public ByteStreamReader {
class MockDownloadDestinationObserver : public DownloadDestinationObserver {
public:
- MOCK_METHOD3(DestinationUpdate, void(int64, int64, const std::string&));
+ MOCK_METHOD3(DestinationUpdate, void(int64_t, int64_t, const std::string&));
MOCK_METHOD1(DestinationError, void(DownloadInterruptReason));
MOCK_METHOD1(DestinationCompleted, void(const std::string&));
// Doesn't override any methods in the base class. Used to make sure
// that the last DestinationUpdate before a Destination{Completed,Error}
// had the right values.
- MOCK_METHOD3(CurrentUpdateStatus,
- void(int64, int64, const std::string&));
+ MOCK_METHOD3(CurrentUpdateStatus, void(int64_t, int64_t, const std::string&));
};
MATCHER(IsNullCallback, "") { return (arg.is_null()); }
@@ -79,12 +83,12 @@ class TestDownloadFileImpl : public DownloadFileImpl {
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
base::WeakPtr<DownloadDestinationObserver> observer)
- : DownloadFileImpl(save_info.Pass(),
+ : DownloadFileImpl(std::move(save_info),
default_downloads_directory,
url,
referrer_url,
calculate_hash,
- stream.Pass(),
+ std::move(stream),
bound_net_log,
observer) {}
@@ -112,7 +116,7 @@ class DownloadFileTest : public testing::Test {
static const char* kTestData2;
static const char* kTestData3;
static const char* kDataHash;
- static const uint32 kDummyDownloadId;
+ static const uint32_t kDummyDownloadId;
static const int kDummyChildId;
static const int kDummyRequestId;
@@ -129,7 +133,8 @@ class DownloadFileTest : public testing::Test {
~DownloadFileTest() override {}
- void SetUpdateDownloadInfo(int64 bytes, int64 bytes_per_sec,
+ void SetUpdateDownloadInfo(int64_t bytes,
+ int64_t bytes_per_sec,
const std::string& hash_state) {
bytes_ = bytes;
bytes_per_sec_ = bytes_per_sec;
@@ -172,16 +177,14 @@ class DownloadFileTest : public testing::Test {
scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
scoped_ptr<TestDownloadFileImpl> download_file_impl(
- new TestDownloadFileImpl(save_info.Pass(),
- base::FilePath(),
- GURL(), // Source
- GURL(), // Referrer
- calculate_hash,
- scoped_ptr<ByteStreamReader>(input_stream_),
- net::BoundNetLog(),
- observer_factory_.GetWeakPtr()));
+ new TestDownloadFileImpl(
+ std::move(save_info), base::FilePath(),
+ GURL(), // Source
+ GURL(), // Referrer
+ calculate_hash, scoped_ptr<ByteStreamReader>(input_stream_),
+ net::BoundNetLog(), observer_factory_.GetWeakPtr()));
download_file_impl->SetClientGuid("12345678-ABCD-1234-DCBA-123456789ABC");
- download_file_ = download_file_impl.Pass();
+ download_file_ = std::move(download_file_impl);
EXPECT_CALL(*input_stream_, Read(_, _))
.WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
@@ -234,7 +237,7 @@ class DownloadFileTest : public testing::Test {
void VerifyStreamAndSize() {
::testing::Mock::VerifyAndClearExpectations(input_stream_);
- int64 size;
+ int64_t size;
EXPECT_TRUE(base::GetFileSize(download_file_->FullPath(), &size));
EXPECT_EQ(expected_data_.size(), static_cast<size_t>(size));
}
@@ -335,8 +338,8 @@ class DownloadFileTest : public testing::Test {
base::Closure sink_callback_;
// Latest update sent to the observer.
- int64 bytes_;
- int64 bytes_per_sec_;
+ int64_t bytes_;
+ int64_t bytes_per_sec_;
std::string hash_state_;
base::MessageLoop loop_;
@@ -397,7 +400,7 @@ const char* DownloadFileTest::kTestData3 = "Final line.";
const char* DownloadFileTest::kDataHash =
"CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8";
-const uint32 DownloadFileTest::kDummyDownloadId = 23;
+const uint32_t DownloadFileTest::kDummyDownloadId = 23;
const int DownloadFileTest::kDummyChildId = 3;
const int DownloadFileTest::kDummyRequestId = 67;
@@ -778,11 +781,11 @@ TEST_F(DownloadFileTest, ConfirmUpdate) {
// Run the message loops for 750ms and check for results.
loop_.task_runner()->PostDelayedTask(FROM_HERE,
- base::MessageLoop::QuitClosure(),
+ base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(750));
loop_.Run();
- EXPECT_EQ(static_cast<int64>(strlen(kTestData1) + strlen(kTestData2)),
+ EXPECT_EQ(static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)),
bytes_);
EXPECT_EQ(download_file_->GetHashState(), hash_state_);
diff --git a/chromium/content/browser/download/download_item_factory.h b/chromium/content/browser/download/download_item_factory.h
index d4198cb62e1..0069e43422e 100644
--- a/chromium/content/browser/download/download_item_factory.h
+++ b/chromium/content/browser/download/download_item_factory.h
@@ -9,6 +9,8 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_FACTORY_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_FACTORY_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -39,7 +41,7 @@ public:
virtual DownloadItemImpl* CreatePersistedItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -50,8 +52,8 @@ public:
const base::Time& end_time,
const std::string& etag,
const std::string& last_modified,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -60,13 +62,13 @@ public:
virtual DownloadItemImpl* CreateActiveItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) = 0;
virtual DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
diff --git a/chromium/content/browser/download/download_item_impl.cc b/chromium/content/browser/download/download_item_impl.cc
index 1e5d53aef00..cef57731792 100644
--- a/chromium/content/browser/download/download_item_impl.cc
+++ b/chromium/content/browser/download/download_item_impl.cc
@@ -23,11 +23,10 @@
#include "content/browser/download/download_item_impl.h"
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/logging.h"
@@ -49,7 +48,7 @@
#include "content/public/browser/download_danger_type.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_url_parameters.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/referrer.h"
#include "net/base/net_util.h"
@@ -93,13 +92,12 @@ static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) {
}
bool IsDownloadResumptionEnabled() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableDownloadResumption);
+ return base::FeatureList::IsEnabled(features::kDownloadResumption);
}
} // namespace
-const uint32 DownloadItem::kInvalidId = 0;
+const uint32_t DownloadItem::kInvalidId = 0;
const char DownloadItem::kEmptyFileHash[] = "";
@@ -108,7 +106,7 @@ const int DownloadItemImpl::kMaxAutoResumeAttempts = 5;
// Constructor for reading from the history service.
DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -119,8 +117,8 @@ DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
const base::Time& end_time,
const std::string& etag,
const std::string& last_modified,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -167,16 +165,15 @@ DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
}
// Constructing for a regular download:
-DownloadItemImpl::DownloadItemImpl(
- DownloadItemImplDelegate* delegate,
- uint32 download_id,
- const DownloadCreateInfo& info,
- const net::BoundNetLog& bound_net_log)
+DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
+ uint32_t download_id,
+ const DownloadCreateInfo& info,
+ const net::BoundNetLog& bound_net_log)
: is_save_package_download_(false),
download_id_(download_id),
- target_disposition_(
- (info.save_info->prompt_for_save_location) ?
- TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE),
+ target_disposition_((info.save_info->prompt_for_save_location)
+ ? TARGET_DISPOSITION_PROMPT
+ : TARGET_DISPOSITION_OVERWRITE),
url_chain_(info.url_chain),
referrer_url_(info.referrer_url),
tab_url_(info.tab_url),
@@ -228,14 +225,14 @@ DownloadItemImpl::DownloadItemImpl(
// Constructing for the "Save Page As..." feature:
DownloadItemImpl::DownloadItemImpl(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log)
: is_save_package_download_(true),
- request_handle_(request_handle.Pass()),
+ request_handle_(std::move(request_handle)),
download_id_(download_id),
current_path_(path),
target_path_(path),
@@ -477,7 +474,7 @@ void DownloadItemImpl::ShowDownloadInShell() {
delegate_->ShowDownloadInShell(this);
}
-uint32 DownloadItemImpl::GetId() const {
+uint32_t DownloadItemImpl::GetId() const {
return download_id_;
}
@@ -504,9 +501,8 @@ bool DownloadItemImpl::CanResume() const {
if (state_ != INTERRUPTED_INTERNAL)
return false;
- // Downloads that don't have a WebContents should still be resumable, but this
- // isn't currently the case. See ResumeInterruptedDownload().
- if (!GetWebContents())
+ // We currently only support HTTP(S) requests for download resumption.
+ if (!GetURL().SchemeIsHTTPOrHTTPS())
return false;
ResumeMode resume_mode = GetResumeMode();
@@ -666,19 +662,12 @@ void DownloadItemImpl::DeleteFile(const base::Callback<void(bool)>& callback) {
}
bool DownloadItemImpl::IsDangerous() const {
-#if defined(OS_WIN) || defined(OS_MACOSX)
- // TODO(noelutz): At this point only the windows views and OSX UI supports
- // warnings based on dangerous content.
return (danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE ||
danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_URL ||
danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT ||
danger_type_ == DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT ||
danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST ||
danger_type_ == DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED);
-#else
- return (danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE ||
- danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
-#endif
}
DownloadDangerType DownloadItemImpl::GetDangerType() const {
@@ -689,7 +678,7 @@ bool DownloadItemImpl::TimeRemaining(base::TimeDelta* remaining) const {
if (total_bytes_ <= 0)
return false; // We never received the content_length for this download.
- int64 speed = CurrentSpeed();
+ int64_t speed = CurrentSpeed();
if (speed == 0)
return false;
@@ -698,7 +687,7 @@ bool DownloadItemImpl::TimeRemaining(base::TimeDelta* remaining) const {
return true;
}
-int64 DownloadItemImpl::CurrentSpeed() const {
+int64_t DownloadItemImpl::CurrentSpeed() const {
if (is_paused_)
return 0;
return bytes_per_sec_;
@@ -717,11 +706,11 @@ bool DownloadItemImpl::AllDataSaved() const {
return all_data_saved_;
}
-int64 DownloadItemImpl::GetTotalBytes() const {
+int64_t DownloadItemImpl::GetTotalBytes() const {
return total_bytes_;
}
-int64 DownloadItemImpl::GetReceivedBytes() const {
+int64_t DownloadItemImpl::GetReceivedBytes() const {
return received_bytes_;
}
@@ -891,7 +880,6 @@ DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const {
mode = RESUME_MODE_IMMEDIATE_CONTINUE;
break;
- case DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION:
case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE:
case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT:
if (force_user)
@@ -1000,7 +988,7 @@ const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const {
return bound_net_log_;
}
-void DownloadItemImpl::SetTotalBytes(int64 total_bytes) {
+void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) {
total_bytes_ = total_bytes;
}
@@ -1027,8 +1015,8 @@ void DownloadItemImpl::MarkAsComplete() {
TransitionTo(COMPLETE_INTERNAL, UPDATE_OBSERVERS);
}
-void DownloadItemImpl::DestinationUpdate(int64 bytes_so_far,
- int64 bytes_per_sec,
+void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far,
+ int64_t bytes_per_sec,
const std::string& hash_state) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DVLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far
@@ -1129,8 +1117,8 @@ void DownloadItemImpl::Start(
DCHECK(file.get());
DCHECK(req_handle.get());
- download_file_ = file.Pass();
- request_handle_ = req_handle.Pass();
+ download_file_ = std::move(file);
+ request_handle_ = std::move(req_handle);
if (GetState() == CANCELLED) {
// The download was in the process of resuming when it was cancelled. Don't
@@ -1681,25 +1669,13 @@ void DownloadItemImpl::AutoResumeIfValid() {
void DownloadItemImpl::ResumeInterruptedDownload() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // If the flag for downloads resumption isn't enabled, ignore
- // this request.
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- if (!command_line.HasSwitch(switches::kEnableDownloadResumption))
+ if (!IsDownloadResumptionEnabled())
return;
// If we're not interrupted, ignore the request; our caller is drunk.
if (state_ != INTERRUPTED_INTERNAL)
return;
- // If we can't get a web contents, we can't resume the download.
- // TODO(rdsmith): Find some alternative web contents to use--this
- // means we can't restart a download if it's a download imported
- // from the history.
- if (!GetWebContents())
- return;
-
// Reset the appropriate state if restarting.
ResumeMode mode = GetResumeMode();
if (mode == RESUME_MODE_IMMEDIATE_RESTART ||
@@ -1710,9 +1686,14 @@ void DownloadItemImpl::ResumeInterruptedDownload() {
etag_ = "";
}
- scoped_ptr<DownloadUrlParameters> download_params(
- DownloadUrlParameters::FromWebContents(GetWebContents(),
- GetOriginalUrl()));
+ scoped_ptr<DownloadUrlParameters> download_params;
+ if (GetWebContents()) {
+ download_params =
+ DownloadUrlParameters::FromWebContents(GetWebContents(), GetURL());
+ } else {
+ download_params = make_scoped_ptr(new DownloadUrlParameters(
+ GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext()));
+ }
download_params->set_file_path(GetFullPath());
download_params->set_offset(GetReceivedBytes());
@@ -1723,7 +1704,7 @@ void DownloadItemImpl::ResumeInterruptedDownload() {
base::Bind(&DownloadItemImpl::OnResumeRequestStarted,
weak_ptr_factory_.GetWeakPtr()));
- delegate_->ResumeInterruptedDownload(download_params.Pass(), GetId());
+ delegate_->ResumeInterruptedDownload(std::move(download_params), GetId());
// Just in case we were interrupted while paused.
is_paused_ = false;
@@ -1745,7 +1726,7 @@ DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState(
case INTERRUPTED_INTERNAL:
return INTERRUPTED;
case RESUMING_INTERNAL:
- return INTERRUPTED;
+ return IN_PROGRESS;
case MAX_DOWNLOAD_INTERNAL_STATE:
break;
}
diff --git a/chromium/content/browser/download/download_item_impl.h b/chromium/content/browser/download/download_item_impl.h
index 37041cad6b2..c527861287f 100644
--- a/chromium/content/browser/download/download_item_impl.h
+++ b/chromium/content/browser/download/download_item_impl.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_IMPL_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_IMPL_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
@@ -50,7 +52,7 @@ class CONTENT_EXPORT DownloadItemImpl
// Constructing from persistent store:
// |bound_net_log| is constructed externally for our use.
DownloadItemImpl(DownloadItemImplDelegate* delegate,
- uint32 id,
+ uint32_t id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -61,8 +63,8 @@ class CONTENT_EXPORT DownloadItemImpl
const base::Time& end_time,
const std::string& etag,
const std::string& last_modified,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -72,14 +74,14 @@ class CONTENT_EXPORT DownloadItemImpl
// Constructing for a regular download.
// |bound_net_log| is constructed externally for our use.
DownloadItemImpl(DownloadItemImplDelegate* delegate,
- uint32 id,
+ uint32_t id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log);
// Constructing for the "Save Page As..." feature:
// |bound_net_log| is constructed externally for our use.
DownloadItemImpl(DownloadItemImplDelegate* delegate,
- uint32 id,
+ uint32_t id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
@@ -100,7 +102,7 @@ class CONTENT_EXPORT DownloadItemImpl
void Remove() override;
void OpenDownload() override;
void ShowDownloadInShell() override;
- uint32 GetId() const override;
+ uint32_t GetId() const override;
DownloadState GetState() const override;
DownloadInterruptReason GetLastReason() const override;
bool IsPaused() const override;
@@ -135,11 +137,11 @@ class CONTENT_EXPORT DownloadItemImpl
bool IsDangerous() const override;
DownloadDangerType GetDangerType() const override;
bool TimeRemaining(base::TimeDelta* remaining) const override;
- int64 CurrentSpeed() const override;
+ int64_t CurrentSpeed() const override;
int PercentComplete() const override;
bool AllDataSaved() const override;
- int64 GetTotalBytes() const override;
- int64 GetReceivedBytes() const override;
+ int64_t GetTotalBytes() const override;
+ int64_t GetReceivedBytes() const override;
base::Time GetStartTime() const override;
base::Time GetEndTime() const override;
bool CanShowInFolder() override;
@@ -199,7 +201,7 @@ class CONTENT_EXPORT DownloadItemImpl
// DownloadItemImpl routines only needed by SavePackage ----------------------
// Called by SavePackage to set the total number of bytes on the item.
- virtual void SetTotalBytes(int64 total_bytes);
+ virtual void SetTotalBytes(int64_t total_bytes);
virtual void OnAllDataSaved(const std::string& final_hash);
@@ -208,8 +210,8 @@ class CONTENT_EXPORT DownloadItemImpl
virtual void MarkAsComplete();
// DownloadDestinationObserver
- void DestinationUpdate(int64 bytes_so_far,
- int64 bytes_per_sec,
+ void DestinationUpdate(int64_t bytes_so_far,
+ int64_t bytes_per_sec,
const std::string& hash_state) override;
void DestinationError(DownloadInterruptReason reason) override;
void DestinationCompleted(const std::string& final_hash) override;
@@ -393,7 +395,7 @@ class CONTENT_EXPORT DownloadItemImpl
// download system.
scoped_ptr<DownloadRequestHandleInterface> request_handle_;
- uint32 download_id_;
+ uint32_t download_id_;
// Display name for the download. If this is empty, then the display name is
// considered to be |target_path_.BaseName()|.
@@ -457,13 +459,13 @@ class CONTENT_EXPORT DownloadItemImpl
std::string remote_address_;
// Total bytes expected.
- int64 total_bytes_;
+ int64_t total_bytes_;
// Current received bytes.
- int64 received_bytes_;
+ int64_t received_bytes_;
// Current speed. Calculated by the DownloadFile.
- int64 bytes_per_sec_;
+ int64_t bytes_per_sec_;
// Sha256 hash of the content. This might be empty either because
// the download isn't done yet or because the hash isn't needed
diff --git a/chromium/content/browser/download/download_item_impl_delegate.cc b/chromium/content/browser/download/download_item_impl_delegate.cc
index a069fa84e90..c1ed48cd124 100644
--- a/chromium/content/browser/download/download_item_impl_delegate.cc
+++ b/chromium/content/browser/download/download_item_impl_delegate.cc
@@ -57,7 +57,8 @@ void DownloadItemImplDelegate::CheckForFileRemoval(
DownloadItemImpl* download_item) {}
void DownloadItemImplDelegate::ResumeInterruptedDownload(
- scoped_ptr<DownloadUrlParameters> params, uint32 id) {}
+ scoped_ptr<DownloadUrlParameters> params,
+ uint32_t id) {}
BrowserContext* DownloadItemImplDelegate::GetBrowserContext() const {
return NULL;
diff --git a/chromium/content/browser/download/download_item_impl_delegate.h b/chromium/content/browser/download/download_item_impl_delegate.h
index 72e079b8963..1925963f0a2 100644
--- a/chromium/content/browser/download/download_item_impl_delegate.h
+++ b/chromium/content/browser/download/download_item_impl_delegate.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_IMPL_DELEGATE_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_IMPL_DELEGATE_H_
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/download_danger_type.h"
#include "content/public/browser/download_item.h"
@@ -69,7 +72,7 @@ class CONTENT_EXPORT DownloadItemImplDelegate {
// Called when an interrupted download is resumed.
virtual void ResumeInterruptedDownload(
scoped_ptr<content::DownloadUrlParameters> params,
- uint32 id);
+ uint32_t id);
// For contextual issues like language and prefs.
virtual BrowserContext* GetBrowserContext() const;
diff --git a/chromium/content/browser/download/download_item_impl_unittest.cc b/chromium/content/browser/download/download_item_impl_unittest.cc
index 786d9031104..0afad1bfca2 100644
--- a/chromium/content/browser/download/download_item_impl_unittest.cc
+++ b/chromium/content/browser/download/download_item_impl_unittest.cc
@@ -2,23 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/download/download_item_impl.h"
+
+#include <stdint.h>
+#include <utility>
+
#include "base/callback.h"
-#include "base/command_line.h"
+#include "base/feature_list.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/threading/thread.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_create_info.h"
#include "content/browser/download/download_file_factory.h"
-#include "content/browser/download/download_item_impl.h"
#include "content/browser/download/download_item_impl_delegate.h"
#include "content/browser/download/download_request_handle.h"
#include "content/browser/download/mock_download_file.h"
#include "content/public/browser/download_destination_observer.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_url_parameters.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/content_features.h"
#include "content/public/test/mock_download_item.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -53,12 +58,12 @@ class MockDelegate : public DownloadItemImplDelegate {
MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&));
MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*));
- void ResumeInterruptedDownload(
- scoped_ptr<DownloadUrlParameters> params, uint32 id) override {
+ void ResumeInterruptedDownload(scoped_ptr<DownloadUrlParameters> params,
+ uint32_t id) override {
MockResumeInterruptedDownload(params.get(), id);
}
MOCK_METHOD2(MockResumeInterruptedDownload,
- void(DownloadUrlParameters* params, uint32 id));
+ void(DownloadUrlParameters* params, uint32_t id));
MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*());
MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*));
@@ -92,25 +97,9 @@ class MockRequestHandle : public DownloadRequestHandleInterface {
MOCK_CONST_METHOD0(DebugString, std::string());
};
-// Schedules a task to invoke the RenameCompletionCallback with |new_path| on
-// the UI thread. Should only be used as the action for
-// MockDownloadFile::Rename as follows:
-// EXPECT_CALL(download_file, Rename*(_,_))
-// .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
-// new_path));
-ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(arg1, interrupt_reason, new_path));
-}
-
-} // namespace
-
-class DownloadItemTest : public testing::Test {
+class TestDownloadItemObserver : public DownloadItem::Observer {
public:
- class MockObserver : public DownloadItem::Observer {
- public:
- explicit MockObserver(DownloadItem* item)
+ explicit TestDownloadItemObserver(DownloadItem* item)
: item_(item),
last_state_(item->GetState()),
removed_(false),
@@ -118,80 +107,85 @@ class DownloadItemTest : public testing::Test {
updated_(false),
interrupt_count_(0),
resume_count_(0) {
- item_->AddObserver(this);
- }
+ item_->AddObserver(this);
+ }
- ~MockObserver() override {
- if (item_) item_->RemoveObserver(this);
- }
+ ~TestDownloadItemObserver() override {
+ if (item_)
+ item_->RemoveObserver(this);
+ }
- void OnDownloadRemoved(DownloadItem* download) override {
- DVLOG(20) << " " << __FUNCTION__
- << " download = " << download->DebugString(false);
- removed_ = true;
- }
+ bool download_removed() const { return removed_; }
+ bool download_destroyed() const { return destroyed_; }
+ int interrupt_count() const { return interrupt_count_; }
+ int resume_count() const { return resume_count_; }
- void OnDownloadUpdated(DownloadItem* download) override {
- DVLOG(20) << " " << __FUNCTION__
- << " download = " << download->DebugString(false);
- updated_ = true;
- DownloadItem::DownloadState new_state = download->GetState();
- if (last_state_ == DownloadItem::IN_PROGRESS &&
- new_state == DownloadItem::INTERRUPTED) {
- interrupt_count_++;
- }
- if (last_state_ == DownloadItem::INTERRUPTED &&
- new_state == DownloadItem::IN_PROGRESS) {
- resume_count_++;
- }
- last_state_ = new_state;
- }
+ bool CheckAndResetDownloadUpdated() {
+ bool was_updated = updated_;
+ updated_ = false;
+ return was_updated;
+ }
- void OnDownloadOpened(DownloadItem* download) override {
- DVLOG(20) << " " << __FUNCTION__
- << " download = " << download->DebugString(false);
- }
+ private:
+ void OnDownloadRemoved(DownloadItem* download) override {
+ DVLOG(20) << " " << __FUNCTION__
+ << " download = " << download->DebugString(false);
+ removed_ = true;
+ }
- void OnDownloadDestroyed(DownloadItem* download) override {
- DVLOG(20) << " " << __FUNCTION__
- << " download = " << download->DebugString(false);
- destroyed_ = true;
- item_->RemoveObserver(this);
- item_ = NULL;
+ void OnDownloadUpdated(DownloadItem* download) override {
+ DVLOG(20) << " " << __FUNCTION__
+ << " download = " << download->DebugString(false);
+ updated_ = true;
+ DownloadItem::DownloadState new_state = download->GetState();
+ if (last_state_ == DownloadItem::IN_PROGRESS &&
+ new_state == DownloadItem::INTERRUPTED) {
+ interrupt_count_++;
}
-
- bool CheckRemoved() {
- return removed_;
+ if (last_state_ == DownloadItem::INTERRUPTED &&
+ new_state == DownloadItem::IN_PROGRESS) {
+ resume_count_++;
}
+ last_state_ = new_state;
+ }
- bool CheckDestroyed() {
- return destroyed_;
- }
+ void OnDownloadOpened(DownloadItem* download) override {
+ DVLOG(20) << " " << __FUNCTION__
+ << " download = " << download->DebugString(false);
+ }
- bool CheckUpdated() {
- bool was_updated = updated_;
- updated_ = false;
- return was_updated;
- }
+ void OnDownloadDestroyed(DownloadItem* download) override {
+ DVLOG(20) << " " << __FUNCTION__
+ << " download = " << download->DebugString(false);
+ destroyed_ = true;
+ item_->RemoveObserver(this);
+ item_ = NULL;
+ }
- int GetInterruptCount() {
- return interrupt_count_;
- }
+ DownloadItem* item_;
+ DownloadItem::DownloadState last_state_;
+ bool removed_;
+ bool destroyed_;
+ bool updated_;
+ int interrupt_count_;
+ int resume_count_;
+};
- int GetResumeCount() {
- return resume_count_;
- }
+// Schedules a task to invoke the RenameCompletionCallback with |new_path| on
+// the UI thread. Should only be used as the action for
+// MockDownloadFile::Rename as follows:
+// EXPECT_CALL(download_file, Rename*(_,_))
+// .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
+// new_path));
+ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(arg1, interrupt_reason, new_path));
+}
- private:
- DownloadItem* item_;
- DownloadItem::DownloadState last_state_;
- bool removed_;
- bool destroyed_;
- bool updated_;
- int interrupt_count_;
- int resume_count_;
- };
+} // namespace
+class DownloadItemTest : public testing::Test {
+ public:
DownloadItemTest()
: ui_thread_(BrowserThread::UI, &loop_),
file_thread_(BrowserThread::FILE, &loop_),
@@ -202,6 +196,11 @@ class DownloadItemTest : public testing::Test {
}
virtual void SetUp() {
+ base::FeatureList::ClearInstanceForTesting();
+ scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
+ feature_list->InitializeFromCommandLine(features::kDownloadResumption.name,
+ std::string());
+ base::FeatureList::SetInstance(std::move(feature_list));
}
virtual void TearDown() {
@@ -213,21 +212,21 @@ class DownloadItemTest : public testing::Test {
// be torn down at the end of the test unless DestroyDownloadItem is
// called.
DownloadItemImpl* CreateDownloadItem() {
- // Normally, the download system takes ownership of info, and is
- // responsible for deleting it. In these unit tests, however, we
- // don't call the function that deletes it, so we do so ourselves.
- scoped_ptr<DownloadCreateInfo> info_;
-
- info_.reset(new DownloadCreateInfo());
- static uint32 next_id = DownloadItem::kInvalidId + 1;
- info_->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
- info_->save_info->prompt_for_save_location = false;
- info_->url_chain.push_back(GURL());
- info_->etag = "SomethingToSatisfyResumption";
-
- DownloadItemImpl* download =
- new DownloadItemImpl(
- &delegate_, next_id++, *(info_.get()), net::BoundNetLog());
+ scoped_ptr<DownloadCreateInfo> info;
+
+ info.reset(new DownloadCreateInfo());
+ info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
+ info->save_info->prompt_for_save_location = false;
+ info->url_chain.push_back(GURL());
+ info->etag = "SomethingToSatisfyResumption";
+
+ return CreateDownloadItemWithCreateInfo(std::move(info));
+ }
+
+ DownloadItemImpl* CreateDownloadItemWithCreateInfo(
+ scoped_ptr<DownloadCreateInfo> info) {
+ DownloadItemImpl* download = new DownloadItemImpl(
+ &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog());
allocated_downloads_.insert(download);
return download;
}
@@ -250,7 +249,7 @@ class DownloadItemTest : public testing::Test {
scoped_ptr<DownloadRequestHandleInterface> request_handle(
new NiceMock<MockRequestHandle>);
- item->Start(download_file.Pass(), request_handle.Pass());
+ item->Start(std::move(download_file), std::move(request_handle));
loop_.RunUntilIdle();
// So that we don't have a function writing to a stack variable
@@ -296,7 +295,8 @@ class DownloadItemTest : public testing::Test {
EXPECT_EQ(expected_state, item->GetState());
if (expected_state == DownloadItem::IN_PROGRESS) {
- EXPECT_CALL(*download_file, Cancel());
+ if (download_file)
+ EXPECT_CALL(*download_file, Cancel());
item->Cancel(true);
loop_.RunUntilIdle();
}
@@ -322,6 +322,7 @@ class DownloadItemTest : public testing::Test {
}
private:
+ int next_download_id_ = DownloadItem::kInvalidId + 1;
base::MessageLoopForUI loop_;
TestBrowserThread ui_thread_; // UI thread
TestBrowserThread file_thread_; // FILE thread
@@ -339,10 +340,10 @@ class DownloadItemTest : public testing::Test {
TEST_F(DownloadItemTest, NotificationAfterUpdate) {
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string());
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed());
}
@@ -351,37 +352,37 @@ TEST_F(DownloadItemTest, NotificationAfterCancel) {
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(user_cancel, NULL);
EXPECT_CALL(*download_file, Cancel());
- MockObserver observer1(user_cancel);
+ TestDownloadItemObserver observer1(user_cancel);
user_cancel->Cancel(true);
- ASSERT_TRUE(observer1.CheckUpdated());
+ ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated());
DownloadItemImpl* system_cancel = CreateDownloadItem();
download_file = AddDownloadFileToDownloadItem(system_cancel, NULL);
EXPECT_CALL(*download_file, Cancel());
- MockObserver observer2(system_cancel);
+ TestDownloadItemObserver observer2(system_cancel);
system_cancel->Cancel(false);
- ASSERT_TRUE(observer2.CheckUpdated());
+ ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterComplete) {
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
item->OnAllDataSaved(DownloadItem::kEmptyFileHash);
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
item->MarkAsComplete();
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) {
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
item->OnDownloadedFileRemoved();
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterInterrupted) {
@@ -389,31 +390,28 @@ TEST_F(DownloadItemTest, NotificationAfterInterrupted) {
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_CALL(*download_file, Cancel());
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_,_))
.Times(0);
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
}
TEST_F(DownloadItemTest, NotificationAfterDestroyed) {
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
DestroyDownloadItem(item);
- ASSERT_TRUE(observer.CheckDestroyed());
+ ASSERT_TRUE(observer.download_destroyed());
}
TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
-
+ TestBrowserContext test_browser_context;
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
- DownloadItemImplDelegate::DownloadTargetCallback callback;
+ TestDownloadItemObserver observer(item);
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
@@ -421,27 +419,32 @@ TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
EXPECT_CALL(*download_file, FullPath())
.WillOnce(Return(base::FilePath()));
EXPECT_CALL(*download_file, Detach());
+ EXPECT_CALL(*mock_delegate(), GetBrowserContext())
+ .WillRepeatedly(Return(&test_browser_context));
+ EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1);
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
- ASSERT_TRUE(observer.CheckUpdated());
- // Should attempt to auto-resume. Because we don't have a mock WebContents,
- // ResumeInterruptedDownload() will abort early, with another interrupt,
- // which will be ignored.
- ASSERT_EQ(1, observer.GetInterruptCount());
- ASSERT_EQ(0, observer.GetResumeCount());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
+ // Since the download is resumed automatically, the interrupt count doesn't
+ // increase.
+ ASSERT_EQ(0, observer.interrupt_count());
+
+ // Test expectations verify that ResumeInterruptedDownload() is called (by way
+ // of MockResumeInterruptedDownload) after the download is interrupted. But
+ // the mock doesn't follow through with the resumption.
+ // ResumeInterruptedDownload() being called is sufficient for verifying that
+ // the automatic resumption was triggered.
RunAllPendingInMessageLoops();
- CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
+ // The download item is currently in RESUMING_INTERNAL state, which maps to
+ // IN_PROGRESS.
+ CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
}
// Same as above, but with a non-continuable interrupt.
TEST_F(DownloadItemTest, RestartAfterInterrupted) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
-
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
- DownloadItemImplDelegate::DownloadTargetCallback callback;
+ TestDownloadItemObserver observer(item);
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
@@ -449,23 +452,19 @@ TEST_F(DownloadItemTest, RestartAfterInterrupted) {
EXPECT_CALL(*download_file, Cancel());
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
// Should not try to auto-resume.
- ASSERT_EQ(1, observer.GetInterruptCount());
- ASSERT_EQ(0, observer.GetResumeCount());
+ ASSERT_EQ(1, observer.interrupt_count());
+ ASSERT_EQ(0, observer.resume_count());
RunAllPendingInMessageLoops();
- CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
+ CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
}
// Check we do correct cleanup for RESUME_MODE_INVALID interrupts.
TEST_F(DownloadItemTest, UnresumableInterrupt) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
-
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
- DownloadItemImplDelegate::DownloadTargetCallback callback;
+ TestDownloadItemObserver observer(item);
MockDownloadFile* download_file =
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
@@ -481,22 +480,20 @@ TEST_F(DownloadItemTest, UnresumableInterrupt) {
item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
// Should not try to auto-resume.
- ASSERT_EQ(1, observer.GetInterruptCount());
- ASSERT_EQ(0, observer.GetResumeCount());
+ ASSERT_EQ(1, observer.interrupt_count());
+ ASSERT_EQ(0, observer.resume_count());
- CleanupItem(item, download_file, DownloadItem::INTERRUPTED);
+ CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
}
TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
-
+ TestBrowserContext test_browser_context;
DownloadItemImpl* item = CreateDownloadItem();
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
MockDownloadFile* mock_download_file(NULL);
scoped_ptr<DownloadFile> download_file;
MockRequestHandle* mock_request_handle(NULL);
@@ -505,6 +502,10 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
.WillRepeatedly(SaveArg<1>(&callback));
+ EXPECT_CALL(*mock_delegate(), GetBrowserContext())
+ .WillRepeatedly(Return(&test_browser_context));
+ EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _))
+ .Times(DownloadItemImpl::kMaxAutoResumeAttempts);
for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
DVLOG(20) << "Loop iteration " << i;
@@ -516,17 +517,9 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
ON_CALL(*mock_download_file, FullPath())
.WillByDefault(Return(base::FilePath()));
- // It's too complicated to set up a WebContents instance that would cause
- // the MockDownloadItemDelegate's ResumeInterruptedDownload() function
- // to be callled, so we simply verify that GetWebContents() is called.
- if (i < (DownloadItemImpl::kMaxAutoResumeAttempts - 1)) {
- EXPECT_CALL(*mock_request_handle, GetWebContents())
- .WillRepeatedly(Return(static_cast<WebContents*>(NULL)));
- }
-
// Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem
// to allow for holding onto the request handle.
- item->Start(download_file.Pass(), request_handle.Pass());
+ item->Start(std::move(download_file), std::move(request_handle));
RunAllPendingInMessageLoops();
if (i == 0) {
// Target determination is only done the first time through.
@@ -540,17 +533,57 @@ TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
RunAllPendingInMessageLoops();
}
- ASSERT_EQ(i, observer.GetResumeCount());
// Use a continuable interrupt.
item->DestinationObserverAsWeakPtr()->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
- ASSERT_EQ(i + 1, observer.GetInterruptCount());
::testing::Mock::VerifyAndClearExpectations(mock_download_file);
}
- CleanupItem(item, mock_download_file, DownloadItem::INTERRUPTED);
+ EXPECT_EQ(1, observer.interrupt_count());
+ CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
+}
+
+// Test that resumption uses the final URL in a URL chain when resuming.
+TEST_F(DownloadItemTest, ResumeUsingFinalURL) {
+ TestBrowserContext test_browser_context;
+ scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo);
+ create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
+ create_info->save_info->prompt_for_save_location = false;
+ create_info->etag = "SomethingToSatisfyResumption";
+ create_info->url_chain.push_back(GURL("http://example.com/a"));
+ create_info->url_chain.push_back(GURL("http://example.com/b"));
+ create_info->url_chain.push_back(GURL("http://example.com/c"));
+
+ DownloadItemImpl* item =
+ CreateDownloadItemWithCreateInfo(std::move(create_info));
+ TestDownloadItemObserver observer(item);
+ MockDownloadFile* download_file =
+ DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
+
+ // Interrupt the download, using a continuable interrupt.
+ EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath()));
+ EXPECT_CALL(*download_file, Detach());
+ EXPECT_CALL(*mock_delegate(), GetBrowserContext())
+ .WillRepeatedly(Return(&test_browser_context));
+ EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(
+ Property(&DownloadUrlParameters::url,
+ GURL("http://example.com/c")),
+ _))
+ .Times(1);
+ item->DestinationObserverAsWeakPtr()->DestinationError(
+ DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
+
+ // Test expectations verify that ResumeInterruptedDownload() is called (by way
+ // of MockResumeInterruptedDownload) after the download is interrupted. But
+ // the mock doesn't follow through with the resumption.
+ // ResumeInterruptedDownload() being called is sufficient for verifying that
+ // the resumption was triggered.
+ RunAllPendingInMessageLoops();
+
+ // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS.
+ CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
}
TEST_F(DownloadItemTest, NotificationAfterRemove) {
@@ -558,47 +591,47 @@ TEST_F(DownloadItemTest, NotificationAfterRemove) {
MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL);
EXPECT_CALL(*download_file, Cancel());
EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
item->Remove();
- ASSERT_TRUE(observer.CheckUpdated());
- ASSERT_TRUE(observer.CheckRemoved());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
+ ASSERT_TRUE(observer.download_removed());
}
TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
// Setting to NOT_DANGEROUS does not trigger a notification.
DownloadItemImpl* safe_item = CreateDownloadItem();
- MockObserver safe_observer(safe_item);
+ TestDownloadItemObserver safe_observer(safe_item);
safe_item->OnAllDataSaved(std::string());
- EXPECT_TRUE(safe_observer.CheckUpdated());
+ EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
- EXPECT_TRUE(safe_observer.CheckUpdated());
+ EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
// Setting to unsafe url or unsafe file should trigger a notification.
DownloadItemImpl* unsafeurl_item =
CreateDownloadItem();
- MockObserver unsafeurl_observer(unsafeurl_item);
+ TestDownloadItemObserver unsafeurl_observer(unsafeurl_item);
unsafeurl_item->OnAllDataSaved(std::string());
- EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
+ EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
- EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
+ EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
unsafeurl_item->ValidateDangerousDownload();
- EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
+ EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
DownloadItemImpl* unsafefile_item =
CreateDownloadItem();
- MockObserver unsafefile_observer(unsafefile_item);
+ TestDownloadItemObserver unsafefile_observer(unsafefile_item);
unsafefile_item->OnAllDataSaved(std::string());
- EXPECT_TRUE(unsafefile_observer.CheckUpdated());
+ EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
- EXPECT_TRUE(unsafefile_observer.CheckUpdated());
+ EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
unsafefile_item->ValidateDangerousDownload();
- EXPECT_TRUE(unsafefile_observer.CheckUpdated());
+ EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
}
// DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run
@@ -611,7 +644,7 @@ TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
AddDownloadFileToDownloadItem(item, &callback);
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
base::FilePath target_path(kDummyPath);
base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
base::FilePath new_intermediate_path(
@@ -624,9 +657,9 @@ TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
// other than NOT_DANGEROUS.
callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
- EXPECT_FALSE(observer.CheckUpdated());
+ EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
RunAllPendingInMessageLoops();
- EXPECT_TRUE(observer.CheckUpdated());
+ EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
EXPECT_EQ(new_intermediate_path, item->GetFullPath());
CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
@@ -634,7 +667,7 @@ TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
DownloadItemImpl* item = CreateDownloadItem();
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
MockDownloadFile* mock_download_file(new MockDownloadFile);
scoped_ptr<DownloadFile> download_file(mock_download_file);
scoped_ptr<DownloadRequestHandleInterface> request_handle(
@@ -642,15 +675,15 @@ TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
EXPECT_CALL(*mock_download_file, Initialize(_));
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _));
- item->Start(download_file.Pass(), request_handle.Pass());
+ item->Start(std::move(download_file), std::move(request_handle));
item->Pause();
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
ASSERT_TRUE(item->IsPaused());
item->Resume();
- ASSERT_TRUE(observer.CheckUpdated());
+ ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
RunAllPendingInMessageLoops();
@@ -689,7 +722,7 @@ TEST_F(DownloadItemTest, Start) {
scoped_ptr<DownloadRequestHandleInterface> request_handle(
new NiceMock<MockRequestHandle>);
EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
- item->Start(download_file.Pass(), request_handle.Pass());
+ item->Start(std::move(download_file), std::move(request_handle));
RunAllPendingInMessageLoops();
CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
@@ -812,8 +845,6 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
// intermediate path should be retained when the download is interrupted after
// the intermediate rename succeeds.
TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
@@ -847,8 +878,6 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
// As above. If the intermediate rename fails, then the interrupt reason should
// be set to the destination error and the intermediate path should be empty.
TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
DownloadItemImpl* item = CreateDownloadItem();
DownloadItemImplDelegate::DownloadTargetCallback callback;
MockDownloadFile* download_file =
@@ -901,13 +930,13 @@ TEST_F(DownloadItemTest, DestinationUpdate) {
DownloadItemImpl* item = CreateDownloadItem();
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
EXPECT_EQ(0l, item->CurrentSpeed());
EXPECT_EQ("", item->GetHashState());
EXPECT_EQ(0l, item->GetReceivedBytes());
EXPECT_EQ(0l, item->GetTotalBytes());
- EXPECT_FALSE(observer.CheckUpdated());
+ EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
item->SetTotalBytes(100l);
EXPECT_EQ(100l, item->GetTotalBytes());
@@ -916,14 +945,14 @@ TEST_F(DownloadItemTest, DestinationUpdate) {
EXPECT_EQ("deadbeef", item->GetHashState());
EXPECT_EQ(10l, item->GetReceivedBytes());
EXPECT_EQ(100l, item->GetTotalBytes());
- EXPECT_TRUE(observer.CheckUpdated());
+ EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
as_observer->DestinationUpdate(200, 20, "livebeef");
EXPECT_EQ(20l, item->CurrentSpeed());
EXPECT_EQ("livebeef", item->GetHashState());
EXPECT_EQ(200l, item->GetReceivedBytes());
EXPECT_EQ(0l, item->GetTotalBytes());
- EXPECT_TRUE(observer.CheckUpdated());
+ EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
}
TEST_F(DownloadItemTest, DestinationError) {
@@ -932,17 +961,17 @@ TEST_F(DownloadItemTest, DestinationError) {
DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason());
- EXPECT_FALSE(observer.CheckUpdated());
+ EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
EXPECT_CALL(*download_file, Cancel());
as_observer->DestinationError(
DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
mock_delegate()->VerifyAndClearExpectations();
- EXPECT_TRUE(observer.CheckUpdated());
+ EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
item->GetLastReason());
@@ -952,17 +981,17 @@ TEST_F(DownloadItemTest, DestinationCompleted) {
DownloadItemImpl* item = CreateDownloadItem();
base::WeakPtr<DownloadDestinationObserver> as_observer(
item->DestinationObserverAsWeakPtr());
- MockObserver observer(item);
+ TestDownloadItemObserver observer(item);
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_EQ("", item->GetHash());
EXPECT_EQ("", item->GetHashState());
EXPECT_FALSE(item->AllDataSaved());
- EXPECT_FALSE(observer.CheckUpdated());
+ EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
as_observer->DestinationUpdate(10, 20, "deadbeef");
- EXPECT_TRUE(observer.CheckUpdated());
- EXPECT_FALSE(observer.CheckUpdated()); // Confirm reset.
+ EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
+ EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset.
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_EQ("", item->GetHash());
EXPECT_EQ("deadbeef", item->GetHashState());
@@ -971,7 +1000,7 @@ TEST_F(DownloadItemTest, DestinationCompleted) {
as_observer->DestinationCompleted("livebeef");
mock_delegate()->VerifyAndClearExpectations();
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
- EXPECT_TRUE(observer.CheckUpdated());
+ EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
EXPECT_EQ("livebeef", item->GetHash());
EXPECT_EQ("", item->GetHashState());
EXPECT_TRUE(item->AllDataSaved());
@@ -1247,8 +1276,6 @@ TEST_F(DownloadItemTest, StealDangerousDownload) {
}
TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
base::FilePath returned_path;
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
@@ -1273,8 +1300,6 @@ TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
}
TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
base::FilePath returned_path;
DownloadItemImpl* item = CreateDownloadItem();
MockDownloadFile* download_file =
diff --git a/chromium/content/browser/download/download_manager_impl.cc b/chromium/content/browser/download/download_manager_impl.cc
index 7562c0f3619..97c0a85e714 100644
--- a/chromium/content/browser/download/download_manager_impl.cc
+++ b/chromium/content/browser/download/download_manager_impl.cc
@@ -5,12 +5,14 @@
#include "content/browser/download/download_manager_impl.h"
#include <iterator>
+#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/debug/alias.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
@@ -28,7 +30,6 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_manager_delegate.h"
@@ -49,8 +50,10 @@
namespace content {
namespace {
-void BeginDownload(scoped_ptr<DownloadUrlParameters> params,
- uint32 download_id) {
+scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread> BeginDownload(
+ scoped_ptr<DownloadUrlParameters> params,
+ uint32_t download_id,
+ base::WeakPtr<DownloadManagerImpl> download_manager) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and
// DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so
@@ -64,7 +67,7 @@ void BeginDownload(scoped_ptr<DownloadUrlParameters> params,
scoped_ptr<net::UploadElementReader> reader(
net::UploadOwnedBytesElementReader::CreateWithString(body));
request->set_upload(
- net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ net::ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
}
if (params->post_id() >= 0) {
// The POST in this case does not have an actual body, and only works
@@ -73,10 +76,9 @@ void BeginDownload(scoped_ptr<DownloadUrlParameters> params,
// plan on how to display the UI for that.
DCHECK(params->prefer_cache());
DCHECK_EQ("POST", params->method());
- ScopedVector<net::UploadElementReader> element_readers;
- request->set_upload(make_scoped_ptr(
- new net::ElementsUploadDataStream(element_readers.Pass(),
- params->post_id())));
+ std::vector<scoped_ptr<net::UploadElementReader>> element_readers;
+ request->set_upload(make_scoped_ptr(new net::ElementsUploadDataStream(
+ std::move(element_readers), params->post_id())));
}
// If we're not at the beginning of the file, retrieve only the remaining
@@ -89,20 +91,21 @@ void BeginDownload(scoped_ptr<DownloadUrlParameters> params,
// We shouldn't be asked to continue if we don't have a verifier.
DCHECK(params->offset() == 0 || has_etag || has_last_modified);
- if (params->offset() > 0) {
+ if (params->offset() > 0 && (has_etag || has_last_modified)) {
request->SetExtraRequestHeaderByName(
"Range",
base::StringPrintf("bytes=%" PRId64 "-", params->offset()),
true);
- if (has_last_modified) {
- request->SetExtraRequestHeaderByName("If-Unmodified-Since",
- params->last_modified(),
- true);
- }
- if (has_etag) {
- request->SetExtraRequestHeaderByName("If-Match", params->etag(), true);
- }
+ // In accordance with RFC 2616 Section 14.27, use If-Range to specify that
+ // the server return the entire entity if the validator doesn't match.
+ // Last-Modified can be used in the absence of ETag as a validator if the
+ // response headers satisfied the HttpUtil::HasStrongValidators() predicate.
+ //
+ // This function assumes that HasStrongValidators() was true and that the
+ // ETag and Last-Modified header values supplied are valid.
+ request->SetExtraRequestHeaderByName(
+ "If-Range", has_etag ? params->etag() : params->last_modified(), true);
}
for (DownloadUrlParameters::RequestHeadersType::const_iterator iter
@@ -121,44 +124,23 @@ void BeginDownload(scoped_ptr<DownloadUrlParameters> params,
save_info->prompt_for_save_location = params->prompt();
save_info->file = params->GetFile();
- ResourceDispatcherHost::Get()->BeginDownload(
- request.Pass(),
- params->referrer(),
- params->content_initiated(),
- params->resource_context(),
- params->render_process_host_id(),
- params->render_view_host_routing_id(),
- params->render_frame_host_routing_id(),
- params->prefer_cache(),
- params->do_not_prompt_for_login(),
- save_info.Pass(),
- download_id,
- params->callback());
-}
-
-class MapValueIteratorAdapter {
- public:
- explicit MapValueIteratorAdapter(
- base::hash_map<int64, DownloadItem*>::const_iterator iter)
- : iter_(iter) {
- }
- ~MapValueIteratorAdapter() {}
-
- DownloadItem* operator*() { return iter_->second; }
-
- MapValueIteratorAdapter& operator++() {
- ++iter_;
- return *this;
- }
-
- bool operator!=(const MapValueIteratorAdapter& that) const {
- return iter_ != that.iter_;
+ if (params->render_process_host_id() != -1) {
+ ResourceDispatcherHost::Get()->BeginDownload(
+ std::move(request), params->referrer(), params->content_initiated(),
+ params->resource_context(), params->render_process_host_id(),
+ params->render_view_host_routing_id(),
+ params->render_frame_host_routing_id(), params->prefer_cache(),
+ params->do_not_prompt_for_login(), std::move(save_info), download_id,
+ params->callback());
+ return nullptr;
}
-
- private:
- base::hash_map<int64, DownloadItem*>::const_iterator iter_;
- // Allow copy and assign.
-};
+ return scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>(
+ UrlDownloader::BeginDownload(download_manager, std::move(request),
+ params->referrer(), params->prefer_cache(),
+ std::move(save_info), download_id,
+ params->callback())
+ .release());
+}
class DownloadItemFactoryImpl : public DownloadItemFactory {
public:
@@ -167,7 +149,7 @@ class DownloadItemFactoryImpl : public DownloadItemFactory {
DownloadItemImpl* CreatePersistedItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -178,8 +160,8 @@ class DownloadItemFactoryImpl : public DownloadItemFactory {
const base::Time& end_time,
const std::string& etag,
const std::string& last_modified,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -209,7 +191,7 @@ class DownloadItemFactoryImpl : public DownloadItemFactory {
DownloadItemImpl* CreateActiveItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) override {
return new DownloadItemImpl(delegate, download_id, info, bound_net_log);
@@ -217,15 +199,14 @@ class DownloadItemFactoryImpl : public DownloadItemFactory {
DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log) override {
- return new DownloadItemImpl(delegate, download_id, path, url,
- mime_type, request_handle.Pass(),
- bound_net_log);
+ return new DownloadItemImpl(delegate, download_id, path, url, mime_type,
+ std::move(request_handle), bound_net_log);
}
};
@@ -250,7 +231,8 @@ DownloadManagerImpl::~DownloadManagerImpl() {
}
DownloadItemImpl* DownloadManagerImpl::CreateActiveItem(
- uint32 id, const DownloadCreateInfo& info) {
+ uint32_t id,
+ const DownloadCreateInfo& info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!ContainsKey(downloads_, id));
net::BoundNetLog bound_net_log =
@@ -267,7 +249,7 @@ void DownloadManagerImpl::GetNextId(const DownloadIdCallback& callback) {
delegate_->GetNextId(callback);
return;
}
- static uint32 next_id = content::DownloadItem::kInvalidId + 1;
+ static uint32_t next_id = content::DownloadItem::kInvalidId + 1;
callback.Run(next_id++);
}
@@ -347,6 +329,7 @@ void DownloadManagerImpl::Shutdown() {
download->Cancel(false);
}
STLDeleteValues(&downloads_);
+ url_downloaders_.clear();
// We'll have nothing more to report to the observers after this point.
observers_.Clear();
@@ -362,15 +345,11 @@ void DownloadManagerImpl::StartDownload(
const DownloadUrlParameters::OnStartedCallback& on_started) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(info);
- uint32 download_id = info->download_id;
+ uint32_t download_id = info->download_id;
const bool new_download = (download_id == content::DownloadItem::kInvalidId);
- base::Callback<void(uint32)> got_id(base::Bind(
- &DownloadManagerImpl::StartDownloadWithId,
- weak_factory_.GetWeakPtr(),
- base::Passed(info.Pass()),
- base::Passed(stream.Pass()),
- on_started,
- new_download));
+ base::Callback<void(uint32_t)> got_id(base::Bind(
+ &DownloadManagerImpl::StartDownloadWithId, weak_factory_.GetWeakPtr(),
+ base::Passed(&info), base::Passed(&stream), on_started, new_download));
if (new_download) {
GetNextId(got_id);
} else {
@@ -383,7 +362,7 @@ void DownloadManagerImpl::StartDownloadWithId(
scoped_ptr<ByteStreamReader> stream,
const DownloadUrlParameters::OnStartedCallback& on_started,
bool new_download,
- uint32 id) {
+ uint32_t id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(content::DownloadItem::kInvalidId, id);
DownloadItemImpl* download = NULL;
@@ -397,13 +376,16 @@ void DownloadManagerImpl::StartDownloadWithId(
// If the download is no longer known to the DownloadManager, then it was
// removed after it was resumed. Ignore. If the download is cancelled
// while resuming, then also ignore the request.
- info->request_handle.CancelRequest();
+ info->request_handle->CancelRequest();
if (!on_started.is_null())
on_started.Run(NULL, DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
+ // The ByteStreamReader lives and dies on the FILE thread.
+ BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE,
+ stream.release());
return;
}
download = item_iterator->second;
- DCHECK_EQ(DownloadItem::INTERRUPTED, download->GetState());
+ DCHECK_EQ(download->GetState(), DownloadItem::IN_PROGRESS);
download->MergeOriginInfoOnResume(*info);
}
@@ -416,13 +398,11 @@ void DownloadManagerImpl::StartDownloadWithId(
}
// Create the download file and start the download.
- scoped_ptr<DownloadFile> download_file(
- file_factory_->CreateFile(
- info->save_info.Pass(), default_download_directory,
- info->url(), info->referrer_url,
- delegate_ && delegate_->GenerateFileHash(),
- stream.Pass(), download->GetBoundNetLog(),
- download->DestinationObserverAsWeakPtr()));
+ scoped_ptr<DownloadFile> download_file(file_factory_->CreateFile(
+ std::move(info->save_info), default_download_directory, info->url(),
+ info->referrer_url, delegate_ && delegate_->GenerateFileHash(),
+ std::move(stream), download->GetBoundNetLog(),
+ download->DestinationObserverAsWeakPtr()));
// Attach the client ID identifying the app to the AV system.
if (download_file.get() && delegate_) {
@@ -430,9 +410,7 @@ void DownloadManagerImpl::StartDownloadWithId(
delegate_->ApplicationClientIdForFileScanning());
}
- scoped_ptr<DownloadRequestHandleInterface> req_handle(
- new DownloadRequestHandle(info->request_handle));
- download->Start(download_file.Pass(), req_handle.Pass());
+ download->Start(std::move(download_file), std::move(info->request_handle));
// For interrupted downloads, Start() will transition the state to
// IN_PROGRESS and consumers will be notified via OnDownloadUpdated().
@@ -467,7 +445,7 @@ void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) {
}
}
-void DownloadManagerImpl::OnFileExistenceChecked(uint32 download_id,
+void DownloadManagerImpl::OnFileExistenceChecked(uint32_t download_id,
bool result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!result) { // File does not exist.
@@ -489,12 +467,8 @@ void DownloadManagerImpl::CreateSavePackageDownloadItem(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
GetNextId(base::Bind(
&DownloadManagerImpl::CreateSavePackageDownloadItemWithId,
- weak_factory_.GetWeakPtr(),
- main_file_path,
- page_url,
- mime_type,
- base::Passed(request_handle.Pass()),
- item_created));
+ weak_factory_.GetWeakPtr(), main_file_path, page_url, mime_type,
+ base::Passed(std::move(request_handle)), item_created));
}
void DownloadManagerImpl::CreateSavePackageDownloadItemWithId(
@@ -503,19 +477,14 @@ void DownloadManagerImpl::CreateSavePackageDownloadItemWithId(
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const DownloadItemImplCreated& item_created,
- uint32 id) {
+ uint32_t id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(content::DownloadItem::kInvalidId, id);
DCHECK(!ContainsKey(downloads_, id));
net::BoundNetLog bound_net_log =
net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
DownloadItemImpl* download_item = item_factory_->CreateSavePageItem(
- this,
- id,
- main_file_path,
- page_url,
- mime_type,
- request_handle.Pass(),
+ this, id, main_file_path, page_url, mime_type, std::move(request_handle),
bound_net_log);
downloads_[download_item->GetId()] = download_item;
FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(
@@ -535,22 +504,24 @@ void DownloadManagerImpl::OnSavePackageSuccessfullyFinished(
// download.
void DownloadManagerImpl::ResumeInterruptedDownload(
scoped_ptr<content::DownloadUrlParameters> params,
- uint32 id) {
+ uint32_t id) {
RecordDownloadSource(INITIATED_BY_RESUMPTION);
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&BeginDownload, base::Passed(&params), id));
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&BeginDownload, base::Passed(&params), id,
+ weak_factory_.GetWeakPtr()),
+ base::Bind(&DownloadManagerImpl::AddUrlDownloader,
+ weak_factory_.GetWeakPtr()));
}
void DownloadManagerImpl::SetDownloadItemFactoryForTesting(
scoped_ptr<DownloadItemFactory> item_factory) {
- item_factory_ = item_factory.Pass();
+ item_factory_ = std::move(item_factory);
}
void DownloadManagerImpl::SetDownloadFileFactoryForTesting(
scoped_ptr<DownloadFileFactory> file_factory) {
- file_factory_ = file_factory.Pass();
+ file_factory_ = std::move(file_factory);
}
DownloadFileFactory* DownloadManagerImpl::GetDownloadFileFactoryForTesting() {
@@ -561,12 +532,28 @@ void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) {
if (!download)
return;
- uint32 download_id = download->GetId();
+ uint32_t download_id = download->GetId();
if (downloads_.erase(download_id) == 0)
return;
delete download;
}
+void DownloadManagerImpl::AddUrlDownloader(
+ scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread> downloader) {
+ if (downloader)
+ url_downloaders_.push_back(std::move(downloader));
+}
+
+void DownloadManagerImpl::RemoveUrlDownloader(UrlDownloader* downloader) {
+ for (auto ptr = url_downloaders_.begin(); ptr != url_downloaders_.end();
+ ++ptr) {
+ if (ptr->get() == downloader) {
+ url_downloaders_.erase(ptr);
+ return;
+ }
+ }
+}
+
namespace {
bool RemoveDownloadBetween(base::Time remove_begin,
@@ -637,9 +624,12 @@ void DownloadManagerImpl::DownloadUrl(
DCHECK(params->prefer_cache());
DCHECK_EQ("POST", params->method());
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &BeginDownload, base::Passed(&params),
- content::DownloadItem::kInvalidId));
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&BeginDownload, base::Passed(&params),
+ content::DownloadItem::kInvalidId, weak_factory_.GetWeakPtr()),
+ base::Bind(&DownloadManagerImpl::AddUrlDownloader,
+ weak_factory_.GetWeakPtr()));
}
void DownloadManagerImpl::AddObserver(Observer* observer) {
@@ -651,7 +641,7 @@ void DownloadManagerImpl::RemoveObserver(Observer* observer) {
}
DownloadItem* DownloadManagerImpl::CreateDownloadItem(
- uint32 id,
+ uint32_t id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -662,8 +652,8 @@ DownloadItem* DownloadManagerImpl::CreateDownloadItem(
const base::Time& end_time,
const std::string& etag,
const std::string& last_modified,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -724,7 +714,7 @@ int DownloadManagerImpl::NonMaliciousInProgressCount() const {
return count;
}
-DownloadItem* DownloadManagerImpl::GetDownload(uint32 download_id) {
+DownloadItem* DownloadManagerImpl::GetDownload(uint32_t download_id) {
return ContainsKey(downloads_, download_id) ? downloads_[download_id] : NULL;
}
diff --git a/chromium/content/browser/download/download_manager_impl.h b/chromium/content/browser/download/download_manager_impl.h
index 372fd58b616..ebac07ab081 100644
--- a/chromium/content/browser/download/download_manager_impl.h
+++ b/chromium/content/browser/download/download_manager_impl.h
@@ -5,12 +5,16 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_IMPL_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_IMPL_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
+#include <vector>
#include "base/callback_forward.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -18,7 +22,9 @@
#include "base/sequenced_task_runner_helpers.h"
#include "base/synchronization/lock.h"
#include "content/browser/download/download_item_impl_delegate.h"
+#include "content/browser/download/url_downloader.h"
#include "content/common/content_export.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/download_url_parameters.h"
@@ -79,7 +85,7 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
content::DownloadItem* CreateDownloadItem(
- uint32 id,
+ uint32_t id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -90,8 +96,8 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
const base::Time& end_time,
const std::string& etag,
const std::string& last_modified,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
content::DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -100,7 +106,7 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
int NonMaliciousInProgressCount() const override;
BrowserContext* GetBrowserContext() const override;
void CheckForHistoryFilesRemoval() override;
- DownloadItem* GetDownload(uint32 id) override;
+ DownloadItem* GetDownload(uint32_t id) override;
// For testing; specifically, accessed from TestFileErrorInjector.
void SetDownloadItemFactoryForTesting(
@@ -109,9 +115,11 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
scoped_ptr<DownloadFileFactory> file_factory);
virtual DownloadFileFactory* GetDownloadFileFactoryForTesting();
+ void RemoveUrlDownloader(UrlDownloader* downloader);
+
private:
typedef std::set<DownloadItem*> DownloadSet;
- typedef base::hash_map<uint32, DownloadItemImpl*> DownloadMap;
+ typedef base::hash_map<uint32_t, DownloadItemImpl*> DownloadMap;
typedef std::vector<DownloadItemImpl*> DownloadItemImplVector;
typedef base::Callback<bool(const DownloadItemImpl*)> DownloadRemover;
@@ -124,7 +132,7 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
scoped_ptr<ByteStreamReader> stream,
const DownloadUrlParameters::OnStartedCallback& on_started,
bool new_download,
- uint32 id);
+ uint32_t id);
void CreateSavePackageDownloadItemWithId(
const base::FilePath& main_file_path,
@@ -132,11 +140,11 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const DownloadItemImplCreated& on_started,
- uint32 id);
+ uint32_t id);
// Create a new active item based on the info. Separate from
// StartDownload() for testing.
- DownloadItemImpl* CreateActiveItem(uint32 id,
+ DownloadItemImpl* CreateActiveItem(uint32_t id,
const DownloadCreateInfo& info);
// Get next download id. |callback| is called on the UI thread and may
@@ -146,7 +154,7 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
// Called with the result of DownloadManagerDelegate::CheckForFileExistence.
// Updates the state of the file and then notifies this update to the file's
// observer.
- void OnFileExistenceChecked(uint32 download_id, bool result);
+ void OnFileExistenceChecked(uint32_t download_id, bool result);
// Remove all downloads for which |remover| returns true.
int RemoveDownloads(const DownloadRemover& remover);
@@ -163,11 +171,14 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
void CheckForFileRemoval(DownloadItemImpl* download_item) override;
void ResumeInterruptedDownload(
scoped_ptr<content::DownloadUrlParameters> params,
- uint32 id) override;
+ uint32_t id) override;
void OpenDownload(DownloadItemImpl* download) override;
void ShowDownloadInShell(DownloadItemImpl* download) override;
void DownloadRemoved(DownloadItemImpl* download) override;
+ void AddUrlDownloader(
+ scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread> downloader);
+
// Factory for creation of downloads items.
scoped_ptr<DownloadItemFactory> item_factory_;
@@ -196,6 +207,9 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
net::NetLog* net_log_;
+ std::vector<scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>>
+ url_downloaders_;
+
base::WeakPtrFactory<DownloadManagerImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DownloadManagerImpl);
diff --git a/chromium/content/browser/download/download_manager_impl_unittest.cc b/chromium/content/browser/download/download_manager_impl_unittest.cc
index d4f923370b6..78d13863470 100644
--- a/chromium/content/browser/download/download_manager_impl_unittest.cc
+++ b/chromium/content/browser/download/download_manager_impl_unittest.cc
@@ -2,11 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/download/download_manager_impl.h"
+
+#include <stddef.h>
+#include <stdint.h>
#include <set>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -21,7 +27,6 @@
#include "content/browser/download/download_item_factory.h"
#include "content/browser/download/download_item_impl.h"
#include "content/browser/download/download_item_impl_delegate.h"
-#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_request_handle.h"
#include "content/browser/download/mock_download_file.h"
#include "content/public/browser/browser_context.h"
@@ -106,7 +111,7 @@ class MockDownloadItemImpl : public DownloadItemImpl {
MOCK_METHOD0(ShowDownloadInShell, void());
MOCK_METHOD0(ValidateDangerousDownload, void());
MOCK_METHOD1(StealDangerousDownload, void(const AcquireFileCallback&));
- MOCK_METHOD3(UpdateProgress, void(int64, int64, const std::string&));
+ MOCK_METHOD3(UpdateProgress, void(int64_t, int64_t, const std::string&));
MOCK_METHOD1(Cancel, void(bool));
MOCK_METHOD0(MarkAsComplete, void());
MOCK_METHOD1(OnAllDataSaved, void(const std::string&));
@@ -120,7 +125,7 @@ class MockDownloadItemImpl : public DownloadItemImpl {
MOCK_METHOD0(Remove, void());
MOCK_CONST_METHOD1(TimeRemaining, bool(base::TimeDelta*));
- MOCK_CONST_METHOD0(CurrentSpeed, int64());
+ MOCK_CONST_METHOD0(CurrentSpeed, int64_t());
MOCK_CONST_METHOD0(PercentComplete, int());
MOCK_CONST_METHOD0(AllDataSaved, bool());
MOCK_CONST_METHOD1(MatchesQuery, bool(const base::string16& query));
@@ -131,7 +136,7 @@ class MockDownloadItemImpl : public DownloadItemImpl {
MOCK_METHOD1(OnContentCheckCompleted, void(DownloadDangerType));
MOCK_CONST_METHOD0(GetState, DownloadState());
MOCK_CONST_METHOD0(GetUrlChain, const std::vector<GURL>&());
- MOCK_METHOD1(SetTotalBytes, void(int64));
+ MOCK_METHOD1(SetTotalBytes, void(int64_t));
MOCK_CONST_METHOD0(GetURL, const GURL&());
MOCK_CONST_METHOD0(GetOriginalUrl, const GURL&());
MOCK_CONST_METHOD0(GetReferrerUrl, const GURL&());
@@ -143,11 +148,11 @@ class MockDownloadItemImpl : public DownloadItemImpl {
MOCK_CONST_METHOD0(GetOriginalMimeType, std::string());
MOCK_CONST_METHOD0(GetReferrerCharset, std::string());
MOCK_CONST_METHOD0(GetRemoteAddress, std::string());
- MOCK_CONST_METHOD0(GetTotalBytes, int64());
- MOCK_CONST_METHOD0(GetReceivedBytes, int64());
+ MOCK_CONST_METHOD0(GetTotalBytes, int64_t());
+ MOCK_CONST_METHOD0(GetReceivedBytes, int64_t());
MOCK_CONST_METHOD0(GetHashState, const std::string&());
MOCK_CONST_METHOD0(GetHash, const std::string&());
- MOCK_CONST_METHOD0(GetId, uint32());
+ MOCK_CONST_METHOD0(GetId, uint32_t());
MOCK_CONST_METHOD0(GetStartTime, base::Time());
MOCK_CONST_METHOD0(GetEndTime, base::Time());
MOCK_METHOD0(GetDownloadManager, DownloadManager*());
@@ -232,7 +237,7 @@ class MockDownloadItemFactory
// Overridden methods from DownloadItemFactory.
DownloadItemImpl* CreatePersistedItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -243,8 +248,8 @@ class MockDownloadItemFactory
const base::Time& end_time,
const std::string& etag,
const std::string& last_modofied,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -252,12 +257,12 @@ class MockDownloadItemFactory
const net::BoundNetLog& bound_net_log) override;
DownloadItemImpl* CreateActiveItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) override;
DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
@@ -265,7 +270,7 @@ class MockDownloadItemFactory
const net::BoundNetLog& bound_net_log) override;
private:
- std::map<uint32, MockDownloadItemImpl*> items_;
+ std::map<uint32_t, MockDownloadItemImpl*> items_;
DownloadItemImplDelegate item_delegate_;
DISALLOW_COPY_AND_ASSIGN(MockDownloadItemFactory);
@@ -285,8 +290,8 @@ MockDownloadItemImpl* MockDownloadItemFactory::PopItem() {
if (items_.empty())
return NULL;
- std::map<uint32, MockDownloadItemImpl*>::iterator first_item
- = items_.begin();
+ std::map<uint32_t, MockDownloadItemImpl*>::iterator first_item =
+ items_.begin();
MockDownloadItemImpl* result = first_item->second;
items_.erase(first_item);
return result;
@@ -299,7 +304,7 @@ void MockDownloadItemFactory::RemoveItem(int id) {
DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
@@ -310,8 +315,8 @@ DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem(
const base::Time& end_time,
const std::string& etag,
const std::string& last_modified,
- int64 received_bytes,
- int64 total_bytes,
+ int64_t received_bytes,
+ int64_t total_bytes,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
@@ -328,7 +333,7 @@ DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem(
DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) {
DCHECK(items_.find(download_id) == items_.end());
@@ -348,7 +353,7 @@ DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem(
DownloadItemImpl* MockDownloadItemFactory::CreateSavePageItem(
DownloadItemImplDelegate* delegate,
- uint32 download_id,
+ uint32_t download_id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
@@ -422,6 +427,7 @@ class MockBrowserContext : public BrowserContext {
MOCK_METHOD0(GetPushMessagingService, PushMessagingService*());
MOCK_METHOD0(GetSSLHostStateDelegate, SSLHostStateDelegate*());
MOCK_METHOD0(GetPermissionManager, PermissionManager*());
+ MOCK_METHOD0(GetBackgroundSyncController, BackgroundSyncController*());
scoped_ptr<ZoomLevelDelegate> CreateZoomLevelDelegate(
const base::FilePath& path) override {
@@ -436,8 +442,7 @@ class MockDownloadManagerObserver : public DownloadManager::Observer {
MOCK_METHOD2(OnDownloadCreated, void(
DownloadManager*, DownloadItem*));
MOCK_METHOD1(ManagerGoingDown, void(DownloadManager*));
- MOCK_METHOD2(SelectFileDialogDisplayed, void(
- DownloadManager*, int32));
+ MOCK_METHOD2(SelectFileDialogDisplayed, void(DownloadManager*, int32_t));
};
} // namespace
@@ -476,11 +481,9 @@ class DownloadManagerTest : public testing::Test {
download_manager_.reset(new DownloadManagerImpl(
NULL, mock_browser_context_.get()));
download_manager_->SetDownloadItemFactoryForTesting(
- scoped_ptr<DownloadItemFactory>(
- mock_download_item_factory_.get()).Pass());
+ scoped_ptr<DownloadItemFactory>(mock_download_item_factory_.get()));
download_manager_->SetDownloadFileFactoryForTesting(
- scoped_ptr<DownloadFileFactory>(
- mock_download_file_factory_.get()).Pass());
+ scoped_ptr<DownloadFileFactory>(mock_download_file_factory_.get()));
observer_.reset(new MockDownloadManagerObserver());
download_manager_->AddObserver(observer_.get());
download_manager_->SetDelegate(mock_download_manager_delegate_.get());
@@ -516,9 +519,9 @@ class DownloadManagerTest : public testing::Test {
// Args are ignored except for download id, so everything else can be
// null.
- uint32 id = next_download_id_;
+ uint32_t id = next_download_id_;
++next_download_id_;
- info.request_handle = DownloadRequestHandle();
+ info.request_handle.reset(new DownloadRequestHandle);
download_manager_->CreateActiveItem(id, info);
DCHECK(mock_download_item_factory_->GetItem(id));
MockDownloadItemImpl& item(*mock_download_item_factory_->GetItem(id));
@@ -526,7 +529,7 @@ class DownloadManagerTest : public testing::Test {
// we call Start on it immediately, so we need to set that expectation
// in the factory.
scoped_ptr<DownloadRequestHandleInterface> req_handle;
- item.Start(scoped_ptr<DownloadFile>(), req_handle.Pass());
+ item.Start(scoped_ptr<DownloadFile>(), std::move(req_handle));
DCHECK(id < download_urls_.size());
EXPECT_CALL(item, GetURL()).WillRepeatedly(ReturnRef(download_urls_[id]));
@@ -594,7 +597,7 @@ class DownloadManagerTest : public testing::Test {
scoped_ptr<MockDownloadManagerDelegate> mock_download_manager_delegate_;
scoped_ptr<MockBrowserContext> mock_browser_context_;
scoped_ptr<MockDownloadManagerObserver> observer_;
- uint32 next_download_id_;
+ uint32_t next_download_id_;
DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest);
};
@@ -603,7 +606,7 @@ class DownloadManagerTest : public testing::Test {
TEST_F(DownloadManagerTest, StartDownload) {
scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
scoped_ptr<ByteStreamReader> stream;
- uint32 local_id(5); // Random value
+ uint32_t local_id(5); // Random value
base::FilePath download_path(FILE_PATH_LITERAL("download/path"));
EXPECT_FALSE(download_manager_->GetDownload(local_id));
@@ -627,8 +630,8 @@ TEST_F(DownloadManagerTest, StartDownload) {
stream.get(), _, _))
.WillOnce(Return(mock_file));
- download_manager_->StartDownload(
- info.Pass(), stream.Pass(), DownloadUrlParameters::OnStartedCallback());
+ download_manager_->StartDownload(std::move(info), std::move(stream),
+ DownloadUrlParameters::OnStartedCallback());
EXPECT_TRUE(download_manager_->GetDownload(local_id));
}
@@ -672,7 +675,7 @@ TEST_F(DownloadManagerTest, DetermineDownloadTarget_False) {
// Confirm the DownloadManagerImpl::RemoveAllDownloads() functionality
TEST_F(DownloadManagerTest, RemoveAllDownloads) {
base::Time now(base::Time::Now());
- for (uint32 i = 0; i < 4; ++i) {
+ for (uint32_t i = 0; i < 4; ++i) {
MockDownloadItemImpl& item(AddItemToManager());
EXPECT_EQ(i, item.GetId());
EXPECT_CALL(item, GetStartTime())
@@ -707,7 +710,7 @@ TEST_F(DownloadManagerTest, RemoveAllDownloads) {
// Confirm that only downloads with same origin are removed.
TEST_F(DownloadManagerTest, RemoveSameOriginDownloads) {
base::Time now(base::Time::Now());
- for (uint32 i = 0; i < 2; ++i) {
+ for (uint32_t i = 0; i < 2; ++i) {
MockDownloadItemImpl& item(AddItemToManager());
EXPECT_CALL(item, GetStartTime()).WillRepeatedly(Return(now));
EXPECT_CALL(item, GetState())
diff --git a/chromium/content/browser/download/download_net_log_parameters.cc b/chromium/content/browser/download/download_net_log_parameters.cc
index 6aefb821f4d..e81c813af2f 100644
--- a/chromium/content/browser/download/download_net_log_parameters.cc
+++ b/chromium/content/browser/download/download_net_log_parameters.cc
@@ -4,9 +4,11 @@
#include "content/browser/download/download_net_log_parameters.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "content/public/browser/download_interrupt_reasons.h"
@@ -59,7 +61,7 @@ scoped_ptr<base::Value> ItemActivatedNetLogCallback(
base::Int64ToString(download_item->GetReceivedBytes()));
dict->SetBoolean("has_user_gesture", download_item->HasUserGesture());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> ItemCheckedNetLogCallback(
@@ -69,7 +71,7 @@ scoped_ptr<base::Value> ItemCheckedNetLogCallback(
dict->SetString("danger_type", download_danger_names[danger_type]);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> ItemRenamedNetLogCallback(
@@ -81,12 +83,12 @@ scoped_ptr<base::Value> ItemRenamedNetLogCallback(
dict->SetString("old_filename", old_filename->AsUTF8Unsafe());
dict->SetString("new_filename", new_filename->AsUTF8Unsafe());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> ItemInterruptedNetLogCallback(
DownloadInterruptReason reason,
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* hash_state,
net::NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -96,13 +98,13 @@ scoped_ptr<base::Value> ItemInterruptedNetLogCallback(
dict->SetString("hash_state",
base::HexEncode(hash_state->data(), hash_state->size()));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> ItemResumingNetLogCallback(
bool user_initiated,
DownloadInterruptReason reason,
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* hash_state,
net::NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -113,11 +115,11 @@ scoped_ptr<base::Value> ItemResumingNetLogCallback(
dict->SetString("hash_state",
base::HexEncode(hash_state->data(), hash_state->size()));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> ItemCompletingNetLogCallback(
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* final_hash,
net::NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -126,7 +128,7 @@ scoped_ptr<base::Value> ItemCompletingNetLogCallback(
dict->SetString("final_hash",
base::HexEncode(final_hash->data(), final_hash->size()));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> ItemFinishedNetLogCallback(
@@ -136,11 +138,11 @@ scoped_ptr<base::Value> ItemFinishedNetLogCallback(
dict->SetString("auto_opened", auto_opened ? "yes" : "no");
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> ItemCanceledNetLogCallback(
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* hash_state,
net::NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -149,19 +151,19 @@ scoped_ptr<base::Value> ItemCanceledNetLogCallback(
dict->SetString("hash_state",
base::HexEncode(hash_state->data(), hash_state->size()));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> FileOpenedNetLogCallback(
const base::FilePath* file_name,
- int64 start_offset,
+ int64_t start_offset,
net::NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("file_name", file_name->AsUTF8Unsafe());
dict->SetString("start_offset", base::Int64ToString(start_offset));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> FileStreamDrainedNetLogCallback(
@@ -173,7 +175,7 @@ scoped_ptr<base::Value> FileStreamDrainedNetLogCallback(
dict->SetInteger("stream_size", static_cast<int>(stream_size));
dict->SetInteger("num_buffers", static_cast<int>(num_buffers));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> FileRenamedNetLogCallback(
@@ -185,7 +187,7 @@ scoped_ptr<base::Value> FileRenamedNetLogCallback(
dict->SetString("old_filename", old_filename->AsUTF8Unsafe());
dict->SetString("new_filename", new_filename->AsUTF8Unsafe());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> FileErrorNetLogCallback(
@@ -197,7 +199,7 @@ scoped_ptr<base::Value> FileErrorNetLogCallback(
dict->SetString("operation", operation);
dict->SetInteger("net_error", net_error);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> FileInterruptedNetLogCallback(
@@ -212,7 +214,7 @@ scoped_ptr<base::Value> FileInterruptedNetLogCallback(
dict->SetInteger("os_error", os_error);
dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason));
- return dict.Pass();
+ return std::move(dict);
}
} // namespace content
diff --git a/chromium/content/browser/download/download_net_log_parameters.h b/chromium/content/browser/download/download_net_log_parameters.h
index 6e103bdff5f..2f4b6a006e5 100644
--- a/chromium/content/browser/download/download_net_log_parameters.h
+++ b/chromium/content/browser/download/download_net_log_parameters.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "content/public/browser/download_item.h"
@@ -46,7 +49,7 @@ scoped_ptr<base::Value> ItemRenamedNetLogCallback(
// Returns NetLog parameters when a DownloadItem is interrupted.
scoped_ptr<base::Value> ItemInterruptedNetLogCallback(
DownloadInterruptReason reason,
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* hash_state,
net::NetLogCaptureMode capture_mode);
@@ -54,13 +57,13 @@ scoped_ptr<base::Value> ItemInterruptedNetLogCallback(
scoped_ptr<base::Value> ItemResumingNetLogCallback(
bool user_initiated,
DownloadInterruptReason reason,
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* hash_state,
net::NetLogCaptureMode capture_mode);
// Returns NetLog parameters when a DownloadItem is completing.
scoped_ptr<base::Value> ItemCompletingNetLogCallback(
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* final_hash,
net::NetLogCaptureMode capture_mode);
@@ -71,14 +74,14 @@ scoped_ptr<base::Value> ItemFinishedNetLogCallback(
// Returns NetLog parameters when a DownloadItem is canceled.
scoped_ptr<base::Value> ItemCanceledNetLogCallback(
- int64 bytes_so_far,
+ int64_t bytes_so_far,
const std::string* hash_state,
net::NetLogCaptureMode capture_mode);
// Returns NetLog parameters when a DownloadFile is opened.
scoped_ptr<base::Value> FileOpenedNetLogCallback(
const base::FilePath* file_name,
- int64 start_offset,
+ int64_t start_offset,
net::NetLogCaptureMode capture_mode);
// Returns NetLog parameters when a DownloadFile is opened.
diff --git a/chromium/content/browser/download/download_request_core.cc b/chromium/content/browser/download/download_request_core.cc
new file mode 100644
index 00000000000..072ba7b0b55
--- /dev/null
+++ b/chromium/content/browser/download/download_request_core.cc
@@ -0,0 +1,366 @@
+// 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/download/download_request_core.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
+#include "base/single_thread_task_runner.h"
+#include "base/strings/stringprintf.h"
+#include "base/thread_task_runner_handle.h"
+#include "content/browser/byte_stream.h"
+#include "content/browser/download/download_create_info.h"
+#include "content/browser/download/download_interrupt_reasons_impl.h"
+#include "content/browser/download/download_manager_impl.h"
+#include "content/browser/download/download_request_handle.h"
+#include "content/browser/download/download_stats.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_item.h"
+#include "content/public/browser/download_manager_delegate.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/power_save_blocker.h"
+#include "content/public/browser/web_contents.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_context.h"
+
+namespace content {
+
+const int DownloadRequestCore::kDownloadByteStreamSize = 100 * 1024;
+
+DownloadRequestCore::DownloadRequestCore(
+ net::URLRequest* request,
+ scoped_ptr<DownloadSaveInfo> save_info,
+ const base::Closure& on_ready_to_read_callback)
+ : on_ready_to_read_callback_(on_ready_to_read_callback),
+ request_(request),
+ save_info_(std::move(save_info)),
+ last_buffer_size_(0),
+ bytes_read_(0),
+ pause_count_(0),
+ was_deferred_(false) {
+ DCHECK(request_);
+ DCHECK(save_info_);
+ DCHECK(!on_ready_to_read_callback_.is_null());
+ RecordDownloadCount(UNTHROTTLED_COUNT);
+ power_save_blocker_ = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
+ PowerSaveBlocker::kReasonOther, "Download in progress");
+}
+
+DownloadRequestCore::~DownloadRequestCore() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Remove output stream callback if a stream exists.
+ if (stream_writer_)
+ stream_writer_->RegisterCallback(base::Closure());
+
+ UMA_HISTOGRAM_TIMES("SB2.DownloadDuration",
+ base::TimeTicks::Now() - download_start_time_);
+}
+
+// Send the download creation information to the download thread.
+void DownloadRequestCore::OnResponseStarted(
+ scoped_ptr<DownloadCreateInfo>* create_info,
+ scoped_ptr<ByteStreamReader>* stream_reader) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(save_info_);
+ DVLOG(20) << __FUNCTION__ << "()" << DebugString();
+ download_start_time_ = base::TimeTicks::Now();
+
+ // If it's a download, we don't want to poison the cache with it.
+ request()->StopCaching();
+
+ // Lower priority as well, so downloads don't contend for resources
+ // with main frames.
+ request()->SetPriority(net::IDLE);
+
+ // If the content-length header is not present (or contains something other
+ // than numbers), the incoming content_length is -1 (unknown size).
+ // Set the content length to 0 to indicate unknown size to DownloadManager.
+ int64_t content_length = request()->GetExpectedContentSize() > 0
+ ? request()->GetExpectedContentSize()
+ : 0;
+
+ // Deleted in DownloadManager.
+ scoped_ptr<DownloadCreateInfo> info(
+ new DownloadCreateInfo(base::Time::Now(), content_length,
+ request()->net_log(), std::move(save_info_)));
+
+ // Create the ByteStream for sending data to the download sink.
+ CreateByteStream(
+ base::ThreadTaskRunnerHandle::Get(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
+ kDownloadByteStreamSize, &stream_writer_, stream_reader);
+ stream_writer_->RegisterCallback(
+ base::Bind(&DownloadRequestCore::ResumeRequest, AsWeakPtr()));
+
+ info->url_chain = request()->url_chain();
+ info->referrer_url = GURL(request()->referrer());
+ string mime_type;
+ request()->GetMimeType(&mime_type);
+ info->mime_type = mime_type;
+ info->remote_address = request()->GetSocketAddress().host();
+ if (request()->response_headers()) {
+ // Grab the first content-disposition header. There may be more than one,
+ // though as of this writing, the network stack ensures if there are, they
+ // are all duplicates.
+ request()->response_headers()->EnumerateHeader(
+ nullptr, "Content-Disposition", &info->content_disposition);
+ }
+ RecordDownloadMimeType(info->mime_type);
+ RecordDownloadContentDisposition(info->content_disposition);
+
+ // Get the last modified time and etag.
+ const net::HttpResponseHeaders* headers = request()->response_headers();
+ if (headers) {
+ if (headers->HasStrongValidators()) {
+ // If we don't have strong validators as per RFC 2616 section 13.3.3, then
+ // we neither store nor use them for range requests.
+ if (!headers->EnumerateHeader(nullptr, "Last-Modified",
+ &info->last_modified))
+ info->last_modified.clear();
+ if (!headers->EnumerateHeader(nullptr, "ETag", &info->etag))
+ info->etag.clear();
+ }
+
+ int status = headers->response_code();
+ if (2 == status / 100 && status != net::HTTP_PARTIAL_CONTENT) {
+ // Success & not range response; if we asked for a range, we didn't
+ // get it--reset the file pointers to reflect that.
+ info->save_info->offset = 0;
+ info->save_info->hash_state = "";
+ }
+
+ if (!headers->GetMimeType(&info->original_mime_type))
+ info->original_mime_type.clear();
+ }
+
+ // Blink verifies that the requester of this download is allowed to set a
+ // suggested name for the security origin of the downlaod URL. However, this
+ // assumption doesn't hold if there were cross origin redirects. Therefore,
+ // clear the suggested_name for such requests.
+ if (info->url_chain.size() > 1 &&
+ info->url_chain.front().GetOrigin() != info->url_chain.back().GetOrigin())
+ info->save_info->suggested_name.clear();
+
+ info.swap(*create_info);
+}
+
+// Create a new buffer, which will be handed to the download thread for file
+// writing and deletion.
+bool DownloadRequestCore::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
+ int* buf_size,
+ int min_size) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(buf && buf_size);
+ DCHECK(!read_buffer_.get());
+
+ *buf_size = min_size < 0 ? kReadBufSize : min_size;
+ last_buffer_size_ = *buf_size;
+ read_buffer_ = new net::IOBuffer(*buf_size);
+ *buf = read_buffer_.get();
+ return true;
+}
+
+// Pass the buffer to the download file writer.
+bool DownloadRequestCore::OnReadCompleted(int bytes_read, bool* defer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(read_buffer_.get());
+
+ base::TimeTicks now(base::TimeTicks::Now());
+ if (!last_read_time_.is_null()) {
+ double seconds_since_last_read = (now - last_read_time_).InSecondsF();
+ if (now == last_read_time_)
+ // Use 1/10 ms as a "very small number" so that we avoid
+ // divide-by-zero error and still record a very high potential bandwidth.
+ seconds_since_last_read = 0.00001;
+
+ double actual_bandwidth = (bytes_read) / seconds_since_last_read;
+ double potential_bandwidth = last_buffer_size_ / seconds_since_last_read;
+ RecordBandwidth(actual_bandwidth, potential_bandwidth);
+ }
+ last_read_time_ = now;
+
+ if (!bytes_read)
+ return true;
+ bytes_read_ += bytes_read;
+ DCHECK(read_buffer_.get());
+
+ // Take the data ship it down the stream. If the stream is full, pause the
+ // request; the stream callback will resume it.
+ if (!stream_writer_->Write(read_buffer_, bytes_read)) {
+ PauseRequest();
+ *defer = was_deferred_ = true;
+ last_stream_pause_time_ = now;
+ }
+
+ read_buffer_ = NULL; // Drop our reference.
+
+ if (pause_count_ > 0)
+ *defer = was_deferred_ = true;
+
+ return true;
+}
+
+DownloadInterruptReason DownloadRequestCore::OnResponseCompleted(
+ const net::URLRequestStatus& status) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ int response_code = status.is_success() ? request()->GetResponseCode() : 0;
+ DVLOG(20) << __FUNCTION__ << "()" << DebugString()
+ << " status.status() = " << status.status()
+ << " status.error() = " << status.error()
+ << " response_code = " << response_code;
+
+ net::Error error_code = net::OK;
+ if (status.status() == net::URLRequestStatus::FAILED ||
+ // Note cancels as failures too.
+ status.status() == net::URLRequestStatus::CANCELED) {
+ error_code = static_cast<net::Error>(status.error()); // Normal case.
+ // Make sure that at least the fact of failure comes through.
+ if (error_code == net::OK)
+ error_code = net::ERR_FAILED;
+ }
+
+ // ERR_CONTENT_LENGTH_MISMATCH and ERR_INCOMPLETE_CHUNKED_ENCODING are
+ // allowed since a number of servers in the wild close the connection too
+ // early by mistake. Other browsers - IE9, Firefox 11.0, and Safari 5.1.4 -
+ // treat downloads as complete in both cases, so we follow their lead.
+ if (error_code == net::ERR_CONTENT_LENGTH_MISMATCH ||
+ error_code == net::ERR_INCOMPLETE_CHUNKED_ENCODING) {
+ error_code = net::OK;
+ }
+ DownloadInterruptReason reason = ConvertNetErrorToInterruptReason(
+ error_code, DOWNLOAD_INTERRUPT_FROM_NETWORK);
+
+ if (status.status() == net::URLRequestStatus::CANCELED &&
+ status.error() == net::ERR_ABORTED) {
+ // CANCELED + ERR_ABORTED == something outside of the network
+ // stack cancelled the request. There aren't that many things that
+ // could do this to a download request (whose lifetime is separated from
+ // the tab from which it came). We map this to USER_CANCELLED as the
+ // case we know about (system suspend because of laptop close) corresponds
+ // to a user action.
+ // TODO(ahendrickson) -- Find a better set of codes to use here, as
+ // CANCELED/ERR_ABORTED can occur for reasons other than user cancel.
+ if (net::IsCertStatusError(request()->ssl_info().cert_status))
+ reason = DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM;
+ else
+ reason = DOWNLOAD_INTERRUPT_REASON_USER_CANCELED;
+ }
+
+ if (status.is_success() && reason == DOWNLOAD_INTERRUPT_REASON_NONE &&
+ request()->response_headers()) {
+ // Handle server's response codes.
+ switch (response_code) {
+ case -1: // Non-HTTP request.
+ case net::HTTP_OK:
+ case net::HTTP_CREATED:
+ case net::HTTP_ACCEPTED:
+ case net::HTTP_NON_AUTHORITATIVE_INFORMATION:
+ case net::HTTP_RESET_CONTENT:
+ case net::HTTP_PARTIAL_CONTENT:
+ // Expected successful codes.
+ break;
+ case net::HTTP_NO_CONTENT:
+ case net::HTTP_NOT_FOUND:
+ reason = DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
+ break;
+ case net::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
+ // Retry by downloading from the start automatically:
+ // If we haven't received data when we get this error, we won't.
+ reason = DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE;
+ break;
+ case net::HTTP_UNAUTHORIZED:
+ // Server didn't authorize this request.
+ reason = DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED;
+ break;
+ case net::HTTP_FORBIDDEN:
+ // Server forbids access to this resource.
+ reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN;
+ break;
+ default: // All other errors.
+ // Redirection and informational codes should have been handled earlier
+ // in the stack.
+ DCHECK_NE(3, response_code / 100);
+ DCHECK_NE(1, response_code / 100);
+ reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED;
+ break;
+ }
+ }
+
+ std::string accept_ranges;
+ bool has_strong_validators = false;
+ if (request()->response_headers()) {
+ request()->response_headers()->EnumerateHeader(nullptr, "Accept-Ranges",
+ &accept_ranges);
+ has_strong_validators =
+ request()->response_headers()->HasStrongValidators();
+ }
+ RecordAcceptsRanges(accept_ranges, bytes_read_, has_strong_validators);
+ RecordNetworkBlockage(base::TimeTicks::Now() - download_start_time_,
+ total_pause_time_);
+
+ // Send the info down the stream. Conditional is in case we get
+ // OnResponseCompleted without OnResponseStarted.
+ if (stream_writer_)
+ stream_writer_->Close(reason);
+
+ // If the error mapped to something unknown, record it so that
+ // we can drill down.
+ if (reason == DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Download.MapErrorNetworkFailed",
+ std::abs(status.error()));
+ }
+
+ stream_writer_.reset(); // We no longer need the stream.
+ read_buffer_ = nullptr;
+
+ return reason;
+}
+
+void DownloadRequestCore::PauseRequest() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ ++pause_count_;
+}
+
+void DownloadRequestCore::ResumeRequest() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_LT(0, pause_count_);
+
+ --pause_count_;
+
+ if (!was_deferred_)
+ return;
+ if (pause_count_ > 0)
+ return;
+
+ was_deferred_ = false;
+ if (!last_stream_pause_time_.is_null()) {
+ total_pause_time_ += (base::TimeTicks::Now() - last_stream_pause_time_);
+ last_stream_pause_time_ = base::TimeTicks();
+ }
+
+ on_ready_to_read_callback_.Run();
+}
+
+std::string DownloadRequestCore::DebugString() const {
+ return base::StringPrintf(
+ "{"
+ " url_ = "
+ "\"%s\""
+ " }",
+ request() ? request()->url().spec().c_str() : "<NULL request>");
+}
+
+} // namespace content
diff --git a/chromium/content/browser/download/download_request_core.h b/chromium/content/browser/download/download_request_core.h
new file mode 100644
index 00000000000..22ca862ef85
--- /dev/null
+++ b/chromium/content/browser/download/download_request_core.h
@@ -0,0 +1,137 @@
+// 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_DOWNLOAD_DOWNLOAD_REQUEST_CORE_H_
+#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_CORE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/loader/resource_handler.h"
+#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_save_info.h"
+#include "content/public/browser/download_url_parameters.h"
+
+namespace net {
+class URLRequest;
+} // namespace net
+
+namespace content {
+class DownloadManagerImpl;
+class ByteStreamReader;
+class ByteStreamWriter;
+class PowerSaveBlocker;
+struct DownloadCreateInfo;
+
+// This class encapsulates the core logic for reading data from a URLRequest and
+// writing it into a ByteStream. It's common to both DownloadResourceHandler and
+// UrlDownloader.
+//
+// Created, lives on and dies on the IO thread.
+class CONTENT_EXPORT DownloadRequestCore
+ : public base::SupportsWeakPtr<DownloadRequestCore> {
+ public:
+ // Size of the buffer used between the DownloadRequestCore and the
+ // downstream receiver of its output.
+ static const int kDownloadByteStreamSize;
+
+ // |request| *must* outlive the DownloadRequestCore. |save_info| must be
+ // valid.
+ //
+ // Invokes |on_ready_to_read_callback| if a previous call to OnReadCompleted()
+ // resulted in |defer| being set to true, and DownloadRequestCore is now ready
+ // to commence reading.
+ DownloadRequestCore(net::URLRequest* request,
+ scoped_ptr<DownloadSaveInfo> save_info,
+ const base::Closure& on_ready_to_read_callback);
+ ~DownloadRequestCore();
+
+ // Should be called when the URLRequest::Delegate receives OnResponseStarted.
+ // Constructs a DownloadCreateInfo and a ByteStreamReader that should be
+ // passed into DownloadManagerImpl::StartDownload().
+ //
+ // Only populates the response derived fields of DownloadCreateInfo, with the
+ // exception of |save_info|.
+ void OnResponseStarted(scoped_ptr<DownloadCreateInfo>* info,
+ scoped_ptr<ByteStreamReader>* stream_reader);
+
+ // Starts a read cycle. Creates a new IOBuffer which can be passed into
+ // URLRequest::Read(). Call OnReadCompleted() when the Read operation
+ // completes.
+ bool OnWillRead(scoped_refptr<net::IOBuffer>* buf,
+ int* buf_size,
+ int min_size);
+
+ // Should be called when the Read() operation completes. |defer| will be set
+ // to true if reading is to be suspended. In the latter case, once more data
+ // can be read, invokes the |on_ready_to_read_callback|.
+ bool OnReadCompleted(int bytes_read, bool* defer);
+
+ // Called to signal that the response is complete. If the return value is
+ // something other than DOWNLOAD_INTERRUPT_REASON_NONE, then the download
+ // should be considered interrupted.
+ //
+ // It is expected that once this method is invoked, the DownloadRequestCore
+ // object will be destroyed in short order without invoking any other methods
+ // other than the destructor.
+ DownloadInterruptReason OnResponseCompleted(
+ const net::URLRequestStatus& status);
+
+ // Called if the request should suspend reading. A subsequent
+ // OnReadCompleted() will result in |defer| being set to true.
+ //
+ // Each PauseRequest() must be balanced with a call to ResumeRequest().
+ void PauseRequest();
+
+ // Balances a call to PauseRequest(). If no more pauses are outstanding and
+ // the reader end of the ByteStream is ready to receive more data,
+ // DownloadRequestCore will invoke the |on_ready_to_read_callback| to signal
+ // to the caller that the read cycles should commence.
+ void ResumeRequest();
+
+ std::string DebugString() const;
+
+ protected:
+ net::URLRequest* request() const { return request_; }
+
+ private:
+ base::Closure on_ready_to_read_callback_;
+ net::URLRequest* request_;
+ scoped_ptr<DownloadSaveInfo> save_info_;
+
+ // Data flow
+ scoped_refptr<net::IOBuffer> read_buffer_; // From URLRequest.
+ scoped_ptr<ByteStreamWriter> stream_writer_; // To rest of system.
+
+ // Keeps the system from sleeping while this is alive. If the
+ // system enters power saving mode while a request is alive, it can cause the
+ // request to fail and the associated download will be interrupted.
+ scoped_ptr<PowerSaveBlocker> power_save_blocker_;
+
+ // The following are used to collect stats.
+ base::TimeTicks download_start_time_;
+ base::TimeTicks last_read_time_;
+ base::TimeTicks last_stream_pause_time_;
+ base::TimeDelta total_pause_time_;
+ size_t last_buffer_size_;
+ int64_t bytes_read_;
+
+ int pause_count_;
+ bool was_deferred_;
+
+ // Each successful OnWillRead will yield a buffer of this size.
+ static const int kReadBufSize = 32768; // bytes
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadRequestCore);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_CORE_H_
diff --git a/chromium/content/browser/download/download_request_handle.cc b/chromium/content/browser/download/download_request_handle.cc
index 6e319d3abee..67dda4f5029 100644
--- a/chromium/content/browser/download/download_request_handle.cc
+++ b/chromium/content/browser/download/download_request_handle.cc
@@ -5,7 +5,6 @@
#include "content/browser/download/download_request_handle.h"
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -13,12 +12,13 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/browser_side_navigation_policy.h"
namespace content {
-DownloadRequestHandle::~DownloadRequestHandle() {
-}
+DownloadRequestHandleInterface::~DownloadRequestHandleInterface() {}
+
+DownloadRequestHandle::~DownloadRequestHandle() {}
DownloadRequestHandle::DownloadRequestHandle()
: child_id_(-1),
@@ -42,12 +42,11 @@ DownloadRequestHandle::DownloadRequestHandle(
}
WebContents* DownloadRequestHandle::GetWebContents() const {
- // PlzNavigate: if a FrameTreeNodeID was provided, use it to return the
+ // PlzNavigate: if a FrameTreeNodeId was provided, use it to return the
// WebContents.
// TODO(davidben): This logic should be abstracted within the ResourceLoader
// stack. https://crbug.com/376003
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id_);
if (frame_tree_node) {
@@ -64,12 +63,11 @@ WebContents* DownloadRequestHandle::GetWebContents() const {
}
DownloadManager* DownloadRequestHandle::GetDownloadManager() const {
- // PlzNavigate: if a FrameTreeNodeID was provided, use it to return the
+ // PlzNavigate: if a FrameTreeNodeId was provided, use it to return the
// DownloadManager.
// TODO(davidben): This logic should be abstracted within the ResourceLoader
// stack. https://crbug.com/376003
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id_);
if (frame_tree_node) {
diff --git a/chromium/content/browser/download/download_request_handle.h b/chromium/content/browser/download/download_request_handle.h
index 3e237758ed8..5d047c75910 100644
--- a/chromium/content/browser/download/download_request_handle.h
+++ b/chromium/content/browser/download/download_request_handle.h
@@ -24,7 +24,7 @@ class WebContents;
// DownloadRequestHandleInterface is defined for mocking purposes.
class CONTENT_EXPORT DownloadRequestHandleInterface {
public:
- virtual ~DownloadRequestHandleInterface() {}
+ virtual ~DownloadRequestHandleInterface();
// These functions must be called on the UI thread.
virtual WebContents* GetWebContents() const = 0;
diff --git a/chromium/content/browser/download/download_resource_handler.cc b/chromium/content/browser/download/download_resource_handler.cc
index d806d944933..e06b3095e99 100644
--- a/chromium/content/browser/download/download_resource_handler.cc
+++ b/chromium/content/browser/download/download_resource_handler.cc
@@ -7,34 +7,22 @@
#include <string>
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
-#include "base/thread_task_runner_handle.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_create_info.h"
#include "content/browser/download/download_interrupt_reasons_impl.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_request_handle.h"
-#include "content/browser/download/download_stats.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_interrupt_reasons.h"
-#include "content/public/browser/download_item.h"
-#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/power_save_blocker.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/resource_response.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_status_code.h"
-#include "net/url_request/url_request_context.h"
namespace content {
@@ -45,17 +33,6 @@ struct DownloadResourceHandler::DownloadTabInfo {
namespace {
-void CallStartedCBOnUIThread(
- const DownloadUrlParameters::OnStartedCallback& started_cb,
- DownloadItem* item,
- DownloadInterruptReason interrupt_reason) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- if (started_cb.is_null())
- return;
- started_cb.Run(item, interrupt_reason);
-}
-
// Static function in order to prevent any accidental accesses to
// DownloadResourceHandler members from the UI thread.
static void StartOnUIThread(
@@ -65,7 +42,8 @@ static void StartOnUIThread(
const DownloadUrlParameters::OnStartedCallback& started_cb) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DownloadManager* download_manager = info->request_handle.GetDownloadManager();
+ DownloadManager* download_manager =
+ info->request_handle->GetDownloadManager();
if (!download_manager) {
// NULL in unittests or if the page closed right after starting the
// download.
@@ -81,7 +59,8 @@ static void StartOnUIThread(
info->tab_url = tab_info->tab_url;
info->tab_referrer_url = tab_info->tab_referrer_url;
- download_manager->StartDownload(info.Pass(), stream.Pass(), started_cb);
+ download_manager->StartDownload(std::move(info), std::move(stream),
+ started_cb);
}
void InitializeDownloadTabInfoOnUIThread(
@@ -104,25 +83,19 @@ void DeleteOnUIThread(
} // namespace
-const int DownloadResourceHandler::kDownloadByteStreamSize = 100 * 1024;
-
DownloadResourceHandler::DownloadResourceHandler(
- uint32 id,
+ uint32_t id,
net::URLRequest* request,
const DownloadUrlParameters::OnStartedCallback& started_cb,
scoped_ptr<DownloadSaveInfo> save_info)
: ResourceHandler(request),
download_id_(id),
started_cb_(started_cb),
- save_info_(save_info.Pass()),
tab_info_(new DownloadTabInfo()),
- last_buffer_size_(0),
- bytes_read_(0),
- pause_count_(0),
- was_deferred_(false),
- on_response_started_called_(false) {
- RecordDownloadCount(UNTHROTTLED_COUNT);
-
+ core_(request,
+ std::move(save_info),
+ base::Bind(&DownloadResourceHandler::OnCoreReadyToRead,
+ base::Unretained(this))) {
// Do UI thread initialization for tab_info_ asap after
// DownloadResourceHandler creation since the tab could be navigated
// before StartOnUIThread gets called. This is safe because deletion
@@ -137,9 +110,19 @@ DownloadResourceHandler::DownloadResourceHandler(
request_info->GetRequestID(),
request_info->frame_tree_node_id()),
tab_info_.get()));
- power_save_blocker_ = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
- PowerSaveBlocker::kReasonOther, "Download in progress");
+}
+
+DownloadResourceHandler::~DownloadResourceHandler() {
+ // This won't do anything if the callback was called before.
+ // If it goes through, it will likely be because OnWillStart() returned
+ // false somewhere in the chain of resource handlers.
+ CallStartedCB(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
+
+ if (tab_info_) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DeleteOnUIThread, base::Passed(&tab_info_)));
+ }
}
bool DownloadResourceHandler::OnRequestRedirected(
@@ -153,127 +136,39 @@ bool DownloadResourceHandler::OnRequestRedirected(
bool DownloadResourceHandler::OnResponseStarted(
ResourceResponse* response,
bool* defer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // There can be only one (call)
- DCHECK(!on_response_started_called_);
- on_response_started_called_ = true;
-
- DVLOG(20) << __FUNCTION__ << "()" << DebugString();
- download_start_time_ = base::TimeTicks::Now();
-
- // If it's a download, we don't want to poison the cache with it.
- request()->StopCaching();
-
- // Lower priority as well, so downloads don't contend for resources
- // with main frames.
- request()->SetPriority(net::IDLE);
+ scoped_ptr<DownloadCreateInfo> create_info;
+ scoped_ptr<ByteStreamReader> stream_reader;
- // If the content-length header is not present (or contains something other
- // than numbers), the incoming content_length is -1 (unknown size).
- // Set the content length to 0 to indicate unknown size to DownloadManager.
- int64 content_length =
- response->head.content_length > 0 ? response->head.content_length : 0;
+ core_.OnResponseStarted(&create_info, &stream_reader);
const ResourceRequestInfoImpl* request_info = GetRequestInfo();
-
- // Deleted in DownloadManager.
- scoped_ptr<DownloadCreateInfo> info(
- new DownloadCreateInfo(base::Time::Now(),
- content_length,
- request()->net_log(),
- request_info->HasUserGesture(),
- request_info->GetPageTransition(),
- save_info_.Pass()));
-
- // Create the ByteStream for sending data to the download sink.
- scoped_ptr<ByteStreamReader> stream_reader;
- CreateByteStream(
- base::ThreadTaskRunnerHandle::Get(),
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
- kDownloadByteStreamSize, &stream_writer_, &stream_reader);
- stream_writer_->RegisterCallback(
- base::Bind(&DownloadResourceHandler::ResumeRequest, AsWeakPtr()));
-
- info->download_id = download_id_;
- info->url_chain = request()->url_chain();
- info->referrer_url = GURL(request()->referrer());
- info->mime_type = response->head.mime_type;
- info->remote_address = request()->GetSocketAddress().host();
- if (request()->response_headers()) {
- // Grab the first content-disposition header. There may be more than one,
- // though as of this writing, the network stack ensures if there are, they
- // are all duplicates.
- request()->response_headers()->EnumerateHeader(
- nullptr, "content-disposition", &info->content_disposition);
- }
- RecordDownloadMimeType(info->mime_type);
- RecordDownloadContentDisposition(info->content_disposition);
-
- info->request_handle = DownloadRequestHandle(
+ create_info->download_id = download_id_;
+ create_info->has_user_gesture = request_info->HasUserGesture();
+ create_info->transition_type = request_info->GetPageTransition();
+ create_info->request_handle.reset(new DownloadRequestHandle(
AsWeakPtr(), request_info->GetChildID(), request_info->GetRouteID(),
- request_info->GetRequestID(), request_info->frame_tree_node_id());
-
- // Get the last modified time and etag.
- const net::HttpResponseHeaders* headers = request()->response_headers();
- if (headers) {
- if (headers->HasStrongValidators()) {
- // If we don't have strong validators as per RFC 2616 section 13.3.3, then
- // we neither store nor use them for range requests.
- if (!headers->EnumerateHeader(NULL, "Last-Modified",
- &info->last_modified))
- info->last_modified.clear();
- if (!headers->EnumerateHeader(NULL, "ETag", &info->etag))
- info->etag.clear();
- }
+ request_info->GetRequestID(), request_info->frame_tree_node_id()));
- int status = headers->response_code();
- if (2 == status / 100 && status != net::HTTP_PARTIAL_CONTENT) {
- // Success & not range response; if we asked for a range, we didn't
- // get it--reset the file pointers to reflect that.
- info->save_info->offset = 0;
- info->save_info->hash_state = "";
- }
-
- if (!headers->GetMimeType(&info->original_mime_type))
- info->original_mime_type.clear();
- }
-
- // Blink verifies that the requester of this download is allowed to set a
- // suggested name for the security origin of the downlaod URL. However, this
- // assumption doesn't hold if there were cross origin redirects. Therefore,
- // clear the suggested_name for such requests.
- if (info->url_chain.size() > 1 &&
- info->url_chain.front().GetOrigin() != info->url_chain.back().GetOrigin())
- info->save_info->suggested_name.clear();
+ // The MIME type in ResourceResponse is the product of
+ // MimeTypeResourceHandler.
+ create_info->mime_type = response->head.mime_type;
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&StartOnUIThread,
- base::Passed(&info),
- base::Passed(&tab_info_),
- base::Passed(&stream_reader),
- // Pass to StartOnUIThread so that variable
- // access is always on IO thread but function
- // is called on UI thread.
- started_cb_));
- // Guaranteed to be called in StartOnUIThread
- started_cb_.Reset();
-
+ base::Bind(&StartOnUIThread, base::Passed(&create_info),
+ base::Passed(&tab_info_), base::Passed(&stream_reader),
+ base::ResetAndReturn(&started_cb_)));
return true;
}
void DownloadResourceHandler::CallStartedCB(
- DownloadItem* item,
DownloadInterruptReason interrupt_reason) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (started_cb_.is_null())
return;
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &CallStartedCBOnUIThread, started_cb_, item, interrupt_reason));
- started_cb_.Reset();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(base::ResetAndReturn(&started_cb_),
+ nullptr, interrupt_reason));
}
bool DownloadResourceHandler::OnWillStart(const GURL& url, bool* defer) {
@@ -290,180 +185,20 @@ bool DownloadResourceHandler::OnBeforeNetworkStart(const GURL& url,
bool DownloadResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
int* buf_size,
int min_size) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(buf && buf_size);
- DCHECK(!read_buffer_.get());
-
- *buf_size = min_size < 0 ? kReadBufSize : min_size;
- last_buffer_size_ = *buf_size;
- read_buffer_ = new net::IOBuffer(*buf_size);
- *buf = read_buffer_.get();
- return true;
+ return core_.OnWillRead(buf, buf_size, min_size);
}
// Pass the buffer to the download file writer.
bool DownloadResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(read_buffer_.get());
-
- base::TimeTicks now(base::TimeTicks::Now());
- if (!last_read_time_.is_null()) {
- double seconds_since_last_read = (now - last_read_time_).InSecondsF();
- if (now == last_read_time_)
- // Use 1/10 ms as a "very small number" so that we avoid
- // divide-by-zero error and still record a very high potential bandwidth.
- seconds_since_last_read = 0.00001;
-
- double actual_bandwidth = (bytes_read)/seconds_since_last_read;
- double potential_bandwidth = last_buffer_size_/seconds_since_last_read;
- RecordBandwidth(actual_bandwidth, potential_bandwidth);
- }
- last_read_time_ = now;
-
- if (!bytes_read)
- return true;
- bytes_read_ += bytes_read;
- DCHECK(read_buffer_.get());
-
- // Take the data ship it down the stream. If the stream is full, pause the
- // request; the stream callback will resume it.
- if (!stream_writer_->Write(read_buffer_, bytes_read)) {
- PauseRequest();
- *defer = was_deferred_ = true;
- last_stream_pause_time_ = now;
- }
-
- read_buffer_ = NULL; // Drop our reference.
-
- if (pause_count_ > 0)
- *defer = was_deferred_ = true;
-
- return true;
+ return core_.OnReadCompleted(bytes_read, defer);
}
void DownloadResourceHandler::OnResponseCompleted(
const net::URLRequestStatus& status,
const std::string& security_info,
bool* defer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- int response_code = status.is_success() ? request()->GetResponseCode() : 0;
- DVLOG(20) << __FUNCTION__ << "()" << DebugString()
- << " status.status() = " << status.status()
- << " status.error() = " << status.error()
- << " response_code = " << response_code;
-
- net::Error error_code = net::OK;
- if (status.status() == net::URLRequestStatus::FAILED ||
- // Note cancels as failures too.
- status.status() == net::URLRequestStatus::CANCELED) {
- error_code = static_cast<net::Error>(status.error()); // Normal case.
- // Make sure that at least the fact of failure comes through.
- if (error_code == net::OK)
- error_code = net::ERR_FAILED;
- }
-
- // ERR_CONTENT_LENGTH_MISMATCH and ERR_INCOMPLETE_CHUNKED_ENCODING are
- // allowed since a number of servers in the wild close the connection too
- // early by mistake. Other browsers - IE9, Firefox 11.0, and Safari 5.1.4 -
- // treat downloads as complete in both cases, so we follow their lead.
- if (error_code == net::ERR_CONTENT_LENGTH_MISMATCH ||
- error_code == net::ERR_INCOMPLETE_CHUNKED_ENCODING) {
- error_code = net::OK;
- }
- DownloadInterruptReason reason =
- ConvertNetErrorToInterruptReason(
- error_code, DOWNLOAD_INTERRUPT_FROM_NETWORK);
-
- if (status.status() == net::URLRequestStatus::CANCELED &&
- status.error() == net::ERR_ABORTED) {
- // CANCELED + ERR_ABORTED == something outside of the network
- // stack cancelled the request. There aren't that many things that
- // could do this to a download request (whose lifetime is separated from
- // the tab from which it came). We map this to USER_CANCELLED as the
- // case we know about (system suspend because of laptop close) corresponds
- // to a user action.
- // TODO(ahendrickson) -- Find a better set of codes to use here, as
- // CANCELED/ERR_ABORTED can occur for reasons other than user cancel.
- if (net::IsCertStatusError(request()->ssl_info().cert_status))
- reason = DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM;
- else
- reason = DOWNLOAD_INTERRUPT_REASON_USER_CANCELED;
- }
-
- if (status.is_success() &&
- reason == DOWNLOAD_INTERRUPT_REASON_NONE &&
- request()->response_headers()) {
- // Handle server's response codes.
- switch(response_code) {
- case -1: // Non-HTTP request.
- case net::HTTP_OK:
- case net::HTTP_CREATED:
- case net::HTTP_ACCEPTED:
- case net::HTTP_NON_AUTHORITATIVE_INFORMATION:
- case net::HTTP_RESET_CONTENT:
- case net::HTTP_PARTIAL_CONTENT:
- // Expected successful codes.
- break;
- case net::HTTP_NO_CONTENT:
- case net::HTTP_NOT_FOUND:
- reason = DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
- break;
- case net::HTTP_PRECONDITION_FAILED:
- // Failed our 'If-Unmodified-Since' or 'If-Match'; see
- // download_manager_impl.cc BeginDownload()
- reason = DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION;
- break;
- case net::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
- // Retry by downloading from the start automatically:
- // If we haven't received data when we get this error, we won't.
- reason = DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE;
- break;
- case net::HTTP_UNAUTHORIZED:
- // Server didn't authorize this request.
- reason = DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED;
- break;
- case net::HTTP_FORBIDDEN:
- // Server forbids access to this resource.
- reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN;
- break;
- default: // All other errors.
- // Redirection and informational codes should have been handled earlier
- // in the stack.
- DCHECK_NE(3, response_code / 100);
- DCHECK_NE(1, response_code / 100);
- reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED;
- break;
- }
- }
-
- std::string accept_ranges;
- bool has_strong_validators = false;
- if (request()->response_headers()) {
- request()->response_headers()->EnumerateHeader(
- NULL, "Accept-Ranges", &accept_ranges);
- has_strong_validators =
- request()->response_headers()->HasStrongValidators();
- }
- RecordAcceptsRanges(accept_ranges, bytes_read_, has_strong_validators);
- RecordNetworkBlockage(base::TimeTicks::Now() - download_start_time_,
- total_pause_time_);
-
- CallStartedCB(NULL, reason);
-
- // Send the info down the stream. Conditional is in case we get
- // OnResponseCompleted without OnResponseStarted.
- if (stream_writer_)
- stream_writer_->Close(reason);
-
- // If the error mapped to something unknown, record it so that
- // we can drill down.
- if (reason == DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Download.MapErrorNetworkFailed",
- std::abs(status.error()));
- }
-
- stream_writer_.reset(); // We no longer need the stream.
- read_buffer_ = NULL;
+ DownloadInterruptReason result = core_.OnResponseCompleted(status);
+ CallStartedCB(result);
}
void DownloadResourceHandler::OnDataDownloaded(int bytes_downloaded) {
@@ -471,35 +206,22 @@ void DownloadResourceHandler::OnDataDownloaded(int bytes_downloaded) {
}
void DownloadResourceHandler::PauseRequest() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- ++pause_count_;
+ core_.PauseRequest();
}
void DownloadResourceHandler::ResumeRequest() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_LT(0, pause_count_);
-
- --pause_count_;
-
- if (!was_deferred_)
- return;
- if (pause_count_ > 0)
- return;
-
- was_deferred_ = false;
- if (!last_stream_pause_time_.is_null()) {
- total_pause_time_ += (base::TimeTicks::Now() - last_stream_pause_time_);
- last_stream_pause_time_ = base::TimeTicks();
- }
+ core_.ResumeRequest();
+}
+void DownloadResourceHandler::OnCoreReadyToRead() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
controller()->Resume();
}
void DownloadResourceHandler::CancelRequest() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const ResourceRequestInfo* info = GetRequestInfo();
+ const ResourceRequestInfoImpl* info = GetRequestInfo();
ResourceDispatcherHostImpl::Get()->CancelRequest(
info->GetChildID(),
info->GetRequestID());
@@ -507,7 +229,7 @@ void DownloadResourceHandler::CancelRequest() {
}
std::string DownloadResourceHandler::DebugString() const {
- const ResourceRequestInfo* info = GetRequestInfo();
+ const ResourceRequestInfoImpl* info = GetRequestInfo();
return base::StringPrintf("{"
" url_ = " "\"%s\""
" info = {"
@@ -524,28 +246,4 @@ std::string DownloadResourceHandler::DebugString() const {
info->GetRouteID());
}
-DownloadResourceHandler::~DownloadResourceHandler() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- // This won't do anything if the callback was called before.
- // If it goes through, it will likely be because OnWillStart() returned
- // false somewhere in the chain of resource handlers.
- CallStartedCB(NULL, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
-
- // Remove output stream callback if a stream exists.
- if (stream_writer_)
- stream_writer_->RegisterCallback(base::Closure());
-
- // tab_info_ must be destroyed on UI thread, since
- // InitializeDownloadTabInfoOnUIThread might still be using it.
- if (tab_info_.get()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&DeleteOnUIThread, base::Passed(&tab_info_)));
- }
-
- UMA_HISTOGRAM_TIMES("SB2.DownloadDuration",
- base::TimeTicks::Now() - download_start_time_);
-}
-
} // namespace content
diff --git a/chromium/content/browser/download/download_resource_handler.h b/chromium/content/browser/download/download_resource_handler.h
index 9c8f53dd8d2..22a10a8a049 100644
--- a/chromium/content/browser/download/download_resource_handler.h
+++ b/chromium/content/browser/download/download_resource_handler.h
@@ -5,10 +5,14 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_H_
+#include <stdint.h>
+
#include <string>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "content/browser/download/download_request_core.h"
#include "content/browser/loader/resource_handler.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_manager.h"
@@ -33,14 +37,10 @@ class CONTENT_EXPORT DownloadResourceHandler
public:
struct DownloadTabInfo;
- // Size of the buffer used between the DownloadResourceHandler and the
- // downstream receiver of its output.
- static const int kDownloadByteStreamSize;
-
// started_cb will be called exactly once on the UI thread.
// |id| should be invalid if the id should be automatically assigned.
DownloadResourceHandler(
- uint32 id,
+ uint32_t id,
net::URLRequest* request,
const DownloadUrlParameters::OnStartedCallback& started_cb,
scoped_ptr<DownloadSaveInfo> save_info);
@@ -87,14 +87,15 @@ class CONTENT_EXPORT DownloadResourceHandler
// Arrange for started_cb_ to be called on the UI thread with the
// below values, nulling out started_cb_. Should only be called
// on the IO thread.
- void CallStartedCB(DownloadItem* item,
- DownloadInterruptReason interrupt_reason);
+ void CallStartedCB(DownloadInterruptReason interrupt_reason);
+
+ void OnCoreReadyToRead();
+
+ uint32_t download_id_;
- uint32 download_id_;
// This is read only on the IO thread, but may only
// be called on the UI thread.
DownloadUrlParameters::OnStartedCallback started_cb_;
- scoped_ptr<DownloadSaveInfo> save_info_;
// Stores information about the download that must be acquired on the UI
// thread before StartOnUIThread is called.
@@ -104,32 +105,7 @@ class CONTENT_EXPORT DownloadResourceHandler
// deletion must occur on the IO thread.
scoped_ptr<DownloadTabInfo> tab_info_;
- // Data flow
- scoped_refptr<net::IOBuffer> read_buffer_; // From URLRequest.
- scoped_ptr<ByteStreamWriter> stream_writer_; // To rest of system.
-
- // Keeps the system from sleeping while this ResourceHandler is alive. If the
- // system enters power saving mode while a request is alive, it can cause the
- // request to fail and the associated download will be interrupted.
- scoped_ptr<PowerSaveBlocker> power_save_blocker_;
-
- // The following are used to collect stats.
- base::TimeTicks download_start_time_;
- base::TimeTicks last_read_time_;
- base::TimeTicks last_stream_pause_time_;
- base::TimeDelta total_pause_time_;
- size_t last_buffer_size_;
- int64 bytes_read_;
-
- int pause_count_;
- bool was_deferred_;
-
- // For DCHECKing
- bool on_response_started_called_;
-
- static const int kReadBufSize = 32768; // bytes
- static const int kThrottleTimeMs = 200; // milliseconds
-
+ DownloadRequestCore core_;
DISALLOW_COPY_AND_ASSIGN(DownloadResourceHandler);
};
diff --git a/chromium/content/browser/download/download_stats.cc b/chromium/content/browser/download/download_stats.cc
index 3f7d692f2a7..6cd66f2e0fd 100644
--- a/chromium/content/browser/download/download_stats.cc
+++ b/chromium/content/browser/download/download_stats.cc
@@ -4,6 +4,7 @@
#include "content/browser/download/download_stats.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_util.h"
@@ -342,10 +343,11 @@ void RecordDownloadSource(DownloadSource source) {
"Download.Sources", source, DOWNLOAD_SOURCE_LAST_ENTRY);
}
-void RecordDownloadCompleted(const base::TimeTicks& start, int64 download_len) {
+void RecordDownloadCompleted(const base::TimeTicks& start,
+ int64_t download_len) {
RecordDownloadCount(COMPLETED_COUNT);
UMA_HISTOGRAM_LONG_TIMES("Download.Time", (base::TimeTicks::Now() - start));
- int64 max = 1024 * 1024 * 1024; // One Terabyte.
+ int64_t max = 1024 * 1024 * 1024; // One Terabyte.
download_len /= 1024; // In Kilobytes
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.DownloadSize",
download_len,
@@ -355,8 +357,8 @@ void RecordDownloadCompleted(const base::TimeTicks& start, int64 download_len) {
}
void RecordDownloadInterrupted(DownloadInterruptReason reason,
- int64 received,
- int64 total) {
+ int64_t received,
+ int64_t total) {
RecordDownloadCount(INTERRUPTED_COUNT);
UMA_HISTOGRAM_CUSTOM_ENUMERATION(
"Download.InterruptedReason",
@@ -367,11 +369,11 @@ void RecordDownloadInterrupted(DownloadInterruptReason reason,
// The maximum should be 2^kBuckets, to have the logarithmic bucket
// boundaries fall on powers of 2.
static const int kBuckets = 30;
- static const int64 kMaxKb = 1 << kBuckets; // One Terabyte, in Kilobytes.
- int64 delta_bytes = total - received;
+ static const int64_t kMaxKb = 1 << kBuckets; // One Terabyte, in Kilobytes.
+ int64_t delta_bytes = total - received;
bool unknown_size = total <= 0;
- int64 received_kb = received / 1024;
- int64 total_kb = total / 1024;
+ int64_t received_kb = received / 1024;
+ int64_t total_kb = total / 1024;
UMA_HISTOGRAM_CUSTOM_COUNTS("Download.InterruptedReceivedSizeK",
received_kb,
1,
@@ -462,9 +464,9 @@ void RecordDownloadWriteLoopCount(int count) {
}
void RecordAcceptsRanges(const std::string& accepts_ranges,
- int64 download_len,
+ int64_t download_len,
bool has_strong_validator) {
- int64 max = 1024 * 1024 * 1024; // One Terabyte.
+ int64_t max = 1024 * 1024 * 1024; // One Terabyte.
download_len /= 1024; // In Kilobytes
static const int kBuckets = 50;
diff --git a/chromium/content/browser/download/download_stats.h b/chromium/content/browser/download/download_stats.h
index 3ae2612f8ea..a029a0b4f34 100644
--- a/chromium/content/browser/download/download_stats.h
+++ b/chromium/content/browser/download/download_stats.h
@@ -7,9 +7,11 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_STATS_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_STATS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "content/common/content_export.h"
#include "content/public/browser/download_danger_type.h"
#include "content/public/browser/download_interrupt_reasons.h"
@@ -127,12 +129,13 @@ void RecordDownloadCount(DownloadCountTypes type);
void RecordDownloadSource(DownloadSource source);
// Record COMPLETED_COUNT and how long the download took.
-void RecordDownloadCompleted(const base::TimeTicks& start, int64 download_len);
+void RecordDownloadCompleted(const base::TimeTicks& start,
+ int64_t download_len);
// Record INTERRUPTED_COUNT, |reason|, |received| and |total| bytes.
void RecordDownloadInterrupted(DownloadInterruptReason reason,
- int64 received,
- int64 total);
+ int64_t received,
+ int64_t total);
// Record that a download has been classified as malicious.
void RecordMaliciousDownloadClassified(DownloadDangerType danger_type);
@@ -177,7 +180,7 @@ void RecordOpen(const base::Time& end, bool first);
// support and ETag indicates downloads that are candidates for partial
// resumption.
void RecordAcceptsRanges(const std::string& accepts_ranges,
- int64 download_len,
+ int64_t download_len,
bool has_strong_validator);
// Record the number of downloads removed by ClearAll.
diff --git a/chromium/content/browser/download/drag_download_file.cc b/chromium/content/browser/download/drag_download_file.cc
index 2014270e38c..afb533a56bf 100644
--- a/chromium/content/browser/download/drag_download_file.cc
+++ b/chromium/content/browser/download/drag_download_file.cc
@@ -4,10 +4,14 @@
#include "content/browser/download/drag_download_file.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
+#include "build/build_config.h"
#include "content/browser/download/download_stats.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
@@ -68,8 +72,8 @@ class DragDownloadFile::DragDownloadFileUI : public DownloadItem::Observer {
params->set_callback(base::Bind(&DragDownloadFileUI::OnDownloadStarted,
weak_ptr_factory_.GetWeakPtr()));
params->set_file_path(file_path);
- params->set_file(file.Pass()); // Nulls file.
- download_manager->DownloadUrl(params.Pass());
+ params->set_file(std::move(file)); // Nulls file.
+ download_manager->DownloadUrl(std::move(params));
}
void Cancel() {
@@ -159,7 +163,7 @@ DragDownloadFile::DragDownloadFile(const base::FilePath& file_path,
const std::string& referrer_encoding,
WebContents* web_contents)
: file_path_(file_path),
- file_(file.Pass()),
+ file_(std::move(file)),
drag_message_loop_(base::MessageLoop::current()),
state_(INITIALIZED),
drag_ui_(NULL),
diff --git a/chromium/content/browser/download/drag_download_file.h b/chromium/content/browser/download/drag_download_file.h
index 825f73668aa..70502d34769 100644
--- a/chromium/content/browser/download/drag_download_file.h
+++ b/chromium/content/browser/download/drag_download_file.h
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
diff --git a/chromium/content/browser/download/drag_download_file_browsertest.cc b/chromium/content/browser/download/drag_download_file_browsertest.cc
index e6a85159b57..8986c391350 100644
--- a/chromium/content/browser/download/drag_download_file_browsertest.cc
+++ b/chromium/content/browser/download/drag_download_file_browsertest.cc
@@ -4,6 +4,7 @@
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/download/download_file_factory.h"
#include "content/browser/download/download_file_impl.h"
@@ -51,9 +52,9 @@ class DragDownloadFileTest : public ContentBrowserTest {
~DragDownloadFileTest() override {}
void Succeed() {
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::MessageLoopForUI::current()->QuitClosure());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::MessageLoopForUI::current()->QuitWhenIdleClosure());
}
void FailFast() {
@@ -92,8 +93,7 @@ class DragDownloadFileTest : public ContentBrowserTest {
IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_NetError) {
base::FilePath name(downloads_directory().AppendASCII(
"DragDownloadFileTest_NetError.txt"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl(
- base::FilePath(FILE_PATH_LITERAL("download-test.lib"))));
+ GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
Referrer referrer;
std::string referrer_encoding;
scoped_refptr<DragDownloadFile> file(
@@ -112,8 +112,7 @@ IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_NetError) {
IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_Complete) {
base::FilePath name(downloads_directory().AppendASCII(
"DragDownloadFileTest_Complete.txt"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl(
- base::FilePath(FILE_PATH_LITERAL("download-test.lib"))));
+ GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
Referrer referrer;
std::string referrer_encoding;
SetUpServer();
diff --git a/chromium/content/browser/download/drag_download_util.cc b/chromium/content/browser/download/drag_download_util.cc
index f259af22c6c..b9e5f9e39af 100644
--- a/chromium/content/browser/download/drag_download_util.cc
+++ b/chromium/content/browser/download/drag_download_util.cc
@@ -4,6 +4,8 @@
#include "content/browser/download/drag_download_util.h"
+#include <stddef.h>
+
#include <string>
#include "base/bind.h"
@@ -14,6 +16,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"
@@ -79,7 +82,7 @@ base::File CreateFileForDrop(base::FilePath* file_path) {
new_file_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
if (file.IsValid()) {
*file_path = new_file_path;
- return file.Pass();
+ return file;
}
}
diff --git a/chromium/content/browser/download/drag_download_util.h b/chromium/content/browser/download/drag_download_util.h
index 38b516c5854..343ef798fba 100644
--- a/chromium/content/browser/download/drag_download_util.h
+++ b/chromium/content/browser/download/drag_download_util.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DRAG_DOWNLOAD_UTIL_H_
#define CONTENT_BROWSER_DOWNLOAD_DRAG_DOWNLOAD_UTIL_H_
-#include "base/basictypes.h"
#include "base/files/file.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "content/browser/download/drag_download_file.h"
diff --git a/chromium/content/browser/download/file_metadata_linux.cc b/chromium/content/browser/download/file_metadata_linux.cc
index 1864d29a717..b6b1779c52e 100644
--- a/chromium/content/browser/download/file_metadata_linux.cc
+++ b/chromium/content/browser/download/file_metadata_linux.cc
@@ -4,6 +4,7 @@
#include "content/browser/download/file_metadata_linux.h"
+#include <stddef.h>
#include <sys/types.h>
#include <sys/xattr.h>
diff --git a/chromium/content/browser/download/file_metadata_unittest_linux.cc b/chromium/content/browser/download/file_metadata_unittest_linux.cc
index c20e573115e..84f31be5352 100644
--- a/chromium/content/browser/download/file_metadata_unittest_linux.cc
+++ b/chromium/content/browser/download/file_metadata_unittest_linux.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <errno.h>
+#include <stddef.h>
#include <sys/types.h>
#include <sys/xattr.h>
diff --git a/chromium/content/browser/download/mhtml_generation_browsertest.cc b/chromium/content/browser/download/mhtml_generation_browsertest.cc
index fbe9a1f6db9..7a3b00fe319 100644
--- a/chromium/content/browser/download/mhtml_generation_browsertest.cc
+++ b/chromium/content/browser/download/mhtml_generation_browsertest.cc
@@ -2,72 +2,152 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/bind.h"
+#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
+#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::ContainsRegex;
+using testing::HasSubstr;
+
namespace content {
class MHTMLGenerationTest : public ContentBrowserTest {
public:
- MHTMLGenerationTest() : mhtml_generated_(false), file_size_(0) {}
-
- void MHTMLGenerated(int64 size) {
- mhtml_generated_ = true;
- file_size_ = size;
- base::MessageLoopForUI::current()->Quit();
- }
+ MHTMLGenerationTest() : has_mhtml_callback_run_(false), file_size_(0) {}
protected:
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(embedded_test_server()->Start());
ContentBrowserTest::SetUp();
}
- bool mhtml_generated() const { return mhtml_generated_; }
- int64 file_size() const { return file_size_; }
+ void GenerateMHTML(const base::FilePath& path, const GURL& url) {
+ NavigateToURL(shell(), url);
+
+ base::RunLoop run_loop;
+ shell()->web_contents()->GenerateMHTML(
+ path, base::Bind(&MHTMLGenerationTest::MHTMLGenerated, this,
+ run_loop.QuitClosure()));
+
+ // Block until the MHTML is generated.
+ run_loop.Run();
+
+ EXPECT_TRUE(has_mhtml_callback_run());
+ }
+
+ bool has_mhtml_callback_run() const { return has_mhtml_callback_run_; }
+ int64_t file_size() const { return file_size_; }
base::ScopedTempDir temp_dir_;
private:
- bool mhtml_generated_;
- int64 file_size_;
+ void MHTMLGenerated(base::Closure quit_closure, int64_t size) {
+ has_mhtml_callback_run_ = true;
+ file_size_ = size;
+ quit_closure.Run();
+ }
+
+ bool has_mhtml_callback_run_;
+ int64_t file_size_;
};
// Tests that generating a MHTML does create contents.
// Note that the actual content of the file is not tested, the purpose of this
-// test is to ensure we were successfull in creating the MHTML data from the
+// test is to ensure we were successful in creating the MHTML data from the
// renderer.
IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, GenerateMHTML) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
base::FilePath path(temp_dir_.path());
path = path.Append(FILE_PATH_LITERAL("test.mht"));
- NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+ GenerateMHTML(path, embedded_test_server()->GetURL("/simple_page.html"));
+ ASSERT_FALSE(HasFailure());
- shell()->web_contents()->GenerateMHTML(
- path, base::Bind(&MHTMLGenerationTest::MHTMLGenerated, this));
+ // Make sure the actual generated file has some contents.
+ EXPECT_GT(file_size(), 0); // Verify the size reported by the callback.
+ int64_t file_size;
+ ASSERT_TRUE(base::GetFileSize(path, &file_size));
+ EXPECT_GT(file_size, 100); // Verify the actual file size.
+}
- // Block until the MHTML is generated.
- RunMessageLoop();
+IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, InvalidPath) {
+ base::FilePath path(FILE_PATH_LITERAL("/invalid/file/path"));
- EXPECT_TRUE(mhtml_generated());
- EXPECT_GT(file_size(), 0);
+ GenerateMHTML(path, embedded_test_server()->GetURL(
+ "/download/local-about-blank-subframes.html"));
+ ASSERT_FALSE(HasFailure()); // No failures with the invocation itself?
- // Make sure the actual generated file has some contents.
- int64 file_size;
- ASSERT_TRUE(base::GetFileSize(path, &file_size));
- EXPECT_GT(file_size, 100);
+ EXPECT_EQ(file_size(), -1); // Expecting that the callback reported failure.
+}
+
+// Test suite that allows testing --site-per-process against cross-site frames.
+// See http://dev.chromium.org/developers/design-documents/site-isolation.
+class MHTMLGenerationSitePerProcessTest : public MHTMLGenerationTest {
+ public:
+ MHTMLGenerationSitePerProcessTest() {}
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ MHTMLGenerationTest::SetUpCommandLine(command_line);
+
+ // Append --site-per-process flag.
+ content::IsolateAllSitesForTesting(command_line);
+ }
+
+ void SetUpOnMainThread() override {
+ MHTMLGenerationTest::SetUpOnMainThread();
+
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ content::SetupCrossSiteRedirector(embedded_test_server());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MHTMLGenerationSitePerProcessTest);
+};
+
+// Test for crbug.com/538766.
+// Disabled because the test will fail until the bug is fixed
+// (but note that the test only fails with --site-per-process flag).
+IN_PROC_BROWSER_TEST_F(MHTMLGenerationSitePerProcessTest,
+ DISABLED_GenerateMHTML) {
+ base::FilePath path(temp_dir_.path());
+ path = path.Append(FILE_PATH_LITERAL("test.mht"));
+
+ GURL url(embedded_test_server()->GetURL(
+ "a.com", "/frame_tree/page_with_one_frame.html"));
+ GenerateMHTML(path, url);
+ ASSERT_FALSE(HasFailure());
+
+ std::string mhtml;
+ ASSERT_TRUE(base::ReadFileToString(path, &mhtml));
+
+ // Make sure the contents of both frames are present.
+ EXPECT_THAT(mhtml, HasSubstr("This page has one cross-site iframe"));
+ EXPECT_THAT(mhtml, HasSubstr("This page has no title")); // From title1.html.
+
+ // Make sure that URLs of both frames are present
+ // (note that these are single-line regexes).
+ EXPECT_THAT(
+ mhtml,
+ ContainsRegex("Content-Location:.*/frame_tree/page_with_one_frame.html"));
+ EXPECT_THAT(mhtml, ContainsRegex("Content-Location:.*/title1.html"));
}
} // namespace content
diff --git a/chromium/content/browser/download/mhtml_generation_manager.cc b/chromium/content/browser/download/mhtml_generation_manager.cc
index 91eb4ecfbc5..ef9202330d2 100644
--- a/chromium/content/browser/download/mhtml_generation_manager.cc
+++ b/chromium/content/browser/download/mhtml_generation_manager.cc
@@ -4,33 +4,66 @@
#include "content/browser/download/mhtml_generation_manager.h"
+#include <map>
+#include <queue>
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file.h"
+#include "base/guid.h"
+#include "base/macros.h"
+#include "base/scoped_observer.h"
#include "base/stl_util.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "base/strings/stringprintf.h"
+#include "content/browser/bad_message.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/common/frame_messages.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/web_contents.h"
-#include "content/common/view_messages.h"
+#include "net/base/mime_util.h"
namespace content {
+// The class and all of its members live on the UI thread. Only static methods
+// are executed on other threads.
class MHTMLGenerationManager::Job : public RenderProcessHostObserver {
public:
- Job();
+ Job(int job_id, WebContents* web_contents, GenerateMHTMLCallback callback);
~Job() override;
- void SetWebContents(WebContents* web_contents);
-
- base::File browser_file() { return browser_file_.Pass(); }
- void set_browser_file(base::File file) { browser_file_ = file.Pass(); }
-
- int process_id() { return process_id_; }
- int routing_id() { return routing_id_; }
+ int id() const { return job_id_; }
+ void set_browser_file(base::File file) { browser_file_ = std::move(file); }
+
+ GenerateMHTMLCallback callback() const { return callback_; }
+
+ // Handler for FrameHostMsg_SerializeAsMHTMLResponse (a notification from the
+ // renderer that the MHTML generation for previous frame has finished).
+ // Returns |true| upon success; |false| otherwise.
+ bool OnSerializeAsMHTMLResponse(
+ RenderFrameHostImpl* sender,
+ const std::set<std::string>& digests_of_uris_of_serialized_resources);
+
+ // Sends IPC to the renderer, asking for MHTML generation of the next frame.
+ //
+ // Returns true if the message was sent successfully; false otherwise.
+ bool SendToNextRenderFrame();
+
+ // Indicates if more calls to SendToNextRenderFrame are needed.
+ bool IsDone() const {
+ bool waiting_for_response_from_renderer =
+ frame_tree_node_id_of_busy_frame_ !=
+ FrameTreeNode::kFrameTreeNodeInvalidId;
+ bool no_more_requests_to_send = pending_frame_tree_node_ids_.empty();
+ return !waiting_for_response_from_renderer && no_more_requests_to_send;
+ }
- GenerateMHTMLCallback callback() { return callback_; }
- void set_callback(GenerateMHTMLCallback callback) { callback_ = callback; }
+ // Close the file on the file thread and respond back on the UI thread with
+ // file size.
+ void CloseFile(base::Callback<void(int64_t file_size)> callback);
// RenderProcessHostObserver:
void RenderProcessExited(RenderProcessHost* host,
@@ -39,200 +72,354 @@ class MHTMLGenerationManager::Job : public RenderProcessHostObserver {
void RenderProcessHostDestroyed(RenderProcessHost* host) override;
private:
+ static int64_t CloseFileOnFileThread(base::File file);
+ void AddFrame(RenderFrameHost* render_frame_host);
+
+ // Creates a new map with values (content ids) the same as in
+ // |frame_tree_node_to_content_id_| map, but with the keys translated from
+ // frame_tree_node_id into a |site_instance|-specific routing_id.
+ std::map<int, std::string> CreateFrameRoutingIdToContentId(
+ SiteInstance* site_instance);
+
+ // Id used to map renderer responses to jobs.
+ // See also MHTMLGenerationManager::id_to_job_ map.
+ int job_id_;
+
+ // The IDs of frames that still need to be processed.
+ std::queue<int> pending_frame_tree_node_ids_;
+
+ // Identifies a frame to which we've sent FrameMsg_SerializeAsMHTML but for
+ // which we didn't yet process FrameHostMsg_SerializeAsMHTMLResponse via
+ // OnSerializeAsMHTMLResponse.
+ int frame_tree_node_id_of_busy_frame_;
+
// The handle to the file the MHTML is saved to for the browser process.
base::File browser_file_;
- // The IDs mapping to a specific contents.
- int process_id_;
- int routing_id_;
+ // Map from frames to content ids (see WebFrameSerializer::generateMHTMLParts
+ // for more details about what "content ids" are and how they are used).
+ std::map<int, std::string> frame_tree_node_to_content_id_;
+
+ // MIME multipart boundary to use in the MHTML doc.
+ std::string mhtml_boundary_marker_;
+
+ // Digests of URIs of already generated MHTML parts.
+ std::set<std::string> digests_of_already_serialized_uris_;
+ std::string salt_;
// The callback to call once generation is complete.
GenerateMHTMLCallback callback_;
- // The RenderProcessHost being observed, or NULL if none is.
- RenderProcessHost* host_;
+ // RAII helper for registering this Job as a RenderProcessHost observer.
+ ScopedObserver<RenderProcessHost, MHTMLGenerationManager::Job>
+ observed_renderer_process_host_;
+
DISALLOW_COPY_AND_ASSIGN(Job);
};
-MHTMLGenerationManager::Job::Job()
- : process_id_(-1),
- routing_id_(-1),
- host_(NULL) {
+MHTMLGenerationManager::Job::Job(int job_id,
+ WebContents* web_contents,
+ GenerateMHTMLCallback callback)
+ : job_id_(job_id),
+ frame_tree_node_id_of_busy_frame_(FrameTreeNode::kFrameTreeNodeInvalidId),
+ mhtml_boundary_marker_(net::GenerateMimeMultipartBoundary()),
+ salt_(base::GenerateGUID()),
+ callback_(callback),
+ observed_renderer_process_host_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ web_contents->ForEachFrame(base::Bind(
+ &MHTMLGenerationManager::Job::AddFrame,
+ base::Unretained(this))); // Safe because ForEachFrame is synchronous.
+
+ // Main frame needs to be processed first.
+ DCHECK(!pending_frame_tree_node_ids_.empty());
+ DCHECK(FrameTreeNode::GloballyFindByID(pending_frame_tree_node_ids_.front())
+ ->parent() == nullptr);
}
MHTMLGenerationManager::Job::~Job() {
- if (host_)
- host_->RemoveObserver(this);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
-void MHTMLGenerationManager::Job::SetWebContents(WebContents* web_contents) {
- process_id_ = web_contents->GetRenderProcessHost()->GetID();
- routing_id_ = web_contents->GetRenderViewHost()->GetRoutingID();
- host_ = web_contents->GetRenderProcessHost();
- host_->AddObserver(this);
+std::map<int, std::string>
+MHTMLGenerationManager::Job::CreateFrameRoutingIdToContentId(
+ SiteInstance* site_instance) {
+ std::map<int, std::string> result;
+ for (const auto& it : frame_tree_node_to_content_id_) {
+ int ftn_id = it.first;
+ const std::string& content_id = it.second;
+
+ FrameTreeNode* ftn = FrameTreeNode::GloballyFindByID(ftn_id);
+ if (!ftn)
+ continue;
+
+ int routing_id =
+ ftn->render_manager()->GetRoutingIdForSiteInstance(site_instance);
+ if (routing_id == MSG_ROUTING_NONE)
+ continue;
+
+ result[routing_id] = content_id;
+ }
+ return result;
+}
+
+bool MHTMLGenerationManager::Job::SendToNextRenderFrame() {
+ DCHECK(browser_file_.IsValid());
+ DCHECK_LT(0u, pending_frame_tree_node_ids_.size());
+
+ FrameMsg_SerializeAsMHTML_Params ipc_params;
+ ipc_params.job_id = job_id_;
+ ipc_params.mhtml_boundary_marker = mhtml_boundary_marker_;
+
+ int frame_tree_node_id = pending_frame_tree_node_ids_.front();
+ pending_frame_tree_node_ids_.pop();
+ ipc_params.is_last_frame = pending_frame_tree_node_ids_.empty();
+
+ FrameTreeNode* ftn = FrameTreeNode::GloballyFindByID(frame_tree_node_id);
+ if (!ftn) // The contents went away.
+ return false;
+ RenderFrameHost* rfh = ftn->current_frame_host();
+
+ // Get notified if the target of the IPC message dies between responding.
+ observed_renderer_process_host_.RemoveAll();
+ observed_renderer_process_host_.Add(rfh->GetProcess());
+
+ // Tell the renderer to skip (= deduplicate) already covered MHTML parts.
+ ipc_params.salt = salt_;
+ ipc_params.digests_of_uris_to_skip = digests_of_already_serialized_uris_;
+
+ ipc_params.destination_file = IPC::GetFileHandleForProcess(
+ browser_file_.GetPlatformFile(), rfh->GetProcess()->GetHandle(),
+ false); // |close_source_handle|.
+ ipc_params.frame_routing_id_to_content_id =
+ CreateFrameRoutingIdToContentId(rfh->GetSiteInstance());
+
+ // Send the IPC asking the renderer to serialize the frame.
+ DCHECK_EQ(FrameTreeNode::kFrameTreeNodeInvalidId,
+ frame_tree_node_id_of_busy_frame_);
+ frame_tree_node_id_of_busy_frame_ = frame_tree_node_id;
+ rfh->Send(new FrameMsg_SerializeAsMHTML(rfh->GetRoutingID(), ipc_params));
+ return true;
}
void MHTMLGenerationManager::Job::RenderProcessExited(
RenderProcessHost* host,
base::TerminationStatus status,
int exit_code) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
MHTMLGenerationManager::GetInstance()->RenderProcessExited(this);
}
+void MHTMLGenerationManager::Job::AddFrame(RenderFrameHost* render_frame_host) {
+ auto* rfhi = static_cast<RenderFrameHostImpl*>(render_frame_host);
+ int frame_tree_node_id = rfhi->frame_tree_node()->frame_tree_node_id();
+ pending_frame_tree_node_ids_.push(frame_tree_node_id);
+
+ std::string guid = base::GenerateGUID();
+ std::string content_id = base::StringPrintf("<frame-%d-%s@mhtml.blink>",
+ frame_tree_node_id, guid.c_str());
+ frame_tree_node_to_content_id_[frame_tree_node_id] = content_id;
+}
+
void MHTMLGenerationManager::Job::RenderProcessHostDestroyed(
RenderProcessHost* host) {
- host_ = NULL;
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ observed_renderer_process_host_.Remove(host);
+}
+
+void MHTMLGenerationManager::Job::CloseFile(
+ base::Callback<void(int64_t)> callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (!browser_file_.IsValid()) {
+ callback.Run(-1);
+ return;
+ }
+
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&MHTMLGenerationManager::Job::CloseFileOnFileThread,
+ base::Passed(std::move(browser_file_))),
+ callback);
+}
+
+bool MHTMLGenerationManager::Job::OnSerializeAsMHTMLResponse(
+ RenderFrameHostImpl* sender,
+ const std::set<std::string>& digests_of_uris_of_serialized_resources) {
+ // Sanitize renderer input / reject unexpected messages.
+ int sender_id = sender->frame_tree_node()->frame_tree_node_id();
+ if (sender_id != frame_tree_node_id_of_busy_frame_) {
+ ReceivedBadMessage(sender->GetProcess(),
+ bad_message::DWNLD_INVALID_SERIALIZE_AS_MHTML_RESPONSE);
+ return false; // Report failure.
+ }
+ frame_tree_node_id_of_busy_frame_ = FrameTreeNode::kFrameTreeNodeInvalidId;
+
+ // Renderer should be deduping resources with the same uris.
+ DCHECK_EQ(0u, base::STLSetIntersection<std::set<std::string>>(
+ digests_of_already_serialized_uris_,
+ digests_of_uris_of_serialized_resources).size());
+ digests_of_already_serialized_uris_.insert(
+ digests_of_uris_of_serialized_resources.begin(),
+ digests_of_uris_of_serialized_resources.end());
+
+ if (pending_frame_tree_node_ids_.empty())
+ return true; // Report success.
+
+ return SendToNextRenderFrame();
+}
+
+// static
+int64_t MHTMLGenerationManager::Job::CloseFileOnFileThread(base::File file) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ DCHECK(file.IsValid());
+ int64_t file_size = file.GetLength();
+ file.Close();
+ return file_size;
}
MHTMLGenerationManager* MHTMLGenerationManager::GetInstance() {
return base::Singleton<MHTMLGenerationManager>::get();
}
-MHTMLGenerationManager::MHTMLGenerationManager() {
-}
+MHTMLGenerationManager::MHTMLGenerationManager() : next_job_id_(0) {}
MHTMLGenerationManager::~MHTMLGenerationManager() {
STLDeleteValues(&id_to_job_);
}
void MHTMLGenerationManager::SaveMHTML(WebContents* web_contents,
- const base::FilePath& file,
+ const base::FilePath& file_path,
const GenerateMHTMLCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
int job_id = NewJob(web_contents, callback);
- base::ProcessHandle renderer_process =
- web_contents->GetRenderProcessHost()->GetHandle();
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&MHTMLGenerationManager::CreateFile, base::Unretained(this),
- job_id, file, renderer_process));
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&MHTMLGenerationManager::CreateFile, file_path),
+ base::Bind(&MHTMLGenerationManager::OnFileAvailable,
+ base::Unretained(this), // Safe b/c |this| is a singleton.
+ job_id));
}
-void MHTMLGenerationManager::StreamMHTML(
- WebContents* web_contents,
- base::File browser_file,
- const GenerateMHTMLCallback& callback) {
+void MHTMLGenerationManager::OnSerializeAsMHTMLResponse(
+ RenderFrameHostImpl* sender,
+ int job_id,
+ bool mhtml_generation_in_renderer_succeeded,
+ const std::set<std::string>& digests_of_uris_of_serialized_resources) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- int job_id = NewJob(web_contents, callback);
-
- base::ProcessHandle renderer_process =
- web_contents->GetRenderProcessHost()->GetHandle();
- IPC::PlatformFileForTransit renderer_file =
- IPC::GetFileHandleForProcess(browser_file.GetPlatformFile(),
- renderer_process, false);
+ Job* job = FindJob(job_id);
+ if (!job) {
+ ReceivedBadMessage(sender->GetProcess(),
+ bad_message::DWNLD_INVALID_SERIALIZE_AS_MHTML_RESPONSE);
+ return;
+ }
- FileAvailable(job_id, browser_file.Pass(), renderer_file);
-}
+ if (!mhtml_generation_in_renderer_succeeded) {
+ JobFinished(job, JobStatus::FAILURE);
+ return;
+ }
+ if (!job->OnSerializeAsMHTMLResponse(
+ sender, digests_of_uris_of_serialized_resources)) {
+ JobFinished(job, JobStatus::FAILURE);
+ return;
+ }
-void MHTMLGenerationManager::MHTMLGenerated(int job_id, int64 mhtml_data_size) {
- JobFinished(job_id, mhtml_data_size);
+ if (job->IsDone())
+ JobFinished(job, JobStatus::SUCCESS);
}
-void MHTMLGenerationManager::CreateFile(
- int job_id, const base::FilePath& file_path,
- base::ProcessHandle renderer_process) {
+// static
+base::File MHTMLGenerationManager::CreateFile(const base::FilePath& file_path) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- base::File browser_file(
- file_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+
+ // SECURITY NOTE: A file descriptor to the file created below will be passed
+ // to multiple renderer processes which (in out-of-process iframes mode) can
+ // act on behalf of separate web principals. Therefore it is important to
+ // only allow writing to the file and forbid reading from the file (as this
+ // would allow reading content generated by other renderers / other web
+ // principals).
+ uint32_t file_flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE;
+
+ base::File browser_file(file_path, file_flags);
if (!browser_file.IsValid()) {
LOG(ERROR) << "Failed to create file to save MHTML at: " <<
file_path.value();
}
-
- IPC::PlatformFileForTransit renderer_file =
- IPC::GetFileHandleForProcess(browser_file.GetPlatformFile(),
- renderer_process, false);
-
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&MHTMLGenerationManager::FileAvailable,
- base::Unretained(this),
- job_id,
- base::Passed(&browser_file),
- renderer_file));
+ return browser_file;
}
-void MHTMLGenerationManager::FileAvailable(
- int job_id,
- base::File browser_file,
- IPC::PlatformFileForTransit renderer_file) {
+void MHTMLGenerationManager::OnFileAvailable(int job_id,
+ base::File browser_file) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ Job* job = FindJob(job_id);
+ DCHECK(job);
+
if (!browser_file.IsValid()) {
LOG(ERROR) << "Failed to create file";
- JobFinished(job_id, -1);
+ JobFinished(job, JobStatus::FAILURE);
return;
}
- IDToJobMap::iterator iter = id_to_job_.find(job_id);
- if (iter == id_to_job_.end()) {
- NOTREACHED();
- return;
- }
-
- Job* job = iter->second;
- job->set_browser_file(browser_file.Pass());
+ job->set_browser_file(std::move(browser_file));
- RenderViewHost* rvh = RenderViewHost::FromID(
- job->process_id(), job->routing_id());
- if (!rvh) {
- // The contents went away.
- JobFinished(job_id, -1);
- return;
+ if (!job->SendToNextRenderFrame()) {
+ JobFinished(job, JobStatus::FAILURE);
}
-
- rvh->Send(new ViewMsg_SavePageAsMHTML(rvh->GetRoutingID(), job_id,
- renderer_file));
}
-void MHTMLGenerationManager::JobFinished(int job_id, int64 file_size) {
+void MHTMLGenerationManager::JobFinished(Job* job, JobStatus job_status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- IDToJobMap::iterator iter = id_to_job_.find(job_id);
- if (iter == id_to_job_.end()) {
- NOTREACHED();
- return;
- }
+ DCHECK(job);
- Job* job = iter->second;
- job->callback().Run(file_size);
+ job->CloseFile(
+ base::Bind(&MHTMLGenerationManager::OnFileClosed,
+ base::Unretained(this), // Safe b/c |this| is a singleton.
+ job->id(), job_status));
+}
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&MHTMLGenerationManager::CloseFile, base::Unretained(this),
- base::Passed(job->browser_file())));
+void MHTMLGenerationManager::OnFileClosed(int job_id,
+ JobStatus job_status,
+ int64_t file_size) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ Job* job = FindJob(job_id);
+ DCHECK(job);
+
+ job->callback().Run(job_status == JobStatus::SUCCESS ? file_size : -1);
id_to_job_.erase(job_id);
delete job;
}
-void MHTMLGenerationManager::CloseFile(base::File file) {
- DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- file.Close();
-}
-
int MHTMLGenerationManager::NewJob(WebContents* web_contents,
const GenerateMHTMLCallback& callback) {
- static int id_counter = 0;
- int job_id = id_counter++;
- Job* job = new Job();
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ int job_id = next_job_id_++;
+ Job* job = new Job(job_id, web_contents, callback);
id_to_job_[job_id] = job;
- job->SetWebContents(web_contents);
- job->set_callback(callback);
return job_id;
}
-void MHTMLGenerationManager::RenderProcessExited(Job* job) {
+MHTMLGenerationManager::Job* MHTMLGenerationManager::FindJob(int job_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- for (IDToJobMap::iterator it = id_to_job_.begin(); it != id_to_job_.end();
- ++it) {
- if (it->second == job) {
- JobFinished(it->first, -1);
- return;
- }
+
+ IDToJobMap::iterator iter = id_to_job_.find(job_id);
+ if (iter == id_to_job_.end()) {
+ NOTREACHED();
+ return nullptr;
}
- NOTREACHED();
+ return iter->second;
+}
+
+void MHTMLGenerationManager::RenderProcessExited(Job* job) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(job);
+ JobFinished(job, JobStatus::FAILURE);
}
} // namespace content
diff --git a/chromium/content/browser/download/mhtml_generation_manager.h b/chromium/content/browser/download/mhtml_generation_manager.h
index 4caa805dc96..24e729a86d7 100644
--- a/chromium/content/browser/download/mhtml_generation_manager.h
+++ b/chromium/content/browser/download/mhtml_generation_manager.h
@@ -5,9 +5,14 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_MHTML_GENERATION_MANAGER_H_
#define CONTENT_BROWSER_DOWNLOAD_MHTML_GENERATION_MANAGER_H_
+#include <stdint.h>
+
#include <map>
+#include <set>
+#include <string>
#include "base/files/file.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/process/process.h"
#include "ipc/ipc_platform_file.h"
@@ -18,68 +23,69 @@ class FilePath;
namespace content {
+class RenderFrameHostImpl;
class WebContents;
+// The class and all of its members live on the UI thread. Only static methods
+// are executed on other threads.
class MHTMLGenerationManager {
public:
static MHTMLGenerationManager* GetInstance();
- typedef base::Callback<void(int64 /* size of the file */)>
- GenerateMHTMLCallback;
+ // GenerateMHTMLCallback is called to report completion and status of MHTML
+ // generation. On success |file_size| indicates the size of the
+ // generated file. On failure |file_size| is -1.
+ typedef base::Callback<void(int64_t file_size)> GenerateMHTMLCallback;
// Instructs the render view to generate a MHTML representation of the current
// page for |web_contents|.
void SaveMHTML(WebContents* web_contents,
- const base::FilePath& file,
+ const base::FilePath& file_path,
const GenerateMHTMLCallback& callback);
- // Instructs the render view to generate a MHTML representation of the current
- // page for |web_contents|.
- void StreamMHTML(WebContents* web_contents,
- base::File file,
- const GenerateMHTMLCallback& callback);
-
- // Notification from the renderer that the MHTML generation finished.
- // |mhtml_data_size| contains the size in bytes of the generated MHTML data,
- // or -1 in case of failure.
- void MHTMLGenerated(int job_id, int64 mhtml_data_size);
+ // Handler for FrameHostMsg_SerializeAsMHTMLResponse (a notification from the
+ // renderer that the MHTML generation finished for a single frame).
+ void OnSerializeAsMHTMLResponse(
+ RenderFrameHostImpl* sender,
+ int job_id,
+ bool mhtml_generation_in_renderer_succeeded,
+ const std::set<std::string>& digests_of_uris_of_serialized_resources);
private:
friend struct base::DefaultSingletonTraits<MHTMLGenerationManager>;
class Job;
+ enum class JobStatus { SUCCESS, FAILURE };
MHTMLGenerationManager();
virtual ~MHTMLGenerationManager();
// Called on the file thread to create |file|.
- void CreateFile(int job_id,
- const base::FilePath& file,
- base::ProcessHandle renderer_process);
+ static base::File CreateFile(const base::FilePath& file_path);
// Called on the UI thread when the file that should hold the MHTML data has
- // been created. This receives a handle to that file for the browser process
- // and one for the renderer process.
- void FileAvailable(int job_id,
- base::File browser_file,
- IPC::PlatformFileForTransit renderer_file);
+ // been created.
+ void OnFileAvailable(int job_id, base::File browser_file);
- // Called on the file thread to close the file the MHTML was saved to.
- void CloseFile(base::File file);
+ // Called on the UI thread when a job has been finished.
+ void JobFinished(Job* job, JobStatus job_status);
- // Called on the UI thread when a job has been processed (successfully or
- // not). Closes the file and removes the job from the job map.
- // |mhtml_data_size| is -1 if the MHTML generation failed.
- void JobFinished(int job_id, int64 mhtml_data_size);
+ // Called on the UI thread after the file got finalized and we have its size.
+ void OnFileClosed(int job_id, JobStatus job_status, int64_t file_size);
- // Creates an register a new job.
+ // Creates and registers a new job.
int NewJob(WebContents* web_contents, const GenerateMHTMLCallback& callback);
+ // Finds job by id. Returns nullptr if no job with a given id was found.
+ Job* FindJob(int job_id);
+
// Called when the render process connected to a job exits.
void RenderProcessExited(Job* job);
typedef std::map<int, Job*> IDToJobMap;
IDToJobMap id_to_job_;
+ int next_job_id_;
+
DISALLOW_COPY_AND_ASSIGN(MHTMLGenerationManager);
};
diff --git a/chromium/content/browser/download/mock_download_file.h b/chromium/content/browser/download/mock_download_file.h
index 8be2c9351db..a0020b686c9 100644
--- a/chromium/content/browser/download/mock_download_file.h
+++ b/chromium/content/browser/download/mock_download_file.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_MOCK_DOWNLOAD_FILE_H_
#define CONTENT_BROWSER_DOWNLOAD_MOCK_DOWNLOAD_FILE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
@@ -40,8 +43,8 @@ class MockDownloadFile : public DownloadFile {
MOCK_METHOD0(Finish, void());
MOCK_CONST_METHOD0(FullPath, base::FilePath());
MOCK_CONST_METHOD0(InProgress, bool());
- MOCK_CONST_METHOD0(BytesSoFar, int64());
- MOCK_CONST_METHOD0(CurrentSpeed, int64());
+ MOCK_CONST_METHOD0(BytesSoFar, int64_t());
+ MOCK_CONST_METHOD0(CurrentSpeed, int64_t());
MOCK_METHOD1(GetHash, bool(std::string* hash));
MOCK_METHOD0(GetHashState, std::string());
MOCK_METHOD0(SendUpdate, void());
diff --git a/chromium/content/browser/download/rate_estimator.cc b/chromium/content/browser/download/rate_estimator.cc
index dcdd71af41d..953e958e566 100644
--- a/chromium/content/browser/download/rate_estimator.cc
+++ b/chromium/content/browser/download/rate_estimator.cc
@@ -40,15 +40,15 @@ RateEstimator::RateEstimator(TimeDelta bucket_time,
RateEstimator::~RateEstimator() {
}
-void RateEstimator::Increment(uint32 count) {
+void RateEstimator::Increment(uint32_t count) {
Increment(count, TimeTicks::Now());
}
-void RateEstimator::Increment(uint32 count, TimeTicks now) {
+void RateEstimator::Increment(uint32_t count, TimeTicks now) {
ClearOldBuckets(now);
- int64 seconds_since_oldest = (now - oldest_time_).InSeconds();
+ int64_t seconds_since_oldest = (now - oldest_time_).InSeconds();
DCHECK(seconds_since_oldest >= 0);
- int64 delta_buckets = seconds_since_oldest / bucket_time_.InSeconds();
+ int64_t delta_buckets = seconds_since_oldest / bucket_time_.InSeconds();
DCHECK(delta_buckets >= 0);
size_t index_offset = static_cast<size_t>(delta_buckets);
DCHECK(index_offset <= history_.size());
@@ -56,17 +56,17 @@ void RateEstimator::Increment(uint32 count, TimeTicks now) {
history_[current_index] += count;
}
-uint64 RateEstimator::GetCountPerSecond() const {
+uint64_t RateEstimator::GetCountPerSecond() const {
return GetCountPerSecond(TimeTicks::Now());
}
-uint64 RateEstimator::GetCountPerSecond(TimeTicks now) const {
+uint64_t RateEstimator::GetCountPerSecond(TimeTicks now) const {
const_cast<RateEstimator*>(this)->ClearOldBuckets(now);
// TODO(cbentzel): Support fractional seconds for active bucket?
// We explicitly don't check for overflow here. If it happens, unsigned
// arithmetic at least guarantees behavior by wrapping around. The estimate
// will be off, but the code will still be valid.
- uint64 total_count = 0;
+ uint64_t total_count = 0;
for (size_t i = 0; i < bucket_count_; ++i) {
size_t index = (oldest_index_ + i) % history_.size();
total_count += history_[index];
@@ -75,9 +75,9 @@ uint64 RateEstimator::GetCountPerSecond(TimeTicks now) const {
}
void RateEstimator::ClearOldBuckets(TimeTicks now) {
- int64 seconds_since_oldest = (now - oldest_time_).InSeconds();
+ int64_t seconds_since_oldest = (now - oldest_time_).InSeconds();
- int64 delta_buckets = seconds_since_oldest / bucket_time_.InSeconds();
+ int64_t delta_buckets = seconds_since_oldest / bucket_time_.InSeconds();
// It's possible (although unlikely) for there to be rollover with TimeTicks.
// If that's the case, just reset the history.
diff --git a/chromium/content/browser/download/rate_estimator.h b/chromium/content/browser/download/rate_estimator.h
index 111e8eb8d8b..09e55582387 100644
--- a/chromium/content/browser/download/rate_estimator.h
+++ b/chromium/content/browser/download/rate_estimator.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_RATE_ESTIMATOR_H_
#define CONTENT_BROWSER_DOWNLOAD_RATE_ESTIMATOR_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
@@ -28,19 +30,19 @@ class CONTENT_EXPORT RateEstimator {
// Increment the counter by |count|. The first variant uses the current time,
// the second variant provides the time that |count| is observed.
- void Increment(uint32 count);
- void Increment(uint32 count, base::TimeTicks now);
+ void Increment(uint32_t count);
+ void Increment(uint32_t count, base::TimeTicks now);
// Get a rate estimate, in terms of counts/second. The first variant uses the
// current time, the second variant provides the time.
- uint64 GetCountPerSecond() const;
- uint64 GetCountPerSecond(base::TimeTicks now) const;
+ uint64_t GetCountPerSecond() const;
+ uint64_t GetCountPerSecond(base::TimeTicks now) const;
private:
void ClearOldBuckets(base::TimeTicks now);
void ResetBuckets(base::TimeTicks now);
- std::vector<uint32> history_;
+ std::vector<uint32_t> history_;
base::TimeDelta bucket_time_;
size_t oldest_index_;
size_t bucket_count_;
diff --git a/chromium/content/browser/download/save_file.cc b/chromium/content/browser/download/save_file.cc
index a5c7488242f..5085e477c15 100644
--- a/chromium/content/browser/download/save_file.cc
+++ b/chromium/content/browser/download/save_file.cc
@@ -72,7 +72,7 @@ bool SaveFile::InProgress() const {
return file_.in_progress();
}
-int64 SaveFile::BytesSoFar() const {
+int64_t SaveFile::BytesSoFar() const {
return file_.bytes_so_far();
}
diff --git a/chromium/content/browser/download/save_file.h b/chromium/content/browser/download/save_file.h
index e00be689429..1dc82170ad0 100644
--- a/chromium/content/browser/download/save_file.h
+++ b/chromium/content/browser/download/save_file.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_H_
#define CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/download/base_file.h"
#include "content/browser/download/save_types.h"
@@ -34,12 +37,12 @@ class SaveFile {
void AnnotateWithSourceInformation();
base::FilePath FullPath() const;
bool InProgress() const;
- int64 BytesSoFar() const;
+ int64_t BytesSoFar() const;
bool GetHash(std::string* hash);
std::string DebugString() const;
// Accessors.
- int save_id() const { return info_->save_id; }
+ SaveItemId save_item_id() const { return info_->save_item_id; }
int render_process_id() const { return info_->render_process_id; }
int request_id() const { return info_->request_id; }
SaveFileCreateInfo::SaveFileSource save_source() const {
diff --git a/chromium/content/browser/download/save_file_manager.cc b/chromium/content/browser/download/save_file_manager.cc
index 14abb510e0c..cf2e59ce3f1 100644
--- a/chromium/content/browser/download/save_file_manager.cc
+++ b/chromium/content/browser/download/save_file_manager.cc
@@ -25,9 +25,7 @@
namespace content {
-SaveFileManager::SaveFileManager()
- : next_id_(0) {
-}
+SaveFileManager::SaveFileManager() {}
SaveFileManager::~SaveFileManager() {
// Check for clean shutdown.
@@ -48,139 +46,80 @@ void SaveFileManager::OnShutdown() {
STLDeleteValues(&save_file_map_);
}
-SaveFile* SaveFileManager::LookupSaveFile(int save_id) {
- SaveFileMap::iterator it = save_file_map_.find(save_id);
- return it == save_file_map_.end() ? NULL : it->second;
-}
-
-// Called on the IO thread when
-// a) The ResourceDispatcherHostImpl has decided that a request is savable.
-// b) The resource does not come from the network, but we still need a
-// save ID for for managing the status of the saving operation. So we
-// file a request from the file thread to the IO thread to generate a
-// unique save ID.
-int SaveFileManager::GetNextId() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return next_id_++;
-}
-
-void SaveFileManager::RegisterStartingRequest(const GURL& save_url,
- SavePackage* save_package) {
- // Make sure it runs in the UI thread.
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- int contents_id = save_package->contents_id();
-
- // Register this starting request.
- StartingRequestsMap& starting_requests =
- contents_starting_requests_[contents_id];
- bool never_present = starting_requests.insert(
- StartingRequestsMap::value_type(save_url.spec(), save_package)).second;
- DCHECK(never_present);
-}
-
-SavePackage* SaveFileManager::UnregisterStartingRequest(
- const GURL& save_url, int contents_id) {
- // Make sure it runs in UI thread.
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- ContentsToStartingRequestsMap::iterator it =
- contents_starting_requests_.find(contents_id);
- if (it != contents_starting_requests_.end()) {
- StartingRequestsMap& requests = it->second;
- StartingRequestsMap::iterator sit = requests.find(save_url.spec());
- if (sit == requests.end())
- return NULL;
-
- // Found, erase it from starting list and return SavePackage.
- SavePackage* save_package = sit->second;
- requests.erase(sit);
- // If there is no element in requests, remove it
- if (requests.empty())
- contents_starting_requests_.erase(it);
- return save_package;
- }
-
- return NULL;
+SaveFile* SaveFileManager::LookupSaveFile(SaveItemId save_item_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ SaveFileMap::iterator it = save_file_map_.find(save_item_id);
+ return it == save_file_map_.end() ? nullptr : it->second;
}
// Look up a SavePackage according to a save id.
-SavePackage* SaveFileManager::LookupPackage(int save_id) {
+SavePackage* SaveFileManager::LookupPackage(SaveItemId save_item_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SavePackageMap::iterator it = packages_.find(save_id);
+ SavePackageMap::iterator it = packages_.find(save_item_id);
if (it != packages_.end())
return it->second;
- return NULL;
+ return nullptr;
}
// Call from SavePackage for starting a saving job
-void SaveFileManager::SaveURL(
- const GURL& url,
- const Referrer& referrer,
- int render_process_host_id,
- int render_view_id,
- int render_frame_id,
- SaveFileCreateInfo::SaveFileSource save_source,
- const base::FilePath& file_full_path,
- ResourceContext* context,
- SavePackage* save_package) {
+void SaveFileManager::SaveURL(SaveItemId save_item_id,
+ const GURL& url,
+ const Referrer& referrer,
+ int render_process_host_id,
+ int render_view_routing_id,
+ int render_frame_routing_id,
+ SaveFileCreateInfo::SaveFileSource save_source,
+ const base::FilePath& file_full_path,
+ ResourceContext* context,
+ SavePackage* save_package) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Register a saving job.
- RegisterStartingRequest(url, save_package);
if (save_source == SaveFileCreateInfo::SAVE_FILE_FROM_NET) {
DCHECK(url.is_valid());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&SaveFileManager::OnSaveURL, this, url, referrer,
- render_process_host_id, render_view_id, render_frame_id,
- context));
+ save_item_id, save_package->id(), render_process_host_id,
+ render_view_routing_id, render_frame_routing_id, context));
} else {
// We manually start the save job.
- SaveFileCreateInfo* info = new SaveFileCreateInfo(file_full_path,
- url,
- save_source,
- -1);
- info->render_process_id = render_process_host_id;
- info->render_frame_id = render_frame_id;
+ SaveFileCreateInfo* info = new SaveFileCreateInfo(
+ file_full_path, url, save_item_id, save_package->id(),
+ render_process_host_id, render_frame_routing_id, save_source);
// Since the data will come from render process, so we need to start
// this kind of save job by ourself.
BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&SaveFileManager::OnRequireSaveJobFromOtherSource,
- this, info));
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&SaveFileManager::StartSave, this, info));
}
}
// Utility function for look up table maintenance, called on the UI thread.
// A manager may have multiple save page job (SavePackage) in progress,
// so we just look up the save id and remove it from the tracking table.
-// If the save id is -1, it means we just send a request to save, but the
-// saving action has still not happened, need to call UnregisterStartingRequest
-// to remove it from the tracking map.
-void SaveFileManager::RemoveSaveFile(int save_id, const GURL& save_url,
- SavePackage* package) {
- DCHECK(package);
+void SaveFileManager::RemoveSaveFile(SaveItemId save_item_id,
+ SavePackage* save_package) {
+ DCHECK(save_package);
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// A save page job (SavePackage) can only have one manager,
// so remove it if it exists.
- if (save_id == -1) {
- SavePackage* old_package =
- UnregisterStartingRequest(save_url, package->contents_id());
- DCHECK_EQ(old_package, package);
- } else {
- SavePackageMap::iterator it = packages_.find(save_id);
- if (it != packages_.end())
- packages_.erase(it);
- }
+ SavePackageMap::iterator it = packages_.find(save_item_id);
+ if (it != packages_.end())
+ packages_.erase(it);
}
// Static
SavePackage* SaveFileManager::GetSavePackageFromRenderIds(
- int render_process_id, int render_frame_id) {
+ int render_process_id,
+ int render_frame_routing_id) {
RenderFrameHost* render_frame_host =
- RenderFrameHost::FromID(render_process_id, render_frame_id);
+ RenderFrameHost::FromID(render_process_id, render_frame_routing_id);
+ if (!render_frame_host)
+ return nullptr;
+
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(
render_frame_host));
@@ -199,12 +138,12 @@ void SaveFileManager::DeleteDirectoryOrFile(const base::FilePath& full_path,
this, full_path, is_dir));
}
-void SaveFileManager::SendCancelRequest(int save_id) {
+void SaveFileManager::SendCancelRequest(SaveItemId save_item_id) {
// Cancel the request which has specific save id.
- DCHECK_GT(save_id, -1);
+ DCHECK(!save_item_id.is_null());
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::CancelSave, this, save_id));
+ base::Bind(&SaveFileManager::CancelSave, this, save_item_id));
}
// Notifications sent from the IO thread and run on the file thread:
@@ -221,24 +160,24 @@ void SaveFileManager::StartSave(SaveFileCreateInfo* info) {
// TODO(phajdan.jr): We should check the return value and handle errors here.
save_file->Initialize();
- DCHECK(!LookupSaveFile(info->save_id));
- save_file_map_[info->save_id] = save_file;
+ DCHECK(!LookupSaveFile(info->save_item_id));
+ save_file_map_[info->save_item_id] = save_file;
info->path = save_file->FullPath();
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&SaveFileManager::OnStartSave, this, info));
+ base::Bind(&SaveFileManager::OnStartSave, this, *info));
}
// We do forward an update to the UI thread here, since we do not use timer to
// update the UI. If the user has canceled the saving action (in the UI
// thread). We may receive a few more updates before the IO thread gets the
// cancel message. We just delete the data since the SaveFile has been deleted.
-void SaveFileManager::UpdateSaveProgress(int save_id,
+void SaveFileManager::UpdateSaveProgress(SaveItemId save_item_id,
net::IOBuffer* data,
int data_len) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- SaveFile* save_file = LookupSaveFile(save_id);
+ SaveFile* save_file = LookupSaveFile(save_item_id);
if (save_file) {
DCHECK(save_file->InProgress());
@@ -246,146 +185,91 @@ void SaveFileManager::UpdateSaveProgress(int save_id,
save_file->AppendDataToFile(data->data(), data_len);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&SaveFileManager::OnUpdateSaveProgress,
- this,
- save_file->save_id(),
- save_file->BytesSoFar(),
+ base::Bind(&SaveFileManager::OnUpdateSaveProgress, this,
+ save_file->save_item_id(), save_file->BytesSoFar(),
reason == DOWNLOAD_INTERRUPT_REASON_NONE));
}
}
// The IO thread will call this when saving is completed or it got error when
-// fetching data. In the former case, we forward the message to OnSaveFinished
-// in UI thread. In the latter case, the save ID will be -1, which means the
-// saving action did not even start, so we need to call OnErrorFinished in UI
-// thread, which will use the save URL to find corresponding request record and
-// delete it.
-void SaveFileManager::SaveFinished(int save_id,
- const GURL& save_url,
- int render_process_id,
+// fetching data. We forward the message to OnSaveFinished in UI thread.
+void SaveFileManager::SaveFinished(SaveItemId save_item_id,
+ SavePackageId save_package_id,
bool is_success) {
DVLOG(20) << " " << __FUNCTION__ << "()"
- << " save_id = " << save_id
- << " save_url = \"" << save_url.spec() << "\""
+ << " save_item_id = " << save_item_id
+ << " save_package_id = " << save_package_id
<< " is_success = " << is_success;
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- SaveFileMap::iterator it = save_file_map_.find(save_id);
- if (it != save_file_map_.end()) {
- SaveFile* save_file = it->second;
- // This routine may be called twice from the same SavePackage - once for the
- // file itself, and once when all frames have been serialized.
- // So we can't assert that the file is InProgress() here.
- // TODO(rdsmith): Fix this logic and put the DCHECK below back in.
- // DCHECK(save_file->InProgress());
-
+ SaveFile* save_file = LookupSaveFile(save_item_id);
+ if (save_file != nullptr) {
+ DCHECK(save_file->InProgress());
DVLOG(20) << " " << __FUNCTION__ << "()"
<< " save_file = " << save_file->DebugString();
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&SaveFileManager::OnSaveFinished, this, save_id,
- save_file->BytesSoFar(), is_success));
+ base::Bind(&SaveFileManager::OnSaveFinished, this, save_item_id,
+ save_file->BytesSoFar(), is_success));
save_file->Finish();
save_file->Detach();
- } else if (save_id == -1) {
- // Before saving started, we got error. We still call finish process.
- DCHECK(!save_url.is_empty());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&SaveFileManager::OnErrorFinished, this, save_url,
- render_process_id));
}
}
// Notifications sent from the file thread and run on the UI thread.
-void SaveFileManager::OnStartSave(const SaveFileCreateInfo* info) {
+void SaveFileManager::OnStartSave(const SaveFileCreateInfo& info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SavePackage* save_package =
- GetSavePackageFromRenderIds(info->render_process_id,
- info->render_frame_id);
+ SavePackage* save_package = GetSavePackageFromRenderIds(
+ info.render_process_id, info.render_frame_routing_id);
if (!save_package) {
// Cancel this request.
- SendCancelRequest(info->save_id);
+ SendCancelRequest(info.save_item_id);
return;
}
// Insert started saving job to tracking list.
- SavePackageMap::iterator sit = packages_.find(info->save_id);
- if (sit == packages_.end()) {
- // Find the registered request. If we can not find, it means we have
- // canceled the job before.
- SavePackage* old_save_package = UnregisterStartingRequest(info->url,
- info->render_process_id);
- if (!old_save_package) {
- // Cancel this request.
- SendCancelRequest(info->save_id);
- return;
- }
- DCHECK_EQ(old_save_package, save_package);
- packages_[info->save_id] = save_package;
- } else {
- NOTREACHED();
- }
+ DCHECK(packages_.find(info.save_item_id) == packages_.end());
+ packages_[info.save_item_id] = save_package;
// Forward this message to SavePackage.
- save_package->StartSave(info);
+ save_package->StartSave(&info);
}
-void SaveFileManager::OnUpdateSaveProgress(int save_id, int64 bytes_so_far,
+void SaveFileManager::OnUpdateSaveProgress(SaveItemId save_item_id,
+ int64_t bytes_so_far,
bool write_success) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SavePackage* package = LookupPackage(save_id);
+ SavePackage* package = LookupPackage(save_item_id);
if (package)
- package->UpdateSaveProgress(save_id, bytes_so_far, write_success);
+ package->UpdateSaveProgress(save_item_id, bytes_so_far, write_success);
else
- SendCancelRequest(save_id);
+ SendCancelRequest(save_item_id);
}
-void SaveFileManager::OnSaveFinished(int save_id,
- int64 bytes_so_far,
+void SaveFileManager::OnSaveFinished(SaveItemId save_item_id,
+ int64_t bytes_so_far,
bool is_success) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SavePackage* package = LookupPackage(save_id);
+ SavePackage* package = LookupPackage(save_item_id);
if (package)
- package->SaveFinished(save_id, bytes_so_far, is_success);
-}
-
-void SaveFileManager::OnErrorFinished(const GURL& save_url, int contents_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SavePackage* save_package = UnregisterStartingRequest(save_url, contents_id);
- if (save_package)
- save_package->SaveFailed(save_url);
+ package->SaveFinished(save_item_id, bytes_so_far, is_success);
}
// Notifications sent from the UI thread and run on the IO thread.
-void SaveFileManager::OnSaveURL(
- const GURL& url,
- const Referrer& referrer,
- int render_process_host_id,
- int render_view_id,
- int render_frame_id,
- ResourceContext* context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- ResourceDispatcherHostImpl::Get()->BeginSaveFile(url,
- referrer,
- render_process_host_id,
- render_view_id,
- render_frame_id,
- context);
-}
-
-void SaveFileManager::OnRequireSaveJobFromOtherSource(
- SaveFileCreateInfo* info) {
+void SaveFileManager::OnSaveURL(const GURL& url,
+ const Referrer& referrer,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ int render_process_host_id,
+ int render_view_routing_id,
+ int render_frame_routing_id,
+ ResourceContext* context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(info->save_id, -1);
- // Generate a unique save id.
- info->save_id = GetNextId();
- // Start real saving action.
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::StartSave, this, info));
+ ResourceDispatcherHostImpl::Get()->BeginSaveFile(
+ url, referrer, save_item_id, save_package_id, render_process_host_id,
+ render_view_routing_id, render_frame_routing_id, context);
}
void SaveFileManager::ExecuteCancelSaveRequest(int render_process_id,
@@ -402,9 +286,9 @@ void SaveFileManager::ExecuteCancelSaveRequest(int render_process_id,
// but we do forward the cancel to the IO thread. Since this message has been
// sent from the UI thread, the saving job may have already completed and
// won't exist in our map.
-void SaveFileManager::CancelSave(int save_id) {
+void SaveFileManager::CancelSave(SaveItemId save_item_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- SaveFileMap::iterator it = save_file_map_.find(save_id);
+ SaveFileMap::iterator it = save_file_map_.find(save_item_id);
if (it != save_file_map_.end()) {
SaveFile* save_file = it->second;
@@ -432,14 +316,15 @@ void SaveFileManager::CancelSave(int save_id) {
}
}
-// It is possible that SaveItem which has specified save_id has been canceled
+// It is possible that SaveItem which has specified save_item_id has been
+// canceled
// before this function runs. So if we can not find corresponding SaveFile by
-// using specified save_id, just return.
+// using specified save_item_id, just return.
void SaveFileManager::SaveLocalFile(const GURL& original_file_url,
- int save_id,
- int render_process_id) {
+ SaveItemId save_item_id,
+ SavePackageId save_package_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- SaveFile* save_file = LookupSaveFile(save_id);
+ SaveFile* save_file = LookupSaveFile(save_item_id);
if (!save_file)
return;
// If it has finished, just return.
@@ -456,14 +341,14 @@ void SaveFileManager::SaveLocalFile(const GURL& original_file_url,
// If we can not get valid file path from original URL, treat it as
// disk error.
if (file_path.empty())
- SaveFinished(save_id, original_file_url, render_process_id, false);
+ SaveFinished(save_item_id, save_package_id, false);
// Copy the local file to the temporary file. It will be renamed to its
// final name later.
bool success = base::CopyFile(file_path, save_file->FullPath());
if (!success)
base::DeleteFile(save_file->FullPath(), false);
- SaveFinished(save_id, original_file_url, render_process_id, success);
+ SaveFinished(save_item_id, save_package_id, success);
}
void SaveFileManager::OnDeleteDirectoryOrFile(const base::FilePath& full_path,
@@ -474,24 +359,25 @@ void SaveFileManager::OnDeleteDirectoryOrFile(const base::FilePath& full_path,
base::DeleteFile(full_path, is_dir);
}
-void SaveFileManager::RenameAllFiles(
- const FinalNameList& final_names,
- const base::FilePath& resource_dir,
- int render_process_id,
- int render_frame_id,
- int save_package_id) {
+void SaveFileManager::RenameAllFiles(const FinalNamesMap& final_names,
+ const base::FilePath& resource_dir,
+ int render_process_id,
+ int render_frame_routing_id,
+ SavePackageId save_package_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
if (!resource_dir.empty() && !base::PathExists(resource_dir))
base::CreateDirectory(resource_dir);
- for (FinalNameList::const_iterator i = final_names.begin();
- i != final_names.end(); ++i) {
- SaveFileMap::iterator it = save_file_map_.find(i->first);
+ for (const auto& i : final_names) {
+ SaveItemId save_item_id = i.first;
+ const base::FilePath& final_name = i.second;
+
+ SaveFileMap::iterator it = save_file_map_.find(save_item_id);
if (it != save_file_map_.end()) {
SaveFile* save_file = it->second;
DCHECK(!save_file->InProgress());
- save_file->Rename(i->second);
+ save_file->Rename(final_name);
delete save_file;
save_file_map_.erase(it);
}
@@ -499,29 +385,28 @@ void SaveFileManager::RenameAllFiles(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&SaveFileManager::OnFinishSavePageJob, this,
- render_process_id, render_frame_id, save_package_id));
+ base::Bind(&SaveFileManager::OnFinishSavePageJob, this, render_process_id,
+ render_frame_routing_id, save_package_id));
}
void SaveFileManager::OnFinishSavePageJob(int render_process_id,
- int render_frame_id,
- int save_package_id) {
+ int render_frame_routing_id,
+ SavePackageId save_package_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
SavePackage* save_package =
- GetSavePackageFromRenderIds(render_process_id, render_frame_id);
+ GetSavePackageFromRenderIds(render_process_id, render_frame_routing_id);
if (save_package && save_package->id() == save_package_id)
save_package->Finish();
}
void SaveFileManager::RemoveSavedFileFromFileMap(
- const SaveIDList& save_ids) {
+ const std::vector<SaveItemId>& save_item_ids) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- for (SaveIDList::const_iterator i = save_ids.begin();
- i != save_ids.end(); ++i) {
- SaveFileMap::iterator it = save_file_map_.find(*i);
+ for (const SaveItemId save_item_id : save_item_ids) {
+ SaveFileMap::iterator it = save_file_map_.find(save_item_id);
if (it != save_file_map_.end()) {
SaveFile* save_file = it->second;
DCHECK(!save_file->InProgress());
diff --git a/chromium/content/browser/download/save_file_manager.h b/chromium/content/browser/download/save_file_manager.h
index 4302846be21..3f36206f43c 100644
--- a/chromium/content/browser/download/save_file_manager.h
+++ b/chromium/content/browser/download/save_file_manager.h
@@ -49,19 +49,20 @@
// data)
//
//
-// The SaveFileManager tracks saving requests, mapping from a save ID (unique
-// integer created in the IO thread) to the SavePackage for the contents where
-// the saving job was initiated. In the event of a contents closure during
-// saving, the SavePackage will notify the SaveFileManage to cancel all SaveFile
-// jobs.
+// The SaveFileManager tracks saving requests, mapping from a save item id to
+// the SavePackage for the contents where the saving job was initiated. In the
+// event of a contents closure during saving, the SavePackage will notify the
+// SaveFileManage to cancel all SaveFile jobs.
#ifndef CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H_
#define CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/download/save_types.h"
#include "content/common/content_export.h"
@@ -89,18 +90,14 @@ class SaveFileManager : public base::RefCountedThreadSafe<SaveFileManager> {
// Lifetime management.
CONTENT_EXPORT void Shutdown();
- // Called on the IO thread. This generates unique IDs for
- // SaveFileResourceHandler objects (there's one per file in a SavePackage).
- // Note that this is different from the SavePackage's id.
- int GetNextId();
-
// Save the specified URL. Called on the UI thread and forwarded to the
// ResourceDispatcherHostImpl on the IO thread.
- void SaveURL(const GURL& url,
+ void SaveURL(SaveItemId save_item_id,
+ const GURL& url,
const Referrer& referrer,
int render_process_host_id,
- int render_view_id,
- int render_frame_id,
+ int render_view_routing_id,
+ int render_frame_routing_id,
SaveFileCreateInfo::SaveFileSource save_source,
const base::FilePath& file_full_path,
ResourceContext* context,
@@ -108,20 +105,20 @@ class SaveFileManager : public base::RefCountedThreadSafe<SaveFileManager> {
// Notifications sent from the IO thread and run on the file thread:
void StartSave(SaveFileCreateInfo* info);
- void UpdateSaveProgress(int save_id, net::IOBuffer* data, int size);
- void SaveFinished(int save_id,
- const GURL& save_url,
- int render_process_id,
+ void UpdateSaveProgress(SaveItemId save_item_id,
+ net::IOBuffer* data,
+ int size);
+ void SaveFinished(SaveItemId save_item_id,
+ SavePackageId save_package_id,
bool is_success);
// Notifications sent from the UI thread and run on the file thread.
- // Cancel a SaveFile instance which has specified save id.
- void CancelSave(int save_id);
+ // Cancel a SaveFile instance which has specified save item id.
+ void CancelSave(SaveItemId save_item_id);
// Called on the UI thread to remove a save package from SaveFileManager's
// tracking map.
- void RemoveSaveFile(int save_id, const GURL& save_url,
- SavePackage* package);
+ void RemoveSaveFile(SaveItemId save_item_id, SavePackage* package);
// Helper function for deleting specified file.
void DeleteDirectoryOrFile(const base::FilePath& full_path, bool is_dir);
@@ -129,22 +126,19 @@ class SaveFileManager : public base::RefCountedThreadSafe<SaveFileManager> {
// Runs on file thread to save a file by copying from file system when
// original url is using file scheme.
void SaveLocalFile(const GURL& original_file_url,
- int save_id,
- int render_process_id);
+ SaveItemId save_item_id,
+ SavePackageId save_package_id);
// Renames all the successfully saved files.
- // |final_names| points to a vector which contains pairs of save ids and
- // final names of successfully saved files.
- void RenameAllFiles(
- const FinalNameList& final_names,
- const base::FilePath& resource_dir,
- int render_process_id,
- int render_frame_id,
- int save_package_id);
+ void RenameAllFiles(const FinalNamesMap& final_names,
+ const base::FilePath& resource_dir,
+ int render_process_id,
+ int render_frame_routing_id,
+ SavePackageId save_package_id);
// When the user cancels the saving, we need to remove all remaining saved
// files of this page saving job from save_file_map_.
- void RemoveSavedFileFromFileMap(const SaveIDList & save_ids);
+ void RemoveSavedFileFromFileMap(const std::vector<SaveItemId>& save_item_ids);
private:
friend class base::RefCountedThreadSafe<SaveFileManager>;
@@ -157,47 +151,37 @@ class SaveFileManager : public base::RefCountedThreadSafe<SaveFileManager> {
// Called only on UI thread to get the SavePackage for a contents's browser
// context.
static SavePackage* GetSavePackageFromRenderIds(int render_process_id,
- int render_Frame_id);
-
- // Register a starting request. Associate the save URL with a
- // SavePackage for further matching.
- void RegisterStartingRequest(const GURL& save_url,
- SavePackage* save_package);
- // Unregister a start request according save URL, disassociate
- // the save URL and SavePackage.
- SavePackage* UnregisterStartingRequest(const GURL& save_url,
- int contents_id);
+ int render_frame_routing_id);
- // Look up the SavePackage according to save id.
- SavePackage* LookupPackage(int save_id);
+ // Look up the SavePackage according to save item id.
+ SavePackage* LookupPackage(SaveItemId save_item_id);
// Called only on the file thread.
- // Look up one in-progress saving item according to save id.
- SaveFile* LookupSaveFile(int save_id);
+ // Look up one in-progress saving item according to save item id.
+ SaveFile* LookupSaveFile(SaveItemId save_item_id);
// Help function for sending notification of canceling specific request.
- void SendCancelRequest(int save_id);
+ void SendCancelRequest(SaveItemId save_item_id);
// Notifications sent from the file thread and run on the UI thread.
// Lookup the SaveManager for this WebContents' saving browser context and
// inform it the saving job has been started.
- void OnStartSave(const SaveFileCreateInfo* info);
+ void OnStartSave(const SaveFileCreateInfo& info);
// Update the SavePackage with the current state of a started saving job.
// If the SavePackage for this saving job is gone, cancel the request.
- void OnUpdateSaveProgress(int save_id,
- int64 bytes_so_far,
+ void OnUpdateSaveProgress(SaveItemId save_item_id,
+ int64_t bytes_so_far,
bool write_success);
// Update the SavePackage with the finish state, and remove the request
// tracking entries.
- void OnSaveFinished(int save_id, int64 bytes_so_far, bool is_success);
- // For those requests that do not have valid save id, use
- // map:(url, SavePackage) to find the request and remove it.
- void OnErrorFinished(const GURL& save_url, int contents_id);
+ void OnSaveFinished(SaveItemId save_item_id,
+ int64_t bytes_so_far,
+ bool is_success);
// Notifies SavePackage that the whole page saving job is finished.
void OnFinishSavePageJob(int render_process_id,
- int render_frame_id,
- int save_package_id);
+ int render_frame_routing_id,
+ SavePackageId save_package_id);
// Notifications sent from the UI thread and run on the file thread.
@@ -209,43 +193,25 @@ class SaveFileManager : public base::RefCountedThreadSafe<SaveFileManager> {
// Initiates a request for URL to be saved.
void OnSaveURL(const GURL& url,
const Referrer& referrer,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
int render_process_host_id,
- int render_view_id,
- int render_frame_id,
+ int render_view_routing_id,
+ int render_frame_routing_id,
ResourceContext* context);
- // Handler for a notification sent to the IO thread for generating save id.
- void OnRequireSaveJobFromOtherSource(SaveFileCreateInfo* info);
// Call ResourceDispatcherHostImpl's CancelRequest method to execute cancel
// action in the IO thread.
void ExecuteCancelSaveRequest(int render_process_id, int request_id);
- // Unique ID for the next SaveFile object.
- int next_id_;
-
- // A map of all saving jobs by using save id.
- typedef base::hash_map<int, SaveFile*> SaveFileMap;
+ // A map from save_item_id into SaveFiles.
+ typedef base::hash_map<SaveItemId, SaveFile*> SaveFileMap;
SaveFileMap save_file_map_;
// Tracks which SavePackage to send data to, called only on UI thread.
- // SavePackageMap maps save IDs to their SavePackage.
- typedef base::hash_map<int, SavePackage*> SavePackageMap;
+ // SavePackageMap maps save item ids to their SavePackage.
+ typedef base::hash_map<SaveItemId, SavePackage*> SavePackageMap;
SavePackageMap packages_;
- // There is a gap between after calling SaveURL() and before calling
- // StartSave(). In this gap, each request does not have save id for tracking.
- // But sometimes users might want to stop saving job or ResourceDispatcherHost
- // calls SaveFinished with save id -1 for network error. We name the requests
- // as starting requests. For tracking those starting requests, we need to
- // have some data structure.
- // First we use a hashmap to map the request URL to SavePackage, then we use a
- // hashmap to map the contents id (we actually use render_process_id) to the
- // hashmap since it is possible to save the same URL in different contents at
- // same time.
- typedef base::hash_map<std::string, SavePackage*> StartingRequestsMap;
- typedef base::hash_map<int, StartingRequestsMap>
- ContentsToStartingRequestsMap;
- ContentsToStartingRequestsMap contents_starting_requests_;
-
DISALLOW_COPY_AND_ASSIGN(SaveFileManager);
};
diff --git a/chromium/content/browser/download/save_file_resource_handler.cc b/chromium/content/browser/download/save_file_resource_handler.cc
index de1e81fba4d..faf5605710a 100644
--- a/chromium/content/browser/download/save_file_resource_handler.cc
+++ b/chromium/content/browser/download/save_file_resource_handler.cc
@@ -17,18 +17,20 @@
namespace content {
SaveFileResourceHandler::SaveFileResourceHandler(net::URLRequest* request,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
int render_process_host_id,
- int render_frame_id,
+ int render_frame_routing_id,
const GURL& url,
SaveFileManager* manager)
: ResourceHandler(request),
- save_id_(-1),
+ save_item_id_(save_item_id),
+ save_package_id_(save_package_id),
render_process_id_(render_process_host_id),
- render_frame_id_(render_frame_id),
+ render_frame_routing_id_(render_frame_routing_id),
url_(url),
content_length_(0),
- save_manager_(manager) {
-}
+ save_manager_(manager) {}
SaveFileResourceHandler::~SaveFileResourceHandler() {
}
@@ -43,18 +45,11 @@ bool SaveFileResourceHandler::OnRequestRedirected(
bool SaveFileResourceHandler::OnResponseStarted(ResourceResponse* response,
bool* defer) {
- save_id_ = save_manager_->GetNextId();
// |save_manager_| consumes (deletes):
- SaveFileCreateInfo* info = new SaveFileCreateInfo;
- info->url = url_;
- info->final_url = final_url_;
- info->total_bytes = content_length_;
- info->save_id = save_id_;
- info->render_process_id = render_process_id_;
- info->render_frame_id = render_frame_id_;
- info->request_id = GetRequestID();
- info->content_disposition = content_disposition_;
- info->save_source = SaveFileCreateInfo::SAVE_FILE_FROM_NET;
+ SaveFileCreateInfo* info = new SaveFileCreateInfo(
+ url_, final_url_, save_item_id_, save_package_id_, render_process_id_,
+ render_frame_routing_id_, GetRequestID(), content_disposition_,
+ content_length_);
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&SaveFileManager::StartSave, save_manager_, info));
@@ -89,8 +84,8 @@ bool SaveFileResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
read_buffer_.swap(buffer);
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::UpdateSaveProgress,
- save_manager_, save_id_, buffer, bytes_read));
+ base::Bind(&SaveFileManager::UpdateSaveProgress, save_manager_,
+ save_item_id_, buffer, bytes_read));
return true;
}
@@ -100,8 +95,9 @@ void SaveFileResourceHandler::OnResponseCompleted(
bool* defer) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::SaveFinished, save_manager_, save_id_, url_,
- render_process_id_, status.is_success() && !status.is_io_pending()));
+ base::Bind(&SaveFileManager::SaveFinished, save_manager_, save_item_id_,
+ save_package_id_,
+ status.is_success() && !status.is_io_pending()));
read_buffer_ = NULL;
}
diff --git a/chromium/content/browser/download/save_file_resource_handler.h b/chromium/content/browser/download/save_file_resource_handler.h
index 42851346c31..e559e44a63e 100644
--- a/chromium/content/browser/download/save_file_resource_handler.h
+++ b/chromium/content/browser/download/save_file_resource_handler.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_DOWNLOAD_SAVE_FILE_RESOURCE_HANDLER_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "content/browser/download/save_types.h"
#include "content/browser/loader/resource_handler.h"
#include "url/gurl.h"
@@ -22,8 +26,10 @@ class SaveFileManager;
class SaveFileResourceHandler : public ResourceHandler {
public:
SaveFileResourceHandler(net::URLRequest* request,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
int render_process_host_id,
- int render_frame_id,
+ int render_frame_routing_id,
const GURL& url,
SaveFileManager* manager);
~SaveFileResourceHandler() override;
@@ -71,14 +77,15 @@ class SaveFileResourceHandler : public ResourceHandler {
}
private:
- int save_id_;
+ SaveItemId save_item_id_;
+ SavePackageId save_package_id_;
int render_process_id_;
- int render_frame_id_;
+ int render_frame_routing_id_;
scoped_refptr<net::IOBuffer> read_buffer_;
std::string content_disposition_;
GURL url_;
GURL final_url_;
- int64 content_length_;
+ int64_t content_length_;
SaveFileManager* save_manager_;
static const int kReadBufSize = 32768; // bytes
diff --git a/chromium/content/browser/download/save_item.cc b/chromium/content/browser/download/save_item.cc
index 9e516204202..edea2632804 100644
--- a/chromium/content/browser/download/save_item.cc
+++ b/chromium/content/browser/download/save_item.cc
@@ -9,24 +9,35 @@
#include "content/browser/download/save_file.h"
#include "content/browser/download/save_file_manager.h"
#include "content/browser/download/save_package.h"
+#include "content/public/browser/browser_thread.h"
namespace content {
+namespace {
+
+SaveItemId GetNextSaveItemId() {
+ static int g_next_save_item_id = 1;
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return SaveItemId::FromUnsafeValue(g_next_save_item_id++);
+}
+
+} // namespace
+
// Constructor for SaveItem when creating each saving job.
SaveItem::SaveItem(const GURL& url,
const Referrer& referrer,
SavePackage* package,
SaveFileCreateInfo::SaveFileSource save_source)
- : save_id_(-1),
- url_(url),
- referrer_(referrer),
- total_bytes_(0),
- received_bytes_(0),
- state_(WAIT_START),
- has_final_name_(false),
- is_success_(false),
- save_source_(save_source),
- package_(package) {
+ : save_item_id_(GetNextSaveItemId()),
+ url_(url),
+ referrer_(referrer),
+ total_bytes_(0),
+ received_bytes_(0),
+ state_(WAIT_START),
+ has_final_name_(false),
+ is_success_(false),
+ save_source_(save_source),
+ package_(package) {
DCHECK(package);
}
@@ -41,7 +52,7 @@ void SaveItem::Start() {
// If we've received more data than we were expecting (bad server info?),
// revert to 'unknown size mode'.
-void SaveItem::UpdateSize(int64 bytes_so_far) {
+void SaveItem::UpdateSize(int64_t bytes_so_far) {
received_bytes_ = bytes_so_far;
if (received_bytes_ >= total_bytes_)
total_bytes_ = 0;
@@ -50,7 +61,7 @@ void SaveItem::UpdateSize(int64 bytes_so_far) {
// Updates from the file thread may have been posted while this saving job
// was being canceled in the UI thread, so we'll accept them unless we're
// complete.
-void SaveItem::Update(int64 bytes_so_far) {
+void SaveItem::Update(int64_t bytes_so_far) {
if (state_ != IN_PROGRESS) {
NOTREACHED();
return;
@@ -75,17 +86,8 @@ void SaveItem::Cancel() {
}
// Set finish state for a save item
-void SaveItem::Finish(int64 size, bool is_success) {
- // When this function is called, the SaveItem should be one of following
- // three situations.
- // a) The data of this SaveItem is finished saving. So it should have
- // generated final name.
- // b) Error happened before the start of saving process. So no |save_id_| is
- // generated for this SaveItem and the |is_success_| should be false.
- // c) Error happened in the start of saving process, the SaveItem has a save
- // id, |is_success_| should be false, and the |size| should be 0.
- DCHECK(has_final_name() || (save_id_ == -1 && !is_success_) ||
- (save_id_ != -1 && !is_success_ && !size));
+void SaveItem::Finish(int64_t size, bool is_success) {
+ DCHECK(has_final_name() || !is_success_);
state_ = COMPLETE;
is_success_ = is_success;
UpdateSize(size);
@@ -120,12 +122,7 @@ void SaveItem::Rename(const base::FilePath& full_path) {
has_final_name_ = true;
}
-void SaveItem::SetSaveId(int32 save_id) {
- DCHECK_EQ(-1, save_id_);
- save_id_ = save_id;
-}
-
-void SaveItem::SetTotalBytes(int64 total_bytes) {
+void SaveItem::SetTotalBytes(int64_t total_bytes) {
DCHECK_EQ(0, total_bytes_);
total_bytes_ = total_bytes;
}
diff --git a/chromium/content/browser/download/save_item.h b/chromium/content/browser/download/save_item.h
index d7cbb4f0329..b0e655da71e 100644
--- a/chromium/content/browser/download/save_item.h
+++ b/chromium/content/browser/download/save_item.h
@@ -5,8 +5,10 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_SAVE_ITEM_H_
#define CONTENT_BROWSER_DOWNLOAD_SAVE_ITEM_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "content/browser/download/save_types.h"
#include "content/public/common/referrer.h"
#include "url/gurl.h"
@@ -35,13 +37,13 @@ class SaveItem {
void Start();
// Received a new chunk of data.
- void Update(int64 bytes_so_far);
+ void Update(int64_t bytes_so_far);
// Cancel saving item.
void Cancel();
// Saving operation completed.
- void Finish(int64 size, bool is_success);
+ void Finish(int64_t size, bool is_success);
// Rough percent complete, -1 means we don't know (since we didn't receive a
// total size).
@@ -50,19 +52,17 @@ class SaveItem {
// Update path for SaveItem, the actual file is renamed on the file thread.
void Rename(const base::FilePath& full_path);
- void SetSaveId(int32 save_id);
-
- void SetTotalBytes(int64 total_bytes);
+ void SetTotalBytes(int64_t total_bytes);
// Accessors.
+ SaveItemId id() const { return save_item_id_; }
SaveState state() const { return state_; }
const base::FilePath& full_path() const { return full_path_; }
const base::FilePath& file_name() const { return file_name_; }
const GURL& url() const { return url_; }
const Referrer& referrer() const { return referrer_; }
- int64 total_bytes() const { return total_bytes_; }
- int64 received_bytes() const { return received_bytes_; }
- int32 save_id() const { return save_id_; }
+ int64_t total_bytes() const { return total_bytes_; }
+ int64_t received_bytes() const { return received_bytes_; }
bool has_final_name() const { return has_final_name_; }
bool success() const { return is_success_; }
SaveFileCreateInfo::SaveFileSource save_source() const {
@@ -72,10 +72,10 @@ class SaveItem {
private:
// Internal helper for maintaining consistent received and total sizes.
- void UpdateSize(int64 size);
+ void UpdateSize(int64_t size);
- // Request ID assigned by the ResourceDispatcherHost.
- int32 save_id_;
+ // Unique identifier for this SaveItem instance.
+ const SaveItemId save_item_id_;
// Full path to the save item file.
base::FilePath full_path_;
@@ -88,10 +88,10 @@ class SaveItem {
Referrer referrer_;
// Total bytes expected.
- int64 total_bytes_;
+ int64_t total_bytes_;
// Current received bytes.
- int64 received_bytes_;
+ int64_t received_bytes_;
// The current state of this save item.
SaveState state_;
diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc
index 96871950bac..5b7d6a6ead1 100644
--- a/chromium/content/browser/download/save_package.cc
+++ b/chromium/content/browser/download/save_package.cc
@@ -5,12 +5,14 @@
#include "content/browser/download/save_package.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
@@ -18,13 +20,18 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
+#include "build/build_config.h"
#include "components/url_formatter/url_formatter.h"
+#include "content/browser/bad_message.h"
#include "content/browser/download/download_item_impl.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_stats.h"
#include "content/browser/download/save_file.h"
#include "content/browser/download/save_file_manager.h"
#include "content/browser/download/save_item.h"
+#include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/render_frame_host_impl.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_delegate.h"
@@ -45,17 +52,18 @@
#include "net/base/io_buffer.h"
#include "net/base/mime_util.h"
#include "net/url_request/url_request_context.h"
-#include "third_party/WebKit/public/web/WebPageSerializerClient.h"
#include "url/url_constants.h"
using base::Time;
-using blink::WebPageSerializerClient;
namespace content {
namespace {
-// A counter for uniquely identifying each save package.
-int g_save_package_id = 0;
+// Generates unique ids for SavePackage::unique_id_ field.
+SavePackageId GetNextSavePackageId() {
+ static int g_save_package_id = 0;
+ return SavePackageId::FromUnsafeValue(g_save_package_id++);
+}
// Default name which will be used when we can not get proper name from
// resource URL.
@@ -63,21 +71,21 @@ const char kDefaultSaveName[] = "saved_resource";
// Maximum number of file ordinal number. I think it's big enough for resolving
// name-conflict files which has same base file name.
-const int32 kMaxFileOrdinalNumber = 9999;
+const int32_t kMaxFileOrdinalNumber = 9999;
// Maximum length for file path. Since Windows have MAX_PATH limitation for
// file path, we need to make sure length of file path of every saved file
// is less than MAX_PATH
#if defined(OS_WIN)
-const uint32 kMaxFilePathLength = MAX_PATH - 1;
+const uint32_t kMaxFilePathLength = MAX_PATH - 1;
#elif defined(OS_POSIX)
-const uint32 kMaxFilePathLength = PATH_MAX - 1;
+const uint32_t kMaxFilePathLength = PATH_MAX - 1;
#endif
// Maximum length for file ordinal number part. Since we only support the
// maximum 9999 for ordinal number, which means maximum file ordinal number part
// should be "(9998)", so the value is 6.
-const uint32 kMaxFileOrdinalNumberPartLength = 6;
+const uint32_t kMaxFileOrdinalNumberPartLength = 6;
// Strip current ordinal number, if any. Should only be used on pure
// file names, i.e. those stripped of their extensions.
@@ -158,14 +166,14 @@ SavePackage::SavePackage(WebContents* web_contents,
all_save_items_count_(0),
file_name_set_(&base::FilePath::CompareLessIgnoreCase),
wait_state_(INITIALIZE),
- contents_id_(web_contents->GetRenderProcessHost()->GetID()),
- unique_id_(g_save_package_id++),
+ unique_id_(GetNextSavePackageId()),
wrote_to_completed_file_(false),
wrote_to_failed_file_(false) {
DCHECK(page_url_.is_valid());
DCHECK((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
(save_type_ == SAVE_PAGE_TYPE_AS_MHTML) ||
- (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
+ (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML))
+ << save_type_;
DCHECK(!saved_main_file_path_.empty() &&
saved_main_file_path_.value().length() <= kMaxFilePathLength);
DCHECK(!saved_main_directory_path_.empty() &&
@@ -190,8 +198,7 @@ SavePackage::SavePackage(WebContents* web_contents)
all_save_items_count_(0),
file_name_set_(&base::FilePath::CompareLessIgnoreCase),
wait_state_(INITIALIZE),
- contents_id_(web_contents->GetRenderProcessHost()->GetID()),
- unique_id_(g_save_package_id++),
+ unique_id_(GetNextSavePackageId()),
wrote_to_completed_file_(false),
wrote_to_failed_file_(false) {
DCHECK(page_url_.is_valid());
@@ -220,8 +227,7 @@ SavePackage::SavePackage(WebContents* web_contents,
all_save_items_count_(0),
file_name_set_(&base::FilePath::CompareLessIgnoreCase),
wait_state_(INITIALIZE),
- contents_id_(0),
- unique_id_(g_save_package_id++),
+ unique_id_(GetNextSavePackageId()),
wrote_to_completed_file_(false),
wrote_to_failed_file_(false) {}
@@ -235,20 +241,20 @@ SavePackage::~SavePackage() {
// We should no longer be observing the DownloadItem at this point.
CHECK(!download_);
- DCHECK(all_save_items_count_ == (waiting_item_queue_.size() +
- completed_count() +
- in_process_count()));
- // Free all SaveItems.
- while (!waiting_item_queue_.empty()) {
- // We still have some items which are waiting for start to save.
- SaveItem* save_item = waiting_item_queue_.front();
- waiting_item_queue_.pop();
- delete save_item;
- }
+ DCHECK_EQ(all_save_items_count_, waiting_item_queue_.size() +
+ completed_count() + in_process_count());
- STLDeleteValues(&saved_success_items_);
+ // Free all SaveItems.
+ STLDeleteElements(&waiting_item_queue_);
STLDeleteValues(&in_progress_items_);
+ STLDeleteValues(&saved_success_items_);
STLDeleteValues(&saved_failed_items_);
+ // Clear containers that contain (now dangling/invalid) pointers to the
+ // save items freed above. This is not strictly required (as the containers
+ // will be destructed soon by ~SavePackage), but seems like good code hygiene.
+ frame_tree_node_id_to_contained_save_items_.clear();
+ frame_tree_node_id_to_save_item_.clear();
+ url_to_save_item_.clear();
file_manager_ = NULL;
}
@@ -314,11 +320,10 @@ bool SavePackage::Init(
new SavePackageRequestHandle(AsWeakPtr()));
// The download manager keeps ownership but adds us as an observer.
download_manager_->CreateSavePackageDownloadItem(
- saved_main_file_path_,
- page_url_,
- ((save_type_ == SAVE_PAGE_TYPE_AS_MHTML) ?
- "multipart/related" : "text/html"),
- request_handle.Pass(),
+ saved_main_file_path_, page_url_,
+ ((save_type_ == SAVE_PAGE_TYPE_AS_MHTML) ? "multipart/related"
+ : "text/html"),
+ std::move(request_handle),
base::Bind(&SavePackage::InitWithDownloadItem, AsWeakPtr(),
download_created_callback));
return true;
@@ -344,7 +349,7 @@ void SavePackage::InitWithDownloadItem(
web_contents()->GenerateMHTML(saved_main_file_path_, base::Bind(
&SavePackage::OnMHTMLGenerated, this));
} else {
- DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_) << save_type_;
+ DCHECK_EQ(SAVE_PAGE_TYPE_AS_ONLY_HTML, save_type_);
wait_state_ = NET_FILES;
SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ?
SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
@@ -354,7 +359,7 @@ void SavePackage::InitWithDownloadItem(
this,
save_source);
// Add this item to waiting list.
- waiting_item_queue_.push(save_item);
+ waiting_item_queue_.push_back(save_item);
all_save_items_count_ = 1;
download_->SetTotalBytes(1);
@@ -362,7 +367,7 @@ void SavePackage::InitWithDownloadItem(
}
}
-void SavePackage::OnMHTMLGenerated(int64 size) {
+void SavePackage::OnMHTMLGenerated(int64_t size) {
if (size <= 0) {
Cancel(false);
return;
@@ -395,12 +400,12 @@ void SavePackage::OnMHTMLGenerated(int64 size) {
// On POSIX, the length of |pure_file_name| + |file_name_ext| is further
// restricted by NAME_MAX. The maximum allowed path looks like:
// '/path/to/save_dir' + '/' + NAME_MAX.
-uint32 SavePackage::GetMaxPathLengthForDirectory(
+uint32_t SavePackage::GetMaxPathLengthForDirectory(
const base::FilePath& base_dir) {
#if defined(OS_POSIX)
- return std::min(kMaxFilePathLength,
- static_cast<uint32>(base_dir.value().length()) +
- NAME_MAX + 1);
+ return std::min(
+ kMaxFilePathLength,
+ static_cast<uint32_t>(base_dir.value().length()) + NAME_MAX + 1);
#else
return kMaxFilePathLength;
#endif
@@ -426,7 +431,7 @@ uint32 SavePackage::GetMaxPathLengthForDirectory(
bool SavePackage::GetSafePureFileName(
const base::FilePath& dir_path,
const base::FilePath::StringType& file_name_ext,
- uint32 max_file_path_len,
+ uint32_t max_file_path_len,
base::FilePath::StringType* pure_file_name) {
DCHECK(!pure_file_name->empty());
int available_length = static_cast<int>(max_file_path_len -
@@ -477,7 +482,7 @@ bool SavePackage::GenerateFileName(const std::string& disposition,
}
// Need to make sure the suggested file name is not too long.
- uint32 max_path = GetMaxPathLengthForDirectory(saved_main_directory_path_);
+ uint32_t max_path = GetMaxPathLengthForDirectory(saved_main_directory_path_);
// Get safe pure file name.
if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext,
@@ -504,7 +509,7 @@ bool SavePackage::GenerateFileName(const std::string& disposition,
return false;
// Prepare the new ordinal number.
- uint32 ordinal_number;
+ uint32_t ordinal_number;
FileNameCountMap::iterator it = file_name_count_map_.find(base_file_name);
if (it == file_name_count_map_.end()) {
// First base-name-conflict resolving, use 1 as initial ordinal number.
@@ -548,11 +553,11 @@ bool SavePackage::GenerateFileName(const std::string& disposition,
}
// We have received a message from SaveFileManager about a new saving job. We
-// create a SaveItem and store it in our in_progress list.
+// find a SaveItem and store it in our in_progress list.
void SavePackage::StartSave(const SaveFileCreateInfo* info) {
DCHECK(info && !info->url.is_empty());
- SaveUrlItemMap::iterator it = in_progress_items_.find(info->url.spec());
+ SaveItemIdMap::iterator it = in_progress_items_.find(info->save_item_id);
if (it == in_progress_items_.end()) {
// If not found, we must have cancel action.
DCHECK(canceled());
@@ -562,7 +567,6 @@ void SavePackage::StartSave(const SaveFileCreateInfo* info) {
DCHECK(!saved_main_file_path_.empty());
- save_item->SetSaveId(info->save_id);
save_item->SetTotalBytes(info->total_bytes);
// Determine the proper path for a saving job, by choosing either the default
@@ -589,13 +593,13 @@ void SavePackage::StartSave(const SaveFileCreateInfo* info) {
if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_DOM)
Cancel(true);
else
- SaveFinished(save_item->save_id(), 0, false);
+ SaveFinished(save_item->id(), 0, false);
return;
}
// When saving page as only-HTML, we only have a SaveItem whose url
// must be page_url_.
- DCHECK(save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML);
+ DCHECK_EQ(SAVE_PAGE_TYPE_AS_COMPLETE_HTML, save_type_);
DCHECK(!saved_main_directory_path_.empty());
// Now we get final name retrieved from GenerateFileName, we will use it
@@ -613,11 +617,8 @@ void SavePackage::StartSave(const SaveFileCreateInfo* info) {
if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_FILE) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::SaveLocalFile,
- file_manager_,
- save_item->url(),
- save_item->save_id(),
- contents_id()));
+ base::Bind(&SaveFileManager::SaveLocalFile, file_manager_,
+ save_item->url(), save_item->id(), id()));
return;
}
@@ -630,46 +631,42 @@ void SavePackage::StartSave(const SaveFileCreateInfo* info) {
}
}
-SaveItem* SavePackage::LookupItemInProcessBySaveId(int32 save_id) {
- if (in_process_count()) {
- for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
- it != in_progress_items_.end(); ++it) {
- SaveItem* save_item = it->second;
- DCHECK(save_item->state() == SaveItem::IN_PROGRESS);
- if (save_item->save_id() == save_id)
- return save_item;
- }
+SaveItem* SavePackage::LookupSaveItemInProcess(SaveItemId save_item_id) {
+ auto it = in_progress_items_.find(save_item_id);
+ if (it != in_progress_items_.end()) {
+ SaveItem* save_item = it->second;
+ DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state());
+ return save_item;
}
- return NULL;
+ return nullptr;
}
void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) {
- SaveUrlItemMap::iterator it = in_progress_items_.find(
- save_item->url().spec());
+ SaveItemIdMap::iterator it = in_progress_items_.find(save_item->id());
DCHECK(it != in_progress_items_.end());
DCHECK(save_item == it->second);
in_progress_items_.erase(it);
if (save_item->success()) {
// Add it to saved_success_items_.
- DCHECK(saved_success_items_.find(save_item->save_id()) ==
+ DCHECK(saved_success_items_.find(save_item->id()) ==
saved_success_items_.end());
- saved_success_items_[save_item->save_id()] = save_item;
+ saved_success_items_[save_item->id()] = save_item;
} else {
// Add it to saved_failed_items_.
- DCHECK(saved_failed_items_.find(save_item->url().spec()) ==
+ DCHECK(saved_failed_items_.find(save_item->id()) ==
saved_failed_items_.end());
- saved_failed_items_[save_item->url().spec()] = save_item;
+ saved_failed_items_[save_item->id()] = save_item;
}
}
// Called for updating saving state.
-bool SavePackage::UpdateSaveProgress(int32 save_id,
- int64 size,
+bool SavePackage::UpdateSaveProgress(SaveItemId save_item_id,
+ int64_t size,
bool write_success) {
// Because we might have canceled this saving job before,
// so we might not find corresponding SaveItem.
- SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
+ SaveItem* save_item = LookupSaveItemInProcess(save_item_id);
if (!save_item)
return false;
@@ -694,10 +691,9 @@ void SavePackage::Stop() {
// When stopping, if it still has some items in in_progress, cancel them.
DCHECK(canceled());
if (in_process_count()) {
- SaveUrlItemMap::iterator it = in_progress_items_.begin();
- for (; it != in_progress_items_.end(); ++it) {
- SaveItem* save_item = it->second;
- DCHECK(save_item->state() == SaveItem::IN_PROGRESS);
+ for (const auto& it : in_progress_items_) {
+ SaveItem* save_item = it.second;
+ DCHECK_EQ(SaveItem::IN_PROGRESS, save_item->state());
save_item->Cancel();
}
// Remove all in progress item to saved map. For failed items, they will
@@ -709,19 +705,16 @@ void SavePackage::Stop() {
// This vector contains the save ids of the save files which SaveFileManager
// needs to remove from its save_file_map_.
- SaveIDList save_ids;
- for (SavedItemMap::iterator it = saved_success_items_.begin();
- it != saved_success_items_.end(); ++it)
- save_ids.push_back(it->first);
- for (SaveUrlItemMap::iterator it = saved_failed_items_.begin();
- it != saved_failed_items_.end(); ++it)
- save_ids.push_back(it->second->save_id());
+ std::vector<SaveItemId> save_item_ids;
+ for (const auto& it : saved_success_items_)
+ save_item_ids.push_back(it.first);
+ for (const auto& it : saved_failed_items_)
+ save_item_ids.push_back(it.first);
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap,
- file_manager_,
- save_ids));
+ base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, file_manager_,
+ save_item_ids));
finished_ = true;
wait_state_ = FAILED;
@@ -741,14 +734,9 @@ void SavePackage::CheckFinish() {
saved_success_items_.size() > 1) ?
saved_main_directory_path_ : base::FilePath();
- // This vector contains the final names of all the successfully saved files
- // along with their save ids. It will be passed to SaveFileManager to do the
- // renaming job.
- FinalNameList final_names;
- for (SavedItemMap::iterator it = saved_success_items_.begin();
- it != saved_success_items_.end(); ++it)
- final_names.push_back(std::make_pair(it->first,
- it->second->full_path()));
+ FinalNamesMap final_names;
+ for (const auto& it : saved_success_items_)
+ final_names.insert(std::make_pair(it.first, it.second->full_path()));
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
@@ -774,26 +762,25 @@ void SavePackage::Finish() {
RecordSavePackageEvent(SAVE_PACKAGE_FINISHED);
// Record any errors that occurred.
- if (wrote_to_completed_file_) {
+ if (wrote_to_completed_file_)
RecordSavePackageEvent(SAVE_PACKAGE_WRITE_TO_COMPLETED);
- }
- if (wrote_to_failed_file_) {
+ if (wrote_to_failed_file_)
RecordSavePackageEvent(SAVE_PACKAGE_WRITE_TO_FAILED);
- }
// This vector contains the save ids of the save files which SaveFileManager
// needs to remove from its save_file_map_.
- SaveIDList save_ids;
- for (SaveUrlItemMap::iterator it = saved_failed_items_.begin();
- it != saved_failed_items_.end(); ++it)
- save_ids.push_back(it->second->save_id());
+ std::vector<SaveItemId> list_of_failed_save_item_ids;
+ for (const auto& it : saved_failed_items_) {
+ SaveItem* save_item = it.second;
+ DCHECK_EQ(it.first, save_item->id());
+ list_of_failed_save_item_ids.push_back(save_item->id());
+ }
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap,
- file_manager_,
- save_ids));
+ base::Bind(&SaveFileManager::RemoveSavedFileFromFileMap, file_manager_,
+ list_of_failed_save_item_ids));
if (download_) {
// Hack to avoid touching download_ after user cancel.
@@ -812,17 +799,19 @@ void SavePackage::Finish() {
}
// Called for updating end state.
-void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) {
+void SavePackage::SaveFinished(SaveItemId save_item_id,
+ int64_t size,
+ bool is_success) {
// Because we might have canceled this saving job before,
// so we might not find corresponding SaveItem. Just ignore it.
- SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
+ SaveItem* save_item = LookupSaveItemInProcess(save_item_id);
if (!save_item)
return;
// Let SaveItem set end state.
save_item->Finish(size, is_success);
// Remove the associated save id and SavePackage.
- file_manager_->RemoveSaveFile(save_id, save_item->url(), this);
+ file_manager_->RemoveSaveFile(save_item->id(), this);
PutInProgressItemToSavedMap(save_item);
@@ -855,63 +844,12 @@ void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) {
CheckFinish();
}
-// Sometimes, the net io will only call SaveFileManager::SaveFinished with
-// save id -1 when it encounters error. Since in this case, save id will be
-// -1, so we can only use URL to find which SaveItem is associated with
-// this error.
-// Saving an item failed. If it's a sub-resource, ignore it. If the error comes
-// from serializing HTML data, then cancel saving page.
-void SavePackage::SaveFailed(const GURL& save_url) {
- SaveUrlItemMap::iterator it = in_progress_items_.find(save_url.spec());
- if (it == in_progress_items_.end()) {
- NOTREACHED(); // Should not exist!
- return;
- }
- SaveItem* save_item = it->second;
-
- save_item->Finish(0, false);
-
- PutInProgressItemToSavedMap(save_item);
-
- // Inform the DownloadItem to update UI.
- // We use the received bytes as number of saved files.
- // Hack to avoid touching download_ after user cancel.
- // TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem
- // with SavePackage flow.
- if (download_ && (download_->GetState() == DownloadItem::IN_PROGRESS)) {
- download_->DestinationUpdate(
- completed_count(), CurrentSpeed(), std::string());
- }
-
- if ((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
- (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) ||
- (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM)) {
- // We got error when saving page. Treat it as disk error.
- Cancel(true);
- }
-
- if (canceled()) {
- DCHECK(finished_);
- return;
- }
-
- // Continue processing the save page job.
- DoSavingProcess();
-
- CheckFinish();
-}
-
void SavePackage::SaveCanceled(SaveItem* save_item) {
// Call the RemoveSaveFile in UI thread.
- file_manager_->RemoveSaveFile(save_item->save_id(),
- save_item->url(),
- this);
- if (save_item->save_id() != -1)
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::CancelSave,
- file_manager_,
- save_item->save_id()));
+ file_manager_->RemoveSaveFile(save_item->id(), this);
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&SaveFileManager::CancelSave, file_manager_, save_item->id()));
}
// Initiate a saving job of a specific URL. We send the request to
@@ -925,24 +863,19 @@ void SavePackage::SaveNextFile(bool process_all_remaining_items) {
do {
// Pop SaveItem from waiting list.
SaveItem* save_item = waiting_item_queue_.front();
- waiting_item_queue_.pop();
+ waiting_item_queue_.pop_front();
// Add the item to in_progress_items_.
- SaveUrlItemMap::iterator it = in_progress_items_.find(
- save_item->url().spec());
+ SaveItemIdMap::iterator it = in_progress_items_.find(save_item->id());
DCHECK(it == in_progress_items_.end());
- in_progress_items_[save_item->url().spec()] = save_item;
+ in_progress_items_[save_item->id()] = save_item;
save_item->Start();
- file_manager_->SaveURL(save_item->url(),
- save_item->referrer(),
- web_contents()->GetRenderProcessHost()->GetID(),
- routing_id(),
- web_contents()->GetMainFrame()->GetRoutingID(),
- save_item->save_source(),
- save_item->full_path(),
- web_contents()->
- GetBrowserContext()->GetResourceContext(),
- this);
+ file_manager_->SaveURL(
+ save_item->id(), save_item->url(), save_item->referrer(),
+ web_contents()->GetRenderProcessHost()->GetID(), routing_id(),
+ web_contents()->GetMainFrame()->GetRoutingID(),
+ save_item->save_source(), save_item->full_path(),
+ web_contents()->GetBrowserContext()->GetResourceContext(), this);
} while (process_all_remaining_items && waiting_item_queue_.size());
}
@@ -956,9 +889,9 @@ int SavePackage::PercentComplete() {
return completed_count() / all_save_items_count_;
}
-int64 SavePackage::CurrentSpeed() const {
+int64_t SavePackage::CurrentSpeed() const {
base::TimeDelta diff = base::TimeTicks::Now() - start_tick_;
- int64 diff_ms = diff.InMilliseconds();
+ int64_t diff_ms = diff.InMilliseconds();
return diff_ms == 0 ? 0 : completed_count() * 1000 / diff_ms;
}
@@ -974,7 +907,7 @@ void SavePackage::DoSavingProcess() {
// Start a new SaveItem job if we still have job in waiting queue.
if (waiting_item_queue_.size()) {
- DCHECK(wait_state_ == NET_FILES);
+ DCHECK_EQ(NET_FILES, wait_state_);
SaveItem* save_item = waiting_item_queue_.front();
if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
SaveNextFile(false);
@@ -989,15 +922,16 @@ void SavePackage::DoSavingProcess() {
}
} else if (in_process_count()) {
// Continue asking for HTML data.
- DCHECK(wait_state_ == HTML_DATA);
+ DCHECK_EQ(HTML_DATA, wait_state_);
}
} else {
// Save as HTML only or MHTML.
- DCHECK(wait_state_ == NET_FILES);
+ DCHECK_EQ(NET_FILES, wait_state_);
DCHECK((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
- (save_type_ == SAVE_PAGE_TYPE_AS_MHTML));
+ (save_type_ == SAVE_PAGE_TYPE_AS_MHTML))
+ << save_type_;
if (waiting_item_queue_.size()) {
- DCHECK(all_save_items_count_ == waiting_item_queue_.size());
+ DCHECK_EQ(all_save_items_count_, waiting_item_queue_.size());
SaveNextFile(false);
}
}
@@ -1006,7 +940,8 @@ void SavePackage::DoSavingProcess() {
bool SavePackage::OnMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host) {
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(SavePackage, message, render_frame_host)
+ auto* rfhi = static_cast<RenderFrameHostImpl*>(render_frame_host);
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(SavePackage, message, rfhi)
IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksResponse,
OnSavableResourceLinksResponse)
IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksError,
@@ -1025,103 +960,106 @@ bool SavePackage::OnMessageReceived(const IPC::Message& message,
void SavePackage::GetSerializedHtmlWithLocalLinks() {
if (wait_state_ != HTML_DATA)
return;
- std::vector<GURL> saved_links;
- std::vector<base::FilePath> saved_file_paths;
- int successful_started_items_count = 0;
- // Collect all saved items which have local storage.
// First collect the status of all the resource files and check whether they
- // have created local files although they have not been completely saved.
- // If yes, the file can be saved. Otherwise, there is a disk error, so we
- // need to cancel the page saving job.
- for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
- it != in_progress_items_.end(); ++it) {
- DCHECK(it->second->save_source() ==
- SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
- if (it->second->has_final_name())
+ // have created local files (although they have not been completely saved).
+ int successful_started_items_count = 0;
+ for (const auto& item : in_progress_items_) {
+ DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM,
+ item.second->save_source());
+ if (item.second->has_final_name())
successful_started_items_count++;
- saved_links.push_back(it->second->url());
- saved_file_paths.push_back(it->second->file_name());
}
-
// If not all file of HTML resource have been started, then wait.
if (successful_started_items_count != in_process_count())
return;
- // Collect all saved success items.
- for (SavedItemMap::iterator it = saved_success_items_.begin();
- it != saved_success_items_.end(); ++it) {
- DCHECK(it->second->has_final_name());
- saved_links.push_back(it->second->url());
- saved_file_paths.push_back(it->second->file_name());
- }
-
- // Get the relative directory name.
- base::FilePath relative_dir_name = saved_main_directory_path_.BaseName();
-
// Ask all frames for their serialized data.
DCHECK_EQ(0, number_of_frames_pending_response_);
- web_contents()->ForEachFrame(base::Bind(
- &SavePackage::GetSerializedHtmlWithLocalLinksForFrame,
- base::Unretained(this), // Safe, because ForEachFrame is synchronous.
- saved_links, saved_file_paths, relative_dir_name));
- DCHECK_LT(0, number_of_frames_pending_response_);
+ FrameTree* frame_tree =
+ static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame())
+ ->frame_tree_node()->frame_tree();
+ for (const auto& item : frame_tree_node_id_to_save_item_) {
+ DCHECK(item.second); // SaveItem* != nullptr.
+ int frame_tree_node_id = item.first;
+ FrameTreeNode* frame_tree_node = frame_tree->FindByID(frame_tree_node_id);
+ if (frame_tree_node) {
+ GetSerializedHtmlWithLocalLinksForFrame(frame_tree_node);
+ number_of_frames_pending_response_++;
+ }
+ }
+ if (number_of_frames_pending_response_ == 0) {
+ // All frames disappeared since gathering of savable resources?
+ // Treat this as cancellation.
+ Cancel(false);
+ }
}
void SavePackage::GetSerializedHtmlWithLocalLinksForFrame(
- const std::vector<GURL>& saved_links,
- const std::vector<base::FilePath>& saved_file_paths,
- const base::FilePath& relative_dir_name,
- RenderFrameHost* target) {
- number_of_frames_pending_response_++;
+ FrameTreeNode* target_tree_node) {
+ DCHECK(target_tree_node);
+ int target_frame_tree_node_id = target_tree_node->frame_tree_node_id();
+
+ // Collect all saved success items.
+ // SECURITY NOTE: We don't send *all* urls / local paths, but only
+ // those that the given frame had access to already (because it contained
+ // the savable resources / subframes associated with save items).
+ std::map<GURL, base::FilePath> url_to_local_path;
+ auto it = frame_tree_node_id_to_contained_save_items_.find(
+ target_frame_tree_node_id);
+ if (it != frame_tree_node_id_to_contained_save_items_.end()) {
+ for (SaveItem* save_item : it->second) {
+ DCHECK(save_item->has_final_name());
+ base::FilePath local_path(base::FilePath::kCurrentDirectory);
+ if (target_tree_node->IsMainFrame()) {
+ local_path = local_path.Append(saved_main_directory_path_.BaseName());
+ }
+ local_path = local_path.Append(save_item->file_name());
+ url_to_local_path[save_item->url()] = local_path;
+ }
+ }
+
+ // Ask target frame to serialize itself.
+ RenderFrameHostImpl* target = target_tree_node->current_frame_host();
target->Send(new FrameMsg_GetSerializedHtmlWithLocalLinks(
- target->GetRoutingID(), saved_links, saved_file_paths,
- relative_dir_name));
+ target->GetRoutingID(), url_to_local_path));
}
// Process the serialized HTML content data of a specified frame
// retrieved from the renderer process.
void SavePackage::OnSerializedHtmlWithLocalLinksResponse(
- RenderFrameHost* sender,
- const GURL& frame_url,
+ RenderFrameHostImpl* sender,
const std::string& data,
- int32 status) {
- WebPageSerializerClient::PageSerializationStatus flag =
- static_cast<WebPageSerializerClient::PageSerializationStatus>(status);
-
- // When calling WebPageSerializer::serialize in non-recursive mode, the
- // AllFramesAreFinished is redundant - it is sent by each frame right after
- // CurrentFrameIsFinished. Therefore we ignore AllFramesAreFinished and
- // instead track pending frames in |number_of_frames_pending_response_|.
- if (flag == WebPageSerializerClient::AllFramesAreFinished)
- return;
-
+ bool end_of_data) {
// Check current state.
if (wait_state_ != HTML_DATA)
return;
- int id = contents_id();
-
- SaveUrlItemMap::iterator it = in_progress_items_.find(frame_url.spec());
- if (it == in_progress_items_.end()) {
- for (SavedItemMap::iterator saved_it = saved_success_items_.begin();
- saved_it != saved_success_items_.end(); ++saved_it) {
- if (saved_it->second->url() == frame_url) {
+ int frame_tree_node_id = sender->frame_tree_node()->frame_tree_node_id();
+ auto it = frame_tree_node_id_to_save_item_.find(frame_tree_node_id);
+ if (it == frame_tree_node_id_to_save_item_.end()) {
+ // This is parimarily sanitization of IPC (renderer shouldn't send
+ // OnSerializedHtmlFragment IPC without being asked to), but it might also
+ // occur in the wild (if old renderer response reaches a new SavePackage).
+ return;
+ }
+ SaveItem* save_item = it->second;
+ DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_item->save_source());
+ if (save_item->state() != SaveItem::IN_PROGRESS) {
+ for (const auto& saved_it : saved_success_items_) {
+ if (saved_it.second->url() == save_item->url()) {
wrote_to_completed_file_ = true;
break;
}
}
- it = saved_failed_items_.find(frame_url.spec());
- if (it != saved_failed_items_.end())
+ auto it2 = saved_failed_items_.find(save_item->id());
+ if (it2 != saved_failed_items_.end())
wrote_to_failed_file_ = true;
return;
}
- SaveItem* save_item = it->second;
- DCHECK(save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
-
if (!data.empty()) {
// Prepare buffer for saving HTML data.
scoped_refptr<net::IOBuffer> new_data(new net::IOBuffer(data.size()));
@@ -1130,44 +1068,22 @@ void SavePackage::OnSerializedHtmlWithLocalLinksResponse(
// Call write file functionality in file thread.
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::UpdateSaveProgress,
- file_manager_,
- save_item->save_id(),
- new_data,
- static_cast<int>(data.size())));
+ base::Bind(&SaveFileManager::UpdateSaveProgress, file_manager_,
+ save_item->id(), new_data, static_cast<int>(data.size())));
}
// Current frame is completed saving, call finish in file thread.
- if (flag == WebPageSerializerClient::CurrentFrameIsFinished) {
+ if (end_of_data) {
DVLOG(20) << " " << __FUNCTION__ << "()"
- << " save_id = " << save_item->save_id()
- << " url = \"" << save_item->url().spec() << "\"";
+ << " save_item_id = " << save_item->id() << " url = \""
+ << save_item->url().spec() << "\"";
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::SaveFinished,
- file_manager_,
- save_item->save_id(),
- save_item->url(),
- id,
- true));
+ base::Bind(&SaveFileManager::SaveFinished, file_manager_,
+ save_item->id(), id(), true));
number_of_frames_pending_response_--;
DCHECK_LE(0, number_of_frames_pending_response_);
}
-
- // If all frames are finished saving, we need to close the remaining
- // SaveItems.
- if (number_of_frames_pending_response_ == 0) {
- for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
- it != in_progress_items_.end(); ++it) {
- DVLOG(20) << " " << __FUNCTION__ << "()"
- << " save_id = " << it->second->save_id() << " url = \""
- << it->second->url().spec() << "\"";
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&SaveFileManager::SaveFinished, file_manager_,
- it->second->save_id(), it->second->url(), id, true));
- }
- }
}
// Ask for all savable resource links from backend, include main frame and
@@ -1179,52 +1095,128 @@ void SavePackage::GetSavableResourceLinks() {
wait_state_ = RESOURCES_LIST;
DCHECK_EQ(0, number_of_frames_pending_response_);
- web_contents()->ForEachFrame(base::Bind(
- &SavePackage::GetSavableResourceLinksForFrame,
- base::Unretained(this))); // Safe, because ForEachFrame is synchronous.
+ number_of_frames_pending_response_ = web_contents()->SendToAllFrames(
+ new FrameMsg_GetSavableResourceLinks(MSG_ROUTING_NONE));
DCHECK_LT(0, number_of_frames_pending_response_);
-}
-void SavePackage::GetSavableResourceLinksForFrame(RenderFrameHost* target) {
- number_of_frames_pending_response_++;
- target->Send(new FrameMsg_GetSavableResourceLinks(target->GetRoutingID()));
+ // Enqueue the main frame separately (because this frame won't show up in any
+ // of OnSavableResourceLinksResponse callbacks).
+ FrameTreeNode* main_frame_tree_node =
+ static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame())
+ ->frame_tree_node();
+ EnqueueFrame(FrameTreeNode::kFrameTreeNodeInvalidId, // No container.
+ main_frame_tree_node->frame_tree_node_id(),
+ main_frame_tree_node->current_url());
}
void SavePackage::OnSavableResourceLinksResponse(
- RenderFrameHost* sender,
- const GURL& frame_url,
+ RenderFrameHostImpl* sender,
const std::vector<GURL>& resources_list,
- const std::vector<Referrer>& referrers_list) {
+ const Referrer& referrer,
+ const std::vector<SavableSubframe>& subframes) {
if (wait_state_ != RESOURCES_LIST)
return;
- if (resources_list.size() != referrers_list.size())
- return;
-
// Add all sub-resources to wait list.
- for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) {
- const GURL& u = resources_list[i];
- if (!u.is_valid())
+ int container_frame_tree_node_id =
+ sender->frame_tree_node()->frame_tree_node_id();
+ for (const GURL& u : resources_list) {
+ EnqueueSavableResource(container_frame_tree_node_id, u, referrer);
+ }
+ for (const SavableSubframe& subframe : subframes) {
+ FrameTreeNode* subframe_tree_node =
+ sender->frame_tree_node()->frame_tree()->FindByRoutingID(
+ sender->GetProcess()->GetID(), subframe.routing_id);
+
+ if (!subframe_tree_node) {
+ // crbug.com/541354 - Raciness when saving a dynamically changing page.
continue;
- if (unique_urls_to_save_.count(u))
+ }
+ if (subframe_tree_node->parent() != sender->frame_tree_node()) {
+ // Only reachable if the renderer has a bug or has been compromised.
+ ReceivedBadMessage(
+ sender->GetProcess(),
+ bad_message::DWNLD_INVALID_SAVABLE_RESOURCE_LINKS_RESPONSE);
continue;
- unique_urls_to_save_.insert(u);
+ }
- SaveFileCreateInfo::SaveFileSource save_source =
- u.SchemeIsFile() ? SaveFileCreateInfo::SAVE_FILE_FROM_FILE
- : SaveFileCreateInfo::SAVE_FILE_FROM_NET;
- SaveItem* save_item = new SaveItem(u, referrers_list[i], this, save_source);
- waiting_item_queue_.push(save_item);
+ EnqueueFrame(container_frame_tree_node_id,
+ subframe_tree_node->frame_tree_node_id(),
+ subframe.original_url);
}
- // Store savable frame_url for later processing.
- if (frame_url.is_valid())
- frame_urls_to_save_.push_back(frame_url);
-
CompleteSavableResourceLinksResponse();
}
-void SavePackage::OnSavableResourceLinksError(RenderFrameHost* sender) {
+SaveItem* SavePackage::CreatePendingSaveItem(
+ int container_frame_tree_node_id,
+ const GURL& url,
+ const Referrer& referrer,
+ SaveFileCreateInfo::SaveFileSource save_source) {
+ DCHECK(url.is_valid()); // |url| should be validated by the callers.
+
+ SaveItem* save_item;
+ Referrer sanitized_referrer = Referrer::SanitizeForRequest(url, referrer);
+ save_item = new SaveItem(url, sanitized_referrer, this, save_source);
+ waiting_item_queue_.push_back(save_item);
+
+ frame_tree_node_id_to_contained_save_items_[container_frame_tree_node_id]
+ .push_back(save_item);
+ return save_item;
+}
+
+SaveItem* SavePackage::CreatePendingSaveItemDeduplicatingByUrl(
+ int container_frame_tree_node_id,
+ const GURL& url,
+ const Referrer& referrer,
+ SaveFileCreateInfo::SaveFileSource save_source) {
+ DCHECK(url.is_valid()); // |url| should be validated by the callers.
+
+ // Frames should not be deduplicated by URL.
+ DCHECK_NE(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_source);
+
+ SaveItem* save_item;
+ auto it = url_to_save_item_.find(url);
+ if (it != url_to_save_item_.end()) {
+ save_item = it->second;
+ frame_tree_node_id_to_contained_save_items_[container_frame_tree_node_id]
+ .push_back(save_item);
+ } else {
+ save_item = CreatePendingSaveItem(container_frame_tree_node_id, url,
+ referrer, save_source);
+ url_to_save_item_[url] = save_item;
+ }
+
+ return save_item;
+}
+
+void SavePackage::EnqueueSavableResource(int container_frame_tree_node_id,
+ const GURL& url,
+ const Referrer& referrer) {
+ if (!url.is_valid())
+ return;
+
+ SaveFileCreateInfo::SaveFileSource save_source =
+ url.SchemeIsFile() ? SaveFileCreateInfo::SAVE_FILE_FROM_FILE
+ : SaveFileCreateInfo::SAVE_FILE_FROM_NET;
+ CreatePendingSaveItemDeduplicatingByUrl(container_frame_tree_node_id, url,
+ referrer, save_source);
+}
+
+void SavePackage::EnqueueFrame(int container_frame_tree_node_id,
+ int frame_tree_node_id,
+ const GURL& frame_original_url) {
+ if (!frame_original_url.is_valid())
+ return;
+
+ SaveItem* save_item =
+ CreatePendingSaveItem(container_frame_tree_node_id, frame_original_url,
+ Referrer(), SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
+ DCHECK(save_item);
+ frame_tree_node_id_to_save_item_[frame_tree_node_id] = save_item;
+}
+
+void SavePackage::OnSavableResourceLinksError(RenderFrameHostImpl* sender) {
CompleteSavableResourceLinksResponse();
}
@@ -1234,19 +1226,16 @@ void SavePackage::CompleteSavableResourceLinksResponse() {
if (number_of_frames_pending_response_ != 0)
return; // Need to wait for more responses from RenderFrames.
- // Add frame urls to the waiting_item_queue_. This is done *after* processing
- // all savable resource links (i.e. in OnSavableResourceLinksResponse), to
- // prefer their referrers in cases where the frame url has already been
- // covered by savable resource links.
- for (auto& frame_url : frame_urls_to_save_) {
- DCHECK(frame_url.is_valid());
- if (0 == unique_urls_to_save_.count(frame_url)) {
- unique_urls_to_save_.insert(frame_url);
- SaveItem* save_item = new SaveItem(
- frame_url, Referrer(), this, SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
- waiting_item_queue_.push(save_item);
- }
- }
+ // Sort |waiting_item_queue_| so that frames go last (frames are identified by
+ // SAVE_FILE_FROM_DOM in the comparison function below).
+ std::stable_sort(
+ waiting_item_queue_.begin(), waiting_item_queue_.end(),
+ [](SaveItem* x, SaveItem* y) {
+ DCHECK(x);
+ DCHECK(y);
+ return (x->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) &&
+ (y->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
+ });
all_save_items_count_ = static_cast<int>(waiting_item_queue_.size());
@@ -1366,7 +1355,7 @@ const base::FilePath::CharType* SavePackage::ExtensionForMimeType(
#elif defined(OS_WIN)
base::FilePath::StringType mime_type(base::UTF8ToWide(contents_mime_type));
#endif // OS_WIN
- for (uint32 i = 0; i < arraysize(extensions); ++i) {
+ for (uint32_t i = 0; i < arraysize(extensions); ++i) {
if (mime_type == extensions[i].mime_type)
return extensions[i].suggested_extension;
}
@@ -1425,7 +1414,7 @@ void SavePackage::CreateDirectoryOnFileThread(
base::FilePath::StringType file_name_ext = suggested_filename.Extension();
// Need to make sure the suggested file name is not too long.
- uint32 max_path = GetMaxPathLengthForDirectory(save_dir);
+ uint32_t max_path = GetMaxPathLengthForDirectory(save_dir);
if (GetSafePureFileName(save_dir, file_name_ext, max_path, &pure_file_name)) {
save_dir = save_dir.Append(pure_file_name + file_name_ext);
diff --git a/chromium/content/browser/download/save_package.h b/chromium/content/browser/download/save_package.h
index 818ad5bf524..eabf65717a0 100644
--- a/chromium/content/browser/download/save_package.h
+++ b/chromium/content/browser/download/save_package.h
@@ -5,18 +5,23 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_SAVE_PACKAGE_H_
#define CONTENT_BROWSER_DOWNLOAD_SAVE_PACKAGE_H_
-#include <queue>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <deque>
+#include <map>
#include <set>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
+#include "content/browser/download/save_types.h"
#include "content/common/content_export.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager_delegate.h"
@@ -31,11 +36,13 @@ class GURL;
namespace content {
class DownloadItemImpl;
class DownloadManagerImpl;
-class WebContents;
+class FrameTreeNode;
+class RenderFrameHostImpl;
+struct SavableSubframe;
class SaveFileManager;
class SaveItem;
class SavePackage;
-struct SaveFileCreateInfo;
+class WebContents;
// The SavePackage object manages the process of saving a page as only-html or
// complete-html or MHTML and providing the information for displaying saving
@@ -103,9 +110,10 @@ class CONTENT_EXPORT SavePackage
// Notifications sent from the file thread to the UI thread.
void StartSave(const SaveFileCreateInfo* info);
- bool UpdateSaveProgress(int32 save_id, int64 size, bool write_success);
- void SaveFinished(int32 save_id, int64 size, bool is_success);
- void SaveFailed(const GURL& save_url);
+ bool UpdateSaveProgress(SaveItemId save_item_id,
+ int64_t size,
+ bool write_success);
+ void SaveFinished(SaveItemId save_item_id, int64_t size, bool is_success);
void SaveCanceled(SaveItem* save_item);
// Rough percent complete, -1 means we don't know (since we didn't receive a
@@ -115,8 +123,8 @@ class CONTENT_EXPORT SavePackage
bool canceled() const { return user_canceled_ || disk_error_occurred_; }
bool finished() const { return finished_; }
SavePageType save_type() const { return save_type_; }
- int contents_id() const { return contents_id_; }
- int id() const { return unique_id_; }
+
+ SavePackageId id() const { return unique_id_; }
void GetSaveInfo();
@@ -128,7 +136,7 @@ class CONTENT_EXPORT SavePackage
DownloadItemImpl* item);
// Callback for WebContents::GenerateMHTML().
- void OnMHTMLGenerated(int64 size);
+ void OnMHTMLGenerated(int64_t size);
// For testing only.
SavePackage(WebContents* web_contents,
@@ -162,12 +170,12 @@ class CONTENT_EXPORT SavePackage
// This is needed on POSIX, which restrict the length of file names in
// addition to the restriction on the length of path names.
// |base_dir| is assumed to be a directory name with no trailing slash.
- static uint32 GetMaxPathLengthForDirectory(const base::FilePath& base_dir);
+ static uint32_t GetMaxPathLengthForDirectory(const base::FilePath& base_dir);
static bool GetSafePureFileName(
const base::FilePath& dir_path,
const base::FilePath::StringType& file_name_ext,
- uint32 max_file_path_len,
+ uint32_t max_file_path_len,
base::FilePath::StringType* pure_file_name);
// Create a file name based on the response from the server.
@@ -176,48 +184,75 @@ class CONTENT_EXPORT SavePackage
bool need_html_ext,
base::FilePath::StringType* generated_name);
- // Set of methods to get all savable resource links from current web page,
- // including main frame and sub-frames.
+ // Main routine that initiates asking all frames for their savable resources.
+ //
+ // Responses are received asynchronously by OnSavableResourceLinks... methods
+ // and pending responses are counted/tracked by
+ // CompleteSavableResourceLinksResponse.
+ //
+ // OnSavableResourceLinksResponse creates SaveItems for each savable resource
+ // and each subframe - these SaveItems get enqueued into |waiting_item_queue_|
+ // with the help of CreatePendingSaveItem, EnqueueSavableResource,
+ // EnqueueFrame.
void GetSavableResourceLinks();
- void GetSavableResourceLinksForFrame(RenderFrameHost* target);
+
+ // Response from |sender| frame to GetSavableResourceLinks request.
void OnSavableResourceLinksResponse(
- RenderFrameHost* sender,
- const GURL& frame_url,
+ RenderFrameHostImpl* sender,
const std::vector<GURL>& resources_list,
- const std::vector<Referrer>& referrers_list);
- void OnSavableResourceLinksError(RenderFrameHost* sender);
+ const Referrer& referrer,
+ const std::vector<SavableSubframe>& subframes);
+
+ // Helper for finding or creating a SaveItem with the given parameters.
+ SaveItem* CreatePendingSaveItem(
+ int container_frame_tree_node_id,
+ const GURL& url,
+ const Referrer& referrer,
+ SaveFileCreateInfo::SaveFileSource save_source);
+
+ // Helper for finding a SaveItem with the given url, or falling back to
+ // creating a SaveItem with the given parameters.
+ SaveItem* CreatePendingSaveItemDeduplicatingByUrl(
+ int container_frame_tree_node_id,
+ const GURL& url,
+ const Referrer& referrer,
+ SaveFileCreateInfo::SaveFileSource save_source);
+
+ // Helper to enqueue a savable resource reported by GetSavableResourceLinks.
+ void EnqueueSavableResource(int container_frame_tree_node_id,
+ const GURL& url,
+ const Referrer& referrer);
+ // Helper to enqueue a subframe reported by GetSavableResourceLinks.
+ void EnqueueFrame(int container_frame_tree_node_id,
+ int frame_tree_node_id,
+ const GURL& frame_original_url);
+
+ // Response to GetSavableResourceLinks that indicates an error when processing
+ // the frame associated with |sender|.
+ void OnSavableResourceLinksError(RenderFrameHostImpl* sender);
+
+ // Helper tracking how many |number_of_frames_pending_response_| we have
+ // left and kicking off the next phase after we got all the
+ // OnSavableResourceLinksResponse messages we were waiting for.
void CompleteSavableResourceLinksResponse();
// For each frame in the current page, ask the renderer process associated
// with that frame to serialize that frame into html.
void GetSerializedHtmlWithLocalLinks();
- // Ask renderer process to serialize |target| frame into html data
- // with lists which contain all resource links that have a local copy.
- // - The parameter |saved_links| contains original URLs of all saved links
- // (which may include URLs referred to from the whole page (not just from
- // the |target| frame).
- // - The parameter |saved_file_paths| contains corresponding local file paths
- // of all saved links, which is matched with |saved_links| vector one by
- // one.
- // - The parameter |relative_dir_name| is relative path of directory which
- // contain all saved auxiliary files included all sub frames and resouces.
- void GetSerializedHtmlWithLocalLinksForFrame(
- const std::vector<GURL>& saved_links,
- const std::vector<base::FilePath>& saved_file_paths,
- const base::FilePath& relative_dir_name,
- RenderFrameHost* target);
+ // Ask renderer process to serialize |target_tree_node| into html data
+ // with resource links replaced with a link to a locally saved copy.
+ void GetSerializedHtmlWithLocalLinksForFrame(FrameTreeNode* target_tree_node);
// Routes html data (sent by renderer process in response to
// GetSerializedHtmlWithLocalLinksForFrame above) to the associated local file
// (and also keeps track of when all frames have been completed).
- void OnSerializedHtmlWithLocalLinksResponse(RenderFrameHost* sender,
- const GURL& frame_url,
+ void OnSerializedHtmlWithLocalLinksResponse(RenderFrameHostImpl* sender,
const std::string& data,
- int32 status);
+ bool end_of_data);
- // Look up SaveItem by save id from in progress map.
- SaveItem* LookupItemInProcessBySaveId(int32 save_id);
+ // Look up SaveItem by save item id from in progress map.
+ SaveItem* LookupSaveItemInProcess(SaveItemId save_item_id);
// Remove SaveItem from in progress map and put it to saved map.
void PutInProgressItemToSavedMap(SaveItem* save_item);
@@ -237,11 +272,12 @@ class CONTENT_EXPORT SavePackage
SavePageType type,
const SavePackageDownloadCreatedCallback& cb);
- typedef base::hash_map<std::string, SaveItem*> SaveUrlItemMap;
+ // Map from SaveItem::id() (aka save_item_id) into a SaveItem.
+ typedef base::hash_map<SaveItemId, SaveItem*> SaveItemIdMap;
// in_progress_items_ is map of all saving job in in-progress state.
- SaveUrlItemMap in_progress_items_;
+ SaveItemIdMap in_progress_items_;
// saved_failed_items_ is map of all saving job which are failed.
- SaveUrlItemMap saved_failed_items_;
+ SaveItemIdMap saved_failed_items_;
// The number of in process SaveItems.
int in_process_count() const {
@@ -260,7 +296,7 @@ class CONTENT_EXPORT SavePackage
// presented by the DownloadItem to the UI as bytes per second, which is
// not correct but matches the way the total and received number of files is
// presented as the total and received bytes.
- int64 CurrentSpeed() const;
+ int64_t CurrentSpeed() const;
// Helper function for preparing suggested name for the SaveAs Dialog. The
// suggested name is determined by the web document's title.
@@ -283,22 +319,35 @@ class CONTENT_EXPORT SavePackage
static const base::FilePath::CharType* ExtensionForMimeType(
const std::string& contents_mime_type);
- typedef std::queue<SaveItem*> SaveItemQueue;
+ typedef std::deque<SaveItem*> SaveItemQueue;
// A queue for items we are about to start saving.
SaveItemQueue waiting_item_queue_;
- // Used to de-dupe urls that are being gathered into |waiting_item_queue_|.
- std::set<GURL> unique_urls_to_save_;
-
- // Temporarily stores urls of savable frames, until we can process them.
- std::vector<GURL> frame_urls_to_save_;
+ // Used to de-dupe urls that are being gathered into |waiting_item_queue_|
+ // and also to find SaveItems to associate with a containing frame.
+ // Note that |url_to_save_item_| does NOT own SaveItems - they
+ // remain owned by waiting_item_queue_, in_progress_items_, etc.
+ std::map<GURL, SaveItem*> url_to_save_item_;
+
+ // Map used to route responses from a given a subframe (i.e.
+ // OnSerializedHtmlWithLocalLinksResponse) to the right SaveItem.
+ // Note that |frame_tree_node_id_to_save_item_| does NOT own SaveItems - they
+ // remain owned by waiting_item_queue_, in_progress_items_, etc.
+ base::hash_map<int, SaveItem*> frame_tree_node_id_to_save_item_;
+
+ // Used to limit which local paths get exposed to which frames
+ // (i.e. to prevent information disclosure to oop frames).
+ // Note that |frame_tree_node_id_to_contained_save_items_| does NOT own
+ // SaveItems - they remain owned by waiting_item_queue_, in_progress_items_,
+ // etc.
+ base::hash_map<int, std::vector<SaveItem*>>
+ frame_tree_node_id_to_contained_save_items_;
// Number of frames that we still need to get a response from.
int number_of_frames_pending_response_;
- typedef base::hash_map<int32, SaveItem*> SavedItemMap;
// saved_success_items_ is map of all saving job which are successfully saved.
- SavedItemMap saved_success_items_;
+ base::hash_map<SaveItemId, SaveItem*> saved_success_items_;
// Non-owning pointer for handling file writing on the file thread.
SaveFileManager* file_manager_;
@@ -343,7 +392,7 @@ class CONTENT_EXPORT SavePackage
// This set is used to eliminate duplicated file names in saving directory.
FileNameSet file_name_set_;
- typedef base::hash_map<base::FilePath::StringType, uint32> FileNameCountMap;
+ typedef base::hash_map<base::FilePath::StringType, uint32_t> FileNameCountMap;
// This map is used to track serial number for specified filename.
FileNameCountMap file_name_count_map_;
@@ -351,12 +400,8 @@ class CONTENT_EXPORT SavePackage
// from outside.
WaitState wait_state_;
- // Since for one contents, it can only have one SavePackage in same time.
- // Now we actually use render_process_id as the contents's unique id.
- const int contents_id_;
-
// Unique ID for this SavePackage.
- const int unique_id_;
+ const SavePackageId unique_id_;
// Variables to record errors that happened so we can record them via
// UMA statistics.
diff --git a/chromium/content/browser/download/save_package_browsertest.cc b/chromium/content/browser/download/save_package_browsertest.cc
index 5b3bc173634..cca77cf4ac8 100644
--- a/chromium/content/browser/download/save_package_browsertest.cc
+++ b/chromium/content/browser/download/save_package_browsertest.cc
@@ -7,10 +7,11 @@
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
namespace content {
-const char kTestFile[] = "files/simple_page.html";
+const char kTestFile[] = "/simple_page.html";
class SavePackageBrowserTest : public ContentBrowserTest {
protected:
@@ -34,22 +35,21 @@ class SavePackageBrowserTest : public ContentBrowserTest {
// Create a SavePackage and delete it without calling Init.
// SavePackage dtor has various asserts/checks that should not fire.
IN_PROC_BROWSER_TEST_F(SavePackageBrowserTest, ImplicitCancel) {
- ASSERT_TRUE(test_server()->Start());
- GURL url = test_server()->GetURL(kTestFile);
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL(kTestFile);
NavigateToURL(shell(), url);
base::FilePath full_file_name, dir;
GetDestinationPaths("a", &full_file_name, &dir);
scoped_refptr<SavePackage> save_package(new SavePackage(
shell()->web_contents(), SAVE_PAGE_TYPE_AS_ONLY_HTML, full_file_name,
dir));
- ASSERT_TRUE(test_server()->Stop());
}
// Create a SavePackage, call Cancel, then delete it.
// SavePackage dtor has various asserts/checks that should not fire.
IN_PROC_BROWSER_TEST_F(SavePackageBrowserTest, ExplicitCancel) {
- ASSERT_TRUE(test_server()->Start());
- GURL url = test_server()->GetURL(kTestFile);
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL(kTestFile);
NavigateToURL(shell(), url);
base::FilePath full_file_name, dir;
GetDestinationPaths("a", &full_file_name, &dir);
@@ -57,7 +57,6 @@ IN_PROC_BROWSER_TEST_F(SavePackageBrowserTest, ExplicitCancel) {
shell()->web_contents(), SAVE_PAGE_TYPE_AS_ONLY_HTML, full_file_name,
dir));
save_package->Cancel(true);
- ASSERT_TRUE(test_server()->Stop());
}
} // namespace content
diff --git a/chromium/content/browser/download/save_package_unittest.cc b/chromium/content/browser/download/save_package_unittest.cc
index 2665d2bed9d..fc89b6d1806 100644
--- a/chromium/content/browser/download/save_package_unittest.cc
+++ b/chromium/content/browser/download/save_package_unittest.cc
@@ -2,12 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/download/save_package.h"
#include "content/public/common/url_constants.h"
#include "content/test/test_render_view_host.h"
@@ -30,11 +35,11 @@ namespace {
// This constant copied from save_package.cc.
#if defined(OS_WIN)
-const uint32 kMaxFilePathLength = MAX_PATH - 1;
-const uint32 kMaxFileNameLength = MAX_PATH - 1;
+const uint32_t kMaxFilePathLength = MAX_PATH - 1;
+const uint32_t kMaxFileNameLength = MAX_PATH - 1;
#elif defined(OS_POSIX)
-const uint32 kMaxFilePathLength = PATH_MAX - 1;
-const uint32 kMaxFileNameLength = NAME_MAX;
+const uint32_t kMaxFilePathLength = PATH_MAX - 1;
+const uint32_t kMaxFileNameLength = NAME_MAX;
#endif
// Used to make long filenames.
@@ -248,7 +253,7 @@ TEST_F(SavePackageTest, MAYBE_TestLongSafePureFilename) {
#endif
// Test that the filename + extension doesn't exceed kMaxFileNameLength
- uint32 max_path = SavePackage::GetMaxPathLengthForDirectory(save_dir);
+ uint32_t max_path = SavePackage::GetMaxPathLengthForDirectory(save_dir);
ASSERT_TRUE(SavePackage::GetSafePureFileName(save_dir, ext, max_path,
&filename));
EXPECT_TRUE(filename.length() <= kMaxFileNameLength-ext.length());
@@ -325,7 +330,7 @@ TEST_F(SavePackageTest, MAYBE_TestEnsureMimeExtension) {
{ FPL("filename.abc"), FPL("filename.abc"), "unknown/unknown" },
{ FPL("filename"), FPL("filename"), "unknown/unknown" },
};
- for (uint32 i = 0; i < arraysize(kExtensionTests); ++i) {
+ for (uint32_t i = 0; i < arraysize(kExtensionTests); ++i) {
base::FilePath original = base::FilePath(kExtensionTests[i].page_title);
base::FilePath expected = base::FilePath(kExtensionTests[i].expected_name);
std::string mime_type(kExtensionTests[i].contents_mime_type);
@@ -408,14 +413,9 @@ TEST_F(SavePackageTest, MAYBE_TestSuggestedSaveNames) {
}
}
-static const base::FilePath::CharType* kTestDir =
- FILE_PATH_LITERAL("save_page");
-
// GetUrlToBeSaved method should return correct url to be saved.
TEST_F(SavePackageTest, TestGetUrlToBeSaved) {
- base::FilePath file_name(FILE_PATH_LITERAL("a.htm"));
- GURL url = net::URLRequestMockHTTPJob::GetMockUrl(
- base::FilePath(kTestDir).Append(file_name));
+ GURL url = net::URLRequestMockHTTPJob::GetMockUrl("save_page/a.htm");
NavigateAndCommit(url);
EXPECT_EQ(url, GetUrlToBeSaved());
}
@@ -425,13 +425,10 @@ TEST_F(SavePackageTest, TestGetUrlToBeSaved) {
// Ex:GetUrlToBeSaved method should return http://www.google.com
// when user types view-source:http://www.google.com
TEST_F(SavePackageTest, TestGetUrlToBeSavedViewSource) {
- base::FilePath file_name(FILE_PATH_LITERAL("a.htm"));
- GURL mock_url = net::URLRequestMockHTTPJob::GetMockUrl(
- base::FilePath(kTestDir).Append(file_name));
+ GURL mock_url = net::URLRequestMockHTTPJob::GetMockUrl("save_page/a.htm");
GURL view_source_url =
GURL(kViewSourceScheme + std::string(":") + mock_url.spec());
- GURL actual_url = net::URLRequestMockHTTPJob::GetMockUrl(
- base::FilePath(kTestDir).Append(file_name));
+ GURL actual_url = net::URLRequestMockHTTPJob::GetMockUrl("save_page/a.htm");
NavigateAndCommit(view_source_url);
EXPECT_EQ(actual_url, GetUrlToBeSaved());
EXPECT_EQ(view_source_url, contents()->GetLastCommittedURL());
diff --git a/chromium/content/browser/download/save_types.cc b/chromium/content/browser/download/save_types.cc
index 2d02154ea8d..9c4972a8854 100644
--- a/chromium/content/browser/download/save_types.cc
+++ b/chromium/content/browser/download/save_types.cc
@@ -4,30 +4,46 @@
#include "content/browser/download/save_types.h"
+#include "base/files/file_path.h"
+
namespace content {
SaveFileCreateInfo::SaveFileCreateInfo(const base::FilePath& path,
const GURL& url,
- SaveFileSource save_source,
- int32 save_id)
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ int render_process_id,
+ int render_frame_routing_id,
+ SaveFileSource save_source)
: path(path),
url(url),
- save_id(save_id),
- render_process_id(-1),
- render_frame_id(-1),
+ save_item_id(save_item_id),
+ save_package_id(save_package_id),
+ render_process_id(render_process_id),
+ render_frame_routing_id(render_frame_routing_id),
request_id(-1),
total_bytes(0),
- save_source(save_source) {
-}
+ save_source(save_source) {}
-SaveFileCreateInfo::SaveFileCreateInfo()
- : save_id(-1),
- render_process_id(-1),
- render_frame_id(-1),
- request_id(-1),
- total_bytes(0),
- save_source(SAVE_FILE_FROM_UNKNOWN) {
-}
+SaveFileCreateInfo::SaveFileCreateInfo(const GURL& url,
+ const GURL& final_url,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ int render_process_id,
+ int render_frame_routing_id,
+ int request_id,
+ const std::string& content_disposition,
+ int64_t total_bytes)
+ : url(url),
+ final_url(final_url),
+ save_item_id(save_item_id),
+ save_package_id(save_package_id),
+ render_process_id(render_process_id),
+ render_frame_routing_id(render_frame_routing_id),
+ request_id(request_id),
+ content_disposition(content_disposition),
+ total_bytes(total_bytes),
+ save_source(SaveFileCreateInfo::SAVE_FILE_FROM_NET) {}
SaveFileCreateInfo::~SaveFileCreateInfo() {}
diff --git a/chromium/content/browser/download/save_types.h b/chromium/content/browser/download/save_types.h
index f8f8d10fb6a..83d890b8dc9 100644
--- a/chromium/content/browser/download/save_types.h
+++ b/chromium/content/browser/download/save_types.h
@@ -5,17 +5,27 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_SAVE_TYPES_H_
#define CONTENT_BROWSER_DOWNLOAD_SAVE_TYPES_H_
+#include <stdint.h>
+
+#include <map>
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "content/common/id_type.h"
#include "url/gurl.h"
namespace content {
-typedef std::vector<std::pair<int, base::FilePath> > FinalNameList;
-typedef std::vector<int> SaveIDList;
+
+class SavePackage;
+using SavePackageId = IdType32<SavePackage>;
+
+class SaveItem;
+using SaveItemId = IdType32<SaveItem>;
+
+// Map from save_item_id into final file path.
+using FinalNamesMap = std::map<SaveItemId, base::FilePath>;
// This structure is used to handle and deliver some info
// when processing each save item job.
@@ -33,12 +43,25 @@ struct SaveFileCreateInfo {
SAVE_FILE_FROM_FILE
};
+ // Constructor for SAVE_FILE_FROM_DOM and/or SAVE_FILE_FROM_FILE.
SaveFileCreateInfo(const base::FilePath& path,
const GURL& url,
- SaveFileSource save_source,
- int32 save_id);
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ int render_process_id,
+ int render_frame_routing_id,
+ SaveFileSource save_source);
- SaveFileCreateInfo();
+ // Constructor for SAVE_FILE_FROM_NET case.
+ SaveFileCreateInfo(const GURL& url,
+ const GURL& final_url,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ int render_process_id,
+ int render_frame_routing_id,
+ int request_id,
+ const std::string& content_disposition,
+ int64_t total_bytes);
~SaveFileCreateInfo();
@@ -49,18 +72,19 @@ struct SaveFileCreateInfo {
GURL url;
// Final URL of the saved resource since some URL might be redirected.
GURL final_url;
- // The unique identifier for saving job, assigned at creation by
- // the SaveFileManager for its internal record keeping.
- int save_id;
+ // The unique identifier of SaveItem object associated with this job.
+ SaveItemId save_item_id;
+ // ID of SavePackage object.
+ SavePackageId save_package_id;
// IDs for looking up the contents we are associated with.
int render_process_id;
- int render_frame_id;
+ int render_frame_routing_id;
// Handle for informing the ResourceDispatcherHost of a UI based cancel.
int request_id;
// Disposition info from HTTP response.
std::string content_disposition;
// Total bytes of saved file.
- int64 total_bytes;
+ int64_t total_bytes;
// Source type of saved file.
SaveFileSource save_source;
};
diff --git a/chromium/content/browser/download/url_downloader.cc b/chromium/content/browser/download/url_downloader.cc
new file mode 100644
index 00000000000..b178a1d4b26
--- /dev/null
+++ b/chromium/content/browser/download/url_downloader.cc
@@ -0,0 +1,291 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/download/url_downloader.h"
+
+#include "base/callback_helpers.h"
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "content/browser/byte_stream.h"
+#include "content/browser/download/download_create_info.h"
+#include "content/browser/download/download_manager_impl.h"
+#include "content/browser/download/download_request_handle.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_save_info.h"
+#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_status_code.h"
+#include "ui/base/page_transition_types.h"
+
+namespace content {
+
+class UrlDownloader::RequestHandle : public DownloadRequestHandleInterface {
+ public:
+ RequestHandle(base::WeakPtr<UrlDownloader> downloader,
+ base::WeakPtr<DownloadManagerImpl> download_manager_impl,
+ scoped_refptr<base::SequencedTaskRunner> downloader_task_runner)
+ : downloader_(downloader),
+ download_manager_impl_(download_manager_impl),
+ downloader_task_runner_(downloader_task_runner) {}
+ RequestHandle(RequestHandle&& other)
+ : downloader_(std::move(other.downloader_)),
+ download_manager_impl_(std::move(other.download_manager_impl_)),
+ downloader_task_runner_(std::move(other.downloader_task_runner_)) {}
+ RequestHandle& operator=(RequestHandle&& other) {
+ downloader_ = std::move(other.downloader_);
+ download_manager_impl_ = std::move(other.download_manager_impl_);
+ downloader_task_runner_ = std::move(other.downloader_task_runner_);
+ return *this;
+ }
+
+ // DownloadRequestHandleInterface
+ WebContents* GetWebContents() const override { return nullptr; }
+ DownloadManager* GetDownloadManager() const override {
+ return download_manager_impl_ ? download_manager_impl_.get() : nullptr;
+ }
+ void PauseRequest() const override {
+ downloader_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UrlDownloader::PauseRequest, downloader_));
+ }
+ void ResumeRequest() const override {
+ downloader_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UrlDownloader::ResumeRequest, downloader_));
+ }
+ void CancelRequest() const override {
+ downloader_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UrlDownloader::CancelRequest, downloader_));
+ }
+ std::string DebugString() const override { return std::string(); }
+
+ private:
+ base::WeakPtr<UrlDownloader> downloader_;
+ base::WeakPtr<DownloadManagerImpl> download_manager_impl_;
+ scoped_refptr<base::SequencedTaskRunner> downloader_task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(RequestHandle);
+};
+
+// static
+scoped_ptr<UrlDownloader> UrlDownloader::BeginDownload(
+ base::WeakPtr<DownloadManagerImpl> download_manager,
+ scoped_ptr<net::URLRequest> request,
+ const Referrer& referrer,
+ bool prefer_cache,
+ scoped_ptr<DownloadSaveInfo> save_info,
+ uint32_t download_id,
+ const DownloadUrlParameters::OnStartedCallback& started_callback) {
+ if (!referrer.url.is_valid())
+ request->SetReferrer(std::string());
+ else
+ request->SetReferrer(referrer.url.spec());
+
+ int extra_load_flags = net::LOAD_NORMAL;
+ if (prefer_cache) {
+ // If there is upload data attached, only retrieve from cache because there
+ // is no current mechanism to prompt the user for their consent for a
+ // re-post. For GETs, try to retrieve data from the cache and skip
+ // validating the entry if present.
+ if (request->get_upload() != NULL)
+ extra_load_flags |= net::LOAD_ONLY_FROM_CACHE;
+ else
+ extra_load_flags |= net::LOAD_PREFERRING_CACHE;
+ } else {
+ extra_load_flags |= net::LOAD_DISABLE_CACHE;
+ }
+ request->SetLoadFlags(request->load_flags() | extra_load_flags);
+
+ if (request->url().SchemeIs(url::kBlobScheme))
+ return nullptr;
+
+ // From this point forward, the |UrlDownloader| is responsible for
+ // |started_callback|.
+ scoped_ptr<UrlDownloader> downloader(
+ new UrlDownloader(std::move(request), download_manager,
+ std::move(save_info), download_id, started_callback));
+ downloader->Start();
+
+ return downloader;
+}
+
+UrlDownloader::UrlDownloader(
+ scoped_ptr<net::URLRequest> request,
+ base::WeakPtr<DownloadManagerImpl> manager,
+ scoped_ptr<DownloadSaveInfo> save_info,
+ uint32_t download_id,
+ const DownloadUrlParameters::OnStartedCallback& on_started_callback)
+ : request_(std::move(request)),
+ manager_(manager),
+ download_id_(download_id),
+ on_started_callback_(on_started_callback),
+ handler_(
+ request_.get(),
+ std::move(save_info),
+ base::Bind(&UrlDownloader::ResumeReading, base::Unretained(this))),
+ weak_ptr_factory_(this) {}
+
+UrlDownloader::~UrlDownloader() {
+ CallStartedCallbackOnFailure(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
+}
+
+void UrlDownloader::Start() {
+ DCHECK(!request_->is_pending());
+
+ if (!request_->status().is_success())
+ return;
+
+ request_->set_delegate(this);
+ request_->Start();
+}
+
+void UrlDownloader::OnReceivedRedirect(net::URLRequest* request,
+ const net::RedirectInfo& redirect_info,
+ bool* defer_redirect) {
+ DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec();
+ request_->CancelWithError(net::ERR_ABORTED);
+}
+
+void UrlDownloader::OnResponseStarted(net::URLRequest* request) {
+ DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
+
+ if (!request_->status().is_success()) {
+ ResponseCompleted();
+ return;
+ }
+
+ scoped_ptr<DownloadCreateInfo> create_info;
+ scoped_ptr<ByteStreamReader> stream_reader;
+
+ handler_.OnResponseStarted(&create_info, &stream_reader);
+
+ create_info->download_id = download_id_;
+ create_info->request_handle.reset(
+ new RequestHandle(weak_ptr_factory_.GetWeakPtr(), manager_,
+ base::SequencedTaskRunnerHandle::Get()));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DownloadManagerImpl::StartDownload, manager_,
+ base::Passed(&create_info), base::Passed(&stream_reader),
+ base::ResetAndReturn(&on_started_callback_)));
+
+ if (request_->status().is_success())
+ StartReading(false); // Read the first chunk.
+ else
+ ResponseCompleted();
+}
+
+void UrlDownloader::StartReading(bool is_continuation) {
+ int bytes_read;
+
+ // Make sure we track the buffer in at least one place. This ensures it gets
+ // deleted even in the case the request has already finished its job and
+ // doesn't use the buffer.
+ scoped_refptr<net::IOBuffer> buf;
+ int buf_size;
+ if (!handler_.OnWillRead(&buf, &buf_size, -1)) {
+ request_->CancelWithError(net::ERR_ABORTED);
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&UrlDownloader::ResponseCompleted,
+ weak_ptr_factory_.GetWeakPtr()));
+ return;
+ }
+
+ DCHECK(buf.get());
+ DCHECK(buf_size > 0);
+
+ request_->Read(buf.get(), buf_size, &bytes_read);
+
+ // If IO is pending, wait for the URLRequest to call OnReadCompleted.
+ if (request_->status().is_io_pending())
+ return;
+
+ if (!is_continuation || bytes_read <= 0) {
+ OnReadCompleted(request_.get(), bytes_read);
+ } else {
+ // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
+ // thread in case the URLRequest can provide data synchronously.
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UrlDownloader::OnReadCompleted,
+ weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read));
+ }
+}
+
+void UrlDownloader::OnReadCompleted(net::URLRequest* request, int bytes_read) {
+ DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
+ << " bytes_read = " << bytes_read;
+
+ // bytes_read == -1 always implies an error.
+ if (bytes_read == -1 || !request_->status().is_success()) {
+ ResponseCompleted();
+ return;
+ }
+
+ DCHECK(bytes_read >= 0);
+ DCHECK(request_->status().is_success());
+
+ bool defer = false;
+ if (!handler_.OnReadCompleted(bytes_read, &defer)) {
+ request_->CancelWithError(net::ERR_ABORTED);
+ return;
+ } else if (defer) {
+ return;
+ }
+
+ if (!request_->status().is_success())
+ return;
+
+ if (bytes_read > 0) {
+ StartReading(true); // Read the next chunk.
+ } else {
+ // URLRequest reported an EOF. Call ResponseCompleted.
+ DCHECK_EQ(0, bytes_read);
+ ResponseCompleted();
+ }
+}
+
+void UrlDownloader::ResponseCompleted() {
+ DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
+
+ handler_.OnResponseCompleted(request_->status());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this));
+}
+
+void UrlDownloader::ResumeReading() {
+ if (request_->status().is_success()) {
+ StartReading(false); // Read the next chunk (OK to complete synchronously).
+ } else {
+ ResponseCompleted();
+ }
+}
+
+void UrlDownloader::CallStartedCallbackOnFailure(
+ DownloadInterruptReason result) {
+ if (on_started_callback_.is_null())
+ return;
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(base::ResetAndReturn(&on_started_callback_), nullptr, result));
+}
+
+void UrlDownloader::PauseRequest() {
+ handler_.PauseRequest();
+}
+
+void UrlDownloader::ResumeRequest() {
+ handler_.ResumeRequest();
+}
+
+void UrlDownloader::CancelRequest() {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/download/url_downloader.h b/chromium/content/browser/download/url_downloader.h
new file mode 100644
index 00000000000..787feb4c91b
--- /dev/null
+++ b/chromium/content/browser/download/url_downloader.h
@@ -0,0 +1,75 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOADER_H_
+#define CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOADER_H_
+
+#include <stdint.h>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/download/download_request_core.h"
+#include "content/public/browser/download_save_info.h"
+#include "content/public/browser/download_url_parameters.h"
+#include "content/public/common/referrer.h"
+#include "net/url_request/redirect_info.h"
+#include "net/url_request/url_request.h"
+
+namespace content {
+class DownloadManagerImpl;
+
+class UrlDownloader : public net::URLRequest::Delegate {
+ public:
+ UrlDownloader(
+ scoped_ptr<net::URLRequest> request,
+ base::WeakPtr<DownloadManagerImpl> manager,
+ scoped_ptr<DownloadSaveInfo> save_info,
+ uint32_t download_id,
+ const DownloadUrlParameters::OnStartedCallback& on_started_callback);
+ ~UrlDownloader() override;
+
+ static scoped_ptr<UrlDownloader> BeginDownload(
+ base::WeakPtr<DownloadManagerImpl> download_manager,
+ scoped_ptr<net::URLRequest> request,
+ const Referrer& referrer,
+ bool prefer_cache,
+ scoped_ptr<DownloadSaveInfo> save_info,
+ uint32_t download_id,
+ const DownloadUrlParameters::OnStartedCallback& started_callback);
+
+ // URLRequest::Delegate:
+ void OnReceivedRedirect(net::URLRequest* request,
+ const net::RedirectInfo& redirect_info,
+ bool* defer_redirect) override;
+ void OnResponseStarted(net::URLRequest* request) override;
+ void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
+
+ void StartReading(bool is_continuation);
+ void ResponseCompleted();
+
+ void Start();
+ void ResumeReading();
+
+ void CallStartedCallbackOnFailure(DownloadInterruptReason result);
+
+ private:
+ class RequestHandle;
+
+ void PauseRequest();
+ void ResumeRequest();
+ void CancelRequest();
+
+ scoped_ptr<net::URLRequest> request_;
+ base::WeakPtr<DownloadManagerImpl> manager_;
+ uint32_t download_id_;
+ DownloadUrlParameters::OnStartedCallback on_started_callback_;
+
+ DownloadRequestCore handler_;
+
+ base::WeakPtrFactory<UrlDownloader> weak_ptr_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOADER_H_
diff --git a/chromium/content/browser/file_descriptor_info_impl.cc b/chromium/content/browser/file_descriptor_info_impl.cc
index 45ce54246ec..f071b426d58 100644
--- a/chromium/content/browser/file_descriptor_info_impl.cc
+++ b/chromium/content/browser/file_descriptor_info_impl.cc
@@ -4,6 +4,10 @@
#include "content/browser/file_descriptor_info_impl.h"
+#include <utility>
+
+#include "base/stl_util.h"
+
namespace content {
// static
@@ -23,7 +27,7 @@ void FileDescriptorInfoImpl::Share(int id, base::PlatformFile fd) {
void FileDescriptorInfoImpl::Transfer(int id, base::ScopedFD fd) {
AddToMapping(id, fd.get());
- owned_descriptors_.push_back(new base::ScopedFD(fd.Pass()));
+ owned_descriptors_.push_back(std::move(fd));
}
base::PlatformFile FileDescriptorInfoImpl::GetFDAt(size_t i) const {
@@ -48,24 +52,20 @@ bool FileDescriptorInfoImpl::HasID(int id) const {
}
bool FileDescriptorInfoImpl::OwnsFD(base::PlatformFile file) const {
- return owned_descriptors_.end() !=
- std::find_if(
- owned_descriptors_.begin(), owned_descriptors_.end(),
- [file](const base::ScopedFD* fd) { return fd->get() == file; });
+ return ContainsValue(owned_descriptors_, file);
}
base::ScopedFD FileDescriptorInfoImpl::ReleaseFD(base::PlatformFile file) {
DCHECK(OwnsFD(file));
base::ScopedFD fd;
- auto found = std::find_if(
- owned_descriptors_.begin(), owned_descriptors_.end(),
- [file](const base::ScopedFD* fd) { return fd->get() == file; });
+ auto found =
+ std::find(owned_descriptors_.begin(), owned_descriptors_.end(), file);
- (*found)->swap(fd);
+ std::swap(*found, fd);
owned_descriptors_.erase(found);
- return fd.Pass();
+ return fd;
}
void FileDescriptorInfoImpl::AddToMapping(int id, base::PlatformFile fd) {
diff --git a/chromium/content/browser/file_descriptor_info_impl.h b/chromium/content/browser/file_descriptor_info_impl.h
index 40db9593244..2195eb99eca 100644
--- a/chromium/content/browser/file_descriptor_info_impl.h
+++ b/chromium/content/browser/file_descriptor_info_impl.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_FILE_DESCRIPTOR_INFO_IMPL_H_
#define CONTENT_BROWSER_FILE_DESCRIPTOR_INFO_IMPL_H_
+#include <stddef.h>
+
+#include <vector>
+
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "content/common/content_export.h"
#include "content/public/browser/file_descriptor_info.h"
@@ -34,7 +37,7 @@ class FileDescriptorInfoImpl : public FileDescriptorInfo {
void AddToMapping(int id, base::PlatformFile fd);
bool HasID(int id) const;
base::FileHandleMappingVector mapping_;
- ScopedVector<base::ScopedFD> owned_descriptors_;
+ std::vector<base::ScopedFD> owned_descriptors_;
};
}
diff --git a/chromium/content/browser/file_descriptor_info_impl_unittest.cc b/chromium/content/browser/file_descriptor_info_impl_unittest.cc
index 9724a7cff64..c92200fbe09 100644
--- a/chromium/content/browser/file_descriptor_info_impl_unittest.cc
+++ b/chromium/content/browser/file_descriptor_info_impl_unittest.cc
@@ -6,8 +6,8 @@
#include <fcntl.h>
#include <unistd.h>
+#include <utility>
-#include "base/basictypes.h"
#include "base/posix/eintr_wrapper.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -43,7 +43,7 @@ TEST_F(FileDescriptorInfoTest, Transfer) {
base::ScopedFD fd(GetSafeFd());
int raw_fd = fd.get();
- target->Transfer(testingId, fd.Pass());
+ target->Transfer(testingId, std::move(fd));
ASSERT_EQ(1U, target->GetMappingSize());
ASSERT_EQ(target->GetFDAt(0), raw_fd);
ASSERT_EQ(target->GetIDAt(0), testingId);
diff --git a/chromium/content/browser/fileapi/blob_reader_unittest.cc b/chromium/content/browser/fileapi/blob_reader_unittest.cc
index a7e095c802a..d16b552d392 100644
--- a/chromium/content/browser/fileapi/blob_reader_unittest.cc
+++ b/chromium/content/browser/fileapi/blob_reader_unittest.cc
@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "storage/browser/blob/blob_reader.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
@@ -24,6 +28,7 @@
#include "net/disk_cache/disk_cache.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_handle.h"
+#include "storage/browser/blob/blob_reader.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/fileapi/file_stream_reader.h"
#include "storage/browser/fileapi/file_system_context.h"
@@ -55,7 +60,7 @@ class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle {
class DelayedReadEntry : public disk_cache::Entry {
public:
explicit DelayedReadEntry(disk_cache::ScopedEntryPtr entry)
- : entry_(entry.Pass()) {}
+ : entry_(std::move(entry)) {}
~DelayedReadEntry() override { EXPECT_FALSE(HasPendingReadCallbacks()); }
bool HasPendingReadCallbacks() { return !pending_read_callbacks_.empty(); }
@@ -80,7 +85,7 @@ class DelayedReadEntry : public disk_cache::Entry {
return entry_->GetLastModified();
}
- int32 GetDataSize(int index) const override {
+ int32_t GetDataSize(int index) const override {
return entry_->GetDataSize(index);
}
@@ -106,23 +111,23 @@ class DelayedReadEntry : public disk_cache::Entry {
return entry_->WriteData(index, offset, buf, buf_len, callback, truncate);
}
- int ReadSparseData(int64 offset,
+ int ReadSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override {
return entry_->ReadSparseData(offset, buf, buf_len, callback);
}
- int WriteSparseData(int64 offset,
+ int WriteSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override {
return entry_->WriteSparseData(offset, buf, buf_len, callback);
}
- int GetAvailableRange(int64 offset,
+ int GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) override {
return entry_->GetAvailableRange(offset, len, start, callback);
}
@@ -149,7 +154,7 @@ scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache(
thread, nullptr, &cache, callback.callback());
EXPECT_EQ(net::OK, callback.GetResult(rv));
- return cache.Pass();
+ return cache;
}
disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
@@ -166,7 +171,7 @@ disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
iobuffer->size(), callback.callback(), false);
EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
- return entry.Pass();
+ return entry;
}
template <typename T>
@@ -225,7 +230,8 @@ class FakeFileStreamReader : public FileStreamReader {
return net::ERR_IO_PENDING;
}
- int64 GetLength(const net::Int64CompletionCallback& size_callback) override {
+ int64_t GetLength(
+ const net::Int64CompletionCallback& size_callback) override {
// When async_task_runner_ is not set, return synchronously.
if (!async_task_runner_.get()) {
if (net_error_ == net::OK) {
@@ -319,10 +325,10 @@ class BlobReaderTest : public ::testing::Test {
protected:
void InitializeReader(BlobDataBuilder* builder) {
- blob_handle_ = builder ? context_.AddFinishedBlob(builder).Pass() : nullptr;
+ blob_handle_ = builder ? context_.AddFinishedBlob(builder) : nullptr;
provider_ = new MockFileStreamReaderProvider();
scoped_ptr<BlobReader::FileStreamReaderProvider> temp_ptr(provider_);
- reader_.reset(new BlobReader(blob_handle_.get(), temp_ptr.Pass(),
+ reader_.reset(new BlobReader(blob_handle_.get(), std::move(temp_ptr),
message_loop_.task_runner().get()));
}
@@ -723,7 +729,7 @@ TEST_F(BlobReaderTest, DiskCacheAsync) {
scoped_refptr<BlobDataBuilder::DataHandle> data_handle =
new EmptyDataHandle();
scoped_ptr<DelayedReadEntry> delayed_read_entry(new DelayedReadEntry(
- CreateDiskCacheEntry(cache.get(), "test entry", kData).Pass()));
+ CreateDiskCacheEntry(cache.get(), "test entry", kData)));
b.AppendDiskCacheEntry(data_handle, delayed_read_entry.get(),
kTestDiskCacheStreamIndex);
this->InitializeReader(&b);
@@ -828,7 +834,7 @@ TEST_F(BlobReaderTest, DiskCacheRange) {
TEST_F(BlobReaderTest, FileSomeAsyncSegmentedOffsetsUnknownSizes) {
// This tests includes:
- // * Unknown file sizes (item length of uint64::max) for every other item.
+ // * Unknown file sizes (item length of uint64_t::max) for every other item.
// * Offsets for every 3rd file item.
// * Non-async reader for every 4th file item.
BlobDataBuilder b("uuid");
diff --git a/chromium/content/browser/fileapi/blob_storage_context_unittest.cc b/chromium/content/browser/fileapi/blob_storage_context_unittest.cc
index 5ae280e444e..72df9841708 100644
--- a/chromium/content/browser/fileapi/blob_storage_context_unittest.cc
+++ b/chromium/content/browser/fileapi/blob_storage_context_unittest.cc
@@ -4,6 +4,8 @@
#include "storage/browser/blob/blob_storage_context.h"
+#include <stdint.h>
+
#include <limits>
#include <string>
@@ -52,7 +54,7 @@ scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache() {
callback.callback());
EXPECT_EQ(net::OK, callback.GetResult(rv));
- return cache.Pass();
+ return cache;
}
disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
@@ -69,7 +71,7 @@ disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
iobuffer->size(), callback.callback(), false);
EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
- return entry.Pass();
+ return entry;
}
void SetupBasicBlob(BlobStorageHost* host, const std::string& id) {
diff --git a/chromium/content/browser/fileapi/blob_storage_host.h b/chromium/content/browser/fileapi/blob_storage_host.h
index dc277ae5acc..ecfbc569262 100644
--- a/chromium/content/browser/fileapi/blob_storage_host.h
+++ b/chromium/content/browser/fileapi/blob_storage_host.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "storage/common/data_element.h"
diff --git a/chromium/content/browser/fileapi/blob_url_request_job_unittest.cc b/chromium/content/browser/fileapi/blob_url_request_job_unittest.cc
index 96becf0de09..782a1e581db 100644
--- a/chromium/content/browser/fileapi/blob_url_request_job_unittest.cc
+++ b/chromium/content/browser/fileapi/blob_url_request_job_unittest.cc
@@ -2,7 +2,10 @@
// 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 <stdint.h>
+
+#include <limits>
+
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -80,7 +83,7 @@ scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache() {
callback.callback());
EXPECT_EQ(net::OK, callback.GetResult(rv));
- return cache.Pass();
+ return cache;
}
disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
@@ -97,7 +100,7 @@ disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
iobuffer->size(), callback.callback(), false);
EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
- return entry.Pass();
+ return entry;
}
} // namespace
@@ -224,7 +227,7 @@ class BlobURLRequestJobTest : public testing::Test {
}
void TestSuccessNonrangeRequest(const std::string& expected_response,
- int64 expected_content_length) {
+ int64_t expected_content_length) {
expected_status_code_ = 200;
expected_response_ = expected_response;
TestRequest("GET", net::HttpRequestHeaders());
@@ -285,21 +288,21 @@ class BlobURLRequestJobTest : public testing::Test {
storage::BlobDataHandle* GetHandleFromBuilder() {
if (!blob_handle_) {
- blob_handle_ = blob_context_.AddFinishedBlob(blob_data_.get()).Pass();
+ blob_handle_ = blob_context_.AddFinishedBlob(blob_data_.get());
}
return blob_handle_.get();
}
// This only works if all the Blob items have a definite pre-computed length.
// Otherwise, this will fail a CHECK.
- int64 GetTotalBlobLength() {
- int64 total = 0;
+ int64_t GetTotalBlobLength() {
+ int64_t total = 0;
scoped_ptr<BlobDataSnapshot> data =
GetHandleFromBuilder()->CreateSnapshot();
const auto& items = data->items();
for (const auto& item : items) {
- int64 length = base::checked_cast<int64>(item->length());
- CHECK(length <= kint64max - total);
+ int64_t length = base::checked_cast<int64_t>(item->length());
+ CHECK(length <= std::numeric_limits<int64_t>::max() - total);
total += length;
}
return total;
@@ -342,7 +345,8 @@ TEST_F(BlobURLRequestJobTest, TestGetSimpleDataRequest) {
}
TEST_F(BlobURLRequestJobTest, TestGetSimpleFileRequest) {
- blob_data_->AppendFile(temp_file1_, 0, kuint64max, base::Time());
+ blob_data_->AppendFile(temp_file1_, 0, std::numeric_limits<uint64_t>::max(),
+ base::Time());
TestSuccessNonrangeRequest(kTestFileData1, arraysize(kTestFileData1) - 1);
}
@@ -356,14 +360,16 @@ TEST_F(BlobURLRequestJobTest, TestGetLargeFileRequest) {
ASSERT_EQ(static_cast<int>(large_data.size()),
base::WriteFile(large_temp_file, large_data.data(),
large_data.size()));
- blob_data_->AppendFile(large_temp_file, 0, kuint64max, base::Time());
+ blob_data_->AppendFile(large_temp_file, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time());
TestSuccessNonrangeRequest(large_data, large_data.size());
}
TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileRequest) {
base::FilePath non_existent_file =
temp_file1_.InsertBeforeExtension(FILE_PATH_LITERAL("-na"));
- blob_data_->AppendFile(non_existent_file, 0, kuint64max, base::Time());
+ blob_data_->AppendFile(non_existent_file, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time());
TestErrorRequest(404);
}
@@ -382,7 +388,8 @@ TEST_F(BlobURLRequestJobTest, TestGetSlicedFileRequest) {
TEST_F(BlobURLRequestJobTest, TestGetSimpleFileSystemFileRequest) {
SetUpFileSystem();
- blob_data_->AppendFileSystemFile(temp_file_system_file1_, 0, kuint64max,
+ blob_data_->AppendFileSystemFile(temp_file_system_file1_, 0,
+ std::numeric_limits<uint64_t>::max(),
base::Time());
TestSuccessNonrangeRequest(kTestFileSystemFileData1,
arraysize(kTestFileSystemFileData1) - 1);
@@ -398,7 +405,8 @@ TEST_F(BlobURLRequestJobTest, TestGetLargeFileSystemFileRequest) {
const char kFilename[] = "LargeBlob.dat";
WriteFileSystemFile(kFilename, large_data.data(), large_data.size(), NULL);
- blob_data_->AppendFileSystemFile(GetFileSystemURL(kFilename), 0, kuint64max,
+ blob_data_->AppendFileSystemFile(GetFileSystemURL(kFilename), 0,
+ std::numeric_limits<uint64_t>::max(),
base::Time());
TestSuccessNonrangeRequest(large_data, large_data.size());
}
@@ -406,15 +414,16 @@ TEST_F(BlobURLRequestJobTest, TestGetLargeFileSystemFileRequest) {
TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileSystemFileRequest) {
SetUpFileSystem();
GURL non_existent_file = GetFileSystemURL("non-existent.dat");
- blob_data_->AppendFileSystemFile(non_existent_file, 0, kuint64max,
- base::Time());
+ blob_data_->AppendFileSystemFile(
+ non_existent_file, 0, std::numeric_limits<uint64_t>::max(), base::Time());
TestErrorRequest(404);
}
TEST_F(BlobURLRequestJobTest, TestGetInvalidFileSystemFileRequest) {
SetUpFileSystem();
GURL invalid_file;
- blob_data_->AppendFileSystemFile(invalid_file, 0, kuint64max, base::Time());
+ blob_data_->AppendFileSystemFile(
+ invalid_file, 0, std::numeric_limits<uint64_t>::max(), base::Time());
TestErrorRequest(500);
}
@@ -463,7 +472,7 @@ TEST_F(BlobURLRequestJobTest, TestGetRangeRequest1) {
EXPECT_EQ(6, request_->response_headers()->GetContentLength());
- int64 first = 0, last = 0, length = 0;
+ int64_t first = 0, last = 0, length = 0;
EXPECT_TRUE(
request_->response_headers()->GetContentRange(&first, &last, &length));
EXPECT_EQ(5, first);
@@ -484,8 +493,8 @@ TEST_F(BlobURLRequestJobTest, TestGetRangeRequest2) {
EXPECT_EQ(10, request_->response_headers()->GetContentLength());
- int64 total = GetTotalBlobLength();
- int64 first = 0, last = 0, length = 0;
+ int64_t total = GetTotalBlobLength();
+ int64_t first = 0, last = 0, length = 0;
EXPECT_TRUE(
request_->response_headers()->GetContentRange(&first, &last, &length));
EXPECT_EQ(total - 10, first);
@@ -506,7 +515,7 @@ TEST_F(BlobURLRequestJobTest, TestGetRangeRequest3) {
EXPECT_EQ(3, request_->response_headers()->GetContentLength());
- int64 first = 0, last = 0, length = 0;
+ int64_t first = 0, last = 0, length = 0;
EXPECT_TRUE(
request_->response_headers()->GetContentRange(&first, &last, &length));
EXPECT_EQ(0, first);
diff --git a/chromium/content/browser/fileapi/browser_file_system_helper.cc b/chromium/content/browser/fileapi/browser_file_system_helper.cc
index 4ab06e61754..64402cd54e3 100644
--- a/chromium/content/browser/fileapi/browser_file_system_helper.cc
+++ b/chromium/content/browser/fileapi/browser_file_system_helper.cc
@@ -4,7 +4,9 @@
#include "content/browser/fileapi/browser_file_system_helper.h"
+#include <stddef.h>
#include <string>
+#include <utility>
#include <vector>
#include "base/command_line.h"
@@ -77,12 +79,9 @@ scoped_refptr<storage::FileSystemContext> CreateFileSystemContext(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
file_task_runner.get(),
BrowserContext::GetMountPoints(browser_context),
- browser_context->GetSpecialStoragePolicy(),
- quota_manager_proxy,
- additional_backends.Pass(),
- url_request_auto_mount_handlers,
- profile_path,
- CreateBrowserFileSystemOptions(is_incognito));
+ browser_context->GetSpecialStoragePolicy(), quota_manager_proxy,
+ std::move(additional_backends), url_request_auto_mount_handlers,
+ profile_path, CreateBrowserFileSystemOptions(is_incognito));
std::vector<storage::FileSystemType> types;
file_system_context->GetFileSystemTypes(&types);
diff --git a/chromium/content/browser/fileapi/chrome_blob_storage_context.cc b/chromium/content/browser/fileapi/chrome_blob_storage_context.cc
index 5e2c4c83d1d..8b9ed718098 100644
--- a/chromium/content/browser/fileapi/chrome_blob_storage_context.cc
+++ b/chromium/content/browser/fileapi/chrome_blob_storage_context.cc
@@ -4,6 +4,8 @@
#include "content/browser/fileapi/chrome_blob_storage_context.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/guid.h"
#include "content/public/browser/blob_handle.h"
@@ -25,7 +27,7 @@ const char kBlobStorageContextKeyName[] = "content_blob_storage_context";
class BlobHandleImpl : public BlobHandle {
public:
explicit BlobHandleImpl(scoped_ptr<storage::BlobDataHandle> handle)
- : handle_(handle.Pass()) {}
+ : handle_(std::move(handle)) {}
~BlobHandleImpl() override {}
@@ -78,8 +80,8 @@ scoped_ptr<BlobHandle> ChromeBlobStorageContext::CreateMemoryBackedBlob(
return scoped_ptr<BlobHandle>();
scoped_ptr<BlobHandle> blob_handle(
- new BlobHandleImpl(blob_data_handle.Pass()));
- return blob_handle.Pass();
+ new BlobHandleImpl(std::move(blob_data_handle)));
+ return blob_handle;
}
scoped_ptr<BlobHandle> ChromeBlobStorageContext::CreateFileBackedBlob(
@@ -99,8 +101,8 @@ scoped_ptr<BlobHandle> ChromeBlobStorageContext::CreateFileBackedBlob(
return scoped_ptr<BlobHandle>();
scoped_ptr<BlobHandle> blob_handle(
- new BlobHandleImpl(blob_data_handle.Pass()));
- return blob_handle.Pass();
+ new BlobHandleImpl(std::move(blob_data_handle)));
+ return blob_handle;
}
ChromeBlobStorageContext::~ChromeBlobStorageContext() {}
diff --git a/chromium/content/browser/fileapi/chrome_blob_storage_context.h b/chromium/content/browser/fileapi/chrome_blob_storage_context.h
index 0c565459a2c..8dd1eec75e0 100644
--- a/chromium/content/browser/fileapi/chrome_blob_storage_context.h
+++ b/chromium/content/browser/fileapi/chrome_blob_storage_context.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_FILEAPI_CHROME_BLOB_STORAGE_CONTEXT_H_
#define CONTENT_BROWSER_FILEAPI_CHROME_BLOB_STORAGE_CONTEXT_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/sequenced_task_runner_helpers.h"
diff --git a/chromium/content/browser/fileapi/copy_or_move_file_validator_unittest.cc b/chromium/content/browser/fileapi/copy_or_move_file_validator_unittest.cc
index c07db9db006..2b62b5351c8 100644
--- a/chromium/content/browser/fileapi/copy_or_move_file_validator_unittest.cc
+++ b/chromium/content/browser/fileapi/copy_or_move_file_validator_unittest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -99,7 +103,7 @@ class CopyOrMoveFileValidatorTestHelper {
scoped_ptr<storage::CopyOrMoveFileValidatorFactory> factory) {
TestFileSystemBackend* backend = static_cast<TestFileSystemBackend*>(
file_system_context_->GetFileSystemBackend(kWithValidatorType));
- backend->InitializeCopyOrMoveFileValidatorFactory(factory.Pass());
+ backend->InitializeCopyOrMoveFileValidatorFactory(std::move(factory));
}
void CopyTest(base::File::Error expected) {
@@ -161,7 +165,7 @@ class CopyOrMoveFileValidatorTestHelper {
url);
}
- bool FileExists(const FileSystemURL& url, int64 expected_size) {
+ bool FileExists(const FileSystemURL& url, int64_t expected_size) {
return AsyncFileTestHelper::FileExists(
file_system_context_.get(), url, expected_size);
}
@@ -279,7 +283,7 @@ TEST(CopyOrMoveFileValidatorTest, AcceptAll) {
helper.SetUp();
scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
new TestCopyOrMoveFileValidatorFactory(VALID));
- helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
+ helper.SetMediaCopyOrMoveFileValidatorFactory(std::move(factory));
helper.CopyTest(base::File::FILE_OK);
helper.MoveTest(base::File::FILE_OK);
@@ -292,7 +296,7 @@ TEST(CopyOrMoveFileValidatorTest, AcceptNone) {
helper.SetUp();
scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
- helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
+ helper.SetMediaCopyOrMoveFileValidatorFactory(std::move(factory));
helper.CopyTest(base::File::FILE_ERROR_SECURITY);
helper.MoveTest(base::File::FILE_ERROR_SECURITY);
@@ -306,11 +310,11 @@ TEST(CopyOrMoveFileValidatorTest, OverrideValidator) {
helper.SetUp();
scoped_ptr<CopyOrMoveFileValidatorFactory> reject_factory(
new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
- helper.SetMediaCopyOrMoveFileValidatorFactory(reject_factory.Pass());
+ helper.SetMediaCopyOrMoveFileValidatorFactory(std::move(reject_factory));
scoped_ptr<CopyOrMoveFileValidatorFactory> accept_factory(
new TestCopyOrMoveFileValidatorFactory(VALID));
- helper.SetMediaCopyOrMoveFileValidatorFactory(accept_factory.Pass());
+ helper.SetMediaCopyOrMoveFileValidatorFactory(std::move(accept_factory));
helper.CopyTest(base::File::FILE_ERROR_SECURITY);
helper.MoveTest(base::File::FILE_ERROR_SECURITY);
@@ -323,7 +327,7 @@ TEST(CopyOrMoveFileValidatorTest, RejectPostWrite) {
helper.SetUp();
scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
new TestCopyOrMoveFileValidatorFactory(POST_WRITE_INVALID));
- helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
+ helper.SetMediaCopyOrMoveFileValidatorFactory(std::move(factory));
helper.CopyTest(base::File::FILE_ERROR_SECURITY);
helper.MoveTest(base::File::FILE_ERROR_SECURITY);
diff --git a/chromium/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc b/chromium/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
index bbcae168c8a..055b8f2c97f 100644
--- a/chromium/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
+++ b/chromium/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
@@ -2,14 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
#include <map>
#include <queue>
+#include <utility>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -112,14 +115,14 @@ struct ProgressRecord {
storage::FileSystemOperation::CopyProgressType type;
FileSystemURL source_url;
FileSystemURL dest_url;
- int64 size;
+ int64_t size;
};
void RecordProgressCallback(std::vector<ProgressRecord>* records,
storage::FileSystemOperation::CopyProgressType type,
const FileSystemURL& source_url,
const FileSystemURL& dest_url,
- int64 size) {
+ int64_t size) {
ProgressRecord record;
record.type = type;
record.source_url = source_url;
@@ -128,8 +131,8 @@ void RecordProgressCallback(std::vector<ProgressRecord>* records,
records->push_back(record);
}
-void RecordFileProgressCallback(std::vector<int64>* records,
- int64 progress) {
+void RecordFileProgressCallback(std::vector<int64_t>* records,
+ int64_t progress) {
records->push_back(progress);
}
@@ -218,7 +221,8 @@ class CopyOrMoveOperationTestHelper {
test_backend->set_require_copy_or_move_validator(
require_copy_or_move_validator);
if (init_copy_or_move_validator)
- test_backend->InitializeCopyOrMoveFileValidatorFactory(factory.Pass());
+ test_backend->InitializeCopyOrMoveFileValidatorFactory(
+ std::move(factory));
}
backend->ResolveURL(
FileSystemURL::CreateForTest(origin_, dest_type_, base::FilePath()),
@@ -237,14 +241,14 @@ class CopyOrMoveOperationTestHelper {
1024 * 1024);
}
- int64 GetSourceUsage() {
- int64 usage = 0;
+ int64_t GetSourceUsage() {
+ int64_t usage = 0;
GetUsageAndQuota(src_type_, &usage, NULL);
return usage;
}
- int64 GetDestUsage() {
- int64 usage = 0;
+ int64_t GetDestUsage() {
+ int64_t usage = 0;
GetUsageAndQuota(dest_type_, &usage, NULL);
return usage;
}
@@ -364,7 +368,7 @@ class CopyOrMoveOperationTestHelper {
file_system_context_.get(), url, size);
}
- bool FileExists(const FileSystemURL& url, int64 expected_size) {
+ bool FileExists(const FileSystemURL& url, int64_t expected_size) {
return AsyncFileTestHelper::FileExists(
file_system_context_.get(), url, expected_size);
}
@@ -376,8 +380,8 @@ class CopyOrMoveOperationTestHelper {
private:
void GetUsageAndQuota(storage::FileSystemType type,
- int64* usage,
- int64* quota) {
+ int64_t* usage,
+ int64_t* quota) {
storage::QuotaStatusCode status = AsyncFileTestHelper::GetUsageAndQuota(
quota_manager_.get(), origin_, type, usage, quota);
ASSERT_EQ(storage::kQuotaStatusOk, status);
@@ -406,12 +410,12 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFile) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
- int64 src_initial_usage = helper.GetSourceUsage();
- int64 dest_initial_usage = helper.GetDestUsage();
+ int64_t src_initial_usage = helper.GetSourceUsage();
+ int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source file.
ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
- int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
+ int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
// Copy it.
ASSERT_EQ(base::File::FILE_OK, helper.Copy(src, dest));
@@ -420,10 +424,10 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFile) {
ASSERT_TRUE(helper.FileExists(src, 10));
ASSERT_TRUE(helper.FileExists(dest, 10));
- int64 src_new_usage = helper.GetSourceUsage();
+ int64_t src_new_usage = helper.GetSourceUsage();
ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
- int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
+ int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
ASSERT_EQ(src_increase, dest_increase);
}
@@ -435,12 +439,12 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleFile) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
- int64 src_initial_usage = helper.GetSourceUsage();
- int64 dest_initial_usage = helper.GetDestUsage();
+ int64_t src_initial_usage = helper.GetSourceUsage();
+ int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source file.
ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
- int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
+ int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
// Move it.
ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
@@ -449,10 +453,10 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleFile) {
ASSERT_FALSE(helper.FileExists(src, AsyncFileTestHelper::kDontCheckSize));
ASSERT_TRUE(helper.FileExists(dest, 10));
- int64 src_new_usage = helper.GetSourceUsage();
+ int64_t src_new_usage = helper.GetSourceUsage();
ASSERT_EQ(src_initial_usage, src_new_usage);
- int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
+ int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
ASSERT_EQ(src_increase, dest_increase);
}
@@ -464,12 +468,12 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleDirectory) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
- int64 src_initial_usage = helper.GetSourceUsage();
- int64 dest_initial_usage = helper.GetDestUsage();
+ int64_t src_initial_usage = helper.GetSourceUsage();
+ int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source directory.
ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
- int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
+ int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
// Copy it.
ASSERT_EQ(base::File::FILE_OK, helper.Copy(src, dest));
@@ -478,10 +482,10 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleDirectory) {
ASSERT_TRUE(helper.DirectoryExists(src));
ASSERT_TRUE(helper.DirectoryExists(dest));
- int64 src_new_usage = helper.GetSourceUsage();
+ int64_t src_new_usage = helper.GetSourceUsage();
ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
- int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
+ int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
ASSERT_EQ(src_increase, dest_increase);
}
@@ -493,12 +497,12 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleDirectory) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
- int64 src_initial_usage = helper.GetSourceUsage();
- int64 dest_initial_usage = helper.GetDestUsage();
+ int64_t src_initial_usage = helper.GetSourceUsage();
+ int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source directory.
ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
- int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
+ int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
// Move it.
ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
@@ -507,10 +511,10 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleDirectory) {
ASSERT_FALSE(helper.DirectoryExists(src));
ASSERT_TRUE(helper.DirectoryExists(dest));
- int64 src_new_usage = helper.GetSourceUsage();
+ int64_t src_new_usage = helper.GetSourceUsage();
ASSERT_EQ(src_initial_usage, src_new_usage);
- int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
+ int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
ASSERT_EQ(src_increase, dest_increase);
}
@@ -522,8 +526,8 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
- int64 src_initial_usage = helper.GetSourceUsage();
- int64 dest_initial_usage = helper.GetDestUsage();
+ int64_t src_initial_usage = helper.GetSourceUsage();
+ int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source directory.
ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
@@ -531,7 +535,7 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) {
helper.SetUpTestCaseFiles(src,
kRegularFileSystemTestCases,
kRegularFileSystemTestCaseSize));
- int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
+ int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
// Copy it.
ASSERT_EQ(base::File::FILE_OK,
@@ -547,10 +551,10 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) {
kRegularFileSystemTestCases,
kRegularFileSystemTestCaseSize);
- int64 src_new_usage = helper.GetSourceUsage();
+ int64_t src_new_usage = helper.GetSourceUsage();
ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
- int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
+ int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
ASSERT_EQ(src_increase, dest_increase);
}
@@ -562,8 +566,8 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveDirectory) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
- int64 src_initial_usage = helper.GetSourceUsage();
- int64 dest_initial_usage = helper.GetDestUsage();
+ int64_t src_initial_usage = helper.GetSourceUsage();
+ int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source directory.
ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
@@ -571,7 +575,7 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveDirectory) {
helper.SetUpTestCaseFiles(src,
kRegularFileSystemTestCases,
kRegularFileSystemTestCaseSize));
- int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
+ int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
// Move it.
ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
@@ -584,10 +588,10 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveDirectory) {
kRegularFileSystemTestCases,
kRegularFileSystemTestCaseSize);
- int64 src_new_usage = helper.GetSourceUsage();
+ int64_t src_new_usage = helper.GetSourceUsage();
ASSERT_EQ(src_initial_usage, src_new_usage);
- int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
+ int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
ASSERT_EQ(src_increase, dest_increase);
}
@@ -701,7 +705,7 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, ProgressCallback) {
EXPECT_EQ(begin_index + 1, end_index);
} else {
// PROGRESS event's size should be assending order.
- int64 current_size = 0;
+ int64_t current_size = 0;
for (size_t j = begin_index + 1; j < end_index; ++j) {
if (records[j].source_url == src_url) {
EXPECT_EQ(FileSystemOperation::PROGRESS, records[j].type);
@@ -739,9 +743,9 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelper) {
scoped_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
- std::vector<int64> progress;
+ std::vector<int64_t> progress;
CopyOrMoveOperationDelegate::StreamCopyHelper helper(
- reader.Pass(), writer.Pass(),
+ std::move(reader), std::move(writer),
storage::FlushPolicy::NO_FLUSH_ON_COMPLETION,
10, // buffer size
base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
@@ -795,9 +799,9 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelperWithFlush) {
scoped_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
- std::vector<int64> progress;
+ std::vector<int64_t> progress;
CopyOrMoveOperationDelegate::StreamCopyHelper helper(
- reader.Pass(), writer.Pass(),
+ std::move(reader), std::move(writer),
storage::FlushPolicy::NO_FLUSH_ON_COMPLETION,
10, // buffer size
base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
@@ -846,9 +850,9 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelper_Cancel) {
scoped_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
- std::vector<int64> progress;
+ std::vector<int64_t> progress;
CopyOrMoveOperationDelegate::StreamCopyHelper helper(
- reader.Pass(), writer.Pass(),
+ std::move(reader), std::move(writer),
storage::FlushPolicy::NO_FLUSH_ON_COMPLETION,
10, // buffer size
base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
diff --git a/chromium/content/browser/fileapi/dragged_file_util_unittest.cc b/chromium/content/browser/fileapi/dragged_file_util_unittest.cc
index 38d83374baa..07c983bad4a 100644
--- a/chromium/content/browser/fileapi/dragged_file_util_unittest.cc
+++ b/chromium/content/browser/fileapi/dragged_file_util_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <map>
#include <queue>
#include <set>
@@ -12,8 +14,10 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/public/test/async_file_test_helper.h"
#include "content/public/test/test_file_system_context.h"
#include "content/test/fileapi_test_file_set.h"
@@ -247,8 +251,8 @@ class DraggedFileUtilTest : public testing::Test {
}
scoped_ptr<storage::FileSystemOperationContext> GetOperationContext() {
- return make_scoped_ptr(new storage::FileSystemOperationContext(
- file_system_context())).Pass();
+ return make_scoped_ptr(
+ new storage::FileSystemOperationContext(file_system_context()));
}
@@ -374,8 +378,6 @@ TEST_F(DraggedFileUtilTest, ReadDirectoryTest) {
storage::DirectoryEntry entry;
entry.is_directory = file_info.IsDirectory();
entry.name = current.BaseName().value();
- entry.size = file_info.GetSize();
- entry.last_modified_time = file_info.GetLastModifiedTime();
expected_entry_map[entry.name] = entry;
#if defined(OS_POSIX)
@@ -403,9 +405,6 @@ TEST_F(DraggedFileUtilTest, ReadDirectoryTest) {
EXPECT_TRUE(found != expected_entry_map.end());
EXPECT_EQ(found->second.name, entry.name);
EXPECT_EQ(found->second.is_directory, entry.is_directory);
- EXPECT_EQ(found->second.size, entry.size);
- EXPECT_EQ(found->second.last_modified_time.ToDoubleT(),
- entry.last_modified_time.ToDoubleT());
}
}
}
diff --git a/chromium/content/browser/fileapi/external_mount_points_unittest.cc b/chromium/content/browser/fileapi/external_mount_points_unittest.cc
index 02103da2a94..59be8624c40 100644
--- a/chromium/content/browser/fileapi/external_mount_points_unittest.cc
+++ b/chromium/content/browser/fileapi/external_mount_points_unittest.cc
@@ -4,9 +4,12 @@
#include "storage/browser/fileapi/external_mount_points.h"
+#include <stddef.h>
+
#include <string>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/common/fileapi/file_system_mount_option.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/browser/fileapi/file_system_browsertest.cc b/chromium/content/browser/fileapi/file_system_browsertest.cc
index 5ff96006abc..5c60c28f3a8 100644
--- a/chromium/content/browser/fileapi/file_system_browsertest.cc
+++ b/chromium/content/browser/fileapi/file_system_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
@@ -63,7 +65,7 @@ class FileSystemBrowserTestWithLowQuota : public FileSystemBrowserTest {
shell()->web_contents()->GetBrowserContext())->GetQuotaManager());
}
- static void SetTempQuota(int64 bytes, scoped_refptr<QuotaManager> qm) {
+ static void SetTempQuota(int64_t bytes, scoped_refptr<QuotaManager> qm) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
diff --git a/chromium/content/browser/fileapi/file_system_context_unittest.cc b/chromium/content/browser/fileapi/file_system_context_unittest.cc
index b1ffb6359d0..f5ed8982a7a 100644
--- a/chromium/content/browser/fileapi/file_system_context_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_context_unittest.cc
@@ -4,9 +4,13 @@
#include "storage/browser/fileapi/file_system_context.h"
+#include <stddef.h>
+
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/quota/mock_quota_manager.h"
#include "content/public/test/mock_special_storage_policy.h"
#include "content/public/test/test_file_system_options.h"
diff --git a/chromium/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc b/chromium/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc
index 754f323ba1b..15f376ce44b 100644
--- a/chromium/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "storage/browser/fileapi/file_system_dir_url_request_job.h"
-
+#include <stdint.h>
#include <string>
+#include <utility>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -17,6 +17,7 @@
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/public/test/mock_special_storage_policy.h"
#include "content/public/test/test_file_system_backend.h"
#include "content/public/test/test_file_system_context.h"
@@ -29,6 +30,7 @@
#include "net/url_request/url_request_test_util.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/file_system_context.h"
+#include "storage/browser/fileapi/file_system_dir_url_request_job.h"
#include "storage/browser/fileapi/file_system_file_util.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_url.h"
@@ -161,7 +163,7 @@ class FileSystemDirURLRequestJobTest : public testing::Test {
handlers.push_back(base::Bind(&TestAutoMountForURLRequest));
file_system_context_ = CreateFileSystemContextWithAutoMountersForTesting(
- NULL, additional_providers.Pass(), handlers, temp_dir_.path());
+ NULL, std::move(additional_providers), handlers, temp_dir_.path());
}
void OnOpenFileSystem(const GURL& root_url,
@@ -228,7 +230,7 @@ class FileSystemDirURLRequestJobTest : public testing::Test {
context.get(), CreateURL(path), NULL));
}
- void TruncateFile(const base::StringPiece file_name, int64 length) {
+ void TruncateFile(const base::StringPiece file_name, int64_t length) {
base::FilePath path = base::FilePath().AppendASCII(file_name);
scoped_ptr<FileSystemOperationContext> context(NewOperationContext());
ASSERT_EQ(base::File::FILE_OK, file_util()->Truncate(
@@ -249,7 +251,7 @@ class FileSystemDirURLRequestJobTest : public testing::Test {
const std::string& name,
const std::string& url,
bool is_directory,
- int64 size) {
+ int64_t size) {
#define STR "([^\"]*)"
icu::UnicodeString pattern("^<script>addRow\\(\"" STR "\",\"" STR
"\",(0|1),\"" STR "\",\"" STR "\"\\);</script>");
diff --git a/chromium/content/browser/fileapi/file_system_file_stream_reader_unittest.cc b/chromium/content/browser/fileapi/file_system_file_stream_reader_unittest.cc
index 5e13f15c288..acb36500edb 100644
--- a/chromium/content/browser/fileapi/file_system_file_stream_reader_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_file_stream_reader_unittest.cc
@@ -4,10 +4,14 @@
#include "storage/browser/fileapi/file_system_file_stream_reader.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <limits>
#include <string>
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "content/public/test/async_file_test_helper.h"
@@ -89,7 +93,7 @@ class FileSystemFileStreamReaderTest : public testing::Test {
protected:
storage::FileSystemFileStreamReader* CreateFileReader(
const std::string& file_name,
- int64 initial_offset,
+ int64_t initial_offset,
const base::Time& expected_modification_time) {
return new FileSystemFileStreamReader(file_system_context_.get(),
GetFileSystemURL(file_name),
@@ -163,7 +167,7 @@ TEST_F(FileSystemFileStreamReaderTest, Empty) {
ASSERT_EQ(0U, data.size());
net::TestInt64CompletionCallback callback;
- int64 length_result = reader->GetLength(callback.callback());
+ int64_t length_result = reader->GetLength(callback.callback());
if (length_result == net::ERR_IO_PENDING)
length_result = callback.WaitForResult();
ASSERT_EQ(0, length_result);
@@ -173,7 +177,7 @@ TEST_F(FileSystemFileStreamReaderTest, GetLengthNormal) {
scoped_ptr<FileSystemFileStreamReader> reader(
CreateFileReader(kTestFileName, 0, test_file_modification_time()));
net::TestInt64CompletionCallback callback;
- int64 result = reader->GetLength(callback.callback());
+ int64_t result = reader->GetLength(callback.callback());
if (result == net::ERR_IO_PENDING)
result = callback.WaitForResult();
ASSERT_EQ(kTestDataSize, result);
@@ -187,7 +191,7 @@ TEST_F(FileSystemFileStreamReaderTest, GetLengthAfterModified) {
scoped_ptr<FileSystemFileStreamReader> reader(
CreateFileReader(kTestFileName, 0, fake_expected_modification_time));
net::TestInt64CompletionCallback callback;
- int64 result = reader->GetLength(callback.callback());
+ int64_t result = reader->GetLength(callback.callback());
if (result == net::ERR_IO_PENDING)
result = callback.WaitForResult();
ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
@@ -204,7 +208,7 @@ TEST_F(FileSystemFileStreamReaderTest, GetLengthWithOffset) {
scoped_ptr<FileSystemFileStreamReader> reader(
CreateFileReader(kTestFileName, 3, base::Time()));
net::TestInt64CompletionCallback callback;
- int64 result = reader->GetLength(callback.callback());
+ int64_t result = reader->GetLength(callback.callback());
if (result == net::ERR_IO_PENDING)
result = callback.WaitForResult();
// Initial offset does not affect the result of GetLength.
diff --git a/chromium/content/browser/fileapi/file_system_operation_impl_unittest.cc b/chromium/content/browser/fileapi/file_system_operation_impl_unittest.cc
index b000da2d1e7..66891d1c22a 100644
--- a/chromium/content/browser/fileapi/file_system_operation_impl_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_operation_impl_unittest.cc
@@ -4,10 +4,14 @@
#include "storage/browser/fileapi/file_system_operation_impl.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
@@ -155,7 +159,7 @@ class FileSystemOperationImplTest
return url;
}
- int64 GetFileSize(const std::string& path) {
+ int64_t GetFileSize(const std::string& path) {
base::File::Info info;
EXPECT_TRUE(base::GetFileInfo(PlatformPath(path), &info));
return info.size;
@@ -238,12 +242,12 @@ class FileSystemOperationImplTest
closure.Run();
}
- int64 GetDataSizeOnDisk() {
+ int64_t GetDataSizeOnDisk() {
return sandbox_file_system_.ComputeCurrentOriginUsage() -
sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
}
- void GetUsageAndQuota(int64* usage, int64* quota) {
+ void GetUsageAndQuota(int64_t* usage, int64_t* quota) {
storage::QuotaStatusCode status =
AsyncFileTestHelper::GetUsageAndQuota(quota_manager_.get(),
sandbox_file_system_.origin(),
@@ -254,8 +258,8 @@ class FileSystemOperationImplTest
ASSERT_EQ(storage::kQuotaStatusOk, status);
}
- int64 ComputePathCost(const FileSystemURL& url) {
- int64 base_usage;
+ int64_t ComputePathCost(const FileSystemURL& url) {
+ int64_t base_usage;
GetUsageAndQuota(&base_usage, NULL);
AsyncFileTestHelper::CreateFile(
@@ -264,27 +268,27 @@ class FileSystemOperationImplTest
change_observer()->ResetCount();
- int64 total_usage;
+ int64_t total_usage;
GetUsageAndQuota(&total_usage, NULL);
return total_usage - base_usage;
}
void GrantQuotaForCurrentUsage() {
- int64 usage;
+ int64_t usage;
GetUsageAndQuota(&usage, NULL);
quota_manager()->SetQuota(sandbox_file_system_.origin(),
sandbox_file_system_.storage_type(),
usage);
}
- int64 GetUsage() {
- int64 usage = 0;
+ int64_t GetUsage() {
+ int64_t usage = 0;
GetUsageAndQuota(&usage, NULL);
return usage;
}
- void AddQuota(int64 quota_delta) {
- int64 quota;
+ void AddQuota(int64_t quota_delta) {
+ int64_t quota;
GetUsageAndQuota(NULL, &quota);
quota_manager()->SetQuota(sandbox_file_system_.origin(),
sandbox_file_system_.storage_type(),
@@ -385,12 +389,12 @@ class FileSystemOperationImplTest
return status;
}
- base::File::Error GetMetadata(const FileSystemURL& url) {
+ base::File::Error GetMetadata(const FileSystemURL& url, int fields) {
base::File::Error status;
base::RunLoop run_loop;
update_observer_.Enable();
operation_runner()->GetMetadata(
- url, RecordMetadataCallback(run_loop.QuitClosure(), &status));
+ url, fields, RecordMetadataCallback(run_loop.QuitClosure(), &status));
run_loop.Run();
update_observer_.Disable();
return status;
@@ -707,7 +711,7 @@ TEST_F(FileSystemOperationImplTest, TestCopyFailureByQuota) {
EXPECT_EQ(6, GetFileSize("src/file"));
FileSystemURL dest_file(URLForPath("dest/file"));
- int64 dest_path_cost = ComputePathCost(dest_file);
+ int64_t dest_path_cost = ComputePathCost(dest_file);
GrantQuotaForCurrentUsage();
AddQuota(6 + dest_path_cost - 1);
@@ -823,7 +827,7 @@ TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileSuccess) {
FileSystemURL dest_dir(CreateDirectory("dest"));
- int64 before_usage;
+ int64_t before_usage;
GetUsageAndQuota(&before_usage, NULL);
// Check that the file copied and corresponding usage increased.
@@ -833,7 +837,7 @@ TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileSuccess) {
EXPECT_EQ(1, change_observer()->create_file_count());
EXPECT_TRUE(FileExists("dest/file"));
- int64 after_usage;
+ int64_t after_usage;
GetUsageAndQuota(&after_usage, NULL);
EXPECT_GT(after_usage, before_usage);
@@ -938,7 +942,8 @@ TEST_F(FileSystemOperationImplTest, TestCreateDirSuccessExclusive) {
TEST_F(FileSystemOperationImplTest, TestExistsAndMetadataFailure) {
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
- GetMetadata(URLForPath("nonexistent")));
+ GetMetadata(URLForPath("nonexistent"),
+ storage::FileSystemOperation::GET_METADATA_FIELD_NONE));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
FileExists(URLForPath("nonexistent")));
@@ -956,14 +961,20 @@ TEST_F(FileSystemOperationImplTest, TestExistsAndMetadataSuccess) {
EXPECT_EQ(base::File::FILE_OK, DirectoryExists(dir));
++read_access;
- EXPECT_EQ(base::File::FILE_OK, GetMetadata(dir));
+ EXPECT_EQ(
+ base::File::FILE_OK,
+ GetMetadata(
+ dir, storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY));
EXPECT_TRUE(info().is_directory);
++read_access;
EXPECT_EQ(base::File::FILE_OK, FileExists(file));
++read_access;
- EXPECT_EQ(base::File::FILE_OK, GetMetadata(file));
+ EXPECT_EQ(
+ base::File::FILE_OK,
+ GetMetadata(
+ file, storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY));
EXPECT_FALSE(info().is_directory);
++read_access;
@@ -1077,7 +1088,11 @@ TEST_F(FileSystemOperationImplTest, TestTruncate) {
base::WriteFile(platform_path, test_data, data_size));
// Check that its length is the size of the data written.
- EXPECT_EQ(base::File::FILE_OK, GetMetadata(file));
+ EXPECT_EQ(
+ base::File::FILE_OK,
+ GetMetadata(
+ file, storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY |
+ storage::FileSystemOperation::GET_METADATA_FIELD_SIZE));
EXPECT_FALSE(info().is_directory);
EXPECT_EQ(data_size, info().size);
@@ -1208,7 +1223,7 @@ TEST_F(FileSystemOperationImplTest,
EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file1, 30));
EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file2, 2));
- const int64 all_file_size = 5000 + 400 + 30 + 2;
+ const int64_t all_file_size = 5000 + 400 + 30 + 2;
EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
EXPECT_EQ(all_file_size + total_path_cost, GetUsage());
@@ -1231,17 +1246,17 @@ TEST_F(FileSystemOperationImplTest,
FileSystemURL dest1(CreateDirectory("dest1"));
FileSystemURL dest2(CreateDirectory("dest2"));
- int64 usage = GetUsage();
+ int64_t usage = GetUsage();
FileSystemURL child_file1(CreateFile("src/file1"));
FileSystemURL child_file2(CreateFile("src/file2"));
FileSystemURL child_dir(CreateDirectory("src/dir"));
- int64 child_path_cost = GetUsage() - usage;
+ int64_t child_path_cost = GetUsage() - usage;
usage += child_path_cost;
FileSystemURL grandchild_file1(CreateFile("src/dir/file1"));
FileSystemURL grandchild_file2(CreateFile("src/dir/file2"));
- int64 total_path_cost = GetUsage();
- int64 grandchild_path_cost = total_path_cost - usage;
+ int64_t total_path_cost = GetUsage();
+ int64_t grandchild_path_cost = total_path_cost - usage;
EXPECT_EQ(0, GetDataSizeOnDisk());
@@ -1250,10 +1265,10 @@ TEST_F(FileSystemOperationImplTest,
EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file1, 60));
EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file2, 5));
- const int64 child_file_size = 8000 + 700;
- const int64 grandchild_file_size = 60 + 5;
- const int64 all_file_size = child_file_size + grandchild_file_size;
- int64 expected_usage = all_file_size + total_path_cost;
+ const int64_t child_file_size = 8000 + 700;
+ const int64_t grandchild_file_size = 60 + 5;
+ const int64_t all_file_size = child_file_size + grandchild_file_size;
+ int64_t expected_usage = all_file_size + total_path_cost;
usage = GetUsage();
EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
diff --git a/chromium/content/browser/fileapi/file_system_operation_impl_write_unittest.cc b/chromium/content/browser/fileapi/file_system_operation_impl_write_unittest.cc
index ae3277fc2c8..34ed554f993 100644
--- a/chromium/content/browser/fileapi/file_system_operation_impl_write_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_operation_impl_write_unittest.cc
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <utility>
#include <vector>
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
@@ -94,12 +97,12 @@ class FileSystemOperationImplWriteTest
base::File::Error status() const { return status_; }
base::File::Error cancel_status() const { return cancel_status_; }
- void add_bytes_written(int64 bytes, bool complete) {
+ void add_bytes_written(int64_t bytes, bool complete) {
bytes_written_ += bytes;
EXPECT_FALSE(complete_);
complete_ = complete;
}
- int64 bytes_written() const { return bytes_written_; }
+ int64_t bytes_written() const { return bytes_written_; }
bool complete() const { return complete_; }
protected:
@@ -127,18 +130,18 @@ class FileSystemOperationImplWriteTest
weak_factory_.GetWeakPtr());
}
- void DidWrite(base::File::Error status, int64 bytes, bool complete) {
+ void DidWrite(base::File::Error status, int64_t bytes, bool complete) {
if (status == base::File::FILE_OK) {
add_bytes_written(bytes, complete);
if (complete)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
} else {
EXPECT_FALSE(complete_);
EXPECT_EQ(status_, base::File::FILE_OK);
complete_ = true;
status_ = status;
if (base::MessageLoop::current()->is_running())
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
}
@@ -161,7 +164,7 @@ class FileSystemOperationImplWriteTest
// For post-operation status.
base::File::Error status_;
base::File::Error cancel_status_;
- int64 bytes_written_;
+ int64_t bytes_written_;
bool complete_;
scoped_ptr<MockBlobURLRequestContext> url_request_context_;
@@ -209,8 +212,8 @@ TEST_F(FileSystemOperationImplWriteTest, TestWriteZero) {
TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidBlobUrl) {
scoped_ptr<storage::BlobDataHandle> null_handle;
file_system_context_->operation_runner()->Write(
- &url_request_context(), URLForPath(virtual_path_),
- null_handle.Pass(), 0, RecordWriteCallback());
+ &url_request_context(), URLForPath(virtual_path_), std::move(null_handle),
+ 0, RecordWriteCallback());
base::MessageLoop::current()->Run();
EXPECT_EQ(0, bytes_written());
diff --git a/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc b/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc
index 075ba2130ff..082a7e3d60b 100644
--- a/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
@@ -194,11 +196,9 @@ class MultiThreadFileSystemOperationRunnerTest : public testing::Test {
base::ThreadTaskRunnerHandle::Get().get(),
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
storage::ExternalMountPoints::CreateRefCounted().get(),
- make_scoped_refptr(new MockSpecialStoragePolicy()).get(),
- nullptr,
- additional_providers.Pass(),
- std::vector<storage::URLRequestAutoMountHandler>(),
- base_dir,
+ make_scoped_refptr(new MockSpecialStoragePolicy()).get(), nullptr,
+ std::move(additional_providers),
+ std::vector<storage::URLRequestAutoMountHandler>(), base_dir,
CreateAllowFileAccessOptions());
// Disallow IO on the main loop.
@@ -222,8 +222,8 @@ class MultiThreadFileSystemOperationRunnerTest : public testing::Test {
}
private:
- content::TestBrowserThreadBundle thread_bundle_;
base::ScopedTempDir base_;
+ content::TestBrowserThreadBundle thread_bundle_;
scoped_refptr<FileSystemContext> file_system_context_;
DISALLOW_COPY_AND_ASSIGN(MultiThreadFileSystemOperationRunnerTest);
diff --git a/chromium/content/browser/fileapi/file_system_quota_client_unittest.cc b/chromium/content/browser/fileapi/file_system_quota_client_unittest.cc
index b3333a0af1b..e3a24c20151 100644
--- a/chromium/content/browser/fileapi/file_system_quota_client_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_quota_client_unittest.cc
@@ -2,10 +2,12 @@
// 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 <stdint.h>
+
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "content/public/test/async_file_test_helper.h"
#include "content/public/test/test_file_system_context.h"
@@ -52,7 +54,7 @@ class FileSystemQuotaClientTest : public testing::Test {
struct TestFile {
bool isDirectory;
const char* name;
- int64 size;
+ int64_t size;
const char* origin_url;
storage::StorageType type;
};
@@ -71,9 +73,9 @@ class FileSystemQuotaClientTest : public testing::Test {
weak_factory_.GetWeakPtr()));
}
- int64 GetOriginUsage(FileSystemQuotaClient* quota_client,
- const std::string& origin_url,
- storage::StorageType type) {
+ int64_t GetOriginUsage(FileSystemQuotaClient* quota_client,
+ const std::string& origin_url,
+ storage::StorageType type) {
GetOriginUsageAsync(quota_client, origin_url, type);
base::RunLoop().RunUntilIdle();
return usage_;
@@ -125,7 +127,7 @@ class FileSystemQuotaClientTest : public testing::Test {
}
bool CreateFileSystemFile(const base::FilePath& file_path,
- int64 file_size,
+ int64_t file_size,
const std::string& origin_url,
storage::StorageType storage_type) {
if (file_path.empty())
@@ -174,11 +176,11 @@ class FileSystemQuotaClientTest : public testing::Test {
// directory before adding a file or directory to it, so that we can just
// count the basename of each addition. A recursive creation of a path, which
// created more than one directory in a single shot, would break this.
- int64 ComputeFilePathsCostForOriginAndType(const TestFile* files,
- int num_files,
- const std::string& origin_url,
- storage::StorageType type) {
- int64 file_paths_cost = 0;
+ int64_t ComputeFilePathsCostForOriginAndType(const TestFile* files,
+ int num_files,
+ const std::string& origin_url,
+ storage::StorageType type) {
+ int64_t file_paths_cost = 0;
for (int i = 0; i < num_files; i++) {
if (files[i].type == type &&
GURL(files[i].origin_url) == GURL(origin_url)) {
@@ -202,7 +204,7 @@ class FileSystemQuotaClientTest : public testing::Test {
weak_factory_.GetWeakPtr()));
}
- int64 usage() const { return usage_; }
+ int64_t usage() const { return usage_; }
storage::QuotaStatusCode status() { return deletion_status_; }
int additional_callback_count() const { return additional_callback_count_; }
void set_additional_callback_count(int count) {
@@ -210,15 +212,13 @@ class FileSystemQuotaClientTest : public testing::Test {
}
private:
- void OnGetUsage(int64 usage) {
- usage_ = usage;
- }
+ void OnGetUsage(int64_t usage) { usage_ = usage; }
void OnGetOrigins(const std::set<GURL>& origins) {
origins_ = origins;
}
- void OnGetAdditionalUsage(int64 usage_unused) {
+ void OnGetAdditionalUsage(int64_t usage_unused) {
++additional_callback_count_;
}
@@ -229,7 +229,7 @@ class FileSystemQuotaClientTest : public testing::Test {
base::ScopedTempDir data_dir_;
base::MessageLoop message_loop_;
scoped_refptr<storage::FileSystemContext> file_system_context_;
- int64 usage_;
+ int64_t usage_;
int additional_callback_count_;
std::set<GURL> origins_;
storage::QuotaStatusCode deletion_status_;
@@ -263,7 +263,7 @@ TEST_F(FileSystemQuotaClientTest, OneFileTest) {
{false, "foo", 4921, kDummyURL1, kTemporary},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
+ const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
for (int i = 0; i < 2; i++) {
@@ -280,7 +280,7 @@ TEST_F(FileSystemQuotaClientTest, TwoFilesTest) {
{false, "bar", 41, kDummyURL1, kTemporary},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
+ const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
for (int i = 0; i < 2; i++) {
@@ -298,7 +298,7 @@ TEST_F(FileSystemQuotaClientTest, EmptyFilesTest) {
{false, "baz", 0, kDummyURL1, kTemporary},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
+ const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
for (int i = 0; i < 2; i++) {
@@ -316,7 +316,7 @@ TEST_F(FileSystemQuotaClientTest, SubDirectoryTest) {
{false, "bar", 4814, kDummyURL1, kTemporary},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
+ const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
for (int i = 0; i < 2; i++) {
@@ -338,10 +338,12 @@ TEST_F(FileSystemQuotaClientTest, MultiTypeTest) {
{false, "bar", 9, kDummyURL1, kPersistent},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost_temporary = ComputeFilePathsCostForOriginAndType(
- kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
- const int64 file_paths_cost_persistent = ComputeFilePathsCostForOriginAndType(
- kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
+ const int64_t file_paths_cost_temporary =
+ ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
+ kDummyURL1, kTemporary);
+ const int64_t file_paths_cost_persistent =
+ ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
+ kDummyURL1, kTemporary);
for (int i = 0; i < 2; i++) {
EXPECT_EQ(133 + 14 + file_paths_cost_temporary,
@@ -372,16 +374,18 @@ TEST_F(FileSystemQuotaClientTest, MultiDomainTest) {
{false, "baz", 18, kDummyURL2, kPersistent},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost_temporary1 = ComputeFilePathsCostForOriginAndType(
- kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
- const int64 file_paths_cost_persistent1 =
+ const int64_t file_paths_cost_temporary1 =
+ ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
+ kDummyURL1, kTemporary);
+ const int64_t file_paths_cost_persistent1 =
+ ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
+ kDummyURL1, kPersistent);
+ const int64_t file_paths_cost_temporary2 =
ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
- kDummyURL1, kPersistent);
- const int64 file_paths_cost_temporary2 = ComputeFilePathsCostForOriginAndType(
- kFiles, arraysize(kFiles), kDummyURL2, kTemporary);
- const int64 file_paths_cost_persistent2 =
+ kDummyURL2, kTemporary);
+ const int64_t file_paths_cost_persistent2 =
ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
- kDummyURL2, kPersistent);
+ kDummyURL2, kPersistent);
for (int i = 0; i < 2; i++) {
EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1,
@@ -403,7 +407,7 @@ TEST_F(FileSystemQuotaClientTest, GetUsage_MultipleTasks) {
{false, "bar", 22, kDummyURL1, kTemporary},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
+ const int64_t file_paths_cost = ComputeFilePathsCostForOriginAndType(
kFiles, arraysize(kFiles), kDummyURL1, kTemporary);
// Dispatching three GetUsage tasks.
@@ -505,21 +509,21 @@ TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) {
{false, "g", 64, "https://bar.com/", kTemporary},
};
InitializeOriginFiles(quota_client.get(), kFiles, arraysize(kFiles));
- const int64 file_paths_cost_temporary_foo_https =
+ const int64_t file_paths_cost_temporary_foo_https =
ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
- "https://foo.com/", kTemporary);
- const int64 file_paths_cost_persistent_foo =
+ "https://foo.com/", kTemporary);
+ const int64_t file_paths_cost_persistent_foo =
ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
- "http://foo.com/", kPersistent);
- const int64 file_paths_cost_temporary_bar =
+ "http://foo.com/", kPersistent);
+ const int64_t file_paths_cost_temporary_bar =
ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
- "http://bar.com/", kTemporary);
- const int64 file_paths_cost_temporary_bar_https =
+ "http://bar.com/", kTemporary);
+ const int64_t file_paths_cost_temporary_bar_https =
ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
- "https://bar.com/", kTemporary);
- const int64 file_paths_cost_persistent_bar_https =
+ "https://bar.com/", kTemporary);
+ const int64_t file_paths_cost_persistent_bar_https =
ComputeFilePathsCostForOriginAndType(kFiles, arraysize(kFiles),
- "https://bar.com/", kPersistent);
+ "https://bar.com/", kPersistent);
DeleteOriginData(quota_client.get(), "http://foo.com/", kTemporary);
base::RunLoop().RunUntilIdle();
diff --git a/chromium/content/browser/fileapi/file_system_url_request_job_unittest.cc b/chromium/content/browser/fileapi/file_system_url_request_job_unittest.cc
index dca1c535083..4b2715c29ab 100644
--- a/chromium/content/browser/fileapi/file_system_url_request_job_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_url_request_job_unittest.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "storage/browser/fileapi/file_system_url_request_job.h"
-
+#include <stddef.h>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/files/file_path.h"
@@ -12,6 +12,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/format_macros.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/rand_util.h"
@@ -36,6 +37,7 @@
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_file_util.h"
+#include "storage/browser/fileapi/file_system_url_request_job.h"
#include "testing/gtest/include/gtest/gtest.h"
using content::AsyncFileTestHelper;
@@ -166,7 +168,7 @@ class FileSystemURLRequestJobTest : public testing::Test {
handlers.push_back(base::Bind(&TestAutoMountForURLRequest));
file_system_context_ = CreateFileSystemContextWithAutoMountersForTesting(
- NULL, additional_providers.Pass(), handlers, temp_dir_.path());
+ NULL, std::move(additional_providers), handlers, temp_dir_.path());
ASSERT_EQ(static_cast<int>(sizeof(kTestFileData)) - 1,
base::WriteFile(mnt_point.AppendASCII("foo"), kTestFileData,
@@ -246,10 +248,12 @@ class FileSystemURLRequestJobTest : public testing::Test {
return GURL(kFileSystemURLPrefix + path);
}
- // Put the message loop at the top, so that it's the last thing deleted.
+ // Temp directory is at the top because it must be deleted last.
+ base::ScopedTempDir temp_dir_;
+
+ // The message loop must be deleted second to last.
base::MessageLoopForIO message_loop_;
- base::ScopedTempDir temp_dir_;
scoped_refptr<storage::FileSystemContext> file_system_context_;
net::URLRequestContext empty_context_;
diff --git a/chromium/content/browser/fileapi/file_system_url_unittest.cc b/chromium/content/browser/fileapi/file_system_url_unittest.cc
index e4dd5e2b3f5..ef13cf103ca 100644
--- a/chromium/content/browser/fileapi/file_system_url_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_url_unittest.cc
@@ -4,7 +4,10 @@
#include "storage/browser/fileapi/file_system_url.h"
+#include <stddef.h>
+
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "storage/common/fileapi/file_system_types.h"
#include "storage/common/fileapi/file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/browser/fileapi/file_system_usage_cache_unittest.cc b/chromium/content/browser/fileapi/file_system_usage_cache_unittest.cc
index f67485c8c90..70557d299b2 100644
--- a/chromium/content/browser/fileapi/file_system_usage_cache_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_usage_cache_unittest.cc
@@ -4,9 +4,13 @@
#include "storage/browser/fileapi/file_system_usage_cache.h"
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -45,18 +49,18 @@ TEST_F(FileSystemUsageCacheTest, CreateTest) {
}
TEST_F(FileSystemUsageCacheTest, SetSizeTest) {
- static const int64 size = 240122;
+ static const int64_t size = 240122;
base::FilePath usage_file_path = GetUsageFilePath();
- int64 usage = 0;
+ int64_t usage = 0;
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, size));
EXPECT_TRUE(usage_cache()->GetUsage(usage_file_path, &usage));
EXPECT_EQ(size, usage);
}
TEST_F(FileSystemUsageCacheTest, SetLargeSizeTest) {
- static const int64 size = kint64max;
+ static const int64_t size = std::numeric_limits<int64_t>::max();
base::FilePath usage_file_path = GetUsageFilePath();
- int64 usage = 0;
+ int64_t usage = 0;
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, size));
EXPECT_TRUE(usage_cache()->GetUsage(usage_file_path, &usage));
EXPECT_EQ(size, usage);
@@ -64,8 +68,8 @@ TEST_F(FileSystemUsageCacheTest, SetLargeSizeTest) {
TEST_F(FileSystemUsageCacheTest, IncAndGetSizeTest) {
base::FilePath usage_file_path = GetUsageFilePath();
- uint32 dirty = 0;
- int64 usage = 0;
+ uint32_t dirty = 0;
+ int64_t usage = 0;
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, 98214));
ASSERT_TRUE(usage_cache()->IncrementDirty(usage_file_path));
EXPECT_TRUE(usage_cache()->GetDirty(usage_file_path, &dirty));
@@ -75,9 +79,9 @@ TEST_F(FileSystemUsageCacheTest, IncAndGetSizeTest) {
}
TEST_F(FileSystemUsageCacheTest, DecAndGetSizeTest) {
- static const int64 size = 71839;
+ static const int64_t size = 71839;
base::FilePath usage_file_path = GetUsageFilePath();
- int64 usage = 0;
+ int64_t usage = 0;
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, size));
// DecrementDirty for dirty = 0 is invalid. It returns false.
ASSERT_FALSE(usage_cache()->DecrementDirty(usage_file_path));
@@ -86,9 +90,9 @@ TEST_F(FileSystemUsageCacheTest, DecAndGetSizeTest) {
}
TEST_F(FileSystemUsageCacheTest, IncDecAndGetSizeTest) {
- static const int64 size = 198491;
+ static const int64_t size = 198491;
base::FilePath usage_file_path = GetUsageFilePath();
- int64 usage = 0;
+ int64_t usage = 0;
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, size));
ASSERT_TRUE(usage_cache()->IncrementDirty(usage_file_path));
ASSERT_TRUE(usage_cache()->DecrementDirty(usage_file_path));
@@ -98,8 +102,8 @@ TEST_F(FileSystemUsageCacheTest, IncDecAndGetSizeTest) {
TEST_F(FileSystemUsageCacheTest, DecIncAndGetSizeTest) {
base::FilePath usage_file_path = GetUsageFilePath();
- uint32 dirty = 0;
- int64 usage = 0;
+ uint32_t dirty = 0;
+ int64_t usage = 0;
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, 854238));
// DecrementDirty for dirty = 0 is invalid. It returns false.
ASSERT_FALSE(usage_cache()->DecrementDirty(usage_file_path));
@@ -113,9 +117,9 @@ TEST_F(FileSystemUsageCacheTest, DecIncAndGetSizeTest) {
}
TEST_F(FileSystemUsageCacheTest, ManyIncsSameDecsAndGetSizeTest) {
- static const int64 size = 82412;
+ static const int64_t size = 82412;
base::FilePath usage_file_path = GetUsageFilePath();
- int64 usage = 0;
+ int64_t usage = 0;
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, size));
for (int i = 0; i < 20; i++)
ASSERT_TRUE(usage_cache()->IncrementDirty(usage_file_path));
@@ -126,8 +130,8 @@ TEST_F(FileSystemUsageCacheTest, ManyIncsSameDecsAndGetSizeTest) {
}
TEST_F(FileSystemUsageCacheTest, ManyIncsLessDecsAndGetSizeTest) {
- uint32 dirty = 0;
- int64 usage = 0;
+ uint32_t dirty = 0;
+ int64_t usage = 0;
base::FilePath usage_file_path = GetUsageFilePath();
ASSERT_TRUE(usage_cache()->UpdateUsage(usage_file_path, 19319));
for (int i = 0; i < 20; i++)
@@ -141,7 +145,7 @@ TEST_F(FileSystemUsageCacheTest, ManyIncsLessDecsAndGetSizeTest) {
}
TEST_F(FileSystemUsageCacheTest, GetSizeWithoutCacheFileTest) {
- int64 usage = 0;
+ int64_t usage = 0;
base::FilePath usage_file_path = GetUsageFilePath();
EXPECT_FALSE(usage_cache()->GetUsage(usage_file_path, &usage));
}
diff --git a/chromium/content/browser/fileapi/file_writer_delegate_unittest.cc b/chromium/content/browser/fileapi/file_writer_delegate_unittest.cc
index af60d3fcfa4..c12e3c3e6c2 100644
--- a/chromium/content/browser/fileapi/file_writer_delegate_unittest.cc
+++ b/chromium/content/browser/fileapi/file_writer_delegate_unittest.cc
@@ -2,14 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <limits>
#include <string>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -52,29 +56,30 @@ class Result {
write_status_(FileWriterDelegate::SUCCESS_IO_PENDING) {}
base::File::Error status() const { return status_; }
- int64 bytes_written() const { return bytes_written_; }
+ int64_t bytes_written() const { return bytes_written_; }
FileWriterDelegate::WriteProgressStatus write_status() const {
return write_status_;
}
- void DidWrite(base::File::Error status, int64 bytes,
+ void DidWrite(base::File::Error status,
+ int64_t bytes,
FileWriterDelegate::WriteProgressStatus write_status) {
write_status_ = write_status;
if (status == base::File::FILE_OK) {
bytes_written_ += bytes;
if (write_status_ != FileWriterDelegate::SUCCESS_IO_PENDING)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
} else {
EXPECT_EQ(base::File::FILE_OK, status_);
status_ = status;
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
}
private:
// For post-operation status.
base::File::Error status_;
- int64 bytes_written_;
+ int64_t bytes_written_;
FileWriterDelegate::WriteProgressStatus write_status_;
};
@@ -90,13 +95,13 @@ class FileWriterDelegateTest : public PlatformTest {
void SetUp() override;
void TearDown() override;
- int64 usage() {
+ int64_t usage() {
return file_system_context_->GetQuotaUtil(kFileSystemType)
->GetOriginUsageOnFileTaskRunner(
file_system_context_.get(), kOrigin, kFileSystemType);
}
- int64 GetFileSizeOnDisk(const char* test_file_path) {
+ int64_t GetFileSizeOnDisk(const char* test_file_path) {
// There might be in-flight flush/write.
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
base::Bind(&base::DoNothing));
@@ -115,10 +120,9 @@ class FileWriterDelegateTest : public PlatformTest {
kOrigin, kFileSystemType, base::FilePath().FromUTF8Unsafe(file_name));
}
- FileWriterDelegate* CreateWriterDelegate(
- const char* test_file_path,
- int64 offset,
- int64 allowed_growth) {
+ FileWriterDelegate* CreateWriterDelegate(const char* test_file_path,
+ int64_t offset,
+ int64_t allowed_growth) {
storage::SandboxFileStreamWriter* writer =
new storage::SandboxFileStreamWriter(
file_system_context_.get(),
@@ -138,8 +142,8 @@ class FileWriterDelegateTest : public PlatformTest {
// and creates a new FileWriterDelegate for the file.
void PrepareForWrite(const char* test_file_path,
const GURL& blob_url,
- int64 offset,
- int64 allowed_growth) {
+ int64_t offset,
+ int64_t allowed_growth) {
file_writer_delegate_.reset(
CreateWriterDelegate(test_file_path, offset, allowed_growth));
request_ = empty_context_.CreateRequest(
@@ -175,26 +179,24 @@ class FileWriterDelegateTestJob : public net::URLRequestJob {
: net::URLRequestJob(request, network_delegate),
content_(content),
remaining_bytes_(content.length()),
- cursor_(0) {
- }
+ cursor_(0),
+ weak_factory_(this) {}
void Start() override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&FileWriterDelegateTestJob::NotifyHeadersComplete, this));
+ FROM_HERE, base::Bind(&FileWriterDelegateTestJob::NotifyHeadersComplete,
+ weak_factory_.GetWeakPtr()));
}
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override {
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override {
if (remaining_bytes_ < buf_size)
- buf_size = static_cast<int>(remaining_bytes_);
+ buf_size = remaining_bytes_;
for (int i = 0; i < buf_size; ++i)
buf->data()[i] = content_[cursor_++];
remaining_bytes_ -= buf_size;
- SetStatus(net::URLRequestStatus());
- *bytes_read = buf_size;
- return true;
+ return buf_size;
}
int GetResponseCode() const override { return 200; }
@@ -206,6 +208,8 @@ class FileWriterDelegateTestJob : public net::URLRequestJob {
std::string content_;
int remaining_bytes_;
int cursor_;
+
+ base::WeakPtrFactory<FileWriterDelegateTestJob> weak_factory_;
};
class BlobURLRequestJobFactory : public net::URLRequestJobFactory {
@@ -276,11 +280,11 @@ TEST_F(FileWriterDelegateTest, WriteSuccessWithoutQuotaLimit) {
const GURL kBlobURL("blob:nolimit");
content_ = kData;
- PrepareForWrite("test", kBlobURL, 0, kint64max);
+ PrepareForWrite("test", kBlobURL, 0, std::numeric_limits<int64_t>::max());
Result result;
ASSERT_EQ(0, usage());
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_), GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::SUCCESS_COMPLETED, result.write_status());
@@ -295,12 +299,12 @@ TEST_F(FileWriterDelegateTest, WriteSuccessWithoutQuotaLimit) {
TEST_F(FileWriterDelegateTest, WriteSuccessWithJustQuota) {
const GURL kBlobURL("blob:just");
content_ = kData;
- const int64 kAllowedGrowth = kDataSize;
+ const int64_t kAllowedGrowth = kDataSize;
PrepareForWrite("test", kBlobURL, 0, kAllowedGrowth);
Result result;
ASSERT_EQ(0, usage());
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_), GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::SUCCESS_COMPLETED, result.write_status());
file_writer_delegate_.reset();
@@ -315,12 +319,12 @@ TEST_F(FileWriterDelegateTest, WriteSuccessWithJustQuota) {
TEST_F(FileWriterDelegateTest, DISABLED_WriteFailureByQuota) {
const GURL kBlobURL("blob:failure");
content_ = kData;
- const int64 kAllowedGrowth = kDataSize - 1;
+ const int64_t kAllowedGrowth = kDataSize - 1;
PrepareForWrite("test", kBlobURL, 0, kAllowedGrowth);
Result result;
ASSERT_EQ(0, usage());
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_), GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::ERROR_WRITE_STARTED, result.write_status());
file_writer_delegate_.reset();
@@ -336,12 +340,12 @@ TEST_F(FileWriterDelegateTest, DISABLED_WriteFailureByQuota) {
TEST_F(FileWriterDelegateTest, WriteZeroBytesSuccessfullyWithZeroQuota) {
const GURL kBlobURL("blob:zero");
content_ = "";
- int64 kAllowedGrowth = 0;
+ int64_t kAllowedGrowth = 0;
PrepareForWrite("test", kBlobURL, 0, kAllowedGrowth);
Result result;
ASSERT_EQ(0, usage());
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_), GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::SUCCESS_COMPLETED, result.write_status());
file_writer_delegate_.reset();
@@ -366,17 +370,18 @@ TEST_F(FileWriterDelegateTest, WriteSuccessWithoutQuotaLimitConcurrent) {
const GURL kBlobURL2("blob:nolimitconcurrent2");
content_ = kData;
- PrepareForWrite("test", kBlobURL, 0, kint64max);
+ PrepareForWrite("test", kBlobURL, 0, std::numeric_limits<int64_t>::max());
// Credate another FileWriterDelegate for concurrent write.
- file_writer_delegate2.reset(CreateWriterDelegate("test2", 0, kint64max));
+ file_writer_delegate2.reset(
+ CreateWriterDelegate("test2", 0, std::numeric_limits<int64_t>::max()));
request2 = empty_context_.CreateRequest(
kBlobURL2, net::DEFAULT_PRIORITY, file_writer_delegate2.get());
Result result, result2;
ASSERT_EQ(0, usage());
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
- file_writer_delegate2->Start(request2.Pass(), GetWriteCallback(&result2));
+ file_writer_delegate_->Start(std::move(request_), GetWriteCallback(&result));
+ file_writer_delegate2->Start(std::move(request2), GetWriteCallback(&result2));
base::MessageLoop::current()->Run();
if (result.write_status() == FileWriterDelegate::SUCCESS_IO_PENDING ||
result2.write_status() == FileWriterDelegate::SUCCESS_IO_PENDING)
@@ -401,15 +406,16 @@ TEST_F(FileWriterDelegateTest, WritesWithQuotaAndOffset) {
content_ = kData;
// Writing kDataSize (=45) bytes data while allowed_growth is 100.
- int64 offset = 0;
- int64 allowed_growth = 100;
+ int64_t offset = 0;
+ int64_t allowed_growth = 100;
ASSERT_LT(kDataSize, allowed_growth);
PrepareForWrite("test", kBlobURL, offset, allowed_growth);
{
Result result;
ASSERT_EQ(0, usage());
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_),
+ GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::SUCCESS_COMPLETED, result.write_status());
file_writer_delegate_.reset();
@@ -427,7 +433,8 @@ TEST_F(FileWriterDelegateTest, WritesWithQuotaAndOffset) {
{
Result result;
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_),
+ GetWriteCallback(&result));
base::MessageLoop::current()->Run();
EXPECT_EQ(kDataSize, usage());
EXPECT_EQ(GetFileSizeOnDisk("test"), usage());
@@ -444,7 +451,8 @@ TEST_F(FileWriterDelegateTest, WritesWithQuotaAndOffset) {
{
Result result;
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_),
+ GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::SUCCESS_COMPLETED, result.write_status());
file_writer_delegate_.reset();
@@ -459,11 +467,12 @@ TEST_F(FileWriterDelegateTest, WritesWithQuotaAndOffset) {
offset = 0;
allowed_growth = -20;
PrepareForWrite("test", kBlobURL, offset, allowed_growth);
- int64 pre_write_usage = GetFileSizeOnDisk("test");
+ int64_t pre_write_usage = GetFileSizeOnDisk("test");
{
Result result;
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_),
+ GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::SUCCESS_COMPLETED, result.write_status());
file_writer_delegate_.reset();
@@ -483,7 +492,8 @@ TEST_F(FileWriterDelegateTest, WritesWithQuotaAndOffset) {
{
Result result;
- file_writer_delegate_->Start(request_.Pass(), GetWriteCallback(&result));
+ file_writer_delegate_->Start(std::move(request_),
+ GetWriteCallback(&result));
base::MessageLoop::current()->Run();
ASSERT_EQ(FileWriterDelegate::ERROR_WRITE_STARTED, result.write_status());
file_writer_delegate_.reset();
diff --git a/chromium/content/browser/fileapi/fileapi_message_filter.cc b/chromium/content/browser/fileapi/fileapi_message_filter.cc
index 1babfd54546..8594aef48bd 100644
--- a/chromium/content/browser/fileapi/fileapi_message_filter.cc
+++ b/chromium/content/browser/fileapi/fileapi_message_filter.cc
@@ -5,16 +5,19 @@
#include "content/browser/fileapi/fileapi_message_filter.h"
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/fileapi/blob_storage_host.h"
@@ -53,9 +56,8 @@ namespace content {
namespace {
-const uint32 kFilteredMessageClasses[] = {
- BlobMsgStart,
- FileSystemMsgStart,
+const uint32_t kFilteredMessageClasses[] = {
+ BlobMsgStart, FileSystemMsgStart,
};
void RevokeFilePermission(int child_id, const base::FilePath& path) {
@@ -106,7 +108,7 @@ FileAPIMessageFilter::FileAPIMessageFilter(
DCHECK(stream_context);
}
-void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
+void FileAPIMessageFilter::OnChannelConnected(int32_t peer_pid) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (request_context_getter_.get()) {
@@ -316,7 +318,10 @@ void FileAPIMessageFilter::OnReadMetadata(
}
operations_[request_id] = operation_runner()->GetMetadata(
- url, base::Bind(&FileAPIMessageFilter::DidGetMetadata, this, request_id));
+ url, FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY |
+ FileSystemOperation::GET_METADATA_FIELD_SIZE |
+ FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED,
+ base::Bind(&FileAPIMessageFilter::DidGetMetadata, this, request_id));
}
void FileAPIMessageFilter::OnCreate(
@@ -383,11 +388,10 @@ void FileAPIMessageFilter::OnReadDirectory(
this, request_id));
}
-void FileAPIMessageFilter::OnWrite(
- int request_id,
- const GURL& path,
- const std::string& blob_uuid,
- int64 offset) {
+void FileAPIMessageFilter::OnWrite(int request_id,
+ const GURL& path,
+ const std::string& blob_uuid,
+ int64_t offset) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!request_context_) {
// We can't write w/o a request context, trying to do so will crash.
@@ -408,14 +412,13 @@ void FileAPIMessageFilter::OnWrite(
blob_storage_context_->context()->GetBlobDataFromUUID(blob_uuid);
operations_[request_id] = operation_runner()->Write(
- request_context_, url, blob.Pass(), offset,
+ request_context_, url, std::move(blob), offset,
base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id));
}
-void FileAPIMessageFilter::OnTruncate(
- int request_id,
- const GURL& path,
- int64 length) {
+void FileAPIMessageFilter::OnTruncate(int request_id,
+ const GURL& path,
+ int64_t length) {
FileSystemURL url(context_->CrackURL(path));
if (!ValidateFileSystemURL(request_id, url))
return;
@@ -493,9 +496,11 @@ void FileAPIMessageFilter::OnCreateSnapshotFile(
FileSystemBackend* backend = context_->GetFileSystemBackend(url.type());
if (backend->SupportsStreaming(url)) {
operations_[request_id] = operation_runner()->GetMetadata(
- url,
- base::Bind(&FileAPIMessageFilter::DidGetMetadataForStreaming,
- this, request_id));
+ url, FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY |
+ FileSystemOperation::GET_METADATA_FIELD_SIZE |
+ FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED,
+ base::Bind(&FileAPIMessageFilter::DidGetMetadataForStreaming, this,
+ request_id));
} else {
operations_[request_id] = operation_runner()->CreateSnapshotFile(
url,
@@ -753,7 +758,7 @@ void FileAPIMessageFilter::DidReadDirectory(
void FileAPIMessageFilter::DidWrite(int request_id,
base::File::Error result,
- int64 bytes,
+ int64_t bytes,
bool complete) {
if (result == base::File::FILE_OK) {
Send(new FileSystemMsg_DidWrite(request_id, bytes, complete));
diff --git a/chromium/content/browser/fileapi/fileapi_message_filter.h b/chromium/content/browser/fileapi/fileapi_message_filter.h
index 3ad767ecabe..74d056fef8e 100644
--- a/chromium/content/browser/fileapi/fileapi_message_filter.h
+++ b/chromium/content/browser/fileapi/fileapi_message_filter.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_FILEAPI_FILEAPI_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_FILEAPI_FILEAPI_MESSAGE_FILTER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
@@ -12,6 +15,7 @@
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_util_proxy.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "content/browser/streams/stream.h"
@@ -73,7 +77,7 @@ class CONTENT_EXPORT FileAPIMessageFilter : public BrowserMessageFilter {
StreamContext* stream_context);
// BrowserMessageFilter implementation.
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnChannelClosing() override;
base::TaskRunner* OverrideTaskRunnerForMessage(
const IPC::Message& message) override;
@@ -111,8 +115,8 @@ class CONTENT_EXPORT FileAPIMessageFilter : public BrowserMessageFilter {
void OnWrite(int request_id,
const GURL& path,
const std::string& blob_uuid,
- int64 offset);
- void OnTruncate(int request_id, const GURL& path, int64 length);
+ int64_t offset);
+ void OnTruncate(int request_id, const GURL& path, int64_t length);
void OnTouchFile(int request_id,
const GURL& path,
const base::Time& last_access_time,
@@ -172,7 +176,7 @@ class CONTENT_EXPORT FileAPIMessageFilter : public BrowserMessageFilter {
bool has_more);
void DidWrite(int request_id,
base::File::Error result,
- int64 bytes,
+ int64_t bytes,
bool complete);
void DidOpenFileSystem(int request_id,
const GURL& root,
diff --git a/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc b/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc
index 58f555e10fb..1fe224e38ec 100644
--- a/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc
+++ b/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/fileapi/fileapi_message_filter.h"
+#include <stddef.h>
+
#include <string>
#include <vector>
diff --git a/chromium/content/browser/fileapi/isolated_context_unittest.cc b/chromium/content/browser/fileapi/isolated_context_unittest.cc
index 72969344505..64f0c29404c 100644
--- a/chromium/content/browser/fileapi/isolated_context_unittest.cc
+++ b/chromium/content/browser/fileapi/isolated_context_unittest.cc
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/isolated_context.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/browser/fileapi/local_file_stream_reader_unittest.cc b/chromium/content/browser/fileapi/local_file_stream_reader_unittest.cc
index fefd996095b..2404d655536 100644
--- a/chromium/content/browser/fileapi/local_file_stream_reader_unittest.cc
+++ b/chromium/content/browser/fileapi/local_file_stream_reader_unittest.cc
@@ -4,6 +4,9 @@
#include "storage/browser/fileapi/local_file_stream_reader.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/files/file.h"
@@ -11,6 +14,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -56,7 +60,7 @@ void NeverCalled(int) { ADD_FAILURE(); }
void EmptyCallback() {}
void QuitLoop() {
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
} // namespace
@@ -86,7 +90,7 @@ class LocalFileStreamReaderTest : public testing::Test {
protected:
LocalFileStreamReader* CreateFileReader(
const base::FilePath& path,
- int64 initial_offset,
+ int64_t initial_offset,
const base::Time& expected_modification_time) {
return new LocalFileStreamReader(
file_task_runner(),
@@ -151,7 +155,7 @@ TEST_F(LocalFileStreamReaderTest, Empty) {
ASSERT_EQ(0U, data.size());
net::TestInt64CompletionCallback callback;
- int64 length_result = reader->GetLength(callback.callback());
+ int64_t length_result = reader->GetLength(callback.callback());
if (length_result == net::ERR_IO_PENDING)
length_result = callback.WaitForResult();
ASSERT_EQ(0, result);
@@ -161,7 +165,7 @@ TEST_F(LocalFileStreamReaderTest, GetLengthNormal) {
scoped_ptr<LocalFileStreamReader> reader(
CreateFileReader(test_path(), 0, test_file_modification_time()));
net::TestInt64CompletionCallback callback;
- int64 result = reader->GetLength(callback.callback());
+ int64_t result = reader->GetLength(callback.callback());
if (result == net::ERR_IO_PENDING)
result = callback.WaitForResult();
ASSERT_EQ(kTestDataSize, result);
@@ -175,7 +179,7 @@ TEST_F(LocalFileStreamReaderTest, GetLengthAfterModified) {
scoped_ptr<LocalFileStreamReader> reader(
CreateFileReader(test_path(), 0, test_file_modification_time()));
net::TestInt64CompletionCallback callback;
- int64 result = reader->GetLength(callback.callback());
+ int64_t result = reader->GetLength(callback.callback());
if (result == net::ERR_IO_PENDING)
result = callback.WaitForResult();
ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
@@ -192,7 +196,7 @@ TEST_F(LocalFileStreamReaderTest, GetLengthWithOffset) {
scoped_ptr<LocalFileStreamReader> reader(
CreateFileReader(test_path(), 3, base::Time()));
net::TestInt64CompletionCallback callback;
- int64 result = reader->GetLength(callback.callback());
+ int64_t result = reader->GetLength(callback.callback());
if (result == net::ERR_IO_PENDING)
result = callback.WaitForResult();
// Initial offset does not affect the result of GetLength.
@@ -222,7 +226,7 @@ TEST_F(LocalFileStreamReaderTest, ReadAfterModified) {
EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
EXPECT_EQ(0U, data.size());
- // Due to precision loss converting int64->double->int64 (e.g. through
+ // Due to precision loss converting int64_t->double->int64_t (e.g. through
// Blink) the expected/actual time may vary by microseconds. With
// modification time delta < 10us this should work.
TouchTestFile(base::TimeDelta::FromMicroseconds(1));
diff --git a/chromium/content/browser/fileapi/local_file_stream_writer_unittest.cc b/chromium/content/browser/fileapi/local_file_stream_writer_unittest.cc
index 9e05310eb8f..a6d8b996675 100644
--- a/chromium/content/browser/fileapi/local_file_stream_writer_unittest.cc
+++ b/chromium/content/browser/fileapi/local_file_stream_writer_unittest.cc
@@ -4,6 +4,8 @@
#include "storage/browser/fileapi/local_file_stream_writer.h"
+#include <stdint.h>
+
#include <string>
#include "base/callback.h"
@@ -82,7 +84,7 @@ class LocalFileStreamWriterTest : public testing::Test {
}
LocalFileStreamWriter* CreateWriter(const base::FilePath& path,
- int64 offset) {
+ int64_t offset) {
return new LocalFileStreamWriter(file_task_runner(), path, offset,
FileStreamWriter::OPEN_EXISTING_FILE);
}
diff --git a/chromium/content/browser/fileapi/local_file_util_unittest.cc b/chromium/content/browser/fileapi/local_file_util_unittest.cc
index a0c9615d5fb..28ff6b3ba9d 100644
--- a/chromium/content/browser/fileapi/local_file_util_unittest.cc
+++ b/chromium/content/browser/fileapi/local_file_util_unittest.cc
@@ -2,15 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <string>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/public/test/async_file_test_helper.h"
#include "content/public/test/test_file_system_context.h"
#include "storage/browser/fileapi/async_file_util_adapter.h"
@@ -89,7 +93,7 @@ class LocalFileUtilTest : public testing::Test {
return base::DirectoryExists(LocalPath(file_name));
}
- int64 GetSize(const char *file_name) {
+ int64_t GetSize(const char* file_name) {
base::File::Info info;
base::GetFileInfo(LocalPath(file_name), &info);
return info.size;
diff --git a/chromium/content/browser/fileapi/mock_file_change_observer.h b/chromium/content/browser/fileapi/mock_file_change_observer.h
index 92c24e1bc80..cd39b24f21c 100644
--- a/chromium/content/browser/fileapi/mock_file_change_observer.h
+++ b/chromium/content/browser/fileapi/mock_file_change_observer.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_FILEAPI_MOCK_FILE_CHANGE_OBSERVER_H_
#define CONTENT_BROWSER_FILEAPI_MOCK_FILE_CHANGE_OBSERVER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "storage/browser/fileapi/file_observers.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/task_runner_bound_observer_list.h"
diff --git a/chromium/content/browser/fileapi/mock_file_update_observer.cc b/chromium/content/browser/fileapi/mock_file_update_observer.cc
index 2951d3ec77e..fb51a522f2b 100644
--- a/chromium/content/browser/fileapi/mock_file_update_observer.cc
+++ b/chromium/content/browser/fileapi/mock_file_update_observer.cc
@@ -26,7 +26,7 @@ void MockFileUpdateObserver::OnStartUpdate(const FileSystemURL& url) {
++start_update_count_[url];
}
-void MockFileUpdateObserver::OnUpdate(const FileSystemURL& url, int64 delta) {
+void MockFileUpdateObserver::OnUpdate(const FileSystemURL& url, int64_t delta) {
if (!is_ready_)
return;
int start = start_update_count_[url];
diff --git a/chromium/content/browser/fileapi/mock_file_update_observer.h b/chromium/content/browser/fileapi/mock_file_update_observer.h
index 64bd85e46c6..c4af5c05460 100644
--- a/chromium/content/browser/fileapi/mock_file_update_observer.h
+++ b/chromium/content/browser/fileapi/mock_file_update_observer.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_FILEAPI_MOCK_FILE_UPDATE_OBSERVER_H_
#define CONTENT_BROWSER_FILEAPI_MOCK_FILE_UPDATE_OBSERVER_H_
+#include <stdint.h>
+
#include <map>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "storage/browser/fileapi/file_observers.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/task_runner_bound_observer_list.h"
@@ -26,7 +28,7 @@ class MockFileUpdateObserver : public FileUpdateObserver {
// FileUpdateObserver overrides.
void OnStartUpdate(const FileSystemURL& url) override;
- void OnUpdate(const FileSystemURL& url, int64 delta) override;
+ void OnUpdate(const FileSystemURL& url, int64_t delta) override;
void OnEndUpdate(const FileSystemURL& url) override;
void Enable() { is_ready_ = true; }
diff --git a/chromium/content/browser/fileapi/mock_url_request_delegate.cc b/chromium/content/browser/fileapi/mock_url_request_delegate.cc
index 455b4586d18..79333b740e5 100644
--- a/chromium/content/browser/fileapi/mock_url_request_delegate.cc
+++ b/chromium/content/browser/fileapi/mock_url_request_delegate.cc
@@ -4,6 +4,8 @@
#include "content/browser/fileapi/mock_url_request_delegate.h"
+#include <stddef.h>
+
#include "base/run_loop.h"
#include "net/base/io_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -66,7 +68,7 @@ void MockURLRequestDelegate::ReceiveData(net::URLRequest* request,
}
void MockURLRequestDelegate::RequestComplete() {
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
} // namespace
diff --git a/chromium/content/browser/fileapi/native_file_util_unittest.cc b/chromium/content/browser/fileapi/native_file_util_unittest.cc
index 85aadb672f7..210f8b9cca5 100644
--- a/chromium/content/browser/fileapi/native_file_util_unittest.cc
+++ b/chromium/content/browser/fileapi/native_file_util_unittest.cc
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <set>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "storage/browser/fileapi/native_file_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -37,7 +40,7 @@ class NativeFileUtilTest : public testing::Test {
!base::DirectoryExists(path);
}
- int64 GetSize(const base::FilePath& path) {
+ int64_t GetSize(const base::FilePath& path) {
base::File::Info info;
base::GetFileInfo(path, &info);
return info.size;
diff --git a/chromium/content/browser/fileapi/obfuscated_file_util_unittest.cc b/chromium/content/browser/fileapi/obfuscated_file_util_unittest.cc
index 06638ff9b8a..8d434fa1ca7 100644
--- a/chromium/content/browser/fileapi/obfuscated_file_util_unittest.cc
+++ b/chromium/content/browser/fileapi/obfuscated_file_util_unittest.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <limits>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -11,9 +15,11 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/fileapi/mock_file_change_observer.h"
#include "content/public/test/async_file_test_helper.h"
#include "content/public/test/mock_special_storage_policy.h"
@@ -54,8 +60,8 @@ bool FileExists(const base::FilePath& path) {
return base::PathExists(path) && !base::DirectoryExists(path);
}
-int64 GetSize(const base::FilePath& path) {
- int64 size;
+int64_t GetSize(const base::FilePath& path) {
+ int64_t size;
EXPECT_TRUE(base::GetFileSize(path, &size));
return size;
}
@@ -182,15 +188,15 @@ class ObfuscatedFileUtilTest : public testing::Test {
}
scoped_ptr<FileSystemOperationContext> LimitedContext(
- int64 allowed_bytes_growth) {
+ int64_t allowed_bytes_growth) {
scoped_ptr<FileSystemOperationContext> context(
sandbox_file_system_.NewOperationContext());
context->set_allowed_bytes_growth(allowed_bytes_growth);
- return context.Pass();
+ return context;
}
scoped_ptr<FileSystemOperationContext> UnlimitedContext() {
- return LimitedContext(kint64max);
+ return LimitedContext(std::numeric_limits<int64_t>::max());
}
FileSystemOperationContext* NewContext(
@@ -253,13 +259,13 @@ class ObfuscatedFileUtilTest : public testing::Test {
return GetTypeString(type_);
}
- int64 ComputeTotalFileSize() {
+ int64_t ComputeTotalFileSize() {
return sandbox_file_system_.ComputeCurrentOriginUsage() -
sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
}
void GetUsageFromQuotaManager() {
- int64 quota = -1;
+ int64_t quota = -1;
quota_status_ =
AsyncFileTestHelper::GetUsageAndQuota(quota_manager_.get(),
origin(),
@@ -274,13 +280,13 @@ class ObfuscatedFileUtilTest : public testing::Test {
usage_cache()->Delete(sandbox_file_system_.GetUsageCachePath());
}
- int64 SizeByQuotaUtil() {
+ int64_t SizeByQuotaUtil() {
return sandbox_file_system_.GetCachedOriginUsage();
}
- int64 SizeInUsageFile() {
+ int64_t SizeInUsageFile() {
base::RunLoop().RunUntilIdle();
- int64 usage = 0;
+ int64_t usage = 0;
return usage_cache()->GetUsage(
sandbox_file_system_.GetUsageCachePath(), &usage) ? usage : -1;
}
@@ -298,7 +304,7 @@ class ObfuscatedFileUtilTest : public testing::Test {
return AsyncFileTestHelper::DirectoryExists(file_system_context(), url);
}
- int64 usage() const { return usage_; }
+ int64_t usage() const { return usage_; }
storage::FileSystemUsageCache* usage_cache() {
return sandbox_file_system_.usage_cache();
}
@@ -307,7 +313,7 @@ class ObfuscatedFileUtilTest : public testing::Test {
return sandbox_file_system_.CreateURLFromUTF8(path);
}
- int64 PathCost(const FileSystemURL& url) {
+ int64_t PathCost(const FileSystemURL& url) {
return ObfuscatedFileUtil::ComputeFilePathCost(url.path());
}
@@ -393,8 +399,8 @@ class ObfuscatedFileUtilTest : public testing::Test {
public:
UsageVerifyHelper(scoped_ptr<FileSystemOperationContext> context,
SandboxFileSystemTestHelper* file_system,
- int64 expected_usage)
- : context_(context.Pass()),
+ int64_t expected_usage)
+ : context_(std::move(context)),
sandbox_file_system_(file_system),
expected_usage_(expected_usage) {}
@@ -415,18 +421,19 @@ class ObfuscatedFileUtilTest : public testing::Test {
scoped_ptr<FileSystemOperationContext> context_;
SandboxFileSystemTestHelper* sandbox_file_system_;
- int64 expected_usage_;
+ int64_t expected_usage_;
};
- scoped_ptr<UsageVerifyHelper> AllowUsageIncrease(int64 requested_growth) {
- int64 usage = sandbox_file_system_.GetCachedOriginUsage();
+ scoped_ptr<UsageVerifyHelper> AllowUsageIncrease(int64_t requested_growth) {
+ int64_t usage = sandbox_file_system_.GetCachedOriginUsage();
return scoped_ptr<UsageVerifyHelper>(new UsageVerifyHelper(
LimitedContext(requested_growth),
&sandbox_file_system_, usage + requested_growth));
}
- scoped_ptr<UsageVerifyHelper> DisallowUsageIncrease(int64 requested_growth) {
- int64 usage = sandbox_file_system_.GetCachedOriginUsage();
+ scoped_ptr<UsageVerifyHelper> DisallowUsageIncrease(
+ int64_t requested_growth) {
+ int64_t usage = sandbox_file_system_.GetCachedOriginUsage();
return scoped_ptr<UsageVerifyHelper>(new UsageVerifyHelper(
LimitedContext(requested_growth - 1), &sandbox_file_system_, usage));
}
@@ -544,7 +551,7 @@ class ObfuscatedFileUtilTest : public testing::Test {
base::FilePath root_file_path = source_dir.path();
base::FilePath src_file_path = root_file_path.AppendASCII("file_name");
FileSystemURL dest_url = CreateURLFromUTF8("new file");
- int64 src_file_length = 87;
+ int64_t src_file_length = 87;
base::File file(src_file_path,
base::File::FLAG_CREATE | base::File::FLAG_WRITE);
@@ -567,7 +574,7 @@ class ObfuscatedFileUtilTest : public testing::Test {
EXPECT_TRUE(change_observer()->HasNoChange());
}
- const int64 path_cost =
+ const int64_t path_cost =
ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path());
if (!overwrite) {
// Verify that file creation requires sufficient quota for the path.
@@ -779,7 +786,7 @@ class ObfuscatedFileUtilTest : public testing::Test {
EXPECT_EQ(kFakeDirectoryData, origin_db_data);
}
- int64 ComputeCurrentUsage() {
+ int64_t ComputeCurrentUsage() {
return sandbox_file_system_.ComputeCurrentOriginUsage() -
sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
}
@@ -802,7 +809,7 @@ class ObfuscatedFileUtilTest : public testing::Test {
storage::FileSystemType type_;
SandboxFileSystemTestHelper sandbox_file_system_;
storage::QuotaStatusCode quota_status_;
- int64 usage_;
+ int64_t usage_;
storage::MockFileChangeObserver change_observer_;
storage::ChangeObserverList change_observers_;
base::WeakPtrFactory<ObfuscatedFileUtilTest> weak_factory_;
@@ -844,7 +851,7 @@ TEST_F(ObfuscatedFileUtilTest, TestCreateAndDeleteFile) {
ASSERT_TRUE(file.created());
EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
- CheckFileAndCloseHandle(url, file.Pass());
+ CheckFileAndCloseHandle(url, std::move(file));
context.reset(NewContext(NULL));
base::FilePath local_path;
@@ -880,7 +887,7 @@ TEST_F(ObfuscatedFileUtilTest, TestCreateAndDeleteFile) {
ASSERT_TRUE(file.created());
EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
- CheckFileAndCloseHandle(url, file.Pass());
+ CheckFileAndCloseHandle(url, std::move(file));
context.reset(NewContext(NULL));
EXPECT_EQ(base::File::FILE_OK,
@@ -1264,7 +1271,7 @@ TEST_F(ObfuscatedFileUtilTest, TestPathQuotas) {
EXPECT_EQ(base::File::FILE_OK,
ofu()->EnsureFileExists(context.get(), url, &created));
EXPECT_TRUE(created);
- int64 path_cost = ObfuscatedFileUtil::ComputeFilePathCost(url.path());
+ int64_t path_cost = ObfuscatedFileUtil::ComputeFilePathCost(url.path());
EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth());
context->set_allowed_bytes_growth(1024);
@@ -1330,8 +1337,8 @@ TEST_F(ObfuscatedFileUtilTest, TestCopyOrMoveFileNotFound) {
}
TEST_F(ObfuscatedFileUtilTest, TestCopyOrMoveFileSuccess) {
- const int64 kSourceLength = 5;
- const int64 kDestLength = 50;
+ const int64_t kSourceLength = 5;
+ const int64_t kDestLength = 50;
for (size_t i = 0; i < arraysize(kCopyMoveTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i);
@@ -1504,7 +1511,7 @@ TEST_F(ObfuscatedFileUtilTest, TestMovePathQuotasWithoutRename) {
dir_url, src_url.path().value());
bool is_copy = false;
- int64 allowed_bytes_growth = -1000; // Over quota, this should still work.
+ int64_t allowed_bytes_growth = -1000; // Over quota, this should still work.
// Move, no rename, no overwrite.
context.reset(NewContext(NULL));
context->set_allowed_bytes_growth(allowed_bytes_growth);
@@ -1655,7 +1662,7 @@ TEST_F(ObfuscatedFileUtilTest, TestOriginEnumerator) {
TEST_F(ObfuscatedFileUtilTest, TestRevokeUsageCache) {
scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
- int64 expected_quota = 0;
+ int64_t expected_quota = 0;
for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i);
@@ -2072,7 +2079,7 @@ TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) {
FileSystemURL to_file2(CreateURLFromUTF8("tofile2"));
bool created;
- int64 expected_total_file_size = 0;
+ int64_t expected_total_file_size = 0;
ASSERT_EQ(base::File::FILE_OK,
ofu()->EnsureFileExists(
AllowUsageIncrease(PathCost(from_file))->context(),
@@ -2087,7 +2094,7 @@ TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) {
ASSERT_TRUE(created);
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 from_file_size = 1020;
+ int64_t from_file_size = 1020;
expected_total_file_size += from_file_size;
ASSERT_EQ(base::File::FILE_OK,
ofu()->Truncate(
@@ -2095,7 +2102,7 @@ TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) {
from_file, from_file_size));
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 obstacle_file_size = 1;
+ int64_t obstacle_file_size = 1;
expected_total_file_size += obstacle_file_size;
ASSERT_EQ(base::File::FILE_OK,
ofu()->Truncate(
@@ -2103,7 +2110,7 @@ TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) {
obstacle_file, obstacle_file_size));
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 to_file1_size = from_file_size;
+ int64_t to_file1_size = from_file_size;
expected_total_file_size += to_file1_size;
ASSERT_EQ(base::File::FILE_OK,
ofu()->CopyOrMoveFile(
@@ -2122,7 +2129,7 @@ TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) {
true /* copy */));
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 old_obstacle_file_size = obstacle_file_size;
+ int64_t old_obstacle_file_size = obstacle_file_size;
obstacle_file_size = from_file_size;
expected_total_file_size += obstacle_file_size - old_obstacle_file_size;
ASSERT_EQ(base::File::FILE_OK,
@@ -2134,7 +2141,7 @@ TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) {
true /* copy */));
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 old_from_file_size = from_file_size;
+ int64_t old_from_file_size = from_file_size;
from_file_size = old_from_file_size - 1;
expected_total_file_size += from_file_size - old_from_file_size;
ASSERT_EQ(base::File::FILE_OK,
@@ -2169,7 +2176,7 @@ TEST_F(ObfuscatedFileUtilTest, TestQuotaOnMoveFile) {
FileSystemURL to_file(CreateURLFromUTF8("tofile"));
bool created;
- int64 expected_total_file_size = 0;
+ int64_t expected_total_file_size = 0;
ASSERT_EQ(base::File::FILE_OK,
ofu()->EnsureFileExists(
AllowUsageIncrease(PathCost(from_file))->context(),
@@ -2177,7 +2184,7 @@ TEST_F(ObfuscatedFileUtilTest, TestQuotaOnMoveFile) {
ASSERT_TRUE(created);
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 from_file_size = 1020;
+ int64_t from_file_size = 1020;
expected_total_file_size += from_file_size;
ASSERT_EQ(base::File::FILE_OK,
ofu()->Truncate(
@@ -2217,7 +2224,7 @@ TEST_F(ObfuscatedFileUtilTest, TestQuotaOnMoveFile) {
from_file, from_file_size));
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 obstacle_file_size = 1;
+ int64_t obstacle_file_size = 1;
expected_total_file_size += obstacle_file_size;
ASSERT_EQ(base::File::FILE_OK,
ofu()->Truncate(
@@ -2225,7 +2232,7 @@ TEST_F(ObfuscatedFileUtilTest, TestQuotaOnMoveFile) {
obstacle_file, obstacle_file_size));
ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
- int64 old_obstacle_file_size = obstacle_file_size;
+ int64_t old_obstacle_file_size = obstacle_file_size;
obstacle_file_size = from_file_size;
from_file_size = 0;
expected_total_file_size -= old_obstacle_file_size;
diff --git a/chromium/content/browser/fileapi/plugin_private_file_system_backend_unittest.cc b/chromium/content/browser/fileapi/plugin_private_file_system_backend_unittest.cc
index 8c5e45d0d37..e875e873762 100644
--- a/chromium/content/browser/fileapi/plugin_private_file_system_backend_unittest.cc
+++ b/chromium/content/browser/fileapi/plugin_private_file_system_backend_unittest.cc
@@ -2,7 +2,6 @@
// 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/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.h"
diff --git a/chromium/content/browser/fileapi/recursive_operation_delegate_unittest.cc b/chromium/content/browser/fileapi/recursive_operation_delegate_unittest.cc
index a99a5575a2d..abcdf54e65b 100644
--- a/chromium/content/browser/fileapi/recursive_operation_delegate_unittest.cc
+++ b/chromium/content/browser/fileapi/recursive_operation_delegate_unittest.cc
@@ -6,11 +6,11 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -73,7 +73,7 @@ class LoggingRecursiveOperation : public storage::RecursiveOperationDelegate {
}
operation_runner()->GetMetadata(
- url,
+ url, storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY,
base::Bind(&LoggingRecursiveOperation::DidGetMetadata,
weak_factory_.GetWeakPtr(), callback));
}
diff --git a/chromium/content/browser/fileapi/sandbox_database_test_helper.cc b/chromium/content/browser/fileapi/sandbox_database_test_helper.cc
index 205b653e370..45dbaff79c3 100644
--- a/chromium/content/browser/fileapi/sandbox_database_test_helper.cc
+++ b/chromium/content/browser/fileapi/sandbox_database_test_helper.cc
@@ -4,14 +4,16 @@
#include "content/browser/fileapi/sandbox_database_test_helper.h"
+#include <stdint.h>
+
#include <algorithm>
#include <functional>
+#include <limits>
#include <vector>
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
-#include "base/stl_util.h"
#include "storage/common/fileapi/file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,22 +29,23 @@ void CorruptDatabase(const base::FilePath& db_path,
base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
base::FilePath file_path;
base::FilePath picked_file_path;
- uint64 picked_file_number = kuint64max;
+ uint64_t picked_file_number = std::numeric_limits<uint64_t>::max();
while (!(file_path = file_enum.Next()).empty()) {
- uint64 number = kuint64max;
+ uint64_t number = std::numeric_limits<uint64_t>::max();
leveldb::FileType file_type;
EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
&number, &file_type));
if (file_type == type &&
- (picked_file_number == kuint64max || picked_file_number < number)) {
+ (picked_file_number == std::numeric_limits<uint64_t>::max() ||
+ picked_file_number < number)) {
picked_file_path = file_path;
picked_file_number = number;
}
}
EXPECT_FALSE(picked_file_path.empty());
- EXPECT_NE(kuint64max, picked_file_number);
+ EXPECT_NE(std::numeric_limits<uint64_t>::max(), picked_file_number);
base::File file(picked_file_path,
base::File::FLAG_OPEN | base::File::FLAG_READ |
@@ -60,7 +63,7 @@ void CorruptDatabase(const base::FilePath& db_path,
size = std::min(size, static_cast<size_t>(file_info.size - offset));
std::vector<char> buf(size);
- int read_size = file.Read(offset, vector_as_array(&buf), buf.size());
+ int read_size = file.Read(offset, buf.data(), buf.size());
EXPECT_LT(0, read_size);
EXPECT_GE(buf.size(), static_cast<size_t>(read_size));
buf.resize(read_size);
@@ -68,7 +71,7 @@ void CorruptDatabase(const base::FilePath& db_path,
std::transform(buf.begin(), buf.end(), buf.begin(),
std::logical_not<char>());
- int written_size = file.Write(offset, vector_as_array(&buf), buf.size());
+ int written_size = file.Write(offset, buf.data(), buf.size());
EXPECT_GT(written_size, 0);
EXPECT_EQ(buf.size(), static_cast<size_t>(written_size));
}
@@ -79,7 +82,7 @@ void DeleteDatabaseFile(const base::FilePath& db_path,
base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
base::FilePath file_path;
while (!(file_path = file_enum.Next()).empty()) {
- uint64 number = kuint64max;
+ uint64_t number = std::numeric_limits<uint64_t>::max();
leveldb::FileType file_type;
EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
&number, &file_type));
diff --git a/chromium/content/browser/fileapi/sandbox_database_test_helper.h b/chromium/content/browser/fileapi/sandbox_database_test_helper.h
index 881bdff2ce3..05ac2262be6 100644
--- a/chromium/content/browser/fileapi/sandbox_database_test_helper.h
+++ b/chromium/content/browser/fileapi/sandbox_database_test_helper.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
#define CONTENT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
-#include <cstddef>
+#include <stddef.h>
#include "third_party/leveldatabase/src/db/filename.h"
diff --git a/chromium/content/browser/fileapi/sandbox_directory_database_unittest.cc b/chromium/content/browser/fileapi/sandbox_directory_database_unittest.cc
index dcb74a272c2..7414856529d 100644
--- a/chromium/content/browser/fileapi/sandbox_directory_database_unittest.cc
+++ b/chromium/content/browser/fileapi/sandbox_directory_database_unittest.cc
@@ -5,11 +5,14 @@
#include "storage/browser/fileapi/sandbox_directory_database.h"
#include <math.h>
+#include <stddef.h>
+#include <stdint.h>
#include <limits>
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -496,7 +499,7 @@ TEST_F(SandboxDirectoryDatabaseTest, TestOverwritingMoveFileSuccess) {
}
TEST_F(SandboxDirectoryDatabaseTest, TestGetNextInteger) {
- int64 next = -1;
+ int64_t next = -1;
EXPECT_TRUE(db()->GetNextInteger(&next));
EXPECT_EQ(0, next);
EXPECT_TRUE(db()->GetNextInteger(&next));
@@ -514,7 +517,7 @@ TEST_F(SandboxDirectoryDatabaseTest, TestGetNextInteger) {
TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_Empty) {
EXPECT_TRUE(db()->IsFileSystemConsistent());
- int64 next = -1;
+ int64_t next = -1;
EXPECT_TRUE(db()->GetNextInteger(&next));
EXPECT_EQ(0, next);
EXPECT_TRUE(db()->IsFileSystemConsistent());
diff --git a/chromium/content/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc b/chromium/content/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc
index fd25aa7f937..d021229756c 100644
--- a/chromium/content/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc
+++ b/chromium/content/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc
@@ -4,7 +4,6 @@
#include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
-#include "base/basictypes.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.h"
diff --git a/chromium/content/browser/fileapi/sandbox_file_system_backend_unittest.cc b/chromium/content/browser/fileapi/sandbox_file_system_backend_unittest.cc
index 38630b87790..2787be01d2f 100644
--- a/chromium/content/browser/fileapi/sandbox_file_system_backend_unittest.cc
+++ b/chromium/content/browser/fileapi/sandbox_file_system_backend_unittest.cc
@@ -4,11 +4,13 @@
#include "storage/browser/fileapi/sandbox_file_system_backend.h"
+#include <stddef.h>
+
#include <set>
-#include "base/basictypes.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
diff --git a/chromium/content/browser/fileapi/sandbox_isolated_origin_database_unittest.cc b/chromium/content/browser/fileapi/sandbox_isolated_origin_database_unittest.cc
index 5f7f55f8005..f93fed770a8 100644
--- a/chromium/content/browser/fileapi/sandbox_isolated_origin_database_unittest.cc
+++ b/chromium/content/browser/fileapi/sandbox_isolated_origin_database_unittest.cc
@@ -2,7 +2,6 @@
// 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/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "storage/browser/fileapi/sandbox_isolated_origin_database.h"
diff --git a/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc b/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc
index 44dad2032d7..8338304e6a6 100644
--- a/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc
+++ b/chromium/content/browser/fileapi/sandbox_origin_database_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <algorithm>
#include <functional>
#include <limits>
@@ -12,6 +14,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/stl_util.h"
#include "content/browser/fileapi/sandbox_database_test_helper.h"
#include "storage/browser/fileapi/sandbox_origin_database.h"
diff --git a/chromium/content/browser/fileapi/sandbox_prioritized_origin_database_unittest.cc b/chromium/content/browser/fileapi/sandbox_prioritized_origin_database_unittest.cc
index 0fb01153a57..5c748a32bb9 100644
--- a/chromium/content/browser/fileapi/sandbox_prioritized_origin_database_unittest.cc
+++ b/chromium/content/browser/fileapi/sandbox_prioritized_origin_database_unittest.cc
@@ -2,7 +2,6 @@
// 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/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "storage/browser/fileapi/sandbox_origin_database.h"
diff --git a/chromium/content/browser/fileapi/timed_task_helper_unittest.cc b/chromium/content/browser/fileapi/timed_task_helper_unittest.cc
index 1bdc25d727a..11bdc0207b5 100644
--- a/chromium/content/browser/fileapi/timed_task_helper_unittest.cc
+++ b/chromium/content/browser/fileapi/timed_task_helper_unittest.cc
@@ -2,7 +2,6 @@
// 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/bind.h"
#include "base/location.h"
#include "base/memory/scoped_ptr.h"
diff --git a/chromium/content/browser/fileapi/transient_file_util_unittest.cc b/chromium/content/browser/fileapi/transient_file_util_unittest.cc
index 2ed8b746495..07e13f7016d 100644
--- a/chromium/content/browser/fileapi/transient_file_util_unittest.cc
+++ b/chromium/content/browser/fileapi/transient_file_util_unittest.cc
@@ -2,10 +2,10 @@
// 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/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "content/public/test/test_file_system_context.h"
diff --git a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc b/chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc
index 3cf45fe418c..1951b94c12b 100644
--- a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc
+++ b/chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc
@@ -19,8 +19,8 @@ namespace content {
UploadFileSystemFileElementReader::UploadFileSystemFileElementReader(
storage::FileSystemContext* file_system_context,
const GURL& url,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
const base::Time& expected_modification_time)
: file_system_context_(file_system_context),
url_(url),
@@ -29,8 +29,7 @@ UploadFileSystemFileElementReader::UploadFileSystemFileElementReader(
expected_modification_time_(expected_modification_time),
stream_length_(0),
position_(0),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
UploadFileSystemFileElementReader::~UploadFileSystemFileElementReader() {
}
@@ -44,18 +43,16 @@ int UploadFileSystemFileElementReader::Init(
// Initialize the stream reader and the length.
stream_reader_ = file_system_context_->CreateFileStreamReader(
- file_system_context_->CrackURL(url_),
- range_offset_,
- range_length_ == std::numeric_limits<uint64>::max()
+ file_system_context_->CrackURL(url_), range_offset_,
+ range_length_ == std::numeric_limits<uint64_t>::max()
? storage::kMaximumLength
- : base::checked_cast<int64>(range_length_),
+ : base::checked_cast<int64_t>(range_length_),
expected_modification_time_);
DCHECK(stream_reader_);
- const int64 result = stream_reader_->GetLength(
+ const int64_t result = stream_reader_->GetLength(
base::Bind(&UploadFileSystemFileElementReader::OnGetLength,
- weak_ptr_factory_.GetWeakPtr(),
- callback));
+ weak_ptr_factory_.GetWeakPtr(), callback));
if (result >= 0) {
stream_length_ = result;
return net::OK;
@@ -65,11 +62,11 @@ int UploadFileSystemFileElementReader::Init(
return static_cast<int>(result);
}
-uint64 UploadFileSystemFileElementReader::GetContentLength() const {
+uint64_t UploadFileSystemFileElementReader::GetContentLength() const {
return std::min(stream_length_, range_length_);
}
-uint64 UploadFileSystemFileElementReader::BytesRemaining() const {
+uint64_t UploadFileSystemFileElementReader::BytesRemaining() const {
return GetContentLength() - position_;
}
@@ -80,8 +77,8 @@ int UploadFileSystemFileElementReader::Read(
DCHECK_LT(0, buf_length);
DCHECK(stream_reader_);
- const uint64 num_bytes_to_read =
- std::min(BytesRemaining(), static_cast<uint64>(buf_length));
+ const uint64_t num_bytes_to_read =
+ std::min(BytesRemaining(), static_cast<uint64_t>(buf_length));
if (num_bytes_to_read == 0)
return 0;
@@ -98,7 +95,7 @@ int UploadFileSystemFileElementReader::Read(
void UploadFileSystemFileElementReader::OnGetLength(
const net::CompletionCallback& callback,
- int64 result) {
+ int64_t result) {
if (result >= 0) {
stream_length_ = result;
callback.Run(net::OK);
diff --git a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.h b/chromium/content/browser/fileapi/upload_file_system_file_element_reader.h
index bc2a6f7a71a..5510ce540b6 100644
--- a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.h
+++ b/chromium/content/browser/fileapi/upload_file_system_file_element_reader.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_FILEAPI_UPLOAD_FILE_SYSTEM_FILE_ELEMENT_READER_H_
#define CONTENT_BROWSER_FILEAPI_UPLOAD_FILE_SYSTEM_FILE_ELEMENT_READER_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
@@ -28,33 +31,33 @@ class CONTENT_EXPORT UploadFileSystemFileElementReader :
UploadFileSystemFileElementReader(
storage::FileSystemContext* file_system_context,
const GURL& url,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
const base::Time& expected_modification_time);
~UploadFileSystemFileElementReader() override;
// UploadElementReader overrides:
int Init(const net::CompletionCallback& callback) override;
- uint64 GetContentLength() const override;
- uint64 BytesRemaining() const override;
+ uint64_t GetContentLength() const override;
+ uint64_t BytesRemaining() const override;
int Read(net::IOBuffer* buf,
int buf_length,
const net::CompletionCallback& callback) override;
private:
- void OnGetLength(const net::CompletionCallback& callback, int64 result);
+ void OnGetLength(const net::CompletionCallback& callback, int64_t result);
void OnRead(const net::CompletionCallback& callback, int result);
scoped_refptr<storage::FileSystemContext> file_system_context_;
const GURL url_;
- const uint64 range_offset_;
- const uint64 range_length_;
+ const uint64_t range_offset_;
+ const uint64_t range_length_;
const base::Time expected_modification_time_;
scoped_ptr<storage::FileStreamReader> stream_reader_;
- uint64 stream_length_;
- uint64 position_;
+ uint64_t stream_length_;
+ uint64_t position_;
base::WeakPtrFactory<UploadFileSystemFileElementReader> weak_ptr_factory_;
diff --git a/chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc b/chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc
index 7e16a725039..61ef5508f56 100644
--- a/chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc
+++ b/chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc
@@ -4,7 +4,13 @@
#include "content/browser/fileapi/upload_file_system_file_element_reader.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
+
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "content/public/test/async_file_test_helper.h"
@@ -60,12 +66,9 @@ class UploadFileSystemFileElementReaderTest : public testing::Test {
&file_modification_time_);
// Create and initialize a reader.
- reader_.reset(
- new UploadFileSystemFileElementReader(file_system_context_.get(),
- file_url_,
- 0,
- kuint64max,
- file_modification_time_));
+ reader_.reset(new UploadFileSystemFileElementReader(
+ file_system_context_.get(), file_url_, 0,
+ std::numeric_limits<uint64_t>::max(), file_modification_time_));
net::TestCompletionCallback callback;
ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(callback.callback()));
EXPECT_EQ(net::OK, callback.WaitForResult());
@@ -244,8 +247,8 @@ TEST_F(UploadFileSystemFileElementReaderTest, Range) {
net::TestCompletionCallback init_callback;
ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(net::OK, init_callback.WaitForResult());
- EXPECT_EQ(static_cast<uint64>(kLength), reader_->GetContentLength());
- EXPECT_EQ(static_cast<uint64>(kLength), reader_->BytesRemaining());
+ EXPECT_EQ(static_cast<uint64_t>(kLength), reader_->GetContentLength());
+ EXPECT_EQ(static_cast<uint64_t>(kLength), reader_->BytesRemaining());
scoped_refptr<net::IOBufferWithSize> buf = new net::IOBufferWithSize(kLength);
net::TestCompletionCallback read_callback;
ASSERT_EQ(net::ERR_IO_PENDING,
@@ -260,12 +263,9 @@ TEST_F(UploadFileSystemFileElementReaderTest, FileChanged) {
// Expect one second before the actual modification time to simulate change.
const base::Time expected_modification_time =
file_modification_time_ - base::TimeDelta::FromSeconds(1);
- reader_.reset(
- new UploadFileSystemFileElementReader(file_system_context_.get(),
- file_url_,
- 0,
- kuint64max,
- expected_modification_time));
+ reader_.reset(new UploadFileSystemFileElementReader(
+ file_system_context_.get(), file_url_, 0,
+ std::numeric_limits<uint64_t>::max(), expected_modification_time));
net::TestCompletionCallback init_callback;
ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult());
@@ -274,7 +274,8 @@ TEST_F(UploadFileSystemFileElementReaderTest, FileChanged) {
TEST_F(UploadFileSystemFileElementReaderTest, WrongURL) {
const GURL wrong_url = GetFileSystemURL("wrong_file_name.dat");
reader_.reset(new UploadFileSystemFileElementReader(
- file_system_context_.get(), wrong_url, 0, kuint64max, base::Time()));
+ file_system_context_.get(), wrong_url, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time()));
net::TestCompletionCallback init_callback;
ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, init_callback.WaitForResult());
diff --git a/chromium/content/browser/font_list_async.cc b/chromium/content/browser/font_list_async.cc
index 422531947a4..730f6731c50 100644
--- a/chromium/content/browser/font_list_async.cc
+++ b/chromium/content/browser/font_list_async.cc
@@ -4,6 +4,8 @@
#include "content/public/browser/font_list_async.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/values.h"
#include "content/common/font_list.h"
@@ -17,7 +19,7 @@ namespace {
void ReturnFontListToOriginalThread(
const base::Callback<void(scoped_ptr<base::ListValue>)>& callback,
scoped_ptr<base::ListValue> result) {
- callback.Run(result.Pass());
+ callback.Run(std::move(result));
}
void GetFontListInBlockingPool(
diff --git a/chromium/content/browser/frame_host/DEPS b/chromium/content/browser/frame_host/DEPS
index 09569cb1402..a6068f73b0b 100644
--- a/chromium/content/browser/frame_host/DEPS
+++ b/chromium/content/browser/frame_host/DEPS
@@ -5,6 +5,8 @@ include_rules = [
"-content/public/browser/web_contents.h",
"-content/public/browser/web_contents_delegate.h",
"-content/public/browser/web_contents_view.h",
+
+ "+third_party/kasko",
]
specific_include_rules = {
diff --git a/chromium/content/browser/frame_host/cross_process_frame_connector.cc b/chromium/content/browser/frame_host/cross_process_frame_connector.cc
index 7fb24a48369..1d8b23c0411 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.cc
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.cc
@@ -7,11 +7,13 @@
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_manager.h"
#include "content/browser/compositor/surface_utils.h"
+#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_manager.h"
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
#include "content/browser/renderer_host/render_view_host_impl.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/render_widget_host_view_base.h"
#include "content/common/frame_messages.h"
@@ -42,6 +44,7 @@ bool CrossProcessFrameConnector::OnMessageReceived(const IPC::Message& msg) {
OnReclaimCompositorResources)
IPC_MESSAGE_HANDLER(FrameHostMsg_ForwardInputEvent, OnForwardInputEvent)
IPC_MESSAGE_HANDLER(FrameHostMsg_FrameRectChanged, OnFrameRectChanged)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_VisibilityChanged, OnVisibilityChanged)
IPC_MESSAGE_HANDLER(FrameHostMsg_InitializeChildFrame,
OnInitializeChildFrame)
IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence, OnSatisfySequence)
@@ -74,7 +77,7 @@ void CrossProcessFrameConnector::RenderProcessGone() {
}
void CrossProcessFrameConnector::ChildFrameCompositorFrameSwapped(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
int host_id,
int route_id,
scoped_ptr<cc::CompositorFrame> frame) {
@@ -163,6 +166,30 @@ void CrossProcessFrameConnector::GetScreenInfo(blink::WebScreenInfo* results) {
static_cast<RenderWidgetHostViewBase*>(rwhv)->GetScreenInfo(results);
}
+void CrossProcessFrameConnector::UpdateCursor(const WebCursor& cursor) {
+ RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView();
+ if (root_view)
+ root_view->UpdateCursor(cursor);
+}
+
+void CrossProcessFrameConnector::TransformPointToRootCoordSpace(
+ const gfx::Point& point,
+ cc::SurfaceId surface_id,
+ gfx::Point* transformed_point) {
+ RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView();
+ *transformed_point = point;
+ if (root_view)
+ root_view->TransformPointToLocalCoordSpace(point, surface_id,
+ transformed_point);
+}
+
+bool CrossProcessFrameConnector::HasFocus() {
+ RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView();
+ if (root_view)
+ return root_view->HasFocus();
+ return false;
+}
+
void CrossProcessFrameConnector::OnForwardInputEvent(
const blink::WebInputEvent* event) {
if (!view_)
@@ -173,7 +200,7 @@ void CrossProcessFrameConnector::OnForwardInputEvent(
RenderWidgetHostImpl* parent_widget =
manager->ForInnerDelegate()
? manager->GetOuterRenderWidgetHostForKeyboardInput()
- : frame_proxy_in_parent_renderer_->GetRenderViewHost();
+ : frame_proxy_in_parent_renderer_->GetRenderViewHost()->GetWidget();
if (blink::WebInputEvent::isKeyboardEventType(event->type)) {
if (!parent_widget->GetLastKeyboardEvent())
@@ -202,6 +229,16 @@ void CrossProcessFrameConnector::OnFrameRectChanged(
SetSize(frame_rect);
}
+void CrossProcessFrameConnector::OnVisibilityChanged(bool visible) {
+ if (!view_)
+ return;
+
+ if (visible)
+ view_->Show();
+ else
+ view_->Hide();
+}
+
void CrossProcessFrameConnector::SetDeviceScaleFactor(float scale_factor) {
device_scale_factor_ = scale_factor;
// The RenderWidgetHost is null in unit tests.
@@ -218,4 +255,19 @@ void CrossProcessFrameConnector::SetSize(gfx::Rect frame_rect) {
view_->SetSize(frame_rect.size());
}
+RenderWidgetHostViewBase*
+CrossProcessFrameConnector::GetRootRenderWidgetHostView() {
+ RenderFrameHostImpl* top_host = frame_proxy_in_parent_renderer_->
+ frame_tree_node()->frame_tree()->root()->current_frame_host();
+
+ // This method should return the root RWHV from the top-level WebContents,
+ // in the case of nested WebContents.
+ while (top_host->frame_tree_node()->render_manager()->ForInnerDelegate()) {
+ top_host = top_host->frame_tree_node()->render_manager()->
+ GetOuterDelegateNode()->frame_tree()->root()->current_frame_host();
+ }
+
+ return static_cast<RenderWidgetHostViewBase*>(top_host->GetView());
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/cross_process_frame_connector.h b/chromium/content/browser/frame_host/cross_process_frame_connector.h
index 48547213e13..6f31ec606fa 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.h
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_CROSS_PROCESS_FRAME_CONNECTOR_H_
#define CONTENT_BROWSER_FRAME_HOST_CROSS_PROCESS_FRAME_CONNECTOR_H_
+#include <stdint.h>
+
#include "cc/output/compositor_frame.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/rect.h"
@@ -29,7 +31,9 @@ struct FrameHostMsg_ReclaimCompositorResources_Params;
namespace content {
class RenderFrameProxyHost;
class RenderWidgetHostImpl;
+class RenderWidgetHostViewBase;
class RenderWidgetHostViewChildFrame;
+class WebCursor;
// CrossProcessFrameConnector provides the platform view abstraction for
// RenderWidgetHostViewChildFrame allowing RWHVChildFrame to remain ignorant
@@ -84,7 +88,7 @@ class CONTENT_EXPORT CrossProcessFrameConnector {
void RenderProcessGone();
virtual void ChildFrameCompositorFrameSwapped(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
int host_id,
int route_id,
scoped_ptr<cc::CompositorFrame> frame);
@@ -96,6 +100,14 @@ class CONTENT_EXPORT CrossProcessFrameConnector {
gfx::Rect ChildFrameRect();
float device_scale_factor() const { return device_scale_factor_; }
void GetScreenInfo(blink::WebScreenInfo* results);
+ void UpdateCursor(const WebCursor& cursor);
+ void TransformPointToRootCoordSpace(const gfx::Point& point,
+ cc::SurfaceId surface_id,
+ gfx::Point* transformed_point);
+
+ // Determines whether the root RenderWidgetHostView (and thus the current
+ // page) has focus.
+ bool HasFocus();
private:
// Handlers for messages received from the parent frame.
@@ -105,6 +117,7 @@ class CONTENT_EXPORT CrossProcessFrameConnector {
const FrameHostMsg_ReclaimCompositorResources_Params& params);
void OnForwardInputEvent(const blink::WebInputEvent* event);
void OnFrameRectChanged(const gfx::Rect& frame_rect);
+ void OnVisibilityChanged(bool visible);
void OnInitializeChildFrame(gfx::Rect frame_rect, float scale_factor);
void OnSatisfySequence(const cc::SurfaceSequence& sequence);
void OnRequireSequence(const cc::SurfaceId& id,
@@ -113,6 +126,9 @@ class CONTENT_EXPORT CrossProcessFrameConnector {
void SetDeviceScaleFactor(float scale_factor);
void SetSize(gfx::Rect frame_rect);
+ // Retrieve the view for the top-level frame under the same WebContents.
+ RenderWidgetHostViewBase* GetRootRenderWidgetHostView();
+
// The RenderFrameProxyHost that routes messages to the parent frame's
// renderer process.
RenderFrameProxyHost* frame_proxy_in_parent_renderer_;
diff --git a/chromium/content/browser/frame_host/cross_site_transferring_request.h b/chromium/content/browser/frame_host/cross_site_transferring_request.h
index 0d696a3d69a..2d5d9228359 100644
--- a/chromium/content/browser/frame_host/cross_site_transferring_request.h
+++ b/chromium/content/browser/frame_host/cross_site_transferring_request.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_CROSS_SITE_TRANSFERRING_REQUEST_H_
#define CONTENT_BROWSER_FRAME_HOST_CROSS_SITE_TRANSFERRING_REQUEST_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
diff --git a/chromium/content/browser/frame_host/debug_urls.cc b/chromium/content/browser/frame_host/debug_urls.cc
index 21e6bd25052..f3190a74acb 100644
--- a/chromium/content/browser/frame_host/debug_urls.cc
+++ b/chromium/content/browser/frame_host/debug_urls.cc
@@ -22,6 +22,7 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/url_constants.h"
#include "ppapi/proxy/ppapi_messages.h"
+#include "third_party/kasko/kasko_features.h"
#include "url/gurl.h"
#if defined(ENABLE_PLUGINS)
@@ -42,7 +43,7 @@ const char kAsanCorruptHeapBlock[] = "/browser-corrupt-heap-block";
const char kAsanCorruptHeap[] = "/browser-corrupt-heap";
#endif
-#if defined(KASKO)
+#if BUILDFLAG(ENABLE_KASKO)
// Define the Kasko debug URLs.
const char kKaskoCrashDomain[] = "kasko";
const char kKaskoSendReport[] = "/send-report";
@@ -66,7 +67,7 @@ void HandlePpapiFlashDebugURL(const GURL& url) {
}
bool IsKaskoDebugURL(const GURL& url) {
-#if defined(KASKO)
+#if BUILDFLAG(ENABLE_KASKO)
return (url.is_valid() && url.SchemeIs(kChromeUIScheme) &&
url.DomainIs(kKaskoCrashDomain) &&
url.path() == kKaskoSendReport);
@@ -76,12 +77,27 @@ bool IsKaskoDebugURL(const GURL& url) {
}
void HandleKaskoDebugURL() {
-#if defined(KASKO)
+#if BUILDFLAG(ENABLE_KASKO)
+ // Signature of the exported crash key setting function.
+ using SetCrashKeyValueImplPtr = void(__cdecl *)(const wchar_t*,
+ const wchar_t*);
// Signature of an enhanced crash reporting function.
- typedef void(__cdecl * ReportCrashWithProtobufPtr)(EXCEPTION_POINTERS*,
+ using ReportCrashWithProtobufPtr = void(__cdecl *)(EXCEPTION_POINTERS*,
const char*);
HMODULE exe_hmodule = ::GetModuleHandle(NULL);
+
+ // First, set a crash key using the exported function reserved for Kasko
+ // clients (SyzyASAN for now).
+ SetCrashKeyValueImplPtr set_crash_key_value_impl =
+ reinterpret_cast<SetCrashKeyValueImplPtr>(
+ ::GetProcAddress(exe_hmodule, "SetCrashKeyValueImpl"));
+ if (set_crash_key_value_impl)
+ set_crash_key_value_impl(L"kasko-set-crash-key-value-impl", L"true");
+ else
+ NOTREACHED();
+
+ // Next, invoke a crash report via Kasko.
ReportCrashWithProtobufPtr report_crash_with_protobuf =
reinterpret_cast<ReportCrashWithProtobufPtr>(
::GetProcAddress(exe_hmodule, "ReportCrashWithProtobuf"));
@@ -162,7 +178,7 @@ bool HandleDebugURL(const GURL& url, ui::PageTransition transition) {
bool is_telemetry_navigation =
base::CommandLine::ForCurrentProcess()->HasSwitch(
cc::switches::kEnableGpuBenchmarking) &&
- (transition & ui::PAGE_TRANSITION_TYPED);
+ (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED));
if (!(transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) &&
!is_telemetry_navigation)
diff --git a/chromium/content/browser/frame_host/frame_mojo_shell.cc b/chromium/content/browser/frame_host/frame_mojo_shell.cc
index 91a38759741..ece035648f4 100644
--- a/chromium/content/browser/frame_host/frame_mojo_shell.cc
+++ b/chromium/content/browser/frame_host/frame_mojo_shell.cc
@@ -4,6 +4,9 @@
#include "content/browser/frame_host/frame_mojo_shell.h"
+#include <utility>
+
+#include "build/build_config.h"
#include "content/browser/mojo/mojo_shell_context.h"
#include "content/common/mojo/service_registry_impl.h"
#include "content/public/browser/content_browser_client.h"
@@ -11,8 +14,24 @@
#include "content/public/browser/site_instance.h"
#include "content/public/common/content_client.h"
+#if defined(OS_ANDROID) && defined(ENABLE_MOJO_MEDIA)
+#include "content/browser/media/android/provision_fetcher_impl.h"
+#endif
+
namespace content {
+namespace {
+
+void RegisterFrameMojoShellServices(ServiceRegistry* registry,
+ RenderFrameHost* render_frame_host) {
+#if defined(OS_ANDROID) && defined(ENABLE_MOJO_MEDIA)
+ registry->AddService(
+ base::Bind(&ProvisionFetcherImpl::Create, render_frame_host));
+#endif
+}
+
+} // namespace
+
FrameMojoShell::FrameMojoShell(RenderFrameHost* frame_host)
: frame_host_(frame_host) {
}
@@ -22,7 +41,7 @@ FrameMojoShell::~FrameMojoShell() {
void FrameMojoShell::BindRequest(
mojo::InterfaceRequest<mojo::Shell> shell_request) {
- bindings_.AddBinding(this, shell_request.Pass());
+ bindings_.AddBinding(this, std::move(shell_request));
}
// TODO(xhwang): Currently no callers are exposing |exposed_services|. So we
@@ -44,7 +63,8 @@ void FrameMojoShell::ConnectToApplication(
capability_filter = filter->filter.To<mojo::shell::CapabilityFilter>();
MojoShellContext::ConnectToApplication(
GURL(application_url->url), frame_host_->GetSiteInstance()->GetSiteURL(),
- services.Pass(), frame_services.Pass(), capability_filter, callback);
+ std::move(services), std::move(frame_services), capability_filter,
+ callback);
}
void FrameMojoShell::QuitApplication() {
@@ -54,6 +74,10 @@ ServiceRegistryImpl* FrameMojoShell::GetServiceRegistry() {
if (!service_registry_) {
service_registry_.reset(new ServiceRegistryImpl());
+ // TODO(rockot/xhwang): Currently all applications connected share the same
+ // set of services registered in the |registry|. We may want to provide
+ // different services for different apps for better isolation.
+ RegisterFrameMojoShellServices(service_registry_.get(), frame_host_);
GetContentClient()->browser()->RegisterFrameMojoShellServices(
service_registry_.get(), frame_host_);
}
diff --git a/chromium/content/browser/frame_host/frame_mojo_shell.h b/chromium/content/browser/frame_host/frame_mojo_shell.h
index b2817a0a505..08a60e9b831 100644
--- a/chromium/content/browser/frame_host/frame_mojo_shell.h
+++ b/chromium/content/browser/frame_host/frame_mojo_shell.h
@@ -7,9 +7,9 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "mojo/application/public/interfaces/shell.mojom.h"
#include "mojo/common/weak_binding_set.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/shell/public/interfaces/shell.mojom.h"
namespace content {
diff --git a/chromium/content/browser/frame_host/frame_navigation_entry.cc b/chromium/content/browser/frame_host/frame_navigation_entry.cc
index 77245990768..a7a414e85a3 100644
--- a/chromium/content/browser/frame_host/frame_navigation_entry.cc
+++ b/chromium/content/browser/frame_host/frame_navigation_entry.cc
@@ -13,35 +13,39 @@ FrameNavigationEntry::FrameNavigationEntry(int frame_tree_node_id)
}
FrameNavigationEntry::FrameNavigationEntry(int frame_tree_node_id,
- int64 item_sequence_number,
- int64 document_sequence_number,
+ const std::string& frame_unique_name,
+ int64_t item_sequence_number,
+ int64_t document_sequence_number,
SiteInstanceImpl* site_instance,
const GURL& url,
const Referrer& referrer)
: frame_tree_node_id_(frame_tree_node_id),
+ frame_unique_name_(frame_unique_name),
item_sequence_number_(item_sequence_number),
document_sequence_number_(document_sequence_number),
site_instance_(site_instance),
url_(url),
- referrer_(referrer) {
-}
+ referrer_(referrer) {}
FrameNavigationEntry::~FrameNavigationEntry() {
}
FrameNavigationEntry* FrameNavigationEntry::Clone() const {
FrameNavigationEntry* copy = new FrameNavigationEntry(frame_tree_node_id_);
- copy->UpdateEntry(item_sequence_number_, document_sequence_number_,
- site_instance_.get(), url_, referrer_, page_state_);
+ copy->UpdateEntry(frame_unique_name_, item_sequence_number_,
+ document_sequence_number_, site_instance_.get(), url_,
+ referrer_, page_state_);
return copy;
}
-void FrameNavigationEntry::UpdateEntry(int64 item_sequence_number,
- int64 document_sequence_number,
+void FrameNavigationEntry::UpdateEntry(const std::string& frame_unique_name,
+ int64_t item_sequence_number,
+ int64_t document_sequence_number,
SiteInstanceImpl* site_instance,
const GURL& url,
const Referrer& referrer,
const PageState& page_state) {
+ frame_unique_name_ = frame_unique_name;
item_sequence_number_ = item_sequence_number;
document_sequence_number_ = document_sequence_number;
site_instance_ = site_instance;
@@ -50,4 +54,20 @@ void FrameNavigationEntry::UpdateEntry(int64 item_sequence_number,
page_state_ = page_state;
}
+void FrameNavigationEntry::set_item_sequence_number(
+ int64_t item_sequence_number) {
+ // Once assigned, the item sequence number shouldn't change.
+ DCHECK(item_sequence_number_ == -1 ||
+ item_sequence_number_ == item_sequence_number);
+ item_sequence_number_ = item_sequence_number;
+}
+
+void FrameNavigationEntry::set_document_sequence_number(
+ int64_t document_sequence_number) {
+ // Once assigned, the document sequence number shouldn't change.
+ DCHECK(document_sequence_number_ == -1 ||
+ document_sequence_number_ == document_sequence_number);
+ document_sequence_number_ = document_sequence_number;
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/frame_navigation_entry.h b/chromium/content/browser/frame_host/frame_navigation_entry.h
index 9dbaff20dcf..67a27063700 100644
--- a/chromium/content/browser/frame_host/frame_navigation_entry.h
+++ b/chromium/content/browser/frame_host/frame_navigation_entry.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_FRAME_NAVIGATION_ENTRY_H_
#define CONTENT_BROWSER_FRAME_HOST_FRAME_NAVIGATION_ENTRY_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/site_instance_impl.h"
#include "content/public/common/page_state.h"
@@ -19,19 +21,18 @@ namespace content {
// For now, it is owned by a single NavigationEntry and only tracks the main
// frame.
//
-// TODO(creis): In --site-per-process, fill in a tree of FrameNavigationEntries
-// in each NavigationEntry, one per frame. FrameNavigationEntries may be shared
-// across NavigationEntries if the frame hasn't changed.
+// If SiteIsolationPolicy::UseSubframeNavigationEntries is true, there will be a
+// tree of FrameNavigationEntries in each NavigationEntry, one per frame.
+// TODO(creis): Share these FrameNavigationEntries across NavigationEntries if
+// the frame hasn't changed.
class CONTENT_EXPORT FrameNavigationEntry
: public base::RefCounted<FrameNavigationEntry> {
public:
- // TODO(creis): We should not use FTN IDs here, since they will change if you
- // leave a page and come back later. We should evaluate whether Blink's
- // unique names would work instead, similar to HistoryNode.
explicit FrameNavigationEntry(int frame_tree_node_id);
FrameNavigationEntry(int frame_tree_node_id,
- int64 item_sequence_number,
- int64 document_sequence_number,
+ const std::string& frame_unique_name,
+ int64_t item_sequence_number,
+ int64_t document_sequence_number,
SiteInstanceImpl* site_instance,
const GURL& url,
const Referrer& referrer);
@@ -41,8 +42,9 @@ class CONTENT_EXPORT FrameNavigationEntry
FrameNavigationEntry* Clone() const;
// Updates all the members of this entry.
- void UpdateEntry(int64 item_sequence_number,
- int64 document_sequence_number,
+ void UpdateEntry(const std::string& frame_unique_name,
+ int64_t item_sequence_number,
+ int64_t document_sequence_number,
SiteInstanceImpl* site_instance,
const GURL& url,
const Referrer& referrer,
@@ -51,22 +53,36 @@ class CONTENT_EXPORT FrameNavigationEntry
// The ID of the FrameTreeNode this entry is for. -1 for the main frame,
// since we don't always know the FrameTreeNode ID when creating the overall
// NavigationEntry.
- // TODO(creis): Replace with frame sequence number or unique name.
+ // TODO(creis): Consider removing |frame_tree_node_id| in favor of
+ // |frame_unique_name|, if we can move unique name computation to the browser
+ // process.
int frame_tree_node_id() const { return frame_tree_node_id_; }
+ void set_frame_tree_node_id(int frame_tree_node_id) {
+ frame_tree_node_id_ = frame_tree_node_id;
+ }
+
+ // The unique name of the frame this entry is for. This is a stable name for
+ // the frame based on its position in the tree and relation to other named
+ // frames, which does not change after cross-process navigations or restores.
+ // Only the main frame can have an empty name.
+ //
+ // This is unique relative to other frames in the same page, but not among
+ // other pages (i.e., not globally unique).
+ const std::string& frame_unique_name() const { return frame_unique_name_; }
+ void set_frame_unique_name(const std::string& frame_unique_name) {
+ frame_unique_name_ = frame_unique_name;
+ }
// Keeps track of where this entry belongs in the frame's session history.
// The item sequence number identifies each stop in the back/forward history
// and is globally unique. The document sequence number increments for each
// new document and is also globally unique. In-page navigations get a new
- // item sequence number but the same document sequence number.
- void set_item_sequence_number(int64 item_sequence_number) {
- item_sequence_number_ = item_sequence_number;
- }
- int64 item_sequence_number() const { return item_sequence_number_; }
- void set_document_sequence_number(int64 document_sequence_number) {
- document_sequence_number_ = document_sequence_number;
- }
- int64 document_sequence_number() const { return document_sequence_number_; }
+ // item sequence number but the same document sequence number. These numbers
+ // should not change once assigned.
+ void set_item_sequence_number(int64_t item_sequence_number);
+ int64_t item_sequence_number() const { return item_sequence_number_; }
+ void set_document_sequence_number(int64_t document_sequence_number);
+ int64_t document_sequence_number() const { return document_sequence_number_; }
// The SiteInstance responsible for rendering this frame. All frames sharing
// a SiteInstance must live in the same process. This is a refcounted pointer
@@ -94,15 +110,16 @@ class CONTENT_EXPORT FrameNavigationEntry
virtual ~FrameNavigationEntry();
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- // For all new fields, update |Clone|.
+ // Add all new fields to |UpdateEntry|.
// TODO(creis): These fields have implications for session restore. This is
// currently managed by NavigationEntry, but the logic will move here.
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
// See the accessors above for descriptions.
int frame_tree_node_id_;
- int64 item_sequence_number_;
- int64 document_sequence_number_;
+ std::string frame_unique_name_;
+ int64_t item_sequence_number_;
+ int64_t document_sequence_number_;
scoped_refptr<SiteInstanceImpl> site_instance_;
GURL url_;
Referrer referrer_;
diff --git a/chromium/content/browser/frame_host/frame_tree.cc b/chromium/content/browser/frame_host/frame_tree.cc
index ac4b1db9069..e92d28f80be 100644
--- a/chromium/content/browser/frame_host/frame_tree.cc
+++ b/chromium/content/browser/frame_host/frame_tree.cc
@@ -4,6 +4,8 @@
#include "content/browser/frame_host/frame_tree.h"
+#include <stddef.h>
+
#include <queue>
#include <utility>
@@ -18,6 +20,7 @@
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/common/input_messages.h"
#include "content/common/site_isolation_policy.h"
#include "third_party/WebKit/public/web/WebSandboxFlags.h"
@@ -94,6 +97,14 @@ bool IsNodeLoading(bool* is_loading, FrameTreeNode* node) {
return true;
}
+// Helper function used with FrameTree::ForEach to collect SiteInstances
+// involved in rendering a single FrameTree (which is a subset of SiteInstances
+// in main frame's proxy_hosts_ because of openers).
+bool CollectSiteInstances(std::set<SiteInstance*>* set, FrameTreeNode* node) {
+ set->insert(node->current_frame_host()->GetSiteInstance());
+ return true;
+}
+
} // namespace
FrameTree::FrameTree(Navigator* navigator,
@@ -115,12 +126,14 @@ FrameTree::FrameTree(Navigator* navigator,
// document scope.
blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None)),
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties())),
focused_frame_tree_node_id_(-1),
- load_progress_(0.0) {
-}
+ load_progress_(0.0) {}
FrameTree::~FrameTree() {
+ delete root_;
+ root_ = nullptr;
}
FrameTreeNode* FrameTree::FindByID(int frame_tree_node_id) {
@@ -151,7 +164,7 @@ FrameTreeNode* FrameTree::FindByRoutingID(int process_id, int routing_id) {
FrameTreeNode* FrameTree::FindByName(const std::string& name) {
if (name.empty())
- return root_.get();
+ return root_;
FrameTreeNode* node = nullptr;
ForEach(base::Bind(&FrameTreeNodeForName, name, &node));
@@ -167,7 +180,7 @@ void FrameTree::ForEach(
const base::Callback<bool(FrameTreeNode*)>& on_node,
FrameTreeNode* skip_this_subtree) const {
std::queue<FrameTreeNode*> queue;
- queue.push(root_.get());
+ queue.push(root_);
while (!queue.empty()) {
FrameTreeNode* node = queue.front();
@@ -183,29 +196,36 @@ void FrameTree::ForEach(
}
}
-RenderFrameHostImpl* FrameTree::AddFrame(FrameTreeNode* parent,
- int process_id,
- int new_routing_id,
- blink::WebTreeScopeType scope,
- const std::string& frame_name,
- blink::WebSandboxFlags sandbox_flags) {
+bool FrameTree::AddFrame(
+ FrameTreeNode* parent,
+ int process_id,
+ int new_routing_id,
+ blink::WebTreeScopeType scope,
+ const std::string& frame_name,
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties) {
+ CHECK_NE(new_routing_id, MSG_ROUTING_NONE);
+
// A child frame always starts with an initial empty document, which means
// it is in the same SiteInstance as the parent frame. Ensure that the process
// which requested a child frame to be added is the same as the process of the
// parent node.
- // We return nullptr if this is not the case, which can happen in a race if an
- // old RFH sends a CreateChildFrame message as we're swapping to a new RFH.
if (parent->current_frame_host()->GetProcess()->GetID() != process_id)
- return nullptr;
+ return false;
- scoped_ptr<FrameTreeNode> node(
- new FrameTreeNode(this, parent->navigator(), render_frame_delegate_,
- render_view_delegate_, render_widget_delegate_,
- manager_delegate_, scope, frame_name, sandbox_flags));
- FrameTreeNode* node_ptr = node.get();
// AddChild is what creates the RenderFrameHost.
- parent->AddChild(node.Pass(), process_id, new_routing_id);
- return node_ptr->current_frame_host();
+ FrameTreeNode* added_node = parent->AddChild(
+ make_scoped_ptr(new FrameTreeNode(
+ this, parent->navigator(), render_frame_delegate_,
+ render_view_delegate_, render_widget_delegate_, manager_delegate_,
+ scope, frame_name, sandbox_flags, frame_owner_properties)),
+ process_id, new_routing_id);
+
+ // Now that the new node is part of the FrameTree and has a RenderFrameHost,
+ // we can announce the creation of the initial RenderFrame which already
+ // exists in the renderer process.
+ added_node->current_frame_host()->SetRenderFrameCreated(true);
+ return true;
}
void FrameTree::RemoveFrame(FrameTreeNode* child) {
@@ -231,8 +251,7 @@ void FrameTree::CreateProxiesForSiteInstance(
root()->render_manager()->CreateRenderFrameProxy(site_instance);
} else {
root()->render_manager()->CreateRenderFrame(
- site_instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
- nullptr);
+ site_instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr);
}
} else {
root()->render_manager()->EnsureRenderViewInitialized(render_view_host,
@@ -256,20 +275,42 @@ FrameTreeNode* FrameTree::GetFocusedFrame() {
return FindByID(focused_frame_tree_node_id_);
}
-void FrameTree::SetFocusedFrame(FrameTreeNode* node) {
- // If the focused frame changed across processes, send a message to the old
- // focused frame's renderer process to clear focus from that frame and fire
- // blur events.
- FrameTreeNode* oldFocusedFrame = GetFocusedFrame();
- if (oldFocusedFrame &&
- oldFocusedFrame->current_frame_host()->GetSiteInstance() !=
- node->current_frame_host()->GetSiteInstance()) {
- DCHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
- oldFocusedFrame->current_frame_host()->ClearFocus();
+void FrameTree::SetFocusedFrame(FrameTreeNode* node, SiteInstance* source) {
+ if (node == GetFocusedFrame())
+ return;
+
+ std::set<SiteInstance*> frame_tree_site_instances;
+ ForEach(base::Bind(&CollectSiteInstances, &frame_tree_site_instances));
+
+ SiteInstance* current_instance =
+ node->current_frame_host()->GetSiteInstance();
+
+ // Update the focused frame in all other SiteInstances. If focus changes to
+ // a cross-process frame, this allows the old focused frame's renderer
+ // process to clear focus from that frame and fire blur events. It also
+ // ensures that the latest focused frame is available in all renderers to
+ // compute document.activeElement.
+ //
+ // We do not notify the |source| SiteInstance because it already knows the
+ // new focused frame (since it initiated the focus change), and we notify the
+ // new focused frame's SiteInstance (if it differs from |source|) separately
+ // below.
+ for (const auto& instance : frame_tree_site_instances) {
+ if (instance != source && instance != current_instance) {
+ DCHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
+ RenderFrameProxyHost* proxy =
+ node->render_manager()->GetRenderFrameProxyHost(instance);
+ proxy->SetFocusedFrame();
+ }
}
- node->set_last_focus_time(base::TimeTicks::Now());
+ // If |node| was focused from a cross-process frame (i.e., via
+ // window.focus()), tell its RenderFrame that it should focus.
+ if (current_instance != source)
+ node->current_frame_host()->SetFocusedFrame();
+
focused_frame_tree_node_id_ = node->frame_tree_node_id();
+ node->DidFocus();
}
void FrameTree::SetFrameRemoveListener(
@@ -277,11 +318,12 @@ void FrameTree::SetFrameRemoveListener(
on_frame_removed_ = on_frame_removed;
}
-RenderViewHostImpl* FrameTree::CreateRenderViewHost(SiteInstance* site_instance,
- int32 routing_id,
- int32 main_frame_routing_id,
- bool swapped_out,
- bool hidden) {
+RenderViewHostImpl* FrameTree::CreateRenderViewHost(
+ SiteInstance* site_instance,
+ int32_t routing_id,
+ int32_t main_frame_routing_id,
+ bool swapped_out,
+ bool hidden) {
RenderViewHostMap::iterator iter =
render_view_host_map_.find(site_instance->GetId());
if (iter != render_view_host_map_.end()) {
@@ -328,7 +370,7 @@ void FrameTree::AddRenderViewHostRef(RenderViewHostImpl* render_view_host) {
void FrameTree::ReleaseRenderViewHostRef(RenderViewHostImpl* render_view_host) {
SiteInstance* site_instance = render_view_host->GetSiteInstance();
- int32 site_instance_id = site_instance->GetId();
+ int32_t site_instance_id = site_instance->GetId();
RenderViewHostMap::iterator iter =
render_view_host_map_.find(site_instance_id);
if (iter != render_view_host_map_.end() && iter->second == render_view_host) {
@@ -337,7 +379,7 @@ void FrameTree::ReleaseRenderViewHostRef(RenderViewHostImpl* render_view_host) {
CHECK_GT(iter->second->ref_count(), 0);
iter->second->decrement_ref_count();
if (iter->second->ref_count() == 0) {
- iter->second->Shutdown();
+ iter->second->ShutdownAndDestroy();
render_view_host_map_.erase(iter);
}
} else {
@@ -358,7 +400,7 @@ void FrameTree::ReleaseRenderViewHostRef(RenderViewHostImpl* render_view_host) {
CHECK_GT(render_view_host->ref_count(), 0);
render_view_host->decrement_ref_count();
if (render_view_host->ref_count() == 0) {
- render_view_host->Shutdown();
+ render_view_host->ShutdownAndDestroy();
render_view_host_pending_shutdown_map_.erase(multi_iter);
}
break;
@@ -373,7 +415,7 @@ void FrameTree::FrameRemoved(FrameTreeNode* frame) {
// No notification for the root frame.
if (!frame->parent()) {
- CHECK_EQ(frame, root_.get());
+ CHECK_EQ(frame, root_);
return;
}
@@ -409,4 +451,29 @@ bool FrameTree::IsLoading() {
return is_loading;
}
+void FrameTree::ReplicatePageFocus(bool is_focused) {
+ std::set<SiteInstance*> frame_tree_site_instances;
+ ForEach(base::Bind(&CollectSiteInstances, &frame_tree_site_instances));
+
+ // Send the focus update to main frame's proxies in all SiteInstances of
+ // other frames in this FrameTree. Note that the main frame might also know
+ // about proxies in SiteInstances for frames in a different FrameTree (e.g.,
+ // for window.open), so we can't just iterate over its proxy_hosts_ in
+ // RenderFrameHostManager.
+ for (const auto& instance : frame_tree_site_instances)
+ SetPageFocus(instance, is_focused);
+}
+
+void FrameTree::SetPageFocus(SiteInstance* instance, bool is_focused) {
+ RenderFrameHostManager* root_manager = root_->render_manager();
+
+ // This is only used to set page-level focus in cross-process subframes, and
+ // requests to set focus in main frame's SiteInstance are ignored.
+ if (instance != root_manager->current_frame_host()->GetSiteInstance()) {
+ RenderFrameProxyHost* proxy =
+ root_manager->GetRenderFrameProxyHost(instance);
+ proxy->Send(new InputMsg_SetFocus(proxy->GetRoutingID(), is_focused));
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/frame_tree.h b/chromium/content/browser/frame_host/frame_tree.h
index 02412880785..6fc21f61cb0 100644
--- a/chromium/content/browser/frame_host/frame_tree.h
+++ b/chromium/content/browser/frame_host/frame_tree.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_FRAME_TREE_H_
#define CONTENT_BROWSER_FRAME_HOST_FRAME_TREE_H_
+#include <stdint.h>
+
#include <string>
#include "base/callback.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/common/content_export.h"
@@ -51,7 +54,7 @@ class CONTENT_EXPORT FrameTree {
RenderFrameHostManager::Delegate* manager_delegate);
~FrameTree();
- FrameTreeNode* root() const { return root_.get(); }
+ FrameTreeNode* root() const { return root_; }
// Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
// of this FrameTree.
@@ -73,17 +76,20 @@ class CONTENT_EXPORT FrameTree {
// it safe to remove children during the callback.
void ForEach(const base::Callback<bool(FrameTreeNode*)>& on_node) const;
- // Frame tree manipulation routines.
- // |process_id| is required to disambiguate |new_routing_id|, and it must
- // match the process of the |parent| node. Otherwise this method returns
- // nullptr. Passing MSG_ROUTING_NONE for |new_routing_id| will allocate a new
- // routing ID for the new frame.
- RenderFrameHostImpl* AddFrame(FrameTreeNode* parent,
- int process_id,
- int new_routing_id,
- blink::WebTreeScopeType scope,
- const std::string& frame_name,
- blink::WebSandboxFlags sandbox_flags);
+ // Adds a new child frame to the frame tree. |process_id| is required to
+ // disambiguate |new_routing_id|, and it must match the process of the
+ // |parent| node. Otherwise no child is added and this method returns false.
+ bool AddFrame(FrameTreeNode* parent,
+ int process_id,
+ int new_routing_id,
+ blink::WebTreeScopeType scope,
+ const std::string& frame_name,
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties);
+
+ // Removes a frame from the frame tree. |child|, its children, and objects
+ // owned by their RenderFrameHostManagers are immediately deleted. The root
+ // node cannot be removed this way.
void RemoveFrame(FrameTreeNode* child);
// This method walks the entire frame tree and creates a RenderFrameProxyHost
@@ -101,8 +107,12 @@ class CONTENT_EXPORT FrameTree {
// Returns the focused frame.
FrameTreeNode* GetFocusedFrame();
- // Sets the focused frame.
- void SetFocusedFrame(FrameTreeNode* node);
+ // Sets the focused frame to |node|. |source| identifies the SiteInstance
+ // that initiated this focus change. If this FrameTree has SiteInstances
+ // other than |source|, those SiteInstances will be notified about the new
+ // focused frame. Note that |source| may differ from |node|'s current
+ // SiteInstance (e.g., this happens for cross-process window.focus() calls).
+ void SetFocusedFrame(FrameTreeNode* node, SiteInstance* source);
// Allows a client to listen for frame removal. The listener should expect
// to receive the RenderViewHostImpl containing the frame and the renderer-
@@ -114,8 +124,8 @@ class CONTENT_EXPORT FrameTree {
// |site_instance|. The RenderViewHost will have its Shutdown method called
// when all of the RenderFrameHosts using it are deleted.
RenderViewHostImpl* CreateRenderViewHost(SiteInstance* site_instance,
- int32 routing_id,
- int32 main_frame_routing_id,
+ int32_t routing_id,
+ int32_t main_frame_routing_id,
bool swapped_out,
bool hidden);
@@ -146,6 +156,16 @@ class CONTENT_EXPORT FrameTree {
// Returns true if at least one of the nodes in this FrameTree is loading.
bool IsLoading();
+ // Set page-level focus in all SiteInstances involved in rendering
+ // this FrameTree, not including the current main frame's
+ // SiteInstance. The focus update will be sent via the main frame's proxies
+ // in those SiteInstances.
+ void ReplicatePageFocus(bool is_focused);
+
+ // Updates page-level focus for this FrameTree in the subframe renderer
+ // identified by |instance|.
+ void SetPageFocus(SiteInstance* instance, bool is_focused);
+
private:
FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest, RemoveFocusedFrame);
typedef base::hash_map<int, RenderViewHostImpl*> RenderViewHostMap;
@@ -180,7 +200,11 @@ class CONTENT_EXPORT FrameTree {
// their state is already gone away).
RenderViewHostMultiMap render_view_host_pending_shutdown_map_;
- scoped_ptr<FrameTreeNode> root_;
+ // This is an owned ptr to the root FrameTreeNode, which never changes over
+ // the lifetime of the FrameTree. It is not a scoped_ptr because we need the
+ // pointer to remain valid even while the FrameTreeNode is being destroyed,
+ // since it's common for a node to test whether it's the root node.
+ FrameTreeNode* root_;
int focused_frame_tree_node_id_;
diff --git a/chromium/content/browser/frame_host/frame_tree_browsertest.cc b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
index a0450de934b..1ffdd0a21d2 100644
--- a/chromium/content/browser/frame_host/frame_tree_browsertest.cc
+++ b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -16,9 +18,11 @@
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
+#include "content/test/test_frame_navigation_observer.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "url/url_constants.h"
// For fine-grained suppression on flaky tests.
#if defined(OS_WIN)
@@ -33,10 +37,19 @@ class FrameTreeBrowserTest : public ContentBrowserTest {
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
SetupCrossSiteRedirector(embedded_test_server());
}
+ protected:
+ std::string GetOriginFromRenderer(FrameTreeNode* node) {
+ std::string origin;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ node->current_frame_host(),
+ "window.domAutomationController.send(document.origin);", &origin));
+ return origin;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(FrameTreeBrowserTest);
};
@@ -205,37 +218,236 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, IsRenderFrameLive) {
// Ensure that origins are correctly set on navigations.
IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, OriginSetOnNavigation) {
- GURL main_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
+ GURL about_blank(url::kAboutBlankURL);
+ GURL main_url(
+ embedded_test_server()->GetURL("a.com", "/frame_tree/top.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ WebContents* contents = shell()->web_contents();
// It is safe to obtain the root frame tree node here, as it doesn't change.
- FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()->root();
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();
// Extra '/' is added because the replicated origin is serialized in RFC 6454
// format, which dictates no trailing '/', whereas GURL::GetOrigin does put a
// '/' at the end.
- EXPECT_EQ(root->current_replication_state().origin.Serialize() + '/',
- main_url.GetOrigin().spec());
+ EXPECT_EQ(main_url.GetOrigin().spec(),
+ root->current_origin().Serialize() + '/');
+ EXPECT_EQ(
+ main_url.GetOrigin().spec(),
+ root->current_frame_host()->GetLastCommittedOrigin().Serialize() + '/');
- GURL frame_url(embedded_test_server()->GetURL("/title1.html"));
+ // The iframe is inititially same-origin.
+ EXPECT_TRUE(
+ root->current_frame_host()->GetLastCommittedOrigin().IsSameOriginWith(
+ root->child_at(0)->current_frame_host()->GetLastCommittedOrigin()));
+ EXPECT_EQ(root->current_origin().Serialize(), GetOriginFromRenderer(root));
+ EXPECT_EQ(root->child_at(0)->current_origin().Serialize(),
+ GetOriginFromRenderer(root->child_at(0)));
+
+ // Navigate the iframe cross-origin.
+ GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
NavigateFrameToURL(root->child_at(0), frame_url);
-
- EXPECT_EQ(
- root->child_at(0)->current_replication_state().origin.Serialize() + '/',
- frame_url.GetOrigin().spec());
+ EXPECT_EQ(frame_url, root->child_at(0)->current_url());
+ EXPECT_EQ(frame_url.GetOrigin().spec(),
+ root->child_at(0)->current_origin().Serialize() + '/');
+ EXPECT_FALSE(
+ root->current_frame_host()->GetLastCommittedOrigin().IsSameOriginWith(
+ root->child_at(0)->current_frame_host()->GetLastCommittedOrigin()));
+ EXPECT_EQ(root->current_origin().Serialize(), GetOriginFromRenderer(root));
+ EXPECT_EQ(root->child_at(0)->current_origin().Serialize(),
+ GetOriginFromRenderer(root->child_at(0)));
+
+ // Parent-initiated about:blank navigation should inherit the parent's a.com
+ // origin.
+ NavigateIframeToURL(contents, "1-1-id", about_blank);
+ EXPECT_EQ(about_blank, root->child_at(0)->current_url());
+ EXPECT_EQ(main_url.GetOrigin().spec(),
+ root->child_at(0)->current_origin().Serialize() + '/');
+ EXPECT_EQ(root->current_frame_host()->GetLastCommittedOrigin().Serialize(),
+ root->child_at(0)
+ ->current_frame_host()
+ ->GetLastCommittedOrigin()
+ .Serialize());
+ EXPECT_TRUE(
+ root->current_frame_host()->GetLastCommittedOrigin().IsSameOriginWith(
+ root->child_at(0)->current_frame_host()->GetLastCommittedOrigin()));
+ EXPECT_EQ(root->current_origin().Serialize(), GetOriginFromRenderer(root));
+ EXPECT_EQ(root->child_at(0)->current_origin().Serialize(),
+ GetOriginFromRenderer(root->child_at(0)));
GURL data_url("data:text/html,foo");
EXPECT_TRUE(NavigateToURL(shell(), data_url));
// Navigating to a data URL should set a unique origin. This is represented
// as "null" per RFC 6454.
- EXPECT_EQ(root->current_replication_state().origin.Serialize(), "null");
+ EXPECT_EQ("null", root->current_origin().Serialize());
+ EXPECT_TRUE(contents->GetMainFrame()->GetLastCommittedOrigin().unique());
+ EXPECT_EQ("null", GetOriginFromRenderer(root));
// Re-navigating to a normal URL should update the origin.
EXPECT_TRUE(NavigateToURL(shell(), main_url));
- EXPECT_EQ(root->current_replication_state().origin.Serialize() + '/',
- main_url.GetOrigin().spec());
+ EXPECT_EQ(main_url.GetOrigin().spec(),
+ root->current_origin().Serialize() + '/');
+ EXPECT_EQ(
+ main_url.GetOrigin().spec(),
+ contents->GetMainFrame()->GetLastCommittedOrigin().Serialize() + '/');
+ EXPECT_FALSE(contents->GetMainFrame()->GetLastCommittedOrigin().unique());
+ EXPECT_EQ(root->current_origin().Serialize(), GetOriginFromRenderer(root));
+}
+
+// Tests a cross-origin navigation to a blob URL. The main frame initiates this
+// navigation on its grandchild. It should wind up in the main frame's process.
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, NavigateGrandchildToBlob) {
+ WebContents* contents = shell()->web_contents();
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();
+
+ // First, snapshot the FrameTree for a normal A(B(A)) case where all frames
+ // are served over http. The blob test should result in the same structure.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(a))")));
+ std::string reference_tree = FrameTreeVisualizer().DepictFrameTree(root);
+
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ // The root node will initiate the navigation; its grandchild node will be the
+ // target of the navigation.
+ FrameTreeNode* target = root->child_at(0)->child_at(0);
+
+ std::string blob_url_string;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ root->current_frame_host(),
+ "function receiveMessage(event) {"
+ " document.body.appendChild(document.createTextNode(event.data));"
+ " domAutomationController.send(event.source.location.href);"
+ "}"
+ "window.addEventListener('message', receiveMessage, false);"
+ "var blob = new Blob(["
+ " '<html><body><div>This is blob content.</div><script>"
+ " window.parent.parent.postMessage(\"HI\", document.origin);"
+ " </script></body></html>'], {type: 'text/html'});"
+ "var blob_url = URL.createObjectURL(blob);"
+ "frames[0][0].location.href = blob_url;",
+ &blob_url_string));
+ EXPECT_EQ(GURL(blob_url_string), target->current_url());
+ EXPECT_EQ(url::kBlobScheme, target->current_url().scheme());
+ EXPECT_FALSE(target->current_origin().unique());
+ EXPECT_EQ("a.com", target->current_origin().host());
+ EXPECT_EQ(url::kHttpScheme, target->current_origin().scheme());
+
+ std::string document_body;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ target->current_frame_host(),
+ "domAutomationController.send(document.body.children[0].innerHTML);",
+ &document_body));
+ EXPECT_EQ("This is blob content.", document_body);
+ EXPECT_EQ(reference_tree, FrameTreeVisualizer().DepictFrameTree(root));
+}
+
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, NavigateChildToAboutBlank) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ WebContentsImpl* contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+
+ // The leaf node (c.com) will be navigated. Its parent node (b.com) will
+ // initiate the navigation.
+ FrameTreeNode* target =
+ contents->GetFrameTree()->root()->child_at(0)->child_at(0);
+ FrameTreeNode* initiator = target->parent();
+
+ // Give the target a name.
+ EXPECT_TRUE(
+ ExecuteScript(target->current_frame_host(), "window.name = 'target';"));
+
+ // Use window.open(about:blank), then poll the document for access.
+ std::string about_blank_origin;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ initiator->current_frame_host(),
+ "var didNavigate = false;"
+ "var intervalID = setInterval(function() {"
+ " if (!didNavigate) {"
+ " didNavigate = true;"
+ " window.open('about:blank', 'target');"
+ " }"
+ " // Poll the document until it doesn't throw a SecurityError.\n"
+ " try {"
+ " frames[0].document.write('Hi from ' + document.domain);"
+ " } catch (e) { return; }"
+ " clearInterval(intervalID);"
+ " domAutomationController.send(frames[0].document.origin);"
+ "}, 16);",
+ &about_blank_origin));
+ EXPECT_EQ(GURL(url::kAboutBlankURL), target->current_url());
+ EXPECT_EQ(url::kAboutScheme, target->current_url().scheme());
+ EXPECT_FALSE(target->current_origin().unique());
+ EXPECT_EQ("b.com", target->current_origin().host());
+ EXPECT_EQ(url::kHttpScheme, target->current_origin().scheme());
+ EXPECT_EQ(target->current_origin().Serialize(), about_blank_origin);
+
+ std::string document_body;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ target->current_frame_host(),
+ "domAutomationController.send(document.body.innerHTML);",
+ &document_body));
+ EXPECT_EQ("Hi from b.com", document_body);
+}
+
+// Nested iframes, three origins: A(B(C)). Frame A navigates C to about:blank
+// (via window.open). This should wind up in A's origin per the spec. Test fails
+// because of http://crbug.com/564292
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest,
+ DISABLED_NavigateGrandchildToAboutBlank) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ WebContentsImpl* contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+
+ // The leaf node (c.com) will be navigated. Its grandparent node (a.com) will
+ // initiate the navigation.
+ FrameTreeNode* target =
+ contents->GetFrameTree()->root()->child_at(0)->child_at(0);
+ FrameTreeNode* initiator = target->parent()->parent();
+
+ // Give the target a name.
+ EXPECT_TRUE(
+ ExecuteScript(target->current_frame_host(), "window.name = 'target';"));
+
+ // Use window.open(about:blank), then poll the document for access.
+ std::string about_blank_origin;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ initiator->current_frame_host(),
+ "var didNavigate = false;"
+ "var intervalID = setInterval(function() {"
+ " if (!didNavigate) {"
+ " didNavigate = true;"
+ " window.open('about:blank', 'target');"
+ " }"
+ " // May raise a SecurityError, that's expected.\n"
+ " frames[0][0].document.write('Hi from ' + document.domain);"
+ " clearInterval(intervalID);"
+ " domAutomationController.send(frames[0][0].document.origin);"
+ "}, 16);",
+ &about_blank_origin));
+ EXPECT_EQ(GURL(url::kAboutBlankURL), target->current_url());
+ EXPECT_EQ(url::kAboutScheme, target->current_url().scheme());
+ EXPECT_FALSE(target->current_origin().unique());
+ EXPECT_EQ("a.com", target->current_origin().host());
+ EXPECT_EQ(url::kHttpScheme, target->current_origin().scheme());
+ EXPECT_EQ(target->current_origin().Serialize(), about_blank_origin);
+
+ std::string document_body;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ target->current_frame_host(),
+ "domAutomationController.send(document.body.innerHTML);",
+ &document_body));
+ EXPECT_EQ("Hi from a.com", document_body);
}
// Ensure that sandbox flags are correctly set when child frames are created.
@@ -266,13 +478,10 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, SandboxFlagsSetForChildFrames) {
// Sandboxed frames should set a unique origin unless they have the
// "allow-same-origin" directive.
- EXPECT_EQ(root->child_at(0)->current_replication_state().origin.Serialize(),
- "null");
- EXPECT_EQ(root->child_at(1)->current_replication_state().origin.Serialize(),
- "null");
- EXPECT_EQ(
- root->child_at(2)->current_replication_state().origin.Serialize() + "/",
- main_url.GetOrigin().spec());
+ EXPECT_EQ(root->child_at(0)->current_origin().Serialize(), "null");
+ EXPECT_EQ(root->child_at(1)->current_origin().Serialize(), "null");
+ EXPECT_EQ(root->child_at(2)->current_origin().Serialize() + "/",
+ main_url.GetOrigin().spec());
// Navigating to a different URL should not clear sandbox flags.
GURL frame_url(embedded_test_server()->GetURL("/title1.html"));
@@ -322,7 +531,7 @@ class CrossProcessFrameTreeBrowserTest : public ContentBrowserTest {
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
SetupCrossSiteRedirector(embedded_test_server());
}
@@ -393,32 +602,29 @@ IN_PROC_BROWSER_TEST_F(CrossProcessFrameTreeBrowserTest,
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()->root();
- EXPECT_EQ(root->current_replication_state().origin.Serialize() + '/',
+ EXPECT_EQ(root->current_origin().Serialize() + '/',
main_url.GetOrigin().spec());
// First frame is an about:blank frame. Check that its origin is correctly
// inherited from the parent.
- EXPECT_EQ(
- root->child_at(0)->current_replication_state().origin.Serialize() + '/',
- main_url.GetOrigin().spec());
+ EXPECT_EQ(root->child_at(0)->current_origin().Serialize() + '/',
+ main_url.GetOrigin().spec());
// Second frame loads a same-site page. Its origin should also be the same
// as the parent.
- EXPECT_EQ(
- root->child_at(1)->current_replication_state().origin.Serialize() + '/',
- main_url.GetOrigin().spec());
+ EXPECT_EQ(root->child_at(1)->current_origin().Serialize() + '/',
+ main_url.GetOrigin().spec());
// Load cross-site page into the first frame.
GURL cross_site_url(
embedded_test_server()->GetURL("foo.com", "/title2.html"));
NavigateFrameToURL(root->child_at(0), cross_site_url);
- EXPECT_EQ(
- root->child_at(0)->current_replication_state().origin.Serialize() + '/',
- cross_site_url.GetOrigin().spec());
+ EXPECT_EQ(root->child_at(0)->current_origin().Serialize() + '/',
+ cross_site_url.GetOrigin().spec());
// The root's origin shouldn't have changed.
- EXPECT_EQ(root->current_replication_state().origin.Serialize() + '/',
+ EXPECT_EQ(root->current_origin().Serialize() + '/',
main_url.GetOrigin().spec());
GURL data_url("data:text/html,foo");
@@ -426,8 +632,7 @@ IN_PROC_BROWSER_TEST_F(CrossProcessFrameTreeBrowserTest,
// Navigating to a data URL should set a unique origin. This is represented
// as "null" per RFC 6454.
- EXPECT_EQ(root->child_at(1)->current_replication_state().origin.Serialize(),
- "null");
+ EXPECT_EQ(root->child_at(1)->current_origin().Serialize(), "null");
}
} // namespace content
diff --git a/chromium/content/browser/frame_host/frame_tree_node.cc b/chromium/content/browser/frame_host/frame_tree_node.cc
index c44c19c1077..b975a051106 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.cc
+++ b/chromium/content/browser/frame_host/frame_tree_node.cc
@@ -5,8 +5,9 @@
#include "content/browser/frame_host/frame_tree_node.h"
#include <queue>
+#include <utility>
-#include "base/command_line.h"
+#include "base/macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "content/browser/frame_host/frame_tree.h"
@@ -17,7 +18,7 @@
#include "content/common/frame_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/browser_side_navigation_policy.h"
namespace content {
@@ -25,9 +26,9 @@ namespace {
// This is a global map between frame_tree_node_ids and pointers to
// FrameTreeNodes.
-typedef base::hash_map<int, FrameTreeNode*> FrameTreeNodeIDMap;
+typedef base::hash_map<int, FrameTreeNode*> FrameTreeNodeIdMap;
-base::LazyInstance<FrameTreeNodeIDMap> g_frame_tree_node_id_map =
+base::LazyInstance<FrameTreeNodeIdMap> g_frame_tree_node_id_map =
LAZY_INSTANCE_INITIALIZER;
// These values indicate the loading progress status. The minimum progress
@@ -62,20 +63,22 @@ int FrameTreeNode::next_frame_tree_node_id_ = 1;
// static
FrameTreeNode* FrameTreeNode::GloballyFindByID(int frame_tree_node_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- FrameTreeNodeIDMap* nodes = g_frame_tree_node_id_map.Pointer();
- FrameTreeNodeIDMap::iterator it = nodes->find(frame_tree_node_id);
+ FrameTreeNodeIdMap* nodes = g_frame_tree_node_id_map.Pointer();
+ FrameTreeNodeIdMap::iterator it = nodes->find(frame_tree_node_id);
return it == nodes->end() ? nullptr : it->second;
}
-FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
- Navigator* navigator,
- RenderFrameHostDelegate* render_frame_delegate,
- RenderViewHostDelegate* render_view_delegate,
- RenderWidgetHostDelegate* render_widget_delegate,
- RenderFrameHostManager::Delegate* manager_delegate,
- blink::WebTreeScopeType scope,
- const std::string& name,
- blink::WebSandboxFlags sandbox_flags)
+FrameTreeNode::FrameTreeNode(
+ FrameTree* frame_tree,
+ Navigator* navigator,
+ RenderFrameHostDelegate* render_frame_delegate,
+ RenderViewHostDelegate* render_view_delegate,
+ RenderWidgetHostDelegate* render_widget_delegate,
+ RenderFrameHostManager::Delegate* manager_delegate,
+ blink::WebTreeScopeType scope,
+ const std::string& name,
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties)
: frame_tree_(frame_tree),
navigator_(navigator),
render_manager_(this,
@@ -88,18 +91,24 @@ FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
opener_(nullptr),
opener_observer_(nullptr),
has_committed_real_load_(false),
- replication_state_(scope, name, sandbox_flags),
+ replication_state_(
+ scope,
+ name,
+ sandbox_flags,
+ false /* should enforce strict mixed content checking */),
// Effective sandbox flags also need to be set, since initial sandbox
// flags should apply to the initial empty document in the frame.
effective_sandbox_flags_(sandbox_flags),
+ frame_owner_properties_(frame_owner_properties),
loading_progress_(kLoadingProgressNotStarted) {
- std::pair<FrameTreeNodeIDMap::iterator, bool> result =
+ std::pair<FrameTreeNodeIdMap::iterator, bool> result =
g_frame_tree_node_id_map.Get().insert(
std::make_pair(frame_tree_node_id_, this));
CHECK(result.second);
}
FrameTreeNode::~FrameTreeNode() {
+ children_.clear();
frame_tree_->FrameRemoved(this);
FOR_EACH_OBSERVER(Observer, observers_, OnFrameTreeNodeDestroyed(this));
@@ -121,21 +130,20 @@ bool FrameTreeNode::IsMainFrame() const {
return frame_tree_->root() == this;
}
-void FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child,
- int process_id,
- int frame_routing_id) {
+FrameTreeNode* FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child,
+ int process_id,
+ int frame_routing_id) {
// Child frame must always be created in the same process as the parent.
CHECK_EQ(process_id, render_manager_.current_host()->GetProcess()->GetID());
+ child->set_parent(this);
// Initialize the RenderFrameHost for the new node. We always create child
// frames in the same SiteInstance as the current frame, and they can swap to
// a different one if they navigate away.
child->render_manager()->Init(
- render_manager_.current_host()->GetSiteInstance()->GetBrowserContext(),
render_manager_.current_host()->GetSiteInstance(),
render_manager_.current_host()->GetRoutingID(), frame_routing_id,
MSG_ROUTING_NONE);
- child->set_parent(this);
// Other renderer processes in this BrowsingInstance may need to find out
// about the new frame. Create a proxy for the child frame in all
@@ -145,33 +153,29 @@ void FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child,
if (SiteIsolationPolicy::AreCrossProcessFramesPossible())
render_manager_.CreateProxiesForChildFrame(child.get());
- children_.push_back(child.release());
+ children_.push_back(std::move(child));
+ return children_.back().get();
}
void FrameTreeNode::RemoveChild(FrameTreeNode* child) {
- std::vector<FrameTreeNode*>::iterator iter;
- for (iter = children_.begin(); iter != children_.end(); ++iter) {
- if ((*iter) == child)
- break;
- }
-
- if (iter != children_.end()) {
- // Subtle: we need to make sure the node is gone from the tree before
- // observers are notified of its deletion.
- scoped_ptr<FrameTreeNode> node_to_delete(*iter);
- children_.weak_erase(iter);
- node_to_delete.reset();
+ for (auto iter = children_.begin(); iter != children_.end(); ++iter) {
+ if (iter->get() == child) {
+ // Subtle: we need to make sure the node is gone from the tree before
+ // observers are notified of its deletion.
+ scoped_ptr<FrameTreeNode> node_to_delete(std::move(*iter));
+ children_.erase(iter);
+ node_to_delete.reset();
+ return;
+ }
}
}
void FrameTreeNode::ResetForNewProcess() {
current_url_ = GURL();
- // The children may not have been cleared if a cross-process navigation
- // commits before the old process cleans everything up. Make sure the child
- // nodes get deleted before swapping to a new process.
- ScopedVector<FrameTreeNode> old_children = children_.Pass();
- old_children.clear(); // May notify observers.
+ // Remove child nodes from the tree, then delete them. This destruction
+ // operation will notify observers.
+ std::vector<scoped_ptr<FrameTreeNode>>().swap(children_);
}
void FrameTreeNode::SetOpener(FrameTreeNode* opener) {
@@ -207,6 +211,16 @@ void FrameTreeNode::SetFrameName(const std::string& name) {
replication_state_.name = name;
}
+void FrameTreeNode::SetEnforceStrictMixedContentChecking(bool should_enforce) {
+ if (should_enforce ==
+ replication_state_.should_enforce_strict_mixed_content_checking) {
+ return;
+ }
+ render_manager_.OnEnforceStrictMixedContentChecking(should_enforce);
+ replication_state_.should_enforce_strict_mixed_content_checking =
+ should_enforce;
+}
+
bool FrameTreeNode::IsDescendantOf(FrameTreeNode* other) const {
if (!other || !other->child_count())
return false;
@@ -240,8 +254,7 @@ bool FrameTreeNode::IsLoading() const {
DCHECK(current_frame_host);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
if (navigation_request_)
return true;
@@ -265,8 +278,7 @@ bool FrameTreeNode::CommitPendingSandboxFlags() {
void FrameTreeNode::CreatedNavigationRequest(
scoped_ptr<NavigationRequest> navigation_request) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
ResetNavigationRequest(false);
// Force the throbber to start to keep it in sync with what is happening in
@@ -279,14 +291,13 @@ void FrameTreeNode::CreatedNavigationRequest(
DidStartLoading(true);
}
- navigation_request_ = navigation_request.Pass();
+ navigation_request_ = std::move(navigation_request);
render_manager()->DidCreateNavigationRequest(*navigation_request_);
}
void FrameTreeNode::ResetNavigationRequest(bool is_commit) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
if (!navigation_request_)
return;
navigation_request_.reset();
@@ -370,10 +381,8 @@ void FrameTreeNode::DidChangeLoadProgress(double load_progress) {
}
bool FrameTreeNode::StopLoading() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
ResetNavigationRequest(false);
- }
// TODO(nasko): see if child frames should send IPCs in site-per-process
// mode.
@@ -384,4 +393,9 @@ bool FrameTreeNode::StopLoading() {
return true;
}
+void FrameTreeNode::DidFocus() {
+ last_focus_time_ = base::TimeTicks::Now();
+ FOR_EACH_OBSERVER(Observer, observers_, OnFrameTreeNodeFocused(this));
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/frame_tree_node.h b/chromium/content/browser/frame_host/frame_tree_node.h
index 2d033a65db6..9103b63aa70 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.h
+++ b/chromium/content/browser/frame_host/frame_tree_node.h
@@ -5,16 +5,19 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_FRAME_TREE_NODE_H_
#define CONTENT_BROWSER_FRAME_HOST_FRAME_TREE_NODE_H_
+#include <stddef.h>
+
#include <string>
+#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#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 "content/common/frame_replication_state.h"
+#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -36,10 +39,13 @@ class CONTENT_EXPORT FrameTreeNode {
// Invoked when a FrameTreeNode is being destroyed.
virtual void OnFrameTreeNodeDestroyed(FrameTreeNode* node) {}
+ // Invoked when a FrameTreeNode becomes focused.
+ virtual void OnFrameTreeNodeFocused(FrameTreeNode* node) {}
+
virtual ~Observer() {}
};
- static const int kFrameTreeNodeInvalidID = -1;
+ static const int kFrameTreeNodeInvalidId = -1;
// Returns the FrameTreeNode with the given global |frame_tree_node_id|,
// regardless of which FrameTree it is in.
@@ -53,7 +59,8 @@ class CONTENT_EXPORT FrameTreeNode {
RenderFrameHostManager::Delegate* manager_delegate,
blink::WebTreeScopeType scope,
const std::string& name,
- blink::WebSandboxFlags sandbox_flags);
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties);
~FrameTreeNode();
@@ -62,9 +69,9 @@ class CONTENT_EXPORT FrameTreeNode {
bool IsMainFrame() const;
- void AddChild(scoped_ptr<FrameTreeNode> child,
- int process_id,
- int frame_routing_id);
+ FrameTreeNode* AddChild(scoped_ptr<FrameTreeNode> child,
+ int process_id,
+ int frame_routing_id);
void RemoveChild(FrameTreeNode* child);
// Clears process specific-state in this node to prepare for a new process.
@@ -90,6 +97,8 @@ class CONTENT_EXPORT FrameTreeNode {
return replication_state_.name;
}
+ const url::Origin& frame_origin() const { return replication_state_.origin; }
+
size_t child_count() const {
return children_.size();
}
@@ -104,9 +113,10 @@ class CONTENT_EXPORT FrameTreeNode {
void SetOpener(FrameTreeNode* opener);
FrameTreeNode* child_at(size_t index) const {
- return children_[index];
+ return children_[index].get();
}
+ // Returns the URL of the last committed page in this frame.
const GURL& current_url() const {
return current_url_;
}
@@ -120,12 +130,21 @@ class CONTENT_EXPORT FrameTreeNode {
return has_committed_real_load_;
}
+ // Returns the origin of the last committed page in this frame.
+ const url::Origin& current_origin() const {
+ return replication_state_.origin;
+ }
+
// Set the current origin and notify proxies about the update.
void SetCurrentOrigin(const url::Origin& origin);
// Set the current name and notify proxies about the update.
void SetFrameName(const std::string& name);
+ // Sets the current enforcement of strict mixed content checking and
+ // notifies proxies about the update.
+ void SetEnforceStrictMixedContentChecking(bool should_enforce);
+
blink::WebSandboxFlags effective_sandbox_flags() {
return effective_sandbox_flags_;
}
@@ -138,6 +157,15 @@ class CONTENT_EXPORT FrameTreeNode {
// return true if the sandbox flags were changed.
bool CommitPendingSandboxFlags();
+ const blink::WebFrameOwnerProperties& frame_owner_properties() {
+ return frame_owner_properties_;
+ }
+
+ void set_frame_owner_properties(
+ const blink::WebFrameOwnerProperties& frame_owner_properties) {
+ frame_owner_properties_ = frame_owner_properties;
+ }
+
bool HasSameOrigin(const FrameTreeNode& node) const {
return replication_state_.origin.IsSameOriginWith(
node.replication_state_.origin);
@@ -205,9 +233,10 @@ class CONTENT_EXPORT FrameTreeNode {
// Returns the time this frame was last focused.
base::TimeTicks last_focus_time() const { return last_focus_time_; }
- void set_last_focus_time(const base::TimeTicks& last_focus_time) {
- last_focus_time_ = last_focus_time;
- }
+
+ // Called when this node becomes focused. Updates the node's last focused
+ // time and notifies observers.
+ void DidFocus();
private:
class OpenerDestroyedObserver;
@@ -251,7 +280,7 @@ class CONTENT_EXPORT FrameTreeNode {
scoped_ptr<OpenerDestroyedObserver> opener_observer_;
// The immediate children of this specific frame.
- ScopedVector<FrameTreeNode> children_;
+ std::vector<scoped_ptr<FrameTreeNode>> children_;
// Track the current frame's last committed URL.
// TODO(creis): Consider storing a reference to the last committed
@@ -276,6 +305,14 @@ class CONTENT_EXPORT FrameTreeNode {
// flags when a navigation for this frame commits.
blink::WebSandboxFlags effective_sandbox_flags_;
+ // Tracks the scrolling and margin properties for this frame. These
+ // properties affect the child renderer but are stored on its parent's
+ // frame element. When this frame's parent dynamically updates these
+ // properties, we update them here too.
+ //
+ // Note that dynamic updates only take effect on the next frame navigation.
+ blink::WebFrameOwnerProperties frame_owner_properties_;
+
// Used to track this node's loading progress (from 0 to 1).
double loading_progress_;
diff --git a/chromium/content/browser/frame_host/frame_tree_unittest.cc b/chromium/content/browser/frame_host/frame_tree_unittest.cc
index b40628b7cfa..93d481684fd 100644
--- a/chromium/content/browser/frame_host/frame_tree_unittest.cc
+++ b/chromium/content/browser/frame_host/frame_tree_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/frame_host/frame_tree.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/frame_host/navigator_impl.h"
@@ -123,6 +126,8 @@ class FrameTreeTest : public RenderViewHostImplTestHarness {
// - Add a series of nodes and verify tree structure.
// - Remove a series of nodes and verify tree structure.
TEST_F(FrameTreeTest, Shape) {
+ main_test_rfh()->InitializeRenderFrameIfNeeded();
+
// Use the FrameTree of the WebContents so that it has all the delegates it
// needs. We may want to consider a test version of this.
FrameTree* frame_tree = contents()->GetFrameTree();
@@ -135,94 +140,114 @@ TEST_F(FrameTreeTest, Shape) {
// Do not navigate each frame separately, since that will clutter the test
// itself. Instead, leave them in "not live" state, which is indicated by the
// * after the frame id, since this test cares about the shape, not the
- // frame liveliness.
- EXPECT_EQ("1*: []", GetTreeState(frame_tree));
+ // frame liveness.
+ EXPECT_EQ("2: []", GetTreeState(frame_tree));
// Simulate attaching a series of frames to build the frame tree.
frame_tree->AddFrame(root, process_id, 14, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(root, process_id, 15, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(root, process_id, 16, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(root->child_at(0), process_id, 244,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(root->child_at(1), process_id, 255,
blink::WebTreeScopeType::Document, no_children_node,
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(root->child_at(0), process_id, 245,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
- EXPECT_EQ("1*: [14*: [244*: [], 245*: []], "
- "15*: [255* 'no children node': []], "
- "16*: []]",
- GetTreeState(frame_tree));
+ EXPECT_EQ(
+ "2: [14: [244: [], 245: []], "
+ "15: [255 'no children node': []], "
+ "16: []]",
+ GetTreeState(frame_tree));
FrameTreeNode* child_16 = root->child_at(2);
frame_tree->AddFrame(child_16, process_id, 264,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 265,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 266,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 267,
blink::WebTreeScopeType::Document, deep_subtree,
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 268,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
FrameTreeNode* child_267 = child_16->child_at(3);
frame_tree->AddFrame(child_267, process_id, 365,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(child_267->child_at(0), process_id, 455,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(child_267->child_at(0)->child_at(0), process_id, 555,
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
frame_tree->AddFrame(child_267->child_at(0)->child_at(0)->child_at(0),
process_id, 655, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
// Now that's it's fully built, verify the tree structure is as expected.
- EXPECT_EQ("1*: [14*: [244*: [], 245*: []], "
- "15*: [255* 'no children node': []], "
- "16*: [264*: [], 265*: [], 266*: [], "
- "267* 'node with deep subtree': "
- "[365*: [455*: [555*: [655*: []]]]], 268*: []]]",
- GetTreeState(frame_tree));
+ EXPECT_EQ(
+ "2: [14: [244: [], 245: []], "
+ "15: [255 'no children node': []], "
+ "16: [264: [], 265: [], 266: [], "
+ "267 'node with deep subtree': "
+ "[365: [455: [555: [655: []]]]], 268: []]]",
+ GetTreeState(frame_tree));
FrameTreeNode* child_555 = child_267->child_at(0)->child_at(0)->child_at(0);
frame_tree->RemoveFrame(child_555);
- EXPECT_EQ("1*: [14*: [244*: [], 245*: []], "
- "15*: [255* 'no children node': []], "
- "16*: [264*: [], 265*: [], 266*: [], "
- "267* 'node with deep subtree': "
- "[365*: [455*: []]], 268*: []]]",
- GetTreeState(frame_tree));
+ EXPECT_EQ(
+ "2: [14: [244: [], 245: []], "
+ "15: [255 'no children node': []], "
+ "16: [264: [], 265: [], 266: [], "
+ "267 'node with deep subtree': "
+ "[365: [455: []]], 268: []]]",
+ GetTreeState(frame_tree));
frame_tree->RemoveFrame(child_16->child_at(1));
- EXPECT_EQ("1*: [14*: [244*: [], 245*: []], "
- "15*: [255* 'no children node': []], "
- "16*: [264*: [], 266*: [], "
- "267* 'node with deep subtree': "
- "[365*: [455*: []]], 268*: []]]",
- GetTreeState(frame_tree));
+ EXPECT_EQ(
+ "2: [14: [244: [], 245: []], "
+ "15: [255 'no children node': []], "
+ "16: [264: [], 266: [], "
+ "267 'node with deep subtree': "
+ "[365: [455: []]], 268: []]]",
+ GetTreeState(frame_tree));
frame_tree->RemoveFrame(root->child_at(1));
- EXPECT_EQ("1*: [14*: [244*: [], 245*: []], "
- "16*: [264*: [], 266*: [], "
- "267* 'node with deep subtree': "
- "[365*: [455*: []]], 268*: []]]",
- GetTreeState(frame_tree));
+ EXPECT_EQ(
+ "2: [14: [244: [], 245: []], "
+ "16: [264: [], 266: [], "
+ "267 'node with deep subtree': "
+ "[365: [455: []]], 268: []]]",
+ GetTreeState(frame_tree));
}
// Ensure frames can be found by frame_tree_node_id, routing ID, or name.
@@ -234,12 +259,15 @@ TEST_F(FrameTreeTest, FindFrames) {
FrameTreeNode* root = frame_tree->root();
main_test_rfh()->OnCreateChildFrame(22, blink::WebTreeScopeType::Document,
- "child0", blink::WebSandboxFlags::None);
+ "child0", blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(23, blink::WebTreeScopeType::Document,
- "child1", blink::WebSandboxFlags::None);
+ "child1", blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(24, blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
FrameTreeNode* child0 = root->child_at(0);
FrameTreeNode* child1 = root->child_at(1);
@@ -248,7 +276,7 @@ TEST_F(FrameTreeTest, FindFrames) {
// Add one grandchild frame.
child1->current_frame_host()->OnCreateChildFrame(
33, blink::WebTreeScopeType::Document, "grandchild",
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
FrameTreeNode* grandchild = child1->child_at(0);
// Ensure they can be found by FTN id.
@@ -285,11 +313,14 @@ TEST_F(FrameTreeTest, PreviousSibling) {
FrameTree* frame_tree = contents()->GetFrameTree();
FrameTreeNode* root = frame_tree->root();
main_test_rfh()->OnCreateChildFrame(22, blink::WebTreeScopeType::Document,
- "child0", blink::WebSandboxFlags::None);
+ "child0", blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(23, blink::WebTreeScopeType::Document,
- "child1", blink::WebSandboxFlags::None);
+ "child1", blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(24, blink::WebTreeScopeType::Document,
- "child2", blink::WebSandboxFlags::None);
+ "child2", blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
FrameTreeNode* child0 = root->child_at(0);
FrameTreeNode* child1 = root->child_at(1);
FrameTreeNode* child2 = root->child_at(2);
@@ -297,7 +328,7 @@ TEST_F(FrameTreeTest, PreviousSibling) {
// Add one grandchild frame.
child1->current_frame_host()->OnCreateChildFrame(
33, blink::WebTreeScopeType::Document, "grandchild",
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
FrameTreeNode* grandchild = child1->child_at(0);
EXPECT_EQ(nullptr, root->PreviousSibling());
@@ -312,7 +343,7 @@ TEST_F(FrameTreeTest, PreviousSibling) {
TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
TreeWalkingWebContentsLogger activity(contents());
contents()->NavigateAndCommit(GURL("http://www.google.com"));
- EXPECT_EQ("RenderFrameCreated(1) -> 1: []", activity.GetLog());
+ EXPECT_EQ("RenderFrameCreated(2) -> 2: []", activity.GetLog());
FrameTree* frame_tree = contents()->GetFrameTree();
FrameTreeNode* root = frame_tree->root();
@@ -320,22 +351,24 @@ TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
// Simulate attaching a series of frames to build the frame tree.
main_test_rfh()->OnCreateChildFrame(14, blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(14) -> 1: []\n"
- "RenderFrameCreated(14) -> 1: [14: []]",
+ "RenderFrameHostChanged(new)(14) -> 2: []\n"
+ "RenderFrameCreated(14) -> 2: [14: []]",
activity.GetLog());
main_test_rfh()->OnCreateChildFrame(18, blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(18) -> 1: [14: []]\n"
- "RenderFrameCreated(18) -> 1: [14: [], 18: []]",
+ "RenderFrameHostChanged(new)(18) -> 2: [14: []]\n"
+ "RenderFrameCreated(18) -> 2: [14: [], 18: []]",
activity.GetLog());
frame_tree->RemoveFrame(root->child_at(0));
- EXPECT_EQ("RenderFrameDeleted(14) -> 1: [18: []]", activity.GetLog());
+ EXPECT_EQ("RenderFrameDeleted(14) -> 2: [18: []]", activity.GetLog());
frame_tree->RemoveFrame(root->child_at(0));
- EXPECT_EQ("RenderFrameDeleted(18) -> 1: []", activity.GetLog());
+ EXPECT_EQ("RenderFrameDeleted(18) -> 2: []", activity.GetLog());
}
// Make sure that WebContentsObservers see a consistent view of the tree after
@@ -343,30 +376,32 @@ TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) {
TreeWalkingWebContentsLogger activity(contents());
contents()->NavigateAndCommit(GURL("http://www.google.com"));
- EXPECT_EQ("RenderFrameCreated(1) -> 1: []", activity.GetLog());
+ EXPECT_EQ("RenderFrameCreated(2) -> 2: []", activity.GetLog());
main_test_rfh()->OnCreateChildFrame(22, blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(22) -> 1: []\n"
- "RenderFrameCreated(22) -> 1: [22: []]",
+ "RenderFrameHostChanged(new)(22) -> 2: []\n"
+ "RenderFrameCreated(22) -> 2: [22: []]",
activity.GetLog());
main_test_rfh()->OnCreateChildFrame(23, blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(23) -> 1: [22: []]\n"
- "RenderFrameCreated(23) -> 1: [22: [], 23: []]",
+ "RenderFrameHostChanged(new)(23) -> 2: [22: []]\n"
+ "RenderFrameCreated(23) -> 2: [22: [], 23: []]",
activity.GetLog());
// Crash the renderer
main_test_rfh()->GetProcess()->SimulateCrash();
EXPECT_EQ(
- "RenderProcessGone -> 1*: [22*: [], 23*: []]\n"
- "RenderFrameDeleted(23) -> 1*: [22*: [], 23*: []]\n"
- "RenderFrameDeleted(22) -> 1*: [22*: [], 23*: []]\n"
- "RenderFrameDeleted(1) -> 1*: []",
+ "RenderProcessGone -> 2*: [22*: [], 23*: []]\n"
+ "RenderFrameDeleted(23) -> 2*: [22*: [], 23*: []]\n"
+ "RenderFrameDeleted(22) -> 2*: [22*: [], 23*: []]\n"
+ "RenderFrameDeleted(2) -> 2*: []",
activity.GetLog());
}
@@ -378,13 +413,13 @@ TEST_F(FrameTreeTest, FailAddFrameWithWrongProcessId) {
FrameTreeNode* root = frame_tree->root();
int process_id = root->current_frame_host()->GetProcess()->GetID();
- ASSERT_EQ("1: []", GetTreeState(frame_tree));
+ ASSERT_EQ("2: []", GetTreeState(frame_tree));
// Simulate attaching a frame from mismatched process id.
ASSERT_FALSE(frame_tree->AddFrame(
root, process_id + 1, 1, blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None));
- ASSERT_EQ("1: []", GetTreeState(frame_tree));
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties()));
+ ASSERT_EQ("2: []", GetTreeState(frame_tree));
}
// Ensure that frames removed while a process has crashed are not preserved in
@@ -397,15 +432,18 @@ TEST_F(FrameTreeTest, ProcessCrashClearsGlobalMap) {
main_test_rfh()->OnCreateChildFrame(22, blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(23, blink::WebTreeScopeType::Document,
std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
// Add one grandchild frame.
RenderFrameHostImpl* child1_rfh = root->child_at(0)->current_frame_host();
child1_rfh->OnCreateChildFrame(33, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
// Ensure they can be found by id.
int id1 = root->child_at(0)->frame_tree_node_id();
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.cc b/chromium/content/browser/frame_host/interstitial_page_impl.cc
index 2fe3c900bd6..9e63d829f1a 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl.cc
+++ b/chromium/content/browser/frame_host/interstitial_page_impl.cc
@@ -4,16 +4,19 @@
#include "content/browser/frame_host/interstitial_page_impl.h"
+#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
+#include "build/build_config.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"
@@ -182,11 +185,6 @@ InterstitialPageImpl::InterstitialPageImpl(
delegate_(delegate),
weak_ptr_factory_(this) {
InitInterstitialPageMap();
- // It would be inconsistent to create an interstitial with no new navigation
- // (which is the case when the interstitial was triggered by a sub-resource on
- // a page) when we have a pending entry (in the process of loading a new top
- // frame).
- DCHECK(new_navigation || !web_contents->GetController().GetPendingEntry());
}
InterstitialPageImpl::~InterstitialPageImpl() {
@@ -226,7 +224,8 @@ void InterstitialPageImpl::Show() {
// already been destroyed.
notification_registrar_.Add(
this, NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
- Source<RenderWidgetHost>(controller_->delegate()->GetRenderViewHost()));
+ Source<RenderWidgetHost>(
+ controller_->delegate()->GetRenderViewHost()->GetWidget()));
// Update the g_web_contents_to_interstitial_page map.
iter = g_web_contents_to_interstitial_page->find(web_contents_);
@@ -243,7 +242,7 @@ void InterstitialPageImpl::Show() {
// Give delegates a chance to set some states on the navigation entry.
delegate_->OverrideEntry(entry.get());
- controller_->SetTransientEntry(entry.Pass());
+ controller_->SetTransientEntry(std::move(entry));
static_cast<WebContentsImpl*>(web_contents_)->DidChangeVisibleSSLState();
}
@@ -272,7 +271,7 @@ void InterstitialPageImpl::Hide() {
Disable();
RenderWidgetHostView* old_view =
- controller_->delegate()->GetRenderViewHost()->GetView();
+ controller_->delegate()->GetRenderViewHost()->GetWidget()->GetView();
if (controller_->delegate()->GetInterstitialPage() == this &&
old_view &&
!old_view->IsShowing() &&
@@ -287,10 +286,14 @@ void InterstitialPageImpl::Hide() {
// If the focus was on the interstitial, let's keep it to the page.
// (Note that in unit-tests the RVH may not have a view).
- if (render_view_host_->GetView() &&
- render_view_host_->GetView()->HasFocus() &&
- controller_->delegate()->GetRenderViewHost()->GetView()) {
- controller_->delegate()->GetRenderViewHost()->GetView()->Focus();
+ if (render_view_host_->GetWidget()->GetView() &&
+ render_view_host_->GetWidget()->GetView()->HasFocus() &&
+ controller_->delegate()->GetRenderViewHost()->GetWidget()->GetView()) {
+ controller_->delegate()
+ ->GetRenderViewHost()
+ ->GetWidget()
+ ->GetView()
+ ->Focus();
}
// Delete this and call Shutdown on the RVH asynchronously, as we may have
@@ -345,10 +348,8 @@ void InterstitialPageImpl::Observe(
if (action_taken_ == NO_ACTION) {
// The RenderViewHost is being destroyed (as part of the tab being
// closed); make sure we clear the blocked requests.
- RenderViewHost* rvh = static_cast<RenderViewHost*>(
- static_cast<RenderViewHostImpl*>(
- RenderWidgetHostImpl::From(
- Source<RenderWidgetHost>(source).ptr())));
+ RenderViewHost* rvh =
+ RenderViewHost::From(Source<RenderWidgetHost>(source).ptr());
DCHECK(rvh->GetProcess()->GetID() == original_child_id_ &&
rvh->GetRoutingID() == original_rvh_id_);
TakeActionOnResourceDispatcher(CANCEL);
@@ -392,7 +393,7 @@ void InterstitialPageImpl::RenderFrameCreated(
void InterstitialPageImpl::UpdateTitle(
RenderFrameHost* render_frame_host,
- int32 page_id,
+ int32_t page_id,
const base::string16& title,
base::i18n::TextDirection title_direction) {
if (!enabled())
@@ -508,11 +509,11 @@ void InterstitialPageImpl::DidNavigate(
// The RenderViewHost has loaded its contents, we can show it now.
if (!controller_->delegate()->IsHidden())
- render_view_host_->GetView()->Show();
+ render_view_host_->GetWidget()->GetView()->Show();
controller_->delegate()->AttachInterstitialPage(this);
RenderWidgetHostView* rwh_view =
- controller_->delegate()->GetRenderViewHost()->GetView();
+ controller_->delegate()->GetRenderViewHost()->GetWidget()->GetView();
// The RenderViewHost may already have crashed before we even get here.
if (rwh_view) {
@@ -592,9 +593,12 @@ RenderViewHostImpl* InterstitialPageImpl::CreateRenderViewHost() {
new SessionStorageNamespaceImpl(dom_storage_context);
// Use the RenderViewHost from our FrameTree.
+ // TODO(avi): The view routing ID can be restored to MSG_ROUTING_NONE once
+ // RenderViewHostImpl has-a RenderWidgetHostImpl. https://crbug.com/545684
+ int32_t widget_routing_id = site_instance->GetProcess()->GetNextRoutingID();
frame_tree_.root()->render_manager()->Init(
- browser_context, site_instance.get(), MSG_ROUTING_NONE, MSG_ROUTING_NONE,
- MSG_ROUTING_NONE);
+ site_instance.get(), widget_routing_id, MSG_ROUTING_NONE,
+ widget_routing_id);
return frame_tree_.root()->current_frame_host()->render_view_host();
}
@@ -604,12 +608,12 @@ WebContentsView* InterstitialPageImpl::CreateWebContentsView() {
WebContentsView* wcv =
static_cast<WebContentsImpl*>(web_contents())->GetView();
RenderWidgetHostViewBase* view =
- wcv->CreateViewForWidget(render_view_host_, false);
- render_view_host_->SetView(view);
+ wcv->CreateViewForWidget(render_view_host_->GetWidget(), false);
+ RenderWidgetHostImpl::From(render_view_host_->GetWidget())->SetView(view);
render_view_host_->AllowBindings(BINDINGS_POLICY_DOM_AUTOMATION);
- int32 max_page_id = web_contents()->
- GetMaxPageIDForSiteInstance(render_view_host_->GetSiteInstance());
+ int32_t max_page_id = web_contents()->GetMaxPageIDForSiteInstance(
+ render_view_host_->GetSiteInstance());
render_view_host_->CreateRenderView(MSG_ROUTING_NONE,
MSG_ROUTING_NONE,
max_page_id,
@@ -715,8 +719,8 @@ void InterstitialPageImpl::SetSize(const gfx::Size& size) {
#if !defined(OS_MACOSX)
// When a tab is closed, we might be resized after our view was NULLed
// (typically if there was an info-bar).
- if (render_view_host_->GetView())
- render_view_host_->GetView()->SetSize(size);
+ if (render_view_host_->GetWidget()->GetView())
+ render_view_host_->GetWidget()->GetView()->SetSize(size);
#else
// TODO(port): Does Mac need to SetSize?
NOTIMPLEMENTED();
@@ -727,7 +731,7 @@ void InterstitialPageImpl::Focus() {
// Focus the native window.
if (!enabled())
return;
- render_view_host_->GetView()->Focus();
+ render_view_host_->GetWidget()->GetView()->Focus();
}
void InterstitialPageImpl::FocusThroughTabTraversal(bool reverse) {
@@ -737,7 +741,7 @@ void InterstitialPageImpl::FocusThroughTabTraversal(bool reverse) {
}
RenderWidgetHostView* InterstitialPageImpl::GetView() {
- return render_view_host_->GetView();
+ return render_view_host_->GetWidget()->GetView();
}
RenderFrameHost* InterstitialPageImpl::GetMainFrame() const {
@@ -752,27 +756,24 @@ void InterstitialPageImpl::DontCreateViewForTesting() {
create_view_ = false;
}
-gfx::Rect InterstitialPageImpl::GetRootWindowResizerRect() const {
- return gfx::Rect();
-}
-
void InterstitialPageImpl::CreateNewWindow(
SiteInstance* source_site_instance,
- int route_id,
- int main_frame_route_id,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) {
NOTREACHED() << "InterstitialPage does not support showing popups yet.";
}
-void InterstitialPageImpl::CreateNewWidget(int32 render_process_id,
- int32 route_id,
+void InterstitialPageImpl::CreateNewWidget(int32_t render_process_id,
+ int32_t route_id,
blink::WebPopupType popup_type) {
NOTREACHED() << "InterstitialPage does not support showing drop-downs yet.";
}
-void InterstitialPageImpl::CreateNewFullscreenWidget(int32 render_process_id,
- int32 route_id) {
+void InterstitialPageImpl::CreateNewFullscreenWidget(int32_t render_process_id,
+ int32_t route_id) {
NOTREACHED()
<< "InterstitialPage does not support showing full screen popups.";
}
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.h b/chromium/content/browser/frame_host/interstitial_page_impl.h
index 1dd685da87d..0bb90cfda1d 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl.h
+++ b/chromium/content/browser/frame_host/interstitial_page_impl.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_IMPL_H_
#define CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_IMPL_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.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"
@@ -100,7 +104,7 @@ class CONTENT_EXPORT InterstitialPageImpl
const IPC::Message& message) override;
void RenderFrameCreated(RenderFrameHost* render_frame_host) override;
void UpdateTitle(RenderFrameHost* render_frame_host,
- int32 page_id,
+ int32_t page_id,
const base::string16& title,
base::i18n::TextDirection title_direction) override;
AccessibilityMode GetAccessibilityMode() const override;
@@ -119,18 +123,18 @@ class CONTENT_EXPORT InterstitialPageImpl
int error_code) override;
RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const override;
- gfx::Rect GetRootWindowResizerRect() const override;
void CreateNewWindow(
SiteInstance* source_site_instance,
- int route_id,
- int main_frame_route_id,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) override;
- void CreateNewWidget(int32 render_process_id,
- int32 route_id,
+ void CreateNewWidget(int32_t render_process_id,
+ int32_t route_id,
blink::WebPopupType popup_type) override;
- void CreateNewFullscreenWidget(int32 render_process_id,
- int32 route_id) override;
+ void CreateNewFullscreenWidget(int32_t render_process_id,
+ int32_t route_id) override;
void ShowCreatedWindow(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc b/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc
index 405b3b17ea1..05cf0fa99ff 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc
@@ -4,8 +4,10 @@
#include "content/browser/frame_host/interstitial_page_impl.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/clipboard_messages.h"
#include "content/common/frame_messages.h"
@@ -239,7 +241,8 @@ class InterstitialPageImplTest : public ContentBrowserTest {
// Focus the interstitial frame
FrameTree* frame_tree = static_cast<RenderViewHostDelegate*>(
interstitial_.get())->GetFrameTree();
- frame_tree->SetFocusedFrame(frame_tree->root());
+ frame_tree->SetFocusedFrame(frame_tree->root(),
+ frame_tree->GetMainFrame()->GetSiteInstance());
clipboard_message_watcher_ =
new ClipboardMessageWatcher(interstitial_.get());
diff --git a/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h b/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h
index 8a8621912af..0ee1be04976 100644
--- a/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h
+++ b/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_NAVIGATOR_IMPL_H_
#define CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_NAVIGATOR_IMPL_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/frame_host/navigator.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/frame_host/navigation_controller_android.cc b/chromium/content/browser/frame_host/navigation_controller_android.cc
index 6b87d93d8cb..81745177fb9 100644
--- a/chromium/content/browser/frame_host/navigation_controller_android.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/frame_host/navigation_controller_android.h"
+#include <stdint.h>
+
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
@@ -12,6 +14,7 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/ssl_host_state_delegate.h"
#include "jni/NavigationControllerImpl_jni.h"
+#include "net/base/data_url.h"
#include "ui/gfx/android/java_bitmap.h"
using base::android::AttachCurrentThread;
@@ -90,90 +93,119 @@ NavigationControllerAndroid::GetJavaObject() {
return base::android::ScopedJavaLocalRef<jobject>(obj_);
}
-jboolean NavigationControllerAndroid::CanGoBack(JNIEnv* env, jobject obj) {
+jboolean NavigationControllerAndroid::CanGoBack(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return navigation_controller_->CanGoBack();
}
-jboolean NavigationControllerAndroid::CanGoForward(JNIEnv* env,
- jobject obj) {
+jboolean NavigationControllerAndroid::CanGoForward(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return navigation_controller_->CanGoForward();
}
-jboolean NavigationControllerAndroid::CanGoToOffset(JNIEnv* env,
- jobject obj,
- jint offset) {
+jboolean NavigationControllerAndroid::CanGoToOffset(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint offset) {
return navigation_controller_->CanGoToOffset(offset);
}
-void NavigationControllerAndroid::GoBack(JNIEnv* env, jobject obj) {
+void NavigationControllerAndroid::GoBack(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
navigation_controller_->GoBack();
}
-void NavigationControllerAndroid::GoForward(JNIEnv* env, jobject obj) {
+void NavigationControllerAndroid::GoForward(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
navigation_controller_->GoForward();
}
void NavigationControllerAndroid::GoToOffset(JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jint offset) {
navigation_controller_->GoToOffset(offset);
}
-jboolean NavigationControllerAndroid::IsInitialNavigation(JNIEnv* env,
- jobject obj) {
+jboolean NavigationControllerAndroid::IsInitialNavigation(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return navigation_controller_->IsInitialNavigation();
}
-void NavigationControllerAndroid::LoadIfNecessary(JNIEnv* env, jobject obj) {
+void NavigationControllerAndroid::LoadIfNecessary(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
navigation_controller_->LoadIfNecessary();
}
-void NavigationControllerAndroid::ContinuePendingReload(JNIEnv* env,
- jobject obj) {
+void NavigationControllerAndroid::ContinuePendingReload(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
navigation_controller_->ContinuePendingReload();
}
void NavigationControllerAndroid::Reload(JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jboolean check_for_repost) {
navigation_controller_->Reload(check_for_repost);
}
-void NavigationControllerAndroid::ReloadIgnoringCache(
+void NavigationControllerAndroid::ReloadToRefreshContent(
JNIEnv* env,
jobject obj,
jboolean check_for_repost) {
+ navigation_controller_->ReloadToRefreshContent(check_for_repost);
+}
+
+void NavigationControllerAndroid::ReloadIgnoringCache(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean check_for_repost) {
navigation_controller_->ReloadIgnoringCache(check_for_repost);
}
-void NavigationControllerAndroid::RequestRestoreLoad(JNIEnv* env, jobject obj) {
+void NavigationControllerAndroid::ReloadDisableLoFi(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean check_for_repost) {
+ navigation_controller_->ReloadDisableLoFi(check_for_repost);
+}
+
+void NavigationControllerAndroid::RequestRestoreLoad(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
navigation_controller_->SetNeedsReload();
}
-void NavigationControllerAndroid::CancelPendingReload(JNIEnv* env,
- jobject obj) {
+void NavigationControllerAndroid::CancelPendingReload(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
navigation_controller_->CancelPendingReload();
}
-void NavigationControllerAndroid::GoToNavigationIndex(JNIEnv* env,
- jobject obj,
- jint index) {
+void NavigationControllerAndroid::GoToNavigationIndex(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint index) {
navigation_controller_->GoToIndex(index);
}
void NavigationControllerAndroid::LoadUrl(
JNIEnv* env,
- jobject obj,
- jstring url,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& url,
jint load_url_type,
jint transition_type,
- jstring j_referrer_url,
+ const JavaParamRef<jstring>& j_referrer_url,
jint referrer_policy,
jint ua_override_option,
- jstring extra_headers,
- jbyteArray post_data,
- jstring base_url_for_data_url,
- jstring virtual_url_for_data_url,
+ const JavaParamRef<jstring>& extra_headers,
+ const JavaParamRef<jbyteArray>& post_data,
+ const JavaParamRef<jstring>& base_url_for_data_url,
+ const JavaParamRef<jstring>& virtual_url_for_data_url,
+ const JavaParamRef<jstring>& data_url_as_string,
jboolean can_load_local_resources,
jboolean is_renderer_initiated,
jboolean should_replace_current_entry) {
@@ -195,7 +227,7 @@ void NavigationControllerAndroid::LoadUrl(
params.extra_headers = ConvertJavaStringToUTF8(env, extra_headers);
if (post_data) {
- std::vector<uint8> http_body_vector;
+ std::vector<uint8_t> http_body_vector;
base::android::JavaByteArrayToByteVector(env, post_data, &http_body_vector);
params.browser_initiated_post_data =
base::RefCountedBytes::TakeVector(&http_body_vector);
@@ -211,6 +243,24 @@ void NavigationControllerAndroid::LoadUrl(
GURL(ConvertJavaStringToUTF8(env, virtual_url_for_data_url));
}
+ if (data_url_as_string) {
+ // Treat |data_url_as_string| as if we were intending to put it into a GURL
+ // field. Note that kMaxURLChars is only enforced when serializing URLs
+ // for IPC.
+ GURL data_url = GURL(ConvertJavaStringToUTF8(env, data_url_as_string));
+ DCHECK(data_url.SchemeIs(url::kDataScheme));
+ DCHECK(params.url.SchemeIs(url::kDataScheme));
+#if DCHECK_IS_ON()
+ {
+ std::string mime_type, charset, data;
+ DCHECK(net::DataURL::Parse(params.url, &mime_type, &charset, &data));
+ DCHECK(data.empty());
+ }
+#endif
+ std::string s = data_url.spec();
+ params.data_url_as_string = base::RefCountedString::TakeString(&s);
+ }
+
if (j_referrer_url) {
params.referrer = content::Referrer(
GURL(ConvertJavaStringToUTF8(env, j_referrer_url)),
@@ -220,15 +270,18 @@ void NavigationControllerAndroid::LoadUrl(
navigation_controller_->LoadURLWithParams(params);
}
-void NavigationControllerAndroid::ClearHistory(JNIEnv* env, jobject obj) {
+void NavigationControllerAndroid::ClearHistory(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
// TODO(creis): Do callers of this need to know if it fails?
if (navigation_controller_->CanPruneAllButLastCommitted())
navigation_controller_->PruneAllButLastCommitted();
}
-jint NavigationControllerAndroid::GetNavigationHistory(JNIEnv* env,
- jobject obj,
- jobject history) {
+jint NavigationControllerAndroid::GetNavigationHistory(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& history) {
// Iterate through navigation entries to populate the list
int count = navigation_controller_->GetEntryCount();
for (int i = 0; i < count; ++i) {
@@ -241,8 +294,8 @@ jint NavigationControllerAndroid::GetNavigationHistory(JNIEnv* env,
void NavigationControllerAndroid::GetDirectedNavigationHistory(
JNIEnv* env,
- jobject obj,
- jobject history,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& history,
jboolean is_forward,
jint max_entries) {
// Iterate through navigation entries to populate the list
@@ -264,30 +317,32 @@ void NavigationControllerAndroid::GetDirectedNavigationHistory(
ScopedJavaLocalRef<jstring>
NavigationControllerAndroid::GetOriginalUrlForVisibleNavigationEntry(
JNIEnv* env,
- jobject obj) {
+ const JavaParamRef<jobject>& obj) {
NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
if (entry == NULL)
return ScopedJavaLocalRef<jstring>(env, NULL);
return ConvertUTF8ToJavaString(env, entry->GetOriginalRequestURL().spec());
}
-void NavigationControllerAndroid::ClearSslPreferences(JNIEnv* env,
- jobject obj) {
+void NavigationControllerAndroid::ClearSslPreferences(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
content::SSLHostStateDelegate* delegate =
navigation_controller_->GetBrowserContext()->GetSSLHostStateDelegate();
if (delegate)
delegate->Clear();
}
-bool NavigationControllerAndroid::GetUseDesktopUserAgent(JNIEnv* env,
- jobject obj) {
+bool NavigationControllerAndroid::GetUseDesktopUserAgent(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
return entry && entry->GetIsOverridingUserAgent();
}
void NavigationControllerAndroid::SetUseDesktopUserAgent(
JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jboolean enabled,
jboolean reload_on_state_change) {
if (GetUseDesktopUserAgent(env, obj) == enabled)
@@ -311,7 +366,7 @@ void NavigationControllerAndroid::SetUseDesktopUserAgent(
base::android::ScopedJavaLocalRef<jobject>
NavigationControllerAndroid::GetEntryAtIndex(JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
int index) {
if (index < 0 || index >= navigation_controller_->GetEntryCount())
return base::android::ScopedJavaLocalRef<jobject>();
@@ -322,7 +377,8 @@ NavigationControllerAndroid::GetEntryAtIndex(JNIEnv* env,
}
base::android::ScopedJavaLocalRef<jobject>
-NavigationControllerAndroid::GetPendingEntry(JNIEnv* env, jobject obj) {
+NavigationControllerAndroid::GetPendingEntry(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
content::NavigationEntry* entry = navigation_controller_->GetPendingEntry();
if (!entry)
@@ -332,31 +388,35 @@ NavigationControllerAndroid::GetPendingEntry(JNIEnv* env, jobject obj) {
env, entry, navigation_controller_->GetPendingEntryIndex());
}
-jint NavigationControllerAndroid::GetLastCommittedEntryIndex(JNIEnv* env,
- jobject obj) {
+jint NavigationControllerAndroid::GetLastCommittedEntryIndex(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return navigation_controller_->GetLastCommittedEntryIndex();
}
-jboolean NavigationControllerAndroid::RemoveEntryAtIndex(JNIEnv* env,
- jobject obj,
- jint index) {
+jboolean NavigationControllerAndroid::RemoveEntryAtIndex(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint index) {
return navigation_controller_->RemoveEntryAtIndex(index);
}
-jboolean NavigationControllerAndroid::CanCopyStateOver(JNIEnv* env,
- jobject obj) {
+jboolean NavigationControllerAndroid::CanCopyStateOver(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return navigation_controller_->GetEntryCount() == 0 &&
!navigation_controller_->GetPendingEntry();
}
-jboolean NavigationControllerAndroid::CanPruneAllButLastCommitted(JNIEnv* env,
- jobject obj) {
+jboolean NavigationControllerAndroid::CanPruneAllButLastCommitted(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return navigation_controller_->CanPruneAllButLastCommitted();
}
void NavigationControllerAndroid::CopyStateFrom(
JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jlong source_navigation_controller_android) {
navigation_controller_->CopyStateFrom(
*(reinterpret_cast<NavigationControllerAndroid*>(
@@ -365,7 +425,7 @@ void NavigationControllerAndroid::CopyStateFrom(
void NavigationControllerAndroid::CopyStateFromAndPrune(
JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jlong source_navigation_controller_android,
jboolean replace_entry) {
navigation_controller_->CopyStateFromAndPrune(
diff --git a/chromium/content/browser/frame_host/navigation_controller_android.h b/chromium/content/browser/frame_host/navigation_controller_android.h
index 1d9600ed8e7..e22eb882a82 100644
--- a/chromium/content/browser/frame_host/navigation_controller_android.h
+++ b/chromium/content/browser/frame_host/navigation_controller_android.h
@@ -8,8 +8,8 @@
#include <jni.h>
#include "base/android/scoped_java_ref.h"
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
namespace content {
@@ -33,66 +33,111 @@ class CONTENT_EXPORT NavigationControllerAndroid {
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);
- jboolean IsInitialNavigation(JNIEnv* env, jobject obj);
- void LoadIfNecessary(JNIEnv* env, jobject obj);
- void ContinuePendingReload(JNIEnv* env, jobject obj);
- void Reload(JNIEnv* env, jobject obj, jboolean check_for_repost);
- void ReloadIgnoringCache(JNIEnv* env, jobject obj, jboolean check_for_repost);
- void RequestRestoreLoad(JNIEnv* env, jobject obj);
- void CancelPendingReload(JNIEnv* env, jobject obj);
- void GoToNavigationIndex(JNIEnv* env, jobject obj, jint index);
- void LoadUrl(JNIEnv* env,
- jobject obj,
- jstring url,
- jint load_url_type,
- jint transition_type,
- jstring j_referrer_url,
- jint referrer_policy,
- jint ua_override_option,
- jstring extra_headers,
- jbyteArray post_data,
- jstring base_url_for_data_url,
- jstring virtual_url_for_data_url,
- jboolean can_load_local_resources,
- jboolean is_renderer_initiated,
- jboolean should_replace_current_entry);
- void ClearSslPreferences(JNIEnv* env, jobject /* obj */);
- bool GetUseDesktopUserAgent(JNIEnv* env, jobject /* obj */);
- void SetUseDesktopUserAgent(JNIEnv* env,
- jobject /* obj */,
- jboolean state,
- jboolean reload_on_state_change);
- base::android::ScopedJavaLocalRef<jobject> GetEntryAtIndex(JNIEnv* env,
- jobject obj,
- int index);
- base::android::ScopedJavaLocalRef<jobject> GetPendingEntry(JNIEnv* env,
- jobject /* obj */);
- int GetNavigationHistory(JNIEnv* env, jobject obj, jobject history);
- void GetDirectedNavigationHistory(JNIEnv* env,
- jobject obj,
- jobject history,
- jboolean is_forward,
- jint max_entries);
+ jboolean CanGoBack(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ jboolean CanGoForward(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ jboolean CanGoToOffset(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint offset);
+ void GoBack(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void GoForward(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void GoToOffset(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint offset);
+ jboolean IsInitialNavigation(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void LoadIfNecessary(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void ContinuePendingReload(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void Reload(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean check_for_repost);
+ void ReloadToRefreshContent(JNIEnv* env,
+ jobject obj,
+ jboolean check_for_repost);
+ void ReloadIgnoringCache(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean check_for_repost);
+ void ReloadDisableLoFi(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean check_for_repost);
+ void RequestRestoreLoad(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void CancelPendingReload(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void GoToNavigationIndex(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint index);
+ void LoadUrl(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& url,
+ jint load_url_type,
+ jint transition_type,
+ const base::android::JavaParamRef<jstring>& j_referrer_url,
+ jint referrer_policy,
+ jint ua_override_option,
+ const base::android::JavaParamRef<jstring>& extra_headers,
+ const base::android::JavaParamRef<jbyteArray>& post_data,
+ const base::android::JavaParamRef<jstring>& base_url_for_data_url,
+ const base::android::JavaParamRef<jstring>& virtual_url_for_data_url,
+ const base::android::JavaParamRef<jstring>& data_url_as_string,
+ jboolean can_load_local_resources,
+ jboolean is_renderer_initiated,
+ jboolean should_replace_current_entry);
+ void ClearSslPreferences(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& /* obj */);
+ bool GetUseDesktopUserAgent(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& /* obj */);
+ void SetUseDesktopUserAgent(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& /* obj */,
+ jboolean state,
+ jboolean reload_on_state_change);
+ base::android::ScopedJavaLocalRef<jobject> GetEntryAtIndex(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ int index);
+ base::android::ScopedJavaLocalRef<jobject> GetPendingEntry(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& /* obj */);
+ int GetNavigationHistory(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& history);
+ void GetDirectedNavigationHistory(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& history,
+ jboolean is_forward,
+ jint max_entries);
base::android::ScopedJavaLocalRef<jstring>
- GetOriginalUrlForVisibleNavigationEntry(JNIEnv* env, jobject obj);
- void ClearHistory(JNIEnv* env, jobject obj);
- int GetLastCommittedEntryIndex(JNIEnv* env, jobject obj);
- jboolean RemoveEntryAtIndex(JNIEnv* env, jobject obj, jint index);
- jboolean CanCopyStateOver(JNIEnv* env, jobject obj);
- jboolean CanPruneAllButLastCommitted(JNIEnv* env, jobject obj);
+ GetOriginalUrlForVisibleNavigationEntry(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void ClearHistory(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ int GetLastCommittedEntryIndex(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ jboolean RemoveEntryAtIndex(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint index);
+ jboolean CanCopyStateOver(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ jboolean CanPruneAllButLastCommitted(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
void CopyStateFrom(JNIEnv* env,
- jobject obj,
+ const base::android::JavaParamRef<jobject>& obj,
jlong source_native_navigation_controller_android);
void CopyStateFromAndPrune(JNIEnv* env,
- jobject obj,
- jlong source_native_navigation_controller_android,
- jboolean replace_entry);
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong source_native_navigation_controller_android,
+ jboolean replace_entry);
private:
NavigationController* navigation_controller_;
diff --git a/chromium/content/browser/frame_host/navigation_controller_delegate.h b/chromium/content/browser/frame_host/navigation_controller_delegate.h
index e30cc1d12e8..9922ac59817 100644
--- a/chromium/content/browser/frame_host/navigation_controller_delegate.h
+++ b/chromium/content/browser/frame_host/navigation_controller_delegate.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATION_CONTROLLER_DELEGATE_H_
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_CONTROLLER_DELEGATE_H_
+#include <stdint.h>
+
#include <string>
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_controller.h"
@@ -38,8 +40,8 @@ class NavigationControllerDelegate {
virtual const std::string& GetContentsMimeType() const = 0;
virtual void NotifyNavigationStateChanged(InvalidateTypes changed_flags) = 0;
virtual void Stop() = 0;
- virtual int32 GetMaxPageID() = 0;
- virtual int32 GetMaxPageIDForSiteInstance(SiteInstance* site_instance) = 0;
+ virtual int32_t GetMaxPageID() = 0;
+ virtual int32_t GetMaxPageIDForSiteInstance(SiteInstance* site_instance) = 0;
virtual bool IsLoading() const = 0;
virtual bool IsBeingDestroyed() const = 0;
virtual bool CanOverscrollContent() const = 0;
@@ -53,9 +55,9 @@ class NavigationControllerDelegate {
virtual void SetHistoryOffsetAndLength(int history_offset,
int history_length) = 0;
virtual void CopyMaxPageIDsFrom(WebContents* web_contents) = 0;
- virtual void UpdateMaxPageID(int32 page_id) = 0;
+ virtual void UpdateMaxPageID(int32_t page_id) = 0;
virtual void UpdateMaxPageIDForSiteInstance(SiteInstance* site_instance,
- int32 page_id) = 0;
+ int32_t page_id) = 0;
virtual void ActivateAndShowRepostFormWarningDialog() = 0;
virtual bool HasAccessedInitialDocument() = 0;
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.cc b/chromium/content/browser/frame_host/navigation_controller_impl.cc
index 8a0c2071d62..071cec8e4bb 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.cc
@@ -35,6 +35,8 @@
#include "content/browser/frame_host/navigation_controller_impl.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
@@ -74,6 +76,7 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
+#include "content/public/common/content_switches.h"
#include "media/base/mime_util.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"
@@ -127,7 +130,7 @@ NavigationEntryImpl::RestoreType ControllerRestoreTypeToEntryType(
// Configure all the NavigationEntries in entries for restore. This resets
// the transition type to reload and makes sure the content state isn't empty.
void ConfigureEntriesForRestore(
- ScopedVector<NavigationEntryImpl>* entries,
+ std::vector<scoped_ptr<NavigationEntryImpl>>* entries,
NavigationController::RestoreType type) {
for (size_t i = 0; i < entries->size(); ++i) {
// Use a transition type of reload so that we don't incorrectly increase
@@ -135,7 +138,7 @@ void ConfigureEntriesForRestore(
(*entries)[i]->SetTransitionType(ui::PAGE_TRANSITION_RELOAD);
(*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type));
// NOTE(darin): This code is only needed for backwards compat.
- SetPageStateIfEmpty((*entries)[i]);
+ SetPageStateIfEmpty((*entries)[i].get());
}
}
@@ -145,6 +148,13 @@ bool ShouldKeepOverride(const NavigationEntry* last_entry) {
return last_entry && last_entry->GetIsOverridingUserAgent();
}
+// Helper method for FrameTree::ForEach to set the nav_entry_id on each current
+// RenderFrameHost in the tree.
+bool SetFrameNavEntryID(int nav_entry_id, FrameTreeNode* node) {
+ node->current_frame_host()->set_nav_entry_id(nav_entry_id);
+ return true;
+}
+
} // namespace
// NavigationControllerImpl ----------------------------------------------------
@@ -261,19 +271,21 @@ void NavigationControllerImpl::SetBrowserContext(
void NavigationControllerImpl::Restore(
int selected_navigation,
RestoreType type,
- ScopedVector<NavigationEntry>* entries) {
+ std::vector<scoped_ptr<NavigationEntry>>* entries) {
// Verify that this controller is unused and that the input is valid.
DCHECK(GetEntryCount() == 0 && !GetPendingEntry());
DCHECK(selected_navigation >= 0 &&
selected_navigation < static_cast<int>(entries->size()));
needs_reload_ = true;
- for (size_t i = 0; i < entries->size(); ++i) {
- NavigationEntryImpl* entry =
- NavigationEntryImpl::FromNavigationEntry((*entries)[i]);
- entries_.push_back(entry);
- }
- entries->weak_clear();
+ entries_.reserve(entries->size());
+ for (auto& entry : *entries)
+ entries_.push_back(
+ NavigationEntryImpl::FromNavigationEntry(std::move(entry)));
+
+ // At this point, the |entries| is full of empty scoped_ptrs, so it can be
+ // cleared out safely.
+ entries->clear();
// And finish the restore.
FinishRestore(selected_navigation, type);
@@ -282,12 +294,23 @@ void NavigationControllerImpl::Restore(
void NavigationControllerImpl::Reload(bool check_for_repost) {
ReloadInternal(check_for_repost, RELOAD);
}
+void NavigationControllerImpl::ReloadToRefreshContent(bool check_for_repost) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableNonValidatingReloadOnRefreshContent)) {
+ ReloadInternal(check_for_repost, NO_RELOAD);
+ } else {
+ ReloadInternal(check_for_repost, RELOAD);
+ }
+}
void NavigationControllerImpl::ReloadIgnoringCache(bool check_for_repost) {
ReloadInternal(check_for_repost, RELOAD_IGNORING_CACHE);
}
void NavigationControllerImpl::ReloadOriginalRequestURL(bool check_for_repost) {
ReloadInternal(check_for_repost, RELOAD_ORIGINAL_REQUEST_URL);
}
+void NavigationControllerImpl::ReloadDisableLoFi(bool check_for_repost) {
+ ReloadInternal(check_for_repost, RELOAD_DISABLE_LOFI_MODE);
+}
void NavigationControllerImpl::ReloadInternal(bool check_for_repost,
ReloadType reload_type) {
@@ -402,16 +425,24 @@ bool NavigationControllerImpl::IsInitialNavigation() const {
return is_initial_navigation_;
}
+bool NavigationControllerImpl::IsInitialBlankNavigation() const {
+ // TODO(creis): Once we create a NavigationEntry for the initial blank page,
+ // we'll need to check for entry count 1 and restore_type RESTORE_NONE (to
+ // exclude the cloned tab case).
+ return IsInitialNavigation() && GetEntryCount() == 0;
+}
+
NavigationEntryImpl* NavigationControllerImpl::GetEntryWithPageID(
- SiteInstance* instance, int32 page_id) const {
+ SiteInstance* instance,
+ int32_t page_id) const {
int index = GetEntryIndexWithPageID(instance, page_id);
- return (index != -1) ? entries_[index] : nullptr;
+ return (index != -1) ? entries_[index].get() : nullptr;
}
NavigationEntryImpl*
NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const {
int index = GetEntryIndexWithUniqueID(nav_entry_id);
- return (index != -1) ? entries_[index] : nullptr;
+ return (index != -1) ? entries_[index].get() : nullptr;
}
void NavigationControllerImpl::LoadEntry(
@@ -419,7 +450,7 @@ void NavigationControllerImpl::LoadEntry(
// When navigating to a new page, we don't know for sure if we will actually
// end up leaving the current page. The new page load could for example
// result in a download or a 'no content' response (e.g., a mailto: URL).
- SetPendingEntry(entry.Pass());
+ SetPendingEntry(std::move(entry));
NavigateToPendingEntry(NO_RELOAD);
}
@@ -435,7 +466,7 @@ void NavigationControllerImpl::SetPendingEntry(
NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() const {
if (transient_entry_index_ != -1)
- return entries_[transient_entry_index_];
+ return entries_[transient_entry_index_].get();
if (pending_entry_)
return pending_entry_;
return GetLastCommittedEntry();
@@ -443,7 +474,7 @@ NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() const {
NavigationEntryImpl* NavigationControllerImpl::GetVisibleEntry() const {
if (transient_entry_index_ != -1)
- return entries_[transient_entry_index_];
+ return entries_[transient_entry_index_].get();
// The pending entry is safe to return for new (non-history), browser-
// initiated navigations. Most renderer-initiated navigations should not
// show the pending entry, to prevent URL spoof attacks.
@@ -485,7 +516,7 @@ int NavigationControllerImpl::GetCurrentEntryIndex() const {
NavigationEntryImpl* NavigationControllerImpl::GetLastCommittedEntry() const {
if (last_committed_entry_index_ == -1)
return NULL;
- return entries_[last_committed_entry_index_];
+ return entries_[last_committed_entry_index_].get();
}
bool NavigationControllerImpl::CanViewSource() const {
@@ -512,7 +543,7 @@ NavigationEntryImpl* NavigationControllerImpl::GetEntryAtIndex(
if (index < 0 || index >= GetEntryCount())
return nullptr;
- return entries_[index];
+ return entries_[index].get();
}
NavigationEntryImpl* NavigationControllerImpl::GetEntryAtOffset(
@@ -531,7 +562,7 @@ void NavigationControllerImpl::TakeScreenshot() {
void NavigationControllerImpl::SetScreenshotManager(
scoped_ptr<NavigationEntryScreenshotManager> manager) {
if (manager.get())
- screenshot_manager_ = manager.Pass();
+ screenshot_manager_ = std::move(manager);
else
screenshot_manager_.reset(new NavigationEntryScreenshotManager(this));
}
@@ -731,7 +762,7 @@ void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) {
if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
entry = GetLastCommittedEntry()->Clone();
entry->SetPageID(-1);
- entry->AddOrUpdateFrameEntry(node, -1, -1, nullptr, params.url,
+ entry->AddOrUpdateFrameEntry(node, "", -1, -1, nullptr, params.url,
params.referrer, PageState());
}
}
@@ -778,6 +809,9 @@ void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) {
case LOAD_TYPE_DATA:
entry->SetBaseURLForDataURL(params.base_url_for_data_url);
entry->SetVirtualURL(params.virtual_url_for_data_url);
+#if defined(OS_ANDROID)
+ entry->SetDataURLAsString(params.data_url_as_string);
+#endif
entry->SetCanLoadLocalResources(params.can_load_local_resources);
break;
default:
@@ -785,7 +819,7 @@ void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) {
break;
};
- LoadEntry(entry.Pass());
+ LoadEntry(std::move(entry));
}
bool NavigationControllerImpl::RendererDidNavigate(
@@ -937,13 +971,13 @@ bool NavigationControllerImpl::RendererDidNavigate(
NotifyNavigationEntryCommitted(details);
- // Update the RenderViewHost of the top-level RenderFrameHost's notion of what
- // entry it's showing for use later.
- RenderFrameHostImpl* main_frame =
- rfh->frame_tree_node()->frame_tree()->root()->current_frame_host();
- static_cast<RenderViewHostImpl*>(main_frame->GetRenderViewHost())->
- set_nav_entry_id(active_entry->GetUniqueID());
-
+ // Update the nav_entry_id for each RenderFrameHost in the tree, so that each
+ // one knows the latest NavigationEntry it is showing (whether it has
+ // committed anything in this navigation or not). This allows things like
+ // state and title updates from RenderFrames to apply to the latest relevant
+ // NavigationEntry.
+ delegate_->GetFrameTree()->ForEach(
+ base::Bind(&SetFrameNavEntryID, active_entry->GetUniqueID()));
return true;
}
@@ -1107,6 +1141,7 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
// Update the FrameNavigationEntry for new main frame commits.
FrameNavigationEntry* frame_entry =
new_entry->GetFrameEntry(rfh->frame_tree_node());
+ frame_entry->set_frame_unique_name(params.frame_unique_name);
frame_entry->set_item_sequence_number(params.item_sequence_number);
frame_entry->set_document_sequence_number(params.document_sequence_number);
@@ -1128,7 +1163,7 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
last_committed_entry_index_ = -1;
}
- InsertOrReplaceEntry(new_entry.Pass(), replace_entry);
+ InsertOrReplaceEntry(std::move(new_entry), replace_entry);
}
void NavigationControllerImpl::RendererDidNavigateToExistingPage(
@@ -1242,7 +1277,7 @@ void NavigationControllerImpl::RendererDidNavigateNewSubframe(
if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
// Make sure new_entry takes ownership of frame_entry in a scoped_refptr.
FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
- rfh->frame_tree_node()->frame_tree_node_id(),
+ rfh->frame_tree_node()->frame_tree_node_id(), params.frame_unique_name,
params.item_sequence_number, params.document_sequence_number,
rfh->GetSiteInstance(), params.url, params.referrer);
new_entry = GetLastCommittedEntry()->CloneAndReplace(rfh->frame_tree_node(),
@@ -1257,7 +1292,7 @@ void NavigationControllerImpl::RendererDidNavigateNewSubframe(
}
new_entry->SetPageID(params.page_id);
- InsertOrReplaceEntry(new_entry.Pass(), false);
+ InsertOrReplaceEntry(std::move(new_entry), false);
}
bool NavigationControllerImpl::RendererDidNavigateAutoSubframe(
@@ -1303,9 +1338,9 @@ bool NavigationControllerImpl::RendererDidNavigateAutoSubframe(
// it may be a "history auto" case where we update an existing one.
NavigationEntryImpl* last_committed = GetLastCommittedEntry();
last_committed->AddOrUpdateFrameEntry(
- rfh->frame_tree_node(), params.item_sequence_number,
- params.document_sequence_number, rfh->GetSiteInstance(), params.url,
- params.referrer, params.page_state);
+ rfh->frame_tree_node(), params.frame_unique_name,
+ params.item_sequence_number, params.document_sequence_number,
+ rfh->GetSiteInstance(), params.url, params.referrer, params.page_state);
// Cross-process subframe navigations may leave a pending entry around.
// Clear it if it's actually for the subframe.
@@ -1325,11 +1360,11 @@ bool NavigationControllerImpl::RendererDidNavigateAutoSubframe(
int NavigationControllerImpl::GetIndexOfEntry(
const NavigationEntryImpl* entry) const {
- const NavigationEntries::const_iterator i(std::find(
- entries_.begin(),
- entries_.end(),
- entry));
- return (i == entries_.end()) ? -1 : static_cast<int>(i - entries_.begin());
+ for (size_t i = 0; i < entries_.size(); ++i) {
+ if (entries_[i].get() == entry)
+ return i;
+ }
+ return -1;
}
// There are two general cases where a navigation is "in page":
@@ -1363,6 +1398,9 @@ bool NavigationControllerImpl::IsURLInPageNavigation(
}
WebPreferences prefs = rfh->GetRenderViewHost()->GetWebkitPreferences();
+ const url::Origin& committed_origin = static_cast<RenderFrameHostImpl*>(rfh)
+ ->frame_tree_node()
+ ->current_origin();
bool is_same_origin = last_committed_url.is_empty() ||
// TODO(japhet): We should only permit navigations
// originating from about:blank to be in-page if the
@@ -1374,7 +1412,7 @@ bool NavigationControllerImpl::IsURLInPageNavigation(
last_committed_url.GetOrigin() == url.GetOrigin() ||
!prefs.web_security_enabled ||
(prefs.allow_universal_access_from_file_urls &&
- last_committed_url.SchemeIs(url::kFileScheme));
+ committed_origin.scheme() == url::kFileScheme);
if (!is_same_origin && renderer_says_in_page) {
bad_message::ReceivedBadMessage(rfh->GetProcess(),
bad_message::NC_IN_PAGE_NAVIGATION);
@@ -1457,7 +1495,7 @@ void NavigationControllerImpl::CopyStateFromAndPrune(
// new and existing navigations in the tab's current SiteInstances are
// identified properly.
NavigationEntryImpl* last_committed = GetLastCommittedEntry();
- int32 site_max_page_id =
+ int32_t site_max_page_id =
delegate_->GetMaxPageIDForSiteInstance(last_committed->site_instance());
delegate_->CopyMaxPageIDsFrom(source->delegate()->GetWebContents());
delegate_->UpdateMaxPageIDForSiteInstance(last_committed->site_instance(),
@@ -1529,11 +1567,11 @@ void NavigationControllerImpl::SetSessionStorageNamespace(
CHECK(successful_insert) << "Cannot replace existing SessionStorageNamespace";
}
-void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) {
+void NavigationControllerImpl::SetMaxRestoredPageID(int32_t max_id) {
max_restored_page_id_ = max_id;
}
-int32 NavigationControllerImpl::GetMaxRestoredPageID() const {
+int32_t NavigationControllerImpl::GetMaxRestoredPageID() const {
return max_restored_page_id_;
}
@@ -1646,13 +1684,9 @@ void NavigationControllerImpl::InsertOrReplaceEntry(
// When replacing, don't prune the forward history.
if (replace && current_size > 0) {
- int32 page_id = entry->GetPageID();
+ int32_t page_id = entry->GetPageID();
- // ScopedVectors don't automatically delete the replaced value, so make sure
- // the previous value gets deleted.
- scoped_ptr<NavigationEntryImpl> old_entry(
- entries_[last_committed_entry_index_]);
- entries_[last_committed_entry_index_] = entry.release();
+ entries_[last_committed_entry_index_] = std::move(entry);
// This is a new page ID, so we need everybody to know about it.
delegate_->UpdateMaxPageID(page_id);
@@ -1679,8 +1713,8 @@ void NavigationControllerImpl::InsertOrReplaceEntry(
PruneOldestEntryIfFull();
- int32 page_id = entry->GetPageID();
- entries_.push_back(entry.Pass());
+ int32_t page_id = entry->GetPageID();
+ entries_.push_back(std::move(entry));
last_committed_entry_index_ = static_cast<int>(entries_.size()) - 1;
// This is a new page ID, so we need everybody to know about it.
@@ -1734,7 +1768,7 @@ void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) {
// For session history navigations only the pending_entry_index_ is set.
if (!pending_entry_) {
CHECK_NE(pending_entry_index_, -1);
- pending_entry_ = entries_[pending_entry_index_];
+ pending_entry_ = entries_[pending_entry_index_].get();
}
// Any renderer-side debug URLs or javascript: URLs should be ignored if the
@@ -1829,10 +1863,12 @@ void NavigationControllerImpl::FindFramesToNavigate(
return;
// Schedule a load in this frame if the new item isn't for the same item
- // sequence number in the same SiteInstance.
+ // sequence number in the same SiteInstance. Newly restored items may not have
+ // a SiteInstance yet, in which case it will be assigned on first commit.
if (!old_item ||
new_item->item_sequence_number() != old_item->item_sequence_number() ||
- new_item->site_instance() != old_item->site_instance()) {
+ (new_item->site_instance() != nullptr &&
+ new_item->site_instance() != old_item->site_instance())) {
if (old_item &&
new_item->document_sequence_number() ==
old_item->document_sequence_number()) {
@@ -1918,7 +1954,7 @@ void NavigationControllerImpl::FinishRestore(int selected_index,
DCHECK(selected_index >= 0 && selected_index < GetEntryCount());
ConfigureEntriesForRestore(&entries_, type);
- SetMaxRestoredPageID(static_cast<int32>(GetEntryCount()));
+ SetMaxRestoredPageID(static_cast<int32_t>(GetEntryCount()));
last_committed_entry_index_ = selected_index;
}
@@ -1958,8 +1994,8 @@ void NavigationControllerImpl::DiscardTransientEntry() {
transient_entry_index_ = -1;
}
-int NavigationControllerImpl::GetEntryIndexWithPageID(
- SiteInstance* instance, int32 page_id) const {
+int NavigationControllerImpl::GetEntryIndexWithPageID(SiteInstance* instance,
+ int32_t page_id) const {
for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) {
if ((entries_[i]->site_instance() == instance) &&
(entries_[i]->GetPageID() == page_id))
@@ -1980,7 +2016,7 @@ int NavigationControllerImpl::GetEntryIndexWithUniqueID(
NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const {
if (transient_entry_index_ == -1)
return NULL;
- return entries_[transient_entry_index_];
+ return entries_[transient_entry_index_].get();
}
void NavigationControllerImpl::SetTransientEntry(
@@ -1991,7 +2027,7 @@ void NavigationControllerImpl::SetTransientEntry(
index = last_committed_entry_index_ + 1;
DiscardTransientEntry();
entries_.insert(entries_.begin() + index,
- NavigationEntryImpl::FromNavigationEntry(entry.release()));
+ NavigationEntryImpl::FromNavigationEntry(std::move(entry)));
transient_entry_index_ = index;
delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL);
}
@@ -2008,7 +2044,7 @@ void NavigationControllerImpl::InsertEntriesFrom(
// NavigationEntries, it will not be safe to share them with another tab.
// Must have a version of Clone that recreates them.
entries_.insert(entries_.begin() + insert_index++,
- source.entries_[i]->Clone().Pass());
+ source.entries_[i]->Clone());
}
}
}
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.h b/chromium/content/browser/frame_host/navigation_controller_impl.h
index a5136d932bd..72b76d7464a 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.h
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.h
@@ -5,10 +5,15 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATION_CONTROLLER_IMPL_H_
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_CONTROLLER_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
-#include "base/memory/scoped_vector.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/frame_host/navigation_controller_delegate.h"
@@ -40,7 +45,7 @@ class CONTENT_EXPORT NavigationControllerImpl
void SetBrowserContext(BrowserContext* browser_context) override;
void Restore(int selected_navigation,
RestoreType type,
- ScopedVector<NavigationEntry>* entries) override;
+ std::vector<scoped_ptr<NavigationEntry>>* entries) override;
NavigationEntryImpl* GetActiveEntry() const override;
NavigationEntryImpl* GetVisibleEntry() const override;
int GetCurrentEntryIndex() const override;
@@ -72,16 +77,19 @@ class CONTENT_EXPORT NavigationControllerImpl
const SessionStorageNamespaceMap& GetSessionStorageNamespaceMap()
const override;
SessionStorageNamespace* GetDefaultSessionStorageNamespace() override;
- void SetMaxRestoredPageID(int32 max_id) override;
- int32 GetMaxRestoredPageID() const override;
+ void SetMaxRestoredPageID(int32_t max_id) override;
+ int32_t GetMaxRestoredPageID() const override;
bool NeedsReload() const override;
void SetNeedsReload() override;
void CancelPendingReload() override;
void ContinuePendingReload() override;
bool IsInitialNavigation() const override;
+ bool IsInitialBlankNavigation() const override;
void Reload(bool check_for_repost) override;
+ void ReloadToRefreshContent(bool check_for_repost) override;
void ReloadIgnoringCache(bool check_for_repost) override;
void ReloadOriginalRequestURL(bool check_for_repost) override;
+ void ReloadDisableLoFi(bool check_for_repost) override;
void NotifyEntryChanged(const NavigationEntry* entry) override;
void CopyStateFrom(const NavigationController& source) override;
void CopyStateFromAndPrune(NavigationController* source,
@@ -105,17 +113,15 @@ class CONTENT_EXPORT NavigationControllerImpl
// Return the index of the entry with the corresponding instance and page_id,
// or -1 if not found.
- int GetEntryIndexWithPageID(SiteInstance* instance,
- int32 page_id) const;
+ int GetEntryIndexWithPageID(SiteInstance* instance, int32_t page_id) const;
// Return the index of the entry with the given unique id, or -1 if not found.
int GetEntryIndexWithUniqueID(int nav_entry_id) const;
// Return the entry with the corresponding instance and page_id, or null if
// not found.
- NavigationEntryImpl* GetEntryWithPageID(
- SiteInstance* instance,
- int32 page_id) const;
+ NavigationEntryImpl* GetEntryWithPageID(SiteInstance* instance,
+ int32_t page_id) const;
// Return the entry with the given unique id, or null if not found.
NavigationEntryImpl* GetEntryWithUniqueID(int nav_entry_id) const;
@@ -350,9 +356,8 @@ class CONTENT_EXPORT NavigationControllerImpl
// The user browser context associated with this controller.
BrowserContext* browser_context_;
- // List of NavigationEntry for this tab
- using NavigationEntries = ScopedVector<NavigationEntryImpl>;
- NavigationEntries entries_;
+ // List of |NavigationEntry|s for this controller.
+ std::vector<scoped_ptr<NavigationEntryImpl>> entries_;
// An entry we haven't gotten a response for yet. This will be discarded
// when we navigate again. It's used only so we know what the currently
@@ -396,7 +401,7 @@ class CONTENT_EXPORT NavigationControllerImpl
// The max restored page ID in this controller, if it was restored. We must
// store this so that WebContentsImpl can tell any renderer in charge of one
// of the restored entries to update its max page ID.
- int32 max_restored_page_id_;
+ int32_t max_restored_page_id_;
// Manages the SSL security UI.
SSLManager ssl_manager_;
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index f566e71e8c5..c9fa5bdc0db 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -2,12 +2,18 @@
// 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_impl.h"
+
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/frame_host/frame_navigation_entry.h"
#include "content/browser/frame_host/frame_tree.h"
-#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/site_isolation_policy.h"
@@ -26,6 +32,7 @@
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
+#include "content/shell/common/shell_switches.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
@@ -37,7 +44,7 @@ class NavigationControllerBrowserTest : public ContentBrowserTest {
protected:
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
}
};
@@ -66,20 +73,101 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, LoadCrossSiteSubframe) {
EXPECT_EQ(AreAllSitesIsolatedForTesting(), cross_process);
}
+// Verifies that the base, history, and data URLs for LoadDataWithBaseURL end up
+// in the expected parts of the NavigationEntry in each stage of navigation, and
+// that we don't kill the renderer on reload. See https://crbug.com/522567.
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, LoadDataWithBaseURL) {
const GURL base_url("http://baseurl");
const GURL history_url("http://historyurl");
const std::string data = "<html><body>foo</body></html>";
+ const GURL data_url = GURL("data:text/html;charset=utf-8," + data);
- const NavigationController& controller =
- shell()->web_contents()->GetController();
- // Load data. Blocks until it is done.
- content::LoadDataWithBaseURL(shell(), history_url, data, base_url);
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+
+ // Load data, but don't commit yet.
+ TestNavigationObserver same_tab_observer(shell()->web_contents(), 1);
+ shell()->LoadDataWithBaseURL(history_url, data, base_url);
+
+ // Verify the pending NavigationEntry.
+ NavigationEntryImpl* pending_entry = controller.GetPendingEntry();
+ EXPECT_EQ(base_url, pending_entry->GetBaseURLForDataURL());
+ EXPECT_EQ(history_url, pending_entry->GetVirtualURL());
+ EXPECT_EQ(history_url, pending_entry->GetHistoryURLForDataURL());
+ EXPECT_EQ(data_url, pending_entry->GetURL());
+
+ // Let the navigation commit.
+ same_tab_observer.Wait();
+
+ // Verify the last committed NavigationEntry.
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ EXPECT_EQ(base_url, entry->GetBaseURLForDataURL());
+ EXPECT_EQ(history_url, entry->GetVirtualURL());
+ EXPECT_EQ(history_url, entry->GetHistoryURLForDataURL());
+ EXPECT_EQ(data_url, entry->GetURL());
- // We should use history_url instead of the base_url as the original url of
+ // We should use data_url instead of the base_url as the original url of
// this navigation entry, because base_url is only used for resolving relative
// paths in the data, or enforcing same origin policy.
- EXPECT_EQ(controller.GetVisibleEntry()->GetOriginalRequestURL(), history_url);
+ EXPECT_EQ(data_url, entry->GetOriginalRequestURL());
+
+ // Now reload and make sure the renderer isn't killed.
+ ReloadBlockUntilNavigationsComplete(shell(), 1);
+ EXPECT_TRUE(shell()->web_contents()->GetMainFrame()->IsRenderFrameLive());
+
+ // Verify the last committed NavigationEntry hasn't changed.
+ NavigationEntryImpl* reload_entry = controller.GetLastCommittedEntry();
+ EXPECT_EQ(entry, reload_entry);
+ EXPECT_EQ(base_url, reload_entry->GetBaseURLForDataURL());
+ EXPECT_EQ(history_url, reload_entry->GetVirtualURL());
+ EXPECT_EQ(history_url, reload_entry->GetHistoryURLForDataURL());
+ EXPECT_EQ(data_url, reload_entry->GetOriginalRequestURL());
+ EXPECT_EQ(data_url, reload_entry->GetURL());
+}
+
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ NavigateFromLoadDataWithBaseURL) {
+ const GURL base_url("http://baseurl");
+ const GURL history_url("http://historyurl");
+ const std::string data = "<html><body></body></html>";
+ const GURL data_url = GURL("data:text/html;charset=utf-8," + data);
+
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+
+ // Load data and commit.
+ {
+ TestNavigationObserver same_tab_observer(shell()->web_contents(), 1);
+ shell()->LoadDataWithBaseURL(history_url, data, base_url);
+ same_tab_observer.Wait();
+ EXPECT_EQ(1, controller.GetEntryCount());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ EXPECT_EQ(base_url, entry->GetBaseURLForDataURL());
+ EXPECT_EQ(history_url, entry->GetVirtualURL());
+ EXPECT_EQ(history_url, entry->GetHistoryURLForDataURL());
+ EXPECT_EQ(data_url, entry->GetURL());
+ }
+
+ // TODO(boliu): Add test for in-page fragment navigation. See
+ // crbug.com/561034.
+
+ // Navigate with Javascript.
+ {
+ GURL navigate_url = embedded_test_server()->base_url();
+ std::string script = "document.location = '" +
+ navigate_url.spec() + "';";
+ TestNavigationObserver same_tab_observer(shell()->web_contents(), 1);
+ EXPECT_TRUE(content::ExecuteScript(shell()->web_contents(), script));
+ same_tab_observer.Wait();
+ EXPECT_EQ(2, controller.GetEntryCount());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ EXPECT_TRUE(entry->GetBaseURLForDataURL().is_empty());
+ EXPECT_TRUE(entry->GetHistoryURLForDataURL().is_empty());
+ EXPECT_EQ(navigate_url, entry->GetVirtualURL());
+ EXPECT_EQ(navigate_url, entry->GetURL());
+ }
}
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, UniqueIDs) {
@@ -103,6 +191,55 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, UniqueIDs) {
controller.GetEntryAtIndex(1)->GetUniqueID());
}
+// Ensures that RenderFrameHosts end up with the correct nav_entry_id() after
+// navigations.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, UniqueIDsOnFrames) {
+ NavigationController& controller = shell()->web_contents()->GetController();
+
+ // Load a main frame with an about:blank subframe.
+ GURL main_url(embedded_test_server()->GetURL(
+ "/navigation_controller/page_with_iframe.html"));
+ NavigateToURL(shell(), main_url);
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1U, root->child_count());
+ ASSERT_NE(nullptr, root->child_at(0));
+
+ // The main frame's nav_entry_id should match the last committed entry.
+ int unique_id = controller.GetLastCommittedEntry()->GetUniqueID();
+ EXPECT_EQ(unique_id, root->current_frame_host()->nav_entry_id());
+
+ // The about:blank iframe should have inherited the same nav_entry_id.
+ EXPECT_EQ(unique_id, root->child_at(0)->current_frame_host()->nav_entry_id());
+
+ // Use NavigateFrameToURL to go cross-site in the subframe.
+ GURL foo_url(embedded_test_server()->GetURL(
+ "foo.com", "/navigation_controller/simple_page_1.html"));
+ NavigateFrameToURL(root->child_at(0), foo_url);
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+ // The unique ID should have stayed the same for the auto-subframe navigation,
+ // since the new page replaces the initial about:blank page in the subframe.
+ EXPECT_EQ(unique_id, controller.GetLastCommittedEntry()->GetUniqueID());
+ EXPECT_EQ(unique_id, root->current_frame_host()->nav_entry_id());
+ EXPECT_EQ(unique_id, root->child_at(0)->current_frame_host()->nav_entry_id());
+
+ // Navigating in the subframe again should create a new entry.
+ GURL foo_url2(embedded_test_server()->GetURL(
+ "foo.com", "/navigation_controller/simple_page_2.html"));
+ NavigateFrameToURL(root->child_at(0), foo_url2);
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+ int unique_id2 = controller.GetLastCommittedEntry()->GetUniqueID();
+ EXPECT_NE(unique_id, unique_id2);
+
+ // The unique ID should have updated for the current RenderFrameHost in both
+ // frames, not just the subframe.
+ EXPECT_EQ(unique_id2, root->current_frame_host()->nav_entry_id());
+ EXPECT_EQ(unique_id2,
+ root->child_at(0)->current_frame_host()->nav_entry_id());
+}
+
// This test used to make sure that a scheme used to prevent spoofs didn't ever
// interfere with navigations. We switched to a different scheme, so now this is
// just a test to make sure we can still navigate once we prune the history
@@ -1829,7 +1966,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Verify subframe entries if they're enabled (e.g. in --site-per-process).
if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
- // The entry should have a new FrameNavigationEntries for the subframe.
+ // The entry should have a FrameNavigationEntry for the subframe.
ASSERT_EQ(1U, entry2->root_node()->children.size());
EXPECT_EQ(frame_url2, entry2->root_node()->children[0]->frame_entry->url());
} else {
@@ -1851,7 +1988,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Verify subframe entries if they're enabled (e.g. in --site-per-process).
if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
- // The entry should have a new FrameNavigationEntries for the subframe.
+ // The entry should have a FrameNavigationEntry for the subframe.
ASSERT_EQ(1U, entry1->root_node()->children.size());
EXPECT_EQ(frame_url, entry1->root_node()->children[0]->frame_entry->url());
} else {
@@ -1873,7 +2010,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Verify subframe entries if they're enabled (e.g. in --site-per-process).
if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
- // The entry should have a new FrameNavigationEntries for the subframe.
+ // The entry should have a FrameNavigationEntry for the subframe.
ASSERT_EQ(1U, entry2->root_node()->children.size());
EXPECT_EQ(frame_url2, entry2->root_node()->children[0]->frame_entry->url());
} else {
@@ -1895,7 +2032,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Verify subframe entries if they're enabled (e.g. in --site-per-process).
if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
- // The entry should have a new FrameNavigationEntries for the subframe.
+ // The entry should have a FrameNavigationEntry for the subframe.
ASSERT_EQ(1U, entry3->root_node()->children.size());
EXPECT_EQ(frame_url3, entry3->root_node()->children[0]->frame_entry->url());
} else {
@@ -1904,6 +2041,576 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
}
}
+// Verify the tree of FrameNavigationEntries after subframes are recreated in
+// history navigations, including nested frames. The history will look like:
+// 1. initial_url
+// 2. main_url_a (data_url)
+// 3. main_url_a (frame_url_b (data_url))
+// 4. main_url_a (frame_url_b (frame_url_c))
+// 5. main_url_d
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ FrameNavigationEntry_RecreatedSubframeBackForward) {
+ // 1. Start on a page with no frames.
+ GURL initial_url(embedded_test_server()->GetURL(
+ "/navigation_controller/simple_page_1.html"));
+ NavigateToURL(shell(), initial_url);
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ EXPECT_EQ(initial_url, root->current_url());
+ NavigationEntryImpl* entry1 = controller.GetLastCommittedEntry();
+ EXPECT_EQ(0U, entry1->root_node()->children.size());
+
+ // 2. Navigate to a page with a data URL iframe.
+ GURL main_url_a(embedded_test_server()->GetURL(
+ "a.com", "/navigation_controller/page_with_data_iframe.html"));
+ GURL data_url("data:text/html,Subframe");
+ NavigateToURL(shell(), main_url_a);
+ ASSERT_EQ(1U, root->child_count());
+ ASSERT_EQ(0U, root->child_at(0)->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->current_url());
+
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry();
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have a FrameNavigationEntry for the data subframe.
+ ASSERT_EQ(1U, entry2->root_node()->children.size());
+ EXPECT_EQ(data_url, entry2->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry2->root_node()->children.size());
+ }
+
+ // 3. Navigate the iframe cross-site to a page with a nested iframe.
+ GURL frame_url_b(embedded_test_server()->GetURL(
+ "b.com", "/navigation_controller/page_with_data_iframe.html"));
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ NavigateFrameToURL(root->child_at(0), frame_url_b);
+ capturer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->child_at(0)->current_url());
+
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry3 = controller.GetLastCommittedEntry();
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have a FrameNavigationEntry for the b.com subframe.
+ ASSERT_EQ(1U, entry3->root_node()->children.size());
+ ASSERT_EQ(1U, entry3->root_node()->children[0]->children.size());
+ EXPECT_EQ(frame_url_b,
+ entry3->root_node()->children[0]->frame_entry->url());
+ EXPECT_EQ(
+ data_url,
+ entry3->root_node()->children[0]->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry3->root_node()->children.size());
+ }
+
+ // 4. Navigate the nested iframe cross-site.
+ GURL frame_url_c(embedded_test_server()->GetURL(
+ "c.com", "/navigation_controller/simple_page_2.html"));
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0)->child_at(0));
+ NavigateFrameToURL(root->child_at(0)->child_at(0), frame_url_c);
+ capturer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+ EXPECT_EQ(frame_url_c, root->child_at(0)->child_at(0)->current_url());
+
+ EXPECT_EQ(4, controller.GetEntryCount());
+ EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry4 = controller.GetLastCommittedEntry();
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have FrameNavigationEntries for the subframes.
+ ASSERT_EQ(1U, entry4->root_node()->children.size());
+ ASSERT_EQ(1U, entry4->root_node()->children[0]->children.size());
+ EXPECT_EQ(frame_url_b,
+ entry4->root_node()->children[0]->frame_entry->url());
+ EXPECT_EQ(
+ frame_url_c,
+ entry4->root_node()->children[0]->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry4->root_node()->children.size());
+ }
+
+ // 5. Navigate main frame cross-site, destroying the frames.
+ GURL main_url_d(embedded_test_server()->GetURL(
+ "d.com", "/navigation_controller/simple_page_2.html"));
+ NavigateToURL(shell(), main_url_d);
+ ASSERT_EQ(0U, root->child_count());
+ EXPECT_EQ(main_url_d, root->current_url());
+
+ EXPECT_EQ(5, controller.GetEntryCount());
+ EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry5 = controller.GetLastCommittedEntry();
+ EXPECT_EQ(0U, entry5->root_node()->children.size());
+
+ // 6. Go back, recreating the iframe and its nested iframe.
+ {
+ TestNavigationObserver back_load_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoBack();
+ back_load_observer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ ASSERT_EQ(1U, root->child_at(0)->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+ EXPECT_EQ(frame_url_c, root->child_at(0)->child_at(0)->current_url());
+
+ EXPECT_EQ(5, controller.GetEntryCount());
+ EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry4, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have FrameNavigationEntries for the subframes.
+ ASSERT_EQ(1U, entry4->root_node()->children.size());
+ ASSERT_EQ(1U, entry4->root_node()->children[0]->children.size());
+ EXPECT_EQ(frame_url_b,
+ entry4->root_node()->children[0]->frame_entry->url());
+ EXPECT_EQ(
+ frame_url_c,
+ entry4->root_node()->children[0]->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry4->root_node()->children.size());
+ }
+
+ // 7. Go back again, to the data URL in the nested iframe.
+ {
+ TestNavigationObserver back_load_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoBack();
+ back_load_observer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ ASSERT_EQ(1U, root->child_at(0)->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->child_at(0)->current_url());
+
+ EXPECT_EQ(5, controller.GetEntryCount());
+ EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry3, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have FrameNavigationEntries for the subframes.
+ ASSERT_EQ(1U, entry3->root_node()->children.size());
+ ASSERT_EQ(1U, entry3->root_node()->children[0]->children.size());
+ EXPECT_EQ(frame_url_b,
+ entry3->root_node()->children[0]->frame_entry->url());
+ EXPECT_EQ(
+ data_url,
+ entry3->root_node()->children[0]->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry3->root_node()->children.size());
+ }
+
+ // 8. Go back again, to the data URL in the first subframe.
+ {
+ TestNavigationObserver back_load_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoBack();
+ back_load_observer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ ASSERT_EQ(0U, root->child_at(0)->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->current_url());
+
+ EXPECT_EQ(5, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry2, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have a FrameNavigationEntry for the subframe.
+ ASSERT_EQ(1U, entry2->root_node()->children.size());
+ EXPECT_EQ(data_url, entry2->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry2->root_node()->children.size());
+ }
+
+ // 9. Go back again, to the initial main frame page.
+ {
+ TestNavigationObserver back_load_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoBack();
+ back_load_observer.Wait();
+ }
+ ASSERT_EQ(0U, root->child_count());
+ EXPECT_EQ(initial_url, root->current_url());
+
+ EXPECT_EQ(5, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry1, controller.GetLastCommittedEntry());
+ EXPECT_EQ(0U, entry1->root_node()->children.size());
+
+ // 10. Go forward multiple entries and verify the correct subframe URLs load.
+ {
+ TestNavigationObserver back_load_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoToOffset(2);
+ back_load_observer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->child_at(0)->current_url());
+
+ EXPECT_EQ(5, controller.GetEntryCount());
+ EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry3, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have FrameNavigationEntries for the subframes.
+ ASSERT_EQ(1U, entry3->root_node()->children.size());
+ EXPECT_EQ(frame_url_b,
+ entry3->root_node()->children[0]->frame_entry->url());
+ EXPECT_EQ(
+ data_url,
+ entry3->root_node()->children[0]->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry3->root_node()->children.size());
+ }
+}
+
+// Verify that we navigate to the fallback (original) URL if a subframe's
+// FrameNavigationEntry can't be found during a history navigation.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ FrameNavigationEntry_SubframeHistoryFallback) {
+ // This test only makes sense when subframe FrameNavigationEntries are in use.
+ if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
+ return;
+
+ // 1. Start on a page with a data URL iframe.
+ GURL main_url_a(embedded_test_server()->GetURL(
+ "a.com", "/navigation_controller/page_with_data_iframe.html"));
+ GURL data_url("data:text/html,Subframe");
+ NavigateToURL(shell(), main_url_a);
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1U, root->child_count());
+ ASSERT_EQ(0U, root->child_at(0)->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->current_url());
+
+ EXPECT_EQ(1, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry1 = controller.GetLastCommittedEntry();
+
+ // The entry should have a FrameNavigationEntry for the data subframe.
+ ASSERT_EQ(1U, entry1->root_node()->children.size());
+ EXPECT_EQ(data_url, entry1->root_node()->children[0]->frame_entry->url());
+
+ // 2. Navigate the iframe cross-site.
+ GURL frame_url_b(embedded_test_server()->GetURL(
+ "b.com", "/navigation_controller/simple_page_1.html"));
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ NavigateFrameToURL(root->child_at(0), frame_url_b);
+ capturer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry();
+
+ // The entry should have a FrameNavigationEntry for the b.com subframe.
+ ASSERT_EQ(1U, entry2->root_node()->children.size());
+ EXPECT_EQ(frame_url_b, entry2->root_node()->children[0]->frame_entry->url());
+
+ // 3. Navigate main frame cross-site, destroying the frames.
+ GURL main_url_c(embedded_test_server()->GetURL(
+ "c.com", "/navigation_controller/simple_page_2.html"));
+ NavigateToURL(shell(), main_url_c);
+ ASSERT_EQ(0U, root->child_count());
+ EXPECT_EQ(main_url_c, root->current_url());
+
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry3 = controller.GetLastCommittedEntry();
+ EXPECT_EQ(0U, entry3->root_node()->children.size());
+
+ // Force the subframe entry to have the wrong name, so that it isn't found
+ // when we go back.
+ entry2->root_node()->children[0]->frame_entry->set_frame_unique_name("wrong");
+
+ // 4. Go back, recreating the iframe. The subframe entry won't be found, and
+ // we should fall back to the default URL.
+ {
+ TestNavigationObserver back_load_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoBack();
+ back_load_observer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->current_url());
+
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry2, controller.GetLastCommittedEntry());
+
+ // The entry should have both the stale FrameNavigationEntry with the old
+ // name and the new FrameNavigationEntry for the fallback navigation.
+ ASSERT_EQ(2U, entry2->root_node()->children.size());
+ EXPECT_EQ(frame_url_b, entry2->root_node()->children[0]->frame_entry->url());
+ EXPECT_EQ(data_url, entry2->root_node()->children[1]->frame_entry->url());
+}
+
+// Verify that subframes can be restored in a new NavigationController using the
+// PageState of an existing NavigationEntry.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ FrameNavigationEntry_RestoreViaPageState) {
+ // 1. Start on a page with a data URL iframe.
+ GURL main_url_a(embedded_test_server()->GetURL(
+ "a.com", "/navigation_controller/page_with_data_iframe.html"));
+ GURL data_url("data:text/html,Subframe");
+ NavigateToURL(shell(), main_url_a);
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1U, root->child_count());
+ ASSERT_EQ(0U, root->child_at(0)->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->current_url());
+
+ EXPECT_EQ(1, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry1 = controller.GetLastCommittedEntry();
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have a FrameNavigationEntry for the data subframe.
+ ASSERT_EQ(1U, entry1->root_node()->children.size());
+ EXPECT_EQ(data_url, entry1->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry1->root_node()->children.size());
+ }
+
+ // 2. Navigate the iframe cross-site.
+ GURL frame_url_b(embedded_test_server()->GetURL(
+ "b.com", "/navigation_controller/simple_page_1.html"));
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ NavigateFrameToURL(root->child_at(0), frame_url_b);
+ capturer.Wait();
+ }
+ ASSERT_EQ(1U, root->child_count());
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry();
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have a FrameNavigationEntry for the b.com subframe.
+ ASSERT_EQ(1U, entry2->root_node()->children.size());
+ EXPECT_EQ(frame_url_b,
+ entry2->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry2->root_node()->children.size());
+ }
+
+ // 3. Navigate main frame cross-site, destroying the frames.
+ GURL main_url_c(embedded_test_server()->GetURL(
+ "c.com", "/navigation_controller/simple_page_2.html"));
+ NavigateToURL(shell(), main_url_c);
+ ASSERT_EQ(0U, root->child_count());
+ EXPECT_EQ(main_url_c, root->current_url());
+
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry3 = controller.GetLastCommittedEntry();
+ EXPECT_EQ(0U, entry3->root_node()->children.size());
+
+ // 4. Create a NavigationEntry with the same PageState as |entry2| and verify
+ // it has the same FrameNavigationEntry structure.
+ scoped_ptr<NavigationEntryImpl> restored_entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ NavigationControllerImpl::CreateNavigationEntry(
+ main_url_a, Referrer(), ui::PAGE_TRANSITION_RELOAD, false,
+ std::string(), controller.GetBrowserContext()));
+ restored_entry->SetPageID(0);
+ EXPECT_EQ(0U, restored_entry->root_node()->children.size());
+ restored_entry->SetPageState(entry2->GetPageState());
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have a FrameNavigationEntry for the b.com subframe.
+ EXPECT_EQ(main_url_a, restored_entry->root_node()->frame_entry->url());
+ ASSERT_EQ(1U, restored_entry->root_node()->children.size());
+ EXPECT_EQ(frame_url_b,
+ restored_entry->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, restored_entry->root_node()->children.size());
+ }
+
+ // 5. Restore the new entry in a new tab and verify the correct URLs load.
+ std::vector<scoped_ptr<NavigationEntry>> entries;
+ entries.push_back(std::move(restored_entry));
+ Shell* new_shell = Shell::CreateNewWindow(
+ controller.GetBrowserContext(), GURL::EmptyGURL(), nullptr, gfx::Size());
+ FrameTreeNode* new_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ NavigationControllerImpl& new_controller =
+ static_cast<NavigationControllerImpl&>(
+ new_shell->web_contents()->GetController());
+ new_controller.Restore(
+ entries.size() - 1,
+ NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
+ ASSERT_EQ(0u, entries.size());
+ {
+ TestNavigationObserver restore_observer(new_shell->web_contents());
+ new_controller.LoadIfNecessary();
+ restore_observer.Wait();
+ }
+ ASSERT_EQ(1U, new_root->child_count());
+ EXPECT_EQ(main_url_a, new_root->current_url());
+ EXPECT_EQ(frame_url_b, new_root->child_at(0)->current_url());
+
+ EXPECT_EQ(1, new_controller.GetEntryCount());
+ EXPECT_EQ(0, new_controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* new_entry = new_controller.GetLastCommittedEntry();
+
+ // Verify subframe entries if they're enabled (e.g. in --site-per-process).
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // The entry should have a FrameNavigationEntry for the b.com subframe.
+ EXPECT_EQ(main_url_a, new_entry->root_node()->frame_entry->url());
+ ASSERT_EQ(1U, new_entry->root_node()->children.size());
+ EXPECT_EQ(frame_url_b,
+ new_entry->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, new_entry->root_node()->children.size());
+ }
+}
+
+// Verifies that the |frame_unique_name| is set to the correct frame, so that we
+// can match subframe FrameNavigationEntries to newly created frames after
+// back/forward and restore.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ FrameNavigationEntry_FrameUniqueName) {
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+
+ // 1. Navigate the main frame.
+ GURL url(embedded_test_server()->GetURL(
+ "/navigation_controller/page_with_links.html"));
+ NavigateToURL(shell(), url);
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ SiteInstance* main_site_instance =
+ root->current_frame_host()->GetSiteInstance();
+
+ // The main frame defaults to an empty name.
+ FrameNavigationEntry* frame_entry =
+ controller.GetLastCommittedEntry()->GetFrameEntry(root);
+ EXPECT_EQ("", frame_entry->frame_unique_name());
+
+ // Test subframe unique names only if enabled, e.g. in --site-per-process.
+ if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
+ return;
+
+ // 2. Add an unnamed subframe, which does an AUTO_SUBFRAME navigation.
+ {
+ LoadCommittedCapturer capturer(shell()->web_contents());
+ std::string script = "var iframe = document.createElement('iframe');"
+ "iframe.src = '" + url.spec() + "';"
+ "document.body.appendChild(iframe);";
+ EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
+ capturer.Wait();
+ EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.transition_type());
+ }
+
+ // The root FrameNavigationEntry hasn't changed.
+ EXPECT_EQ(frame_entry,
+ controller.GetLastCommittedEntry()->GetFrameEntry(root));
+
+ // The subframe should have a generated name.
+ FrameTreeNode* subframe = root->child_at(0);
+ EXPECT_EQ(main_site_instance,
+ subframe->current_frame_host()->GetSiteInstance());
+ FrameNavigationEntry* subframe_entry =
+ controller.GetLastCommittedEntry()->GetFrameEntry(subframe);
+ std::string unnamed_subframe_name = "<!--framePath //<!--frame0-->-->";
+ EXPECT_EQ(unnamed_subframe_name, subframe_entry->frame_unique_name());
+
+ // 3. Add a named subframe.
+ {
+ LoadCommittedCapturer capturer(shell()->web_contents());
+ std::string script = "var iframe = document.createElement('iframe');"
+ "iframe.src = '" + url.spec() + "';"
+ "iframe.name = 'foo';"
+ "document.body.appendChild(iframe);";
+ EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
+ capturer.Wait();
+ EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.transition_type());
+ }
+
+ // The new subframe should have the specified name.
+ EXPECT_EQ(frame_entry,
+ controller.GetLastCommittedEntry()->GetFrameEntry(root));
+ FrameTreeNode* foo_subframe = root->child_at(1);
+ EXPECT_EQ(main_site_instance,
+ foo_subframe->current_frame_host()->GetSiteInstance());
+ FrameNavigationEntry* foo_subframe_entry =
+ controller.GetLastCommittedEntry()->GetFrameEntry(foo_subframe);
+ std::string named_subframe_name = "foo";
+ EXPECT_EQ(named_subframe_name, foo_subframe_entry->frame_unique_name());
+
+ // 4. Navigating in the subframes cross-process shouldn't change their names.
+ // TODO(creis): Fix the unnamed case in https://crbug.com/502317.
+ GURL bar_url(embedded_test_server()->GetURL(
+ "bar.com", "/navigation_controller/simple_page_1.html"));
+ NavigateFrameToURL(foo_subframe, bar_url);
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+ EXPECT_NE(main_site_instance,
+ foo_subframe->current_frame_host()->GetSiteInstance());
+ foo_subframe_entry =
+ controller.GetLastCommittedEntry()->GetFrameEntry(foo_subframe);
+ EXPECT_EQ(named_subframe_name, foo_subframe_entry->frame_unique_name());
+}
+
// Verifies that item sequence numbers and document sequence numbers update
// properly for main frames and subframes.
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
@@ -1922,8 +2629,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
FrameNavigationEntry* frame_entry =
controller.GetLastCommittedEntry()->GetFrameEntry(root);
- int64 isn_1 = frame_entry->item_sequence_number();
- int64 dsn_1 = frame_entry->document_sequence_number();
+ int64_t isn_1 = frame_entry->item_sequence_number();
+ int64_t dsn_1 = frame_entry->document_sequence_number();
EXPECT_NE(-1, isn_1);
EXPECT_NE(-1, dsn_1);
@@ -1933,8 +2640,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
frame_entry = controller.GetLastCommittedEntry()->GetFrameEntry(root);
- int64 isn_2 = frame_entry->item_sequence_number();
- int64 dsn_2 = frame_entry->document_sequence_number();
+ int64_t isn_2 = frame_entry->item_sequence_number();
+ int64_t dsn_2 = frame_entry->document_sequence_number();
EXPECT_NE(-1, isn_2);
EXPECT_NE(isn_1, isn_2);
EXPECT_EQ(dsn_1, dsn_2);
@@ -1946,10 +2653,10 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// 3. Add a subframe, which does an AUTO_SUBFRAME navigation.
{
LoadCommittedCapturer capturer(shell()->web_contents());
- std::string script = "var iframe = document.createElement('iframe');"
- "iframe.src = '" + url.spec() + "';"
- "document.body.appendChild(iframe);";
- EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
+ std::string add_script = "var iframe = document.createElement('iframe');"
+ "iframe.src = '" + url.spec() + "';"
+ "document.body.appendChild(iframe);";
+ EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), add_script));
capturer.Wait();
EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.transition_type());
}
@@ -1962,8 +2669,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
FrameTreeNode* subframe = root->child_at(0);
FrameNavigationEntry* subframe_entry =
controller.GetLastCommittedEntry()->GetFrameEntry(subframe);
- int64 isn_3 = subframe_entry->item_sequence_number();
- int64 dsn_3 = subframe_entry->document_sequence_number();
+ int64_t isn_3 = subframe_entry->item_sequence_number();
+ int64_t dsn_3 = subframe_entry->document_sequence_number();
EXPECT_NE(-1, isn_2);
EXPECT_NE(isn_2, isn_3);
EXPECT_NE(dsn_2, dsn_3);
@@ -1973,39 +2680,113 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
subframe_entry = controller.GetLastCommittedEntry()->GetFrameEntry(subframe);
- int64 isn_4 = subframe_entry->item_sequence_number();
- int64 dsn_4 = subframe_entry->document_sequence_number();
+ int64_t isn_4 = subframe_entry->item_sequence_number();
+ int64_t dsn_4 = subframe_entry->document_sequence_number();
EXPECT_NE(-1, isn_4);
EXPECT_NE(isn_3, isn_4);
EXPECT_EQ(dsn_3, dsn_4);
}
-namespace {
-
-class HttpThrottle : public ResourceThrottle {
+// Support a set of tests that isolate only a subset of sites with
+// out-of-process iframes (OOPIFs).
+class NavigationControllerOopifBrowserTest
+ : public NavigationControllerBrowserTest {
public:
- // ResourceThrottle
- void WillStartRequest(bool* defer) override {
- *defer = true;
- }
+ NavigationControllerOopifBrowserTest() {}
- const char* GetNameForLogging() const override {
- return "HttpThrottle";
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // Enable the OOPIF framework but only isolate sites from a single TLD.
+ command_line->AppendSwitchASCII(switches::kIsolateSitesForTesting, "*.is");
}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NavigationControllerOopifBrowserTest);
};
-class StallDelegate : public ResourceDispatcherHostDelegate {
- // ResourceDispatcherHostDelegate
- void RequestBeginning(
- net::URLRequest* request,
- content::ResourceContext* resource_context,
- content::AppCacheService* appcache_service,
- ResourceType resource_type,
- ScopedVector<content::ResourceThrottle>* throttles) override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- throttles->push_back(new HttpThrottle);
+// Verify that restoring a NavigationEntry with cross-site subframes does not
+// create out-of-process iframes unless the current SiteIsolationPolicy says to.
+IN_PROC_BROWSER_TEST_F(NavigationControllerOopifBrowserTest,
+ RestoreWithoutExtraOopifs) {
+ // This test requires OOPIFs to be possible.
+ EXPECT_TRUE(SiteIsolationPolicy::AreCrossProcessFramesPossible());
+
+ // 1. Start on a page with a data URL iframe.
+ GURL main_url_a(embedded_test_server()->GetURL(
+ "a.com", "/navigation_controller/page_with_data_iframe.html"));
+ GURL data_url("data:text/html,Subframe");
+ EXPECT_TRUE(NavigateToURL(shell(), main_url_a));
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(data_url, root->child_at(0)->current_url());
+
+ // 2. Navigate the iframe cross-site.
+ GURL frame_url_b(embedded_test_server()->GetURL(
+ "b.com", "/navigation_controller/simple_page_1.html"));
+ NavigateFrameToURL(root->child_at(0), frame_url_b);
+ EXPECT_EQ(main_url_a, root->current_url());
+ EXPECT_EQ(frame_url_b, root->child_at(0)->current_url());
+
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry();
+
+ // 3. Create a NavigationEntry with the same PageState as |entry2|.
+ scoped_ptr<NavigationEntryImpl> restored_entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ NavigationControllerImpl::CreateNavigationEntry(
+ main_url_a, Referrer(), ui::PAGE_TRANSITION_RELOAD, false,
+ std::string(), controller.GetBrowserContext()));
+ restored_entry->SetPageID(0);
+ EXPECT_EQ(0U, restored_entry->root_node()->children.size());
+ restored_entry->SetPageState(entry2->GetPageState());
+
+ // The entry should have no SiteInstance in the FrameNavigationEntry for the
+ // b.com subframe.
+ EXPECT_FALSE(
+ restored_entry->root_node()->children[0]->frame_entry->site_instance());
+
+ // 4. Restore the new entry in a new tab and verify the correct URLs load.
+ std::vector<scoped_ptr<NavigationEntry>> entries;
+ entries.push_back(std::move(restored_entry));
+ Shell* new_shell = Shell::CreateNewWindow(
+ controller.GetBrowserContext(), GURL::EmptyGURL(), nullptr, gfx::Size());
+ FrameTreeNode* new_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ NavigationControllerImpl& new_controller =
+ static_cast<NavigationControllerImpl&>(
+ new_shell->web_contents()->GetController());
+ new_controller.Restore(
+ entries.size() - 1,
+ NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
+ ASSERT_EQ(0u, entries.size());
+ {
+ TestNavigationObserver restore_observer(new_shell->web_contents());
+ new_controller.LoadIfNecessary();
+ restore_observer.Wait();
}
-};
+ ASSERT_EQ(1U, new_root->child_count());
+ EXPECT_EQ(main_url_a, new_root->current_url());
+ EXPECT_EQ(frame_url_b, new_root->child_at(0)->current_url());
+
+ // The subframe should only be in a different SiteInstance if OOPIFs are
+ // required for all sites.
+ if (AreAllSitesIsolatedForTesting()) {
+ EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(0)->current_frame_host()->GetSiteInstance());
+ } else {
+ EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(0)->current_frame_host()->GetSiteInstance());
+ }
+}
+
+namespace {
// Loads |start_url|, then loads |stalled_url| which stalls. While the page is
// stalled, an in-page navigation happens. Make sure that all the navigations
@@ -2026,7 +2807,7 @@ void DoReplaceStateWhilePending(Shell* shell,
EXPECT_TRUE(NavigateToURL(shell, start_url));
// Have the user decide to go to a different page which is very slow.
- StallDelegate stall_delegate;
+ NavigationStallDelegate stall_delegate(stalled_url);
ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
controller.LoadURL(
stalled_url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
@@ -2311,10 +3092,10 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_TRUE(NavigateToURL(shell(), url1));
// Have the user decide to go to a different page which is very slow.
- StallDelegate stall_delegate;
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
GURL url2(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_2.html"));
+ NavigationStallDelegate stall_delegate(url2);
+ ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
// That should be the pending entry.
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
index 4be1b1a8d39..775feb3debf 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -2,18 +2,23 @@
// 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 "content/browser/frame_host/navigation_controller_impl.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/cross_site_transferring_request.h"
#include "content/browser/frame_host/frame_navigation_entry.h"
-#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/frame_host/navigation_request.h"
@@ -31,7 +36,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/page_state.h"
#include "content/public/common/page_type.h"
#include "content/public/common/url_constants.h"
@@ -44,6 +49,7 @@
#include "net/base/net_util.h"
#include "skia/ext/platform_canvas.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
#include "third_party/WebKit/public/web/WebSandboxFlags.h"
using base::Time;
@@ -133,7 +139,7 @@ namespace content {
// function.
TEST(TimeSmoother, Basic) {
NavigationControllerImpl::TimeSmoother smoother;
- for (int64 i = 1; i < 1000; ++i) {
+ for (int64_t i = 1; i < 1000; ++i) {
base::Time t = base::Time::FromInternalValue(i);
EXPECT_EQ(t, smoother.GetSmoothedTime(t));
}
@@ -145,7 +151,7 @@ TEST(TimeSmoother, SingleDuplicate) {
NavigationControllerImpl::TimeSmoother smoother;
base::Time t = base::Time::FromInternalValue(1);
EXPECT_EQ(t, smoother.GetSmoothedTime(t));
- for (int64 i = 1; i < 1000; ++i) {
+ for (int64_t i = 1; i < 1000; ++i) {
base::Time expected_t = base::Time::FromInternalValue(i + 1);
t = base::Time::FromInternalValue(i);
EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
@@ -155,14 +161,14 @@ TEST(TimeSmoother, SingleDuplicate) {
// With k duplicates and timestamps thereafter increasing by one
// microsecond, the smoothed time should always be k behind.
TEST(TimeSmoother, ManyDuplicates) {
- const int64 kNumDuplicates = 100;
+ const int64_t kNumDuplicates = 100;
NavigationControllerImpl::TimeSmoother smoother;
base::Time t = base::Time::FromInternalValue(1);
- for (int64 i = 0; i < kNumDuplicates; ++i) {
+ for (int64_t i = 0; i < kNumDuplicates; ++i) {
base::Time expected_t = base::Time::FromInternalValue(i + 1);
EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
}
- for (int64 i = 1; i < 1000; ++i) {
+ for (int64_t i = 1; i < 1000; ++i) {
base::Time expected_t =
base::Time::FromInternalValue(i + kNumDuplicates);
t = base::Time::FromInternalValue(i);
@@ -173,10 +179,10 @@ TEST(TimeSmoother, ManyDuplicates) {
// If the clock jumps far back enough after a run of duplicates, it
// should immediately jump to that value.
TEST(TimeSmoother, ClockBackwardsJump) {
- const int64 kNumDuplicates = 100;
+ const int64_t kNumDuplicates = 100;
NavigationControllerImpl::TimeSmoother smoother;
base::Time t = base::Time::FromInternalValue(1000);
- for (int64 i = 0; i < kNumDuplicates; ++i) {
+ for (int64_t i = 0; i < kNumDuplicates; ++i) {
base::Time expected_t = base::Time::FromInternalValue(i + 1000);
EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
}
@@ -221,8 +227,7 @@ class NavigationControllerTest
}
bool HasNavigationRequest() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
return contents()->GetFrameTree()->root()->navigation_request() !=
nullptr;
}
@@ -231,8 +236,7 @@ class NavigationControllerTest
}
const GURL GetLastNavigationURL() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
NavigationRequest* navigation_request =
contents()->GetFrameTree()->root()->navigation_request();
CHECK(navigation_request);
@@ -539,6 +543,9 @@ void CheckNavigationEntryMatchLoadParams(
if (!load_params.virtual_url_for_data_url.is_empty()) {
EXPECT_EQ(load_params.virtual_url_for_data_url, entry->GetVirtualURL());
}
+#if defined(OS_ANDROID)
+ EXPECT_EQ(load_params.data_url_as_string, entry->GetDataURLAsString());
+#endif
if (NavigationController::UA_OVERRIDE_INHERIT !=
load_params.override_user_agent) {
bool should_override = (NavigationController::UA_OVERRIDE_TRUE ==
@@ -594,6 +601,25 @@ TEST_F(NavigationControllerTest, LoadURLWithExtraParams_Data) {
CheckNavigationEntryMatchLoadParams(load_params, entry);
}
+#if defined(OS_ANDROID)
+TEST_F(NavigationControllerTest, LoadURLWithExtraParams_Data_Android) {
+ NavigationControllerImpl& controller = controller_impl();
+
+ NavigationController::LoadURLParams load_params(GURL("data:,"));
+ load_params.load_type = NavigationController::LOAD_TYPE_DATA;
+ load_params.base_url_for_data_url = GURL("http://foo");
+ load_params.virtual_url_for_data_url = GURL(url::kAboutBlankURL);
+ std::string s("data:,data");
+ load_params.data_url_as_string = base::RefCountedString::TakeString(&s);
+ load_params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
+
+ controller.LoadURLWithParams(load_params);
+ NavigationEntryImpl* entry = controller.GetPendingEntry();
+
+ CheckNavigationEntryMatchLoadParams(load_params, entry);
+}
+#endif
+
TEST_F(NavigationControllerTest, LoadURLWithExtraParams_HttpPost) {
NavigationControllerImpl& controller = controller_impl();
@@ -1022,8 +1048,7 @@ TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) {
EXPECT_EQ(-1, controller.GetPendingEntryIndex());
EXPECT_FALSE(controller.GetPendingEntry());
EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation))
+ if (IsBrowserSideNavigationEnabled())
EXPECT_EQ(4, delegate->navigation_state_change_count());
else
EXPECT_EQ(2, delegate->navigation_state_change_count());
@@ -1175,7 +1200,7 @@ TEST_F(NavigationControllerTest, LoadURL_WithBindings) {
// that orig_rfh belongs to, to prevent it from being destroyed when
// it gets swapped out, so that we can reuse orig_rfh when the
// controller goes back.
- orig_rfh->GetSiteInstance()->increment_active_frame_count();
+ orig_rfh->GetSiteInstance()->IncrementActiveFrameCount();
// Navigate to a second URL, simulate the beforeunload ack for the cross-site
// transition, and set bindings on the pending RenderViewHost to simulate a
@@ -2025,8 +2050,9 @@ TEST_F(NavigationControllerTest, NewSubframe) {
// Prereq: add a subframe with an initial auto-subframe navigation.
main_test_rfh()->OnCreateChildFrame(
- MSG_ROUTING_NONE, blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ process()->GetNextRoutingID(), blink::WebTreeScopeType::Document,
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
RenderFrameHostImpl* subframe =
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host();
const GURL subframe_url("http://foo1/subframe");
@@ -2105,8 +2131,9 @@ TEST_F(NavigationControllerTest, AutoSubframe) {
// Add a subframe and navigate it.
main_test_rfh()->OnCreateChildFrame(
- MSG_ROUTING_NONE, blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ process()->GetNextRoutingID(), blink::WebTreeScopeType::Document,
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
RenderFrameHostImpl* subframe =
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host();
const GURL url2("http://foo/2");
@@ -2150,8 +2177,9 @@ TEST_F(NavigationControllerTest, AutoSubframe) {
// Add a second subframe and navigate.
main_test_rfh()->OnCreateChildFrame(
- MSG_ROUTING_NONE, blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ process()->GetNextRoutingID(), blink::WebTreeScopeType::Document,
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
RenderFrameHostImpl* subframe2 =
contents()->GetFrameTree()->root()->child_at(1)->current_frame_host();
const GURL url3("http://foo/3");
@@ -2194,9 +2222,10 @@ TEST_F(NavigationControllerTest, AutoSubframe) {
}
// Add a nested subframe and navigate.
- subframe->OnCreateChildFrame(MSG_ROUTING_NONE,
+ subframe->OnCreateChildFrame(process()->GetNextRoutingID(),
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
RenderFrameHostImpl* subframe3 = contents()
->GetFrameTree()
->root()
@@ -2259,8 +2288,9 @@ TEST_F(NavigationControllerTest, BackSubframe) {
// Prereq: add a subframe with an initial auto-subframe navigation.
main_test_rfh()->OnCreateChildFrame(
- MSG_ROUTING_NONE, blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ process()->GetNextRoutingID(), blink::WebTreeScopeType::Document,
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
RenderFrameHostImpl* subframe =
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host();
const GURL subframe_url("http://foo1/subframe");
@@ -2320,6 +2350,7 @@ TEST_F(NavigationControllerTest, BackSubframe) {
params.did_create_new_entry = true;
params.url = url3;
params.transition = ui::PAGE_TRANSITION_MANUAL_SUBFRAME;
+ params.page_state = PageState::CreateFromURL(url3);
EXPECT_TRUE(controller.RendererDidNavigate(subframe, params, &details));
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
@@ -2344,6 +2375,7 @@ TEST_F(NavigationControllerTest, BackSubframe) {
params.did_create_new_entry = false;
params.url = url2;
params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
+ params.page_state = PageState::CreateFromURL(url2);
EXPECT_TRUE(controller.RendererDidNavigate(subframe, params, &details));
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
@@ -2358,8 +2390,9 @@ TEST_F(NavigationControllerTest, BackSubframe) {
params.page_id = 1;
params.nav_entry_id = entry1->GetUniqueID();
params.did_create_new_entry = false;
- params.url = url1;
+ params.url = subframe_url;
params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
+ params.page_state = PageState::CreateFromURL(subframe_url);
EXPECT_TRUE(controller.RendererDidNavigate(subframe, params, &details));
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
@@ -2760,7 +2793,7 @@ TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) {
TEST_F(NavigationControllerTest, RestoreNavigate) {
// Create a NavigationController with a restored set of tabs.
GURL url("http://foo");
- ScopedVector<NavigationEntry> entries;
+ std::vector<scoped_ptr<NavigationEntry>> entries;
scoped_ptr<NavigationEntry> entry =
NavigationControllerImpl::CreateNavigationEntry(
url, Referrer(), ui::PAGE_TRANSITION_RELOAD, false, std::string(),
@@ -2770,7 +2803,7 @@ TEST_F(NavigationControllerTest, RestoreNavigate) {
entry->SetPageState(PageState::CreateFromEncodedData("state"));
const base::Time timestamp = base::Time::Now();
entry->SetTimestamp(timestamp);
- entries.push_back(entry.Pass());
+ entries.push_back(std::move(entry));
scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>(
WebContents::Create(WebContents::CreateParams(browser_context()))));
NavigationControllerImpl& our_controller = our_contents->GetController();
@@ -2833,7 +2866,7 @@ TEST_F(NavigationControllerTest, RestoreNavigate) {
TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) {
// Create a NavigationController with a restored set of tabs.
GURL url("http://foo");
- ScopedVector<NavigationEntry> entries;
+ std::vector<scoped_ptr<NavigationEntry>> entries;
scoped_ptr<NavigationEntry> new_entry =
NavigationControllerImpl::CreateNavigationEntry(
url, Referrer(), ui::PAGE_TRANSITION_RELOAD, false, std::string(),
@@ -2841,7 +2874,7 @@ TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) {
new_entry->SetPageID(0);
new_entry->SetTitle(base::ASCIIToUTF16("Title"));
new_entry->SetPageState(PageState::CreateFromEncodedData("state"));
- entries.push_back(new_entry.Pass());
+ entries.push_back(std::move(new_entry));
scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>(
WebContents::Create(WebContents::CreateParams(browser_context()))));
NavigationControllerImpl& our_controller = our_contents->GetController();
@@ -3082,7 +3115,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
// Adding a transient with no pending entry.
scoped_ptr<NavigationEntry> transient_entry(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
// We should not have received any notifications.
EXPECT_EQ(0U, notifications.size());
@@ -3112,7 +3145,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
// Add a transient again, then navigate with no pending entry this time.
transient_entry.reset(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
main_test_rfh()->SendRendererInitiatedNavigationRequest(url3, true);
main_test_rfh()->PrepareForCommit();
@@ -3127,7 +3160,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
entry_id = controller.GetPendingEntry()->GetUniqueID();
transient_entry.reset(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
main_test_rfh()->PrepareForCommit();
main_test_rfh()->SendNavigate(4, entry_id, true, url4);
@@ -3137,7 +3170,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
// Add a transient and go back. This should simply remove the transient.
transient_entry.reset(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
EXPECT_TRUE(controller.CanGoBack());
EXPECT_FALSE(controller.CanGoForward());
@@ -3155,7 +3188,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
// Add a transient and go to an entry before the current one.
transient_entry.reset(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
controller.GoToIndex(1);
entry_id = controller.GetPendingEntry()->GetUniqueID();
@@ -3171,7 +3204,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
// Add a transient and go to an entry after the current one.
transient_entry.reset(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
controller.GoToIndex(3);
entry_id = controller.GetPendingEntry()->GetUniqueID();
@@ -3187,7 +3220,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
// Add a transient and go forward.
transient_entry.reset(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
EXPECT_TRUE(controller.CanGoForward());
controller.GoForward();
@@ -3203,7 +3236,7 @@ TEST_F(NavigationControllerTest, TransientEntry) {
// Add a transient and do an in-page navigation, replacing the current entry.
transient_entry.reset(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
main_test_rfh()->SendRendererInitiatedNavigationRequest(url3_ref, false);
@@ -3241,7 +3274,7 @@ TEST_F(NavigationControllerTest, ReloadTransient) {
// A transient entry is added, interrupting the navigation.
scoped_ptr<NavigationEntry> transient_entry(new NavigationEntryImpl);
transient_entry->SetURL(transient_url);
- controller.SetTransientEntry(transient_entry.Pass());
+ controller.SetTransientEntry(std::move(transient_entry));
EXPECT_TRUE(controller.GetTransientEntry());
EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
@@ -3280,7 +3313,8 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
// can show them in new tabs when it is safe.
main_test_rfh()->SendRendererInitiatedNavigationRequest(url1, false);
main_test_rfh()->PrepareForCommit();
- navigator->DidStartProvisionalLoad(main_test_rfh(), url1);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), url1,
+ base::TimeTicks::Now());
// Simulate what happens if a BrowserURLHandler rewrites the URL, causing
// the virtual URL to differ from the URL.
@@ -3294,7 +3328,8 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
// If the user clicks another link, we should replace the pending entry.
main_test_rfh()->SendRendererInitiatedNavigationRequest(url2, false);
main_test_rfh()->PrepareForCommit();
- navigator->DidStartProvisionalLoad(main_test_rfh(), url2);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), url2,
+ base::TimeTicks::Now());
EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
EXPECT_EQ(url2, controller.GetPendingEntry()->GetVirtualURL());
@@ -3304,20 +3339,23 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetVirtualURL());
// We should not replace the pending entry for an error URL.
- navigator->DidStartProvisionalLoad(main_test_rfh(), url1);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), url1,
+ base::TimeTicks::Now());
EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
- navigator->DidStartProvisionalLoad(main_test_rfh(),
- GURL(kUnreachableWebDataURL));
+ navigator->DidStartProvisionalLoad(
+ main_test_rfh(), GURL(kUnreachableWebDataURL), base::TimeTicks::Now());
EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
// We should remember if the pending entry will replace the current one.
// http://crbug.com/308444.
- navigator->DidStartProvisionalLoad(main_test_rfh(), url1);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), url1,
+ base::TimeTicks::Now());
controller.GetPendingEntry()->set_should_replace_entry(true);
main_test_rfh()->SendRendererInitiatedNavigationRequest(url2, false);
main_test_rfh()->PrepareForCommit();
- navigator->DidStartProvisionalLoad(main_test_rfh(), url2);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), url2,
+ base::TimeTicks::Now());
EXPECT_TRUE(controller.GetPendingEntry()->should_replace_entry());
main_test_rfh()->SendNavigate(0, 0, false, url2);
EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
@@ -3598,6 +3636,21 @@ TEST_F(NavigationControllerTest, IsInPageNavigation) {
EXPECT_TRUE(controller.IsURLInPageNavigation(other_url, true,
main_test_rfh()));
+ // Don't believe the renderer if it claims a cross-origin navigation is
+ // in-page.
+ const GURL different_origin_url("http://www.example.com");
+ MockRenderProcessHost* rph = main_test_rfh()->GetProcess();
+ EXPECT_EQ(0, rph->bad_msg_count());
+ EXPECT_FALSE(controller.IsURLInPageNavigation(different_origin_url, true,
+ main_test_rfh()));
+ EXPECT_EQ(1, rph->bad_msg_count());
+}
+
+// Tests that IsInPageNavigation behaves properly with the
+// allow_universal_access_from_file_urls flag.
+TEST_F(NavigationControllerTest, IsInPageNavigationWithUniversalFileAccess) {
+ NavigationControllerImpl& controller = controller_impl();
+
// Test allow_universal_access_from_file_urls flag.
const GURL different_origin_url("http://www.example.com");
MockRenderProcessHost* rph = main_test_rfh()->GetProcess();
@@ -3606,32 +3659,51 @@ TEST_F(NavigationControllerTest, IsInPageNavigation) {
test_rvh()->UpdateWebkitPreferences(prefs);
prefs = test_rvh()->GetWebkitPreferences();
EXPECT_TRUE(prefs.allow_universal_access_from_file_urls);
- // Allow in page navigation if existing URL is file scheme.
+
+ // Allow in page navigation to be cross-origin if existing URL is file scheme.
const GURL file_url("file:///foo/index.html");
- main_test_rfh()->NavigateAndCommitRendererInitiated(0, false, file_url);
+ const url::Origin file_origin(file_url);
+ main_test_rfh()->NavigateAndCommitRendererInitiated(0, true, file_url);
+ EXPECT_TRUE(file_origin.IsSameOriginWith(
+ main_test_rfh()->frame_tree_node()->current_origin()));
EXPECT_EQ(0, rph->bad_msg_count());
EXPECT_TRUE(controller.IsURLInPageNavigation(different_origin_url, true,
main_test_rfh()));
EXPECT_EQ(0, rph->bad_msg_count());
- // Don't honor allow_universal_access_from_file_urls if existing URL is
- // not file scheme.
- main_test_rfh()->NavigateAndCommitRendererInitiated(0, false, url);
- EXPECT_FALSE(controller.IsURLInPageNavigation(different_origin_url, true,
- main_test_rfh()));
- EXPECT_EQ(1, rph->bad_msg_count());
- // Remove allow_universal_access_from_file_urls flag.
- prefs.allow_universal_access_from_file_urls = false;
- test_rvh()->UpdateWebkitPreferences(prefs);
- prefs = test_rvh()->GetWebkitPreferences();
- EXPECT_FALSE(prefs.allow_universal_access_from_file_urls);
+ // Doing a replaceState to a cross-origin URL is thus allowed.
+ FrameHostMsg_DidCommitProvisionalLoad_Params params;
+ params.page_id = 1;
+ params.nav_entry_id = 1;
+ params.did_create_new_entry = false;
+ params.url = different_origin_url;
+ params.origin = file_origin;
+ params.transition = ui::PAGE_TRANSITION_LINK;
+ params.gesture = NavigationGestureUser;
+ params.page_state = PageState::CreateFromURL(different_origin_url);
+ params.was_within_same_page = true;
+ params.is_post = false;
+ params.post_id = -1;
+ main_test_rfh()->SendRendererInitiatedNavigationRequest(different_origin_url,
+ false);
+ main_test_rfh()->PrepareForCommit();
+ contents()->GetMainFrame()->SendNavigateWithParams(&params);
- // Don't believe the renderer if it claims a cross-origin navigation is
- // in-page.
- EXPECT_EQ(1, rph->bad_msg_count());
+ // At this point, we should still consider the current origin to be file://,
+ // so that a file URL would still be in-page. See https://crbug.com/553418.
+ EXPECT_TRUE(file_origin.IsSameOriginWith(
+ main_test_rfh()->frame_tree_node()->current_origin()));
+ EXPECT_TRUE(
+ controller.IsURLInPageNavigation(file_url, true, main_test_rfh()));
+ EXPECT_EQ(0, rph->bad_msg_count());
+
+ // Don't honor allow_universal_access_from_file_urls if actual URL is
+ // not file scheme.
+ const GURL url("http://www.google.com/home.html");
+ main_test_rfh()->NavigateAndCommitRendererInitiated(2, true, url);
EXPECT_FALSE(controller.IsURLInPageNavigation(different_origin_url, true,
main_test_rfh()));
- EXPECT_EQ(2, rph->bad_msg_count());
+ EXPECT_EQ(1, rph->bad_msg_count());
}
// Some pages can have subframes with the same base URL (minus the reference) as
@@ -3650,8 +3722,9 @@ TEST_F(NavigationControllerTest, SameSubframe) {
// Add and navigate a subframe that would normally count as in-page.
main_test_rfh()->OnCreateChildFrame(
- MSG_ROUTING_NONE, blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ process()->GetNextRoutingID(), blink::WebTreeScopeType::Document,
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
RenderFrameHostImpl* subframe =
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host();
const GURL subframe_url("http://www.google.com/#");
@@ -3816,8 +3889,9 @@ TEST_F(NavigationControllerTest, SubframeWhilePending) {
// Send a subframe update from the first page, as if one had just
// automatically loaded. Auto subframes don't increment the page ID.
main_test_rfh()->OnCreateChildFrame(
- MSG_ROUTING_NONE, blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ process()->GetNextRoutingID(), blink::WebTreeScopeType::Document,
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
RenderFrameHostImpl* subframe =
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host();
const GURL url1_sub("http://foo/subframe");
@@ -4343,14 +4417,14 @@ TEST_F(NavigationControllerTest, CopyRestoredStateAndNavigate) {
};
const GURL kInitialUrl("http://site3.com");
- ScopedVector<NavigationEntry> entries;
+ std::vector<scoped_ptr<NavigationEntry>> entries;
for (size_t i = 0; i < arraysize(kRestoredUrls); ++i) {
scoped_ptr<NavigationEntry> entry =
NavigationControllerImpl::CreateNavigationEntry(
kRestoredUrls[i], Referrer(), ui::PAGE_TRANSITION_RELOAD, false,
std::string(), browser_context());
entry->SetPageID(static_cast<int>(i));
- entries.push_back(entry.Pass());
+ entries.push_back(std::move(entry));
}
// Create a WebContents with restored entries.
@@ -4561,6 +4635,7 @@ TEST_F(NavigationControllerTest, IsInitialNavigation) {
// Initial state.
EXPECT_TRUE(controller.IsInitialNavigation());
+ EXPECT_TRUE(controller.IsInitialBlankNavigation());
// After commit, it stays false.
const GURL url1("http://foo1");
@@ -4568,11 +4643,20 @@ TEST_F(NavigationControllerTest, IsInitialNavigation) {
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
EXPECT_FALSE(controller.IsInitialNavigation());
+ EXPECT_FALSE(controller.IsInitialBlankNavigation());
// After starting a new navigation, it stays false.
const GURL url2("http://foo2");
controller.LoadURL(
url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
+ EXPECT_FALSE(controller.IsInitialNavigation());
+ EXPECT_FALSE(controller.IsInitialBlankNavigation());
+
+ // For cloned tabs, IsInitialNavigationShould be true but
+ // IsInitialBlankNavigation should be false.
+ scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
+ EXPECT_TRUE(clone->GetController().IsInitialNavigation());
+ EXPECT_FALSE(clone->GetController().IsInitialBlankNavigation());
}
// Check that the favicon is not reused across a client redirect.
@@ -4820,10 +4904,8 @@ TEST_F(NavigationControllerTest, ClearHistoryList) {
// Assume that the RenderFrame correctly cleared its history and commit the
// navigation.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
contents()->GetMainFrame()->SendBeforeUnloadACK(true);
- }
contents()->GetPendingMainFrame()->
set_simulate_history_list_was_cleared(true);
contents()->CommitPendingNavigation();
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.cc b/chromium/content/browser/frame_host/navigation_entry_impl.cc
index 1adb2be5d70..258429a90b1 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.cc
@@ -4,25 +4,89 @@
#include "content/browser/frame_host/navigation_entry_impl.h"
+#include <stddef.h>
+
#include <queue>
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "components/url_formatter/url_formatter.h"
+#include "content/common/content_constants_internal.h"
#include "content/common/navigation_params.h"
+#include "content/common/page_state_serialization.h"
+#include "content/common/site_isolation_policy.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/url_constants.h"
#include "ui/gfx/text_elider.h"
+using base::UTF16ToUTF8;
+
+namespace content {
+
+namespace {
+
// Use this to get a new unique ID for a NavigationEntry during construction.
// The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
-static int GetUniqueIDInConstructor() {
+int GetUniqueIDInConstructor() {
static int unique_id_counter = 0;
return ++unique_id_counter;
}
-namespace content {
+void RecursivelyGenerateFrameEntries(const ExplodedFrameState& state,
+ NavigationEntryImpl::TreeNode* node) {
+ node->frame_entry = new FrameNavigationEntry(
+ -1, UTF16ToUTF8(state.target.string()), state.item_sequence_number,
+ state.document_sequence_number, nullptr, GURL(state.url_string.string()),
+ Referrer(GURL(state.referrer.string()), state.referrer_policy));
+
+ // Set a single-frame PageState on the entry.
+ ExplodedPageState page_state;
+ page_state.top = state;
+ std::string data;
+ if (EncodePageState(page_state, &data))
+ node->frame_entry->set_page_state(PageState::CreateFromEncodedData(data));
+
+ for (const ExplodedFrameState& child_state : state.children) {
+ NavigationEntryImpl::TreeNode* child_node =
+ new NavigationEntryImpl::TreeNode(nullptr);
+ node->children.push_back(child_node);
+ RecursivelyGenerateFrameEntries(child_state, child_node);
+ }
+}
+
+void RecursivelyGenerateFrameState(
+ NavigationEntryImpl::TreeNode* node,
+ ExplodedFrameState* state,
+ std::vector<base::NullableString16>* referenced_files) {
+ // The FrameNavigationEntry's PageState contains just the ExplodedFrameState
+ // for that particular frame.
+ ExplodedPageState exploded_page_state;
+ if (!DecodePageState(node->frame_entry->page_state().ToEncodedData(),
+ &exploded_page_state)) {
+ NOTREACHED();
+ return;
+ }
+ ExplodedFrameState frame_state = exploded_page_state.top;
+
+ // Copy the FrameNavigationEntry's frame state into the destination state.
+ *state = frame_state;
+
+ // Copy the frame's files into the PageState's |referenced_files|.
+ referenced_files->reserve(referenced_files->size() +
+ exploded_page_state.referenced_files.size());
+ for (auto& file : exploded_page_state.referenced_files)
+ referenced_files->push_back(file);
+
+ state->children.resize(node->children.size());
+ for (size_t i = 0; i < node->children.size(); ++i) {
+ RecursivelyGenerateFrameState(node->children[i], &state->children[i],
+ referenced_files);
+ }
+}
+
+} // namespace
int NavigationEntryImpl::kInvalidBindings = -1;
@@ -65,11 +129,11 @@ NavigationEntryImpl::TreeNode::CloneAndReplace(
child->CloneAndReplace(frame_tree_node, frame_navigation_entry));
}
- return copy.Pass();
+ return copy;
}
scoped_ptr<NavigationEntry> NavigationEntry::Create() {
- return make_scoped_ptr(new NavigationEntryImpl()).Pass();
+ return make_scoped_ptr(new NavigationEntryImpl());
}
NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry(
@@ -100,7 +164,7 @@ NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance,
ui::PageTransition transition_type,
bool is_renderer_initiated)
: frame_tree_(new TreeNode(
- new FrameNavigationEntry(-1, -1, -1, instance, url, referrer))),
+ new FrameNavigationEntry(-1, "", -1, -1, instance, url, referrer))),
unique_id_(GetUniqueIDInConstructor()),
bindings_(kInvalidBindings),
page_type_(PAGE_TYPE_NORMAL),
@@ -151,6 +215,23 @@ const GURL& NavigationEntryImpl::GetBaseURLForDataURL() const {
return base_url_for_data_url_;
}
+#if defined(OS_ANDROID)
+void NavigationEntryImpl::SetDataURLAsString(
+ scoped_refptr<base::RefCountedString> data_url) {
+ if (data_url) {
+ // A quick check that it's actually a data URL.
+ DCHECK(base::StartsWith(data_url->front_as<char>(), url::kDataScheme,
+ base::CompareCase::SENSITIVE));
+ }
+ data_url_as_string_ = data_url;
+}
+
+const scoped_refptr<const base::RefCountedString>
+NavigationEntryImpl::GetDataURLAsString() const {
+ return data_url_as_string_;
+}
+#endif
+
void NavigationEntryImpl::SetReferrer(const Referrer& referrer) {
frame_tree_->frame_entry->set_referrer(referrer);
}
@@ -178,18 +259,54 @@ const base::string16& NavigationEntryImpl::GetTitle() const {
}
void NavigationEntryImpl::SetPageState(const PageState& state) {
- frame_tree_->frame_entry->set_page_state(state);
+ if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ frame_tree_->frame_entry->set_page_state(state);
+ return;
+ }
+
+ // This should only be called when restoring a NavigationEntry, so there
+ // should be no subframe FrameNavigationEntries yet.
+ DCHECK_EQ(0U, frame_tree_->children.size());
+
+ // If the PageState can't be parsed or has no children, just store it on the
+ // main frame's FrameNavigationEntry without recursively creating subframe
+ // entries.
+ ExplodedPageState exploded_state;
+ if (!DecodePageState(state.ToEncodedData(), &exploded_state) ||
+ exploded_state.top.children.size() == 0U) {
+ frame_tree_->frame_entry->set_page_state(state);
+ return;
+ }
+
+ RecursivelyGenerateFrameEntries(exploded_state.top, frame_tree_.get());
}
-const PageState& NavigationEntryImpl::GetPageState() const {
- return frame_tree_->frame_entry->page_state();
+PageState NavigationEntryImpl::GetPageState() const {
+ // Just return the main frame's PageState in default Chrome, or if there are
+ // no subframe FrameNavigationEntries.
+ if (!SiteIsolationPolicy::UseSubframeNavigationEntries() ||
+ frame_tree_->children.size() == 0U)
+ return frame_tree_->frame_entry->page_state();
+
+ // When we're using subframe entries, each FrameNavigationEntry has a
+ // frame-specific PageState. We combine these into an ExplodedPageState tree
+ // and generate a full PageState from it.
+ ExplodedPageState exploded_state;
+ RecursivelyGenerateFrameState(frame_tree_.get(), &exploded_state.top,
+ &exploded_state.referenced_files);
+
+ std::string encoded_data;
+ if (!EncodePageState(exploded_state, &encoded_data))
+ return frame_tree_->frame_entry->page_state();
+
+ return PageState::CreateFromEncodedData(encoded_data);
}
void NavigationEntryImpl::SetPageID(int page_id) {
page_id_ = page_id;
}
-int32 NavigationEntryImpl::GetPageID() const {
+int32_t NavigationEntryImpl::GetPageID() const {
return page_id_;
}
@@ -278,11 +395,11 @@ bool NavigationEntryImpl::GetHasPostData() const {
return has_post_data_;
}
-void NavigationEntryImpl::SetPostID(int64 post_id) {
+void NavigationEntryImpl::SetPostID(int64_t post_id) {
post_id_ = post_id;
}
-int64 NavigationEntryImpl::GetPostID() const {
+int64_t NavigationEntryImpl::GetPostID() const {
return post_id_;
}
@@ -424,6 +541,9 @@ scoped_ptr<NavigationEntryImpl> NavigationEntryImpl::CloneAndReplace(
copy->extra_headers_ = extra_headers_;
// ResetForCommit: source_site_instance_
copy->base_url_for_data_url_ = base_url_for_data_url_;
+#if defined(OS_ANDROID)
+ copy->data_url_as_string_ = data_url_as_string_;
+#endif
// ResetForCommit: is_renderer_initiated_
copy->cached_display_title_ = cached_display_title_;
// ResetForCommit: transferred_global_request_id_
@@ -434,14 +554,15 @@ scoped_ptr<NavigationEntryImpl> NavigationEntryImpl::CloneAndReplace(
// ResetForCommit: intent_received_timestamp_
copy->extra_data_ = extra_data_;
- return copy.Pass();
+ return copy;
}
CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
const GURL& dest_url,
const Referrer& dest_referrer,
- const FrameNavigationEntry& frame_entry,
- FrameMsg_Navigate_Type::Value navigation_type) const {
+ FrameMsg_Navigate_Type::Value navigation_type,
+ LoFiState lofi_state,
+ const base::TimeTicks& navigation_start) const {
FrameMsg_UILoadMetricsReportType::Value report_type =
FrameMsg_UILoadMetricsReportType::NO_REPORT;
base::TimeTicks ui_timestamp = base::TimeTicks();
@@ -454,7 +575,8 @@ CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
return CommonNavigationParams(
dest_url, dest_referrer, GetTransitionType(), navigation_type,
!IsViewSourceMode(), should_replace_entry(), ui_timestamp, report_type,
- GetBaseURLForDataURL(), GetHistoryURLForDataURL());
+ GetBaseURLForDataURL(), GetHistoryURLForDataURL(), lofi_state,
+ navigation_start);
}
StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
@@ -478,7 +600,6 @@ StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
const FrameNavigationEntry& frame_entry,
- base::TimeTicks navigation_start,
bool is_same_document_history_load,
bool has_committed_real_load,
bool intended_as_new_entry,
@@ -503,13 +624,29 @@ RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
current_offset_to_send = -1;
current_length_to_send = 0;
}
- return RequestNavigationParams(
- GetIsOverridingUserAgent(), navigation_start, redirects,
- GetCanLoadLocalResources(), base::Time::Now(), frame_entry.page_state(),
- GetPageID(), GetUniqueID(), is_same_document_history_load,
- has_committed_real_load, intended_as_new_entry, pending_offset_to_send,
- current_offset_to_send, current_length_to_send,
- should_clear_history_list());
+
+ RequestNavigationParams request_params(
+ GetIsOverridingUserAgent(), redirects, GetCanLoadLocalResources(),
+ base::Time::Now(), frame_entry.page_state(), GetPageID(), GetUniqueID(),
+ is_same_document_history_load, has_committed_real_load,
+ intended_as_new_entry, pending_offset_to_send, current_offset_to_send,
+ current_length_to_send, IsViewSourceMode(), should_clear_history_list());
+#if defined(OS_ANDROID)
+ if (GetDataURLAsString() &&
+ GetDataURLAsString()->size() <= kMaxLengthOfDataURLString) {
+ // The number of characters that is enough for validating a data: URI. From
+ // the GURL's POV, the only important part here is scheme, it doesn't check
+ // the actual content. Thus we can take only the prefix of the url, to avoid
+ // unneeded copying of a potentially long string.
+ const size_t kDataUriPrefixMaxLen = 64;
+ GURL data_url(std::string(
+ GetDataURLAsString()->front_as<char>(),
+ std::min(GetDataURLAsString()->size(), kDataUriPrefixMaxLen)));
+ if (data_url.is_valid() && data_url.SchemeIs(url::kDataScheme))
+ request_params.data_url_as_string = GetDataURLAsString()->data();
+ }
+#endif
+ return request_params;
}
void NavigationEntryImpl::ResetForCommit() {
@@ -533,13 +670,15 @@ void NavigationEntryImpl::ResetForCommit() {
#endif
}
-void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node,
- int64 item_sequence_number,
- int64 document_sequence_number,
- SiteInstanceImpl* site_instance,
- const GURL& url,
- const Referrer& referrer,
- const PageState& page_state) {
+void NavigationEntryImpl::AddOrUpdateFrameEntry(
+ FrameTreeNode* frame_tree_node,
+ const std::string& frame_unique_name,
+ int64_t item_sequence_number,
+ int64_t document_sequence_number,
+ SiteInstanceImpl* site_instance,
+ const GURL& url,
+ const Referrer& referrer,
+ const PageState& page_state) {
// We should already have a TreeNode for the parent node by the time this node
// commits. Find it first.
DCHECK(frame_tree_node->parent());
@@ -556,7 +695,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node,
for (TreeNode* child : parent_node->children) {
if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) {
// Update the existing FrameNavigationEntry (e.g., for replaceState).
- child->frame_entry->UpdateEntry(item_sequence_number,
+ child->frame_entry->UpdateEntry(frame_unique_name, item_sequence_number,
document_sequence_number, site_instance,
url, referrer, page_state);
return;
@@ -567,8 +706,8 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node,
// Unordered list, since we expect to look up entries by frame sequence number
// or unique name.
FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
- frame_tree_node_id, item_sequence_number, document_sequence_number,
- site_instance, url, referrer);
+ frame_tree_node_id, frame_unique_name, item_sequence_number,
+ document_sequence_number, site_instance, url, referrer);
frame_entry->set_page_state(page_state);
parent_node->children.push_back(
new NavigationEntryImpl::TreeNode(frame_entry));
@@ -580,6 +719,24 @@ FrameNavigationEntry* NavigationEntryImpl::GetFrameEntry(
return tree_node ? tree_node->frame_entry.get() : nullptr;
}
+FrameNavigationEntry* NavigationEntryImpl::GetFrameEntryByUniqueName(
+ const std::string& unique_name) const {
+ NavigationEntryImpl::TreeNode* node = nullptr;
+ std::queue<NavigationEntryImpl::TreeNode*> work_queue;
+ work_queue.push(root_node());
+ while (!work_queue.empty()) {
+ node = work_queue.front();
+ work_queue.pop();
+ if (node->frame_entry->frame_unique_name() == unique_name)
+ return node->frame_entry.get();
+
+ // Enqueue any children and keep looking.
+ for (auto& child : node->children)
+ work_queue.push(child);
+ }
+ return nullptr;
+}
+
void NavigationEntryImpl::SetScreenshotPNGData(
scoped_refptr<base::RefCountedBytes> png_data) {
screenshot_ = png_data;
@@ -601,8 +758,8 @@ NavigationEntryImpl::TreeNode* NavigationEntryImpl::FindFrameEntry(
work_queue.pop();
if (node->MatchesFrame(frame_tree_node)) {
// Only the root TreeNode should have a FTN ID of -1.
- DCHECK_IMPLIES(node->frame_entry->frame_tree_node_id() == -1,
- node == root_node());
+ DCHECK(node->frame_entry->frame_tree_node_id() != -1 ||
+ node == root_node());
return node;
}
// Enqueue any children and keep looking.
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.h b/chromium/content/browser/frame_host/navigation_entry_impl.h
index 8aec8152ba7..ac5a3f2f593 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.h
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_IMPL_H_
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_IMPL_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/frame_navigation_entry.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/site_instance_impl.h"
@@ -82,6 +85,12 @@ class CONTENT_EXPORT NavigationEntryImpl
const GURL& GetURL() const override;
void SetBaseURLForDataURL(const GURL& url) override;
const GURL& GetBaseURLForDataURL() const override;
+#if defined(OS_ANDROID)
+ void SetDataURLAsString(
+ scoped_refptr<base::RefCountedString> data_url) override;
+ const scoped_refptr<const base::RefCountedString> GetDataURLAsString()
+ const override;
+#endif
void SetReferrer(const Referrer& referrer) override;
const Referrer& GetReferrer() const override;
void SetVirtualURL(const GURL& url) override;
@@ -89,9 +98,9 @@ class CONTENT_EXPORT NavigationEntryImpl
void SetTitle(const base::string16& title) override;
const base::string16& GetTitle() const override;
void SetPageState(const PageState& state) override;
- const PageState& GetPageState() const override;
+ PageState GetPageState() const override;
void SetPageID(int page_id) override;
- int32 GetPageID() const override;
+ int32_t GetPageID() const override;
const base::string16& GetTitleForDisplay(
const std::string& languages) const override;
bool IsViewSourceMode() const override;
@@ -100,8 +109,8 @@ class CONTENT_EXPORT NavigationEntryImpl
const GURL& GetUserTypedURL() const override;
void SetHasPostData(bool has_post_data) override;
bool GetHasPostData() const override;
- void SetPostID(int64 post_id) override;
- int64 GetPostID() const override;
+ void SetPostID(int64_t post_id) override;
+ int64_t GetPostID() const override;
void SetBrowserInitiatedPostData(const base::RefCountedMemory* data) override;
const base::RefCountedMemory* GetBrowserInitiatedPostData() const override;
const FaviconStatus& GetFavicon() const override;
@@ -146,12 +155,12 @@ class CONTENT_EXPORT NavigationEntryImpl
CommonNavigationParams ConstructCommonNavigationParams(
const GURL& dest_url,
const Referrer& dest_referrer,
- const FrameNavigationEntry& frame_entry,
- FrameMsg_Navigate_Type::Value navigation_type) const;
+ FrameMsg_Navigate_Type::Value navigation_type,
+ LoFiState lofi_state,
+ const base::TimeTicks& navigation_start) const;
StartNavigationParams ConstructStartNavigationParams() const;
RequestNavigationParams ConstructRequestNavigationParams(
const FrameNavigationEntry& frame_entry,
- base::TimeTicks navigation_start,
bool is_same_document_history_load,
bool has_committed_real_load,
bool intended_as_new_entry,
@@ -179,8 +188,9 @@ class CONTENT_EXPORT NavigationEntryImpl
// Does nothing if there is no entry already and |url| is about:blank, since
// that does not count as a real commit.
void AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node,
- int64 item_sequence_number,
- int64 document_sequence_number,
+ const std::string& frame_unique_name,
+ int64_t item_sequence_number,
+ int64_t document_sequence_number,
SiteInstanceImpl* site_instance,
const GURL& url,
const Referrer& referrer,
@@ -190,6 +200,15 @@ class CONTENT_EXPORT NavigationEntryImpl
// there is one in this NavigationEntry.
FrameNavigationEntry* GetFrameEntry(FrameTreeNode* frame_tree_node) const;
+ // Returns the FrameNavigationEntry corresponding to the frame with the given
+ // |unique_name|, if any. This is useful when the FrameTreeNode cannot be used
+ // to find the entry, such as for a newly created subframe in a history
+ // navigation. Callers should update the FrameTreeNode ID of the entry so that
+ // it can be found with |GetFrameEntry| above.
+ // TODO(creis): Generate or verify the unique_name in the browser process.
+ FrameNavigationEntry* GetFrameEntryByUniqueName(
+ const std::string& unique_name) const;
+
void set_unique_id(int unique_id) {
unique_id_ = unique_id;
}
@@ -371,12 +390,12 @@ class CONTENT_EXPORT NavigationEntryImpl
bool update_virtual_url_with_url_;
base::string16 title_;
FaviconStatus favicon_;
- int32 page_id_;
+ int32_t page_id_;
SSLStatus ssl_;
ui::PageTransition transition_type_;
GURL user_typed_url_;
bool has_post_data_;
- int64 post_id_;
+ int64_t post_id_;
RestoreType restore_type_;
GURL original_request_url_;
bool is_overriding_user_agent_;
@@ -409,6 +428,12 @@ class CONTENT_EXPORT NavigationEntryImpl
// persisted by Android WebView.
GURL base_url_for_data_url_;
+#if defined(OS_ANDROID)
+ // Used for passing really big data URLs from browser to renderers. Only used
+ // and persisted by Android WebView.
+ scoped_refptr<const base::RefCountedString> data_url_as_string_;
+#endif
+
// Whether the entry, while loading, was created for a renderer-initiated
// navigation. This dictates whether the URL should be displayed before the
// navigation commits. It is cleared in |ResetForCommit| and not persisted.
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc b/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
index 4b5d13861cc..7319b5347c6 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
@@ -6,6 +6,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/public/common/ssl_status.h"
diff --git a/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc b/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc
index 8ad5080d375..44bc2a03faa 100644
--- a/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc
@@ -5,6 +5,7 @@
#include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/threading/worker_pool.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
@@ -86,7 +87,8 @@ void NavigationEntryScreenshotManager::TakeScreenshot() {
return;
RenderViewHost* render_view_host = owner_->delegate()->GetRenderViewHost();
- content::RenderWidgetHostView* view = render_view_host->GetView();
+ content::RenderWidgetHostView* view =
+ render_view_host->GetWidget()->GetView();
if (!view)
return;
@@ -115,14 +117,12 @@ void NavigationEntryScreenshotManager::ClearAllScreenshots() {
void NavigationEntryScreenshotManager::TakeScreenshotImpl(
RenderViewHost* host,
NavigationEntryImpl* entry) {
- DCHECK(host && host->GetView());
+ DCHECK(host && host->GetWidget()->GetView());
DCHECK(entry);
- host->CopyFromBackingStore(
- gfx::Rect(),
- host->GetView()->GetViewBounds().size(),
+ host->GetWidget()->CopyFromBackingStore(
+ gfx::Rect(), host->GetWidget()->GetView()->GetViewBounds().size(),
base::Bind(&NavigationEntryScreenshotManager::OnScreenshotTaken,
- screenshot_factory_.GetWeakPtr(),
- entry->GetUniqueID()),
+ screenshot_factory_.GetWeakPtr(), entry->GetUniqueID()),
kAlpha_8_SkColorType);
}
diff --git a/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.h b/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.h
index df85f560867..40600af2d22 100644
--- a/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.h
+++ b/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_SCREENSHOT_MANAGER_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.cc b/chromium/content/browser/frame_host/navigation_handle_impl.cc
index 18a2fcd24ab..743d2ead8e6 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.cc
@@ -4,27 +4,44 @@
#include "content/browser/frame_host/navigation_handle_impl.h"
+#include <utility>
+
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
#include "net/url_request/redirect_info.h"
namespace content {
+namespace {
+
+void UpdateThrottleCheckResult(
+ NavigationThrottle::ThrottleCheckResult* to_update,
+ NavigationThrottle::ThrottleCheckResult result) {
+ *to_update = result;
+}
+
+} // namespace
+
// static
scoped_ptr<NavigationHandleImpl> NavigationHandleImpl::Create(
const GURL& url,
- bool is_main_frame,
- NavigatorDelegate* delegate) {
+ FrameTreeNode* frame_tree_node,
+ const base::TimeTicks& navigation_start) {
return scoped_ptr<NavigationHandleImpl>(
- new NavigationHandleImpl(url, is_main_frame, delegate));
+ new NavigationHandleImpl(url, frame_tree_node, navigation_start));
}
-NavigationHandleImpl::NavigationHandleImpl(const GURL& url,
- const bool is_main_frame,
- NavigatorDelegate* delegate)
+NavigationHandleImpl::NavigationHandleImpl(
+ const GURL& url,
+ FrameTreeNode* frame_tree_node,
+ const base::TimeTicks& navigation_start)
: url_(url),
- is_main_frame_(is_main_frame),
is_post_(false),
has_user_gesture_(false),
transition_(ui::PAGE_TRANSITION_LINK),
@@ -34,12 +51,24 @@ NavigationHandleImpl::NavigationHandleImpl(const GURL& url,
is_same_page_(false),
state_(INITIAL),
is_transferring_(false),
- delegate_(delegate) {
- delegate_->DidStartNavigation(this);
+ frame_tree_node_(frame_tree_node),
+ next_index_(0),
+ navigation_start_(navigation_start) {
+ DCHECK(!navigation_start.is_null());
+ GetDelegate()->DidStartNavigation(this);
}
NavigationHandleImpl::~NavigationHandleImpl() {
- delegate_->DidFinishNavigation(this);
+ GetDelegate()->DidFinishNavigation(this);
+
+ // Cancel the navigation on the IO thread if the NavigationHandle is being
+ // destroyed in the middle of the NavigationThrottles checks.
+ if (!IsBrowserSideNavigationEnabled() && !complete_callback_.is_null())
+ RunCompleteCallback(NavigationThrottle::CANCEL_AND_IGNORE);
+}
+
+NavigatorDelegate* NavigationHandleImpl::GetDelegate() const {
+ return frame_tree_node_->navigator()->GetDelegate();
}
const GURL& NavigationHandleImpl::GetURL() {
@@ -47,7 +76,11 @@ const GURL& NavigationHandleImpl::GetURL() {
}
bool NavigationHandleImpl::IsInMainFrame() {
- return is_main_frame_;
+ return frame_tree_node_->IsMainFrame();
+}
+
+const base::TimeTicks& NavigationHandleImpl::NavigationStart() {
+ return navigation_start_;
}
bool NavigationHandleImpl::IsPost() {
@@ -98,6 +131,13 @@ bool NavigationHandleImpl::IsSamePage() {
return is_same_page_;
}
+const net::HttpResponseHeaders* NavigationHandleImpl::GetResponseHeaders() {
+ DCHECK(state_ >= WILL_REDIRECT_REQUEST)
+ << "This accessor should only be called when the request encountered a "
+ "redirect or received a response";
+ return response_headers_.get();
+}
+
bool NavigationHandleImpl::HasCommitted() {
return state_ == DID_COMMIT || state_ == DID_COMMIT_ERROR_PAGE;
}
@@ -106,9 +146,31 @@ bool NavigationHandleImpl::IsErrorPage() {
return state_ == DID_COMMIT_ERROR_PAGE;
}
+void NavigationHandleImpl::Resume() {
+ CHECK(state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT);
+ NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
+ if (state_ == DEFERRING_START) {
+ result = CheckWillStartRequest();
+ } else {
+ result = CheckWillRedirectRequest();
+ }
+
+ if (result != NavigationThrottle::DEFER)
+ RunCompleteCallback(result);
+}
+
+void NavigationHandleImpl::CancelDeferredNavigation(
+ NavigationThrottle::ThrottleCheckResult result) {
+ DCHECK(state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT);
+ DCHECK(result == NavigationThrottle::CANCEL_AND_IGNORE ||
+ result == NavigationThrottle::CANCEL);
+ state_ = CANCELING;
+ RunCompleteCallback(result);
+}
+
void NavigationHandleImpl::RegisterThrottleForTesting(
scoped_ptr<NavigationThrottle> navigation_throttle) {
- throttles_.push_back(navigation_throttle.Pass());
+ throttles_.push_back(std::move(navigation_throttle));
}
NavigationThrottle::ThrottleCheckResult
@@ -118,8 +180,14 @@ NavigationHandleImpl::CallWillStartRequestForTesting(
bool has_user_gesture,
ui::PageTransition transition,
bool is_external_protocol) {
- return WillStartRequest(is_post, sanitized_referrer, has_user_gesture,
- transition, is_external_protocol);
+ NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
+ WillStartRequest(is_post, sanitized_referrer, has_user_gesture, transition,
+ is_external_protocol,
+ base::Bind(&UpdateThrottleCheckResult, &result));
+
+ // Reset the callback to ensure it will not be called later.
+ complete_callback_.Reset();
+ return result;
}
NavigationThrottle::ThrottleCheckResult
@@ -128,16 +196,31 @@ NavigationHandleImpl::CallWillRedirectRequestForTesting(
bool new_method_is_post,
const GURL& new_referrer_url,
bool new_is_external_protocol) {
- return WillRedirectRequest(new_url, new_method_is_post, new_referrer_url,
- new_is_external_protocol);
+ NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
+ WillRedirectRequest(new_url, new_method_is_post, new_referrer_url,
+ new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders>(),
+ base::Bind(&UpdateThrottleCheckResult, &result));
+
+ // Reset the callback to ensure it will not be called later.
+ complete_callback_.Reset();
+ return result;
+}
+
+void NavigationHandleImpl::InitServiceWorkerHandle(
+ ServiceWorkerContextWrapper* service_worker_context) {
+ DCHECK(IsBrowserSideNavigationEnabled());
+ service_worker_handle_.reset(
+ new ServiceWorkerNavigationHandle(service_worker_context));
}
-NavigationThrottle::ThrottleCheckResult NavigationHandleImpl::WillStartRequest(
+void NavigationHandleImpl::WillStartRequest(
bool is_post,
const Referrer& sanitized_referrer,
bool has_user_gesture,
ui::PageTransition transition,
- bool is_external_protocol) {
+ bool is_external_protocol,
+ const ThrottleChecksFinishedCallback& callback) {
// Update the navigation parameters.
is_post_ = is_post;
sanitized_referrer_ = sanitized_referrer;
@@ -146,6 +229,7 @@ NavigationThrottle::ThrottleCheckResult NavigationHandleImpl::WillStartRequest(
is_external_protocol_ = is_external_protocol;
state_ = WILL_SEND_REQUEST;
+ complete_callback_ = callback;
// Register the navigation throttles. The ScopedVector returned by
// GetNavigationThrottles is not assigned to throttles_ directly because it
@@ -160,57 +244,136 @@ NavigationThrottle::ThrottleCheckResult NavigationHandleImpl::WillStartRequest(
}
// Notify each throttle of the request.
- for (NavigationThrottle* throttle : throttles_) {
- NavigationThrottle::ThrottleCheckResult result =
- throttle->WillStartRequest();
- if (result == NavigationThrottle::CANCEL_AND_IGNORE)
- return NavigationThrottle::CANCEL_AND_IGNORE;
- }
- return NavigationThrottle::PROCEED;
+ NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest();
+
+ // If the navigation is not deferred, run the callback.
+ if (result != NavigationThrottle::DEFER)
+ RunCompleteCallback(result);
}
-NavigationThrottle::ThrottleCheckResult
-NavigationHandleImpl::WillRedirectRequest(const GURL& new_url,
- bool new_method_is_post,
- const GURL& new_referrer_url,
- bool new_is_external_protocol) {
+void NavigationHandleImpl::WillRedirectRequest(
+ const GURL& new_url,
+ bool new_method_is_post,
+ const GURL& new_referrer_url,
+ bool new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders> response_headers,
+ const ThrottleChecksFinishedCallback& callback) {
// Update the navigation parameters.
url_ = new_url;
is_post_ = new_method_is_post;
sanitized_referrer_.url = new_referrer_url;
sanitized_referrer_ = Referrer::SanitizeForRequest(url_, sanitized_referrer_);
is_external_protocol_ = new_is_external_protocol;
+ response_headers_ = response_headers;
- // Have each throttle be notified of the request.
- for (NavigationThrottle* throttle : throttles_) {
- NavigationThrottle::ThrottleCheckResult result =
- throttle->WillRedirectRequest();
- if (result == NavigationThrottle::CANCEL_AND_IGNORE)
- return NavigationThrottle::CANCEL_AND_IGNORE;
- }
- return NavigationThrottle::PROCEED;
+ state_ = WILL_REDIRECT_REQUEST;
+ complete_callback_ = callback;
+
+ // Notify each throttle of the request.
+ NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest();
+
+ // If the navigation is not deferred, run the callback.
+ if (result != NavigationThrottle::DEFER)
+ RunCompleteCallback(result);
}
void NavigationHandleImpl::DidRedirectNavigation(const GURL& new_url) {
url_ = new_url;
- delegate_->DidRedirectNavigation(this);
+ GetDelegate()->DidRedirectNavigation(this);
}
void NavigationHandleImpl::ReadyToCommitNavigation(
- RenderFrameHostImpl* render_frame_host) {
- CHECK(!render_frame_host_);
+ RenderFrameHostImpl* render_frame_host,
+ scoped_refptr<net::HttpResponseHeaders> response_headers) {
+ DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
render_frame_host_ = render_frame_host;
+ response_headers_ = response_headers;
state_ = READY_TO_COMMIT;
- delegate_->ReadyToCommitNavigation(this);
+
+ // Only notify the WebContentsObservers when PlzNavigate is enabled, as
+ // |render_frame_host_| may be wrong in the case of transfer navigations.
+ if (IsBrowserSideNavigationEnabled())
+ GetDelegate()->ReadyToCommitNavigation(this);
}
void NavigationHandleImpl::DidCommitNavigation(
bool same_page,
RenderFrameHostImpl* render_frame_host) {
- CHECK_IMPLIES(render_frame_host_, render_frame_host_ == render_frame_host);
+ DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
is_same_page_ = same_page;
render_frame_host_ = render_frame_host;
state_ = net_error_code_ == net::OK ? DID_COMMIT : DID_COMMIT_ERROR_PAGE;
}
+NavigationThrottle::ThrottleCheckResult
+NavigationHandleImpl::CheckWillStartRequest() {
+ DCHECK(state_ == WILL_SEND_REQUEST || state_ == DEFERRING_START);
+ DCHECK(state_ != WILL_SEND_REQUEST || next_index_ == 0);
+ DCHECK(state_ != DEFERRING_START || next_index_ != 0);
+ for (size_t i = next_index_; i < throttles_.size(); ++i) {
+ NavigationThrottle::ThrottleCheckResult result =
+ throttles_[i]->WillStartRequest();
+ switch (result) {
+ case NavigationThrottle::PROCEED:
+ continue;
+
+ case NavigationThrottle::CANCEL:
+ case NavigationThrottle::CANCEL_AND_IGNORE:
+ state_ = CANCELING;
+ return result;
+
+ case NavigationThrottle::DEFER:
+ state_ = DEFERRING_START;
+ next_index_ = i + 1;
+ return result;
+
+ default:
+ NOTREACHED();
+ }
+ }
+ next_index_ = 0;
+ state_ = WILL_SEND_REQUEST;
+ return NavigationThrottle::PROCEED;
+}
+
+NavigationThrottle::ThrottleCheckResult
+NavigationHandleImpl::CheckWillRedirectRequest() {
+ DCHECK(state_ == WILL_REDIRECT_REQUEST || state_ == DEFERRING_REDIRECT);
+ DCHECK(state_ != WILL_REDIRECT_REQUEST || next_index_ == 0);
+ DCHECK(state_ != DEFERRING_REDIRECT || next_index_ != 0);
+ for (size_t i = next_index_; i < throttles_.size(); ++i) {
+ NavigationThrottle::ThrottleCheckResult result =
+ throttles_[i]->WillRedirectRequest();
+ switch (result) {
+ case NavigationThrottle::PROCEED:
+ continue;
+
+ case NavigationThrottle::CANCEL:
+ case NavigationThrottle::CANCEL_AND_IGNORE:
+ state_ = CANCELING;
+ return result;
+
+ case NavigationThrottle::DEFER:
+ state_ = DEFERRING_REDIRECT;
+ next_index_ = i + 1;
+ return result;
+
+ default:
+ NOTREACHED();
+ }
+ }
+ next_index_ = 0;
+ state_ = WILL_REDIRECT_REQUEST;
+ return NavigationThrottle::PROCEED;
+}
+
+void NavigationHandleImpl::RunCompleteCallback(
+ NavigationThrottle::ThrottleCheckResult result) {
+ DCHECK(result != NavigationThrottle::DEFER);
+ if (!complete_callback_.is_null())
+ complete_callback_.Run(result);
+
+ complete_callback_.Reset();
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.h b/chromium/content/browser/frame_host/navigation_handle_impl.h
index edd7b5552c9..192cdab3348 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.h
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.h
@@ -7,9 +7,13 @@
#include "content/public/browser/navigation_handle.h"
+#include <stddef.h>
+
+#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
+#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/navigation_throttle.h"
@@ -18,6 +22,8 @@
namespace content {
class NavigatorDelegate;
+class ServiceWorkerContextWrapper;
+class ServiceWorkerNavigationHandle;
struct NavigationRequestInfo;
// This class keeps track of a single navigation. It is created upon receipt of
@@ -55,14 +61,20 @@ struct NavigationRequestInfo;
// the RenderFrameHost still apply.
class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
public:
- static scoped_ptr<NavigationHandleImpl> Create(const GURL& url,
- bool is_main_frame,
- NavigatorDelegate* delegate);
+ // |navigation_start| comes from the DidStartProvisionalLoad IPC, which tracks
+ // both renderer-initiated and browser-initiated navigation start.
+ // PlzNavigate: This value always comes from the CommonNavigationParams
+ // associated with this navigation.
+ static scoped_ptr<NavigationHandleImpl> Create(
+ const GURL& url,
+ FrameTreeNode* frame_tree_node,
+ const base::TimeTicks& navigation_start);
~NavigationHandleImpl() override;
// NavigationHandle implementation:
const GURL& GetURL() override;
bool IsInMainFrame() override;
+ const base::TimeTicks& NavigationStart() override;
bool IsPost() override;
const Referrer& GetReferrer() override;
bool HasUserGesture() override;
@@ -73,6 +85,9 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool IsSamePage() override;
bool HasCommitted() override;
bool IsErrorPage() override;
+ void Resume() override;
+ void CancelDeferredNavigation(
+ NavigationThrottle::ThrottleCheckResult result) override;
void RegisterThrottleForTesting(
scoped_ptr<NavigationThrottle> navigation_throttle) override;
NavigationThrottle::ThrottleCheckResult CallWillStartRequestForTesting(
@@ -87,7 +102,13 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
const GURL& new_referrer_url,
bool new_is_external_protocol) override;
- NavigatorDelegate* delegate() const { return delegate_; }
+ NavigatorDelegate* GetDelegate() const;
+
+ // Returns the response headers for the request. This can only be accessed
+ // after a redirect was encountered or after the the navigation is ready to
+ // commit. It should not be modified, as modifications will not be reflected
+ // in the network stack.
+ const net::HttpResponseHeaders* GetResponseHeaders();
void set_net_error_code(net::Error net_error_code) {
net_error_code_ = net_error_code;
@@ -102,20 +123,45 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
is_transferring_ = is_transferring;
}
- // Called when the URLRequest will start in the network stack.
- NavigationThrottle::ThrottleCheckResult WillStartRequest(
- bool is_post,
- const Referrer& sanitized_referrer,
- bool has_user_gesture,
- ui::PageTransition transition,
- bool is_external_protocol);
+ // Updates the RenderFrameHost that is about to commit the navigation. This
+ // is used during transfer navigations.
+ void set_render_frame_host(RenderFrameHostImpl* render_frame_host) {
+ render_frame_host_ = render_frame_host;
+ }
+
+ // PlzNavigate
+ void InitServiceWorkerHandle(
+ ServiceWorkerContextWrapper* service_worker_context);
+ ServiceWorkerNavigationHandle* service_worker_handle() const {
+ return service_worker_handle_.get();
+ }
+
+ typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)>
+ ThrottleChecksFinishedCallback;
+
+ // Called when the URLRequest will start in the network stack. |callback|
+ // will be called when all throttle checks have completed. This will allow
+ // the caller to cancel the navigation or let it proceed.
+ void WillStartRequest(bool is_post,
+ const Referrer& sanitized_referrer,
+ bool has_user_gesture,
+ ui::PageTransition transition,
+ bool is_external_protocol,
+ const ThrottleChecksFinishedCallback& callback);
// Called when the URLRequest will be redirected in the network stack.
- NavigationThrottle::ThrottleCheckResult WillRedirectRequest(
+ // |callback| will be called when all throttles check have completed. This
+ // will allow the caller to cancel the navigation or let it proceed.
+ void WillRedirectRequest(
const GURL& new_url,
bool new_method_is_post,
const GURL& new_referrer_url,
- bool new_is_external_protocol);
+ bool new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders> response_headers,
+ const ThrottleChecksFinishedCallback& callback);
+
+ // Returns the FrameTreeNode this navigation is happening in.
+ FrameTreeNode* frame_tree_node() { return frame_tree_node_; }
// Called when the navigation was redirected. This will update the |url_| and
// inform the delegate.
@@ -124,7 +170,9 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// Called when the navigation is ready to be committed in
// |render_frame_host|. This will update the |state_| and inform the
// delegate.
- void ReadyToCommitNavigation(RenderFrameHostImpl* render_frame_host);
+ void ReadyToCommitNavigation(
+ RenderFrameHostImpl* render_frame_host,
+ scoped_refptr<net::HttpResponseHeaders> response_headers);
// Called when the navigation was committed in |render_frame_host|. This will
// update the |state_|.
@@ -132,22 +180,37 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
RenderFrameHostImpl* render_frame_host);
private:
+ friend class NavigationHandleImplTest;
+
// Used to track the state the navigation is currently in.
enum State {
INITIAL = 0,
WILL_SEND_REQUEST,
+ DEFERRING_START,
+ WILL_REDIRECT_REQUEST,
+ DEFERRING_REDIRECT,
+ CANCELING,
READY_TO_COMMIT,
DID_COMMIT,
DID_COMMIT_ERROR_PAGE,
};
NavigationHandleImpl(const GURL& url,
- const bool is_main_frame,
- NavigatorDelegate* delegate);
+ FrameTreeNode* frame_tree_node,
+ const base::TimeTicks& navigation_start);
+
+ NavigationThrottle::ThrottleCheckResult CheckWillStartRequest();
+ NavigationThrottle::ThrottleCheckResult CheckWillRedirectRequest();
+
+ // Helper function to run and reset the |complete_callback_|. This marks the
+ // end of a round of NavigationThrottleChecks.
+ void RunCompleteCallback(NavigationThrottle::ThrottleCheckResult result);
+
+ // Used in tests.
+ State state() const { return state_; }
// See NavigationHandle for a description of those member variables.
GURL url_;
- const bool is_main_frame_;
bool is_post_;
Referrer sanitized_referrer_;
bool has_user_gesture_;
@@ -156,6 +219,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
net::Error net_error_code_;
RenderFrameHostImpl* render_frame_host_;
bool is_same_page_;
+ scoped_refptr<net::HttpResponseHeaders> response_headers_;
// The state the navigation is in.
State state_;
@@ -164,13 +228,26 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// the DidStartProvisionalLoad is received from the new renderer.
bool is_transferring_;
- // The delegate that should be notified about events related to this
- // navigation.
- NavigatorDelegate* delegate_;
+ // The FrameTreeNode this navigation is happening in.
+ FrameTreeNode* frame_tree_node_;
// A list of Throttles registered for this navigation.
ScopedVector<NavigationThrottle> throttles_;
+ // The index of the next throttle to check.
+ size_t next_index_;
+
+ // The time this navigation started.
+ const base::TimeTicks navigation_start_;
+
+ // This callback will be run when all throttle checks have been performed.
+ ThrottleChecksFinishedCallback complete_callback_;
+
+ // PlzNavigate
+ // Manages the lifetime of a pre-created ServiceWorkerProviderHost until a
+ // corresponding ServiceWorkerNetworkProvider is created in the renderer.
+ scoped_ptr<ServiceWorkerNavigationHandle> service_worker_handle_;
+
DISALLOW_COPY_AND_ASSIGN(NavigationHandleImpl);
};
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc b/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc
new file mode 100644
index 00000000000..ee999cb31b0
--- /dev/null
+++ b/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -0,0 +1,490 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/macros.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/public/browser/navigation_throttle.h"
+#include "content/test/test_render_frame_host.h"
+
+namespace content {
+
+// Test version of a NavigationThrottle. It will always return the same
+// NavigationThrottle::ThrottleCheckResult |result_|, It also monitors the
+// number of times WillStartRequest and WillRedirectRequest were called.
+class TestNavigationThrottle : public NavigationThrottle {
+ public:
+ TestNavigationThrottle(NavigationHandle* handle,
+ NavigationThrottle::ThrottleCheckResult result)
+ : NavigationThrottle(handle),
+ result_(result),
+ will_start_calls_(0),
+ will_redirect_calls_(0) {}
+
+ ~TestNavigationThrottle() override {}
+
+ NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
+ ++will_start_calls_;
+ return result_;
+ }
+
+ NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override {
+ ++will_redirect_calls_;
+ return result_;
+ }
+
+ int will_start_calls() const { return will_start_calls_; }
+ int will_redirect_calls() const { return will_redirect_calls_; }
+
+ private:
+ // The result returned by the TestNavigationThrottle.
+ NavigationThrottle::ThrottleCheckResult result_;
+
+ // The number of times WillStartRequest and WillRedirectRequest were called.
+ int will_start_calls_;
+ int will_redirect_calls_;
+};
+
+class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
+ public:
+ NavigationHandleImplTest()
+ : was_callback_called_(false),
+ callback_result_(NavigationThrottle::DEFER) {}
+
+ void SetUp() override {
+ RenderViewHostImplTestHarness::SetUp();
+ test_handle_ = NavigationHandleImpl::Create(
+ GURL(), main_test_rfh()->frame_tree_node(), base::TimeTicks::Now());
+ }
+
+ void TearDown() override {
+ // Release the |test_handle_| before destroying the WebContents, to match
+ // the WebContentsObserverSanityChecker expectations.
+ test_handle_.reset();
+ RenderViewHostImplTestHarness::TearDown();
+ }
+
+ bool IsDeferringStart() {
+ return test_handle_->state() == NavigationHandleImpl::DEFERRING_START;
+ }
+
+ bool IsDeferringRedirect() {
+ return test_handle_->state() == NavigationHandleImpl::DEFERRING_REDIRECT;
+ }
+
+ bool IsCanceling() {
+ return test_handle_->state() == NavigationHandleImpl::CANCELING;
+ }
+
+ // Helper function to call WillStartRequest on |handle|. If this function
+ // returns DEFER, |callback_result_| will be set to the actual result of
+ // the throttle checks when they are finished.
+ void SimulateWillStartRequest() {
+ was_callback_called_ = false;
+ callback_result_ = NavigationThrottle::DEFER;
+
+ // It's safe to use base::Unretained since the NavigationHandle is owned by
+ // the NavigationHandleImplTest.
+ test_handle_->WillStartRequest(
+ false, Referrer(), false, ui::PAGE_TRANSITION_LINK, false,
+ base::Bind(&NavigationHandleImplTest::UpdateThrottleCheckResult,
+ base::Unretained(this)));
+ }
+
+ // Helper function to call WillRedirectRequest on |handle|. If this function
+ // returns DEFER, |callback_result_| will be set to the actual result of the
+ // throttle checks when they are finished.
+ // TODO(clamy): this should also simulate that WillStartRequest was called if
+ // it has not been called before.
+ void SimulateWillRedirectRequest() {
+ was_callback_called_ = false;
+ callback_result_ = NavigationThrottle::DEFER;
+
+ // It's safe to use base::Unretained since the NavigationHandle is owned by
+ // the NavigationHandleImplTest.
+ test_handle_->WillRedirectRequest(
+ GURL(), false, GURL(), false, scoped_refptr<net::HttpResponseHeaders>(),
+ base::Bind(&NavigationHandleImplTest::UpdateThrottleCheckResult,
+ base::Unretained(this)));
+ }
+
+ // Returns the handle used in tests.
+ NavigationHandleImpl* test_handle() const { return test_handle_.get(); }
+
+ // Whether the callback was called.
+ bool was_callback_called() const { return was_callback_called_; }
+
+ // Returns the callback_result.
+ NavigationThrottle::ThrottleCheckResult callback_result() const {
+ return callback_result_;
+ }
+
+ // Creates, register and returns a TestNavigationThrottle that will return
+ // |result| on checks.
+ TestNavigationThrottle* CreateTestNavigationThrottle(
+ NavigationThrottle::ThrottleCheckResult result) {
+ TestNavigationThrottle* test_throttle =
+ new TestNavigationThrottle(test_handle(), result);
+ test_handle()->RegisterThrottleForTesting(
+ scoped_ptr<TestNavigationThrottle>(test_throttle));
+ return test_throttle;
+ }
+
+ private:
+ // The callback provided to NavigationHandleImpl::WillStartRequest and
+ // NavigationHandleImpl::WillRedirectRequest during the tests.
+ void UpdateThrottleCheckResult(
+ NavigationThrottle::ThrottleCheckResult result) {
+ callback_result_ = result;
+ was_callback_called_ = true;
+ }
+
+ scoped_ptr<NavigationHandleImpl> test_handle_;
+ bool was_callback_called_;
+ NavigationThrottle::ThrottleCheckResult callback_result_;
+};
+
+// Checks that a deferred navigation can be properly resumed.
+TEST_F(NavigationHandleImplTest, ResumeDeferred) {
+ TestNavigationThrottle* test_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Simulate WillStartRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Resume the request. It should no longer be deferred and the callback
+ // should have been called.
+ test_handle()->Resume();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Simulate WillRedirectRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillRedirectRequest();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_TRUE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(1, test_throttle->will_redirect_calls());
+
+ // Resume the request. It should no longer be deferred and the callback
+ // should have been called.
+ test_handle()->Resume();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(1, test_throttle->will_redirect_calls());
+}
+
+// Checks that a navigation deferred during WillStartRequest can be properly
+// cancelled.
+TEST_F(NavigationHandleImplTest, CancelDeferredWillStart) {
+ TestNavigationThrottle* test_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Simulate WillStartRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Cancel the request. The callback should have been called.
+ test_handle()->CancelDeferredNavigation(
+ NavigationThrottle::CANCEL_AND_IGNORE);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(IsCanceling());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+}
+
+// Checks that a navigation deferred during WillRedirectRequest can be properly
+// cancelled.
+TEST_F(NavigationHandleImplTest, CancelDeferredWillRedirect) {
+ TestNavigationThrottle* test_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Simulate WillRedirectRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillRedirectRequest();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_TRUE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(0, test_throttle->will_start_calls());
+ EXPECT_EQ(1, test_throttle->will_redirect_calls());
+
+ // Cancel the request. The callback should have been called.
+ test_handle()->CancelDeferredNavigation(
+ NavigationThrottle::CANCEL_AND_IGNORE);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(IsCanceling());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_EQ(0, test_throttle->will_start_calls());
+ EXPECT_EQ(1, test_throttle->will_redirect_calls());
+}
+
+// Checks that a navigation deferred can be canceled and not ignored.
+TEST_F(NavigationHandleImplTest, CancelDeferredNoIgnore) {
+ TestNavigationThrottle* test_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Simulate WillRedirectRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+
+ // Cancel the request. The callback should have been called with CANCEL, and
+ // not CANCEL_AND_IGNORE.
+ test_handle()->CancelDeferredNavigation(NavigationThrottle::CANCEL);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(IsCanceling());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
+ EXPECT_EQ(1, test_throttle->will_start_calls());
+ EXPECT_EQ(0, test_throttle->will_redirect_calls());
+}
+
+// Checks that a NavigationThrottle asking to defer followed by a
+// NavigationThrottle asking to proceed behave correctly.
+TEST_F(NavigationHandleImplTest, DeferThenProceed) {
+ TestNavigationThrottle* defer_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ TestNavigationThrottle* proceed_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, defer_throttle->will_start_calls());
+ EXPECT_EQ(0, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(0, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+
+ // Simulate WillStartRequest. The request should be deferred. The callback
+ // should not have been called. The second throttle should not have been
+ // notified.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(1, defer_throttle->will_start_calls());
+ EXPECT_EQ(0, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(0, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+
+ // Resume the request. It should no longer be deferred and the callback
+ // should have been called. The second throttle should have been notified.
+ test_handle()->Resume();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
+ EXPECT_EQ(1, defer_throttle->will_start_calls());
+ EXPECT_EQ(0, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(1, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+
+ // Simulate WillRedirectRequest. The request should be deferred. The callback
+ // should not have been called. The second throttle should not have been
+ // notified.
+ SimulateWillRedirectRequest();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_TRUE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(1, defer_throttle->will_start_calls());
+ EXPECT_EQ(1, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(1, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+
+ // Resume the request. It should no longer be deferred and the callback
+ // should have been called. The second throttle should have been notified.
+ test_handle()->Resume();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
+ EXPECT_EQ(1, defer_throttle->will_start_calls());
+ EXPECT_EQ(1, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(1, proceed_throttle->will_start_calls());
+ EXPECT_EQ(1, proceed_throttle->will_redirect_calls());
+}
+
+// Checks that a NavigationThrottle asking to defer followed by a
+// NavigationThrottle asking to cancel behave correctly in WillStartRequest.
+TEST_F(NavigationHandleImplTest, DeferThenCancelWillStartRequest) {
+ TestNavigationThrottle* defer_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ TestNavigationThrottle* cancel_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, defer_throttle->will_start_calls());
+ EXPECT_EQ(0, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+
+ // Simulate WillStartRequest. The request should be deferred. The callback
+ // should not have been called. The second throttle should not have been
+ // notified.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(1, defer_throttle->will_start_calls());
+ EXPECT_EQ(0, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+
+ // Resume the request. The callback should have been called. The second
+ // throttle should have been notified.
+ test_handle()->Resume();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(IsCanceling());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_EQ(1, defer_throttle->will_start_calls());
+ EXPECT_EQ(0, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(1, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+}
+
+// Checks that a NavigationThrottle asking to defer followed by a
+// NavigationThrottle asking to cancel behave correctly in WillRedirectRequest.
+TEST_F(NavigationHandleImplTest, DeferThenCancelWillRedirectRequest) {
+ TestNavigationThrottle* defer_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ TestNavigationThrottle* cancel_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, defer_throttle->will_start_calls());
+ EXPECT_EQ(0, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+
+ // Simulate WillRedirectRequest. The request should be deferred. The callback
+ // should not have been called. The second throttle should not have been
+ // notified.
+ SimulateWillRedirectRequest();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_TRUE(IsDeferringRedirect());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_EQ(0, defer_throttle->will_start_calls());
+ EXPECT_EQ(1, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+
+ // Resume the request. The callback should have been called. The second
+ // throttle should have been notified.
+ test_handle()->Resume();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(IsCanceling());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_EQ(0, defer_throttle->will_start_calls());
+ EXPECT_EQ(1, defer_throttle->will_redirect_calls());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(1, cancel_throttle->will_redirect_calls());
+}
+
+// Checks that a NavigationThrottle asking to cancel followed by a
+// NavigationThrottle asking to proceed behave correctly in WillStartRequest.
+// The navigation will be canceled directly, and the second throttle will not
+// be called.
+TEST_F(NavigationHandleImplTest, CancelThenProceedWillStartRequest) {
+ TestNavigationThrottle* cancel_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
+ TestNavigationThrottle* proceed_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+ EXPECT_EQ(0, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+
+ // Simulate WillStartRequest. The request should not be deferred. The
+ // callback should not have been called. The second throttle should not have
+ // been notified.
+ SimulateWillStartRequest();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_EQ(1, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+ EXPECT_EQ(0, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+}
+
+// Checks that a NavigationThrottle asking to cancel followed by a
+// NavigationThrottle asking to proceed behave correctly in WillRedirectRequest.
+// The navigation will be canceled directly, and the second throttle will not
+// be called.
+TEST_F(NavigationHandleImplTest, CancelThenProceedWillRedirectRequest) {
+ TestNavigationThrottle* cancel_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
+ TestNavigationThrottle* proceed_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(0, cancel_throttle->will_redirect_calls());
+ EXPECT_EQ(0, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+
+ // Simulate WillRedirectRequest. The request should not be deferred. The
+ // callback should not have been called. The second throttle should not have
+ // been notified.
+ SimulateWillRedirectRequest();
+ EXPECT_FALSE(IsDeferringStart());
+ EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_EQ(0, cancel_throttle->will_start_calls());
+ EXPECT_EQ(1, cancel_throttle->will_redirect_calls());
+ EXPECT_EQ(0, proceed_throttle->will_start_calls());
+ EXPECT_EQ(0, proceed_throttle->will_redirect_calls());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_request.cc b/chromium/content/browser/frame_host/navigation_request.cc
index 2c784a3e43e..582a6803dfb 100644
--- a/chromium/content/browser/frame_host/navigation_request.cc
+++ b/chromium/content/browser/frame_host/navigation_request.cc
@@ -4,6 +4,8 @@
#include "content/browser/frame_host/navigation_request.h"
+#include <utility>
+
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
@@ -11,15 +13,20 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/loader/navigation_url_loader.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/resource_request_body.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/navigation_throttle.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/resource_response.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/redirect_info.h"
+#include "third_party/WebKit/public/web/WebSandboxFlags.h"
namespace content {
@@ -61,7 +68,7 @@ scoped_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
const NavigationEntryImpl& entry,
FrameMsg_Navigate_Type::Value navigation_type,
bool is_same_document_history_load,
- base::TimeTicks navigation_start,
+ const base::TimeTicks& navigation_start,
NavigationControllerImpl* controller) {
std::string method = entry.GetHasPostData() ? "POST" : "GET";
@@ -85,20 +92,23 @@ scoped_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
}
scoped_ptr<NavigationRequest> navigation_request(new NavigationRequest(
- frame_tree_node,
- entry.ConstructCommonNavigationParams(dest_url, dest_referrer,
- frame_entry, navigation_type),
+ frame_tree_node, entry.ConstructCommonNavigationParams(
+ dest_url, dest_referrer, navigation_type,
+ LOFI_UNSPECIFIED, navigation_start),
BeginNavigationParams(method, headers.ToString(),
- LoadFlagFromNavigationType(navigation_type), false),
+ LoadFlagFromNavigationType(navigation_type),
+ false, // has_user_gestures
+ false, // skip_service_worker
+ REQUEST_CONTEXT_TYPE_LOCATION),
entry.ConstructRequestNavigationParams(
- frame_entry, navigation_start, is_same_document_history_load,
+ frame_entry, is_same_document_history_load,
frame_tree_node->has_committed_real_load(),
controller->GetPendingEntryIndex() == -1,
controller->GetIndexOfEntry(&entry),
controller->GetLastCommittedEntryIndex(),
controller->GetEntryCount()),
request_body, true, &frame_entry, &entry));
- return navigation_request.Pass();
+ return navigation_request;
}
// static
@@ -116,13 +126,25 @@ scoped_ptr<NavigationRequest> NavigationRequest::CreateRendererInitiated(
// renderer and sent to the browser instead of being measured here.
// TODO(clamy): The pending history list offset should be properly set.
// TODO(clamy): Set has_committed_real_load.
- RequestNavigationParams request_params;
- request_params.current_history_list_offset = current_history_list_offset;
- request_params.current_history_list_length = current_history_list_length;
+ RequestNavigationParams request_params(
+ false, // is_overriding_user_agent
+ std::vector<GURL>(), // redirects
+ false, // can_load_local_resources
+ base::Time::Now(), // request_time
+ PageState(), // page_state
+ -1, // page_id
+ 0, // nav_entry_id
+ false, // is_same_document_history_load
+ false, // has_committed_real_load
+ false, // intended_as_new_entry
+ -1, // pending_history_list_offset
+ current_history_list_offset, current_history_list_length,
+ false, // is_view_source
+ false); // should_clear_history_list
scoped_ptr<NavigationRequest> navigation_request(
new NavigationRequest(frame_tree_node, common_params, begin_params,
request_params, body, false, nullptr, nullptr));
- return navigation_request.Pass();
+ return navigation_request;
}
NavigationRequest::NavigationRequest(
@@ -143,7 +165,7 @@ NavigationRequest::NavigationRequest(
restore_type_(NavigationEntryImpl::RESTORE_NONE),
is_view_source_(false),
bindings_(NavigationEntryImpl::kInvalidBindings) {
- DCHECK_IMPLIES(browser_initiated, entry != nullptr && frame_entry != nullptr);
+ DCHECK(!browser_initiated || (entry != nullptr && frame_entry != nullptr));
if (browser_initiated) {
// TODO(clamy): use the FrameNavigationEntry for the source SiteInstance
// once it has been moved from the NavigationEntry.
@@ -159,6 +181,10 @@ NavigationRequest::NavigationRequest(
frame_tree_node->current_frame_host()->GetSiteInstance();
}
+ // TODO(mkwst): This is incorrect. It ought to use the definition from
+ // 'Document::firstPartyForCookies()' in Blink, which walks the ancestor tree
+ // and verifies that all origins are PSL-matches (and special-cases extension
+ // URLs).
const GURL& first_party_for_cookies =
frame_tree_node->IsMainFrame()
? common_params.url
@@ -167,37 +193,30 @@ NavigationRequest::NavigationRequest(
false : frame_tree_node->parent()->IsMainFrame();
info_.reset(new NavigationRequestInfo(
common_params, begin_params, first_party_for_cookies,
- frame_tree_node->IsMainFrame(), parent_is_main_frame,
- frame_tree_node->frame_tree_node_id(), body));
+ frame_tree_node->frame_origin(), frame_tree_node->IsMainFrame(),
+ parent_is_main_frame, frame_tree_node->frame_tree_node_id(), body));
}
NavigationRequest::~NavigationRequest() {
}
-bool NavigationRequest::BeginNavigation() {
+void NavigationRequest::BeginNavigation() {
DCHECK(!loader_);
DCHECK(state_ == NOT_STARTED || state_ == WAITING_FOR_RENDERER_RESPONSE);
state_ = STARTED;
if (ShouldMakeNetworkRequestForURL(common_params_.url)) {
+ // It's safe to use base::Unretained because this NavigationRequest owns
+ // the NavigationHandle where the callback will be stored.
// TODO(clamy): pass the real value for |is_external_protocol| if needed.
- NavigationThrottle::ThrottleCheckResult result =
- navigation_handle_->WillStartRequest(
- begin_params_.method == "POST",
- Referrer::SanitizeForRequest(common_params_.url,
- common_params_.referrer),
- begin_params_.has_user_gesture, common_params_.transition, false);
-
- // Abort the request if needed. This will destroy the NavigationRequest.
- if (result == NavigationThrottle::CANCEL_AND_IGNORE) {
- frame_tree_node_->ResetNavigationRequest(false);
- return false;
- }
-
- loader_ = NavigationURLLoader::Create(
- frame_tree_node_->navigator()->GetController()->GetBrowserContext(),
- info_.Pass(), this);
- return true;
+ navigation_handle_->WillStartRequest(
+ begin_params_.method == "POST",
+ Referrer::SanitizeForRequest(common_params_.url,
+ common_params_.referrer),
+ begin_params_.has_user_gesture, common_params_.transition, false,
+ base::Bind(&NavigationRequest::OnStartChecksComplete,
+ base::Unretained(this)));
+ return;
}
// There is no need to make a network request for this navigation, so commit
@@ -205,22 +224,16 @@ bool NavigationRequest::BeginNavigation() {
state_ = RESPONSE_STARTED;
frame_tree_node_->navigator()->CommitNavigation(
frame_tree_node_, nullptr, scoped_ptr<StreamHandle>());
- return false;
-
- // TODO(davidben): Fire (and add as necessary) observer methods such as
- // DidStartProvisionalLoadForFrame for the navigation.
}
-void NavigationRequest::CreateNavigationHandle(NavigatorDelegate* delegate) {
+void NavigationRequest::CreateNavigationHandle() {
navigation_handle_ = NavigationHandleImpl::Create(
- common_params_.url, frame_tree_node_->IsMainFrame(), delegate);
+ common_params_.url, frame_tree_node_, common_params_.navigation_start);
}
void NavigationRequest::TransferNavigationHandleOwnership(
RenderFrameHostImpl* render_frame_host) {
- render_frame_host->SetNavigationHandle(navigation_handle_.Pass());
- render_frame_host->navigation_handle()->ReadyToCommitNavigation(
- render_frame_host);
+ render_frame_host->SetNavigationHandle(std::move(navigation_handle_));
}
void NavigationRequest::OnRequestRedirected(
@@ -232,21 +245,15 @@ void NavigationRequest::OnRequestRedirected(
// TODO(clamy): Have CSP + security upgrade checks here.
// TODO(clamy): Kill the renderer if FilterURL fails?
- // TODO(clamy): pass the real value for |is_external_protocol| if needed.
- NavigationThrottle::ThrottleCheckResult result =
- navigation_handle_->WillRedirectRequest(
- common_params_.url, begin_params_.method == "POST",
- common_params_.referrer.url, false);
-
- // Abort the request if needed. This will destroy the NavigationRequest.
- if (result == NavigationThrottle::CANCEL_AND_IGNORE) {
- frame_tree_node_->ResetNavigationRequest(false);
- return;
- }
-
- loader_->FollowRedirect();
- navigation_handle_->DidRedirectNavigation(redirect_info.new_url);
+ // It's safe to use base::Unretained because this NavigationRequest owns the
+ // NavigationHandle where the callback will be stored.
+ // TODO(clamy): pass the real value for |is_external_protocol| if needed.
+ navigation_handle_->WillRedirectRequest(
+ common_params_.url, begin_params_.method == "POST",
+ common_params_.referrer.url, false, response->head.headers,
+ base::Bind(&NavigationRequest::OnRedirectChecksComplete,
+ base::Unretained(this)));
}
void NavigationRequest::OnResponseStarted(
@@ -254,8 +261,19 @@ void NavigationRequest::OnResponseStarted(
scoped_ptr<StreamHandle> body) {
DCHECK(state_ == STARTED);
state_ = RESPONSE_STARTED;
- frame_tree_node_->navigator()->CommitNavigation(frame_tree_node_,
- response.get(), body.Pass());
+
+ // Update the service worker params of the request params.
+ request_params_.should_create_service_worker =
+ (frame_tree_node_->current_replication_state().sandbox_flags &
+ blink::WebSandboxFlags::Origin) != blink::WebSandboxFlags::Origin;
+ if (navigation_handle_->service_worker_handle()) {
+ request_params_.service_worker_provider_id =
+ navigation_handle_->service_worker_handle()
+ ->service_worker_provider_host_id();
+ }
+
+ frame_tree_node_->navigator()->CommitNavigation(
+ frame_tree_node_, response.get(), std::move(body));
}
void NavigationRequest::OnRequestFailed(bool has_stale_copy_in_cache,
@@ -268,8 +286,78 @@ void NavigationRequest::OnRequestFailed(bool has_stale_copy_in_cache,
}
void NavigationRequest::OnRequestStarted(base::TimeTicks timestamp) {
+ if (frame_tree_node_->IsMainFrame()) {
+ TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
+ "navigation", "Navigation timeToNetworkStack", navigation_handle_.get(),
+ timestamp.ToInternalValue());
+ }
+
frame_tree_node_->navigator()->LogResourceRequestTime(timestamp,
common_params_.url);
}
+void NavigationRequest::OnStartChecksComplete(
+ NavigationThrottle::ThrottleCheckResult result) {
+ CHECK(result != NavigationThrottle::DEFER);
+
+ // Abort the request if needed. This will destroy the NavigationRequest.
+ if (result == NavigationThrottle::CANCEL_AND_IGNORE ||
+ result == NavigationThrottle::CANCEL) {
+ // TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
+ frame_tree_node_->ResetNavigationRequest(false);
+ return;
+ }
+
+ InitializeServiceWorkerHandleIfNeeded();
+ loader_ = NavigationURLLoader::Create(
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext(),
+ std::move(info_), navigation_handle_->service_worker_handle(), this);
+}
+
+void NavigationRequest::OnRedirectChecksComplete(
+ NavigationThrottle::ThrottleCheckResult result) {
+ CHECK(result != NavigationThrottle::DEFER);
+
+ // Abort the request if needed. This will destroy the NavigationRequest.
+ if (result == NavigationThrottle::CANCEL_AND_IGNORE ||
+ result == NavigationThrottle::CANCEL) {
+ // TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
+ frame_tree_node_->ResetNavigationRequest(false);
+ return;
+ }
+
+ loader_->FollowRedirect();
+ navigation_handle_->DidRedirectNavigation(common_params_.url);
+}
+
+void NavigationRequest::InitializeServiceWorkerHandleIfNeeded() {
+ // Only initialize the ServiceWorkerNavigationHandle if it can be created for
+ // this frame.
+ bool can_create_service_worker =
+ (frame_tree_node_->current_replication_state().sandbox_flags &
+ blink::WebSandboxFlags::Origin) != blink::WebSandboxFlags::Origin;
+ if (!can_create_service_worker)
+ return;
+
+ // Use the SiteInstance of the navigating RenderFrameHost to get access to
+ // the StoragePartition. Using the url of the navigation will result in a
+ // wrong StoragePartition being picked when a WebView is navigating.
+ RenderFrameHostImpl* navigating_frame_host =
+ frame_tree_node_->render_manager()->speculative_frame_host();
+ if (!navigating_frame_host)
+ navigating_frame_host = frame_tree_node_->current_frame_host();
+ DCHECK(navigating_frame_host);
+
+ BrowserContext* browser_context =
+ frame_tree_node_->navigator()->GetController()->GetBrowserContext();
+ StoragePartition* partition = BrowserContext::GetStoragePartition(
+ browser_context, navigating_frame_host->GetSiteInstance());
+ DCHECK(partition);
+
+ ServiceWorkerContextWrapper* service_worker_context =
+ static_cast<ServiceWorkerContextWrapper*>(
+ partition->GetServiceWorkerContext());
+ navigation_handle_->InitServiceWorkerHandle(service_worker_context);
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_request.h b/chromium/content/browser/frame_host/navigation_request.h
index b711278123b..fb418c54d11 100644
--- a/chromium/content/browser/frame_host/navigation_request.h
+++ b/chromium/content/browser/frame_host/navigation_request.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATION_REQUEST_H_
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_REQUEST_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
@@ -13,6 +13,7 @@
#include "content/common/content_export.h"
#include "content/common/frame_message_enums.h"
#include "content/common/navigation_params.h"
+#include "content/public/browser/navigation_throttle.h"
namespace content {
@@ -65,12 +66,14 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
const NavigationEntryImpl& entry,
FrameMsg_Navigate_Type::Value navigation_type,
bool is_same_document_history_load,
- base::TimeTicks navigation_start,
+ const base::TimeTicks& navigation_start,
NavigationControllerImpl* controller);
// Creates a request for a renderer-intiated navigation.
// Note: |body| is sent to the IO thread when calling BeginNavigation, and
// should no longer be manipulated afterwards on the UI thread.
+ // TODO(clamy): see if ResourceRequestBody could be un-refcounted to avoid
+ // threading subtleties.
static scoped_ptr<NavigationRequest> CreateRendererInitiated(
FrameTreeNode* frame_tree_node,
const CommonNavigationParams& common_params,
@@ -81,11 +84,8 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
~NavigationRequest() override;
- // Called on the UI thread by the Navigator to start the navigation. Returns
- // whether a request was made on the IO thread.
- // TODO(clamy): see if ResourceRequestBody could be un-refcounted to avoid
- // threading subtleties.
- bool BeginNavigation();
+ // Called on the UI thread by the Navigator to start the navigation.
+ void BeginNavigation();
const CommonNavigationParams& common_params() const { return common_params_; }
@@ -128,7 +128,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// Creates a NavigationHandle. This should be called after any previous
// NavigationRequest for the FrameTreeNode has been destroyed.
- void CreateNavigationHandle(NavigatorDelegate* delegate);
+ void CreateNavigationHandle();
// Transfers the ownership of the NavigationHandle to |render_frame_host|.
// This should be called when the navigation is ready to commit, because the
@@ -157,6 +157,14 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
void OnRequestFailed(bool has_stale_copy_in_cache, int net_error) override;
void OnRequestStarted(base::TimeTicks timestamp) override;
+ // Called when the NavigationThrottles have been checked by the
+ // NavigationHandle.
+ void OnStartChecksComplete(NavigationThrottle::ThrottleCheckResult result);
+ void OnRedirectChecksComplete(NavigationThrottle::ThrottleCheckResult result);
+
+ // Called when the navigation is about to be sent to the IO thread.
+ void InitializeServiceWorkerHandleIfNeeded();
+
FrameTreeNode* frame_tree_node_;
// Initialized on creation of the NavigationRequest. Sent to the renderer when
@@ -166,9 +174,11 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// redirects.
// Note: |common_params_| and |begin_params_| are not const as they can be
// modified during redirects.
+ // Note: |request_params_| is not const because service_worker_provider_id
+ // and should_create_service_worker will be set in OnResponseStarted.
CommonNavigationParams common_params_;
BeginNavigationParams begin_params_;
- const RequestNavigationParams request_params_;
+ RequestNavigationParams request_params_;
const bool browser_initiated_;
NavigationState state_;
diff --git a/chromium/content/browser/frame_host/navigation_request_info.cc b/chromium/content/browser/frame_host/navigation_request_info.cc
index 14b900b9aa4..5bfd979a256 100644
--- a/chromium/content/browser/frame_host/navigation_request_info.cc
+++ b/chromium/content/browser/frame_host/navigation_request_info.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "content/browser/frame_host/navigation_request_info.h"
+#include "content/common/service_worker/service_worker_types.h"
namespace content {
@@ -10,6 +11,7 @@ NavigationRequestInfo::NavigationRequestInfo(
const CommonNavigationParams& common_params,
const BeginNavigationParams& begin_params,
const GURL& first_party_for_cookies,
+ const url::Origin& request_initiator,
bool is_main_frame,
bool parent_is_main_frame,
int frame_tree_node_id,
@@ -17,11 +19,11 @@ NavigationRequestInfo::NavigationRequestInfo(
: common_params(common_params),
begin_params(begin_params),
first_party_for_cookies(first_party_for_cookies),
+ request_initiator(request_initiator),
is_main_frame(is_main_frame),
parent_is_main_frame(parent_is_main_frame),
frame_tree_node_id(frame_tree_node_id),
- request_body(request_body) {
-}
+ request_body(request_body) {}
NavigationRequestInfo::~NavigationRequestInfo() {}
diff --git a/chromium/content/browser/frame_host/navigation_request_info.h b/chromium/content/browser/frame_host/navigation_request_info.h
index c6bc6b6c8ee..ef677db499e 100644
--- a/chromium/content/browser/frame_host/navigation_request_info.h
+++ b/chromium/content/browser/frame_host/navigation_request_info.h
@@ -7,13 +7,13 @@
#include <string>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/common/navigation_params.h"
#include "content/common/resource_request_body.h"
#include "content/public/common/referrer.h"
#include "url/gurl.h"
+#include "url/origin.h"
namespace content {
class ResourceRequestBody;
@@ -23,8 +23,9 @@ class ResourceRequestBody;
// to the IO thread by a NavigationRequest object.
struct CONTENT_EXPORT NavigationRequestInfo {
NavigationRequestInfo(const CommonNavigationParams& common_params,
- const BeginNavigationParams& params,
+ const BeginNavigationParams& begin_params,
const GURL& first_party_for_cookies,
+ const url::Origin& request_initiator,
bool is_main_frame,
bool parent_is_main_frame,
int frame_tree_node_id,
@@ -38,6 +39,9 @@ struct CONTENT_EXPORT NavigationRequestInfo {
// checked by the third-party cookie blocking policy.
const GURL first_party_for_cookies;
+ // The origin of the context which initiated the request.
+ const url::Origin request_initiator;
+
const bool is_main_frame;
const bool parent_is_main_frame;
diff --git a/chromium/content/browser/frame_host/navigator.cc b/chromium/content/browser/frame_host/navigator.cc
index ba3892ede03..333d1033374 100644
--- a/chromium/content/browser/frame_host/navigator.cc
+++ b/chromium/content/browser/frame_host/navigator.cc
@@ -26,6 +26,11 @@ bool Navigator::NavigateToPendingEntry(
return false;
}
+bool Navigator::NavigateNewChildFrame(RenderFrameHostImpl* render_frame_host,
+ const std::string& unique_name) {
+ return false;
+}
+
base::TimeTicks Navigator::GetCurrentLoadStart() {
return base::TimeTicks::Now();
}
diff --git a/chromium/content/browser/frame_host/navigator.h b/chromium/content/browser/frame_host/navigator.h
index e2f737d586f..b5e0e84a538 100644
--- a/chromium/content/browser/frame_host/navigator.h
+++ b/chromium/content/browser/frame_host/navigator.h
@@ -53,8 +53,10 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
// Notifications coming from the RenderFrameHosts ----------------------------
// The RenderFrameHostImpl started a provisional load.
- virtual void DidStartProvisionalLoad(RenderFrameHostImpl* render_frame_host,
- const GURL& url) {};
+ virtual void DidStartProvisionalLoad(
+ RenderFrameHostImpl* render_frame_host,
+ const GURL& url,
+ const base::TimeTicks& navigation_start) {};
// The RenderFrameHostImpl has failed a provisional load.
virtual void DidFailProvisionalLoadWithError(
@@ -94,6 +96,14 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
NavigationController::ReloadType reload_type,
bool is_same_document_history_load);
+ // Called on a newly created subframe during a history navigation. The browser
+ // process looks up the corresponding FrameNavigationEntry for the new frame
+ // based on |unique_name| and navigates it in the correct process. Returns
+ // false if the FrameNavigationEntry can't be found or the navigation fails.
+ // This is only used in OOPIF-enabled modes.
+ virtual bool NavigateNewChildFrame(RenderFrameHostImpl* render_frame_host,
+ const std::string& unique_name);
+
// Navigation requests -------------------------------------------------------
virtual base::TimeTicks GetCurrentLoadStart();
@@ -114,14 +124,11 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
virtual void RequestTransferURL(
RenderFrameHostImpl* render_frame_host,
const GURL& url,
- SiteInstance* source_site_instance,
const std::vector<GURL>& redirect_chain,
const Referrer& referrer,
ui::PageTransition page_transition,
- WindowOpenDisposition disposition,
const GlobalRequestID& transferred_global_request_id,
- bool should_replace_current_entry,
- bool user_gesture) {}
+ bool should_replace_current_entry) {}
// PlzNavigate
// Called after receiving a BeforeUnloadACK IPC from the renderer. If
diff --git a/chromium/content/browser/frame_host/navigator_delegate.cc b/chromium/content/browser/frame_host/navigator_delegate.cc
index 4389c81e2fb..416be628a96 100644
--- a/chromium/content/browser/frame_host/navigator_delegate.cc
+++ b/chromium/content/browser/frame_host/navigator_delegate.cc
@@ -10,6 +10,10 @@ bool NavigatorDelegate::CanOverscrollContent() const {
return false;
}
+bool NavigatorDelegate::ShouldTransferNavigation() {
+ return true;
+}
+
bool NavigatorDelegate::ShouldPreserveAbortedURLs() {
return false;
}
diff --git a/chromium/content/browser/frame_host/navigator_delegate.h b/chromium/content/browser/frame_host/navigator_delegate.h
index 1494cc339f2..3263ffd1740 100644
--- a/chromium/content/browser/frame_host/navigator_delegate.h
+++ b/chromium/content/browser/frame_host/navigator_delegate.h
@@ -97,11 +97,6 @@ class CONTENT_EXPORT NavigatorDelegate {
// WebContents::NotifyNavigationStateChanged.
virtual void NotifyChangedNavigationState(InvalidateTypes changed_flags) {}
- // Notifies the Navigator embedder that it is beginning to navigate a frame.
- virtual void AboutToNavigateRenderFrame(
- RenderFrameHostImpl* old_host,
- RenderFrameHostImpl* new_host) {}
-
// Notifies the Navigator embedder that a navigation to the pending
// NavigationEntry has started in the browser process.
virtual void DidStartNavigationToPendingEntry(
@@ -113,6 +108,10 @@ class CONTENT_EXPORT NavigatorDelegate {
virtual void RequestOpenURL(RenderFrameHostImpl* render_frame_host,
const OpenURLParams& params) {}
+ // Returns whether to continue a navigation that needs to transfer to a
+ // different process between the load start and commit.
+ virtual bool ShouldTransferNavigation();
+
// Returns whether URLs for aborted browser-initiated navigations should be
// preserved in the omnibox. Defaults to false.
virtual bool ShouldPreserveAbortedURLs();
diff --git a/chromium/content/browser/frame_host/navigator_impl.cc b/chromium/content/browser/frame_host/navigator_impl.cc
index 0759ebff60a..ea89de66283 100644
--- a/chromium/content/browser/frame_host/navigator_impl.cc
+++ b/chromium/content/browser/frame_host/navigator_impl.cc
@@ -4,7 +4,8 @@
#include "content/browser/frame_host/navigator_impl.h"
-#include "base/command_line.h"
+#include <utility>
+
#include "base/metrics/histogram.h"
#include "base/time/time.h"
#include "content/browser/frame_host/frame_tree.h"
@@ -35,11 +36,11 @@
#include "content/public/browser/stream_handle.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/content_constants.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/url_constants.h"
-#include "content/public/common/url_utils.h"
#include "net/base/net_errors.h"
namespace content {
@@ -53,6 +54,7 @@ FrameMsg_Navigate_Type::Value GetNavigationType(
case NavigationControllerImpl::RELOAD:
return FrameMsg_Navigate_Type::RELOAD;
case NavigationControllerImpl::RELOAD_IGNORING_CACHE:
+ case NavigationControllerImpl::RELOAD_DISABLE_LOFI_MODE:
return FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE;
case NavigationControllerImpl::RELOAD_ORIGINAL_REQUEST_URL:
return FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
@@ -72,13 +74,6 @@ FrameMsg_Navigate_Type::Value GetNavigationType(
return FrameMsg_Navigate_Type::NORMAL;
}
-RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) {
- if (SiteIsolationPolicy::AreCrossProcessFramesPossible())
- return rfh->frame_tree_node()->render_manager();
-
- return rfh->frame_tree_node()->frame_tree()->root()->render_manager();
-}
-
} // namespace
struct NavigatorImpl::NavigationMetricsData {
@@ -118,7 +113,8 @@ NavigationController* NavigatorImpl::GetController() {
void NavigatorImpl::DidStartProvisionalLoad(
RenderFrameHostImpl* render_frame_host,
- const GURL& url) {
+ const GURL& url,
+ const base::TimeTicks& navigation_start) {
bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
bool is_error_page = (url.spec() == kUnreachableWebDataURL);
bool is_iframe_srcdoc = (url.spec() == kAboutSrcDocURL);
@@ -137,11 +133,8 @@ void NavigatorImpl::DidStartProvisionalLoad(
is_error_page, is_iframe_srcdoc);
}
- if (is_error_page ||
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (is_error_page || IsBrowserSideNavigationEnabled())
return;
- }
if (render_frame_host->navigation_handle()) {
if (render_frame_host->navigation_handle()->is_transferring()) {
@@ -158,8 +151,8 @@ void NavigatorImpl::DidStartProvisionalLoad(
render_frame_host->SetNavigationHandle(scoped_ptr<NavigationHandleImpl>());
}
- render_frame_host->SetNavigationHandle(
- NavigationHandleImpl::Create(validated_url, is_main_frame, delegate_));
+ render_frame_host->SetNavigationHandle(NavigationHandleImpl::Create(
+ validated_url, render_frame_host->frame_tree_node(), navigation_start));
}
void NavigatorImpl::DidFailProvisionalLoadWithError(
@@ -253,7 +246,8 @@ bool NavigatorImpl::NavigateToEntry(
const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry,
NavigationController::ReloadType reload_type,
- bool is_same_document_history_load) {
+ bool is_same_document_history_load,
+ bool is_pending_entry) {
TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry");
GURL dest_url = frame_entry.url();
@@ -278,8 +272,8 @@ bool NavigatorImpl::NavigateToEntry(
// The renderer will reject IPC messages with URLs longer than
// this limit, so don't attempt to navigate with a longer URL.
- if (dest_url.spec().size() > GetMaxURLChars()) {
- LOG(WARNING) << "Refusing to load URL as it exceeds " << GetMaxURLChars()
+ if (dest_url.spec().size() > kMaxURLChars) {
+ LOG(WARNING) << "Refusing to load URL as it exceeds " << kMaxURLChars
<< " characters.";
return false;
}
@@ -289,43 +283,58 @@ bool NavigatorImpl::NavigateToEntry(
// "Open link in new tab"). We need to keep it above RFHM::Navigate() call to
// capture the time needed for the RenderFrameHost initialization.
base::TimeTicks navigation_start = base::TimeTicks::Now();
-
- RenderFrameHostManager* manager = frame_tree_node->render_manager();
+ TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(
+ "navigation", "NavigationTiming navigationStart",
+ TRACE_EVENT_SCOPE_GLOBAL, navigation_start.ToInternalValue());
// PlzNavigate: the RenderFrameHosts are no longer asked to navigate.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url,
entry.restore_type()));
RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry,
entry, reload_type, is_same_document_history_load,
navigation_start);
+ if (frame_tree_node->IsMainFrame() &&
+ frame_tree_node->navigation_request()) {
+ // TODO(carlosk): extend these traces to support subframes and
+ // non-PlzNavigate navigations.
+ // For these traces below we're using the navigation handle as the async
+ // trace id, |navigation_start| as the timestamp and reporting the
+ // FrameTreeNode id as a parameter. For navigations where no network
+ // request is made (data URLs, JavaScript URLs, etc) there is no handle
+ // and so no tracing is done.
+ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
+ "navigation", "Navigation timeToNetworkStack",
+ frame_tree_node->navigation_request()->navigation_handle(),
+ navigation_start.ToInternalValue(),
+ "FrameTreeNode id", frame_tree_node->frame_tree_node_id());
+ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
+ "navigation", "Navigation timeToCommit",
+ frame_tree_node->navigation_request()->navigation_handle(),
+ navigation_start.ToInternalValue(),
+ "FrameTreeNode id", frame_tree_node->frame_tree_node_id());
+ }
- // Notify observers about navigation.
- if (delegate_)
+ // Notify observers about navigation if this is for the pending entry.
+ if (delegate_ && is_pending_entry)
delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type);
return true;
}
RenderFrameHostImpl* dest_render_frame_host =
- manager->Navigate(dest_url, frame_entry, entry);
+ frame_tree_node->render_manager()->Navigate(dest_url, frame_entry, entry);
if (!dest_render_frame_host)
return false; // Unable to create the desired RenderFrameHost.
// Make sure no code called via RFHM::Navigate clears the pending entry.
- CHECK_EQ(controller_->GetPendingEntry(), &entry);
+ if (is_pending_entry)
+ CHECK_EQ(controller_->GetPendingEntry(), &entry);
// For security, we should never send non-Web-UI URLs to a Web UI renderer.
// Double check that here.
CheckWebUIRendererDoesNotDisplayNormalURL(dest_render_frame_host, dest_url);
- // Notify observers that we will navigate in this RenderFrame.
- if (delegate_) {
- delegate_->AboutToNavigateRenderFrame(frame_tree_node->current_frame_host(),
- dest_render_frame_host);
- }
-
// Navigate in the desired RenderFrameHost.
// We can skip this step in the rare case that this is a transfer navigation
// which began in the chosen RenderFrameHost, since the request has already
@@ -340,12 +349,18 @@ bool NavigatorImpl::NavigateToEntry(
// Create the navigation parameters.
FrameMsg_Navigate_Type::Value navigation_type =
GetNavigationType(controller_->GetBrowserContext(), entry, reload_type);
+ LoFiState lofi_state =
+ (reload_type ==
+ NavigationController::ReloadType::RELOAD_DISABLE_LOFI_MODE
+ ? LOFI_OFF
+ : LOFI_UNSPECIFIED);
dest_render_frame_host->Navigate(
entry.ConstructCommonNavigationParams(dest_url, dest_referrer,
- frame_entry, navigation_type),
+ navigation_type, lofi_state,
+ navigation_start),
entry.ConstructStartNavigationParams(),
entry.ConstructRequestNavigationParams(
- frame_entry, navigation_start, is_same_document_history_load,
+ frame_entry, is_same_document_history_load,
frame_tree_node->has_committed_real_load(),
controller_->GetPendingEntryIndex() == -1,
controller_->GetIndexOfEntry(&entry),
@@ -358,7 +373,8 @@ bool NavigatorImpl::NavigateToEntry(
}
// Make sure no code called via RFH::Navigate clears the pending entry.
- CHECK_EQ(controller_->GetPendingEntry(), &entry);
+ if (is_pending_entry)
+ CHECK_EQ(controller_->GetPendingEntry(), &entry);
if (controller_->GetPendingEntryIndex() == -1 &&
dest_url.SchemeIs(url::kJavaScriptScheme)) {
@@ -374,9 +390,8 @@ bool NavigatorImpl::NavigateToEntry(
}
// Notify observers about navigation.
- if (delegate_) {
+ if (delegate_ && is_pending_entry)
delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type);
- }
return true;
}
@@ -388,7 +403,31 @@ bool NavigatorImpl::NavigateToPendingEntry(
bool is_same_document_history_load) {
return NavigateToEntry(frame_tree_node, frame_entry,
*controller_->GetPendingEntry(), reload_type,
- is_same_document_history_load);
+ is_same_document_history_load, true);
+}
+
+bool NavigatorImpl::NavigateNewChildFrame(
+ RenderFrameHostImpl* render_frame_host,
+ const std::string& unique_name) {
+ NavigationEntryImpl* entry =
+ controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id());
+ if (!entry)
+ return false;
+
+ FrameNavigationEntry* frame_entry =
+ entry->GetFrameEntryByUniqueName(unique_name);
+ if (!frame_entry)
+ return false;
+
+ // Update the FrameNavigationEntry's FrameTreeNode ID (which is currently the
+ // ID of the old FrameTreeNode that no longer exists) to be the ID of the
+ // newly created frame.
+ frame_entry->set_frame_tree_node_id(
+ render_frame_host->frame_tree_node()->frame_tree_node_id());
+
+ return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry,
+ *entry, NavigationControllerImpl::NO_RELOAD, false,
+ false);
}
void NavigatorImpl::DidNavigate(
@@ -433,6 +472,9 @@ void NavigatorImpl::DidNavigate(
// created via ViewMsg_New and FrameMsg_NewFrameProxy.
render_frame_host->frame_tree_node()->SetCurrentOrigin(params.origin);
+ render_frame_host->frame_tree_node()->SetEnforceStrictMixedContentChecking(
+ params.should_enforce_strict_mixed_content_checking);
+
// When using --site-per-process, we notify the RFHM for all navigations,
// not just main frame navigations.
if (oopifs_possible) {
@@ -472,6 +514,12 @@ void NavigatorImpl::DidNavigate(
// Keep track of each frame's URL in its FrameTreeNode.
render_frame_host->frame_tree_node()->SetCurrentURL(params.url);
+ if (did_navigate && render_frame_host->frame_tree_node()->IsMainFrame() &&
+ IsBrowserSideNavigationEnabled()) {
+ TRACE_EVENT_ASYNC_END0("navigation", "Navigation timeToCommit",
+ render_frame_host->navigation_handle());
+ }
+
// Send notification about committed provisional loads. This notification is
// different from the NAV_ENTRY_COMMITTED notification which doesn't include
// the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations.
@@ -539,44 +587,27 @@ void NavigatorImpl::RequestOpenURL(RenderFrameHostImpl* render_frame_host,
WindowOpenDisposition disposition,
bool should_replace_current_entry,
bool user_gesture) {
- SiteInstance* current_site_instance =
- GetRenderManager(render_frame_host)->current_frame_host()->
- GetSiteInstance();
+ // This call only makes sense for subframes if OOPIFs are possible.
+ DCHECK(!render_frame_host->GetParent() ||
+ SiteIsolationPolicy::AreCrossProcessFramesPossible());
+
// If this came from a swapped out RenderFrameHost, we only allow the request
// if we are still in the same BrowsingInstance.
// TODO(creis): Move this to RenderFrameProxyHost::OpenURL.
+ SiteInstance* current_site_instance = render_frame_host->frame_tree_node()
+ ->current_frame_host()
+ ->GetSiteInstance();
if (render_frame_host->is_swapped_out() &&
!render_frame_host->GetSiteInstance()->IsRelatedSiteInstance(
current_site_instance)) {
return;
}
- // Delegate to RequestTransferURL because this is just the generic
- // case where |old_request_id| is empty.
// TODO(creis): Pass the redirect_chain into this method to support client
// redirects. http://crbug.com/311721.
std::vector<GURL> redirect_chain;
- RequestTransferURL(render_frame_host, url, source_site_instance,
- redirect_chain, referrer, ui::PAGE_TRANSITION_LINK,
- disposition, GlobalRequestID(),
- should_replace_current_entry, user_gesture);
-}
-void NavigatorImpl::RequestTransferURL(
- RenderFrameHostImpl* render_frame_host,
- const GURL& url,
- SiteInstance* source_site_instance,
- const std::vector<GURL>& redirect_chain,
- const Referrer& referrer,
- ui::PageTransition page_transition,
- WindowOpenDisposition disposition,
- const GlobalRequestID& transferred_global_request_id,
- bool should_replace_current_entry,
- bool user_gesture) {
GURL dest_url(url);
- SiteInstance* current_site_instance =
- GetRenderManager(render_frame_host)->current_frame_host()->
- GetSiteInstance();
if (!GetContentClient()->browser()->ShouldAllowOpenURL(
current_site_instance, url)) {
dest_url = GURL(url::kAboutBlankURL);
@@ -593,26 +624,23 @@ void NavigatorImpl::RequestTransferURL(
render_frame_host->frame_tree_node()->frame_tree_node_id();
}
- OpenURLParams params(
- dest_url, referrer, frame_tree_node_id, disposition, page_transition,
- true /* is_renderer_initiated */);
+ OpenURLParams params(dest_url, referrer, frame_tree_node_id, disposition,
+ ui::PAGE_TRANSITION_LINK,
+ true /* is_renderer_initiated */);
params.source_site_instance = source_site_instance;
if (redirect_chain.size() > 0)
params.redirect_chain = redirect_chain;
- params.transferred_global_request_id = transferred_global_request_id;
params.should_replace_current_entry = should_replace_current_entry;
params.user_gesture = user_gesture;
- if (GetRenderManager(render_frame_host)->web_ui()) {
+ if (render_frame_host->web_ui()) {
// Web UI pages sometimes want to override the page transition type for
// link clicks (e.g., so the new tab page can specify AUTO_BOOKMARK for
// automatically generated suggestions). We don't override other types
// like TYPED because they have different implications (e.g., autocomplete).
if (ui::PageTransitionCoreTypeIs(
params.transition, ui::PAGE_TRANSITION_LINK))
- params.transition =
- GetRenderManager(render_frame_host)->web_ui()->
- GetLinkTransitionType();
+ params.transition = render_frame_host->web_ui()->GetLinkTransitionType();
// Note also that we hide the referrer for Web UI pages. We don't really
// want web sites to see a referrer of "chrome://blah" (and some
@@ -628,11 +656,71 @@ void NavigatorImpl::RequestTransferURL(
delegate_->RequestOpenURL(render_frame_host, params);
}
+void NavigatorImpl::RequestTransferURL(
+ RenderFrameHostImpl* render_frame_host,
+ const GURL& url,
+ const std::vector<GURL>& redirect_chain,
+ const Referrer& referrer,
+ ui::PageTransition page_transition,
+ const GlobalRequestID& transferred_global_request_id,
+ bool should_replace_current_entry) {
+ // This call only makes sense for subframes if OOPIFs are possible.
+ DCHECK(!render_frame_host->GetParent() ||
+ SiteIsolationPolicy::AreCrossProcessFramesPossible());
+
+ // Allow the delegate to cancel the transfer.
+ if (!delegate_->ShouldTransferNavigation())
+ return;
+
+ GURL dest_url(url);
+ Referrer referrer_to_use(referrer);
+ FrameTreeNode* node = render_frame_host->frame_tree_node();
+ SiteInstance* current_site_instance = render_frame_host->GetSiteInstance();
+ if (!GetContentClient()->browser()->ShouldAllowOpenURL(current_site_instance,
+ url)) {
+ dest_url = GURL(url::kAboutBlankURL);
+ }
+
+ // TODO(creis): Determine if this transfer started as a browser-initiated
+ // navigation. See https://crbug.com/495161.
+ bool is_renderer_initiated = true;
+ if (render_frame_host->web_ui()) {
+ // Web UI pages sometimes want to override the page transition type for
+ // link clicks (e.g., so the new tab page can specify AUTO_BOOKMARK for
+ // automatically generated suggestions). We don't override other types
+ // like TYPED because they have different implications (e.g., autocomplete).
+ if (ui::PageTransitionCoreTypeIs(page_transition, ui::PAGE_TRANSITION_LINK))
+ page_transition = render_frame_host->web_ui()->GetLinkTransitionType();
+
+ // Note also that we hide the referrer for Web UI pages. We don't really
+ // want web sites to see a referrer of "chrome://blah" (and some
+ // chrome: URLs might have search terms or other stuff we don't want to
+ // send to the site), so we send no referrer.
+ referrer_to_use = Referrer();
+
+ // Navigations in Web UI pages count as browser-initiated navigations.
+ is_renderer_initiated = false;
+ }
+
+ NavigationController::LoadURLParams load_url_params(dest_url);
+ // The source_site_instance only matters for navigations via RenderFrameProxy,
+ // which go through RequestOpenURL.
+ load_url_params.source_site_instance = nullptr;
+ load_url_params.transition_type = page_transition;
+ load_url_params.frame_tree_node_id = node->frame_tree_node_id();
+ load_url_params.referrer = referrer_to_use;
+ load_url_params.redirect_chain = redirect_chain;
+ load_url_params.is_renderer_initiated = is_renderer_initiated;
+ load_url_params.transferred_global_request_id = transferred_global_request_id;
+ load_url_params.should_replace_current_entry = should_replace_current_entry;
+
+ controller_->LoadURLWithParams(load_url_params);
+}
+
// PlzNavigate
void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node,
bool proceed) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
DCHECK(frame_tree_node);
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
@@ -661,8 +749,7 @@ void NavigatorImpl::OnBeginNavigation(
// TODO(clamy): the url sent by the renderer should be validated with
// FilterURL.
// This is a renderer-initiated navigation.
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
DCHECK(frame_tree_node);
NavigationRequest* ongoing_navigation_request =
@@ -686,7 +773,7 @@ void NavigatorImpl::OnBeginNavigation(
controller_->GetLastCommittedEntryIndex(),
controller_->GetEntryCount()));
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
- navigation_request->CreateNavigationHandle(delegate_);
+ navigation_request->CreateNavigationHandle();
if (frame_tree_node->IsMainFrame()) {
// Renderer-initiated main-frame navigations that need to swap processes
@@ -709,8 +796,7 @@ void NavigatorImpl::OnBeginNavigation(
void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node,
ResourceResponse* response,
scoped_ptr<StreamHandle> body) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
DCHECK(navigation_request);
@@ -747,18 +833,18 @@ void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node,
render_frame_host, navigation_request->common_params().url);
navigation_request->TransferNavigationHandleOwnership(render_frame_host);
- render_frame_host->CommitNavigation(response, body.Pass(),
+ render_frame_host->navigation_handle()->ReadyToCommitNavigation(
+ render_frame_host, response ? response->head.headers : nullptr);
+ render_frame_host->CommitNavigation(response, std::move(body),
navigation_request->common_params(),
navigation_request->request_params());
-
}
// PlzNavigate
void NavigatorImpl::FailedNavigation(FrameTreeNode* frame_tree_node,
bool has_stale_copy_in_cache,
int error_code) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
DCHECK(navigation_request);
@@ -777,6 +863,8 @@ void NavigatorImpl::FailedNavigation(FrameTreeNode* frame_tree_node,
render_frame_host, navigation_request->common_params().url);
navigation_request->TransferNavigationHandleOwnership(render_frame_host);
+ render_frame_host->navigation_handle()->ReadyToCommitNavigation(
+ render_frame_host, scoped_refptr<net::HttpResponseHeaders>());
render_frame_host->FailedNavigation(navigation_request->common_params(),
navigation_request->request_params(),
has_stale_copy_in_cache, error_code);
@@ -784,8 +872,7 @@ void NavigatorImpl::FailedNavigation(FrameTreeNode* frame_tree_node,
// PlzNavigate
void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
frame_tree_node->ResetNavigationRequest(false);
if (frame_tree_node->IsMainFrame())
navigation_data_.reset();
@@ -839,8 +926,7 @@ void NavigatorImpl::RequestNavigation(
NavigationController::ReloadType reload_type,
bool is_same_document_history_load,
base::TimeTicks navigation_start) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
DCHECK(frame_tree_node);
// This value must be set here because creating a NavigationRequest might
@@ -855,7 +941,7 @@ void NavigatorImpl::RequestNavigation(
navigation_type, is_same_document_history_load, navigation_start,
controller_));
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
- navigation_request->CreateNavigationHandle(delegate_);
+ navigation_request->CreateNavigationHandle();
// Have the current renderer execute its beforeunload event if needed. If it
// is not needed (when beforeunload dispatch is not needed or this navigation
@@ -952,7 +1038,7 @@ void NavigatorImpl::DidStartMainFrameNavigation(
entry->set_should_replace_entry(pending_entry->should_replace_entry());
entry->SetRedirectChain(pending_entry->GetRedirectChain());
}
- controller_->SetPendingEntry(entry.Pass());
+ controller_->SetPendingEntry(std::move(entry));
if (delegate_)
delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL);
}
diff --git a/chromium/content/browser/frame_host/navigator_impl.h b/chromium/content/browser/frame_host/navigator_impl.h
index 8b52dfb5adc..a8907689a6c 100644
--- a/chromium/content/browser/frame_host/navigator_impl.h
+++ b/chromium/content/browser/frame_host/navigator_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATOR_IMPL_H_
#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
@@ -36,8 +37,10 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
// Navigator implementation.
NavigatorDelegate* GetDelegate() override;
NavigationController* GetController() override;
- void DidStartProvisionalLoad(RenderFrameHostImpl* render_frame_host,
- const GURL& url) override;
+ void DidStartProvisionalLoad(
+ RenderFrameHostImpl* render_frame_host,
+ const GURL& url,
+ const base::TimeTicks& navigation_start) override;
void DidFailProvisionalLoadWithError(
RenderFrameHostImpl* render_frame_host,
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params)
@@ -54,6 +57,8 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
const FrameNavigationEntry& frame_entry,
NavigationController::ReloadType reload_type,
bool is_same_document_history_load) override;
+ bool NavigateNewChildFrame(RenderFrameHostImpl* render_frame_host,
+ const std::string& unique_name) override;
void RequestOpenURL(RenderFrameHostImpl* render_frame_host,
const GURL& url,
SiteInstance* source_site_instance,
@@ -63,14 +68,11 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
bool user_gesture) override;
void RequestTransferURL(RenderFrameHostImpl* render_frame_host,
const GURL& url,
- SiteInstance* source_site_instance,
const std::vector<GURL>& redirect_chain,
const Referrer& referrer,
ui::PageTransition page_transition,
- WindowOpenDisposition disposition,
const GlobalRequestID& transferred_global_request_id,
- bool should_replace_current_entry,
- bool user_gesture) override;
+ bool should_replace_current_entry) override;
void OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, bool proceed) override;
void OnBeginNavigation(FrameTreeNode* frame_tree_node,
const CommonNavigationParams& common_params,
@@ -96,13 +98,15 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
friend class NavigatorTestWithBrowserSideNavigation;
~NavigatorImpl() override;
- // Navigates to the given entry, which must be the pending entry. Private
- // because all callers should use NavigateToPendingEntry.
+ // Navigates to the given entry, which might be the pending entry (if
+ // |is_pending_entry| is true). Private because all callers should use either
+ // NavigateToPendingEntry or NavigateToNewChildFrame.
bool NavigateToEntry(FrameTreeNode* frame_tree_node,
const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry,
NavigationController::ReloadType reload_type,
- bool is_same_document_history_load);
+ bool is_same_document_history_load,
+ bool is_pending_entry);
bool ShouldAssignSiteForURL(const GURL& url);
diff --git a/chromium/content/browser/frame_host/navigator_impl_unittest.cc b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
index 59da7512bee..efb85766a81 100644
--- a/chromium/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/macros.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigation_request.h"
@@ -123,7 +126,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_FALSE(main_test_rfh()->IsRenderFrameLive());
// Start a browser-initiated navigation.
- int32 site_instance_id = main_test_rfh()->GetSiteInstance()->GetId();
+ int32_t site_instance_id = main_test_rfh()->GetSiteInstance()->GetId();
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
int entry_id = RequestNavigation(node, kUrl);
NavigationRequest* request = node->navigation_request();
@@ -219,7 +222,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
contents()->NavigateAndCommit(kUrl1);
EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
- int32 site_instance_id_1 = main_test_rfh()->GetSiteInstance()->GetId();
+ int32_t site_instance_id_1 = main_test_rfh()->GetSiteInstance()->GetId();
// Start a renderer-initiated non-user-initiated navigation.
process()->sink().ClearMessages();
@@ -539,7 +542,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Confirm a speculative RenderFrameHost was created.
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
- int32 site_instance_id_1 = speculative_rfh->GetSiteInstance()->GetId();
+ int32_t site_instance_id_1 = speculative_rfh->GetSiteInstance()->GetId();
EXPECT_EQ(kUrl1_site, speculative_rfh->GetSiteInstance()->GetSiteURL());
// Request navigation to the 2nd URL; the NavigationRequest must have been
@@ -557,7 +560,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Confirm that a new speculative RenderFrameHost was created.
speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
- int32 site_instance_id_2 = speculative_rfh->GetSiteInstance()->GetId();
+ int32_t site_instance_id_2 = speculative_rfh->GetSiteInstance()->GetId();
EXPECT_NE(site_instance_id_1, site_instance_id_2);
// Have the RenderFrameHost commit the navigation.
@@ -740,7 +743,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Initialization.
contents()->NavigateAndCommit(kUrl0);
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
- int32 site_instance_id_0 = main_test_rfh()->GetSiteInstance()->GetId();
+ int32_t site_instance_id_0 = main_test_rfh()->GetSiteInstance()->GetId();
// Start a renderer-initiated non-user-initiated navigation to the 1st URL.
process()->sink().ClearMessages();
@@ -835,7 +838,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl),
speculative_rfh->GetSiteInstance()->GetSiteURL());
EXPECT_FALSE(node->render_manager()->pending_frame_host());
- int32 site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
+ int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
// Ask Navigator to commit the navigation by simulating a call to
// OnResponseStarted.
@@ -862,7 +865,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
const GURL kUrlInit("http://wikipedia.org/");
contents()->NavigateAndCommit(kUrlInit);
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
- int32 init_site_instance_id = main_test_rfh()->GetSiteInstance()->GetId();
+ int32_t init_site_instance_id = main_test_rfh()->GetSiteInstance()->GetId();
// Begin navigating to another site.
const GURL kUrl("http://google.com/");
@@ -870,7 +873,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
int entry_id = RequestNavigation(node, kUrl);
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
- int32 site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
+ int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
RenderFrameDeletedObserver rfh_deleted_observer(speculative_rfh);
EXPECT_NE(init_site_instance_id, site_instance_id);
EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
@@ -913,7 +916,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// known final SiteInstance.
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrlRedirect),
speculative_rfh->GetSiteInstance()->GetSiteURL());
- int32 redirect_site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
+ int32_t redirect_site_instance_id =
+ speculative_rfh->GetSiteInstance()->GetId();
EXPECT_NE(init_site_instance_id, redirect_site_instance_id);
EXPECT_NE(site_instance_id, redirect_site_instance_id);
@@ -945,7 +949,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Increment active frame count to cause the RenderFrameHost to be swapped out
// (instead of immediately destroyed).
- rfh1->GetSiteInstance()->increment_active_frame_count();
+ rfh1->GetSiteInstance()->IncrementActiveFrameCount();
// Navigate to another site to swap out the initial RenderFrameHost.
const GURL kUrl2("http://chromium.org/");
diff --git a/chromium/content/browser/frame_host/popup_menu_helper_mac.h b/chromium/content/browser/frame_host/popup_menu_helper_mac.h
index 5575d89483c..27d3f718c5f 100644
--- a/chromium/content/browser/frame_host/popup_menu_helper_mac.h
+++ b/chromium/content/browser/frame_host/popup_menu_helper_mac.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
diff --git a/chromium/content/browser/frame_host/popup_menu_helper_mac.mm b/chromium/content/browser/frame_host/popup_menu_helper_mac.mm
index 1ab1917d713..5cef607e10e 100644
--- a/chromium/content/browser/frame_host/popup_menu_helper_mac.mm
+++ b/chromium/content/browser/frame_host/popup_menu_helper_mac.mm
@@ -9,6 +9,8 @@
#include "base/mac/scoped_nsobject.h"
#import "base/mac/scoped_sending_event.h"
#include "base/message_loop/message_loop.h"
+#include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
@@ -32,10 +34,12 @@ PopupMenuHelper::PopupMenuHelper(RenderFrameHost* render_frame_host)
popup_was_hidden_(false) {
notification_registrar_.Add(
this, NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
- Source<RenderWidgetHost>(render_frame_host->GetRenderViewHost()));
+ Source<RenderWidgetHost>(
+ render_frame_host->GetRenderViewHost()->GetWidget()));
notification_registrar_.Add(
this, NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
- Source<RenderWidgetHost>(render_frame_host->GetRenderViewHost()));
+ Source<RenderWidgetHost>(
+ render_frame_host->GetRenderViewHost()->GetWidget()));
}
void PopupMenuHelper::ShowPopupMenu(
@@ -117,14 +121,18 @@ void PopupMenuHelper::DontShowPopupMenuForTesting() {
RenderWidgetHostViewMac* PopupMenuHelper::GetRenderWidgetHostView() const {
return static_cast<RenderWidgetHostViewMac*>(
- render_frame_host_->GetRenderViewHost()->GetView());
+ render_frame_host_->frame_tree_node()
+ ->frame_tree()
+ ->root()
+ ->current_frame_host()
+ ->GetView());
}
void PopupMenuHelper::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
DCHECK_EQ(Source<RenderWidgetHost>(source).ptr(),
- render_frame_host_->GetRenderViewHost());
+ render_frame_host_->GetRenderViewHost()->GetWidget());
switch (type) {
case NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: {
render_frame_host_ = NULL;
diff --git a/chromium/content/browser/frame_host/render_frame_host_delegate.cc b/chromium/content/browser/frame_host/render_frame_host_delegate.cc
index 1c8ecd9373f..ec119050bec 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.cc
@@ -6,6 +6,7 @@
#include "base/callback.h"
#include "base/strings/string16.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "ipc/ipc_message.h"
#include "ui/gfx/native_widget_types.h"
@@ -24,7 +25,9 @@ const GURL& RenderFrameHostDelegate::GetMainFrameLastCommittedURL() const {
}
bool RenderFrameHostDelegate::AddMessageToConsole(
- int32 level, const base::string16& message, int32 line_no,
+ int32_t level,
+ const base::string16& message,
+ int32_t line_no,
const base::string16& source_id) {
return false;
}
@@ -66,12 +69,21 @@ RenderFrameHostDelegate::GetGeolocationServiceContext() {
return NULL;
}
+WakeLockServiceContext* RenderFrameHostDelegate::GetWakeLockServiceContext() {
+ return nullptr;
+}
+
bool RenderFrameHostDelegate::ShouldRouteMessageEvent(
RenderFrameHost* target_rfh,
SiteInstance* source_site_instance) const {
return false;
}
+scoped_ptr<WebUIImpl> RenderFrameHostDelegate::CreateWebUIForRenderFrameHost(
+ const GURL& url) {
+ return nullptr;
+}
+
#if defined(OS_WIN)
gfx::NativeViewAccessible
RenderFrameHostDelegate::GetParentNativeViewAccessible() {
diff --git a/chromium/content/browser/frame_host/render_frame_host_delegate.h b/chromium/content/browser/frame_host/render_frame_host_delegate.h
index 0f8e555d30c..ee5aae52bda 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.h
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_DELEGATE_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_DELEGATE_H_
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
#include "base/i18n/rtl.h"
+#include "build/build_config.h"
+#include "content/browser/webui/web_ui_impl.h"
#include "content/common/content_export.h"
#include "content/common/frame_message_enums.h"
#include "content/public/browser/site_instance.h"
@@ -28,7 +31,9 @@ class Message;
namespace content {
class GeolocationServiceContext;
+class PageState;
class RenderFrameHost;
+class WakeLockServiceContext;
class WebContents;
struct AXEventNotificationDetails;
struct ContextMenuParams;
@@ -47,9 +52,9 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
virtual const GURL& GetMainFrameLastCommittedURL() const;
// A message was added to to the console.
- virtual bool AddMessageToConsole(int32 level,
+ virtual bool AddMessageToConsole(int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id);
// Informs the delegate whenever a RenderFrameHost is created.
@@ -91,10 +96,14 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
// level frame.
virtual void DocumentOnLoadCompleted(RenderFrameHost* render_frame_host) {}
+ // The state for the page changed and should be updated in session history.
+ virtual void UpdateStateForFrame(RenderFrameHost* render_frame_host,
+ const PageState& page_state) {}
+
// The page's title was changed and should be updated. Only called for the
// top-level frame.
virtual void UpdateTitle(RenderFrameHost* render_frame_host,
- int32 page_id,
+ int32_t page_id,
const base::string16& title,
base::i18n::TextDirection title_direction) {}
@@ -136,6 +145,9 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
// Gets the GeolocationServiceContext associated with this delegate.
virtual GeolocationServiceContext* GetGeolocationServiceContext();
+ // Gets the WakeLockServiceContext associated with this delegate.
+ virtual WakeLockServiceContext* GetWakeLockServiceContext();
+
// Notification that the frame wants to go into fullscreen mode.
// |origin| represents the origin of the frame that requests fullscreen.
virtual void EnterFullscreenMode(const GURL& origin) {}
@@ -163,6 +175,10 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
// https://crbug.com/330264.
virtual void EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) {}
+ // Creates a WebUI object for a frame navigating to |url|. If no WebUI
+ // applies, returns null.
+ virtual scoped_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(const GURL& url);
+
#if defined(OS_WIN)
// Returns the frame's parent's NativeViewAccessible.
virtual gfx::NativeViewAccessible GetParentNativeViewAccessible();
diff --git a/chromium/content/browser/frame_host/render_frame_host_factory.cc b/chromium/content/browser/frame_host/render_frame_host_factory.cc
index 6f896ce45ae..d91354bfe33 100644
--- a/chromium/content/browser/frame_host/render_frame_host_factory.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_factory.cc
@@ -21,8 +21,8 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostFactory::Create(
RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
- int32 routing_id,
- int32 widget_routing_id,
+ int32_t routing_id,
+ int32_t widget_routing_id,
int flags) {
if (factory_) {
return factory_->CreateRenderFrameHost(
diff --git a/chromium/content/browser/frame_host/render_frame_host_factory.h b/chromium/content/browser/frame_host/render_frame_host_factory.h
index 9bd123bc145..1b2fdc3aa4b 100644
--- a/chromium/content/browser/frame_host/render_frame_host_factory.h
+++ b/chromium/content/browser/frame_host/render_frame_host_factory.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_FACTORY_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_FACTORY_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
@@ -33,8 +35,8 @@ class CONTENT_EXPORT RenderFrameHostFactory {
RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
- int32 routing_id,
- int32 widget_routing_id,
+ int32_t routing_id,
+ int32_t widget_routing_id,
int flags);
// Returns true if there is currently a globally-registered factory.
@@ -53,8 +55,8 @@ class CONTENT_EXPORT RenderFrameHostFactory {
RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
- int32 routing_id,
- int32 widget_routing_id,
+ int32_t routing_id,
+ int32_t widget_routing_id,
int flags) = 0;
// Registers a factory to be called when new RenderFrameHostImpls are created.
diff --git a/chromium/content/browser/frame_host/render_frame_host_impl.cc b/chromium/content/browser/frame_host/render_frame_host_impl.cc
index 9e611ace533..f0de4ccf8e7 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.cc
@@ -4,19 +4,23 @@
#include "content/browser/frame_host/render_frame_host_impl.h"
+#include <utility>
+
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram.h"
#include "base/process/kill.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_mode_helper.h"
#include "content/browser/accessibility/ax_tree_id_registry.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
-#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/devtools/render_frame_devtools_agent_host.h"
+#include "content/browser/download/mhtml_generation_manager.h"
#include "content/browser/frame_host/cross_process_frame_connector.h"
#include "content/browser/frame_host/cross_site_transferring_request.h"
#include "content/browser/frame_host/frame_mojo_shell.h"
@@ -39,8 +43,11 @@
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/renderer_host/render_view_host_impl.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/render_widget_host_view_base.h"
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/accessibility_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/input_messages.h"
@@ -61,8 +68,8 @@
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/browser/user_metrics.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_constants.h"
-#include "content/public/common/content_switches.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
@@ -79,7 +86,9 @@
#endif
#if defined(ENABLE_WEBVR)
+#include "base/command_line.h"
#include "content/browser/vr/vr_device_manager.h"
+#include "content/public/common/content_switches.h"
#endif
using base::TimeDelta;
@@ -99,7 +108,7 @@ int g_next_javascript_callback_id = 1;
bool g_allow_injecting_javascript = false;
// The (process id, routing id) pair that identifies one RenderFrame.
-typedef std::pair<int32, int32> RenderFrameHostID;
+typedef std::pair<int32_t, int32_t> RenderFrameHostID;
typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*>
RoutingIDFrameMap;
base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map =
@@ -132,10 +141,12 @@ RenderFrameHost* RenderFrameHost::FromID(int render_process_id,
return RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
}
+#if defined(OS_ANDROID)
// static
void RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView() {
g_allow_injecting_javascript = true;
}
+#endif
// static
RenderFrameHostImpl* RenderFrameHostImpl::FromID(int process_id,
@@ -168,8 +179,8 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
- int32 routing_id,
- int32 widget_routing_id,
+ int32_t routing_id,
+ int32_t widget_routing_id,
int flags)
: render_view_host_(render_view_host),
delegate_(delegate),
@@ -187,9 +198,13 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
unload_ack_is_for_navigation_(false),
is_loading_(false),
pending_commit_(false),
+ nav_entry_id_(0),
accessibility_reset_token_(0),
accessibility_reset_count_(0),
no_create_browser_accessibility_manager_for_testing_(false),
+ web_ui_type_(WebUI::kNoWebUI),
+ pending_web_ui_type_(WebUI::kNoWebUI),
+ should_reuse_web_ui_(false),
weak_ptr_factory_(this) {
bool is_swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
bool hidden = !!(flags & CREATE_RF_HIDDEN);
@@ -203,7 +218,13 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
rfh_state_ = STATE_SWAPPED_OUT;
} else {
rfh_state_ = STATE_DEFAULT;
- GetSiteInstance()->increment_active_frame_count();
+ GetSiteInstance()->IncrementActiveFrameCount();
+ }
+
+ // New child frames should inherit the nav_entry_id of their parent.
+ if (frame_tree_node_->parent()) {
+ set_nav_entry_id(
+ frame_tree_node_->parent()->current_frame_host()->nav_entry_id());
}
SetUpMojoIfNeeded();
@@ -211,13 +232,28 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
&RenderFrameHostImpl::OnSwappedOut, weak_ptr_factory_.GetWeakPtr())));
if (widget_routing_id != MSG_ROUTING_NONE) {
- render_widget_host_ = new RenderWidgetHostImpl(rwh_delegate, GetProcess(),
- widget_routing_id, hidden);
- render_widget_host_->set_owned_by_render_frame_host(true);
+ // TODO(avi): Once RenderViewHostImpl has-a RenderWidgetHostImpl, the main
+ // render frame should probably start owning the RenderWidgetHostImpl,
+ // so this logic checking for an already existing RWHI should be removed.
+ // https://crbug.com/545684
+ render_widget_host_ =
+ RenderWidgetHostImpl::FromID(GetProcess()->GetID(), widget_routing_id);
+ if (!render_widget_host_) {
+ DCHECK(frame_tree_node->parent());
+ render_widget_host_ = new RenderWidgetHostImpl(rwh_delegate, GetProcess(),
+ widget_routing_id, hidden);
+ render_widget_host_->set_owned_by_render_frame_host(true);
+ } else {
+ DCHECK(!render_widget_host_->owned_by_render_frame_host());
+ }
}
}
RenderFrameHostImpl::~RenderFrameHostImpl() {
+ // Release the WebUI instances before all else as the WebUI may accesses the
+ // RenderFrameHost during cleanup.
+ ClearAllWebUI();
+
GetProcess()->RemoveRoute(routing_id_);
g_routing_id_frame_map.Get().erase(
RenderFrameHostID(GetProcess()->GetID(), routing_id_));
@@ -225,14 +261,19 @@ RenderFrameHostImpl::~RenderFrameHostImpl() {
if (delegate_ && render_frame_created_)
delegate_->RenderFrameDeleted(this);
- // If this was swapped out, it already decremented the active frame count of
- // the SiteInstance it belongs to.
- if (IsRFHStateActive(rfh_state_))
- GetSiteInstance()->decrement_active_frame_count();
+ bool is_active = IsRFHStateActive(rfh_state_);
- // Notify the FrameTree that this RFH is going away, allowing it to shut down
- // the corresponding RenderViewHost if it is no longer needed.
- frame_tree_->ReleaseRenderViewHostRef(render_view_host_);
+ // If this RenderFrameHost is swapped out, it already decremented the active
+ // frame count of the SiteInstance it belongs to.
+ if (is_active)
+ GetSiteInstance()->DecrementActiveFrameCount();
+
+ // If this RenderFrameHost is swapping with a RenderFrameProxyHost, the
+ // RenderFrame will already be deleted in the renderer process. Main frame
+ // RenderFrames will be cleaned up as part of deleting its RenderView. In all
+ // other cases, the RenderFrame should be cleaned up (if it exists).
+ if (is_active && !frame_tree_node_->IsMainFrame() && render_frame_created_)
+ Send(new FrameMsg_Delete(routing_id_));
// NULL out the swapout timer; in crash dumps this member will be null only if
// the dtor has run.
@@ -242,10 +283,15 @@ RenderFrameHostImpl::~RenderFrameHostImpl() {
iter.second.Run(false);
}
- if (render_widget_host_) {
+ if (render_widget_host_ &&
+ render_widget_host_->owned_by_render_frame_host()) {
// Shutdown causes the RenderWidgetHost to delete itself.
- render_widget_host_->Shutdown();
+ render_widget_host_->ShutdownAndDestroyWidget(true);
}
+
+ // Notify the FrameTree that this RFH is going away, allowing it to shut down
+ // the corresponding RenderViewHost if it is no longer needed.
+ frame_tree_->ReleaseRenderViewHostRef(render_view_host_);
}
int RenderFrameHostImpl::GetRoutingID() {
@@ -272,6 +318,10 @@ RenderFrameHost* RenderFrameHostImpl::GetParent() {
return parent_node->current_frame_host();
}
+int RenderFrameHostImpl::GetFrameTreeNodeId() {
+ return frame_tree_node_->frame_tree_node_id();
+}
+
const std::string& RenderFrameHostImpl::GetFrameName() {
return frame_tree_node_->frame_name();
}
@@ -288,8 +338,14 @@ GURL RenderFrameHostImpl::GetLastCommittedURL() {
return frame_tree_node_->current_url();
}
+url::Origin RenderFrameHostImpl::GetLastCommittedOrigin() {
+ // Origin is stored per-FTN, so it's incorrect to call for a non-current RFH.
+ CHECK(this == frame_tree_node_->current_frame_host());
+ return frame_tree_node_->current_origin();
+}
+
gfx::NativeView RenderFrameHostImpl::GetNativeView() {
- RenderWidgetHostView* view = render_view_host_->GetView();
+ RenderWidgetHostView* view = render_view_host_->GetWidget()->GetView();
if (!view)
return NULL;
return view->GetNativeView();
@@ -395,7 +451,7 @@ blink::WebPageVisibilityState RenderFrameHostImpl::GetVisibilityState() {
bool RenderFrameHostImpl::Send(IPC::Message* message) {
if (IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart) {
- return render_view_host_->input_router()->SendInput(
+ return render_view_host_->GetWidget()->input_router()->SendInput(
make_scoped_ptr(message));
}
@@ -420,6 +476,21 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
}
}
+ // This message map is for handling internal IPC messages which should not
+ // be dispatched to other objects.
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(RenderFrameHostImpl, msg)
+ // This message is synthetic and doesn't come from RenderFrame, but from
+ // RenderProcessHost.
+ IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ // Internal IPCs should not be leaked outside of this object, so return
+ // early.
+ if (handled)
+ return true;
+
if (delegate_->OnMessageReceived(this, msg))
return true;
@@ -429,13 +500,13 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
proxy->cross_process_frame_connector()->OnMessageReceived(msg))
return true;
- bool handled = true;
+ handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderFrameHostImpl, msg)
IPC_MESSAGE_HANDLER(FrameHostMsg_AddMessageToConsole, OnAddMessageToConsole)
IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach)
IPC_MESSAGE_HANDLER(FrameHostMsg_FrameFocused, OnFrameFocused)
- IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoadForFrame,
- OnDidStartProvisionalLoadForFrame)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoad,
+ OnDidStartProvisionalLoad)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailProvisionalLoadWithError,
OnDidFailProvisionalLoadWithError)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailLoadWithError,
@@ -443,6 +514,7 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad,
OnDidCommitProvisionalLoad(msg))
IPC_MESSAGE_HANDLER(FrameHostMsg_DidDropNavigation, OnDidDropNavigation)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateState, OnUpdateState)
IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
IPC_MESSAGE_HANDLER(FrameHostMsg_DocumentOnLoadCompleted,
OnDocumentOnLoadCompleted)
@@ -461,9 +533,13 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
OnDidAccessInitialDocument)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeOpener, OnDidChangeOpener)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeName, OnDidChangeName)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_EnforceStrictMixedContentChecking,
+ OnEnforceStrictMixedContentChecking)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidAssignPageId, OnDidAssignPageId)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeSandboxFlags,
OnDidChangeSandboxFlags)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeFrameOwnerProperties,
+ OnDidChangeFrameOwnerProperties)
IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateTitle, OnUpdateTitle)
IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateEncoding, OnUpdateEncoding)
IPC_MESSAGE_HANDLER(FrameHostMsg_BeginNavigation,
@@ -479,13 +555,12 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(AccessibilityHostMsg_SnapshotResponse,
OnAccessibilitySnapshotResponse)
IPC_MESSAGE_HANDLER(FrameHostMsg_ToggleFullscreen, OnToggleFullscreen)
- // The following message is synthetic and doesn't come from RenderFrame, but
- // from RenderProcessHost.
- IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress,
OnDidChangeLoadProgress)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_SerializeAsMHTMLResponse,
+ OnSerializeAsMHTMLResponse)
#if defined(OS_MACOSX) || defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(FrameHostMsg_ShowPopup, OnShowPopup)
IPC_MESSAGE_HANDLER(FrameHostMsg_HidePopup, OnHidePopup)
@@ -526,10 +601,15 @@ void RenderFrameHostImpl::AccessibilitySetScrollOffset(
routing_id_, acc_obj_id, offset));
}
-void RenderFrameHostImpl::AccessibilitySetTextSelection(
- int object_id, int start_offset, int end_offset) {
- Send(new AccessibilityMsg_SetTextSelection(
- routing_id_, object_id, start_offset, end_offset));
+void RenderFrameHostImpl::AccessibilitySetSelection(int anchor_object_id,
+ int anchor_offset,
+ int focus_object_id,
+ int focus_offset) {
+ Send(new AccessibilityMsg_SetSelection(routing_id_,
+ focus_object_id,
+ anchor_offset,
+ focus_object_id,
+ focus_offset));
}
void RenderFrameHostImpl::AccessibilitySetValue(
@@ -538,14 +618,14 @@ void RenderFrameHostImpl::AccessibilitySetValue(
}
bool RenderFrameHostImpl::AccessibilityViewHasFocus() const {
- RenderWidgetHostView* view = render_view_host_->GetView();
+ RenderWidgetHostView* view = render_view_host_->GetWidget()->GetView();
if (view)
return view->HasFocus();
return false;
}
gfx::Rect RenderFrameHostImpl::AccessibilityGetViewBounds() const {
- RenderWidgetHostView* view = render_view_host_->GetView();
+ RenderWidgetHostView* view = render_view_host_->GetWidget()->GetView();
if (view)
return view->GetViewBounds();
return gfx::Rect();
@@ -554,7 +634,7 @@ gfx::Rect RenderFrameHostImpl::AccessibilityGetViewBounds() const {
gfx::Point RenderFrameHostImpl::AccessibilityOriginInScreen(
const gfx::Rect& bounds) const {
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
- render_view_host_->GetView());
+ render_view_host_->GetWidget()->GetView());
if (view)
return view->AccessibilityOriginInScreen(bounds);
return gfx::Point();
@@ -591,7 +671,7 @@ void RenderFrameHostImpl::AccessibilityFatalError() {
gfx::AcceleratedWidget
RenderFrameHostImpl::AccessibilityGetAcceleratedWidget() {
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
- render_view_host_->GetView());
+ render_view_host_->GetWidget()->GetView());
if (view)
return view->AccessibilityGetAcceleratedWidget();
return gfx::kNullAcceleratedWidget;
@@ -600,7 +680,7 @@ gfx::AcceleratedWidget
gfx::NativeViewAccessible
RenderFrameHostImpl::AccessibilityGetNativeViewAccessible() {
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
- render_view_host_->GetView());
+ render_view_host_->GetWidget()->GetView());
if (view)
return view->AccessibilityGetNativeViewAccessible();
return NULL;
@@ -629,6 +709,7 @@ bool RenderFrameHostImpl::CreateRenderFrame(int proxy_routing_id,
params.parent_routing_id = parent_routing_id;
params.previous_sibling_routing_id = previous_sibling_routing_id;
params.replication_state = frame_tree_node()->current_replication_state();
+ params.frame_owner_properties = frame_tree_node()->frame_owner_properties();
if (render_widget_host_) {
params.widget_params.routing_id = render_widget_host_->GetRoutingID();
@@ -644,7 +725,10 @@ bool RenderFrameHostImpl::CreateRenderFrame(int proxy_routing_id,
// The RenderWidgetHost takes ownership of its view. It is tied to the
// lifetime of the current RenderProcessHost for this RenderFrameHost.
- if (render_widget_host_) {
+ // TODO(avi): This will need to change to initialize a
+ // RenderWidgetHostViewAura for the main frame once RenderViewHostImpl has-a
+ // RenderWidgetHostImpl. https://crbug.com/545684
+ if (parent_routing_id != MSG_ROUTING_NONE && render_widget_host_) {
RenderWidgetHostView* rwhv =
new RenderWidgetHostViewChildFrame(render_widget_host_);
rwhv->Hide();
@@ -685,13 +769,15 @@ void RenderFrameHostImpl::SetRenderFrameCreated(bool created) {
}
void RenderFrameHostImpl::Init() {
- GetProcess()->ResumeRequestsForView(routing_id_);
+ // TODO(csharrison): Call GetProcess()->ResumeRequestsForFrame(routing_id_)
+ // once ResourceDispatcherHostImpl is keyed on render frame routing ids
+ // instead of render view routing ids.
}
void RenderFrameHostImpl::OnAddMessageToConsole(
- int32 level,
+ int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id) {
if (delegate_->AddMessageToConsole(level, message, line_no, source_id))
return;
@@ -699,7 +785,7 @@ void RenderFrameHostImpl::OnAddMessageToConsole(
// Pass through log level only on WebUI pages to limit console spew.
const bool is_web_ui =
HasWebUIScheme(delegate_->GetMainFrameLastCommittedURL());
- const int32 resolved_level = is_web_ui ? level : ::logging::LOG_INFO;
+ const int32_t resolved_level = is_web_ui ? level : ::logging::LOG_INFO;
// LogMessages can be persisted so this shouldn't be logged in incognito mode.
// This rule is not applied to WebUI pages, because source code of WebUI is a
@@ -718,23 +804,19 @@ void RenderFrameHostImpl::OnCreateChildFrame(
int new_routing_id,
blink::WebTreeScopeType scope,
const std::string& frame_name,
- blink::WebSandboxFlags sandbox_flags) {
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties) {
// It is possible that while a new RenderFrameHost was committed, the
// RenderFrame corresponding to this host sent an IPC message to create a
// frame and it is delivered after this host is swapped out.
// Ignore such messages, as we know this RenderFrameHost is going away.
- if (rfh_state_ != RenderFrameHostImpl::STATE_DEFAULT)
- return;
-
- RenderFrameHostImpl* new_frame =
- frame_tree_->AddFrame(frame_tree_node_, GetProcess()->GetID(),
- new_routing_id, scope, frame_name, sandbox_flags);
- if (!new_frame)
+ if (rfh_state_ != RenderFrameHostImpl::STATE_DEFAULT ||
+ frame_tree_node_->current_frame_host() != this)
return;
- // We know that the RenderFrame has been created in this case, immediately
- // after the CreateChildFrame IPC was sent.
- new_frame->SetRenderFrameCreated(true);
+ frame_tree_->AddFrame(frame_tree_node_, GetProcess()->GetID(), new_routing_id,
+ scope, frame_name, sandbox_flags,
+ frame_owner_properties);
}
void RenderFrameHostImpl::OnDetach() {
@@ -742,10 +824,21 @@ void RenderFrameHostImpl::OnDetach() {
}
void RenderFrameHostImpl::OnFrameFocused() {
- frame_tree_->SetFocusedFrame(frame_tree_node_);
+ frame_tree_->SetFocusedFrame(frame_tree_node_, GetSiteInstance());
}
void RenderFrameHostImpl::OnOpenURL(const FrameHostMsg_OpenURL_Params& params) {
+ if (params.is_history_navigation_in_new_child) {
+ DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+
+ // Try to find a FrameNavigationEntry that matches this frame instead, based
+ // on the frame's unique name. If this can't be found, fall back to the
+ // default params using OpenURL below.
+ if (frame_tree_node_->navigator()->NavigateNewChildFrame(
+ this, params.frame_unique_name))
+ return;
+ }
+
OpenURL(params, GetSiteInstance());
}
@@ -768,16 +861,16 @@ void RenderFrameHostImpl::OnDocumentOnLoadCompleted(
delegate_->DocumentOnLoadCompleted(this);
}
-void RenderFrameHostImpl::OnDidStartProvisionalLoadForFrame(const GURL& url) {
- frame_tree_node_->navigator()->DidStartProvisionalLoad(
- this, url);
+void RenderFrameHostImpl::OnDidStartProvisionalLoad(
+ const GURL& url,
+ const base::TimeTicks& navigation_start) {
+ frame_tree_node_->navigator()->DidStartProvisionalLoad(this, url,
+ navigation_start);
}
void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError(
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
- navigation_handle_) {
+ if (!IsBrowserSideNavigationEnabled() && navigation_handle_) {
navigation_handle_->set_net_error_code(
static_cast<net::Error>(params.error_code));
}
@@ -910,8 +1003,7 @@ void RenderFrameHostImpl::OnDidCommitProvisionalLoad(const IPC::Message& msg) {
// message.
if (!navigation_handle_) {
navigation_handle_ = NavigationHandleImpl::Create(
- validated_params.url, frame_tree_node_->IsMainFrame(),
- frame_tree_node_->navigator()->GetDelegate());
+ validated_params.url, frame_tree_node_, base::TimeTicks::Now());
}
accessibility_reset_count_ = 0;
@@ -931,10 +1023,8 @@ void RenderFrameHostImpl::OnDidCommitProvisionalLoad(const IPC::Message& msg) {
}
// PlzNavigate
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
pending_commit_ = false;
- }
}
void RenderFrameHostImpl::OnDidDropNavigation() {
@@ -946,17 +1036,23 @@ void RenderFrameHostImpl::OnDidDropNavigation() {
navigation_handle_.reset();
}
-RenderWidgetHostImpl* RenderFrameHostImpl::GetRenderWidgetHost() {
- if (render_widget_host_)
- return render_widget_host_;
+void RenderFrameHostImpl::OnUpdateState(const PageState& state) {
+ // TODO(creis): Verify the state's ISN matches the last committed FNE.
- // TODO(kenrb): When RenderViewHost no longer inherits RenderWidgetHost,
- // we can remove this fallback. Currently it is only used for the main
- // frame.
- if (!GetParent())
- return static_cast<RenderWidgetHostImpl*>(render_view_host_);
+ // Without this check, the renderer can trick the browser into using
+ // filenames it can't access in a future session restore.
+ // TODO(creis): Move CanAccessFilesOfPageState to RenderFrameHostImpl.
+ if (!render_view_host_->CanAccessFilesOfPageState(state)) {
+ bad_message::ReceivedBadMessage(
+ GetProcess(), bad_message::RFH_CAN_ACCESS_FILES_OF_PAGE_STATE);
+ return;
+ }
- return nullptr;
+ delegate_->UpdateStateForFrame(this, state);
+}
+
+RenderWidgetHostImpl* RenderFrameHostImpl::GetRenderWidgetHost() {
+ return render_widget_host_;
}
RenderWidgetHostView* RenderFrameHostImpl::GetView() {
@@ -967,7 +1063,8 @@ RenderWidgetHostView* RenderFrameHostImpl::GetView() {
frame = static_cast<RenderFrameHostImpl*>(frame->GetParent());
}
- return render_view_host_->GetView();
+ NOTREACHED();
+ return nullptr;
}
int RenderFrameHostImpl::GetEnabledBindings() {
@@ -976,15 +1073,16 @@ int RenderFrameHostImpl::GetEnabledBindings() {
void RenderFrameHostImpl::SetNavigationHandle(
scoped_ptr<NavigationHandleImpl> navigation_handle) {
- navigation_handle_ = navigation_handle.Pass();
+ navigation_handle_ = std::move(navigation_handle);
+ if (navigation_handle_)
+ navigation_handle_->set_render_frame_host(this);
}
scoped_ptr<NavigationHandleImpl>
RenderFrameHostImpl::PassNavigationHandleOwnership() {
- DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ DCHECK(!IsBrowserSideNavigationEnabled());
navigation_handle_->set_is_transferring(true);
- return navigation_handle_.Pass();
+ return std::move(navigation_handle_);
}
void RenderFrameHostImpl::OnCrossSiteResponse(
@@ -995,7 +1093,7 @@ void RenderFrameHostImpl::OnCrossSiteResponse(
ui::PageTransition page_transition,
bool should_replace_current_entry) {
frame_tree_node_->render_manager()->OnCrossSiteResponse(
- this, global_request_id, cross_site_transferring_request.Pass(),
+ this, global_request_id, std::move(cross_site_transferring_request),
transfer_url_chain, referrer, page_transition,
should_replace_current_entry);
}
@@ -1016,7 +1114,6 @@ void RenderFrameHostImpl::SwapOut(
return;
}
- SetState(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT);
swapout_event_monitor_timeout_->Start(
base::TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS));
@@ -1034,6 +1131,10 @@ void RenderFrameHostImpl::SwapOut(
replication_state));
}
+ // If this is the last active frame in the SiteInstance, the SetState call
+ // below will trigger the deletion of the SiteInstance's proxies.
+ SetState(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT);
+
if (!GetParent())
delegate_->SwappedOut(this);
}
@@ -1042,8 +1143,9 @@ void RenderFrameHostImpl::OnBeforeUnloadACK(
bool proceed,
const base::TimeTicks& renderer_before_unload_start_time,
const base::TimeTicks& renderer_before_unload_end_time) {
- TRACE_EVENT_ASYNC_END0(
- "navigation", "RenderFrameHostImpl::BeforeUnload", this);
+ TRACE_EVENT_ASYNC_END1("navigation", "RenderFrameHostImpl BeforeUnload", this,
+ "FrameTreeNode id",
+ frame_tree_node_->frame_tree_node_id());
DCHECK(!GetParent());
// If this renderer navigated while the beforeunload request was in flight, we
// may have cleared this state in OnDidCommitProvisionalLoad, in which case we
@@ -1106,16 +1208,14 @@ void RenderFrameHostImpl::OnBeforeUnloadACK(
}
// Resets beforeunload waiting state.
is_waiting_for_beforeunload_ack_ = false;
- render_view_host_->decrement_in_flight_event_count();
- render_view_host_->StopHangMonitorTimeout();
+ render_view_host_->GetWidget()->decrement_in_flight_event_count();
+ render_view_host_->GetWidget()->StopHangMonitorTimeout();
send_before_unload_start_time_ = base::TimeTicks();
// PlzNavigate: if the ACK is for a navigation, send it to the Navigator to
// have the current navigation stop/proceed. Otherwise, send it to the
// RenderFrameHostManager which handles closing.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
- unload_ack_is_for_navigation_) {
+ if (IsBrowserSideNavigationEnabled() && unload_ack_is_for_navigation_) {
// TODO(clamy): see if before_unload_end_time should be transmitted to the
// Navigator.
frame_tree_node_->navigator()->OnBeforeUnloadACK(
@@ -1165,7 +1265,7 @@ void RenderFrameHostImpl::OnRenderProcessGone(int status, int exit_code) {
// Execute any pending AX tree snapshot callbacks with an empty response,
// since we're never going to get a response from this renderer.
for (const auto& iter : ax_tree_snapshot_callbacks_)
- iter.second.Run(ui::AXTreeUpdate<ui::AXNodeData>());
+ iter.second.Run(ui::AXTreeUpdate());
ax_tree_snapshot_callbacks_.clear();
// Note: don't add any more code at this point in the function because
@@ -1181,6 +1281,7 @@ void RenderFrameHostImpl::OnSwappedOut() {
TRACE_EVENT_ASYNC_END0("navigation", "RenderFrameHostImpl::SwapOut", this);
swapout_event_monitor_timeout_->Stop();
+ ClearAllWebUI();
// If this is a main frame RFH that's about to be deleted, update its RVH's
// swapped-out state here, since SetState won't be called once this RFH is
@@ -1213,6 +1314,15 @@ void RenderFrameHostImpl::OnContextMenu(const ContextMenuParams& params) {
process->FilterURL(false, &validated_params.page_url);
process->FilterURL(true, &validated_params.frame_url);
+ // It is necessary to transform the coordinates to account for nested
+ // RenderWidgetHosts, such as with out-of-process iframes.
+ gfx::Point original_point(validated_params.x, validated_params.y);
+ gfx::Point transformed_point = original_point;
+ static_cast<RenderWidgetHostViewBase*>(GetView())
+ ->TransformPointToRootCoordSpace(original_point, &transformed_point);
+ validated_params.x = transformed_point.x();
+ validated_params.y = transformed_point.y();
+
delegate_->ShowContextMenu(this, validated_params);
}
@@ -1235,7 +1345,7 @@ void RenderFrameHostImpl::OnJavaScriptExecuteResponse(
}
}
-void RenderFrameHostImpl::OnVisualStateResponse(uint64 id) {
+void RenderFrameHostImpl::OnVisualStateResponse(uint64_t id) {
auto it = visual_state_callbacks_.find(id);
if (it != visual_state_callbacks_.end()) {
it->second.Run(true);
@@ -1254,7 +1364,7 @@ void RenderFrameHostImpl::OnRunJavaScriptMessage(
// While a JS message dialog is showing, tabs in the same process shouldn't
// process input events.
GetProcess()->SetIgnoreInputEvents(true);
- render_view_host_->StopHangMonitorTimeout();
+ render_view_host_->GetWidget()->StopHangMonitorTimeout();
delegate_->RunJavaScriptMessage(this, message, default_prompt,
frame_url, type, reply_msg);
}
@@ -1267,7 +1377,7 @@ void RenderFrameHostImpl::OnRunBeforeUnloadConfirm(
// While a JS beforeunload dialog is showing, tabs in the same process
// shouldn't process input events.
GetProcess()->SetIgnoreInputEvents(true);
- render_view_host_->StopHangMonitorTimeout();
+ render_view_host_->GetWidget()->StopHangMonitorTimeout();
delegate_->RunBeforeUnloadConfirm(this, message, is_reload, reply_msg);
}
@@ -1283,7 +1393,7 @@ void RenderFrameHostImpl::OnDidAccessInitialDocument() {
delegate_->DidAccessInitialDocument();
}
-void RenderFrameHostImpl::OnDidChangeOpener(int32 opener_routing_id) {
+void RenderFrameHostImpl::OnDidChangeOpener(int32_t opener_routing_id) {
frame_tree_node_->render_manager()->DidChangeOpener(opener_routing_id,
GetSiteInstance());
}
@@ -1296,29 +1406,40 @@ void RenderFrameHostImpl::OnDidChangeName(const std::string& name) {
delegate_->DidChangeName(this, name);
}
-void RenderFrameHostImpl::OnDidAssignPageId(int32 page_id) {
+void RenderFrameHostImpl::OnEnforceStrictMixedContentChecking() {
+ frame_tree_node()->SetEnforceStrictMixedContentChecking(true);
+}
+
+void RenderFrameHostImpl::OnDidAssignPageId(int32_t page_id) {
// Update the RVH's current page ID so that future IPCs from the renderer
// correspond to the new page.
render_view_host_->page_id_ = page_id;
}
+FrameTreeNode* RenderFrameHostImpl::FindAndVerifyChild(
+ int32_t child_frame_routing_id,
+ bad_message::BadMessageReason reason) {
+ FrameTreeNode* child = frame_tree_node()->frame_tree()->FindByRoutingID(
+ GetProcess()->GetID(), child_frame_routing_id);
+ // A race can result in |child| to be nullptr. Avoid killing the renderer in
+ // that case.
+ if (child && child->parent() != frame_tree_node()) {
+ bad_message::ReceivedBadMessage(GetProcess(), reason);
+ return nullptr;
+ }
+ return child;
+}
+
void RenderFrameHostImpl::OnDidChangeSandboxFlags(
- int32 frame_routing_id,
+ int32_t frame_routing_id,
blink::WebSandboxFlags flags) {
- FrameTree* frame_tree = frame_tree_node()->frame_tree();
- FrameTreeNode* child =
- frame_tree->FindByRoutingID(GetProcess()->GetID(), frame_routing_id);
- if (!child)
- return;
-
// Ensure that a frame can only update sandbox flags for its immediate
// children. If this is not the case, the renderer is considered malicious
// and is killed.
- if (child->parent() != frame_tree_node()) {
- bad_message::ReceivedBadMessage(GetProcess(),
- bad_message::RFH_SANDBOX_FLAGS);
+ FrameTreeNode* child = FindAndVerifyChild(
+ frame_routing_id, bad_message::RFH_SANDBOX_FLAGS);
+ if (!child)
return;
- }
child->set_sandbox_flags(flags);
@@ -1334,11 +1455,34 @@ void RenderFrameHostImpl::OnDidChangeSandboxFlags(
}
}
+void RenderFrameHostImpl::OnDidChangeFrameOwnerProperties(
+ int32_t frame_routing_id,
+ const blink::WebFrameOwnerProperties& frame_owner_properties) {
+ FrameTreeNode* child = FindAndVerifyChild(
+ frame_routing_id, bad_message::RFH_OWNER_PROPERTY);
+ if (!child)
+ return;
+
+ child->set_frame_owner_properties(frame_owner_properties);
+
+ // Notify the RenderFrame if it lives in a different process from its parent.
+ // These properties only affect the RenderFrame and live in its parent
+ // (HTMLFrameOwnerElement). Therefore, we do not need to notify this frame's
+ // proxies.
+ RenderFrameHost* child_rfh = child->current_frame_host();
+ if (child_rfh->GetSiteInstance() != GetSiteInstance()) {
+ child_rfh->Send(new FrameMsg_SetFrameOwnerProperties(
+ child_rfh->GetRoutingID(), frame_owner_properties));
+ }
+}
+
void RenderFrameHostImpl::OnUpdateTitle(
const base::string16& title,
blink::WebTextDirection title_direction) {
- // This message is only sent for top-level frames. TODO(avi): when frame tree
- // mirroring works correctly, add a check here to enforce it.
+ // This message should only be sent for top-level frames.
+ if (frame_tree_node_->parent())
+ return;
+
if (title.length() > kMaxTitleChars) {
NOTREACHED() << "Renderer sent too many characters in title.";
return;
@@ -1359,8 +1503,7 @@ void RenderFrameHostImpl::OnBeginNavigation(
const CommonNavigationParams& common_params,
const BeginNavigationParams& begin_params,
scoped_refptr<ResourceRequestBody> body) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
CommonNavigationParams validated_params = common_params;
GetProcess()->FilterURL(false, &validated_params.url);
frame_tree_node()->navigator()->OnBeginNavigation(
@@ -1384,10 +1527,12 @@ void RenderFrameHostImpl::OnDispatchLoad() {
RenderWidgetHostViewBase* RenderFrameHostImpl::GetViewForAccessibility() {
return static_cast<RenderWidgetHostViewBase*>(
- frame_tree_node_->IsMainFrame() ? render_view_host_->GetView()
- : frame_tree_node_->frame_tree()
- ->GetMainFrame()
- ->render_view_host_->GetView());
+ frame_tree_node_->IsMainFrame()
+ ? render_view_host_->GetWidget()->GetView()
+ : frame_tree_node_->frame_tree()
+ ->GetMainFrame()
+ ->render_view_host_->GetWidget()
+ ->GetView());
}
void RenderFrameHostImpl::OnAccessibilityEvents(
@@ -1418,6 +1563,11 @@ void RenderFrameHostImpl::OnAccessibilityEvents(
detail.event_type = param.event_type;
detail.id = param.id;
detail.ax_tree_id = GetAXTreeID();
+ if (param.update.has_tree_data) {
+ detail.update.has_tree_data = true;
+ AXContentTreeDataToAXTreeData(param.update.tree_data,
+ &detail.update.tree_data);
+ }
detail.update.node_id_to_clear = param.update.node_id_to_clear;
detail.update.nodes.resize(param.update.nodes.size());
for (size_t i = 0; i < param.update.nodes.size(); ++i) {
@@ -1470,7 +1620,7 @@ void RenderFrameHostImpl::OnAccessibilityLocationChanges(
return;
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
- render_view_host_->GetView());
+ render_view_host_->GetWidget()->GetView());
if (view && RenderFrameHostImpl::IsRFHStateActive(rfh_state())) {
AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode();
if (accessibility_mode & AccessibilityModeFlagPlatform) {
@@ -1499,15 +1649,20 @@ void RenderFrameHostImpl::OnAccessibilityFindInPageResult(
void RenderFrameHostImpl::OnAccessibilitySnapshotResponse(
int callback_id,
- const ui::AXTreeUpdate<AXContentNodeData>& snapshot) {
+ const AXContentTreeUpdate& snapshot) {
const auto& it = ax_tree_snapshot_callbacks_.find(callback_id);
if (it != ax_tree_snapshot_callbacks_.end()) {
- ui::AXTreeUpdate<ui::AXNodeData> dst_snapshot;
+ ui::AXTreeUpdate dst_snapshot;
dst_snapshot.nodes.resize(snapshot.nodes.size());
for (size_t i = 0; i < snapshot.nodes.size(); ++i) {
AXContentNodeDataToAXNodeData(snapshot.nodes[i],
&dst_snapshot.nodes[i]);
}
+ if (snapshot.has_tree_data) {
+ AXContentTreeDataToAXTreeData(snapshot.tree_data,
+ &dst_snapshot.tree_data);
+ dst_snapshot.has_tree_data = true;
+ }
it->second.Run(dst_snapshot);
ax_tree_snapshot_callbacks_.erase(it);
} else {
@@ -1523,7 +1678,7 @@ void RenderFrameHostImpl::OnToggleFullscreen(bool enter_fullscreen) {
// The previous call might change the fullscreen state. We need to make sure
// the renderer is aware of that, which is done via the resize message.
- render_view_host_->WasResized();
+ render_view_host_->GetWidget()->WasResized();
}
void RenderFrameHostImpl::OnDidStartLoading(bool to_different_document) {
@@ -1566,6 +1721,14 @@ void RenderFrameHostImpl::OnDidChangeLoadProgress(double load_progress) {
frame_tree_node_->DidChangeLoadProgress(load_progress);
}
+void RenderFrameHostImpl::OnSerializeAsMHTMLResponse(
+ int job_id,
+ bool success,
+ const std::set<std::string>& digests_of_uris_of_serialized_resources) {
+ MHTMLGenerationManager::GetInstance()->OnSerializeAsMHTMLResponse(
+ this, job_id, success, digests_of_uris_of_serialized_resources);
+}
+
#if defined(OS_MACOSX) || defined(OS_ANDROID)
void RenderFrameHostImpl::OnShowPopup(
const FrameHostMsg_ShowPopup_Params& params) {
@@ -1605,6 +1768,18 @@ void RenderFrameHostImpl::RegisterMojoServices() {
base::Unretained(this))));
}
+ WakeLockServiceContext* wake_lock_service_context =
+ delegate_ ? delegate_->GetWakeLockServiceContext() : nullptr;
+ if (wake_lock_service_context) {
+ // WakeLockServiceContext is owned by WebContentsImpl so it will outlive
+ // this RenderFrameHostImpl, hence a raw pointer can be bound to service
+ // factory callback.
+ GetServiceRegistry()->AddService<WakeLockService>(
+ base::Bind(&WakeLockServiceContext::CreateService,
+ base::Unretained(wake_lock_service_context),
+ GetProcess()->GetID(), GetRoutingID()));
+ }
+
if (!permission_service_context_)
permission_service_context_.reset(new PermissionServiceContext(this));
@@ -1631,6 +1806,9 @@ void RenderFrameHostImpl::RegisterMojoServices() {
base::Bind(&VRDeviceManager::BindRequest));
}
#endif
+
+ GetContentClient()->browser()->RegisterRenderFrameMojoServices(
+ GetServiceRegistry(), this);
}
void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) {
@@ -1641,9 +1819,9 @@ void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) {
// We update the number of RenderFrameHosts in a SiteInstance when the swapped
// out status of a RenderFrameHost gets flipped to/from active.
if (!IsRFHStateActive(rfh_state_) && IsRFHStateActive(rfh_state))
- GetSiteInstance()->increment_active_frame_count();
+ GetSiteInstance()->IncrementActiveFrameCount();
else if (IsRFHStateActive(rfh_state_) && !IsRFHStateActive(rfh_state))
- GetSiteInstance()->decrement_active_frame_count();
+ GetSiteInstance()->DecrementActiveFrameCount();
// The active and swapped out state of the RVH is determined by its main
// frame, since subframes should have their own widgets.
@@ -1663,8 +1841,8 @@ void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) {
rfh_state_ == STATE_SWAPPED_OUT) {
if (is_waiting_for_beforeunload_ack_) {
is_waiting_for_beforeunload_ack_ = false;
- render_view_host_->decrement_in_flight_event_count();
- render_view_host_->StopHangMonitorTimeout();
+ render_view_host_->GetWidget()->decrement_in_flight_event_count();
+ render_view_host_->GetWidget()->StopHangMonitorTimeout();
}
send_before_unload_start_time_ = base::TimeTicks();
render_view_host_->is_waiting_for_close_ack_ = false;
@@ -1686,28 +1864,22 @@ void RenderFrameHostImpl::Navigate(
const StartNavigationParams& start_params,
const RequestNavigationParams& request_params) {
TRACE_EVENT0("navigation", "RenderFrameHostImpl::Navigate");
- DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ DCHECK(!IsBrowserSideNavigationEnabled());
UpdatePermissionsForNavigation(common_params, request_params);
// Only send the message if we aren't suspended at the start of a cross-site
// request.
if (navigations_suspended_) {
- // Shouldn't be possible to have a second navigation while suspended, since
- // navigations will only be suspended during a cross-site request. If a
- // second navigation occurs, RenderFrameHostManager will cancel this pending
- // RFH and create a new pending RFH.
- DCHECK(!suspended_nav_params_.get());
+ // This may replace an existing set of params, if this is a pending RFH that
+ // is navigated twice consecutively.
suspended_nav_params_.reset(
new NavigationParams(common_params, start_params, request_params));
} else {
// Get back to a clean state, in case we start a new navigation without
// completing a RFH swap or unload handler.
SetState(RenderFrameHostImpl::STATE_DEFAULT);
-
- Send(new FrameMsg_Navigate(routing_id_, common_params, start_params,
- request_params));
+ SendNavigateMessage(common_params, start_params, request_params);
}
// Force the throbber to start. This is done because Blink's "started loading"
@@ -1730,9 +1902,9 @@ void RenderFrameHostImpl::NavigateToInterstitialURL(const GURL& data_url) {
CommonNavigationParams common_params(
data_url, Referrer(), ui::PAGE_TRANSITION_LINK,
FrameMsg_Navigate_Type::NORMAL, false, false, base::TimeTicks::Now(),
- FrameMsg_UILoadMetricsReportType::NO_REPORT, GURL(), GURL());
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ FrameMsg_UILoadMetricsReportType::NO_REPORT, GURL(), GURL(), LOFI_OFF,
+ base::TimeTicks::Now());
+ if (IsBrowserSideNavigationEnabled()) {
CommitNavigation(nullptr, nullptr, common_params,
RequestNavigationParams());
} else {
@@ -1761,15 +1933,13 @@ void RenderFrameHostImpl::DispatchBeforeUnload(bool for_navigation) {
// TODO(creis): Support beforeunload on subframes. For now just pretend that
// the handler ran and allowed the navigation to proceed.
if (!ShouldDispatchBeforeUnload()) {
- DCHECK(!(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
- for_navigation));
+ DCHECK(!(IsBrowserSideNavigationEnabled() && for_navigation));
frame_tree_node_->render_manager()->OnBeforeUnloadACK(
for_navigation, true, base::TimeTicks::Now());
return;
}
- TRACE_EVENT_ASYNC_BEGIN0(
- "navigation", "RenderFrameHostImpl::BeforeUnload", this);
+ TRACE_EVENT_ASYNC_BEGIN1("navigation", "RenderFrameHostImpl BeforeUnload",
+ this, "&RenderFrameHostImpl", (void*)this);
// This may be called more than once (if the user clicks the tab close button
// several times, or if she clicks the tab close button then the browser close
@@ -1790,8 +1960,8 @@ void RenderFrameHostImpl::DispatchBeforeUnload(bool for_navigation) {
unload_ack_is_for_navigation_ = for_navigation;
// Increment the in-flight event count, to ensure that input events won't
// cancel the timeout timer.
- render_view_host_->increment_in_flight_event_count();
- render_view_host_->StartHangMonitorTimeout(
+ render_view_host_->GetWidget()->increment_in_flight_event_count();
+ render_view_host_->GetWidget()->StartHangMonitorTimeout(
TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS));
send_before_unload_start_time_ = base::TimeTicks::Now();
Send(new FrameMsg_BeforeUnload(routing_id_));
@@ -1817,8 +1987,8 @@ void RenderFrameHostImpl::UpdateOpener() {
Send(new FrameMsg_UpdateOpener(GetRoutingID(), opener_routing_id));
}
-void RenderFrameHostImpl::ClearFocus() {
- Send(new FrameMsg_ClearFocus(routing_id_));
+void RenderFrameHostImpl::SetFocusedFrame() {
+ Send(new FrameMsg_SetFocusedFrame(routing_id_));
}
void RenderFrameHostImpl::ExtendSelectionAndDelete(size_t before,
@@ -1839,10 +2009,10 @@ void RenderFrameHostImpl::JavaScriptDialogClosed(
// leave the current page. In this case, use the regular timeout value used
// during the (before)unload handling.
if (is_waiting) {
- render_view_host_->StartHangMonitorTimeout(
+ render_view_host_->GetWidget()->StartHangMonitorTimeout(
success
? TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)
- : render_view_host_->hung_renderer_delay_);
+ : render_view_host_->GetWidget()->hung_renderer_delay());
}
FrameHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg,
@@ -1855,8 +2025,10 @@ void RenderFrameHostImpl::JavaScriptDialogClosed(
// continuing to run its script and dragging out the process.
// This must be done after sending the reply since RenderView can't close
// correctly while waiting for a response.
- if (is_waiting && dialog_was_suppressed)
- render_view_host_->delegate_->RendererUnresponsive(render_view_host_);
+ if (is_waiting && dialog_was_suppressed) {
+ render_view_host_->GetWidget()->delegate()->RendererUnresponsive(
+ render_view_host_->GetWidget());
+ }
}
// PlzNavigate
@@ -1883,7 +2055,7 @@ void RenderFrameHostImpl::CommitNavigation(
// TODO(clamy): Release the stream handle once the renderer has finished
// reading it.
- stream_handle_ = body.Pass();
+ stream_handle_ = std::move(body);
// When navigating to a Javascript url, no commit is expected from the
// RenderFrameHost, nor should the throbber start.
@@ -1929,8 +2101,8 @@ void RenderFrameHostImpl::SetUpMojoIfNeeded() {
mojo::ServiceProviderPtr services;
setup->ExchangeServiceProviders(routing_id_, GetProxy(&services),
- exposed_services.Pass());
- service_registry_->BindRemoteServiceProvider(services.Pass());
+ std::move(exposed_services));
+ service_registry_->BindRemoteServiceProvider(std::move(services));
#if defined(OS_ANDROID)
service_registry_android_.reset(
@@ -1963,6 +2135,97 @@ bool RenderFrameHostImpl::IsFocused() {
frame_tree_->GetFocusedFrame()->IsDescendantOf(frame_tree_node()));
}
+bool RenderFrameHostImpl::UpdatePendingWebUI(const GURL& dest_url,
+ int entry_bindings) {
+ WebUI::TypeID new_web_ui_type =
+ WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
+ GetSiteInstance()->GetBrowserContext(), dest_url);
+
+ // If the required WebUI matches the pending WebUI or if it matches the
+ // to-be-reused active WebUI, then leave everything as is.
+ if (new_web_ui_type == pending_web_ui_type_ ||
+ (should_reuse_web_ui_ && new_web_ui_type == web_ui_type_)) {
+ return false;
+ }
+
+ // Reset the pending WebUI as from this point it will certainly not be reused.
+ ClearPendingWebUI();
+
+ // If this navigation is not to a WebUI, skip directly to bindings work.
+ if (new_web_ui_type != WebUI::kNoWebUI) {
+ if (new_web_ui_type == web_ui_type_) {
+ // The active WebUI should be reused when dest_url requires a WebUI and
+ // its type matches the current.
+ DCHECK(web_ui_);
+ should_reuse_web_ui_ = true;
+ } else {
+ // Otherwise create a new pending WebUI.
+ pending_web_ui_ = delegate_->CreateWebUIForRenderFrameHost(dest_url);
+ DCHECK(pending_web_ui_);
+ pending_web_ui_type_ = new_web_ui_type;
+
+ // If we have assigned (zero or more) bindings to the NavigationEntry in
+ // the past, make sure we're not granting it different bindings than it
+ // had before. If so, note it and don't give it any bindings, to avoid a
+ // potential privilege escalation.
+ if (entry_bindings != NavigationEntryImpl::kInvalidBindings &&
+ pending_web_ui_->GetBindings() != entry_bindings) {
+ RecordAction(
+ base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
+ ClearPendingWebUI();
+ }
+ }
+ }
+ DCHECK_EQ(!pending_web_ui_, pending_web_ui_type_ == WebUI::kNoWebUI);
+
+ // Either grant or check the RenderViewHost with/for proper bindings.
+ if (pending_web_ui_ && !render_view_host_->GetProcess()->IsForGuestsOnly()) {
+ // If a WebUI was created for the URL and the RenderView is not in a guest
+ // process, then enable missing bindings with the RenderViewHost.
+ int new_bindings = pending_web_ui_->GetBindings();
+ if ((render_view_host_->GetEnabledBindings() & new_bindings) !=
+ new_bindings) {
+ render_view_host_->AllowBindings(new_bindings);
+ }
+ } else if (render_view_host_->is_active()) {
+ // If the ongoing navigation is not to a WebUI or the RenderView is in a
+ // guest process, ensure that we don't create an unprivileged RenderView in
+ // a WebUI-enabled process unless it's swapped out.
+ bool url_acceptable_for_webui =
+ WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
+ GetSiteInstance()->GetBrowserContext(), dest_url);
+ if (!url_acceptable_for_webui) {
+ CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ GetProcess()->GetID()));
+ }
+ }
+ return true;
+}
+
+void RenderFrameHostImpl::CommitPendingWebUI() {
+ if (should_reuse_web_ui_) {
+ should_reuse_web_ui_ = false;
+ } else {
+ web_ui_ = std::move(pending_web_ui_);
+ web_ui_type_ = pending_web_ui_type_;
+ pending_web_ui_type_ = WebUI::kNoWebUI;
+ }
+ DCHECK(!pending_web_ui_ && pending_web_ui_type_ == WebUI::kNoWebUI &&
+ !should_reuse_web_ui_);
+}
+
+void RenderFrameHostImpl::ClearPendingWebUI() {
+ pending_web_ui_.reset();
+ pending_web_ui_type_ = WebUI::kNoWebUI;
+ should_reuse_web_ui_ = false;
+}
+
+void RenderFrameHostImpl::ClearAllWebUI() {
+ ClearPendingWebUI();
+ web_ui_type_ = WebUI::kNoWebUI;
+ web_ui_.reset();
+}
+
const image_downloader::ImageDownloaderPtr&
RenderFrameHostImpl::GetMojoImageDownloader() {
if (!mojo_image_downloader_.get() && GetServiceRegistry()) {
@@ -2036,8 +2299,8 @@ void RenderFrameHostImpl::ActivateFindInPageResultForAccessibility(
void RenderFrameHostImpl::InsertVisualStateCallback(
const VisualStateCallback& callback) {
- static uint64 next_id = 1;
- uint64 key = next_id++;
+ static uint64_t next_id = 1;
+ uint64_t key = next_id++;
Send(new FrameMsg_VisualStateRequest(routing_id_, key));
visual_state_callbacks_.insert(std::make_pair(key, callback));
}
@@ -2046,7 +2309,7 @@ bool RenderFrameHostImpl::IsRenderFrameLive() {
bool is_live = GetProcess()->HasConnection() && render_frame_created_;
// Sanity check: the RenderView should always be live if the RenderFrame is.
- DCHECK_IMPLIES(is_live, render_view_host_->IsRenderViewLive());
+ DCHECK(!is_live || render_view_host_->IsRenderViewLive());
return is_live;
}
@@ -2056,7 +2319,7 @@ bool RenderFrameHostImpl::IsRenderFrameLive() {
void RenderFrameHostImpl::SetParentNativeViewAccessible(
gfx::NativeViewAccessible accessible_parent) {
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
- render_view_host_->GetView());
+ render_view_host_->GetWidget()->GetView());
if (view)
view->SetParentNativeViewAccessible(accessible_parent);
}
@@ -2112,12 +2375,13 @@ void RenderFrameHostImpl::SetNavigationsSuspended(
SetState(RenderFrameHostImpl::STATE_DEFAULT);
DCHECK(!proceed_time.is_null());
- suspended_nav_params_->request_params.browser_navigation_start =
- proceed_time;
- Send(new FrameMsg_Navigate(routing_id_,
- suspended_nav_params_->common_params,
- suspended_nav_params_->start_params,
- suspended_nav_params_->request_params));
+ // TODO(csharrison): Make sure that PlzNavigate and the current architecture
+ // measure navigation start in the same way in the presence of the
+ // BeforeUnload event.
+ suspended_nav_params_->common_params.navigation_start = proceed_time;
+ SendNavigateMessage(suspended_nav_params_->common_params,
+ suspended_nav_params_->start_params,
+ suspended_nav_params_->request_params);
suspended_nav_params_.reset();
}
}
@@ -2132,6 +2396,16 @@ void RenderFrameHostImpl::CancelSuspendedNavigations() {
navigations_suspended_ = false;
}
+void RenderFrameHostImpl::SendNavigateMessage(
+ const CommonNavigationParams& common_params,
+ const StartNavigationParams& start_params,
+ const RequestNavigationParams& request_params) {
+ RenderFrameDevToolsAgentHost::OnBeforeNavigation(
+ frame_tree_node_->current_frame_host(), this);
+ Send(new FrameMsg_Navigate(
+ routing_id_, common_params, start_params, request_params));
+}
+
void RenderFrameHostImpl::DidUseGeolocationPermission() {
PermissionManager* permission_manager =
GetSiteInstance()->GetBrowserContext()->GetPermissionManager();
@@ -2232,16 +2506,8 @@ void RenderFrameHostImpl::AXContentNodeDataToAXNodeData(
// instance IDs to generic attributes with global AXTreeIDs.
for (auto iter : src.content_int_attributes) {
AXContentIntAttribute attr = iter.first;
- int32 value = iter.second;
+ int32_t value = iter.second;
switch (attr) {
- case AX_CONTENT_ATTR_ROUTING_ID:
- dst->int_attributes.push_back(std::make_pair(
- ui::AX_ATTR_TREE_ID, RoutingIDToAXTreeID(value)));
- break;
- case AX_CONTENT_ATTR_PARENT_ROUTING_ID:
- dst->int_attributes.push_back(std::make_pair(
- ui::AX_ATTR_PARENT_TREE_ID, RoutingIDToAXTreeID(value)));
- break;
case AX_CONTENT_ATTR_CHILD_ROUTING_ID:
dst->int_attributes.push_back(std::make_pair(
ui::AX_ATTR_CHILD_TREE_ID, RoutingIDToAXTreeID(value)));
@@ -2258,4 +2524,17 @@ void RenderFrameHostImpl::AXContentNodeDataToAXNodeData(
}
}
+void RenderFrameHostImpl::AXContentTreeDataToAXTreeData(
+ const AXContentTreeData& src,
+ ui::AXTreeData* dst) {
+ // Copy the common fields.
+ *dst = src;
+
+ if (src.routing_id != -1)
+ dst->tree_id = RoutingIDToAXTreeID(src.routing_id);
+
+ if (src.parent_routing_id != -1)
+ dst->parent_tree_id = RoutingIDToAXTreeID(src.parent_routing_id);
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_host_impl.h b/chromium/content/browser/frame_host/render_frame_host_impl.h
index 45628549287..b457a076e55 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.h
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.h
@@ -5,17 +5,26 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_IMPL_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
+#include <set>
+#include <string>
#include <vector>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/bad_message.h"
#include "content/browser/site_instance_impl.h"
+#include "content/browser/webui/web_ui_impl.h"
#include "content/common/accessibility_mode_enums.h"
#include "content/common/ax_content_node_data.h"
#include "content/common/content_export.h"
@@ -27,6 +36,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/javascript_message_type.h"
#include "net/http/http_response_headers.h"
+#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
#include "third_party/WebKit/public/web/WebTextDirection.h"
#include "third_party/WebKit/public/web/WebTreeScopeType.h"
#include "ui/accessibility/ax_node_data.h"
@@ -90,7 +100,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
public BrowserAccessibilityDelegate {
public:
using AXTreeSnapshotCallback =
- base::Callback<void(const ui::AXTreeUpdate<ui::AXNodeData>&)>;
+ base::Callback<void(
+ const ui::AXTreeUpdate&)>;
// Keeps track of the state of the RenderFrameHostImpl, particularly with
// respect to swap out.
@@ -129,9 +140,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
SiteInstanceImpl* GetSiteInstance() override;
RenderProcessHost* GetProcess() override;
RenderFrameHost* GetParent() override;
+ int GetFrameTreeNodeId() override;
const std::string& GetFrameName() override;
bool IsCrossProcessSubframe() override;
GURL GetLastCommittedURL() override;
+ url::Origin GetLastCommittedOrigin() override;
gfx::NativeView GetNativeView() override;
void AddMessageToConsole(ConsoleMessageLevel level,
const std::string& message) override;
@@ -172,9 +185,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
const gfx::Point& point) override;
void AccessibilitySetScrollOffset(int acc_obj_id,
const gfx::Point& offset) override;
- void AccessibilitySetTextSelection(int acc_obj_id,
- int start_offset,
- int end_offset) override;
+ void AccessibilitySetSelection(int anchor_object_id,
+ int anchor_offset,
+ int focus_object_id,
+ int focus_offset) override;
void AccessibilitySetValue(int acc_obj_id, const base::string16& value)
override;
bool AccessibilityViewHasFocus() const override;
@@ -203,15 +217,25 @@ class CONTENT_EXPORT RenderFrameHostImpl
void Init();
int routing_id() const { return routing_id_; }
- void OnCreateChildFrame(int new_routing_id,
- blink::WebTreeScopeType scope,
- const std::string& frame_name,
- blink::WebSandboxFlags sandbox_flags);
+ void OnCreateChildFrame(
+ int new_routing_id,
+ blink::WebTreeScopeType scope,
+ const std::string& frame_name,
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties);
RenderViewHostImpl* render_view_host() { return render_view_host_; }
RenderFrameHostDelegate* delegate() { return delegate_; }
FrameTreeNode* frame_tree_node() { return frame_tree_node_; }
+ // Returns the associated WebUI or null if none applies.
+ WebUIImpl* web_ui() const { return web_ui_.get(); }
+
+ // Returns the pending WebUI, or null if none applies.
+ WebUIImpl* pending_web_ui() const {
+ return should_reuse_web_ui_ ? web_ui_.get() : pending_web_ui_.get();
+ }
+
// Returns this RenderFrameHost's loading state. This method is only used by
// FrameTreeNode. The proper way to check whether a frame is loading is to
// call FrameTreeNode::IsLoading.
@@ -248,6 +272,14 @@ class CONTENT_EXPORT RenderFrameHostImpl
// TODO(creis): Make bindings frame-specific, to support cases like <webview>.
int GetEnabledBindings();
+ // The unique ID of the latest NavigationEntry that this RenderFrameHost is
+ // showing. This may change even when this frame hasn't committed a page,
+ // such as for a new subframe navigation in a different frame.
+ int nav_entry_id() const { return nav_entry_id_; }
+ void set_nav_entry_id(int nav_entry_id) { nav_entry_id_ = nav_entry_id; }
+
+ // A NavigationHandle for the pending navigation in this frame, if any. This
+ // is cleared when the navigation commits.
NavigationHandleImpl* navigation_handle() const {
return navigation_handle_.get();
}
@@ -373,8 +405,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
// another renderer process.
void UpdateOpener();
- // Clear focus from this frame in the renderer process.
- void ClearFocus();
+ // Set this frame as focused in the renderer process. This supports
+ // cross-process window.focus() calls.
+ void SetFocusedFrame();
// Deletes the current selection plus the specified number of characters
// before and after the selection or caret.
@@ -467,6 +500,26 @@ class CONTENT_EXPORT RenderFrameHostImpl
// addition, its associated RenderWidgetHost has to be focused.
bool IsFocused();
+ // Updates the pending WebUI of this RenderFrameHost based on the provided
+ // |dest_url|, setting it to either none, a new instance or to reuse the
+ // currently active one. Returns true if the pending WebUI was updated.
+ // If this is a history navigation its NavigationEntry bindings should be
+ // provided through |entry_bindings| to allow verifying that they are not
+ // being set differently this time around. Otherwise |entry_bindings| should
+ // be set to NavigationEntryImpl::kInvalidBindings so that no checks are done.
+ bool UpdatePendingWebUI(const GURL& dest_url, int entry_bindings);
+
+ // Updates the active WebUI with the pending one set by the last call to
+ // UpdatePendingWebUI and then clears any pending data. If UpdatePendingWebUI
+ // was not called the active WebUI will simply be cleared.
+ void CommitPendingWebUI();
+
+ // Destroys the pending WebUI and resets related data.
+ void ClearPendingWebUI();
+
+ // Destroys all WebUI instances and resets related data.
+ void ClearAllWebUI();
+
// Returns the Mojo ImageDownloader service.
const image_downloader::ImageDownloaderPtr& GetMojoImageDownloader();
@@ -483,8 +536,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
- int32 routing_id,
- int32 widget_routing_id,
+ int32_t routing_id,
+ int32_t widget_routing_id,
int flags);
private:
@@ -494,9 +547,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, CrashSubframe);
// IPC Message handlers.
- void OnAddMessageToConsole(int32 level,
+ void OnAddMessageToConsole(int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id);
void OnDetach();
void OnFrameFocused();
@@ -504,7 +557,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnDocumentOnLoadCompleted(
FrameMsg_UILoadMetricsReportType::Value report_type,
base::TimeTicks ui_timestamp);
- void OnDidStartProvisionalLoadForFrame(const GURL& url);
+ void OnDidStartProvisionalLoad(
+ const GURL& url,
+ const base::TimeTicks& navigation_start);
void OnDidFailProvisionalLoadWithError(
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params);
void OnDidFailLoadWithError(
@@ -514,6 +569,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
bool was_ignored_by_handler);
void OnDidCommitProvisionalLoad(const IPC::Message& msg);
void OnDidDropNavigation();
+ void OnUpdateState(const PageState& state);
void OnBeforeUnloadACK(
bool proceed,
const base::TimeTicks& renderer_before_unload_start_time,
@@ -522,7 +578,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnRenderProcessGone(int status, int error_code);
void OnContextMenu(const ContextMenuParams& params);
void OnJavaScriptExecuteResponse(int id, const base::ListValue& result);
- void OnVisualStateResponse(uint64 id);
+ void OnVisualStateResponse(uint64_t id);
void OnRunJavaScriptMessage(const base::string16& message,
const base::string16& default_prompt,
const GURL& frame_url,
@@ -536,11 +592,15 @@ class CONTENT_EXPORT RenderFrameHostImpl
size_t start_offset,
size_t end_offset);
void OnDidAccessInitialDocument();
- void OnDidChangeOpener(int32 opener_routing_id);
+ void OnDidChangeOpener(int32_t opener_routing_id);
void OnDidChangeName(const std::string& name);
- void OnDidAssignPageId(int32 page_id);
- void OnDidChangeSandboxFlags(int32 frame_routing_id,
+ void OnEnforceStrictMixedContentChecking();
+ void OnDidAssignPageId(int32_t page_id);
+ void OnDidChangeSandboxFlags(int32_t frame_routing_id,
blink::WebSandboxFlags flags);
+ void OnDidChangeFrameOwnerProperties(
+ int32_t frame_routing_id,
+ const blink::WebFrameOwnerProperties& frame_owner_properties);
void OnUpdateTitle(const base::string16& title,
blink::WebTextDirection title_direction);
void OnUpdateEncoding(const std::string& encoding);
@@ -557,11 +617,15 @@ class CONTENT_EXPORT RenderFrameHostImpl
const AccessibilityHostMsg_FindInPageResultParams& params);
void OnAccessibilitySnapshotResponse(
int callback_id,
- const ui::AXTreeUpdate<AXContentNodeData>& snapshot);
+ const AXContentTreeUpdate& snapshot);
void OnToggleFullscreen(bool enter_fullscreen);
void OnDidStartLoading(bool to_different_document);
void OnDidStopLoading();
void OnDidChangeLoadProgress(double load_progress);
+ void OnSerializeAsMHTMLResponse(
+ int job_id,
+ bool success,
+ const std::set<std::string>& digests_of_uris_of_serialized_resources);
#if defined(OS_MACOSX) || defined(OS_ANDROID)
void OnShowPopup(const FrameHostMsg_ShowPopup_Params& params);
@@ -608,11 +672,31 @@ class CONTENT_EXPORT RenderFrameHostImpl
void AXContentNodeDataToAXNodeData(const AXContentNodeData& src,
ui::AXNodeData* dst);
+ // Convert the content-layer-specific AXContentTreeData to a general-purpose
+ // AXTreeData structure.
+ void AXContentTreeDataToAXTreeData(const AXContentTreeData& src,
+ ui::AXTreeData* dst);
+
// Returns the RenderWidgetHostView used for accessibility. For subframes,
// this function will return the platform view on the main frame; for main
// frames, it will return the current frame's view.
RenderWidgetHostViewBase* GetViewForAccessibility();
+ // Sends a navigate message to the RenderFrame and notifies DevTools about
+ // navigation happening. Should be used instead of sending the message
+ // directly.
+ void SendNavigateMessage(
+ const content::CommonNavigationParams& common_params,
+ const content::StartNavigationParams& start_params,
+ const content::RequestNavigationParams& request_params);
+
+ // Returns the child FrameTreeNode if |child_frame_routing_id| is an
+ // immediate child of this FrameTreeNode. |child_frame_routing_id| is
+ // considered untrusted, so the renderer process is killed if it refers to a
+ // FrameTreeNode that is not a child of this node.
+ FrameTreeNode* FindAndVerifyChild(int32_t child_frame_routing_id,
+ bad_message::BadMessageReason reason);
+
// For now, RenderFrameHosts indirectly keep RenderViewHosts alive via a
// refcount that calls Shutdown when it reaches zero. This allows each
// RenderFrameHostManager to just care about RenderFrameHosts, while ensuring
@@ -663,7 +747,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
// The mapping of pending JavaScript calls created by
// ExecuteJavaScript and their corresponding callbacks.
std::map<int, JavaScriptResultCallback> javascript_callbacks_;
- std::map<uint64, VisualStateCallback> visual_state_callbacks_;
+ std::map<uint64_t, VisualStateCallback> visual_state_callbacks_;
// RenderFrameHosts that need management of the rendering and input events
// for their frame subtrees require RenderWidgetHosts. This typically
@@ -726,6 +810,13 @@ class CONTENT_EXPORT RenderFrameHostImpl
// tests.
bool pending_commit_;
+ // The unique ID of the latest NavigationEntry that this RenderFrameHost is
+ // showing. This may change even when this frame hasn't committed a page,
+ // such as for a new subframe navigation in a different frame. Tracking this
+ // allows us to send things like title and state updates to the latest
+ // relevant NavigationEntry.
+ int nav_entry_id_;
+
// Used to swap out or shut down this RFH when the unload event is taking too
// long to execute, depending on the number of active frames in the
// SiteInstance.
@@ -781,6 +872,22 @@ class CONTENT_EXPORT RenderFrameHostImpl
// NavigationHandle for it is owned by the NavigationRequest.
scoped_ptr<NavigationHandleImpl> navigation_handle_;
+ // The associated WebUIImpl and its type. They will be set if the current
+ // document is from WebUI source. Otherwise they will be null and
+ // WebUI::kNoWebUI, respectively.
+ scoped_ptr<WebUIImpl> web_ui_;
+ WebUI::TypeID web_ui_type_;
+
+ // The pending WebUIImpl and its type. These values will be used exclusively
+ // for same-site navigations to keep a transition of a WebUI in a pending
+ // state until the navigation commits.
+ scoped_ptr<WebUIImpl> pending_web_ui_;
+ WebUI::TypeID pending_web_ui_type_;
+
+ // If true the associated WebUI should be reused when CommitPendingWebUI is
+ // called (no pending instance should be set).
+ bool should_reuse_web_ui_;
+
// NOTE: This must be the last member.
base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;
diff --git a/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc
index e5d40f58353..6547788162e 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -4,6 +4,7 @@
#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "base/macros.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -121,17 +122,12 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, RemoveFocusedFrame) {
// Test that a frame is visible/hidden depending on its WebContents visibility
// state.
-// Flaky on Mac. http://crbug.com/467670
-#if defined(OS_MACOSX)
-#define MAYBE_GetVisibilityState_Basic DISABLED_GetVisibilityState_Basic
-#else
-#define MAYBE_GetVisibilityState_Basic GetVisibilityState_Basic
-#endif
IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
- MAYBE_GetVisibilityState_Basic) {
+ GetVisibilityState_Basic) {
EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo")));
WebContents* web_contents = shell()->web_contents();
+ web_contents->WasShown();
EXPECT_EQ(blink::WebPageVisibilityStateVisible,
web_contents->GetMainFrame()->GetVisibilityState());
@@ -141,20 +137,15 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
}
// Test that a frame visibility can be overridden by the ContentBrowserClient.
-// Flaky on Mac. http://crbug.com/525592
-#if defined(OS_MACOSX)
-#define MAYBE_GetVisibilityState_Override DISABLED_GetVisibilityState_Override
-#else
-#define MAYBE_GetVisibilityState_Override GetVisibilityState_Override
-#endif
IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
- MAYBE_GetVisibilityState_Override) {
+ GetVisibilityState_Override) {
EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo")));
WebContents* web_contents = shell()->web_contents();
PrerenderTestContentBrowserClient new_client;
ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
+ web_contents->WasShown();
EXPECT_EQ(blink::WebPageVisibilityStateVisible,
web_contents->GetMainFrame()->GetVisibilityState());
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager.cc b/chromium/content/browser/frame_host/render_frame_host_manager.cc
index 79a477d1e02..093dd4a5fa8 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.cc
@@ -4,6 +4,8 @@
#include "content/browser/frame_host/render_frame_host_manager.h"
+#include <stddef.h>
+
#include <algorithm>
#include <utility>
@@ -30,7 +32,6 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
-#include "content/browser/webui/web_ui_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
@@ -39,8 +40,8 @@
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/user_metrics.h"
-#include "content/public/browser/web_ui_controller.h"
#include "content/public/common/browser_plugin_guest_mode.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/referrer.h"
#include "content/public/common/url_constants.h"
@@ -85,128 +86,23 @@ bool OpenerForFrameTreeNode(
} // namespace
-// A helper class to hold all frame proxies and register as a
-// RenderProcessHostObserver for them.
-class RenderFrameHostManager::RenderFrameProxyHostMap
- : public RenderProcessHostObserver {
- public:
- using MapType = base::hash_map<int32, RenderFrameProxyHost*>;
-
- RenderFrameProxyHostMap(RenderFrameHostManager* manager);
- ~RenderFrameProxyHostMap() override;
-
- // Read-only access to the underlying map of site instance ID to
- // RenderFrameProxyHosts.
- MapType::const_iterator begin() const { return map_.begin(); }
- MapType::const_iterator end() const { return map_.end(); }
- bool empty() const { return map_.empty(); }
-
- // Returns the proxy with the specified ID, or nullptr if there is no such
- // one.
- RenderFrameProxyHost* Get(int32 id);
-
- // Adds the specified proxy with the specified ID. It is an error (and fatal)
- // to add more than one proxy with the specified ID.
- void Add(int32 id, scoped_ptr<RenderFrameProxyHost> proxy);
-
- // Removes the proxy with the specified site instance ID.
- void Remove(int32 id);
-
- // Removes all proxies.
- void Clear();
-
- // RenderProcessHostObserver implementation.
- void RenderProcessWillExit(RenderProcessHost* host) override;
- void RenderProcessExited(RenderProcessHost* host,
- base::TerminationStatus status,
- int exit_code) override;
-
- private:
- RenderFrameHostManager* manager_;
- MapType map_;
-};
-
-RenderFrameHostManager::RenderFrameProxyHostMap::RenderFrameProxyHostMap(
- RenderFrameHostManager* manager)
- : manager_(manager) {}
-
-RenderFrameHostManager::RenderFrameProxyHostMap::~RenderFrameProxyHostMap() {
- Clear();
-}
-
-RenderFrameProxyHost* RenderFrameHostManager::RenderFrameProxyHostMap::Get(
- int32 id) {
- auto it = map_.find(id);
- if (it != map_.end())
- return it->second;
- return nullptr;
-}
-
-void RenderFrameHostManager::RenderFrameProxyHostMap::Add(
- int32 id,
- scoped_ptr<RenderFrameProxyHost> proxy) {
- CHECK_EQ(0u, map_.count(id)) << "Inserting a duplicate item.";
-
- // If this is the first proxy that has this process host, observe the
- // process host.
- RenderProcessHost* host = proxy->GetProcess();
- size_t count =
- std::count_if(begin(), end(), [host](MapType::value_type item) {
- return item.second->GetProcess() == host;
- });
- if (count == 0)
- host->AddObserver(this);
-
- map_[id] = proxy.release();
-}
-
-void RenderFrameHostManager::RenderFrameProxyHostMap::Remove(int32 id) {
- auto it = map_.find(id);
- if (it == map_.end())
- return;
-
- // If this is the last proxy that has this process host, stop observing the
- // process host.
- RenderProcessHost* host = it->second->GetProcess();
- size_t count =
- std::count_if(begin(), end(), [host](MapType::value_type item) {
- return item.second->GetProcess() == host;
- });
- if (count == 1)
- host->RemoveObserver(this);
-
- delete it->second;
- map_.erase(it);
-}
-
-void RenderFrameHostManager::RenderFrameProxyHostMap::Clear() {
- std::set<RenderProcessHost*> hosts;
- for (const auto& pair : map_)
- hosts.insert(pair.second->GetProcess());
- for (auto host : hosts)
- host->RemoveObserver(this);
-
- STLDeleteValues(&map_);
-}
-
-void RenderFrameHostManager::RenderFrameProxyHostMap::RenderProcessWillExit(
- RenderProcessHost* host) {
- manager_->RendererProcessClosing(host);
-}
-
-void RenderFrameHostManager::RenderFrameProxyHostMap::RenderProcessExited(
- RenderProcessHost* host,
- base::TerminationStatus status,
- int exit_code) {
- manager_->RendererProcessClosing(host);
-}
-
// static
bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) {
node->render_manager()->pending_delete_hosts_.clear();
return true;
}
+// static
+bool RenderFrameHostManager::ClearWebUIInstances(FrameTreeNode* node) {
+ node->current_frame_host()->ClearAllWebUI();
+ if (node->render_manager()->pending_render_frame_host_)
+ node->render_manager()->pending_render_frame_host_->ClearAllWebUI();
+ // PlzNavigate
+ if (node->render_manager()->speculative_render_frame_host_)
+ node->render_manager()->speculative_render_frame_host_->ClearAllWebUI();
+ return true;
+}
+
RenderFrameHostManager::RenderFrameHostManager(
FrameTreeNode* frame_tree_node,
RenderFrameHostDelegate* render_frame_delegate,
@@ -218,25 +114,17 @@ RenderFrameHostManager::RenderFrameHostManager(
render_frame_delegate_(render_frame_delegate),
render_view_delegate_(render_view_delegate),
render_widget_delegate_(render_widget_delegate),
- proxy_hosts_(new RenderFrameProxyHostMap(this)),
interstitial_page_(nullptr),
- should_reuse_web_ui_(false),
weak_factory_(this) {
DCHECK(frame_tree_node_);
}
RenderFrameHostManager::~RenderFrameHostManager() {
- if (pending_render_frame_host_) {
- scoped_ptr<RenderFrameHostImpl> relic = UnsetPendingRenderFrameHost();
- ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get());
- }
-
- if (speculative_render_frame_host_) {
- scoped_ptr<RenderFrameHostImpl> relic = UnsetSpeculativeRenderFrameHost();
- ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get());
- }
+ if (pending_render_frame_host_)
+ UnsetPendingRenderFrameHost();
- ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host_.get());
+ if (speculative_render_frame_host_)
+ UnsetSpeculativeRenderFrameHost();
// Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts.
// It is important to delete those prior to deleting the current
@@ -245,25 +133,20 @@ RenderFrameHostManager::~RenderFrameHostManager() {
// the current RenderFrameHost and uses it during its destructor.
ResetProxyHosts();
- // Release the WebUI prior to resetting the current RenderFrameHost, as the
- // WebUI accesses the RenderFrameHost during cleanup.
- web_ui_.reset();
-
// We should always have a current RenderFrameHost except in some tests.
SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>());
}
-void RenderFrameHostManager::Init(BrowserContext* browser_context,
- SiteInstance* site_instance,
- int32 view_routing_id,
- int32 frame_routing_id,
- int32 widget_routing_id) {
- // Create a RenderViewHost and RenderFrameHost, once we have an instance. It
- // is important to immediately give this SiteInstance to a RenderViewHost so
- // that the SiteInstance is ref counted.
- if (!site_instance)
- site_instance = SiteInstance::Create(browser_context);
-
+void RenderFrameHostManager::Init(SiteInstance* site_instance,
+ int32_t view_routing_id,
+ int32_t frame_routing_id,
+ int32_t widget_routing_id) {
+ DCHECK(site_instance);
+ // TODO(avi): While RenderViewHostImpl is-a RenderWidgetHostImpl, this must
+ // hold true to avoid having two RenderWidgetHosts for the top-level frame.
+ // https://crbug.com/545684
+ DCHECK(!frame_tree_node_->IsMainFrame() ||
+ view_routing_id == widget_routing_id);
int flags = delegate_->IsHidden() ? CREATE_RF_HIDDEN : 0;
SetRenderFrameHost(CreateRenderFrameHost(site_instance, view_routing_id,
frame_routing_id, widget_routing_id,
@@ -290,6 +173,17 @@ RenderViewHostImpl* RenderFrameHostManager::pending_render_view_host() const {
return pending_render_frame_host_->render_view_host();
}
+WebUIImpl* RenderFrameHostManager::GetNavigatingWebUI() const {
+ if (IsBrowserSideNavigationEnabled()) {
+ if (speculative_render_frame_host_)
+ return speculative_render_frame_host_->web_ui();
+ } else {
+ if (pending_render_frame_host_)
+ return pending_render_frame_host_->web_ui();
+ }
+ return render_frame_host_->pending_web_ui();
+}
+
RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const {
if (interstitial_page_)
return interstitial_page_->GetView();
@@ -299,8 +193,8 @@ RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const {
}
bool RenderFrameHostManager::ForInnerDelegate() {
- return delegate_->GetOuterDelegateFrameTreeNodeID() !=
- FrameTreeNode::kFrameTreeNodeInvalidID;
+ return delegate_->GetOuterDelegateFrameTreeNodeId() !=
+ FrameTreeNode::kFrameTreeNodeInvalidId;
}
RenderWidgetHostImpl*
@@ -310,26 +204,32 @@ RenderFrameHostManager::GetOuterRenderWidgetHostForKeyboardInput() {
FrameTreeNode* outer_contents_frame_tree_node =
FrameTreeNode::GloballyFindByID(
- delegate_->GetOuterDelegateFrameTreeNodeID());
+ delegate_->GetOuterDelegateFrameTreeNodeId());
return outer_contents_frame_tree_node->parent()
->current_frame_host()
- ->render_view_host();
+ ->render_view_host()
+ ->GetWidget();
+}
+
+FrameTreeNode* RenderFrameHostManager::GetOuterDelegateNode() {
+ int outer_contents_frame_tree_node_id =
+ delegate_->GetOuterDelegateFrameTreeNodeId();
+ return FrameTreeNode::GloballyFindByID(outer_contents_frame_tree_node_id);
}
RenderFrameProxyHost* RenderFrameHostManager::GetProxyToParent() {
if (frame_tree_node_->IsMainFrame())
return nullptr;
- return proxy_hosts_->Get(frame_tree_node_->parent()
- ->render_manager()
- ->current_frame_host()
- ->GetSiteInstance()
- ->GetId());
+ return GetRenderFrameProxyHost(frame_tree_node_->parent()
+ ->render_manager()
+ ->current_frame_host()
+ ->GetSiteInstance());
}
RenderFrameProxyHost* RenderFrameHostManager::GetProxyToOuterDelegate() {
int outer_contents_frame_tree_node_id =
- delegate_->GetOuterDelegateFrameTreeNodeID();
+ delegate_->GetOuterDelegateFrameTreeNodeId();
FrameTreeNode* outer_contents_frame_tree_node =
FrameTreeNode::GloballyFindByID(outer_contents_frame_tree_node_id);
if (!outer_contents_frame_tree_node ||
@@ -345,33 +245,12 @@ RenderFrameProxyHost* RenderFrameHostManager::GetProxyToOuterDelegate() {
void RenderFrameHostManager::RemoveOuterDelegateFrame() {
FrameTreeNode* outer_delegate_frame_tree_node =
FrameTreeNode::GloballyFindByID(
- delegate_->GetOuterDelegateFrameTreeNodeID());
+ delegate_->GetOuterDelegateFrameTreeNodeId());
DCHECK(outer_delegate_frame_tree_node->parent());
outer_delegate_frame_tree_node->frame_tree()->RemoveFrame(
outer_delegate_frame_tree_node);
}
-void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) {
- pending_web_ui_ = CreateWebUI(url, bindings);
- pending_and_current_web_ui_.reset();
-}
-
-scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url,
- int bindings) {
- scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url));
-
- // If we have assigned (zero or more) bindings to this NavigationEntry in the
- // past, make sure we're not granting it different bindings than it had
- // before. If so, note it and don't give it any bindings, to avoid a
- // potential privilege escalation.
- if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings &&
- new_web_ui->GetBindings() != bindings) {
- RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
- return nullptr;
- }
- return new_web_ui.Pass();
-}
-
RenderFrameHostImpl* RenderFrameHostManager::Navigate(
const GURL& dest_url,
const FrameNavigationEntry& frame_entry,
@@ -393,7 +272,7 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
// If the current render_frame_host_ isn't live, we should create it so
// that we don't show a sad tab while the dest_render_frame_host fetches
// its first page. (Bug 1145340)
- if (dest_render_frame_host != render_frame_host_ &&
+ if (dest_render_frame_host != render_frame_host_.get() &&
!render_frame_host_->IsRenderFrameLive()) {
// Note: we don't call InitRenderView here because we are navigating away
// soon anyway, and we don't have the NavigationEntry for this host.
@@ -417,14 +296,20 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
// Recreate the opener chain.
CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(),
frame_tree_node_);
- if (!InitRenderView(dest_render_frame_host->render_view_host(),
- MSG_ROUTING_NONE))
+ if (!InitRenderView(dest_render_frame_host->render_view_host(), nullptr))
return nullptr;
+ if (GetNavigatingWebUI()) {
+ // A new RenderView was created and there is a navigating WebUI which
+ // never interacted with it. So notify the WebUI using RenderViewCreated.
+ GetNavigatingWebUI()->RenderViewCreated(
+ dest_render_frame_host->render_view_host());
+ }
+
// Now that we've created a new renderer, be sure to hide it if it isn't
// our primary one. Otherwise, we might crash if we try to call Show()
// on it later.
- if (dest_render_frame_host != render_frame_host_) {
+ if (dest_render_frame_host != render_frame_host_.get()) {
if (dest_render_frame_host->GetView())
dest_render_frame_host->GetView()->Hide();
} else {
@@ -432,8 +317,9 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
// need to set the visibility of the new View to the correct value here
// after reload.
if (dest_render_frame_host->GetView() &&
- dest_render_frame_host->render_view_host()->is_hidden() !=
- delegate_->IsHidden()) {
+ dest_render_frame_host->render_view_host()
+ ->GetWidget()
+ ->is_hidden() != delegate_->IsHidden()) {
if (delegate_->IsHidden()) {
dest_render_frame_host->GetView()->Hide();
} else {
@@ -464,7 +350,7 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
// NavigationHandle that came from the transferring RenderFrameHost.
DCHECK(transfer_navigation_handle_);
dest_render_frame_host->SetNavigationHandle(
- transfer_navigation_handle_.Pass());
+ std::move(transfer_navigation_handle_));
}
DCHECK(!transfer_navigation_handle_);
@@ -483,8 +369,7 @@ void RenderFrameHostManager::Stop() {
}
// PlzNavigate: a loading speculative RenderFrameHost should also stop.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
if (speculative_render_frame_host_ &&
speculative_render_frame_host_->is_loading()) {
speculative_render_frame_host_->Send(
@@ -494,9 +379,11 @@ void RenderFrameHostManager::Stop() {
}
void RenderFrameHostManager::SetIsLoading(bool is_loading) {
- render_frame_host_->render_view_host()->SetIsLoading(is_loading);
- if (pending_render_frame_host_)
- pending_render_frame_host_->render_view_host()->SetIsLoading(is_loading);
+ render_frame_host_->render_view_host()->GetWidget()->SetIsLoading(is_loading);
+ if (pending_render_frame_host_) {
+ pending_render_frame_host_->render_view_host()->GetWidget()->SetIsLoading(
+ is_loading);
+ }
}
bool RenderFrameHostManager::ShouldCloseTabOnUnresponsiveRenderer() {
@@ -540,8 +427,7 @@ void RenderFrameHostManager::OnBeforeUnloadACK(
bool proceed,
const base::TimeTicks& proceed_time) {
if (for_cross_site_transition) {
- DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ DCHECK(!IsBrowserSideNavigationEnabled());
// Ignore if we're not in a cross-process navigation.
if (!pending_render_frame_host_)
return;
@@ -576,11 +462,8 @@ void RenderFrameHostManager::OnBeforeUnloadACK(
}
// PlzNavigate: clean up the speculative RenderFrameHost if there is one.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
- speculative_render_frame_host_) {
+ if (IsBrowserSideNavigationEnabled() && speculative_render_frame_host_)
CleanUpNavigation();
- }
// This is not a cross-process navigation; the tab is being closed.
render_frame_host_->render_view_host()->ClosePage();
@@ -605,12 +488,12 @@ void RenderFrameHostManager::OnCrossSiteResponse(
// TODO(creis): We need to handle the case that the pending RFH has changed
// in the mean time, while this was being posted from the IO thread. We
// should probably cancel the request in that case.
- DCHECK(pending_render_frame_host == pending_render_frame_host_ ||
- pending_render_frame_host == render_frame_host_);
+ DCHECK(pending_render_frame_host == pending_render_frame_host_.get() ||
+ pending_render_frame_host == render_frame_host_.get());
// Store the transferring request so that we can release it if the transfer
// navigation matches.
- cross_site_transferring_request_ = cross_site_transferring_request.Pass();
+ cross_site_transferring_request_ = std::move(cross_site_transferring_request);
// Store the NavigationHandle to give it to the appropriate RenderFrameHost
// after it started navigating.
@@ -639,13 +522,9 @@ void RenderFrameHostManager::OnCrossSiteResponse(
std::vector<GURL> rest_of_chain = transfer_url_chain;
rest_of_chain.pop_back();
- // We don't know whether the original request had |user_action| set to true.
- // However, since we force the navigation to be in the current tab, it
- // doesn't matter.
pending_render_frame_host->frame_tree_node()->navigator()->RequestTransferURL(
- pending_render_frame_host, transfer_url, nullptr, rest_of_chain, referrer,
- page_transition, CURRENT_TAB, global_request_id,
- should_replace_current_entry, true);
+ pending_render_frame_host, transfer_url, rest_of_chain, referrer,
+ page_transition, global_request_id, should_replace_current_entry);
// The transferring request was only needed during the RequestTransferURL
// call, so it is safe to clear at this point.
@@ -670,24 +549,38 @@ void RenderFrameHostManager::CommitPendingIfNecessary(
RenderFrameHostImpl* render_frame_host,
bool was_caused_by_user_gesture) {
if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
- DCHECK_IMPLIES(should_reuse_web_ui_, web_ui_);
+ // There's no pending/speculative RenderFrameHost so it must be that the
+ // current renderer process completed a navigation.
// We should only hear this from our current renderer.
- DCHECK_EQ(render_frame_host_, render_frame_host);
-
- // Even when there is no pending RVH, there may be a pending Web UI.
- if (pending_web_ui() || speculative_web_ui_)
- CommitPending();
+ DCHECK_EQ(render_frame_host_.get(), render_frame_host);
+
+ // If the current RenderFrameHost has a pending WebUI it must be committed.
+ // Note: When one tries to move same-site commit logic into RenderFrameHost
+ // itself, mind that the focus setting logic inside CommitPending also needs
+ // to be moved there.
+ if (render_frame_host_->pending_web_ui())
+ CommitPendingWebUI();
return;
}
- if (render_frame_host == pending_render_frame_host_ ||
- render_frame_host == speculative_render_frame_host_) {
- // The pending cross-process navigation completed, so show the renderer.
+ if (render_frame_host == pending_render_frame_host_.get() ||
+ render_frame_host == speculative_render_frame_host_.get()) {
+ // A cross-process navigation completed, so show the new renderer. If a
+ // same-process navigation is also ongoing, it will be canceled when the
+ // pending/speculative RenderFrameHost replaces the current one in the
+ // commit call below.
CommitPending();
- } else if (render_frame_host == render_frame_host_) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ } else if (render_frame_host == render_frame_host_.get()) {
+ // A same-process navigation committed while a simultaneous cross-process
+ // navigation is still ongoing.
+
+ // If the current RenderFrameHost has a pending WebUI it must be committed.
+ if (render_frame_host_->pending_web_ui())
+ CommitPendingWebUI();
+
+ // Decide on canceling the ongoing cross-process navigation.
+ if (IsBrowserSideNavigationEnabled()) {
CleanUpNavigation();
} else {
if (was_caused_by_user_gesture) {
@@ -700,7 +593,7 @@ void RenderFrameHostManager::CommitPendingIfNecessary(
}
} else {
// No one else should be sending us DidNavigate in this state.
- DCHECK(false);
+ NOTREACHED();
}
}
@@ -722,7 +615,7 @@ void RenderFrameHostManager::DidChangeOpener(
frame_tree_node_->SetOpener(opener);
- for (const auto& pair : *proxy_hosts_) {
+ for (const auto& pair : proxy_hosts_) {
if (pair.second->GetSiteInstance() == source_site_instance)
continue;
pair.second->UpdateOpener();
@@ -758,7 +651,7 @@ void RenderFrameHostManager::CommitPendingSandboxFlags() {
// the parent process since it already knows the latest flags.
SiteInstance* parent_site_instance =
frame_tree_node_->parent()->current_frame_host()->GetSiteInstance();
- for (const auto& pair : *proxy_hosts_) {
+ for (const auto& pair : proxy_hosts_) {
if (pair.second->GetSiteInstance() != parent_site_instance) {
pair.second->Send(new FrameMsg_DidUpdateSandboxFlags(
pair.second->GetRoutingID(),
@@ -767,43 +660,6 @@ void RenderFrameHostManager::CommitPendingSandboxFlags() {
}
}
-void RenderFrameHostManager::RendererProcessClosing(
- RenderProcessHost* render_process_host) {
- // Remove any swapped out RVHs from this process, so that we don't try to
- // swap them back in while the process is exiting. Start by finding them,
- // since there could be more than one.
- std::list<int> ids_to_remove;
- // Do not remove proxies in the dead process that still have active frame
- // count though, we just reset them to be uninitialized.
- std::list<int> ids_to_keep;
- for (const auto& pair : *proxy_hosts_) {
- RenderFrameProxyHost* proxy = pair.second;
- if (proxy->GetProcess() != render_process_host)
- continue;
-
- if (static_cast<SiteInstanceImpl*>(proxy->GetSiteInstance())
- ->active_frame_count() >= 1U) {
- ids_to_keep.push_back(pair.first);
- } else {
- ids_to_remove.push_back(pair.first);
- }
- }
-
- // Now delete them.
- while (!ids_to_remove.empty()) {
- proxy_hosts_->Remove(ids_to_remove.back());
- ids_to_remove.pop_back();
- }
-
- while (!ids_to_keep.empty()) {
- frame_tree_node_->frame_tree()->ForEach(
- base::Bind(
- &RenderFrameHostManager::ResetProxiesInSiteInstance,
- ids_to_keep.back()));
- ids_to_keep.pop_back();
- }
-}
-
void RenderFrameHostManager::SwapOutOldFrame(
scoped_ptr<RenderFrameHostImpl> old_render_frame_host) {
TRACE_EVENT1("navigation", "RenderFrameHostManager::SwapOutOldFrame",
@@ -822,35 +678,24 @@ void RenderFrameHostManager::SwapOutOldFrame(
// If the old RFH is not live, just return as there is no further work to do.
// It will be deleted and there will be no proxy created.
- int32 old_site_instance_id =
- old_render_frame_host->GetSiteInstance()->GetId();
- if (!old_render_frame_host->IsRenderFrameLive()) {
- ShutdownProxiesIfLastActiveFrameInSiteInstance(old_render_frame_host.get());
+ if (!old_render_frame_host->IsRenderFrameLive())
return;
- }
// If there are no active frames besides this one, we can delete the old
// RenderFrameHost once it runs its unload handler, without replacing it with
// a proxy.
- size_t active_frame_count =
- old_render_frame_host->GetSiteInstance()->active_frame_count();
- if (active_frame_count <= 1) {
- // Clear out any proxies from this SiteInstance, in case this was the
- // last one keeping other proxies alive.
- ShutdownProxiesIfLastActiveFrameInSiteInstance(old_render_frame_host.get());
-
+ if (old_render_frame_host->GetSiteInstance()->active_frame_count() <= 1) {
// Tell the old RenderFrameHost to swap out, with no proxy to replace it.
old_render_frame_host->SwapOut(nullptr, true);
- MoveToPendingDeleteHosts(old_render_frame_host.Pass());
+ MoveToPendingDeleteHosts(std::move(old_render_frame_host));
return;
}
// Otherwise there are active views and we need a proxy for the old RFH.
// (There should not be one yet.)
- RenderFrameProxyHost* proxy = new RenderFrameProxyHost(
- old_render_frame_host->GetSiteInstance(),
- old_render_frame_host->render_view_host(), frame_tree_node_);
- proxy_hosts_->Add(old_site_instance_id, make_scoped_ptr(proxy));
+ RenderFrameProxyHost* proxy =
+ CreateRenderFrameProxyHost(old_render_frame_host->GetSiteInstance(),
+ old_render_frame_host->render_view_host());
// Tell the old RenderFrameHost to swap out and be replaced by the proxy.
old_render_frame_host->SwapOut(proxy, true);
@@ -862,7 +707,7 @@ void RenderFrameHostManager::SwapOutOldFrame(
// In --site-per-process, frames delete their RFH rather than storing it
// in the proxy. Schedule it for deletion once the SwapOutACK comes in.
// TODO(creis): This will be the default when we remove swappedout://.
- MoveToPendingDeleteHosts(old_render_frame_host.Pass());
+ MoveToPendingDeleteHosts(std::move(old_render_frame_host));
} else {
// We shouldn't get here for subframes, since we only swap subframes when
// --site-per-process is used.
@@ -870,7 +715,7 @@ void RenderFrameHostManager::SwapOutOldFrame(
// The old RenderFrameHost will stay alive inside the proxy so that existing
// JavaScript window references to it stay valid.
- proxy->TakeFrameHostOwnership(old_render_frame_host.Pass());
+ proxy->TakeFrameHostOwnership(std::move(old_render_frame_host));
}
}
@@ -888,26 +733,33 @@ void RenderFrameHostManager::DiscardUnusedFrame(
// Any currently suspended navigations are no longer needed.
render_frame_host->CancelSuspendedNavigations();
- RenderFrameProxyHost* proxy = new RenderFrameProxyHost(
- site_instance, render_frame_host->render_view_host(), frame_tree_node_);
- proxy_hosts_->Add(site_instance->GetId(), make_scoped_ptr(proxy));
-
- // Check if the RenderFrameHost is already swapped out, to avoid swapping it
- // out again.
- if (!render_frame_host->is_swapped_out())
- render_frame_host->SwapOut(proxy, false);
+ // If a proxy already exists for the |site_instance|, just reuse it instead
+ // of creating a new one. There is no need to call SwapOut on the
+ // |render_frame_host|, as this method is only called to discard a pending
+ // or speculative RenderFrameHost, i.e. one that has never hosted an actual
+ // document.
+ RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance);
+ if (!proxy) {
+ proxy = CreateRenderFrameProxyHost(site_instance,
+ render_frame_host->render_view_host());
+ }
if (!SiteIsolationPolicy::IsSwappedOutStateForbidden()) {
DCHECK(frame_tree_node_->IsMainFrame());
- proxy->TakeFrameHostOwnership(render_frame_host.Pass());
+
+ // When using swapped out RenderFrameHosts, it is possible for the pending
+ // RenderFrameHost to be an existing one in swapped out state. Since it
+ // has been used to start a navigation, it could have committed a
+ // document. Check if |render_frame_host| is already swapped out, to avoid
+ // swapping it out again.
+ if (!render_frame_host->is_swapped_out())
+ render_frame_host->SwapOut(proxy, false);
+
+ proxy->TakeFrameHostOwnership(std::move(render_frame_host));
}
}
- if (render_frame_host) {
- // We won't be coming back, so delete this one.
- ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host.get());
- render_frame_host.reset();
- }
+ render_frame_host.reset();
}
void RenderFrameHostManager::MoveToPendingDeleteHosts(
@@ -950,14 +802,17 @@ bool RenderFrameHostManager::DeleteFromPendingList(
}
void RenderFrameHostManager::ResetProxyHosts() {
- proxy_hosts_->Clear();
+ for (auto& pair : proxy_hosts_) {
+ static_cast<SiteInstanceImpl*>(pair.second->GetSiteInstance())
+ ->RemoveObserver(this);
+ }
+ proxy_hosts_.clear();
}
// PlzNavigate
void RenderFrameHostManager::DidCreateNavigationRequest(
const NavigationRequest& request) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
// Clean up any state in case there's an ongoing navigation.
// TODO(carlosk): remove this cleanup here once we properly cancel ongoing
// navigations.
@@ -970,8 +825,7 @@ void RenderFrameHostManager::DidCreateNavigationRequest(
// PlzNavigate
RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
const NavigationRequest& request) {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
@@ -1002,45 +856,57 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
// if needed when it no longer breaks OAuth popups (see
// https://crbug.com/440266).
bool is_main_frame = frame_tree_node_->IsMainFrame();
+ bool notify_webui_of_rv_creation = false;
if (current_site_instance == dest_site_instance.get() ||
(!request.browser_initiated() && is_main_frame) ||
(!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() &&
!current_site_instance->RequiresDedicatedProcess())) {
- // Reuse the current RFH if its SiteInstance matches the the navigation's
- // or if this is a subframe navigation. We only swap RFHs for subframes when
- // --site-per-process is enabled.
- CleanUpNavigation();
+ // Reuse the current RenderFrameHost if its SiteInstance matches the
+ // navigation's or if this is a subframe navigation. We only swap
+ // RenderFrameHosts for subframes when --site-per-process is enabled.
+
+ // GetFrameHostForNavigation will be called more than once during a
+ // navigation (currently twice, on request and when it's about to commit in
+ // the renderer). In the follow up calls an existing pending WebUI should
+ // not be recreated if the URL didn't change. So instead of calling
+ // CleanUpNavigation just discard the speculative RenderFrameHost if one
+ // exists.
+ if (speculative_render_frame_host_)
+ DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
+
+ UpdatePendingWebUIOnCurrentFrameHost(request.common_params().url,
+ request.bindings());
+
navigation_rfh = render_frame_host_.get();
- // As SiteInstances are the same, check if the WebUI should be reused.
- const NavigationEntry* current_navigation_entry =
- delegate_->GetLastCommittedNavigationEntryForRenderManager();
- should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry,
- request.common_params().url);
- if (!should_reuse_web_ui_) {
- speculative_web_ui_ = CreateWebUI(request.common_params().url,
- request.bindings());
- // Make sure the current RenderViewHost has the right bindings.
- if (speculative_web_ui() &&
- !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
- render_frame_host_->render_view_host()->AllowBindings(
- speculative_web_ui()->GetBindings());
- }
- }
+ DCHECK(!speculative_render_frame_host_);
} else {
- // If the SiteInstance for the final URL doesn't match the one from the
- // speculatively created RenderFrameHost, create a new RenderFrameHost using
- // this new SiteInstance.
+ // If the current RenderFrameHost cannot be used a speculative one is
+ // created with the SiteInstance for the current URL. If a speculative
+ // RenderFrameHost already exists we try as much as possible to reuse it and
+ // its associated WebUI.
+
+ // Check if an existing speculative RenderFrameHost can be reused.
if (!speculative_render_frame_host_ ||
speculative_render_frame_host_->GetSiteInstance() !=
dest_site_instance.get()) {
+ // If a previous speculative RenderFrameHost didn't exist or if its
+ // SiteInstance differs from the one for the current URL, a new one needs
+ // to be created.
CleanUpNavigation();
- bool success = CreateSpeculativeRenderFrameHost(
- request.common_params().url, current_site_instance,
- dest_site_instance.get(), request.bindings());
+ bool success = CreateSpeculativeRenderFrameHost(current_site_instance,
+ dest_site_instance.get());
DCHECK(success);
}
DCHECK(speculative_render_frame_host_);
+
+ bool changed_web_ui = speculative_render_frame_host_->UpdatePendingWebUI(
+ request.common_params().url, request.bindings());
+ speculative_render_frame_host_->CommitPendingWebUI();
+ DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui());
+ notify_webui_of_rv_creation =
+ changed_web_ui && speculative_render_frame_host_->web_ui();
+
navigation_rfh = speculative_render_frame_host_.get();
// Check if our current RFH is live.
@@ -1062,11 +928,11 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
if (!navigation_rfh->IsRenderFrameLive()) {
// Recreate the opener chain.
CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_);
- if (!InitRenderView(navigation_rfh->render_view_host(), MSG_ROUTING_NONE)) {
+ if (!InitRenderView(navigation_rfh->render_view_host(), nullptr))
return nullptr;
- }
+ notify_webui_of_rv_creation = true;
- if (navigation_rfh == render_frame_host_) {
+ if (navigation_rfh == render_frame_host_.get()) {
// TODO(nasko): This is a very ugly hack. The Chrome extensions process
// manager still uses NotificationService and expects to see a
// RenderViewHost changed notification after WebContents and
@@ -1076,17 +942,22 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
delegate_->NotifyMainFrameSwappedFromRenderManager(
nullptr, render_frame_host_->render_view_host());
}
+ DCHECK(navigation_rfh->IsRenderFrameLive());
}
+ // If a WebUI was created in a speculative RenderFrameHost or a new RenderView
+ // was created then the WebUI never interacted with the RenderView. Notify
+ // using RenderViewCreated.
+ if (notify_webui_of_rv_creation && GetNavigatingWebUI())
+ GetNavigatingWebUI()->RenderViewCreated(navigation_rfh->render_view_host());
+
return navigation_rfh;
}
// PlzNavigate
void RenderFrameHostManager::CleanUpNavigation() {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
- speculative_web_ui_.reset();
- should_reuse_web_ui_ = false;
+ CHECK(IsBrowserSideNavigationEnabled());
+ render_frame_host_->ClearPendingWebUI();
if (speculative_render_frame_host_)
DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
}
@@ -1094,21 +965,20 @@ void RenderFrameHostManager::CleanUpNavigation() {
// PlzNavigate
scoped_ptr<RenderFrameHostImpl>
RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() {
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
speculative_render_frame_host_->GetProcess()->RemovePendingView();
- return speculative_render_frame_host_.Pass();
+ return std::move(speculative_render_frame_host_);
}
void RenderFrameHostManager::OnDidStartLoading() {
- for (const auto& pair : *proxy_hosts_) {
+ for (const auto& pair : proxy_hosts_) {
pair.second->Send(
new FrameMsg_DidStartLoading(pair.second->GetRoutingID()));
}
}
void RenderFrameHostManager::OnDidStopLoading() {
- for (const auto& pair : *proxy_hosts_) {
+ for (const auto& pair : proxy_hosts_) {
pair.second->Send(new FrameMsg_DidStopLoading(pair.second->GetRoutingID()));
}
}
@@ -1122,17 +992,28 @@ void RenderFrameHostManager::OnDidUpdateName(const std::string& name) {
if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
return;
- for (const auto& pair : *proxy_hosts_) {
+ for (const auto& pair : proxy_hosts_) {
pair.second->Send(
new FrameMsg_DidUpdateName(pair.second->GetRoutingID(), name));
}
}
+void RenderFrameHostManager::OnEnforceStrictMixedContentChecking(
+ bool should_enforce) {
+ if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
+ return;
+
+ for (const auto& pair : proxy_hosts_) {
+ pair.second->Send(new FrameMsg_EnforceStrictMixedContentChecking(
+ pair.second->GetRoutingID(), should_enforce));
+ }
+}
+
void RenderFrameHostManager::OnDidUpdateOrigin(const url::Origin& origin) {
if (!SiteIsolationPolicy::IsSwappedOutStateForbidden())
return;
- for (const auto& pair : *proxy_hosts_) {
+ for (const auto& pair : proxy_hosts_) {
pair.second->Send(
new FrameMsg_DidUpdateOrigin(pair.second->GetRoutingID(), origin));
}
@@ -1147,40 +1028,47 @@ RenderFrameHostManager::SiteInstanceDescriptor::SiteInstanceDescriptor(
new_site_url = SiteInstance::GetSiteForURL(browser_context, dest_url);
}
-// static
-bool RenderFrameHostManager::ClearProxiesInSiteInstance(
- int32 site_instance_id,
- FrameTreeNode* node) {
- RenderFrameProxyHost* proxy =
- node->render_manager()->proxy_hosts_->Get(site_instance_id);
- if (proxy) {
- // Delete the proxy. If it is for a main frame (and thus the RFH is stored
- // in the proxy) and it was still pending swap out, move the RFH to the
- // pending deletion list first.
- if (node->IsMainFrame() &&
- proxy->render_frame_host() &&
- proxy->render_frame_host()->rfh_state() ==
- RenderFrameHostImpl::STATE_PENDING_SWAP_OUT) {
- DCHECK(!SiteIsolationPolicy::IsSwappedOutStateForbidden());
- scoped_ptr<RenderFrameHostImpl> swapped_out_rfh =
- proxy->PassFrameHostOwnership();
- node->render_manager()->MoveToPendingDeleteHosts(swapped_out_rfh.Pass());
- }
- node->render_manager()->proxy_hosts_->Remove(site_instance_id);
+void RenderFrameHostManager::RenderProcessGone(SiteInstanceImpl* instance) {
+ GetRenderFrameProxyHost(instance)->set_render_frame_proxy_created(false);
+}
+
+void RenderFrameHostManager::ActiveFrameCountIsZero(
+ SiteInstanceImpl* site_instance) {
+ // |site_instance| no longer contains any active RenderFrameHosts, so we don't
+ // need to maintain a proxy there anymore.
+ RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance);
+ CHECK(proxy);
+
+ // Delete the proxy. If it is for a main frame (and the RFH is stored
+ // in the proxy) and it was still pending swap out, move the RFH to the
+ // pending deletion list first.
+ if (frame_tree_node_->IsMainFrame() && proxy->render_frame_host() &&
+ proxy->render_frame_host()->rfh_state() ==
+ RenderFrameHostImpl::STATE_PENDING_SWAP_OUT) {
+ DCHECK(!SiteIsolationPolicy::IsSwappedOutStateForbidden());
+ scoped_ptr<RenderFrameHostImpl> swapped_out_rfh =
+ proxy->PassFrameHostOwnership();
+ MoveToPendingDeleteHosts(std::move(swapped_out_rfh));
}
- return true;
+ DeleteRenderFrameProxyHost(site_instance);
}
-// static.
-bool RenderFrameHostManager::ResetProxiesInSiteInstance(int32 site_instance_id,
- FrameTreeNode* node) {
- RenderFrameProxyHost* proxy =
- node->render_manager()->proxy_hosts_->Get(site_instance_id);
- if (proxy)
- proxy->set_render_frame_proxy_created(false);
+RenderFrameProxyHost* RenderFrameHostManager::CreateRenderFrameProxyHost(
+ SiteInstance* site_instance,
+ RenderViewHostImpl* rvh) {
+ auto result = proxy_hosts_.add(site_instance->GetId(),
+ make_scoped_ptr(new RenderFrameProxyHost(
+ site_instance, rvh, frame_tree_node_)));
+ CHECK(result.second) << "A proxy already existed for this SiteInstance.";
+ static_cast<SiteInstanceImpl*>(site_instance)->AddObserver(this);
+ return result.first->second;
+}
- return true;
+void RenderFrameHostManager::DeleteRenderFrameProxyHost(
+ SiteInstance* site_instance) {
+ static_cast<SiteInstanceImpl*>(site_instance)->RemoveObserver(this);
+ proxy_hosts_.erase(site_instance->GetId());
}
bool RenderFrameHostManager::ShouldTransitionCrossSite() {
@@ -1213,6 +1101,12 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
SiteInstance* new_site_instance,
const GURL& new_effective_url,
bool new_is_view_source_mode) const {
+ // A subframe must stay in the same BrowsingInstance as its parent.
+ // TODO(nasko): Ensure that SiteInstance swap is still triggered for subframes
+ // in the cases covered by the rest of the checks in this method.
+ if (!frame_tree_node_->IsMainFrame())
+ return false;
+
// If new_entry already has a SiteInstance, assume it is correct. We only
// need to force a swap if it is in a different BrowsingInstance.
if (new_site_instance) {
@@ -1232,7 +1126,7 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
return false;
// For security, we should transition between processes when one is a Web UI
- // page and one isn't.
+ // page and one isn't, or if the WebUI types differ.
if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
render_frame_host_->GetProcess()->GetID()) ||
WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
@@ -1243,6 +1137,15 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
browser_context, new_effective_url)) {
return true;
}
+
+ // Force swap if the current WebUI type differs from the one for the
+ // destination.
+ if (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
+ browser_context, current_effective_url) !=
+ WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
+ browser_context, new_effective_url)) {
+ return true;
+ }
} else {
// Force a swap if it's a Web UI URL.
if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
@@ -1270,18 +1173,6 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
return false;
}
-bool RenderFrameHostManager::ShouldReuseWebUI(
- const NavigationEntry* current_entry,
- const GURL& new_url) const {
- NavigationControllerImpl& controller =
- delegate_->GetControllerForRenderManager();
- return current_entry && web_ui_ &&
- (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
- controller.GetBrowserContext(), current_entry->GetURL()) ==
- WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
- controller.GetBrowserContext(), new_url));
-}
-
SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
const GURL& dest_url,
SiteInstance* source_instance,
@@ -1507,6 +1398,45 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
return SiteInstanceDescriptor(browser_context, dest_url, true);
}
+bool RenderFrameHostManager::IsRendererTransferNeededForNavigation(
+ RenderFrameHostImpl* rfh,
+ const GURL& dest_url) {
+ // A transfer is not needed if the current SiteInstance doesn't yet have a
+ // site. This is the case for tests that use NavigateToURL.
+ if (!rfh->GetSiteInstance()->HasSite())
+ return false;
+
+ // We do not currently swap processes for navigations in webview tag guests.
+ if (rfh->GetSiteInstance()->GetSiteURL().SchemeIs(kGuestScheme))
+ return false;
+
+ // Don't swap processes for extensions embedded in DevTools. See
+ // https://crbug.com/564216.
+ if (rfh->GetSiteInstance()->GetSiteURL().SchemeIs(kChromeDevToolsScheme)) {
+ // TODO(nick): https://crbug.com/570483 Check to see if |dest_url| is a
+ // devtools extension, and swap processes if not.
+ return false;
+ }
+
+ BrowserContext* context = rfh->GetSiteInstance()->GetBrowserContext();
+ GURL effective_url = SiteInstanceImpl::GetEffectiveURL(context, dest_url);
+
+ // TODO(nasko, nick): These following --site-per-process checks are
+ // overly simplistic. Update them to match all the cases
+ // considered by DetermineSiteInstanceForURL.
+ if (SiteInstance::IsSameWebSite(rfh->GetSiteInstance()->GetBrowserContext(),
+ rfh->GetSiteInstance()->GetSiteURL(),
+ dest_url)) {
+ return false; // The same site, no transition needed.
+ }
+
+ // The sites differ. If either one requires a dedicated process,
+ // then a transfer is needed.
+ return rfh->GetSiteInstance()->RequiresDedicatedProcess() ||
+ SiteInstanceImpl::DoesSiteRequireDedicatedProcess(context,
+ effective_url);
+}
+
SiteInstance* RenderFrameHostManager::ConvertToSiteInstance(
const SiteInstanceDescriptor& descriptor,
SiteInstance* candidate_instance) {
@@ -1583,8 +1513,8 @@ void RenderFrameHostManager::CreatePendingRenderFrameHost(
CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
// Create a non-swapped-out RFH with the given opener.
- pending_render_frame_host_ = CreateRenderFrame(
- new_instance, pending_web_ui(), create_render_frame_flags, nullptr);
+ pending_render_frame_host_ =
+ CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
}
void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
@@ -1637,9 +1567,9 @@ void RenderFrameHostManager::CreateProxiesForNewNamedFrame() {
scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
SiteInstance* site_instance,
- int32 view_routing_id,
- int32 frame_routing_id,
- int32 widget_routing_id,
+ int32_t view_routing_id,
+ int32_t frame_routing_id,
+ int32_t widget_routing_id,
int flags) {
if (frame_routing_id == MSG_ROUTING_NONE)
frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
@@ -1653,6 +1583,20 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
if (frame_tree_node_->IsMainFrame()) {
render_view_host = frame_tree->CreateRenderViewHost(
site_instance, view_routing_id, frame_routing_id, swapped_out, hidden);
+ // TODO(avi): It's a bit bizarre that this logic lives here instead of in
+ // CreateRenderFrame(). It turns out that FrameTree::CreateRenderViewHost
+ // doesn't /always/ create a new RenderViewHost. It first tries to find an
+ // already existing one to reuse by a SiteInstance lookup. If it finds one,
+ // then the supplied routing IDs are completely ignored.
+ // CreateRenderFrame() could do this lookup too, but it seems redundant to
+ // do this lookup in two places. This is a good yak shave to clean up, or,
+ // if just ignored, should be an easy cleanup once RenderViewHostImpl has-a
+ // RenderWidgetHostImpl. https://crbug.com/545684
+ if (view_routing_id == MSG_ROUTING_NONE) {
+ widget_routing_id = render_view_host->GetRoutingID();
+ } else {
+ DCHECK_EQ(view_routing_id, render_view_host->GetRoutingID());
+ }
} else {
render_view_host = frame_tree->GetRenderViewHost(site_instance);
CHECK(render_view_host);
@@ -1666,18 +1610,10 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
// PlzNavigate
bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
- const GURL& url,
SiteInstance* old_instance,
- SiteInstance* new_instance,
- int bindings) {
+ SiteInstance* new_instance) {
CHECK(new_instance);
CHECK_NE(old_instance, new_instance);
- CHECK(!should_reuse_web_ui_);
-
- // Note: |speculative_web_ui_| must be initialized before starting the
- // |speculative_render_frame_host_| creation steps otherwise the WebUI
- // won't be properly initialized.
- speculative_web_ui_ = CreateWebUI(url, bindings);
// The process for the new SiteInstance may (if we're sharing a process with
// another host that already initialized it) or may not (we have our own
@@ -1692,19 +1628,13 @@ bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
if (delegate_->IsHidden())
create_render_frame_flags |= CREATE_RF_HIDDEN;
speculative_render_frame_host_ =
- CreateRenderFrame(new_instance, speculative_web_ui_.get(),
- create_render_frame_flags, nullptr);
+ CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
- if (!speculative_render_frame_host_) {
- speculative_web_ui_.reset();
- return false;
- }
- return true;
+ return !!speculative_render_frame_host_;
}
scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
SiteInstance* instance,
- WebUIImpl* web_ui,
int flags,
int* view_routing_id_ptr) {
bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
@@ -1712,12 +1642,12 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
SiteIsolationPolicy::IsSwappedOutStateForbidden();
CHECK(instance);
- CHECK_IMPLIES(swapped_out_forbidden, !swapped_out);
- CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(),
- frame_tree_node_->IsMainFrame());
+ CHECK(!swapped_out_forbidden || !swapped_out);
+ CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible() ||
+ frame_tree_node_->IsMainFrame());
// Swapped out views should always be hidden.
- DCHECK_IMPLIES(swapped_out, (flags & CREATE_RF_HIDDEN));
+ DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN));
scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
bool success = true;
@@ -1743,18 +1673,22 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
new_render_frame_host = proxy->PassFrameHostOwnership();
new_render_frame_host->GetProcess()->AddPendingView();
- proxy_hosts_->Remove(instance->GetId());
+ DeleteRenderFrameProxyHost(instance);
// NB |proxy| is deleted at this point.
// If we are reusing the RenderViewHost and it doesn't already have a
// RenderWidgetHostView, we need to create one if this is the main frame.
- if (!render_view_host->GetView() && frame_tree_node_->IsMainFrame())
+ if (render_view_host->IsRenderViewLive() &&
+ !render_view_host->GetWidget()->GetView() &&
+ frame_tree_node_->IsMainFrame()) {
delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host);
+ }
}
} else {
// Create a new RenderFrameHost if we don't find an existing one.
- int32 widget_routing_id = MSG_ROUTING_NONE;
+ int32_t widget_routing_id = MSG_ROUTING_NONE;
+
// A RenderFrame in a different process from its parent RenderFrame
// requires a RenderWidget for input/layout/painting.
if (frame_tree_node_->parent() &&
@@ -1768,43 +1702,37 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, widget_routing_id, flags);
RenderViewHostImpl* render_view_host =
new_render_frame_host->render_view_host();
- int proxy_routing_id = MSG_ROUTING_NONE;
// Prevent the process from exiting while we're trying to navigate in it.
// Otherwise, if the new RFH is swapped out already, store it.
if (!swapped_out) {
new_render_frame_host->GetProcess()->AddPendingView();
} else {
- proxy = new RenderFrameProxyHost(
- new_render_frame_host->GetSiteInstance(),
- new_render_frame_host->render_view_host(), frame_tree_node_);
- proxy_hosts_->Add(instance->GetId(), make_scoped_ptr(proxy));
- proxy_routing_id = proxy->GetRoutingID();
- proxy->TakeFrameHostOwnership(new_render_frame_host.Pass());
+ proxy =
+ CreateRenderFrameProxyHost(new_render_frame_host->GetSiteInstance(),
+ new_render_frame_host->render_view_host());
+ proxy->TakeFrameHostOwnership(std::move(new_render_frame_host));
}
if (frame_tree_node_->IsMainFrame()) {
- success = InitRenderView(render_view_host, proxy_routing_id);
+ success = InitRenderView(render_view_host, proxy);
// If we are reusing the RenderViewHost and it doesn't already have a
// RenderWidgetHostView, we need to create one if this is the main frame.
- if (!swapped_out && !render_view_host->GetView())
+ if (!swapped_out && !render_view_host->GetWidget()->GetView())
delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host);
} else {
DCHECK(render_view_host->IsRenderViewLive());
}
if (success) {
- // Remember that InitRenderView also created the RenderFrameProxy.
- if (swapped_out)
- proxy->set_render_frame_proxy_created(true);
if (frame_tree_node_->IsMainFrame()) {
// Don't show the main frame's view until we get a DidNavigate from it.
// Only the RenderViewHost for the top-level RenderFrameHost has a
// RenderWidgetHostView; RenderWidgetHosts for out-of-process iframes
// will be created later and hidden.
- if (render_view_host->GetView())
- render_view_host->GetView()->Hide();
+ if (render_view_host->GetWidget()->GetView())
+ render_view_host->GetWidget()->GetView()->Hide();
}
// RenderViewHost for |instance| might exist prior to calling
// CreateRenderFrame. In such a case, InitRenderView will not create the
@@ -1823,25 +1751,10 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
}
}
- // When a new RenderView is created by the renderer process, the new
- // WebContents gets a RenderViewHost in the SiteInstance of its opener
- // WebContents. If not used in the first navigation, this RVH is swapped out
- // and is not granted bindings, so we may need to grant them when swapping it
- // in.
- if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) {
- int required_bindings = web_ui->GetBindings();
- RenderViewHost* render_view_host =
- new_render_frame_host->render_view_host();
- if ((render_view_host->GetEnabledBindings() & required_bindings) !=
- required_bindings) {
- render_view_host->AllowBindings(required_bindings);
- }
- }
-
// Returns the new RFH if it isn't swapped out.
if (success && !swapped_out) {
DCHECK(new_render_frame_host->GetSiteInstance() == instance);
- return new_render_frame_host.Pass();
+ return new_render_frame_host;
}
return nullptr;
}
@@ -1870,16 +1783,12 @@ int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
if (proxy && proxy->is_render_frame_proxy_live())
return proxy->GetRoutingID();
- if (!proxy) {
- proxy =
- new RenderFrameProxyHost(instance, render_view_host, frame_tree_node_);
- proxy_hosts_->Add(instance->GetId(), make_scoped_ptr(proxy));
- }
+ if (!proxy)
+ proxy = CreateRenderFrameProxyHost(instance, render_view_host);
if (SiteIsolationPolicy::IsSwappedOutStateForbidden() &&
frame_tree_node_->IsMainFrame()) {
- InitRenderView(render_view_host, proxy->GetRoutingID());
- proxy->set_render_frame_proxy_created(true);
+ InitRenderView(render_view_host, proxy);
} else {
proxy->InitRenderFrameProxy();
}
@@ -1888,10 +1797,12 @@ int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
}
void RenderFrameHostManager::CreateProxiesForChildFrame(FrameTreeNode* child) {
- for (const auto& pair : *proxy_hosts_) {
+ RenderFrameProxyHost* outer_delegate_proxy =
+ ForInnerDelegate() ? GetProxyToOuterDelegate() : nullptr;
+ for (const auto& pair : proxy_hosts_) {
// Do not create proxies for subframes in the outer delegate's process,
// since the outer delegate does not need to interact with them.
- if (ForInnerDelegate() && pair.second == GetProxyToOuterDelegate())
+ if (pair.second == outer_delegate_proxy)
continue;
child->render_manager()->CreateRenderFrameProxy(
@@ -1913,18 +1824,15 @@ void RenderFrameHostManager::EnsureRenderViewInitialized(
if (!proxy)
return;
- InitRenderView(render_view_host, proxy->GetRoutingID());
- proxy->set_render_frame_proxy_created(true);
+ InitRenderView(render_view_host, proxy);
}
void RenderFrameHostManager::CreateOuterDelegateProxy(
SiteInstance* outer_contents_site_instance,
RenderFrameHostImpl* render_frame_host) {
CHECK(BrowserPluginGuestMode::UseCrossProcessFramesForGuests());
- RenderFrameProxyHost* proxy = new RenderFrameProxyHost(
- outer_contents_site_instance, nullptr, frame_tree_node_);
- proxy_hosts_->Add(outer_contents_site_instance->GetId(),
- make_scoped_ptr(proxy));
+ RenderFrameProxyHost* proxy =
+ CreateRenderFrameProxyHost(outer_contents_site_instance, nullptr);
// Swap the outer WebContents's frame with the proxy to inner WebContents.
//
@@ -1948,7 +1856,7 @@ void RenderFrameHostManager::SetRWHViewForInnerContents(
bool RenderFrameHostManager::InitRenderView(
RenderViewHostImpl* render_view_host,
- int proxy_routing_id) {
+ RenderFrameProxyHost* proxy) {
// Ensure the renderer process is initialized before creating the
// RenderView.
if (!render_view_host->GetProcess()->Init())
@@ -1958,34 +1866,18 @@ bool RenderFrameHostManager::InitRenderView(
if (render_view_host->IsRenderViewLive())
return true;
- // If the ongoing navigation is to a WebUI and the RenderView is not in a
- // guest process, tell the RenderViewHost about any bindings it will need
- // enabled.
- WebUIImpl* dest_web_ui = nullptr;
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
- dest_web_ui =
- should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
- } else {
- dest_web_ui = pending_web_ui();
- }
- if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) {
- render_view_host->AllowBindings(dest_web_ui->GetBindings());
- } else {
- // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
- // process unless it's swapped out.
- if (render_view_host->is_active()) {
- CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
- render_view_host->GetProcess()->GetID()));
- }
- }
-
int opener_frame_routing_id =
GetOpenerRoutingID(render_view_host->GetSiteInstance());
- return delegate_->CreateRenderViewForRenderManager(
- render_view_host, opener_frame_routing_id, proxy_routing_id,
+ bool created = delegate_->CreateRenderViewForRenderManager(
+ render_view_host, opener_frame_routing_id,
+ proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE,
frame_tree_node_->current_replication_state());
+
+ if (created && proxy)
+ proxy->set_render_frame_proxy_created(true);
+
+ return created;
}
bool RenderFrameHostManager::InitRenderFrame(
@@ -2062,49 +1954,33 @@ int RenderFrameHostManager::GetRoutingIdForSiteInstance(
return MSG_ROUTING_NONE;
}
-void RenderFrameHostManager::CommitPending() {
- TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
+void RenderFrameHostManager::CommitPendingWebUI() {
+ TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPendingWebUI",
"FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
- bool browser_side_navigation =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation);
+ DCHECK(render_frame_host_->pending_web_ui());
// First check whether we're going to want to focus the location bar after
// this commit. We do this now because the navigation hasn't formally
- // committed yet, so if we've already cleared |pending_web_ui_| the call chain
+ // committed yet, so if we've already cleared the pending WebUI the call chain
// this triggers won't be able to figure out what's going on.
bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
- // 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.
- DCHECK(!(pending_web_ui_ && pending_and_current_web_ui_));
- if (pending_web_ui_ || speculative_web_ui_) {
- DCHECK(!should_reuse_web_ui_);
- web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release()
- : pending_web_ui_.release());
- } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) {
- if (browser_side_navigation) {
- DCHECK(web_ui_);
- should_reuse_web_ui_ = false;
- } else {
- DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
- pending_and_current_web_ui_.reset();
- }
- } else {
- web_ui_.reset();
- }
- DCHECK(!speculative_web_ui_);
- DCHECK(!should_reuse_web_ui_);
+ render_frame_host_->CommitPendingWebUI();
- // It's possible for the pending_render_frame_host_ to be nullptr when we
- // aren't crossing process boundaries. If so, we just needed to handle the Web
- // UI committing above and we're done.
- if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
- if (will_focus_location_bar)
- delegate_->SetFocusToLocationBar(false);
- return;
- }
+ if (will_focus_location_bar)
+ delegate_->SetFocusToLocationBar(false);
+}
+
+void RenderFrameHostManager::CommitPending() {
+ TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
+ "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
+ DCHECK(pending_render_frame_host_ || speculative_render_frame_host_);
+
+ // First check whether we're going to want to focus the location bar after
+ // this commit. We do this now because the navigation hasn't formally
+ // committed yet, so if we've already cleared the pending WebUI the call chain
+ // this triggers won't be able to figure out what's going on.
+ bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
// Remember if the page was focused so we can focus the new renderer in
// that case.
@@ -2114,23 +1990,23 @@ void RenderFrameHostManager::CommitPending() {
bool is_main_frame = frame_tree_node_->IsMainFrame();
+ // While the old frame is still current, remove its children from the tree.
+ frame_tree_node_->ResetForNewProcess();
+
// Swap in the pending or speculative frame and make it active. Also ensure
// the FrameTree stays in sync.
scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
- if (!browser_side_navigation) {
+ if (!IsBrowserSideNavigationEnabled()) {
DCHECK(!speculative_render_frame_host_);
old_render_frame_host =
- SetRenderFrameHost(pending_render_frame_host_.Pass());
+ SetRenderFrameHost(std::move(pending_render_frame_host_));
} else {
// PlzNavigate
DCHECK(speculative_render_frame_host_);
old_render_frame_host =
- SetRenderFrameHost(speculative_render_frame_host_.Pass());
+ SetRenderFrameHost(std::move(speculative_render_frame_host_));
}
- // Remove the children of the old frame from the tree.
- frame_tree_node_->ResetForNewProcess();
-
// The process will no longer try to exit, so we can decrement the count.
render_frame_host_->GetProcess()->RemovePendingView();
@@ -2153,8 +2029,10 @@ void RenderFrameHostManager::CommitPending() {
// For top-level frames, also hide the old RenderViewHost's view.
// TODO(creis): As long as show/hide are on RVH, we don't want to hide on
// subframe navigations or we will interfere with the top-level frame.
- if (is_main_frame && old_render_frame_host->render_view_host()->GetView())
- old_render_frame_host->render_view_host()->GetView()->Hide();
+ if (is_main_frame &&
+ old_render_frame_host->render_view_host()->GetWidget()->GetView()) {
+ old_render_frame_host->render_view_host()->GetWidget()->GetView()->Hide();
+ }
// Make sure the size is up to date. (Fix for bug 1079768.)
delegate_->UpdateRenderViewSizeForRenderManager();
@@ -2162,7 +2040,14 @@ void RenderFrameHostManager::CommitPending() {
if (will_focus_location_bar) {
delegate_->SetFocusToLocationBar(false);
} else if (focus_render_view && render_frame_host_->GetView()) {
- render_frame_host_->GetView()->Focus();
+ if (is_main_frame) {
+ render_frame_host_->GetView()->Focus();
+ } else {
+ // The main frame's view is already focused, but we need to set
+ // page-level focus in the subframe's renderer.
+ frame_tree_node_->frame_tree()->SetPageFocus(
+ render_frame_host_->GetSiteInstance(), true);
+ }
}
// Notify that we've swapped RenderFrameHosts. We do this before shutting down
@@ -2187,12 +2072,12 @@ void RenderFrameHostManager::CommitPending() {
// out ack arrives (or immediately if the process isn't live).
// In the --site-per-process case, old subframe RFHs are not kept alive inside
// the proxy.
- SwapOutOldFrame(old_render_frame_host.Pass());
+ SwapOutOldFrame(std::move(old_render_frame_host));
if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) {
// Since the new RenderFrameHost is now committed, there must be no proxies
// for its SiteInstance. Delete any existing ones.
- proxy_hosts_->Remove(render_frame_host_->GetSiteInstance()->GetId());
+ DeleteRenderFrameProxyHost(render_frame_host_->GetSiteInstance());
}
// If this is a subframe, it should have a CrossProcessFrameConnector
@@ -2210,47 +2095,7 @@ void RenderFrameHostManager::CommitPending() {
// After all is done, there must never be a proxy in the list which has the
// same SiteInstance as the current RenderFrameHost.
- CHECK(!proxy_hosts_->Get(render_frame_host_->GetSiteInstance()->GetId()));
-}
-
-void RenderFrameHostManager::ShutdownProxiesIfLastActiveFrameInSiteInstance(
- RenderFrameHostImpl* render_frame_host) {
- if (!render_frame_host)
- return;
- if (!RenderFrameHostImpl::IsRFHStateActive(render_frame_host->rfh_state()))
- return;
- if (render_frame_host->GetSiteInstance()->active_frame_count() > 1U)
- return;
-
- // After |render_frame_host| goes away, there will be no active frames left in
- // its SiteInstance, so we can delete all proxies created in that SiteInstance
- // on behalf of frames anywhere in the BrowsingInstance.
- int32 site_instance_id = render_frame_host->GetSiteInstance()->GetId();
-
- // First remove any proxies for this SiteInstance from our own list.
- ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_);
-
- // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts
- // in the SiteInstance, then tell their respective FrameTrees to remove all
- // RenderFrameProxyHosts corresponding to them.
- // TODO(creis): Replace this with a RenderFrameHostIterator that protects
- // against use-after-frees if a later element is deleted before getting to it.
- scoped_ptr<RenderWidgetHostIterator> widgets(
- RenderWidgetHostImpl::GetAllRenderWidgetHosts());
- while (RenderWidgetHost* widget = widgets->GetNextHost()) {
- if (!widget->IsRenderView())
- continue;
- RenderViewHostImpl* rvh =
- static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget));
- if (site_instance_id == rvh->GetSiteInstance()->GetId()) {
- // This deletes all RenderFrameHosts using the |rvh|, which then causes
- // |rvh| to Shutdown.
- FrameTree* tree = rvh->GetDelegate()->GetFrameTree();
- tree->ForEach(base::Bind(
- &RenderFrameHostManager::ClearProxiesInSiteInstance,
- site_instance_id));
- }
- }
+ CHECK(!GetRenderFrameProxyHost(render_frame_host_->GetSiteInstance()));
}
RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
@@ -2262,27 +2107,48 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
bool dest_is_view_source_mode,
const GlobalRequestID& transferred_request_id,
int bindings) {
- // Don't swap for subframes unless we are in --site-per-process. We can get
- // here in tests for subframes (e.g., NavigateFrameToURL).
- if (!frame_tree_node_->IsMainFrame() &&
- !SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
- return render_frame_host_.get();
- }
+ if (!frame_tree_node_->IsMainFrame()) {
+ // Don't swap for subframes unless we are in an OOPIF-enabled mode. We can
+ // get here in tests for subframes (e.g., NavigateFrameToURL).
+ if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
+ return render_frame_host_.get();
- // If we are currently navigating cross-process, we want to get back to normal
- // and then navigate as usual.
- if (pending_render_frame_host_)
- CancelPending();
+ // If dest_url is a unique origin like about:blank, then the need for a swap
+ // is determined by the source_instance.
+ GURL resolved_url = dest_url;
+ if (url::Origin(resolved_url).unique()) {
+ // If there is no source_instance for a unique origin, then we should
+ // avoid a process swap.
+ if (!source_instance)
+ return render_frame_host_.get();
+
+ // Use source_instance to determine if a swap is needed.
+ resolved_url = source_instance->GetSiteURL();
+ }
+
+ // If we are in an OOPIF mode that only applies to some sites, only swap if
+ // the policy determines that a transfer would have been needed. We can get
+ // here for session restore.
+ if (!IsRendererTransferNeededForNavigation(render_frame_host_.get(),
+ resolved_url)) {
+ DCHECK(!dest_instance ||
+ dest_instance == render_frame_host_->GetSiteInstance());
+ return render_frame_host_.get();
+ }
+ }
SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
dest_url, source_instance, dest_instance, nullptr, transition,
dest_is_restore, dest_is_view_source_mode);
- const NavigationEntry* current_entry =
- delegate_->GetLastCommittedNavigationEntryForRenderManager();
-
- DCHECK(!pending_render_frame_host_);
+ // If we are currently navigating cross-process to a pending RFH for a
+ // different SiteInstance, we want to get back to normal and then navigate as
+ // usual. We will reuse the pending RFH below if it matches the destination
+ // SiteInstance.
+ if (pending_render_frame_host_ &&
+ pending_render_frame_host_->GetSiteInstance() != new_instance)
+ CancelPending();
if (new_instance.get() != current_instance) {
TRACE_EVENT_INSTANT2(
@@ -2294,16 +2160,24 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
// New SiteInstance: create a pending RFH to navigate.
- // This will possibly create (set to nullptr) a Web UI object for the
- // pending page. We'll use this later to give the page special access. This
- // must happen before the new renderer is created below so it will get
- // bindings. It must also happen after the above conditional call to
- // CancelPending(), otherwise CancelPending may clear the pending_web_ui_
- // and the page will not have its bindings set appropriately.
- SetPendingWebUI(dest_url, bindings);
- CreatePendingRenderFrameHost(current_instance, new_instance.get());
+ if (!pending_render_frame_host_)
+ CreatePendingRenderFrameHost(current_instance, new_instance.get());
+ DCHECK(pending_render_frame_host_);
if (!pending_render_frame_host_)
return nullptr;
+ DCHECK_EQ(new_instance, pending_render_frame_host_->GetSiteInstance());
+
+ pending_render_frame_host_->UpdatePendingWebUI(dest_url, bindings);
+ pending_render_frame_host_->CommitPendingWebUI();
+ DCHECK_EQ(GetNavigatingWebUI(), pending_render_frame_host_->web_ui());
+
+ // If a WebUI exists in the pending RenderFrameHost it was just created, as
+ // well as the RenderView, and they never interacted. So notify it using
+ // RenderViewCreated.
+ if (pending_render_frame_host_->web_ui()) {
+ pending_render_frame_host_->web_ui()->RenderViewCreated(
+ pending_render_frame_host_->render_view_host());
+ }
// Check if our current RFH is live before we set up a transition.
if (!render_frame_host_->IsRenderFrameLive()) {
@@ -2317,24 +2191,20 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
}
// Otherwise, it's safe to treat this as a pending cross-process transition.
- // We now have a pending RFH.
- DCHECK(pending_render_frame_host_);
-
- // We need to wait until the beforeunload handler has run, unless we are
- // transferring an existing request (in which case it has already run).
- // Suspend the new render view (i.e., don't let it send the cross-process
- // Navigate message) until we hear back from the old renderer's
- // beforeunload handler. If the handler returns false, we'll have to
- // cancel the request.
- //
- DCHECK(!pending_render_frame_host_->are_navigations_suspended());
bool is_transfer = transferred_request_id != GlobalRequestID();
if (is_transfer) {
// We don't need to stop the old renderer or run beforeunload/unload
// handlers, because those have already been done.
DCHECK(cross_site_transferring_request_->request_id() ==
transferred_request_id);
- } else {
+ } else if (!pending_render_frame_host_->are_navigations_suspended()) {
+ // If the pending RFH hasn't already been suspended from a previous
+ // attempt to navigate it, then we need to wait for the beforeunload
+ // handler to run. Suspend navigations in the pending RFH until we hear
+ // back from the old RFH's beforeunload handler (via OnBeforeUnloadACK or
+ // a timeout). If the handler returns false, we'll have to cancel the
+ // request.
+ //
// Also make sure the old render view stops, in case a load is in
// progress. (We don't want to do this for transfers, since it will
// interrupt the transfer with an unexpected DidStopLoading.)
@@ -2342,10 +2212,6 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
render_frame_host_->GetRoutingID()));
pending_render_frame_host_->SetNavigationsSuspended(true,
base::TimeTicks());
- // Unless we are transferring an existing request, we should now tell the
- // old render view to run its beforeunload handler, since it doesn't
- // otherwise know that the cross-site request is happening. This will
- // trigger a call to OnBeforeUnloadACK with the reply.
render_frame_host_->DispatchBeforeUnload(true);
}
@@ -2359,25 +2225,9 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
// original site). In that case, we have a proxy for the current RFH but
// haven't deleted it yet. The new navigation will swap it back in, so we can
// delete the proxy.
- proxy_hosts_->Remove(new_instance.get()->GetId());
-
- if (ShouldReuseWebUI(current_entry, dest_url)) {
- pending_web_ui_.reset();
- pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
- } else {
- SetPendingWebUI(dest_url, bindings);
- // Make sure the new RenderViewHost has the right bindings.
- if (pending_web_ui() &&
- !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
- render_frame_host_->render_view_host()->AllowBindings(
- pending_web_ui()->GetBindings());
- }
- }
+ DeleteRenderFrameProxyHost(new_instance.get());
- if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) {
- pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(),
- frame_tree_node_->IsMainFrame());
- }
+ UpdatePendingWebUIOnCurrentFrameHost(dest_url, bindings);
// The renderer can exit view source mode when any error or cancellation
// happen. We must overwrite to recover the mode.
@@ -2390,16 +2240,46 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
return render_frame_host_.get();
}
+void RenderFrameHostManager::UpdatePendingWebUIOnCurrentFrameHost(
+ const GURL& dest_url,
+ int entry_bindings) {
+ bool pending_webui_changed =
+ render_frame_host_->UpdatePendingWebUI(dest_url, entry_bindings);
+ DCHECK_EQ(GetNavigatingWebUI(), render_frame_host_->pending_web_ui());
+
+ if (render_frame_host_->pending_web_ui() && pending_webui_changed &&
+ render_frame_host_->IsRenderFrameLive()) {
+ // If a pending WebUI exists in the current RenderFrameHost and it has been
+ // updated and the associated RenderFrame is alive, notify the WebUI about
+ // the RenderView.
+ // Note: If the RenderFrame is not alive at this point the notification will
+ // happen later, when the RenderView is created.
+ if (render_frame_host_->pending_web_ui() == render_frame_host_->web_ui()) {
+ // If the active WebUI is being reused it has already interacting with
+ // this RenderView in the past, so call RenderViewReused.
+ render_frame_host_->pending_web_ui()->RenderViewReused(
+ render_frame_host_->render_view_host(),
+ frame_tree_node_->IsMainFrame());
+ } else {
+ // If this is a new WebUI it has never interacted with the existing
+ // RenderView so call RenderViewCreated.
+ render_frame_host_->pending_web_ui()->RenderViewCreated(
+ render_frame_host_->render_view_host());
+ }
+ }
+}
+
void RenderFrameHostManager::CancelPending() {
TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
"FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
+ render_frame_host_->ClearPendingWebUI();
DiscardUnusedFrame(UnsetPendingRenderFrameHost());
}
scoped_ptr<RenderFrameHostImpl>
RenderFrameHostManager::UnsetPendingRenderFrameHost() {
scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
- pending_render_frame_host_.Pass();
+ std::move(pending_render_frame_host_);
RenderFrameDevToolsAgentHost::OnCancelPendingNavigation(
pending_render_frame_host.get(),
@@ -2408,18 +2288,15 @@ RenderFrameHostManager::UnsetPendingRenderFrameHost() {
// We no longer need to prevent the process from exiting.
pending_render_frame_host->GetProcess()->RemovePendingView();
- pending_web_ui_.reset();
- pending_and_current_web_ui_.reset();
-
- return pending_render_frame_host.Pass();
+ return pending_render_frame_host;
}
scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
scoped_ptr<RenderFrameHostImpl> render_frame_host) {
// Swap the two.
scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
- render_frame_host_.Pass();
- render_frame_host_ = render_frame_host.Pass();
+ std::move(render_frame_host_);
+ render_frame_host_ = std::move(render_frame_host);
if (frame_tree_node_->IsMainFrame()) {
// Update the count of top-level frames using this SiteInstance. All
@@ -2436,13 +2313,12 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
}
}
- return old_render_frame_host.Pass();
+ return old_render_frame_host;
}
bool RenderFrameHostManager::IsRVHOnSwappedOutList(
RenderViewHostImpl* rvh) const {
- RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(
- rvh->GetSiteInstance());
+ RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(rvh->GetSiteInstance());
if (!proxy)
return false;
// If there is a proxy without RFH, it is for a subframe in the SiteInstance
@@ -2457,8 +2333,7 @@ bool RenderFrameHostManager::IsOnSwappedOutList(
if (!rfh->GetSiteInstance())
return false;
- RenderFrameProxyHost* host =
- proxy_hosts_->Get(rfh->GetSiteInstance()->GetId());
+ RenderFrameProxyHost* host = GetRenderFrameProxyHost(rfh->GetSiteInstance());
if (!host)
return false;
@@ -2475,13 +2350,17 @@ RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost(
RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost(
SiteInstance* instance) const {
- return proxy_hosts_->Get(instance->GetId());
+ auto it = proxy_hosts_.find(instance->GetId());
+ if (it != proxy_hosts_.end())
+ return it->second;
+ return nullptr;
}
std::map<int, RenderFrameProxyHost*>
RenderFrameHostManager::GetAllProxyHostsForTesting() {
std::map<int, RenderFrameProxyHost*> result;
- result.insert(proxy_hosts_->begin(), proxy_hosts_->end());
+ for (const auto& pair : proxy_hosts_)
+ result[pair.first] = pair.second;
return result;
}
@@ -2585,8 +2464,7 @@ void RenderFrameHostManager::CreateOpenerProxiesForFrameTree(
frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance);
} else {
frame_tree->root()->render_manager()->CreateRenderFrame(
- instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
- nullptr);
+ instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr);
}
}
}
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager.h b/chromium/content/browser/frame_host/render_frame_host_manager.h
index 826718fe2e1..b3b1d7439ce 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.h
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.h
@@ -5,13 +5,18 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_MANAGER_H_
+#include <stdint.h>
+
#include <list>
#include <map>
-#include "base/basictypes.h"
+#include "base/containers/hash_tables.h"
+#include "base/containers/scoped_ptr_hash_map.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/content_export.h"
@@ -33,9 +38,7 @@ class NavigationEntryImpl;
class NavigationHandleImpl;
class NavigationRequest;
class NavigatorTestWithBrowserSideNavigation;
-class RenderFrameHost;
class RenderFrameHostDelegate;
-class RenderFrameHostImpl;
class RenderFrameHostManagerTest;
class RenderFrameProxyHost;
class RenderViewHost;
@@ -94,7 +97,8 @@ struct FrameReplicationState;
// RenderFrameProxyHost, to be used (for example) if the user goes back. The
// process only stays live if another tab is using it, but if so, the existing
// frame relationships will be maintained.
-class CONTENT_EXPORT RenderFrameHostManager {
+class CONTENT_EXPORT RenderFrameHostManager
+ : public SiteInstanceImpl::Observer {
public:
// Functions implemented by our owner that we need.
//
@@ -148,12 +152,6 @@ class CONTENT_EXPORT RenderFrameHostManager {
virtual NavigationControllerImpl&
GetControllerForRenderManager() = 0;
- // Creates a WebUI object for the given URL if one applies. Ownership of the
- // returned pointer will be passed to the caller. If no WebUI applies,
- // returns NULL.
- virtual scoped_ptr<WebUIImpl> CreateWebUIForRenderManager(
- const GURL& url) = 0;
-
// Returns the navigation entry of the current navigation, or NULL if there
// is none.
virtual NavigationEntry*
@@ -173,9 +171,9 @@ class CONTENT_EXPORT RenderFrameHostManager {
// If the delegate is an inner WebContents, this method returns the
// FrameTreeNode ID of the frame in the outer WebContents which hosts
- // the inner WebContents. Returns FrameTreeNode::kFrameTreeNodeInvalidID
+ // the inner WebContents. Returns FrameTreeNode::kFrameTreeNodeInvalidId
// if the delegate does not have an outer WebContents.
- virtual int GetOuterDelegateFrameTreeNodeID() = 0;
+ virtual int GetOuterDelegateFrameTreeNodeId() = 0;
protected:
virtual ~Delegate() {}
@@ -186,6 +184,10 @@ class CONTENT_EXPORT RenderFrameHostManager {
// WebContentsImpl.
static bool ClearRFHsPendingShutdown(FrameTreeNode* node);
+ // Used with FrameTree::ForEach to destroy all WebUI instances associated with
+ // RenderFrameHosts.
+ static bool ClearWebUIInstances(FrameTreeNode* node);
+
// All three delegate pointers must be non-NULL and are not owned by this
// class. They must outlive this class. The RenderViewHostDelegate and
// RenderWidgetHostDelegate are what will be installed into all
@@ -201,11 +203,10 @@ class CONTENT_EXPORT RenderFrameHostManager {
~RenderFrameHostManager();
// For arguments, see WebContentsImpl constructor.
- void Init(BrowserContext* browser_context,
- SiteInstance* site_instance,
- int32 view_routing_id,
- int32 frame_routing_id,
- int32 widget_routing_id);
+ void Init(SiteInstance* site_instance,
+ int32_t view_routing_id,
+ int32_t frame_routing_id,
+ int32_t widget_routing_id);
// Returns the currently active RenderFrameHost.
//
@@ -233,6 +234,10 @@ class CONTENT_EXPORT RenderFrameHostManager {
// remote frames.
RenderWidgetHostImpl* GetOuterRenderWidgetHostForKeyboardInput();
+ // Return the FrameTreeNode for the frame in the outer WebContents (if any)
+ // that contains the inner WebContents.
+ FrameTreeNode* GetOuterDelegateNode();
+
RenderFrameProxyHost* GetProxyToParent();
// Returns the proxy to inner WebContents in the outer WebContents's
@@ -246,7 +251,7 @@ class CONTENT_EXPORT RenderFrameHostManager {
// somehwere else.
void RemoveOuterDelegateFrame();
- // Returns the pending RenderFrameHost, or NULL if there is no pending one.
+ // Returns the pending RenderFrameHost, or null if there is no pending one.
RenderFrameHostImpl* pending_frame_host() const {
return pending_render_frame_host_.get();
}
@@ -260,21 +265,10 @@ class CONTENT_EXPORT RenderFrameHostManager {
// TODO(creis): Remove this when we no longer use RVH for navigation.
RenderViewHostImpl* pending_render_view_host() const;
- // Returns the current committed Web UI or NULL if none applies.
- WebUIImpl* web_ui() const { return web_ui_.get(); }
-
- // Returns the Web UI for the pending navigation, or NULL of none applies.
- WebUIImpl* pending_web_ui() const {
- return pending_web_ui_.get() ? pending_web_ui_.get() :
- pending_and_current_web_ui_.get();
- }
-
- // PlzNavigate
- // Returns the speculative WebUI for the navigation (a newly created one or
- // the current one if it should be reused). If none is set returns nullptr.
- WebUIImpl* speculative_web_ui() const {
- return should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
- }
+ // Returns the WebUI associated with the ongoing navigation, it being either
+ // the active or the pending one from the navigating RenderFrameHost. Returns
+ // null if there's no ongoing navigation or if no WebUI applies.
+ WebUIImpl* GetNavigatingWebUI() const;
// Called when we want to instruct the renderer to navigate to the given
// navigation entry. It may create a new RenderFrameHost or re-use an existing
@@ -323,6 +317,20 @@ class CONTENT_EXPORT RenderFrameHostManager {
ui::PageTransition page_transition,
bool should_replace_current_entry);
+ // Determines whether a navigation to |dest_url| may be completed using an
+ // existing RenderFrameHost, or whether transferring to a new RenderFrameHost
+ // backed by a different render process is required. This is a security policy
+ // check determined by the current site isolation mode, and must be done
+ // before the resource at |dest_url| is delivered to |existing_rfh|.
+ //
+ // |existing_rfh| must belong to this RFHM, but it can be a pending or current
+ // host.
+ //
+ // When this function returns true for a subframe, an out-of-process iframe
+ // must be created.
+ bool IsRendererTransferNeededForNavigation(RenderFrameHostImpl* existing_rfh,
+ const GURL& dest_url);
+
// Called when a renderer's frame navigates.
void DidNavigateFrame(RenderFrameHostImpl* render_frame_host,
bool was_caused_by_user_gesture);
@@ -336,19 +344,12 @@ class CONTENT_EXPORT RenderFrameHostManager {
void DidChangeOpener(int opener_routing_id,
SiteInstance* source_site_instance);
- // Sets the pending Web UI for the pending navigation, ensuring that the
- // bindings are appropriate compared to |bindings|.
- void SetPendingWebUI(const GURL& url, int bindings);
-
- // Creates and initializes a RenderFrameHost. The |web_ui| is an optional
- // input parameter used to double check bindings when swapping back in a
- // previously existing RenderFrameHost. If |flags| has the
+ // Creates and initializes a RenderFrameHost. If |flags| has the
// CREATE_RF_SWAPPED_OUT bit set from the CreateRenderFrameFlags enum, it will
// initially be placed on the swapped out hosts list. If |view_routing_id_ptr|
// is not nullptr it will be set to the routing id of the view associated with
// the frame.
scoped_ptr<RenderFrameHostImpl> CreateRenderFrame(SiteInstance* instance,
- WebUIImpl* web_ui,
int flags,
int* view_routing_id_ptr);
@@ -442,6 +443,10 @@ class CONTENT_EXPORT RenderFrameHostManager {
// window.name property.
void OnDidUpdateName(const std::string& name);
+ // Sends updated enforcement of strict mixed content checking to all
+ // frame proxies when the frame changes its setting.
+ void OnEnforceStrictMixedContentChecking(bool should_enforce);
+
// Send updated origin to all frame proxies when the frame navigates to a new
// origin.
void OnDidUpdateOrigin(const url::Origin& origin);
@@ -488,6 +493,10 @@ class CONTENT_EXPORT RenderFrameHostManager {
// the values are RenderFrameProxyHosts.
std::map<int, RenderFrameProxyHost*> GetAllProxyHostsForTesting();
+ // SiteInstanceImpl::Observer
+ void ActiveFrameCountIsZero(SiteInstanceImpl* site_instance) override;
+ void RenderProcessGone(SiteInstanceImpl* site_instance) override;
+
private:
friend class NavigatorTestWithBrowserSideNavigation;
friend class RenderFrameHostManagerTest;
@@ -517,14 +526,11 @@ class CONTENT_EXPORT RenderFrameHostManager {
bool new_is_related_to_current;
};
- // Used with FrameTree::ForEach to erase RenderFrameProxyHosts from a
- // FrameTreeNode's RenderFrameHostManager.
- static bool ClearProxiesInSiteInstance(int32 site_instance_id,
- FrameTreeNode* node);
- // Used with FrameTree::ForEach to reset initialized state of
- // RenderFrameProxyHosts from a FrameTreeNode's RenderFrameHostManager.
- static bool ResetProxiesInSiteInstance(int32 site_instance_id,
- FrameTreeNode* node);
+ // Create a RenderFrameProxyHost owned by this object.
+ RenderFrameProxyHost* CreateRenderFrameProxyHost(SiteInstance* site_instance,
+ RenderViewHostImpl* rvh);
+ // Delete a RenderFrameProxyHost owned by this object.
+ void DeleteRenderFrameProxyHost(SiteInstance* site_instance);
// Returns whether this tab should transition to a new renderer for
// cross-site URLs. Enabled unless we see the --process-per-tab command line
@@ -551,16 +557,6 @@ class CONTENT_EXPORT RenderFrameHostManager {
const GURL& new_effective_url,
bool new_is_view_source_mode) const;
- // Creates a new Web UI, ensuring that the bindings are appropriate compared
- // to |bindings|.
- scoped_ptr<WebUIImpl> CreateWebUI(const GURL& url, int bindings);
-
- // Returns true if it is safe to reuse the current WebUI when navigating from
- // |current_entry| to |new_url|.
- bool ShouldReuseWebUI(
- const NavigationEntry* current_entry,
- const GURL& new_url) const;
-
// Returns the SiteInstance to use for the navigation.
SiteInstance* GetSiteInstanceForNavigation(const GURL& dest_url,
SiteInstance* source_instance,
@@ -640,36 +636,37 @@ class CONTENT_EXPORT RenderFrameHostManager {
FrameTreeNode* skip_this_node);
// Creates a RenderFrameHost and corresponding RenderViewHost if necessary.
- scoped_ptr<RenderFrameHostImpl> CreateRenderFrameHost(SiteInstance* instance,
- int32 view_routing_id,
- int32 frame_routing_id,
- int32 widget_routing_id,
- int flags);
+ scoped_ptr<RenderFrameHostImpl> CreateRenderFrameHost(
+ SiteInstance* instance,
+ int32_t view_routing_id,
+ int32_t frame_routing_id,
+ int32_t widget_routing_id,
+ int flags);
// PlzNavigate
- // Creates and initializes a speculative RenderFrameHost and/or WebUI for an
- // ongoing navigation. They might be destroyed and re-created later if the
- // navigation is redirected to a different SiteInstance.
- bool CreateSpeculativeRenderFrameHost(const GURL& url,
- SiteInstance* old_instance,
- SiteInstance* new_instance,
- int bindings);
-
- // Sets up the necessary state for a new RenderViewHost. Creates a
- // RenderFrameProxy in the target renderer process with the given
- // |proxy_routing_id|, which is used to route IPC messages when in swapped
- // out state. Returns early if the RenderViewHost has already been
- // initialized for another RenderFrameHost.
+ // Create and initialize a speculative RenderFrameHost for an ongoing
+ // navigation. It might be destroyed and re-created later if the navigation
+ // is redirected to a different SiteInstance.
+ bool CreateSpeculativeRenderFrameHost(SiteInstance* old_instance,
+ SiteInstance* new_instance);
+
+ // Sets up the necessary state for a new RenderViewHost. If |proxy| is not
+ // null, it creates a RenderFrameProxy in the target renderer process which is
+ // used to route IPC messages when in swapped out state. Returns early if the
+ // RenderViewHost has already been initialized for another RenderFrameHost.
bool InitRenderView(RenderViewHostImpl* render_view_host,
- int proxy_routing_id);
+ RenderFrameProxyHost* proxy);
// Initialization for RenderFrameHost uses the same sequence as InitRenderView
// above.
bool InitRenderFrame(RenderFrameHostImpl* render_frame_host);
- // Sets the pending RenderFrameHost/WebUI to be the active one. Note that this
- // doesn't require the pending render_frame_host_ pointer to be non-NULL,
- // since there could be Web UI switching as well. Call this for every commit.
+ // Makes the pending WebUI on the current RenderFrameHost active. Call this
+ // when the current RenderFrameHost commits and it has a pending WebUI.
+ void CommitPendingWebUI();
+
+ // Sets the pending RenderFrameHost to be the active one. Call when the
+ // pending RenderFrameHost commits.
// If PlzNavigate is enabled the method will set the speculative (not pending)
// RenderFrameHost to be the active one.
void CommitPending();
@@ -696,13 +693,6 @@ class CONTENT_EXPORT RenderFrameHostManager {
void MoveToPendingDeleteHosts(
scoped_ptr<RenderFrameHostImpl> render_frame_host);
- // If |render_frame_host| is the last remaining active frame in its
- // SiteInstance, this will shutdown all the RenderFrameProxyHosts in the
- // SiteInstance. This is appropriate if |render_frame_host| is about to be
- // destroyed.
- void ShutdownProxiesIfLastActiveFrameInSiteInstance(
- RenderFrameHostImpl* render_frame_host);
-
// Helper method to terminate the pending RenderFrameHost. The frame may be
// deleted immediately, or it may be kept around in hopes of later reuse.
void CancelPending();
@@ -725,9 +715,10 @@ class CONTENT_EXPORT RenderFrameHostManager {
const GlobalRequestID& transferred_request_id,
int bindings);
- // Called when a renderer process is starting to close. We should not
- // schedule new navigations in its swapped out RenderFrameHosts after this.
- void RendererProcessClosing(RenderProcessHost* render_process_host);
+ // Updates the pending WebUI of the current RenderFrameHost for a same-site
+ // navigation.
+ void UpdatePendingWebUIOnCurrentFrameHost(const GURL& dest_url,
+ int entry_bindings);
// For use in creating RenderFrameHosts.
FrameTreeNode* frame_tree_node_;
@@ -741,25 +732,15 @@ class CONTENT_EXPORT RenderFrameHostManager {
RenderViewHostDelegate* render_view_delegate_;
RenderWidgetHostDelegate* render_widget_delegate_;
- // Our RenderFrameHost and its associated Web UI (if any, will be NULL for
- // non-WebUI pages). This object is responsible for all communication with
- // a child RenderFrame instance.
+ // Our RenderFrameHost which is responsible for all communication with a child
+ // RenderFrame instance.
// For now, RenderFrameHost keeps a RenderViewHost in its SiteInstance alive.
// Eventually, RenderViewHost will be replaced with a page context.
scoped_ptr<RenderFrameHostImpl> render_frame_host_;
- scoped_ptr<WebUIImpl> web_ui_;
// A RenderFrameHost used to load a cross-site page. This remains hidden
- // while a cross-site request is pending until it calls DidNavigate. It may
- // have an associated Web UI, in which case the Web UI pointer will be non-
- // NULL.
- //
- // The |pending_web_ui_| may be non-NULL even when the
- // |pending_render_frame_host_| is NULL. This will happen when we're
- // transitioning between two Web UI pages: the RFH won't be swapped, so the
- // pending pointer will be unused, but there will be a pending Web UI
- // associated with the navigation.
- // Note: This is not used in PlzNavigate.
+ // while a cross-site request is pending until it calls DidNavigate.
+ // Note: This member is not used in PlzNavigate.
scoped_ptr<RenderFrameHostImpl> pending_render_frame_host_;
// If a pending request needs to be transferred to another process, this
@@ -775,16 +756,9 @@ class CONTENT_EXPORT RenderFrameHostManager {
// navigations in PlzNavigate.
scoped_ptr<NavigationHandleImpl> transfer_navigation_handle_;
- // If either of these is non-NULL, the pending navigation is to a chrome:
- // page. The scoped_ptr is used if pending_web_ui_ != web_ui_, the WeakPtr is
- // used for when they reference the same object. If either is non-NULL, the
- // other should be NULL.
- // Note: These are not used in PlzNavigate.
- scoped_ptr<WebUIImpl> pending_web_ui_;
- base::WeakPtr<WebUIImpl> pending_and_current_web_ui_;
-
- class RenderFrameProxyHostMap;
- scoped_ptr<RenderFrameProxyHostMap> proxy_hosts_;
+ // Proxy hosts, indexed by site instance ID.
+ base::ScopedPtrHashMap<int32_t, scoped_ptr<RenderFrameProxyHost>>
+ proxy_hosts_;
// A list of RenderFrameHosts waiting to shut down after swapping out. We use
// a linked list since we expect frequent deletes and no indexed access, and
@@ -797,21 +771,15 @@ class CONTENT_EXPORT RenderFrameHostManager {
InterstitialPageImpl* interstitial_page_;
// PlzNavigate
- // These members store a speculative RenderFrameHost and WebUI. They are
- // created early in a navigation so a renderer process can be started in
- // parallel, if needed. This is purely a performance optimization and is not
- // required for correct behavior. The created RenderFrameHost might be
- // discarded later on if the final URL's SiteInstance isn't compatible with
- // what was used to create it.
- // Note: PlzNavigate only uses speculative RenderFrameHost and WebUI, not
- // the pending ones.
+ // Stores a speculative RenderFrameHost which is created early in a navigation
+ // so a renderer process can be started in parallel, if needed.
+ // This is purely a performance optimization and is not required for correct
+ // behavior. The speculative RenderFrameHost might be discarded later on if
+ // the final URL's SiteInstance isn't compatible with the one used to create
+ // it.
+ // Note: PlzNavigate only uses the speculative RenderFrameHost, not the
+ // pending one.
scoped_ptr<RenderFrameHostImpl> speculative_render_frame_host_;
- scoped_ptr<WebUIImpl> speculative_web_ui_;
-
- // PlzNavigate
- // If true at navigation commit time the current WebUI will be kept instead of
- // creating a new one.
- bool should_reuse_web_ui_;
base::WeakPtrFactory<RenderFrameHostManager> weak_factory_;
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc
index fcf00e8fc0f..afb1ca06df8 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <set>
#include "base/command_line.h"
@@ -10,20 +13,25 @@
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/browser/webui/web_ui_impl.h"
#include "content/common/content_constants_internal.h"
+#include "content/common/input_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/bindings_policy.h"
@@ -42,7 +50,7 @@
#include "net/base/net_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
using base::ASCIIToUTF16;
@@ -73,36 +81,36 @@ class RenderFrameHostManagerTest : public ContentBrowserTest {
replace_host_.SetHostStr(foo_com_);
}
- static bool GetFilePathWithHostAndPortReplacement(
+ static void GetFilePathWithHostAndPortReplacement(
const std::string& original_file_path,
const net::HostPortPair& host_port_pair,
std::string* replacement_path) {
- std::vector<net::SpawnedTestServer::StringPair> replacement_text;
+ base::StringPairs replacement_text;
replacement_text.push_back(
make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
- return net::SpawnedTestServer::GetFilePathWithReplacements(
+ net::test_server::GetFilePathWithReplacements(
original_file_path, replacement_text, replacement_path);
}
void StartServer() {
// Support multiple sites on the test server.
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
- foo_host_port_ = test_server()->host_port_pair();
+ foo_host_port_ = embedded_test_server()->host_port_pair();
foo_host_port_.set_host(foo_com_);
}
void StartEmbeddedServer() {
// Support multiple sites on the embedded test server.
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
SetupCrossSiteRedirector(embedded_test_server());
}
// Returns a URL on foo.com with the given path.
GURL GetCrossSiteURL(const std::string& path) {
- GURL cross_site_url(test_server()->GetURL(path));
+ GURL cross_site_url(embedded_test_server()->GetURL(path));
return cross_site_url.ReplaceComponents(replace_host_);
}
@@ -228,6 +236,13 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_EQ("/title2.html", new_shell->web_contents()->GetVisibleURL().path());
+ // Check that `window.opener` is not set.
+ success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ new_shell->web_contents(),
+ "window.domAutomationController.send(window.opener == null);", &success));
+ EXPECT_TRUE(success);
+
// Wait for the cross-site transition in the new tab to finish.
WaitForLoadStop(new_shell->web_contents());
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
@@ -241,6 +256,102 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_NE(orig_site_instance, noref_blank_site_instance);
}
+// Same as above, but for 'noopener'
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ SwapProcessWithRelNopenerAndTargetBlank) {
+ StartEmbeddedServer();
+
+ NavigateToPageWithLinks(shell());
+
+ // Get the original SiteInstance for later comparison.
+ scoped_refptr<SiteInstance> orig_site_instance(
+ shell()->web_contents()->GetSiteInstance());
+ EXPECT_TRUE(orig_site_instance.get() != NULL);
+
+ // Test clicking a rel=noreferrer + target=blank link.
+ ShellAddedObserver new_shell_observer;
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ shell()->web_contents(),
+ "window.domAutomationController.send(clickNoOpenerTargetBlankLink());",
+ &success));
+ EXPECT_TRUE(success);
+
+ // Wait for the window to open.
+ Shell* new_shell = new_shell_observer.GetShell();
+
+ EXPECT_EQ("/title2.html", new_shell->web_contents()->GetVisibleURL().path());
+
+ // Check that `window.opener` is not set.
+ success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ new_shell->web_contents(),
+ "window.domAutomationController.send(window.opener == null);", &success));
+ EXPECT_TRUE(success);
+
+ // Wait for the cross-site transition in the new tab to finish.
+ WaitForLoadStop(new_shell->web_contents());
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(new_shell->web_contents());
+ EXPECT_FALSE(
+ web_contents->GetRenderManagerForTesting()->pending_render_view_host());
+
+ // Should have a new SiteInstance.
+ scoped_refptr<SiteInstance> noopener_blank_site_instance(
+ new_shell->web_contents()->GetSiteInstance());
+ EXPECT_NE(orig_site_instance, noopener_blank_site_instance);
+}
+
+// 'noopener' also works from 'window.open'
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ SwapProcessWithWindowOpenAndNoopener) {
+ StartEmbeddedServer();
+
+ NavigateToPageWithLinks(shell());
+
+ // Get the original SiteInstance for later comparison.
+ scoped_refptr<SiteInstance> orig_site_instance(
+ shell()->web_contents()->GetSiteInstance());
+ EXPECT_TRUE(orig_site_instance.get());
+
+ // Test opening a window with the 'noopener' feature.
+ ShellAddedObserver new_shell_observer;
+ bool hasWindowReference = true;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ shell()->web_contents(),
+ "window.domAutomationController.send("
+ " openWindowWithTargetAndFeatures('/title2.html', '', 'noopener')"
+ ");",
+ &hasWindowReference));
+ // We should not get a reference to the opened window.
+ EXPECT_FALSE(hasWindowReference);
+
+ // Wait for the window to open.
+ Shell* new_shell = new_shell_observer.GetShell();
+
+ // Wait for the cross-site transition in the new tab to finish.
+ WaitForLoadStop(new_shell->web_contents());
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(new_shell->web_contents());
+ EXPECT_FALSE(
+ web_contents->GetRenderManagerForTesting()->pending_render_view_host());
+
+ EXPECT_EQ("/title2.html",
+ new_shell->web_contents()->GetLastCommittedURL().path());
+
+ // Check that `window.opener` is not set.
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ new_shell->web_contents(),
+ "window.domAutomationController.send(window.opener == null);", &success));
+ EXPECT_TRUE(success);
+
+ // Should have a new SiteInstance.
+ scoped_refptr<SiteInstance> noopener_blank_site_instance(
+ new_shell->web_contents()->GetSiteInstance());
+ EXPECT_NE(orig_site_instance, noopener_blank_site_instance);
+}
+
// As of crbug.com/69267, we create a new BrowsingInstance (and SiteInstance)
// for rel=noreferrer links in new windows, even to same site pages and named
// targets.
@@ -271,6 +382,62 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Opens in new window.
EXPECT_EQ("/title2.html", new_shell->web_contents()->GetVisibleURL().path());
+ // Check that `window.opener` is not set.
+ success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ new_shell->web_contents(),
+ "window.domAutomationController.send(window.opener == null);", &success));
+ EXPECT_TRUE(success);
+
+ // Wait for the cross-site transition in the new tab to finish.
+ WaitForLoadStop(new_shell->web_contents());
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(new_shell->web_contents());
+ EXPECT_FALSE(
+ web_contents->GetRenderManagerForTesting()->pending_render_view_host());
+
+ // Should have a new SiteInstance (in a new BrowsingInstance).
+ scoped_refptr<SiteInstance> noref_blank_site_instance(
+ new_shell->web_contents()->GetSiteInstance());
+ EXPECT_NE(orig_site_instance, noref_blank_site_instance);
+}
+
+// Same as above, but for 'noopener'
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ SwapProcessWithSameSiteRelNoopener) {
+ StartEmbeddedServer();
+
+ // Load a page with links that open in a new window.
+ NavigateToPageWithLinks(shell());
+
+ // Get the original SiteInstance for later comparison.
+ scoped_refptr<SiteInstance> orig_site_instance(
+ shell()->web_contents()->GetSiteInstance());
+ EXPECT_TRUE(orig_site_instance.get() != NULL);
+
+ // Test clicking a same-site rel=noopener + target=foo link.
+ ShellAddedObserver new_shell_observer;
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(),
+ "window.domAutomationController.send("
+ "clickSameSiteNoOpenerTargetedLink())"
+ ";",
+ &success));
+ EXPECT_TRUE(success);
+
+ // Wait for the window to open.
+ Shell* new_shell = new_shell_observer.GetShell();
+
+ // Opens in new window.
+ EXPECT_EQ("/title2.html", new_shell->web_contents()->GetVisibleURL().path());
+
+ // Check that `window.opener` is not set.
+ success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ new_shell->web_contents(),
+ "window.domAutomationController.send(window.opener == null);", &success));
+ EXPECT_TRUE(success);
+
// Wait for the cross-site transition in the new tab to finish.
WaitForLoadStop(new_shell->web_contents());
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
@@ -343,6 +510,43 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
bool success = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
shell()->web_contents(),
+ "window.domAutomationController.send(clickNoRefLink());", &success));
+ EXPECT_TRUE(success);
+
+ // Wait for the cross-site transition in the current tab to finish.
+ WaitForLoadStop(shell()->web_contents());
+
+ // Opens in same window.
+ EXPECT_EQ(1u, Shell::windows().size());
+ EXPECT_EQ("/title2.html",
+ shell()->web_contents()->GetLastCommittedURL().path());
+
+ // Should have the same SiteInstance unless we're in site-per-process mode.
+ scoped_refptr<SiteInstance> noref_site_instance(
+ shell()->web_contents()->GetSiteInstance());
+ if (AreAllSitesIsolatedForTesting())
+ EXPECT_NE(orig_site_instance, noref_site_instance);
+ else
+ EXPECT_EQ(orig_site_instance, noref_site_instance);
+}
+
+// Same as above, but for 'noopener'
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ DontSwapProcessWithOnlyRelNoOpener) {
+ StartEmbeddedServer();
+
+ // Load a page with links that open in a new window.
+ NavigateToPageWithLinks(shell());
+
+ // Get the original SiteInstance for later comparison.
+ scoped_refptr<SiteInstance> orig_site_instance(
+ shell()->web_contents()->GetSiteInstance());
+ EXPECT_TRUE(orig_site_instance.get() != NULL);
+
+ // Test clicking a rel=noreferrer link.
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ shell()->web_contents(),
"window.domAutomationController.send(clickNoRefLink());",
&success));
EXPECT_TRUE(success);
@@ -996,8 +1200,8 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ClickLinkAfter204Error) {
EXPECT_TRUE(orig_site_instance.get() != NULL);
// Load a cross-site page that fails with a 204 error.
- EXPECT_TRUE(NavigateToURLAndExpectNoCommit(shell(),
- GetCrossSiteURL("nocontent")));
+ EXPECT_TRUE(
+ NavigateToURLAndExpectNoCommit(shell(), GetCrossSiteURL("/nocontent")));
// We should still be looking at the normal page. Because we started from a
// blank new tab, the typed URL will still be visible until the user clears it
@@ -1013,7 +1217,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ClickLinkAfter204Error) {
// Renderer-initiated navigations should work.
base::string16 expected_title = ASCIIToUTF16("Title Of Awesomeness");
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
- GURL url = test_server()->GetURL("files/title2.html");
+ GURL url = embedded_test_server()->GetURL("/title2.html");
EXPECT_TRUE(ExecuteScript(
shell()->web_contents(),
base::StringPrintf("location.href = '%s'", url.spec().c_str())));
@@ -1021,7 +1225,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ClickLinkAfter204Error) {
// Opens in same tab.
EXPECT_EQ(1u, Shell::windows().size());
- EXPECT_EQ("/files/title2.html",
+ EXPECT_EQ("/title2.html",
shell()->web_contents()->GetLastCommittedURL().path());
// Should have the same SiteInstance.
@@ -1035,11 +1239,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ClickLinkAfter204Error) {
// about:blank page is modified by another window. At that point, we should
// revert to showing about:blank to prevent a URL spoof.
IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ShowLoadingURLUntilSpoof) {
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
// Load a page that can open a URL that won't commit in a new window.
- NavigateToURL(
- shell(), test_server()->GetURL("files/click-nocontent-link.html"));
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/click-nocontent-link.html"));
WebContents* orig_contents = shell()->web_contents();
// Click a /nocontent link that opens in a new window but never commits.
@@ -1085,11 +1289,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ShowLoadingURLUntilSpoof) {
// show the pending URL without allowing a spoof.
IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
DontShowLoadingURLIfNotInitialNav) {
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
// Load a page that can open a URL that won't commit in a new window.
- NavigateToURL(
- shell(), test_server()->GetURL("files/click-nocontent-link.html"));
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/click-nocontent-link.html"));
WebContents* orig_contents = shell()->web_contents();
// Click a /nocontent link that opens in a new window but never commits.
@@ -1540,16 +1744,19 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
shell()->web_contents()->GetRenderProcessHost()->GetID()));
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
shell()->web_contents());
- WebUIImpl* webui = web_contents->GetRenderManagerForTesting()->web_ui();
+ FrameTreeNode* root = web_contents->GetFrameTree()->root();
+ WebUIImpl* webui = root->current_frame_host()->web_ui();
EXPECT_TRUE(webui);
- EXPECT_FALSE(web_contents->GetRenderManagerForTesting()->pending_web_ui());
+ EXPECT_FALSE(
+ web_contents->GetRenderManagerForTesting()->GetNavigatingWebUI());
- // Navigate to another WebUI URL that reuses the WebUI object. Make sure we
- // clear pending_web_ui() when it commits.
+ // Navigate to another WebUI URL that reuses the WebUI object. Make sure we
+ // clear GetNavigatingWebUI() when it commits.
GURL webui_url2(webui_url.spec() + "#foo");
NavigateToURL(shell(), webui_url2);
- EXPECT_EQ(webui, web_contents->GetRenderManagerForTesting()->web_ui());
- EXPECT_FALSE(web_contents->GetRenderManagerForTesting()->pending_web_ui());
+ EXPECT_EQ(webui, root->current_frame_host()->web_ui());
+ EXPECT_FALSE(
+ web_contents->GetRenderManagerForTesting()->GetNavigatingWebUI());
}
class RFHMProcessPerTabTest : public RenderFrameHostManagerTest {
@@ -1640,9 +1847,9 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, WebUIGetsBindings) {
}
// crbug.com/424526
-// The test loads a WebUI page in rocess-per-tab mode, then navigates to a blank
-// page and then to a regular page. The bug reproduces if blank page is visited
-// in between WebUI and regular page.
+// The test loads a WebUI page in process-per-tab mode, then navigates to a
+// blank page and then to a regular page. The bug reproduces if blank page is
+// visited in between WebUI and regular page.
IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
ForceSwapAfterWebUIBindings) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
@@ -1651,14 +1858,20 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
const GURL web_ui_url(std::string(kChromeUIScheme) + "://" +
std::string(kChromeUIGpuHost));
- NavigateToURL(shell(), web_ui_url);
+ EXPECT_TRUE(NavigateToURL(shell(), web_ui_url));
EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
shell()->web_contents()->GetRenderProcessHost()->GetID()));
- NavigateToURL(shell(), GURL(url::kAboutBlankURL));
+ // Capture the SiteInstance before navigating to about:blank to ensure
+ // it doesn't change.
+ scoped_refptr<SiteInstance> orig_site_instance(
+ shell()->web_contents()->GetSiteInstance());
+
+ EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
+ EXPECT_NE(orig_site_instance, shell()->web_contents()->GetSiteInstance());
GURL regular_page_url(embedded_test_server()->GetURL("/title2.html"));
- NavigateToURL(shell(), regular_page_url);
+ EXPECT_TRUE(NavigateToURL(shell(), regular_page_url));
EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
shell()->web_contents()->GetRenderProcessHost()->GetID()));
}
@@ -1705,7 +1918,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
file = file.AppendASCII("bar");
// Navigate to url and get it to reference a file in its PageState.
- GURL url1(test_server()->GetURL("files/file_input.html"));
+ GURL url1(embedded_test_server()->GetURL("/file_input.html"));
NavigateToURL(shell(), url1);
int process_id = shell()->web_contents()->GetRenderProcessHost()->GetID();
scoped_ptr<FileChooserDelegate> delegate(new FileChooserDelegate(file));
@@ -1721,7 +1934,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
RenderProcessHostWatcher exit_observer(
shell()->web_contents()->GetRenderProcessHost(),
RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
- NavigateToURL(shell(), GetCrossSiteURL("files/title1.html"));
+ NavigateToURL(shell(), GetCrossSiteURL("/title1.html"));
exit_observer.Wait();
EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
shell()->web_contents()->GetRenderProcessHost()->GetID(), file));
@@ -1749,7 +1962,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Navigate to a same site page to trigger a PageState update and ensure the
// renderer is not killed.
EXPECT_TRUE(
- NavigateToURL(shell(), test_server()->GetURL("files/title2.html")));
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")));
}
// Test for http://crbug.com/441966.
@@ -1761,7 +1974,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
file = file.AppendASCII("bar");
// Navigate to url and get it to reference a file in its PageState.
- GURL url1(test_server()->GetURL("files/file_input_subframe.html"));
+ GURL url1(embedded_test_server()->GetURL("/file_input_subframe.html"));
NavigateToURL(shell(), url1);
WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
FrameTreeNode* root = wc->GetFrameTree()->root();
@@ -1779,7 +1992,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
RenderProcessHostWatcher exit_observer(
shell()->web_contents()->GetRenderProcessHost(),
RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
- NavigateToURL(shell(), GetCrossSiteURL("files/title1.html"));
+ NavigateToURL(shell(), GetCrossSiteURL("/title1.html"));
exit_observer.Wait();
EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
shell()->web_contents()->GetRenderProcessHost()->GetID(), file));
@@ -1860,7 +2073,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root();
- int32 orig_site_instance_id =
+ int32_t orig_site_instance_id =
root->current_frame_host()->GetSiteInstance()->GetId();
int initial_process_id =
root->current_frame_host()->GetSiteInstance()->GetProcess()->GetID();
@@ -2076,5 +2289,175 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_EQ(expected_url.spec(), result);
}
+// Tests that going back to the same SiteInstance as a pending RenderFrameHost
+// doesn't create a duplicate RenderFrameProxyHost. For example:
+// 1. Navigate to a page on the opener site - a.com
+// 2. Navigate to a page on site b.com
+// 3. Start a navigation to another page on a.com, but commit is delayed.
+// 4. Go back.
+// See https://crbug.com/541619.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ PopupPendingAndBackToSameSiteInstance) {
+ StartEmbeddedServer();
+ GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ NavigateToURL(shell(), main_url);
+
+ // Open a popup to navigate.
+ Shell* new_shell =
+ OpenPopup(shell()->web_contents(), GURL(url::kAboutBlankURL), "foo");
+ EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
+ new_shell->web_contents()->GetSiteInstance());
+
+ // Navigate the popup to a different site.
+ NavigateToURL(new_shell,
+ embedded_test_server()->GetURL("b.com", "/title2.html"));
+
+ // Navigate again to the original site, but to a page that will take a while
+ // to commit.
+ GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
+ NavigationStallDelegate stall_delegate(same_site_url);
+ ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ new_shell->LoadURL(same_site_url);
+
+ // Going back in history should work and the test should not crash.
+ TestNavigationObserver back_nav_load_observer(new_shell->web_contents());
+ new_shell->web_contents()->GetController().GoBack();
+ back_nav_load_observer.Wait();
+
+ ResourceDispatcherHost::Get()->SetDelegate(nullptr);
+}
+
+// Tests that InputMsg type IPCs are ignored by swapped out RenderViews. It
+// uses the SetFocus IPC, as RenderView has a CHECK to ensure that condition
+// never happens.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ InputMsgToSwappedOutRVHIsIgnored) {
+ StartEmbeddedServer();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
+
+ // Open a popup to navigate cross-process.
+ Shell* new_shell =
+ OpenPopup(shell()->web_contents(), GURL(url::kAboutBlankURL), "foo");
+ EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
+ new_shell->web_contents()->GetSiteInstance());
+
+ // Keep a pointer to the RenderViewHost, which will be in swapped out
+ // state after navigating cross-process. This is how this test is causing
+ // a swapped out RenderView to receive InputMsg IPC message.
+ WebContentsImpl* new_web_contents =
+ static_cast<WebContentsImpl*>(new_shell->web_contents());
+ FrameTreeNode* new_root = new_web_contents->GetFrameTree()->root();
+ RenderViewHostImpl* rvh = new_web_contents->GetRenderViewHost();
+
+ // Navigate the popup to a different site, so the |rvh| is swapped out.
+ EXPECT_TRUE(NavigateToURL(
+ new_shell, embedded_test_server()->GetURL("b.com", "/title2.html")));
+ EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
+ new_shell->web_contents()->GetSiteInstance());
+ EXPECT_EQ(rvh, new_root->render_manager()->GetSwappedOutRenderViewHost(
+ shell()->web_contents()->GetSiteInstance()));
+
+ // Setup a process observer to ensure there is no crash and send the IPC
+ // message.
+ RenderProcessHostWatcher watcher(
+ rvh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ rvh->Send(new InputMsg_SetFocus(rvh->GetRoutingID(), true));
+
+ // The test must wait for a process to exit, but if the IPC message is
+ // properly ignored, there will be no crash. Therefore, navigate the
+ // original window to the same site as the popup, which will just exit the
+ // process cleanly.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("b.com", "/title3.html")));
+ watcher.Wait();
+ EXPECT_TRUE(watcher.did_exit_normally());
+}
+
+// Tests that navigating cross-process and reusing an existing RenderViewHost
+// (whose process has been killed/crashed) recreates properly the RenderView and
+// RenderFrameProxy on the renderer side.
+// See https://crbug.com/544271
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ RenderViewInitAfterProcessKill) {
+ StartEmbeddedServer();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
+
+ // Open a popup to navigate.
+ Shell* new_shell =
+ OpenPopup(shell()->web_contents(), GURL(url::kAboutBlankURL), "foo");
+ FrameTreeNode* popup_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
+ new_shell->web_contents()->GetSiteInstance());
+
+ // Navigate the popup to a different site.
+ EXPECT_TRUE(NavigateToURL(
+ new_shell, embedded_test_server()->GetURL("b.com", "/title2.html")));
+ EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
+ new_shell->web_contents()->GetSiteInstance());
+
+ // Kill the process hosting the popup.
+ RenderProcessHost* process = popup_root->current_frame_host()->GetProcess();
+ RenderProcessHostWatcher crash_observer(
+ process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ process->Shutdown(0, false);
+ crash_observer.Wait();
+ EXPECT_FALSE(popup_root->current_frame_host()->IsRenderFrameLive());
+ EXPECT_FALSE(
+ popup_root->current_frame_host()->render_view_host()->IsRenderViewLive());
+
+ // Navigate the main tab to the site of the popup. This will cause the
+ // RenderView for b.com in the main tab to be recreated. If the issue
+ // is not fixed, this will result in process crash and failing test.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("b.com", "/title3.html")));
+}
+
+// Ensure that we use the same pending RenderFrameHost if a second navigation to
+// its site occurs before it commits. Otherwise the renderer process will have
+// two competing pending RenderFrames that both try to swap with the same
+// RenderFrameProxy. See https://crbug.com/545900.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ ConsecutiveNavigationsToSite) {
+ StartEmbeddedServer();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
+
+ // Open a popup and navigate it to b.com to keep the b.com process alive.
+ Shell* new_shell =
+ OpenPopup(shell()->web_contents(), GURL(url::kAboutBlankURL), "popup");
+ NavigateToURL(new_shell,
+ embedded_test_server()->GetURL("b.com", "/title3.html"));
+
+ // Start a cross-site navigation to the same site but don't commit.
+ GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
+ NavigationStallDelegate stall_delegate(cross_site_url);
+ ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ shell()->LoadURL(cross_site_url);
+
+ WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
+ shell()->web_contents());
+ RenderFrameHostImpl* pending_rfh =
+ web_contents->GetRenderManagerForTesting()->pending_frame_host();
+ ASSERT_TRUE(pending_rfh);
+
+ // Navigate to the same new site and verify that we commit in the same RFH.
+ GURL cross_site_url2(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ TestNavigationObserver navigation_observer(web_contents, 1);
+ shell()->LoadURL(cross_site_url2);
+ EXPECT_EQ(pending_rfh,
+ web_contents->GetRenderManagerForTesting()->pending_frame_host());
+ navigation_observer.Wait();
+ EXPECT_EQ(cross_site_url2, web_contents->GetLastCommittedURL());
+ EXPECT_EQ(pending_rfh, web_contents->GetMainFrame());
+ EXPECT_FALSE(
+ web_contents->GetRenderManagerForTesting()->pending_frame_host());
+
+ ResourceDispatcherHost::Get()->SetDelegate(nullptr);
+}
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc b/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc
index a6d04cde898..e6e53607689 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -2,22 +2,29 @@
// 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_manager.h"
+
+#include <stdint.h>
+#include <utility>
+
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/histogram_tester.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/compositor/test/no_transport_image_transport_factory.h"
#include "content/browser/frame_host/cross_site_transferring_request.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigation_request.h"
#include "content/browser/frame_host/navigator.h"
-#include "content/browser/frame_host/render_frame_host_manager.h"
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/frame_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
#include "content/public/browser/notification_details.h"
@@ -30,13 +37,14 @@
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/common/bindings_policy.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/javascript_message_type.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#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/browser_side_navigation_test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
#include "content/test/test_render_frame_host.h"
@@ -44,17 +52,48 @@
#include "content/test/test_web_contents.h"
#include "net/base/load_flags.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
#include "third_party/WebKit/public/web/WebSandboxFlags.h"
#include "ui/base/page_transition_types.h"
namespace content {
namespace {
+// Helper to check that the provided RenderProcessHost received exactly one
+// page focus message with the provided focus and routing ID values.
+void VerifyPageFocusMessage(MockRenderProcessHost* rph,
+ bool expected_focus,
+ int expected_routing_id) {
+ const IPC::Message* message =
+ rph->sink().GetUniqueMessageMatching(InputMsg_SetFocus::ID);
+ EXPECT_TRUE(message);
+ EXPECT_EQ(expected_routing_id, message->routing_id());
+ InputMsg_SetFocus::Param params;
+ EXPECT_TRUE(InputMsg_SetFocus::Read(message, &params));
+ EXPECT_EQ(expected_focus, base::get<0>(params));
+}
+
+// Helper function for strict mixed content checking tests.
+void CheckMixedContentIPC(TestRenderFrameHost* rfh,
+ bool expected_param,
+ int expected_routing_id) {
+ const IPC::Message* message =
+ rfh->GetProcess()->sink().GetUniqueMessageMatching(
+ FrameMsg_EnforceStrictMixedContentChecking::ID);
+ ASSERT_TRUE(message);
+ EXPECT_EQ(expected_routing_id, message->routing_id());
+ FrameMsg_EnforceStrictMixedContentChecking::Param params;
+ EXPECT_TRUE(
+ FrameMsg_EnforceStrictMixedContentChecking::Read(message, &params));
+ EXPECT_EQ(expected_param, base::get<0>(params));
+}
+
class RenderFrameHostManagerTestWebUIControllerFactory
: public WebUIControllerFactory {
public:
RenderFrameHostManagerTestWebUIControllerFactory()
- : should_create_webui_(false) {
+ : should_create_webui_(false), type_(1) {
+ CHECK_NE(reinterpret_cast<WebUI::TypeID>(type_), WebUI::kNoWebUI);
}
~RenderFrameHostManagerTestWebUIControllerFactory() override {}
@@ -62,16 +101,34 @@ class RenderFrameHostManagerTestWebUIControllerFactory
should_create_webui_ = should_create_webui;
}
+ // This method simulates the expectation that different WebUI instance types
+ // would be created. The |type| value will be returned by GetWebUIType casted
+ // to WebUI::TypeID.
+ // As WebUI::TypeID is a typedef to void pointer, factory implementations
+ // return values that they know to be unique to their respective cases. So
+ // values set here should be safe if kept very low (just above zero).
+ void set_webui_type(uintptr_t type) {
+ CHECK_NE(reinterpret_cast<WebUI::TypeID>(type), WebUI::kNoWebUI);
+ type_ = type;
+ }
+
// WebUIFactory implementation.
WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
const GURL& url) const override {
- if (!(should_create_webui_ && HasWebUIScheme(url)))
- return NULL;
- return new WebUIController(web_ui);
+ // If WebUI creation is enabled for the test and this is a WebUI URL,
+ // returns a new instance.
+ if (should_create_webui_ && HasWebUIScheme(url))
+ return new WebUIController(web_ui);
+ return nullptr;
}
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const override {
+ // If WebUI creation is enabled for the test and this is a WebUI URL,
+ // returns a mock WebUI type.
+ if (should_create_webui_ && HasWebUIScheme(url)) {
+ return reinterpret_cast<WebUI::TypeID>(type_);
+ }
return WebUI::kNoWebUI;
}
@@ -87,6 +144,7 @@ class RenderFrameHostManagerTestWebUIControllerFactory
private:
bool should_create_webui_;
+ uintptr_t type_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManagerTestWebUIControllerFactory);
};
@@ -264,6 +322,8 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
factory_.set_should_create_webui(should_create_webui);
}
+ void set_webui_type(int type) { factory_.set_webui_type(type); }
+
void NavigateActiveAndCommit(const GURL& url) {
// Note: we navigate the active RenderFrameHost because previous navigations
// won't have committed yet, so NavigateAndCommit does the wrong thing
@@ -290,8 +350,8 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, old_rfh->rfh_state());
// Commit the navigation with a new page ID.
- int32 max_page_id = contents()->GetMaxPageIDForSiteInstance(
- active_rfh->GetSiteInstance());
+ int32_t max_page_id =
+ contents()->GetMaxPageIDForSiteInstance(active_rfh->GetSiteInstance());
// Use an observer to avoid accessing a deleted renderer later on when the
// state is being checked.
@@ -370,7 +430,7 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
// Manually increase the number of active frames in the
// SiteInstance that ntp_rfh belongs to, to prevent it from being
// destroyed when it gets swapped out.
- ntp_rfh->GetSiteInstance()->increment_active_frame_count();
+ ntp_rfh->GetSiteInstance()->IncrementActiveFrameCount();
TestRenderFrameHost* dest_rfh = contents()->GetPendingMainFrame();
CHECK(dest_rfh);
@@ -393,14 +453,29 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
const NavigationEntryImpl& entry) {
// Tests currently only navigate using main frame FrameNavigationEntries.
FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
+ NavigationControllerImpl* controller =
+ static_cast<NavigationControllerImpl*>(manager->current_frame_host()
+ ->frame_tree_node()
+ ->navigator()
+ ->GetController());
+ // TODO(carlosk): This implementation below will not work with restore
+ // navigations. Method GetNavigationType should be exposed from
+ // navigator_impl.cc and used here to determine FrameMsg_Navigate_Type.
+ CHECK(entry.restore_type() == NavigationEntryImpl::RESTORE_NONE);
scoped_ptr<NavigationRequest> navigation_request =
NavigationRequest::CreateBrowserInitiated(
manager->frame_tree_node_, frame_entry->url(),
frame_entry->referrer(), *frame_entry, entry,
FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
- static_cast<NavigationControllerImpl*>(&controller()));
+ controller);
+
+ // Simulates request creation that triggers the 1st internal call to
+ // GetFrameHostForNavigation.
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // And also simulates the 2nd and final call to GetFrameHostForNavigation
+ // that determines the final frame that will commit the navigation.
TestRenderFrameHost* frame_host = static_cast<TestRenderFrameHost*>(
manager->GetFrameHostForNavigation(*navigation_request));
CHECK(frame_host);
@@ -415,10 +490,9 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
// PlzNavigate: returns the speculative RenderFrameHost.
RenderFrameHostImpl* GetPendingFrameHost(
RenderFrameHostManager* manager) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
return manager->speculative_render_frame_host_.get();
- }
+
return manager->pending_frame_host();
}
@@ -431,6 +505,19 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
nodes_with_back_links);
}
+ void BaseSimultaneousNavigationWithOneWebUI(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda);
+
+ void BaseSimultaneousNavigationWithTwoWebUIs(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda);
+
private:
RenderFrameHostManagerTestWebUIControllerFactory factory_;
};
@@ -522,15 +609,15 @@ TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
// Send an update favicon message and make sure it works.
{
PluginFaviconMessageObserver observer(contents());
- EXPECT_TRUE(ntp_rfh->GetRenderViewHost()->OnMessageReceived(
- ViewHostMsg_UpdateFaviconURL(
- ntp_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
+ EXPECT_TRUE(ntp_rfh->GetRenderViewHost()->GetWidget()->OnMessageReceived(
+ ViewHostMsg_UpdateFaviconURL(
+ ntp_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
EXPECT_TRUE(observer.favicon_received());
}
// Create one more frame in the same SiteInstance where ntp_rfh
// exists so that it doesn't get deleted on navigation to another
// site.
- ntp_rfh->GetSiteInstance()->increment_active_frame_count();
+ ntp_rfh->GetSiteInstance()->IncrementActiveFrameCount();
// Navigate to a cross-site URL.
NavigateActiveAndCommit(kDestUrl);
@@ -541,10 +628,9 @@ TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
// The new RVH should be able to update its favicon.
{
PluginFaviconMessageObserver observer(contents());
- EXPECT_TRUE(
- dest_rfh->GetRenderViewHost()->OnMessageReceived(
- ViewHostMsg_UpdateFaviconURL(
- dest_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
+ EXPECT_TRUE(dest_rfh->GetRenderViewHost()->GetWidget()->OnMessageReceived(
+ ViewHostMsg_UpdateFaviconURL(
+ dest_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
EXPECT_TRUE(observer.favicon_received());
}
@@ -553,9 +639,8 @@ TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
{
PluginFaviconMessageObserver observer(contents());
EXPECT_TRUE(
- ntp_rvh->OnMessageReceived(
- ViewHostMsg_UpdateFaviconURL(
- dest_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
+ ntp_rvh->GetWidget()->OnMessageReceived(ViewHostMsg_UpdateFaviconURL(
+ dest_rfh->GetRenderViewHost()->GetRoutingID(), icons)));
EXPECT_FALSE(observer.favicon_received());
}
@@ -620,15 +705,15 @@ TEST_F(RenderFrameHostManagerTest, UpdateFaviconURLWhilePendingSwapOut) {
// Send an update favicon message and make sure it works.
{
PluginFaviconMessageObserver observer(contents());
- EXPECT_TRUE(rfh1->GetRenderViewHost()->OnMessageReceived(
- ViewHostMsg_UpdateFaviconURL(
- rfh1->GetRenderViewHost()->GetRoutingID(), icons)));
+ EXPECT_TRUE(rfh1->GetRenderViewHost()->GetWidget()->OnMessageReceived(
+ ViewHostMsg_UpdateFaviconURL(rfh1->GetRenderViewHost()->GetRoutingID(),
+ icons)));
EXPECT_TRUE(observer.favicon_received());
}
// Create one more frame in the same SiteInstance where |rfh1| exists so that
// it doesn't get deleted on navigation to another site.
- rfh1->GetSiteInstance()->increment_active_frame_count();
+ rfh1->GetSiteInstance()->IncrementActiveFrameCount();
// Navigate to a cross-site URL and commit the new page.
controller().LoadURL(
@@ -644,7 +729,7 @@ TEST_F(RenderFrameHostManagerTest, UpdateFaviconURLWhilePendingSwapOut) {
// The new RVH should be able to update its favicons.
{
PluginFaviconMessageObserver observer(contents());
- EXPECT_TRUE(rfh2->GetRenderViewHost()->OnMessageReceived(
+ EXPECT_TRUE(rfh2->GetRenderViewHost()->GetWidget()->OnMessageReceived(
ViewHostMsg_UpdateFaviconURL(rfh2->GetRenderViewHost()->GetRoutingID(),
icons)));
EXPECT_TRUE(observer.favicon_received());
@@ -654,7 +739,7 @@ TEST_F(RenderFrameHostManagerTest, UpdateFaviconURLWhilePendingSwapOut) {
// be ignored.
{
PluginFaviconMessageObserver observer(contents());
- EXPECT_TRUE(rfh1->GetRenderViewHost()->OnMessageReceived(
+ EXPECT_TRUE(rfh1->GetRenderViewHost()->GetWidget()->OnMessageReceived(
ViewHostMsg_UpdateFaviconURL(rfh1->GetRenderViewHost()->GetRoutingID(),
icons)));
EXPECT_FALSE(observer.favicon_received());
@@ -683,14 +768,14 @@ TEST_F(RenderFrameHostManagerTest, DropCreateChildFrameWhileSwappedOut) {
initial_rfh->OnCreateChildFrame(
initial_rfh->GetProcess()->GetNextRoutingID(),
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
EXPECT_TRUE(observer.created());
}
// Create one more frame in the same SiteInstance where initial_rfh
// exists so that initial_rfh doesn't get deleted on navigation to another
// site.
- initial_rfh->GetSiteInstance()->increment_active_frame_count();
+ initial_rfh->GetSiteInstance()->IncrementActiveFrameCount();
// Navigate to a cross-site URL.
NavigateActiveAndCommit(kUrl2);
@@ -707,7 +792,7 @@ TEST_F(RenderFrameHostManagerTest, DropCreateChildFrameWhileSwappedOut) {
initial_rfh->OnCreateChildFrame(
initial_rfh->GetProcess()->GetNextRoutingID(),
blink::WebTreeScopeType::Document, std::string(),
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
EXPECT_FALSE(observer.created());
}
}
@@ -721,7 +806,7 @@ TEST_F(RenderFrameHostManagerTest, WhiteListSwapCompositorFrame) {
TestRenderFrameHost* swapped_out_rfh = CreateSwappedOutRenderFrameHost();
TestRenderWidgetHostView* swapped_out_rwhv =
static_cast<TestRenderWidgetHostView*>(
- swapped_out_rfh->GetRenderViewHost()->GetView());
+ swapped_out_rfh->GetRenderViewHost()->GetWidget()->GetView());
EXPECT_FALSE(swapped_out_rwhv->did_swap_compositor_frame());
MockRenderProcessHost* process_host = swapped_out_rfh->GetProcess();
@@ -731,7 +816,8 @@ TEST_F(RenderFrameHostManagerTest, WhiteListSwapCompositorFrame) {
ViewHostMsg_SwapCompositorFrame msg(
rvh()->GetRoutingID(), 0, frame, std::vector<IPC::Message>());
- EXPECT_TRUE(swapped_out_rfh->render_view_host()->OnMessageReceived(msg));
+ EXPECT_TRUE(
+ swapped_out_rfh->render_view_host()->GetWidget()->OnMessageReceived(msg));
EXPECT_TRUE(swapped_out_rwhv->did_swap_compositor_frame());
}
@@ -923,7 +1009,7 @@ TEST_F(RenderFrameHostManagerTest, AlwaysSendEnableViewSourceMode) {
ASSERT_TRUE(contents()->GetPendingMainFrame())
<< "Expected new pending RenderFrameHost to be created.";
RenderFrameHost* last_rfh = contents()->GetPendingMainFrame();
- int32 new_id =
+ int32_t new_id =
contents()->GetMaxPageIDForSiteInstance(last_rfh->GetSiteInstance()) + 1;
contents()->GetPendingMainFrame()->SendNavigate(new_id, entry_id, true, kUrl);
@@ -1073,7 +1159,7 @@ TEST_F(RenderFrameHostManagerTest, WebUI) {
RenderFrameHostImpl* initial_rfh = manager->current_frame_host();
EXPECT_FALSE(manager->current_host()->IsRenderViewLive());
- EXPECT_FALSE(manager->web_ui());
+ EXPECT_FALSE(manager->current_frame_host()->web_ui());
EXPECT_TRUE(initial_rfh);
const GURL kUrl("chrome://foo");
@@ -1100,13 +1186,18 @@ TEST_F(RenderFrameHostManagerTest, WebUI) {
// The Web UI is committed immediately because the RenderViewHost has not been
// used yet. UpdateStateForNavigate() took the short cut path.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
- EXPECT_FALSE(manager->speculative_web_ui());
+ if (IsBrowserSideNavigationEnabled()) {
+ // In PlzNavigate, there will be a navigating WebUI because
+ // GetFrameHostForNavigation was already called twice and the committed
+ // WebUI should be set to be reused.
+ EXPECT_TRUE(manager->GetNavigatingWebUI());
+ EXPECT_EQ(host->web_ui(), manager->GetNavigatingWebUI());
+ EXPECT_EQ(host->web_ui(), host->pending_web_ui());
} else {
- EXPECT_FALSE(manager->pending_web_ui());
+ // The WebUI was immediately committed and there should be none navigating.
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
}
- EXPECT_TRUE(manager->web_ui());
+ EXPECT_TRUE(manager->current_frame_host()->web_ui());
// Commit.
manager->DidNavigateFrame(host, true);
@@ -1175,12 +1266,8 @@ TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) {
// No cross-process transition happens because we are already in the right
// SiteInstance. We should grant bindings immediately.
EXPECT_EQ(host2, manager2->current_frame_host());
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
- EXPECT_TRUE(manager2->speculative_web_ui());
- } else {
- EXPECT_TRUE(manager2->pending_web_ui());
- }
+ EXPECT_TRUE(manager2->GetNavigatingWebUI());
+ EXPECT_FALSE(host2->web_ui());
EXPECT_TRUE(
host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
@@ -1194,16 +1281,14 @@ TEST_F(RenderFrameHostManagerTest, WebUIWasReused) {
// Navigate to a WebUI page.
const GURL kUrl1("chrome://foo");
contents()->NavigateAndCommit(kUrl1);
- RenderFrameHostManager* manager =
- main_test_rfh()->frame_tree_node()->render_manager();
- WebUIImpl* web_ui = manager->web_ui();
+ WebUIImpl* web_ui = main_test_rfh()->web_ui();
EXPECT_TRUE(web_ui);
// Navigate to another WebUI page which should be same-site and keep the
// current WebUI.
const GURL kUrl2("chrome://foo/bar");
contents()->NavigateAndCommit(kUrl2);
- EXPECT_EQ(web_ui, manager->web_ui());
+ EXPECT_EQ(web_ui, main_test_rfh()->web_ui());
}
// Tests that a WebUI is correctly cleaned up when navigating from a chrome://
@@ -1214,12 +1299,12 @@ TEST_F(RenderFrameHostManagerTest, WebUIWasCleared) {
// Navigate to a WebUI page.
const GURL kUrl1("chrome://foo");
contents()->NavigateAndCommit(kUrl1);
- EXPECT_TRUE(main_test_rfh()->frame_tree_node()->render_manager()->web_ui());
+ EXPECT_TRUE(main_test_rfh()->web_ui());
// Navigate to a non-WebUI page.
const GURL kUrl2("http://www.google.com");
contents()->NavigateAndCommit(kUrl2);
- EXPECT_FALSE(main_test_rfh()->frame_tree_node()->render_manager()->web_ui());
+ EXPECT_FALSE(main_test_rfh()->web_ui());
}
// Tests that we don't end up in an inconsistent state if a page does a back and
@@ -1227,8 +1312,7 @@ TEST_F(RenderFrameHostManagerTest, WebUIWasCleared) {
// Also tests that only user-gesture navigations can interrupt cross-process
// navigations. http://crbug.com/75195
TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
// PlzNavigate uses a significantly different logic for renderer initiated
// navigations and navigation cancellation. Adapting this test would make it
// full of special cases and almost unreadable.
@@ -1333,11 +1417,11 @@ TEST_F(RenderFrameHostManagerTest, NavigateAfterMissingSwapOutACK) {
// Keep active_frame_count nonzero so that no swapped out frames in
// this SiteInstance get forcefully deleted.
- rfh1->GetSiteInstance()->increment_active_frame_count();
+ rfh1->GetSiteInstance()->IncrementActiveFrameCount();
contents()->NavigateAndCommit(kUrl2);
TestRenderFrameHost* rfh2 = main_test_rfh();
- rfh2->GetSiteInstance()->increment_active_frame_count();
+ rfh2->GetSiteInstance()->IncrementActiveFrameCount();
// Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't
// happen, but we have seen it when going back quickly across many entries
@@ -1818,8 +1902,9 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyClose) {
EXPECT_EQ(host2, GetPendingFrameHost(manager));
// 3) Close the tab. -------------------------
- notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
- Source<RenderWidgetHost>(host2->render_view_host()));
+ notifications.ListenFor(
+ NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
+ Source<RenderWidgetHost>(host2->render_view_host()->GetWidget()));
manager->OnBeforeUnloadACK(false, true, base::TimeTicks());
EXPECT_TRUE(
@@ -1846,14 +1931,12 @@ TEST_F(RenderFrameHostManagerTest, CloseWithPendingWhileUnresponsive) {
// Start a navigation to a new site.
controller().LoadURL(
kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
rfh1->PrepareForCommit();
- }
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
// Simulate the unresponsiveness timer. The tab should close.
- contents()->RendererUnresponsive(rfh1->render_view_host());
+ contents()->RendererUnresponsive(rfh1->render_view_host()->GetWidget());
EXPECT_TRUE(close_delegate.is_closed());
}
@@ -1918,7 +2001,7 @@ TEST_F(RenderFrameHostManagerTest, SwapOutFrameAfterSwapOutACK) {
// Increment the number of active frames in SiteInstanceImpl so that rfh1 is
// not deleted on swap out.
- rfh1->GetSiteInstance()->increment_active_frame_count();
+ rfh1->GetSiteInstance()->IncrementActiveFrameCount();
// Navigate to new site, simulating onbeforeunload approval.
controller().LoadURL(
@@ -1968,7 +2051,7 @@ TEST_F(RenderFrameHostManagerTest,
// Increment the number of active frames in SiteInstanceImpl so that rfh1 is
// not deleted on swap out.
scoped_refptr<SiteInstanceImpl> site_instance = rfh1->GetSiteInstance();
- site_instance->increment_active_frame_count();
+ site_instance->IncrementActiveFrameCount();
// Navigate to new site, simulating onbeforeunload approval.
controller().LoadURL(
@@ -2044,7 +2127,7 @@ TEST_F(RenderFrameHostManagerTest,
// created.
scoped_refptr<SiteInstanceImpl> site_instance =
pending_rfh->GetSiteInstance();
- site_instance->increment_active_frame_count();
+ site_instance->IncrementActiveFrameCount();
contents()->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, false, now, now));
@@ -2080,11 +2163,11 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation, DetachPendingChild) {
contents()->GetMainFrame()->OnCreateChildFrame(
contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(),
blink::WebTreeScopeType::Document, "frame_name",
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
contents()->GetMainFrame()->OnCreateChildFrame(
contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(),
blink::WebTreeScopeType::Document, "frame_name",
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
RenderFrameHostManager* root_manager =
contents()->GetFrameTree()->root()->render_manager();
RenderFrameHostManager* iframe1 =
@@ -2221,7 +2304,7 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation,
contents1->GetMainFrame()->OnCreateChildFrame(
contents1->GetMainFrame()->GetProcess()->GetNextRoutingID(),
blink::WebTreeScopeType::Document, "frame_name",
- blink::WebSandboxFlags::None);
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
RenderFrameHostManager* iframe =
contents()->GetFrameTree()->root()->child_at(0)->render_manager();
NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl2,
@@ -2252,6 +2335,53 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation,
iframe->GetRenderFrameProxyHost(contents2->GetSiteInstance()));
}
+// Ensure that we don't grant WebUI bindings to a pending RenderViewHost when
+// creating proxies for a non-WebUI subframe navigation. This was possible due
+// to the InitRenderView call from CreateRenderFrameProxy.
+// See https://crbug.com/536145.
+TEST_F(RenderFrameHostManagerTestWithSiteIsolation,
+ DontGrantPendingWebUIToSubframe) {
+ set_should_create_webui(true);
+
+ // Make sure the initial process is live so that the pending WebUI navigation
+ // does not commit immediately. Give the page a subframe as well.
+ const GURL kUrl1("http://foo.com");
+ RenderFrameHostImpl* main_rfh = contents()->GetMainFrame();
+ NavigateAndCommit(kUrl1);
+ EXPECT_TRUE(main_rfh->render_view_host()->IsRenderViewLive());
+ EXPECT_TRUE(main_rfh->IsRenderFrameLive());
+ main_rfh->OnCreateChildFrame(main_rfh->GetProcess()->GetNextRoutingID(),
+ blink::WebTreeScopeType::Document, std::string(),
+ blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
+ RenderFrameHostManager* subframe_rfhm =
+ contents()->GetFrameTree()->root()->child_at(0)->render_manager();
+
+ // Start a pending WebUI navigation in the main frame and verify that the
+ // pending RVH has bindings.
+ const GURL kWebUIUrl("chrome://foo");
+ NavigationEntryImpl webui_entry(
+ nullptr /* instance */, -1 /* page_id */, kWebUIUrl, Referrer(),
+ base::string16() /* title */, ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ RenderFrameHostManager* main_rfhm = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* webui_rfh = NavigateToEntry(main_rfhm, webui_entry);
+ EXPECT_EQ(webui_rfh, GetPendingFrameHost(main_rfhm));
+ EXPECT_TRUE(webui_rfh->render_view_host()->GetEnabledBindings() &
+ BINDINGS_POLICY_WEB_UI);
+
+ // Before it commits, do a cross-process navigation in a subframe. This
+ // should not grant WebUI bindings to the subframe's RVH.
+ const GURL kSubframeUrl("http://bar.com");
+ NavigationEntryImpl subframe_entry(
+ nullptr /* instance */, -1 /* page_id */, kSubframeUrl, Referrer(),
+ base::string16() /* title */, ui::PAGE_TRANSITION_LINK,
+ false /* is_renderer_init */);
+ RenderFrameHostImpl* bar_rfh = NavigateToEntry(subframe_rfhm, subframe_entry);
+ EXPECT_FALSE(bar_rfh->render_view_host()->GetEnabledBindings() &
+ BINDINGS_POLICY_WEB_UI);
+}
+
// Test that opener proxies are created properly with a cycle on the opener
// chain.
TEST_F(RenderFrameHostManagerTest, CreateOpenerProxiesWithCycleOnOpenerChain) {
@@ -2377,23 +2507,29 @@ TEST_F(RenderFrameHostManagerTest, CreateOpenerProxiesWhenOpenerPointsToSelf) {
// set separately in a second pass, since their opener routing IDs won't be
// available during the first pass of CreateOpenerProxies.
TEST_F(RenderFrameHostManagerTest, TraverseComplexOpenerChain) {
+ contents()->NavigateAndCommit(GURL("http://tab1.com"));
FrameTree* tree1 = contents()->GetFrameTree();
FrameTreeNode* root1 = tree1->root();
int process_id = root1->current_frame_host()->GetProcess()->GetID();
tree1->AddFrame(root1, process_id, 12, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
tree1->AddFrame(root1, process_id, 13, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
scoped_ptr<TestWebContents> tab2(
TestWebContents::Create(browser_context(), nullptr));
+ tab2->NavigateAndCommit(GURL("http://tab2.com"));
FrameTree* tree2 = tab2->GetFrameTree();
FrameTreeNode* root2 = tree2->root();
process_id = root2->current_frame_host()->GetProcess()->GetID();
tree2->AddFrame(root2, process_id, 22, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
tree2->AddFrame(root2, process_id, 23, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
scoped_ptr<TestWebContents> tab3(
TestWebContents::Create(browser_context(), nullptr));
@@ -2402,11 +2538,13 @@ TEST_F(RenderFrameHostManagerTest, TraverseComplexOpenerChain) {
scoped_ptr<TestWebContents> tab4(
TestWebContents::Create(browser_context(), nullptr));
+ tab4->NavigateAndCommit(GURL("http://tab4.com"));
FrameTree* tree4 = tab4->GetFrameTree();
FrameTreeNode* root4 = tree4->root();
process_id = root4->current_frame_host()->GetProcess()->GetID();
tree4->AddFrame(root4, process_id, 42, blink::WebTreeScopeType::Document,
- std::string(), blink::WebSandboxFlags::None);
+ std::string(), blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
root1->child_at(1)->SetOpener(root1->child_at(1));
root1->SetOpener(root2->child_at(1));
@@ -2433,4 +2571,680 @@ TEST_F(RenderFrameHostManagerTest, TraverseComplexOpenerChain) {
nodes_with_back_links.end());
}
+// Check that when a window is focused/blurred, the message that sets
+// page-level focus updates is sent to each process involved in rendering the
+// current page.
+//
+// TODO(alexmos): Move this test to FrameTree unit tests once NavigateToEntry
+// is moved to a common place. See https://crbug.com/547275.
+TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
+ // This test only makes sense when cross-site subframes use separate
+ // processes.
+ if (!AreAllSitesIsolatedForTesting())
+ return;
+
+ const GURL kUrlA("http://a.com/");
+ const GURL kUrlB("http://b.com/");
+ const GURL kUrlC("http://c.com/");
+
+ // Set up a page at a.com with three subframes: two for b.com and one for
+ // c.com.
+ contents()->NavigateAndCommit(kUrlA);
+ main_test_rfh()->OnCreateChildFrame(
+ main_test_rfh()->GetProcess()->GetNextRoutingID(),
+ blink::WebTreeScopeType::Document, "frame1",
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
+ main_test_rfh()->OnCreateChildFrame(
+ main_test_rfh()->GetProcess()->GetNextRoutingID(),
+ blink::WebTreeScopeType::Document, "frame2",
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
+ main_test_rfh()->OnCreateChildFrame(
+ main_test_rfh()->GetProcess()->GetNextRoutingID(),
+ blink::WebTreeScopeType::Document, "frame3",
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
+
+ FrameTreeNode* root = contents()->GetFrameTree()->root();
+ RenderFrameHostManager* child1 = root->child_at(0)->render_manager();
+ RenderFrameHostManager* child2 = root->child_at(1)->render_manager();
+ RenderFrameHostManager* child3 = root->child_at(2)->render_manager();
+
+ // Navigate first two subframes to B.
+ NavigationEntryImpl entryB(nullptr /* instance */, -1 /* page_id */, kUrlB,
+ Referrer(kUrlA, blink::WebReferrerPolicyDefault),
+ base::string16() /* title */,
+ ui::PAGE_TRANSITION_LINK,
+ false /* is_renderer_init */);
+ TestRenderFrameHost* host1 =
+ static_cast<TestRenderFrameHost*>(NavigateToEntry(child1, entryB));
+ TestRenderFrameHost* host2 =
+ static_cast<TestRenderFrameHost*>(NavigateToEntry(child2, entryB));
+ child1->DidNavigateFrame(host1, true);
+ child2->DidNavigateFrame(host2, true);
+
+ // Navigate the third subframe to C.
+ NavigationEntryImpl entryC(nullptr /* instance */, -1 /* page_id */, kUrlC,
+ Referrer(kUrlA, blink::WebReferrerPolicyDefault),
+ base::string16() /* title */,
+ ui::PAGE_TRANSITION_LINK,
+ false /* is_renderer_init */);
+ TestRenderFrameHost* host3 =
+ static_cast<TestRenderFrameHost*>(NavigateToEntry(child3, entryC));
+ child3->DidNavigateFrame(host3, true);
+
+ // Make sure the first two subframes and the third subframe are placed in
+ // distinct processes.
+ EXPECT_NE(host1->GetProcess(), main_test_rfh()->GetProcess());
+ EXPECT_EQ(host1->GetProcess(), host2->GetProcess());
+ EXPECT_NE(host3->GetProcess(), main_test_rfh()->GetProcess());
+ EXPECT_NE(host3->GetProcess(), host1->GetProcess());
+
+ // The main frame should have proxies for B and C.
+ RenderFrameProxyHost* proxyB =
+ root->render_manager()->GetRenderFrameProxyHost(host1->GetSiteInstance());
+ EXPECT_TRUE(proxyB);
+ RenderFrameProxyHost* proxyC =
+ root->render_manager()->GetRenderFrameProxyHost(host3->GetSiteInstance());
+ EXPECT_TRUE(proxyC);
+
+ // Focus the main page, and verify that the focus message was sent to all
+ // processes. The message to A should be sent through the main frame's
+ // RenderViewHost, and the message to B and C should be send through proxies
+ // that the main frame has for B and C.
+ main_test_rfh()->GetProcess()->sink().ClearMessages();
+ host1->GetProcess()->sink().ClearMessages();
+ host3->GetProcess()->sink().ClearMessages();
+ main_test_rfh()->GetRenderWidgetHost()->Focus();
+ VerifyPageFocusMessage(main_test_rfh()->GetProcess(), true,
+ main_test_rfh()->GetRenderViewHost()->GetRoutingID());
+ VerifyPageFocusMessage(host1->GetProcess(), true, proxyB->GetRoutingID());
+ VerifyPageFocusMessage(host3->GetProcess(), true, proxyC->GetRoutingID());
+
+ // Similarly, simulate focus loss on main page, and verify that the focus
+ // message was sent to all processes.
+ main_test_rfh()->GetProcess()->sink().ClearMessages();
+ host1->GetProcess()->sink().ClearMessages();
+ host3->GetProcess()->sink().ClearMessages();
+ main_test_rfh()->GetRenderWidgetHost()->Blur();
+ VerifyPageFocusMessage(main_test_rfh()->GetProcess(), false,
+ main_test_rfh()->GetRenderViewHost()->GetRoutingID());
+ VerifyPageFocusMessage(host1->GetProcess(), false, proxyB->GetRoutingID());
+ VerifyPageFocusMessage(host3->GetProcess(), false, proxyC->GetRoutingID());
+}
+
+// Check that page-level focus state is preserved across subframe navigations.
+//
+// TODO(alexmos): Move this test to FrameTree unit tests once NavigateToEntry
+// is moved to a common place. See https://crbug.com/547275.
+TEST_F(RenderFrameHostManagerTest,
+ PageFocusIsPreservedAcrossSubframeNavigations) {
+ // This test only makes sense when cross-site subframes use separate
+ // processes.
+ if (!AreAllSitesIsolatedForTesting())
+ return;
+
+ const GURL kUrlA("http://a.com/");
+ const GURL kUrlB("http://b.com/");
+ const GURL kUrlC("http://c.com/");
+
+ // Set up a page at a.com with a b.com subframe.
+ contents()->NavigateAndCommit(kUrlA);
+ main_test_rfh()->OnCreateChildFrame(
+ main_test_rfh()->GetProcess()->GetNextRoutingID(),
+ blink::WebTreeScopeType::Document, "frame1",
+ blink::WebSandboxFlags::None, blink::WebFrameOwnerProperties());
+
+ FrameTreeNode* root = contents()->GetFrameTree()->root();
+ RenderFrameHostManager* child = root->child_at(0)->render_manager();
+
+ // Navigate subframe to B.
+ NavigationEntryImpl entryB(nullptr /* instance */, -1 /* page_id */, kUrlB,
+ Referrer(kUrlA, blink::WebReferrerPolicyDefault),
+ base::string16() /* title */,
+ ui::PAGE_TRANSITION_LINK,
+ false /* is_renderer_init */);
+ TestRenderFrameHost* hostB =
+ static_cast<TestRenderFrameHost*>(NavigateToEntry(child, entryB));
+ child->DidNavigateFrame(hostB, true);
+
+ // Ensure that the main page is focused.
+ main_test_rfh()->GetView()->Focus();
+ EXPECT_TRUE(main_test_rfh()->GetView()->HasFocus());
+
+ // Navigate the subframe to C.
+ NavigationEntryImpl entryC(nullptr /* instance */, -1 /* page_id */, kUrlC,
+ Referrer(kUrlA, blink::WebReferrerPolicyDefault),
+ base::string16() /* title */,
+ ui::PAGE_TRANSITION_LINK,
+ false /* is_renderer_init */);
+ TestRenderFrameHost* hostC =
+ static_cast<TestRenderFrameHost*>(NavigateToEntry(child, entryC));
+ child->DidNavigateFrame(hostC, true);
+
+ // The main frame should now have a proxy for C.
+ RenderFrameProxyHost* proxy =
+ root->render_manager()->GetRenderFrameProxyHost(hostC->GetSiteInstance());
+ EXPECT_TRUE(proxy);
+
+ // Since the B->C navigation happened while the current page was focused,
+ // page focus should propagate to the new subframe process. Check that
+ // process C received the proper focus message.
+ VerifyPageFocusMessage(hostC->GetProcess(), true, proxy->GetRoutingID());
+}
+
+// Checks that a restore navigation to a WebUI works.
+TEST_F(RenderFrameHostManagerTest, RestoreNavigationToWebUI) {
+ set_should_create_webui(true);
+
+ const GURL kInitUrl("chrome://foo/");
+ SiteInstanceImpl* initial_instance =
+ static_cast<SiteInstanceImpl*>(SiteInstance::Create(browser_context()));
+ initial_instance->SetSite(kInitUrl);
+ scoped_ptr<TestWebContents> web_contents(
+ TestWebContents::Create(browser_context(), initial_instance));
+ RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
+ NavigationControllerImpl& controller = web_contents->GetController();
+
+ // Setup a restored entry.
+ std::vector<scoped_ptr<NavigationEntry>> entries;
+ scoped_ptr<NavigationEntry> new_entry =
+ NavigationControllerImpl::CreateNavigationEntry(
+ kInitUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, false, std::string(),
+ browser_context());
+ new_entry->SetPageID(0);
+ entries.push_back(std::move(new_entry));
+ controller.Restore(
+ 0, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
+ ASSERT_EQ(0u, entries.size());
+ ASSERT_EQ(1, controller.GetEntryCount());
+
+ RenderFrameHostImpl* initial_host = manager->current_frame_host();
+ ASSERT_TRUE(initial_host);
+ EXPECT_FALSE(initial_host->IsRenderFrameLive());
+ EXPECT_FALSE(initial_host->web_ui());
+
+ // Navigation request to an entry from a previous browsing session.
+ NavigationEntryImpl entry(nullptr /* instance */, 0 /* page_id */, kInitUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_RELOAD,
+ false /* is_renderer_init */);
+ entry.set_restore_type(
+ NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY);
+ NavigateToEntry(manager, entry);
+
+ // As the initial renderer was not live, the new RenderFrameHost should be
+ // made immediately active at request time.
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ TestRenderFrameHost* current_host =
+ static_cast<TestRenderFrameHost*>(manager->current_frame_host());
+ ASSERT_TRUE(current_host);
+ EXPECT_EQ(current_host, initial_host);
+ EXPECT_TRUE(current_host->IsRenderFrameLive());
+ WebUIImpl* web_ui = manager->GetNavigatingWebUI();
+ EXPECT_TRUE(web_ui);
+ EXPECT_EQ(web_ui, current_host->pending_web_ui());
+ EXPECT_FALSE(current_host->web_ui());
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(current_host, true);
+ EXPECT_EQ(current_host, manager->current_frame_host());
+ EXPECT_EQ(web_ui, current_host->web_ui());
+ EXPECT_FALSE(current_host->pending_web_ui());
+}
+
+// Shared code until before commit for the SimultaneousNavigationWithOneWebUI*
+// tests, accepting a lambda to execute the commit step.
+void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithOneWebUI(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda) {
+ set_should_create_webui(true);
+ NavigateActiveAndCommit(GURL("chrome://foo/"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host1 = manager->current_frame_host();
+ EXPECT_TRUE(host1->IsRenderFrameLive());
+ WebUIImpl* web_ui = host1->web_ui();
+ EXPECT_TRUE(web_ui);
+
+ // Starts a reload of the WebUI page.
+ contents()->GetController().Reload(true);
+
+ // It should be a same-site navigation reusing the same WebUI.
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host1->web_ui());
+ EXPECT_EQ(web_ui, host1->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Navigation request to a non-WebUI page.
+ const GURL kUrl("http://google.com");
+ NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry);
+ ASSERT_TRUE(host2);
+
+ // The previous navigation should still be ongoing along with the new,
+ // cross-site one.
+ // Note: Simultaneous navigations are weird: there are two ongoing
+ // navigations, a same-site using a WebUI and a cross-site not using one. So
+ // it's unclear what GetNavigatingWebUI should return in this case. As it
+ // currently favors the cross-site navigation it returns null.
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host1->web_ui());
+ EXPECT_EQ(web_ui, host1->pending_web_ui());
+
+ EXPECT_NE(host2, host1);
+ EXPECT_EQ(host2, GetPendingFrameHost(manager));
+ EXPECT_FALSE(host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+ EXPECT_NE(web_ui, host2->web_ui());
+
+ commit_lambda(host1, host2, web_ui, manager);
+}
+
+// Simulates two simultaneous navigations involving one WebUI where the current
+// RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithOneWebUI1) {
+ auto commit_current_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, WebUIImpl* web_ui,
+ RenderFrameHostManager* manager) {
+ // The current RenderFrameHost commits; its WebUI should still be in place.
+ manager->DidNavigateFrame(host1, true);
+ EXPECT_EQ(host1, manager->current_frame_host());
+ EXPECT_EQ(web_ui, host1->web_ui());
+ EXPECT_FALSE(host1->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithOneWebUI(commit_current_frame_host);
+}
+
+// Simulates two simultaneous navigations involving one WebUI where the new,
+// cross-site RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithOneWebUI2) {
+ auto commit_new_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, WebUIImpl* web_ui,
+ RenderFrameHostManager* manager) {
+ // The new RenderFrameHost commits; there should be no active WebUI.
+ manager->DidNavigateFrame(host2, true);
+ EXPECT_EQ(host2, manager->current_frame_host());
+ EXPECT_FALSE(host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithOneWebUI(commit_new_frame_host);
+}
+
+// Shared code until before commit for the SimultaneousNavigationWithTwoWebUIs*
+// tests, accepting a lambda to execute the commit step.
+void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithTwoWebUIs(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda) {
+ set_should_create_webui(true);
+ set_webui_type(1);
+ NavigateActiveAndCommit(GURL("chrome://foo/"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host1 = manager->current_frame_host();
+ EXPECT_TRUE(host1->IsRenderFrameLive());
+ WebUIImpl* web_ui1 = host1->web_ui();
+ EXPECT_TRUE(web_ui1);
+
+ // Starts a reload of the WebUI page.
+ contents()->GetController().Reload(true);
+
+ // It should be a same-site navigation reusing the same WebUI.
+ EXPECT_EQ(web_ui1, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui1, host1->web_ui());
+ EXPECT_EQ(web_ui1, host1->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Navigation another WebUI page, with a different type.
+ set_webui_type(2);
+ const GURL kUrl("chrome://bar/");
+ NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry);
+ ASSERT_TRUE(host2);
+
+ // The previous navigation should still be ongoing along with the new,
+ // cross-site one.
+ // Note: simultaneous navigations are weird: there are two ongoing
+ // navigations, a same-site and a cross-site both going to WebUIs. So it's
+ // unclear what GetNavigatingWebUI should return in this case. As it currently
+ // favors the cross-site navigation it returns the speculative/pending
+ // RenderFrameHost's WebUI instance.
+ EXPECT_EQ(web_ui1, host1->web_ui());
+ EXPECT_EQ(web_ui1, host1->pending_web_ui());
+ WebUIImpl* web_ui2 = manager->GetNavigatingWebUI();
+ EXPECT_TRUE(web_ui2);
+ EXPECT_NE(web_ui2, web_ui1);
+
+ EXPECT_NE(host2, host1);
+ EXPECT_EQ(host2, GetPendingFrameHost(manager));
+ EXPECT_EQ(web_ui2, host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+
+ commit_lambda(host1, host2, web_ui1, web_ui2, manager);
+}
+
+// Simulates two simultaneous navigations involving two WebUIs where the current
+// RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithTwoWebUIs1) {
+ auto commit_current_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2,
+ WebUIImpl* web_ui1, WebUIImpl* web_ui2, RenderFrameHostManager* manager) {
+ // The current RenderFrameHost commits; its WebUI should still be active.
+ manager->DidNavigateFrame(host1, true);
+ EXPECT_EQ(host1, manager->current_frame_host());
+ EXPECT_EQ(web_ui1, host1->web_ui());
+ EXPECT_FALSE(host1->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithTwoWebUIs(commit_current_frame_host);
+}
+
+// Simulates two simultaneous navigations involving two WebUIs where the new,
+// cross-site RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithTwoWebUIs2) {
+ auto commit_new_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2,
+ WebUIImpl* web_ui1, WebUIImpl* web_ui2, RenderFrameHostManager* manager) {
+ // The new RenderFrameHost commits; its WebUI should now be active.
+ manager->DidNavigateFrame(host2, true);
+ EXPECT_EQ(host2, manager->current_frame_host());
+ EXPECT_EQ(web_ui2, host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithTwoWebUIs(commit_new_frame_host);
+}
+
+// RenderFrameHostManagerTest extension for PlzNavigate enabled tests.
+class RenderFrameHostManagerTestWithBrowserSideNavigation
+ : public RenderFrameHostManagerTest {
+ public:
+ void SetUp() override {
+ EnableBrowserSideNavigation();
+ RenderFrameHostManagerTest::SetUp();
+ }
+};
+
+// PlzNavigate: Tests that the correct intermediary and final navigation states
+// are reached when navigating from a renderer that is not live to a WebUI URL.
+TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
+ NavigateFromDeadRendererToWebUI) {
+ set_should_create_webui(true);
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+
+ RenderFrameHostImpl* initial_host = manager->current_frame_host();
+ ASSERT_TRUE(initial_host);
+ EXPECT_FALSE(initial_host->IsRenderFrameLive());
+
+ // Navigation request.
+ const GURL kUrl("chrome://foo");
+ NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
+ scoped_ptr<NavigationRequest> navigation_request =
+ NavigationRequest::CreateBrowserInitiated(
+ contents()->GetFrameTree()->root(), frame_entry->url(),
+ frame_entry->referrer(), *frame_entry, entry,
+ FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
+ static_cast<NavigationControllerImpl*>(&controller()));
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // As the initial RenderFrame was not live, the new RenderFrameHost should be
+ // made as active/current immediately along with its WebUI at request time.
+ RenderFrameHostImpl* host = manager->current_frame_host();
+ ASSERT_TRUE(host);
+ EXPECT_NE(host, initial_host);
+ EXPECT_TRUE(host->IsRenderFrameLive());
+ WebUIImpl* web_ui = host->web_ui();
+ EXPECT_TRUE(web_ui);
+ EXPECT_FALSE(host->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Prepare to commit, update the navigating RenderFrameHost.
+ EXPECT_EQ(host, manager->GetFrameHostForNavigation(*navigation_request));
+
+ // There should be a pending WebUI set to reuse the current one.
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_EQ(web_ui, host->pending_web_ui());
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+
+ // No pending RenderFrameHost as the current one should be reused.
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(host, true);
+ EXPECT_EQ(host, manager->current_frame_host());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_FALSE(host->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+}
+
+// PlzNavigate: Tests that the correct intermediary and final navigation states
+// are reached when navigating same-site between two WebUIs of the same type.
+TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
+ NavigateSameSiteBetweenWebUIs) {
+ set_should_create_webui(true);
+ NavigateActiveAndCommit(GURL("chrome://foo"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host = manager->current_frame_host();
+ EXPECT_TRUE(host->IsRenderFrameLive());
+ WebUIImpl* web_ui = host->web_ui();
+ EXPECT_TRUE(web_ui);
+
+ // Navigation request. No change in the returned WebUI type.
+ const GURL kUrl("chrome://foo/bar");
+ NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
+ scoped_ptr<NavigationRequest> navigation_request =
+ NavigationRequest::CreateBrowserInitiated(
+ contents()->GetFrameTree()->root(), frame_entry->url(),
+ frame_entry->referrer(), *frame_entry, entry,
+ FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
+ static_cast<NavigationControllerImpl*>(&controller()));
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // The current WebUI should still be in place and the pending WebUI should be
+ // set to reuse it.
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_EQ(web_ui, host->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Prepare to commit, update the navigating RenderFrameHost.
+ EXPECT_EQ(host, manager->GetFrameHostForNavigation(*navigation_request));
+
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_EQ(web_ui, host->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(host, true);
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(host->pending_web_ui());
+}
+
+// PlzNavigate: Tests that the correct intermediary and final navigation states
+// are reached when navigating cross-site between two different WebUI types.
+TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
+ NavigateCrossSiteBetweenWebUIs) {
+ // Cross-site navigations will always cause the change of the WebUI instance
+ // but for consistency sake different types will be set for each navigation.
+ set_should_create_webui(true);
+ set_webui_type(1);
+ NavigateActiveAndCommit(GURL("chrome://foo"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host = manager->current_frame_host();
+ EXPECT_TRUE(host->IsRenderFrameLive());
+ EXPECT_TRUE(host->web_ui());
+
+ // Set the WebUI controller to return a different WebUIType value. This will
+ // cause the next navigation to "chrome://bar" to require a different WebUI
+ // than the current one, forcing it to be treated as cross-site.
+ set_webui_type(2);
+
+ // Navigation request.
+ const GURL kUrl("chrome://bar");
+ NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
+ scoped_ptr<NavigationRequest> navigation_request =
+ NavigationRequest::CreateBrowserInitiated(
+ contents()->GetFrameTree()->root(), frame_entry->url(),
+ frame_entry->referrer(), *frame_entry, entry,
+ FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
+ static_cast<NavigationControllerImpl*>(&controller()));
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // The current WebUI should still be in place and there should be a new
+ // active WebUI instance in the speculative RenderFrameHost.
+ EXPECT_TRUE(manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(manager->current_frame_host()->pending_web_ui());
+ RenderFrameHostImpl* speculative_host = GetPendingFrameHost(manager);
+ EXPECT_TRUE(speculative_host);
+ WebUIImpl* next_web_ui = manager->GetNavigatingWebUI();
+ EXPECT_TRUE(next_web_ui);
+ EXPECT_EQ(next_web_ui, speculative_host->web_ui());
+ EXPECT_NE(next_web_ui, manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(speculative_host->pending_web_ui());
+
+ // Prepare to commit, update the navigating RenderFrameHost.
+ EXPECT_EQ(speculative_host,
+ manager->GetFrameHostForNavigation(*navigation_request));
+
+ EXPECT_TRUE(manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(manager->current_frame_host()->pending_web_ui());
+ EXPECT_EQ(speculative_host, GetPendingFrameHost(manager));
+ EXPECT_NE(next_web_ui, manager->current_frame_host()->web_ui());
+ EXPECT_EQ(next_web_ui, speculative_host->web_ui());
+ EXPECT_EQ(next_web_ui, manager->GetNavigatingWebUI());
+ EXPECT_FALSE(speculative_host->pending_web_ui());
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(speculative_host, true);
+ EXPECT_EQ(speculative_host, manager->current_frame_host());
+ EXPECT_EQ(next_web_ui, manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ EXPECT_FALSE(speculative_host->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+}
+
+// Tests that frame proxies receive updates when a frame's enforcement
+// of strict mixed content checking changes.
+TEST_F(RenderFrameHostManagerTestWithSiteIsolation,
+ ProxiesReceiveShouldEnforceStrictMixedContentChecking) {
+ const GURL kUrl1("http://www.google.test");
+ const GURL kUrl2("http://www.google2.test");
+ const GURL kUrl3("http://www.google2.test/foo");
+
+ contents()->NavigateAndCommit(kUrl1);
+
+ // Create a child frame and navigate it cross-site.
+ main_test_rfh()->OnCreateChildFrame(
+ main_test_rfh()->GetProcess()->GetNextRoutingID(),
+ blink::WebTreeScopeType::Document, "frame1", blink::WebSandboxFlags::None,
+ blink::WebFrameOwnerProperties());
+
+ FrameTreeNode* root = contents()->GetFrameTree()->root();
+ RenderFrameHostManager* child = root->child_at(0)->render_manager();
+
+ // Navigate subframe to kUrl2.
+ NavigationEntryImpl entry1(nullptr /* instance */, -1 /* page_id */, kUrl2,
+ Referrer(kUrl1, blink::WebReferrerPolicyDefault),
+ base::string16() /* title */,
+ ui::PAGE_TRANSITION_LINK,
+ false /* is_renderer_init */);
+ TestRenderFrameHost* child_host =
+ static_cast<TestRenderFrameHost*>(NavigateToEntry(child, entry1));
+ child->DidNavigateFrame(child_host, true);
+
+ // Verify that parent and child are in different processes.
+ EXPECT_NE(child_host->GetProcess(), main_test_rfh()->GetProcess());
+
+ // Change the parent's enforcement of strict mixed content checking,
+ // and check that the correct IPC is sent to the child frame's
+ // process.
+ EXPECT_FALSE(root->current_replication_state()
+ .should_enforce_strict_mixed_content_checking);
+ main_test_rfh()->DidEnforceStrictMixedContentChecking();
+ RenderFrameProxyHost* proxy_to_child =
+ root->render_manager()->GetRenderFrameProxyHost(
+ child_host->GetSiteInstance());
+ EXPECT_NO_FATAL_FAILURE(
+ CheckMixedContentIPC(child_host, true, proxy_to_child->GetRoutingID()));
+ EXPECT_TRUE(root->current_replication_state()
+ .should_enforce_strict_mixed_content_checking);
+
+ // Do the same for the child's enforcement. In general, the parent
+ // needs to know the status of the child's flag in case a grandchild
+ // is created: if A.com embeds B.com, and B.com enforces strict mixed
+ // content checking, and B.com adds an iframe to A.com, then the
+ // A.com process needs to know B.com's flag so that the grandchild
+ // A.com frame can inherit it.
+ EXPECT_FALSE(root->child_at(0)
+ ->current_replication_state()
+ .should_enforce_strict_mixed_content_checking);
+ child_host->DidEnforceStrictMixedContentChecking();
+ RenderFrameProxyHost* proxy_to_parent =
+ child->GetRenderFrameProxyHost(main_test_rfh()->GetSiteInstance());
+ EXPECT_NO_FATAL_FAILURE(CheckMixedContentIPC(
+ main_test_rfh(), true, proxy_to_parent->GetRoutingID()));
+ EXPECT_TRUE(root->child_at(0)
+ ->current_replication_state()
+ .should_enforce_strict_mixed_content_checking);
+
+ // Check that the flag for the parent's proxy to the child is reset
+ // when the child navigates.
+ main_test_rfh()->GetProcess()->sink().ClearMessages();
+ FrameHostMsg_DidCommitProvisionalLoad_Params commit_params;
+ commit_params.page_id = 0;
+ commit_params.nav_entry_id = 0;
+ commit_params.did_create_new_entry = false;
+ commit_params.url = kUrl3;
+ commit_params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
+ commit_params.should_update_history = false;
+ commit_params.gesture = NavigationGestureAuto;
+ commit_params.was_within_same_page = false;
+ commit_params.is_post = false;
+ commit_params.page_state = PageState::CreateFromURL(kUrl3);
+ commit_params.should_enforce_strict_mixed_content_checking = false;
+ child_host->SendNavigateWithParams(&commit_params);
+ EXPECT_NO_FATAL_FAILURE(CheckMixedContentIPC(
+ main_test_rfh(), false, proxy_to_parent->GetRoutingID()));
+ EXPECT_FALSE(root->child_at(0)
+ ->current_replication_state()
+ .should_enforce_strict_mixed_content_checking);
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_message_filter.cc b/chromium/content/browser/frame_host/render_frame_message_filter.cc
index d7e9d9e605b..21a811a85a9 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.cc
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.cc
@@ -4,6 +4,11 @@
#include "content/browser/frame_host/render_frame_message_filter.h"
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/metrics/field_trial.h"
+#include "base/strings/string_util.h"
+#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -14,6 +19,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_constants.h"
+#include "content/public/common/content_switches.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "net/cookies/cookie_store.h"
#include "net/url_request/url_request_context.h"
@@ -39,12 +45,16 @@ namespace {
const int kPluginsRefreshThresholdInSeconds = 3;
#endif
-void CreateChildFrameOnUI(int process_id,
- int parent_routing_id,
- blink::WebTreeScopeType scope,
- const std::string& frame_name,
- blink::WebSandboxFlags sandbox_flags,
- int new_routing_id) {
+const char kEnforceStrictSecureExperiment[] = "StrictSecureCookies";
+
+void CreateChildFrameOnUI(
+ int process_id,
+ int parent_routing_id,
+ blink::WebTreeScopeType scope,
+ const std::string& frame_name,
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties,
+ int new_routing_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHostImpl* render_frame_host =
RenderFrameHostImpl::FromID(process_id, parent_routing_id);
@@ -52,7 +62,8 @@ void CreateChildFrameOnUI(int process_id,
// processing a subframe creation message.
if (render_frame_host) {
render_frame_host->OnCreateChildFrame(new_routing_id, scope, frame_name,
- sandbox_flags);
+ sandbox_flags,
+ frame_owner_properties);
}
}
@@ -290,6 +301,8 @@ bool RenderFrameMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(FrameHostMsg_CookiesEnabled, OnCookiesEnabled)
IPC_MESSAGE_HANDLER(FrameHostMsg_Are3DAPIsBlocked, OnAre3DAPIsBlocked)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidLose3DContext, OnDidLose3DContext)
+ IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_RenderProcessGone,
+ OnRenderProcessGone())
#if defined(ENABLE_PLUGINS)
IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_GetPlugins, OnGetPlugins)
IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo)
@@ -317,12 +330,14 @@ void RenderFrameMessageFilter::OnCreateChildFrame(
blink::WebTreeScopeType scope,
const std::string& frame_name,
blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties,
int* new_routing_id) {
*new_routing_id = render_widget_helper_->GetNextRoutingID();
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&CreateChildFrameOnUI, render_process_id_, parent_routing_id,
- scope, frame_name, sandbox_flags, *new_routing_id));
+ scope, frame_name, sandbox_flags, frame_owner_properties,
+ *new_routing_id));
}
void RenderFrameMessageFilter::OnSetCookie(int render_frame_id,
@@ -338,9 +353,19 @@ void RenderFrameMessageFilter::OnSetCookie(int render_frame_id,
}
net::CookieOptions options;
+ bool experimental_web_platform_features_enabled =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures);
+ const std::string enforce_strict_secure_group =
+ base::FieldTrialList::FindFullName(kEnforceStrictSecureExperiment);
+ if (experimental_web_platform_features_enabled ||
+ base::StartsWith(enforce_strict_secure_group, "Enabled",
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ options.set_enforce_strict_secure();
+ }
if (GetContentClient()->browser()->AllowSetCookie(
url, first_party_for_cookies, cookie, resource_context_,
- render_process_id_, render_frame_id, &options)) {
+ render_process_id_, render_frame_id, options)) {
net::URLRequestContext* context = GetRequestContextForURL(url);
// Pass a null callback since we don't care about when the 'set' completes.
context->cookie_store()->SetCookieWithOptionsAsync(
@@ -396,7 +421,8 @@ void RenderFrameMessageFilter::CheckPolicyForCookies(
net::URLRequestContext* context = GetRequestContextForURL(url);
// Check the policy for get cookies, and pass cookie_list to the
// TabSpecificContentSetting for logging purpose.
- if (GetContentClient()->browser()->AllowGetCookie(
+ if (context &&
+ GetContentClient()->browser()->AllowGetCookie(
url, first_party_for_cookies, cookie_list, resource_context_,
render_process_id_, render_frame_id)) {
// Gets the cookies from cookie store if allowed.
@@ -445,6 +471,14 @@ void RenderFrameMessageFilter::OnDidLose3DContext(
top_origin_url, guilt);
}
+void RenderFrameMessageFilter::OnRenderProcessGone() {
+ // FrameHostMessage_RenderProcessGone is a synthetic IPC message used by
+ // RenderProcessHostImpl to clean things up after a crash (it's injected
+ // downstream of this filter). Allowing it to proceed would enable a renderer
+ // to fake its own death; instead, actually kill the renderer.
+ bad_message::ReceivedBadMessage(
+ this, bad_message::RFMF_RENDERER_FAKED_ITS_OWN_DEATH);
+}
#if defined(ENABLE_PLUGINS)
@@ -547,7 +581,7 @@ void RenderFrameMessageFilter::OnOpenChannelToPepperPlugin(
void RenderFrameMessageFilter::OnDidCreateOutOfProcessPepperInstance(
int plugin_child_id,
- int32 pp_instance,
+ int32_t pp_instance,
PepperRendererInstanceData instance_data,
bool is_external) {
// It's important that we supply the render process ID ourselves based on the
@@ -573,7 +607,7 @@ void RenderFrameMessageFilter::OnDidCreateOutOfProcessPepperInstance(
void RenderFrameMessageFilter::OnDidDeleteOutOfProcessPepperInstance(
int plugin_child_id,
- int32 pp_instance,
+ int32_t pp_instance,
bool is_external) {
if (is_external) {
// We provide the BrowserPpapiHost to the embedder, so it's safe to cast.
@@ -599,7 +633,7 @@ void RenderFrameMessageFilter::OnOpenChannelToPpapiBroker(
void RenderFrameMessageFilter::OnPluginInstanceThrottleStateChange(
int plugin_child_id,
- int32 pp_instance,
+ int32_t pp_instance,
bool is_throttled) {
// Feature is only implemented for non-external Plugins.
PpapiPluginProcessHost::OnPluginInstanceThrottleStateChange(
diff --git a/chromium/content/browser/frame_host/render_frame_message_filter.h b/chromium/content/browser/frame_host/render_frame_message_filter.h
index a6c1443c8c5..194e2079b44 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.h
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.h
@@ -5,12 +5,15 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include <set>
#include "content/common/frame_replication_state.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/common/three_d_api_types.h"
#include "net/cookies/canonical_cookie.h"
+#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
#include "third_party/WebKit/public/web/WebTreeScopeType.h"
#if defined(ENABLE_PLUGINS)
@@ -58,11 +61,13 @@ class RenderFrameMessageFilter : public BrowserMessageFilter {
~RenderFrameMessageFilter() override;
- void OnCreateChildFrame(int parent_routing_id,
- blink::WebTreeScopeType scope,
- const std::string& frame_name,
- blink::WebSandboxFlags sandbox_flags,
- int* new_render_frame_id);
+ void OnCreateChildFrame(
+ int parent_routing_id,
+ blink::WebTreeScopeType scope,
+ const std::string& frame_name,
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::WebFrameOwnerProperties& frame_owner_properties,
+ int* new_render_frame_id);
void OnSetCookie(int render_frame_id,
const GURL& url,
const GURL& first_party_for_cookies,
@@ -96,6 +101,8 @@ class RenderFrameMessageFilter : public BrowserMessageFilter {
ThreeDAPIType context_type,
int arb_robustness_status_code);
+ void OnRenderProcessGone();
+
#if defined(ENABLE_PLUGINS)
void OnGetPlugins(bool refresh, IPC::Message* reply_msg);
void GetPluginsCallback(IPC::Message* reply_msg,
@@ -118,16 +125,16 @@ class RenderFrameMessageFilter : public BrowserMessageFilter {
IPC::Message* reply_msg);
void OnDidCreateOutOfProcessPepperInstance(
int plugin_child_id,
- int32 pp_instance,
+ int32_t pp_instance,
PepperRendererInstanceData instance_data,
bool is_external);
void OnDidDeleteOutOfProcessPepperInstance(int plugin_child_id,
- int32 pp_instance,
+ int32_t pp_instance,
bool is_external);
void OnOpenChannelToPpapiBroker(int routing_id,
const base::FilePath& path);
void OnPluginInstanceThrottleStateChange(int plugin_child_id,
- int32 pp_instance,
+ int32_t pp_instance,
bool is_throttled);
#endif // ENABLE_PLUGINS
diff --git a/chromium/content/browser/renderer_host/render_message_filter_browsertest.cc b/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc
index 78194fbee5d..3362e96081c 100644
--- a/chromium/content/browser/renderer_host/render_message_filter_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc
@@ -4,9 +4,10 @@
#include <string>
-#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/test/histogram_tester.h"
+#include "content/browser/bad_message.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
@@ -21,7 +22,7 @@
#include "ipc/ipc_security_test_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
@@ -37,23 +38,22 @@ std::string GetCookieFromJS(RenderFrameHost* frame) {
} // namespace
-using RenderMessageFilterBrowserTest = ContentBrowserTest;
+using RenderFrameMessageFilterBrowserTest = ContentBrowserTest;
// Exercises basic cookie operations via javascript, including an http page
// interacting with secure cookies.
-IN_PROC_BROWSER_TEST_F(RenderMessageFilterBrowserTest, Cookies) {
+IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, Cookies) {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
SetupCrossSiteRedirector(embedded_test_server());
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server.Start());
- // The server sends a HttpOnly cookie. The RenderMessageFilter should never
- // allow this to be sent to any renderer process.
- GURL https_url = https_server.GetURL("set-cookie?notforjs=1;HttpOnly");
+ // The server sends a HttpOnly cookie. The RenderFrameMessageFilter should
+ // never allow this to be sent to any renderer process.
+ GURL https_url = https_server.GetURL("/set-cookie?notforjs=1;HttpOnly");
GURL http_url = embedded_test_server()->GetURL("/frame_with_load_event.html");
Shell* shell2 = CreateBrowser();
@@ -102,9 +102,10 @@ IN_PROC_BROWSER_TEST_F(RenderMessageFilterBrowserTest, Cookies) {
EXPECT_EQ("B=2; D=4", GetCookieFromJS(web_contents_http->GetMainFrame()));
}
-// The RenderMessageFilter will kill processes when they access the cookies of
-// sites other than the site the process is dedicated to, under site isolation.
-IN_PROC_BROWSER_TEST_F(RenderMessageFilterBrowserTest,
+// The RenderFrameMessageFilter will kill processes when they access the cookies
+// of sites other than the site the process is dedicated to, under site
+// isolation.
+IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest,
CrossSiteCookieSecurityEnforcement) {
// The code under test is only active under site isolation.
if (!AreAllSitesIsolatedForTesting()) {
@@ -112,7 +113,7 @@ IN_PROC_BROWSER_TEST_F(RenderMessageFilterBrowserTest,
}
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
SetupCrossSiteRedirector(embedded_test_server());
NavigateToURL(shell(),
embedded_test_server()->GetURL("/frame_with_load_event.html"));
@@ -175,4 +176,36 @@ IN_PROC_BROWSER_TEST_F(RenderMessageFilterBrowserTest,
v.DepictFrameTree(tab->GetFrameTree()->root()));
}
+// FrameHostMsg_RenderProcessGone is a synthetic message that's really an
+// implementation detail of RenderProcessHostImpl's crash recovery. It should be
+// ignored if it arrives over the IPC channel.
+IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, RenderProcessGone) {
+ GURL web_url("http://foo.com/simple_page.html");
+ NavigateToURL(shell(), web_url);
+ RenderFrameHost* web_rfh = shell()->web_contents()->GetMainFrame();
+
+ base::HistogramTester uma;
+
+ ASSERT_TRUE(web_rfh->IsRenderFrameLive());
+ RenderProcessHostWatcher web_process_killed(
+ web_rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ web_rfh->GetProcess()->GetChannel(),
+ FrameHostMsg_RenderProcessGone(
+ web_rfh->GetRoutingID(), base::TERMINATION_STATUS_NORMAL_TERMINATION,
+ 0));
+
+ EXPECT_THAT(uma.GetAllSamples("Stability.BadMessageTerminated.Content"),
+ testing::ElementsAre(base::Bucket(
+ bad_message::RFMF_RENDERER_FAKED_ITS_OWN_DEATH, 1)));
+
+ // If the message had gone through, we'd have marked the RFH as dead but
+ // left the RPH and its connection alive, and the Wait below would hang.
+ web_process_killed.Wait();
+
+ ASSERT_FALSE(web_rfh->GetProcess()->HasConnection());
+ ASSERT_FALSE(web_rfh->IsRenderFrameLive());
+ ASSERT_FALSE(web_process_killed.did_exit_normally());
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_proxy_host.cc b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
index 2ef3d264d61..49bcfc9093a 100644
--- a/chromium/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/frame_host/render_frame_proxy_host.h"
+#include <utility>
+
#include "base/lazy_instance.h"
#include "content/browser/bad_message.h"
#include "content/browser/frame_host/cross_process_frame_connector.h"
@@ -25,7 +27,7 @@ namespace content {
namespace {
// The (process id, routing id) pair that identifies one RenderFrameProxy.
-typedef std::pair<int32, int32> RenderFrameProxyHostID;
+typedef std::pair<int32_t, int32_t> RenderFrameProxyHostID;
typedef base::hash_map<RenderFrameProxyHostID, RenderFrameProxyHost*>
RoutingIDFrameProxyMap;
base::LazyInstance<RoutingIDFrameProxyMap> g_routing_id_frame_proxy_map =
@@ -57,9 +59,9 @@ RenderFrameProxyHost::RenderFrameProxyHost(SiteInstance* site_instance,
std::make_pair(
RenderFrameProxyHostID(GetProcess()->GetID(), routing_id_),
this)).second);
- CHECK_IMPLIES(!render_view_host,
- frame_tree_node_->render_manager()->ForInnerDelegate() &&
- frame_tree_node_->IsMainFrame());
+ CHECK(render_view_host ||
+ (frame_tree_node_->render_manager()->ForInnerDelegate() &&
+ frame_tree_node_->IsMainFrame()));
if (render_view_host)
frame_tree_node_->frame_tree()->AddRenderViewHostRef(render_view_host_);
@@ -122,13 +124,13 @@ RenderWidgetHostView* RenderFrameProxyHost::GetRenderWidgetHostView() {
void RenderFrameProxyHost::TakeFrameHostOwnership(
scoped_ptr<RenderFrameHostImpl> render_frame_host) {
CHECK(render_frame_host_ == nullptr);
- render_frame_host_ = render_frame_host.Pass();
+ render_frame_host_ = std::move(render_frame_host);
render_frame_host_->set_render_frame_proxy_host(this);
}
scoped_ptr<RenderFrameHostImpl> RenderFrameProxyHost::PassFrameHostOwnership() {
render_frame_host_->set_render_frame_proxy_host(NULL);
- return render_frame_host_.Pass();
+ return std::move(render_frame_host_);
}
bool RenderFrameProxyHost::Send(IPC::Message *msg) {
@@ -146,6 +148,8 @@ bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
IPC_MESSAGE_HANDLER(FrameHostMsg_RouteMessageEvent, OnRouteMessageEvent)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeOpener, OnDidChangeOpener)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_AdvanceFocus, OnAdvanceFocus)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_FrameFocused, OnFrameFocused)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -218,6 +222,10 @@ void RenderFrameProxyHost::UpdateOpener() {
Send(new FrameMsg_UpdateOpener(GetRoutingID(), opener_routing_id));
}
+void RenderFrameProxyHost::SetFocusedFrame() {
+ Send(new FrameMsg_SetFocusedFrame(routing_id_));
+}
+
void RenderFrameProxyHost::OnDetach() {
if (frame_tree_node_->render_manager()->ForInnerDelegate()) {
// Only main frame proxy can detach for inner WebContents.
@@ -316,9 +324,39 @@ void RenderFrameProxyHost::OnRouteMessageEvent(
}
}
-void RenderFrameProxyHost::OnDidChangeOpener(int32 opener_routing_id) {
+void RenderFrameProxyHost::OnDidChangeOpener(int32_t opener_routing_id) {
frame_tree_node_->render_manager()->DidChangeOpener(opener_routing_id,
GetSiteInstance());
}
+void RenderFrameProxyHost::OnAdvanceFocus(blink::WebFocusType type,
+ int32_t source_routing_id) {
+ RenderFrameHostImpl* target_rfh =
+ frame_tree_node_->render_manager()->current_frame_host();
+
+ // Translate the source RenderFrameHost in this process to its equivalent
+ // RenderFrameProxyHost in the target process. This is needed for continuing
+ // the focus traversal from correct place in a parent frame after one of its
+ // child frames finishes its traversal.
+ RenderFrameHostImpl* source_rfh =
+ RenderFrameHostImpl::FromID(GetProcess()->GetID(), source_routing_id);
+ int32_t source_proxy_routing_id = MSG_ROUTING_NONE;
+ if (source_rfh) {
+ RenderFrameProxyHost* source_proxy =
+ source_rfh->frame_tree_node()
+ ->render_manager()
+ ->GetRenderFrameProxyHost(target_rfh->GetSiteInstance());
+ if (source_proxy)
+ source_proxy_routing_id = source_proxy->GetRoutingID();
+ }
+
+ target_rfh->Send(new FrameMsg_AdvanceFocus(target_rfh->GetRoutingID(), type,
+ source_proxy_routing_id));
+}
+
+void RenderFrameProxyHost::OnFrameFocused() {
+ frame_tree_node_->frame_tree()->SetFocusedFrame(frame_tree_node_,
+ GetSiteInstance());
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_proxy_host.h b/chromium/content/browser/frame_host/render_frame_proxy_host.h
index 061a6ba94e5..390de28e6b8 100644
--- a/chromium/content/browser/frame_host/render_frame_proxy_host.h
+++ b/chromium/content/browser/frame_host/render_frame_proxy_host.h
@@ -5,11 +5,15 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_PROXY_HOST_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_PROXY_HOST_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
+#include "third_party/WebKit/public/platform/WebFocusType.h"
struct FrameMsg_PostMessage_Params;
@@ -111,6 +115,11 @@ class RenderFrameProxyHost
// another renderer process.
void UpdateOpener();
+ // Set this proxy as the focused frame in the renderer process. This is
+ // called to replicate the focused frame when a frame in a different process
+ // becomes focused.
+ void SetFocusedFrame();
+
void set_render_frame_proxy_created(bool created) {
render_frame_proxy_created_ = created;
}
@@ -123,7 +132,9 @@ class RenderFrameProxyHost
void OnDetach();
void OnOpenURL(const FrameHostMsg_OpenURL_Params& params);
void OnRouteMessageEvent(const FrameMsg_PostMessage_Params& params);
- void OnDidChangeOpener(int32 opener_routing_id);
+ void OnDidChangeOpener(int32_t opener_routing_id);
+ void OnAdvanceFocus(blink::WebFocusType type, int32_t source_routing_id);
+ void OnFrameFocused();
// This RenderFrameProxyHost's routing id.
int routing_id_;
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_child_frame.cc b/chromium/content/browser/frame_host/render_widget_host_view_child_frame.cc
index 07cd5b53652..e8d384e7233 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_child_frame.cc
+++ b/chromium/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -4,6 +4,11 @@
#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include "build/build_config.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_manager.h"
@@ -73,6 +78,8 @@ void RenderWidgetHostViewChildFrame::Focus() {
}
bool RenderWidgetHostViewChildFrame::HasFocus() const {
+ if (frame_connector_)
+ return frame_connector_->HasFocus();
return false;
}
@@ -125,6 +132,9 @@ RenderWidgetHostViewChildFrame::GetNativeViewAccessible() {
}
void RenderWidgetHostViewChildFrame::SetBackgroundColor(SkColor color) {
+ RenderWidgetHostViewBase::SetBackgroundColor(color);
+ bool opaque = GetBackgroundOpaque();
+ host_->SetBackgroundOpaque(opaque);
}
gfx::Size RenderWidgetHostViewChildFrame::GetPhysicalBackingSize() const {
@@ -162,6 +172,8 @@ void RenderWidgetHostViewChildFrame::MovePluginWindows(
}
void RenderWidgetHostViewChildFrame::UpdateCursor(const WebCursor& cursor) {
+ if (frame_connector_)
+ frame_connector_->UpdateCursor(cursor);
}
void RenderWidgetHostViewChildFrame::SetIsLoading(bool is_loading) {
@@ -223,15 +235,15 @@ void RenderWidgetHostViewChildFrame::SelectionBoundsChanged(
const ViewHostMsg_SelectionBounds_Params& params) {
}
-#if defined(OS_ANDROID)
void RenderWidgetHostViewChildFrame::LockCompositingSurface() {
+ NOTIMPLEMENTED();
}
void RenderWidgetHostViewChildFrame::UnlockCompositingSurface() {
+ NOTIMPLEMENTED();
}
-#endif
-void RenderWidgetHostViewChildFrame::SurfaceDrawn(uint32 output_surface_id,
+void RenderWidgetHostViewChildFrame::SurfaceDrawn(uint32_t output_surface_id,
cc::SurfaceDrawStatus drawn) {
cc::CompositorFrameAck ack;
DCHECK_GT(ack_pending_count_, 0U);
@@ -245,8 +257,8 @@ void RenderWidgetHostViewChildFrame::SurfaceDrawn(uint32 output_surface_id,
}
void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame(
- uint32 output_surface_id,
- scoped_ptr<cc::CompositorFrame> frame) {
+ uint32_t output_surface_id,
+ scoped_ptr<cc::CompositorFrame> frame) {
last_scroll_offset_ = frame->metadata.root_scroll_offset;
if (!frame_connector_)
@@ -256,15 +268,13 @@ void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame(
// the embedder's renderer to be composited.
if (!frame->delegated_frame_data || !use_surfaces_) {
frame_connector_->ChildFrameCompositorFrameSwapped(
- output_surface_id,
- host_->GetProcess()->GetID(),
- host_->GetRoutingID(),
- frame.Pass());
+ output_surface_id, host_->GetProcess()->GetID(), host_->GetRoutingID(),
+ std::move(frame));
return;
}
cc::RenderPass* root_pass =
- frame->delegated_frame_data->render_pass_list.back();
+ frame->delegated_frame_data->render_pass_list.back().get();
gfx::Size frame_size = root_pass->output_rect.size();
float scale_factor = frame->metadata.device_scale_factor;
@@ -309,7 +319,7 @@ void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame(
ack_pending_count_++;
// If this value grows very large, something is going wrong.
DCHECK_LT(ack_pending_count_, 1000U);
- surface_factory_->SubmitCompositorFrame(surface_id_, frame.Pass(),
+ surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame),
ack_callback);
}
@@ -371,6 +381,17 @@ void RenderWidgetHostViewChildFrame::ProcessMouseWheelEvent(
host_->ForwardWheelEvent(event);
}
+void RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpace(
+ const gfx::Point& point,
+ gfx::Point* transformed_point) {
+ *transformed_point = point;
+ if (!frame_connector_ || !use_surfaces_)
+ return;
+
+ frame_connector_->TransformPointToRootCoordSpace(point, surface_id_,
+ transformed_point);
+}
+
#if defined(OS_MACOSX)
void RenderWidgetHostViewChildFrame::SetActive(bool active) {
}
@@ -413,11 +434,11 @@ void RenderWidgetHostViewChildFrame::CopyFromCompositingSurface(
}
void RenderWidgetHostViewChildFrame::CopyFromCompositingSurfaceToVideoFrame(
- const gfx::Rect& src_subrect,
- const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) {
+ const gfx::Rect& src_subrect,
+ const scoped_refptr<media::VideoFrame>& target,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) {
NOTIMPLEMENTED();
- callback.Run(false);
+ callback.Run(gfx::Rect(), false);
}
bool RenderWidgetHostViewChildFrame::CanCopyToVideoFrame() const {
@@ -459,11 +480,21 @@ void RenderWidgetHostViewChildFrame::ReturnResources(
std::back_inserter(surface_returned_resources_));
}
+void RenderWidgetHostViewChildFrame::SetBeginFrameSource(
+ cc::SurfaceId surface_id,
+ cc::BeginFrameSource* begin_frame_source) {
+ // TODO(tansell): Hook this up.
+}
+
BrowserAccessibilityManager*
RenderWidgetHostViewChildFrame::CreateBrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate) {
+#if defined(OS_ANDROID) && defined(USE_AURA)
+ return nullptr;
+#else
return BrowserAccessibilityManager::Create(
BrowserAccessibilityManager::GetEmptyDocument(), delegate);
+#endif
}
void RenderWidgetHostViewChildFrame::ClearCompositorSurfaceIfNecessary() {
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_child_frame.h b/chromium/content/browser/frame_host/render_widget_host_view_child_frame.h
index 68fed301302..4bacd21f3d8 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_child_frame.h
+++ b/chromium/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -5,7 +5,14 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_WIDGET_HOST_VIEW_CHILD_FRAME_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_WIDGET_HOST_VIEW_CHILD_FRAME_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "cc/resources/returned_resource.h"
#include "cc/surfaces/surface_factory_client.h"
#include "cc/surfaces/surface_id_allocator.h"
@@ -100,10 +107,10 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) override;
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
bool CanCopyToVideoFrame() const override;
bool HasAcceleratedSurface(const gfx::Size& desired_size) override;
- void OnSwapCompositorFrame(uint32 output_surface_id,
+ void OnSwapCompositorFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) override;
// Since the URL of content rendered by this class is not displayed in
// the URL bar, this method does not need an implementation.
@@ -121,6 +128,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void ProcessKeyboardEvent(const NativeWebKeyboardEvent& event) override;
void ProcessMouseEvent(const blink::WebMouseEvent& event) override;
void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
+ void TransformPointToRootCoordSpace(const gfx::Point& point,
+ gfx::Point* transformed_point) override;
#if defined(OS_MACOSX)
// RenderWidgetHostView implementation.
@@ -139,10 +148,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
#endif // defined(OS_MACOSX)
// RenderWidgetHostViewBase implementation.
-#if defined(OS_ANDROID)
void LockCompositingSurface() override;
void UnlockCompositingSurface() override;
-#endif // defined(OS_ANDROID)
#if defined(OS_WIN)
void SetParentNativeViewAccessible(
@@ -154,10 +161,12 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// cc::SurfaceFactoryClient implementation.
void ReturnResources(const cc::ReturnedResourceArray& resources) override;
+ void SetBeginFrameSource(cc::SurfaceId surface_id,
+ cc::BeginFrameSource* begin_frame_source) override;
// Declared 'public' instead of 'protected' here to allow derived classes
// to Bind() to it.
- void SurfaceDrawn(uint32 output_surface_id, cc::SurfaceDrawStatus drawn);
+ void SurfaceDrawn(uint32_t output_surface_id, cc::SurfaceDrawStatus drawn);
protected:
friend class RenderWidgetHostView;
@@ -181,11 +190,11 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
scoped_ptr<cc::SurfaceIdAllocator> id_allocator_;
scoped_ptr<cc::SurfaceFactory> surface_factory_;
cc::SurfaceId surface_id_;
- uint32 next_surface_sequence_;
- uint32 last_output_surface_id_;
+ uint32_t next_surface_sequence_;
+ uint32_t last_output_surface_id_;
gfx::Size current_surface_size_;
float current_surface_scale_factor_;
- uint32 ack_pending_count_;
+ uint32_t ack_pending_count_;
cc::ReturnedResourceArray surface_returned_resources_;
// frame_connector_ provides a platform abstraction. Messages
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc b/chromium/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
index e560382ef19..835af3bff44 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -27,7 +28,7 @@ class RenderWidgetHostViewChildFrameTest : public ContentBrowserTest {
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
SetupCrossSiteRedirector(embedded_test_server());
}
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc b/chromium/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
index 495c5898158..fbf418b38c0 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
+++ b/chromium/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
@@ -4,8 +4,12 @@
#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
-#include "base/basictypes.h"
+#include <stdint.h>
+#include <utility>
+
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
+#include "build/build_config.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_manager.h"
@@ -44,7 +48,7 @@ class MockCrossProcessFrameConnector : public CrossProcessFrameConnector {
~MockCrossProcessFrameConnector() override {}
void ChildFrameCompositorFrameSwapped(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
int host_id,
int route_id,
scoped_ptr<cc::CompositorFrame> frame) override {
@@ -88,7 +92,7 @@ class RenderWidgetHostViewChildFrameTest : public testing::Test {
MockRenderProcessHost* process_host =
new MockRenderProcessHost(browser_context_.get());
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
widget_host_ =
new RenderWidgetHostImpl(&delegate_, process_host, routing_id, false);
view_ = new RenderWidgetHostViewChildFrame(widget_host_);
@@ -139,7 +143,7 @@ scoped_ptr<cc::CompositorFrame> CreateDelegatedFrame(float scale_factor,
scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
pass->SetNew(cc::RenderPassId(1, 1), gfx::Rect(size), damage,
gfx::Transform());
- frame->delegated_frame_data->render_pass_list.push_back(pass.Pass());
+ frame->delegated_frame_data->render_pass_list.push_back(std::move(pass));
return frame;
}
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_guest.cc b/chromium/content/browser/frame_host/render_widget_host_view_guest.cc
index ecda893dbb7..6d4a1811c5b 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_guest.cc
+++ b/chromium/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -2,18 +2,24 @@
// 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_widget_host_view_guest.h"
+
+#include <utility>
+
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "build/build_config.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_manager.h"
#include "cc/surfaces/surface_sequence.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/compositor/surface_utils.h"
-#include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/gpu/gpu_messages.h"
@@ -56,16 +62,9 @@ RenderWidgetHostViewGuest::RenderWidgetHostViewGuest(
// |guest| is NULL during test.
guest_(guest ? guest->AsWeakPtr() : base::WeakPtr<BrowserPluginGuest>()),
platform_view_(platform_view) {
-#if defined(USE_AURA)
- gesture_recognizer_.reset(ui::GestureRecognizer::Create());
- gesture_recognizer_->AddGestureEventHelper(this);
-#endif // defined(USE_AURA)
}
RenderWidgetHostViewGuest::~RenderWidgetHostViewGuest() {
-#if defined(USE_AURA)
- gesture_recognizer_->RemoveGestureEventHelper(this);
-#endif // defined(USE_AURA)
}
bool RenderWidgetHostViewGuest::OnMessageReceivedFromEmbedder(
@@ -95,8 +94,22 @@ void RenderWidgetHostViewGuest::Show() {
// The two sizes may fall out of sync if we switch RenderWidgetHostViews,
// resize, and then switch page, as is the case with interstitial pages.
// NOTE: |guest_| is NULL in unit tests.
- if (guest_)
+ if (guest_) {
SetSize(guest_->web_contents()->GetViewBounds().size());
+ // Since we were last shown, our renderer may have had a different surface
+ // set (e.g. showing an interstitial), so we resend our current surface to
+ // the renderer.
+ if (!surface_id_.is_null()) {
+ cc::SurfaceSequence sequence = cc::SurfaceSequence(
+ id_allocator_->id_namespace(), next_surface_sequence_++);
+ GetSurfaceManager()
+ ->GetSurfaceForId(surface_id_)
+ ->AddDestructionDependency(sequence);
+ guest_->SetChildFrameSurface(surface_id_, current_surface_size_,
+ current_surface_scale_factor_,
+ sequence);
+ }
+ }
host_->WasShown(ui::LatencyInfo());
}
@@ -133,29 +146,43 @@ bool RenderWidgetHostViewGuest::HasFocus() const {
#if defined(USE_AURA)
void RenderWidgetHostViewGuest::ProcessAckedTouchEvent(
const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
- // TODO(fsamuel): Currently we will only take this codepath if the guest has
- // requested touch events. A better solution is to always forward touchpresses
- // to the embedder process to target a BrowserPlugin, and then route all
- // subsequent touch points of that touchdown to the appropriate guest until
- // that touch point is released.
- ScopedVector<ui::TouchEvent> events;
- if (!MakeUITouchEventsFromWebTouchEvents(touch, &events, LOCAL_COORDINATES))
- return;
+ // TODO(tdresser): Since all ProcessAckedTouchEvent() uses is the event id,
+ // don't pass the full event object here. https://crbug.com/550581.
+ GetOwnerRenderWidgetHostView()->ProcessAckedTouchEvent(touch, ack_result);
+}
+#endif
- ui::EventResult result = (ack_result ==
- INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED;
- for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(),
- end = events.end(); iter != end; ++iter) {
- if (!gesture_recognizer_->ProcessTouchEventPreDispatch(*iter, this))
- continue;
-
- scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
- gestures.reset(gesture_recognizer_->AckTouchEvent(
- (*iter)->unique_event_id(), result, this));
- ProcessGestures(gestures.get());
+void RenderWidgetHostViewGuest::ProcessTouchEvent(
+ const blink::WebTouchEvent& event,
+ const ui::LatencyInfo& latency) {
+ if (event.type == blink::WebInputEvent::TouchStart) {
+ DCHECK(guest_->GetOwnerRenderWidgetHostView());
+ RenderWidgetHostImpl* embedder = static_cast<RenderWidgetHostImpl*>(
+ guest_->GetOwnerRenderWidgetHostView()->GetRenderWidgetHost());
+ if (!embedder->GetView()->HasFocus())
+ embedder->GetView()->Focus();
+ }
+
+ host_->ForwardTouchEventWithLatencyInfo(event, latency);
+}
+
+void RenderWidgetHostViewGuest::RegisterSurfaceNamespaceId() {
+ DCHECK(host_);
+ if (host_->delegate() && host_->delegate()->GetInputEventRouter()) {
+ RenderWidgetHostInputEventRouter* router =
+ host_->delegate()->GetInputEventRouter();
+ if (!router->is_registered(GetSurfaceIdNamespace()))
+ router->AddSurfaceIdNamespaceOwner(GetSurfaceIdNamespace(), this);
+ }
+}
+
+void RenderWidgetHostViewGuest::UnregisterSurfaceNamespaceId() {
+ DCHECK(host_);
+ if (host_->delegate() && host_->delegate()->GetInputEventRouter()) {
+ host_->delegate()->GetInputEventRouter()->RemoveSurfaceIdNamespaceOwner(
+ GetSurfaceIdNamespace());
}
}
-#endif
gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const {
if (!guest_)
@@ -205,7 +232,7 @@ void RenderWidgetHostViewGuest::SetTooltipText(
}
void RenderWidgetHostViewGuest::OnSwapCompositorFrame(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) {
if (!guest_ || !guest_->attached()) {
// We shouldn't hang on to a surface while we are detached.
@@ -217,15 +244,13 @@ void RenderWidgetHostViewGuest::OnSwapCompositorFrame(
// When not using surfaces, the frame just gets proxied to
// the embedder's renderer to be composited.
if (!frame->delegated_frame_data || !use_surfaces_) {
- guest_->SwapCompositorFrame(output_surface_id,
- host_->GetProcess()->GetID(),
- host_->GetRoutingID(),
- frame.Pass());
+ guest_->SwapCompositorFrame(output_surface_id, host_->GetProcess()->GetID(),
+ host_->GetRoutingID(), std::move(frame));
return;
}
cc::RenderPass* root_pass =
- frame->delegated_frame_data->render_pass_list.back();
+ frame->delegated_frame_data->render_pass_list.back().get();
gfx::Size frame_size = root_pass->output_rect.size();
float scale_factor = frame->metadata.device_scale_factor;
@@ -271,7 +296,7 @@ void RenderWidgetHostViewGuest::OnSwapCompositorFrame(
ack_pending_count_++;
// If this value grows very large, something is going wrong.
DCHECK(ack_pending_count_ < 1000);
- surface_factory_->SubmitCompositorFrame(surface_id_, frame.Pass(),
+ surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame),
ack_callback);
}
@@ -420,19 +445,6 @@ void RenderWidgetHostViewGuest::SelectionBoundsChanged(
rwhv->SelectionBoundsChanged(guest_params);
}
-void RenderWidgetHostViewGuest::SetBackgroundColor(SkColor color) {
- // Content embedders can toggle opaque backgrounds through this API.
- // We plumb the value here so that BrowserPlugin updates its compositing
- // state in response to this change. We also want to preserve this flag
- // after recovering from a crash so we let BrowserPluginGuest store it.
- if (!guest_)
- return;
- RenderWidgetHostViewBase::SetBackgroundColor(color);
- bool opaque = GetBackgroundOpaque();
- host_->SetBackgroundOpaque(opaque);
- guest_->SetContentsOpaque(opaque);
-}
-
bool RenderWidgetHostViewGuest::LockMouse() {
return platform_view_->LockMouse();
}
@@ -526,13 +538,13 @@ void RenderWidgetHostViewGuest::ShowDisambiguationPopup(
}
#endif // defined(OS_ANDROID) || defined(USE_AURA)
-#if defined(OS_ANDROID)
void RenderWidgetHostViewGuest::LockCompositingSurface() {
+ NOTIMPLEMENTED();
}
void RenderWidgetHostViewGuest::UnlockCompositingSurface() {
+ NOTIMPLEMENTED();
}
-#endif // defined(OS_ANDROID)
#if defined(OS_WIN)
void RenderWidgetHostViewGuest::SetParentNativeViewAccessible(
@@ -551,32 +563,6 @@ void RenderWidgetHostViewGuest::DestroyGuestView() {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
-bool RenderWidgetHostViewGuest::CanDispatchToConsumer(
- ui::GestureConsumer* consumer) {
- CHECK_EQ(static_cast<RenderWidgetHostViewGuest*>(consumer), this);
- return true;
-}
-
-void RenderWidgetHostViewGuest::DispatchGestureEvent(
- ui::GestureEvent* event) {
- ForwardGestureEventToRenderer(event);
-}
-
-void RenderWidgetHostViewGuest::DispatchCancelTouchEvent(
- ui::TouchEvent* event) {
- if (!host_)
- return;
-
- blink::WebTouchEvent cancel_event;
- // TODO(rbyers): This event has no touches in it. Don't we need to know what
- // touches are currently active in order to cancel them all properly?
- WebTouchEventTraits::ResetType(blink::WebInputEvent::TouchCancel,
- event->time_stamp().InSecondsF(),
- &cancel_event);
-
- host_->ForwardTouchEventWithLatencyInfo(cancel_event, *event->latency());
-}
-
bool RenderWidgetHostViewGuest::ForwardGestureEventToRenderer(
ui::GestureEvent* gesture) {
#if defined(USE_AURA)
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_guest.h b/chromium/content/browser/frame_host/render_widget_host_view_guest.h
index 2ff172ee846..f9d4b1663ce 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_guest.h
+++ b/chromium/content/browser/frame_host/render_widget_host_view_guest.h
@@ -5,9 +5,14 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_WIDGET_HOST_VIEW_GUEST_H_
#define CONTENT_BROWSER_FRAME_HOST_RENDER_WIDGET_HOST_VIEW_GUEST_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
#include "content/common/content_export.h"
#include "content/common/cursors/webcursor.h"
@@ -39,8 +44,7 @@ struct NativeWebKeyboardEvent;
// the relevant calls to the platform view.
class CONTENT_EXPORT RenderWidgetHostViewGuest
: public RenderWidgetHostViewChildFrame,
- public ui::GestureConsumer,
- public ui::GestureEventHelper {
+ public ui::GestureConsumer {
public:
RenderWidgetHostViewGuest(
RenderWidgetHost* widget,
@@ -64,7 +68,6 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
gfx::NativeViewId GetNativeViewId() const override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
gfx::Rect GetViewBounds() const override;
- void SetBackgroundColor(SkColor color) override;
gfx::Size GetPhysicalBackingSize() const override;
base::string16 GetSelectedText() const override;
@@ -92,12 +95,17 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
const gfx::Range& range) override;
void SelectionBoundsChanged(
const ViewHostMsg_SelectionBounds_Params& params) override;
- void OnSwapCompositorFrame(uint32 output_surface_id,
+ void OnSwapCompositorFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) override;
#if defined(USE_AURA)
void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) override;
#endif
+ void ProcessTouchEvent(const blink::WebTouchEvent& event,
+ const ui::LatencyInfo& latency) override;
+ void RegisterSurfaceNamespaceId();
+ void UnregisterSurfaceNamespaceId();
+
bool LockMouse() override;
void UnlockMouse() override;
void GetScreenInfo(blink::WebScreenInfo* results) override;
@@ -125,10 +133,8 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
const SkBitmap& zoomed_bitmap) override;
#endif // defined(OS_ANDROID) || defined(USE_AURA)
-#if defined(OS_ANDROID)
void LockCompositingSurface() override;
void UnlockCompositingSurface() override;
-#endif // defined(OS_ANDROID)
#if defined(OS_WIN)
void SetParentNativeViewAccessible(
@@ -142,11 +148,6 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
void GestureEventAck(const blink::WebGestureEvent& event,
InputEventAckState ack_result) override;
- // Overridden from ui::GestureEventHelper.
- bool CanDispatchToConsumer(ui::GestureConsumer* consumer) override;
- void DispatchGestureEvent(ui::GestureEvent* event) override;
- void DispatchCancelTouchEvent(ui::TouchEvent* event) override;
-
protected:
friend class RenderWidgetHostView;
@@ -175,9 +176,6 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
// RenderWidgetHostViewGuest mostly only cares about stuff related to
// compositing, the rest are directly forwared to this |platform_view_|.
base::WeakPtr<RenderWidgetHostViewBase> platform_view_;
-#if defined(USE_AURA)
- scoped_ptr<ui::GestureRecognizer> gesture_recognizer_;
-#endif
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuest);
};
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc b/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
index d5267f24461..119eb38a840 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
+++ b/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
@@ -4,9 +4,13 @@
#include "content/browser/frame_host/render_widget_host_view_guest.h"
-#include "base/basictypes.h"
+#include <stdint.h>
+#include <utility>
+
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "build/build_config.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_manager.h"
@@ -53,7 +57,7 @@ class RenderWidgetHostViewGuestTest : public testing::Test {
browser_context_.reset(new TestBrowserContext);
MockRenderProcessHost* process_host =
new MockRenderProcessHost(browser_context_.get());
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
widget_host_ =
new RenderWidgetHostImpl(&delegate_, process_host, routing_id, false);
view_ = new RenderWidgetHostViewGuest(
@@ -136,7 +140,7 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
// Call base-class version so that we can test UpdateGuestSizeIfNecessary().
BrowserPluginGuest::SwapCompositorFrame(output_surface_id, host_process_id,
- host_routing_id, frame.Pass());
+ host_routing_id, std::move(frame));
}
void SetChildFrameSurface(const cc::SurfaceId& surface_id,
@@ -181,7 +185,7 @@ class RenderWidgetHostViewGuestSurfaceTest
browser_plugin_guest_ = new TestBrowserPluginGuest(
web_contents_.get(), &browser_plugin_guest_delegate_);
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
widget_host_ =
new RenderWidgetHostImpl(&delegate_, process_host, routing_id, false);
view_ = new RenderWidgetHostViewGuest(
@@ -236,7 +240,7 @@ scoped_ptr<cc::CompositorFrame> CreateDelegatedFrame(float scale_factor,
scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
pass->SetNew(cc::RenderPassId(1, 1), gfx::Rect(size), damage,
gfx::Transform());
- frame->delegated_frame_data->render_pass_list.push_back(pass.Pass());
+ frame->delegated_frame_data->render_pass_list.push_back(std::move(pass));
return frame;
}
} // anonymous namespace
diff --git a/chromium/content/browser/gamepad/gamepad_consumer.h b/chromium/content/browser/gamepad/gamepad_consumer.h
index 1ef5c48038c..a733d4a82a9 100644
--- a/chromium/content/browser/gamepad/gamepad_consumer.h
+++ b/chromium/content/browser/gamepad/gamepad_consumer.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_CONSUMER_H_
#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_CONSUMER_H_
-#include "base/basictypes.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebGamepad.h"
diff --git a/chromium/content/browser/gamepad/gamepad_data_fetcher.cc b/chromium/content/browser/gamepad/gamepad_data_fetcher.cc
new file mode 100644
index 00000000000..891722461e5
--- /dev/null
+++ b/chromium/content/browser/gamepad/gamepad_data_fetcher.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gamepad/gamepad_data_fetcher.h"
+
+#include <stddef.h>
+#include <string.h>
+
+#include "base/logging.h"
+#include "build/build_config.h"
+
+namespace {
+
+#if !defined(OS_ANDROID)
+const float kMinAxisResetValue = 0.1f;
+#endif
+
+} // namespace
+
+namespace content {
+
+using blink::WebGamepad;
+using blink::WebGamepads;
+
+#if !defined(OS_ANDROID)
+void GamepadDataFetcher::MapAndSanitizeGamepadData(
+ PadState* pad_state, WebGamepad* pad) {
+ DCHECK(pad_state);
+ DCHECK(pad);
+
+ if (!pad_state->data.connected) {
+ memset(pad, 0, sizeof(WebGamepad));
+ return;
+ }
+
+ // Copy the current state to the output buffer, using the mapping
+ // function, if there is one available.
+ if (pad_state->mapper)
+ pad_state->mapper(pad_state->data, pad);
+ else
+ *pad = pad_state->data;
+
+ // About sanitization: Gamepads may report input event if the user is not
+ // interacting with it, due to hardware problems or environmental ones (pad
+ // has something heavy leaning against an axis.) This may cause user gestures
+ // to be detected erroniously, exposing gamepad information when the user had
+ // no intention of doing so. To avoid this we require that each button or axis
+ // report being at rest (zero) at least once before exposing its value to the
+ // Gamepad API. This state is tracked by the axis_mask and button_mask
+ // bitfields. If the bit for an axis or button is 0 it means the axis has
+ // never reported being at rest, and the value will be forced to zero.
+
+ // We can skip axis sanitation if all available axes have been masked.
+ uint32_t full_axis_mask = (1 << pad->axesLength) - 1;
+ if (pad_state->axis_mask != full_axis_mask) {
+ for (size_t axis = 0; axis < pad->axesLength; ++axis) {
+ if (!(pad_state->axis_mask & 1 << axis)) {
+ if (fabs(pad->axes[axis]) < kMinAxisResetValue) {
+ pad_state->axis_mask |= 1 << axis;
+ } else {
+ pad->axes[axis] = 0.0f;
+ }
+ }
+ }
+ }
+
+ // We can skip button sanitation if all available buttons have been masked.
+ uint32_t full_button_mask = (1 << pad->buttonsLength) - 1;
+ if (pad_state->button_mask != full_button_mask) {
+ for (size_t button = 0; button < pad->buttonsLength; ++button) {
+ if (!(pad_state->button_mask & 1 << button)) {
+ if (!pad->buttons[button].pressed) {
+ pad_state->button_mask |= 1 << button;
+ } else {
+ pad->buttons[button].pressed = false;
+ pad->buttons[button].value = 0.0f;
+ }
+ }
+ }
+ }
+}
+#endif
+
+} // namespace content
diff --git a/chromium/content/browser/gamepad/gamepad_data_fetcher.h b/chromium/content/browser/gamepad/gamepad_data_fetcher.h
index 17887d5d0e1..a395fd9b0d2 100644
--- a/chromium/content/browser/gamepad/gamepad_data_fetcher.h
+++ b/chromium/content/browser/gamepad/gamepad_data_fetcher.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_DATA_FETCHER_H_
#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_DATA_FETCHER_H_
-namespace blink {
-class WebGamepads;
-}
+#include <stdint.h>
+
+#include "build/build_config.h"
+#include "content/browser/gamepad/gamepad_standard_mappings.h"
+#include "third_party/WebKit/public/platform/WebGamepads.h"
namespace content {
@@ -19,6 +21,39 @@ class GamepadDataFetcher {
virtual void GetGamepadData(blink::WebGamepads* pads,
bool devices_changed_hint) = 0;
virtual void PauseHint(bool paused) {}
+
+#if !defined(OS_ANDROID)
+ struct PadState {
+ // Gamepad data, unmapped.
+ blink::WebGamepad data;
+
+ // Functions to map from device data to standard layout, if available. May
+ // be null if no mapping is available.
+ GamepadStandardMappingFunction mapper;
+
+ // Sanitization masks
+ // axis_mask and button_mask are bitfields that represent the reset state of
+ // each input. If a button or axis has ever reported 0 in the past the
+ // corresponding bit will be set to 1.
+
+ // If we ever increase the max axis count this will need to be updated.
+ static_assert(blink::WebGamepad::axesLengthCap <=
+ std::numeric_limits<uint32_t>::digits,
+ "axis_mask is not large enough");
+ uint32_t axis_mask;
+
+ // If we ever increase the max button count this will need to be updated.
+ static_assert(blink::WebGamepad::buttonsLengthCap <=
+ std::numeric_limits<uint32_t>::digits,
+ "button_mask is not large enough");
+ uint32_t button_mask;
+ };
+
+ void MapAndSanitizeGamepadData(PadState* pad_state, blink::WebGamepad* pad);
+
+ protected:
+ PadState pad_state_[blink::WebGamepads::itemsLengthCap];
+#endif
};
} // namespace content
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher.h b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher.h
index 04aab03e265..d2dc8b73d76 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher.h
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher.h
@@ -8,8 +8,9 @@
#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_H_
#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/gamepad/gamepad_data_fetcher.h"
#if defined(OS_ANDROID)
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.cc b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.cc
index 471a041efe9..1e38cc7f5a9 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.cc
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/gamepad/gamepad_platform_data_fetcher_android.h"
+#include <stddef.h>
+
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.h b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.h
index 4acdfb3b0ad..c6ea2e37e1a 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.h
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_android.h
@@ -11,6 +11,7 @@
#include <jni.h>
#include "base/android/jni_android.h"
+#include "base/macros.h"
#include "content/browser/gamepad/gamepad_data_fetcher.h"
#include "content/browser/gamepad/gamepad_provider.h"
#include "content/browser/gamepad/gamepad_standard_mappings.h"
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
index b3f658e993c..f6fd2d4ef39 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
@@ -11,6 +11,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_number_conversions.h"
@@ -69,9 +70,12 @@ using blink::WebGamepad;
using blink::WebGamepads;
GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() {
- for (size_t i = 0; i < arraysize(device_fds_); ++i)
- device_fds_[i] = -1;
- memset(mappers_, 0, sizeof(mappers_));
+ for (size_t i = 0; i < arraysize(pad_state_); ++i) {
+ device_fd_[i] = -1;
+ pad_state_[i].mapper = 0;
+ pad_state_[i].axis_mask = 0;
+ pad_state_[i].button_mask = 0;
+ }
std::vector<UdevLinux::UdevMonitorFilter> filters;
filters.push_back(UdevLinux::UdevMonitorFilter(kInputSubsystem, NULL));
@@ -85,29 +89,22 @@ GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() {
GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() {
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i)
- CloseFileDescriptorIfValid(device_fds_[i]);
+ CloseFileDescriptorIfValid(device_fd_[i]);
}
void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) {
TRACE_EVENT0("GAMEPAD", "GetGamepadData");
- data_.length = WebGamepads::itemsLengthCap;
-
// Update our internal state.
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
- if (device_fds_[i] >= 0) {
+ if (device_fd_[i] >= 0) {
ReadDeviceData(i);
}
}
- // Copy to the current state to the output buffer, using the mapping
- // function, if there is one available.
- pads->length = data_.length;
+ pads->length = WebGamepads::itemsLengthCap;
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
- if (mappers_[i])
- mappers_[i](data_.items[i], &pads->items[i]);
- else
- pads->items[i] = data_.items[i];
+ MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]);
}
}
@@ -115,10 +112,10 @@ void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) {
void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) {
int index;
std::string node_path;
- if (IsGamepad(dev, &index, &node_path)) {
- int& device_fd = device_fds_[index];
- WebGamepad& pad = data_.items[index];
- GamepadStandardMappingFunction& mapper = mappers_[index];
+ if (IsGamepad(dev, &index, &node_path)) {
+ int& device_fd = device_fd_[index];
+ WebGamepad& pad = pad_state_[index].data;
+ GamepadStandardMappingFunction& mapper = pad_state_[index].mapper;
CloseFileDescriptorIfValid(device_fd);
@@ -203,6 +200,9 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) {
pad.mapping[0] = 0;
}
+ pad_state_[index].axis_mask = 0;
+ pad_state_[index].button_mask = 0;
+
pad.connected = true;
}
}
@@ -242,8 +242,8 @@ void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) {
return;
}
- const int& fd = device_fds_[index];
- WebGamepad& pad = data_.items[index];
+ const int& fd = device_fd_[index];
+ WebGamepad& pad = pad_state_[index].data;
DCHECK_GE(fd, 0);
js_event event;
@@ -252,14 +252,18 @@ void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) {
if (event.type & JS_EVENT_AXIS) {
if (item >= WebGamepad::axesLengthCap)
continue;
+
pad.axes[item] = event.value / kMaxLinuxAxisValue;
+
if (item >= pad.axesLength)
pad.axesLength = item + 1;
} else if (event.type & JS_EVENT_BUTTON) {
if (item >= WebGamepad::buttonsLengthCap)
continue;
+
pad.buttons[item].pressed = event.value;
pad.buttons[item].value = event.value ? 1.0 : 0.0;
+
if (item >= pad.buttonsLength)
pad.buttonsLength = item + 1;
}
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h
index dab9497fef0..b98646a4e7f 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h
@@ -5,14 +5,14 @@
#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_LINUX_H_
#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_LINUX_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/gamepad/gamepad_data_fetcher.h"
-#include "content/browser/gamepad/gamepad_standard_mappings.h"
-#include "third_party/WebKit/public/platform/WebGamepads.h"
extern "C" {
struct udev_device;
@@ -36,15 +36,8 @@ class GamepadPlatformDataFetcherLinux : public GamepadDataFetcher {
void EnumerateDevices();
void ReadDeviceData(size_t index);
- // File descriptors for the /dev/input/js* devices. -1 if not in use.
- int device_fds_[blink::WebGamepads::itemsLengthCap];
-
- // Functions to map from device data to standard layout, if available. May
- // be null if no mapping is available.
- GamepadStandardMappingFunction mappers_[blink::WebGamepads::itemsLengthCap];
-
- // Data that's returned to the consumer.
- blink::WebGamepads data_;
+ // File descriptor for the /dev/input/js* devices. -1 if not in use.
+ int device_fd_[blink::WebGamepads::itemsLengthCap];
scoped_ptr<UdevLinux> udev_;
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
index 15de8d1cc4b..ebfe57e35f4 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
@@ -5,16 +5,16 @@
#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_MAC_H_
#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_MAC_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
#include "base/compiler_specific.h"
#include "base/mac/scoped_cftyperef.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "content/browser/gamepad/gamepad_data_fetcher.h"
-#include "content/browser/gamepad/gamepad_standard_mappings.h"
#include "content/browser/gamepad/xbox_data_fetcher_mac.h"
#include "content/common/gamepad_hardware_buffer.h"
-#include "third_party/WebKit/public/platform/WebGamepads.h"
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/hid/IOHIDManager.h>
@@ -72,9 +72,9 @@ class GamepadPlatformDataFetcherMac : public GamepadDataFetcher,
void RegisterForNotifications();
void UnregisterFromNotifications();
- scoped_ptr<XboxDataFetcher> xbox_fetcher_;
+ void SanitizeGamepadData(size_t index, blink::WebGamepad* pad);
- blink::WebGamepads data_;
+ scoped_ptr<XboxDataFetcher> xbox_fetcher_;
// Side-band data that's not passed to the consumer, but we need to maintain
// to update data_.
@@ -87,9 +87,6 @@ class GamepadPlatformDataFetcherMac : public GamepadDataFetcher,
IOHIDElementRef axis_elements[blink::WebGamepad::axesLengthCap];
CFIndex axis_minimums[blink::WebGamepad::axesLengthCap];
CFIndex axis_maximums[blink::WebGamepad::axesLengthCap];
- // Function to map from device data to standard layout, if available.
- // May be null if no mapping is available.
- GamepadStandardMappingFunction mapper;
} hid;
struct {
XboxController* device;
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
index f25d15a5cf1..4d55c558562 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
@@ -4,8 +4,12 @@
#include "content/browser/gamepad/gamepad_platform_data_fetcher_mac.h"
+#include <stdint.h>
+#include <string.h>
+
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -154,7 +158,7 @@ void GamepadPlatformDataFetcherMac::ValueChangedCallback(void* context,
bool GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements,
size_t slot) {
- WebGamepad& pad = data_.items[slot];
+ WebGamepad& pad = pad_state_[slot].data;
AssociatedData& associated = associated_[slot];
CHECK(!associated.is_xbox);
@@ -228,7 +232,7 @@ bool GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements,
size_t GamepadPlatformDataFetcherMac::GetEmptySlot() {
// Find a free slot for this device.
for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) {
- if (!data_.items[slot].connected)
+ if (!pad_state_[slot].data.connected)
return slot;
}
return WebGamepads::itemsLengthCap;
@@ -238,7 +242,7 @@ size_t GamepadPlatformDataFetcherMac::GetSlotForDevice(IOHIDDeviceRef device) {
for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) {
// If we already have this device, and it's already connected, don't do
// anything now.
- if (data_.items[slot].connected &&
+ if (pad_state_[slot].data.connected &&
!associated_[slot].is_xbox &&
associated_[slot].hid.device_ref == device)
return WebGamepads::itemsLengthCap;
@@ -251,7 +255,7 @@ size_t GamepadPlatformDataFetcherMac::GetSlotForXboxDevice(
for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) {
if (associated_[slot].is_xbox &&
associated_[slot].xbox.location_id == device->location_id()) {
- if (data_.items[slot].connected) {
+ if (pad_state_[slot].data.connected) {
// The device is already connected. No idea why we got a second "device
// added" call, but let's not add it twice.
DCHECK_EQ(associated_[slot].xbox.device, device);
@@ -295,27 +299,27 @@ void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) {
char vendor_as_str[5], product_as_str[5];
snprintf(vendor_as_str, sizeof(vendor_as_str), "%04x", vendor_int);
snprintf(product_as_str, sizeof(product_as_str), "%04x", product_int);
- associated_[slot].hid.mapper =
+ pad_state_[slot].mapper =
GetGamepadStandardMappingFunction(vendor_as_str, product_as_str);
NSString* ident = [NSString stringWithFormat:
@"%@ (%sVendor: %04x Product: %04x)",
product,
- associated_[slot].hid.mapper ? "STANDARD GAMEPAD " : "",
+ pad_state_[slot].mapper ? "STANDARD GAMEPAD " : "",
vendor_int,
product_int];
CopyNSStringAsUTF16LittleEndian(
ident,
- data_.items[slot].id,
- sizeof(data_.items[slot].id));
+ pad_state_[slot].data.id,
+ sizeof(pad_state_[slot].data.id));
- if (associated_[slot].hid.mapper) {
+ if (pad_state_[slot].mapper) {
CopyNSStringAsUTF16LittleEndian(
@"standard",
- data_.items[slot].mapping,
- sizeof(data_.items[slot].mapping));
+ pad_state_[slot].data.mapping,
+ sizeof(pad_state_[slot].data.mapping));
} else {
- data_.items[slot].mapping[0] = 0;
+ pad_state_[slot].data.mapping[0] = 0;
}
base::ScopedCFTypeRef<CFArrayRef> elements(
@@ -325,9 +329,9 @@ void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) {
return;
associated_[slot].hid.device_ref = device;
- data_.items[slot].connected = true;
- if (slot >= data_.length)
- data_.length = slot + 1;
+ pad_state_[slot].data.connected = true;
+ pad_state_[slot].axis_mask = 0;
+ pad_state_[slot].button_mask = 0;
}
void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) {
@@ -337,7 +341,7 @@ void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) {
// Find the index for this device.
size_t slot;
for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) {
- if (data_.items[slot].connected &&
+ if (pad_state_[slot].data.connected &&
!associated_[slot].is_xbox &&
associated_[slot].hid.device_ref == device)
break;
@@ -345,7 +349,7 @@ void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) {
DCHECK(slot < WebGamepads::itemsLengthCap);
// Leave associated device_ref so that it will be reconnected in the same
// location. Simply mark it as disconnected.
- data_.items[slot].connected = false;
+ pad_state_[slot].data.connected = false;
}
void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) {
@@ -357,16 +361,16 @@ void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) {
// Find device slot.
size_t slot;
- for (slot = 0; slot < data_.length; ++slot) {
- if (data_.items[slot].connected &&
+ for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) {
+ if (pad_state_[slot].data.connected &&
!associated_[slot].is_xbox &&
associated_[slot].hid.device_ref == device)
break;
}
- if (slot == data_.length)
+ if (slot == WebGamepads::itemsLengthCap)
return;
- WebGamepad& pad = data_.items[slot];
+ WebGamepad& pad = pad_state_[slot].data;
AssociatedData& associated = associated_[slot];
uint32_t value_length = IOHIDValueGetLength(value);
@@ -420,23 +424,24 @@ void GamepadPlatformDataFetcherMac::XboxDeviceAdd(XboxController* device) {
device->GetProductId(), device->GetVendorId()];
CopyNSStringAsUTF16LittleEndian(
ident,
- data_.items[slot].id,
- sizeof(data_.items[slot].id));
+ pad_state_[slot].data.id,
+ sizeof(pad_state_[slot].data.id));
CopyNSStringAsUTF16LittleEndian(
@"standard",
- data_.items[slot].mapping,
- sizeof(data_.items[slot].mapping));
+ pad_state_[slot].data.mapping,
+ sizeof(pad_state_[slot].data.mapping));
associated_[slot].is_xbox = true;
associated_[slot].xbox.device = device;
associated_[slot].xbox.location_id = device->location_id();
- data_.items[slot].connected = true;
- data_.items[slot].axesLength = 4;
- data_.items[slot].buttonsLength = 17;
- data_.items[slot].timestamp = 0;
- if (slot >= data_.length)
- data_.length = slot + 1;
+ pad_state_[slot].data.connected = true;
+ pad_state_[slot].data.axesLength = 4;
+ pad_state_[slot].data.buttonsLength = 17;
+ pad_state_[slot].data.timestamp = 0;
+ pad_state_[slot].mapper = 0;
+ pad_state_[slot].axis_mask = 0;
+ pad_state_[slot].button_mask = 0;
}
void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) {
@@ -446,7 +451,7 @@ void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) {
// Find the index for this device.
size_t slot;
for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) {
- if (data_.items[slot].connected &&
+ if (pad_state_[slot].data.connected &&
associated_[slot].is_xbox &&
associated_[slot].xbox.device == device)
break;
@@ -454,23 +459,23 @@ void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) {
DCHECK(slot < WebGamepads::itemsLengthCap);
// Leave associated location id so that the controller will be reconnected in
// the same slot if it is plugged in again. Simply mark it as disconnected.
- data_.items[slot].connected = false;
+ pad_state_[slot].data.connected = false;
}
void GamepadPlatformDataFetcherMac::XboxValueChanged(
XboxController* device, const XboxController::Data& data) {
// Find device slot.
size_t slot;
- for (slot = 0; slot < data_.length; ++slot) {
- if (data_.items[slot].connected &&
+ for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) {
+ if (pad_state_[slot].data.connected &&
associated_[slot].is_xbox &&
associated_[slot].xbox.device == device)
break;
}
- if (slot == data_.length)
+ if (slot == WebGamepads::itemsLengthCap)
return;
- WebGamepad& pad = data_.items[slot];
+ WebGamepad& pad = pad_state_[slot].data;
for (size_t i = 0; i < 6; i++) {
pad.buttons[i].pressed = data.buttons[i];
@@ -497,15 +502,9 @@ void GamepadPlatformDataFetcherMac::GetGamepadData(WebGamepads* pads, bool) {
return;
}
- // Copy to the current state to the output buffer, using the mapping
- // function, if there is one available.
pads->length = WebGamepads::itemsLengthCap;
- for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
- if (!associated_[i].is_xbox && associated_[i].hid.mapper)
- associated_[i].hid.mapper(data_.items[i], &pads->items[i]);
- else
- pads->items[i] = data_.items[i];
- }
+ for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i)
+ MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]);
}
} // namespace content
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc
index aca009605ed..3983694f110 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc
@@ -4,6 +4,9 @@
#include "content/browser/gamepad/gamepad_platform_data_fetcher_win.h"
+#include <stddef.h>
+#include <string.h>
+
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "base/win/windows_version.h"
@@ -34,7 +37,7 @@ float NormalizeXInputAxis(SHORT value) {
return ((value + 32768.f) / 32767.5f) - 1.f;
}
-const WebUChar* const GamepadSubTypeName(BYTE sub_type) {
+const WebUChar* GamepadSubTypeName(BYTE sub_type) {
switch (sub_type) {
case kDeviceSubTypeGamepad: return L"GAMEPAD";
case kDeviceSubTypeWheel: return L"WHEEL";
@@ -55,8 +58,12 @@ const WebUChar* const GamepadSubTypeName(BYTE sub_type) {
GamepadPlatformDataFetcherWin::GamepadPlatformDataFetcherWin()
: xinput_dll_(base::FilePath(FILE_PATH_LITERAL("xinput1_3.dll"))),
xinput_available_(GetXInputDllFunctions()) {
- for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i)
- pad_state_[i].status = DISCONNECTED;
+ for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
+ platform_pad_state_[i].status = DISCONNECTED;
+ pad_state_[i].mapper = NULL;
+ pad_state_[i].axis_mask = 0;
+ pad_state_[i].button_mask = 0;
+ }
raw_input_fetcher_.reset(new RawInputDataFetcher());
raw_input_fetcher_->StartMonitor();
@@ -68,7 +75,7 @@ GamepadPlatformDataFetcherWin::~GamepadPlatformDataFetcherWin() {
int GamepadPlatformDataFetcherWin::FirstAvailableGamepadId() const {
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
- if (pad_state_[i].status == DISCONNECTED)
+ if (platform_pad_state_[i].status == DISCONNECTED)
return i;
}
return -1;
@@ -76,8 +83,8 @@ int GamepadPlatformDataFetcherWin::FirstAvailableGamepadId() const {
bool GamepadPlatformDataFetcherWin::HasXInputGamepad(int index) const {
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
- if (pad_state_[i].status == XINPUT_CONNECTED &&
- pad_state_[i].xinput_index == index)
+ if (platform_pad_state_[i].status == XINPUT_CONNECTED &&
+ platform_pad_state_[i].xinput_index == index)
return true;
}
return false;
@@ -86,21 +93,20 @@ bool GamepadPlatformDataFetcherWin::HasXInputGamepad(int index) const {
bool GamepadPlatformDataFetcherWin::HasRawInputGamepad(
const HANDLE handle) const {
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
- if (pad_state_[i].status == RAWINPUT_CONNECTED &&
- pad_state_[i].raw_input_handle == handle)
+ if (platform_pad_state_[i].status == RAWINPUT_CONNECTED &&
+ platform_pad_state_[i].raw_input_handle == handle)
return true;
}
return false;
}
-void GamepadPlatformDataFetcherWin::EnumerateDevices(
- WebGamepads* pads) {
+void GamepadPlatformDataFetcherWin::EnumerateDevices() {
TRACE_EVENT0("GAMEPAD", "EnumerateDevices");
// Mark all disconnected pads DISCONNECTED.
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
- if (!pads->items[i].connected)
- pad_state_[i].status = DISCONNECTED;
+ if (!pad_state_[i].data.connected)
+ platform_pad_state_[i].status = DISCONNECTED;
}
for (size_t i = 0; i < XUSER_MAX_COUNT; ++i) {
@@ -109,11 +115,13 @@ void GamepadPlatformDataFetcherWin::EnumerateDevices(
int pad_index = FirstAvailableGamepadId();
if (pad_index == -1)
return; // We can't add any more gamepads.
- WebGamepad& pad = pads->items[pad_index];
+ WebGamepad& pad = pad_state_[pad_index].data;
if (xinput_available_ && GetXInputPadConnectivity(i, &pad)) {
- pad_state_[pad_index].status = XINPUT_CONNECTED;
- pad_state_[pad_index].xinput_index = i;
+ platform_pad_state_[pad_index].status = XINPUT_CONNECTED;
+ platform_pad_state_[pad_index].xinput_index = i;
pad_state_[pad_index].mapper = NULL;
+ pad_state_[pad_index].axis_mask = 0;
+ pad_state_[pad_index].button_mask = 0;
}
}
@@ -129,15 +137,18 @@ void GamepadPlatformDataFetcherWin::EnumerateDevices(
int pad_index = FirstAvailableGamepadId();
if (pad_index == -1)
return;
- WebGamepad& pad = pads->items[pad_index];
+ WebGamepad& pad = pad_state_[pad_index].data;
pad.connected = true;
PadState& state = pad_state_[pad_index];
- state.status = RAWINPUT_CONNECTED;
- state.raw_input_handle = gamepad->handle;
+ PlatformPadState& platform_state = platform_pad_state_[pad_index];
+ platform_state.status = RAWINPUT_CONNECTED;
+ platform_state.raw_input_handle = gamepad->handle;
std::string vendor = base::StringPrintf("%04x", gamepad->vendor_id);
std::string product = base::StringPrintf("%04x", gamepad->product_id);
state.mapper = GetGamepadStandardMappingFunction(vendor, product);
+ state.axis_mask = 0;
+ state.button_mask = 0;
swprintf(pad.id, WebGamepad::idLengthCap,
L"%ls (%lsVendor: %04x Product: %04x)",
@@ -148,12 +159,10 @@ void GamepadPlatformDataFetcherWin::EnumerateDevices(
swprintf(pad.mapping, WebGamepad::mappingLengthCap, L"standard");
else
pad.mapping[0] = 0;
-
}
}
}
-
void GamepadPlatformDataFetcherWin::GetGamepadData(WebGamepads* pads,
bool devices_changed_hint) {
TRACE_EVENT0("GAMEPAD", "GetGamepadData");
@@ -172,20 +181,23 @@ void GamepadPlatformDataFetcherWin::GetGamepadData(WebGamepads* pads,
// here by only doing this when the devices are updated (despite
// documentation claiming it's OK to call it any time).
if (devices_changed_hint)
- EnumerateDevices(pads);
+ EnumerateDevices();
pads->length = 0;
+
for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
// We rely on device_changed and GetCapabilities to tell us that
// something's been connected, but we will mark as disconnected if
// Get___PadState returns that we've lost the pad.
- if (!pads->items[i].connected)
+ if (!pad_state_[i].data.connected)
continue;
- if (pad_state_[i].status == XINPUT_CONNECTED)
- GetXInputPadData(i, &pads->items[i]);
- else if (pad_state_[i].status == RAWINPUT_CONNECTED)
- GetRawInputPadData(i, &pads->items[i]);
+ if (platform_pad_state_[i].status == XINPUT_CONNECTED)
+ GetXInputPadData(i, &pad_state_[i].data);
+ else if (platform_pad_state_[i].status == RAWINPUT_CONNECTED)
+ GetRawInputPadData(i, &pad_state_[i].data);
+
+ MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]);
if (pads->items[i].connected)
pads->length++;
@@ -226,30 +238,33 @@ void GamepadPlatformDataFetcherWin::GetXInputPadData(
XINPUT_STATE state;
memset(&state, 0, sizeof(XINPUT_STATE));
TRACE_EVENT_BEGIN1("GAMEPAD", "XInputGetState", "id", i);
- DWORD dwResult = xinput_get_state_(pad_state_[i].xinput_index, &state);
+ DWORD dwResult = xinput_get_state_(platform_pad_state_[i].xinput_index,
+ &state);
TRACE_EVENT_END1("GAMEPAD", "XInputGetState", "id", i);
if (dwResult == ERROR_SUCCESS) {
pad->timestamp = state.dwPacketNumber;
pad->buttonsLength = 0;
-#define ADD(b) pad->buttons[pad->buttonsLength].pressed = \
- (state.Gamepad.wButtons & (b)) != 0; \
- pad->buttons[pad->buttonsLength++].value = \
- ((state.Gamepad.wButtons & (b)) ? 1.f : 0.f);
+ WORD val = state.Gamepad.wButtons;
+#define ADD(b) pad->buttons[pad->buttonsLength].pressed = (val & (b)) != 0; \
+ pad->buttons[pad->buttonsLength++].value = ((val & (b)) ? 1.f : 0.f);
ADD(XINPUT_GAMEPAD_A);
ADD(XINPUT_GAMEPAD_B);
ADD(XINPUT_GAMEPAD_X);
ADD(XINPUT_GAMEPAD_Y);
ADD(XINPUT_GAMEPAD_LEFT_SHOULDER);
ADD(XINPUT_GAMEPAD_RIGHT_SHOULDER);
+
pad->buttons[pad->buttonsLength].pressed =
- state.Gamepad.bLeftTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
+ state.Gamepad.bLeftTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
pad->buttons[pad->buttonsLength++].value =
- state.Gamepad.bLeftTrigger / 255.f;
+ state.Gamepad.bLeftTrigger / 255.f;
+
pad->buttons[pad->buttonsLength].pressed =
- state.Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
+ state.Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
pad->buttons[pad->buttonsLength++].value =
- state.Gamepad.bRightTrigger / 255.f;
+ state.Gamepad.bRightTrigger / 255.f;
+
ADD(XINPUT_GAMEPAD_BACK);
ADD(XINPUT_GAMEPAD_START);
ADD(XINPUT_GAMEPAD_LEFT_THUMB);
@@ -260,11 +275,17 @@ void GamepadPlatformDataFetcherWin::GetXInputPadData(
ADD(XINPUT_GAMEPAD_DPAD_RIGHT);
#undef ADD
pad->axesLength = 0;
+
+ float value = 0.0;
+#define ADD(a, factor) value = factor * NormalizeXInputAxis(a); \
+ pad->axes[pad->axesLength++] = value;
+
// XInput are +up/+right, -down/-left, we want -up/-left.
- pad->axes[pad->axesLength++] = NormalizeXInputAxis(state.Gamepad.sThumbLX);
- pad->axes[pad->axesLength++] = -NormalizeXInputAxis(state.Gamepad.sThumbLY);
- pad->axes[pad->axesLength++] = NormalizeXInputAxis(state.Gamepad.sThumbRX);
- pad->axes[pad->axesLength++] = -NormalizeXInputAxis(state.Gamepad.sThumbRY);
+ ADD(state.Gamepad.sThumbLX, 1);
+ ADD(state.Gamepad.sThumbLY, -1);
+ ADD(state.Gamepad.sThumbRX, 1);
+ ADD(state.Gamepad.sThumbRY, -1);
+#undef ADD
} else {
pad->connected = false;
}
@@ -274,32 +295,23 @@ void GamepadPlatformDataFetcherWin::GetRawInputPadData(
int index,
WebGamepad* pad) {
RawGamepadInfo* gamepad = raw_input_fetcher_->GetGamepadInfo(
- pad_state_[index].raw_input_handle);
+ platform_pad_state_[index].raw_input_handle);
if (!gamepad) {
pad->connected = false;
return;
}
- WebGamepad raw_pad = *pad;
-
- raw_pad.timestamp = gamepad->report_id;
- raw_pad.buttonsLength = gamepad->buttons_length;
- raw_pad.axesLength = gamepad->axes_length;
+ pad->timestamp = gamepad->report_id;
+ pad->buttonsLength = gamepad->buttons_length;
+ pad->axesLength = gamepad->axes_length;
- for (unsigned int i = 0; i < raw_pad.buttonsLength; i++) {
- raw_pad.buttons[i].pressed = gamepad->buttons[i];
- raw_pad.buttons[i].value = gamepad->buttons[i] ? 1.0 : 0.0;
+ for (unsigned int i = 0; i < pad->buttonsLength; i++) {
+ pad->buttons[i].pressed = gamepad->buttons[i];
+ pad->buttons[i].value = gamepad->buttons[i] ? 1.0 : 0.0;
}
- for (unsigned int i = 0; i < raw_pad.axesLength; i++)
- raw_pad.axes[i] = gamepad->axes[i].value;
-
- // Copy to the current state to the output buffer, using the mapping
- // function, if there is one available.
- if (pad_state_[index].mapper)
- pad_state_[index].mapper(raw_pad, pad);
- else
- *pad = raw_pad;
+ for (unsigned int i = 0; i < pad->axesLength; i++)
+ pad->axes[i] = gamepad->axes[i].value;
}
bool GamepadPlatformDataFetcherWin::GetXInputDllFunctions() {
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.h b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.h
index 33dab0ca2e6..f1efab3440b 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.h
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_win.h
@@ -16,8 +16,8 @@
#include <windows.h>
#include <XInput.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -56,7 +56,7 @@ class GamepadPlatformDataFetcherWin : public GamepadDataFetcher {
bool GetXInputDllFunctions();
// Scan for connected XInput and DirectInput gamepads.
- void EnumerateDevices(blink::WebGamepads* pads);
+ void EnumerateDevices();
bool GetXInputPadConnectivity(int i, blink::WebGamepad* pad) const;
void GetXInputPadData(int i, blink::WebGamepad* pad);
@@ -81,14 +81,13 @@ class GamepadPlatformDataFetcherWin : public GamepadDataFetcher {
RAWINPUT_CONNECTED
};
- struct PadState {
+ struct PlatformPadState {
PadConnectionStatus status;
- GamepadStandardMappingFunction mapper;
int xinput_index; // XInput-only
HANDLE raw_input_handle; // RawInput-only fields.
};
- PadState pad_state_[blink::WebGamepads::itemsLengthCap];
+ PlatformPadState platform_pad_state_[blink::WebGamepads::itemsLengthCap];
scoped_ptr<RawInputDataFetcher> raw_input_fetcher_;
diff --git a/chromium/content/browser/gamepad/gamepad_provider.cc b/chromium/content/browser/gamepad/gamepad_provider.cc
index eef900133b0..682afc51d35 100644
--- a/chromium/content/browser/gamepad/gamepad_provider.cc
+++ b/chromium/content/browser/gamepad/gamepad_provider.cc
@@ -2,8 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/gamepad/gamepad_provider.h"
+
+#include <stddef.h>
+#include <string.h>
#include <cmath>
#include <set>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -14,9 +19,9 @@
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
#include "content/browser/gamepad/gamepad_data_fetcher.h"
#include "content/browser/gamepad/gamepad_platform_data_fetcher.h"
-#include "content/browser/gamepad/gamepad_provider.h"
#include "content/browser/gamepad/gamepad_service.h"
#include "content/common/gamepad_hardware_buffer.h"
#include "content/common/gamepad_messages.h"
@@ -50,7 +55,7 @@ GamepadProvider::GamepadProvider(scoped_ptr<GamepadDataFetcher> fetcher)
have_scheduled_do_poll_(false),
devices_changed_(true),
ever_had_user_gesture_(false) {
- Initialize(fetcher.Pass());
+ Initialize(std::move(fetcher));
}
GamepadProvider::~GamepadProvider() {
@@ -156,7 +161,7 @@ void GamepadProvider::DoInitializePollingThread(
if (!fetcher)
fetcher.reset(new GamepadPlatformDataFetcher);
- data_fetcher_ = fetcher.Pass();
+ data_fetcher_ = std::move(fetcher);
}
void GamepadProvider::SendPauseHint(bool paused) {
diff --git a/chromium/content/browser/gamepad/gamepad_provider.h b/chromium/content/browser/gamepad/gamepad_provider.h
index ce9c11a8e09..f2dcad245bb 100644
--- a/chromium/content/browser/gamepad/gamepad_provider.h
+++ b/chromium/content/browser/gamepad/gamepad_provider.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
diff --git a/chromium/content/browser/gamepad/gamepad_provider_unittest.cc b/chromium/content/browser/gamepad/gamepad_provider_unittest.cc
index c810a6ac0cd..7e3a29c88b8 100644
--- a/chromium/content/browser/gamepad/gamepad_provider_unittest.cc
+++ b/chromium/content/browser/gamepad/gamepad_provider_unittest.cc
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "content/browser/gamepad/gamepad_data_fetcher.h"
#include "content/browser/gamepad/gamepad_provider.h"
#include "content/browser/gamepad/gamepad_test_helpers.h"
@@ -126,8 +128,8 @@ TEST_F(GamepadProviderTest, UserGesture) {
no_button_data.items[0].axesLength = 2;
no_button_data.items[0].buttons[0].value = 0.f;
no_button_data.items[0].buttons[0].pressed = false;
- no_button_data.items[0].axes[0] = -1.f;
- no_button_data.items[0].axes[1] = .5f;
+ no_button_data.items[0].axes[0] = 0.f;
+ no_button_data.items[0].axes[1] = .4f;
WebGamepads button_down_data = no_button_data;
button_down_data.items[0].buttons[0].value = 1.f;
diff --git a/chromium/content/browser/gamepad/gamepad_service.cc b/chromium/content/browser/gamepad/gamepad_service.cc
index 67930f6118d..411ae01182e 100644
--- a/chromium/content/browser/gamepad/gamepad_service.cc
+++ b/chromium/content/browser/gamepad/gamepad_service.cc
@@ -4,6 +4,8 @@
#include "content/browser/gamepad/gamepad_service.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
@@ -26,7 +28,7 @@ GamepadService::GamepadService()
}
GamepadService::GamepadService(scoped_ptr<GamepadDataFetcher> fetcher)
- : provider_(new GamepadProvider(fetcher.Pass())),
+ : provider_(new GamepadProvider(std::move(fetcher))),
num_active_consumers_(0),
gesture_callback_pending_(false) {
SetInstance(this);
diff --git a/chromium/content/browser/gamepad/gamepad_service.h b/chromium/content/browser/gamepad/gamepad_service.h
index c94d320c6b6..22bea8c02a8 100644
--- a/chromium/content/browser/gamepad/gamepad_service.h
+++ b/chromium/content/browser/gamepad/gamepad_service.h
@@ -7,8 +7,8 @@
#include <set>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/memory/singleton.h"
diff --git a/chromium/content/browser/gamepad/gamepad_service_unittest.cc b/chromium/content/browser/gamepad/gamepad_service_unittest.cc
index acfa6a37acc..5b9d1c28e18 100644
--- a/chromium/content/browser/gamepad/gamepad_service_unittest.cc
+++ b/chromium/content/browser/gamepad/gamepad_service_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <string.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "content/browser/gamepad/gamepad_consumer.h"
diff --git a/chromium/content/browser/gamepad/gamepad_standard_mappings_linux.cc b/chromium/content/browser/gamepad/gamepad_standard_mappings_linux.cc
index 48b59ac5a90..3cd7747b3f5 100644
--- a/chromium/content/browser/gamepad/gamepad_standard_mappings_linux.cc
+++ b/chromium/content/browser/gamepad/gamepad_standard_mappings_linux.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
+#include "base/macros.h"
#include "content/browser/gamepad/gamepad_standard_mappings.h"
namespace content {
@@ -232,10 +235,9 @@ struct MappingData {
} AvailableMappings[] = {
// http://www.linux-usb.org/usb.ids
{"0079", "0006", MapperDragonRiseGeneric}, // DragonRise Generic USB
- {"045e", "028e", MapperXInputStyleGamepad}, // Xbox 360 Controller
- {"045e",
- "028f",
- MapperXInputStyleGamepad}, // Xbox 360 Wireless Controller
+ {"045e", "028e", MapperXInputStyleGamepad}, // Xbox 360 Wired
+ {"045e", "028f", MapperXInputStyleGamepad}, // Xbox 360 Wireless
+ {"045e", "0719", MapperXInputStyleGamepad}, // Xbox 360 Wireless
{"046d", "c21d", MapperXInputStyleGamepad}, // Logitech F310
{"046d", "c21e", MapperXInputStyleGamepad}, // Logitech F510
{"046d", "c21f", MapperXInputStyleGamepad}, // Logitech F710
diff --git a/chromium/content/browser/gamepad/gamepad_standard_mappings_mac.mm b/chromium/content/browser/gamepad/gamepad_standard_mappings_mac.mm
index 4377bd2af11..2d3be550c97 100644
--- a/chromium/content/browser/gamepad/gamepad_standard_mappings_mac.mm
+++ b/chromium/content/browser/gamepad/gamepad_standard_mappings_mac.mm
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
+#include "base/macros.h"
#include "content/browser/gamepad/gamepad_standard_mappings.h"
namespace content {
@@ -263,8 +266,9 @@ struct MappingData {
} AvailableMappings[] = {
// http://www.linux-usb.org/usb.ids
{"0079", "0006", MapperDragonRiseGeneric}, // DragonRise Generic USB
- {"045e", "028e", MapperXbox360Gamepad}, // Xbox 360 Controller
- {"045e", "028f", MapperXbox360Gamepad}, // Xbox 360 Wireless Controller
+ {"045e", "028e", MapperXbox360Gamepad}, // Xbox 360 Wired
+ {"045e", "028f", MapperXbox360Gamepad}, // Xbox 360 Wireless
+ {"045e", "0719", MapperXbox360Gamepad}, // Xbox 360 Wireless
{"046d", "c216", MapperDirectInputStyle}, // Logitech F310, D mode
{"046d", "c218", MapperDirectInputStyle}, // Logitech F510, D mode
{"046d", "c219", MapperDirectInputStyle}, // Logitech F710, D mode
diff --git a/chromium/content/browser/gamepad/gamepad_standard_mappings_win.cc b/chromium/content/browser/gamepad/gamepad_standard_mappings_win.cc
index c03fe4fbf70..37723778f13 100644
--- a/chromium/content/browser/gamepad/gamepad_standard_mappings_win.cc
+++ b/chromium/content/browser/gamepad/gamepad_standard_mappings_win.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
+#include "base/macros.h"
#include "content/browser/gamepad/gamepad_standard_mappings.h"
namespace content {
diff --git a/chromium/content/browser/gamepad/gamepad_test_helpers.h b/chromium/content/browser/gamepad/gamepad_test_helpers.h
index dbaa9664912..5e30f99fad3 100644
--- a/chromium/content/browser/gamepad/gamepad_test_helpers.h
+++ b/chromium/content/browser/gamepad/gamepad_test_helpers.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_TEST_HELPERS_H_
#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_TEST_HELPERS_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
diff --git a/chromium/content/browser/gamepad/raw_input_data_fetcher_win.cc b/chromium/content/browser/gamepad/raw_input_data_fetcher_win.cc
index 8b3b34fb006..0693eef9eb8 100644
--- a/chromium/content/browser/gamepad/raw_input_data_fetcher_win.cc
+++ b/chromium/content/browser/gamepad/raw_input_data_fetcher_win.cc
@@ -4,6 +4,9 @@
#include "content/browser/gamepad/raw_input_data_fetcher_win.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/trace_event/trace_event.h"
#include "content/common/gamepad_hardware_buffer.h"
#include "content/common/gamepad_messages.h"
@@ -58,9 +61,9 @@ void RawInputDataFetcher::WillDestroyCurrentMessageLoop() {
}
RAWINPUTDEVICE* RawInputDataFetcher::GetRawInputDevices(DWORD flags) {
- int usage_count = arraysize(DeviceUsages);
+ size_t usage_count = arraysize(DeviceUsages);
scoped_ptr<RAWINPUTDEVICE[]> devices(new RAWINPUTDEVICE[usage_count]);
- for (int i = 0; i < usage_count; ++i) {
+ for (size_t i = 0; i < usage_count; ++i) {
devices[i].dwFlags = flags;
devices[i].usUsagePage = 1;
devices[i].usUsage = DeviceUsages[i];
@@ -187,7 +190,7 @@ RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) {
}
DCHECK_EQ(0u, result);
- scoped_ptr<uint8[]> di_buffer(new uint8[size]);
+ scoped_ptr<uint8_t[]> di_buffer(new uint8_t[size]);
RID_DEVICE_INFO* device_info =
reinterpret_cast<RID_DEVICE_INFO*>(di_buffer.get());
result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO,
@@ -200,8 +203,8 @@ RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) {
// Make sure this device is of a type that we want to observe.
bool valid_type = false;
- for (int i = 0; i < arraysize(DeviceUsages); ++i) {
- if (device_info->hid.usUsage == DeviceUsages[i]) {
+ for (USHORT device_usage : DeviceUsages) {
+ if (device_info->hid.usUsage == device_usage) {
valid_type = true;
break;
}
@@ -266,7 +269,7 @@ RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) {
}
DCHECK_EQ(0u, result);
- gamepad_info->ppd_buffer.reset(new uint8[size]);
+ gamepad_info->ppd_buffer.reset(new uint8_t[size]);
gamepad_info->preparsed_data =
reinterpret_cast<PHIDP_PREPARSED_DATA>(gamepad_info->ppd_buffer.get());
result = GetRawInputDeviceInfo(hDevice, RIDI_PREPARSEDDATA,
@@ -389,8 +392,10 @@ void RawInputDataFetcher::UpdateGamepad(
for (uint32_t j = 0; j < buttons_length; j++) {
int32_t button_index = usages[j].Usage - 1;
if (button_index >= 0 &&
- button_index < blink::WebGamepad::buttonsLengthCap)
+ button_index <
+ static_cast<int>(blink::WebGamepad::buttonsLengthCap)) {
gamepad_info->buttons[button_index] = true;
+ }
}
}
}
@@ -440,7 +445,7 @@ LRESULT RawInputDataFetcher::OnInput(HRAWINPUT input_handle) {
DCHECK_EQ(0u, result);
// Retrieve the input record.
- scoped_ptr<uint8[]> buffer(new uint8[size]);
+ scoped_ptr<uint8_t[]> buffer(new uint8_t[size]);
RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get());
result = GetRawInputData(
input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER));
diff --git a/chromium/content/browser/gamepad/raw_input_data_fetcher_win.h b/chromium/content/browser/gamepad/raw_input_data_fetcher_win.h
index 3de85df7326..69b780d5793 100644
--- a/chromium/content/browser/gamepad/raw_input_data_fetcher_win.h
+++ b/chromium/content/browser/gamepad/raw_input_data_fetcher_win.h
@@ -7,6 +7,7 @@
#include "build/build_config.h"
+#include <stdint.h>
#include <stdlib.h>
#include <Unknwn.h>
#include <WinDef.h>
@@ -16,6 +17,7 @@
#include <map>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -39,7 +41,7 @@ struct RawGamepadInfo {
~RawGamepadInfo();
HANDLE handle;
- scoped_ptr<uint8[]> ppd_buffer;
+ scoped_ptr<uint8_t[]> ppd_buffer;
PHIDP_PREPARSED_DATA preparsed_data;
uint32_t report_id;
diff --git a/chromium/content/browser/gamepad/xbox_data_fetcher_mac.cc b/chromium/content/browser/gamepad/xbox_data_fetcher_mac.cc
index 163f96cb3ac..7ef35318d18 100644
--- a/chromium/content/browser/gamepad/xbox_data_fetcher_mac.cc
+++ b/chromium/content/browser/gamepad/xbox_data_fetcher_mac.cc
@@ -69,17 +69,17 @@ struct Xbox360ButtonData {
bool x : 1;
bool y : 1;
- uint8 trigger_left;
- uint8 trigger_right;
+ uint8_t trigger_left;
+ uint8_t trigger_right;
- int16 stick_left_x;
- int16 stick_left_y;
- int16 stick_right_x;
- int16 stick_right_y;
+ int16_t stick_left_x;
+ int16_t stick_left_y;
+ int16_t stick_right_x;
+ int16_t stick_right_y;
// Always 0.
- uint32 dummy2;
- uint16 dummy3;
+ uint32_t dummy2;
+ uint16_t dummy3;
};
struct XboxOneButtonData {
@@ -103,13 +103,13 @@ struct XboxOneButtonData {
bool stick_left_click : 1;
bool stick_right_click : 1;
- uint16 trigger_left;
- uint16 trigger_right;
+ uint16_t trigger_left;
+ uint16_t trigger_right;
- int16 stick_left_x;
- int16 stick_left_y;
- int16 stick_right_x;
- int16 stick_right_y;
+ int16_t stick_left_x;
+ int16_t stick_left_y;
+ int16_t stick_right_x;
+ int16_t stick_right_y;
};
#pragma pack(pop)
@@ -118,17 +118,17 @@ static_assert(sizeof(XboxOneButtonData) == 14, "xbox button data wrong size");
// From MSDN:
// http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx#dead_zone
-const int16 kLeftThumbDeadzone = 7849;
-const int16 kRightThumbDeadzone = 8689;
-const uint8 kXbox360TriggerDeadzone = 30;
-const uint16 kXboxOneTriggerMax = 1023;
-const uint16 kXboxOneTriggerDeadzone = 120;
-
-void NormalizeAxis(int16 x,
- int16 y,
- int16 deadzone,
- float* x_out,
- float* y_out) {
+const int16_t kLeftThumbDeadzone = 7849;
+const int16_t kRightThumbDeadzone = 8689;
+const uint8_t kXbox360TriggerDeadzone = 30;
+const uint16_t kXboxOneTriggerMax = 1023;
+const uint16_t kXboxOneTriggerDeadzone = 120;
+
+void NormalizeAxis(int16_t x,
+ int16_t y,
+ int16_t deadzone,
+ float* x_out,
+ float* y_out) {
float x_val = x;
float y_val = y;
@@ -157,13 +157,15 @@ void NormalizeAxis(int16 x,
}
}
-float NormalizeTrigger(uint8 value) {
- return value < kXbox360TriggerDeadzone ? 0 :
- static_cast<float>(value - kXbox360TriggerDeadzone) /
- (std::numeric_limits<uint8>::max() - kXbox360TriggerDeadzone);
+float NormalizeTrigger(uint8_t value) {
+ return value < kXbox360TriggerDeadzone
+ ? 0
+ : static_cast<float>(value - kXbox360TriggerDeadzone) /
+ (std::numeric_limits<uint8_t>::max() -
+ kXbox360TriggerDeadzone);
}
-float NormalizeXboxOneTrigger(uint16 value) {
+float NormalizeXboxOneTrigger(uint16_t value) {
return value < kXboxOneTriggerDeadzone ? 0 :
static_cast<float>(value - kXboxOneTriggerDeadzone) /
(kXboxOneTriggerMax - kXboxOneTriggerDeadzone);
@@ -398,17 +400,17 @@ bool XboxController::OpenDevice(io_service_t service) {
// The interface should have two pipes. Pipe 1 with direction kUSBIn and pipe
// 2 with direction kUSBOut. Both pipes should have type kUSBInterrupt.
- uint8 num_endpoints;
+ uint8_t num_endpoints;
kr = (*interface_)->GetNumEndpoints(interface_, &num_endpoints);
if (kr != KERN_SUCCESS || num_endpoints < 2)
return false;
for (int i = 1; i <= 2; i++) {
- uint8 direction;
- uint8 number;
- uint8 transfer_type;
- uint16 max_packet_size;
- uint8 interval;
+ uint8_t direction;
+ uint8_t number;
+ uint8_t transfer_type;
+ uint16_t max_packet_size;
+ uint8_t interval;
kr = (*interface_)->GetPipeProperties(interface_,
i,
@@ -423,7 +425,7 @@ bool XboxController::OpenDevice(io_service_t service) {
if (i == read_endpoint_) {
if (direction != kUSBIn)
return false;
- read_buffer_.reset(new uint8[max_packet_size]);
+ read_buffer_.reset(new uint8_t[max_packet_size]);
read_buffer_size_ = max_packet_size;
QueueRead();
} else if (i == control_endpoint_) {
@@ -521,13 +523,13 @@ void XboxController::ProcessXbox360Packet(size_t length) {
IOError();
return;
}
- uint8* buffer = read_buffer_.get();
+ uint8_t* buffer = read_buffer_.get();
if (buffer[1] != length)
// Length in packet doesn't match length reported by USB.
return;
- uint8 type = buffer[0];
+ uint8_t type = buffer[0];
buffer += 2;
length -= 2;
switch (type) {
@@ -562,9 +564,9 @@ void XboxController::ProcessXboxOnePacket(size_t length) {
IOError();
return;
}
- uint8* buffer = read_buffer_.get();
+ uint8_t* buffer = read_buffer_.get();
- uint8 type = buffer[0];
+ uint8_t type = buffer[0];
buffer += 4;
length -= 4;
switch (type) {
@@ -783,7 +785,7 @@ void XboxDataFetcher::RemoveController(XboxController* controller) {
delete controller;
}
-void XboxDataFetcher::RemoveControllerByLocationID(uint32 location_id) {
+void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) {
XboxController* controller = NULL;
for (std::set<XboxController*>::iterator i = controllers_.begin();
i != controllers_.end();
diff --git a/chromium/content/browser/gamepad/xbox_data_fetcher_mac.h b/chromium/content/browser/gamepad/xbox_data_fetcher_mac.h
index d88ad968233..599a63cf6cd 100644
--- a/chromium/content/browser/gamepad/xbox_data_fetcher_mac.h
+++ b/chromium/content/browser/gamepad/xbox_data_fetcher_mac.h
@@ -7,13 +7,15 @@
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
+#include <stddef.h>
+#include <stdint.h>
#include <set>
-#include "base/basictypes.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_ioobject.h"
#include "base/mac/scoped_ioplugininterface.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
class XboxController {
@@ -116,8 +118,8 @@ class XboxController {
// aren't correctly framed. The 360 controller frames its packets with a 2
// byte header (type, total length) so we can reframe the packet data
// ourselves.
- uint16 read_buffer_size_;
- scoped_ptr<uint8[]> read_buffer_;
+ uint16_t read_buffer_size_;
+ scoped_ptr<uint8_t[]> read_buffer_;
// The pattern that the LEDs on the device are currently displaying, or
// LED_NUM_PATTERNS if unknown.
@@ -162,7 +164,7 @@ class XboxDataFetcher : public XboxController::Delegate {
static void DeviceRemoved(void* context, io_iterator_t iterator);
void AddController(XboxController* controller);
void RemoveController(XboxController* controller);
- void RemoveControllerByLocationID(uint32 id);
+ void RemoveControllerByLocationID(uint32_t id);
void XboxControllerGotData(XboxController* controller,
const XboxController::Data& data) override;
void XboxControllerError(XboxController* controller) override;
diff --git a/chromium/content/browser/geofencing/geofencing_dispatcher_host.cc b/chromium/content/browser/geofencing/geofencing_dispatcher_host.cc
index 4b8c865a2c1..191ddcfa7cb 100644
--- a/chromium/content/browser/geofencing/geofencing_dispatcher_host.cc
+++ b/chromium/content/browser/geofencing/geofencing_dispatcher_host.cc
@@ -46,7 +46,7 @@ void GeofencingDispatcherHost::OnRegisterRegion(
int request_id,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
- int64 service_worker_registration_id) {
+ int64_t service_worker_registration_id) {
// Sanity check on region_id
if (region_id.length() > kMaxRegionIdLength) {
Send(new GeofencingMsg_RegisterRegionComplete(
@@ -68,7 +68,7 @@ void GeofencingDispatcherHost::OnUnregisterRegion(
int thread_id,
int request_id,
const std::string& region_id,
- int64 service_worker_registration_id) {
+ int64_t service_worker_registration_id) {
// Sanity check on region_id
if (region_id.length() > kMaxRegionIdLength) {
Send(new GeofencingMsg_UnregisterRegionComplete(
@@ -88,7 +88,7 @@ void GeofencingDispatcherHost::OnUnregisterRegion(
void GeofencingDispatcherHost::OnGetRegisteredRegions(
int thread_id,
int request_id,
- int64 service_worker_registration_id) {
+ int64_t service_worker_registration_id) {
GeofencingRegistrations result;
GeofencingStatus status =
diff --git a/chromium/content/browser/geofencing/geofencing_dispatcher_host.h b/chromium/content/browser/geofencing/geofencing_dispatcher_host.h
index ea4b6a1e66e..53a3b2086d6 100644
--- a/chromium/content/browser/geofencing/geofencing_dispatcher_host.h
+++ b/chromium/content/browser/geofencing/geofencing_dispatcher_host.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_GEOFENCING_GEOFENCING_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_DISPATCHER_HOST_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/common/geofencing_types.h"
#include "content/public/browser/browser_message_filter.h"
@@ -31,14 +34,14 @@ class GeofencingDispatcherHost : public BrowserMessageFilter {
int request_id,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
- int64 service_worker_registration_id);
+ int64_t service_worker_registration_id);
void OnUnregisterRegion(int thread_id,
int request_id,
const std::string& region_id,
- int64 service_worker_registration_id);
+ int64_t service_worker_registration_id);
void OnGetRegisteredRegions(int thread_id,
int request_id,
- int64 service_worker_registration_id);
+ int64_t service_worker_registration_id);
void RegisterRegionCompleted(int thread_id,
int request_id,
diff --git a/chromium/content/browser/geofencing/geofencing_manager.cc b/chromium/content/browser/geofencing/geofencing_manager.cc
index d44605771f8..1fce30f3b4d 100644
--- a/chromium/content/browser/geofencing/geofencing_manager.cc
+++ b/chromium/content/browser/geofencing/geofencing_manager.cc
@@ -10,6 +10,8 @@
#include "content/browser/geofencing/geofencing_service.h"
#include "content/browser/geofencing/mock_geofencing_service.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/common/geofencing_messages.h"
+#include "content/common/service_worker/service_worker_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
@@ -20,19 +22,19 @@
namespace content {
struct GeofencingManager::Registration {
- Registration(int64 service_worker_registration_id,
+ Registration(int64_t service_worker_registration_id,
const GURL& service_worker_origin,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback,
- int64 geofencing_registration_id);
- int64 service_worker_registration_id;
+ int64_t geofencing_registration_id);
+ int64_t service_worker_registration_id;
GURL service_worker_origin;
std::string region_id;
blink::WebCircularGeofencingRegion region;
// Registration ID as returned by the |GeofencingService|.
- int64 geofencing_registration_id;
+ int64_t geofencing_registration_id;
// Callback to call when registration is completed. This field is reset when
// registration is complete.
@@ -44,19 +46,18 @@ struct GeofencingManager::Registration {
};
GeofencingManager::Registration::Registration(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const GURL& service_worker_origin,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const GeofencingManager::StatusCallback& callback,
- int64 geofencing_registration_id)
+ int64_t geofencing_registration_id)
: service_worker_registration_id(service_worker_registration_id),
service_worker_origin(service_worker_origin),
region_id(region_id),
region(region),
geofencing_registration_id(geofencing_registration_id),
- registration_callback(callback) {
-}
+ registration_callback(callback) {}
GeofencingManager::GeofencingManager(
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
@@ -100,7 +101,7 @@ void GeofencingManager::ShutdownOnIO() {
}
void GeofencingManager::RegisterRegion(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback) {
@@ -137,7 +138,7 @@ void GeofencingManager::RegisterRegion(
service_->RegisterRegion(region, this));
}
-void GeofencingManager::UnregisterRegion(int64 service_worker_registration_id,
+void GeofencingManager::UnregisterRegion(int64_t service_worker_registration_id,
const std::string& region_id,
const StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -178,7 +179,7 @@ void GeofencingManager::UnregisterRegion(int64 service_worker_registration_id,
}
GeofencingStatus GeofencingManager::GetRegisteredRegions(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
std::map<std::string, blink::WebCircularGeofencingRegion>* result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
CHECK(result);
@@ -240,13 +241,13 @@ void GeofencingManager::SetMockPosition(double latitude, double longitude) {
}
void GeofencingManager::OnRegistrationDeleted(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const GURL& pattern) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
CleanUpForServiceWorker(service_worker_registration_id);
}
-void GeofencingManager::RegistrationFinished(int64 geofencing_registration_id,
+void GeofencingManager::RegistrationFinished(int64_t geofencing_registration_id,
GeofencingStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
Registration* registration = FindRegistrationById(geofencing_registration_id);
@@ -260,18 +261,18 @@ void GeofencingManager::RegistrationFinished(int64 geofencing_registration_id,
ClearRegistration(registration);
}
-void GeofencingManager::RegionEntered(int64 geofencing_registration_id) {
+void GeofencingManager::RegionEntered(int64_t geofencing_registration_id) {
DispatchGeofencingEvent(blink::WebGeofencingEventTypeEnter,
geofencing_registration_id);
}
-void GeofencingManager::RegionExited(int64 geofencing_registration_id) {
+void GeofencingManager::RegionExited(int64_t geofencing_registration_id) {
DispatchGeofencingEvent(blink::WebGeofencingEventTypeLeave,
geofencing_registration_id);
}
GeofencingManager::Registration* GeofencingManager::FindRegistration(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& region_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ServiceWorkerRegistrationsMap::iterator registrations_iterator =
@@ -286,7 +287,7 @@ GeofencingManager::Registration* GeofencingManager::FindRegistration(
}
GeofencingManager::Registration* GeofencingManager::FindRegistrationById(
- int64 geofencing_registration_id) {
+ int64_t geofencing_registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
RegistrationIdRegistrationMap::iterator registration_iterator =
registrations_by_id_.find(geofencing_registration_id);
@@ -296,12 +297,12 @@ GeofencingManager::Registration* GeofencingManager::FindRegistrationById(
}
GeofencingManager::Registration& GeofencingManager::AddRegistration(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const GURL& service_worker_origin,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback,
- int64 geofencing_registration_id) {
+ int64_t geofencing_registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!FindRegistration(service_worker_registration_id, region_id));
RegionIdRegistrationMap::iterator registration =
@@ -330,7 +331,7 @@ void GeofencingManager::ClearRegistration(Registration* registration) {
}
void GeofencingManager::CleanUpForServiceWorker(
- int64 service_worker_registration_id) {
+ int64_t service_worker_registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ServiceWorkerRegistrationsMap::iterator registrations_iterator =
registrations_.find(service_worker_registration_id);
@@ -348,7 +349,7 @@ void GeofencingManager::CleanUpForServiceWorker(
void GeofencingManager::DispatchGeofencingEvent(
blink::WebGeofencingEventType event_type,
- int64 geofencing_registration_id) {
+ int64_t geofencing_registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
Registration* registration = FindRegistrationById(geofencing_registration_id);
if (!registration ||
@@ -358,7 +359,7 @@ void GeofencingManager::DispatchGeofencingEvent(
return;
}
- service_worker_context_->FindRegistrationForId(
+ service_worker_context_->FindReadyRegistrationForId(
registration->service_worker_registration_id,
registration->service_worker_origin,
base::Bind(&GeofencingManager::DeliverGeofencingEvent,
@@ -369,7 +370,7 @@ void GeofencingManager::DispatchGeofencingEvent(
void GeofencingManager::DeliverGeofencingEvent(
blink::WebGeofencingEventType event_type,
- int64 geofencing_registration_id,
+ int64_t geofencing_registration_id,
ServiceWorkerStatusCode service_worker_status,
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration) {
@@ -388,30 +389,52 @@ void GeofencingManager::DeliverGeofencingEvent(
ServiceWorkerVersion* active_version =
service_worker_registration->active_version();
- if (!active_version) {
- // TODO(mek): No active version, potentially because one is still being
- // installed. Handle this somehow.
- return;
- }
+ DCHECK(active_version);
// Hold on to the service worker registration in the callback to keep it alive
// until the callback dies. Otherwise the registration could be released when
// this method returns - before the event is delivered to the service worker.
- base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback =
- base::Bind(&GeofencingManager::DeliverGeofencingEventEnd,
- this,
- service_worker_registration);
- active_version->DispatchGeofencingEvent(dispatch_event_callback,
- event_type,
- registration->region_id,
- registration->region);
+ active_version->RunAfterStartWorker(
+ base::Bind(&GeofencingManager::OnEventError, this),
+ base::Bind(&GeofencingManager::DeliverEventToRunningWorker, this,
+ service_worker_registration, event_type,
+ registration->region_id, registration->region,
+ make_scoped_refptr(active_version)));
}
-void GeofencingManager::DeliverGeofencingEventEnd(
+void GeofencingManager::DeliverEventToRunningWorker(
const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
+ blink::WebGeofencingEventType event_type,
+ const std::string& region_id,
+ const blink::WebCircularGeofencingRegion& region,
+ const scoped_refptr<ServiceWorkerVersion>& worker) {
+ int request_id =
+ worker->StartRequest(ServiceWorkerMetrics::EventType::GEOFENCING,
+ base::Bind(&GeofencingManager::OnEventError, this));
+
+ worker->DispatchEvent<ServiceWorkerHostMsg_GeofencingEventFinished>(
+ request_id, ServiceWorkerMsg_GeofencingEvent(request_id, event_type,
+ region_id, region),
+ base::Bind(&GeofencingManager::OnEventResponse, this, worker,
+ service_worker_registration));
+}
+
+void GeofencingManager::OnEventResponse(
+ const scoped_refptr<ServiceWorkerVersion>& worker,
+ const scoped_refptr<ServiceWorkerRegistration>& registration,
+ int request_id,
+ blink::WebServiceWorkerEventResult result) {
+ bool finish_result = worker->FinishRequest(request_id);
+ DCHECK(finish_result)
+ << "No messages should be passed to handler if request had "
+ "already finished";
+ // TODO(mek): log/check result.
+}
+
+void GeofencingManager::OnEventError(
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // TODO(mek): log/check result.
+ // TODO(mek): log/check errors.
}
} // namespace content
diff --git a/chromium/content/browser/geofencing/geofencing_manager.h b/chromium/content/browser/geofencing/geofencing_manager.h
index 62b85f92d23..afe3d2dd729 100644
--- a/chromium/content/browser/geofencing/geofencing_manager.h
+++ b/chromium/content/browser/geofencing/geofencing_manager.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_GEOFENCING_GEOFENCING_MANAGER_H_
#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_MANAGER_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
@@ -19,6 +21,7 @@
#include "content/common/content_export.h"
#include "content/common/geofencing_types.h"
#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/WebKit/public/platform/WebGeofencingEventType.h"
namespace base {
template <typename T>
@@ -68,7 +71,7 @@ class CONTENT_EXPORT GeofencingManager
// (or in progress of being registered) region will fail.
// TODO(mek): Behavior when using an already used ID might need to be revised
// depending on what the actual spec ends up saying about this.
- void RegisterRegion(int64 service_worker_registration_id,
+ void RegisterRegion(int64_t service_worker_registration_id,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback);
@@ -79,7 +82,7 @@ class CONTENT_EXPORT GeofencingManager
// (RegisterRegion hasn't called its callback yet) will fail.
// TODO(mek): Maybe better behavior would be to allow unregistering still
// in-progress registrations.
- void UnregisterRegion(int64 service_worker_registration_id,
+ void UnregisterRegion(int64_t service_worker_registration_id,
const std::string& region_id,
const StatusCallback& callback);
@@ -90,7 +93,7 @@ class CONTENT_EXPORT GeofencingManager
// has been called already (so it doesn't include still in progress
// registrations).
GeofencingStatus GetRegisteredRegions(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
std::map<std::string, blink::WebCircularGeofencingRegion>* result);
// Enables or disables mock geofencing service.
@@ -117,74 +120,88 @@ class CONTENT_EXPORT GeofencingManager
void ShutdownOnIO();
// ServiceWorkerContextObserver implementation.
- void OnRegistrationDeleted(int64 service_worker_registration_id,
+ void OnRegistrationDeleted(int64_t service_worker_registration_id,
const GURL& pattern) override;
// GeofencingRegistrationDelegate implementation.
- void RegistrationFinished(int64 geofencing_registration_id,
+ void RegistrationFinished(int64_t geofencing_registration_id,
GeofencingStatus status) override;
- void RegionEntered(int64 geofencing_registration_id) override;
- void RegionExited(int64 geofencing_registration_id) override;
+ void RegionEntered(int64_t geofencing_registration_id) override;
+ void RegionExited(int64_t geofencing_registration_id) override;
// Looks up a particular geofence registration. Returns nullptr if no
// registration with the given IDs exists.
- Registration* FindRegistration(int64 service_worker_registration_id,
+ Registration* FindRegistration(int64_t service_worker_registration_id,
const std::string& region_id);
// Looks up a particular geofence registration. Returns nullptr if no
// registration with the given ID exists.
- Registration* FindRegistrationById(int64 geofencing_registration_id);
+ Registration* FindRegistrationById(int64_t geofencing_registration_id);
// Registers a new registration, returning a reference to the newly inserted
// object. Assumes no registration with the same IDs currently exists.
Registration& AddRegistration(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const GURL& service_worker_origin,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback,
- int64 geofencing_registration_id);
+ int64_t geofencing_registration_id);
// Clears a registration.
void ClearRegistration(Registration* registration);
// Unregisters and clears all registrations associated with a specific
// service worker.
- void CleanUpForServiceWorker(int64 service_worker_registration_id);
+ void CleanUpForServiceWorker(int64_t service_worker_registration_id);
// Starts dispatching a particular geofencing |event_type| for the geofence
// registration with the given ID. This first looks up the Service Worker
// Registration the geofence is associated with, and then attempts to deliver
// the event to that service worker.
void DispatchGeofencingEvent(blink::WebGeofencingEventType event_type,
- int64 geofencing_registration_id);
+ int64_t geofencing_registration_id);
// Delivers an event to the specified service worker for the given geofence.
// If the geofence registration id is no longer valid, this method does
// nothing. This assumes the |service_worker_registration| is the service
// worker the geofence registration is associated with.
void DeliverGeofencingEvent(blink::WebGeofencingEventType event_type,
- int64 geofencing_registration_id,
+ int64_t geofencing_registration_id,
ServiceWorkerStatusCode service_worker_status,
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration);
- // Called when delivery of a geofence event to a service worker has finished
- // (or failed to finish).
- void DeliverGeofencingEventEnd(const scoped_refptr<ServiceWorkerRegistration>&
- service_worker_registration,
- ServiceWorkerStatusCode service_worker_status);
+ // Delivers an event to a specific service worker version. Called as callback
+ // after the worker has started.
+ void DeliverEventToRunningWorker(
+ const scoped_refptr<ServiceWorkerRegistration>&
+ service_worker_registration,
+ blink::WebGeofencingEventType event_type,
+ const std::string& region_id,
+ const blink::WebCircularGeofencingRegion& region,
+ const scoped_refptr<ServiceWorkerVersion>& worker);
+
+ // Called for every response received for an event. There should only be one.
+ void OnEventResponse(const scoped_refptr<ServiceWorkerVersion>& worker,
+ const scoped_refptr<ServiceWorkerRegistration>&
+ service_worker_registration,
+ int request_id,
+ blink::WebServiceWorkerEventResult result);
+
+ // Called when dispatching an event failed.
+ void OnEventError(ServiceWorkerStatusCode service_worker_status);
// Map of all registered regions for a particular service worker registration.
typedef std::map<std::string, Registration> RegionIdRegistrationMap;
// Map of service worker registration id to the regions registered by that
// service worker.
- typedef std::map<int64, RegionIdRegistrationMap>
+ typedef std::map<int64_t, RegionIdRegistrationMap>
ServiceWorkerRegistrationsMap;
ServiceWorkerRegistrationsMap registrations_;
// Map of all registered regions by geofencing_registration_id.
- typedef std::map<int64, RegionIdRegistrationMap::iterator>
+ typedef std::map<int64_t, RegionIdRegistrationMap::iterator>
RegistrationIdRegistrationMap;
RegistrationIdRegistrationMap registrations_by_id_;
diff --git a/chromium/content/browser/geofencing/geofencing_manager_unittest.cc b/chromium/content/browser/geofencing/geofencing_manager_unittest.cc
index 16cf1bbe895..bd905d1c312 100644
--- a/chromium/content/browser/geofencing/geofencing_manager_unittest.cc
+++ b/chromium/content/browser/geofencing/geofencing_manager_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/message_loop/message_loop.h"
#include "content/browser/geofencing/geofencing_manager.h"
@@ -19,10 +21,9 @@ typedef std::map<std::string, WebCircularGeofencingRegion> RegionMap;
namespace {
-static const int kRenderProcessId = 99;
static const char* kTestRegionId = "region-id";
-static const int64 kTestGeofencingRegistrationId = 42;
-static const int64 kTestGeofencingRegistrationId2 = 43;
+static const int64_t kTestGeofencingRegistrationId = 42;
+static const int64_t kTestGeofencingRegistrationId2 = 43;
bool RegionsMatch(const WebCircularGeofencingRegion& expected,
const WebCircularGeofencingRegion& arg) {
@@ -45,9 +46,9 @@ class TestGeofencingService : public GeofencingService {
}
MOCK_METHOD2(RegisterRegion,
- int64(const WebCircularGeofencingRegion& region,
- GeofencingRegistrationDelegate* delegate));
- MOCK_METHOD1(UnregisterRegion, void(int64 geofencing_registration_id));
+ int64_t(const WebCircularGeofencingRegion& region,
+ GeofencingRegistrationDelegate* delegate));
+ MOCK_METHOD1(UnregisterRegion, void(int64_t geofencing_registration_id));
private:
bool is_available_;
@@ -89,10 +90,10 @@ class StatusCatcher {
};
void SaveResponseCallback(bool* called,
- int64* store_registration_id,
+ int64_t* store_registration_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
@@ -100,7 +101,7 @@ void SaveResponseCallback(bool* called,
ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback(
bool* called,
- int64* store_registration_id) {
+ int64_t* store_registration_id) {
return base::Bind(&SaveResponseCallback, called, store_registration_id);
}
@@ -123,8 +124,7 @@ class GeofencingManagerTest : public testing::Test {
}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
service_ = new TestGeofencingService();
manager_ = new GeofencingManager(helper_->context_wrapper());
manager_->SetServiceForTesting(service_);
@@ -149,7 +149,7 @@ class GeofencingManagerTest : public testing::Test {
const std::string& name) {
GURL pattern("http://www.example.com/" + name);
GURL script_url("http://www.example.com/service_worker.js");
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
bool called = false;
helper_->context()->RegisterServiceWorker(
pattern, script_url, nullptr,
@@ -178,7 +178,7 @@ class GeofencingManagerTest : public testing::Test {
}
GeofencingStatus RegisterRegionSync(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& id,
const WebCircularGeofencingRegion& region) {
StatusCatcher result;
@@ -191,11 +191,11 @@ class GeofencingManagerTest : public testing::Test {
}
GeofencingStatus RegisterRegionSyncWithServiceResult(
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& id,
const WebCircularGeofencingRegion& region,
GeofencingStatus service_status,
- int64 geofencing_registration_id) {
+ int64_t geofencing_registration_id) {
StatusCatcher result;
GeofencingRegistrationDelegate* delegate = 0;
EXPECT_CALL(
@@ -213,10 +213,11 @@ class GeofencingManagerTest : public testing::Test {
return result.Wait();
}
- GeofencingStatus UnregisterRegionSync(int64 service_worker_registration_id,
- const std::string& id,
- bool should_call_service,
- int64 geofencing_registration_id = 0) {
+ GeofencingStatus UnregisterRegionSync(
+ int64_t service_worker_registration_id,
+ const std::string& id,
+ bool should_call_service,
+ int64_t geofencing_registration_id = 0) {
StatusCatcher result;
if (should_call_service) {
EXPECT_CALL(*service_, UnregisterRegion(geofencing_registration_id));
@@ -228,7 +229,7 @@ class GeofencingManagerTest : public testing::Test {
return result.Wait();
}
- void VerifyRegions(int64 service_worker_registration_id,
+ void VerifyRegions(int64_t service_worker_registration_id,
const RegionMap& expected_regions) {
RegionMap regions;
EXPECT_EQ(GEOFENCING_STATUS_OK,
diff --git a/chromium/content/browser/geofencing/geofencing_provider.h b/chromium/content/browser/geofencing/geofencing_provider.h
index ea2c207ef0e..a2052a42951 100644
--- a/chromium/content/browser/geofencing/geofencing_provider.h
+++ b/chromium/content/browser/geofencing/geofencing_provider.h
@@ -5,7 +5,8 @@
#ifndef CONTENT_BROWSER_GEOFENCING_GEOFENCING_PROVIDER_H_
#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_PROVIDER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/callback_forward.h"
#include "content/common/geofencing_types.h"
@@ -30,13 +31,13 @@ class GeofencingProvider {
// implemented yet.
// Implementations of RegisterRegion must asynchronously call the |callback|
// to indicate success or failure.
- virtual void RegisterRegion(int64 geofencing_registration_id,
+ virtual void RegisterRegion(int64_t geofencing_registration_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback) = 0;
// Called by |GeofencingService| to unregister an existing registration. Will
// only be called once for each registration.
- virtual void UnregisterRegion(int64 geofencing_registration_id) = 0;
+ virtual void UnregisterRegion(int64_t geofencing_registration_id) = 0;
};
} // namespace content
diff --git a/chromium/content/browser/geofencing/geofencing_registration_delegate.h b/chromium/content/browser/geofencing/geofencing_registration_delegate.h
index 10d6cea6077..3c5814d8ac0 100644
--- a/chromium/content/browser/geofencing/geofencing_registration_delegate.h
+++ b/chromium/content/browser/geofencing/geofencing_registration_delegate.h
@@ -5,7 +5,8 @@
#ifndef CONTENT_BROWSER_GEOFENCING_GEOFENCING_REGISTRATION_DELEGATE_H_
#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_REGISTRATION_DELEGATE_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "content/common/geofencing_types.h"
namespace content {
@@ -17,10 +18,10 @@ namespace content {
// TODO(mek): Add methods for geofence enter/leave events.
class GeofencingRegistrationDelegate {
public:
- virtual void RegistrationFinished(int64 geofencing_registration_id,
+ virtual void RegistrationFinished(int64_t geofencing_registration_id,
GeofencingStatus status) = 0;
- virtual void RegionEntered(int64 geofencing_registration_id) = 0;
- virtual void RegionExited(int64 geofencing_registration_id) = 0;
+ virtual void RegionEntered(int64_t geofencing_registration_id) = 0;
+ virtual void RegionExited(int64_t geofencing_registration_id) = 0;
protected:
virtual ~GeofencingRegistrationDelegate() {}
diff --git a/chromium/content/browser/geofencing/geofencing_service.cc b/chromium/content/browser/geofencing/geofencing_service.cc
index d3dc2594fb6..9f429d55957 100644
--- a/chromium/content/browser/geofencing/geofencing_service.cc
+++ b/chromium/content/browser/geofencing/geofencing_service.cc
@@ -4,6 +4,8 @@
#include "content/browser/geofencing/geofencing_service.h"
+#include <utility>
+
#include "base/location.h"
#include "base/memory/singleton.h"
#include "base/single_thread_task_runner.h"
@@ -27,11 +29,11 @@ void RunSoon(const base::Closure& callback) {
struct GeofencingServiceImpl::Registration {
Registration();
Registration(const blink::WebCircularGeofencingRegion& region,
- int64 geofencing_registration_id,
+ int64_t geofencing_registration_id,
GeofencingRegistrationDelegate* delegate);
blink::WebCircularGeofencingRegion region;
- int64 geofencing_registration_id;
+ int64_t geofencing_registration_id;
GeofencingRegistrationDelegate* delegate;
enum RegistrationState {
@@ -56,13 +58,12 @@ GeofencingServiceImpl::Registration::Registration()
GeofencingServiceImpl::Registration::Registration(
const blink::WebCircularGeofencingRegion& region,
- int64 geofencing_registration_id,
+ int64_t geofencing_registration_id,
GeofencingRegistrationDelegate* delegate)
: region(region),
geofencing_registration_id(geofencing_registration_id),
delegate(delegate),
- state(STATE_REGISTERING) {
-}
+ state(STATE_REGISTERING) {}
GeofencingServiceImpl::GeofencingServiceImpl() : next_registration_id_(0) {
}
@@ -80,12 +81,12 @@ bool GeofencingServiceImpl::IsServiceAvailable() {
return EnsureProvider();
}
-int64 GeofencingServiceImpl::RegisterRegion(
+int64_t GeofencingServiceImpl::RegisterRegion(
const blink::WebCircularGeofencingRegion& region,
GeofencingRegistrationDelegate* delegate) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- int64 geofencing_registration_id = GetNextId();
+ int64_t geofencing_registration_id = GetNextId();
registrations_[geofencing_registration_id] =
Registration(region, geofencing_registration_id, delegate);
@@ -107,7 +108,8 @@ int64 GeofencingServiceImpl::RegisterRegion(
return geofencing_registration_id;
}
-void GeofencingServiceImpl::UnregisterRegion(int64 geofencing_registration_id) {
+void GeofencingServiceImpl::UnregisterRegion(
+ int64_t geofencing_registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
RegistrationsMap::iterator registration_iterator =
@@ -140,7 +142,7 @@ void GeofencingServiceImpl::UnregisterRegion(int64 geofencing_registration_id) {
void GeofencingServiceImpl::SetProviderForTesting(
scoped_ptr<GeofencingProvider> provider) {
DCHECK(!provider_.get());
- provider_ = provider.Pass();
+ provider_ = std::move(provider);
}
int GeofencingServiceImpl::RegistrationCountForTesting() {
@@ -157,14 +159,14 @@ bool GeofencingServiceImpl::EnsureProvider() {
return true;
}
-int64 GeofencingServiceImpl::GetNextId() {
+int64_t GeofencingServiceImpl::GetNextId() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return next_registration_id_++;
}
void GeofencingServiceImpl::NotifyRegistrationFinished(
- int64 geofencing_registration_id,
+ int64_t geofencing_registration_id,
GeofencingStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/geofencing/geofencing_service.h b/chromium/content/browser/geofencing/geofencing_service.h
index 998dc491727..8c91193703f 100644
--- a/chromium/content/browser/geofencing/geofencing_service.h
+++ b/chromium/content/browser/geofencing/geofencing_service.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_GEOFENCING_GEOFENCING_SERVICE_H_
#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_SERVICE_H_
+#include <stdint.h>
+
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "content/common/geofencing_types.h"
@@ -41,12 +43,13 @@ class GeofencingService {
// inform the delegate of the result of the attempt to register the region.
// This does not transfer ownership of the |delegate|. Callers have to ensure
// that the delegate remains valid as long as the region is registered.
- virtual int64 RegisterRegion(const blink::WebCircularGeofencingRegion& region,
- GeofencingRegistrationDelegate* delegate) = 0;
+ virtual int64_t RegisterRegion(
+ const blink::WebCircularGeofencingRegion& region,
+ GeofencingRegistrationDelegate* delegate) = 0;
// Unregister a region. This is assumed to always succeed. It is safe to call
// this even if a registration is still in progress.
- virtual void UnregisterRegion(int64 geofencing_registration_id) = 0;
+ virtual void UnregisterRegion(int64_t geofencing_registration_id) = 0;
};
// This class combines all the geofence registrations from the various per
@@ -64,10 +67,9 @@ class CONTENT_EXPORT GeofencingServiceImpl
// GeofencingServiceInterface implementation.
bool IsServiceAvailable() override;
- int64 RegisterRegion(
- const blink::WebCircularGeofencingRegion& region,
- GeofencingRegistrationDelegate* delegate) override;
- void UnregisterRegion(int64 geofencing_registration_id) override;
+ int64_t RegisterRegion(const blink::WebCircularGeofencingRegion& region,
+ GeofencingRegistrationDelegate* delegate) override;
+ void UnregisterRegion(int64_t geofencing_registration_id) override;
protected:
friend class GeofencingServiceTest;
@@ -80,7 +82,7 @@ class CONTENT_EXPORT GeofencingServiceImpl
private:
struct Registration;
- typedef std::map<int64, Registration> RegistrationsMap;
+ typedef std::map<int64_t, Registration> RegistrationsMap;
// This method checks if a |GeofencingProvider| exists, creates a new one if
// not, and finally returns false if it can't create a provider for the
@@ -88,14 +90,14 @@ class CONTENT_EXPORT GeofencingServiceImpl
bool EnsureProvider();
// Returns a new unique ID to use for the next geofence registration.
- int64 GetNextId();
+ int64_t GetNextId();
// Notifies the correct delegate that registration has completed for a
// specific geofence registration.
- void NotifyRegistrationFinished(int64 geofencing_registration_id,
+ void NotifyRegistrationFinished(int64_t geofencing_registration_id,
GeofencingStatus status);
- int64 next_registration_id_;
+ int64_t next_registration_id_;
RegistrationsMap registrations_;
scoped_ptr<GeofencingProvider> provider_;
diff --git a/chromium/content/browser/geofencing/geofencing_service_unittest.cc b/chromium/content/browser/geofencing/geofencing_service_unittest.cc
index 7fbe0355c8a..8d512ace076 100644
--- a/chromium/content/browser/geofencing/geofencing_service_unittest.cc
+++ b/chromium/content/browser/geofencing/geofencing_service_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "content/browser/geofencing/geofencing_provider.h"
#include "content/browser/geofencing/geofencing_registration_delegate.h"
#include "content/browser/geofencing/geofencing_service.h"
@@ -30,18 +32,19 @@ class MockGeofencingRegistrationDelegate
: public GeofencingRegistrationDelegate {
public:
MOCK_METHOD2(RegistrationFinished,
- void(int64 geofencing_registration_id, GeofencingStatus status));
- MOCK_METHOD1(RegionEntered, void(int64 geofencing_registration_id));
- MOCK_METHOD1(RegionExited, void(int64 geofencing_registration_id));
+ void(int64_t geofencing_registration_id,
+ GeofencingStatus status));
+ MOCK_METHOD1(RegionEntered, void(int64_t geofencing_registration_id));
+ MOCK_METHOD1(RegionExited, void(int64_t geofencing_registration_id));
};
class MockGeofencingProvider : public GeofencingProvider {
public:
MOCK_METHOD3(RegisterRegion,
- void(int64 geofencing_registration_id,
+ void(int64_t geofencing_registration_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback));
- MOCK_METHOD1(UnregisterRegion, void(int64 geofencing_registration_id));
+ MOCK_METHOD1(UnregisterRegion, void(int64_t geofencing_registration_id));
};
ACTION_P(QuitRunner, runner) {
@@ -79,12 +82,12 @@ class GeofencingServiceTest : public testing::Test {
int RegistrationCount() { return service_->RegistrationCountForTesting(); }
- int64 RegisterRegionSync(const WebCircularGeofencingRegion& region,
- GeofencingStatus provider_status) {
+ int64_t RegisterRegionSync(const WebCircularGeofencingRegion& region,
+ GeofencingStatus provider_status) {
scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner());
// The registration ID that is passed to the provider.
- int64 provider_registration_id = -1;
+ int64_t provider_registration_id = -1;
// The callback that is passed to the provider.
GeofencingProvider::StatusCallback callback;
@@ -95,7 +98,7 @@ class GeofencingServiceTest : public testing::Test {
.WillOnce(testing::DoAll(SaveRegistrationId(&provider_registration_id),
SaveStatusCallback(&callback)));
- int64 geofencing_registration_id =
+ int64_t geofencing_registration_id =
service_->RegisterRegion(region, &delegate_);
// Service should have synchronously called the provider.
@@ -124,7 +127,7 @@ class GeofencingServiceTest : public testing::Test {
TEST_F(GeofencingServiceTest, RegisterRegion_NoProvider) {
scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner());
- int64 geofencing_registration_id =
+ int64_t geofencing_registration_id =
service_->RegisterRegion(test_region_, &delegate_);
EXPECT_CALL(delegate_,
RegistrationFinished(
@@ -171,7 +174,7 @@ TEST_F(GeofencingServiceTest, UnregisterRegion_DuringSuccesfullRegistration) {
testing::_, WebCircularGeofencingRegionEq(test_region_), testing::_))
.WillOnce(SaveStatusCallback(&callback));
- int64 geofencing_registration_id =
+ int64_t geofencing_registration_id =
service_->RegisterRegion(test_region_, &delegate_);
// Service should have synchronously called the provider.
diff --git a/chromium/content/browser/geofencing/mock_geofencing_service.cc b/chromium/content/browser/geofencing/mock_geofencing_service.cc
index c3a1f27a3d3..edf5a9232c4 100644
--- a/chromium/content/browser/geofencing/mock_geofencing_service.cc
+++ b/chromium/content/browser/geofencing/mock_geofencing_service.cc
@@ -21,7 +21,7 @@ namespace content {
namespace {
void RegisterRegionResult(GeofencingRegistrationDelegate* delegate,
- int64 geofencing_registration_id,
+ int64_t geofencing_registration_id,
GeofencingStatus status) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -99,10 +99,10 @@ bool MockGeofencingService::IsServiceAvailable() {
return available_;
}
-int64 MockGeofencingService::RegisterRegion(
+int64_t MockGeofencingService::RegisterRegion(
const blink::WebCircularGeofencingRegion& region,
GeofencingRegistrationDelegate* delegate) {
- int64 id = next_id_++;
+ int64_t id = next_id_++;
Registration& registration = registrations_[id];
registration.region = region;
registration.delegate = delegate;
@@ -118,7 +118,8 @@ int64 MockGeofencingService::RegisterRegion(
return id;
}
-void MockGeofencingService::UnregisterRegion(int64 geofencing_registration_id) {
+void MockGeofencingService::UnregisterRegion(
+ int64_t geofencing_registration_id) {
registrations_.erase(geofencing_registration_id);
}
diff --git a/chromium/content/browser/geofencing/mock_geofencing_service.h b/chromium/content/browser/geofencing/mock_geofencing_service.h
index 6ba9f0dd995..e69b07bebdb 100644
--- a/chromium/content/browser/geofencing/mock_geofencing_service.h
+++ b/chromium/content/browser/geofencing/mock_geofencing_service.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_GEOFENCING_MOCK_GEOFENCING_SERVICE_H_
#define CONTENT_BROWSER_GEOFENCING_MOCK_GEOFENCING_SERVICE_H_
+#include <stdint.h>
+
#include <map>
#include "content/browser/geofencing/geofencing_service.h"
@@ -27,16 +29,16 @@ class MockGeofencingService : public GeofencingService {
// GeofencingService implementation.
bool IsServiceAvailable() override;
- int64 RegisterRegion(const blink::WebCircularGeofencingRegion& region,
- GeofencingRegistrationDelegate* delegate) override;
- void UnregisterRegion(int64 geofencing_registration_id) override;
+ int64_t RegisterRegion(const blink::WebCircularGeofencingRegion& region,
+ GeofencingRegistrationDelegate* delegate) override;
+ void UnregisterRegion(int64_t geofencing_registration_id) override;
private:
struct Registration;
bool available_;
- std::map<int64, Registration> registrations_;
- int64 next_id_;
+ std::map<int64_t, Registration> registrations_;
+ int64_t next_id_;
bool has_position_;
double last_latitude_;
double last_longitude_;
diff --git a/chromium/content/browser/geolocation/empty_wifi_data_provider.h b/chromium/content/browser/geolocation/empty_wifi_data_provider.h
index 4ab138454c2..e591b9b5a55 100644
--- a/chromium/content/browser/geolocation/empty_wifi_data_provider.h
+++ b/chromium/content/browser/geolocation/empty_wifi_data_provider.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_EMPTY_WIFI_DATA_PROVIDER_H_
#define CONTENT_BROWSER_GEOLOCATION_EMPTY_WIFI_DATA_PROVIDER_H_
+#include "base/macros.h"
#include "content/browser/geolocation/wifi_data_provider.h"
namespace content {
diff --git a/chromium/content/browser/geolocation/fake_access_token_store.h b/chromium/content/browser/geolocation/fake_access_token_store.h
index 423b317e489..b6b674dfe73 100644
--- a/chromium/content/browser/geolocation/fake_access_token_store.h
+++ b/chromium/content/browser/geolocation/fake_access_token_store.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_FAKE_ACCESS_TOKEN_STORE_H_
#define CONTENT_BROWSER_GEOLOCATION_FAKE_ACCESS_TOKEN_STORE_H_
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "content/public/browser/access_token_store.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chromium/content/browser/geolocation/geolocation_provider_impl.cc b/chromium/content/browser/geolocation/geolocation_provider_impl.cc
index fc792f24847..60d9efbfc44 100644
--- a/chromium/content/browser/geolocation/geolocation_provider_impl.cc
+++ b/chromium/content/browser/geolocation/geolocation_provider_impl.cc
@@ -37,7 +37,7 @@ GeolocationProviderImpl::AddLocationUpdateCallback(
callback.Run(position_);
}
- return subscription.Pass();
+ return subscription;
}
void GeolocationProviderImpl::UserDidOptIntoLocationServices() {
diff --git a/chromium/content/browser/geolocation/geolocation_provider_impl.h b/chromium/content/browser/geolocation/geolocation_provider_impl.h
index 72dc9e8afed..fe07da7822f 100644
--- a/chromium/content/browser/geolocation/geolocation_provider_impl.h
+++ b/chromium/content/browser/geolocation/geolocation_provider_impl.h
@@ -8,9 +8,9 @@
#include <list>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
#include "content/public/browser/geolocation_provider.h"
diff --git a/chromium/content/browser/geolocation/geolocation_provider_impl_unittest.cc b/chromium/content/browser/geolocation/geolocation_provider_impl_unittest.cc
index 3ba4dae1baa..0b354fd01d5 100644
--- a/chromium/content/browser/geolocation/geolocation_provider_impl_unittest.cc
+++ b/chromium/content/browser/geolocation/geolocation_provider_impl_unittest.cc
@@ -5,6 +5,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
@@ -64,7 +65,7 @@ class AsyncMockGeolocationObserver : public MockGeolocationObserver {
public:
void OnLocationUpdate(const Geoposition& position) override {
MockGeolocationObserver::OnLocationUpdate(position);
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
};
@@ -144,7 +145,7 @@ bool GeolocationProviderTest::ProvidersStarted() {
provider_->task_runner()->PostTaskAndReply(
FROM_HERE, base::Bind(&GeolocationProviderTest::GetProvidersStarted,
base::Unretained(this), &started),
- base::MessageLoop::QuitClosure());
+ base::MessageLoop::QuitWhenIdleClosure());
message_loop_.Run();
return started;
}
diff --git a/chromium/content/browser/geolocation/geolocation_service_context.cc b/chromium/content/browser/geolocation/geolocation_service_context.cc
index 7a250237d87..7cdeb354faf 100644
--- a/chromium/content/browser/geolocation/geolocation_service_context.cc
+++ b/chromium/content/browser/geolocation/geolocation_service_context.cc
@@ -4,6 +4,8 @@
#include "content/browser/geolocation/geolocation_service_context.h"
+#include <utility>
+
namespace content {
GeolocationServiceContext::GeolocationServiceContext() : paused_(false) {
@@ -16,7 +18,7 @@ void GeolocationServiceContext::CreateService(
const base::Closure& update_callback,
mojo::InterfaceRequest<GeolocationService> request) {
GeolocationServiceImpl* service =
- new GeolocationServiceImpl(request.Pass(), this, update_callback);
+ new GeolocationServiceImpl(std::move(request), this, update_callback);
services_.push_back(service);
if (geoposition_override_)
service->SetOverride(*geoposition_override_.get());
diff --git a/chromium/content/browser/geolocation/geolocation_service_context.h b/chromium/content/browser/geolocation/geolocation_service_context.h
index 453c8b0dce2..843fd3827cb 100644
--- a/chromium/content/browser/geolocation/geolocation_service_context.h
+++ b/chromium/content/browser/geolocation/geolocation_service_context.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_CONTEXT_H_
#define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_CONTEXT_H_
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "content/browser/geolocation/geolocation_service_impl.h"
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl.cc b/chromium/content/browser/geolocation/geolocation_service_impl.cc
index aae95ac01b6..764ff10abdd 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl.cc
+++ b/chromium/content/browser/geolocation/geolocation_service_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/geolocation/geolocation_service_impl.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/metrics/histogram.h"
#include "content/browser/geolocation/geolocation_service_context.h"
@@ -62,7 +64,7 @@ GeolocationServiceImpl::GeolocationServiceImpl(
mojo::InterfaceRequest<GeolocationService> request,
GeolocationServiceContext* context,
const base::Closure& update_callback)
- : binding_(this, request.Pass()),
+ : binding_(this, std::move(request)),
context_(context),
update_callback_(update_callback),
high_accuracy_(false),
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl.h b/chromium/content/browser/geolocation/geolocation_service_impl.h
index 45b37e7fd60..d72706e5b3c 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl.h
+++ b/chromium/content/browser/geolocation/geolocation_service_impl.h
@@ -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 "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/geolocation/geolocation_provider_impl.h"
#include "content/common/geolocation_service.mojom.h"
#include "content/public/common/mojo_geoposition.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding.h"
#ifndef CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_IMPL_H_
#define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_IMPL_H_
diff --git a/chromium/content/browser/geolocation/location_api_adapter_android.cc b/chromium/content/browser/geolocation/location_api_adapter_android.cc
index 2396b55d985..4037ab6e36c 100644
--- a/chromium/content/browser/geolocation/location_api_adapter_android.cc
+++ b/chromium/content/browser/geolocation/location_api_adapter_android.cc
@@ -4,6 +4,7 @@
#include "content/browser/geolocation/location_api_adapter_android.h"
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
diff --git a/chromium/content/browser/geolocation/location_arbitrator_impl.cc b/chromium/content/browser/geolocation/location_arbitrator_impl.cc
index 20d9a5127db..03e3676f7e6 100644
--- a/chromium/content/browser/geolocation/location_arbitrator_impl.cc
+++ b/chromium/content/browser/geolocation/location_arbitrator_impl.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "build/build_config.h"
#include "content/browser/geolocation/network_location_provider.h"
#include "content/public/browser/access_token_store.h"
#include "content/public/browser/content_browser_client.h"
@@ -23,7 +24,7 @@ const char* kDefaultNetworkProviderUrl =
// To avoid oscillations, set this to twice the expected update interval of a
// a GPS-type location provider (in case it misses a beat) plus a little.
-const int64 LocationArbitratorImpl::kFixStaleTimeoutMilliseconds =
+const int64_t LocationArbitratorImpl::kFixStaleTimeoutMilliseconds =
11 * base::Time::kMillisecondsPerSecond;
LocationArbitratorImpl::LocationArbitratorImpl(
diff --git a/chromium/content/browser/geolocation/location_arbitrator_impl.h b/chromium/content/browser/geolocation/location_arbitrator_impl.h
index 3ef7d5dfc6e..65a55321022 100644
--- a/chromium/content/browser/geolocation/location_arbitrator_impl.h
+++ b/chromium/content/browser/geolocation/location_arbitrator_impl.h
@@ -5,7 +5,10 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_LOCATION_ARBITRATOR_IMPL_H_
#define CONTENT_BROWSER_GEOLOCATION_LOCATION_ARBITRATOR_IMPL_H_
+#include <stdint.h>
+
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
@@ -32,7 +35,7 @@ class CONTENT_EXPORT LocationArbitratorImpl : public LocationArbitrator {
// Number of milliseconds newer a location provider has to be that it's worth
// switching to this location provider on the basis of it being fresher
// (regardles of relative accuracy). Public for tests.
- static const int64 kFixStaleTimeoutMilliseconds;
+ static const int64_t kFixStaleTimeoutMilliseconds;
typedef base::Callback<void(const Geoposition&)> LocationUpdateCallback;
diff --git a/chromium/content/browser/geolocation/location_provider_base.h b/chromium/content/browser/geolocation/location_provider_base.h
index b0ca80e119f..a95efa1546c 100644
--- a/chromium/content/browser/geolocation/location_provider_base.h
+++ b/chromium/content/browser/geolocation/location_provider_base.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_LOCATION_PROVIDER_BASE_H_
#define CONTENT_BROWSER_GEOLOCATION_LOCATION_PROVIDER_BASE_H_
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/location_provider.h"
diff --git a/chromium/content/browser/geolocation/mock_location_arbitrator.cc b/chromium/content/browser/geolocation/mock_location_arbitrator.cc
index f48915e07f1..154fcae4bee 100644
--- a/chromium/content/browser/geolocation/mock_location_arbitrator.cc
+++ b/chromium/content/browser/geolocation/mock_location_arbitrator.cc
@@ -15,7 +15,7 @@ MockLocationArbitrator::MockLocationArbitrator()
}
void MockLocationArbitrator::StartProviders(bool use_high_accuracy) {
- providers_started_ = true;;
+ providers_started_ = true;
}
void MockLocationArbitrator::StopProviders() {
diff --git a/chromium/content/browser/geolocation/mock_location_arbitrator.h b/chromium/content/browser/geolocation/mock_location_arbitrator.h
index efdb8b1cf9d..31e66016b19 100644
--- a/chromium/content/browser/geolocation/mock_location_arbitrator.h
+++ b/chromium/content/browser/geolocation/mock_location_arbitrator.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_MOCK_LOCATION_ARBITRATOR_H_
#define CONTENT_BROWSER_GEOLOCATION_MOCK_LOCATION_ARBITRATOR_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/browser/geolocation/location_arbitrator.h"
namespace content {
diff --git a/chromium/content/browser/geolocation/mock_location_provider.h b/chromium/content/browser/geolocation/mock_location_provider.h
index bedd2a4fad6..ec1a9777313 100644
--- a/chromium/content/browser/geolocation/mock_location_provider.h
+++ b/chromium/content/browser/geolocation/mock_location_provider.h
@@ -7,6 +7,7 @@
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
diff --git a/chromium/content/browser/geolocation/network_location_provider.h b/chromium/content/browser/geolocation/network_location_provider.h
index e3588c64272..69d891f2494 100644
--- a/chromium/content/browser/geolocation/network_location_provider.h
+++ b/chromium/content/browser/geolocation/network_location_provider.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H_
#define CONTENT_BROWSER_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H_
+#include <stddef.h>
+
#include <list>
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/content/browser/geolocation/network_location_provider_unittest.cc b/chromium/content/browser/geolocation/network_location_provider_unittest.cc
index aa3b68730f1..724eb356427 100644
--- a/chromium/content/browser/geolocation/network_location_provider_unittest.cc
+++ b/chromium/content/browser/geolocation/network_location_provider_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -41,7 +44,7 @@ class MessageLoopQuitListener {
const Geoposition& position) {
EXPECT_EQ(client_message_loop_, base::MessageLoop::current());
updated_provider_ = provider;
- client_message_loop_->Quit();
+ client_message_loop_->QuitWhenIdle();
}
base::MessageLoop* client_message_loop_;
diff --git a/chromium/content/browser/geolocation/network_location_request.cc b/chromium/content/browser/geolocation/network_location_request.cc
index be13119e337..dd23daeeddd 100644
--- a/chromium/content/browser/geolocation/network_location_request.cc
+++ b/chromium/content/browser/geolocation/network_location_request.cc
@@ -4,6 +4,9 @@
#include "content/browser/geolocation/network_location_request.h"
+#include <stdint.h>
+
+#include <limits>
#include <set>
#include <string>
@@ -209,11 +212,12 @@ void FormUploadData(const WifiData& wifi_data,
const base::Time& timestamp,
const base::string16& access_token,
std::string* upload_data) {
- int age = kint32min; // Invalid so AddInteger() will ignore.
+ int age = std::numeric_limits<int32_t>::min(); // Invalid so AddInteger()
+ // will ignore.
if (!timestamp.is_null()) {
// Convert absolute timestamps into a relative age.
- int64 delta_ms = (base::Time::Now() - timestamp).InMilliseconds();
- if (delta_ms >= 0 && delta_ms < kint32max)
+ int64_t delta_ms = (base::Time::Now() - timestamp).InMilliseconds();
+ if (delta_ms >= 0 && delta_ms < std::numeric_limits<int32_t>::max())
age = static_cast<int>(delta_ms);
}
@@ -234,7 +238,7 @@ void AddString(const std::string& property_name, const std::string& value,
void AddInteger(const std::string& property_name, int value,
base::DictionaryValue* dict) {
DCHECK(dict);
- if (value != kint32min)
+ if (value != std::numeric_limits<int32_t>::min())
dict->SetInteger(property_name, value);
}
diff --git a/chromium/content/browser/geolocation/network_location_request.h b/chromium/content/browser/geolocation/network_location_request.h
index f0734e00c25..fe15b72267d 100644
--- a/chromium/content/browser/geolocation/network_location_request.h
+++ b/chromium/content/browser/geolocation/network_location_request.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_NETWORK_LOCATION_REQUEST_H_
#define CONTENT_BROWSER_GEOLOCATION_NETWORK_LOCATION_REQUEST_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/geolocation/wifi_data_provider.h"
diff --git a/chromium/content/browser/geolocation/osx_wifi.h b/chromium/content/browser/geolocation/osx_wifi.h
deleted file mode 100644
index cef998b91d9..00000000000
--- a/chromium/content/browser/geolocation/osx_wifi.h
+++ /dev/null
@@ -1,102 +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.
-
-// The remainder of this file is copied from the Gears project:
-// http://code.google.com/p/gears/source/browse/trunk/gears/geolocation/osx_wifi.h
-
-// The contents of this file are taken from Apple80211.h from the iStumbler
-// project (http://www.istumbler.net). This project is released under the BSD
-// license with the following restrictions.
-//
-// Copyright (c) 02006, Alf Watt (alf@istumbler.net). All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// * Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// * Neither the name of iStumbler nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// This is the reverse engineered header for the Apple80211 private framework.
-// The framework can be found at
-// /System/Library/PrivateFrameworks/Apple80211.framework.
-
-#ifndef CONTENT_BROWSER_GEOLOCATION_OSX_WIFI_H_
-#define CONTENT_BROWSER_GEOLOCATION_OSX_WIFI_H_
-
-#include <CoreFoundation/CoreFoundation.h>
-
-extern "C" {
-
-typedef SInt32 WIErr;
-
-// A WirelessContext should be created using WirelessAttach
-// before any other Wireless functions are called. WirelessDetach
-// is used to dispose of a WirelessContext.
-struct WirelessContext;
-
-// WirelessAttach
-//
-// This should be called before all other wireless functions.
-typedef WIErr (*WirelessAttachFunction)(WirelessContext** outContext,
- const UInt32);
-
-// WirelessDetach
-//
-// This should be called after all other wireless functions.
-typedef WIErr (*WirelessDetachFunction)(WirelessContext* inContext);
-
-typedef UInt16 WINetworkInfoFlags;
-
-struct WirelessNetworkInfo
-{
- UInt16 channel; // Channel for the network.
- SInt16 noise; // Noise for the network. 0 for Adhoc.
- SInt16 signal; // Signal strength of the network. 0 for Adhoc.
- UInt8 macAddress[6]; // MAC address of the wireless access point.
- UInt16 beaconInterval; // Beacon interval in milliseconds
- WINetworkInfoFlags flags; // Flags for the network
- UInt16 nameLen;
- SInt8 name[32];
-};
-
-// WirelessScanSplit
-//
-// WirelessScanSplit scans for available wireless networks. It will allocate 2
-// CFArrays to store a list of managed and adhoc networks. The arrays hold
-// CFData objects which contain WirelessNetworkInfo structures.
-//
-// Note: An adhoc network created on the computer the scan is running on will
-// not be found. WirelessGetInfo can be used to find info about a local adhoc
-// network.
-//
-// If stripDups != 0 only one bases tation for each SSID will be returned.
-typedef WIErr (*WirelessScanSplitFunction)(WirelessContext* inContext,
- CFArrayRef* apList,
- CFArrayRef* adhocList,
- const UInt32 stripDups);
-
-} // extern "C"
-
-#endif // CONTENT_BROWSER_GEOLOCATION_OSX_WIFI_H_
diff --git a/chromium/content/browser/geolocation/wifi_data.cc b/chromium/content/browser/geolocation/wifi_data.cc
index bcfb9811bb7..2f41c33ee48 100644
--- a/chromium/content/browser/geolocation/wifi_data.cc
+++ b/chromium/content/browser/geolocation/wifi_data.cc
@@ -4,17 +4,20 @@
#include "content/browser/geolocation/wifi_data.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <algorithm>
+#include <limits>
#include "base/logging.h"
namespace content {
AccessPointData::AccessPointData()
- : radio_signal_strength(kint32min),
- channel(kint32min),
- signal_to_noise(kint32min) {
-}
+ : radio_signal_strength(std::numeric_limits<int32_t>::min()),
+ channel(std::numeric_limits<int32_t>::min()),
+ signal_to_noise(std::numeric_limits<int32_t>::min()) {}
AccessPointData::~AccessPointData() {}
diff --git a/chromium/content/browser/geolocation/wifi_data.h b/chromium/content/browser/geolocation/wifi_data.h
index 72bc3065abb..d6e0b33ab4e 100644
--- a/chromium/content/browser/geolocation/wifi_data.h
+++ b/chromium/content/browser/geolocation/wifi_data.h
@@ -7,7 +7,6 @@
#include <set>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/geolocation/wifi_data_provider.h b/chromium/content/browser/geolocation/wifi_data_provider.h
index 98d22963e9f..96ab8817b8a 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider.h
+++ b/chromium/content/browser/geolocation/wifi_data_provider.h
@@ -7,9 +7,9 @@
#include <set>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_chromeos.cc b/chromium/content/browser/geolocation/wifi_data_provider_chromeos.cc
index 18d84bad109..6060ec1bdbb 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_chromeos.cc
+++ b/chromium/content/browser/geolocation/wifi_data_provider_chromeos.cc
@@ -6,6 +6,8 @@
#include "content/browser/geolocation/wifi_data_provider_chromeos.h"
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/network/geolocation_handler.h"
@@ -144,7 +146,7 @@ bool WifiDataProviderChromeOs::GetAccessPointData(
return true;
chromeos::WifiAccessPointVector access_points;
- int64 age_ms = 0;
+ int64_t age_ms = 0;
if (!chromeos::NetworkHandler::Get()->geolocation_handler()->
GetWifiAccessPoints(&access_points, &age_ms)) {
return false;
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_chromeos.h b/chromium/content/browser/geolocation/wifi_data_provider_chromeos.h
index 0e8bc93fd21..e901f0131f8 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_chromeos.h
+++ b/chromium/content/browser/geolocation/wifi_data_provider_chromeos.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_CHROMEOS_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/browser/geolocation/wifi_data_provider.h"
#include "content/browser/geolocation/wifi_polling_policy.h"
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_common.cc b/chromium/content/browser/geolocation/wifi_data_provider_common.cc
index 7bac7abf95c..4406680c215 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_common.cc
+++ b/chromium/content/browser/geolocation/wifi_data_provider_common.cc
@@ -12,7 +12,7 @@
namespace content {
-base::string16 MacAddressAsString16(const uint8 mac_as_int[6]) {
+base::string16 MacAddressAsString16(const uint8_t 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/chromium/content/browser/geolocation/wifi_data_provider_common.h b/chromium/content/browser/geolocation/wifi_data_provider_common.h
index 771dd41efc8..d7cf19515c8 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_common.h
+++ b/chromium/content/browser/geolocation/wifi_data_provider_common.h
@@ -6,8 +6,10 @@
#define CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_COMMON_H_
#include <assert.h>
+#include <stdint.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
@@ -17,8 +19,8 @@
namespace content {
-// Converts a MAC address stored as an array of uint8 to a string.
-base::string16 MacAddressAsString16(const uint8 mac_as_int[6]);
+// Converts a MAC address stored as an array of uint8_t to a string.
+base::string16 MacAddressAsString16(const uint8_t 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/chromium/content/browser/geolocation/wifi_data_provider_common_unittest.cc b/chromium/content/browser/geolocation/wifi_data_provider_common_unittest.cc
index 53d44bcc770..b6521703872 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_common_unittest.cc
+++ b/chromium/content/browser/geolocation/wifi_data_provider_common_unittest.cc
@@ -4,10 +4,12 @@
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
+#include "build/build_config.h"
#include "content/browser/geolocation/wifi_data_provider_common.h"
#include "content/browser/geolocation/wifi_data_provider_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_common_win.cc b/chromium/content/browser/geolocation/wifi_data_provider_common_win.cc
index aac728d4ec0..77ff286062a 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_common_win.cc
+++ b/chromium/content/browser/geolocation/wifi_data_provider_common_win.cc
@@ -5,6 +5,7 @@
#include "content/browser/geolocation/wifi_data_provider_common_win.h"
#include <assert.h>
+#include <stdint.h>
#include "base/strings/utf_string_conversions.h"
#include "content/browser/geolocation/wifi_data_provider_common.h"
@@ -30,9 +31,10 @@ int GetDataFromBssIdList(const NDIS_802_11_BSSID_LIST& bss_id_list,
WifiData::AccessPointDataSet* data) {
// Walk through the BSS IDs.
int found = 0;
- const uint8 *iterator = reinterpret_cast<const uint8*>(&bss_id_list.Bssid[0]);
- const uint8 *end_of_buffer =
- reinterpret_cast<const uint8*>(&bss_id_list) + list_size;
+ const uint8_t* iterator =
+ reinterpret_cast<const uint8_t*>(&bss_id_list.Bssid[0]);
+ const uint8_t* end_of_buffer =
+ reinterpret_cast<const uint8_t*>(&bss_id_list) + list_size;
for (int i = 0; i < static_cast<int>(bss_id_list.NumberOfItems); ++i) {
const NDIS_WLAN_BSSID *bss_id =
reinterpret_cast<const NDIS_WLAN_BSSID*>(iterator);
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm b/chromium/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm
index 7e783f42942..036c7610b43 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm
+++ b/chromium/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm
@@ -8,9 +8,11 @@
#include <dlfcn.h>
#import <Foundation/Foundation.h>
+#include <stdint.h>
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/sys_string_conversions.h"
@@ -152,8 +154,10 @@ bool CoreWlanApi::GetAccessPointData(WifiData::AccessPointDataSet* data) {
AccessPointData access_point_data;
NSData* mac = [network bssidData];
DCHECK([mac length] == 6);
- access_point_data.mac_address = MacAddressAsString16(
- static_cast<const uint8*>([mac bytes]));
+ if (![mac bytes])
+ continue; // crbug.com/545501
+ access_point_data.mac_address =
+ MacAddressAsString16(static_cast<const uint8_t*>([mac bytes]));
access_point_data.radio_signal_strength = [[network rssi] intValue];
access_point_data.channel = [[network channel] intValue];
access_point_data.signal_to_noise =
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_linux.cc b/chromium/content/browser/geolocation/wifi_data_provider_linux.cc
index 5fad8c58bcf..7ec01b67f43 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_linux.cc
+++ b/chromium/content/browser/geolocation/wifi_data_provider_linux.cc
@@ -8,6 +8,10 @@
#include "content/browser/geolocation/wifi_data_provider_linux.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
@@ -155,7 +159,7 @@ bool NetworkManagerWlanApi::GetAccessPointData(
continue; // Check the next device.
}
dbus::MessageReader reader(response.get());
- uint32 device_type = 0;
+ uint32_t device_type = 0;
if (!reader.PopVariantOfUint32(&device_type)) {
LOG(WARNING) << "Unexpected response for " << device_type << ": "
<< response->ToString();
@@ -170,7 +174,7 @@ bool NetworkManagerWlanApi::GetAccessPointData(
++fail_count;
}
}
- // At least one successfull scan overrides any other adapter reporting error.
+ // At least one successful scan overrides any other adapter reporting error.
return success_count || fail_count == 0;
}
@@ -247,7 +251,7 @@ bool NetworkManagerWlanApi::GetAccessPointsForAdapter(
<< ": " << response->ToString();
continue;
}
- const uint8* ssid_bytes = NULL;
+ const uint8_t* ssid_bytes = NULL;
size_t ssid_length = 0;
if (!variant_reader.PopArrayOfBytes(&ssid_bytes, &ssid_length)) {
LOG(WARNING) << "Unexpected response for " << access_point_path.value()
@@ -272,7 +276,7 @@ bool NetworkManagerWlanApi::GetAccessPointsForAdapter(
}
base::ReplaceSubstringsAfterOffset(&mac, 0U, ":", base::StringPiece());
- std::vector<uint8> mac_bytes;
+ std::vector<uint8_t> mac_bytes;
if (!base::HexStringToBytes(mac, &mac_bytes) || mac_bytes.size() != 6) {
LOG(WARNING) << "Can't parse mac address (found " << mac_bytes.size()
<< " bytes) so using raw string: " << mac;
@@ -288,7 +292,7 @@ bool NetworkManagerWlanApi::GetAccessPointsForAdapter(
if (!response)
continue;
dbus::MessageReader reader(response.get());
- uint8 strength = 0;
+ uint8_t strength = 0;
if (!reader.PopVariantOfByte(&strength)) {
LOG(WARNING) << "Unexpected response for " << access_point_path.value()
<< ": " << response->ToString();
@@ -304,7 +308,7 @@ bool NetworkManagerWlanApi::GetAccessPointsForAdapter(
if (!response)
continue;
dbus::MessageReader reader(response.get());
- uint32 frequency = 0;
+ uint32_t frequency = 0;
if (!reader.PopVariantOfUint32(&frequency)) {
LOG(WARNING) << "Unexpected response for " << access_point_path.value()
<< ": " << response->ToString();
@@ -339,7 +343,7 @@ scoped_ptr<dbus::Response> NetworkManagerWlanApi::GetAccessPointProperty(
if (!response) {
LOG(WARNING) << "Failed to get property for " << property_name;
}
- return response.Pass();
+ return response;
}
} // namespace
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_linux.h b/chromium/content/browser/geolocation/wifi_data_provider_linux.h
index 48584257da1..238c95a8f0d 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_linux.h
+++ b/chromium/content/browser/geolocation/wifi_data_provider_linux.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_LINUX_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/browser/geolocation/wifi_data_provider_common.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_linux_unittest.cc b/chromium/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
index 5a4b546a082..3ca35d114b4 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
+++ b/chromium/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/geolocation/wifi_data_provider_linux.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -186,7 +189,7 @@ class GeolocationWifiDataProviderLinuxTest : public testing::Test {
dbus::MessageWriter writer(response.get());
if (property_name == "Ssid") {
- const uint8 kSsid[] = {0x74, 0x65, 0x73, 0x74}; // "test"
+ const uint8_t kSsid[] = {0x74, 0x65, 0x73, 0x74}; // "test"
dbus::MessageWriter variant_writer(response.get());
writer.OpenVariant("ay", &variant_writer);
variant_writer.AppendArrayOfBytes(kSsid, arraysize(kSsid));
@@ -197,11 +200,11 @@ class GeolocationWifiDataProviderLinuxTest : public testing::Test {
writer.AppendVariantOfString(kMacAddress);
} else if (property_name == "Strength") {
// This will be converted to -50.
- const uint8 kStrength = 100;
+ const uint8_t kStrength = 100;
writer.AppendVariantOfByte(kStrength);
} else if (property_name == "Frequency") {
// This will be converted to channel 4.
- const uint32 kFrequency = 2427;
+ const uint32_t kFrequency = 2427;
writer.AppendVariantOfUint32(kFrequency);
}
return response.release();
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_mac.cc b/chromium/content/browser/geolocation/wifi_data_provider_mac.cc
index da541872583..ac5a4845527 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_mac.cc
+++ b/chromium/content/browser/geolocation/wifi_data_provider_mac.cc
@@ -2,18 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// For OSX 10.5 we use the system API function WirelessScanSplit. This function
-// is not documented or included in the SDK, so we use a reverse-engineered
-// header, osx_wifi_.h. This file is taken from the iStumbler project
-// (http://www.istumbler.net).
-
#include "content/browser/geolocation/wifi_data_provider_mac.h"
-#include <dlfcn.h>
-#include <stdio.h>
-
-#include "base/strings/utf_string_conversions.h"
-#include "content/browser/geolocation/osx_wifi.h"
#include "content/browser/geolocation/wifi_data_provider_common.h"
#include "content/browser/geolocation/wifi_data_provider_manager.h"
@@ -24,139 +14,6 @@ const int kDefaultPollingInterval = 120000; // 2 mins
const int kNoChangePollingInterval = 300000; // 5 mins
const int kTwoNoChangePollingInterval = 600000; // 10 mins
const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s
-
-// Provides the wifi API binding for use when running on OSX 10.5 machines using
-// the Apple80211 framework.
-class Apple80211Api : public WifiDataProviderCommon::WlanApiInterface {
- public:
- Apple80211Api();
- ~Apple80211Api() override;
-
- // Must be called before any other interface method. Will return false if the
- // Apple80211 framework cannot be initialized (e.g. running on post-10.5 OSX),
- // in which case no other method may be called.
- bool Init();
-
- // WlanApiInterface
- bool GetAccessPointData(WifiData::AccessPointDataSet* data) override;
-
- private:
- // Handle, context and function pointers for Apple80211 library.
- void* apple_80211_library_;
- WirelessContext* wifi_context_;
- WirelessAttachFunction WirelessAttach_function_;
- WirelessScanSplitFunction WirelessScanSplit_function_;
- WirelessDetachFunction WirelessDetach_function_;
-
- WifiData wifi_data_;
-
- DISALLOW_COPY_AND_ASSIGN(Apple80211Api);
-};
-
-Apple80211Api::Apple80211Api()
- : apple_80211_library_(NULL), wifi_context_(NULL),
- WirelessAttach_function_(NULL), WirelessScanSplit_function_(NULL),
- WirelessDetach_function_(NULL) {
-}
-
-Apple80211Api::~Apple80211Api() {
- if (WirelessDetach_function_)
- (*WirelessDetach_function_)(wifi_context_);
- dlclose(apple_80211_library_);
-}
-
-bool Apple80211Api::Init() {
- DVLOG(1) << "Apple80211Api::Init";
- apple_80211_library_ = dlopen(
- "/System/Library/PrivateFrameworks/Apple80211.framework/Apple80211",
- RTLD_LAZY);
- if (!apple_80211_library_) {
- DLOG(WARNING) << "Could not open Apple80211 library";
- return false;
- }
- WirelessAttach_function_ = reinterpret_cast<WirelessAttachFunction>(
- dlsym(apple_80211_library_, "WirelessAttach"));
- WirelessScanSplit_function_ = reinterpret_cast<WirelessScanSplitFunction>(
- dlsym(apple_80211_library_, "WirelessScanSplit"));
- WirelessDetach_function_ = reinterpret_cast<WirelessDetachFunction>(
- dlsym(apple_80211_library_, "WirelessDetach"));
- DCHECK(WirelessAttach_function_);
- DCHECK(WirelessScanSplit_function_);
- DCHECK(WirelessDetach_function_);
-
- if (!WirelessAttach_function_ || !WirelessScanSplit_function_ ||
- !WirelessDetach_function_) {
- DLOG(WARNING) << "Symbol error. Attach: " << !!WirelessAttach_function_
- << " Split: " << !!WirelessScanSplit_function_
- << " Detach: " << !!WirelessDetach_function_;
- return false;
- }
-
- WIErr err = (*WirelessAttach_function_)(&wifi_context_, 0);
- if (err != noErr) {
- DLOG(WARNING) << "Error attaching: " << err;
- return false;
- }
- return true;
-}
-
-bool Apple80211Api::GetAccessPointData(WifiData::AccessPointDataSet* data) {
- DVLOG(1) << "Apple80211Api::GetAccessPointData";
- DCHECK(data);
- DCHECK(WirelessScanSplit_function_);
- CFArrayRef managed_access_points = NULL;
- CFArrayRef adhoc_access_points = NULL;
- // Arrays returned here are owned by the caller.
- WIErr err = (*WirelessScanSplit_function_)(wifi_context_,
- &managed_access_points,
- &adhoc_access_points,
- 0);
- if (err != noErr) {
- DLOG(WARNING) << "Error spliting scan: " << err;
- return false;
- }
-
- if (managed_access_points == NULL) {
- DLOG(WARNING) << "managed_access_points == NULL";
- return false;
- }
-
- int num_access_points = CFArrayGetCount(managed_access_points);
- DVLOG(1) << "Found " << num_access_points << " managed access points";
- for (int i = 0; i < num_access_points; ++i) {
- const WirelessNetworkInfo* access_point_info =
- reinterpret_cast<const WirelessNetworkInfo*>(
- CFDataGetBytePtr(
- reinterpret_cast<const CFDataRef>(
- CFArrayGetValueAtIndex(managed_access_points, i))));
-
- // Currently we get only MAC address, signal strength, channel
- // signal-to-noise and SSID
- AccessPointData access_point_data;
- access_point_data.mac_address =
- MacAddressAsString16(access_point_info->macAddress);
- // WirelessNetworkInfo::signal appears to be signal strength in dBm.
- access_point_data.radio_signal_strength = access_point_info->signal;
- access_point_data.channel = access_point_info->channel;
- // WirelessNetworkInfo::noise appears to be noise floor in dBm.
- access_point_data.signal_to_noise = access_point_info->signal -
- access_point_info->noise;
- if (!base::UTF8ToUTF16(reinterpret_cast<const char*>(
- access_point_info->name),
- access_point_info->nameLen,
- &access_point_data.ssid)) {
- access_point_data.ssid.clear();
- }
- data->insert(access_point_data);
- }
-
- if (managed_access_points)
- CFRelease(managed_access_points);
- if (adhoc_access_points)
- CFRelease(adhoc_access_points);
-
- return true;
-}
} // namespace
// static
@@ -171,17 +28,10 @@ WifiDataProviderMac::~WifiDataProviderMac() {
}
WifiDataProviderMac::WlanApiInterface* WifiDataProviderMac::NewWlanApi() {
- // Try and find a API binding that works: first try the officially supported
- // CoreWLAN API, and if this fails (e.g. on OSX 10.5) fall back to the reverse
- // engineered Apple80211 API.
WifiDataProviderMac::WlanApiInterface* core_wlan_api = NewCoreWlanApi();
if (core_wlan_api)
return core_wlan_api;
- scoped_ptr<Apple80211Api> wlan_api(new Apple80211Api);
- if (wlan_api->Init())
- return wlan_api.release();
-
DVLOG(1) << "WifiDataProviderMac : failed to initialize any wlan api";
return NULL;
}
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_mac.h b/chromium/content/browser/geolocation/wifi_data_provider_mac.h
index c1bd7985cdc..920c139e078 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_mac.h
+++ b/chromium/content/browser/geolocation/wifi_data_provider_mac.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_MAC_H_
#define CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_MAC_H_
+#include "base/macros.h"
#include "content/browser/geolocation/wifi_data_provider_common.h"
namespace content {
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_manager.h b/chromium/content/browser/geolocation/wifi_data_provider_manager.h
index 966c03a5ced..bb2af81e167 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_manager.h
+++ b/chromium/content/browser/geolocation/wifi_data_provider_manager.h
@@ -17,9 +17,9 @@
#include <set>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
diff --git a/chromium/content/browser/geolocation/wifi_data_provider_win.h b/chromium/content/browser/geolocation/wifi_data_provider_win.h
index 49ed704a38c..a69d7cb04ca 100644
--- a/chromium/content/browser/geolocation/wifi_data_provider_win.h
+++ b/chromium/content/browser/geolocation/wifi_data_provider_win.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_WIN_H_
#define CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_WIN_H_
+#include "base/macros.h"
#include "content/browser/geolocation/wifi_data_provider_common.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/geolocation/wifi_polling_policy.h b/chromium/content/browser/geolocation/wifi_polling_policy.h
index f597e837e7e..5798e5dddaa 100644
--- a/chromium/content/browser/geolocation/wifi_polling_policy.h
+++ b/chromium/content/browser/geolocation/wifi_polling_policy.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_WIFI_POLLING_POLICY_H_
#define CONTENT_BROWSER_GEOLOCATION_WIFI_POLLING_POLICY_H_
+#include "base/macros.h"
+
namespace content {
// Allows sharing and mocking of the update polling policy function.
diff --git a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
index 3a385ca6a46..f432608fb27 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -14,6 +14,7 @@
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
@@ -34,7 +35,7 @@ namespace content {
BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL;
struct BrowserGpuChannelHostFactory::CreateRequest {
- CreateRequest(int32 route_id)
+ CreateRequest(int32_t route_id)
: event(true, false),
gpu_host_id(0),
route_id(route_id),
@@ -42,7 +43,7 @@ struct BrowserGpuChannelHostFactory::CreateRequest {
~CreateRequest() {}
base::WaitableEvent event;
int gpu_host_id;
- int32 route_id;
+ int32_t route_id;
CreateCommandBufferResult result;
};
@@ -287,12 +288,12 @@ BrowserGpuChannelHostFactory::AllocateSharedMemory(size_t size) {
scoped_ptr<base::SharedMemory> shm(new base::SharedMemory());
if (!shm->CreateAnonymous(size))
return scoped_ptr<base::SharedMemory>();
- return shm.Pass();
+ return shm;
}
void BrowserGpuChannelHostFactory::CreateViewCommandBufferOnIO(
CreateRequest* request,
- int32 surface_id,
+ int32_t surface_id,
const GPUCreateCommandBufferConfig& init_params) {
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
if (!host) {
@@ -320,9 +321,9 @@ void BrowserGpuChannelHostFactory::CommandBufferCreatedOnIO(
}
CreateCommandBufferResult BrowserGpuChannelHostFactory::CreateViewCommandBuffer(
- int32 surface_id,
- const GPUCreateCommandBufferConfig& init_params,
- int32 route_id) {
+ int32_t surface_id,
+ const GPUCreateCommandBufferConfig& init_params,
+ int32_t route_id) {
CreateRequest request(route_id);
GetIOThreadTaskRunner()->PostTask(
FROM_HERE,
diff --git a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
index c0bcedceebe..530768c44b4 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -5,11 +5,16 @@
#ifndef CONTENT_BROWSER_GPU_BROWSER_GPU_CHANNEL_HOST_FACTORY_H_
#define CONTENT_BROWSER_GPU_BROWSER_GPU_CHANNEL_HOST_FACTORY_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "ipc/message_filter.h"
@@ -28,9 +33,9 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner() override;
scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) override;
CreateCommandBufferResult CreateViewCommandBuffer(
- int32 surface_id,
+ int32_t surface_id,
const GPUCreateCommandBufferConfig& init_params,
- int32 route_id) override;
+ int32_t route_id) override;
int GpuProcessHostId() { return gpu_host_id_; }
#if !defined(OS_ANDROID)
@@ -55,7 +60,7 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
void GpuChannelEstablished();
void CreateViewCommandBufferOnIO(
CreateRequest* request,
- int32 surface_id,
+ int32_t surface_id,
const GPUCreateCommandBufferConfig& init_params);
static void CommandBufferCreatedOnIO(CreateRequest* request,
CreateCommandBufferResult result);
diff --git a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
index 777f508ad09..d9c25c9344b 100644
--- a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
+++ b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -4,7 +4,8 @@
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
-#include "base/atomic_sequence_num.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
@@ -12,12 +13,13 @@
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/generic_shared_memory_id_generator.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
-#include "content/common/gpu/gpu_memory_buffer_factory_shared_memory.h"
+#include "content/common/gpu/gpu_memory_buffer_factory.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -39,39 +41,60 @@
namespace content {
namespace {
+void HostCreateGpuMemoryBuffer(
+ int surface_id,
+ GpuProcessHost* host,
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ int client_id,
+ const BrowserGpuMemoryBufferManager::CreateCallback& callback) {
+ host->CreateGpuMemoryBuffer(id, size, format, usage, client_id, surface_id,
+ callback);
+}
+
+void HostCreateGpuMemoryBufferFromHandle(
+ const gfx::GpuMemoryBufferHandle& handle,
+ GpuProcessHost* host,
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ int client_id,
+ const BrowserGpuMemoryBufferManager::CreateCallback& callback) {
+ host->CreateGpuMemoryBufferFromHandle(handle, id, size, format, client_id,
+ callback);
+}
+
void GpuMemoryBufferDeleted(
scoped_refptr<base::SingleThreadTaskRunner> destruction_task_runner,
const GpuMemoryBufferImpl::DestructionCallback& destruction_callback,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
destruction_task_runner->PostTask(
- FROM_HERE, base::Bind(destruction_callback, sync_point));
+ FROM_HERE, base::Bind(destruction_callback, sync_token));
}
-bool IsGpuMemoryBufferFactoryConfigurationSupported(
- gfx::GpuMemoryBufferType type,
- const GpuMemoryBufferFactory::Configuration& configuration) {
- switch (type) {
+bool IsNativeGpuMemoryBufferFactoryConfigurationSupported(
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage) {
+ switch (GpuMemoryBufferFactory::GetNativeType()) {
case gfx::SHARED_MEMORY_BUFFER:
- return GpuMemoryBufferFactorySharedMemory::
- IsGpuMemoryBufferConfigurationSupported(configuration.format,
- configuration.usage);
+ return false;
#if defined(OS_MACOSX)
case gfx::IO_SURFACE_BUFFER:
return GpuMemoryBufferFactoryIOSurface::
- IsGpuMemoryBufferConfigurationSupported(configuration.format,
- configuration.usage);
+ IsGpuMemoryBufferConfigurationSupported(format, usage);
#endif
#if defined(OS_ANDROID)
case gfx::SURFACE_TEXTURE_BUFFER:
return GpuMemoryBufferFactorySurfaceTexture::
- IsGpuMemoryBufferConfigurationSupported(configuration.format,
- configuration.usage);
+ IsGpuMemoryBufferConfigurationSupported(format, usage);
#endif
#if defined(USE_OZONE)
case gfx::OZONE_NATIVE_PIXMAP:
return GpuMemoryBufferFactoryOzoneNativePixmap::
- IsGpuMemoryBufferConfigurationSupported(configuration.format,
- configuration.usage);
+ IsGpuMemoryBufferConfigurationSupported(format, usage);
#endif
default:
NOTREACHED();
@@ -79,67 +102,48 @@ bool IsGpuMemoryBufferFactoryConfigurationSupported(
}
}
-gfx::GpuMemoryBufferType GetGpuMemoryBufferFactoryType() {
- std::vector<gfx::GpuMemoryBufferType> supported_types;
- GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
- DCHECK(!supported_types.empty());
-
- // The GPU service will always use the preferred type.
- return supported_types[0];
-}
-
-std::vector<GpuMemoryBufferFactory::Configuration>
-GetSupportedGpuMemoryBufferConfigurations(gfx::GpuMemoryBufferType type) {
- std::vector<GpuMemoryBufferFactory::Configuration> configurations;
-#if defined(OS_MACOSX)
- bool enable_native_gpu_memory_buffers =
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableNativeGpuMemoryBuffers);
-#else
- bool enable_native_gpu_memory_buffers =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableNativeGpuMemoryBuffers);
-#endif
-
- // Disable native buffers when using Mesa.
- if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kUseGL) == gfx::kGLImplementationOSMesaName) {
- enable_native_gpu_memory_buffers = false;
- }
-
- if (enable_native_gpu_memory_buffers) {
- const GpuMemoryBufferFactory::Configuration kNativeConfigurations[] = {
- {gfx::BufferFormat::R_8, gfx::BufferUsage::MAP},
- {gfx::BufferFormat::R_8, gfx::BufferUsage::PERSISTENT_MAP},
- {gfx::BufferFormat::RGBA_4444, gfx::BufferUsage::MAP},
- {gfx::BufferFormat::RGBA_4444, gfx::BufferUsage::PERSISTENT_MAP},
- {gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::MAP},
- {gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::PERSISTENT_MAP},
- {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::MAP},
- {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::PERSISTENT_MAP},
- {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::MAP},
- {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::PERSISTENT_MAP},
- {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::MAP},
- {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::PERSISTENT_MAP},
- };
- for (auto& configuration : kNativeConfigurations) {
- if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration))
- configurations.push_back(configuration);
+GpuMemoryBufferConfigurationSet GetNativeGpuMemoryBufferConfigurations() {
+ GpuMemoryBufferConfigurationSet configurations;
+
+ if (BrowserGpuMemoryBufferManager::IsNativeGpuMemoryBuffersEnabled()) {
+ const gfx::BufferFormat kNativeFormats[] = {
+ gfx::BufferFormat::R_8, gfx::BufferFormat::RGBA_4444,
+ gfx::BufferFormat::RGBA_8888, gfx::BufferFormat::BGRA_8888,
+ gfx::BufferFormat::UYVY_422, gfx::BufferFormat::YUV_420_BIPLANAR};
+ const gfx::BufferUsage kNativeUsages[] = {
+ gfx::BufferUsage::GPU_READ, gfx::BufferUsage::SCANOUT,
+ gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
+ gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT};
+ for (auto& format : kNativeFormats) {
+ for (auto& usage : kNativeUsages) {
+ if (IsNativeGpuMemoryBufferFactoryConfigurationSupported(format, usage))
+ configurations.insert(std::make_pair(format, usage));
+ }
}
}
#if defined(USE_OZONE) || defined(OS_MACOSX)
- const GpuMemoryBufferFactory::Configuration kScanoutConfigurations[] = {
- {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::SCANOUT},
- {gfx::BufferFormat::BGRX_8888, gfx::BufferUsage::SCANOUT},
- {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::SCANOUT},
- {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::SCANOUT},
- };
- for (auto& configuration : kScanoutConfigurations) {
- if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration))
- configurations.push_back(configuration);
- }
+ // Disable native buffers only when using Mesa.
+ bool force_native_gpu_read_write_formats =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kUseGL) != gfx::kGLImplementationOSMesaName;
+#else
+ bool force_native_gpu_read_write_formats = false;
#endif
+ if (force_native_gpu_read_write_formats) {
+ const gfx::BufferFormat kGPUReadWriteFormats[] = {
+ gfx::BufferFormat::RGBA_8888, gfx::BufferFormat::RGBX_8888,
+ gfx::BufferFormat::BGRA_8888, gfx::BufferFormat::BGRX_8888,
+ gfx::BufferFormat::UYVY_422, gfx::BufferFormat::YUV_420_BIPLANAR};
+ const gfx::BufferUsage kGPUReadWriteUsages[] = {
+ gfx::BufferUsage::GPU_READ, gfx::BufferUsage::SCANOUT};
+ for (auto& format : kGPUReadWriteFormats) {
+ for (auto& usage : kGPUReadWriteUsages) {
+ if (IsNativeGpuMemoryBufferFactoryConfigurationSupported(format, usage))
+ configurations.insert(std::make_pair(format, usage));
+ }
+ }
+ }
return configurations;
}
@@ -148,19 +152,19 @@ BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr;
} // namespace
-struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
- AllocateGpuMemoryBufferRequest(const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- int surface_id)
+struct BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferRequest {
+ CreateGpuMemoryBufferRequest(const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ int client_id,
+ int surface_id)
: event(true, false),
size(size),
format(format),
usage(usage),
client_id(client_id),
surface_id(surface_id) {}
- ~AllocateGpuMemoryBufferRequest() {}
+ ~CreateGpuMemoryBufferRequest() {}
base::WaitableEvent event;
gfx::Size size;
gfx::BufferFormat format;
@@ -170,12 +174,27 @@ struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
scoped_ptr<gfx::GpuMemoryBuffer> result;
};
+struct BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandleRequest
+ : public CreateGpuMemoryBufferRequest {
+ CreateGpuMemoryBufferFromHandleRequest(
+ const gfx::GpuMemoryBufferHandle& handle,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ int client_id)
+ : CreateGpuMemoryBufferRequest(size,
+ format,
+ gfx::BufferUsage::GPU_READ,
+ client_id,
+ 0),
+ handle(handle) {}
+ ~CreateGpuMemoryBufferFromHandleRequest() {}
+ gfx::GpuMemoryBufferHandle handle;
+};
+
BrowserGpuMemoryBufferManager::BrowserGpuMemoryBufferManager(
int gpu_client_id,
uint64_t gpu_client_tracing_id)
- : factory_type_(GetGpuMemoryBufferFactoryType()),
- supported_configurations_(
- GetSupportedGpuMemoryBufferConfigurations(factory_type_)),
+ : native_configurations_(GetNativeGpuMemoryBufferConfigurations()),
gpu_client_id_(gpu_client_id),
gpu_client_tracing_id_(gpu_client_tracing_id),
gpu_host_id_(0) {
@@ -193,28 +212,50 @@ BrowserGpuMemoryBufferManager* BrowserGpuMemoryBufferManager::current() {
}
// static
-uint32 BrowserGpuMemoryBufferManager::GetImageTextureTarget(
+bool BrowserGpuMemoryBufferManager::IsNativeGpuMemoryBuffersEnabled() {
+ // Disable native buffers when using Mesa.
+ if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kUseGL) == gfx::kGLImplementationOSMesaName) {
+ return false;
+ }
+
+#if defined(OS_MACOSX)
+ return !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableNativeGpuMemoryBuffers);
+#else
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableNativeGpuMemoryBuffers);
+#endif
+}
+
+// static
+uint32_t BrowserGpuMemoryBufferManager::GetImageTextureTarget(
gfx::BufferFormat format,
gfx::BufferUsage usage) {
- gfx::GpuMemoryBufferType type = GetGpuMemoryBufferFactoryType();
- for (auto& configuration : GetSupportedGpuMemoryBufferConfigurations(type)) {
- if (configuration.format != format || configuration.usage != usage)
- continue;
+ GpuMemoryBufferConfigurationSet native_configurations =
+ GetNativeGpuMemoryBufferConfigurations();
+ if (native_configurations.find(std::make_pair(format, usage)) ==
+ native_configurations.end()) {
+ return GL_TEXTURE_2D;
+ }
- switch (type) {
- case gfx::SURFACE_TEXTURE_BUFFER:
- case gfx::OZONE_NATIVE_PIXMAP:
- // GPU memory buffers that are shared with the GL using EGLImages
- // require TEXTURE_EXTERNAL_OES.
- return GL_TEXTURE_EXTERNAL_OES;
- case gfx::IO_SURFACE_BUFFER:
- // IOSurface backed images require GL_TEXTURE_RECTANGLE_ARB.
- return GL_TEXTURE_RECTANGLE_ARB;
- default:
- return GL_TEXTURE_2D;
- }
+ switch (GpuMemoryBufferFactory::GetNativeType()) {
+ case gfx::SURFACE_TEXTURE_BUFFER:
+ case gfx::OZONE_NATIVE_PIXMAP:
+ // GPU memory buffers that are shared with the GL using EGLImages
+ // require TEXTURE_EXTERNAL_OES.
+ return GL_TEXTURE_EXTERNAL_OES;
+ case gfx::IO_SURFACE_BUFFER:
+ // IOSurface backed images require GL_TEXTURE_RECTANGLE_ARB.
+ return GL_TEXTURE_RECTANGLE_ARB;
+ case gfx::SHARED_MEMORY_BUFFER:
+ return GL_TEXTURE_2D;
+ case gfx::EMPTY_BUFFER:
+ NOTREACHED();
+ return GL_TEXTURE_2D;
}
+ NOTREACHED();
return GL_TEXTURE_2D;
}
@@ -226,10 +267,35 @@ BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer(const gfx::Size& size,
}
scoped_ptr<gfx::GpuMemoryBuffer>
+BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandle(
+ const gfx::GpuMemoryBufferHandle& handle,
+ const gfx::Size& size,
+ gfx::BufferFormat format) {
+ DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ CreateGpuMemoryBufferFromHandleRequest request(handle, size, format,
+ gpu_client_id_);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&BrowserGpuMemoryBufferManager::
+ HandleCreateGpuMemoryBufferFromHandleOnIO,
+ base::Unretained(this), // Safe as we wait for result below.
+ base::Unretained(&request)));
+
+ // We're blocking the UI thread, which is generally undesirable.
+ TRACE_EVENT0(
+ "browser",
+ "BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandle");
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ request.event.Wait();
+ return std::move(request.result);
+}
+
+scoped_ptr<gfx::GpuMemoryBuffer>
BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForScanout(
const gfx::Size& size,
gfx::BufferFormat format,
- int32 surface_id) {
+ int32_t surface_id) {
DCHECK_GT(surface_id, 0);
return AllocateGpuMemoryBufferForSurface(
size, format, gfx::BufferUsage::SCANOUT, surface_id);
@@ -245,16 +311,16 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
const AllocationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Use service side allocation if this is a supported configuration.
- if (IsGpuMemoryBufferConfigurationSupported(format, usage)) {
- AllocateGpuMemoryBufferOnIO(id, size, format, usage, child_client_id, 0,
- false, callback);
+ // Use service side allocation for native configurations.
+ if (IsNativeGpuMemoryBufferConfiguration(format, usage)) {
+ CreateGpuMemoryBufferOnIO(base::Bind(&HostCreateGpuMemoryBuffer, 0), id,
+ size, format, usage, child_client_id, false,
+ callback);
return;
}
// Early out if we cannot fallback to shared memory buffer.
- if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) ||
- !GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) ||
+ if (!GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) ||
!GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) {
callback.Run(gfx::GpuMemoryBufferHandle());
return;
@@ -282,11 +348,11 @@ BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
return GpuMemoryBufferImpl::FromClientBuffer(buffer);
}
-void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
+void BrowserGpuMemoryBufferManager::SetDestructionSyncToken(
gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
static_cast<GpuMemoryBufferImpl*>(buffer)
- ->set_destruction_sync_point(sync_point);
+ ->set_destruction_sync_token(sync_token);
}
bool BrowserGpuMemoryBufferManager::OnMemoryDump(
@@ -318,7 +384,8 @@ bool BrowserGpuMemoryBufferManager::OnMemoryDump(
// corresponding dump for the same buffer, this will avoid to
// double-count them in tracing. If, instead, no other process will emit a
// dump with the same guid, the segment will be accounted to the browser.
- uint64 client_tracing_process_id = ClientIdToTracingProcessId(client_id);
+ uint64_t client_tracing_process_id =
+ ClientIdToTracingProcessId(client_id);
base::trace_event::MemoryAllocatorDumpGuid shared_buffer_guid =
gfx::GetGpuMemoryBufferGUIDForTracing(client_tracing_process_id,
@@ -335,10 +402,10 @@ void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer(
gfx::GpuMemoryBufferId id,
base::ProcessHandle child_process_handle,
int child_client_id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DestroyGpuMemoryBufferOnIO(id, child_client_id, sync_point);
+ DestroyGpuMemoryBufferOnIO(id, child_client_id, sync_token);
}
void BrowserGpuMemoryBufferManager::ProcessRemoved(
@@ -359,26 +426,33 @@ void BrowserGpuMemoryBufferManager::ProcessRemoved(
GpuProcessHost* host = GpuProcessHost::FromID(buffer.second.gpu_host_id);
if (host)
- host->DestroyGpuMemoryBuffer(buffer.first, client_id, 0);
+ host->DestroyGpuMemoryBuffer(buffer.first, client_id, gpu::SyncToken());
}
clients_.erase(client_it);
}
+bool BrowserGpuMemoryBufferManager::IsNativeGpuMemoryBufferConfiguration(
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage) const {
+ return native_configurations_.find(std::make_pair(format, usage)) !=
+ native_configurations_.end();
+}
+
scoped_ptr<gfx::GpuMemoryBuffer>
BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurface(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
- int32 surface_id) {
+ int32_t surface_id) {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
- AllocateGpuMemoryBufferRequest request(size, format, usage, gpu_client_id_,
- surface_id);
+ CreateGpuMemoryBufferRequest request(size, format, usage, gpu_client_id_,
+ surface_id);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(
- &BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO,
+ &BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferOnIO,
base::Unretained(this), // Safe as we wait for result below.
base::Unretained(&request)));
@@ -388,56 +462,100 @@ BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurface(
"BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurface");
base::ThreadRestrictions::ScopedAllowWait allow_wait;
request.event.Wait();
- return request.result.Pass();
+ return std::move(request.result);
}
-bool BrowserGpuMemoryBufferManager::IsGpuMemoryBufferConfigurationSupported(
- gfx::BufferFormat format,
- gfx::BufferUsage usage) const {
- for (auto& configuration : supported_configurations_) {
- if (configuration.format == format && configuration.usage == usage)
- return true;
+void BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferOnIO(
+ CreateGpuMemoryBufferRequest* request) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ gfx::GpuMemoryBufferId new_id = content::GetNextGenericSharedMemoryId();
+
+ // Use service side allocation for native configurations.
+ if (IsNativeGpuMemoryBufferConfiguration(request->format, request->usage)) {
+ // Note: Unretained is safe as this is only used for synchronous allocation
+ // from a non-IO thread.
+ CreateGpuMemoryBufferOnIO(
+ base::Bind(&HostCreateGpuMemoryBuffer, request->surface_id), new_id,
+ request->size, request->format, request->usage, request->client_id,
+ false,
+ base::Bind(
+ &BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO,
+ base::Unretained(this), base::Unretained(request)));
+ return;
}
- return false;
+
+ DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage))
+ << static_cast<int>(request->usage);
+
+ BufferMap& buffers = clients_[request->client_id];
+
+ // Allocate shared memory buffer as fallback.
+ auto insert_result = buffers.insert(std::make_pair(
+ new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER,
+ request->format, request->usage, 0)));
+ DCHECK(insert_result.second);
+
+ // Note: Unretained is safe as IO thread is stopped before manager is
+ // destroyed.
+ request->result = GpuMemoryBufferImplSharedMemory::Create(
+ new_id, request->size, request->format,
+ base::Bind(
+ &GpuMemoryBufferDeleted,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
+ base::Unretained(this), new_id, request->client_id)));
+ request->event.Signal();
}
-void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO(
- AllocateGpuMemoryBufferRequest* request) {
+void BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferFromHandleOnIO(
+ CreateGpuMemoryBufferFromHandleRequest* request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
gfx::GpuMemoryBufferId new_id = content::GetNextGenericSharedMemoryId();
- // Use service side allocation if this is a supported configuration.
- if (IsGpuMemoryBufferConfigurationSupported(request->format,
+ // Use service side allocation for native types.
+ if (request->handle.type != gfx::SHARED_MEMORY_BUFFER) {
+ // Early out if service side allocation is not supported.
+ if (request->handle.type != GpuMemoryBufferFactory::GetNativeType() ||
+ !IsNativeGpuMemoryBufferConfiguration(request->format,
request->usage)) {
+ request->event.Signal();
+ return;
+ }
// Note: Unretained is safe as this is only used for synchronous allocation
// from a non-IO thread.
- AllocateGpuMemoryBufferOnIO(
+ CreateGpuMemoryBufferOnIO(
+ base::Bind(&HostCreateGpuMemoryBufferFromHandle, request->handle),
new_id, request->size, request->format, request->usage,
- request->client_id, request->surface_id, false,
- base::Bind(&BrowserGpuMemoryBufferManager::
- GpuMemoryBufferAllocatedForSurfaceOnIO,
- base::Unretained(this), base::Unretained(request)));
+ request->client_id, false,
+ base::Bind(
+ &BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO,
+ base::Unretained(this), base::Unretained(request)));
return;
}
- DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format))
- << static_cast<int>(request->format);
DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage))
<< static_cast<int>(request->usage);
BufferMap& buffers = clients_[request->client_id];
- // Allocate shared memory buffer as fallback.
+ // Allocate shared memory buffer.
auto insert_result = buffers.insert(std::make_pair(
new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER,
request->format, request->usage, 0)));
DCHECK(insert_result.second);
+ gfx::GpuMemoryBufferHandle handle;
+ handle.id = new_id;
+ handle.handle = request->handle.handle;
+ handle.offset = request->handle.offset;
+ handle.stride = request->handle.stride;
+
// Note: Unretained is safe as IO thread is stopped before manager is
// destroyed.
- request->result = GpuMemoryBufferImplSharedMemory::Create(
- new_id, request->size, request->format,
+ request->result = GpuMemoryBufferImplSharedMemory::CreateFromHandle(
+ handle, request->size, request->format, request->usage,
base::Bind(
&GpuMemoryBufferDeleted,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
@@ -446,12 +564,12 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO(
request->event.Signal();
}
-void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedForSurfaceOnIO(
- AllocateGpuMemoryBufferRequest* request,
+void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO(
+ CreateGpuMemoryBufferRequest* request,
const gfx::GpuMemoryBufferHandle& handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Early out if factory failed to allocate the buffer.
+ // Early out if factory failed to create the buffer.
if (handle.is_null()) {
request->event.Signal();
return;
@@ -469,15 +587,15 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedForSurfaceOnIO(
request->event.Signal();
}
-void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO(
+void BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferOnIO(
+ const CreateDelegate& create_delegate,
gfx::GpuMemoryBufferId id,
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
int client_id,
- int surface_id,
bool reused_gpu_process,
- const AllocationCallback& callback) {
+ const CreateCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
@@ -493,11 +611,11 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO(
reused_gpu_process = false;
} else {
if (reused_gpu_process) {
- // We come here if we retried to allocate the buffer because of a
- // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the
- // same process ID, meaning the failure was not because of a channel
- // error, but another reason. So fail now.
- LOG(ERROR) << "Failed to allocate GpuMemoryBuffer.";
+ // We come here if we retried to create the buffer because of a failure
+ // in GpuMemoryBufferCreatedOnIO, but we ended up with the same process
+ // ID, meaning the failure was not because of a channel error, but
+ // another reason. So fail now.
+ LOG(ERROR) << "Failed to create GpuMemoryBuffer.";
callback.Run(gfx::GpuMemoryBufferHandle());
return;
}
@@ -508,11 +626,11 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO(
// Note: Handling of cases where the client is removed before the allocation
// completes is less subtle if we set the buffer type to EMPTY_BUFFER here
- // and verify that this has not changed when allocation completes.
+ // and verify that this has not changed when creation completes.
auto insert_result = buffers.insert(std::make_pair(
id, BufferInfo(size, gfx::EMPTY_BUFFER, format, usage, 0)));
if (!insert_result.second) {
- DLOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
+ DLOG(ERROR) << "Child process attempted to create a GpuMemoryBuffer with "
"an existing ID.";
callback.Run(gfx::GpuMemoryBufferHandle());
return;
@@ -520,20 +638,20 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO(
// Note: Unretained is safe as IO thread is stopped before manager is
// destroyed.
- host->CreateGpuMemoryBuffer(
- id, size, format, usage, client_id, surface_id,
- base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO,
- base::Unretained(this), id, client_id, surface_id,
+ create_delegate.Run(
+ host, id, size, format, usage, client_id,
+ base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO,
+ base::Unretained(this), create_delegate, id, client_id,
gpu_host_id_, reused_gpu_process, callback));
}
-void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO(
+void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
+ const CreateDelegate& create_delegate,
gfx::GpuMemoryBufferId id,
int client_id,
- int surface_id,
int gpu_host_id,
bool reused_gpu_process,
- const AllocationCallback& callback,
+ const CreateCallback& callback,
const gfx::GpuMemoryBufferHandle& handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -544,7 +662,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO(
if (!handle.is_null()) {
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id);
if (host)
- host->DestroyGpuMemoryBuffer(handle.id, client_id, 0);
+ host->DestroyGpuMemoryBuffer(handle.id, client_id, gpu::SyncToken());
}
callback.Run(gfx::GpuMemoryBufferHandle());
return;
@@ -572,10 +690,10 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO(
gfx::Size size = buffer_it->second.size;
gfx::BufferFormat format = buffer_it->second.format;
gfx::BufferUsage usage = buffer_it->second.usage;
- // Remove the buffer entry and call AllocateGpuMemoryBufferOnIO again.
+ // Remove the buffer entry and call CreateGpuMemoryBufferOnIO again.
buffers.erase(buffer_it);
- AllocateGpuMemoryBufferOnIO(id, size, format, usage, client_id,
- surface_id, reused_gpu_process, callback);
+ CreateGpuMemoryBufferOnIO(create_delegate, id, size, format, usage,
+ client_id, reused_gpu_process, callback);
} else {
// Remove the buffer entry and run the allocation callback with an empty
// handle to indicate failure.
@@ -596,7 +714,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO(
void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO(
gfx::GpuMemoryBufferId id,
int client_id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(clients_.find(client_id) != clients_.end());
@@ -617,7 +735,7 @@ void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO(
GpuProcessHost* host = GpuProcessHost::FromID(buffer_it->second.gpu_host_id);
if (host)
- host->DestroyGpuMemoryBuffer(id, client_id, sync_point);
+ host->DestroyGpuMemoryBuffer(id, client_id, sync_token);
buffers.erase(buffer_it);
}
diff --git a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
index 12fd082975a..0057192b65b 100644
--- a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
+++ b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
@@ -5,22 +5,49 @@
#ifndef CONTENT_BROWSER_GPU_BROWSER_GPU_MEMORY_BUFFER_MANAGER_H_
#define CONTENT_BROWSER_GPU_BROWSER_GPU_MEMORY_BUFFER_MANAGER_H_
-#include <vector>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <utility>
#include "base/callback.h"
+#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/trace_event/memory_dump_provider.h"
#include "content/common/content_export.h"
-#include "content/common/gpu/gpu_memory_buffer_factory.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
namespace content {
+using GpuMemoryBufferConfigurationKey =
+ std::pair<gfx::BufferFormat, gfx::BufferUsage>;
+using GpuMemoryBufferConfigurationSet =
+ base::hash_set<GpuMemoryBufferConfigurationKey>;
+
+} // content
+
+namespace BASE_HASH_NAMESPACE {
+
+template <>
+struct hash<content::GpuMemoryBufferConfigurationKey> {
+ size_t operator()(const content::GpuMemoryBufferConfigurationKey& key) const {
+ return base::HashPair(static_cast<int>(key.first),
+ static_cast<int>(key.second));
+ }
+};
+
+} // namespace BASE_HASH_NAMESPACE
+
+namespace content {
+class GpuProcessHost;
+
class CONTENT_EXPORT BrowserGpuMemoryBufferManager
: public gpu::GpuMemoryBufferManager,
public base::trace_event::MemoryDumpProvider {
public:
- typedef base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)>
- AllocationCallback;
+ using CreateCallback =
+ base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)>;
+ using AllocationCallback = CreateCallback;
BrowserGpuMemoryBufferManager(int gpu_client_id,
uint64_t gpu_client_tracing_id);
@@ -28,18 +55,24 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
static BrowserGpuMemoryBufferManager* current();
- static uint32 GetImageTextureTarget(gfx::BufferFormat format,
- gfx::BufferUsage usage);
+ static bool IsNativeGpuMemoryBuffersEnabled();
+
+ static uint32_t GetImageTextureTarget(gfx::BufferFormat format,
+ gfx::BufferUsage usage);
// Overridden from gpu::GpuMemoryBufferManager:
scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage) override;
+ scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBufferFromHandle(
+ const gfx::GpuMemoryBufferHandle& handle,
+ const gfx::Size& size,
+ gfx::BufferFormat format) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
- void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) override;
+ void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
+ const gpu::SyncToken& sync_token) override;
// Overridden from base::trace_event::MemoryDumpProvider:
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
@@ -49,7 +82,7 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferForScanout(
const gfx::Size& size,
gfx::BufferFormat format,
- int32 surface_id);
+ int32_t surface_id);
void AllocateGpuMemoryBufferForChildProcess(
gfx::GpuMemoryBufferId id,
@@ -63,15 +96,18 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
gfx::GpuMemoryBufferId id,
base::ProcessHandle child_process_handle,
int child_client_id,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
void ProcessRemoved(base::ProcessHandle process_handle, int client_id);
+ bool IsNativeGpuMemoryBufferConfiguration(gfx::BufferFormat format,
+ gfx::BufferUsage usage) const;
+
private:
struct BufferInfo {
BufferInfo()
: type(gfx::EMPTY_BUFFER),
format(gfx::BufferFormat::RGBA_8888),
- usage(gfx::BufferUsage::MAP),
+ usage(gfx::BufferUsage::GPU_READ),
gpu_host_id(0) {}
BufferInfo(const gfx::Size& size,
gfx::GpuMemoryBufferType type,
@@ -90,44 +126,55 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
gfx::BufferUsage usage;
int gpu_host_id;
};
- struct AllocateGpuMemoryBufferRequest;
+
+ struct CreateGpuMemoryBufferRequest;
+ struct CreateGpuMemoryBufferFromHandleRequest;
+
+ using CreateDelegate = base::Callback<void(GpuProcessHost* host,
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ int client_id,
+ const CreateCallback& callback)>;
scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferForSurface(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
- int32 surface_id);
- bool IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage) const;
- void AllocateGpuMemoryBufferForSurfaceOnIO(
- AllocateGpuMemoryBufferRequest* request);
- void GpuMemoryBufferAllocatedForSurfaceOnIO(
- AllocateGpuMemoryBufferRequest* request,
+ int32_t surface_id);
+
+ // Functions that handle synchronous buffer creation requests.
+ void HandleCreateGpuMemoryBufferOnIO(CreateGpuMemoryBufferRequest* request);
+ void HandleCreateGpuMemoryBufferFromHandleOnIO(
+ CreateGpuMemoryBufferFromHandleRequest* request);
+ void HandleGpuMemoryBufferCreatedOnIO(
+ CreateGpuMemoryBufferRequest* request,
const gfx::GpuMemoryBufferHandle& handle);
- void AllocateGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- int surface_id,
- bool reused_gpu_process,
- const AllocationCallback& callback);
- void GpuMemoryBufferAllocatedOnIO(gfx::GpuMemoryBufferId id,
- int client_id,
- int surface_id,
- int gpu_host_id,
- bool reused_gpu_process,
- const AllocationCallback& callback,
- const gfx::GpuMemoryBufferHandle& handle);
+
+ // Functions that implement asynchronous buffer creation.
+ void CreateGpuMemoryBufferOnIO(const CreateDelegate& create_delegate,
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ int client_id,
+ bool reused_gpu_process,
+ const CreateCallback& callback);
+ void GpuMemoryBufferCreatedOnIO(const CreateDelegate& create_delegate,
+ gfx::GpuMemoryBufferId id,
+ int client_id,
+ int gpu_host_id,
+ bool reused_gpu_process,
+ const CreateCallback& callback,
+ const gfx::GpuMemoryBufferHandle& handle);
void DestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
int client_id,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
uint64_t ClientIdToTracingProcessId(int client_id) const;
- const gfx::GpuMemoryBufferType factory_type_;
- const std::vector<GpuMemoryBufferFactory::Configuration>
- supported_configurations_;
+ const GpuMemoryBufferConfigurationSet native_configurations_;
const int gpu_client_id_;
const uint64_t gpu_client_tracing_id_;
diff --git a/chromium/content/browser/gpu/compositor_util.cc b/chromium/content/browser/gpu/compositor_util.cc
index 216d1da24b6..d7b3e40928e 100644
--- a/chromium/content/browser/gpu/compositor_util.cc
+++ b/chromium/content/browser/gpu/compositor_util.cc
@@ -4,14 +4,18 @@
#include "content/browser/gpu/compositor_util.h"
+#include <stddef.h>
+
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_info.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
#include "cc/base/switches.h"
+#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/public/common/content_switches.h"
#include "gpu/config/gpu_feature_type.h"
@@ -208,12 +212,41 @@ bool IsZeroCopyUploadEnabled() {
#endif
}
-bool IsPersistentGpuMemoryBufferEnabled() {
- // Zero copy currently doesn't take advantage of persistent buffers.
+bool IsPartialRasterEnabled() {
+ // Zero copy currently doesn't take advantage of partial raster.
if (IsZeroCopyUploadEnabled())
return false;
const auto& command_line = *base::CommandLine::ForCurrentProcess();
- return command_line.HasSwitch(switches::kEnablePersistentGpuMemoryBuffer);
+ return command_line.HasSwitch(switches::kEnablePartialRaster);
+}
+
+bool IsGpuMemoryBufferCompositorResourcesEnabled() {
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(
+ switches::kEnableGpuMemoryBufferCompositorResources)) {
+ return true;
+ }
+ if (command_line.HasSwitch(
+ switches::kDisableGpuMemoryBufferCompositorResources)) {
+ return false;
+ }
+
+ // Native GPU memory buffers are required.
+ if (!BrowserGpuMemoryBufferManager::IsNativeGpuMemoryBuffersEnabled())
+ return false;
+
+ // GPU rasterization does not support GL_TEXTURE_RECTANGLE_ARB, which is
+ // required by GpuMemoryBuffers on Mac.
+ // http://crbug.com/551072
+ if (IsForceGpuRasterizationEnabled() || IsGpuRasterizationEnabled())
+ return false;
+
+#if defined(OS_MACOSX)
+ return true;
+#else
+ return false;
+#endif
}
bool IsGpuRasterizationEnabled() {
diff --git a/chromium/content/browser/gpu/compositor_util.h b/chromium/content/browser/gpu/compositor_util.h
index ea82ca1c47e..1dc495a7758 100644
--- a/chromium/content/browser/gpu/compositor_util.h
+++ b/chromium/content/browser/gpu/compositor_util.h
@@ -21,9 +21,11 @@ CONTENT_EXPORT bool IsPropertyTreeVerificationEnabled();
// Only one of one-copy and zero-copy can be enabled at a time.
CONTENT_EXPORT bool IsZeroCopyUploadEnabled();
-// Returns true if a persistent GpuMemoryBuffer can be used and is on (via
-// flags, or platform default).
-CONTENT_EXPORT bool IsPersistentGpuMemoryBufferEnabled();
+// Returns true if a partial raster is on (via flags).
+CONTENT_EXPORT bool IsPartialRasterEnabled();
+
+// Returns true if all compositor resources should use GPU memory buffers.
+CONTENT_EXPORT bool IsGpuMemoryBufferCompositorResourcesEnabled();
// Returns true if gpu rasterization is on (via flags) for the renderer.
CONTENT_EXPORT bool IsGpuRasterizationEnabled();
diff --git a/chromium/content/browser/gpu/gpu_arc_video_service_host.cc b/chromium/content/browser/gpu/gpu_arc_video_service_host.cc
new file mode 100644
index 00000000000..7ba572d64f1
--- /dev/null
+++ b/chromium/content/browser/gpu/gpu_arc_video_service_host.cc
@@ -0,0 +1,76 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/gpu_arc_video_service_host.h"
+
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/common/gpu/gpu_messages.h"
+#include "content/public/browser/arc_video_host_delegate.h"
+#include "content/public/browser/browser_thread.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_utils.h"
+#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
+
+namespace content {
+
+namespace {
+
+void CreateChannelOnIOThread(
+ const GpuProcessHost::CreateArcVideoAcceleratorChannelCallback& callback) {
+ GpuProcessHost* gpu_process_host =
+ GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ CAUSE_FOR_GPU_LAUNCH_ARCVIDEOACCELERATOR);
+ gpu_process_host->CreateArcVideoAcceleratorChannel(callback);
+}
+
+void HandleChannelCreatedReply(
+ const arc::VideoHost::OnRequestArcVideoAcceleratorChannelCallback& callback,
+ const IPC::ChannelHandle& handle) {
+ MojoHandle wrapped_handle;
+ MojoResult wrap_result = mojo::embedder::CreatePlatformHandleWrapper(
+ mojo::embedder::ScopedPlatformHandle(
+ mojo::embedder::PlatformHandle(handle.socket.fd)),
+ &wrapped_handle);
+ if (wrap_result != MOJO_RESULT_OK) {
+ LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
+ callback.Run(mojo::ScopedHandle());
+ return;
+ }
+ callback.Run(mojo::ScopedHandle(mojo::Handle(wrapped_handle)));
+}
+
+} // namespace
+
+scoped_ptr<arc::VideoHostDelegate> CreateArcVideoHostDelegate() {
+ return make_scoped_ptr(new GpuArcVideoServiceHost());
+}
+
+GpuArcVideoServiceHost::GpuArcVideoServiceHost()
+ : io_task_runner_(content::BrowserThread::GetMessageLoopProxyForThread(
+ content::BrowserThread::IO)) {}
+
+GpuArcVideoServiceHost::~GpuArcVideoServiceHost() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void GpuArcVideoServiceHost::OnRequestArcVideoAcceleratorChannel(
+ const OnRequestArcVideoAcceleratorChannelCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ io_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&CreateChannelOnIOThread,
+ base::Bind(&HandleChannelCreatedReply, callback)));
+}
+
+void GpuArcVideoServiceHost::OnStopping() {
+ GpuProcessHost::SendOnIO(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
+ new GpuMsg_ShutdownArcVideoService());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_arc_video_service_host.h b/chromium/content/browser/gpu/gpu_arc_video_service_host.h
new file mode 100644
index 00000000000..3a5ca2a1dd3
--- /dev/null
+++ b/chromium/content/browser/gpu/gpu_arc_video_service_host.h
@@ -0,0 +1,54 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_GPU_GPU_ARC_VIDEO_SERVICE_HOST_H_
+#define CONTENT_BROWSER_GPU_GPU_ARC_VIDEO_SERVICE_HOST_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/thread_checker.h"
+#include "components/arc/video/video_host_delegate.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace IPC {
+struct ChannelHandle;
+}
+
+namespace content {
+
+// This class passes requests from arc::VideoInstance to GpuArcVideoService to
+// create a video accelerator channel in GPU process and reply the created
+// channel.
+//
+// Don't be confused two senses of "host" of this class. This class, which
+// implements arc::VideoHost, handles requests from arc::VideoInstance. At the
+// same time, as its name says, this class is the host of corresponding class,
+// GpuArcVideoService, in the GPU process.
+class GpuArcVideoServiceHost : public arc::VideoHostDelegate {
+ public:
+ GpuArcVideoServiceHost();
+ ~GpuArcVideoServiceHost() override;
+
+ // arc::VideoHostDelegate implementation.
+ void OnStopping() override;
+
+ // arc::VideoHost implementation.
+ void OnRequestArcVideoAcceleratorChannel(
+ const OnRequestArcVideoAcceleratorChannelCallback& callback) override;
+
+ private:
+ base::ThreadChecker thread_checker_;
+
+ // IO task runner, where GpuProcessHost tasks run.
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuArcVideoServiceHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_GPU_GPU_ARC_VIDEO_SERVICE_HOST_H_
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.cc b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
index 82813622604..2fe3cae3a06 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
@@ -256,7 +256,8 @@ unsigned int GpuDataManagerImpl::GetDisplayCount() const {
return private_->GetDisplayCount();
}
-bool GpuDataManagerImpl::UpdateActiveGpu(uint32 vendor_id, uint32 device_id) {
+bool GpuDataManagerImpl::UpdateActiveGpu(uint32_t vendor_id,
+ uint32_t device_id) {
base::AutoLock auto_lock(lock_);
return private_->UpdateActiveGpu(vendor_id, device_id);
}
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.h b/chromium/content/browser/gpu/gpu_data_manager_impl.h
index 3fddc38764d..c509e3a2e88 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.h
@@ -5,11 +5,15 @@
#ifndef CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_H_
#define CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/process/kill.h"
@@ -174,7 +178,7 @@ class CONTENT_EXPORT GpuDataManagerImpl
// Set the active gpu.
// Return true if it's a different GPU from the previous active one.
- bool UpdateActiveGpu(uint32 vendor_id, uint32 device_id);
+ bool UpdateActiveGpu(uint32_t vendor_id, uint32_t device_id);
// Called when GPU process initialization failed.
void OnGpuProcessInitFailure();
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
index ec1776cd4b3..1e4fe79c162 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -15,6 +15,7 @@
#include "base/sys_info.h"
#include "base/trace_event/trace_event.h"
#include "base/version.h"
+#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/common/gpu/gpu_messages.h"
@@ -111,7 +112,7 @@ int GetGpuBlacklistHistogramValueWin(GpuFeatureStatus status) {
void UpdateStats(const gpu::GPUInfo& gpu_info,
const gpu::GpuBlacklist* blacklist,
const std::set<int>& blacklisted_features) {
- uint32 max_entry_id = blacklist->max_entry_id();
+ uint32_t max_entry_id = blacklist->max_entry_id();
if (max_entry_id == 0) {
// GPU Blacklist was not loaded. No need to go further.
return;
@@ -129,7 +130,7 @@ void UpdateStats(const gpu::GPUInfo& gpu_info,
0, max_entry_id + 1);
if (blacklisted_features.size() != 0) {
- std::vector<uint32> flag_entries;
+ std::vector<uint32_t> flag_entries;
blacklist->GetDecisionEntries(&flag_entries, disabled);
DCHECK_GT(flag_entries.size(), 0u);
for (size_t i = 0; i < flag_entries.size(); ++i) {
@@ -140,10 +141,10 @@ void UpdateStats(const gpu::GPUInfo& gpu_info,
// This counts how many users are affected by a disabled entry - this allows
// us to understand the impact of an entry before enable it.
- std::vector<uint32> flag_disabled_entries;
+ std::vector<uint32_t> flag_disabled_entries;
disabled = true;
blacklist->GetDecisionEntries(&flag_disabled_entries, disabled);
- for (uint32 disabled_entry : flag_disabled_entries) {
+ for (uint32_t disabled_entry : flag_disabled_entries) {
UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerDisabledEntry",
disabled_entry, max_entry_id + 1);
}
@@ -234,7 +235,7 @@ void DisplayReconfigCallback(CGDirectDisplayID display,
// Gpu change.
bool gpu_changed = false;
if (flags & kCGDisplayAddFlag) {
- uint32 vendor_id, device_id;
+ uint32_t vendor_id, device_id;
if (gpu::CollectGpuID(&vendor_id, &device_id) == gpu::kCollectInfoSuccess) {
gpu_changed = manager->UpdateActiveGpu(vendor_id, device_id);
}
@@ -247,7 +248,7 @@ void DisplayReconfigCallback(CGDirectDisplayID display,
// Block all domains' use of 3D APIs for this many milliseconds if
// approaching a threshold where system stability might be compromised.
-const int64 kBlockAllDomainsMs = 10000;
+const int64_t kBlockAllDomainsMs = 10000;
const int kNumResetsWithinDuration = 1;
// Enums for UMA histograms.
@@ -482,6 +483,7 @@ void GpuDataManagerImplPrivate::SetGLStrings(const std::string& gl_vendor,
gpu_info.gl_renderer = gl_renderer;
gpu_info.gl_version = gl_version;
+ gpu::IdentifyActiveGPU(&gpu_info);
gpu::CollectDriverInfoGL(&gpu_info);
UpdateGpuInfo(gpu_info);
@@ -573,8 +575,27 @@ void GpuDataManagerImplPrivate::UpdateGpuInfoHelper() {
gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision(
gpu::GpuControlList::kOsAny, std::string(), gpu_info_);
+ std::set<std::string> disabled_ext_set;
+
+ // Merge disabled extensions from the command line with gpu driver bug list.
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
+ if (command_line) {
+ const std::vector<std::string>& disabled_command_line_exts =
+ base::SplitString(
+ command_line->GetSwitchValueASCII(switches::kDisableGLExtensions),
+ ", ;", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ disabled_ext_set.insert(disabled_command_line_exts.begin(),
+ disabled_command_line_exts.end());
+ }
+ const std::vector<std::string>& disabled_driver_bug_exts =
+ gpu_driver_bug_list_->GetDisabledExtensions();
+ disabled_ext_set.insert(disabled_driver_bug_exts.begin(),
+ disabled_driver_bug_exts.end());
disabled_extensions_ =
- base::JoinString(gpu_driver_bug_list_->GetDisabledExtensions(), " ");
+ base::JoinString(std::vector<std::string>(disabled_ext_set.begin(),
+ disabled_ext_set.end()),
+ " ");
}
gpu::GpuDriverBugList::AppendWorkaroundsFromCommandLine(
&gpu_driver_bugs_, *base::CommandLine::ForCurrentProcess());
@@ -633,15 +654,10 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
std::string use_gl =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kUseGL);
- base::FilePath swiftshader_path =
- base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
- switches::kSwiftShaderPath);
if (gpu_driver_bugs_.find(gpu::DISABLE_D3D11) != gpu_driver_bugs_.end())
command_line->AppendSwitch(switches::kDisableD3D11);
if (use_swiftshader_) {
command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader");
- if (swiftshader_path.empty())
- swiftshader_path = swiftshader_path_;
} else if ((IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL) ||
IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING) ||
IsFeatureBlacklisted(
@@ -657,9 +673,9 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
else
command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "false");
- if (!swiftshader_path.empty()) {
+ if (!swiftshader_path_.empty()) {
command_line->AppendSwitchPath(switches::kSwiftShaderPath,
- swiftshader_path);
+ swiftshader_path_);
}
if (!gpu_driver_bugs_.empty()) {
@@ -854,8 +870,8 @@ void GpuDataManagerImplPrivate::HandleGpuSwitch() {
new GpuMsg_GpuSwitched);
}
-bool GpuDataManagerImplPrivate::UpdateActiveGpu(
- uint32 vendor_id, uint32 device_id) {
+bool GpuDataManagerImplPrivate::UpdateActiveGpu(uint32_t vendor_id,
+ uint32_t device_id) {
if (gpu_info_.gpu.vendor_id == vendor_id &&
gpu_info_.gpu.device_id == device_id) {
// The primary GPU is active.
@@ -912,13 +928,28 @@ bool GpuDataManagerImplPrivate::ShouldDisableAcceleratedVideoDecode(
return true;
if (group_name == "Disabled")
return true;
+
+ // Accelerated decode is never available with --disable-gpu. It is also
+ // currently non-functional with --single-process and --in-process-gpu, but
+ // these should be fixable. We set the --disable-accelerated-video-decode flag
+ // in these cases so that the renderer can be aware. (Which is important on
+ // Android where there is no fallback once WMPI is selected.)
+ //
+ // TODO(sandersd): Enable support for accelerated decode with
+ // --in-process-gpu, at least on Android (necessary to support WebView).
+ // http://crbug.com/574935.
+ if (command_line->HasSwitch(switches::kDisableGpu) ||
+ command_line->HasSwitch(switches::kSingleProcess) ||
+ command_line->HasSwitch(switches::kInProcessGPU)) {
+ return true;
+ }
+
return false;
}
void GpuDataManagerImplPrivate::GetDisabledExtensions(
std::string* disabled_extensions) const {
DCHECK(disabled_extensions);
-
*disabled_extensions = disabled_extensions_;
}
@@ -973,6 +1004,9 @@ GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(
DCHECK(owner_);
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
+ swiftshader_path_ =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
+ switches::kSwiftShaderPath);
if (command_line->HasSwitch(switches::kDisableGpu))
DisableHardwareAcceleration();
@@ -1047,7 +1081,7 @@ void GpuDataManagerImplPrivate::UpdateGpuSwitchingManager(
const gpu::GPUInfo& gpu_info) {
// The vendor IDs might be 0 on non-PCI devices (like Android), but
// the length of the vector is all we care about in most cases.
- std::vector<uint32> vendor_ids;
+ std::vector<uint32_t> vendor_ids;
vendor_ids.push_back(gpu_info.gpu.vendor_id);
for (const auto& device : gpu_info.secondary_gpus) {
vendor_ids.push_back(device.vendor_id);
@@ -1187,7 +1221,7 @@ GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
}
-int64 GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
+int64_t GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
return kBlockAllDomainsMs;
}
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
index ab6aaf9f7a2..b083b601775 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_
#define CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
#include <map>
#include <set>
@@ -12,9 +15,11 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/observer_list_threadsafe.h"
+#include "build/build_config.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "gpu/config/gpu_blacklist.h"
#include "gpu/config/gpu_driver_bug_list.h"
@@ -114,7 +119,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void SetDisplayCount(unsigned int display_count);
unsigned int GetDisplayCount() const;
- bool UpdateActiveGpu(uint32 vendor_id, uint32 device_id);
+ bool UpdateActiveGpu(uint32_t vendor_id, uint32_t device_id);
void OnGpuProcessInitFailure();
@@ -227,7 +232,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
base::Time at_time);
GpuDataManagerImpl::DomainBlockStatus Are3DAPIsBlockedAtTime(
const GURL& url, base::Time at_time) const;
- int64 GetBlockAllDomainsDurationInMs() const;
+ int64_t GetBlockAllDomainsDurationInMs() const;
bool complete_gpu_info_already_requested_;
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
index 1179a9a6182..f1865594646 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -2,10 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/gpu/gpu_data_manager_impl_private.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "gpu/config/gpu_feature_type.h"
diff --git a/chromium/content/browser/gpu/gpu_internals_ui.cc b/chromium/content/browser/gpu/gpu_internals_ui.cc
index c30afe09621..e93c9015202 100644
--- a/chromium/content/browser/gpu/gpu_internals_ui.cc
+++ b/chromium/content/browser/gpu/gpu_internals_ui.cc
@@ -4,9 +4,7 @@
#include "content/browser/gpu/gpu_internals_ui.h"
-#if defined(OS_LINUX) && defined(USE_X11)
-#include <X11/Xlib.h>
-#endif
+#include <stddef.h>
#include <string>
@@ -15,10 +13,13 @@
#include "base/command_line.h"
#include "base/environment.h"
#include "base/i18n/time_formatting.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/values.h"
+#include "build/build_config.h"
+#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/grit/content_resources.h"
@@ -36,6 +37,9 @@
#include "third_party/angle/src/common/version.h"
#include "ui/gl/gpu_switching_manager.h"
+#if defined(OS_LINUX) && defined(USE_X11)
+#include <X11/Xlib.h>
+#endif
#if defined(OS_WIN)
#include "ui/base/win/shell.h"
#endif
@@ -232,6 +236,89 @@ base::DictionaryValue* GpuInfoAsDictionaryValue() {
return info;
}
+const char* BufferFormatToString(gfx::BufferFormat format) {
+ switch (format) {
+ case gfx::BufferFormat::ATC:
+ return "ATC";
+ case gfx::BufferFormat::ATCIA:
+ return "ATCIA";
+ case gfx::BufferFormat::DXT1:
+ return "DXT1";
+ case gfx::BufferFormat::DXT5:
+ return "DXT5";
+ case gfx::BufferFormat::ETC1:
+ return "ETC1";
+ case gfx::BufferFormat::R_8:
+ return "R_8";
+ case gfx::BufferFormat::RGBA_4444:
+ return "RGBA_4444";
+ case gfx::BufferFormat::RGBX_8888:
+ return "RGBX_8888";
+ case gfx::BufferFormat::RGBA_8888:
+ return "RGBA_8888";
+ case gfx::BufferFormat::BGRX_8888:
+ return "BGRX_8888";
+ case gfx::BufferFormat::BGRA_8888:
+ return "BGRA_8888";
+ case gfx::BufferFormat::YUV_420:
+ return "YUV_420";
+ case gfx::BufferFormat::YUV_420_BIPLANAR:
+ return "YUV_420_BIPLANAR";
+ case gfx::BufferFormat::UYVY_422:
+ return "UYVY_422";
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
+const char* BufferUsageToString(gfx::BufferUsage usage) {
+ switch (usage) {
+ case gfx::BufferUsage::GPU_READ:
+ return "GPU_READ";
+ case gfx::BufferUsage::SCANOUT:
+ return "SCANOUT";
+ case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
+ return "GPU_READ_CPU_READ_WRITE";
+ case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
+ return "GPU_READ_CPU_READ_WRITE_PERSISTENT";
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
+base::DictionaryValue* GpuMemoryBufferInfoAsDictionaryValue() {
+ base::ListValue* gpu_memory_buffer_info = new base::ListValue();
+
+ BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager =
+ BrowserGpuMemoryBufferManager::current();
+
+ for (size_t format = 0;
+ format < static_cast<size_t>(gfx::BufferFormat::LAST) + 1; format++) {
+ std::string native_usage_support;
+ for (size_t usage = 0;
+ usage < static_cast<size_t>(gfx::BufferUsage::LAST) + 1; usage++) {
+ if (gpu_memory_buffer_manager->IsNativeGpuMemoryBufferConfiguration(
+ static_cast<gfx::BufferFormat>(format),
+ static_cast<gfx::BufferUsage>(usage)))
+ native_usage_support = base::StringPrintf(
+ "%s%s %s", native_usage_support.c_str(),
+ native_usage_support.empty() ? "" : ",",
+ BufferUsageToString(static_cast<gfx::BufferUsage>(usage)));
+ }
+ if (native_usage_support.empty())
+ native_usage_support = base::StringPrintf("Software only");
+
+ gpu_memory_buffer_info->Append(NewDescriptionValuePair(
+ BufferFormatToString(static_cast<gfx::BufferFormat>(format)),
+ native_usage_support));
+ }
+
+ base::DictionaryValue* info = new base::DictionaryValue();
+ info->Set("gpu_memory_buffer_info", gpu_memory_buffer_info);
+
+ return info;
+}
+
// This class receives javascript messages from the renderer.
// Note that the WebUI infrastructure runs on the UI thread, therefore all of
// this class's methods are expected to run on the UI thread.
@@ -409,6 +496,14 @@ void GpuMessageHandler::OnGpuInfoUpdate() {
// Send GPU Info to javascript.
web_ui()->CallJavascriptFunction("browserBridge.onGpuInfoUpdate",
*(gpu_info_val.get()));
+
+ // Get GpuMemoryBuffer Info.
+ scoped_ptr<base::DictionaryValue> gpu_memory_buffer_info_val(
+ GpuMemoryBufferInfoAsDictionaryValue());
+
+ // Send GpuMemoryBuffer Info to javascript.
+ web_ui()->CallJavascriptFunction("browserBridge.onGpuMemoryBufferInfoUpdate",
+ *(gpu_memory_buffer_info_val.get()));
}
void GpuMessageHandler::OnGpuSwitched() {
diff --git a/chromium/content/browser/gpu/gpu_internals_ui.h b/chromium/content/browser/gpu/gpu_internals_ui.h
index 41fd7ead277..b465c8e23be 100644
--- a/chromium/content/browser/gpu/gpu_internals_ui.h
+++ b/chromium/content/browser/gpu/gpu_internals_ui.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GPU_GPU_INTERNALS_UI_H_
#define CONTENT_BROWSER_GPU_GPU_INTERNALS_UI_H_
+#include "base/macros.h"
#include "content/public/browser/web_ui_controller.h"
namespace content {
diff --git a/chromium/content/browser/gpu/gpu_ipc_browsertests.cc b/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
index 7154c2eea99..1dcb1549049 100644
--- a/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -4,6 +4,7 @@
#include "base/command_line.h"
#include "base/run_loop.h"
+#include "build/build_config.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
@@ -13,6 +14,9 @@
#include "content/public/common/content_switches.h"
#include "content/public/test/content_browser_test.h"
#include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gl/gl_switches.h"
namespace {
@@ -194,6 +198,52 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
}
#endif
+// Test fails on Windows because GPU Channel set-up fails.
+// Mac only fails GPU set-up on MacOS 10.6, but we have no version-specific
+// macros for disabling tests.
+#if !defined(OS_WIN) && !defined(OS_MACOSX)
+#define MAYBE_GrContextKeepsGpuChannelAlive GrContextKeepsGpuChannelAlive
+#else
+#define MAYBE_GrContextKeepsGpuChannelAlive \
+ DISABLED_GrContextKeepsGpuChannelAlive
+#endif
+IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
+ MAYBE_GrContextKeepsGpuChannelAlive) {
+ // Test for crbug.com/551143
+ // This test verifies that holding a reference to the GrContext created by
+ // a ContextProviderCommandBuffer will keep the gpu channel alive after the
+ // provider has been destroyed. Without this behavior, user code would have
+ // to be careful to destroy objects in the right order to avoid using freed
+ // memory as a function pointer in the GrContext's GrGLInterface instance.
+ DCHECK(!IsChannelEstablished());
+ EstablishAndWait();
+
+ // Step 2: verify that holding onto the provider's GrContext will
+ // retain the host after provider is destroyed.
+ scoped_refptr<ContextProviderCommandBuffer> provider =
+ ContextProviderCommandBuffer::Create(CreateContext(),
+ OFFSCREEN_CONTEXT_FOR_TESTING);
+ EXPECT_TRUE(provider->BindToCurrentThread());
+
+ skia::RefPtr<GrContext> gr_context = skia::SharePtr(provider->GrContext());
+ provider = nullptr;
+
+ SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
+ skia::RefPtr<SkSurface> surface = skia::AdoptRef(SkSurface::NewRenderTarget(
+ gr_context.get(), SkSurface::kNo_Budgeted, info));
+ gr_context = nullptr;
+
+ // use the canvas after the provider and grcontext have been locally
+ // unref'ed. This should work just fine thanks to SkSurface_Gpu ref'ing
+ // the GrContext, which is ref'ing the GrGLInterfaceForWebGraphicsContext3D,
+ // which owns the commandbuffer instance.
+ SkPaint greenFillPaint;
+ greenFillPaint.setColor(SK_ColorGREEN);
+ greenFillPaint.setStyle(SkPaint::kFill_Style);
+ // Passes by not crashing
+ surface->getCanvas()->drawRect(SkRect::MakeWH(100, 100), greenFillPaint);
+}
+
// Test fails on Chromeos + Mac, flaky on Windows because UI Compositor
// establishes a GPU channel.
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
diff --git a/chromium/content/browser/gpu/gpu_process_host.cc b/chromium/content/browser/gpu/gpu_process_host.cc
index ed05dcb8a35..ad9cafeba40 100644
--- a/chromium/content/browser/gpu/gpu_process_host.cc
+++ b/chromium/content/browser/gpu/gpu_process_host.cc
@@ -4,18 +4,23 @@
#include "content/browser/gpu/gpu_process_host.h"
+#include <stddef.h>
+
+#include <utility>
+
#include "base/base64.h"
#include "base/base_switches.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram.h"
#include "base/sha1.h"
#include "base/threading/thread.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "components/tracing/tracing_switches.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/gpu/compositor_util.h"
@@ -23,6 +28,7 @@
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/gpu/shader_disk_cache.h"
+#include "content/browser/mojo/mojo_application_host.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/gpu/gpu_messages.h"
@@ -66,11 +72,6 @@
#include "ui/gfx/x/x11_switches.h"
#endif
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include "content/browser/browser_io_surface_manager_mac.h"
-#include "content/common/child_process_messages.h"
-#endif
-
#if defined(OS_MACOSX)
#include "content/browser/renderer_host/render_widget_resize_helper_mac.h"
#endif
@@ -101,8 +102,12 @@ static const char* const kSwitchNames[] = {
#if defined(OS_WIN)
switches::kEnableAcceleratedVpxDecode,
#endif
+ switches::kEnableHeapProfiling,
switches::kEnableLogging,
switches::kEnableShareGroupAsyncTextureUpload,
+#if defined(OS_ANDROID)
+ switches::kEnableUnifiedMediaPipeline,
+#endif
#if defined(OS_CHROMEOS)
switches::kDisableVaapiAcceleratedVideoEncode,
#endif
@@ -135,6 +140,7 @@ static const char* const kSwitchNames[] = {
switches::kOzonePlatform,
#endif
#if defined(USE_X11) && !defined(OS_CHROMEOS)
+ switches::kWindowDepth,
switches::kX11Display,
#endif
};
@@ -187,16 +193,15 @@ class GpuSandboxedProcessLauncherDelegate
return sandbox;
}
- void PreSandbox(bool* disable_default_policy,
- base::FilePath* exposed_dir) override {
- *disable_default_policy = true;
+ bool DisableDefaultPolicy() override {
+ return true;
}
// For the GPU process we gotten as far as USER_LIMITED. The next level
// which is USER_RESTRICTED breaks both the DirectX backend and the OpenGL
// backend. Note that the GPU process is connected to the interactive
// desktop.
- void PreSpawnTarget(sandbox::TargetPolicy* policy, bool* success) override {
+ bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
if (base::win::GetVersion() > base::win::VERSION_XP) {
if (cmd_line_->GetSwitchValueASCII(switches::kUseGL) ==
gfx::kGLImplementationDesktopName) {
@@ -237,10 +242,8 @@ class GpuSandboxedProcessLauncherDelegate
sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
L"\\\\.\\pipe\\chrome.gpu.*");
- if (result != sandbox::SBOX_ALL_OK) {
- *success = false;
- return;
- }
+ if (result != sandbox::SBOX_ALL_OK)
+ return false;
// Block this DLL even if it is not loaded by the browser process.
policy->AddDllToUnload(L"cmsetac.dll");
@@ -251,10 +254,8 @@ class GpuSandboxedProcessLauncherDelegate
result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
sandbox::TargetPolicy::HANDLES_DUP_BROKER,
L"Section");
- if (result != sandbox::SBOX_ALL_OK) {
- *success = false;
- return;
- }
+ if (result != sandbox::SBOX_ALL_OK)
+ return false;
#endif
if (cmd_line_->HasSwitch(switches::kEnableLogging)) {
@@ -263,16 +264,16 @@ class GpuSandboxedProcessLauncherDelegate
result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_ANY,
log_file_path.c_str());
- if (result != sandbox::SBOX_ALL_OK) {
- *success = false;
- return;
- }
+ if (result != sandbox::SBOX_ALL_OK)
+ return false;
}
}
+
+ return true;
}
#elif defined(OS_POSIX)
- base::ScopedFD TakeIpcFd() override { return ipc_fd_.Pass(); }
+ base::ScopedFD TakeIpcFd() override { return std::move(ipc_fd_); }
#endif // OS_WIN
SandboxType GetSandboxType() override {
@@ -445,13 +446,6 @@ GpuProcessHost::~GpuProcessHost() {
queued_messages_.pop();
}
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- if (!io_surface_manager_token_.IsZero()) {
- BrowserIOSurfaceManager::GetInstance()->InvalidateGpuProcessToken();
- io_surface_manager_token_.SetZero();
- }
-#endif
-
// This is only called on the IO thread so no race against the constructor
// for another GpuProcessHost.
if (g_gpu_process_hosts[kind_] == this)
@@ -468,8 +462,6 @@ GpuProcessHost::~GpuProcessHost() {
uma_memory_stats_received_);
if (uma_memory_stats_received_) {
- UMA_HISTOGRAM_COUNTS_100("GPU.AtExitManagedMemoryClientCount",
- uma_memory_stats_.client_count);
UMA_HISTOGRAM_COUNTS_100("GPU.AtExitContextGroupCount",
uma_memory_stats_.context_group_count);
UMA_HISTOGRAM_CUSTOM_COUNTS(
@@ -478,9 +470,6 @@ GpuProcessHost::~GpuProcessHost() {
UMA_HISTOGRAM_CUSTOM_COUNTS(
"GPU.AtExitMBytesAllocatedMax",
uma_memory_stats_.bytes_allocated_max / 1024 / 1024, 1, 2000, 50);
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "GPU.AtExitMBytesLimit",
- uma_memory_stats_.bytes_limit / 1024 / 1024, 1, 2000, 50);
}
std::string message;
@@ -543,6 +532,9 @@ bool GpuProcessHost::Init() {
if (channel_id.empty())
return false;
+ if (!SetupMojo())
+ return false;
+
if (in_process_) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(g_gpu_main_thread_factory);
@@ -564,17 +556,15 @@ bool GpuProcessHost::Init() {
if (!Send(new GpuMsg_Initialize()))
return false;
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- io_surface_manager_token_ =
- BrowserIOSurfaceManager::GetInstance()->GenerateGpuProcessToken();
- // Note: A valid IOSurface manager token needs to be sent to the Gpu process
- // before any GpuMemoryBuffer allocation requests can be sent.
- Send(new ChildProcessMsg_SetIOSurfaceManagerToken(io_surface_manager_token_));
-#endif
-
return true;
}
+bool GpuProcessHost::SetupMojo() {
+ DCHECK(!mojo_application_host_);
+ mojo_application_host_.reset(new MojoApplicationHost);
+ return mojo_application_host_->Init();
+}
+
void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) {
BrowserThread::PostTask(
BrowserThread::UI,
@@ -614,6 +604,10 @@ bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
OnGpuMemoryBufferCreated)
IPC_MESSAGE_HANDLER(GpuHostMsg_DidCreateOffscreenContext,
OnDidCreateOffscreenContext)
+#if defined(OS_CHROMEOS)
+ IPC_MESSAGE_HANDLER(GpuHostMsg_ArcVideoAcceleratorChannelCreated,
+ OnArcVideoAcceleratorChannelCreated)
+#endif
IPC_MESSAGE_HANDLER(GpuHostMsg_DidLoseContext, OnDidLoseContext)
IPC_MESSAGE_HANDLER(GpuHostMsg_DidDestroyOffscreenContext,
OnDidDestroyOffscreenContext)
@@ -627,6 +621,10 @@ bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
OnDestroyChannel)
IPC_MESSAGE_HANDLER(GpuHostMsg_CacheShader,
OnCacheShader)
+#if defined(OS_WIN)
+ IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceCreatedChildWindow,
+ OnAcceleratedSurfaceCreatedChildWindow)
+#endif
IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message))
IPC_END_MESSAGE_MAP()
@@ -634,7 +632,37 @@ bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
return true;
}
-void GpuProcessHost::OnChannelConnected(int32 peer_pid) {
+#if defined(OS_WIN)
+void GpuProcessHost::OnAcceleratedSurfaceCreatedChildWindow(
+ const gfx::PluginWindowHandle& parent_handle,
+ const gfx::PluginWindowHandle& window_handle) {
+ DCHECK(process_);
+ {
+ DWORD process_id = 0;
+ DWORD thread_id = GetWindowThreadProcessId(parent_handle, &process_id);
+
+ if (!thread_id || process_id != ::GetCurrentProcessId()) {
+ process_->TerminateOnBadMessageReceived(
+ GpuHostMsg_AcceleratedSurfaceCreatedChildWindow::ID);
+ return;
+ }
+ }
+ {
+ DWORD process_id = 0;
+ DWORD thread_id = GetWindowThreadProcessId(window_handle, &process_id);
+
+ if (!thread_id || process_id != process_->GetProcess().Pid()) {
+ process_->TerminateOnBadMessageReceived(
+ GpuHostMsg_AcceleratedSurfaceCreatedChildWindow::ID);
+ return;
+ }
+ }
+
+ ::SetParent(window_handle, parent_handle);
+}
+#endif
+
+void GpuProcessHost::OnChannelConnected(int32_t peer_pid) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnChannelConnected");
while (!queued_messages_.empty()) {
@@ -708,7 +736,7 @@ void GpuProcessHost::CreateGpuMemoryBuffer(
gfx::BufferFormat format,
gfx::BufferUsage usage,
int client_id,
- int32 surface_id,
+ int32_t surface_id,
const CreateGpuMemoryBufferCallback& callback) {
TRACE_EVENT0("gpu", "GpuProcessHost::CreateGpuMemoryBuffer");
@@ -729,19 +757,57 @@ void GpuProcessHost::CreateGpuMemoryBuffer(
}
}
+void GpuProcessHost::CreateGpuMemoryBufferFromHandle(
+ const gfx::GpuMemoryBufferHandle& handle,
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ int client_id,
+ const CreateGpuMemoryBufferCallback& callback) {
+ TRACE_EVENT0("gpu", "GpuProcessHost::CreateGpuMemoryBufferFromHandle");
+
+ DCHECK(CalledOnValidThread());
+
+ GpuMsg_CreateGpuMemoryBufferFromHandle_Params params;
+ params.handle = handle;
+ params.id = id;
+ params.size = size;
+ params.format = format;
+ params.client_id = client_id;
+ if (Send(new GpuMsg_CreateGpuMemoryBufferFromHandle(params))) {
+ create_gpu_memory_buffer_requests_.push(callback);
+ } else {
+ callback.Run(gfx::GpuMemoryBufferHandle());
+ }
+}
+
void GpuProcessHost::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
int client_id,
- int sync_point) {
+ const gpu::SyncToken& sync_token) {
TRACE_EVENT0("gpu", "GpuProcessHost::DestroyGpuMemoryBuffer");
DCHECK(CalledOnValidThread());
- Send(new GpuMsg_DestroyGpuMemoryBuffer(id, client_id, sync_point));
+ Send(new GpuMsg_DestroyGpuMemoryBuffer(id, client_id, sync_token));
+}
+
+#if defined(OS_CHROMEOS)
+void GpuProcessHost::CreateArcVideoAcceleratorChannel(
+ const CreateArcVideoAcceleratorChannelCallback& callback) {
+ DCHECK(CalledOnValidThread());
+
+ if (Send(new GpuMsg_CreateArcVideoAcceleratorChannel())) {
+ create_arc_video_accelerator_channel_requests_.push(callback);
+ } else {
+ callback.Run(IPC::ChannelHandle());
+ }
}
+#endif
void GpuProcessHost::OnInitialized(bool result, const gpu::GPUInfo& gpu_info) {
UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", result);
initialized_ = result;
+ gpu_info_ = gpu_info;
if (!initialized_)
GpuDataManagerImpl::GetInstance()->OnGpuProcessInitFailure();
@@ -777,8 +843,7 @@ void GpuProcessHost::OnChannelEstablished(
return;
}
- callback.Run(channel_handle,
- GpuDataManagerImpl::GetInstance()->GetGPUInfo());
+ callback.Run(channel_handle, gpu_info_);
}
void GpuProcessHost::OnCommandBufferCreated(CreateCommandBufferResult result) {
@@ -806,6 +871,24 @@ void GpuProcessHost::OnGpuMemoryBufferCreated(
callback.Run(handle);
}
+#if defined(OS_CHROMEOS)
+void GpuProcessHost::OnArcVideoAcceleratorChannelCreated(
+ const IPC::ChannelHandle& handle) {
+ if (create_arc_video_accelerator_channel_requests_.empty()) {
+ RouteOnUIThread(
+ GpuHostMsg_OnLogMessage(logging::LOG_WARNING, "WARNING",
+ "Received a ArcVideoAcceleratorChannelCreated "
+ "message but no requests in queue."));
+ return;
+ }
+
+ CreateArcVideoAcceleratorChannelCallback callback =
+ create_arc_video_accelerator_channel_requests_.front();
+ create_arc_video_accelerator_channel_requests_.pop();
+ callback.Run(handle);
+}
+#endif
+
void GpuProcessHost::OnDidCreateOffscreenContext(const GURL& url) {
urls_with_live_offscreen_contexts_.insert(url);
}
@@ -868,6 +951,14 @@ void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped(
void GpuProcessHost::OnProcessLaunched() {
UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime",
base::TimeTicks::Now() - init_start_time_);
+
+ base::ProcessHandle handle;
+ if (in_process_)
+ handle = base::GetCurrentProcessHandle();
+ else
+ handle = process_->GetData().handle;
+
+ mojo_application_host_->Activate(this, handle);
}
void GpuProcessHost::OnProcessLaunchFailed() {
@@ -881,6 +972,10 @@ void GpuProcessHost::OnProcessCrashed(int exit_code) {
process_->GetTerminationStatus(true /* known_dead */, NULL));
}
+ServiceRegistry* GpuProcessHost::GetServiceRegistry() {
+ return mojo_application_host_->service_registry();
+}
+
GpuProcessHost::GpuProcessKind GpuProcessHost::kind() {
return kind_;
}
@@ -891,13 +986,6 @@ void GpuProcessHost::ForceShutdown() {
if (g_gpu_process_hosts[kind_] == this)
g_gpu_process_hosts[kind_] = NULL;
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- if (!io_surface_manager_token_.IsZero()) {
- BrowserIOSurfaceManager::GetInstance()->InvalidateGpuProcessToken();
- io_surface_manager_token_.SetZero();
- }
-#endif
-
process_->ForceShutdown();
}
@@ -1006,6 +1094,15 @@ void GpuProcessHost::SendOutstandingReplies() {
create_gpu_memory_buffer_requests_.pop();
callback.Run(gfx::GpuMemoryBufferHandle());
}
+
+#if defined(OS_CHROMEOS)
+ while (!create_arc_video_accelerator_channel_requests_.empty()) {
+ CreateArcVideoAcceleratorChannelCallback callback =
+ create_arc_video_accelerator_channel_requests_.front();
+ create_arc_video_accelerator_channel_requests_.pop();
+ callback.Run(IPC::ChannelHandle());
+ }
+#endif
}
void GpuProcessHost::BlockLiveOffscreenContexts() {
@@ -1102,7 +1199,7 @@ void GpuProcessHost::LoadedShader(const std::string& key,
Send(new GpuMsg_LoadedShader(data));
}
-void GpuProcessHost::CreateChannelCache(int32 client_id) {
+void GpuProcessHost::CreateChannelCache(int32_t client_id) {
TRACE_EVENT0("gpu", "GpuProcessHost::CreateChannelCache");
scoped_refptr<ShaderDiskCache> cache =
@@ -1115,12 +1212,12 @@ void GpuProcessHost::CreateChannelCache(int32 client_id) {
client_id_to_shader_cache_[client_id] = cache;
}
-void GpuProcessHost::OnDestroyChannel(int32 client_id) {
+void GpuProcessHost::OnDestroyChannel(int32_t client_id) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnDestroyChannel");
client_id_to_shader_cache_.erase(client_id);
}
-void GpuProcessHost::OnCacheShader(int32 client_id,
+void GpuProcessHost::OnCacheShader(int32_t client_id,
const std::string& key,
const std::string& shader) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader");
diff --git a/chromium/content/browser/gpu/gpu_process_host.h b/chromium/content/browser/gpu/gpu_process_host.h
index 02146b16c88..3fb0c006fe2 100644
--- a/chromium/content/browser/gpu/gpu_process_host.h
+++ b/chromium/content/browser/gpu/gpu_process_host.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_
#define CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_
+#include <stdint.h>
+
#include <map>
#include <queue>
#include <set>
@@ -12,9 +14,11 @@
#include "base/callback.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/common/gpu/gpu_memory_uma_stats.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
@@ -30,20 +34,21 @@
#include "ui/gfx/native_widget_types.h"
#include "url/gurl.h"
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include "content/common/mac/io_surface_manager_token.h"
-#endif
-
struct GPUCreateCommandBufferConfig;
namespace IPC {
struct ChannelHandle;
}
+namespace gpu {
+struct SyncToken;
+}
+
namespace content {
class BrowserChildProcessHostImpl;
class GpuMainThread;
class InProcessChildThreadParams;
+class MojoApplicationHost;
class RenderWidgetHostViewFrameSubscriber;
class ShaderDiskCache;
@@ -69,6 +74,11 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
typedef base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)>
CreateGpuMemoryBufferCallback;
+#if defined(OS_CHROMEOS)
+ typedef base::Callback<void(const IPC::ChannelHandle&)>
+ CreateArcVideoAcceleratorChannelCallback;
+#endif
+
static bool gpu_enabled() { return gpu_enabled_; }
static int gpu_crash_count() { return gpu_crash_count_; }
@@ -131,13 +141,30 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
gfx::BufferFormat format,
gfx::BufferUsage usage,
int client_id,
- int32 surface_id,
+ int32_t surface_id,
const CreateGpuMemoryBufferCallback& callback);
+ // Tells the GPU process to create a new GPU memory buffer from an existing
+ // handle.
+ void CreateGpuMemoryBufferFromHandle(
+ const gfx::GpuMemoryBufferHandle& handle,
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ int client_id,
+ const CreateGpuMemoryBufferCallback& callback);
+
// Tells the GPU process to destroy GPU memory buffer.
void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
int client_id,
- int sync_point);
+ const gpu::SyncToken& sync_token);
+
+#if defined(OS_CHROMEOS)
+ // Tells the GPU process to create a new ipc channel for
+ // ArcVideoAccelerator.
+ void CreateArcVideoAcceleratorChannel(
+ const CreateArcVideoAcceleratorChannelCallback& callback);
+#endif
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
@@ -162,21 +189,26 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool Init();
+ // Sets up mojo support in GPU process. Returns false upon failure.
+ bool SetupMojo();
+
// Post an IPC message to the UI shim's message handler on the UI thread.
void RouteOnUIThread(const IPC::Message& message);
// BrowserChildProcessHostDelegate implementation.
bool OnMessageReceived(const IPC::Message& message) override;
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnProcessLaunched() override;
void OnProcessLaunchFailed() override;
void OnProcessCrashed(int exit_code) override;
+ ServiceRegistry* GetServiceRegistry() override;
// Message handlers.
void OnInitialized(bool result, const gpu::GPUInfo& gpu_info);
void OnChannelEstablished(const IPC::ChannelHandle& channel_handle);
void OnCommandBufferCreated(CreateCommandBufferResult result);
void OnGpuMemoryBufferCreated(const gfx::GpuMemoryBufferHandle& handle);
+ void OnArcVideoAcceleratorChannelCreated(const IPC::ChannelHandle& handle);
void OnDidCreateOffscreenContext(const GURL& url);
void OnDidLoseContext(bool offscreen,
gpu::error::ContextLostReason reason,
@@ -187,9 +219,16 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void OnAcceleratedSurfaceBuffersSwapped(const IPC::Message& message);
#endif
- void CreateChannelCache(int32 client_id);
- void OnDestroyChannel(int32 client_id);
- void OnCacheShader(int32 client_id, const std::string& key,
+#if defined(OS_WIN)
+ void OnAcceleratedSurfaceCreatedChildWindow(
+ const gfx::PluginWindowHandle& parent_handle,
+ const gfx::PluginWindowHandle& window_handle);
+#endif
+
+ void CreateChannelCache(int32_t client_id);
+ void OnDestroyChannel(int32_t client_id);
+ void OnCacheShader(int32_t client_id,
+ const std::string& key,
const std::string& shader);
bool LaunchGpuProcess(const std::string& channel_id);
@@ -216,6 +255,13 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// The pending create gpu memory buffer requests we need to reply to.
std::queue<CreateGpuMemoryBufferCallback> create_gpu_memory_buffer_requests_;
+#if defined(OS_CHROMEOS)
+ // The pending create arc video accelerator channel requests we need to reply
+ // to.
+ std::queue<CreateArcVideoAcceleratorChannelCallback>
+ create_arc_video_accelerator_channel_requests_;
+#endif
+
// Qeueud messages to send when the process launches.
std::queue<IPC::Message*> queued_messages_;
@@ -229,6 +275,10 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool swiftshader_rendering_;
GpuProcessKind kind_;
+ // The GPUInfo for the connected process. Only valid after initialized_ is
+ // true.
+ gpu::GPUInfo gpu_info_;
+
scoped_ptr<base::Thread> in_process_gpu_thread_;
// Whether we actually launched a GPU process.
@@ -265,17 +315,15 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool uma_memory_stats_received_;
GPUMemoryUmaStats uma_memory_stats_;
- typedef std::map<int32, scoped_refptr<ShaderDiskCache> >
+ typedef std::map<int32_t, scoped_refptr<ShaderDiskCache>>
ClientIdToShaderCacheMap;
ClientIdToShaderCacheMap client_id_to_shader_cache_;
std::string shader_prefix_key_;
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- // Unique unguessable token that the GPU process is using to register
- // IOSurfaces.
- IOSurfaceManagerToken io_surface_manager_token_;
-#endif
+ // Browser-side Mojo endpoint which sets up a Mojo channel with the child
+ // process and contains the browser's ServiceRegistry.
+ scoped_ptr<MojoApplicationHost> mojo_application_host_;
DISALLOW_COPY_AND_ASSIGN(GpuProcessHost);
};
diff --git a/chromium/content/browser/gpu/gpu_process_host_ui_shim.cc b/chromium/content/browser/gpu/gpu_process_host_ui_shim.cc
index 9fed072ae4a..083c99d457a 100644
--- a/chromium/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/chromium/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -12,6 +12,7 @@
#include "base/lazy_instance.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/compositor/gpu_process_transport_factory.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
@@ -42,13 +43,6 @@ namespace {
#undef DestroyAll
#endif
-#if defined(OS_MACOSX)
-void OnSurfaceDisplayedCallback(int output_surface_id) {
- content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed(
- output_surface_id);
-}
-#endif
-
base::LazyInstance<IDMap<GpuProcessHostUIShim> > g_hosts_by_id =
LAZY_INSTANCE_INITIALIZER;
@@ -246,20 +240,28 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
bool should_not_show_frame =
content::ImageTransportFactory::GetInstance()
->SurfaceShouldNotShowFramesAfterSuspendForRecycle(params.surface_id);
- if (should_not_show_frame) {
- OnSurfaceDisplayedCallback(params.surface_id);
- } else {
+ if (!should_not_show_frame) {
gfx::AcceleratedWidget native_widget =
content::GpuSurfaceTracker::Get()->AcquireNativeWidget(
params.surface_id);
- ui::AcceleratedWidgetMacGotAcceleratedFrame(
- native_widget, params.surface_handle, params.latency_info, params.size,
- params.scale_factor,
- params.damage_rect,
- base::Bind(&OnSurfaceDisplayedCallback, params.surface_id),
- &ack_params.disable_throttling, &ack_params.renderer_id,
- &ack_params.vsync_timebase, &ack_params.vsync_interval);
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
+ CAContextID ca_context_id = params.ca_context_id;
+
+ DCHECK((params.ca_context_id == 0) ^
+ (params.io_surface.get() == MACH_PORT_NULL));
+ if (params.io_surface.get()) {
+ io_surface.reset(IOSurfaceLookupFromMachPort(params.io_surface));
+ }
+
+ ui::AcceleratedWidgetMacGotFrame(native_widget, ca_context_id, io_surface,
+ params.size, params.scale_factor,
+ &ack_params.vsync_timebase,
+ &ack_params.vsync_interval);
}
+
+ content::ImageTransportFactory::GetInstance()->OnGpuSwapBuffersCompleted(
+ params.surface_id, params.latency_info, gfx::SwapResult::SWAP_ACK);
+
Send(new AcceleratedSurfaceMsg_BufferPresented(params.route_id, ack_params));
}
#endif
@@ -270,16 +272,16 @@ void GpuProcessHostUIShim::OnVideoMemoryUsageStatsReceived(
video_memory_usage_stats);
}
-void GpuProcessHostUIShim::OnAddSubscription(
- int32 process_id, unsigned int target) {
+void GpuProcessHostUIShim::OnAddSubscription(int32_t process_id,
+ unsigned int target) {
RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
if (rph) {
rph->OnAddSubscription(target);
}
}
-void GpuProcessHostUIShim::OnRemoveSubscription(
- int32 process_id, unsigned int target) {
+void GpuProcessHostUIShim::OnRemoveSubscription(int32_t process_id,
+ unsigned int target) {
RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
if (rph) {
rph->OnRemoveSubscription(target);
diff --git a/chromium/content/browser/gpu/gpu_process_host_ui_shim.h b/chromium/content/browser/gpu/gpu_process_host_ui_shim.h
index 12602092122..251ca2e7654 100644
--- a/chromium/content/browser/gpu/gpu_process_host_ui_shim.h
+++ b/chromium/content/browser/gpu/gpu_process_host_ui_shim.h
@@ -10,6 +10,8 @@
// portion of this class, the GpuProcessHost, is responsible for
// shuttling messages between the browser and GPU processes.
+#include <stdint.h>
+
#include <string>
#include "base/callback.h"
@@ -17,6 +19,7 @@
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/threading/non_thread_safe.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/common/message_router.h"
#include "content/public/common/gpu_memory_stats.h"
@@ -99,8 +102,8 @@ class GpuProcessHostUIShim : public IPC::Listener,
#endif
void OnVideoMemoryUsageStatsReceived(
const GPUVideoMemoryUsageStats& video_memory_usage_stats);
- void OnAddSubscription(int32 process_id, unsigned int target);
- void OnRemoveSubscription(int32 process_id, unsigned int target);
+ void OnAddSubscription(int32_t process_id, unsigned int target);
+ void OnRemoveSubscription(int32_t process_id, unsigned int target);
// The serial number of the GpuProcessHost / GpuProcessHostUIShim pair.
int host_id_;
diff --git a/chromium/content/browser/gpu/gpu_surface_tracker.cc b/chromium/content/browser/gpu/gpu_surface_tracker.cc
index 721b4d5e7d6..bd4e91dc261 100644
--- a/chromium/content/browser/gpu/gpu_surface_tracker.cc
+++ b/chromium/content/browser/gpu/gpu_surface_tracker.cc
@@ -4,12 +4,13 @@
#include "content/browser/gpu/gpu_surface_tracker.h"
+#include "base/logging.h"
+#include "build/build_config.h"
+
#if defined(OS_ANDROID)
#include <android/native_window_jni.h>
#endif // defined(OS_ANDROID)
-#include "base/logging.h"
-
namespace content {
GpuSurfaceTracker::GpuSurfaceTracker()
diff --git a/chromium/content/browser/gpu/gpu_surface_tracker.h b/chromium/content/browser/gpu/gpu_surface_tracker.h
index 01f16d64d5f..386eeeae7c4 100644
--- a/chromium/content/browser/gpu/gpu_surface_tracker.h
+++ b/chromium/content/browser/gpu/gpu_surface_tracker.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_GPU_GPU_SURFACE_TRACKER_H_
#define CONTENT_BROWSER_GPU_GPU_SURFACE_TRACKER_H_
+#include <stddef.h>
+
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
diff --git a/chromium/content/browser/gpu/shader_disk_cache.cc b/chromium/content/browser/gpu/shader_disk_cache.cc
index 28af40385d8..c582829f5ed 100644
--- a/chromium/content/browser/gpu/shader_disk_cache.cc
+++ b/chromium/content/browser/gpu/shader_disk_cache.cc
@@ -4,6 +4,7 @@
#include "content/browser/gpu/shader_disk_cache.h"
+#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/browser_thread.h"
@@ -426,16 +427,16 @@ ShaderCacheFactory::ShaderCacheFactory() {
ShaderCacheFactory::~ShaderCacheFactory() {
}
-void ShaderCacheFactory::SetCacheInfo(int32 client_id,
+void ShaderCacheFactory::SetCacheInfo(int32_t client_id,
const base::FilePath& path) {
client_id_to_path_map_[client_id] = path;
}
-void ShaderCacheFactory::RemoveCacheInfo(int32 client_id) {
+void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) {
client_id_to_path_map_.erase(client_id);
}
-scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32 client_id) {
+scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) {
ClientIdToPathMap::iterator iter =
client_id_to_path_map_.find(client_id);
if (iter == client_id_to_path_map_.end())
@@ -569,7 +570,7 @@ int ShaderDiskCache::Clear(
return rv;
}
-int32 ShaderDiskCache::Size() {
+int32_t ShaderDiskCache::Size() {
if (!cache_available_)
return -1;
return backend_->GetEntryCount();
diff --git a/chromium/content/browser/gpu/shader_disk_cache.h b/chromium/content/browser/gpu/shader_disk_cache.h
index 9b16dd30a15..e53cb505438 100644
--- a/chromium/content/browser/gpu/shader_disk_cache.h
+++ b/chromium/content/browser/gpu/shader_disk_cache.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_
#define CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_
+#include <stdint.h>
+
#include <map>
#include <queue>
#include <string>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "content/common/content_export.h"
@@ -55,7 +58,7 @@ class CONTENT_EXPORT ShaderDiskCache
int SetAvailableCallback(const net::CompletionCallback& callback);
// Returns the number of elements currently in the cache.
- int32 Size();
+ int32_t Size();
// Set a callback notification for when all current entries have been
// written to the cache.
@@ -111,13 +114,13 @@ class CONTENT_EXPORT ShaderCacheFactory {
const base::Closure& callback);
// Retrieve the shader disk cache for the provided |client_id|.
- scoped_refptr<ShaderDiskCache> Get(int32 client_id);
+ scoped_refptr<ShaderDiskCache> Get(int32_t client_id);
// Set the |path| to be used for the disk cache for |client_id|.
- void SetCacheInfo(int32 client_id, const base::FilePath& path);
+ void SetCacheInfo(int32_t client_id, const base::FilePath& path);
// Remove the path mapping for |client_id|.
- void RemoveCacheInfo(int32 client_id);
+ void RemoveCacheInfo(int32_t client_id);
// Set the provided |cache| into the cache map for the given |path|.
void AddToCache(const base::FilePath& path, ShaderDiskCache* cache);
@@ -138,7 +141,7 @@ class CONTENT_EXPORT ShaderCacheFactory {
typedef std::map<base::FilePath, ShaderDiskCache*> ShaderCacheMap;
ShaderCacheMap shader_cache_map_;
- typedef std::map<int32, base::FilePath> ClientIdToPathMap;
+ typedef std::map<int32_t, base::FilePath> ClientIdToPathMap;
ClientIdToPathMap client_id_to_path_map_;
typedef std::queue<scoped_refptr<ShaderClearHelper> > ShaderClearQueue;
diff --git a/chromium/content/browser/gpu/shader_disk_cache_unittest.cc b/chromium/content/browser/gpu/shader_disk_cache_unittest.cc
index 15894ef6713..826cf50ead4 100644
--- a/chromium/content/browser/gpu/shader_disk_cache_unittest.cc
+++ b/chromium/content/browser/gpu/shader_disk_cache_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/threading/thread.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/gpu/shader_disk_cache.h"
diff --git a/chromium/content/browser/gpu/test_support_gpu.gypi b/chromium/content/browser/gpu/test_support_gpu.gypi
index 7c4beaa24e5..73f87eec63b 100644
--- a/chromium/content/browser/gpu/test_support_gpu.gypi
+++ b/chromium/content/browser/gpu/test_support_gpu.gypi
@@ -25,13 +25,6 @@
'include_dirs': [
'<(DEPTH)/third_party/wtl/include',
],
- 'conditions': [
- ['win_use_allocator_shim==1', {
- 'dependencies': [
- '../base/allocator/allocator.gyp:allocator',
- ],
- }],
- ],
'configurations': {
'Debug': {
'msvs_settings': {
diff --git a/chromium/content/browser/histogram_controller.h b/chromium/content/browser/histogram_controller.h
index 884df8aeee4..1fa319ea5f4 100644
--- a/chromium/content/browser/histogram_controller.h
+++ b/chromium/content/browser/histogram_controller.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/singleton.h"
namespace content {
diff --git a/chromium/content/browser/histogram_internals_request_job.h b/chromium/content/browser/histogram_internals_request_job.h
index 6304198477d..63ce622e405 100644
--- a/chromium/content/browser/histogram_internals_request_job.h
+++ b/chromium/content/browser/histogram_internals_request_job.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/url_request/url_request_simple_job.h"
namespace content {
diff --git a/chromium/content/browser/histogram_message_filter.cc b/chromium/content/browser/histogram_message_filter.cc
index a93a309387a..5c074a26b8d 100644
--- a/chromium/content/browser/histogram_message_filter.cc
+++ b/chromium/content/browser/histogram_message_filter.cc
@@ -8,7 +8,6 @@
#include "base/metrics/histogram.h"
#include "base/metrics/statistics_recorder.h"
#include "content/browser/histogram_controller.h"
-#include "content/browser/tcmalloc_internals_request_job.h"
#include "content/common/child_process_messages.h"
#include "content/public/common/content_switches.h"
diff --git a/chromium/content/browser/histogram_message_filter.h b/chromium/content/browser/histogram_message_filter.h
index 25fa6767b91..2829859e27c 100644
--- a/chromium/content/browser/histogram_message_filter.h
+++ b/chromium/content/browser/histogram_message_filter.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/common/process_type.h"
diff --git a/chromium/content/browser/histogram_synchronizer.h b/chromium/content/browser/histogram_synchronizer.h
index d4d6f368c82..4180c24f994 100644
--- a/chromium/content/browser/histogram_synchronizer.h
+++ b/chromium/content/browser/histogram_synchronizer.h
@@ -8,8 +8,8 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
diff --git a/chromium/content/browser/host_zoom_level_context.cc b/chromium/content/browser/host_zoom_level_context.cc
index 02ddcf55d3c..56f848db613 100644
--- a/chromium/content/browser/host_zoom_level_context.cc
+++ b/chromium/content/browser/host_zoom_level_context.cc
@@ -4,6 +4,8 @@
#include "content/browser/host_zoom_level_context.h"
+#include <utility>
+
#include "base/files/file_path.h"
#include "content/browser/host_zoom_map_impl.h"
#include "content/public/browser/browser_thread.h"
@@ -13,7 +15,7 @@ namespace content {
HostZoomLevelContext::HostZoomLevelContext(
scoped_ptr<ZoomLevelDelegate> zoom_level_delegate)
: host_zoom_map_impl_(new HostZoomMapImpl()),
- zoom_level_delegate_(zoom_level_delegate.Pass()) {
+ zoom_level_delegate_(std::move(zoom_level_delegate)) {
if (zoom_level_delegate_)
zoom_level_delegate_->InitHostZoomMap(host_zoom_map_impl_.get());
}
diff --git a/chromium/content/browser/host_zoom_map_impl.cc b/chromium/content/browser/host_zoom_map_impl.cc
index 2c1c5ec3e8d..cb394f81cbe 100644
--- a/chromium/content/browser/host_zoom_map_impl.cc
+++ b/chromium/content/browser/host_zoom_map_impl.cc
@@ -75,6 +75,8 @@ HostZoomMap* HostZoomMap::Get(SiteInstance* instance) {
}
HostZoomMap* HostZoomMap::GetForWebContents(const WebContents* contents) {
+ // TODO(wjmaclean): Update this behaviour to work with OOPIF.
+ // See crbug.com/528407.
StoragePartition* partition =
BrowserContext::GetStoragePartition(contents->GetBrowserContext(),
contents->GetSiteInstance());
diff --git a/chromium/content/browser/host_zoom_map_impl.h b/chromium/content/browser/host_zoom_map_impl.h
index a9b2a45d3ef..e27402d5c6f 100644
--- a/chromium/content/browser/host_zoom_map_impl.h
+++ b/chromium/content/browser/host_zoom_map_impl.h
@@ -7,9 +7,11 @@
#include <map>
#include <string>
+#include <tuple>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/sequenced_task_runner_helpers.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/host_zoom_map.h"
@@ -112,9 +114,8 @@ class CONTENT_EXPORT HostZoomMapImpl : public NON_EXPORTED_BASE(HostZoomMap),
: render_process_id(render_process_id),
render_view_id(render_view_id) {}
bool operator<(const RenderViewKey& other) const {
- return render_process_id < other.render_process_id ||
- ((render_process_id == other.render_process_id) &&
- (render_view_id < other.render_view_id));
+ return std::tie(render_process_id, render_view_id) <
+ std::tie(other.render_process_id, other.render_view_id);
}
};
diff --git a/chromium/content/browser/host_zoom_map_impl_unittest.cc b/chromium/content/browser/host_zoom_map_impl_unittest.cc
index a96f15e288a..2901e16d7a0 100644
--- a/chromium/content/browser/host_zoom_map_impl_unittest.cc
+++ b/chromium/content/browser/host_zoom_map_impl_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/host_zoom_map_impl.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "content/public/browser/browser_thread.h"
diff --git a/chromium/content/browser/in_process_io_surface_manager_mac.cc b/chromium/content/browser/in_process_io_surface_manager_mac.cc
deleted file mode 100644
index 0ae8103e629..00000000000
--- a/chromium/content/browser/in_process_io_surface_manager_mac.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/in_process_io_surface_manager_mac.h"
-
-#include "base/logging.h"
-
-namespace content {
-
-// static
-InProcessIOSurfaceManager* InProcessIOSurfaceManager::GetInstance() {
- return base::Singleton<
- InProcessIOSurfaceManager,
- base::LeakySingletonTraits<InProcessIOSurfaceManager>>::get();
-}
-
-bool InProcessIOSurfaceManager::RegisterIOSurface(IOSurfaceId io_surface_id,
- int client_id,
- IOSurfaceRef io_surface) {
- base::AutoLock lock(lock_);
-
- DCHECK(io_surfaces_.find(io_surface_id) == io_surfaces_.end());
- io_surfaces_.add(io_surface_id,
- make_scoped_ptr(new base::mac::ScopedMachSendRight(
- IOSurfaceCreateMachPort(io_surface))));
- return true;
-}
-
-void InProcessIOSurfaceManager::UnregisterIOSurface(IOSurfaceId io_surface_id,
- int client_id) {
- base::AutoLock lock(lock_);
-
- DCHECK(io_surfaces_.find(io_surface_id) != io_surfaces_.end());
- io_surfaces_.erase(io_surface_id);
-}
-
-IOSurfaceRef InProcessIOSurfaceManager::AcquireIOSurface(
- IOSurfaceId io_surface_id) {
- base::AutoLock lock(lock_);
-
- DCHECK(io_surfaces_.find(io_surface_id) != io_surfaces_.end());
- return IOSurfaceLookupFromMachPort(io_surfaces_.get(io_surface_id)->get());
-}
-
-InProcessIOSurfaceManager::InProcessIOSurfaceManager() {
-}
-
-InProcessIOSurfaceManager::~InProcessIOSurfaceManager() {
-}
-
-} // namespace content
diff --git a/chromium/content/browser/in_process_io_surface_manager_mac.h b/chromium/content/browser/in_process_io_surface_manager_mac.h
deleted file mode 100644
index d2ef45a6623..00000000000
--- a/chromium/content/browser/in_process_io_surface_manager_mac.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_IN_PROCESS_IO_SURFACE_MANAGER_MAC_H_
-#define CONTENT_BROWSER_IN_PROCESS_IO_SURFACE_MANAGER_MAC_H_
-
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/mac/scoped_mach_port.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/singleton.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/common/mac/io_surface_manager.h"
-
-namespace content {
-
-class CONTENT_EXPORT InProcessIOSurfaceManager : public IOSurfaceManager {
- public:
- static InProcessIOSurfaceManager* GetInstance();
-
- // Overridden from IOSurfaceManager:
- bool RegisterIOSurface(IOSurfaceId io_surface_id,
- int client_id,
- IOSurfaceRef io_surface) override;
- void UnregisterIOSurface(IOSurfaceId io_surface_id, int client_id) override;
- IOSurfaceRef AcquireIOSurface(IOSurfaceId io_surface_id) override;
-
- private:
- friend struct base::DefaultSingletonTraits<InProcessIOSurfaceManager>;
-
- InProcessIOSurfaceManager();
- ~InProcessIOSurfaceManager() override;
-
- using IOSurfaceMap =
- base::ScopedPtrHashMap<IOSurfaceId,
- scoped_ptr<base::mac::ScopedMachSendRight>>;
- IOSurfaceMap io_surfaces_;
- base::Lock lock_;
-
- DISALLOW_COPY_AND_ASSIGN(InProcessIOSurfaceManager);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_IN_PROCESS_IO_SURFACE_MANAGER_MAC_H_
diff --git a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc
index 7bda0bbb3ec..2a1131f92c0 100644
--- a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc
@@ -20,8 +20,8 @@ IndexedDBActiveBlobRegistry::IndexedDBActiveBlobRegistry(
IndexedDBActiveBlobRegistry::~IndexedDBActiveBlobRegistry() {
}
-void IndexedDBActiveBlobRegistry::AddBlobRef(int64 database_id,
- int64 blob_key) {
+void IndexedDBActiveBlobRegistry::AddBlobRef(int64_t database_id,
+ int64_t blob_key) {
DCHECK(backing_store_);
DCHECK(backing_store_->task_runner()->RunsTasksOnCurrentThread());
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
@@ -42,8 +42,8 @@ void IndexedDBActiveBlobRegistry::AddBlobRef(int64 database_id,
}
}
-void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64 database_id,
- int64 blob_key) {
+void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id,
+ int64_t blob_key) {
DCHECK(backing_store_);
DCHECK(backing_store_->task_runner()->RunsTasksOnCurrentThread());
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
@@ -82,8 +82,8 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64 database_id,
}
}
-bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64 database_id,
- int64 blob_key) {
+bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id,
+ int64_t blob_key) {
DCHECK(backing_store_);
DCHECK(backing_store_->task_runner()->RunsTasksOnCurrentThread());
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
@@ -108,8 +108,8 @@ bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64 database_id,
void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe(
scoped_refptr<base::TaskRunner> task_runner,
base::WeakPtr<IndexedDBActiveBlobRegistry> weak_ptr,
- int64 database_id,
- int64 blob_key,
+ int64_t database_id,
+ int64_t blob_key,
const base::FilePath& unused) {
task_runner->PostTask(FROM_HERE,
base::Bind(&IndexedDBActiveBlobRegistry::ReleaseBlobRef,
@@ -119,8 +119,8 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe(
}
storage::ShareableFileReference::FinalReleaseCallback
-IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64 database_id,
- int64 blob_key) {
+IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64_t database_id,
+ int64_t blob_key) {
return base::Bind(
&IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe,
scoped_refptr<base::TaskRunner>(backing_store_->task_runner()),
@@ -130,8 +130,8 @@ IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64 database_id,
}
base::Closure IndexedDBActiveBlobRegistry::GetAddBlobRefCallback(
- int64 database_id,
- int64 blob_key) {
+ int64_t database_id,
+ int64_t blob_key) {
return base::Bind(&IndexedDBActiveBlobRegistry::AddBlobRef,
weak_factory_.GetWeakPtr(),
database_id,
diff --git a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.h b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.h
index 8f78f191b69..e94fef616bd 100644
--- a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.h
+++ b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_ACTIVE_BLOB_REGISTRY_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_ACTIVE_BLOB_REGISTRY_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <utility>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "storage/browser/blob/shareable_file_reference.h"
@@ -29,14 +31,14 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
// which just calls ReleaseBlobRefThreadSafe.
// Use DatabaseMetaDataKey::AllBlobsKey for "the whole database".
- bool MarkDeletedCheckIfUsed(int64 database_id, int64 blob_key);
+ bool MarkDeletedCheckIfUsed(int64_t database_id, int64_t blob_key);
storage::ShareableFileReference::FinalReleaseCallback GetFinalReleaseCallback(
- int64 database_id,
- int64 blob_key);
+ int64_t database_id,
+ int64_t blob_key);
// This closure holds a raw pointer to the IndexedDBActiveBlobRegistry,
// and may not be called after it is deleted.
- base::Closure GetAddBlobRefCallback(int64 database_id, int64 blob_key);
+ base::Closure GetAddBlobRefCallback(int64_t database_id, int64_t blob_key);
// Call this to force the registry to drop its use counts, permitting the
// factory to drop any blob-related refcount for the backing store.
// This will also turn any outstanding callbacks into no-ops.
@@ -45,18 +47,18 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
private:
// Maps blob_key -> IsDeleted; if the record's absent, it's not in active use
// and we don't care if it's deleted.
- typedef std::map<int64, bool> SingleDBMap;
+ typedef std::map<int64_t, bool> SingleDBMap;
// Maps DB ID -> SingleDBMap
- typedef std::map<int64, SingleDBMap> AllDBsMap;
- typedef std::set<int64> DeletedDBSet;
+ typedef std::map<int64_t, SingleDBMap> AllDBsMap;
+ typedef std::set<int64_t> DeletedDBSet;
- void AddBlobRef(int64 database_id, int64 blob_key);
- void ReleaseBlobRef(int64 database_id, int64 blob_key);
+ void AddBlobRef(int64_t database_id, int64_t blob_key);
+ void ReleaseBlobRef(int64_t database_id, int64_t blob_key);
static void ReleaseBlobRefThreadSafe(
scoped_refptr<base::TaskRunner> task_runner,
base::WeakPtr<IndexedDBActiveBlobRegistry> weak_ptr,
- int64 database_id,
- int64 blob_key,
+ int64_t database_id,
+ int64_t blob_key,
const base::FilePath& unused);
AllDBsMap use_tracker_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc
index aa412cf0908..3d6023fc707 100644
--- a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <set>
+#include "base/macros.h"
#include "base/test/test_simple_task_runner.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
@@ -55,7 +58,7 @@ class RegistryTestMockFactory : public MockIndexedDBFactory {
class MockIDBBackingStore : public IndexedDBFakeBackingStore {
public:
- typedef std::pair<int64, int64> KeyPair;
+ typedef std::pair<int64_t, int64_t> KeyPair;
typedef std::set<KeyPair> KeyPairSet;
MockIDBBackingStore(IndexedDBFactory* factory,
@@ -63,14 +66,14 @@ class MockIDBBackingStore : public IndexedDBFakeBackingStore {
: IndexedDBFakeBackingStore(factory, task_runner),
duplicate_calls_(false) {}
- void ReportBlobUnused(int64 database_id, int64 blob_key) override {
+ void ReportBlobUnused(int64_t database_id, int64_t blob_key) override {
unused_blobs_.insert(std::make_pair(database_id, blob_key));
}
bool CheckUnusedBlobsEmpty() const {
return !duplicate_calls_ && !unused_blobs_.size();
}
- bool CheckSingleUnusedBlob(int64 database_id, int64 blob_key) const {
+ bool CheckSingleUnusedBlob(int64_t database_id, int64_t blob_key) const {
return !duplicate_calls_ && unused_blobs_.size() == 1 &&
unused_blobs_.count(std::make_pair(database_id, blob_key));
}
@@ -93,10 +96,10 @@ class IndexedDBActiveBlobRegistryTest : public testing::Test {
typedef storage::ShareableFileReference::FinalReleaseCallback
ReleaseCallback;
- static const int64 kDatabaseId0 = 7;
- static const int64 kDatabaseId1 = 12;
- static const int64 kBlobKey0 = 77;
- static const int64 kBlobKey1 = 14;
+ static const int64_t kDatabaseId0 = 7;
+ static const int64_t kDatabaseId1 = 12;
+ static const int64_t kBlobKey0 = 77;
+ static const int64_t kBlobKey1 = 14;
IndexedDBActiveBlobRegistryTest()
: task_runner_(new base::TestSimpleTaskRunner),
diff --git a/chromium/content/browser/indexed_db/indexed_db_backing_store.cc b/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
index 7eb73aaafc5..e3816d4d37a 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -5,6 +5,7 @@
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include <algorithm>
+#include <utility>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -12,10 +13,12 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/indexed_db/indexed_db_blob_info.h"
#include "content/browser/indexed_db/indexed_db_class_factory.h"
@@ -53,13 +56,13 @@ namespace content {
namespace {
-FilePath GetBlobDirectoryName(const FilePath& path_base, int64 database_id) {
+FilePath GetBlobDirectoryName(const FilePath& path_base, int64_t database_id) {
return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id));
}
FilePath GetBlobDirectoryNameForKey(const FilePath& path_base,
- int64 database_id,
- int64 key) {
+ int64_t database_id,
+ int64_t key) {
FilePath path = GetBlobDirectoryName(path_base, database_id);
path = path.AppendASCII(base::StringPrintf(
"%02x", static_cast<int>(key & 0x000000000000ff00) >> 8));
@@ -67,16 +70,16 @@ FilePath GetBlobDirectoryNameForKey(const FilePath& path_base,
}
FilePath GetBlobFileNameForKey(const FilePath& path_base,
- int64 database_id,
- int64 key) {
+ int64_t database_id,
+ int64_t key) {
FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key);
path = path.AppendASCII(base::StringPrintf("%" PRIx64, key));
return path;
}
bool MakeIDBBlobDirectory(const FilePath& path_base,
- int64 database_id,
- int64 key) {
+ int64_t database_id,
+ int64_t key) {
FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key);
return base::CreateDirectory(path);
}
@@ -104,7 +107,7 @@ static base::FilePath ComputeCorruptionFileName(const GURL& origin_url) {
} // namespace
-static const int64 kKeyGeneratorInitialNumber =
+static const int64_t kKeyGeneratorInitialNumber =
1; // From the IndexedDB specification.
enum IndexedDBBackingStoreErrorSource {
@@ -209,7 +212,7 @@ static leveldb::Status IOErrorStatus() {
template <typename DBOrTransaction>
static leveldb::Status GetInt(DBOrTransaction* db,
const StringPiece& key,
- int64* found_int,
+ int64_t* found_int,
bool* found) {
std::string result;
leveldb::Status s = db->Get(key, &result, found);
@@ -225,7 +228,7 @@ static leveldb::Status GetInt(DBOrTransaction* db,
static void PutInt(LevelDBTransaction* transaction,
const StringPiece& key,
- int64 value) {
+ int64_t value) {
DCHECK_GE(value, 0);
std::string buffer;
EncodeInt(value, &buffer);
@@ -235,7 +238,7 @@ static void PutInt(LevelDBTransaction* transaction,
template <typename DBOrTransaction>
WARN_UNUSED_RESULT static leveldb::Status GetVarInt(DBOrTransaction* db,
const StringPiece& key,
- int64* found_int,
+ int64_t* found_int,
bool* found) {
std::string result;
leveldb::Status s = db->Get(key, &result, found);
@@ -251,7 +254,7 @@ WARN_UNUSED_RESULT static leveldb::Status GetVarInt(DBOrTransaction* db,
static void PutVarInt(LevelDBTransaction* transaction,
const StringPiece& key,
- int64 value) {
+ int64_t value) {
std::string buffer;
EncodeVarInt(value, &buffer);
transaction->Put(key, &buffer);
@@ -313,9 +316,9 @@ const char* IndexedDBBackingStore::Comparator::Name() const {
// 1 - Adds UserIntVersion to DatabaseMetaData.
// 2 - Adds DataVersion to to global metadata.
// 3 - Adds metadata needed for blob support.
-static const int64 kLatestKnownSchemaVersion = 3;
+static const int64_t kLatestKnownSchemaVersion = 3;
WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) {
- int64 db_schema_version = 0;
+ int64_t db_schema_version = 0;
bool found = false;
leveldb::Status s =
GetInt(db, SchemaVersionKey::Encode(), &db_schema_version, &found);
@@ -325,14 +328,16 @@ WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) {
*known = true;
return true;
}
+ if (db_schema_version < 0)
+ return false; // Only corruption should cause this.
if (db_schema_version > kLatestKnownSchemaVersion) {
*known = false;
return true;
}
- const uint32 latest_known_data_version =
+ const uint32_t latest_known_data_version =
blink::kSerializedScriptValueVersion;
- int64 db_data_version = 0;
+ int64_t db_data_version = 0;
s = GetInt(db, DataVersionKey::Encode(), &db_data_version, &found);
if (!s.ok())
return false;
@@ -340,7 +345,8 @@ WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) {
*known = true;
return true;
}
-
+ if (db_data_version < 0)
+ return false; // Only corruption should cause this.
if (db_data_version > latest_known_data_version) {
*known = false;
return true;
@@ -353,7 +359,7 @@ WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) {
// TODO(ericu): Move this down into the member section of this file. I'm
// leaving it here for this CL as it's easier to see the diffs in place.
WARN_UNUSED_RESULT leveldb::Status IndexedDBBackingStore::SetUpMetadata() {
- const uint32 latest_known_data_version =
+ const uint32_t latest_known_data_version =
blink::kSerializedScriptValueVersion;
const std::string schema_version_key = SchemaVersionKey::Encode();
const std::string data_version_key = DataVersionKey::Encode();
@@ -361,8 +367,8 @@ WARN_UNUSED_RESULT leveldb::Status IndexedDBBackingStore::SetUpMetadata() {
scoped_refptr<LevelDBTransaction> transaction =
IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
- int64 db_schema_version = 0;
- int64 db_data_version = 0;
+ int64_t db_schema_version = 0;
+ int64_t db_data_version = 0;
bool found = false;
leveldb::Status s =
GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
@@ -396,7 +402,7 @@ WARN_UNUSED_RESULT leveldb::Status IndexedDBBackingStore::SetUpMetadata() {
for (s = it->Seek(start_key);
s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
s = it->Next()) {
- int64 database_id = 0;
+ int64_t database_id = 0;
found = false;
s = GetInt(transaction.get(), it->Key(), &database_id, &found);
if (!s.ok()) {
@@ -462,8 +468,8 @@ WARN_UNUSED_RESULT leveldb::Status IndexedDBBackingStore::SetUpMetadata() {
template <typename DBOrTransaction>
WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId(
DBOrTransaction* db,
- int64 database_id,
- int64* max_object_store_id) {
+ int64_t database_id,
+ int64_t* max_object_store_id) {
const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode(
database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID);
return GetMaxObjectStoreId(db, max_object_store_id_key, max_object_store_id);
@@ -473,7 +479,7 @@ template <typename DBOrTransaction>
WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId(
DBOrTransaction* db,
const std::string& max_object_store_id_key,
- int64* max_object_store_id) {
+ int64_t* max_object_store_id) {
*max_object_store_id = -1;
bool found = false;
leveldb::Status s =
@@ -506,13 +512,13 @@ class DefaultLevelDBFactory : public LevelDBFactory {
static bool GetBlobKeyGeneratorCurrentNumber(
LevelDBTransaction* leveldb_transaction,
- int64 database_id,
- int64* blob_key_generator_current_number) {
+ int64_t database_id,
+ int64_t* blob_key_generator_current_number) {
const std::string key_gen_key = DatabaseMetaDataKey::Encode(
database_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER);
// Default to initial number if not found.
- int64 cur_number = DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber;
+ int64_t cur_number = DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber;
std::string data;
bool found = false;
@@ -535,10 +541,10 @@ static bool GetBlobKeyGeneratorCurrentNumber(
static bool UpdateBlobKeyGeneratorCurrentNumber(
LevelDBTransaction* leveldb_transaction,
- int64 database_id,
- int64 blob_key_generator_current_number) {
+ int64_t database_id,
+ int64_t blob_key_generator_current_number) {
#ifndef NDEBUG
- int64 old_number;
+ int64_t old_number;
if (!GetBlobKeyGeneratorCurrentNumber(
leveldb_transaction, database_id, &old_number))
return false;
@@ -666,7 +672,7 @@ static leveldb::Status AppendBlobsToLiveBlobJournal(
static leveldb::Status MergeDatabaseIntoBlobJournal(
LevelDBDirectTransaction* transaction,
const std::string& key,
- int64 database_id) {
+ int64_t database_id) {
IDB_TRACE("IndexedDBBackingStore::MergeDatabaseIntoBlobJournal");
BlobJournalType journal;
leveldb::Status s = GetBlobJournal(key, transaction, &journal);
@@ -680,22 +686,22 @@ static leveldb::Status MergeDatabaseIntoBlobJournal(
static leveldb::Status MergeDatabaseIntoPrimaryBlobJournal(
LevelDBDirectTransaction* leveldb_transaction,
- int64 database_id) {
+ int64_t database_id) {
return MergeDatabaseIntoBlobJournal(leveldb_transaction,
BlobJournalKey::Encode(), database_id);
}
static leveldb::Status MergeDatabaseIntoLiveBlobJournal(
LevelDBDirectTransaction* leveldb_transaction,
- int64 database_id) {
+ int64_t database_id) {
return MergeDatabaseIntoBlobJournal(
leveldb_transaction, LiveBlobJournalKey::Encode(), database_id);
}
// Blob Data is encoded as a series of:
-// { is_file [bool], key [int64 as varInt],
+// { is_file [bool], key [int64_t as varInt],
// type [string-with-length, may be empty],
-// (for Blobs only) size [int64 as varInt]
+// (for Blobs only) size [int64_t as varInt]
// (for Files only) fileName [string-with-length]
// }
// There is no length field; just read until you run out of data.
@@ -721,9 +727,9 @@ static bool DecodeBlobData(const std::string& data,
StringPiece slice(data);
while (!slice.empty()) {
bool is_file;
- int64 key;
+ int64_t key;
base::string16 type;
- int64 size;
+ int64_t size;
base::string16 file_name;
if (!DecodeBool(&slice, &is_file))
@@ -740,7 +746,7 @@ static bool DecodeBlobData(const std::string& data,
} else {
if (!DecodeVarInt(&slice, &size) || size < 0)
return false;
- ret.push_back(IndexedDBBlobInfo(type, static_cast<uint64>(size), key));
+ ret.push_back(IndexedDBBlobInfo(type, static_cast<uint64_t>(size), key));
}
}
output->swap(ret);
@@ -762,11 +768,10 @@ IndexedDBBackingStore::IndexedDBBackingStore(
origin_identifier_(ComputeOriginIdentifier(origin_url)),
request_context_(request_context),
task_runner_(task_runner),
- db_(db.Pass()),
- comparator_(comparator.Pass()),
+ db_(std::move(db)),
+ comparator_(std::move(comparator)),
active_blob_registry_(this),
- committing_transaction_count_(0) {
-}
+ committing_transaction_count_(0) {}
IndexedDBBackingStore::~IndexedDBBackingStore() {
if (!blob_path_.empty() && !child_process_ids_granted_.empty()) {
@@ -784,7 +789,7 @@ IndexedDBBackingStore::~IndexedDBBackingStore() {
IndexedDBBackingStore::RecordIdentifier::RecordIdentifier(
const std::string& primary_key,
- int64 version)
+ int64_t version)
: primary_key_(primary_key), version_(version) {
DCHECK(!primary_key.empty());
}
@@ -917,8 +922,8 @@ bool IndexedDBBackingStore::ReadCorruptionInfo(const base::FilePath& path_base,
if (IsPathTooLong(info_path))
return false;
- const int64 max_json_len = 4096;
- int64 file_size(0);
+ const int64_t max_json_len = 4096;
+ int64_t file_size(0);
if (!GetFileSize(info_path, &file_size) || file_size > max_json_len)
return false;
if (!file_size) {
@@ -1087,8 +1092,10 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
}
LOG(ERROR) << "IndexedDB backing store cleanup succeeded, reopening";
- leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, NULL);
- if (!db) {
+ *status =
+ leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, NULL);
+ if (!status->ok()) {
+ DCHECK(!db);
LOG(ERROR) << "IndexedDB backing store reopen after recovery failed";
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED,
origin_url);
@@ -1099,20 +1106,17 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
}
scoped_refptr<IndexedDBBackingStore> backing_store =
- Create(indexed_db_factory,
- origin_url,
- blob_path,
- request_context,
- db.Pass(),
- comparator.Pass(),
- task_runner,
- status);
-
- if (clean_journal && backing_store.get() &&
- !backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()).ok()) {
- HistogramOpenStatus(
- INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, origin_url);
- return scoped_refptr<IndexedDBBackingStore>();
+ Create(indexed_db_factory, origin_url, blob_path, request_context,
+ std::move(db), std::move(comparator), task_runner, status);
+
+ if (clean_journal && backing_store.get()) {
+ *status = backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode());
+ if (!status->ok()) {
+ HistogramOpenStatus(
+ INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR,
+ origin_url);
+ return scoped_refptr<IndexedDBBackingStore>();
+ }
}
return backing_store;
}
@@ -1146,14 +1150,9 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
}
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS, origin_url);
- return Create(NULL /* indexed_db_factory */,
- origin_url,
- base::FilePath(),
- NULL /* request_context */,
- db.Pass(),
- comparator.Pass(),
- task_runner,
- status);
+ return Create(NULL /* indexed_db_factory */, origin_url, base::FilePath(),
+ NULL /* request_context */, std::move(db),
+ std::move(comparator), task_runner, status);
}
// static
@@ -1167,14 +1166,9 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create(
base::SequencedTaskRunner* task_runner,
leveldb::Status* status) {
// TODO(jsbell): Handle comparator name changes.
- scoped_refptr<IndexedDBBackingStore> backing_store(
- new IndexedDBBackingStore(indexed_db_factory,
- origin_url,
- blob_path,
- request_context,
- db.Pass(),
- comparator.Pass(),
- task_runner));
+ scoped_refptr<IndexedDBBackingStore> backing_store(new IndexedDBBackingStore(
+ indexed_db_factory, origin_url, blob_path, request_context, std::move(db),
+ std::move(comparator), task_runner));
*status = backing_store->SetUpMetadata();
if (!status->ok())
return scoped_refptr<IndexedDBBackingStore>();
@@ -1215,7 +1209,7 @@ std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames(
}
// Decode database id (in iterator value).
- int64 database_id = 0;
+ int64_t database_id = 0;
StringPiece value_slice(it->Value());
if (!DecodeInt(&value_slice, &database_id) || !value_slice.empty()) {
INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES);
@@ -1224,7 +1218,7 @@ std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames(
// Look up version by id.
bool found = false;
- int64 database_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
+ int64_t database_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
*s = GetVarInt(db_.get(),
DatabaseMetaDataKey::Encode(
database_id, DatabaseMetaDataKey::USER_INT_VERSION),
@@ -1299,7 +1293,7 @@ leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData(
}
// We don't cache this, we just check it if it's there.
- int64 blob_key_generator_current_number =
+ int64_t blob_key_generator_current_number =
DatabaseMetaDataKey::kInvalidBlobKey;
s = GetVarInt(
@@ -1326,9 +1320,9 @@ leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData(
WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId(
LevelDBTransaction* transaction,
- int64* new_id) {
+ int64_t* new_id) {
*new_id = -1;
- int64 max_database_id = -1;
+ int64_t max_database_id = -1;
bool found = false;
leveldb::Status s =
GetInt(transaction, MaxDatabaseIdKey::Encode(), &max_database_id, &found);
@@ -1341,7 +1335,7 @@ WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId(
DCHECK_GE(max_database_id, 0);
- int64 database_id = max_database_id + 1;
+ int64_t database_id = max_database_id + 1;
PutInt(transaction, MaxDatabaseIdKey::Encode(), database_id);
*new_id = database_id;
return leveldb::Status::OK();
@@ -1350,8 +1344,8 @@ WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId(
leveldb::Status IndexedDBBackingStore::CreateIDBDatabaseMetaData(
const base::string16& name,
const base::string16& version,
- int64 int_version,
- int64* row_id) {
+ int64_t int_version,
+ int64_t* row_id) {
// TODO(jsbell): Don't persist metadata if open fails. http://crbug.com/395472
scoped_refptr<LevelDBTransaction> transaction =
IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
@@ -1389,8 +1383,8 @@ leveldb::Status IndexedDBBackingStore::CreateIDBDatabaseMetaData(
bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion(
IndexedDBBackingStore::Transaction* transaction,
- int64 row_id,
- int64 int_version) {
+ int64_t row_id,
+ int64_t int_version) {
if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION)
int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
DCHECK_GE(int_version, 0) << "int_version was " << int_version;
@@ -1419,8 +1413,8 @@ static leveldb::Status DeleteRangeBasic(LevelDBTransaction* transaction,
static leveldb::Status DeleteBlobsInRange(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const std::string& start_key,
const std::string& end_key,
bool upper_open) {
@@ -1445,8 +1439,8 @@ static leveldb::Status DeleteBlobsInRange(
static leveldb::Status DeleteBlobsInObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id) {
+ int64_t database_id,
+ int64_t object_store_id) {
std::string start_key, stop_key;
start_key =
BlobEntryKey::EncodeMinKeyForObjectStore(database_id, object_store_id);
@@ -1522,8 +1516,8 @@ leveldb::Status IndexedDBBackingStore::DeleteDatabase(
static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it,
const std::string& stop_key,
- int64 object_store_id,
- int64 meta_data_type) {
+ int64_t object_store_id,
+ int64_t meta_data_type) {
if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0)
return false;
@@ -1542,7 +1536,7 @@ static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it,
// TODO(jsbell): This should do some error handling rather than
// plowing ahead when bad data is encountered.
leveldb::Status IndexedDBBackingStore::GetObjectStores(
- int64 database_id,
+ int64_t database_id,
IndexedDBDatabaseMetadata::ObjectStoreMap* object_stores) {
IDB_TRACE("IndexedDBBackingStore::GetObjectStores");
if (!KeyPrefix::IsValidDatabaseId(database_id))
@@ -1571,7 +1565,7 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores(
continue;
}
- int64 object_store_id = meta_data_key.ObjectStoreId();
+ int64_t object_store_id = meta_data_key.ObjectStoreId();
// TODO(jsbell): Do this by direct key lookup rather than iteration, to
// simplify.
@@ -1651,7 +1645,7 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores(
INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
break;
}
- int64 max_index_id;
+ int64_t max_index_id;
{
StringPiece slice(it->Value());
if (!DecodeInt(&slice, &max_index_id) || !slice.empty())
@@ -1688,7 +1682,7 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores(
break;
}
- int64 key_generator_current_number = -1;
+ int64_t key_generator_current_number = -1;
if (CheckObjectStoreAndMetaDataType(
it.get(),
stop_key,
@@ -1726,11 +1720,11 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores(
WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId(
LevelDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id) {
+ int64_t database_id,
+ int64_t object_store_id) {
const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode(
database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID);
- int64 max_object_store_id = -1;
+ int64_t max_object_store_id = -1;
leveldb::Status s = GetMaxObjectStoreId(
transaction, max_object_store_id_key, &max_object_store_id);
if (!s.ok()) {
@@ -1750,8 +1744,8 @@ void IndexedDBBackingStore::Compact() { db_->CompactAll(); }
leveldb::Status IndexedDBBackingStore::CreateObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment) {
@@ -1801,8 +1795,8 @@ leveldb::Status IndexedDBBackingStore::CreateObjectStore(
leveldb::Status IndexedDBBackingStore::DeleteObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id) {
+ int64_t database_id,
+ int64_t object_store_id) {
IDB_TRACE("IndexedDBBackingStore::DeleteObjectStore");
if (!KeyPrefix::ValidIds(database_id, object_store_id))
return InvalidDBKeyStatus();
@@ -1866,8 +1860,8 @@ leveldb::Status IndexedDBBackingStore::DeleteObjectStore(
leveldb::Status IndexedDBBackingStore::GetRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
IndexedDBValue* record) {
IDB_TRACE("IndexedDBBackingStore::GetRecord");
@@ -1894,7 +1888,7 @@ leveldb::Status IndexedDBBackingStore::GetRecord(
return leveldb::Status::NotFound("Record contained no data");
}
- int64 version;
+ int64_t version;
StringPiece slice(data);
if (!DecodeVarInt(&slice, &version)) {
INTERNAL_READ_ERROR_UNTESTED(GET_RECORD);
@@ -1907,14 +1901,14 @@ leveldb::Status IndexedDBBackingStore::GetRecord(
WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber(
LevelDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64* new_version_number) {
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t* new_version_number) {
const std::string last_version_key = ObjectStoreMetaDataKey::Encode(
database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION);
*new_version_number = -1;
- int64 last_version = -1;
+ int64_t last_version = -1;
bool found = false;
leveldb::Status s =
GetInt(transaction, last_version_key, &last_version, &found);
@@ -1927,7 +1921,7 @@ WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber(
DCHECK_GE(last_version, 0);
- int64 version = last_version + 1;
+ int64_t version = last_version + 1;
PutInt(transaction, last_version_key, version);
// TODO(jsbell): Think about how we want to handle the overflow scenario.
@@ -1939,8 +1933,8 @@ WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber(
leveldb::Status IndexedDBBackingStore::PutRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
IndexedDBValue* value,
ScopedVector<storage::BlobDataHandle>* handles,
@@ -1951,7 +1945,7 @@ leveldb::Status IndexedDBBackingStore::PutRecord(
DCHECK(key.IsValid());
LevelDBTransaction* leveldb_transaction = transaction->transaction();
- int64 version = -1;
+ int64_t version = -1;
leveldb::Status s = GetNewVersionNumber(
leveldb_transaction, database_id, object_store_id, &version);
if (!s.ok())
@@ -1988,8 +1982,8 @@ leveldb::Status IndexedDBBackingStore::PutRecord(
leveldb::Status IndexedDBBackingStore::ClearObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id) {
+ int64_t database_id,
+ int64_t object_store_id) {
IDB_TRACE("IndexedDBBackingStore::ClearObjectStore");
if (!KeyPrefix::ValidIds(database_id, object_store_id))
return InvalidDBKeyStatus();
@@ -2009,8 +2003,8 @@ leveldb::Status IndexedDBBackingStore::ClearObjectStore(
leveldb::Status IndexedDBBackingStore::DeleteRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const RecordIdentifier& record_identifier) {
IDB_TRACE("IndexedDBBackingStore::DeleteRecord");
if (!KeyPrefix::ValidIds(database_id, object_store_id))
@@ -2033,8 +2027,8 @@ leveldb::Status IndexedDBBackingStore::DeleteRecord(
leveldb::Status IndexedDBBackingStore::DeleteRange(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& key_range) {
leveldb::Status s;
scoped_ptr<IndexedDBBackingStore::Cursor> start_cursor =
@@ -2096,9 +2090,9 @@ leveldb::Status IndexedDBBackingStore::DeleteRange(
leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64* key_generator_current_number) {
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t* key_generator_current_number) {
if (!KeyPrefix::ValidIds(database_id, object_store_id))
return InvalidDBKeyStatus();
LevelDBTransaction* leveldb_transaction = transaction->transaction();
@@ -2139,7 +2133,7 @@ leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber(
ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
- int64 max_numeric_key = 0;
+ int64_t max_numeric_key = 0;
for (s = it->Seek(start_key);
s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
@@ -2152,7 +2146,7 @@ leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber(
}
scoped_ptr<IndexedDBKey> user_key = data_key.user_key();
if (user_key->type() == blink::WebIDBKeyTypeNumber) {
- int64 n = static_cast<int64>(user_key->number());
+ int64_t n = static_cast<int64_t>(user_key->number());
if (n > max_numeric_key)
max_numeric_key = n;
}
@@ -2168,15 +2162,15 @@ leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber(
leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 new_number,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t new_number,
bool check_current) {
if (!KeyPrefix::ValidIds(database_id, object_store_id))
return InvalidDBKeyStatus();
if (check_current) {
- int64 current_number;
+ int64_t current_number;
leveldb::Status s = GetKeyGeneratorCurrentNumber(
transaction, database_id, object_store_id, &current_number);
if (!s.ok())
@@ -2197,8 +2191,8 @@ leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber(
leveldb::Status IndexedDBBackingStore::KeyExistsInObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
RecordIdentifier* found_record_identifier,
bool* found) {
@@ -2223,7 +2217,7 @@ leveldb::Status IndexedDBBackingStore::KeyExistsInObjectStore(
return InternalInconsistencyStatus();
}
- int64 version;
+ int64_t version;
StringPiece slice(data);
if (!DecodeVarInt(&slice, &version))
return InternalInconsistencyStatus();
@@ -2240,14 +2234,15 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
typedef IndexedDBBackingStore::Transaction::WriteDescriptorVec
WriteDescriptorVec;
ChainedBlobWriterImpl(
- int64 database_id,
+ int64_t database_id,
IndexedDBBackingStore* backing_store,
WriteDescriptorVec* blobs,
scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback)
: waiting_for_callback_(false),
database_id_(database_id),
backing_store_(backing_store),
- callback_(callback) {
+ callback_(callback),
+ aborted_(false) {
blobs_.swap(*blobs);
iter_ = blobs_.begin();
backing_store->task_runner()->PostTask(
@@ -2258,15 +2253,15 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
delegate_.reset(delegate.release());
}
- void ReportWriteCompletion(bool succeeded, int64 bytes_written) override {
+ void ReportWriteCompletion(bool succeeded, int64_t bytes_written) override {
DCHECK(waiting_for_callback_);
DCHECK(!succeeded || bytes_written >= 0);
waiting_for_callback_ = false;
if (delegate_.get()) // Only present for Blob, not File.
content::BrowserThread::DeleteSoon(
content::BrowserThread::IO, FROM_HERE, delegate_.release());
- if (aborted_self_ref_.get()) {
- aborted_self_ref_ = NULL;
+ if (aborted_) {
+ self_ref_ = NULL;
return;
}
if (iter_->size() != -1 && iter_->size() != bytes_written)
@@ -2280,38 +2275,43 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
}
void Abort() override {
+ aborted_ = true;
if (!waiting_for_callback_)
return;
- aborted_self_ref_ = this;
+ self_ref_ = this;
}
private:
- ~ChainedBlobWriterImpl() override { DCHECK(!waiting_for_callback_); }
+ ~ChainedBlobWriterImpl() override {}
void WriteNextFile() {
DCHECK(!waiting_for_callback_);
- DCHECK(!aborted_self_ref_.get());
+ if (aborted_) {
+ self_ref_ = nullptr;
+ return;
+ }
if (iter_ == blobs_.end()) {
+ DCHECK(!self_ref_.get());
callback_->Run(true);
return;
} else {
- waiting_for_callback_ = true;
if (!backing_store_->WriteBlobFile(database_id_, *iter_, this)) {
- waiting_for_callback_ = false;
callback_->Run(false);
return;
}
+ waiting_for_callback_ = true;
}
}
bool waiting_for_callback_;
- scoped_refptr<ChainedBlobWriterImpl> aborted_self_ref_;
+ scoped_refptr<ChainedBlobWriterImpl> self_ref_;
WriteDescriptorVec blobs_;
WriteDescriptorVec::const_iterator iter_;
- int64 database_id_;
+ int64_t database_id_;
IndexedDBBackingStore* backing_store_;
scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback_;
scoped_ptr<FileWriterDelegate> delegate_;
+ bool aborted_;
DISALLOW_COPY_AND_ASSIGN(ChainedBlobWriterImpl);
};
@@ -2327,7 +2327,7 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
bytes_written_(0) {}
void Run(base::File::Error rv,
- int64 bytes,
+ int64_t bytes,
FileWriterDelegate::WriteProgressStatus write_status) {
DCHECK_GE(bytes, 0);
bytes_written_ += bytes;
@@ -2372,7 +2372,7 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
0,
storage::FileStreamWriter::CREATE_NEW_FILE));
scoped_ptr<FileWriterDelegate> delegate(new FileWriterDelegate(
- writer.Pass(), storage::FlushPolicy::FLUSH_ON_COMPLETION));
+ std::move(writer), storage::FlushPolicy::FLUSH_ON_COMPLETION));
DCHECK(blob_url.is_valid());
scoped_ptr<net::URLRequest> blob_request(request_context->CreateRequest(
@@ -2381,9 +2381,9 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
this->file_path_ = file_path;
this->last_modified_ = last_modified;
- delegate->Start(blob_request.Pass(),
+ delegate->Start(std::move(blob_request),
base::Bind(&LocalWriteClosure::Run, this));
- chained_blob_writer_->set_delegate(delegate.Pass());
+ chained_blob_writer_->set_delegate(std::move(delegate));
}
private:
@@ -2426,7 +2426,7 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
scoped_refptr<IndexedDBBackingStore::Transaction::ChainedBlobWriter>
chained_blob_writer_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
- int64 bytes_written_;
+ int64_t bytes_written_;
base::FilePath file_path_;
base::Time last_modified_;
@@ -2435,10 +2435,9 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
};
bool IndexedDBBackingStore::WriteBlobFile(
- int64 database_id,
+ int64_t database_id,
const Transaction::WriteDescriptor& descriptor,
Transaction::ChainedBlobWriter* chained_blob_writer) {
-
if (!MakeIDBBlobDirectory(blob_path_, database_id, descriptor.key()))
return false;
@@ -2454,8 +2453,8 @@ bool IndexedDBBackingStore::WriteBlobFile(
if (descriptor.size() != info.size)
return false;
// The round-trip can be lossy; round to nearest millisecond.
- int64 delta = (descriptor.last_modified() -
- info.last_modified).InMilliseconds();
+ int64_t delta =
+ (descriptor.last_modified() - info.last_modified).InMilliseconds();
if (std::abs(delta) > 1)
return false;
}
@@ -2489,8 +2488,8 @@ bool IndexedDBBackingStore::WriteBlobFile(
return true;
}
-void IndexedDBBackingStore::ReportBlobUnused(int64 database_id,
- int64 blob_key) {
+void IndexedDBBackingStore::ReportBlobUnused(int64_t database_id,
+ int64_t blob_key) {
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
bool all_blobs = blob_key == DatabaseMetaDataKey::kAllBlobsKey;
DCHECK(all_blobs || DatabaseMetaDataKey::IsValidBlobKey(blob_key));
@@ -2516,8 +2515,8 @@ void IndexedDBBackingStore::ReportBlobUnused(int64 database_id,
for (BlobJournalType::iterator journal_iter = live_blob_journal.begin();
journal_iter != live_blob_journal.end();
++journal_iter) {
- int64 current_database_id = journal_iter->first;
- int64 current_blob_key = journal_iter->second;
+ int64_t current_database_id = journal_iter->first;
+ int64_t current_blob_key = journal_iter->second;
bool current_all_blobs =
current_blob_key == DatabaseMetaDataKey::kAllBlobsKey;
DCHECK(KeyPrefix::IsValidDatabaseId(current_database_id) ||
@@ -2564,14 +2563,14 @@ void IndexedDBBackingStore::StartJournalCleaningTimer() {
}
// This assumes a file path of dbId/second-to-LSB-of-counter/counter.
-FilePath IndexedDBBackingStore::GetBlobFileName(int64 database_id,
- int64 key) const {
+FilePath IndexedDBBackingStore::GetBlobFileName(int64_t database_id,
+ int64_t key) const {
return GetBlobFileNameForKey(blob_path_, database_id, key);
}
static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it,
const std::string& stop_key,
- int64 index_id,
+ int64_t index_id,
unsigned char meta_data_type) {
if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0)
return false;
@@ -2590,8 +2589,8 @@ static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it,
// TODO(jsbell): This should do some error handling rather than plowing ahead
// when bad data is encountered.
leveldb::Status IndexedDBBackingStore::GetIndexes(
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
IndexedDBObjectStoreMetadata::IndexMap* indexes) {
IDB_TRACE("IndexedDBBackingStore::GetIndexes");
if (!KeyPrefix::ValidIds(database_id, object_store_id))
@@ -2622,7 +2621,7 @@ leveldb::Status IndexedDBBackingStore::GetIndexes(
// TODO(jsbell): Do this by direct key lookup rather than iteration, to
// simplify.
- int64 index_id = meta_data_key.IndexId();
+ int64_t index_id = meta_data_key.IndexId();
base::string16 index_name;
{
StringPiece slice(it->Value());
@@ -2685,12 +2684,13 @@ leveldb::Status IndexedDBBackingStore::GetIndexes(
return s;
}
-bool IndexedDBBackingStore::RemoveBlobFile(int64 database_id, int64 key) const {
+bool IndexedDBBackingStore::RemoveBlobFile(int64_t database_id,
+ int64_t key) const {
FilePath path = GetBlobFileName(database_id, key);
return base::DeleteFile(path, false);
}
-bool IndexedDBBackingStore::RemoveBlobDirectory(int64 database_id) const {
+bool IndexedDBBackingStore::RemoveBlobDirectory(int64_t database_id) const {
FilePath path = GetBlobDirectoryName(blob_path_, database_id);
return base::DeleteFile(path, true);
}
@@ -2701,8 +2701,8 @@ leveldb::Status IndexedDBBackingStore::CleanUpBlobJournalEntries(
if (journal.empty())
return leveldb::Status::OK();
for (const auto& entry : journal) {
- int64 database_id = entry.first;
- int64 blob_key = entry.second;
+ int64_t database_id = entry.first;
+ int64_t blob_key = entry.second;
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
if (blob_key == DatabaseMetaDataKey::kAllBlobsKey) {
if (!RemoveBlobDirectory(database_id))
@@ -2738,7 +2738,7 @@ leveldb::Status IndexedDBBackingStore::CleanUpBlobJournal(
}
leveldb::Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord(
- int64 database_id,
+ int64_t database_id,
const std::string& object_store_data_key,
IndexedDBValue* value) {
BlobChangeRecord* change_record = NULL;
@@ -2810,10 +2810,10 @@ void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() {
WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
LevelDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id) {
- int64 max_index_id = -1;
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
+ int64_t max_index_id = -1;
const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode(
database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID);
bool found = false;
@@ -2837,9 +2837,9 @@ WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
leveldb::Status IndexedDBBackingStore::CreateIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool is_unique,
@@ -2872,9 +2872,9 @@ leveldb::Status IndexedDBBackingStore::CreateIndex(
leveldb::Status IndexedDBBackingStore::DeleteIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
IDB_TRACE("IndexedDBBackingStore::DeleteIndex");
if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
return InvalidDBKeyStatus();
@@ -2904,9 +2904,9 @@ leveldb::Status IndexedDBBackingStore::DeleteIndex(
leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& key,
const RecordIdentifier& record_identifier) {
IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord");
@@ -2965,9 +2965,9 @@ static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction,
}
static leveldb::Status VersionExists(LevelDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 version,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t version,
const std::string& encoded_primary_key,
bool* exists) {
const std::string key =
@@ -2983,7 +2983,7 @@ static leveldb::Status VersionExists(LevelDBTransaction* transaction,
return s;
StringPiece slice(data);
- int64 decoded;
+ int64_t decoded;
if (!DecodeInt(&slice, &decoded) || !slice.empty())
return InternalInconsistencyStatus();
*exists = (decoded == version);
@@ -2992,9 +2992,9 @@ static leveldb::Status VersionExists(LevelDBTransaction* transaction,
leveldb::Status IndexedDBBackingStore::FindKeyInIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& key,
std::string* found_encoded_primary_key,
bool* found) {
@@ -3022,7 +3022,7 @@ leveldb::Status IndexedDBBackingStore::FindKeyInIndex(
StringPiece slice(it->Value());
- int64 version;
+ int64_t version;
if (!DecodeVarInt(&slice, &version)) {
INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX);
return InternalInconsistencyStatus();
@@ -3051,9 +3051,9 @@ leveldb::Status IndexedDBBackingStore::FindKeyInIndex(
leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& key,
scoped_ptr<IndexedDBKey>* primary_key) {
IDB_TRACE("IndexedDBBackingStore::GetPrimaryKeyViaIndex");
@@ -3089,9 +3089,9 @@ leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex(
leveldb::Status IndexedDBBackingStore::KeyExistsInIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& index_key,
scoped_ptr<IndexedDBKey>* found_primary_key,
bool* exists) {
@@ -3147,13 +3147,12 @@ IndexedDBBackingStore::Cursor::Cursor(
IndexedDBBackingStore::Cursor::Cursor(
scoped_refptr<IndexedDBBackingStore> backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
+ int64_t database_id,
const CursorOptions& cursor_options)
: backing_store_(backing_store.get()),
transaction_(transaction),
database_id_(database_id),
- cursor_options_(cursor_options) {
-}
+ cursor_options_(cursor_options) {}
IndexedDBBackingStore::Cursor::~Cursor() {}
bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) {
@@ -3168,7 +3167,8 @@ bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) {
return Continue(0, READY, s);
}
-bool IndexedDBBackingStore::Cursor::Advance(uint32 count, leveldb::Status* s) {
+bool IndexedDBBackingStore::Cursor::Advance(uint32_t count,
+ leveldb::Status* s) {
*s = leveldb::Status::OK();
while (count--) {
if (!Continue(s))
@@ -3409,7 +3409,7 @@ class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
ObjectStoreKeyCursorImpl(
scoped_refptr<IndexedDBBackingStore> backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
+ int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store,
transaction,
@@ -3454,7 +3454,7 @@ bool ObjectStoreKeyCursorImpl::LoadCurrentRow(leveldb::Status* s) {
current_key_ = object_store_data_key.user_key();
- int64 version;
+ int64_t version;
slice = StringPiece(iterator_->Value());
if (!DecodeVarInt(&slice, &version)) {
INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
@@ -3475,7 +3475,7 @@ class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
ObjectStoreCursorImpl(
scoped_refptr<IndexedDBBackingStore> backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
+ int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store,
transaction,
@@ -3520,7 +3520,7 @@ bool ObjectStoreCursorImpl::LoadCurrentRow(leveldb::Status* s) {
current_key_ = object_store_data_key.user_key();
- int64 version;
+ int64_t version;
StringPiece value_slice = StringPiece(iterator_->Value());
if (!DecodeVarInt(&value_slice, &version)) {
INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
@@ -3547,7 +3547,7 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
IndexKeyCursorImpl(
scoped_refptr<IndexedDBBackingStore> backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
+ int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store,
transaction,
@@ -3608,7 +3608,7 @@ bool IndexKeyCursorImpl::LoadCurrentRow(leveldb::Status* s) {
DCHECK(current_key_);
slice = StringPiece(iterator_->Value());
- int64 index_data_version;
+ int64_t index_data_version;
if (!DecodeVarInt(&slice, &index_data_version)) {
INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
*s = InternalInconsistencyStatus();
@@ -3642,7 +3642,7 @@ bool IndexKeyCursorImpl::LoadCurrentRow(leveldb::Status* s) {
return false;
}
- int64 object_store_data_version;
+ int64_t object_store_data_version;
slice = StringPiece(result);
if (!DecodeVarInt(&slice, &object_store_data_version)) {
INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
@@ -3663,7 +3663,7 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
IndexCursorImpl(
scoped_refptr<IndexedDBBackingStore> backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
+ int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store,
transaction,
@@ -3725,7 +3725,7 @@ bool IndexCursorImpl::LoadCurrentRow(leveldb::Status* s) {
DCHECK(current_key_);
slice = StringPiece(iterator_->Value());
- int64 index_data_version;
+ int64_t index_data_version;
if (!DecodeVarInt(&slice, &index_data_version)) {
INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
*s = InternalInconsistencyStatus();
@@ -3759,7 +3759,7 @@ bool IndexCursorImpl::LoadCurrentRow(leveldb::Status* s) {
return false;
}
- int64 object_store_data_version;
+ int64_t object_store_data_version;
slice = StringPiece(result);
if (!DecodeVarInt(&slice, &object_store_data_version)) {
INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
@@ -3780,8 +3780,8 @@ bool IndexCursorImpl::LoadCurrentRow(leveldb::Status* s) {
bool ObjectStoreCursorOptions(
LevelDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& range,
blink::WebIDBCursorDirection direction,
IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) {
@@ -3853,9 +3853,9 @@ bool ObjectStoreCursorOptions(
bool IndexCursorOptions(
LevelDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& range,
blink::WebIDBCursorDirection direction,
IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) {
@@ -3928,8 +3928,8 @@ bool IndexCursorOptions(
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBBackingStore::OpenObjectStoreCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& range,
blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
@@ -3949,14 +3949,14 @@ IndexedDBBackingStore::OpenObjectStoreCursor(
if (!cursor->FirstSeek(s))
return scoped_ptr<IndexedDBBackingStore::Cursor>();
- return cursor.Pass();
+ return std::move(cursor);
}
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBBackingStore::OpenObjectStoreKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& range,
blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
@@ -3976,15 +3976,15 @@ IndexedDBBackingStore::OpenObjectStoreKeyCursor(
if (!cursor->FirstSeek(s))
return scoped_ptr<IndexedDBBackingStore::Cursor>();
- return cursor.Pass();
+ return std::move(cursor);
}
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBBackingStore::OpenIndexKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& range,
blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
@@ -4005,15 +4005,15 @@ IndexedDBBackingStore::OpenIndexKeyCursor(
if (!cursor->FirstSeek(s))
return scoped_ptr<IndexedDBBackingStore::Cursor>();
- return cursor.Pass();
+ return std::move(cursor);
}
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBBackingStore::OpenIndexCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& range,
blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
@@ -4033,7 +4033,7 @@ IndexedDBBackingStore::OpenIndexCursor(
if (!cursor->FirstSeek(s))
return scoped_ptr<IndexedDBBackingStore::Cursor>();
- return cursor.Pass();
+ return std::move(cursor);
}
IndexedDBBackingStore::Transaction::Transaction(
@@ -4086,7 +4086,7 @@ leveldb::Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction(
for (auto& iter : blob_change_map_) {
std::vector<IndexedDBBlobInfo*> new_blob_keys;
for (auto& entry : iter.second->mutable_blob_info()) {
- int64 next_blob_key = -1;
+ int64_t next_blob_key = -1;
bool result = GetBlobKeyGeneratorCurrentNumber(
pre_transaction.get(), database_id_, &next_blob_key);
if (!result || next_blob_key < 0)
@@ -4387,9 +4387,8 @@ void IndexedDBBackingStore::Transaction::Rollback() {
IndexedDBBackingStore::BlobChangeRecord::BlobChangeRecord(
const std::string& key,
- int64 object_store_id)
- : key_(key), object_store_id_(object_store_id) {
-}
+ int64_t object_store_id)
+ : key_(key), object_store_id_(object_store_id) {}
IndexedDBBackingStore::BlobChangeRecord::~BlobChangeRecord() {
}
@@ -4416,12 +4415,12 @@ IndexedDBBackingStore::BlobChangeRecord::Clone() const {
for (const auto* handle : handles_)
record->handles_.push_back(new storage::BlobDataHandle(*handle));
- return record.Pass();
+ return record;
}
leveldb::Status IndexedDBBackingStore::Transaction::PutBlobInfoIfNeeded(
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const std::string& object_store_data_key,
std::vector<IndexedDBBlobInfo>* blob_info,
ScopedVector<storage::BlobDataHandle>* handles) {
@@ -4455,8 +4454,8 @@ leveldb::Status IndexedDBBackingStore::Transaction::PutBlobInfoIfNeeded(
// leveldb transaction, but only w.r.t. the user keys altered--we don't keep the
// changes to exists or index keys here.
void IndexedDBBackingStore::Transaction::PutBlobInfo(
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const std::string& object_store_data_key,
std::vector<IndexedDBBlobInfo>* blob_info,
ScopedVector<storage::BlobDataHandle>* handles) {
diff --git a/chromium/content/browser/indexed_db/indexed_db_backing_store.h b/chromium/content/browser/indexed_db/indexed_db_backing_store.h
index 52344e1e970..1ba22603a36 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store.h
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store.h
@@ -5,14 +5,17 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
@@ -66,13 +69,13 @@ class CONTENT_EXPORT IndexedDBBackingStore
class CONTENT_EXPORT RecordIdentifier {
public:
- RecordIdentifier(const std::string& primary_key, int64 version);
+ RecordIdentifier(const std::string& primary_key, int64_t version);
RecordIdentifier();
~RecordIdentifier();
const std::string& primary_key() const { return primary_key_; }
- int64 version() const { return version_; }
- void Reset(const std::string& primary_key, int64 version) {
+ int64_t version() const { return version_; }
+ void Reset(const std::string& primary_key, int64_t version) {
primary_key_ = primary_key;
version_ = version;
}
@@ -81,7 +84,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
// TODO(jsbell): Make it more clear that this is the *encoded* version of
// the key.
std::string primary_key_;
- int64 version_;
+ int64_t version_;
DISALLOW_COPY_AND_ASSIGN(RecordIdentifier);
};
@@ -96,11 +99,11 @@ class CONTENT_EXPORT IndexedDBBackingStore
class BlobChangeRecord {
public:
- BlobChangeRecord(const std::string& key, int64 object_store_id);
+ BlobChangeRecord(const std::string& key, int64_t object_store_id);
~BlobChangeRecord();
const std::string& key() const { return key_; }
- int64 object_store_id() const { return object_store_id_; }
+ int64_t object_store_id() const { return object_store_id_; }
void SetBlobInfo(std::vector<IndexedDBBlobInfo>* blob_info);
std::vector<IndexedDBBlobInfo>& mutable_blob_info() { return blob_info_; }
const std::vector<IndexedDBBlobInfo>& blob_info() const {
@@ -111,7 +114,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
private:
std::string key_;
- int64 object_store_id_;
+ int64_t object_store_id_;
std::vector<IndexedDBBlobInfo> blob_info_;
ScopedVector<storage::BlobDataHandle> handles_;
DISALLOW_COPY_AND_ASSIGN(BlobChangeRecord);
@@ -145,13 +148,13 @@ class CONTENT_EXPORT IndexedDBBackingStore
transaction_ = NULL;
}
leveldb::Status PutBlobInfoIfNeeded(
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const std::string& object_store_data_key,
std::vector<IndexedDBBlobInfo>*,
ScopedVector<storage::BlobDataHandle>* handles);
- void PutBlobInfo(int64 database_id,
- int64 object_store_id,
+ void PutBlobInfo(int64_t database_id,
+ int64_t object_store_id,
const std::string& object_store_data_key,
std::vector<IndexedDBBlobInfo>*,
ScopedVector<storage::BlobDataHandle>* handles);
@@ -159,7 +162,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
LevelDBTransaction* transaction() { return transaction_.get(); }
leveldb::Status GetBlobInfoForRecord(
- int64 database_id,
+ int64_t database_id,
const std::string& object_store_data_key,
IndexedDBValue* value);
@@ -212,7 +215,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
// TODO(ericu): Add a reason in the event of failure.
virtual void ReportWriteCompletion(bool succeeded,
- int64 bytes_written) = 0;
+ int64_t bytes_written) = 0;
virtual void Abort() = 0;
@@ -257,11 +260,11 @@ class CONTENT_EXPORT IndexedDBBackingStore
scoped_refptr<LevelDBTransaction> transaction_;
BlobChangeMap blob_change_map_;
BlobChangeMap incognito_blob_map_;
- int64 database_id_;
+ int64_t database_id_;
// List of blob files being newly written as part of this transaction.
// These will be added to the primary blob journal prior to commit, then
- // removed after a sucessful commit.
+ // removed after a successful commit.
BlobJournalType blobs_to_write_;
// List of blob files being deleted as part of this transaction. These will
@@ -285,9 +288,9 @@ class CONTENT_EXPORT IndexedDBBackingStore
struct CursorOptions {
CursorOptions();
~CursorOptions();
- int64 database_id;
- int64 object_store_id;
- int64 index_id;
+ int64_t database_id;
+ int64_t object_store_id;
+ int64_t index_id;
std::string low_key;
bool low_open;
std::string high_key;
@@ -307,7 +310,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
const IndexedDBKey* primary_key,
IteratorState state,
leveldb::Status*);
- bool Advance(uint32 count, leveldb::Status*);
+ bool Advance(uint32_t count, leveldb::Status*);
bool FirstSeek(leveldb::Status*);
virtual Cursor* Clone() = 0;
@@ -319,7 +322,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
protected:
Cursor(scoped_refptr<IndexedDBBackingStore> backing_store,
Transaction* transaction,
- int64 database_id,
+ int64_t database_id,
const CursorOptions& cursor_options);
explicit Cursor(const IndexedDBBackingStore::Cursor* other);
@@ -332,7 +335,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
IndexedDBBackingStore* backing_store_;
Transaction* transaction_;
- int64 database_id_;
+ int64_t database_id_;
const CursorOptions cursor_options_;
scoped_ptr<LevelDBIterator> iterator_;
scoped_ptr<IndexedDBKey> current_key_;
@@ -408,12 +411,12 @@ class CONTENT_EXPORT IndexedDBBackingStore
virtual leveldb::Status CreateIDBDatabaseMetaData(
const base::string16& name,
const base::string16& version,
- int64 int_version,
- int64* row_id);
+ int64_t int_version,
+ int64_t* row_id);
virtual bool UpdateIDBDatabaseIntVersion(
IndexedDBBackingStore::Transaction* transaction,
- int64 row_id,
- int64 int_version);
+ int64_t row_id,
+ int64_t int_version);
virtual leveldb::Status DeleteDatabase(const base::string16& name);
// Assumes caller has already closed the backing store.
@@ -423,136 +426,136 @@ class CONTENT_EXPORT IndexedDBBackingStore
const GURL& origin_url,
const std::string& message);
leveldb::Status GetObjectStores(
- int64 database_id,
+ int64_t database_id,
IndexedDBDatabaseMetadata::ObjectStoreMap* map) WARN_UNUSED_RESULT;
virtual leveldb::Status CreateObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment);
virtual leveldb::Status DeleteObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id) WARN_UNUSED_RESULT;
+ int64_t database_id,
+ int64_t object_store_id) WARN_UNUSED_RESULT;
virtual leveldb::Status GetRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
IndexedDBValue* record) WARN_UNUSED_RESULT;
virtual leveldb::Status PutRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
IndexedDBValue* value,
ScopedVector<storage::BlobDataHandle>* handles,
RecordIdentifier* record) WARN_UNUSED_RESULT;
virtual leveldb::Status ClearObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id) WARN_UNUSED_RESULT;
+ int64_t database_id,
+ int64_t object_store_id) WARN_UNUSED_RESULT;
virtual leveldb::Status DeleteRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const RecordIdentifier& record) WARN_UNUSED_RESULT;
virtual leveldb::Status DeleteRange(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange&) WARN_UNUSED_RESULT;
virtual leveldb::Status GetKeyGeneratorCurrentNumber(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64* current_number) WARN_UNUSED_RESULT;
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t* current_number) WARN_UNUSED_RESULT;
virtual leveldb::Status MaybeUpdateKeyGeneratorCurrentNumber(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 new_state,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t new_state,
bool check_current) WARN_UNUSED_RESULT;
virtual leveldb::Status KeyExistsInObjectStore(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
RecordIdentifier* found_record_identifier,
bool* found) WARN_UNUSED_RESULT;
virtual leveldb::Status CreateIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool is_unique,
bool is_multi_entry) WARN_UNUSED_RESULT;
virtual leveldb::Status DeleteIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id) WARN_UNUSED_RESULT;
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) WARN_UNUSED_RESULT;
virtual leveldb::Status PutIndexDataForRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& key,
const RecordIdentifier& record) WARN_UNUSED_RESULT;
virtual leveldb::Status GetPrimaryKeyViaIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& key,
scoped_ptr<IndexedDBKey>* primary_key) WARN_UNUSED_RESULT;
virtual leveldb::Status KeyExistsInIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& key,
scoped_ptr<IndexedDBKey>* found_primary_key,
bool* exists) WARN_UNUSED_RESULT;
// Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef.
- virtual void ReportBlobUnused(int64 database_id, int64 blob_key);
+ virtual void ReportBlobUnused(int64_t database_id, int64_t blob_key);
- base::FilePath GetBlobFileName(int64 database_id, int64 key) const;
+ base::FilePath GetBlobFileName(int64_t database_id, int64_t key) const;
virtual scoped_ptr<Cursor> OpenObjectStoreKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*);
virtual scoped_ptr<Cursor> OpenObjectStoreCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*);
virtual scoped_ptr<Cursor> OpenIndexKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*);
virtual scoped_ptr<Cursor> OpenIndexCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*);
@@ -574,12 +577,12 @@ class CONTENT_EXPORT IndexedDBBackingStore
leveldb::Status SetUpMetadata();
virtual bool WriteBlobFile(
- int64 database_id,
+ int64_t database_id,
const Transaction::WriteDescriptor& descriptor,
Transaction::ChainedBlobWriter* chained_blob_writer);
// Remove the referenced file on disk.
- virtual bool RemoveBlobFile(int64 database_id, int64 key) const;
+ virtual bool RemoveBlobFile(int64_t database_id, int64_t key) const;
// Schedule a call to CleanPrimaryJournalIgnoreReturn() via
// an owned timer. If this object is destroyed, the timer
@@ -609,20 +612,20 @@ class CONTENT_EXPORT IndexedDBBackingStore
leveldb::Status FindKeyInIndex(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& key,
std::string* found_encoded_primary_key,
bool* found);
- leveldb::Status GetIndexes(int64 database_id,
- int64 object_store_id,
+ leveldb::Status GetIndexes(int64_t database_id,
+ int64_t object_store_id,
IndexedDBObjectStoreMetadata::IndexMap* map)
WARN_UNUSED_RESULT;
// Remove the blob directory for the specified database and all contained
// blob files.
- bool RemoveBlobDirectory(int64 database_id) const;
+ bool RemoveBlobDirectory(int64_t database_id) const;
// Synchronously read the key-specified blob journal entry from the backing
// store, delete all referenced blob files, and erase the journal entry.
diff --git a/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
index 09f1fa2e039..93d281e036a 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -4,6 +4,10 @@
#include "content/browser/indexed_db/indexed_db_backing_store.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
@@ -89,13 +93,9 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
return scoped_refptr<TestableIndexedDBBackingStore>();
scoped_refptr<TestableIndexedDBBackingStore> backing_store(
- new TestableIndexedDBBackingStore(indexed_db_factory,
- origin_url,
- blob_path,
- request_context,
- db.Pass(),
- comparator.Pass(),
- task_runner));
+ new TestableIndexedDBBackingStore(
+ indexed_db_factory, origin_url, blob_path, request_context,
+ std::move(db), std::move(comparator), task_runner));
*status = backing_store->SetUpMetadata();
if (!status->ok())
@@ -109,14 +109,14 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
return writes_;
}
void ClearWrites() { writes_.clear(); }
- const std::vector<int64>& removals() const { return removals_; }
+ const std::vector<int64_t>& removals() const { return removals_; }
void ClearRemovals() { removals_.clear(); }
protected:
~TestableIndexedDBBackingStore() override {}
bool WriteBlobFile(
- int64 database_id,
+ int64_t database_id,
const Transaction::WriteDescriptor& descriptor,
Transaction::ChainedBlobWriter* chained_blob_writer) override {
if (KeyPrefix::IsValidDatabaseId(database_id_)) {
@@ -136,7 +136,7 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
return true;
}
- bool RemoveBlobFile(int64 database_id, int64 key) const override {
+ bool RemoveBlobFile(int64_t database_id, int64_t key) const override {
if (database_id_ != database_id ||
!KeyPrefix::IsValidDatabaseId(database_id)) {
return false;
@@ -162,17 +162,17 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
origin_url,
blob_path,
request_context,
- db.Pass(),
- comparator.Pass(),
+ std::move(db),
+ std::move(comparator),
task_runner),
database_id_(0) {}
- int64 database_id_;
+ int64_t database_id_;
std::vector<Transaction::WriteDescriptor> writes_;
// This is modified in an overridden virtual function that is properly const
// in the real implementation, therefore must be mutable here.
- mutable std::vector<int64> removals_;
+ mutable std::vector<int64_t> removals_;
DISALLOW_COPY_AND_ASSIGN(TestableIndexedDBBackingStore);
};
@@ -295,7 +295,7 @@ class IndexedDBBackingStoreTest : public testing::Test {
const std::vector<IndexedDBBlobInfo>& reads) const {
if (backing_store_->writes().size() != reads.size())
return false;
- std::set<int64> ids;
+ std::set<int64_t> ids;
for (size_t i = 0; i < backing_store_->writes().size(); ++i)
ids.insert(backing_store_->writes()[i].key());
if (ids.size() != backing_store_->writes().size())
@@ -753,12 +753,12 @@ TEST_F(IndexedDBBackingStoreTest, LiveBlobJournal) {
// Make sure that using very high ( more than 32 bit ) values for database_id
// and object_store_id still work.
TEST_F(IndexedDBBackingStoreTest, HighIds) {
- const int64 high_database_id = 1ULL << 35;
- const int64 high_object_store_id = 1ULL << 39;
+ const int64_t high_database_id = 1ULL << 35;
+ const int64_t high_object_store_id = 1ULL << 39;
// index_ids are capped at 32 bits for storage purposes.
- const int64 high_index_id = 1ULL << 29;
+ const int64_t high_index_id = 1ULL << 29;
- const int64 invalid_high_index_id = 1ULL << 37;
+ const int64_t invalid_high_index_id = 1ULL << 37;
const IndexedDBKey& index_key = m_key2;
std::string index_key_raw;
@@ -845,10 +845,11 @@ TEST_F(IndexedDBBackingStoreTest, HighIds) {
// Make sure that other invalid ids do not crash.
TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
// valid ids for use when testing invalid ids
- const int64 database_id = 1;
- const int64 object_store_id = 1;
- const int64 index_id = kMinimumIndexId;
- const int64 invalid_low_index_id = 19; // index_ids must be > kMinimumIndexId
+ const int64_t database_id = 1;
+ const int64_t object_store_id = 1;
+ const int64_t index_id = kMinimumIndexId;
+ const int64_t invalid_low_index_id =
+ 19; // index_ids must be > kMinimumIndexId
IndexedDBValue result_value;
@@ -933,17 +934,17 @@ TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
const base::string16 database_name(ASCIIToUTF16("db1"));
- int64 database_id;
+ int64_t database_id;
const base::string16 version(ASCIIToUTF16("old_string_version"));
- const int64 int_version = 9;
+ const int64_t int_version = 9;
- const int64 object_store_id = 99;
+ const int64_t object_store_id = 99;
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 int64_t index_id = 999;
const base::string16 index_name(ASCIIToUTF16("index1"));
const bool unique = true;
const bool multi_entry = true;
@@ -1021,14 +1022,14 @@ TEST_F(IndexedDBBackingStoreTest, GetDatabaseNames) {
const base::string16 string_version(ASCIIToUTF16("string_version"));
const base::string16 db1_name(ASCIIToUTF16("db1"));
- const int64 db1_version = 1LL;
- int64 db1_id;
+ const int64_t db1_version = 1LL;
+ int64_t db1_id;
// Database records with DEFAULT_INT_VERSION represent stale data,
// and should not be enumerated.
const base::string16 db2_name(ASCIIToUTF16("db2"));
- const int64 db2_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
- int64 db2_id;
+ const int64_t db2_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
+ int64_t db2_id;
leveldb::Status s = backing_store_->CreateIDBDatabaseMetaData(
db1_name, string_version, db1_version, &db1_id);
diff --git a/chromium/content/browser/indexed_db/indexed_db_blob_info.cc b/chromium/content/browser/indexed_db/indexed_db_blob_info.cc
index d61de754b93..a2308c48f46 100644
--- a/chromium/content/browser/indexed_db/indexed_db_blob_info.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_blob_info.cc
@@ -16,19 +16,17 @@ IndexedDBBlobInfo::IndexedDBBlobInfo()
IndexedDBBlobInfo::IndexedDBBlobInfo(const std::string& uuid,
const base::string16& type,
- int64 size)
+ int64_t size)
: is_file_(false),
uuid_(uuid),
type_(type),
size_(size),
- key_(DatabaseMetaDataKey::kInvalidBlobKey) {
-}
+ key_(DatabaseMetaDataKey::kInvalidBlobKey) {}
IndexedDBBlobInfo::IndexedDBBlobInfo(const base::string16& type,
- int64 size,
- int64 key)
- : is_file_(false), type_(type), size_(size), key_(key) {
-}
+ int64_t size,
+ int64_t key)
+ : is_file_(false), type_(type), size_(size), key_(key) {}
IndexedDBBlobInfo::IndexedDBBlobInfo(const std::string& uuid,
const base::FilePath& file_path,
@@ -43,11 +41,14 @@ IndexedDBBlobInfo::IndexedDBBlobInfo(const std::string& uuid,
key_(DatabaseMetaDataKey::kInvalidBlobKey) {
}
-IndexedDBBlobInfo::IndexedDBBlobInfo(int64 key,
+IndexedDBBlobInfo::IndexedDBBlobInfo(int64_t key,
const base::string16& type,
const base::string16& file_name)
- : is_file_(true), type_(type), size_(-1), file_name_(file_name), key_(key) {
-}
+ : is_file_(true),
+ type_(type),
+ size_(-1),
+ file_name_(file_name),
+ key_(key) {}
IndexedDBBlobInfo::IndexedDBBlobInfo(const IndexedDBBlobInfo& other) = default;
@@ -56,7 +57,7 @@ IndexedDBBlobInfo::~IndexedDBBlobInfo() = default;
IndexedDBBlobInfo& IndexedDBBlobInfo::operator=(
const IndexedDBBlobInfo& other) = default;
-void IndexedDBBlobInfo::set_size(int64 size) {
+void IndexedDBBlobInfo::set_size(int64_t size) {
DCHECK_EQ(-1, size_);
size_ = size;
}
@@ -78,7 +79,7 @@ void IndexedDBBlobInfo::set_last_modified(const base::Time& time) {
last_modified_ = time;
}
-void IndexedDBBlobInfo::set_key(int64 key) {
+void IndexedDBBlobInfo::set_key(int64_t key) {
DCHECK_EQ(DatabaseMetaDataKey::kInvalidBlobKey, key_);
key_ = key;
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_blob_info.h b/chromium/content/browser/indexed_db/indexed_db_blob_info.h
index 60da7076a70..c54e065d943 100644
--- a/chromium/content/browser/indexed_db/indexed_db_blob_info.h
+++ b/chromium/content/browser/indexed_db/indexed_db_blob_info.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BLOB_INFO_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BLOB_INFO_H_
+#include <stdint.h>
+
#include <string>
#include "base/callback.h"
@@ -22,14 +24,14 @@ class CONTENT_EXPORT IndexedDBBlobInfo {
// These two are used for Blobs.
IndexedDBBlobInfo(const std::string& uuid,
const base::string16& type,
- int64 size);
- IndexedDBBlobInfo(const base::string16& type, int64 size, int64 key);
+ int64_t size);
+ IndexedDBBlobInfo(const base::string16& type, int64_t size, int64_t key);
// These two are used for Files.
IndexedDBBlobInfo(const std::string& uuid,
const base::FilePath& file_path,
const base::string16& file_name,
const base::string16& type);
- IndexedDBBlobInfo(int64 key,
+ IndexedDBBlobInfo(int64_t key,
const base::string16& type,
const base::string16& file_name);
@@ -40,9 +42,9 @@ class CONTENT_EXPORT IndexedDBBlobInfo {
bool is_file() const { return is_file_; }
const std::string& uuid() const { return uuid_; }
const base::string16& type() const { return type_; }
- int64 size() const { return size_; }
+ int64_t size() const { return size_; }
const base::string16& file_name() const { return file_name_; }
- int64 key() const { return key_; }
+ int64_t key() const { return key_; }
const base::FilePath& file_path() const { return file_path_; }
const base::Time& last_modified() const { return last_modified_; }
const base::Closure& mark_used_callback() const {
@@ -50,11 +52,11 @@ class CONTENT_EXPORT IndexedDBBlobInfo {
}
const ReleaseCallback& release_callback() const { return release_callback_; }
- void set_size(int64 size);
+ void set_size(int64_t size);
void set_uuid(const std::string& uuid);
void set_file_path(const base::FilePath& file_path);
void set_last_modified(const base::Time& time);
- void set_key(int64 key);
+ void set_key(int64_t key);
void set_mark_used_callback(const base::Closure& mark_used_callback);
void set_release_callback(const ReleaseCallback& release_callback);
@@ -62,13 +64,13 @@ class CONTENT_EXPORT IndexedDBBlobInfo {
bool is_file_;
std::string uuid_; // Always for Blob; sometimes for File.
base::string16 type_; // Mime type.
- int64 size_; // -1 if unknown for File.
+ int64_t size_; // -1 if unknown for File.
base::string16 file_name_; // Only for File.
base::FilePath file_path_; // Only for File.
base::Time last_modified_; // Only for File; valid only if size is.
// Valid only when this comes out of the database.
- int64 key_;
+ int64_t key_;
base::Closure mark_used_callback_;
ReleaseCallback release_callback_;
};
diff --git a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
index c8ff36f87bb..e659d96a0db 100644
--- a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file.h"
@@ -10,10 +14,12 @@
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/thread_test_helper.h"
+#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/indexed_db/indexed_db_class_factory.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
@@ -47,7 +53,8 @@ namespace content {
// This browser test is aimed towards exercising the IndexedDB bindings and
// the actual implementation that lives in the browser side.
-class IndexedDBBrowserTest : public ContentBrowserTest {
+class IndexedDBBrowserTest : public ContentBrowserTest,
+ public ::testing::WithParamInterface<const char*> {
public:
IndexedDBBrowserTest() : disk_usage_(-1) {}
@@ -119,7 +126,7 @@ class IndexedDBBrowserTest : public ContentBrowserTest {
shell()->web_contents()->GetBrowserContext())->GetQuotaManager());
}
- static void SetTempQuota(int64 bytes, scoped_refptr<QuotaManager> qm) {
+ static void SetTempQuota(int64_t bytes, scoped_refptr<QuotaManager> qm) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -134,7 +141,7 @@ class IndexedDBBrowserTest : public ContentBrowserTest {
ASSERT_TRUE(helper->Run());
}
- virtual int64 RequestDiskUsage() {
+ virtual int64_t RequestDiskUsage() {
PostTaskAndReplyWithResult(
GetContext()->TaskRunner(),
FROM_HERE,
@@ -175,28 +182,16 @@ class IndexedDBBrowserTest : public ContentBrowserTest {
return GetTestClassFactory();
}
- virtual void DidGetDiskUsage(int64 bytes) {
- disk_usage_ = bytes;
- }
+ virtual void DidGetDiskUsage(int64_t bytes) { disk_usage_ = bytes; }
virtual void DidGetBlobFileCount(int count) { blob_file_count_ = count; }
- int64 disk_usage_;
+ int64_t disk_usage_;
int blob_file_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest);
};
-class IndexedDBBrowserTestWithExperimentalAPIs
- : public IndexedDBBrowserTest,
- public ::testing::WithParamInterface<const char*> {
- public:
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitch(
- switches::kEnableExperimentalWebPlatformFeatures);
- }
-};
-
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTest) {
SimpleTest(GetTestUrl("indexeddb", "cursor_test.html"));
}
@@ -242,8 +237,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CallbackAccounting) {
SimpleTest(GetTestUrl("indexeddb", "callback_accounting.html"));
}
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithExperimentalAPIs,
- GetAllMaxMessageSize) {
+IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, GetAllMaxMessageSize) {
SimpleTest(GetTestUrl("indexeddb", "getall_max_message_size.html"));
}
@@ -362,10 +356,10 @@ class IndexedDBBrowserTestWithVersion123456Schema : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion123456Schema,
DestroyTest) {
- int64 original_size = RequestDiskUsage();
+ int64_t original_size = RequestDiskUsage();
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
- int64 new_size = RequestDiskUsage();
+ int64_t new_size = RequestDiskUsage();
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -377,10 +371,10 @@ class IndexedDBBrowserTestWithVersion987654SSVData : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion987654SSVData,
DestroyTest) {
- int64 original_size = RequestDiskUsage();
+ int64_t original_size = RequestDiskUsage();
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
- int64 new_size = RequestDiskUsage();
+ int64_t new_size = RequestDiskUsage();
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -392,10 +386,10 @@ class IndexedDBBrowserTestWithCorruptLevelDB : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithCorruptLevelDB,
DestroyTest) {
- int64 original_size = RequestDiskUsage();
+ int64_t original_size = RequestDiskUsage();
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
- int64 new_size = RequestDiskUsage();
+ int64_t new_size = RequestDiskUsage();
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -407,10 +401,10 @@ class IndexedDBBrowserTestWithMissingSSTFile : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithMissingSSTFile,
DestroyTest) {
- int64 original_size = RequestDiskUsage();
+ int64_t original_size = RequestDiskUsage();
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_missing_table.html"));
- int64 new_size = RequestDiskUsage();
+ int64_t new_size = RequestDiskUsage();
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -422,14 +416,14 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LevelDBLogFileTest) {
base::FilePath log_file(FILE_PATH_LITERAL("LOG"));
base::FilePath log_file_path =
GetContext()->data_path().Append(leveldb_dir).Append(log_file);
- int64 size;
+ int64_t size;
EXPECT_TRUE(base::GetFileSize(log_file_path, &size));
EXPECT_GT(size, 0);
}
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
SimpleTest(GetTestUrl("indexeddb", "fill_up_5k.html"));
- int64 size = RequestDiskUsage();
+ int64_t size = RequestDiskUsage();
const int kQuotaKilobytes = 2;
EXPECT_GT(size, kQuotaKilobytes * 1024);
SetQuota(kQuotaKilobytes);
@@ -491,7 +485,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, BlobsCountAgainstQuota) {
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteForOriginDeletesBlobs) {
SimpleTest(GetTestUrl("indexeddb", "write_20mb_blob.html"));
- int64 size = RequestDiskUsage();
+ int64_t size = RequestDiskUsage();
// This assertion assumes that we do not compress blobs.
EXPECT_GT(size, 20 << 20 /* 20 MB */);
GetContext()->TaskRunner()->PostTask(
@@ -561,7 +555,7 @@ static void CorruptIndexedDBDatabase(
idb_data_path, recursive, base::FileEnumerator::FILES);
for (base::FilePath idb_file = enumerator.Next(); !idb_file.empty();
idb_file = enumerator.Next()) {
- int64 size(0);
+ int64_t size(0);
GetFileSize(idb_file, &size);
if (idb_file.Extension() == FILE_PATH_LITERAL(".ldb")) {
@@ -619,7 +613,7 @@ static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
scoped_ptr<net::test_server::BasicHttpResponse> http_response(
new net::test_server::BasicHttpResponse);
http_response->set_code(net::HTTP_OK);
- return http_response.Pass();
+ return std::move(http_response);
} else if (request_path == "fail" && !request_query.empty()) {
FailClass failure_class = FAIL_CLASS_NOTHING;
FailMethod failure_method = FAIL_METHOD_NOTHING;
@@ -683,7 +677,7 @@ static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
scoped_ptr<net::test_server::BasicHttpResponse> http_response(
new net::test_server::BasicHttpResponse);
http_response->set_code(net::HTTP_OK);
- return http_response.Pass();
+ return std::move(http_response);
}
// A request for a test resource
@@ -696,18 +690,14 @@ static scoped_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
if (!base::ReadFileToString(resource_path, &file_contents))
return scoped_ptr<net::test_server::HttpResponse>();
http_response->set_content(file_contents);
- return http_response.Pass();
+ return std::move(http_response);
}
} // namespace
-// Experimental for IDBObjectStore.getAll()
-using IndexedDBBrowserCorruptionTest = IndexedDBBrowserTestWithExperimentalAPIs;
-
-IN_PROC_BROWSER_TEST_P(IndexedDBBrowserCorruptionTest,
- OperationOnCorruptedOpenDatabase) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, OperationOnCorruptedOpenDatabase) {
ASSERT_TRUE(embedded_test_server()->Started() ||
- embedded_test_server()->InitializeAndWaitUntilReady());
+ embedded_test_server()->Start());
const GURL& origin_url = embedded_test_server()->base_url();
embedded_test_server()->RegisterRequestHandler(
base::Bind(&CorruptDBRequestHandler,
@@ -724,8 +714,8 @@ IN_PROC_BROWSER_TEST_P(IndexedDBBrowserCorruptionTest,
SimpleTest(embedded_test_server()->GetURL(test_file));
}
-INSTANTIATE_TEST_CASE_P(IndexedDBBrowserCorruptionTestInstantiation,
- IndexedDBBrowserCorruptionTest,
+INSTANTIATE_TEST_CASE_P(IndexedDBBrowserTestInstantiation,
+ IndexedDBBrowserTest,
::testing::Values("failGetBlobJournal",
"get",
"getAll",
@@ -738,11 +728,11 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest,
DeleteCompactsBackingStore) {
const GURL test_url = GetTestUrl("indexeddb", "delete_compact.html");
SimpleTest(GURL(test_url.spec() + "#fill"));
- int64 after_filling = RequestDiskUsage();
+ int64_t after_filling = RequestDiskUsage();
EXPECT_GT(after_filling, 0);
SimpleTest(GURL(test_url.spec() + "#purge"));
- int64 after_deleting = RequestDiskUsage();
+ int64_t after_deleting = RequestDiskUsage();
EXPECT_LT(after_deleting, after_filling);
// The above tests verify basic assertions - that filling writes data and
@@ -792,7 +782,15 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, PRE_VersionChangeCrashResilience) {
exit(0);
}
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, VersionChangeCrashResilience) {
+// Fails to cleanup GPU processes on swarming.
+// http://crbug.com/552543
+#if defined(OS_WIN)
+#define MAYBE_VersionChangeCrashResilience DISABLED_VersionChangeCrashResilience
+#else
+#define MAYBE_VersionChangeCrashResilience VersionChangeCrashResilience
+#endif
+IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest,
+ MAYBE_VersionChangeCrashResilience) {
NavigateAndWaitForTitle(shell(), "version_change_crash.html", "#part3",
"pass - part3 - rolled back");
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_callbacks.cc b/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
index 16bb523757b..6a5ca73916e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/indexed_db_callbacks.h"
+#include <stddef.h>
+
#include <algorithm>
#include "base/metrics/histogram.h"
@@ -32,14 +34,14 @@ using storage::ShareableFileReference;
namespace content {
namespace {
-const int32 kNoCursor = -1;
-const int32 kNoDatabaseCallbacks = -1;
-const int64 kNoTransaction = -1;
+const int32_t kNoCursor = -1;
+const int32_t kNoDatabaseCallbacks = -1;
+const int64_t kNoTransaction = -1;
}
IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id)
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id)
: dispatcher_host_(dispatcher_host),
ipc_callbacks_id_(ipc_callbacks_id),
ipc_thread_id_(ipc_thread_id),
@@ -48,13 +50,12 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
ipc_database_id_(kNoDatabase),
ipc_database_callbacks_id_(kNoDatabaseCallbacks),
data_loss_(blink::WebIDBDataLossNone),
- sent_blocked_(false) {
-}
+ sent_blocked_(false) {}
IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- int32 ipc_cursor_id)
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ int32_t ipc_cursor_id)
: dispatcher_host_(dispatcher_host),
ipc_callbacks_id_(ipc_callbacks_id),
ipc_thread_id_(ipc_thread_id),
@@ -63,14 +64,13 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
ipc_database_id_(kNoDatabase),
ipc_database_callbacks_id_(kNoDatabaseCallbacks),
data_loss_(blink::WebIDBDataLossNone),
- sent_blocked_(false) {
-}
+ sent_blocked_(false) {}
IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- int32 ipc_database_callbacks_id,
- int64 host_transaction_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ int32_t ipc_database_callbacks_id,
+ int64_t host_transaction_id,
const GURL& origin_url)
: dispatcher_host_(dispatcher_host),
ipc_callbacks_id_(ipc_callbacks_id),
@@ -81,8 +81,7 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
ipc_database_id_(kNoDatabase),
ipc_database_callbacks_id_(ipc_database_callbacks_id),
data_loss_(blink::WebIDBDataLossNone),
- sent_blocked_(false) {
-}
+ sent_blocked_(false) {}
IndexedDBCallbacks::~IndexedDBCallbacks() {}
@@ -119,7 +118,7 @@ void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
dispatcher_host_ = NULL;
}
-void IndexedDBCallbacks::OnBlocked(int64 existing_version) {
+void IndexedDBCallbacks::OnBlocked(int64_t existing_version) {
DCHECK(dispatcher_host_.get());
DCHECK_EQ(kNoCursor, ipc_cursor_id_);
@@ -151,7 +150,7 @@ void IndexedDBCallbacks::OnDataLoss(blink::WebIDBDataLoss data_loss,
}
void IndexedDBCallbacks::OnUpgradeNeeded(
- int64 old_version,
+ int64_t old_version,
scoped_ptr<IndexedDBConnection> connection,
const IndexedDBDatabaseMetadata& metadata) {
DCHECK(dispatcher_host_.get());
@@ -162,7 +161,7 @@ void IndexedDBCallbacks::OnUpgradeNeeded(
DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
dispatcher_host_->RegisterTransactionId(host_transaction_id_, origin_url_);
- int32 ipc_database_id =
+ int32_t ipc_database_id =
dispatcher_host_->Add(connection.release(), ipc_thread_id_, origin_url_);
if (ipc_database_id < 0)
return;
@@ -197,7 +196,7 @@ void IndexedDBCallbacks::OnSuccess(scoped_ptr<IndexedDBConnection> connection,
scoped_refptr<IndexedDBCallbacks> self(this);
- int32 ipc_object_id = kNoDatabase;
+ int32_t ipc_object_id = kNoDatabase;
// Only register if the connection was not previously sent in OnUpgradeNeeded.
if (ipc_database_id_ == kNoDatabase) {
ipc_object_id = dispatcher_host_->Add(
@@ -348,7 +347,7 @@ void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor,
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
- int32 ipc_object_id = dispatcher_host_->Add(cursor.get());
+ int32_t ipc_object_id = dispatcher_host_->Add(cursor.get());
scoped_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params(
new IndexedDBMsg_CallbacksSuccessIDBCursor_Params());
params->ipc_thread_id = ipc_thread_id_;
@@ -581,7 +580,7 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
dispatcher_host_ = NULL;
}
-void IndexedDBCallbacks::OnSuccess(int64 value) {
+void IndexedDBCallbacks::OnSuccess(int64_t value) {
DCHECK(dispatcher_host_.get());
DCHECK_EQ(kNoCursor, ipc_cursor_id_);
diff --git a/chromium/content/browser/indexed_db/indexed_db_callbacks.h b/chromium/content/browser/indexed_db/indexed_db_callbacks.h
index ed61f797cb6..df102389ae3 100644
--- a/chromium/content/browser/indexed_db/indexed_db_callbacks.h
+++ b/chromium/content/browser/indexed_db/indexed_db_callbacks.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CALLBACKS_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CALLBACKS_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
@@ -34,21 +36,21 @@ class CONTENT_EXPORT IndexedDBCallbacks
public:
// Simple payload responses
IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id);
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id);
// IndexedDBCursor responses
IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- int32 ipc_cursor_id);
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ int32_t ipc_cursor_id);
// IndexedDBDatabase responses
IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- int32 ipc_database_callbacks_id,
- int64 host_transaction_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ int32_t ipc_database_callbacks_id,
+ int64_t host_transaction_id,
const GURL& origin_url);
virtual void OnError(const IndexedDBDatabaseError& error);
@@ -57,13 +59,13 @@ class CONTENT_EXPORT IndexedDBCallbacks
virtual void OnSuccess(const std::vector<base::string16>& string);
// IndexedDBFactory::Open / DeleteDatabase
- virtual void OnBlocked(int64 existing_version);
+ virtual void OnBlocked(int64_t existing_version);
// IndexedDBFactory::Open
virtual void OnDataLoss(blink::WebIDBDataLoss data_loss,
std::string data_loss_message);
virtual void OnUpgradeNeeded(
- int64 old_version,
+ int64_t old_version,
scoped_ptr<IndexedDBConnection> connection,
const content::IndexedDBDatabaseMetadata& metadata);
virtual void OnSuccess(scoped_ptr<IndexedDBConnection> connection,
@@ -99,7 +101,7 @@ class CONTENT_EXPORT IndexedDBCallbacks
// IndexedDBDatabase::Count
// IndexedDBFactory::DeleteDatabase
- virtual void OnSuccess(int64 value);
+ virtual void OnSuccess(int64_t value);
// IndexedDBDatabase::Delete
// IndexedDBCursor::Continue / Advance (when complete)
@@ -120,17 +122,17 @@ class CONTENT_EXPORT IndexedDBCallbacks
// Originally from IndexedDBCallbacks:
scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_;
- int32 ipc_callbacks_id_;
- int32 ipc_thread_id_;
+ int32_t ipc_callbacks_id_;
+ int32_t ipc_thread_id_;
// IndexedDBCursor callbacks ------------------------
- int32 ipc_cursor_id_;
+ int32_t ipc_cursor_id_;
// IndexedDBDatabase callbacks ------------------------
- int64 host_transaction_id_;
+ int64_t host_transaction_id_;
GURL origin_url_;
- int32 ipc_database_id_;
- int32 ipc_database_callbacks_id_;
+ int32_t ipc_database_id_;
+ int32_t ipc_database_callbacks_id_;
// Stored in OnDataLoss, merged with OnUpgradeNeeded response.
blink::WebIDBDataLoss data_loss_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_class_factory.cc b/chromium/content/browser/indexed_db/indexed_db_class_factory.cc
index cb77cca5a6e..6a314698b34 100644
--- a/chromium/content/browser/indexed_db/indexed_db_class_factory.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_class_factory.cc
@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "content/browser/indexed_db/indexed_db_class_factory.h"
+
+#include <utility>
+
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator_impl.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
@@ -33,9 +36,9 @@ IndexedDBDatabase* IndexedDBClassFactory::CreateIndexedDBDatabase(
}
IndexedDBTransaction* IndexedDBClassFactory::CreateIndexedDBTransaction(
- int64 id,
+ int64_t id,
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& scope,
+ const std::set<int64_t>& scope,
blink::WebIDBTransactionMode mode,
IndexedDBDatabase* db,
IndexedDBBackingStore::Transaction* backing_store_transaction) {
@@ -50,7 +53,7 @@ LevelDBTransaction* IndexedDBClassFactory::CreateLevelDBTransaction(
content::LevelDBIteratorImpl* IndexedDBClassFactory::CreateIteratorImpl(
scoped_ptr<leveldb::Iterator> iterator) {
- return new LevelDBIteratorImpl(iterator.Pass());
+ return new LevelDBIteratorImpl(std::move(iterator));
}
} // namespace content
diff --git a/chromium/content/browser/indexed_db/indexed_db_class_factory.h b/chromium/content/browser/indexed_db/indexed_db_class_factory.h
index b2d202653f6..31e520259ff 100644
--- a/chromium/content/browser/indexed_db/indexed_db_class_factory.h
+++ b/chromium/content/browser/indexed_db/indexed_db_class_factory.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CLASS_FACTORY_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CLASS_FACTORY_H_
+#include <stdint.h>
+
#include <set>
#include "base/lazy_instance.h"
@@ -45,9 +47,9 @@ class CONTENT_EXPORT IndexedDBClassFactory {
const IndexedDBDatabase::Identifier& unique_identifier);
virtual IndexedDBTransaction* CreateIndexedDBTransaction(
- int64 id,
+ int64_t id,
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& scope,
+ const std::set<int64_t>& scope,
blink::WebIDBTransactionMode mode,
IndexedDBDatabase* db,
IndexedDBBackingStore::Transaction* backing_store_transaction);
diff --git a/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
index 2b803d0aea3..02636f8134c 100644
--- a/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
@@ -7,6 +7,7 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
diff --git a/chromium/content/browser/indexed_db/indexed_db_connection.h b/chromium/content/browser/indexed_db/indexed_db_connection.h
index 41925d853cb..4d828e5e6ff 100644
--- a/chromium/content/browser/indexed_db/indexed_db_connection.h
+++ b/chromium/content/browser/indexed_db/indexed_db_connection.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CONNECTION_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CONNECTION_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/indexed_db/indexed_db_database.h"
diff --git a/chromium/content/browser/indexed_db/indexed_db_context_impl.cc b/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
index dbc041f2e71..582f16fc6d7 100644
--- a/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -18,6 +18,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
+#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
@@ -286,7 +287,7 @@ int IndexedDBContextImpl::GetOriginBlobFileCount(const GURL& origin_url) {
return count;
}
-int64 IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) {
+int64_t IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) {
DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
if (data_path_.empty() || !IsInOriginSet(origin_url))
return 0;
@@ -463,7 +464,7 @@ void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) {
}
bool IndexedDBContextImpl::WouldBeOverQuota(const GURL& origin_url,
- int64 additional_bytes) {
+ int64_t additional_bytes) {
if (space_available_map_.find(origin_url) == space_available_map_.end()) {
// We haven't heard back from the QuotaManager yet, just let it through.
return false;
@@ -522,10 +523,10 @@ base::FilePath IndexedDBContextImpl::GetLevelDBPath(
.AddExtension(kLevelDBExtension);
}
-int64 IndexedDBContextImpl::ReadUsageFromDisk(const GURL& origin_url) const {
+int64_t IndexedDBContextImpl::ReadUsageFromDisk(const GURL& origin_url) const {
if (data_path_.empty())
return 0;
- int64 total_size = 0;
+ int64_t total_size = 0;
for (const base::FilePath& path : GetStoragePaths(origin_url))
total_size += base::ComputeDirectorySize(path);
return total_size;
@@ -539,9 +540,9 @@ void IndexedDBContextImpl::EnsureDiskUsageCacheInitialized(
void IndexedDBContextImpl::QueryDiskAndUpdateQuotaUsage(
const GURL& origin_url) {
- int64 former_disk_usage = origin_size_map_[origin_url];
- int64 current_disk_usage = ReadUsageFromDisk(origin_url);
- int64 difference = current_disk_usage - former_disk_usage;
+ int64_t former_disk_usage = origin_size_map_[origin_url];
+ int64_t current_disk_usage = ReadUsageFromDisk(origin_url);
+ int64_t difference = current_disk_usage - former_disk_usage;
if (difference) {
origin_size_map_[origin_url] = current_disk_usage;
// quota_manager_proxy() is NULL in unit tests.
@@ -557,8 +558,8 @@ void IndexedDBContextImpl::QueryDiskAndUpdateQuotaUsage(
void IndexedDBContextImpl::GotUsageAndQuota(const GURL& origin_url,
storage::QuotaStatusCode status,
- int64 usage,
- int64 quota) {
+ int64_t usage,
+ int64_t quota) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(status == storage::kQuotaStatusOk ||
status == storage::kQuotaErrorAbort)
@@ -576,8 +577,8 @@ void IndexedDBContextImpl::GotUsageAndQuota(const GURL& origin_url,
}
void IndexedDBContextImpl::GotUpdatedQuota(const GURL& origin_url,
- int64 usage,
- int64 quota) {
+ int64_t usage,
+ int64_t quota) {
DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
space_available_map_[origin_url] = quota - usage;
}
@@ -597,6 +598,10 @@ void IndexedDBContextImpl::QueryAvailableQuota(const GURL& origin_url) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!quota_manager_proxy() || !quota_manager_proxy()->quota_manager())
return;
+
+ // crbug.com/349708
+ TRACE_EVENT0("io", "IndexedDBContextImpl::QueryAvailableQuota");
+
quota_manager_proxy()->quota_manager()->GetUsageAndQuota(
origin_url,
storage::kStorageTypeTemporary,
diff --git a/chromium/content/browser/indexed_db/indexed_db_context_impl.h b/chromium/content/browser/indexed_db/indexed_db_context_impl.h
index 2955a3a2cf1..d175ce46a65 100644
--- a/chromium/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/chromium/content/browser/indexed_db/indexed_db_context_impl.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CONTEXT_IMPL_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CONTEXT_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
@@ -13,6 +16,7 @@
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
@@ -66,7 +70,7 @@ class CONTENT_EXPORT IndexedDBContextImpl
// IndexedDBContext implementation:
base::SequencedTaskRunner* TaskRunner() const override;
std::vector<IndexedDBInfo> GetAllOriginsInfo() override;
- int64 GetOriginDiskUsage(const GURL& origin_url) override;
+ int64_t GetOriginDiskUsage(const GURL& origin_url) override;
void DeleteForOrigin(const GURL& origin_url) override;
void CopyOriginData(const GURL& origin_url,
IndexedDBContext* dest_context) override;
@@ -79,7 +83,7 @@ class CONTENT_EXPORT IndexedDBContextImpl
void ConnectionClosed(const GURL& origin_url, IndexedDBConnection* db);
void TransactionComplete(const GURL& origin_url);
void DatabaseDeleted(const GURL& origin_url);
- bool WouldBeOverQuota(const GURL& origin_url, int64 additional_bytes);
+ bool WouldBeOverQuota(const GURL& origin_url, int64_t additional_bytes);
bool IsOverQuota(const GURL& origin_url);
storage::QuotaManagerProxy* quota_manager_proxy();
@@ -120,20 +124,20 @@ class CONTENT_EXPORT IndexedDBContextImpl
FRIEND_TEST_ALL_PREFIXES(IndexedDBTest, ForceCloseOpenDatabasesOnDelete);
friend class IndexedDBQuotaClientTest;
- typedef std::map<GURL, int64> OriginToSizeMap;
+ typedef std::map<GURL, int64_t> OriginToSizeMap;
class IndexedDBGetUsageAndQuotaCallback;
base::FilePath GetBlobPath(const std::string& origin_id) const;
base::FilePath GetLevelDBPath(const GURL& origin_url) const;
base::FilePath GetLevelDBPath(const std::string& origin_id) const;
- int64 ReadUsageFromDisk(const GURL& origin_url) const;
+ int64_t ReadUsageFromDisk(const GURL& origin_url) const;
void EnsureDiskUsageCacheInitialized(const GURL& origin_url);
void QueryDiskAndUpdateQuotaUsage(const GURL& origin_url);
void GotUsageAndQuota(const GURL& origin_url,
storage::QuotaStatusCode,
- int64 usage,
- int64 quota);
- void GotUpdatedQuota(const GURL& origin_url, int64 usage, int64 quota);
+ int64_t usage,
+ int64_t quota);
+ void GotUpdatedQuota(const GURL& origin_url, int64_t usage, int64_t quota);
void QueryAvailableQuota(const GURL& origin_url);
std::set<GURL>* GetOriginSet();
diff --git a/chromium/content/browser/indexed_db/indexed_db_cursor.cc b/chromium/content/browser/indexed_db/indexed_db_cursor.cc
index 7172dab8f93..05e788cd40e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_cursor.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_cursor.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/indexed_db_cursor.h"
+#include <stddef.h>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -24,7 +26,7 @@ IndexedDBCursor::IndexedDBCursor(
: task_type_(task_type),
cursor_type_(cursor_type),
transaction_(transaction),
- cursor_(cursor.Pass()),
+ cursor_(std::move(cursor)),
closed_(false) {
transaction_->RegisterOpenCursor(this);
}
@@ -47,7 +49,7 @@ void IndexedDBCursor::Continue(scoped_ptr<IndexedDBKey> key,
callbacks));
}
-void IndexedDBCursor::Advance(uint32 count,
+void IndexedDBCursor::Advance(uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE("IndexedDBCursor::Advance");
@@ -58,7 +60,7 @@ void IndexedDBCursor::Advance(uint32 count,
}
void IndexedDBCursor::CursorAdvanceOperation(
- uint32 count,
+ uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* /*transaction*/) {
IDB_TRACE("IndexedDBCursor::CursorAdvanceOperation");
diff --git a/chromium/content/browser/indexed_db/indexed_db_cursor.h b/chromium/content/browser/indexed_db/indexed_db_cursor.h
index 9dc172a4cea..5d1c3184684 100644
--- a/chromium/content/browser/indexed_db/indexed_db_cursor.h
+++ b/chromium/content/browser/indexed_db/indexed_db_cursor.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CURSOR_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CURSOR_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
@@ -27,7 +29,7 @@ class CONTENT_EXPORT IndexedDBCursor
blink::WebIDBTaskType task_type,
IndexedDBTransaction* transaction);
- void Advance(uint32 count, scoped_refptr<IndexedDBCallbacks> callbacks);
+ void Advance(uint32_t count, scoped_refptr<IndexedDBCallbacks> callbacks);
void Continue(scoped_ptr<IndexedDBKey> key,
scoped_ptr<IndexedDBKey> primary_key,
scoped_refptr<IndexedDBCallbacks> callbacks);
@@ -47,7 +49,7 @@ class CONTENT_EXPORT IndexedDBCursor
scoped_ptr<IndexedDBKey> primary_key,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
- void CursorAdvanceOperation(uint32 count,
+ void CursorAdvanceOperation(uint32_t count,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
void CursorPrefetchIterationOperation(
diff --git a/chromium/content/browser/indexed_db/indexed_db_database.cc b/chromium/content/browser/indexed_db/indexed_db_database.cc
index 5334541c20a..3196cd16d83 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_database.cc
@@ -7,9 +7,11 @@
#include <math.h>
#include <limits>
#include <set>
+#include <utility>
#include "base/auto_reset.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/metrics/histogram_macros.h"
@@ -75,25 +77,25 @@ class IndexedDBDatabase::PendingUpgradeCall {
public:
PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks,
scoped_ptr<IndexedDBConnection> connection,
- int64 transaction_id,
- int64 version)
+ int64_t transaction_id,
+ int64_t version)
: callbacks_(callbacks),
- connection_(connection.Pass()),
+ connection_(std::move(connection)),
version_(version),
transaction_id_(transaction_id) {}
scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; }
// Takes ownership of the connection object.
scoped_ptr<IndexedDBConnection> ReleaseConnection() WARN_UNUSED_RESULT {
- return connection_.Pass();
+ return std::move(connection_);
}
- int64 version() const { return version_; }
- int64 transaction_id() const { return transaction_id_; }
+ int64_t version() const { return version_; }
+ int64_t transaction_id() const { return transaction_id_; }
private:
scoped_refptr<IndexedDBCallbacks> callbacks_;
scoped_ptr<IndexedDBConnection> connection_;
- int64 version_;
- const int64 transaction_id_;
+ int64_t version_;
+ const int64_t transaction_id_;
};
// PendingSuccessCall has a IndexedDBConnection* because the connection is now
@@ -103,16 +105,16 @@ class IndexedDBDatabase::PendingSuccessCall {
public:
PendingSuccessCall(scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBConnection* connection,
- int64 version)
+ int64_t version)
: callbacks_(callbacks), connection_(connection), version_(version) {}
scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; }
IndexedDBConnection* connection() const { return connection_; }
- int64 version() const { return version_; }
+ int64_t version() const { return version_; }
private:
scoped_refptr<IndexedDBCallbacks> callbacks_;
IndexedDBConnection* connection_;
- int64 version_;
+ int64_t version_;
};
class IndexedDBDatabase::PendingDeleteCall {
@@ -162,7 +164,7 @@ IndexedDBDatabase::IndexedDBDatabase(const base::string16& name,
void IndexedDBDatabase::AddObjectStore(
const IndexedDBObjectStoreMetadata& object_store,
- int64 new_max_object_store_id) {
+ int64_t new_max_object_store_id) {
DCHECK(metadata_.object_stores.find(object_store.id) ==
metadata_.object_stores.end());
if (new_max_object_store_id != IndexedDBObjectStoreMetadata::kInvalidId) {
@@ -172,15 +174,15 @@ void IndexedDBDatabase::AddObjectStore(
metadata_.object_stores[object_store.id] = object_store;
}
-void IndexedDBDatabase::RemoveObjectStore(int64 object_store_id) {
+void IndexedDBDatabase::RemoveObjectStore(int64_t object_store_id) {
DCHECK(metadata_.object_stores.find(object_store_id) !=
metadata_.object_stores.end());
metadata_.object_stores.erase(object_store_id);
}
-void IndexedDBDatabase::AddIndex(int64 object_store_id,
+void IndexedDBDatabase::AddIndex(int64_t object_store_id,
const IndexedDBIndexMetadata& index,
- int64 new_max_index_id) {
+ int64_t new_max_index_id) {
DCHECK(metadata_.object_stores.find(object_store_id) !=
metadata_.object_stores.end());
IndexedDBObjectStoreMetadata object_store =
@@ -195,7 +197,7 @@ void IndexedDBDatabase::AddIndex(int64 object_store_id,
metadata_.object_stores[object_store_id] = object_store;
}
-void IndexedDBDatabase::RemoveIndex(int64 object_store_id, int64 index_id) {
+void IndexedDBDatabase::RemoveIndex(int64_t object_store_id, int64_t index_id) {
DCHECK(metadata_.object_stores.find(object_store_id) !=
metadata_.object_stores.end());
IndexedDBObjectStoreMetadata object_store =
@@ -239,11 +241,11 @@ scoped_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection(
new IndexedDBConnection(this, database_callbacks));
connections_.insert(connection.get());
backing_store_->GrantChildProcessPermissions(child_process_id);
- return connection.Pass();
+ return connection;
}
IndexedDBTransaction* IndexedDBDatabase::GetTransaction(
- int64 transaction_id) const {
+ int64_t transaction_id) const {
TransactionMap::const_iterator trans_iterator =
transactions_.find(transaction_id);
if (trans_iterator == transactions_.end())
@@ -251,7 +253,7 @@ IndexedDBTransaction* IndexedDBDatabase::GetTransaction(
return trans_iterator->second;
}
-bool IndexedDBDatabase::ValidateObjectStoreId(int64 object_store_id) const {
+bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const {
if (!ContainsKey(metadata_.object_stores, object_store_id)) {
DLOG(ERROR) << "Invalid object_store_id";
return false;
@@ -259,8 +261,9 @@ bool IndexedDBDatabase::ValidateObjectStoreId(int64 object_store_id) const {
return true;
}
-bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(int64 object_store_id,
- int64 index_id) const {
+bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(
+ int64_t object_store_id,
+ int64_t index_id) const {
if (!ValidateObjectStoreId(object_store_id))
return false;
const IndexedDBObjectStoreMetadata& object_store_metadata =
@@ -273,8 +276,8 @@ bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(int64 object_store_id,
}
bool IndexedDBDatabase::ValidateObjectStoreIdAndOptionalIndexId(
- int64 object_store_id,
- int64 index_id) const {
+ int64_t object_store_id,
+ int64_t index_id) const {
if (!ValidateObjectStoreId(object_store_id))
return false;
const IndexedDBObjectStoreMetadata& object_store_metadata =
@@ -288,8 +291,8 @@ bool IndexedDBDatabase::ValidateObjectStoreIdAndOptionalIndexId(
}
bool IndexedDBDatabase::ValidateObjectStoreIdAndNewIndexId(
- int64 object_store_id,
- int64 index_id) const {
+ int64_t object_store_id,
+ int64_t index_id) const {
if (!ValidateObjectStoreId(object_store_id))
return false;
const IndexedDBObjectStoreMetadata& object_store_metadata =
@@ -301,8 +304,8 @@ bool IndexedDBDatabase::ValidateObjectStoreIdAndNewIndexId(
return true;
}
-void IndexedDBDatabase::CreateObjectStore(int64 transaction_id,
- int64 object_store_id,
+void IndexedDBDatabase::CreateObjectStore(int64_t transaction_id,
+ int64_t object_store_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment) {
@@ -358,8 +361,8 @@ void IndexedDBDatabase::CreateObjectStore(int64 transaction_id,
object_store_id));
}
-void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id,
- int64 object_store_id) {
+void IndexedDBDatabase::DeleteObjectStore(int64_t transaction_id,
+ int64_t object_store_id) {
IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id);
IndexedDBTransaction* transaction = GetTransaction(transaction_id);
if (!transaction)
@@ -375,9 +378,9 @@ void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id,
object_store_id));
}
-void IndexedDBDatabase::CreateIndex(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+void IndexedDBDatabase::CreateIndex(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool unique,
@@ -427,17 +430,17 @@ void IndexedDBDatabase::CreateIndex(int64 transaction_id,
}
void IndexedDBDatabase::CreateIndexAbortOperation(
- int64 object_store_id,
- int64 index_id,
+ int64_t object_store_id,
+ int64_t index_id,
IndexedDBTransaction* transaction) {
DCHECK(!transaction);
IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation");
RemoveIndex(object_store_id, index_id);
}
-void IndexedDBDatabase::DeleteIndex(int64 transaction_id,
- int64 object_store_id,
- int64 index_id) {
+void IndexedDBDatabase::DeleteIndex(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id) {
IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id);
IndexedDBTransaction* transaction = GetTransaction(transaction_id);
if (!transaction)
@@ -455,8 +458,8 @@ void IndexedDBDatabase::DeleteIndex(int64 transaction_id,
}
void IndexedDBDatabase::DeleteIndexOperation(
- int64 object_store_id,
- int64 index_id,
+ int64_t object_store_id,
+ int64_t index_id,
IndexedDBTransaction* transaction) {
IDB_TRACE1(
"IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id());
@@ -491,7 +494,7 @@ void IndexedDBDatabase::DeleteIndexOperation(
}
void IndexedDBDatabase::DeleteIndexAbortOperation(
- int64 object_store_id,
+ int64_t object_store_id,
const IndexedDBIndexMetadata& index_metadata,
IndexedDBTransaction* transaction) {
DCHECK(!transaction);
@@ -499,7 +502,7 @@ void IndexedDBDatabase::DeleteIndexAbortOperation(
AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId);
}
-void IndexedDBDatabase::Commit(int64 transaction_id) {
+void IndexedDBDatabase::Commit(int64_t transaction_id) {
// The frontend suggests that we commit, but we may have previously initiated
// an abort, and so have disposed of the transaction. on_abort has already
// been dispatched to the frontend, so it will find out about that
@@ -516,7 +519,7 @@ void IndexedDBDatabase::Commit(int64 transaction_id) {
}
}
-void IndexedDBDatabase::Abort(int64 transaction_id) {
+void IndexedDBDatabase::Abort(int64_t transaction_id) {
// If the transaction is unknown, then it has already been aborted by the
// backend before this call so it is safe to ignore it.
IDB_TRACE1("IndexedDBDatabase::Abort", "txn.id", transaction_id);
@@ -525,7 +528,7 @@ void IndexedDBDatabase::Abort(int64 transaction_id) {
transaction->Abort();
}
-void IndexedDBDatabase::Abort(int64 transaction_id,
+void IndexedDBDatabase::Abort(int64_t transaction_id,
const IndexedDBDatabaseError& error) {
IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id);
// If the transaction is unknown, then it has already been aborted by the
@@ -535,12 +538,12 @@ void IndexedDBDatabase::Abort(int64 transaction_id,
transaction->Abort(error);
}
-void IndexedDBDatabase::GetAll(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+void IndexedDBDatabase::GetAll(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
bool key_only,
- int64 max_count,
+ int64_t max_count,
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id);
IndexedDBTransaction* transaction = GetTransaction(transaction_id);
@@ -552,14 +555,14 @@ void IndexedDBDatabase::GetAll(int64 transaction_id,
transaction->ScheduleTask(base::Bind(
&IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id,
- Passed(&key_range),
+ base::Passed(&key_range),
key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
max_count, callbacks));
}
-void IndexedDBDatabase::Get(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+void IndexedDBDatabase::Get(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
bool key_only,
scoped_refptr<IndexedDBCallbacks> callbacks) {
@@ -572,18 +575,15 @@ void IndexedDBDatabase::Get(int64 transaction_id,
return;
transaction->ScheduleTask(base::Bind(
- &IndexedDBDatabase::GetOperation,
- this,
- object_store_id,
- index_id,
- Passed(&key_range),
+ &IndexedDBDatabase::GetOperation, this, object_store_id, index_id,
+ base::Passed(&key_range),
key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
callbacks));
}
void IndexedDBDatabase::GetOperation(
- int64 object_store_id,
- int64 index_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
indexed_db::CursorType cursor_type,
scoped_refptr<IndexedDBCallbacks> callbacks,
@@ -744,11 +744,11 @@ void IndexedDBDatabase::GetOperation(
}
void IndexedDBDatabase::GetAllOperation(
- int64 object_store_id,
- int64 index_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
indexed_db::CursorType cursor_type,
- int64 max_count,
+ int64_t max_count,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction) {
IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id());
@@ -818,7 +818,7 @@ void IndexedDBDatabase::GetAllOperation(
!object_store_metadata.key_path.IsNull();
size_t response_size = kMaxIDBMessageOverhead;
- int64 num_found_items = 0;
+ int64_t num_found_items = 0;
while (num_found_items++ < max_count) {
bool cursor_valid;
if (did_first_seek) {
@@ -883,11 +883,11 @@ void IndexedDBDatabase::GetAllOperation(
static scoped_ptr<IndexedDBKey> GenerateKey(
IndexedDBBackingStore* backing_store,
IndexedDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id) {
- const int64 max_generator_value =
+ int64_t database_id,
+ int64_t object_store_id) {
+ const int64_t max_generator_value =
9007199254740992LL; // Maximum integer storable as ECMAScript number.
- int64 current_number;
+ int64_t current_number;
leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber(
transaction->BackingStoreTransaction(),
database_id,
@@ -905,22 +905,19 @@ static scoped_ptr<IndexedDBKey> GenerateKey(
static leveldb::Status UpdateKeyGenerator(IndexedDBBackingStore* backing_store,
IndexedDBTransaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
bool check_current) {
DCHECK_EQ(WebIDBKeyTypeNumber, key.type());
return backing_store->MaybeUpdateKeyGeneratorCurrentNumber(
- transaction->BackingStoreTransaction(),
- database_id,
- object_store_id,
- static_cast<int64>(floor(key.number())) + 1,
- check_current);
+ transaction->BackingStoreTransaction(), database_id, object_store_id,
+ static_cast<int64_t>(floor(key.number())) + 1, check_current);
}
struct IndexedDBDatabase::PutOperationParams {
PutOperationParams() {}
- int64 object_store_id;
+ int64_t object_store_id;
IndexedDBValue value;
ScopedVector<storage::BlobDataHandle> handles;
scoped_ptr<IndexedDBKey> key;
@@ -932,8 +929,8 @@ struct IndexedDBDatabase::PutOperationParams {
DISALLOW_COPY_AND_ASSIGN(PutOperationParams);
};
-void IndexedDBDatabase::Put(int64 transaction_id,
- int64 object_store_id,
+void IndexedDBDatabase::Put(int64_t transaction_id,
+ int64_t object_store_id,
IndexedDBValue* value,
ScopedVector<storage::BlobDataHandle>* handles,
scoped_ptr<IndexedDBKey> key,
@@ -955,7 +952,7 @@ void IndexedDBDatabase::Put(int64 transaction_id,
params->object_store_id = object_store_id;
params->value.swap(*value);
params->handles.swap(*handles);
- params->key = key.Pass();
+ params->key = std::move(key);
params->put_mode = put_mode;
params->callbacks = callbacks;
params->index_keys = index_keys;
@@ -987,9 +984,9 @@ void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params,
"Maximum key generator value reached."));
return;
}
- key = auto_inc_key.Pass();
+ key = std::move(auto_inc_key);
} else {
- key = params->key.Pass();
+ key = std::move(params->key);
}
DCHECK(key->IsValid());
@@ -1105,8 +1102,8 @@ void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params,
}
}
-void IndexedDBDatabase::SetIndexKeys(int64 transaction_id,
- int64 object_store_id,
+void IndexedDBDatabase::SetIndexKeys(int64_t transaction_id,
+ int64_t object_store_id,
scoped_ptr<IndexedDBKey> primary_key,
const std::vector<IndexKeys>& index_keys) {
IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id);
@@ -1181,9 +1178,9 @@ void IndexedDBDatabase::SetIndexKeys(int64 transaction_id,
}
}
-void IndexedDBDatabase::SetIndexesReady(int64 transaction_id,
- int64,
- const std::vector<int64>& index_ids) {
+void IndexedDBDatabase::SetIndexesReady(int64_t transaction_id,
+ int64_t,
+ const std::vector<int64_t>& index_ids) {
IndexedDBTransaction* transaction = GetTransaction(transaction_id);
if (!transaction)
return;
@@ -1205,8 +1202,8 @@ void IndexedDBDatabase::SetIndexesReadyOperation(
struct IndexedDBDatabase::OpenCursorOperationParams {
OpenCursorOperationParams() {}
- int64 object_store_id;
- int64 index_id;
+ int64_t object_store_id;
+ int64_t index_id;
scoped_ptr<IndexedDBKeyRange> key_range;
blink::WebIDBCursorDirection direction;
indexed_db::CursorType cursor_type;
@@ -1218,9 +1215,9 @@ struct IndexedDBDatabase::OpenCursorOperationParams {
};
void IndexedDBDatabase::OpenCursor(
- int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
blink::WebIDBCursorDirection direction,
bool key_only,
@@ -1237,7 +1234,7 @@ void IndexedDBDatabase::OpenCursor(
scoped_ptr<OpenCursorOperationParams> params(new OpenCursorOperationParams());
params->object_store_id = object_store_id;
params->index_id = index_id;
- params->key_range = key_range.Pass();
+ params->key_range = std::move(key_range);
params->direction = direction;
params->cursor_type =
key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE;
@@ -1321,17 +1318,15 @@ void IndexedDBDatabase::OpenCursorOperation(
}
scoped_refptr<IndexedDBCursor> cursor =
- new IndexedDBCursor(backing_store_cursor.Pass(),
- params->cursor_type,
- params->task_type,
- transaction);
+ new IndexedDBCursor(std::move(backing_store_cursor), params->cursor_type,
+ params->task_type, transaction);
params->callbacks->OnSuccess(
cursor, cursor->key(), cursor->primary_key(), cursor->Value());
}
-void IndexedDBDatabase::Count(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+void IndexedDBDatabase::Count(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id);
@@ -1351,13 +1346,13 @@ void IndexedDBDatabase::Count(int64 transaction_id,
}
void IndexedDBDatabase::CountOperation(
- int64 object_store_id,
- int64 index_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction) {
IDB_TRACE1("IndexedDBDatabase::CountOperation", "txn.id", transaction->id());
- uint32 count = 0;
+ uint32_t count = 0;
scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
leveldb::Status s;
@@ -1403,8 +1398,8 @@ void IndexedDBDatabase::CountOperation(
}
void IndexedDBDatabase::DeleteRange(
- int64 transaction_id,
- int64 object_store_id,
+ int64_t transaction_id,
+ int64_t object_store_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id);
@@ -1424,7 +1419,7 @@ void IndexedDBDatabase::DeleteRange(
}
void IndexedDBDatabase::DeleteRangeOperation(
- int64 object_store_id,
+ int64_t object_store_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction) {
@@ -1450,8 +1445,8 @@ void IndexedDBDatabase::DeleteRangeOperation(
callbacks->OnSuccess();
}
-void IndexedDBDatabase::Clear(int64 transaction_id,
- int64 object_store_id,
+void IndexedDBDatabase::Clear(int64_t transaction_id,
+ int64_t object_store_id,
scoped_refptr<IndexedDBCallbacks> callbacks) {
IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id);
IndexedDBTransaction* transaction = GetTransaction(transaction_id);
@@ -1467,7 +1462,7 @@ void IndexedDBDatabase::Clear(int64 transaction_id,
}
void IndexedDBDatabase::ClearOperation(
- int64 object_store_id,
+ int64_t object_store_id,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction) {
IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id());
@@ -1487,7 +1482,7 @@ void IndexedDBDatabase::ClearOperation(
}
void IndexedDBDatabase::DeleteObjectStoreOperation(
- int64 object_store_id,
+ int64_t object_store_id,
IndexedDBTransaction* transaction) {
IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation",
"txn.id",
@@ -1520,13 +1515,13 @@ void IndexedDBDatabase::DeleteObjectStoreOperation(
}
void IndexedDBDatabase::VersionChangeOperation(
- int64 version,
+ int64_t version,
scoped_refptr<IndexedDBCallbacks> callbacks,
scoped_ptr<IndexedDBConnection> connection,
IndexedDBTransaction* transaction) {
IDB_TRACE1(
"IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id());
- int64 old_version = metadata_.int_version;
+ int64_t old_version = metadata_.int_version;
DCHECK_GT(version, old_version);
if (!backing_store_->UpdateIDBDatabaseIntVersion(
@@ -1552,7 +1547,7 @@ void IndexedDBDatabase::VersionChangeOperation(
DCHECK(!pending_second_half_open_);
pending_second_half_open_.reset(
new PendingSuccessCall(callbacks, connection.get(), version));
- callbacks->OnUpgradeNeeded(old_version, connection.Pass(), metadata());
+ callbacks->OnUpgradeNeeded(old_version, std::move(connection), metadata());
}
void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
@@ -1570,7 +1565,7 @@ void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
// Connection was already minted for OnUpgradeNeeded callback.
scoped_ptr<IndexedDBConnection> connection;
- pending_second_half_open_->callbacks()->OnSuccess(connection.Pass(),
+ pending_second_half_open_->callbacks()->OnSuccess(std::move(connection),
this->metadata());
} else {
pending_second_half_open_->callbacks()->OnError(
@@ -1623,7 +1618,7 @@ void IndexedDBDatabase::ProcessPendingCalls() {
DCHECK(pending_run_version_change_transaction_call_->version() >
metadata_.int_version);
scoped_ptr<PendingUpgradeCall> pending_call =
- pending_run_version_change_transaction_call_.Pass();
+ std::move(pending_run_version_change_transaction_call_);
RunVersionChangeTransactionFinal(pending_call->callbacks(),
pending_call->ReleaseConnection(),
pending_call->transaction_id(),
@@ -1663,9 +1658,9 @@ void IndexedDBDatabase::ProcessPendingCalls() {
}
void IndexedDBDatabase::CreateTransaction(
- int64 transaction_id,
+ int64_t transaction_id,
IndexedDBConnection* connection,
- const std::vector<int64>& object_store_ids,
+ const std::vector<int64_t>& object_store_ids,
blink::WebIDBTransactionMode mode) {
IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id);
DCHECK(connections_.count(connection));
@@ -1673,11 +1668,27 @@ void IndexedDBDatabase::CreateTransaction(
if (transactions_.find(transaction_id) != transactions_.end())
return;
+ UMA_HISTOGRAM_COUNTS_1000(
+ "WebCore.IndexedDB.Database.OutstandingTransactionCount",
+ transactions_.size());
+
+ // Throttle transaction creation so that a renderer in a tight loop can't
+ // cause browser memory to grow unbounded by creating transactions faster
+ // than they can be processed.
+ const size_t kMaxTransactionCount = 256;
+ if (transactions_.size() >= kMaxTransactionCount) {
+ connection->callbacks()->OnAbort(
+ transaction_id, IndexedDBDatabaseError(
+ blink::WebIDBDatabaseExceptionUnknownError,
+ "Internal error: Too many transactions queued."));
+ return;
+ }
+
// The transaction will add itself to this database's coordinator, which
// manages the lifetime of the object.
TransactionCreated(IndexedDBClassFactory::Get()->CreateIndexedDBTransaction(
transaction_id, connection->callbacks(),
- std::set<int64>(object_store_ids.begin(), object_store_ids.end()), mode,
+ std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode,
this, new IndexedDBBackingStore::Transaction(backing_store_.get())));
}
@@ -1747,7 +1758,7 @@ void IndexedDBDatabase::OpenConnection(
}
// We may need to change the version.
- int64 local_version = connection.version;
+ int64_t local_version = connection.version;
if (local_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) {
if (!is_new_database) {
connection.callbacks->OnSuccess(
@@ -1788,8 +1799,8 @@ void IndexedDBDatabase::OpenConnection(
void IndexedDBDatabase::RunVersionChangeTransaction(
scoped_refptr<IndexedDBCallbacks> callbacks,
scoped_ptr<IndexedDBConnection> connection,
- int64 transaction_id,
- int64 requested_version) {
+ int64_t transaction_id,
+ int64_t requested_version) {
DCHECK(callbacks.get());
DCHECK(connections_.count(connection.get()));
if (ConnectionCount() > 1) {
@@ -1807,20 +1818,19 @@ void IndexedDBDatabase::RunVersionChangeTransaction(
DCHECK(!pending_run_version_change_transaction_call_);
pending_run_version_change_transaction_call_.reset(new PendingUpgradeCall(
- callbacks, connection.Pass(), transaction_id, requested_version));
+ callbacks, std::move(connection), transaction_id, requested_version));
return;
}
- RunVersionChangeTransactionFinal(
- callbacks, connection.Pass(), transaction_id, requested_version);
+ RunVersionChangeTransactionFinal(callbacks, std::move(connection),
+ transaction_id, requested_version);
}
void IndexedDBDatabase::RunVersionChangeTransactionFinal(
scoped_refptr<IndexedDBCallbacks> callbacks,
scoped_ptr<IndexedDBConnection> connection,
- int64 transaction_id,
- int64 requested_version) {
-
- std::vector<int64> object_store_ids;
+ int64_t transaction_id,
+ int64_t requested_version) {
+ std::vector<int64_t> object_store_ids;
CreateTransaction(transaction_id,
connection.get(),
object_store_ids,
@@ -1874,7 +1884,7 @@ void IndexedDBDatabase::DeleteDatabaseFinal(
}
return;
}
- int64 old_version = metadata_.int_version;
+ int64_t old_version = metadata_.int_version;
metadata_.version = kNoStringVersion;
metadata_.id = kInvalidId;
metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION;
@@ -1950,7 +1960,7 @@ void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) {
}
void IndexedDBDatabase::CreateObjectStoreAbortOperation(
- int64 object_store_id,
+ int64_t object_store_id,
IndexedDBTransaction* transaction) {
DCHECK(!transaction);
IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation");
@@ -1968,7 +1978,7 @@ void IndexedDBDatabase::DeleteObjectStoreAbortOperation(
void IndexedDBDatabase::VersionChangeAbortOperation(
const base::string16& previous_version,
- int64 previous_int_version,
+ int64_t previous_int_version,
IndexedDBTransaction* transaction) {
DCHECK(!transaction);
IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation");
diff --git a/chromium/content/browser/indexed_db/indexed_db_database.h b/chromium/content/browser/indexed_db/indexed_db_database.h
index 66bfe5dc3cc..0049e6c20ee 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database.h
+++ b/chromium/content/browser/indexed_db/indexed_db_database.h
@@ -5,13 +5,16 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/indexed_db/indexed_db.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
@@ -39,13 +42,13 @@ class CONTENT_EXPORT IndexedDBDatabase
: NON_EXPORTED_BASE(public base::RefCounted<IndexedDBDatabase>) {
public:
// An index and corresponding set of keys
- typedef std::pair<int64, std::vector<IndexedDBKey> > IndexKeys;
+ typedef std::pair<int64_t, std::vector<IndexedDBKey>> IndexKeys;
// Identifier is pair of (origin url, database name).
typedef std::pair<GURL, base::string16> Identifier;
- static const int64 kInvalidId = 0;
- static const int64 kMinimumIndexId = 30;
+ static const int64_t kInvalidId = 0;
+ static const int64_t kMinimumIndexId = 30;
static scoped_refptr<IndexedDBDatabase> Create(
const base::string16& name,
@@ -57,30 +60,30 @@ class CONTENT_EXPORT IndexedDBDatabase
const Identifier& identifier() const { return identifier_; }
IndexedDBBackingStore* backing_store() { return backing_store_.get(); }
- int64 id() const { return metadata_.id; }
+ int64_t id() const { return metadata_.id; }
const base::string16& name() const { return metadata_.name; }
void AddObjectStore(const IndexedDBObjectStoreMetadata& metadata,
- int64 new_max_object_store_id);
- void RemoveObjectStore(int64 object_store_id);
- void AddIndex(int64 object_store_id,
+ int64_t new_max_object_store_id);
+ void RemoveObjectStore(int64_t object_store_id);
+ void AddIndex(int64_t object_store_id,
const IndexedDBIndexMetadata& metadata,
- int64 new_max_index_id);
- void RemoveIndex(int64 object_store_id, int64 index_id);
+ int64_t new_max_index_id);
+ void RemoveIndex(int64_t object_store_id, int64_t index_id);
void OpenConnection(const IndexedDBPendingConnection& connection);
void DeleteDatabase(scoped_refptr<IndexedDBCallbacks> callbacks);
const IndexedDBDatabaseMetadata& metadata() const { return metadata_; }
- void CreateObjectStore(int64 transaction_id,
- int64 object_store_id,
+ void CreateObjectStore(int64_t transaction_id,
+ int64_t object_store_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment);
- void DeleteObjectStore(int64 transaction_id, int64 object_store_id);
- void CreateTransaction(int64 transaction_id,
+ void DeleteObjectStore(int64_t transaction_id, int64_t object_store_id);
+ void CreateTransaction(int64_t transaction_id,
IndexedDBConnection* connection,
- const std::vector<int64>& object_store_ids,
+ const std::vector<int64_t>& object_store_ids,
blink::WebIDBTransactionMode mode);
void Close(IndexedDBConnection* connection, bool forced);
void ForceClose();
@@ -90,18 +93,20 @@ class CONTENT_EXPORT IndexedDBDatabase
// pending connection.
void VersionChangeIgnored();
- void Commit(int64 transaction_id);
- void Abort(int64 transaction_id);
- void Abort(int64 transaction_id, const IndexedDBDatabaseError& error);
+ void Commit(int64_t transaction_id);
+ void Abort(int64_t transaction_id);
+ void Abort(int64_t transaction_id, const IndexedDBDatabaseError& error);
- void CreateIndex(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+ void CreateIndex(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
const base::string16& name,
const IndexedDBKeyPath& key_path,
bool unique,
bool multi_entry);
- void DeleteIndex(int64 transaction_id, int64 object_store_id, int64 index_id);
+ void DeleteIndex(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id);
IndexedDBTransactionCoordinator& transaction_coordinator() {
return transaction_coordinator_;
@@ -116,53 +121,53 @@ class CONTENT_EXPORT IndexedDBDatabase
// Called by transactions to report failure committing to the backing store.
void TransactionCommitFailed(const leveldb::Status& status);
- void Get(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+ void Get(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
bool key_only,
scoped_refptr<IndexedDBCallbacks> callbacks);
- void GetAll(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+ void GetAll(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
bool key_only,
- int64 max_count,
+ int64_t max_count,
scoped_refptr<IndexedDBCallbacks> callbacks);
- void Put(int64 transaction_id,
- int64 object_store_id,
+ void Put(int64_t transaction_id,
+ int64_t object_store_id,
IndexedDBValue* value,
ScopedVector<storage::BlobDataHandle>* handles,
scoped_ptr<IndexedDBKey> key,
blink::WebIDBPutMode mode,
scoped_refptr<IndexedDBCallbacks> callbacks,
const std::vector<IndexKeys>& index_keys);
- void SetIndexKeys(int64 transaction_id,
- int64 object_store_id,
+ void SetIndexKeys(int64_t transaction_id,
+ int64_t object_store_id,
scoped_ptr<IndexedDBKey> primary_key,
const std::vector<IndexKeys>& index_keys);
- void SetIndexesReady(int64 transaction_id,
- int64 object_store_id,
- const std::vector<int64>& index_ids);
- void OpenCursor(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+ void SetIndexesReady(int64_t transaction_id,
+ int64_t object_store_id,
+ const std::vector<int64_t>& index_ids);
+ void OpenCursor(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
blink::WebIDBCursorDirection,
bool key_only,
blink::WebIDBTaskType task_type,
scoped_refptr<IndexedDBCallbacks> callbacks);
- void Count(int64 transaction_id,
- int64 object_store_id,
- int64 index_id,
+ void Count(int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks);
- void DeleteRange(int64 transaction_id,
- int64 object_store_id,
+ void DeleteRange(int64_t transaction_id,
+ int64_t object_store_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks);
- void Clear(int64 transaction_id,
- int64 object_store_id,
+ void Clear(int64_t transaction_id,
+ int64_t object_store_id,
scoped_refptr<IndexedDBCallbacks> callbacks);
// Number of connections that have progressed passed initial open call.
@@ -177,41 +182,40 @@ class CONTENT_EXPORT IndexedDBDatabase
size_t PendingDeleteCount() const;
// Asynchronous tasks scheduled within transactions:
- void CreateObjectStoreAbortOperation(int64 object_store_id,
+ void CreateObjectStoreAbortOperation(int64_t object_store_id,
IndexedDBTransaction* transaction);
- void DeleteObjectStoreOperation(
- int64 object_store_id,
- IndexedDBTransaction* transaction);
+ void DeleteObjectStoreOperation(int64_t object_store_id,
+ IndexedDBTransaction* transaction);
void DeleteObjectStoreAbortOperation(
const IndexedDBObjectStoreMetadata& object_store_metadata,
IndexedDBTransaction* transaction);
- void VersionChangeOperation(int64 version,
+ void VersionChangeOperation(int64_t version,
scoped_refptr<IndexedDBCallbacks> callbacks,
scoped_ptr<IndexedDBConnection> connection,
IndexedDBTransaction* transaction);
void VersionChangeAbortOperation(const base::string16& previous_version,
- int64 previous_int_version,
+ int64_t previous_int_version,
IndexedDBTransaction* transaction);
- void DeleteIndexOperation(int64 object_store_id,
- int64 index_id,
+ void DeleteIndexOperation(int64_t object_store_id,
+ int64_t index_id,
IndexedDBTransaction* transaction);
- void CreateIndexAbortOperation(int64 object_store_id,
- int64 index_id,
+ void CreateIndexAbortOperation(int64_t object_store_id,
+ int64_t index_id,
IndexedDBTransaction* transaction);
- void DeleteIndexAbortOperation(int64 object_store_id,
+ void DeleteIndexAbortOperation(int64_t object_store_id,
const IndexedDBIndexMetadata& index_metadata,
IndexedDBTransaction* transaction);
- void GetOperation(int64 object_store_id,
- int64 index_id,
+ void GetOperation(int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
indexed_db::CursorType cursor_type,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
- void GetAllOperation(int64 object_store_id,
- int64 index_id,
+ void GetAllOperation(int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
indexed_db::CursorType cursor_type,
- int64 max_count,
+ int64_t max_count,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
struct PutOperationParams;
@@ -222,16 +226,16 @@ class CONTENT_EXPORT IndexedDBDatabase
struct OpenCursorOperationParams;
void OpenCursorOperation(scoped_ptr<OpenCursorOperationParams> params,
IndexedDBTransaction* transaction);
- void CountOperation(int64 object_store_id,
- int64 index_id,
+ void CountOperation(int64_t object_store_id,
+ int64_t index_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
- void DeleteRangeOperation(int64 object_store_id,
+ void DeleteRangeOperation(int64_t object_store_id,
scoped_ptr<IndexedDBKeyRange> key_range,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
- void ClearOperation(int64 object_store_id,
+ void ClearOperation(int64_t object_store_id,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
@@ -253,7 +257,7 @@ class CONTENT_EXPORT IndexedDBDatabase
class PendingSuccessCall;
class PendingUpgradeCall;
- typedef std::map<int64, IndexedDBTransaction*> TransactionMap;
+ typedef std::map<int64_t, IndexedDBTransaction*> TransactionMap;
typedef std::list<IndexedDBPendingConnection> PendingOpenCallList;
typedef std::list<PendingDeleteCall*> PendingDeleteCallList;
typedef list_set<IndexedDBConnection*> ConnectionSet;
@@ -262,13 +266,13 @@ class CONTENT_EXPORT IndexedDBDatabase
leveldb::Status OpenInternal();
void RunVersionChangeTransaction(scoped_refptr<IndexedDBCallbacks> callbacks,
scoped_ptr<IndexedDBConnection> connection,
- int64 transaction_id,
- int64 requested_version);
+ int64_t transaction_id,
+ int64_t requested_version);
void RunVersionChangeTransactionFinal(
scoped_refptr<IndexedDBCallbacks> callbacks,
scoped_ptr<IndexedDBConnection> connection,
- int64 transaction_id,
- int64 requested_version);
+ int64_t transaction_id,
+ int64_t requested_version);
void ProcessPendingCalls();
bool IsDeleteDatabaseBlocked() const;
@@ -278,15 +282,15 @@ class CONTENT_EXPORT IndexedDBDatabase
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
int child_process_id);
- IndexedDBTransaction* GetTransaction(int64 transaction_id) const;
+ IndexedDBTransaction* GetTransaction(int64_t transaction_id) const;
- bool ValidateObjectStoreId(int64 object_store_id) const;
- bool ValidateObjectStoreIdAndIndexId(int64 object_store_id,
- int64 index_id) const;
- bool ValidateObjectStoreIdAndOptionalIndexId(int64 object_store_id,
- int64 index_id) const;
- bool ValidateObjectStoreIdAndNewIndexId(int64 object_store_id,
- int64 index_id) const;
+ bool ValidateObjectStoreId(int64_t object_store_id) const;
+ bool ValidateObjectStoreIdAndIndexId(int64_t object_store_id,
+ int64_t index_id) const;
+ bool ValidateObjectStoreIdAndOptionalIndexId(int64_t object_store_id,
+ int64_t index_id) const;
+ bool ValidateObjectStoreIdAndNewIndexId(int64_t object_store_id,
+ int64_t index_id) const;
scoped_refptr<IndexedDBBackingStore> backing_store_;
IndexedDBDatabaseMetadata metadata_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc b/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc
index 3d47ad0c11c..35b15c3bce8 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc
@@ -30,8 +30,8 @@ void IndexedDBDatabaseCallbacks::OnForcedClose() {
dispatcher_host_ = NULL;
}
-void IndexedDBDatabaseCallbacks::OnVersionChange(int64 old_version,
- int64 new_version) {
+void IndexedDBDatabaseCallbacks::OnVersionChange(int64_t old_version,
+ int64_t new_version) {
if (!dispatcher_host_.get())
return;
@@ -39,9 +39,8 @@ void IndexedDBDatabaseCallbacks::OnVersionChange(int64 old_version,
ipc_thread_id_, ipc_database_callbacks_id_, old_version, new_version));
}
-void IndexedDBDatabaseCallbacks::OnAbort(
- int64 host_transaction_id,
- const IndexedDBDatabaseError& error) {
+void IndexedDBDatabaseCallbacks::OnAbort(int64_t host_transaction_id,
+ const IndexedDBDatabaseError& error) {
if (!dispatcher_host_.get())
return;
@@ -54,7 +53,7 @@ void IndexedDBDatabaseCallbacks::OnAbort(
error.message()));
}
-void IndexedDBDatabaseCallbacks::OnComplete(int64 host_transaction_id) {
+void IndexedDBDatabaseCallbacks::OnComplete(int64_t host_transaction_id) {
if (!dispatcher_host_.get())
return;
diff --git a/chromium/content/browser/indexed_db/indexed_db_database_callbacks.h b/chromium/content/browser/indexed_db/indexed_db_database_callbacks.h
index ad16a04b1d7..5c8892e5f9b 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database_callbacks.h
+++ b/chromium/content/browser/indexed_db/indexed_db_database_callbacks.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
@@ -21,11 +23,11 @@ class CONTENT_EXPORT IndexedDBDatabaseCallbacks
int ipc_database_callbacks_id);
virtual void OnForcedClose();
- virtual void OnVersionChange(int64 old_version, int64 new_version);
+ virtual void OnVersionChange(int64_t old_version, int64_t new_version);
- virtual void OnAbort(int64 host_transaction_id,
+ virtual void OnAbort(int64_t host_transaction_id,
const IndexedDBDatabaseError& error);
- virtual void OnComplete(int64 host_transaction_id);
+ virtual void OnComplete(int64_t host_transaction_id);
protected:
virtual ~IndexedDBDatabaseCallbacks();
diff --git a/chromium/content/browser/indexed_db/indexed_db_database_error.cc b/chromium/content/browser/indexed_db/indexed_db_database_error.cc
index ff05a779392..05c0cb57846 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database_error.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_database_error.cc
@@ -6,19 +6,17 @@
namespace content {
-IndexedDBDatabaseError::IndexedDBDatabaseError(uint16 code) : code_(code) {
-}
+IndexedDBDatabaseError::IndexedDBDatabaseError(uint16_t code) : code_(code) {}
IndexedDBDatabaseError::IndexedDBDatabaseError() = default;
-IndexedDBDatabaseError::IndexedDBDatabaseError(uint16 code, const char* message)
- : code_(code), message_(base::ASCIIToUTF16(message)) {
-}
+IndexedDBDatabaseError::IndexedDBDatabaseError(uint16_t code,
+ const char* message)
+ : code_(code), message_(base::ASCIIToUTF16(message)) {}
-IndexedDBDatabaseError::IndexedDBDatabaseError(uint16 code,
+IndexedDBDatabaseError::IndexedDBDatabaseError(uint16_t code,
const base::string16& message)
- : code_(code), message_(message) {
-}
+ : code_(code), message_(message) {}
IndexedDBDatabaseError::~IndexedDBDatabaseError() = default;
diff --git a/chromium/content/browser/indexed_db/indexed_db_database_error.h b/chromium/content/browser/indexed_db/indexed_db_database_error.h
index 7b233f028fd..6106f75b1d6 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database_error.h
+++ b/chromium/content/browser/indexed_db/indexed_db_database_error.h
@@ -5,7 +5,8 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_ERROR_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_ERROR_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
@@ -14,18 +15,18 @@ namespace content {
class IndexedDBDatabaseError {
public:
IndexedDBDatabaseError();
- explicit IndexedDBDatabaseError(uint16 code);
- IndexedDBDatabaseError(uint16 code, const char* message);
- IndexedDBDatabaseError(uint16 code, const base::string16& message);
+ explicit IndexedDBDatabaseError(uint16_t code);
+ IndexedDBDatabaseError(uint16_t code, const char* message);
+ IndexedDBDatabaseError(uint16_t code, const base::string16& message);
~IndexedDBDatabaseError();
IndexedDBDatabaseError& operator=(const IndexedDBDatabaseError& rhs);
- uint16 code() const { return code_; }
+ uint16_t code() const { return code_; }
const base::string16& message() const { return message_; }
private:
- uint16 code_ = 0;
+ uint16_t code_ = 0;
base::string16 message_;
};
diff --git a/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc
index eb5df982118..a837945e4a2 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -4,10 +4,13 @@
#include "content/browser/indexed_db/indexed_db_database.h"
+#include <stdint.h>
#include <set>
+#include <utility>
#include "base/auto_reset.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
@@ -71,7 +74,7 @@ TEST(IndexedDBDatabaseTest, ConnectionLifecycle) {
scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks());
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
- const int64 transaction_id1 = 1;
+ const int64_t transaction_id1 = 1;
IndexedDBPendingConnection connection1(
request1,
callbacks1,
@@ -85,7 +88,7 @@ TEST(IndexedDBDatabaseTest, ConnectionLifecycle) {
scoped_refptr<MockIndexedDBCallbacks> request2(new MockIndexedDBCallbacks());
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2(
new MockIndexedDBDatabaseCallbacks());
- const int64 transaction_id2 = 2;
+ const int64_t transaction_id2 = 2;
IndexedDBPendingConnection connection2(
request2,
callbacks2,
@@ -129,7 +132,7 @@ TEST(IndexedDBDatabaseTest, ForcedClose) {
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks(
new MockIndexedDBDatabaseCallbacks());
scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks());
- const int64 upgrade_transaction_id = 3;
+ const int64_t upgrade_transaction_id = 3;
IndexedDBPendingConnection connection(
request,
callbacks,
@@ -139,8 +142,8 @@ TEST(IndexedDBDatabaseTest, ForcedClose) {
database->OpenConnection(connection);
EXPECT_EQ(database.get(), request->connection()->database());
- const int64 transaction_id = 123;
- const std::vector<int64> scope;
+ const int64_t transaction_id = 123;
+ const std::vector<int64_t> scope;
database->CreateTransaction(transaction_id,
request->connection(),
scope,
@@ -159,8 +162,8 @@ class MockDeleteCallbacks : public IndexedDBCallbacks {
blocked_called_(false),
success_called_(false) {}
- void OnBlocked(int64 existing_version) override { blocked_called_ = true; }
- void OnSuccess(int64 result) override { success_called_ = true; }
+ void OnBlocked(int64_t existing_version) override { blocked_called_ = true; }
+ void OnSuccess(int64_t result) override { success_called_ = true; }
bool blocked_called() const { return blocked_called_; }
bool success_called() const { return success_called_; }
@@ -193,7 +196,7 @@ TEST(IndexedDBDatabaseTest, PendingDelete) {
scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks());
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
- const int64 transaction_id1 = 1;
+ const int64_t transaction_id1 = 1;
IndexedDBPendingConnection connection(
request1,
callbacks1,
@@ -241,7 +244,7 @@ class IndexedDBDatabaseOperationTest : public testing::Test {
request_ = new MockIndexedDBCallbacks();
callbacks_ = new MockIndexedDBDatabaseCallbacks();
- const int64 transaction_id = 1;
+ const int64_t transaction_id = 1;
db_->OpenConnection(IndexedDBPendingConnection(
request_,
callbacks_,
@@ -252,7 +255,7 @@ class IndexedDBDatabaseOperationTest : public testing::Test {
db_->metadata().int_version);
transaction_ = IndexedDBClassFactory::Get()->CreateIndexedDBTransaction(
- transaction_id, callbacks_, std::set<int64>() /*scope*/,
+ transaction_id, callbacks_, std::set<int64_t>() /*scope*/,
blink::WebIDBTransactionModeVersionChange, db_.get(),
new IndexedDBFakeBackingStore::FakeTransaction(commit_success_));
db_->TransactionCreated(transaction_.get());
@@ -283,7 +286,7 @@ class IndexedDBDatabaseOperationTest : public testing::Test {
TEST_F(IndexedDBDatabaseOperationTest, CreateObjectStore) {
EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
- const int64 store_id = 1001;
+ const int64_t store_id = 1001;
db_->CreateObjectStore(transaction_->id(),
store_id,
ASCIIToUTF16("store"),
@@ -297,14 +300,14 @@ TEST_F(IndexedDBDatabaseOperationTest, CreateObjectStore) {
TEST_F(IndexedDBDatabaseOperationTest, CreateIndex) {
EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
- const int64 store_id = 1001;
+ const int64_t store_id = 1001;
db_->CreateObjectStore(transaction_->id(),
store_id,
ASCIIToUTF16("store"),
IndexedDBKeyPath(),
false /*auto_increment*/);
EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
- const int64 index_id = 2002;
+ const int64_t index_id = 2002;
db_->CreateIndex(transaction_->id(),
store_id,
index_id,
@@ -336,7 +339,7 @@ class IndexedDBDatabaseOperationAbortTest
TEST_F(IndexedDBDatabaseOperationAbortTest, CreateObjectStore) {
EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
- const int64 store_id = 1001;
+ const int64_t store_id = 1001;
db_->CreateObjectStore(transaction_->id(),
store_id,
ASCIIToUTF16("store"),
@@ -350,14 +353,14 @@ TEST_F(IndexedDBDatabaseOperationAbortTest, CreateObjectStore) {
TEST_F(IndexedDBDatabaseOperationAbortTest, CreateIndex) {
EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
- const int64 store_id = 1001;
+ const int64_t store_id = 1001;
db_->CreateObjectStore(transaction_->id(),
store_id,
ASCIIToUTF16("store"),
IndexedDBKeyPath(),
false /*auto_increment*/);
EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
- const int64 index_id = 2002;
+ const int64_t index_id = 2002;
db_->CreateIndex(transaction_->id(),
store_id,
index_id,
@@ -375,7 +378,7 @@ TEST_F(IndexedDBDatabaseOperationAbortTest, CreateIndex) {
TEST_F(IndexedDBDatabaseOperationTest, CreatePutDelete) {
EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
- const int64 store_id = 1001;
+ const int64_t store_id = 1001;
// Creation is synchronous.
db_->CreateObjectStore(transaction_->id(),
@@ -393,14 +396,8 @@ TEST_F(IndexedDBDatabaseOperationTest, CreatePutDelete) {
std::vector<IndexedDBDatabase::IndexKeys> index_keys;
scoped_refptr<MockIndexedDBCallbacks> request(
new MockIndexedDBCallbacks(false));
- db_->Put(transaction_->id(),
- store_id,
- &value,
- &handles,
- key.Pass(),
- blink::WebIDBPutModeAddOnly,
- request,
- index_keys);
+ db_->Put(transaction_->id(), store_id, &value, &handles, std::move(key),
+ blink::WebIDBPutModeAddOnly, request, index_keys);
// Deletion is asynchronous.
db_->DeleteObjectStore(transaction_->id(),
diff --git a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
index 996e6a50ea7..f0890137038 100644
--- a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
@@ -76,7 +78,7 @@ IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {
delete iter.second.first;
}
-void IndexedDBDispatcherHost::OnChannelConnected(int32 peer_pid) {
+void IndexedDBDispatcherHost::OnChannelConnected(int32_t peer_pid) {
BrowserMessageFilter::OnChannelConnected(peer_pid);
if (request_context_getter_.get()) {
@@ -160,63 +162,63 @@ bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message) {
return handled;
}
-int32 IndexedDBDispatcherHost::Add(IndexedDBCursor* cursor) {
+int32_t IndexedDBDispatcherHost::Add(IndexedDBCursor* cursor) {
if (!cursor_dispatcher_host_) {
return 0;
}
return cursor_dispatcher_host_->map_.Add(cursor);
}
-int32 IndexedDBDispatcherHost::Add(IndexedDBConnection* connection,
- int32 ipc_thread_id,
- const GURL& origin_url) {
+int32_t IndexedDBDispatcherHost::Add(IndexedDBConnection* connection,
+ int32_t ipc_thread_id,
+ const GURL& origin_url) {
if (!database_dispatcher_host_) {
connection->Close();
delete connection;
return -1;
}
- int32 ipc_database_id = database_dispatcher_host_->map_.Add(connection);
+ int32_t ipc_database_id = database_dispatcher_host_->map_.Add(connection);
Context()->ConnectionOpened(origin_url, connection);
database_dispatcher_host_->database_url_map_[ipc_database_id] = origin_url;
return ipc_database_id;
}
-void IndexedDBDispatcherHost::RegisterTransactionId(int64 host_transaction_id,
+void IndexedDBDispatcherHost::RegisterTransactionId(int64_t host_transaction_id,
const GURL& url) {
if (!database_dispatcher_host_)
return;
database_dispatcher_host_->transaction_url_map_[host_transaction_id] = url;
}
-int64 IndexedDBDispatcherHost::HostTransactionId(int64 transaction_id) {
+int64_t IndexedDBDispatcherHost::HostTransactionId(int64_t transaction_id) {
// Inject the renderer process id into the transaction id, to
// uniquely identify this transaction, and effectively bind it to
// the renderer that initiated it. The lower 32 bits of
// transaction_id are guaranteed to be unique within that renderer.
base::ProcessId pid = peer_pid();
DCHECK(!(transaction_id >> 32)) << "Transaction ids can only be 32 bits";
- static_assert(sizeof(base::ProcessId) <= sizeof(int32),
+ static_assert(sizeof(base::ProcessId) <= sizeof(int32_t),
"Process ID must fit in 32 bits");
- return transaction_id | (static_cast<uint64>(pid) << 32);
+ return transaction_id | (static_cast<uint64_t>(pid) << 32);
}
-int64 IndexedDBDispatcherHost::RendererTransactionId(
- int64 host_transaction_id) {
+int64_t IndexedDBDispatcherHost::RendererTransactionId(
+ int64_t host_transaction_id) {
DCHECK(host_transaction_id >> 32 == peer_pid())
<< "Invalid renderer target for transaction id";
return host_transaction_id & 0xffffffff;
}
// static
-uint32 IndexedDBDispatcherHost::TransactionIdToRendererTransactionId(
- int64 host_transaction_id) {
+uint32_t IndexedDBDispatcherHost::TransactionIdToRendererTransactionId(
+ int64_t host_transaction_id) {
return host_transaction_id & 0xffffffff;
}
// static
-uint32 IndexedDBDispatcherHost::TransactionIdToProcessId(
- int64 host_transaction_id) {
+uint32_t IndexedDBDispatcherHost::TransactionIdToProcessId(
+ int64_t host_transaction_id) {
return (host_transaction_id >> 32) & 0xffffffff;
}
@@ -263,7 +265,8 @@ void IndexedDBDispatcherHost::DropBlobData(const std::string& uuid) {
}
}
-IndexedDBCursor* IndexedDBDispatcherHost::GetCursorFromId(int32 ipc_cursor_id) {
+IndexedDBCursor* IndexedDBDispatcherHost::GetCursorFromId(
+ int32_t ipc_cursor_id) {
DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
return cursor_dispatcher_host_->map_.Lookup(ipc_cursor_id);
}
@@ -328,7 +331,7 @@ void IndexedDBDispatcherHost::OnIDBFactoryOpen(
GURL origin_url =
storage::GetOriginFromIdentifier(params.database_identifier);
- int64 host_transaction_id = HostTransactionId(params.transaction_id);
+ int64_t host_transaction_id = HostTransactionId(params.transaction_id);
// TODO(dgrogan): Don't let a non-existing database be opened (and therefore
// created) if this origin is already over quota.
@@ -384,7 +387,7 @@ void IndexedDBDispatcherHost::OnAckReceivedBlobs(
DropBlobData(uuid);
}
-void IndexedDBDispatcherHost::FinishTransaction(int64 host_transaction_id,
+void IndexedDBDispatcherHost::FinishTransaction(int64_t host_transaction_id,
bool committed) {
DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
if (!database_dispatcher_host_)
@@ -409,7 +412,7 @@ void IndexedDBDispatcherHost::FinishTransaction(int64 host_transaction_id,
template <typename ObjectType>
ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
IDMap<ObjectType, IDMapOwnPointer>* map,
- int32 ipc_return_object_id) {
+ int32_t ipc_return_object_id) {
DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
ObjectType* return_object = map->Lookup(ipc_return_object_id);
if (!return_object) {
@@ -423,7 +426,7 @@ ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
template <typename ObjectType>
ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
RefIDMap<ObjectType>* map,
- int32 ipc_return_object_id) {
+ int32_t ipc_return_object_id) {
DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
ObjectType* return_object = map->Lookup(ipc_return_object_id);
if (!return_object) {
@@ -435,7 +438,8 @@ ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
}
template <typename MapType>
-void IndexedDBDispatcherHost::DestroyObject(MapType* map, int32 ipc_object_id) {
+void IndexedDBDispatcherHost::DestroyObject(MapType* map,
+ int32_t ipc_object_id) {
GetOrTerminateProcess(map, ipc_object_id);
map->Remove(ipc_object_id);
}
@@ -465,8 +469,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::CloseAll() {
for (TransactionIDToDatabaseIDMap::iterator iter =
transaction_database_map_.begin();
iter != transaction_database_map_.end();) {
- int64 transaction_id = iter->first;
- int32 ipc_database_id = iter->second;
+ int64_t transaction_id = iter->first;
+ int32_t ipc_database_id = iter->second;
++iter;
IndexedDBConnection* connection = map_.Lookup(ipc_database_id);
if (connection && connection->IsConnected()) {
@@ -535,7 +539,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateObjectStore(
if (!connection || !connection->IsConnected())
return;
- int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
+ int64_t host_transaction_id =
+ parent_->HostTransactionId(params.transaction_id);
connection->database()->CreateObjectStore(host_transaction_id,
params.object_store_id,
params.name,
@@ -550,9 +555,9 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateObjectStore(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteObjectStore(
- int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id) {
+ int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -573,7 +578,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateTransaction(
if (!connection || !connection->IsConnected())
return;
- int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
+ int64_t host_transaction_id =
+ parent_->HostTransactionId(params.transaction_id);
if (transaction_database_map_.find(host_transaction_id) !=
transaction_database_map_.end()) {
@@ -589,7 +595,7 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateTransaction(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClose(
- int32 ipc_database_id) {
+ int32_t ipc_database_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -600,7 +606,7 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClose(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnVersionChangeIgnored(
- int32 ipc_database_id) {
+ int32_t ipc_database_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -611,7 +617,7 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnVersionChangeIgnored(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDestroyed(
- int32 ipc_object_id) {
+ int32_t ipc_object_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -694,7 +700,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut(
scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
parent_, params.ipc_thread_id, params.ipc_callbacks_id));
- int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
+ int64_t host_transaction_id =
+ parent_->HostTransactionId(params.transaction_id);
std::vector<IndexedDBBlobInfo> blob_info(
params.value.blob_or_file_info.size());
@@ -754,7 +761,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetIndexKeys(
if (!connection || !connection->IsConnected())
return;
- int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
+ int64_t host_transaction_id =
+ parent_->HostTransactionId(params.transaction_id);
connection->database()->SetIndexKeys(
host_transaction_id,
params.object_store_id,
@@ -763,10 +771,10 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetIndexKeys(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetIndexesReady(
- int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id,
- const std::vector<int64>& index_ids) {
+ int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id,
+ const std::vector<int64_t>& index_ids) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -838,11 +846,11 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteRange(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClear(
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id) {
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -858,8 +866,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClear(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnAbort(
- int32 ipc_database_id,
- int64 transaction_id) {
+ int32_t ipc_database_id,
+ int64_t transaction_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -871,8 +879,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnAbort(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCommit(
- int32 ipc_database_id,
- int64 transaction_id) {
+ int32_t ipc_database_id,
+ int64_t transaction_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -880,8 +888,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCommit(
if (!connection || !connection->IsConnected())
return;
- int64 host_transaction_id = parent_->HostTransactionId(transaction_id);
- int64 transaction_size = transaction_size_map_[host_transaction_id];
+ int64_t host_transaction_id = parent_->HostTransactionId(transaction_id);
+ int64_t transaction_size = transaction_size_map_[host_transaction_id];
if (transaction_size &&
parent_->Context()->WouldBeOverQuota(
transaction_url_map_[host_transaction_id], transaction_size)) {
@@ -903,7 +911,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateIndex(
if (!connection || !connection->IsConnected())
return;
- int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
+ int64_t host_transaction_id =
+ parent_->HostTransactionId(params.transaction_id);
connection->database()->CreateIndex(host_transaction_id,
params.object_store_id,
params.index_id,
@@ -920,10 +929,10 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateIndex(
}
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteIndex(
- int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id,
- int64 index_id) {
+ int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBConnection* connection =
@@ -968,10 +977,10 @@ bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnAdvance(
- int32 ipc_cursor_id,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- uint32 count) {
+ int32_t ipc_cursor_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ uint32_t count) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
IndexedDBCursor* idb_cursor =
@@ -986,9 +995,9 @@ void IndexedDBDispatcherHost::CursorDispatcherHost::OnAdvance(
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
- int32 ipc_cursor_id,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
+ int32_t ipc_cursor_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
const IndexedDBKey& key,
const IndexedDBKey& primary_key) {
DCHECK(
@@ -1008,9 +1017,9 @@ void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetch(
- int32 ipc_cursor_id,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
+ int32_t ipc_cursor_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
int n) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
@@ -1026,7 +1035,7 @@ void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetch(
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetchReset(
- int32 ipc_cursor_id,
+ int32_t ipc_cursor_id,
int used_prefetches,
int unused_prefetches) {
DCHECK(
@@ -1044,7 +1053,7 @@ void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetchReset(
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed(
- int32 ipc_object_id) {
+ int32_t ipc_object_id) {
DCHECK(
parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
parent_->DestroyObject(&map_, ipc_object_id);
diff --git a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h
index b576a460730..29edb8a9728 100644
--- a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h
+++ b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -5,13 +5,15 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DISPATCHER_HOST_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/id_map.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/public/browser/browser_message_filter.h"
@@ -61,14 +63,14 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
const content::IndexedDBDatabaseMetadata& metadata);
// BrowserMessageFilter implementation.
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnChannelClosing() override;
void OnDestruct() const override;
base::TaskRunner* OverrideTaskRunnerForMessage(
const IPC::Message& message) override;
bool OnMessageReceived(const IPC::Message& message) override;
- void FinishTransaction(int64 host_transaction_id, bool committed);
+ void FinishTransaction(int64_t host_transaction_id, bool committed);
// A shortcut for accessing our context.
IndexedDBContextImpl* Context() { return indexed_db_context_.get(); }
@@ -78,24 +80,26 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
// IndexedDBCallbacks call these methods to add the results into the
// applicable map. See below for more details.
- int32 Add(IndexedDBCursor* cursor);
- int32 Add(IndexedDBConnection* connection,
- int32 ipc_thread_id,
- const GURL& origin_url);
+ int32_t Add(IndexedDBCursor* cursor);
+ int32_t Add(IndexedDBConnection* connection,
+ int32_t ipc_thread_id,
+ const GURL& origin_url);
- void RegisterTransactionId(int64 host_transaction_id, const GURL& origin_url);
+ void RegisterTransactionId(int64_t host_transaction_id,
+ const GURL& origin_url);
- IndexedDBCursor* GetCursorFromId(int32 ipc_cursor_id);
+ IndexedDBCursor* GetCursorFromId(int32_t ipc_cursor_id);
// These are called to map a 32-bit front-end (renderer-specific) transaction
// id to and from a back-end ("host") transaction id that encodes the process
// id in the high 32 bits. The mapping is host-specific and ids are validated.
- int64 HostTransactionId(int64 transaction_id);
- int64 RendererTransactionId(int64 host_transaction_id);
+ int64_t HostTransactionId(int64_t transaction_id);
+ int64_t RendererTransactionId(int64_t host_transaction_id);
// These are called to decode a host transaction ID, for diagnostic purposes.
- static uint32 TransactionIdToRendererTransactionId(int64 host_transaction_id);
- static uint32 TransactionIdToProcessId(int64 host_transaction_id);
+ static uint32_t TransactionIdToRendererTransactionId(
+ int64_t host_transaction_id);
+ static uint32_t TransactionIdToProcessId(int64_t host_transaction_id);
std::string HoldBlobData(const IndexedDBBlobInfo& blob_info);
@@ -107,16 +111,16 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
// Used in nested classes.
typedef std::map<std::string, std::pair<storage::BlobDataHandle*, int>>
BlobDataHandleMap;
- typedef std::map<int64, int64> TransactionIDToDatabaseIDMap;
- typedef std::map<int64, uint64> TransactionIDToSizeMap;
- typedef std::map<int64, GURL> TransactionIDToURLMap;
- typedef std::map<int32, GURL> WebIDBObjectIDToURLMap;
+ typedef std::map<int64_t, int64_t> TransactionIDToDatabaseIDMap;
+ typedef std::map<int64_t, uint64_t> TransactionIDToSizeMap;
+ typedef std::map<int64_t, GURL> TransactionIDToURLMap;
+ typedef std::map<int32_t, GURL> WebIDBObjectIDToURLMap;
// IDMap for RefCounted types
template <typename RefCountedType>
class RefIDMap {
public:
- typedef int32 KeyType;
+ typedef int32_t KeyType;
RefIDMap() {}
~RefIDMap() {}
@@ -154,14 +158,14 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
void OnCreateObjectStore(
const IndexedDBHostMsg_DatabaseCreateObjectStore_Params& params);
- void OnDeleteObjectStore(int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id);
+ void OnDeleteObjectStore(int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id);
void OnCreateTransaction(
const IndexedDBHostMsg_DatabaseCreateTransaction_Params&);
- void OnClose(int32 ipc_database_id);
- void OnVersionChangeIgnored(int32 ipc_database_id);
- void OnDestroyed(int32 ipc_database_id);
+ void OnClose(int32_t ipc_database_id);
+ void OnVersionChangeIgnored(int32_t ipc_database_id);
+ void OnDestroyed(int32_t ipc_database_id);
void OnGet(const IndexedDBHostMsg_DatabaseGet_Params& params);
void OnGetAll(const IndexedDBHostMsg_DatabaseGetAll_Params& params);
@@ -172,28 +176,28 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
std::vector<storage::BlobDataHandle*> handles);
void OnSetIndexKeys(
const IndexedDBHostMsg_DatabaseSetIndexKeys_Params& params);
- void OnSetIndexesReady(int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id,
- const std::vector<int64>& ids);
+ void OnSetIndexesReady(int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id,
+ const std::vector<int64_t>& ids);
void OnOpenCursor(const IndexedDBHostMsg_DatabaseOpenCursor_Params& params);
void OnCount(const IndexedDBHostMsg_DatabaseCount_Params& params);
void OnDeleteRange(
const IndexedDBHostMsg_DatabaseDeleteRange_Params& params);
- void OnClear(int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id);
+ void OnClear(int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id);
void OnCreateIndex(
const IndexedDBHostMsg_DatabaseCreateIndex_Params& params);
- void OnDeleteIndex(int32 ipc_database_id,
- int64 transaction_id,
- int64 object_store_id,
- int64 index_id);
+ void OnDeleteIndex(int32_t ipc_database_id,
+ int64_t transaction_id,
+ int64_t object_store_id,
+ int64_t index_id);
- void OnAbort(int32 ipc_database_id, int64 transaction_id);
- void OnCommit(int32 ipc_database_id, int64 transaction_id);
+ void OnAbort(int32_t ipc_database_id, int64_t transaction_id);
+ void OnCommit(int32_t ipc_database_id, int64_t transaction_id);
IndexedDBDispatcherHost* parent_;
IDMap<IndexedDBConnection, IDMapOwnPointer> map_;
WebIDBObjectIDToURLMap database_url_map_;
@@ -212,23 +216,23 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
bool OnMessageReceived(const IPC::Message& message);
- void OnAdvance(int32 ipc_object_store_id,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
- uint32 count);
- void OnContinue(int32 ipc_object_store_id,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
+ void OnAdvance(int32_t ipc_object_store_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
+ uint32_t count);
+ void OnContinue(int32_t ipc_object_store_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
const IndexedDBKey& key,
const IndexedDBKey& primary_key);
- void OnPrefetch(int32 ipc_cursor_id,
- int32 ipc_thread_id,
- int32 ipc_callbacks_id,
+ void OnPrefetch(int32_t ipc_cursor_id,
+ int32_t ipc_thread_id,
+ int32_t ipc_callbacks_id,
int n);
- void OnPrefetchReset(int32 ipc_cursor_id,
+ void OnPrefetchReset(int32_t ipc_cursor_id,
int used_prefetches,
int unused_prefetches);
- void OnDestroyed(int32 ipc_cursor_id);
+ void OnDestroyed(int32_t ipc_cursor_id);
IndexedDBDispatcherHost* parent_;
RefIDMap<IndexedDBCursor> map_;
@@ -242,13 +246,13 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
// Helper templates.
template <class ReturnType>
ReturnType* GetOrTerminateProcess(IDMap<ReturnType, IDMapOwnPointer>* map,
- int32 ipc_return_object_id);
+ int32_t ipc_return_object_id);
template <class ReturnType>
ReturnType* GetOrTerminateProcess(RefIDMap<ReturnType>* map,
- int32 ipc_return_object_id);
+ int32_t ipc_return_object_id);
template <typename MapType>
- void DestroyObject(MapType* map, int32 ipc_object_id);
+ void DestroyObject(MapType* map, int32_t ipc_object_id);
// Message processing. Most of the work is delegated to the dispatcher hosts
// below.
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory.h b/chromium/content/browser/indexed_db/indexed_db_factory.h
index dc52342501f..a50e5b3631c 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory.h
+++ b/chromium/content/browser/indexed_db/indexed_db_factory.h
@@ -5,13 +5,15 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_FACTORY_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_FACTORY_H_
+#include <stddef.h>
+
#include <map>
#include <set>
#include <string>
#include <utility>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc b/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
index e66ff62b746..2261dcc30f0 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/indexed_db_factory_impl.h"
+#include <stdint.h>
+
#include <utility>
#include <vector>
@@ -23,7 +25,7 @@ using base::ASCIIToUTF16;
namespace content {
-const int64 kBackingStoreGracePeriodMs = 2000;
+const int64_t kBackingStoreGracePeriodMs = 2000;
IndexedDBFactoryImpl::IndexedDBFactoryImpl(IndexedDBContextImpl* context)
: context_(context) {
@@ -270,7 +272,7 @@ void IndexedDBFactoryImpl::DeleteDatabase(
return;
}
if (!ContainsValue(names, name)) {
- const int64 version = 0;
+ const int64_t version = 0;
callbacks->OnSuccess(version);
backing_store = NULL;
ReleaseBackingStore(origin_url, false /* immediate */);
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory_impl.h b/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
index d225fd9173c..b8a8d1a98ce 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_FACTORY_IMPL_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_FACTORY_IMPL_H_
+#include <stddef.h>
+
#include <map>
#include <set>
#include <string>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
namespace content {
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
index 3d55ac7e63e..1dcaecc3378 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_simple_task_runner.h"
@@ -196,6 +200,8 @@ TEST_F(IndexedDBFactoryTest, RejectLongOrigins) {
scoped_refptr<IndexedDBBackingStore> diskStore2 =
factory()->TestOpenBackingStore(ok_origin, base_path);
EXPECT_TRUE(diskStore2.get());
+ // We need a manual close or Windows can't delete the temp directory.
+ factory()->TestCloseBackingStore(diskStore2.get());
}
class DiskFullFactory : public IndexedDBFactoryImpl {
@@ -271,7 +277,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) {
scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
- const int64 transaction_id = 1;
+ const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks,
db_callbacks,
@@ -304,7 +310,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
- const int64 transaction_id = 1;
+ const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks,
db_callbacks,
@@ -399,7 +405,7 @@ TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
- const int64 transaction_id = 1;
+ const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks,
db_callbacks,
@@ -441,10 +447,10 @@ class UpgradeNeededCallbacks : public MockIndexedDBCallbacks {
}
void OnUpgradeNeeded(
- int64 old_version,
+ int64_t old_version,
scoped_ptr<IndexedDBConnection> connection,
const content::IndexedDBDatabaseMetadata& metadata) override {
- connection_ = connection.Pass();
+ connection_ = std::move(connection);
}
protected:
@@ -477,8 +483,8 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const base::string16 db_name(ASCIIToUTF16("db"));
- const int64 db_version = 2;
- const int64 transaction_id = 1;
+ const int64_t db_version = 2;
+ const int64_t transaction_id = 1;
scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
diff --git a/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc b/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc
index 49040ae9478..01f83cbe2cb 100644
--- a/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc
@@ -46,13 +46,13 @@ leveldb::Status IndexedDBFakeBackingStore::GetIDBDatabaseMetaData(
leveldb::Status IndexedDBFakeBackingStore::CreateIDBDatabaseMetaData(
const base::string16& name,
const base::string16& version,
- int64 int_version,
- int64* row_id) {
+ int64_t int_version,
+ int64_t* row_id) {
return leveldb::Status::OK();
}
bool IndexedDBFakeBackingStore::UpdateIDBDatabaseIntVersion(Transaction*,
- int64 row_id,
- int64 version) {
+ int64_t row_id,
+ int64_t version) {
return false;
}
leveldb::Status IndexedDBFakeBackingStore::DeleteDatabase(
@@ -62,8 +62,8 @@ leveldb::Status IndexedDBFakeBackingStore::DeleteDatabase(
leveldb::Status IndexedDBFakeBackingStore::CreateObjectStore(
Transaction*,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const base::string16& name,
const IndexedDBKeyPath&,
bool auto_increment) {
@@ -72,15 +72,15 @@ leveldb::Status IndexedDBFakeBackingStore::CreateObjectStore(
leveldb::Status IndexedDBFakeBackingStore::DeleteObjectStore(
Transaction* transaction,
- int64 database_id,
- int64 object_store_id) {
+ int64_t database_id,
+ int64_t object_store_id) {
return leveldb::Status::OK();
}
leveldb::Status IndexedDBFakeBackingStore::PutRecord(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
IndexedDBValue* value,
ScopedVector<storage::BlobDataHandle>* handles,
@@ -90,36 +90,36 @@ leveldb::Status IndexedDBFakeBackingStore::PutRecord(
leveldb::Status IndexedDBFakeBackingStore::ClearObjectStore(
Transaction*,
- int64 database_id,
- int64 object_store_id) {
+ int64_t database_id,
+ int64_t object_store_id) {
return leveldb::Status::OK();
}
leveldb::Status IndexedDBFakeBackingStore::DeleteRecord(
Transaction*,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const RecordIdentifier&) {
return leveldb::Status::OK();
}
leveldb::Status IndexedDBFakeBackingStore::GetKeyGeneratorCurrentNumber(
Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64* current_number) {
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t* current_number) {
return leveldb::Status::OK();
}
leveldb::Status IndexedDBFakeBackingStore::MaybeUpdateKeyGeneratorCurrentNumber(
Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 new_number,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t new_number,
bool check_current) {
return leveldb::Status::OK();
}
leveldb::Status IndexedDBFakeBackingStore::KeyExistsInObjectStore(
Transaction*,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey&,
RecordIdentifier* found_record_identifier,
bool* found) {
@@ -128,9 +128,9 @@ leveldb::Status IndexedDBFakeBackingStore::KeyExistsInObjectStore(
leveldb::Status IndexedDBFakeBackingStore::CreateIndex(
Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const base::string16& name,
const IndexedDBKeyPath&,
bool is_unique,
@@ -139,29 +139,29 @@ leveldb::Status IndexedDBFakeBackingStore::CreateIndex(
}
leveldb::Status IndexedDBFakeBackingStore::DeleteIndex(Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
return leveldb::Status::OK();
}
leveldb::Status IndexedDBFakeBackingStore::PutIndexDataForRecord(
Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey&,
const RecordIdentifier&) {
return leveldb::Status::OK();
}
-void IndexedDBFakeBackingStore::ReportBlobUnused(int64 database_id,
- int64 blob_key) {}
+void IndexedDBFakeBackingStore::ReportBlobUnused(int64_t database_id,
+ int64_t blob_key) {}
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBFakeBackingStore::OpenObjectStoreKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status* s) {
@@ -170,8 +170,8 @@ IndexedDBFakeBackingStore::OpenObjectStoreKeyCursor(
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBFakeBackingStore::OpenObjectStoreCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status* s) {
@@ -180,9 +180,9 @@ IndexedDBFakeBackingStore::OpenObjectStoreCursor(
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBFakeBackingStore::OpenIndexKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status* s) {
@@ -191,9 +191,9 @@ IndexedDBFakeBackingStore::OpenIndexKeyCursor(
scoped_ptr<IndexedDBBackingStore::Cursor>
IndexedDBFakeBackingStore::OpenIndexCursor(
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status* s) {
diff --git a/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.h b/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.h
index 9a4fd0927a6..8f033005570 100644
--- a/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.h
+++ b/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_FAKE_BACKING_STORE_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_FAKE_BACKING_STORE_H_
+#include <stdint.h>
+
#include <vector>
+#include "base/macros.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
namespace base {
@@ -28,100 +31,101 @@ class IndexedDBFakeBackingStore : public IndexedDBBackingStore {
bool* found) override;
leveldb::Status CreateIDBDatabaseMetaData(const base::string16& name,
const base::string16& version,
- int64 int_version,
- int64* row_id) override;
+ int64_t int_version,
+ int64_t* row_id) override;
bool UpdateIDBDatabaseIntVersion(Transaction*,
- int64 row_id,
- int64 version) override;
+ int64_t row_id,
+ int64_t version) override;
leveldb::Status DeleteDatabase(const base::string16& name) override;
leveldb::Status CreateObjectStore(Transaction*,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const base::string16& name,
const IndexedDBKeyPath&,
bool auto_increment) override;
leveldb::Status DeleteObjectStore(Transaction* transaction,
- int64 database_id,
- int64 object_store_id) override;
+ int64_t database_id,
+ int64_t object_store_id) override;
leveldb::Status PutRecord(IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& key,
IndexedDBValue* value,
ScopedVector<storage::BlobDataHandle>* handles,
RecordIdentifier* record) override;
leveldb::Status ClearObjectStore(Transaction*,
- int64 database_id,
- int64 object_store_id) override;
+ int64_t database_id,
+ int64_t object_store_id) override;
leveldb::Status DeleteRecord(Transaction*,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const RecordIdentifier&) override;
- leveldb::Status GetKeyGeneratorCurrentNumber(Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64* current_number) override;
+ leveldb::Status GetKeyGeneratorCurrentNumber(
+ Transaction*,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t* current_number) override;
leveldb::Status MaybeUpdateKeyGeneratorCurrentNumber(
Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 new_number,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t new_number,
bool check_current) override;
leveldb::Status KeyExistsInObjectStore(
Transaction*,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey&,
RecordIdentifier* found_record_identifier,
bool* found) override;
leveldb::Status CreateIndex(Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const base::string16& name,
const IndexedDBKeyPath&,
bool is_unique,
bool is_multi_entry) override;
leveldb::Status DeleteIndex(Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 index_id) override;
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) override;
leveldb::Status PutIndexDataForRecord(Transaction*,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey&,
const RecordIdentifier&) override;
- void ReportBlobUnused(int64 database_id, int64 blob_key) override;
+ void ReportBlobUnused(int64_t database_id, int64_t blob_key) override;
scoped_ptr<Cursor> OpenObjectStoreKeyCursor(
Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*) override;
scoped_ptr<Cursor> OpenObjectStoreCursor(Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
+ int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*) override;
scoped_ptr<Cursor> OpenIndexKeyCursor(Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*) override;
scoped_ptr<Cursor> OpenIndexCursor(Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKeyRange& key_range,
blink::WebIDBCursorDirection,
leveldb::Status*) override;
diff --git a/chromium/content/browser/indexed_db/indexed_db_index_writer.cc b/chromium/content/browser/indexed_db/indexed_db_index_writer.cc
index 53ae963c04a..79e0252507e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_index_writer.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_index_writer.cc
@@ -4,6 +4,9 @@
#include "content/browser/indexed_db/indexed_db_index_writer.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
@@ -31,9 +34,9 @@ IndexWriter::~IndexWriter() {}
bool IndexWriter::VerifyIndexKeys(
IndexedDBBackingStore* backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
bool* can_add_keys,
const IndexedDBKey& primary_key,
base::string16* error_message) const {
@@ -68,9 +71,9 @@ void IndexWriter::WriteIndexKeys(
const IndexedDBBackingStore::RecordIdentifier& record_identifier,
IndexedDBBackingStore* backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id) const {
- int64 index_id = index_metadata_.id;
+ int64_t database_id,
+ int64_t object_store_id) const {
+ int64_t index_id = index_metadata_.id;
DCHECK_EQ(index_id, index_keys_.first);
for (size_t i = 0; i < index_keys_.second.size(); ++i) {
leveldb::Status s =
@@ -89,9 +92,9 @@ void IndexWriter::WriteIndexKeys(
bool IndexWriter::AddingKeyAllowed(
IndexedDBBackingStore* backing_store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& index_key,
const IndexedDBKey& primary_key,
bool* allowed) const {
@@ -121,7 +124,7 @@ bool IndexWriter::AddingKeyAllowed(
bool MakeIndexWriters(
IndexedDBTransaction* transaction,
IndexedDBBackingStore* backing_store,
- int64 database_id,
+ int64_t database_id,
const IndexedDBObjectStoreMetadata& object_store,
const IndexedDBKey& primary_key, // makes a copy
bool key_was_generated,
@@ -160,7 +163,7 @@ bool MakeIndexWriters(
if (!can_add_keys)
return true;
- index_writers->push_back(index_writer.Pass());
+ index_writers->push_back(std::move(index_writer));
}
*completed = true;
diff --git a/chromium/content/browser/indexed_db/indexed_db_index_writer.h b/chromium/content/browser/indexed_db/indexed_db_index_writer.h
index ef4bb16a525..41b7de31a94 100644
--- a/chromium/content/browser/indexed_db/indexed_db_index_writer.h
+++ b/chromium/content/browser/indexed_db/indexed_db_index_writer.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_INDEX_WRITER_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_INDEX_WRITER_H_
+#include <stdint.h>
+
#include <map>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_database.h"
@@ -29,9 +31,9 @@ class IndexWriter {
bool VerifyIndexKeys(IndexedDBBackingStore* store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
bool* can_add_keys,
const IndexedDBKey& primary_key,
base::string16* error_message) const WARN_UNUSED_RESULT;
@@ -39,17 +41,17 @@ class IndexWriter {
void WriteIndexKeys(const IndexedDBBackingStore::RecordIdentifier& record,
IndexedDBBackingStore* store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id) const;
+ int64_t database_id,
+ int64_t object_store_id) const;
~IndexWriter();
private:
bool AddingKeyAllowed(IndexedDBBackingStore* store,
IndexedDBBackingStore::Transaction* transaction,
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& index_key,
const IndexedDBKey& primary_key,
bool* allowed) const WARN_UNUSED_RESULT;
@@ -63,7 +65,7 @@ class IndexWriter {
bool MakeIndexWriters(
IndexedDBTransaction* transaction,
IndexedDBBackingStore* store,
- int64 database_id,
+ int64_t database_id,
const IndexedDBObjectStoreMetadata& metadata,
const IndexedDBKey& primary_key,
bool key_was_generated,
diff --git a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
index 2dfd6500466..1e8926009dc 100644
--- a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -5,9 +5,11 @@
#include "content/browser/indexed_db/indexed_db_internals_ui.h"
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
@@ -311,7 +313,7 @@ void IndexedDBInternalsUI::OnDownloadDataReady(
origin_url,
temp_path,
connection_count));
- dlm->DownloadUrl(dl_params.Pass());
+ dlm->DownloadUrl(std::move(dl_params));
}
// The entire purpose of this class is to delete the temp file after
diff --git a/chromium/content/browser/indexed_db/indexed_db_internals_ui.h b/chromium/content/browser/indexed_db/indexed_db_internals_ui.h
index 157978f433b..90467deecb3 100644
--- a/chromium/content/browser/indexed_db/indexed_db_internals_ui.h
+++ b/chromium/content/browser/indexed_db/indexed_db_internals_ui.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_INTERNALS_UI_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_INTERNALS_UI_H_
+#include <stddef.h>
+
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/download_interrupt_reasons.h"
diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc
index 45656a86038..eb705378123 100644
--- a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc
@@ -223,7 +223,7 @@ static const unsigned char kIndexMetaDataTypeMaximum = 255;
const unsigned char kMinimumIndexId = 30;
-inline void EncodeIntSafely(int64 value, int64 max, std::string* into) {
+inline void EncodeIntSafely(int64_t value, int64_t max, std::string* into) {
DCHECK_LE(value, max);
return EncodeInt(value, into);
}
@@ -248,12 +248,12 @@ void EncodeBool(bool value, std::string* into) {
into->push_back(value ? 1 : 0);
}
-void EncodeInt(int64 value, std::string* into) {
+void EncodeInt(int64_t value, std::string* into) {
#ifndef NDEBUG
// Exercised by unit tests in debug only.
DCHECK_GE(value, 0);
#endif
- uint64 n = static_cast<uint64>(value);
+ uint64_t n = static_cast<uint64_t>(value);
do {
unsigned char c = n;
@@ -262,12 +262,12 @@ void EncodeInt(int64 value, std::string* into) {
} while (n);
}
-void EncodeVarInt(int64 value, std::string* into) {
+void EncodeVarInt(int64_t value, std::string* into) {
#ifndef NDEBUG
// Exercised by unit tests in debug only.
DCHECK_GE(value, 0);
#endif
- uint64 n = static_cast<uint64>(value);
+ uint64_t n = static_cast<uint64_t>(value);
do {
unsigned char c = n & 0x7f;
@@ -290,7 +290,7 @@ void EncodeString(const base::string16& value, std::string* into) {
base::char16* dst =
reinterpret_cast<base::char16*>(&*into->begin() + current);
for (unsigned i = 0; i < length; ++i)
- *dst++ = htons(*src++);
+ *dst++ = base::HostToNet16(*src++);
}
void EncodeBinary(const std::string& value, std::string* into) {
@@ -404,16 +404,16 @@ bool DecodeBool(StringPiece* slice, bool* value) {
return true;
}
-bool DecodeInt(StringPiece* slice, int64* value) {
+bool DecodeInt(StringPiece* slice, int64_t* value) {
if (slice->empty())
return false;
StringPiece::const_iterator it = slice->begin();
int shift = 0;
- int64 ret = 0;
+ int64_t ret = 0;
while (it != slice->end()) {
unsigned char c = *it++;
- ret |= static_cast<int64>(c) << shift;
+ ret |= static_cast<int64_t>(c) << shift;
shift += 8;
}
*value = ret;
@@ -421,19 +421,19 @@ bool DecodeInt(StringPiece* slice, int64* value) {
return true;
}
-bool DecodeVarInt(StringPiece* slice, int64* value) {
+bool DecodeVarInt(StringPiece* slice, int64_t* value) {
if (slice->empty())
return false;
StringPiece::const_iterator it = slice->begin();
int shift = 0;
- int64 ret = 0;
+ int64_t ret = 0;
do {
if (it == slice->end())
return false;
unsigned char c = *it;
- ret |= static_cast<int64>(c & 0x7f) << shift;
+ ret |= static_cast<int64_t>(c & 0x7f) << shift;
shift += 7;
} while (*it++ & 0x80);
*value = ret;
@@ -455,7 +455,7 @@ bool DecodeString(StringPiece* slice, base::string16* value) {
const base::char16* encoded =
reinterpret_cast<const base::char16*>(slice->begin());
for (unsigned i = 0; i < length; ++i)
- decoded.push_back(ntohs(*encoded++));
+ decoded.push_back(base::NetToHost16(*encoded++));
*value = decoded;
slice->remove_prefix(length * sizeof(base::char16));
@@ -466,7 +466,7 @@ bool DecodeStringWithLength(StringPiece* slice, base::string16* value) {
if (slice->empty())
return false;
- int64 length = 0;
+ int64_t length = 0;
if (!DecodeVarInt(slice, &length) || length < 0)
return false;
size_t bytes = length * sizeof(base::char16);
@@ -485,7 +485,7 @@ bool DecodeBinary(StringPiece* slice, std::string* value) {
if (slice->empty())
return false;
- int64 length = 0;
+ int64_t length = 0;
if (!DecodeVarInt(slice, &length) || length < 0)
return false;
size_t size = length;
@@ -510,7 +510,7 @@ bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) {
return true;
case kIndexedDBKeyArrayTypeByte: {
- int64 length = 0;
+ int64_t length = 0;
if (!DecodeVarInt(slice, &length) || length < 0)
return false;
IndexedDBKey::KeyArray array;
@@ -599,7 +599,7 @@ bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
}
case WebIDBKeyPathTypeArray: {
std::vector<base::string16> array;
- int64 count;
+ int64_t count;
if (!DecodeVarInt(slice, &count))
return false;
DCHECK_GE(count, 0);
@@ -621,8 +621,8 @@ bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
bool DecodeBlobJournal(StringPiece* slice, BlobJournalType* journal) {
BlobJournalType output;
while (!slice->empty()) {
- int64 database_id = -1;
- int64 blob_key = -1;
+ int64_t database_id = -1;
+ int64_t blob_key = -1;
if (!DecodeVarInt(slice, &database_id))
return false;
if (!KeyPrefix::IsValidDatabaseId(database_id))
@@ -648,7 +648,7 @@ bool ConsumeEncodedIDBKey(StringPiece* slice) {
case kIndexedDBKeyMinKeyTypeByte:
return true;
case kIndexedDBKeyArrayTypeByte: {
- int64 length;
+ int64_t length;
if (!DecodeVarInt(slice, &length))
return false;
while (length--) {
@@ -658,7 +658,7 @@ bool ConsumeEncodedIDBKey(StringPiece* slice) {
return true;
}
case kIndexedDBKeyBinaryTypeByte: {
- int64 length = 0;
+ int64_t length = 0;
if (!DecodeVarInt(slice, &length) || length < 0)
return false;
if (slice->size() < static_cast<size_t>(length))
@@ -667,7 +667,7 @@ bool ConsumeEncodedIDBKey(StringPiece* slice) {
return true;
}
case kIndexedDBKeyStringTypeByte: {
- int64 length = 0;
+ int64_t length = 0;
if (!DecodeVarInt(slice, &length) || length < 0)
return false;
if (slice->size() < static_cast<size_t>(length) * sizeof(base::char16))
@@ -721,7 +721,7 @@ static WebIDBKeyType KeyTypeByteToKeyType(unsigned char type) {
int CompareEncodedStringsWithLength(StringPiece* slice1,
StringPiece* slice2,
bool* ok) {
- int64 len1, len2;
+ int64_t len1, len2;
if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
*ok = false;
return 0;
@@ -754,7 +754,7 @@ int CompareEncodedStringsWithLength(StringPiece* slice1,
int CompareEncodedBinary(StringPiece* slice1,
StringPiece* slice2,
bool* ok) {
- int64 len1, len2;
+ int64_t len1, len2;
if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
*ok = false;
return 0;
@@ -786,13 +786,13 @@ int CompareEncodedBinary(StringPiece* slice1,
return binary1.compare(binary2);
}
-static int CompareInts(int64 a, int64 b) {
+static int CompareInts(int64_t a, int64_t b) {
#ifndef NDEBUG
// Exercised by unit tests in debug only.
DCHECK_GE(a, 0);
DCHECK_GE(b, 0);
#endif
- int64 diff = a - b;
+ int64_t diff = a - b;
if (diff < 0)
return -1;
if (diff > 0)
@@ -831,13 +831,13 @@ int CompareEncodedIDBKeys(StringPiece* slice_a,
// Null type or max type; no payload to compare.
return 0;
case kIndexedDBKeyArrayTypeByte: {
- int64 length_a, length_b;
+ int64_t length_a, length_b;
if (!DecodeVarInt(slice_a, &length_a) ||
!DecodeVarInt(slice_b, &length_b)) {
*ok = false;
return 0;
}
- for (int64 i = 0; i < length_a && i < length_b; ++i) {
+ for (int64_t i = 0; i < length_a && i < length_b; ++i) {
int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
if (!*ok || result)
return result;
@@ -940,8 +940,8 @@ int CompareSuffix<IndexDataKey>(StringPiece* slice_a,
return 0;
// sequence number [optional]
- int64 sequence_number_a = -1;
- int64 sequence_number_b = -1;
+ int64_t sequence_number_a = -1;
+ int64_t sequence_number_b = -1;
if (!slice_a->empty() && !DecodeVarInt(slice_a, &sequence_number_a))
return 0;
if (!slice_b->empty() && !DecodeVarInt(slice_b, &sequence_number_b))
@@ -1133,12 +1133,12 @@ KeyPrefix::KeyPrefix()
object_store_id_(INVALID_TYPE),
index_id_(INVALID_TYPE) {}
-KeyPrefix::KeyPrefix(int64 database_id)
+KeyPrefix::KeyPrefix(int64_t database_id)
: database_id_(database_id), object_store_id_(0), index_id_(0) {
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
}
-KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id)
+KeyPrefix::KeyPrefix(int64_t database_id, int64_t object_store_id)
: database_id_(database_id),
object_store_id_(object_store_id),
index_id_(0) {
@@ -1146,7 +1146,9 @@ KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id)
DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
}
-KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id)
+KeyPrefix::KeyPrefix(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id)
: database_id_(database_id),
object_store_id_(object_store_id),
index_id_(index_id) {
@@ -1156,9 +1158,9 @@ KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id)
}
KeyPrefix::KeyPrefix(enum Type type,
- int64 database_id,
- int64 object_store_id,
- int64 index_id)
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id)
: database_id_(database_id),
object_store_id_(object_store_id),
index_id_(index_id) {
@@ -1167,25 +1169,25 @@ KeyPrefix::KeyPrefix(enum Type type,
DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
}
-KeyPrefix KeyPrefix::CreateWithSpecialIndex(int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+KeyPrefix KeyPrefix::CreateWithSpecialIndex(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
DCHECK(index_id);
return KeyPrefix(INVALID_TYPE, database_id, object_store_id, index_id);
}
-bool KeyPrefix::IsValidDatabaseId(int64 database_id) {
+bool KeyPrefix::IsValidDatabaseId(int64_t database_id) {
return (database_id > 0) && (database_id < KeyPrefix::kMaxDatabaseId);
}
-bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id) {
+bool KeyPrefix::IsValidObjectStoreId(int64_t object_store_id) {
return (object_store_id > 0) &&
(object_store_id < KeyPrefix::kMaxObjectStoreId);
}
-bool KeyPrefix::IsValidIndexId(int64 index_id) {
+bool KeyPrefix::IsValidIndexId(int64_t index_id) {
return (index_id >= kMinimumIndexId) && (index_id < KeyPrefix::kMaxIndexId);
}
@@ -1236,9 +1238,9 @@ std::string KeyPrefix::Encode() const {
return EncodeInternal(database_id_, object_store_id_, index_id_);
}
-std::string KeyPrefix::EncodeInternal(int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+std::string KeyPrefix::EncodeInternal(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
std::string database_id_string;
std::string object_store_id_string;
std::string index_id_string;
@@ -1356,7 +1358,7 @@ bool DatabaseFreeListKey::Decode(StringPiece* slice,
return true;
}
-std::string DatabaseFreeListKey::Encode(int64 database_id) {
+std::string DatabaseFreeListKey::Encode(int64_t database_id) {
std::string ret = KeyPrefix::EncodeEmpty();
ret.push_back(kDatabaseFreeListTypeByte);
EncodeVarInt(database_id, &ret);
@@ -1364,10 +1366,10 @@ std::string DatabaseFreeListKey::Encode(int64 database_id) {
}
std::string DatabaseFreeListKey::EncodeMaxKey() {
- return Encode(std::numeric_limits<int64>::max());
+ return Encode(std::numeric_limits<int64_t>::max());
}
-int64 DatabaseFreeListKey::DatabaseId() const {
+int64_t DatabaseFreeListKey::DatabaseId() const {
DCHECK_GE(database_id_, 0);
return database_id_;
}
@@ -1421,15 +1423,15 @@ int DatabaseNameKey::Compare(const DatabaseNameKey& other) {
return database_name_.compare(other.database_name_);
}
-bool DatabaseMetaDataKey::IsValidBlobKey(int64 blob_key) {
+bool DatabaseMetaDataKey::IsValidBlobKey(int64_t blob_key) {
return blob_key >= kBlobKeyGeneratorInitialNumber;
}
-const int64 DatabaseMetaDataKey::kAllBlobsKey = 1;
-const int64 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber = 2;
-const int64 DatabaseMetaDataKey::kInvalidBlobKey = -1;
+const int64_t DatabaseMetaDataKey::kAllBlobsKey = 1;
+const int64_t DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber = 2;
+const int64_t DatabaseMetaDataKey::kInvalidBlobKey = -1;
-std::string DatabaseMetaDataKey::Encode(int64 database_id,
+std::string DatabaseMetaDataKey::Encode(int64_t database_id,
MetaDataType meta_data_type) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
@@ -1460,8 +1462,8 @@ bool ObjectStoreMetaDataKey::Decode(StringPiece* slice,
return true;
}
-std::string ObjectStoreMetaDataKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string ObjectStoreMetaDataKey::Encode(int64_t database_id,
+ int64_t object_store_id,
unsigned char meta_data_type) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
@@ -1471,18 +1473,17 @@ std::string ObjectStoreMetaDataKey::Encode(int64 database_id,
return ret;
}
-std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id) {
- return Encode(database_id,
- std::numeric_limits<int64>::max(),
+std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64_t database_id) {
+ return Encode(database_id, std::numeric_limits<int64_t>::max(),
kObjectMetaDataTypeMaximum);
}
-std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id,
- int64 object_store_id) {
+std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id) {
return Encode(database_id, object_store_id, kObjectMetaDataTypeMaximum);
}
-int64 ObjectStoreMetaDataKey::ObjectStoreId() const {
+int64_t ObjectStoreMetaDataKey::ObjectStoreId() const {
DCHECK_GE(object_store_id_, 0);
return object_store_id_;
}
@@ -1520,9 +1521,9 @@ bool IndexMetaDataKey::Decode(StringPiece* slice, IndexMetaDataKey* result) {
return true;
}
-std::string IndexMetaDataKey::Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id,
+std::string IndexMetaDataKey::Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
unsigned char meta_data_type) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
@@ -1533,17 +1534,15 @@ std::string IndexMetaDataKey::Encode(int64 database_id,
return ret;
}
-std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
- int64 object_store_id) {
- return Encode(database_id,
- object_store_id,
- std::numeric_limits<int64>::max(),
- kIndexMetaDataTypeMaximum);
+std::string IndexMetaDataKey::EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id) {
+ return Encode(database_id, object_store_id,
+ std::numeric_limits<int64_t>::max(), kIndexMetaDataTypeMaximum);
}
-std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+std::string IndexMetaDataKey::EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
return Encode(
database_id, object_store_id, index_id, kIndexMetaDataTypeMaximum);
}
@@ -1559,7 +1558,7 @@ int IndexMetaDataKey::Compare(const IndexMetaDataKey& other) {
return meta_data_type_ - other.meta_data_type_;
}
-int64 IndexMetaDataKey::IndexId() const {
+int64_t IndexMetaDataKey::IndexId() const {
DCHECK_GE(index_id_, 0);
return index_id_;
}
@@ -1583,8 +1582,8 @@ bool ObjectStoreFreeListKey::Decode(StringPiece* slice,
return true;
}
-std::string ObjectStoreFreeListKey::Encode(int64 database_id,
- int64 object_store_id) {
+std::string ObjectStoreFreeListKey::Encode(int64_t database_id,
+ int64_t object_store_id) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
ret.push_back(kObjectStoreFreeListTypeByte);
@@ -1592,11 +1591,11 @@ std::string ObjectStoreFreeListKey::Encode(int64 database_id,
return ret;
}
-std::string ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id) {
- return Encode(database_id, std::numeric_limits<int64>::max());
+std::string ObjectStoreFreeListKey::EncodeMaxKey(int64_t database_id) {
+ return Encode(database_id, std::numeric_limits<int64_t>::max());
}
-int64 ObjectStoreFreeListKey::ObjectStoreId() const {
+int64_t ObjectStoreFreeListKey::ObjectStoreId() const {
DCHECK_GE(object_store_id_, 0);
return object_store_id_;
}
@@ -1629,9 +1628,9 @@ bool IndexFreeListKey::Decode(StringPiece* slice, IndexFreeListKey* result) {
return true;
}
-std::string IndexFreeListKey::Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+std::string IndexFreeListKey::Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
ret.push_back(kIndexFreeListTypeByte);
@@ -1640,10 +1639,10 @@ std::string IndexFreeListKey::Encode(int64 database_id,
return ret;
}
-std::string IndexFreeListKey::EncodeMaxKey(int64 database_id,
- int64 object_store_id) {
- return Encode(
- database_id, object_store_id, std::numeric_limits<int64>::max());
+std::string IndexFreeListKey::EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id) {
+ return Encode(database_id, object_store_id,
+ std::numeric_limits<int64_t>::max());
}
int IndexFreeListKey::Compare(const IndexFreeListKey& other) {
@@ -1654,12 +1653,12 @@ int IndexFreeListKey::Compare(const IndexFreeListKey& other) {
return CompareInts(index_id_, other.index_id_);
}
-int64 IndexFreeListKey::ObjectStoreId() const {
+int64_t IndexFreeListKey::ObjectStoreId() const {
DCHECK_GE(object_store_id_, 0);
return object_store_id_;
}
-int64 IndexFreeListKey::IndexId() const {
+int64_t IndexFreeListKey::IndexId() const {
DCHECK_GE(index_id_, 0);
return index_id_;
}
@@ -1685,7 +1684,7 @@ bool ObjectStoreNamesKey::Decode(StringPiece* slice,
}
std::string ObjectStoreNamesKey::Encode(
- int64 database_id,
+ int64_t database_id,
const base::string16& object_store_name) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
@@ -1720,8 +1719,8 @@ bool IndexNamesKey::Decode(StringPiece* slice, IndexNamesKey* result) {
return true;
}
-std::string IndexNamesKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string IndexNamesKey::Encode(int64_t database_id,
+ int64_t object_store_id,
const base::string16& index_name) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
@@ -1754,8 +1753,8 @@ bool ObjectStoreDataKey::Decode(StringPiece* slice,
return true;
}
-std::string ObjectStoreDataKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string ObjectStoreDataKey::Encode(int64_t database_id,
+ int64_t object_store_id,
const std::string encoded_user_key) {
KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
database_id, object_store_id, kSpecialIndexNumber));
@@ -1765,8 +1764,8 @@ std::string ObjectStoreDataKey::Encode(int64 database_id,
return ret;
}
-std::string ObjectStoreDataKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string ObjectStoreDataKey::Encode(int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& user_key) {
std::string encoded_key;
EncodeIDBKey(user_key, &encoded_key);
@@ -1779,10 +1778,10 @@ scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
if (!DecodeIDBKey(&slice, &key)) {
// TODO(jsbell): Return error.
}
- return key.Pass();
+ return key;
}
-const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
+const int64_t ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
ExistsEntryKey::ExistsEntryKey() {}
ExistsEntryKey::~ExistsEntryKey() {}
@@ -1799,8 +1798,8 @@ bool ExistsEntryKey::Decode(StringPiece* slice, ExistsEntryKey* result) {
return true;
}
-std::string ExistsEntryKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string ExistsEntryKey::Encode(int64_t database_id,
+ int64_t object_store_id,
const std::string& encoded_key) {
KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
database_id, object_store_id, kSpecialIndexNumber));
@@ -1809,8 +1808,8 @@ std::string ExistsEntryKey::Encode(int64 database_id,
return ret;
}
-std::string ExistsEntryKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string ExistsEntryKey::Encode(int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& user_key) {
std::string encoded_key;
EncodeIDBKey(user_key, &encoded_key);
@@ -1823,10 +1822,10 @@ scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
if (!DecodeIDBKey(&slice, &key)) {
// TODO(jsbell): Return error.
}
- return key.Pass();
+ return key;
}
-const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
+const int64_t ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
bool BlobEntryKey::Decode(StringPiece* slice, BlobEntryKey* result) {
KeyPrefix prefix;
@@ -1870,14 +1869,14 @@ std::string BlobEntryKey::ReencodeToObjectStoreDataKey(StringPiece* slice) {
key.database_id_, key.object_store_id_, key.encoded_user_key_);
}
-std::string BlobEntryKey::EncodeMinKeyForObjectStore(int64 database_id,
- int64 object_store_id) {
+std::string BlobEntryKey::EncodeMinKeyForObjectStore(int64_t database_id,
+ int64_t object_store_id) {
// Our implied encoded_user_key_ here is empty, the lowest possible key.
return Encode(database_id, object_store_id, std::string());
}
-std::string BlobEntryKey::EncodeStopKeyForObjectStore(int64 database_id,
- int64 object_store_id) {
+std::string BlobEntryKey::EncodeStopKeyForObjectStore(int64_t database_id,
+ int64_t object_store_id) {
DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
database_id, object_store_id, kSpecialIndexNumber + 1));
@@ -1889,16 +1888,16 @@ std::string BlobEntryKey::Encode() const {
return Encode(database_id_, object_store_id_, encoded_user_key_);
}
-std::string BlobEntryKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string BlobEntryKey::Encode(int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& user_key) {
std::string encoded_key;
EncodeIDBKey(user_key, &encoded_key);
return Encode(database_id, object_store_id, encoded_key);
}
-std::string BlobEntryKey::Encode(int64 database_id,
- int64 object_store_id,
+std::string BlobEntryKey::Encode(int64_t database_id,
+ int64_t object_store_id,
const std::string& encoded_user_key) {
DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
@@ -1906,7 +1905,7 @@ std::string BlobEntryKey::Encode(int64 database_id,
return prefix.Encode() + encoded_user_key;
}
-const int64 BlobEntryKey::kSpecialIndexNumber = kBlobEntryIndexId;
+const int64_t BlobEntryKey::kSpecialIndexNumber = kBlobEntryIndexId;
IndexDataKey::IndexDataKey()
: database_id_(-1),
@@ -1946,12 +1945,12 @@ bool IndexDataKey::Decode(StringPiece* slice, IndexDataKey* result) {
return true;
}
-std::string IndexDataKey::Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id,
+std::string IndexDataKey::Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const std::string& encoded_user_key,
const std::string& encoded_primary_key,
- int64 sequence_number) {
+ int64_t sequence_number) {
KeyPrefix prefix(database_id, object_store_id, index_id);
std::string ret = prefix.Encode();
ret.append(encoded_user_key);
@@ -1960,9 +1959,9 @@ std::string IndexDataKey::Encode(int64 database_id,
return ret;
}
-std::string IndexDataKey::Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id,
+std::string IndexDataKey::Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& user_key) {
std::string encoded_key;
EncodeIDBKey(user_key, &encoded_key);
@@ -1970,9 +1969,9 @@ std::string IndexDataKey::Encode(int64 database_id,
database_id, object_store_id, index_id, encoded_key, MinIDBKey(), 0);
}
-std::string IndexDataKey::Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id,
+std::string IndexDataKey::Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& user_key,
const IndexedDBKey& user_primary_key) {
std::string encoded_key;
@@ -1987,35 +1986,31 @@ std::string IndexDataKey::Encode(int64 database_id,
0);
}
-std::string IndexDataKey::EncodeMinKey(int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+std::string IndexDataKey::EncodeMinKey(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
return Encode(
database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey(), 0);
}
-std::string IndexDataKey::EncodeMaxKey(int64 database_id,
- int64 object_store_id,
- int64 index_id) {
- return Encode(database_id,
- object_store_id,
- index_id,
- MaxIDBKey(),
- MaxIDBKey(),
- std::numeric_limits<int64>::max());
+std::string IndexDataKey::EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
+ return Encode(database_id, object_store_id, index_id, MaxIDBKey(),
+ MaxIDBKey(), std::numeric_limits<int64_t>::max());
}
-int64 IndexDataKey::DatabaseId() const {
+int64_t IndexDataKey::DatabaseId() const {
DCHECK_GE(database_id_, 0);
return database_id_;
}
-int64 IndexDataKey::ObjectStoreId() const {
+int64_t IndexDataKey::ObjectStoreId() const {
DCHECK_GE(object_store_id_, 0);
return object_store_id_;
}
-int64 IndexDataKey::IndexId() const {
+int64_t IndexDataKey::IndexId() const {
DCHECK_GE(index_id_, 0);
return index_id_;
}
@@ -2026,7 +2021,7 @@ scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const {
if (!DecodeIDBKey(&slice, &key)) {
// TODO(jsbell): Return error.
}
- return key.Pass();
+ return key;
}
scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
@@ -2035,7 +2030,7 @@ scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
if (!DecodeIDBKey(&slice, &key)) {
// TODO(jsbell): Return error.
}
- return key.Pass();
+ return key;
}
} // namespace content
diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h
index 4d72652b88d..bd3724c798a 100644
--- a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h
+++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h
@@ -5,12 +5,15 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
@@ -31,8 +34,8 @@ typedef std::vector<BlobJournalEntryType> BlobJournalType;
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 EncodeInt(int64_t value, std::string* into);
+CONTENT_EXPORT void EncodeVarInt(int64_t value, std::string* into);
CONTENT_EXPORT void EncodeString(const base::string16& value,
std::string* into);
CONTENT_EXPORT void EncodeStringWithLength(const base::string16& value,
@@ -50,9 +53,9 @@ CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeByte(base::StringPiece* slice,
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBool(base::StringPiece* slice,
bool* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeInt(base::StringPiece* slice,
- int64* value);
+ int64_t* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeVarInt(base::StringPiece* slice,
- int64* value);
+ int64_t* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeString(base::StringPiece* slice,
base::string16* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeStringWithLength(
@@ -118,58 +121,58 @@ class KeyPrefix {
kMaxObjectStoreIdSizeBytes * 8 - 1; // 63
static const size_t kMaxIndexIdBits = kMaxIndexIdSizeBytes * 8 - 1; // 31
- static const int64 kMaxDatabaseId =
- (1ULL << kMaxDatabaseIdBits) - 1; // max signed int64
- static const int64 kMaxObjectStoreId =
- (1ULL << kMaxObjectStoreIdBits) - 1; // max signed int64
- static const int64 kMaxIndexId =
- (1ULL << kMaxIndexIdBits) - 1; // max signed int32
+ static const int64_t kMaxDatabaseId =
+ (1ULL << kMaxDatabaseIdBits) - 1; // max signed int64_t
+ static const int64_t kMaxObjectStoreId =
+ (1ULL << kMaxObjectStoreIdBits) - 1; // max signed int64_t
+ static const int64_t kMaxIndexId =
+ (1ULL << kMaxIndexIdBits) - 1; // max signed int32_t
- static const int64 kInvalidId = -1;
+ static const int64_t kInvalidId = -1;
KeyPrefix();
- explicit KeyPrefix(int64 database_id);
- KeyPrefix(int64 database_id, int64 object_store_id);
- KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id);
- static KeyPrefix CreateWithSpecialIndex(int64 database_id,
- int64 object_store_id,
- int64 index_id);
+ explicit KeyPrefix(int64_t database_id);
+ KeyPrefix(int64_t database_id, int64_t object_store_id);
+ KeyPrefix(int64_t database_id, int64_t object_store_id, int64_t index_id);
+ static KeyPrefix CreateWithSpecialIndex(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id);
static bool Decode(base::StringPiece* slice, KeyPrefix* result);
std::string Encode() const;
static std::string EncodeEmpty();
int Compare(const KeyPrefix& other) const;
- CONTENT_EXPORT static bool IsValidDatabaseId(int64 database_id);
- static bool IsValidObjectStoreId(int64 index_id);
- static bool IsValidIndexId(int64 index_id);
- static bool ValidIds(int64 database_id,
- int64 object_store_id,
- int64 index_id) {
+ CONTENT_EXPORT static bool IsValidDatabaseId(int64_t database_id);
+ static bool IsValidObjectStoreId(int64_t index_id);
+ static bool IsValidIndexId(int64_t index_id);
+ static bool ValidIds(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id) {
return IsValidDatabaseId(database_id) &&
IsValidObjectStoreId(object_store_id) && IsValidIndexId(index_id);
}
- static bool ValidIds(int64 database_id, int64 object_store_id) {
+ static bool ValidIds(int64_t database_id, int64_t object_store_id) {
return IsValidDatabaseId(database_id) &&
IsValidObjectStoreId(object_store_id);
}
Type type() const;
- int64 database_id_;
- int64 object_store_id_;
- int64 index_id_;
+ int64_t database_id_;
+ int64_t object_store_id_;
+ int64_t index_id_;
private:
// Special constructor for CreateWithSpecialIndex()
KeyPrefix(enum Type,
- int64 database_id,
- int64 object_store_id,
- int64 index_id);
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id);
- static std::string EncodeInternal(int64 database_id,
- int64 object_store_id,
- int64 index_id);
+ static std::string EncodeInternal(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id);
};
class SchemaVersionKey {
@@ -201,13 +204,13 @@ class DatabaseFreeListKey {
public:
DatabaseFreeListKey();
static bool Decode(base::StringPiece* slice, DatabaseFreeListKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id);
+ CONTENT_EXPORT static std::string Encode(int64_t database_id);
static CONTENT_EXPORT std::string EncodeMaxKey();
- int64 DatabaseId() const;
+ int64_t DatabaseId() const;
int Compare(const DatabaseFreeListKey& other) const;
private:
- int64 database_id_;
+ int64_t database_id_;
};
class DatabaseNameKey {
@@ -241,13 +244,13 @@ class DatabaseMetaDataKey {
MAX_SIMPLE_METADATA_TYPE = 6
};
- CONTENT_EXPORT static const int64 kAllBlobsKey;
- static const int64 kBlobKeyGeneratorInitialNumber;
+ CONTENT_EXPORT static const int64_t kAllBlobsKey;
+ static const int64_t kBlobKeyGeneratorInitialNumber;
// All keys <= 0 are invalid. This one's just a convenient example.
- static const int64 kInvalidBlobKey;
+ static const int64_t kInvalidBlobKey;
- static bool IsValidBlobKey(int64 blob_key);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
+ static bool IsValidBlobKey(int64_t blob_key);
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
MetaDataType type);
};
@@ -266,18 +269,18 @@ class ObjectStoreMetaDataKey {
ObjectStoreMetaDataKey();
static bool Decode(base::StringPiece* slice, ObjectStoreMetaDataKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- int64 object_store_id,
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
unsigned char meta_data_type);
- CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id);
- CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
- int64 object_store_id);
- int64 ObjectStoreId() const;
+ CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id);
+ CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id);
+ int64_t ObjectStoreId() const;
unsigned char MetaDataType() const;
int Compare(const ObjectStoreMetaDataKey& other);
private:
- int64 object_store_id_;
+ int64_t object_store_id_;
unsigned char meta_data_type_;
};
@@ -292,22 +295,22 @@ class IndexMetaDataKey {
IndexMetaDataKey();
static bool Decode(base::StringPiece* slice, IndexMetaDataKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
unsigned char meta_data_type);
- CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
- int64 object_store_id);
- CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
- int64 object_store_id,
- int64 index_id);
+ CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id);
+ CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id);
int Compare(const IndexMetaDataKey& other);
- int64 IndexId() const;
+ int64_t IndexId() const;
unsigned char meta_data_type() const { return meta_data_type_; }
private:
- int64 object_store_id_;
- int64 index_id_;
+ int64_t object_store_id_;
+ int64_t index_id_;
unsigned char meta_data_type_;
};
@@ -315,32 +318,32 @@ class ObjectStoreFreeListKey {
public:
ObjectStoreFreeListKey();
static bool Decode(base::StringPiece* slice, ObjectStoreFreeListKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- int64 object_store_id);
- CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id);
- int64 ObjectStoreId() const;
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
+ int64_t object_store_id);
+ CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id);
+ int64_t ObjectStoreId() const;
int Compare(const ObjectStoreFreeListKey& other);
private:
- int64 object_store_id_;
+ int64_t object_store_id_;
};
class IndexFreeListKey {
public:
IndexFreeListKey();
static bool Decode(base::StringPiece* slice, IndexFreeListKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id);
- CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
- int64 object_store_id);
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id);
+ CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id);
int Compare(const IndexFreeListKey& other);
- int64 ObjectStoreId() const;
- int64 IndexId() const;
+ int64_t ObjectStoreId() const;
+ int64_t IndexId() const;
private:
- int64 object_store_id_;
- int64 index_id_;
+ int64_t object_store_id_;
+ int64_t index_id_;
};
class ObjectStoreNamesKey {
@@ -350,7 +353,7 @@ class ObjectStoreNamesKey {
// mapping become unreliable? Can we remove this?
static bool Decode(base::StringPiece* slice, ObjectStoreNamesKey* result);
CONTENT_EXPORT static std::string Encode(
- int64 database_id,
+ int64_t database_id,
const base::string16& object_store_name);
int Compare(const ObjectStoreNamesKey& other);
base::string16 object_store_name() const { return object_store_name_; }
@@ -366,30 +369,30 @@ class IndexNamesKey {
// TODO(jsbell): We never use this to look up index ids, because a mapping
// is kept at a higher level.
static bool Decode(base::StringPiece* slice, IndexNamesKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- int64 object_store_id,
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
const base::string16& index_name);
int Compare(const IndexNamesKey& other);
base::string16 index_name() const { return index_name_; }
private:
- int64 object_store_id_;
+ int64_t object_store_id_;
base::string16 index_name_;
};
class ObjectStoreDataKey {
public:
- static const int64 kSpecialIndexNumber;
+ static const int64_t kSpecialIndexNumber;
ObjectStoreDataKey();
~ObjectStoreDataKey();
static bool Decode(base::StringPiece* slice, ObjectStoreDataKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- int64 object_store_id,
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
const std::string encoded_user_key);
- static std::string Encode(int64 database_id,
- int64 object_store_id,
+ static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& user_key);
scoped_ptr<IndexedDBKey> user_key() const;
private:
@@ -402,16 +405,16 @@ class ExistsEntryKey {
~ExistsEntryKey();
static bool Decode(base::StringPiece* slice, ExistsEntryKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- int64 object_store_id,
+ CONTENT_EXPORT static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
const std::string& encoded_key);
- static std::string Encode(int64 database_id,
- int64 object_store_id,
+ static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& user_key);
scoped_ptr<IndexedDBKey> user_key() const;
private:
- static const int64 kSpecialIndexNumber;
+ static const int64_t kSpecialIndexNumber;
std::string encoded_user_key_;
DISALLOW_COPY_AND_ASSIGN(ExistsEntryKey);
@@ -424,25 +427,25 @@ class BlobEntryKey {
static bool FromObjectStoreDataKey(base::StringPiece* slice,
BlobEntryKey* result);
static std::string ReencodeToObjectStoreDataKey(base::StringPiece* slice);
- static std::string EncodeMinKeyForObjectStore(int64 database_id,
- int64 object_store_id);
- static std::string EncodeStopKeyForObjectStore(int64 database_id,
- int64 object_store_id);
- static std::string Encode(int64 database_id,
- int64 object_store_id,
+ static std::string EncodeMinKeyForObjectStore(int64_t database_id,
+ int64_t object_store_id);
+ static std::string EncodeStopKeyForObjectStore(int64_t database_id,
+ int64_t object_store_id);
+ static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
const IndexedDBKey& user_key);
std::string Encode() const;
- int64 database_id() const { return database_id_; }
- int64 object_store_id() const { return object_store_id_; }
+ int64_t database_id() const { return database_id_; }
+ int64_t object_store_id() const { return object_store_id_; }
private:
- static const int64 kSpecialIndexNumber;
+ static const int64_t kSpecialIndexNumber;
- static std::string Encode(int64 database_id,
- int64 object_store_id,
+ static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
const std::string& encoded_user_key);
- int64 database_id_;
- int64 object_store_id_;
+ int64_t database_id_;
+ int64_t object_store_id_;
// This is the user's ObjectStoreDataKey, not the BlobEntryKey itself.
std::string encoded_user_key_;
};
@@ -453,40 +456,40 @@ class IndexDataKey {
~IndexDataKey();
static bool Decode(base::StringPiece* slice, IndexDataKey* result);
CONTENT_EXPORT static std::string Encode(
- int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const std::string& encoded_user_key,
const std::string& encoded_primary_key,
- int64 sequence_number);
- static std::string Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ int64_t sequence_number);
+ static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& user_key);
- static std::string Encode(int64 database_id,
- int64 object_store_id,
- int64 index_id,
+ static std::string Encode(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id,
const IndexedDBKey& user_key,
const IndexedDBKey& user_primary_key);
- static std::string EncodeMinKey(int64 database_id,
- int64 object_store_id,
- int64 index_id);
- CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
- int64 object_store_id,
- int64 index_id);
- int64 DatabaseId() const;
- int64 ObjectStoreId() const;
- int64 IndexId() const;
+ static std::string EncodeMinKey(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id);
+ CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id,
+ int64_t object_store_id,
+ int64_t index_id);
+ int64_t DatabaseId() const;
+ int64_t ObjectStoreId() const;
+ int64_t IndexId() const;
scoped_ptr<IndexedDBKey> user_key() const;
scoped_ptr<IndexedDBKey> primary_key() const;
private:
- int64 database_id_;
- int64 object_store_id_;
- int64 index_id_;
+ int64_t database_id_;
+ int64_t object_store_id_;
+ int64_t index_id_;
std::string encoded_user_key_;
std::string encoded_primary_key_;
- int64 sequence_number_;
+ int64_t sequence_number_;
DISALLOW_COPY_AND_ASSIGN(IndexDataKey);
};
diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
index bba0c76e3af..2f9e141d0ea 100644
--- a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
@@ -4,10 +4,13 @@
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <limits>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
@@ -169,7 +172,7 @@ TEST(IndexedDBLevelDBCodingTest, MinIDBKey) {
EXPECT_LT(CompareKeys(min_key, date_key), 0);
}
-static std::string WrappedEncodeInt(int64 value) {
+static std::string WrappedEncodeInt(int64_t value) {
std::string buffer;
EncodeInt(value, &buffer);
return buffer;
@@ -213,7 +216,7 @@ TEST(IndexedDBLevelDBCodingTest, DecodeBool) {
}
TEST(IndexedDBLevelDBCodingTest, DecodeInt) {
- std::vector<int64> test_cases;
+ std::vector<int64_t> test_cases;
test_cases.push_back(0);
test_cases.push_back(1);
test_cases.push_back(255);
@@ -227,11 +230,11 @@ TEST(IndexedDBLevelDBCodingTest, DecodeInt) {
#endif
for (size_t i = 0; i < test_cases.size(); ++i) {
- int64 n = test_cases[i];
+ int64_t n = test_cases[i];
std::string v = WrappedEncodeInt(n);
ASSERT_GT(v.size(), 0u);
StringPiece slice(v);
- int64 value;
+ int64_t value;
EXPECT_TRUE(DecodeInt(&slice, &value));
EXPECT_EQ(n, value);
EXPECT_TRUE(slice.empty());
@@ -245,12 +248,12 @@ TEST(IndexedDBLevelDBCodingTest, DecodeInt) {
}
{
StringPiece slice;
- int64 value;
+ int64_t value;
EXPECT_FALSE(DecodeInt(&slice, &value));
}
}
-static std::string WrappedEncodeVarInt(int64 value) {
+static std::string WrappedEncodeVarInt(int64_t value) {
std::string buffer;
EncodeVarInt(value, &buffer);
return buffer;
@@ -270,7 +273,7 @@ TEST(IndexedDBLevelDBCodingTest, EncodeVarInt) {
}
TEST(IndexedDBLevelDBCodingTest, DecodeVarInt) {
- std::vector<int64> test_cases;
+ std::vector<int64_t> test_cases;
test_cases.push_back(0);
test_cases.push_back(1);
test_cases.push_back(255);
@@ -284,11 +287,11 @@ TEST(IndexedDBLevelDBCodingTest, DecodeVarInt) {
#endif
for (size_t i = 0; i < test_cases.size(); ++i) {
- int64 n = test_cases[i];
+ int64_t n = test_cases[i];
std::string v = WrappedEncodeVarInt(n);
ASSERT_GT(v.size(), 0u);
StringPiece slice(v);
- int64 res;
+ int64_t res;
EXPECT_TRUE(DecodeVarInt(&slice, &res));
EXPECT_EQ(n, res);
EXPECT_TRUE(slice.empty());
@@ -949,8 +952,8 @@ TEST(IndexedDBLevelDBCodingTest, ComparisonTest) {
keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 1));
keys.push_back(IndexDataKey::Encode(1, 1, 31, MinIDBKey(), MinIDBKey(), 0));
keys.push_back(IndexDataKey::Encode(1, 2, 30, MinIDBKey(), MinIDBKey(), 0));
- keys.push_back(
- IndexDataKey::EncodeMaxKey(1, 2, std::numeric_limits<int32>::max() - 1));
+ keys.push_back(IndexDataKey::EncodeMaxKey(
+ 1, 2, std::numeric_limits<int32_t>::max() - 1));
for (size_t i = 0; i < keys.size(); ++i) {
EXPECT_EQ(Compare(keys[i], keys[i], false), 0);
@@ -972,7 +975,7 @@ TEST(IndexedDBLevelDBCodingTest, EncodeVarIntVSEncodeByteTest) {
unsigned char n = test_cases[i];
std::string a = WrappedEncodeByte(n);
- std::string b = WrappedEncodeVarInt(static_cast<int64>(n));
+ std::string b = WrappedEncodeVarInt(static_cast<int64_t>(n));
EXPECT_EQ(a.size(), b.size());
EXPECT_EQ(*a.begin(), *b.begin());
diff --git a/chromium/content/browser/indexed_db/indexed_db_metadata.cc b/chromium/content/browser/indexed_db/indexed_db_metadata.cc
index 92c4c318c5a..74bdfbf9d01 100644
--- a/chromium/content/browser/indexed_db/indexed_db_metadata.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_metadata.cc
@@ -9,7 +9,7 @@ namespace content {
IndexedDBIndexMetadata::IndexedDBIndexMetadata() = default;
IndexedDBIndexMetadata::IndexedDBIndexMetadata(const base::string16& name,
- int64 id,
+ int64_t id,
const IndexedDBKeyPath& key_path,
bool unique,
bool multi_entry)
@@ -17,8 +17,7 @@ IndexedDBIndexMetadata::IndexedDBIndexMetadata(const base::string16& name,
id(id),
key_path(key_path),
unique(unique),
- multi_entry(multi_entry) {
-}
+ multi_entry(multi_entry) {}
IndexedDBIndexMetadata::IndexedDBIndexMetadata(
const IndexedDBIndexMetadata& other) = default;
@@ -30,10 +29,10 @@ IndexedDBIndexMetadata& IndexedDBIndexMetadata::operator=(
IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata(
const base::string16& name,
- int64 id,
+ int64_t id,
const IndexedDBKeyPath& key_path,
bool auto_increment,
- int64 max_index_id)
+ int64_t max_index_id)
: name(name),
id(id),
key_path(key_path),
@@ -55,10 +54,10 @@ IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata()
IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata(
const base::string16& name,
- int64 id,
+ int64_t id,
const base::string16& version,
- int64 int_version,
- int64 max_object_store_id)
+ int64_t int_version,
+ int64_t max_object_store_id)
: name(name),
id(id),
version(version),
diff --git a/chromium/content/browser/indexed_db/indexed_db_metadata.h b/chromium/content/browser/indexed_db/indexed_db_metadata.h
index e294868f9f1..288801722f4 100644
--- a/chromium/content/browser/indexed_db/indexed_db_metadata.h
+++ b/chromium/content/browser/indexed_db/indexed_db_metadata.h
@@ -5,20 +5,21 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_METADATA_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_METADATA_H_
+#include <stdint.h>
+
#include <map>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "content/common/indexed_db/indexed_db_key_path.h"
namespace content {
struct CONTENT_EXPORT IndexedDBIndexMetadata {
- static const int64 kInvalidId = -1;
+ static const int64_t kInvalidId = -1;
IndexedDBIndexMetadata();
IndexedDBIndexMetadata(const base::string16& name,
- int64 id,
+ int64_t id,
const IndexedDBKeyPath& key_path,
bool unique,
bool multi_entry);
@@ -27,33 +28,33 @@ struct CONTENT_EXPORT IndexedDBIndexMetadata {
IndexedDBIndexMetadata& operator=(const IndexedDBIndexMetadata& other);
base::string16 name;
- int64 id;
+ int64_t id;
IndexedDBKeyPath key_path;
bool unique;
bool multi_entry;
};
struct CONTENT_EXPORT IndexedDBObjectStoreMetadata {
- typedef std::map<int64, IndexedDBIndexMetadata> IndexMap;
+ typedef std::map<int64_t, IndexedDBIndexMetadata> IndexMap;
- static const int64 kInvalidId = -1;
+ static const int64_t kInvalidId = -1;
IndexedDBObjectStoreMetadata();
IndexedDBObjectStoreMetadata(const base::string16& name,
- int64 id,
+ int64_t id,
const IndexedDBKeyPath& key_path,
bool auto_increment,
- int64 max_index_id);
+ int64_t max_index_id);
IndexedDBObjectStoreMetadata(const IndexedDBObjectStoreMetadata& other);
~IndexedDBObjectStoreMetadata();
IndexedDBObjectStoreMetadata& operator=(
const IndexedDBObjectStoreMetadata& other);
base::string16 name;
- int64 id;
+ int64_t id;
IndexedDBKeyPath key_path;
bool auto_increment;
- int64 max_index_id;
+ int64_t max_index_id;
IndexMap indexes;
};
@@ -65,23 +66,23 @@ struct CONTENT_EXPORT IndexedDBDatabaseMetadata {
DEFAULT_INT_VERSION = 0
};
- typedef std::map<int64, IndexedDBObjectStoreMetadata> ObjectStoreMap;
+ typedef std::map<int64_t, IndexedDBObjectStoreMetadata> ObjectStoreMap;
IndexedDBDatabaseMetadata();
IndexedDBDatabaseMetadata(const base::string16& name,
- int64 id,
+ int64_t id,
const base::string16& version,
- int64 int_version,
- int64 max_object_store_id);
+ int64_t int_version,
+ int64_t max_object_store_id);
IndexedDBDatabaseMetadata(const IndexedDBDatabaseMetadata& other);
~IndexedDBDatabaseMetadata();
IndexedDBDatabaseMetadata& operator=(IndexedDBDatabaseMetadata& other);
base::string16 name;
- int64 id;
+ int64_t id;
base::string16 version;
- int64 int_version;
- int64 max_object_store_id;
+ int64_t int_version;
+ int64_t max_object_store_id;
ObjectStoreMap object_stores;
};
diff --git a/chromium/content/browser/indexed_db/indexed_db_pending_connection.cc b/chromium/content/browser/indexed_db/indexed_db_pending_connection.cc
index b1d63180852..ee16aba741e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_pending_connection.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_pending_connection.cc
@@ -10,8 +10,8 @@ IndexedDBPendingConnection::IndexedDBPendingConnection(
scoped_refptr<IndexedDBCallbacks> callbacks_in,
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks_in,
int child_process_id_in,
- int64 transaction_id_in,
- int64 version_in)
+ int64_t transaction_id_in,
+ int64_t version_in)
: callbacks(callbacks_in),
database_callbacks(database_callbacks_in),
child_process_id(child_process_id_in),
diff --git a/chromium/content/browser/indexed_db/indexed_db_pending_connection.h b/chromium/content/browser/indexed_db/indexed_db_pending_connection.h
index 598bef2641b..b66d9cd4955 100644
--- a/chromium/content/browser/indexed_db/indexed_db_pending_connection.h
+++ b/chromium/content/browser/indexed_db/indexed_db_pending_connection.h
@@ -5,7 +5,8 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_PENDING_CONNECTION_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_PENDING_CONNECTION_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/memory/ref_counted.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_database_callbacks.h"
@@ -21,14 +22,14 @@ struct CONTENT_EXPORT IndexedDBPendingConnection {
scoped_refptr<IndexedDBCallbacks> callbacks_in,
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks_in,
int child_process_id_in,
- int64 transaction_id_in,
- int64 version_in);
+ int64_t transaction_id_in,
+ int64_t version_in);
~IndexedDBPendingConnection();
scoped_refptr<IndexedDBCallbacks> callbacks;
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks;
int child_process_id;
- int64 transaction_id;
- int64 version;
+ int64_t transaction_id;
+ int64_t version;
};
} // namespace content
diff --git a/chromium/content/browser/indexed_db/indexed_db_quota_client.cc b/chromium/content/browser/indexed_db/indexed_db_quota_client.cc
index a33e4289645..433b2c130e0 100644
--- a/chromium/content/browser/indexed_db/indexed_db_quota_client.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_quota_client.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/indexed_db_quota_client.h"
+#include <stdint.h>
+
#include <vector>
#include "base/logging.h"
@@ -25,8 +27,8 @@ storage::QuotaStatusCode DeleteOriginDataOnIndexedDBThread(
return storage::kQuotaStatusOk;
}
-int64 GetOriginUsageOnIndexedDBThread(IndexedDBContextImpl* context,
- const GURL& origin) {
+int64_t GetOriginUsageOnIndexedDBThread(IndexedDBContextImpl* context,
+ const GURL& origin) {
DCHECK(context->TaskRunner()->RunsTasksOnCurrentThread());
return context->GetOriginDiskUsage(origin);
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_quota_client.h b/chromium/content/browser/indexed_db/indexed_db_quota_client.h
index a99588ca3f9..87246383dc2 100644
--- a/chromium/content/browser/indexed_db/indexed_db_quota_client.h
+++ b/chromium/content/browser/indexed_db/indexed_db_quota_client.h
@@ -8,6 +8,7 @@
#include <set>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
index 3bec0b04532..31a413693ed 100644
--- a/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <map>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread.h"
#include "content/browser/browser_thread_impl.h"
@@ -74,9 +77,9 @@ class IndexedDBQuotaClientTest : public testing::Test {
base::MessageLoop::current()->RunUntilIdle();
}
- int64 GetOriginUsage(storage::QuotaClient* client,
- const GURL& origin,
- storage::StorageType type) {
+ int64_t GetOriginUsage(storage::QuotaClient* client,
+ const GURL& origin,
+ storage::StorageType type) {
usage_ = -1;
client->GetOriginUsage(
origin,
@@ -148,7 +151,7 @@ class IndexedDBQuotaClientTest : public testing::Test {
}
private:
- void OnGetOriginUsageComplete(int64 usage) { usage_ = usage; }
+ void OnGetOriginUsageComplete(int64_t usage) { usage_ = usage; }
void OnGetOriginsComplete(const std::set<GURL>& origins) {
origins_ = origins;
@@ -159,7 +162,7 @@ class IndexedDBQuotaClientTest : public testing::Test {
}
base::ScopedTempDir temp_dir_;
- int64 usage_;
+ int64_t usage_;
std::set<GURL> origins_;
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
scoped_refptr<IndexedDBContextImpl> idb_context_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction.cc b/chromium/content/browser/indexed_db/indexed_db_transaction.cc
index 36faa51da0f..befca11e623 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction.cc
@@ -21,7 +21,7 @@
namespace content {
-const int64 kInactivityTimeoutPeriodSeconds = 60;
+const int64_t kInactivityTimeoutPeriodSeconds = 60;
IndexedDBTransaction::TaskQueue::TaskQueue() {}
IndexedDBTransaction::TaskQueue::~TaskQueue() { clear(); }
@@ -54,9 +54,9 @@ IndexedDBTransaction::Operation IndexedDBTransaction::TaskStack::pop() {
}
IndexedDBTransaction::IndexedDBTransaction(
- int64 id,
+ int64_t id,
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& object_store_ids,
+ const std::set<int64_t>& object_store_ids,
blink::WebIDBTransactionMode mode,
IndexedDBDatabase* database,
IndexedDBBackingStore::Transaction* backing_store_transaction)
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction.h b/chromium/content/browser/indexed_db/indexed_db_transaction.h
index 6171b3120d8..18dfb476182 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction.h
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction.h
@@ -5,12 +5,14 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_
+#include <stdint.h>
+
#include <queue>
#include <set>
#include <stack>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
@@ -47,7 +49,7 @@ class CONTENT_EXPORT IndexedDBTransaction
void Start();
blink::WebIDBTransactionMode mode() const { return mode_; }
- const std::set<int64>& scope() const { return object_store_ids_; }
+ const std::set<int64_t>& scope() const { return object_store_ids_; }
void ScheduleTask(Operation task) {
ScheduleTask(blink::WebIDBTaskTypeNormal, task);
@@ -64,7 +66,7 @@ class CONTENT_EXPORT IndexedDBTransaction
IndexedDBBackingStore::Transaction* BackingStoreTransaction() {
return transaction_.get();
}
- int64 id() const { return id_; }
+ int64_t id() const { return id_; }
IndexedDBDatabase* database() const { return database_.get(); }
IndexedDBDatabaseCallbacks* connection() const { return callbacks_.get(); }
@@ -85,9 +87,9 @@ class CONTENT_EXPORT IndexedDBTransaction
// Test classes may derive, but most creation should be done via
// IndexedDBClassFactory.
IndexedDBTransaction(
- int64 id,
+ int64_t id,
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& object_store_ids,
+ const std::set<int64_t>& object_store_ids,
blink::WebIDBTransactionMode mode,
IndexedDBDatabase* db,
IndexedDBBackingStore::Transaction* backing_store_transaction);
@@ -121,8 +123,8 @@ class CONTENT_EXPORT IndexedDBTransaction
leveldb::Status CommitPhaseTwo();
void Timeout();
- const int64 id_;
- const std::set<int64> object_store_ids_;
+ const int64_t id_;
+ const std::set<int64_t> object_store_ids_;
const blink::WebIDBTransactionMode mode_;
bool used_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc b/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
index 58e838b2594..f552141c53c 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
@@ -4,7 +4,6 @@
#include "content/browser/indexed_db/indexed_db_transaction_coordinator.h"
-#include "base/basictypes.h"
#include "base/logging.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
@@ -87,7 +86,7 @@ void IndexedDBTransactionCoordinator::ProcessQueuedTransactions() {
// taking a snapshot of the database, which does not include uncommitted
// data. ("Version change" transactions are exclusive, but handled by the
// connection sequencing in IndexedDBDatabase.)
- std::set<int64> locked_scope;
+ std::set<int64_t> locked_scope;
for (const auto& transaction : started_transactions_) {
if (transaction->mode() == blink::WebIDBTransactionModeReadWrite) {
// Started read/write transactions have exclusive access to the object
@@ -136,7 +135,7 @@ static bool DoSetsIntersect(const std::set<T>& set1,
bool IndexedDBTransactionCoordinator::CanStartTransaction(
IndexedDBTransaction* const transaction,
- const std::set<int64>& locked_scope) const {
+ const std::set<int64_t>& locked_scope) const {
DCHECK(queued_transactions_.count(transaction));
switch (transaction->mode()) {
case blink::WebIDBTransactionModeVersionChange:
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.h b/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.h
index 890541dfd24..e32883a4444 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.h
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_COORDINATOR_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_COORDINATOR_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/indexed_db/list_set.h"
@@ -41,7 +44,7 @@ class IndexedDBTransactionCoordinator {
void ProcessQueuedTransactions();
bool CanStartTransaction(IndexedDBTransaction* const transaction,
- const std::set<int64>& locked_scope) const;
+ const std::set<int64_t>& locked_scope) const;
// Transactions in different states are grouped below.
// list_set is used to provide stable ordering; required by spec
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc
index e033dd79e64..984296807fe 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc
@@ -4,8 +4,11 @@
#include "content/browser/indexed_db/indexed_db_transaction.h"
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.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"
@@ -79,8 +82,8 @@ class IndexedDBTransactionTestMode
};
TEST_F(IndexedDBTransactionTest, Timeout) {
- const int64 id = 0;
- const std::set<int64> scope;
+ const int64_t id = 0;
+ const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
id,
@@ -123,8 +126,8 @@ TEST_F(IndexedDBTransactionTest, Timeout) {
}
TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) {
- const int64 id = 0;
- const std::set<int64> scope;
+ const int64_t id = 0;
+ const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
id,
@@ -155,8 +158,8 @@ TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) {
}
TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) {
- const int64 id = 0;
- const std::set<int64> scope;
+ const int64_t id = 0;
+ const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
id,
@@ -217,8 +220,8 @@ TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) {
}
TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) {
- const int64 id = 0;
- const std::set<int64> scope;
+ const int64_t id = 0;
+ const std::set<int64_t> scope;
const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
id,
@@ -278,8 +281,8 @@ TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) {
}
TEST_P(IndexedDBTransactionTestMode, AbortTasks) {
- const int64 id = 0;
- const std::set<int64> scope;
+ const int64_t id = 0;
+ const std::set<int64_t> scope;
const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
id,
@@ -308,8 +311,8 @@ TEST_P(IndexedDBTransactionTestMode, AbortTasks) {
}
TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) {
- const int64 id = 0;
- const std::set<int64> scope;
+ const int64_t id = 0;
+ const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
id,
diff --git a/chromium/content/browser/indexed_db/indexed_db_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_unittest.cc
index ddb1fdc66bd..f7ea47817e6 100644
--- a/chromium/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_unittest.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread.h"
#include "content/browser/browser_thread_impl.h"
@@ -134,7 +138,7 @@ class ForceCloseDBCallbacks : public IndexedDBCallbacks {
void OnSuccess(const std::vector<base::string16>&) override {}
void OnSuccess(scoped_ptr<IndexedDBConnection> connection,
const IndexedDBDatabaseMetadata& metadata) override {
- connection_ = connection.Pass();
+ connection_ = std::move(connection);
idb_context_->ConnectionOpened(origin_url_, connection_.get());
}
@@ -263,7 +267,7 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) {
scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
new MockIndexedDBDatabaseCallbacks());
- const int64 transaction_id = 1;
+ const int64_t transaction_id = 1;
IndexedDBPendingConnection connection(
callbacks,
db_callbacks,
diff --git a/chromium/content/browser/indexed_db/indexed_db_value.h b/chromium/content/browser/indexed_db/indexed_db_value.h
index 7b2377ad03b..33bb45ae677 100644
--- a/chromium/content/browser/indexed_db/indexed_db_value.h
+++ b/chromium/content/browser/indexed_db/indexed_db_value.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_VALUE_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_VALUE_H_
+#include <stddef.h>
+
#include <algorithm>
#include <string>
#include <vector>
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
index 7efd98625c4..8bd919e7c5d 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
@@ -4,11 +4,13 @@
#include "content/browser/indexed_db/leveldb/leveldb_database.h"
+#include <stdint.h>
#include <cerrno>
+#include <utility>
-#include "base/basictypes.h"
#include "base/files/file.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/strings/string16.h"
@@ -16,6 +18,7 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
+#include "build/build_config.h"
#include "content/browser/indexed_db/indexed_db_class_factory.h"
#include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
@@ -165,7 +168,7 @@ static int CheckFreeSpace(const char* const type,
const base::FilePath& file_name) {
std::string name =
std::string("WebCore.IndexedDB.LevelDB.Open") + type + "FreeDiskSpace";
- int64 free_disk_space_in_k_bytes =
+ int64_t free_disk_space_in_k_bytes =
base::SysInfo::AmountOfFreeDiskSpace(file_name) / 1024;
if (free_disk_space_in_k_bytes < 0) {
base::Histogram::FactoryGet(
@@ -179,7 +182,7 @@ static int CheckFreeSpace(const char* const type,
int clamped_disk_space_k_bytes = free_disk_space_in_k_bytes > INT_MAX
? INT_MAX
: free_disk_space_in_k_bytes;
- const uint64 histogram_max = static_cast<uint64>(1e9);
+ const uint64_t histogram_max = static_cast<uint64_t>(1e9);
static_assert(histogram_max <= INT_MAX, "histogram_max too big");
base::Histogram::FactoryGet(name,
1,
@@ -305,9 +308,9 @@ leveldb::Status LevelDBDatabase::Open(const base::FilePath& file_name,
(*result).reset(new LevelDBDatabase);
(*result)->db_ = make_scoped_ptr(db);
- (*result)->comparator_adapter_ = comparator_adapter.Pass();
+ (*result)->comparator_adapter_ = std::move(comparator_adapter);
(*result)->comparator_ = comparator;
- (*result)->filter_policy_ = filter_policy.Pass();
+ (*result)->filter_policy_ = std::move(filter_policy);
return s;
}
@@ -332,13 +335,13 @@ scoped_ptr<LevelDBDatabase> LevelDBDatabase::OpenInMemory(
}
scoped_ptr<LevelDBDatabase> result(new LevelDBDatabase);
- result->env_ = in_memory_env.Pass();
+ result->env_ = std::move(in_memory_env);
result->db_ = make_scoped_ptr(db);
- result->comparator_adapter_ = comparator_adapter.Pass();
+ result->comparator_adapter_ = std::move(comparator_adapter);
result->comparator_ = comparator;
- result->filter_policy_ = filter_policy.Pass();
+ result->filter_policy_ = std::move(filter_policy);
- return result.Pass();
+ return result;
}
leveldb::Status LevelDBDatabase::Put(const StringPiece& key,
@@ -416,7 +419,7 @@ scoped_ptr<LevelDBIterator> LevelDBDatabase::CreateIterator(
scoped_ptr<leveldb::Iterator> i(db_->NewIterator(read_options));
return scoped_ptr<LevelDBIterator>(
- IndexedDBClassFactory::Get()->CreateIteratorImpl(i.Pass()));
+ IndexedDBClassFactory::Get()->CreateIteratorImpl(std::move(i)));
}
const LevelDBComparator* LevelDBDatabase::Comparator() const {
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_database.h b/chromium/content/browser/indexed_db/leveldb/leveldb_database.h
index 60a38ec3682..d5e469a6861 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_database.h
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_database.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc
index 46c99f4b60b..35d679e9052 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc
@@ -2,9 +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/indexed_db/leveldb/leveldb_iterator_impl.h"
+
+#include <utility>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "content/browser/indexed_db/leveldb/leveldb_iterator_impl.h"
static leveldb::Slice MakeSlice(const base::StringPiece& s) {
return leveldb::Slice(s.begin(), s.size());
@@ -20,8 +23,7 @@ LevelDBIteratorImpl::~LevelDBIteratorImpl() {
}
LevelDBIteratorImpl::LevelDBIteratorImpl(scoped_ptr<leveldb::Iterator> it)
- : iterator_(it.Pass()) {
-}
+ : iterator_(std::move(it)) {}
void LevelDBIteratorImpl::CheckStatus() {
const leveldb::Status& s = iterator_->status();
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h b/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h
index 72b92e0f93b..81284296e34 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_iterator_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_ITERATOR_IMPL_H_
#define CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_ITERATOR_IMPL_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
index 0878f0bd61c..11a77c61ec2 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
@@ -99,8 +99,8 @@ leveldb::Status LevelDBTransaction::Commit() {
base::TimeTicks begin_time = base::TimeTicks::Now();
scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create();
- auto it = data_.begin(), end = data_.end();
- while (it != end) {
+ auto it = data_.begin();
+ while (it != data_.end()) {
if (!it->second->deleted)
write_batch->Put(it->first, it->second->value);
else
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.h b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.h
index 28d76569374..bc9afb1a11a 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.h
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc
index f3012cc9e72..e25d9de8d61 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <algorithm>
#include <cstring>
#include <string>
diff --git a/chromium/content/browser/indexed_db/list_set.h b/chromium/content/browser/indexed_db/list_set.h
index 98f3b88c24c..7ab40e51b99 100644
--- a/chromium/content/browser/indexed_db/list_set.h
+++ b/chromium/content/browser/indexed_db/list_set.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_LIST_SET_H_
#define CONTENT_BROWSER_INDEXED_DB_LIST_SET_H_
+#include <stddef.h>
+
#include <algorithm>
#include <iterator>
#include <list>
diff --git a/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc b/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc
index dc02ff7331c..60202ae0b30 100644
--- a/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc
+++ b/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc
@@ -2,13 +2,16 @@
// 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/mock_browsertest_indexed_db_class_factory.h"
+
+#include <stddef.h>
#include <string>
+#include <utility>
#include "base/logging.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator_impl.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
-#include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
@@ -60,9 +63,9 @@ class IndexedDBTestDatabase : public IndexedDBDatabase {
class IndexedDBTestTransaction : public IndexedDBTransaction {
public:
IndexedDBTestTransaction(
- int64 id,
+ int64_t id,
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& scope,
+ const std::set<int64_t>& scope,
blink::WebIDBTransactionMode mode,
IndexedDBDatabase* db,
IndexedDBBackingStore::Transaction* backing_store_transaction)
@@ -164,7 +167,7 @@ const std::string LevelDBTraceTransaction::s_class_name = "LevelDBTransaction";
class LevelDBTraceIteratorImpl : public LevelDBIteratorImpl {
public:
LevelDBTraceIteratorImpl(scoped_ptr<leveldb::Iterator> iterator, int inst_num)
- : LevelDBIteratorImpl(iterator.Pass()),
+ : LevelDBIteratorImpl(std::move(iterator)),
is_valid_tracer_(s_class_name, "IsValid", inst_num),
seek_to_last_tracer_(s_class_name, "SeekToLast", inst_num),
seek_tracer_(s_class_name, "Seek", inst_num),
@@ -222,7 +225,7 @@ class LevelDBTestIteratorImpl : public content::LevelDBIteratorImpl {
LevelDBTestIteratorImpl(scoped_ptr<leveldb::Iterator> iterator,
FailMethod fail_method,
int fail_on_call_num)
- : LevelDBIteratorImpl(iterator.Pass()),
+ : LevelDBIteratorImpl(std::move(iterator)),
fail_method_(fail_method),
fail_on_call_num_(fail_on_call_num),
current_call_num_(0) {}
@@ -262,9 +265,9 @@ MockBrowserTestIndexedDBClassFactory::CreateIndexedDBDatabase(
IndexedDBTransaction*
MockBrowserTestIndexedDBClassFactory::CreateIndexedDBTransaction(
- int64 id,
+ int64_t id,
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& scope,
+ const std::set<int64_t>& scope,
blink::WebIDBTransactionMode mode,
IndexedDBDatabase* db,
IndexedDBBackingStore::Transaction* backing_store_transaction) {
@@ -300,17 +303,16 @@ LevelDBIteratorImpl* MockBrowserTestIndexedDBClassFactory::CreateIteratorImpl(
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] + 1;
if (only_trace_calls_) {
return new LevelDBTraceIteratorImpl(
- iterator.Pass(), instance_count_[FAIL_CLASS_LEVELDB_ITERATOR]);
+ std::move(iterator), instance_count_[FAIL_CLASS_LEVELDB_ITERATOR]);
} else {
if (failure_class_ == FAIL_CLASS_LEVELDB_ITERATOR &&
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] ==
fail_on_instance_num_[FAIL_CLASS_LEVELDB_ITERATOR]) {
return new LevelDBTestIteratorImpl(
- iterator.Pass(),
- failure_method_,
+ std::move(iterator), failure_method_,
fail_on_call_num_[FAIL_CLASS_LEVELDB_ITERATOR]);
} else {
- return new LevelDBIteratorImpl(iterator.Pass());
+ return new LevelDBIteratorImpl(std::move(iterator));
}
}
}
diff --git a/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h b/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h
index 1b77071f0e5..acc050a6869 100644
--- a/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h
+++ b/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_MOCK_BROWSERTEST_INDEXED_DB_CLASS_FACTORY_H_
#define CONTENT_BROWSER_INDEXED_DB_MOCK_BROWSERTEST_INDEXED_DB_CLASS_FACTORY_H_
+#include <stdint.h>
+
#include <map>
#include <set>
@@ -44,9 +46,9 @@ class MockBrowserTestIndexedDBClassFactory : public IndexedDBClassFactory {
IndexedDBFactory* factory,
const IndexedDBDatabase::Identifier& unique_identifier) override;
IndexedDBTransaction* CreateIndexedDBTransaction(
- int64 id,
+ int64_t id,
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& scope,
+ const std::set<int64_t>& scope,
blink::WebIDBTransactionMode mode,
IndexedDBDatabase* db,
IndexedDBBackingStore::Transaction* backing_store_transaction) override;
diff --git a/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.cc b/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.cc
index 62afee8d438..79c134062c0 100644
--- a/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.cc
+++ b/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/mock_indexed_db_callbacks.h"
+#include <utility>
+
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
@@ -19,8 +21,7 @@ MockIndexedDBCallbacks::~MockIndexedDBCallbacks() {
void MockIndexedDBCallbacks::OnSuccess() {}
-void MockIndexedDBCallbacks::OnSuccess(int64 result) {
-}
+void MockIndexedDBCallbacks::OnSuccess(int64_t result) {}
void MockIndexedDBCallbacks::OnSuccess(const std::vector<base::string16>&) {}
@@ -29,7 +30,7 @@ void MockIndexedDBCallbacks::OnSuccess(const IndexedDBKey& key) {}
void MockIndexedDBCallbacks::OnSuccess(
scoped_ptr<IndexedDBConnection> connection,
const IndexedDBDatabaseMetadata& metadata) {
- connection_ = connection.Pass();
+ connection_ = std::move(connection);
}
} // namespace content
diff --git a/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.h b/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.h
index 24743fe0b32..44fa8d73b92 100644
--- a/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.h
+++ b/chromium/content/browser/indexed_db/mock_indexed_db_callbacks.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_MOCK_INDEXED_DB_CALLBACKS_H_
#define CONTENT_BROWSER_INDEXED_DB_MOCK_INDEXED_DB_CALLBACKS_H_
+#include <stdint.h>
+
#include <vector>
+#include "base/macros.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
@@ -18,7 +21,7 @@ class MockIndexedDBCallbacks : public IndexedDBCallbacks {
explicit MockIndexedDBCallbacks(bool expect_connection);
void OnSuccess() override;
- void OnSuccess(int64 result) override;
+ void OnSuccess(int64_t result) override;
void OnSuccess(const std::vector<base::string16>& result) override;
void OnSuccess(const IndexedDBKey& key) override;
void OnSuccess(scoped_ptr<IndexedDBConnection> connection,
diff --git a/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.cc b/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.cc
index 479bb3af60f..dbb75651b24 100644
--- a/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.cc
+++ b/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.cc
@@ -18,7 +18,7 @@ void MockIndexedDBDatabaseCallbacks::OnForcedClose() {
}
void MockIndexedDBDatabaseCallbacks::OnAbort(
- int64 transaction_id,
+ int64_t transaction_id,
const IndexedDBDatabaseError& error) {
abort_called_ = true;
}
diff --git a/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.h b/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.h
index 31a29645a25..20ea2b5430d 100644
--- a/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.h
+++ b/chromium/content/browser/indexed_db/mock_indexed_db_database_callbacks.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_MOCK_INDEXED_DB_DATABASE_CALLBACKS_H_
#define CONTENT_BROWSER_INDEXED_DB_MOCK_INDEXED_DB_DATABASE_CALLBACKS_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
@@ -14,11 +17,11 @@ class MockIndexedDBDatabaseCallbacks : public IndexedDBDatabaseCallbacks {
public:
MockIndexedDBDatabaseCallbacks();
- void OnVersionChange(int64 old_version, int64 new_version) override {}
+ void OnVersionChange(int64_t old_version, int64_t new_version) override {}
void OnForcedClose() override;
- void OnAbort(int64 transaction_id,
+ void OnAbort(int64_t transaction_id,
const IndexedDBDatabaseError& error) override;
- void OnComplete(int64 transaction_id) override {}
+ void OnComplete(int64_t transaction_id) override {}
bool abort_called() const { return abort_called_; }
bool forced_close_called() const { return forced_close_called_; }
diff --git a/chromium/content/browser/indexed_db/mock_indexed_db_factory.h b/chromium/content/browser/indexed_db/mock_indexed_db_factory.h
index b480758692c..207edf34572 100644
--- a/chromium/content/browser/indexed_db/mock_indexed_db_factory.h
+++ b/chromium/content/browser/indexed_db/mock_indexed_db_factory.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_MOCK_INDEXED_DB_FACTORY_H_
#define CONTENT_BROWSER_INDEXED_DB_MOCK_INDEXED_DB_FACTORY_H_
+#include <stddef.h>
+
#include <string>
+#include "base/macros.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chromium/content/browser/loader/async_resource_handler.cc b/chromium/content/browser/loader/async_resource_handler.cc
index 2eace36852e..df08aa79537 100644
--- a/chromium/content/browser/loader/async_resource_handler.cc
+++ b/chromium/content/browser/loader/async_resource_handler.cc
@@ -11,6 +11,7 @@
#include "base/containers/hash_tables.h"
#include "base/debug/alias.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
@@ -144,10 +145,10 @@ void AsyncResourceHandler::ReportUploadProgress() {
if (progress.position() == last_upload_position_)
return; // No progress made since last time.
- const uint64 kHalfPercentIncrements = 200;
+ const uint64_t kHalfPercentIncrements = 200;
const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000);
- uint64 amt_since_last = progress.position() - last_upload_position_;
+ uint64_t amt_since_last = progress.position() - last_upload_position_;
TimeDelta time_since_last = TimeTicks::Now() - last_upload_ticks_;
bool is_finished = (progress.size() == progress.position());
@@ -318,6 +319,9 @@ bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
int size;
if (!buffer_->ShareToProcess(filter->PeerHandle(), &handle, &size))
return false;
+
+ // TODO(erikchen): Temporary debugging. http://crbug.com/527588.
+ CHECK_LE(size, kBufferSize);
filter->Send(new ResourceMsg_SetDataBuffer(
GetRequestID(), handle, size, filter->peer_pid()));
sent_first_data_msg_ = true;
@@ -329,6 +333,10 @@ bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
int encoded_data_length = current_transfer_size - reported_transfer_size_;
reported_transfer_size_ = current_transfer_size;
+ // TODO(erikchen): Temporary debugging. http://crbug.com/527588.
+ CHECK_LE(data_offset, kBufferSize);
+
+ filter->Send(new ResourceMsg_DataReceivedDebug(GetRequestID(), data_offset));
filter->Send(new ResourceMsg_DataReceived(
GetRequestID(), data_offset, bytes_read, encoded_data_length));
++pending_data_count_;
diff --git a/chromium/content/browser/loader/async_resource_handler.h b/chromium/content/browser/loader/async_resource_handler.h
index 9d460963d52..d7f70c2b504 100644
--- a/chromium/content/browser/loader/async_resource_handler.h
+++ b/chromium/content/browser/loader/async_resource_handler.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_LOADER_ASYNC_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_LOADER_ASYNC_RESOURCE_HANDLER_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/timer/timer.h"
#include "content/browser/loader/resource_handler.h"
@@ -78,7 +81,7 @@ class AsyncResourceHandler : public ResourceHandler,
bool sent_received_response_msg_;
bool sent_first_data_msg_;
- uint64 last_upload_position_;
+ uint64_t last_upload_position_;
bool waiting_for_upload_progress_ack_;
base::TimeTicks last_upload_ticks_;
base::RepeatingTimer progress_timer_;
diff --git a/chromium/content/browser/loader/async_resource_handler_browsertest.cc b/chromium/content/browser/loader/async_resource_handler_browsertest.cc
index cb48a231115..456c31a544f 100644
--- a/chromium/content/browser/loader/async_resource_handler_browsertest.cc
+++ b/chromium/content/browser/loader/async_resource_handler_browsertest.cc
@@ -4,11 +4,14 @@
#include "content/browser/loader/async_resource_handler.h"
+#include <stddef.h>
#include <string>
+#include <utility>
#include "base/format_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -28,8 +31,10 @@ const char kRedirectPostPath[] = "/redirect";
// ThreadSanitizer is too slow to perform the full upload, so tests
// using that build get an easier test which might not show two distinct
-// progress events. See crbug.com/526985.
-#if defined(THREAD_SANITIZER)
+// progress events. See crbug.com/526985. In addition, OSX buildbots have
+// experienced slowdowns on this test (crbug.com/548819), give them the easier
+// test too.
+#if defined(THREAD_SANITIZER) || defined(OS_MACOSX)
const size_t kPayloadSize = 1062882; // 2*3^12
#else
const size_t kPayloadSize = 28697814; // 2*3^15
@@ -44,14 +49,14 @@ scoped_ptr<net::test_server::HttpResponse> HandlePostAndRedirectURLs(
base::CompareCase::SENSITIVE)) {
http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
http_response->AddCustomHeader("Location", kPostPath);
- EXPECT_EQ(request.content.length(), kPayloadSize);;
- return http_response.Pass();
- } else if(base::StartsWith(request.relative_url, kPostPath,
- base::CompareCase::SENSITIVE)) {
+ EXPECT_EQ(request.content.length(), kPayloadSize);
+ return std::move(http_response);
+ } else if (base::StartsWith(request.relative_url, kPostPath,
+ base::CompareCase::SENSITIVE)) {
http_response->set_content("hello");
http_response->set_content_type("text/plain");
EXPECT_EQ(request.content.length(), kPayloadSize);
- return http_response.Pass();
+ return std::move(http_response);
} else {
return scoped_ptr<net::test_server::HttpResponse>();
}
@@ -63,8 +68,8 @@ class AsyncResourceHandlerBrowserTest : public ContentBrowserTest {
};
IN_PROC_BROWSER_TEST_F(AsyncResourceHandlerBrowserTest, UploadProgress) {
- net::test_server::EmbeddedTestServer* test_server = embedded_test_server();
- ASSERT_TRUE(test_server->InitializeAndWaitUntilReady());
+ net::EmbeddedTestServer* test_server = embedded_test_server();
+ ASSERT_TRUE(test_server->Start());
test_server->RegisterRequestHandler(
base::Bind(&HandlePostAndRedirectURLs, kPostPath));
@@ -83,8 +88,8 @@ IN_PROC_BROWSER_TEST_F(AsyncResourceHandlerBrowserTest, UploadProgress) {
IN_PROC_BROWSER_TEST_F(AsyncResourceHandlerBrowserTest,
UploadProgressRedirect) {
- net::test_server::EmbeddedTestServer* test_server = embedded_test_server();
- ASSERT_TRUE(test_server->InitializeAndWaitUntilReady());
+ net::EmbeddedTestServer* test_server = embedded_test_server();
+ ASSERT_TRUE(test_server->Start());
test_server->RegisterRequestHandler(
base::Bind(&HandlePostAndRedirectURLs, kRedirectPostPath));
diff --git a/chromium/content/browser/loader/async_revalidation_driver.cc b/chromium/content/browser/loader/async_revalidation_driver.cc
new file mode 100644
index 00000000000..3c5d45bc13b
--- /dev/null
+++ b/chromium/content/browser/loader/async_revalidation_driver.cc
@@ -0,0 +1,274 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/async_revalidation_driver.h"
+
+#include <utility>
+
+#include "base/callback_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "net/base/net_errors.h"
+#include "net/url_request/url_request_status.h"
+
+namespace content {
+
+namespace {
+// This matches the maximum allocation size of AsyncResourceHandler.
+const int kReadBufSize = 32 * 1024;
+
+// The time to wait for a response. Since this includes the time taken to
+// connect, this has been set to match the connect timeout
+// kTransportConnectJobTimeoutInSeconds.
+const int kResponseTimeoutInSeconds = 240; // 4 minutes.
+
+// This value should not be too large, as this request may be tying up a socket
+// that could be used for something better. However, if it is too small, the
+// cache entry will be truncated for no good reason.
+// TODO(ricea): Find a more scientific way to set this timeout.
+const int kReadTimeoutInSeconds = 30;
+} // namespace
+
+AsyncRevalidationDriver::AsyncRevalidationDriver(
+ scoped_ptr<net::URLRequest> request,
+ scoped_ptr<ResourceThrottle> throttle,
+ const base::Closure& completion_callback)
+ : request_(std::move(request)),
+ throttle_(std::move(throttle)),
+ completion_callback_(completion_callback),
+ weak_ptr_factory_(this) {
+ request_->set_delegate(this);
+ throttle_->set_controller(this);
+}
+
+AsyncRevalidationDriver::~AsyncRevalidationDriver() {}
+
+void AsyncRevalidationDriver::StartRequest() {
+ // Give the handler a chance to delay the URLRequest from being started.
+ bool defer_start = false;
+ throttle_->WillStartRequest(&defer_start);
+
+ if (defer_start) {
+ RecordDefer();
+ } else {
+ StartRequestInternal();
+ }
+}
+
+void AsyncRevalidationDriver::OnReceivedRedirect(
+ net::URLRequest* request,
+ const net::RedirectInfo& redirect_info,
+ bool* defer) {
+ DCHECK_EQ(request_.get(), request);
+
+ // The async revalidation should not follow redirects, because caching is
+ // a property of an individual HTTP resource.
+ DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec();
+ CancelRequestInternal(net::ERR_ABORTED, RESULT_GOT_REDIRECT);
+}
+
+void AsyncRevalidationDriver::OnAuthRequired(
+ net::URLRequest* request,
+ net::AuthChallengeInfo* auth_info) {
+ DCHECK_EQ(request_.get(), request);
+ // This error code doesn't have exactly the right semantics, but it should
+ // be sufficient to narrow down the problem in net logs.
+ CancelRequestInternal(net::ERR_ACCESS_DENIED, RESULT_AUTH_FAILED);
+}
+
+void AsyncRevalidationDriver::OnBeforeNetworkStart(net::URLRequest* request,
+ bool* defer) {
+ DCHECK_EQ(request_.get(), request);
+
+ // Verify that the ResourceScheduler does not defer here.
+ throttle_->WillStartUsingNetwork(defer);
+ DCHECK(!*defer);
+
+ // Start the response timer. This use of base::Unretained() is guaranteed safe
+ // by the semantics of base::OneShotTimer.
+ timer_.Start(FROM_HERE,
+ base::TimeDelta::FromSeconds(kResponseTimeoutInSeconds),
+ base::Bind(&AsyncRevalidationDriver::OnTimeout,
+ base::Unretained(this), RESULT_RESPONSE_TIMEOUT));
+}
+
+void AsyncRevalidationDriver::OnResponseStarted(net::URLRequest* request) {
+ DCHECK_EQ(request_.get(), request);
+
+ DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
+
+ // We have the response. No need to wait any longer.
+ timer_.Stop();
+
+ if (!request_->status().is_success()) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AsyncRevalidation.ResponseError",
+ -request_->status().ToNetError());
+ ResponseCompleted(RESULT_NET_ERROR);
+ // |this| may be deleted after this point.
+ return;
+ }
+
+ const net::HttpResponseInfo& response_info = request_->response_info();
+ if (!response_info.response_time.is_null() && response_info.was_cached) {
+ // The cached entry was revalidated. No need to read it in.
+ ResponseCompleted(RESULT_REVALIDATED);
+ // |this| may be deleted after this point.
+ return;
+ }
+
+ bool defer = false;
+ throttle_->WillProcessResponse(&defer);
+ DCHECK(!defer);
+
+ // Set up the timer for reading the body. This use of base::Unretained() is
+ // guaranteed safe by the semantics of base::OneShotTimer.
+ timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kReadTimeoutInSeconds),
+ base::Bind(&AsyncRevalidationDriver::OnTimeout,
+ base::Unretained(this), RESULT_BODY_TIMEOUT));
+ StartReading(false); // Read the first chunk.
+}
+
+void AsyncRevalidationDriver::OnReadCompleted(net::URLRequest* request,
+ int bytes_read) {
+ // request_ could be NULL if a timeout happened while OnReadCompleted() was
+ // queued to run asynchronously.
+ if (!request_)
+ return;
+ DCHECK_EQ(request_.get(), request);
+ DCHECK(!is_deferred_);
+ DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
+ << " bytes_read = " << bytes_read;
+
+ // bytes_read == 0 is EOF.
+ if (bytes_read == 0) {
+ ResponseCompleted(RESULT_LOADED);
+ return;
+ }
+ // bytes_read == -1 is an error.
+ if (bytes_read == -1 || !request_->status().is_success()) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AsyncRevalidation.ReadError",
+ -request_->status().ToNetError());
+ ResponseCompleted(RESULT_READ_ERROR);
+ // |this| may be deleted after this point.
+ return;
+ }
+
+ DCHECK_GT(bytes_read, 0);
+ StartReading(true); // Read the next chunk.
+}
+
+void AsyncRevalidationDriver::Resume() {
+ DCHECK(is_deferred_);
+ DCHECK(request_);
+ is_deferred_ = false;
+ request_->LogUnblocked();
+ StartRequestInternal();
+}
+
+void AsyncRevalidationDriver::Cancel() {
+ NOTREACHED();
+}
+
+void AsyncRevalidationDriver::CancelAndIgnore() {
+ NOTREACHED();
+}
+
+void AsyncRevalidationDriver::CancelWithError(int error_code) {
+ NOTREACHED();
+}
+
+void AsyncRevalidationDriver::StartRequestInternal() {
+ DCHECK(request_);
+ DCHECK(!request_->is_pending());
+
+ request_->Start();
+}
+
+void AsyncRevalidationDriver::CancelRequestInternal(
+ int error,
+ AsyncRevalidationResult result) {
+ DVLOG(1) << "CancelRequestInternal: " << request_->url().spec();
+
+ // Set the error code since this will be reported to the NetworkDelegate and
+ // recorded in the NetLog.
+ request_->CancelWithError(error);
+
+ // The ResourceScheduler needs to be able to examine the request when the
+ // ResourceThrottle is destroyed, so delete it first.
+ throttle_.reset();
+
+ // Destroy the request so that it doesn't try to send an asynchronous
+ // notification of completion.
+ request_.reset();
+
+ // Cancel timer to prevent OnTimeout() being called.
+ timer_.Stop();
+
+ ResponseCompleted(result);
+ // |this| may deleted after this point.
+}
+
+void AsyncRevalidationDriver::StartReading(bool is_continuation) {
+ int bytes_read = 0;
+ ReadMore(&bytes_read);
+
+ // If IO is pending, wait for the URLRequest to call OnReadCompleted.
+ if (request_->status().is_io_pending())
+ return;
+
+ if (!is_continuation || bytes_read <= 0) {
+ OnReadCompleted(request_.get(), bytes_read);
+ } else {
+ // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
+ // thread in case the URLRequest can provide data synchronously.
+ scoped_refptr<base::SingleThreadTaskRunner> single_thread_task_runner =
+ base::ThreadTaskRunnerHandle::Get();
+ single_thread_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(&AsyncRevalidationDriver::OnReadCompleted,
+ weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read));
+ }
+}
+
+void AsyncRevalidationDriver::ReadMore(int* bytes_read) {
+ DCHECK(!is_deferred_);
+
+ if (!read_buffer_)
+ read_buffer_ = new net::IOBuffer(kReadBufSize);
+
+ timer_.Reset();
+ request_->Read(read_buffer_.get(), kReadBufSize, bytes_read);
+
+ // No need to check the return value here as we'll detect errors by
+ // inspecting the URLRequest's status.
+}
+
+void AsyncRevalidationDriver::ResponseCompleted(
+ AsyncRevalidationResult result) {
+ DVLOG(1) << "ResponseCompleted: "
+ << (request_ ? request_->url().spec() : "(request deleted)")
+ << "result = " << result;
+ UMA_HISTOGRAM_ENUMERATION("Net.AsyncRevalidation.Result", result, RESULT_MAX);
+ DCHECK(!completion_callback_.is_null());
+ base::ResetAndReturn(&completion_callback_).Run();
+ // |this| may be deleted after this point.
+}
+
+void AsyncRevalidationDriver::OnTimeout(AsyncRevalidationResult result) {
+ CancelRequestInternal(net::ERR_TIMED_OUT, result);
+}
+
+void AsyncRevalidationDriver::RecordDefer() {
+ request_->LogBlockedBy(throttle_->GetNameForLogging());
+ DCHECK(!is_deferred_);
+ is_deferred_ = true;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/loader/async_revalidation_driver.h b/chromium/content/browser/loader/async_revalidation_driver.h
new file mode 100644
index 00000000000..b96e06ebd5c
--- /dev/null
+++ b/chromium/content/browser/loader/async_revalidation_driver.h
@@ -0,0 +1,104 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_ASYNC_REVALIDATION_DRIVER_H_
+#define CONTENT_BROWSER_LOADER_ASYNC_REVALIDATION_DRIVER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/timer/timer.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/resource_controller.h"
+#include "content/public/browser/resource_throttle.h"
+#include "net/base/io_buffer.h"
+#include "net/url_request/url_request.h"
+
+namespace net {
+class HttpCache;
+}
+
+namespace content {
+
+// This class is responsible for driving the URLRequest for an async
+// revalidation. It is passed an instance of ResourceThrottle created by
+// content::ResourceScheduler to perform throttling on the request.
+class CONTENT_EXPORT AsyncRevalidationDriver : public net::URLRequest::Delegate,
+ public ResourceController {
+ public:
+ // |completion_callback| is guaranteed to be called on completion,
+ // regardless of success or failure.
+ AsyncRevalidationDriver(scoped_ptr<net::URLRequest> request,
+ scoped_ptr<ResourceThrottle> throttle,
+ const base::Closure& completion_callback);
+ ~AsyncRevalidationDriver() override;
+
+ void StartRequest();
+
+ private:
+ // This enum is logged as histogram "Net.AsyncRevalidation.Result". Only add
+ // new entries at the end and update histograms.xml to match.
+ enum AsyncRevalidationResult {
+ RESULT_LOADED,
+ RESULT_REVALIDATED,
+ RESULT_NET_ERROR,
+ RESULT_READ_ERROR,
+ RESULT_GOT_REDIRECT,
+ RESULT_AUTH_FAILED,
+ RESULT_RESPONSE_TIMEOUT,
+ RESULT_BODY_TIMEOUT,
+ RESULT_MAX
+ };
+
+ // net::URLRequest::Delegate implementation:
+ void OnReceivedRedirect(net::URLRequest* request,
+ const net::RedirectInfo& redirect_info,
+ bool* defer) override;
+ void OnAuthRequired(net::URLRequest* request,
+ net::AuthChallengeInfo* info) override;
+ void OnBeforeNetworkStart(net::URLRequest* request, bool* defer) override;
+ void OnResponseStarted(net::URLRequest* request) override;
+ void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
+
+ // ResourceController implementation:
+ void Resume() override;
+
+ // For simplicity, this class assumes that ResourceScheduler never cancels
+ // requests, and so these three methods are never called.
+ void Cancel() override;
+ void CancelAndIgnore() override;
+ void CancelWithError(int error_code) override;
+
+ // Internal methods.
+ void StartRequestInternal();
+ void CancelRequestInternal(int error, AsyncRevalidationResult result);
+ void StartReading(bool is_continuation);
+ void ReadMore(int* bytes_read);
+ // Logs the result histogram, then calls and clears |completion_callback_|.
+ void ResponseCompleted(AsyncRevalidationResult result);
+ void OnTimeout(AsyncRevalidationResult result);
+ void RecordDefer();
+
+ bool is_deferred_ = false;
+
+ scoped_refptr<net::IOBuffer> read_buffer_;
+ base::OneShotTimer timer_;
+
+ scoped_ptr<net::URLRequest> request_;
+ scoped_ptr<ResourceThrottle> throttle_;
+
+ base::Closure completion_callback_;
+
+ base::WeakPtrFactory<AsyncRevalidationDriver> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AsyncRevalidationDriver);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_ASYNC_REVALIDATION_DRIVER_H_
diff --git a/chromium/content/browser/loader/async_revalidation_driver_unittest.cc b/chromium/content/browser/loader/async_revalidation_driver_unittest.cc
new file mode 100644
index 00000000000..1f5a7e4b1f0
--- /dev/null
+++ b/chromium/content/browser/loader/async_revalidation_driver_unittest.cc
@@ -0,0 +1,397 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/async_revalidation_driver.h"
+
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "content/public/browser/client_certificate_delegate.h"
+#include "content/public/common/content_client.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/test/test_content_browser_client.h"
+#include "ipc/ipc_message.h"
+#include "net/base/net_errors.h"
+#include "net/base/network_delegate_impl.h"
+#include "net/base/request_priority.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "net/url_request/url_request_job_factory.h"
+#include "net/url_request/url_request_job_factory_impl.h"
+#include "net/url_request/url_request_status.h"
+#include "net/url_request/url_request_test_job.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+// Dummy implementation of ResourceThrottle, an instance of which is needed to
+// initialize AsyncRevalidationDriver.
+class ResourceThrottleStub : public ResourceThrottle {
+ public:
+ ResourceThrottleStub() {}
+
+ // If true, defers the request in WillStartRequest.
+ void set_defer_request_on_will_start_request(
+ bool defer_request_on_will_start_request) {
+ defer_request_on_will_start_request_ = defer_request_on_will_start_request;
+ }
+
+ // ResourceThrottler implementation:
+ void WillStartRequest(bool* defer) override {
+ *defer = defer_request_on_will_start_request_;
+ }
+
+ const char* GetNameForLogging() const override {
+ return "ResourceThrottleStub";
+ }
+
+ private:
+ bool defer_request_on_will_start_request_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(ResourceThrottleStub);
+};
+
+// There are multiple layers of boilerplate needed to use a URLRequestTestJob
+// subclass. Subclasses of AsyncRevalidationDriverTest can use
+// BindCreateProtocolHandlerCallback() to bypass most of that boilerplate.
+using CreateProtocolHandlerCallback =
+ base::Callback<scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>()>;
+
+template <typename T>
+CreateProtocolHandlerCallback BindCreateProtocolHandlerCallback() {
+ static_assert(std::is_base_of<net::URLRequestJob, T>::value,
+ "Template argument to BindCreateProtocolHandlerCallback() must "
+ "be a subclass of URLRequestJob.");
+
+ class TemplatedProtocolHandler
+ : public net::URLRequestJobFactory::ProtocolHandler {
+ public:
+ static scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> Create() {
+ return make_scoped_ptr(new TemplatedProtocolHandler());
+ }
+
+ // URLRequestJobFactory::ProtocolHandler implementation:
+ net::URLRequestJob* MaybeCreateJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return new T(request, network_delegate);
+ }
+ };
+
+ return base::Bind(&TemplatedProtocolHandler::Create);
+}
+
+// An implementation of NetworkDelegate that captures the status of the last
+// URLRequest to be destroyed.
+class StatusCapturingNetworkDelegate : public net::NetworkDelegateImpl {
+ public:
+ const net::URLRequestStatus& last_status() { return last_status_; }
+
+ private:
+ // net::NetworkDelegate implementation.
+ void OnURLRequestDestroyed(net::URLRequest* request) override {
+ last_status_ = request->status();
+ }
+
+ net::URLRequestStatus last_status_;
+};
+
+class AsyncRevalidationDriverTest : public testing::Test {
+ protected:
+ // Constructor for test fixtures that subclass this one.
+ AsyncRevalidationDriverTest(
+ const CreateProtocolHandlerCallback& create_protocol_handler_callback)
+ : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+ create_protocol_handler_callback_(create_protocol_handler_callback),
+ raw_ptr_resource_throttle_(nullptr),
+ raw_ptr_request_(nullptr) {
+ test_url_request_context_.set_job_factory(&job_factory_);
+ test_url_request_context_.set_network_delegate(&network_delegate_);
+ }
+
+ // Constructor for tests that use this fixture directly.
+ AsyncRevalidationDriverTest()
+ : AsyncRevalidationDriverTest(
+ base::Bind(net::URLRequestTestJob::CreateProtocolHandler)) {}
+
+ bool async_revalidation_complete_called() const {
+ return async_revalidation_complete_called_;
+ }
+
+ const net::URLRequestStatus& last_status() {
+ return network_delegate_.last_status();
+ }
+
+ void SetUpAsyncRevalidationDriverWithRequestToUrl(const GURL& url) {
+ scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
+ url, net::DEFAULT_PRIORITY, nullptr /* delegate */));
+ raw_ptr_request_ = request.get();
+ raw_ptr_resource_throttle_ = new ResourceThrottleStub();
+ // This use of base::Unretained() is safe because |driver_|, and the closure
+ // passed to it, will be destroyed before this object is.
+ driver_.reset(new AsyncRevalidationDriver(
+ std::move(request), make_scoped_ptr(raw_ptr_resource_throttle_),
+ base::Bind(&AsyncRevalidationDriverTest::OnAsyncRevalidationComplete,
+ base::Unretained(this))));
+ }
+
+ void SetUpAsyncRevalidationDriverWithDefaultRequest() {
+ SetUpAsyncRevalidationDriverWithRequestToUrl(
+ net::URLRequestTestJob::test_url_1());
+ }
+
+ void SetUp() override {
+ job_factory_.SetProtocolHandler("test",
+ create_protocol_handler_callback_.Run());
+ SetUpAsyncRevalidationDriverWithDefaultRequest();
+ }
+
+ void OnAsyncRevalidationComplete() {
+ EXPECT_FALSE(async_revalidation_complete_called_);
+ async_revalidation_complete_called_ = true;
+ driver_.reset();
+ }
+
+ TestBrowserThreadBundle thread_bundle_;
+ net::URLRequestJobFactoryImpl job_factory_;
+ net::TestURLRequestContext test_url_request_context_;
+ StatusCapturingNetworkDelegate network_delegate_;
+ CreateProtocolHandlerCallback create_protocol_handler_callback_;
+
+ // The AsyncRevalidationDriver owns the URLRequest and the ResourceThrottle.
+ ResourceThrottleStub* raw_ptr_resource_throttle_;
+ net::URLRequest* raw_ptr_request_;
+ scoped_ptr<AsyncRevalidationDriver> driver_;
+ bool async_revalidation_complete_called_ = false;
+};
+
+TEST_F(AsyncRevalidationDriverTest, NormalRequestCompletes) {
+ driver_->StartRequest();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(async_revalidation_complete_called());
+}
+
+// Verifies that request that should be deferred at start is deferred.
+TEST_F(AsyncRevalidationDriverTest, DeferOnStart) {
+ raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
+
+ driver_->StartRequest();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(raw_ptr_request_->is_pending());
+ EXPECT_FALSE(async_revalidation_complete_called());
+}
+
+// Verifies that resuming a deferred request works. Assumes that DeferOnStart
+// passes.
+TEST_F(AsyncRevalidationDriverTest, ResumeDeferredRequestWorks) {
+ raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
+
+ driver_->StartRequest();
+ base::RunLoop().RunUntilIdle();
+
+ ResourceController* driver_as_resource_controller = driver_.get();
+ driver_as_resource_controller->Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(async_revalidation_complete_called());
+}
+
+// Verifies that redirects are not followed.
+TEST_F(AsyncRevalidationDriverTest, RedirectsAreNotFollowed) {
+ SetUpAsyncRevalidationDriverWithRequestToUrl(
+ net::URLRequestTestJob::test_url_redirect_to_url_2());
+
+ driver_->StartRequest();
+ while (net::URLRequestTestJob::ProcessOnePendingMessage())
+ base::RunLoop().RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(last_status().is_success());
+ EXPECT_EQ(net::ERR_ABORTED, last_status().error());
+ EXPECT_TRUE(async_revalidation_complete_called());
+}
+
+// A mock URLRequestJob which simulates an SSL client auth request.
+class MockClientCertURLRequestJob : public net::URLRequestTestJob {
+ public:
+ MockClientCertURLRequestJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate)
+ : net::URLRequestTestJob(request, network_delegate, true),
+ weak_factory_(this) {}
+
+ // net::URLRequestTestJob implementation:
+ void Start() override {
+ scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
+ new net::SSLCertRequestInfo);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested,
+ weak_factory_.GetWeakPtr(), cert_request_info));
+ }
+
+ void ContinueWithCertificate(
+ net::X509Certificate* cert,
+ net::SSLPrivateKey* client_private_key) override {
+ ADD_FAILURE() << "Certificate supplied.";
+ }
+
+ void Kill() override {
+ weak_factory_.InvalidateWeakPtrs();
+ URLRequestJob::Kill();
+ }
+
+ private:
+ base::WeakPtrFactory<MockClientCertURLRequestJob> weak_factory_;
+};
+
+class AsyncRevalidationDriverClientCertTest
+ : public AsyncRevalidationDriverTest {
+ protected:
+ AsyncRevalidationDriverClientCertTest()
+ : AsyncRevalidationDriverTest(
+ BindCreateProtocolHandlerCallback<MockClientCertURLRequestJob>()) {}
+};
+
+// Test browser client that causes the test to fail if SelectClientCertificate()
+// is called. Automatically sets itself as the browser client when constructed
+// and restores the old browser client in the destructor.
+class ScopedDontSelectCertificateBrowserClient
+ : public TestContentBrowserClient {
+ public:
+ ScopedDontSelectCertificateBrowserClient() {
+ old_client_ = SetBrowserClientForTesting(this);
+ }
+
+ ~ScopedDontSelectCertificateBrowserClient() override {
+ SetBrowserClientForTesting(old_client_);
+ }
+
+ void SelectClientCertificate(
+ WebContents* web_contents,
+ net::SSLCertRequestInfo* cert_request_info,
+ scoped_ptr<ClientCertificateDelegate> delegate) override {
+ ADD_FAILURE() << "SelectClientCertificate was called.";
+ }
+
+ private:
+ ContentBrowserClient* old_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedDontSelectCertificateBrowserClient);
+};
+
+// Verifies that async revalidation requests do not attempt to provide client
+// certificates.
+TEST_F(AsyncRevalidationDriverClientCertTest, RequestRejected) {
+ // Ensure that SelectClientCertificate is not called during this test.
+ ScopedDontSelectCertificateBrowserClient test_client;
+
+ // Start the request and wait for it to pause.
+ driver_->StartRequest();
+
+ // Because TestBrowserThreadBundle only uses one real thread, this is
+ // sufficient to ensure that tasks posted to the "UI thread" have run.
+ base::RunLoop().RunUntilIdle();
+
+ // Check that the request aborted.
+ EXPECT_FALSE(last_status().is_success());
+ EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, last_status().error());
+ EXPECT_TRUE(async_revalidation_complete_called());
+}
+
+// A mock URLRequestJob which simulates an SSL certificate error.
+class MockSSLErrorURLRequestJob : public net::URLRequestTestJob {
+ public:
+ MockSSLErrorURLRequestJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate)
+ : net::URLRequestTestJob(request, network_delegate, true),
+ weak_factory_(this) {}
+
+ // net::URLRequestTestJob implementation:
+ void Start() override {
+ // This SSLInfo isn't really valid, but it is good enough for testing.
+ net::SSLInfo ssl_info;
+ ssl_info.SetCertError(net::ERR_CERT_DATE_INVALID);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&MockSSLErrorURLRequestJob::NotifySSLCertificateError,
+ weak_factory_.GetWeakPtr(), ssl_info, false));
+ }
+
+ void ContinueDespiteLastError() override {
+ ADD_FAILURE() << "ContinueDespiteLastError called.";
+ }
+
+ private:
+ base::WeakPtrFactory<MockSSLErrorURLRequestJob> weak_factory_;
+};
+
+class AsyncRevalidationDriverSSLErrorTest : public AsyncRevalidationDriverTest {
+ protected:
+ AsyncRevalidationDriverSSLErrorTest()
+ : AsyncRevalidationDriverTest(
+ BindCreateProtocolHandlerCallback<MockSSLErrorURLRequestJob>()) {}
+};
+
+// Verifies that async revalidation requests do not attempt to recover from SSL
+// certificate errors.
+TEST_F(AsyncRevalidationDriverSSLErrorTest, RequestWithSSLErrorRejected) {
+ // Start the request and wait for it to pause.
+ driver_->StartRequest();
+ base::RunLoop().RunUntilIdle();
+
+ // Check that the request has been aborted.
+ EXPECT_FALSE(last_status().is_success());
+ EXPECT_EQ(net::ERR_ABORTED, last_status().error());
+ EXPECT_TRUE(async_revalidation_complete_called());
+}
+
+// A URLRequestTestJob that sets |request_time| and |was_cached| on their
+// response_info, and causes the test to fail if Read() is called.
+class FromCacheURLRequestJob : public net::URLRequestTestJob {
+ public:
+ FromCacheURLRequestJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate)
+ : net::URLRequestTestJob(request, network_delegate, true) {}
+
+ void GetResponseInfo(net::HttpResponseInfo* info) override {
+ URLRequestTestJob::GetResponseInfo(info);
+ info->request_time = base::Time::Now();
+ info->was_cached = true;
+ }
+
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override {
+ ADD_FAILURE() << "ReadRawData() was called.";
+ return URLRequestTestJob::ReadRawData(buf, buf_size);
+ }
+
+ private:
+ ~FromCacheURLRequestJob() override {}
+
+ DISALLOW_COPY_AND_ASSIGN(FromCacheURLRequestJob);
+};
+
+class AsyncRevalidationDriverFromCacheTest
+ : public AsyncRevalidationDriverTest {
+ protected:
+ AsyncRevalidationDriverFromCacheTest()
+ : AsyncRevalidationDriverTest(
+ BindCreateProtocolHandlerCallback<FromCacheURLRequestJob>()) {}
+};
+
+TEST_F(AsyncRevalidationDriverFromCacheTest,
+ CacheNotReadOnSuccessfulRevalidation) {
+ driver_->StartRequest();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(async_revalidation_complete_called());
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/browser/loader/async_revalidation_manager.cc b/chromium/content/browser/loader/async_revalidation_manager.cc
new file mode 100644
index 00000000000..aaaeb68ab83
--- /dev/null
+++ b/chromium/content/browser/loader/async_revalidation_manager.cc
@@ -0,0 +1,191 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/async_revalidation_manager.h"
+
+#include <tuple>
+#include <utility>
+
+#include "base/logging.h"
+#include "content/browser/loader/async_revalidation_driver.h"
+#include "content/browser/loader/resource_message_filter.h"
+#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/browser/loader/resource_scheduler.h"
+#include "content/common/resource_messages.h"
+#include "content/public/browser/resource_throttle.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_transaction_factory.h"
+#include "net/http/http_util.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "url/gurl.h"
+
+namespace content {
+
+AsyncRevalidationManager::AsyncRevalidationKey::AsyncRevalidationKey(
+ const ResourceContext* resource_context,
+ const net::HttpCache* http_cache,
+ const GURL& url)
+ : resource_context(resource_context),
+ http_cache(http_cache),
+ url_key(net::HttpUtil::SpecForRequest(url)) {}
+
+AsyncRevalidationManager::AsyncRevalidationKey::AsyncRevalidationKey(
+ const ResourceContext* resource_context)
+ : resource_context(resource_context), http_cache(nullptr), url_key() {}
+
+AsyncRevalidationManager::AsyncRevalidationKey::~AsyncRevalidationKey() {}
+
+bool AsyncRevalidationManager::AsyncRevalidationKey::LessThan::operator()(
+ const AsyncRevalidationKey& lhs,
+ const AsyncRevalidationKey& rhs) const {
+ return std::tie(lhs.resource_context, lhs.http_cache, lhs.url_key) <
+ std::tie(rhs.resource_context, rhs.http_cache, rhs.url_key);
+}
+
+AsyncRevalidationManager::AsyncRevalidationManager() {}
+
+AsyncRevalidationManager::~AsyncRevalidationManager() {
+ DCHECK(in_progress_.empty());
+}
+
+void AsyncRevalidationManager::BeginAsyncRevalidation(
+ const net::URLRequest& for_request,
+ ResourceScheduler* scheduler) {
+ DCHECK_EQ(for_request.url_chain().size(), 1u);
+ const ResourceRequestInfoImpl* info =
+ ResourceRequestInfoImpl::ForRequest(&for_request);
+ DCHECK(info);
+ if (!info->filter()) {
+ // The child has gone away and we can no longer get ResourceContext and
+ // URLRequestContext to perform async revalidation.
+ // This can happen in the following cases, ordered from bad to not-so-bad
+ //
+ // 1. PlzNavigate (but enabling PlzNavigate automatically disables
+ // stale-while-revalidate; see crbug.com/561609)
+ // 2. <link rel=prefetch> may read a stale cache entry without a
+ // revalidation being performed if the original renderer goes away. This
+ // is a lost optimisation opportunity.
+ //
+ // Not an issue:
+ // 1. Implicit downloads. This method is called before
+ // MimeTypeResourceHandler calls set_is_download, so the renderer process
+ // must still exist for the request not to have been canceled.
+ // 2. Explicit downloads (ie. started via "Save As"). These never use
+ // stale-while-revalidate.
+ // 3. Non-PlzNavigate navigations between renderers. The old renderer
+ // still exists when this method is called.
+ // 4. <a ping>, navigation.sendBeacon() and Content-Security-Policy reports
+ // are POST requests, so they never use stale-while-revalidate.
+ //
+ // TODO(ricea): Resolve these lifetime issues. crbug.com/561591
+ return;
+ }
+
+ ResourceContext* resource_context = nullptr;
+ net::URLRequestContext* request_context = nullptr;
+
+ // The embedder of //content needs to ensure that the URLRequestContext object
+ // remains valid until after the ResourceContext object is destroyed.
+ info->filter()->GetContexts(info->GetResourceType(), info->GetOriginPID(),
+ &resource_context, &request_context);
+
+ AsyncRevalidationKey async_revalidation_key(
+ resource_context, request_context->http_transaction_factory()->GetCache(),
+ for_request.url());
+ std::pair<AsyncRevalidationMap::iterator, bool> insert_result =
+ in_progress_.insert(AsyncRevalidationMap::value_type(
+ async_revalidation_key, scoped_ptr<AsyncRevalidationDriver>()));
+ if (!insert_result.second) {
+ // A matching async revalidation is already in progress for this cache; we
+ // don't need another one.
+ return;
+ }
+
+ net::HttpRequestHeaders headers;
+ headers.AddHeadersFromString(info->original_headers());
+
+ // Construct the request.
+ scoped_ptr<net::URLRequest> new_request = request_context->CreateRequest(
+ for_request.url(), net::MINIMUM_PRIORITY, nullptr);
+
+ new_request->set_method(for_request.method());
+ new_request->set_first_party_for_cookies(
+ for_request.first_party_for_cookies());
+ new_request->set_initiator(for_request.initiator());
+ new_request->set_first_party_url_policy(for_request.first_party_url_policy());
+
+ new_request->SetReferrer(for_request.referrer());
+ new_request->set_referrer_policy(for_request.referrer_policy());
+
+ new_request->SetExtraRequestHeaders(headers);
+
+ // Remove LOAD_SUPPORT_ASYNC_REVALIDATION and LOAD_MAIN_FRAME flags.
+ // Also remove things which shouldn't have been there to begin with,
+ // and unrecognised flags.
+ int load_flags =
+ for_request.load_flags() &
+ (net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_BYPASS_PROXY |
+ net::LOAD_VERIFY_EV_CERT | net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SEND_AUTH_DATA | net::LOAD_MAYBE_USER_GESTURE |
+ net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY);
+ new_request->SetLoadFlags(load_flags);
+
+ // These values would be -1 if the request was created by PlzNavigate. This
+ // would cause the async revalidation to start immediately.
+ // stale-while-revalidate is disabled when PlzNavigate is enabled
+ // to prevent this and other issues. See crbug.com/561610.
+ int child_id = info->GetChildID();
+ int route_id = info->GetRouteID();
+
+ scoped_ptr<ResourceThrottle> throttle =
+ scheduler->ScheduleRequest(child_id, route_id, false, new_request.get());
+
+ // AsyncRevalidationDriver does not outlive its entry in |in_progress_|,
+ // so the iterator and |this| may be passed to base::Bind directly.
+ insert_result.first->second.reset(new AsyncRevalidationDriver(
+ std::move(new_request), std::move(throttle),
+ base::Bind(&AsyncRevalidationManager::OnAsyncRevalidationComplete,
+ base::Unretained(this), insert_result.first)));
+ insert_result.first->second->StartRequest();
+}
+
+void AsyncRevalidationManager::CancelAsyncRevalidationsForResourceContext(
+ ResourceContext* resource_context) {
+ // |resource_context| is the first part of the key, so elements to be
+ // cancelled are contiguous in the map.
+ AsyncRevalidationKey partial_key(resource_context);
+ for (auto it = in_progress_.lower_bound(partial_key);
+ it != in_progress_.end() &&
+ it->first.resource_context == resource_context;) {
+ it = in_progress_.erase(it);
+ }
+}
+
+bool AsyncRevalidationManager::QualifiesForAsyncRevalidation(
+ const ResourceHostMsg_Request& request) {
+ if (request.load_flags &
+ (net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
+ net::LOAD_VALIDATE_CACHE | net::LOAD_PREFERRING_CACHE |
+ net::LOAD_ONLY_FROM_CACHE | net::LOAD_IGNORE_LIMITS |
+ net::LOAD_PREFETCH)) {
+ return false;
+ }
+ if (request.method != "GET")
+ return false;
+ // A GET request should not have a body.
+ if (request.request_body.get())
+ return false;
+ if (!request.url.SchemeIsHTTPOrHTTPS())
+ return false;
+
+ return true;
+}
+
+void AsyncRevalidationManager::OnAsyncRevalidationComplete(
+ AsyncRevalidationMap::iterator it) {
+ in_progress_.erase(it);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/loader/async_revalidation_manager.h b/chromium/content/browser/loader/async_revalidation_manager.h
new file mode 100644
index 00000000000..1070ea9c8bc
--- /dev/null
+++ b/chromium/content/browser/loader/async_revalidation_manager.h
@@ -0,0 +1,107 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_ASYNC_REVALIDATION_MANAGER_H_
+#define CONTENT_BROWSER_LOADER_ASYNC_REVALIDATION_MANAGER_H_
+
+#include <map>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+
+class GURL;
+struct ResourceHostMsg_Request;
+
+namespace net {
+class URLRequest;
+class HttpCache;
+}
+
+namespace content {
+
+class AsyncRevalidationDriver;
+class ResourceContext;
+class ResourceScheduler;
+
+// One instance of this class manages all active AsyncRevalidationDriver objects
+// for all profiles. It is created by and owned by
+// ResourceDispatcherHostImpl. It also implements the creation of a new
+// net::URLRequest and AsyncRevalidationDriver from an existing net::URLRequest
+// that has had the stale-while-revalidate algorithm applied to it.
+class AsyncRevalidationManager {
+ public:
+ AsyncRevalidationManager();
+ ~AsyncRevalidationManager();
+
+ // Starts an async revalidation by copying |for_request|. |scheduler| must
+ // remain valid until this object is destroyed.
+ void BeginAsyncRevalidation(const net::URLRequest& for_request,
+ ResourceScheduler* scheduler);
+
+ // Cancel all pending async revalidations that use ResourceContext.
+ void CancelAsyncRevalidationsForResourceContext(
+ ResourceContext* resource_context);
+
+ static bool QualifiesForAsyncRevalidation(
+ const ResourceHostMsg_Request& request);
+
+ private:
+ // The key of the map of pending async revalidations. This key has a distinct
+ // value for every in-progress async revalidation. It is used to avoid
+ // duplicate async revalidations, and also to cancel affected async
+ // revalidations when a ResourceContext is removed.
+ //
+ // Request headers are intentionally not included in the key for simplicity,
+ // as they usually don't affect caching.
+ //
+ // TODO(ricea): Behave correctly in cases where the request headers do make a
+ // difference. crbug.com/567721
+ struct AsyncRevalidationKey {
+ AsyncRevalidationKey(const ResourceContext* resource_context,
+ const net::HttpCache* http_cache,
+ const GURL& url);
+
+ // Create a prefix key that is used to match all of the
+ // AsyncRevalidationDrivers using |resource_context| in the map.
+ explicit AsyncRevalidationKey(const ResourceContext* resource_context);
+
+ // The key for a map needs to be copyable.
+ AsyncRevalidationKey(const AsyncRevalidationKey& rhs) = default;
+ ~AsyncRevalidationKey();
+
+ // No operator= is generated because the struct members are immutable.
+
+ // |resource_context| and |http_cache| are never dereferenced; they are only
+ // compared to other values.
+ const ResourceContext* const resource_context;
+
+ // There are multiple independent HttpCache objects per ResourceContext.
+ const net::HttpCache* const http_cache;
+
+ // Derived from the url via net::HttpUtil::SpecForRequest().
+ const std::string url_key;
+
+ struct LessThan {
+ bool operator()(const AsyncRevalidationKey& lhs,
+ const AsyncRevalidationKey& rhs) const;
+ };
+ };
+
+ using AsyncRevalidationMap = std::map<AsyncRevalidationKey,
+ scoped_ptr<AsyncRevalidationDriver>,
+ AsyncRevalidationKey::LessThan>;
+
+ void OnAsyncRevalidationComplete(AsyncRevalidationMap::iterator it);
+
+ // Map of AsyncRevalidationDriver instances that are currently in-flight:
+ // either waiting to be scheduled or active on the network.
+ AsyncRevalidationMap in_progress_;
+
+ DISALLOW_COPY_AND_ASSIGN(AsyncRevalidationManager);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_ASYNC_REVALIDATION_MANAGER_H_
diff --git a/chromium/content/browser/loader/async_revalidation_manager_browsertest.cc b/chromium/content/browser/loader/async_revalidation_manager_browsertest.cc
new file mode 100644
index 00000000000..f7999431b42
--- /dev/null
+++ b/chromium/content/browser/loader/async_revalidation_manager_browsertest.cc
@@ -0,0 +1,220 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+using net::test_server::HttpResponse;
+using net::test_server::HttpRequest;
+using net::test_server::BasicHttpResponse;
+
+const char kCountedHtmlPath[] = "/counted.html";
+const char kCookieHtmlPath[] = "/cookie.html";
+
+class AsyncRevalidationManagerBrowserTest : public ContentBrowserTest {
+ protected:
+ AsyncRevalidationManagerBrowserTest() {}
+ ~AsyncRevalidationManagerBrowserTest() override {}
+
+ void SetUp() override {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+ ContentBrowserTest::SetUp();
+ }
+
+ void SetUpOnMainThread() override {
+ embedded_test_server()->StartAcceptingConnections();
+ }
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitch("enable-stale-while-revalidate");
+ }
+
+ base::RunLoop* run_loop() { return &run_loop_; }
+ int requests_counted() const { return requests_counted_; }
+
+ // This method lacks diagnostics for the failure case because TitleWatcher
+ // will just wait until the test times out if |expected_title| does not
+ // appear.
+ bool TitleBecomes(const GURL& url, const std::string& expected_title) {
+ base::string16 expected_title16(base::ASCIIToUTF16(expected_title));
+ TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
+ NavigateToURL(shell(), url);
+ return title_watcher.WaitAndGetTitle() == expected_title16;
+ }
+
+ void RegisterCountingRequestHandler() {
+ embedded_test_server()->RegisterRequestHandler(base::Bind(
+ &AsyncRevalidationManagerBrowserTest::CountingRequestHandler, this));
+ }
+
+ void RegisterCookieRequestHandler() {
+ embedded_test_server()->RegisterRequestHandler(base::Bind(
+ &AsyncRevalidationManagerBrowserTest::CookieRequestHandler, this));
+ }
+
+ private:
+ // A request handler which increases the number in the title tag on every
+ // request.
+ scoped_ptr<HttpResponse> CountingRequestHandler(const HttpRequest& request) {
+ if (request.relative_url != kCountedHtmlPath)
+ return nullptr;
+
+ int version = ++requests_counted_;
+
+ scoped_ptr<BasicHttpResponse> http_response(StaleWhileRevalidateHeaders());
+ http_response->set_content(
+ base::StringPrintf("<title>Version %d</title>", version));
+
+ // The second time this handler is run is the async revalidation. Tests can
+ // use this for synchronisation.
+ if (version == 2)
+ run_loop_.Quit();
+ return std::move(http_response);
+ }
+
+ // A request handler which increases a cookie value on every request.
+ scoped_ptr<HttpResponse> CookieRequestHandler(const HttpRequest& request) {
+ static const char kHtml[] =
+ "<script>\n"
+ "var intervalId;\n"
+ "function checkCookie() {\n"
+ " if (document.cookie.search(/version=2/) != -1) {\n"
+ " clearInterval(intervalId);\n"
+ " document.title = \"PASS\";\n"
+ " }\n"
+ "}\n"
+ "intervalId = setInterval(checkCookie, 10);\n"
+ "</script>\n"
+ "<title>Loaded</title>\n";
+
+ if (request.relative_url != kCookieHtmlPath)
+ return nullptr;
+
+ int version = ++requests_counted_;
+
+ scoped_ptr<BasicHttpResponse> http_response(StaleWhileRevalidateHeaders());
+ http_response->AddCustomHeader("Set-Cookie",
+ base::StringPrintf("version=%d", version));
+ http_response->set_content(kHtml);
+
+ return std::move(http_response);
+ }
+
+ // Generate the standard response headers common to all request handlers.
+ scoped_ptr<BasicHttpResponse> StaleWhileRevalidateHeaders() {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_code(net::HTTP_OK);
+ http_response->set_content_type("text/html; charset=utf-8");
+ http_response->AddCustomHeader("Cache-Control",
+ "max-age=0, stale-while-revalidate=86400");
+ // A validator is needed for revalidations, and hence
+ // stale-while-revalidate, to work.
+ std::string etag = base::StringPrintf(
+ "\"AsyncRevalidationManagerBrowserTest%d\"", requests_counted_);
+ http_response->AddCustomHeader("ETag", etag);
+ return http_response;
+ }
+
+ base::RunLoop run_loop_;
+ int requests_counted_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(AsyncRevalidationManagerBrowserTest);
+};
+
+// Verify that the "Cache-Control: stale-while-revalidate" directive correctly
+// triggers an async revalidation.
+IN_PROC_BROWSER_TEST_F(AsyncRevalidationManagerBrowserTest,
+ StaleWhileRevalidateIsApplied) {
+ RegisterCountingRequestHandler();
+ GURL url(embedded_test_server()->GetURL(kCountedHtmlPath));
+
+ EXPECT_TRUE(TitleBecomes(url, "Version 1"));
+
+ // The first request happens synchronously.
+ EXPECT_EQ(1, requests_counted());
+
+ // Force the renderer to be destroyed so that the Blink cache doesn't
+ // interfere with the result.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ // Load the page again. We should get the stale version from the cache.
+ EXPECT_TRUE(TitleBecomes(url, "Version 1"));
+
+ // Wait for the async revalidation to complete.
+ run_loop()->Run();
+ EXPECT_EQ(2, requests_counted());
+}
+
+// The fresh cache entry must become visible once the async revalidation request
+// has been sent.
+IN_PROC_BROWSER_TEST_F(AsyncRevalidationManagerBrowserTest, CacheIsUpdated) {
+ using base::ASCIIToUTF16;
+ RegisterCountingRequestHandler();
+ GURL url(embedded_test_server()->GetURL(kCountedHtmlPath));
+
+ EXPECT_TRUE(TitleBecomes(url, "Version 1"));
+
+ // Reset the renderer cache.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ // Load the page again. We should get the stale version from the cache.
+ EXPECT_TRUE(TitleBecomes(url, "Version 1"));
+
+ // Wait for the async revalidation request to be processed by the
+ // EmbeddedTestServer.
+ run_loop()->Run();
+
+ // Reset the renderer cache.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ // Since the async revalidation request has been sent, the cache can no
+ // longer return the stale contents.
+ EXPECT_TRUE(TitleBecomes(url, "Version 2"));
+}
+
+// When the asynchronous revalidation arrives, any cookies it contains must be
+// applied immediately.
+IN_PROC_BROWSER_TEST_F(AsyncRevalidationManagerBrowserTest,
+ CookieSetAsynchronously) {
+ RegisterCookieRequestHandler();
+ GURL url(embedded_test_server()->GetURL(kCookieHtmlPath));
+
+ // Set cookie to version=1
+ NavigateToURL(shell(), url);
+
+ // Reset render cache.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ // The page will load from the cache, then when the async revalidation
+ // completes the cookie will update.
+ EXPECT_TRUE(TitleBecomes(url, "PASS"));
+}
+
+} // namespace
+
+} // namespace content
diff --git a/chromium/content/browser/loader/async_revalidation_manager_unittest.cc b/chromium/content/browser/loader/async_revalidation_manager_unittest.cc
new file mode 100644
index 00000000000..d0ec206130d
--- /dev/null
+++ b/chromium/content/browser/loader/async_revalidation_manager_unittest.cc
@@ -0,0 +1,554 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/async_revalidation_manager.h"
+
+#include <deque>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/shared_memory_handle.h"
+#include "base/pickle.h"
+#include "base/run_loop.h"
+#include "base/strings/string_util.h"
+#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/loader/resource_message_filter.h"
+#include "content/common/child_process_host_impl.h"
+#include "content/common/resource_messages.h"
+#include "content/public/browser/resource_context.h"
+#include "content/public/common/appcache_info.h"
+#include "content/public/common/process_type.h"
+#include "content/public/common/resource_type.h"
+#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "ipc/ipc_param_traits.h"
+#include "net/base/load_flags.h"
+#include "net/base/network_delegate.h"
+#include "net/http/http_util.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_job.h"
+#include "net/url_request/url_request_job_factory.h"
+#include "net/url_request/url_request_test_job.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/page_transition_types.h"
+#include "url/gurl.h"
+#include "url/url_constants.h"
+
+namespace content {
+
+namespace {
+
+// This class is a variation on URLRequestTestJob that
+// returns ERR_IO_PENDING before every read, not just the first one.
+class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
+ public:
+ URLRequestTestDelayedCompletionJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const std::string& response_headers,
+ const std::string& response_data)
+ : net::URLRequestTestJob(request,
+ network_delegate,
+ response_headers,
+ response_data,
+ false) {}
+
+ private:
+ bool NextReadAsync() override { return true; }
+};
+
+// A URLRequestJob implementation which sets the |async_revalidation_required|
+// flag on the HttpResponseInfo object to true if the request has the
+// LOAD_SUPPORT_ASYNC_REVALIDATION flag.
+class AsyncRevalidationRequiredURLRequestTestJob
+ : public net::URLRequestTestJob {
+ public:
+ AsyncRevalidationRequiredURLRequestTestJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate)
+ : URLRequestTestJob(request,
+ network_delegate,
+ net::URLRequestTestJob::test_headers(),
+ std::string(),
+ false) {}
+
+ void GetResponseInfo(net::HttpResponseInfo* info) override {
+ URLRequestTestJob::GetResponseInfo(info);
+ if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION)
+ info->async_revalidation_required = true;
+ }
+};
+
+// A URLRequestJob implementation which serves a redirect and sets the
+// |async_revalidation_required| flag on the HttpResponseInfo object to true if
+// the request has the LOAD_SUPPORT_ASYNC_REVALIDATION flag.
+class RedirectAndRevalidateURLRequestTestJob : public net::URLRequestTestJob {
+ public:
+ RedirectAndRevalidateURLRequestTestJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate)
+ : URLRequestTestJob(request,
+ network_delegate,
+ CreateRedirectHeaders(),
+ std::string(),
+ false) {}
+
+ void GetResponseInfo(net::HttpResponseInfo* info) override {
+ URLRequestTestJob::GetResponseInfo(info);
+ if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION)
+ info->async_revalidation_required = true;
+ }
+
+ private:
+ static std::string CreateRedirectHeaders() {
+ static const char kRedirectHeaders[] =
+ "HTTP/1.1 302 MOVED\n"
+ "Location: http://example.com/async-revalidate/from-redirect\n"
+ "\n";
+ return std::string(kRedirectHeaders, arraysize(kRedirectHeaders) - 1);
+ }
+};
+
+class TestURLRequestJobFactory : public net::URLRequestJobFactory {
+ public:
+ TestURLRequestJobFactory() = default;
+
+ // Sets the contents of the response. |headers| should have "\n" as line
+ // breaks and end in "\n\n".
+ void SetResponse(const std::string& headers, const std::string& data) {
+ response_headers_ = headers;
+ response_data_ = data;
+ }
+
+ net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
+ const std::string& scheme,
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ std::string path = request->url().path();
+ if (base::StartsWith(path, "/async-revalidate",
+ base::CompareCase::SENSITIVE)) {
+ return new AsyncRevalidationRequiredURLRequestTestJob(request,
+ network_delegate);
+ }
+ if (base::StartsWith(path, "/redirect", base::CompareCase::SENSITIVE)) {
+ return new RedirectAndRevalidateURLRequestTestJob(request,
+ network_delegate);
+ }
+ return new URLRequestTestDelayedCompletionJob(
+ request, network_delegate, response_headers_, response_data_);
+ }
+
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
+ bool IsHandledProtocol(const std::string& scheme) const override {
+ // If non-standard schemes need to be tested in future it will be
+ // necessary to call ChildProcessSecurityPolicyImpl::
+ // RegisterWebSafeScheme() for them.
+ return scheme == url::kHttpScheme || scheme == url::kHttpsScheme;
+ }
+
+ bool IsHandledURL(const GURL& url) const override {
+ return IsHandledProtocol(url.scheme());
+ }
+
+ bool IsSafeRedirectTarget(const GURL& location) const override {
+ return false;
+ }
+
+ private:
+ std::string response_headers_;
+ std::string response_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
+};
+
+// On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
+// automatically released.
+//
+// See ResourceDispatcher::ReleaseResourcesInDataMessage.
+//
+// TODO(ricea): Maybe share this implementation with
+// resource_dispatcher_host_unittest.cc.
+void ReleaseHandlesInMessage(const IPC::Message& message) {
+ if (message.type() == ResourceMsg_SetDataBuffer::ID) {
+ base::PickleIterator iter(message);
+ int request_id;
+ CHECK(iter.ReadInt(&request_id));
+ base::SharedMemoryHandle shm_handle;
+ if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message, &iter,
+ &shm_handle)) {
+ if (base::SharedMemory::IsHandleValid(shm_handle))
+ base::SharedMemory::CloseHandle(shm_handle);
+ }
+ }
+}
+
+// This filter just deletes any messages that are sent through it.
+class BlackholeFilter : public ResourceMessageFilter {
+ public:
+ explicit BlackholeFilter(ResourceContext* resource_context)
+ : ResourceMessageFilter(
+ ChildProcessHostImpl::GenerateChildProcessUniqueId(),
+ PROCESS_TYPE_RENDERER,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ base::Bind(&BlackholeFilter::GetContexts, base::Unretained(this))),
+ resource_context_(resource_context) {
+ ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
+ }
+
+ bool Send(IPC::Message* msg) override {
+ scoped_ptr<IPC::Message> take_ownership(msg);
+ ReleaseHandlesInMessage(*msg);
+ return true;
+ }
+
+ private:
+ ~BlackholeFilter() override {
+ ChildProcessSecurityPolicyImpl::GetInstance()->Remove(child_id());
+ }
+
+ void GetContexts(ResourceType resource_type,
+ int origin_pid,
+ ResourceContext** resource_context,
+ net::URLRequestContext** request_context) {
+ *resource_context = resource_context_;
+ *request_context = resource_context_->GetRequestContext();
+ }
+
+ ResourceContext* resource_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlackholeFilter);
+};
+
+ResourceHostMsg_Request CreateResourceRequest(const char* method,
+ ResourceType type,
+ const GURL& url) {
+ ResourceHostMsg_Request request;
+ request.method = std::string(method);
+ request.url = url;
+ request.first_party_for_cookies = url; // Bypass third-party cookie blocking.
+ request.referrer_policy = blink::WebReferrerPolicyDefault;
+ request.load_flags = 0;
+ request.origin_pid = 0;
+ request.resource_type = type;
+ request.request_context = 0;
+ request.appcache_host_id = kAppCacheNoHostId;
+ request.download_to_file = false;
+ request.should_reset_appcache = false;
+ request.is_main_frame = true;
+ request.parent_is_main_frame = false;
+ request.parent_render_frame_id = -1;
+ request.transition_type = ui::PAGE_TRANSITION_LINK;
+ request.allow_download = true;
+ return request;
+}
+
+class AsyncRevalidationManagerTest : public ::testing::Test {
+ protected:
+ AsyncRevalidationManagerTest(
+ scoped_ptr<net::TestNetworkDelegate> network_delegate)
+ : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+ network_delegate_(std::move(network_delegate)) {
+ browser_context_.reset(new TestBrowserContext());
+ BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
+ base::RunLoop().RunUntilIdle();
+ ResourceContext* resource_context = browser_context_->GetResourceContext();
+ filter_ = new BlackholeFilter(resource_context);
+ net::URLRequestContext* request_context =
+ resource_context->GetRequestContext();
+ job_factory_.reset(new TestURLRequestJobFactory);
+ request_context->set_job_factory(job_factory_.get());
+ request_context->set_network_delegate(network_delegate_.get());
+ host_.EnableStaleWhileRevalidateForTesting();
+ }
+
+ AsyncRevalidationManagerTest()
+ : AsyncRevalidationManagerTest(
+ make_scoped_ptr(new net::TestNetworkDelegate)) {}
+
+ void TearDown() override {
+ host_.CancelRequestsForProcess(filter_->child_id());
+ host_.Shutdown();
+ host_.CancelRequestsForContext(browser_context_->GetResourceContext());
+ browser_context_.reset();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void SetResponse(const std::string& headers, const std::string& data) {
+ job_factory_->SetResponse(headers, data);
+ }
+
+ // Creates a request using the current test object as the filter and
+ // SubResource as the resource type.
+ void MakeTestRequest(int render_view_id, int request_id, const GURL& url) {
+ ResourceHostMsg_Request request =
+ CreateResourceRequest("GET", RESOURCE_TYPE_SUB_RESOURCE, url);
+ ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
+ host_.OnMessageReceived(msg, filter_.get());
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void EnsureSchemeIsAllowed(const std::string& scheme) {
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+ if (!policy->IsWebSafeScheme(scheme))
+ policy->RegisterWebSafeScheme(scheme);
+ }
+
+ content::TestBrowserThreadBundle thread_bundle_;
+ scoped_ptr<TestBrowserContext> browser_context_;
+ scoped_ptr<TestURLRequestJobFactory> job_factory_;
+ scoped_refptr<BlackholeFilter> filter_;
+ scoped_ptr<net::TestNetworkDelegate> network_delegate_;
+ ResourceDispatcherHostImpl host_;
+};
+
+TEST_F(AsyncRevalidationManagerTest, SupportsAsyncRevalidation) {
+ SetResponse(net::URLRequestTestJob::test_headers(), "delay complete");
+ MakeTestRequest(0, 1, GURL("http://example.com/baz"));
+
+ net::URLRequest* url_request(
+ host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
+ ASSERT_TRUE(url_request);
+
+ EXPECT_TRUE(url_request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION);
+}
+
+TEST_F(AsyncRevalidationManagerTest, AsyncRevalidationNotSupportedForPOST) {
+ SetResponse(net::URLRequestTestJob::test_headers(), "delay complete");
+ // Create POST request.
+ ResourceHostMsg_Request request = CreateResourceRequest(
+ "POST", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/baz.php"));
+ ResourceHostMsg_RequestResource msg(0, 1, request);
+ host_.OnMessageReceived(msg, filter_.get());
+ base::RunLoop().RunUntilIdle();
+
+ net::URLRequest* url_request(
+ host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
+ ASSERT_TRUE(url_request);
+
+ EXPECT_FALSE(url_request->load_flags() &
+ net::LOAD_SUPPORT_ASYNC_REVALIDATION);
+}
+
+TEST_F(AsyncRevalidationManagerTest,
+ AsyncRevalidationNotSupportedAfterRedirect) {
+ static const char kRedirectHeaders[] =
+ "HTTP/1.1 302 MOVED\n"
+ "Location: http://example.com/var\n"
+ "\n";
+ SetResponse(kRedirectHeaders, "");
+
+ MakeTestRequest(0, 1, GURL("http://example.com/baz"));
+
+ net::URLRequest* url_request(
+ host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
+ ASSERT_TRUE(url_request);
+
+ EXPECT_FALSE(url_request->load_flags() &
+ net::LOAD_SUPPORT_ASYNC_REVALIDATION);
+}
+
+// A NetworkDelegate that records the URLRequests as they are created.
+class URLRequestRecordingNetworkDelegate : public net::TestNetworkDelegate {
+ public:
+ URLRequestRecordingNetworkDelegate() : requests_() {}
+
+ net::URLRequest* NextRequest() {
+ EXPECT_FALSE(requests_.empty());
+ if (requests_.empty())
+ return nullptr;
+ net::URLRequest* request = requests_.front();
+ EXPECT_TRUE(request);
+ requests_.pop_front();
+ return request;
+ }
+
+ bool NextRequestWasDestroyed() {
+ net::URLRequest* request = requests_.front();
+ requests_.pop_front();
+ return request == nullptr;
+ }
+
+ bool IsEmpty() const { return requests_.empty(); }
+
+ int OnBeforeURLRequest(net::URLRequest* request,
+ const net::CompletionCallback& callback,
+ GURL* new_url) override {
+ requests_.push_back(request);
+ return TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
+ }
+
+ void OnURLRequestDestroyed(net::URLRequest* request) override {
+ for (auto& recorded_request : requests_) {
+ if (recorded_request == request)
+ recorded_request = nullptr;
+ }
+ net::TestNetworkDelegate::OnURLRequestDestroyed(request);
+ }
+
+ private:
+ std::deque<net::URLRequest*> requests_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLRequestRecordingNetworkDelegate);
+};
+
+class AsyncRevalidationManagerRecordingTest
+ : public AsyncRevalidationManagerTest {
+ public:
+ AsyncRevalidationManagerRecordingTest()
+ : AsyncRevalidationManagerTest(
+ make_scoped_ptr(new URLRequestRecordingNetworkDelegate)) {}
+
+ void TearDown() override {
+ EXPECT_TRUE(IsEmpty());
+ AsyncRevalidationManagerTest::TearDown();
+ }
+
+ URLRequestRecordingNetworkDelegate* recording_network_delegate() const {
+ return static_cast<URLRequestRecordingNetworkDelegate*>(
+ network_delegate_.get());
+ }
+
+ bool NextRequestWasDestroyed() {
+ return recording_network_delegate()->NextRequestWasDestroyed();
+ }
+
+ net::URLRequest* NextRequest() {
+ return recording_network_delegate()->NextRequest();
+ }
+
+ bool IsEmpty() const { return recording_network_delegate()->IsEmpty(); }
+};
+
+// Verify that an async revalidation is actually created when needed.
+TEST_F(AsyncRevalidationManagerRecordingTest, Issued) {
+ // Create the original request.
+ MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));
+
+ net::URLRequest* initial_request = NextRequest();
+ ASSERT_TRUE(initial_request);
+ EXPECT_TRUE(initial_request->load_flags() &
+ net::LOAD_SUPPORT_ASYNC_REVALIDATION);
+
+ net::URLRequest* async_request = NextRequest();
+ ASSERT_TRUE(async_request);
+}
+
+// Verify the the URL of the async revalidation matches the original request.
+TEST_F(AsyncRevalidationManagerRecordingTest, URLMatches) {
+ // Create the original request.
+ MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate/u"));
+
+ // Discard the original request.
+ NextRequest();
+
+ net::URLRequest* async_request = NextRequest();
+ ASSERT_TRUE(async_request);
+ EXPECT_EQ(GURL("http://example.com/async-revalidate/u"),
+ async_request->url());
+}
+
+TEST_F(AsyncRevalidationManagerRecordingTest,
+ AsyncRevalidationsDoNotSupportAsyncRevalidation) {
+ // Create the original request.
+ MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));
+
+ // Discard the original request.
+ NextRequest();
+
+ // Get the async revalidation request.
+ net::URLRequest* async_request = NextRequest();
+ ASSERT_TRUE(async_request);
+ EXPECT_FALSE(async_request->load_flags() &
+ net::LOAD_SUPPORT_ASYNC_REVALIDATION);
+}
+
+TEST_F(AsyncRevalidationManagerRecordingTest, AsyncRevalidationsNotDuplicated) {
+ // Create the original request.
+ MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));
+
+ // Discard the original request.
+ NextRequest();
+
+ // Get the async revalidation request.
+ net::URLRequest* async_request = NextRequest();
+ EXPECT_TRUE(async_request);
+
+ // Start a second request to the same URL.
+ MakeTestRequest(0, 2, GURL("http://example.com/async-revalidate"));
+
+ // Discard the second request.
+ NextRequest();
+
+ // There should not be another async revalidation request.
+ EXPECT_TRUE(IsEmpty());
+}
+
+// Async revalidation to different URLs should not be treated as duplicates.
+TEST_F(AsyncRevalidationManagerRecordingTest,
+ AsyncRevalidationsToSeparateURLsAreSeparate) {
+ // Create two requests to two URLs.
+ MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));
+ MakeTestRequest(0, 2, GURL("http://example.com/async-revalidate2"));
+
+ net::URLRequest* initial_request = NextRequest();
+ ASSERT_TRUE(initial_request);
+ net::URLRequest* initial_async_revalidation = NextRequest();
+ ASSERT_TRUE(initial_async_revalidation);
+ net::URLRequest* second_request = NextRequest();
+ ASSERT_TRUE(second_request);
+ net::URLRequest* second_async_revalidation = NextRequest();
+ ASSERT_TRUE(second_async_revalidation);
+
+ EXPECT_EQ("http://example.com/async-revalidate",
+ initial_request->url().spec());
+ EXPECT_EQ("http://example.com/async-revalidate",
+ initial_async_revalidation->url().spec());
+ EXPECT_EQ("http://example.com/async-revalidate2",
+ second_request->url().spec());
+ EXPECT_EQ("http://example.com/async-revalidate2",
+ second_async_revalidation->url().spec());
+}
+
+// Nothing after the first redirect leg has stale-while-revalidate applied.
+// TODO(ricea): s-w-r should work with redirects. Change this test when it does.
+TEST_F(AsyncRevalidationManagerRecordingTest, NoSWRAfterFirstRedirectLeg) {
+ MakeTestRequest(0, 1, GURL("http://example.com/redirect"));
+
+ net::URLRequest* initial_request = NextRequest();
+ EXPECT_TRUE(initial_request);
+
+ EXPECT_FALSE(initial_request->load_flags() &
+ net::LOAD_SUPPORT_ASYNC_REVALIDATION);
+
+ // An async revalidation happens for the redirect. It has no body, so it has
+ // already completed.
+ EXPECT_TRUE(NextRequestWasDestroyed());
+
+ // But no others.
+ EXPECT_TRUE(IsEmpty());
+}
+
+} // namespace
+
+} // namespace content
diff --git a/chromium/content/browser/loader/certificate_resource_handler.cc b/chromium/content/browser/loader/certificate_resource_handler.cc
deleted file mode 100644
index fd49181f8da..00000000000
--- a/chromium/content/browser/loader/certificate_resource_handler.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/loader/certificate_resource_handler.h"
-
-#include <limits.h>
-
-#include "components/mime_util/mime_util.h"
-#include "content/browser/loader/resource_request_info_impl.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/common/resource_response.h"
-#include "net/base/io_buffer.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_status.h"
-
-namespace content {
-
-CertificateResourceHandler::CertificateResourceHandler(net::URLRequest* request)
- : ResourceHandler(request),
- buffer_(new net::GrowableIOBuffer),
- cert_type_(net::CERTIFICATE_MIME_TYPE_UNKNOWN) {
-}
-
-CertificateResourceHandler::~CertificateResourceHandler() {
-}
-
-bool CertificateResourceHandler::OnRequestRedirected(
- const net::RedirectInfo& redirect_info,
- ResourceResponse* resp,
- bool* defer) {
- return true;
-}
-
-bool CertificateResourceHandler::OnResponseStarted(ResourceResponse* resp,
- bool* defer) {
- cert_type_ =
- mime_util::GetCertificateMimeTypeForMimeType(resp->head.mime_type);
- return cert_type_ != net::CERTIFICATE_MIME_TYPE_UNKNOWN;
-}
-
-bool CertificateResourceHandler::OnWillStart(const GURL& url, bool* defer) {
- return true;
-}
-
-bool CertificateResourceHandler::OnBeforeNetworkStart(const GURL& url,
- bool* defer) {
- return true;
-}
-
-bool CertificateResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
- int* buf_size,
- int min_size) {
- static const int kInitialBufferSizeInBytes = 32768;
- static const int kMaxCertificateSizeInBytes = 1024 * 1024;
-
- // TODO(gauravsh): Should we use 'min_size' here?
- DCHECK(buf);
- DCHECK(buf_size);
-
- if (buffer_->capacity() == 0) {
- buffer_->SetCapacity(kInitialBufferSizeInBytes);
- } else if (buffer_->RemainingCapacity() == 0) {
- int capacity = buffer_->capacity();
- if (capacity >= kMaxCertificateSizeInBytes)
- return false;
- static_assert(kMaxCertificateSizeInBytes < INT_MAX / 2,
- "The size limit ensures the capacity remains in bounds.");
- capacity *= 2;
- if (capacity > kMaxCertificateSizeInBytes)
- capacity = kMaxCertificateSizeInBytes;
- buffer_->SetCapacity(capacity);
- }
-
- *buf = buffer_.get();
- *buf_size = buffer_->RemainingCapacity();
-
- return true;
-}
-
-bool CertificateResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
- DCHECK_LE(0, bytes_read);
- DCHECK_LE(bytes_read, buffer_->RemainingCapacity());
- if (!bytes_read)
- return true;
-
- buffer_->set_offset(buffer_->offset() + bytes_read);
- return true;
-}
-
-void CertificateResourceHandler::OnResponseCompleted(
- const net::URLRequestStatus& urs,
- const std::string& sec_info,
- bool* defer) {
- if (urs.status() != net::URLRequestStatus::SUCCESS)
- return;
-
- // Note that it's up to the browser to verify that the certificate
- // data is well-formed.
- const ResourceRequestInfo* info = GetRequestInfo();
- GetContentClient()->browser()->AddCertificate(
- cert_type_, buffer_->StartOfBuffer(),
- static_cast<size_t>(buffer_->offset()), info->GetChildID(),
- info->GetRenderFrameID());
-}
-
-void CertificateResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- NOTREACHED();
-}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/certificate_resource_handler.h b/chromium/content/browser/loader/certificate_resource_handler.h
deleted file mode 100644
index 743bf9d71dc..00000000000
--- a/chromium/content/browser/loader/certificate_resource_handler.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_LOADER_CERTIFICATE_RESOURCE_HANDLER_H_
-#define CONTENT_BROWSER_LOADER_CERTIFICATE_RESOURCE_HANDLER_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "content/browser/loader/resource_handler.h"
-#include "net/base/mime_util.h"
-
-namespace net {
-class GrowableIOBuffer;
-class URLRequest;
-class URLRequestStatus;
-} // namespace net
-
-namespace content {
-
-// This class handles certificate mime types such as:
-// - "application/x-x509-user-cert"
-// - "application/x-x509-ca-cert"
-// - "application/x-pkcs12"
-//
-class CertificateResourceHandler : public ResourceHandler {
- public:
- explicit CertificateResourceHandler(net::URLRequest* request);
- ~CertificateResourceHandler() override;
-
- // Not needed, as this event handler ought to be the final resource.
- bool OnRequestRedirected(const net::RedirectInfo& redirect_info,
- ResourceResponse* resp,
- bool* defer) override;
-
- // Check if this indeed an X509 cert.
- bool OnResponseStarted(ResourceResponse* resp, bool* defer) override;
-
- // Pass-through implementation.
- bool OnWillStart(const GURL& url, bool* defer) override;
-
- // Pass-through implementation.
- bool OnBeforeNetworkStart(const GURL& url, bool* defer) override;
-
- // Create a new buffer to store received data.
- bool OnWillRead(scoped_refptr<net::IOBuffer>* buf,
- int* buf_size,
- int min_size) override;
-
- // A read was completed, maybe allocate a new buffer for further data.
- bool OnReadCompleted(int bytes_read, bool* defer) override;
-
- // Done downloading the certificate.
- void OnResponseCompleted(const net::URLRequestStatus& urs,
- const std::string& sec_info,
- bool* defer) override;
-
- // N/A to cert downloading.
- void OnDataDownloaded(int bytes_downloaded) override;
-
- private:
- scoped_refptr<net::GrowableIOBuffer> buffer_;
- net::CertificateMimeType cert_type_;
-
- DISALLOW_COPY_AND_ASSIGN(CertificateResourceHandler);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_LOADER_CERTIFICATE_RESOURCE_HANDLER_H_
diff --git a/chromium/content/browser/loader/cross_site_resource_handler.cc b/chromium/content/browser/loader/cross_site_resource_handler.cc
index 7ffb659744a..fad4024ee28 100644
--- a/chromium/content/browser/loader/cross_site_resource_handler.cc
+++ b/chromium/content/browser/loader/cross_site_resource_handler.cc
@@ -5,6 +5,7 @@
#include "content/browser/loader/cross_site_resource_handler.h"
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
@@ -76,9 +77,9 @@ void OnCrossSiteResponseHelper(const CrossSiteResponseParams& params) {
CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
}
rfh->OnCrossSiteResponse(
- params.global_request_id, cross_site_transferring_request.Pass(),
- params.transfer_url_chain, params.referrer,
- params.page_transition, params.should_replace_current_entry);
+ params.global_request_id, std::move(cross_site_transferring_request),
+ params.transfer_url_chain, params.referrer, params.page_transition,
+ params.should_replace_current_entry);
} else if (leak_requests_for_testing_ && cross_site_transferring_request) {
// Some unit tests expect requests to be leaked in this case, so they can
// pass them along manually.
@@ -87,42 +88,23 @@ void OnCrossSiteResponseHelper(const CrossSiteResponseParams& params) {
}
// Returns whether a transfer is needed by doing a check on the UI thread.
-bool CheckNavigationPolicyOnUI(GURL real_url,
- int process_id,
- int render_frame_id) {
+CrossSiteResourceHandler::NavigationDecision
+CheckNavigationPolicyOnUI(GURL real_url, int process_id, int render_frame_id) {
CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
RenderFrameHostImpl* rfh =
RenderFrameHostImpl::FromID(process_id, render_frame_id);
+
+ // Without a valid RFH against which to check, we must cancel the request,
+ // to prevent the resource at |url| from being delivered to a potentially
+ // unsuitable renderer process.
if (!rfh)
- return false;
-
- // A transfer is not needed if the current SiteInstance doesn't yet have a
- // site. This is the case for tests that use NavigateToURL.
- if (!rfh->GetSiteInstance()->HasSite())
- return false;
-
- // For now, GuestViews never transfer on cross-site navigations.
- WebContentsImpl* web_contents =
- static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(rfh));
- if (web_contents->GetBrowserPluginGuest())
- return false;
-
- GURL effective_url = SiteInstanceImpl::GetEffectiveURL(
- rfh->GetSiteInstance()->GetBrowserContext(), real_url);
-
- // TODO(nasko, nick): These following --site-per-process checks are
- // overly simplistic. Update them to match all the cases
- // considered by RenderFrameHostManager::DetermineSiteInstanceForURL.
- if (SiteInstance::IsSameWebSite(rfh->GetSiteInstance()->GetBrowserContext(),
- rfh->GetSiteInstance()->GetSiteURL(),
- real_url)) {
- return false; // The same site, no transition needed.
- }
+ return CrossSiteResourceHandler::NavigationDecision::CANCEL_REQUEST;
- // The sites differ. If either one requires a dedicated process,
- // then a transfer is needed.
- return rfh->GetSiteInstance()->RequiresDedicatedProcess() ||
- SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(effective_url);
+ RenderFrameHostManager* manager = rfh->frame_tree_node()->render_manager();
+ if (manager->IsRendererTransferNeededForNavigation(rfh, real_url))
+ return CrossSiteResourceHandler::NavigationDecision::TRANSFER_REQUIRED;
+ else
+ return CrossSiteResourceHandler::NavigationDecision::USE_EXISTING_RENDERER;
}
} // namespace
@@ -130,13 +112,12 @@ bool CheckNavigationPolicyOnUI(GURL real_url,
CrossSiteResourceHandler::CrossSiteResourceHandler(
scoped_ptr<ResourceHandler> next_handler,
net::URLRequest* request)
- : LayeredResourceHandler(request, next_handler.Pass()),
+ : LayeredResourceHandler(request, std::move(next_handler)),
has_started_response_(false),
in_cross_site_transition_(false),
completed_during_transition_(false),
did_defer_(false),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
CrossSiteResourceHandler::~CrossSiteResourceHandler() {
// Cleanup back-pointer stored on the request info.
@@ -236,11 +217,18 @@ bool CrossSiteResourceHandler::OnNormalResponseStarted(
return next_handler_->OnResponseStarted(response, defer);
}
-void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) {
- if (is_transfer) {
- StartCrossSiteTransition(response_.get());
- } else {
- ResumeResponse();
+void CrossSiteResourceHandler::ResumeOrTransfer(NavigationDecision decision) {
+ switch (decision) {
+ case NavigationDecision::CANCEL_REQUEST:
+ // TODO(nick): What kind of cleanup do we need here?
+ controller()->Cancel();
+ break;
+ case NavigationDecision::USE_EXISTING_RENDERER:
+ ResumeResponse();
+ break;
+ case NavigationDecision::TRANSFER_REQUIRED:
+ StartCrossSiteTransition(response_.get());
+ break;
}
}
diff --git a/chromium/content/browser/loader/cross_site_resource_handler.h b/chromium/content/browser/loader/cross_site_resource_handler.h
index b73a5a1475b..3c38fc758d4 100644
--- a/chromium/content/browser/loader/cross_site_resource_handler.h
+++ b/chromium/content/browser/loader/cross_site_resource_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_LOADER_CROSS_SITE_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_LOADER_CROSS_SITE_RESOURCE_HANDLER_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/loader/layered_resource_handler.h"
@@ -26,6 +27,12 @@ struct TransitionLayerData;
// and not a download.
class CrossSiteResourceHandler : public LayeredResourceHandler {
public:
+ enum class NavigationDecision {
+ TRANSFER_REQUIRED,
+ USE_EXISTING_RENDERER,
+ CANCEL_REQUEST
+ };
+
CrossSiteResourceHandler(scoped_ptr<ResourceHandler> next_handler,
net::URLRequest* request);
~CrossSiteResourceHandler() override;
@@ -63,7 +70,7 @@ class CrossSiteResourceHandler : public LayeredResourceHandler {
bool OnNormalResponseStarted(ResourceResponse* response,
bool* defer);
- void ResumeOrTransfer(bool is_transfer);
+ void ResumeOrTransfer(NavigationDecision decision);
void ResumeIfDeferred();
// Called when about to defer a request. Sets |did_defer_| and logs the
diff --git a/chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc b/chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc
new file mode 100644
index 00000000000..a6df689d032
--- /dev/null
+++ b/chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc
@@ -0,0 +1,278 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/frame_messages.h"
+#include "content/public/browser/resource_dispatcher_host.h"
+#include "content/public/browser/resource_dispatcher_host_delegate.h"
+#include "content/public/browser/resource_throttle.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
+#include "ipc/ipc_security_test_util.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/url_request/url_request.h"
+
+namespace content {
+
+namespace {
+
+// A ResourceDispatchHostDelegate that uses ResourceThrottles to pause a
+// targeted request temporarily, to run a chunk of test code.
+class TestResourceDispatcherHostDelegate
+ : public ShellResourceDispatcherHostDelegate {
+ public:
+ using RequestDeferredHook = base::Callback<void(const base::Closure& resume)>;
+ TestResourceDispatcherHostDelegate() : throttle_created_(false) {}
+
+ void RequestBeginning(net::URLRequest* request,
+ ResourceContext* resource_context,
+ AppCacheService* appcache_service,
+ ResourceType resource_type,
+ ScopedVector<ResourceThrottle>* throttles) override {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ShellResourceDispatcherHostDelegate::RequestBeginning(
+ request, resource_context, appcache_service, resource_type, throttles);
+
+ // If this is a request for the tracked URL, add a throttle to track it.
+ if (request->url() == tracked_url_) {
+ // Expect only a single request for the tracked url.
+ ASSERT_FALSE(throttle_created_);
+ throttle_created_ = true;
+
+ throttles->push_back(
+ new CallbackRunningResourceThrottle(request, this, run_on_start_));
+ }
+ }
+
+ // Starts tracking a URL. The request for previously tracked URL, if any,
+ // must have been made and deleted before calling this function.
+ void SetTrackedURL(const GURL& tracked_url,
+ const RequestDeferredHook& run_on_start) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Should not currently be tracking any URL.
+ ASSERT_FALSE(run_loop_);
+
+ // Create a RunLoop that will be stopped once the request for the tracked
+ // URL has been destroyed, to allow tracking the URL while also waiting for
+ // other events.
+ run_loop_.reset(new base::RunLoop());
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&TestResourceDispatcherHostDelegate::SetTrackedURLOnIOThread,
+ base::Unretained(this), tracked_url, run_on_start,
+ run_loop_->QuitClosure()));
+ }
+
+ // Waits until the tracked URL has been requested, and the request for it has
+ // been destroyed.
+ bool WaitForTrackedURLAndGetCompleted() {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ run_loop_->Run();
+ run_loop_.reset();
+ return tracked_request_completed_;
+ }
+
+ private:
+ // A ResourceThrottle which defers the request at WillStartRequest time until
+ // a test-supplied callback completes. Notifies |tracker| when the request is
+ // destroyed.
+ class CallbackRunningResourceThrottle : public ResourceThrottle {
+ public:
+ CallbackRunningResourceThrottle(net::URLRequest* request,
+ TestResourceDispatcherHostDelegate* tracker,
+ const RequestDeferredHook& run_on_start)
+ : request_(request),
+ tracker_(tracker),
+ run_on_start_(run_on_start),
+ weak_factory_(this) {}
+
+ void WillStartRequest(bool* defer) override {
+ *defer = true;
+ base::Closure resume_request_on_io_thread = base::Bind(
+ base::IgnoreResult(&BrowserThread::PostTask), BrowserThread::IO,
+ FROM_HERE, base::Bind(&CallbackRunningResourceThrottle::Resume,
+ weak_factory_.GetWeakPtr()));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(run_on_start_, resume_request_on_io_thread));
+ }
+
+ ~CallbackRunningResourceThrottle() override {
+ // If the request is deleted without being cancelled, its status will
+ // indicate it succeeded, so have to check if the request is still pending
+ // as well.
+ tracker_->OnTrackedRequestDestroyed(!request_->is_pending() &&
+ request_->status().is_success());
+ }
+
+ // ResourceThrottle implementation:
+ const char* GetNameForLogging() const override {
+ return "CallbackRunningResourceThrottle";
+ }
+
+ private:
+ void Resume() { controller()->Resume(); }
+ net::URLRequest* request_;
+ TestResourceDispatcherHostDelegate* tracker_;
+ RequestDeferredHook run_on_start_;
+ base::WeakPtrFactory<CallbackRunningResourceThrottle> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(CallbackRunningResourceThrottle);
+ };
+
+ void SetTrackedURLOnIOThread(const GURL& tracked_url,
+ const RequestDeferredHook& run_on_start,
+ const base::Closure& run_loop_quit_closure) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ throttle_created_ = false;
+ tracked_url_ = tracked_url;
+ run_on_start_ = run_on_start;
+ run_loop_quit_closure_ = run_loop_quit_closure;
+ }
+
+ void OnTrackedRequestDestroyed(bool completed) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ tracked_request_completed_ = completed;
+ tracked_url_ = GURL();
+ run_on_start_ = RequestDeferredHook();
+
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ run_loop_quit_closure_);
+ }
+
+ // These live on the IO thread.
+ GURL tracked_url_;
+ bool throttle_created_;
+ base::Closure run_loop_quit_closure_;
+ RequestDeferredHook run_on_start_;
+
+ // This lives on the UI thread.
+ scoped_ptr<base::RunLoop> run_loop_;
+
+ // Set on the IO thread while |run_loop_| is non-nullptr, read on the UI
+ // thread after deleting run_loop_.
+ bool tracked_request_completed_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
+};
+
+class CrossSiteResourceHandlerTest : public ContentBrowserTest {
+ public:
+ CrossSiteResourceHandlerTest() : old_delegate_(nullptr) {}
+
+ // ContentBrowserTest implementation:
+ void SetUpOnMainThread() override {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(
+ &CrossSiteResourceHandlerTest::InjectResourceDispatcherHostDelegate,
+ base::Unretained(this)));
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ content::SetupCrossSiteRedirector(embedded_test_server());
+ }
+
+ void TearDownOnMainThread() override {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&CrossSiteResourceHandlerTest::
+ RestoreResourceDispatcherHostDelegate,
+ base::Unretained(this)));
+ }
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ IsolateAllSitesForTesting(command_line);
+ }
+
+ void InjectResourceDispatcherHostDelegate() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate();
+ ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_);
+ }
+
+ void RestoreResourceDispatcherHostDelegate() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_);
+ old_delegate_ = nullptr;
+ }
+
+ TestResourceDispatcherHostDelegate& tracking_delegate() {
+ return tracking_delegate_;
+ }
+
+ private:
+ TestResourceDispatcherHostDelegate tracking_delegate_;
+ ResourceDispatcherHostDelegate* old_delegate_;
+};
+
+void SimulateMaliciousFrameDetachOnUIThread(int render_process_id,
+ int frame_routing_id,
+ const base::Closure& done_cb) {
+ RenderFrameHostImpl* rfh =
+ RenderFrameHostImpl::FromID(render_process_id, frame_routing_id);
+ CHECK(rfh);
+
+ // Inject a frame detach message. An attacker-controlled renderer could do
+ // this without also cancelling the pending navigation (as blink would, if you
+ // removed the iframe from the document via js).
+ rfh->OnMessageReceived(FrameHostMsg_Detach(frame_routing_id));
+ done_cb.Run();
+}
+
+} // namespace
+
+// Regression test for https://crbug.com/538784 -- ensures that one can't
+// sidestep CrossSiteResourceHandler by detaching a frame mid-request.
+IN_PROC_BROWSER_TEST_F(CrossSiteResourceHandlerTest,
+ NoDeliveryToDetachedFrame) {
+ GURL attacker_page = embedded_test_server()->GetURL(
+ "evil.com", "/cross_site_iframe_factory.html?evil(evil)");
+ EXPECT_TRUE(NavigateToURL(shell(), attacker_page));
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ RenderFrameHost* child_frame = root->child_at(0)->current_frame_host();
+
+ // Attacker initiates a navigation to a cross-site document. Under --site-per-
+ // process, these bytes must not be sent to the attacker process.
+ GURL target_resource =
+ embedded_test_server()->GetURL("a.com", "/title1.html");
+
+ // We add a testing hook to simulate the attacker-controlled process sending
+ // FrameHostMsg_Detach before the http response arrives. At the time this test
+ // was written, the resource request had a lifetime separate from the RFH,
+ tracking_delegate().SetTrackedURL(
+ target_resource, base::Bind(&SimulateMaliciousFrameDetachOnUIThread,
+ child_frame->GetProcess()->GetID(),
+ child_frame->GetRoutingID()));
+ EXPECT_TRUE(ExecuteScript(
+ shell()->web_contents()->GetMainFrame(),
+ base::StringPrintf("document.getElementById('child-0').src='%s'",
+ target_resource.spec().c_str())));
+
+ // Wait for the scenario to play out. If this returns false, it means the
+ // request did not succeed, which is good in this case.
+ EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted())
+ << "Request should have been cancelled before reaching the renderer.";
+}
+
+} // namespace content
diff --git a/chromium/content/browser/loader/detachable_resource_handler.cc b/chromium/content/browser/loader/detachable_resource_handler.cc
index df9c357a888..786252f5b6b 100644
--- a/chromium/content/browser/loader/detachable_resource_handler.cc
+++ b/chromium/content/browser/loader/detachable_resource_handler.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/detachable_resource_handler.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/time/time.h"
#include "content/browser/loader/resource_request_info_impl.h"
@@ -24,7 +26,7 @@ DetachableResourceHandler::DetachableResourceHandler(
base::TimeDelta cancel_delay,
scoped_ptr<ResourceHandler> next_handler)
: ResourceHandler(request),
- next_handler_(next_handler.Pass()),
+ next_handler_(std::move(next_handler)),
cancel_delay_(cancel_delay),
is_deferred_(false),
is_finished_(false) {
diff --git a/chromium/content/browser/loader/detachable_resource_handler.h b/chromium/content/browser/loader/detachable_resource_handler.h
index 4bb1763ec8d..95072269956 100644
--- a/chromium/content/browser/loader/detachable_resource_handler.h
+++ b/chromium/content/browser/loader/detachable_resource_handler.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_LOADER_DETACHABLE_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_LOADER_DETACHABLE_RESOURCE_HANDLER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
diff --git a/chromium/content/browser/loader/global_routing_id.h b/chromium/content/browser/loader/global_routing_id.h
index a15e93d78da..df5f202c22e 100644
--- a/chromium/content/browser/loader/global_routing_id.h
+++ b/chromium/content/browser/loader/global_routing_id.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_LOADER_GLOBAL_ROUTING_ID_H_
#define CONTENT_BROWSER_LOADER_GLOBAL_ROUTING_ID_H_
+#include <tuple>
+
namespace content {
// Uniquely identifies the route from which a net::URLRequest comes.
@@ -24,9 +26,8 @@ struct GlobalRoutingID {
int route_id;
bool operator<(const GlobalRoutingID& other) const {
- if (child_id == other.child_id)
- return route_id < other.route_id;
- return child_id < other.child_id;
+ return std::tie(child_id, route_id) <
+ std::tie(other.child_id, other.route_id);
}
bool operator==(const GlobalRoutingID& other) const {
return child_id == other.child_id &&
diff --git a/chromium/content/browser/loader/layered_resource_handler.cc b/chromium/content/browser/loader/layered_resource_handler.cc
index 00048ae520a..9ff3d55e6f3 100644
--- a/chromium/content/browser/loader/layered_resource_handler.cc
+++ b/chromium/content/browser/loader/layered_resource_handler.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/layered_resource_handler.h"
+#include <utility>
+
#include "base/logging.h"
namespace content {
@@ -11,9 +13,7 @@ namespace content {
LayeredResourceHandler::LayeredResourceHandler(
net::URLRequest* request,
scoped_ptr<ResourceHandler> next_handler)
- : ResourceHandler(request),
- next_handler_(next_handler.Pass()) {
-}
+ : ResourceHandler(request), next_handler_(std::move(next_handler)) {}
LayeredResourceHandler::~LayeredResourceHandler() {
}
diff --git a/chromium/content/browser/loader/mime_type_resource_handler.cc b/chromium/content/browser/loader/mime_type_resource_handler.cc
index 59c2b531066..3c69c0ad4d2 100644
--- a/chromium/content/browser/loader/mime_type_resource_handler.cc
+++ b/chromium/content/browser/loader/mime_type_resource_handler.cc
@@ -4,6 +4,7 @@
#include "content/browser/loader/mime_type_resource_handler.h"
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -16,7 +17,6 @@
#include "components/mime_util/mime_util.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/download/download_stats.h"
-#include "content/browser/loader/certificate_resource_handler.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/loader/stream_resource_handler.h"
@@ -86,7 +86,7 @@ MimeTypeResourceHandler::MimeTypeResourceHandler(
ResourceDispatcherHostImpl* host,
PluginService* plugin_service,
net::URLRequest* request)
- : LayeredResourceHandler(request, next_handler.Pass()),
+ : LayeredResourceHandler(request, std::move(next_handler)),
state_(STATE_STARTING),
host_(host),
plugin_service_(plugin_service),
@@ -94,8 +94,7 @@ MimeTypeResourceHandler::MimeTypeResourceHandler(
bytes_read_(0),
must_download_(false),
must_download_is_set_(false),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
MimeTypeResourceHandler::~MimeTypeResourceHandler() {
}
@@ -329,7 +328,7 @@ bool MimeTypeResourceHandler::SelectPluginHandler(bool* defer,
plugin_path, request(), response_.get(), &payload));
if (handler) {
*handled_by_plugin = true;
- return UseAlternateNextHandler(handler.Pass(), payload);
+ return UseAlternateNextHandler(std::move(handler), payload);
}
#endif
return true;
@@ -341,12 +340,14 @@ bool MimeTypeResourceHandler::SelectNextHandler(bool* defer) {
ResourceRequestInfoImpl* info = GetRequestInfo();
const std::string& mime_type = response_->head.mime_type;
- if (mime_util::IsSupportedCertificateMimeType(mime_type)) {
- // Install certificate file.
- info->set_is_download(true);
- scoped_ptr<ResourceHandler> handler(
- new CertificateResourceHandler(request()));
- return UseAlternateNextHandler(handler.Pass(), std::string());
+ // https://crbug.com/568184 - Temporary hack to track servers that aren't
+ // setting Content-Disposition when sending x-x509-user-cert and expecting
+ // the browser to automatically install certificates; this is being
+ // deprecated and will be removed upon full <keygen> removal.
+ if (mime_type == "application/x-x509-user-cert") {
+ UMA_HISTOGRAM_BOOLEAN(
+ "UserCert.ContentDisposition",
+ response_->head.headers->HasHeader("Content-Disposition"));
}
// Allow requests for object/embed tags to be intercepted as streams.
@@ -391,7 +392,7 @@ bool MimeTypeResourceHandler::SelectNextHandler(bool* defer) {
DownloadItem::kInvalidId,
scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()),
DownloadUrlParameters::OnStartedCallback()));
- return UseAlternateNextHandler(handler.Pass(), std::string());
+ return UseAlternateNextHandler(std::move(handler), std::string());
}
bool MimeTypeResourceHandler::UseAlternateNextHandler(
@@ -443,7 +444,7 @@ bool MimeTypeResourceHandler::UseAlternateNextHandler(
// This is handled entirely within the new ResourceHandler, so just reset the
// original ResourceHandler.
- next_handler_ = new_handler.Pass();
+ next_handler_ = std::move(new_handler);
next_handler_->SetController(this);
return CopyReadBufferToNextHandler();
diff --git a/chromium/content/browser/loader/mime_type_resource_handler.h b/chromium/content/browser/loader/mime_type_resource_handler.h
index b5e56c21b70..9217683584d 100644
--- a/chromium/content/browser/loader/mime_type_resource_handler.h
+++ b/chromium/content/browser/loader/mime_type_resource_handler.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/loader/layered_resource_handler.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/loader/mime_type_resource_handler_unittest.cc b/chromium/content/browser/loader/mime_type_resource_handler_unittest.cc
index 92fbbcb1fec..1b3ddcdbdf0 100644
--- a/chromium/content/browser/loader/mime_type_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/mime_type_resource_handler_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/mime_type_resource_handler.h"
+#include <stdint.h>
+
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -90,10 +92,10 @@ class TestResourceDispatcherHost : public ResourceDispatcherHostImpl {
net::URLRequest* request,
bool is_content_initiated,
bool must_download,
- uint32 id,
+ uint32_t id,
scoped_ptr<DownloadSaveInfo> save_info,
const DownloadUrlParameters::OnStartedCallback& started_cb) override {
- return scoped_ptr<ResourceHandler>(new TestResourceHandler).Pass();
+ return scoped_ptr<ResourceHandler>(new TestResourceHandler);
}
scoped_ptr<ResourceHandler> MaybeInterceptAsStream(
@@ -104,7 +106,7 @@ class TestResourceDispatcherHost : public ResourceDispatcherHostImpl {
intercepted_as_stream_count_++;
if (stream_has_handler_) {
intercepted_as_stream_ = true;
- return scoped_ptr<ResourceHandler>(new TestResourceHandler).Pass();
+ return scoped_ptr<ResourceHandler>(new TestResourceHandler);
} else {
return scoped_ptr<ResourceHandler>();
}
@@ -248,17 +250,17 @@ bool MimeTypeResourceHandlerTest::TestStreamIsIntercepted(
is_main_frame, // is_main_frame
false, // parent_is_main_frame
allow_download, // allow_download
- true); // is_async
+ true, // is_async
+ false); // is_using_lofi
TestResourceDispatcherHost host(stream_has_handler_);
TestResourceDispatcherHostDelegate host_delegate(must_download);
host.SetDelegate(&host_delegate);
TestFakePluginService plugin_service(plugin_available_, plugin_stale_);
- scoped_ptr<ResourceHandler> mime_sniffing_handler(
- new MimeTypeResourceHandler(
- scoped_ptr<ResourceHandler>(new TestResourceHandler()).Pass(), &host,
- &plugin_service, request.get()));
+ scoped_ptr<ResourceHandler> mime_sniffing_handler(new MimeTypeResourceHandler(
+ scoped_ptr<ResourceHandler>(new TestResourceHandler()), &host,
+ &plugin_service, request.get()));
TestResourceController resource_controller;
mime_sniffing_handler->SetController(&resource_controller);
@@ -317,6 +319,14 @@ TEST_F(MimeTypeResourceHandlerTest, StreamHandling) {
EXPECT_FALSE(
TestStreamIsIntercepted(allow_download, must_download, resource_type));
+ // Plugin resource request with download not allowed. Stream shouldn't be
+ // intercepted.
+ allow_download = false;
+ must_download = false;
+ resource_type = RESOURCE_TYPE_PLUGIN_RESOURCE;
+ EXPECT_FALSE(
+ TestStreamIsIntercepted(allow_download, must_download, resource_type));
+
// Object request with download not allowed. Stream should be intercepted.
allow_download = false;
must_download = false;
diff --git a/chromium/content/browser/loader/navigation_resource_throttle.cc b/chromium/content/browser/loader/navigation_resource_throttle.cc
index 8dd143cc079..44fd0c131ff 100644
--- a/chromium/content/browser/loader/navigation_resource_throttle.cc
+++ b/chromium/content/browser/loader/navigation_resource_throttle.cc
@@ -23,6 +23,14 @@ namespace {
typedef base::Callback<void(NavigationThrottle::ThrottleCheckResult)>
UIChecksPerformedCallback;
+void SendCheckResultToIOThread(UIChecksPerformedCallback callback,
+ NavigationThrottle::ThrottleCheckResult result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ CHECK(result != NavigationThrottle::DEFER);
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, result));
+}
+
void CheckWillStartRequestOnUIThread(UIChecksPerformedCallback callback,
int render_process_id,
int render_frame_host_id,
@@ -32,48 +40,76 @@ void CheckWillStartRequestOnUIThread(UIChecksPerformedCallback callback,
ui::PageTransition transition,
bool is_external_protocol) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::PROCEED;
RenderFrameHostImpl* render_frame_host =
RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
- if (render_frame_host) {
- NavigationHandleImpl* navigation_handle =
- render_frame_host->navigation_handle();
- if (navigation_handle) {
- result = navigation_handle->WillStartRequest(is_post, sanitized_referrer,
- has_user_gesture, transition,
- is_external_protocol);
- }
+ if (!render_frame_host) {
+ SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED);
+ return;
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback, result));
+
+ NavigationHandleImpl* navigation_handle =
+ render_frame_host->navigation_handle();
+ if (!navigation_handle) {
+ SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED);
+ return;
+ }
+
+ navigation_handle->WillStartRequest(
+ is_post, sanitized_referrer, has_user_gesture, transition,
+ is_external_protocol, base::Bind(&SendCheckResultToIOThread, callback));
}
-void CheckWillRedirectRequestOnUIThread(UIChecksPerformedCallback callback,
- int render_process_id,
- int render_frame_host_id,
- const GURL& new_url,
- bool new_method_is_post,
- const GURL& new_referrer_url,
- bool new_is_external_protocol) {
+void CheckWillRedirectRequestOnUIThread(
+ UIChecksPerformedCallback callback,
+ int render_process_id,
+ int render_frame_host_id,
+ const GURL& new_url,
+ bool new_method_is_post,
+ const GURL& new_referrer_url,
+ bool new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders> headers) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::PROCEED;
RenderFrameHostImpl* render_frame_host =
RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
- if (render_frame_host) {
- NavigationHandleImpl* navigation_handle =
- render_frame_host->navigation_handle();
- if (navigation_handle) {
- RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
- GURL new_validated_url = new_url;
- rph->FilterURL(false, &new_validated_url);
- result = navigation_handle->WillRedirectRequest(
- new_validated_url, new_method_is_post, new_referrer_url,
- new_is_external_protocol);
- }
+ if (!render_frame_host) {
+ SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED);
+ return;
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback, result));
+
+ NavigationHandleImpl* navigation_handle =
+ render_frame_host->navigation_handle();
+ if (!navigation_handle) {
+ SendCheckResultToIOThread(callback, NavigationThrottle::PROCEED);
+ return;
+ }
+
+ GURL new_validated_url(new_url);
+ RenderProcessHost::FromID(render_process_id)
+ ->FilterURL(false, &new_validated_url);
+ navigation_handle->WillRedirectRequest(
+ new_validated_url, new_method_is_post, new_referrer_url,
+ new_is_external_protocol, headers,
+ base::Bind(&SendCheckResultToIOThread, callback));
}
+
+void WillProcessResponseOnUIThread(
+ int render_process_id,
+ int render_frame_host_id,
+ scoped_refptr<net::HttpResponseHeaders> headers) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHostImpl* render_frame_host =
+ RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
+ if (!render_frame_host)
+ return;
+
+ NavigationHandleImpl* navigation_handle =
+ render_frame_host->navigation_handle();
+ if (!navigation_handle)
+ return;
+
+ navigation_handle->ReadyToCommitNavigation(render_frame_host, headers);
+}
+
} // namespace
NavigationResourceThrottle::NavigationResourceThrottle(net::URLRequest* request)
@@ -82,6 +118,7 @@ NavigationResourceThrottle::NavigationResourceThrottle(net::URLRequest* request)
NavigationResourceThrottle::~NavigationResourceThrottle() {}
void NavigationResourceThrottle::WillStartRequest(bool* defer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
if (!info)
return;
@@ -112,6 +149,7 @@ void NavigationResourceThrottle::WillStartRequest(bool* defer) {
void NavigationResourceThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info,
bool* defer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
if (!info)
return;
@@ -128,15 +166,50 @@ void NavigationResourceThrottle::WillRedirectRequest(
UIChecksPerformedCallback callback =
base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed,
weak_ptr_factory_.GetWeakPtr());
+
+ // Send the redirect info to the NavigationHandle on the UI thread.
+ // Note: to avoid threading issues, a copy of the HttpResponseHeaders is sent
+ // in lieu of the original.
+ scoped_refptr<net::HttpResponseHeaders> response_headers;
+ if (request_->response_headers()) {
+ response_headers = new net::HttpResponseHeaders(
+ request_->response_headers()->raw_headers());
+ }
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&CheckWillRedirectRequestOnUIThread, callback,
render_process_id, render_frame_id, redirect_info.new_url,
redirect_info.new_method == "POST",
- GURL(redirect_info.new_referrer), new_is_external_protocol));
+ GURL(redirect_info.new_referrer), new_is_external_protocol,
+ response_headers));
*defer = true;
}
+void NavigationResourceThrottle::WillProcessResponse(bool* defer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
+ if (!info)
+ return;
+
+ int render_process_id, render_frame_id;
+ if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
+ return;
+
+ // Send a copy of the response headers to the NavigationHandle on the UI
+ // thread.
+ scoped_refptr<net::HttpResponseHeaders> response_headers;
+ if (request_->response_headers()) {
+ response_headers = new net::HttpResponseHeaders(
+ request_->response_headers()->raw_headers());
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&WillProcessResponseOnUIThread, render_process_id,
+ render_frame_id, response_headers));
+}
+
const char* NavigationResourceThrottle::GetNameForLogging() const {
return "NavigationResourceThrottle";
}
@@ -146,6 +219,8 @@ void NavigationResourceThrottle::OnUIChecksPerformed(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (result == NavigationThrottle::CANCEL_AND_IGNORE) {
controller()->CancelAndIgnore();
+ } else if (result == NavigationThrottle::CANCEL) {
+ controller()->Cancel();
} else {
controller()->Resume();
}
diff --git a/chromium/content/browser/loader/navigation_resource_throttle.h b/chromium/content/browser/loader/navigation_resource_throttle.h
index e46b59d0669..6357b20aad4 100644
--- a/chromium/content/browser/loader/navigation_resource_throttle.h
+++ b/chromium/content/browser/loader/navigation_resource_throttle.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_
#define CONTENT_BROWSER_LOADER_NAVIGATION_RESOURCE_THROTTLE_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/resource_throttle.h"
@@ -28,6 +28,7 @@ class NavigationResourceThrottle : public ResourceThrottle {
void WillStartRequest(bool* defer) override;
void WillRedirectRequest(const net::RedirectInfo& redirect_info,
bool* defer) override;
+ void WillProcessResponse(bool* defer) override;
const char* GetNameForLogging() const override;
private:
diff --git a/chromium/content/browser/loader/navigation_url_loader.cc b/chromium/content/browser/loader/navigation_url_loader.cc
index c1513dc4a5d..e2507650a81 100644
--- a/chromium/content/browser/loader/navigation_url_loader.cc
+++ b/chromium/content/browser/loader/navigation_url_loader.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/navigation_url_loader.h"
+#include <utility>
+
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_url_loader_factory.h"
#include "content/browser/loader/navigation_url_loader_impl.h"
@@ -15,13 +17,15 @@ static NavigationURLLoaderFactory* g_factory = nullptr;
scoped_ptr<NavigationURLLoader> NavigationURLLoader::Create(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate) {
if (g_factory) {
- return g_factory->CreateLoader(browser_context, request_info.Pass(),
- delegate);
+ return g_factory->CreateLoader(browser_context, std::move(request_info),
+ service_worker_handle, delegate);
}
- return scoped_ptr<NavigationURLLoader>(new NavigationURLLoaderImpl(
- browser_context, request_info.Pass(), delegate));
+ return scoped_ptr<NavigationURLLoader>(
+ new NavigationURLLoaderImpl(browser_context, std::move(request_info),
+ service_worker_handle, delegate));
}
void NavigationURLLoader::SetFactoryForTesting(
diff --git a/chromium/content/browser/loader/navigation_url_loader.h b/chromium/content/browser/loader/navigation_url_loader.h
index 89553f6e30f..0ba836a8d67 100644
--- a/chromium/content/browser/loader/navigation_url_loader.h
+++ b/chromium/content/browser/loader/navigation_url_loader.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_H_
#define CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_H_
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
@@ -15,6 +14,7 @@ namespace content {
class BrowserContext;
class NavigationURLLoaderDelegate;
class NavigationURLLoaderFactory;
+class ServiceWorkerNavigationHandle;
struct CommonNavigationParams;
struct NavigationRequestInfo;
@@ -35,6 +35,7 @@ class CONTENT_EXPORT NavigationURLLoader {
static scoped_ptr<NavigationURLLoader> Create(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate);
// For testing purposes; sets the factory for use in testing.
diff --git a/chromium/content/browser/loader/navigation_url_loader_factory.h b/chromium/content/browser/loader/navigation_url_loader_factory.h
index 770644e0519..a2fd37136a7 100644
--- a/chromium/content/browser/loader/navigation_url_loader_factory.h
+++ b/chromium/content/browser/loader/navigation_url_loader_factory.h
@@ -18,6 +18,7 @@ class NavigationURLLoaderFactory {
virtual scoped_ptr<NavigationURLLoader> CreateLoader(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate) = 0;
protected:
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.cc b/chromium/content/browser/loader/navigation_url_loader_impl.cc
index 7cbd9112d6d..1f95ce3165f 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl.cc
@@ -4,11 +4,15 @@
#include "content/browser/loader/navigation_url_loader_impl.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/location.h"
+#include "base/trace_event/trace_event.h"
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_url_loader_delegate.h"
#include "content/browser/loader/navigation_url_loader_impl_core.h"
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/stream_handle.h"
@@ -18,17 +22,28 @@ namespace content {
NavigationURLLoaderImpl::NavigationURLLoaderImpl(
BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate)
- : delegate_(delegate),
- weak_factory_(this) {
+ : delegate_(delegate), weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
core_ = new NavigationURLLoaderImplCore(weak_factory_.GetWeakPtr());
+
+ // TODO(carlosk): extend this trace to support non-PlzNavigate navigations.
+ // For the trace below we're using the NavigationURLLoaderImplCore as the
+ // async trace id, |navigation_start| as the timestamp and reporting the
+ // FrameTreeNode id as a parameter.
+ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
+ "navigation", "Navigation timeToResponseStarted", core_,
+ request_info->common_params.navigation_start.ToInternalValue(),
+ "FrameTreeNode id", request_info->frame_tree_node_id);
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core =
+ service_worker_handle ? service_worker_handle->core() : nullptr;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&NavigationURLLoaderImplCore::Start, base::Unretained(core_),
browser_context->GetResourceContext(),
- base::Passed(&request_info)));
+ service_worker_handle_core, base::Passed(&request_info)));
}
NavigationURLLoaderImpl::~NavigationURLLoaderImpl() {
@@ -60,7 +75,7 @@ void NavigationURLLoaderImpl::NotifyResponseStarted(
scoped_ptr<StreamHandle> body) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- delegate_->OnResponseStarted(response, body.Pass());
+ delegate_->OnResponseStarted(response, std::move(body));
}
void NavigationURLLoaderImpl::NotifyRequestFailed(bool in_cache,
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.h b/chromium/content/browser/loader/navigation_url_loader_impl.h
index 6a88fc8650c..5c7fcd0d2b0 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl.h
+++ b/chromium/content/browser/loader/navigation_url_loader_impl.h
@@ -19,6 +19,7 @@ struct RedirectInfo;
namespace content {
class NavigationURLLoaderImplCore;
+class ServiceWorkerNavigationHandle;
class StreamHandle;
struct ResourceResponse;
@@ -27,6 +28,7 @@ class NavigationURLLoaderImpl : public NavigationURLLoader {
// The caller is responsible for ensuring that |delegate| outlives the loader.
NavigationURLLoaderImpl(BrowserContext* browser_context,
scoped_ptr<NavigationRequestInfo> request_info,
+ ServiceWorkerNavigationHandle* service_worker_handle,
NavigationURLLoaderDelegate* delegate);
~NavigationURLLoaderImpl() override;
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl_core.cc b/chromium/content/browser/loader/navigation_url_loader_impl_core.cc
index 7fe69513040..bd7ef98f8ea 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl_core.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -10,6 +10,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_resource_handler.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/common/navigation_params.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/stream_handle.h"
@@ -37,6 +38,7 @@ NavigationURLLoaderImplCore::~NavigationURLLoaderImplCore() {
void NavigationURLLoaderImplCore::Start(
ResourceContext* resource_context,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core,
scoped_ptr<NavigationRequestInfo> request_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -45,8 +47,11 @@ void NavigationURLLoaderImplCore::Start(
base::Bind(&NavigationURLLoaderImpl::NotifyRequestStarted, loader_,
base::TimeTicks::Now()));
- ResourceDispatcherHostImpl::Get()->BeginNavigationRequest(
- resource_context, *request_info, this);
+ // The ResourceDispatcherHostImpl can be null in unit tests.
+ if (ResourceDispatcherHostImpl::Get()) {
+ ResourceDispatcherHostImpl::Get()->BeginNavigationRequest(
+ resource_context, *request_info, this, service_worker_handle_core);
+ }
}
void NavigationURLLoaderImplCore::FollowRedirect() {
@@ -56,11 +61,11 @@ void NavigationURLLoaderImplCore::FollowRedirect() {
resource_handler_->FollowRedirect();
}
-
void NavigationURLLoaderImplCore::NotifyRequestRedirected(
const net::RedirectInfo& redirect_info,
ResourceResponse* response) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT_ASYNC_END0("navigation", "Navigation redirectDelay", this);
// Make a copy of the ResourceResponse before it is passed to another thread.
//
@@ -71,12 +76,22 @@ void NavigationURLLoaderImplCore::NotifyRequestRedirected(
BrowserThread::UI, FROM_HERE,
base::Bind(&NavigationURLLoaderImpl::NotifyRequestRedirected, loader_,
redirect_info, response->DeepCopy()));
+
+ // TODO(carlosk): extend this trace to support non-PlzNavigate navigations.
+ // For the trace below we're using the NavigationURLLoaderImplCore as the
+ // async trace id and reporting the new redirect URL as a parameter.
+ TRACE_EVENT_ASYNC_BEGIN2("navigation", "Navigation redirectDelay", this,
+ "&NavigationURLLoaderImplCore", this, "New URL",
+ redirect_info.new_url.spec());
}
void NavigationURLLoaderImplCore::NotifyResponseStarted(
ResourceResponse* response,
scoped_ptr<StreamHandle> body) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT_ASYNC_END0("navigation", "Navigation redirectDelay", this);
+ TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
+ "&NavigationURLLoaderImplCore", this, "success", true);
// If, by the time the task reaches the UI thread, |loader_| has already been
// destroyed, NotifyResponseStarted will not run. |body| will be destructed
@@ -96,6 +111,10 @@ void NavigationURLLoaderImplCore::NotifyResponseStarted(
void NavigationURLLoaderImplCore::NotifyRequestFailed(bool in_cache,
int net_error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT_ASYNC_END0("navigation", "Navigation redirectDelay", this);
+ TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
+ "&NavigationURLLoaderImplCore", this, "success",
+ false);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl_core.h b/chromium/content/browser/loader/navigation_url_loader_impl_core.h
index 8a93469c93b..b12629d92f2 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl_core.h
+++ b/chromium/content/browser/loader/navigation_url_loader_impl_core.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_IMPL_CORE_H_
#define CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_IMPL_CORE_H_
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -23,6 +22,7 @@ class NavigationResourceHandler;
class ResourceContext;
class ResourceHandler;
class ResourceRequestBody;
+class ServiceWorkerNavigationHandleCore;
class StreamHandle;
struct ResourceResponse;
@@ -40,6 +40,7 @@ class NavigationURLLoaderImplCore {
// Starts the request.
void Start(ResourceContext* resource_context,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core,
scoped_ptr<NavigationRequestInfo> request_info);
// Follows the current pending redirect.
diff --git a/chromium/content/browser/loader/navigation_url_loader_unittest.cc b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
index 0a4e26b6f91..efee272495d 100644
--- a/chromium/content/browser/loader/navigation_url_loader_unittest.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -34,6 +36,7 @@
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
namespace content {
@@ -109,7 +112,7 @@ class TestNavigationURLLoaderDelegate : public NavigationURLLoaderDelegate {
void OnResponseStarted(const scoped_refptr<ResourceResponse>& response,
scoped_ptr<StreamHandle> body) override {
response_ = response;
- body_ = body.Pass();
+ body_ = std::move(body);
ASSERT_TRUE(response_started_);
response_started_->Quit();
}
@@ -178,16 +181,17 @@ class NavigationURLLoaderTest : public testing::Test {
scoped_ptr<NavigationURLLoader> MakeTestLoader(
const GURL& url,
NavigationURLLoaderDelegate* delegate) {
- BeginNavigationParams begin_params(
- "GET", std::string(), net::LOAD_NORMAL, false);
+ BeginNavigationParams begin_params("GET", std::string(), net::LOAD_NORMAL,
+ false, false,
+ REQUEST_CONTEXT_TYPE_LOCATION);
CommonNavigationParams common_params;
common_params.url = url;
- scoped_ptr<NavigationRequestInfo> request_info(
- new NavigationRequestInfo(common_params, begin_params, url, true, false,
- -1, scoped_refptr<ResourceRequestBody>()));
+ scoped_ptr<NavigationRequestInfo> request_info(new NavigationRequestInfo(
+ common_params, begin_params, url, url::Origin(url), true, false, -1,
+ scoped_refptr<ResourceRequestBody>()));
- return NavigationURLLoader::Create(browser_context_.get(),
- request_info.Pass(), delegate);
+ return NavigationURLLoader::Create(
+ browser_context_.get(), std::move(request_info), nullptr, delegate);
}
// Helper function for fetching the body of a URL to a string.
diff --git a/chromium/content/browser/loader/power_save_block_resource_throttle.cc b/chromium/content/browser/loader/power_save_block_resource_throttle.cc
index 42e0b0e46d8..76afe12de13 100644
--- a/chromium/content/browser/loader/power_save_block_resource_throttle.cc
+++ b/chromium/content/browser/loader/power_save_block_resource_throttle.cc
@@ -14,8 +14,9 @@ const int kPowerSaveBlockDelaySeconds = 30;
} // namespace
-PowerSaveBlockResourceThrottle::PowerSaveBlockResourceThrottle() {
-}
+PowerSaveBlockResourceThrottle::PowerSaveBlockResourceThrottle(
+ const std::string& host)
+ : host_(host) {}
PowerSaveBlockResourceThrottle::~PowerSaveBlockResourceThrottle() {
}
@@ -41,7 +42,7 @@ const char* PowerSaveBlockResourceThrottle::GetNameForLogging() const {
void PowerSaveBlockResourceThrottle::ActivatePowerSaveBlocker() {
power_save_blocker_ = PowerSaveBlocker::Create(
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
- PowerSaveBlocker::kReasonOther, "Uploading data");
+ PowerSaveBlocker::kReasonOther, "Uploading data to " + host_);
}
} // namespace content
diff --git a/chromium/content/browser/loader/power_save_block_resource_throttle.h b/chromium/content/browser/loader/power_save_block_resource_throttle.h
index 0d0c0803bfd..4c678421a05 100644
--- a/chromium/content/browser/loader/power_save_block_resource_throttle.h
+++ b/chromium/content/browser/loader/power_save_block_resource_throttle.h
@@ -5,8 +5,10 @@
#ifndef CONTENT_BROWSER_LOADER_POWER_SAVE_BLOCK_RESOURCE_THROTTLE_H_
#define CONTENT_BROWSER_LOADER_POWER_SAVE_BLOCK_RESOURCE_THROTTLE_H_
-#include "base/basictypes.h"
+#include <string>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
#include "content/public/browser/resource_throttle.h"
@@ -18,7 +20,7 @@ class PowerSaveBlocker;
// This ResourceThrottle blocks power save until large upload request finishes.
class PowerSaveBlockResourceThrottle : public ResourceThrottle {
public:
- PowerSaveBlockResourceThrottle();
+ explicit PowerSaveBlockResourceThrottle(const std::string& host);
~PowerSaveBlockResourceThrottle() override;
// ResourceThrottle overrides:
@@ -29,6 +31,7 @@ class PowerSaveBlockResourceThrottle : public ResourceThrottle {
private:
void ActivatePowerSaveBlocker();
+ const std::string host_;
base::OneShotTimer timer_;
scoped_ptr<PowerSaveBlocker> power_save_blocker_;
diff --git a/chromium/content/browser/loader/redirect_to_file_resource_handler.cc b/chromium/content/browser/loader/redirect_to_file_resource_handler.cc
index 12fd7d38e54..670b3343d30 100644
--- a/chromium/content/browser/loader/redirect_to_file_resource_handler.cc
+++ b/chromium/content/browser/loader/redirect_to_file_resource_handler.cc
@@ -4,8 +4,11 @@
#include "content/browser/loader/redirect_to_file_resource_handler.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/loader/temporary_file_stream.h"
@@ -61,7 +64,7 @@ class RedirectToFileResourceHandler::Writer {
scoped_ptr<net::FileStream> file_stream,
ShareableFileReference* deletable_file)
: handler_(handler),
- file_stream_(file_stream.Pass()),
+ file_stream_(std::move(file_stream)),
is_writing_(false),
deletable_file_(deletable_file) {
DCHECK(!deletable_file_->path().empty());
@@ -129,7 +132,7 @@ class RedirectToFileResourceHandler::Writer {
RedirectToFileResourceHandler::RedirectToFileResourceHandler(
scoped_ptr<ResourceHandler> next_handler,
net::URLRequest* request)
- : LayeredResourceHandler(request, next_handler.Pass()),
+ : LayeredResourceHandler(request, std::move(next_handler)),
buf_(new net::GrowableIOBuffer()),
buf_write_pending_(false),
write_cursor_(0),
@@ -137,8 +140,7 @@ RedirectToFileResourceHandler::RedirectToFileResourceHandler(
next_buffer_size_(kInitialReadBufSize),
did_defer_(false),
completed_during_write_(false),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
RedirectToFileResourceHandler::~RedirectToFileResourceHandler() {
// Orphan the writer to asynchronously close and release the temporary file.
@@ -249,7 +251,7 @@ void RedirectToFileResourceHandler::DidCreateTemporaryFile(
return;
}
- writer_ = new Writer(this, file_stream.Pass(), deletable_file);
+ writer_ = new Writer(this, std::move(file_stream), deletable_file);
// Resume the request.
DCHECK(did_defer_);
diff --git a/chromium/content/browser/loader/redirect_to_file_resource_handler.h b/chromium/content/browser/loader/redirect_to_file_resource_handler.h
index 1778921e370..cd4d60dc058 100644
--- a/chromium/content/browser/loader/redirect_to_file_resource_handler.h
+++ b/chromium/content/browser/loader/redirect_to_file_resource_handler.h
@@ -5,11 +5,11 @@
#ifndef CONTENT_BROWSER_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/content/browser/loader/resource_buffer.h b/chromium/content/browser/loader/resource_buffer.h
index 0908edbc083..e323bf19a41 100644
--- a/chromium/content/browser/loader/resource_buffer.h
+++ b/chromium/content/browser/loader/resource_buffer.h
@@ -7,7 +7,7 @@
#include <queue>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc b/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc
index b612d302df5..bad9b869c9f 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc
@@ -2,15 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/public/browser/resource_dispatcher_host.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/web_contents.h"
@@ -18,6 +26,7 @@
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_content_browser_client.h"
@@ -28,6 +37,8 @@
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/test/url_request/url_request_mock_http_job.h"
+#include "net/url_request/url_request.h"
+#include "url/gurl.h"
using base::ASCIIToUTF16;
@@ -57,11 +68,6 @@ class ResourceDispatcherHostBrowserTest : public ContentBrowserTest,
got_downloads_ = !!manager->InProgressCount();
}
- GURL GetMockURL(const std::string& file) {
- return net::URLRequestMockHTTPJob::GetMockUrl(
- base::FilePath().AppendASCII(file));
- }
-
void CheckTitleTest(const GURL& url,
const std::string& expected_title) {
base::string16 expected_title16(ASCIIToUTF16(expected_title));
@@ -98,7 +104,7 @@ class ResourceDispatcherHostBrowserTest : public ContentBrowserTest,
// Test title for content created by javascript window.open().
// See http://crbug.com/5988
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle1) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/dynamic1.html"));
base::string16 title;
@@ -111,7 +117,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle1) {
// Test title for content created by javascript window.open().
// See http://crbug.com/5988
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle2) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/dynamic2.html"));
base::string16 title;
@@ -123,26 +129,29 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle2) {
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
SniffHTMLWithNoContentType) {
- CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
- "Content Sniffer Test 0");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test0.html"),
+ "Content Sniffer Test 0");
}
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
RespectNoSniffDirective) {
- CheckTitleTest(GetMockURL("nosniff-test.html"),
+ CheckTitleTest(net::URLRequestMockHTTPJob::GetMockUrl("nosniff-test.html"),
"mock.http/nosniff-test.html");
}
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
DoNotSniffHTMLFromTextPlain) {
- CheckTitleTest(GetMockURL("content-sniffer-test1.html"),
- "mock.http/content-sniffer-test1.html");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test1.html"),
+ "mock.http/content-sniffer-test1.html");
}
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
DoNotSniffHTMLFromImageGIF) {
- CheckTitleTest(GetMockURL("content-sniffer-test2.html"),
- "mock.http/content-sniffer-test2.html");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test2.html"),
+ "mock.http/content-sniffer-test2.html");
}
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
@@ -150,25 +159,30 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
// Make sure no downloads start.
BrowserContext::GetDownloadManager(
shell()->web_contents()->GetBrowserContext())->AddObserver(this);
- CheckTitleTest(GetMockURL("content-sniffer-test3.html"),
- "Content Sniffer Test 3");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test3.html"),
+ "Content Sniffer Test 3");
EXPECT_EQ(1u, Shell::windows().size());
ASSERT_FALSE(got_downloads());
}
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
ContentDispositionEmpty) {
- CheckTitleTest(GetMockURL("content-disposition-empty.html"), "success");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-disposition-empty.html"),
+ "success");
}
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
ContentDispositionInline) {
- CheckTitleTest(GetMockURL("content-disposition-inline.html"), "success");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-disposition-inline.html"),
+ "success");
}
// Test for bug #1091358.
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, SyncXMLHttpRequest) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
NavigateToURL(
shell(), embedded_test_server()->GetURL("/sync_xmlhttprequest.html"));
@@ -184,7 +198,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, SyncXMLHttpRequest) {
// If this flakes, use http://crbug.com/62776.
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
SyncXMLHttpRequest_Disallowed) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
NavigateToURL(
shell(),
embedded_test_server()->GetURL("/sync_xmlhttprequest_disallowed.html"));
@@ -210,7 +224,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
#endif
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
MAYBE_SyncXMLHttpRequest_DuringUnload) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
BrowserContext::GetDownloadManager(
shell()->web_contents()->GetBrowserContext())->AddObserver(this);
@@ -230,15 +244,16 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
// Tests that onunload is run for cross-site requests. (Bug 1114994)
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
DISABLED_CrossSiteOnunloadCookie) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
CheckTitleTest(url, "set cookie on unload");
// Navigate to a new cross-site page, to dispatch unload event and set the
// cookie.
- CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
- "Content Sniffer Test 0");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test0.html"),
+ "Content Sniffer Test 0");
// Check that the cookie was set.
EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
@@ -249,7 +264,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
// without network loads (e.g., about:blank, data URLs).
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
DISABLED_CrossSiteImmediateLoadOnunloadCookie) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
CheckTitleTest(url, "set cookie on unload");
@@ -275,7 +290,7 @@ scoped_ptr<net::test_server::HttpResponse> NoContentResponseHandler(
scoped_ptr<net::test_server::BasicHttpResponse> http_response(
new net::test_server::BasicHttpResponse);
http_response->set_code(net::HTTP_NO_CONTENT);
- return http_response.Pass();
+ return std::move(http_response);
}
} // namespace
@@ -284,7 +299,7 @@ scoped_ptr<net::test_server::HttpResponse> NoContentResponseHandler(
// If this flakes use http://crbug.com/80596.
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
CrossSiteNoUnloadOn204) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
// Start with a URL that sets a cookie in its unload handler.
GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
@@ -328,8 +343,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
// Navigate to a new cross-site page. The browser should not wait around for
// the old renderer's on{before}unload handlers to run.
- CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
- "Content Sniffer Test 0");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test0.html"),
+ "Content Sniffer Test 0");
}
// Tests that cross-site navigations work when the new page does not go through
@@ -337,8 +353,9 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
CrossSiteNavigationNonBuffered) {
// Start with an HTTP page.
- CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
- "Content Sniffer Test 0");
+ CheckTitleTest(
+ net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test0.html"),
+ "Content Sniffer Test 0");
// Now load a file:// page, which does not use the BufferedEventHandler.
// Make sure that the page loads and displays a title, and doesn't get stuck.
@@ -352,7 +369,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
// away from the link doctor page. (Bug 1235537)
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
DISABLED_CrossSiteNavigationErrorPage) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/onunload_cookie.html"));
CheckTitleTest(url, "set cookie on unload");
@@ -397,7 +414,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
CrossSiteNavigationErrorPage2) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/title2.html"));
CheckTitleTest(url, "Title Of Awesomeness");
@@ -428,7 +445,8 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
//
// If the redirect in #2 were not blocked, we'd also see a request
// for http://mock.http:4000/title2.html, and the title would be different.
- CheckTitleTest(GetMockURL("cross-origin-redirect-blocked.html"),
+ CheckTitleTest(net::URLRequestMockHTTPJob::GetMockUrl(
+ "cross-origin-redirect-blocked.html"),
"Title Of More Awesomeness");
}
@@ -459,7 +477,7 @@ scoped_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
http_response->set_code(net::HTTP_FOUND);
http_response->AddCustomHeader(
"Location", request.relative_url.substr(request_path.length()));
- return http_response.Pass();
+ return std::move(http_response);
}
} // namespace
@@ -467,7 +485,7 @@ scoped_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
// Test that we update the cookie policy URLs correctly when transferring
// navigations.
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CookiePolicy) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
embedded_test_server()->RegisterRequestHandler(
base::Bind(&HandleRedirectRequest, "/redirect?"));
@@ -511,7 +529,7 @@ class PageTransitionResourceDispatcherHostDelegate
// when encountering a meta refresh tag.
IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
PageTransitionClientRedirect) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
PageTransitionResourceDispatcherHostDelegate delegate(
embedded_test_server()->GetURL("/title1.html"));
@@ -526,4 +544,215 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
delegate.page_transition() & ui::PAGE_TRANSITION_CLIENT_REDIRECT);
}
+namespace {
+
+// Checks whether the given urls are requested, and that IsUsingLofi() returns
+// the appropriate value when the Lo-Fi state is set.
+class LoFiModeResourceDispatcherHostDelegate
+ : public ResourceDispatcherHostDelegate {
+ public:
+ LoFiModeResourceDispatcherHostDelegate(const GURL& main_frame_url,
+ const GURL& subresource_url,
+ const GURL& iframe_url)
+ : main_frame_url_(main_frame_url),
+ subresource_url_(subresource_url),
+ iframe_url_(iframe_url),
+ main_frame_url_seen_(false),
+ subresource_url_seen_(false),
+ iframe_url_seen_(false),
+ use_lofi_(false),
+ should_enable_lofi_mode_called_(false) {}
+
+ ~LoFiModeResourceDispatcherHostDelegate() override {}
+
+ // ResourceDispatcherHostDelegate implementation:
+ void RequestBeginning(net::URLRequest* request,
+ ResourceContext* resource_context,
+ AppCacheService* appcache_service,
+ ResourceType resource_type,
+ ScopedVector<ResourceThrottle>* throttles) override {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
+ if (request->url() != main_frame_url_ && request->url() != subresource_url_
+ && request->url() != iframe_url_)
+ return;
+ if (request->url() == main_frame_url_) {
+ EXPECT_FALSE(main_frame_url_seen_);
+ main_frame_url_seen_ = true;
+ } else if (request->url() == subresource_url_) {
+ EXPECT_TRUE(main_frame_url_seen_);
+ EXPECT_FALSE(subresource_url_seen_);
+ subresource_url_seen_ = true;
+ } else if (request->url() == iframe_url_) {
+ EXPECT_TRUE(main_frame_url_seen_);
+ EXPECT_FALSE(iframe_url_seen_);
+ iframe_url_seen_ = true;
+ }
+ EXPECT_EQ(use_lofi_, info->IsUsingLoFi());
+ }
+
+ void SetDelegate() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ResourceDispatcherHost::Get()->SetDelegate(this);
+ }
+
+ bool ShouldEnableLoFiMode(
+ const net::URLRequest& request,
+ content::ResourceContext* resource_context) override {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ EXPECT_FALSE(should_enable_lofi_mode_called_);
+ should_enable_lofi_mode_called_ = true;
+ EXPECT_EQ(main_frame_url_, request.url());
+ return use_lofi_;
+ }
+
+ void Reset(bool use_lofi) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ main_frame_url_seen_ = false;
+ subresource_url_seen_ = false;
+ iframe_url_seen_ = false;
+ use_lofi_ = use_lofi;
+ should_enable_lofi_mode_called_ = false;
+ }
+
+ void CheckResourcesRequested(bool should_enable_lofi_mode_called) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ EXPECT_EQ(should_enable_lofi_mode_called, should_enable_lofi_mode_called_);
+ EXPECT_TRUE(main_frame_url_seen_);
+ EXPECT_TRUE(subresource_url_seen_);
+ EXPECT_TRUE(iframe_url_seen_);
+ }
+
+ private:
+ const GURL main_frame_url_;
+ const GURL subresource_url_;
+ const GURL iframe_url_;
+
+ bool main_frame_url_seen_;
+ bool subresource_url_seen_;
+ bool iframe_url_seen_;
+ bool use_lofi_;
+ bool should_enable_lofi_mode_called_;
+
+ DISALLOW_COPY_AND_ASSIGN(LoFiModeResourceDispatcherHostDelegate);
+};
+
+} // namespace
+
+class LoFiResourceDispatcherHostBrowserTest : public ContentBrowserTest {
+ public:
+ ~LoFiResourceDispatcherHostBrowserTest() override {}
+
+ protected:
+ void SetUpOnMainThread() override {
+ ContentBrowserTest::SetUpOnMainThread();
+
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ delegate_.reset(new LoFiModeResourceDispatcherHostDelegate(
+ embedded_test_server()->GetURL("/page_with_iframe.html"),
+ embedded_test_server()->GetURL("/image.jpg"),
+ embedded_test_server()->GetURL("/title1.html")));
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&LoFiModeResourceDispatcherHostDelegate::SetDelegate,
+ base::Unretained(delegate_.get())));
+ }
+
+ void Reset(bool use_lofi) {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&LoFiModeResourceDispatcherHostDelegate::Reset,
+ base::Unretained(delegate_.get()), use_lofi));
+ }
+
+ void CheckResourcesRequested(
+ bool should_enable_lofi_mode_called) {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(
+ &LoFiModeResourceDispatcherHostDelegate::CheckResourcesRequested,
+ base::Unretained(delegate_.get()), should_enable_lofi_mode_called));
+ }
+
+ private:
+ scoped_ptr<LoFiModeResourceDispatcherHostDelegate> delegate_;
+};
+
+// Test that navigating with ShouldEnableLoFiMode returning true fetches the
+// resources with LOFI_ON.
+IN_PROC_BROWSER_TEST_F(LoFiResourceDispatcherHostBrowserTest,
+ ShouldEnableLoFiModeOn) {
+ // Navigate with ShouldEnableLoFiMode returning true.
+ Reset(true);
+ NavigateToURLBlockUntilNavigationsComplete(
+ shell(), embedded_test_server()->GetURL("/page_with_iframe.html"), 1);
+ CheckResourcesRequested(true);
+}
+
+// Test that navigating with ShouldEnableLoFiMode returning false fetches the
+// resources with LOFI_OFF.
+IN_PROC_BROWSER_TEST_F(LoFiResourceDispatcherHostBrowserTest,
+ ShouldEnableLoFiModeOff) {
+ // Navigate with ShouldEnableLoFiMode returning false.
+ NavigateToURLBlockUntilNavigationsComplete(
+ shell(), embedded_test_server()->GetURL("/page_with_iframe.html"), 1);
+ CheckResourcesRequested(true);
+}
+
+// Test that reloading calls ShouldEnableLoFiMode again and changes the Lo-Fi
+// state.
+IN_PROC_BROWSER_TEST_F(LoFiResourceDispatcherHostBrowserTest,
+ ShouldEnableLoFiModeReload) {
+ // Navigate with ShouldEnableLoFiMode returning false.
+ NavigateToURLBlockUntilNavigationsComplete(
+ shell(), embedded_test_server()->GetURL("/page_with_iframe.html"), 1);
+ CheckResourcesRequested(true);
+
+ // Reload. ShouldEnableLoFiMode should be called.
+ Reset(true);
+ ReloadBlockUntilNavigationsComplete(shell(), 1);
+ CheckResourcesRequested(true);
+}
+
+// Test that navigating backwards calls ShouldEnableLoFiMode again and changes
+// the Lo-Fi state.
+IN_PROC_BROWSER_TEST_F(LoFiResourceDispatcherHostBrowserTest,
+ ShouldEnableLoFiModeNavigateBackThenForward) {
+ // Navigate with ShouldEnableLoFiMode returning false.
+ NavigateToURLBlockUntilNavigationsComplete(
+ shell(), embedded_test_server()->GetURL("/page_with_iframe.html"), 1);
+ CheckResourcesRequested(true);
+
+ // Go to a different page.
+ NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
+
+ // Go back with ShouldEnableLoFiMode returning true.
+ Reset(true);
+ TestNavigationObserver tab_observer(shell()->web_contents(), 1);
+ shell()->GoBackOrForward(-1);
+ tab_observer.Wait();
+ CheckResourcesRequested(true);
+}
+
+// Test that reloading with Lo-Fi disabled doesn't call ShouldEnableLoFiMode and
+// already has LOFI_OFF.
+IN_PROC_BROWSER_TEST_F(LoFiResourceDispatcherHostBrowserTest,
+ ShouldEnableLoFiModeReloadDisableLoFi) {
+ // Navigate with ShouldEnableLoFiMode returning true.
+ Reset(true);
+ NavigateToURLBlockUntilNavigationsComplete(
+ shell(), embedded_test_server()->GetURL("/page_with_iframe.html"), 1);
+ CheckResourcesRequested(true);
+
+ // Reload with Lo-Fi disabled.
+ Reset(false);
+ TestNavigationObserver tab_observer(shell()->web_contents(), 1);
+ shell()->web_contents()->GetController().ReloadDisableLoFi(true);
+ tab_observer.Wait();
+ CheckResourcesRequested(false);
+}
+
} // namespace content
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
index 2d7512b63ae..529b9781866 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -6,8 +6,10 @@
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include <stddef.h>
#include <algorithm>
#include <set>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -16,13 +18,16 @@
#include "base/compiler_specific.h"
#include "base/debug/alias.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
+#include "base/strings/string_util.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/time/time.h"
#include "content/browser/appcache/appcache_interceptor.h"
@@ -37,6 +42,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/loader/async_resource_handler.h"
+#include "content/browser/loader/async_revalidation_manager.h"
#include "content/browser/loader/cross_site_resource_handler.h"
#include "content/browser/loader/detachable_resource_handler.h"
#include "content/browser/loader/mime_type_resource_handler.h"
@@ -54,6 +60,7 @@
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/resource_context_impl.h"
+#include "content/browser/service_worker/foreign_fetch_request_handler.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_context.h"
@@ -77,6 +84,7 @@
#include "content/public/browser/stream_handle.h"
#include "content/public/browser/stream_info.h"
#include "content/public/browser/user_metrics.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "ipc/ipc_message_macros.h"
@@ -202,6 +210,7 @@ bool IsDetachableResourceType(ResourceType type) {
switch (type) {
case RESOURCE_TYPE_PREFETCH:
case RESOURCE_TYPE_PING:
+ case RESOURCE_TYPE_CSP_REPORT:
return true;
default:
return false;
@@ -429,13 +438,33 @@ void LogResourceRequestTimeOnUI(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHostImpl* host =
RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
- if (host != NULL) {
+ if (host != nullptr) {
DCHECK(host->frame_tree_node()->IsMainFrame());
host->frame_tree_node()->navigator()->LogResourceRequestTime(
timestamp, url);
}
}
+bool IsUsingLoFi(LoFiState lofi_state,
+ ResourceDispatcherHostDelegate* delegate,
+ const net::URLRequest& request,
+ ResourceContext* resource_context) {
+ if (lofi_state == LOFI_UNSPECIFIED && delegate)
+ return delegate->ShouldEnableLoFiMode(request, resource_context);
+ return lofi_state == LOFI_ON;
+}
+
+// Record RAPPOR for aborted main frame loads. Separate into a fast and
+// slow bucket because a shocking number of aborts happen under 100ms.
+void RecordAbortRapporOnUI(const GURL& url,
+ base::TimeDelta request_loading_time) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (request_loading_time.InMilliseconds() < 100)
+ GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Fast", url);
+ else
+ GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Slow", url);
+}
+
} // namespace
// static
@@ -473,6 +502,24 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl()
base::Unretained(this)));
update_load_states_timer_.reset(new base::RepeatingTimer());
+
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ // This needs to be called to mark the trial as active, even if the result
+ // isn't used.
+ std::string stale_while_revalidate_trial_group =
+ base::FieldTrialList::FindFullName("StaleWhileRevalidate");
+ // stale-while-revalidate currently doesn't work with browser-side navigation.
+ // Only enable stale-while-revalidate if browser navigation is not enabled.
+ //
+ // TODO(ricea): Make stale-while-revalidate and browser-side navigation work
+ // together. Or disable stale-while-revalidate completely before browser-side
+ // navigation becomes the default. crbug.com/561610
+ if (!IsBrowserSideNavigationEnabled() &&
+ (base::StartsWith(stale_while_revalidate_trial_group, "Enabled",
+ base::CompareCase::SENSITIVE) ||
+ command_line->HasSwitch(switches::kEnableStaleWhileRevalidate))) {
+ async_revalidation_manager_.reset(new AsyncRevalidationManager);
+ }
}
ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() {
@@ -578,6 +625,13 @@ void ResourceDispatcherHostImpl::CancelRequestsForContext(
loaders_to_cancel.clear();
+ if (async_revalidation_manager_) {
+ // Cancelling async revalidations should not result in the creation of new
+ // requests. Do it before the CHECKs to ensure this does not happen.
+ async_revalidation_manager_->CancelAsyncRevalidationsForResourceContext(
+ context);
+ }
+
// Validate that no more requests for this context were added.
for (LoaderMap::const_iterator i = pending_loaders_.begin();
i != pending_loaders_.end(); ++i) {
@@ -607,7 +661,7 @@ DownloadInterruptReason ResourceDispatcherHostImpl::BeginDownload(
bool prefer_cache,
bool do_not_prompt_for_login,
scoped_ptr<DownloadSaveInfo> save_info,
- uint32 download_id,
+ uint32_t download_id,
const DownloadStartedCallback& started_callback) {
if (is_shutdown_)
return CallbackAndReturn(started_callback,
@@ -682,12 +736,11 @@ DownloadInterruptReason ResourceDispatcherHostImpl::BeginDownload(
// From this point forward, the |DownloadResourceHandler| is responsible for
// |started_callback|.
- scoped_ptr<ResourceHandler> handler(
- CreateResourceHandlerForDownload(request.get(), is_content_initiated,
- true, download_id, save_info.Pass(),
- started_callback));
+ scoped_ptr<ResourceHandler> handler(CreateResourceHandlerForDownload(
+ request.get(), is_content_initiated, true, download_id,
+ std::move(save_info), started_callback));
- BeginRequestInternal(request.Pass(), handler.Pass());
+ BeginRequestInternal(std::move(request), std::move(handler));
return DOWNLOAD_INTERRUPT_REASON_NONE;
}
@@ -715,14 +768,14 @@ ResourceDispatcherHostImpl::CreateResourceHandlerForDownload(
net::URLRequest* request,
bool is_content_initiated,
bool must_download,
- uint32 id,
+ uint32_t id,
scoped_ptr<DownloadSaveInfo> save_info,
const DownloadUrlParameters::OnStartedCallback& started_cb) {
- scoped_ptr<ResourceHandler> handler(
- new DownloadResourceHandler(id, request, started_cb, save_info.Pass()));
+ scoped_ptr<ResourceHandler> handler(new DownloadResourceHandler(
+ id, request, started_cb, std::move(save_info)));
if (delegate_) {
- const ResourceRequestInfo* request_info(
- ResourceRequestInfo::ForRequest(request));
+ const ResourceRequestInfoImpl* request_info(
+ ResourceRequestInfoImpl::ForRequest(request));
ScopedVector<ResourceThrottle> throttles;
delegate_->DownloadStarting(
@@ -730,12 +783,11 @@ ResourceDispatcherHostImpl::CreateResourceHandlerForDownload(
request_info->GetRouteID(), request_info->GetRequestID(),
is_content_initiated, must_download, &throttles);
if (!throttles.empty()) {
- handler.reset(
- new ThrottlingResourceHandler(
- handler.Pass(), request, throttles.Pass()));
+ handler.reset(new ThrottlingResourceHandler(std::move(handler), request,
+ std::move(throttles)));
}
}
- return handler.Pass();
+ return handler;
}
scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::MaybeInterceptAsStream(
@@ -774,8 +826,8 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::MaybeInterceptAsStream(
stream_info->response_headers =
new net::HttpResponseHeaders(response->head.headers->raw_headers());
}
- delegate_->OnStreamCreated(request, stream_info.Pass());
- return handler.Pass();
+ delegate_->OnStreamCreated(request, std::move(stream_info));
+ return std::move(handler);
}
ResourceDispatcherHostLoginDelegate*
@@ -804,8 +856,8 @@ bool ResourceDispatcherHostImpl::HandleExternalProtocol(ResourceLoader* loader,
return false;
return delegate_->HandleExternalProtocol(
- url, info->GetChildID(), info->GetRouteID(), info->IsMainFrame(),
- info->GetPageTransition(), info->HasUserGesture());
+ url, info->GetChildID(), info->GetWebContentsGetterForRequest(),
+ info->IsMainFrame(), info->GetPageTransition(), info->HasUserGesture());
}
void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) {
@@ -826,6 +878,28 @@ void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader,
if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host))
return;
+ net::URLRequest* request = loader->request();
+ if (request->response_info().async_revalidation_required) {
+ // Async revalidation is only supported for the first redirect leg.
+ DCHECK_EQ(request->url_chain().size(), 1u);
+ DCHECK(async_revalidation_manager_);
+
+ async_revalidation_manager_->BeginAsyncRevalidation(*request,
+ scheduler_.get());
+ }
+
+ // Remove the LOAD_SUPPORT_ASYNC_REVALIDATION flag if it is present.
+ // It is difficult to create a URLRequest with the correct flags and headers
+ // for redirect legs other than the first one. Since stale-while-revalidate in
+ // combination with redirects isn't needed for experimental use, punt on it
+ // for now.
+ // TODO(ricea): Fix this before launching the feature.
+ if (request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION) {
+ int new_load_flags =
+ request->load_flags() & ~net::LOAD_SUPPORT_ASYNC_REVALIDATION;
+ request->SetLoadFlags(new_load_flags);
+ }
+
// Don't notify WebContents observers for requests known to be
// downloads; they aren't really associated with the Webcontents.
// Note that not all downloads are known before content sniffing.
@@ -854,6 +928,12 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) {
info->GetChildID(), info->GetRouteID());
}
+ if (request->response_info().async_revalidation_required) {
+ DCHECK(async_revalidation_manager_);
+ async_revalidation_manager_->BeginAsyncRevalidation(*request,
+ scheduler_.get());
+ }
+
int render_process_id, render_frame_host;
if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host))
return;
@@ -875,7 +955,7 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) {
}
void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
- ResourceRequestInfo* info = loader->GetRequestInfo();
+ ResourceRequestInfoImpl* info = loader->GetRequestInfo();
// Record final result of all resource loads.
if (info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME) {
@@ -895,8 +975,19 @@ void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
"Net.RequestTime2.Success", request_loading_time);
break;
case net::ERR_ABORTED:
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.SentBytes",
+ loader->request()->GetTotalSentBytes(), 1,
+ 50000000, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.ReceivedBytes",
+ loader->request()->GetTotalReceivedBytes(),
+ 1, 50000000, 50);
UMA_HISTOGRAM_LONG_TIMES(
"Net.RequestTime2.ErrAborted", request_loading_time);
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RecordAbortRapporOnUI, loader->request()->url(),
+ request_loading_time));
break;
case net::ERR_CONNECTION_RESET:
UMA_HISTOGRAM_LONG_TIMES(
@@ -1046,10 +1137,11 @@ void ResourceDispatcherHostImpl::OnRequestResource(
"477117 ResourceDispatcherHostImpl::OnRequestResource"));
// When logging time-to-network only care about main frame and non-transfer
// navigations.
+ // PlzNavigate: this log happens from NavigationRequest::OnRequestStarted
+ // instead.
if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME &&
request_data.transferred_request_request_id == -1 &&
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ !IsBrowserSideNavigationEnabled()) {
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -1105,8 +1197,8 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
// ResourceHandlers should always get state related to the request from the
// ResourceRequestInfo rather than caching it locally. This lets us update
// the info object when a transfer occurs.
- info->UpdateForTransfer(child_id, route_id, request_data.origin_pid,
- request_id, request_data.parent_render_frame_id,
+ info->UpdateForTransfer(child_id, route_id, request_data.render_frame_id,
+ request_data.origin_pid, request_id,
filter_->GetWeakPtr());
// Update maps that used the old IDs, if necessary. Some transfers in tests
@@ -1163,8 +1255,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
int child_id = filter_->child_id();
// PlzNavigate: reject invalid renderer main resource request.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
+ if (IsBrowserSideNavigationEnabled() &&
IsResourceTypeFrame(request_data.resource_type) &&
!request_data.url.SchemeIs(url::kBlobScheme)) {
bad_message::ReceivedBadMessage(filter_, bad_message::RDH_INVALID_URL);
@@ -1207,7 +1298,8 @@ void ResourceDispatcherHostImpl::BeginRequest(
ResourceContext* resource_context = NULL;
net::URLRequestContext* request_context = NULL;
- filter_->GetContexts(request_data, &resource_context, &request_context);
+ filter_->GetContexts(request_data.resource_type, request_data.origin_pid,
+ &resource_context, &request_context);
// http://crbug.com/90971
CHECK(ContainsKey(active_resource_contexts_, resource_context));
@@ -1239,6 +1331,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
new_request->set_method(request_data.method);
new_request->set_first_party_for_cookies(
request_data.first_party_for_cookies);
+ new_request->set_initiator(request_data.request_initiator);
// If the request is a MAIN_FRAME request, the first-party URL gets updated on
// redirects.
@@ -1312,6 +1405,13 @@ void ResourceDispatcherHostImpl::BeginRequest(
load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
}
+ bool support_async_revalidation =
+ !is_sync_load && async_revalidation_manager_ &&
+ AsyncRevalidationManager::QualifiesForAsyncRevalidation(request_data);
+
+ if (support_async_revalidation)
+ load_flags |= net::LOAD_SUPPORT_ASYNC_REVALIDATION;
+
// Sync loads should have maximum priority and should be the only
// requets that have the ignore limits flag set.
if (is_sync_load) {
@@ -1331,7 +1431,6 @@ void ResourceDispatcherHostImpl::BeginRequest(
request_data.render_frame_id,
request_data.is_main_frame,
request_data.parent_is_main_frame,
- request_data.parent_render_frame_id,
request_data.resource_type,
request_data.transition_type,
request_data.should_replace_current_entry,
@@ -1346,7 +1445,10 @@ void ResourceDispatcherHostImpl::BeginRequest(
request_data.visiblity_state,
resource_context, filter_->GetWeakPtr(),
report_raw_headers,
- !is_sync_load);
+ !is_sync_load,
+ IsUsingLoFi(request_data.lofi_state, delegate_,
+ *new_request, resource_context),
+ support_async_revalidation ? request_data.headers : std::string());
// Request takes ownership.
extra_info->AssociateWithRequest(new_request.get());
@@ -1361,15 +1463,29 @@ void ResourceDispatcherHostImpl::BeginRequest(
// Initialize the service worker handler for the request. We don't use
// ServiceWorker for synchronous loads to avoid renderer deadlocks.
+ const bool should_skip_service_worker =
+ request_data.skip_service_worker || is_sync_load;
ServiceWorkerRequestHandler::InitializeHandler(
new_request.get(), filter_->service_worker_context(), blob_context,
child_id, request_data.service_worker_provider_id,
- request_data.skip_service_worker || is_sync_load,
+ should_skip_service_worker,
request_data.fetch_request_mode, request_data.fetch_credentials_mode,
request_data.fetch_redirect_mode, request_data.resource_type,
request_data.fetch_request_context_type, request_data.fetch_frame_type,
request_data.request_body);
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures)) {
+ ForeignFetchRequestHandler::InitializeHandler(
+ new_request.get(), filter_->service_worker_context(), blob_context,
+ child_id, request_data.service_worker_provider_id,
+ should_skip_service_worker,
+ request_data.fetch_request_mode, request_data.fetch_credentials_mode,
+ request_data.fetch_redirect_mode, request_data.resource_type,
+ request_data.fetch_request_context_type, request_data.fetch_frame_type,
+ request_data.request_body);
+ }
+
// Have the appcache associate its extra info with the request.
AppCacheInterceptor::SetExtraRequestInfo(
new_request.get(), filter_->appcache_service(), child_id,
@@ -1383,7 +1499,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
resource_context));
if (handler)
- BeginRequestInternal(new_request.Pass(), handler.Pass());
+ BeginRequestInternal(std::move(new_request), std::move(handler));
}
scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
@@ -1414,7 +1530,7 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
// The RedirectToFileResourceHandler depends on being next in the chain.
if (request_data.download_to_file) {
handler.reset(
- new RedirectToFileResourceHandler(handler.Pass(), request));
+ new RedirectToFileResourceHandler(std::move(handler), request));
}
}
@@ -1423,15 +1539,14 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
handler.reset(new DetachableResourceHandler(
request,
base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs),
- handler.Pass()));
+ std::move(handler)));
}
// PlzNavigate: If using --enable-browser-side-navigation, the
// CrossSiteResourceHandler is not needed. This codepath is not used for the
// actual navigation request, but only the subsequent blob URL load. This does
// not require request transfers.
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (!IsBrowserSideNavigationEnabled()) {
// Install a CrossSiteResourceHandler for all main frame requests. This will
// check whether a transfer is required and, if so, pause for the UI thread
// to drive the transfer.
@@ -1446,12 +1561,12 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
request_data.resource_type == RESOURCE_TYPE_SUB_FRAME;
}
if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER)
- handler.reset(new CrossSiteResourceHandler(handler.Pass(), request));
+ handler.reset(new CrossSiteResourceHandler(std::move(handler), request));
}
return AddStandardHandlers(request, request_data.resource_type,
resource_context, filter_->appcache_service(),
- child_id, route_id, handler.Pass());
+ child_id, route_id, std::move(handler));
}
scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
@@ -1465,11 +1580,10 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
// PlzNavigate: do not add ResourceThrottles for main resource requests from
// the renderer. Decisions about the navigation should have been done in the
// initial request.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
- IsResourceTypeFrame(resource_type) && child_id != -1) {
+ if (IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type) &&
+ child_id != -1) {
DCHECK(request->url().SchemeIs(url::kBlobScheme));
- return handler.Pass();
+ return handler;
}
PluginService* plugin_service = nullptr;
@@ -1477,7 +1591,7 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
plugin_service = PluginService::GetInstance();
#endif
// Insert a buffered event handler before the actual one.
- handler.reset(new MimeTypeResourceHandler(handler.Pass(), this,
+ handler.reset(new MimeTypeResourceHandler(std::move(handler), this,
plugin_service, request));
ScopedVector<ResourceThrottle> throttles;
@@ -1485,11 +1599,8 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
// Add a NavigationResourceThrottle for navigations.
// PlzNavigate: the throttle is unnecessary as communication with the UI
// thread is handled by the NavigationURLloader.
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
- IsResourceTypeFrame(resource_type)) {
+ if (!IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type))
throttles.push_back(new NavigationResourceThrottle(request));
- }
if (delegate_) {
delegate_->RequestBeginning(request,
@@ -1501,7 +1612,8 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
if (request->has_upload()) {
// Block power save while uploading data.
- throttles.push_back(new PowerSaveBlockResourceThrottle());
+ throttles.push_back(
+ new PowerSaveBlockResourceThrottle(request->url().host()));
}
// TODO(ricea): Stop looking this up so much.
@@ -1509,10 +1621,10 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
throttles.push_back(scheduler_->ScheduleRequest(child_id, route_id,
info->IsAsync(), request));
- handler.reset(
- new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass()));
+ handler.reset(new ThrottlingResourceHandler(std::move(handler), request,
+ std::move(throttles)));
- return handler.Pass();
+ return handler;
}
void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
@@ -1616,7 +1728,6 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
render_frame_route_id,
false, // is_main_frame
false, // parent_is_main_frame
- -1, // parent_render_frame_id
RESOURCE_TYPE_SUB_RESOURCE,
ui::PAGE_TRANSITION_LINK,
false, // should_replace_current_entry
@@ -1632,7 +1743,9 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
context,
base::WeakPtr<ResourceMessageFilter>(), // filter
false, // report_raw_headers
- true); // is_async
+ true, // is_async
+ false, // is_using_lofi
+ std::string()); // original_headers
}
void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id,
@@ -1679,13 +1792,14 @@ void ResourceDispatcherHostImpl::OnAudioRenderHostStreamStateChanged(
}
// This function is only used for saving feature.
-void ResourceDispatcherHostImpl::BeginSaveFile(
- const GURL& url,
- const Referrer& referrer,
- int child_id,
- int render_view_route_id,
- int render_frame_route_id,
- ResourceContext* context) {
+void ResourceDispatcherHostImpl::BeginSaveFile(const GURL& url,
+ const Referrer& referrer,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ int child_id,
+ int render_view_route_id,
+ int render_frame_route_id,
+ ResourceContext* context) {
if (is_shutdown_)
return;
@@ -1723,14 +1837,11 @@ void ResourceDispatcherHostImpl::BeginSaveFile(
render_frame_route_id, false, context);
extra_info->AssociateWithRequest(request.get()); // Request takes ownership.
- scoped_ptr<ResourceHandler> handler(
- new SaveFileResourceHandler(request.get(),
- child_id,
- render_frame_route_id,
- url,
- save_file_manager_.get()));
+ scoped_ptr<ResourceHandler> handler(new SaveFileResourceHandler(
+ request.get(), save_item_id, save_package_id, child_id,
+ render_frame_route_id, url, save_file_manager_.get()));
- BeginRequestInternal(request.Pass(), handler.Pass());
+ BeginRequestInternal(std::move(request), std::move(handler));
}
void ResourceDispatcherHostImpl::MarkAsTransferredNavigation(
@@ -1957,11 +2068,11 @@ void ResourceDispatcherHostImpl::FinishedWithResourcesForRequest(
void ResourceDispatcherHostImpl::BeginNavigationRequest(
ResourceContext* resource_context,
const NavigationRequestInfo& info,
- NavigationURLLoaderImplCore* loader) {
+ NavigationURLLoaderImplCore* loader,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core) {
// PlzNavigate: BeginNavigationRequest currently should only be used for the
// browser-side navigations project.
- CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation));
+ CHECK(IsBrowserSideNavigationEnabled());
ResourceType resource_type = info.is_main_frame ?
RESOURCE_TYPE_MAIN_FRAME : RESOURCE_TYPE_SUB_FRAME;
@@ -2009,6 +2120,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
new_request->set_method(info.begin_params.method);
new_request->set_first_party_for_cookies(
info.first_party_for_cookies);
+ new_request->set_initiator(info.request_initiator);
if (info.is_main_frame) {
new_request->set_first_party_url_policy(
net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
@@ -2022,10 +2134,11 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
new_request->SetLoadFlags(load_flags);
+ storage::BlobStorageContext* blob_context = GetBlobStorageContext(
+ GetChromeBlobStorageContextForResourceContext(resource_context));
+
// Resolve elements from request_body and prepare upload data.
if (info.request_body.get()) {
- storage::BlobStorageContext* blob_context = GetBlobStorageContext(
- GetChromeBlobStorageContextForResourceContext(resource_context));
AttachRequestBodyBlobDataHandles(
info.request_body.get(),
blob_context);
@@ -2054,18 +2167,14 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
-1, // request_data.origin_pid,
request_id_,
-1, // request_data.render_frame_id,
- info.is_main_frame,
- info.parent_is_main_frame,
- -1, // request_data.parent_render_frame_id,
- resource_type,
- info.common_params.transition,
+ info.is_main_frame, info.parent_is_main_frame,
+ resource_type, info.common_params.transition,
// should_replace_current_entry. This was only maintained at layer for
// request transfers and isn't needed for browser-side navigations.
false,
false, // is download
false, // is stream
- info.common_params.allow_download,
- info.begin_params.has_user_gesture,
+ info.common_params.allow_download, info.begin_params.has_user_gesture,
true, // enable_load_timing
false, // enable_upload_progress
false, // do_not_prompt_for_login
@@ -2073,26 +2182,37 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
// TODO(davidben): This is only used for prerenders. Replace
// is_showing with something for that. Or maybe it just comes from the
// same mechanism as the cookie one.
- blink::WebPageVisibilityStateVisible,
- resource_context,
+ blink::WebPageVisibilityStateVisible, resource_context,
base::WeakPtr<ResourceMessageFilter>(), // filter
false, // request_data.report_raw_headers
- true);
+ true, // is_async
+ IsUsingLoFi(info.common_params.lofi_state, delegate_,
+ *new_request, resource_context),
+ // The original_headers field is for stale-while-revalidate but the
+ // feature doesn't work with PlzNavigate, so it's just a placeholder
+ // here.
+ // TODO(ricea): Make the feature work with stale-while-revalidate
+ // and clean this up.
+ std::string()); // original_headers
// Request takes ownership.
extra_info->AssociateWithRequest(new_request.get());
if (new_request->url().SchemeIs(url::kBlobScheme)) {
// Hang on to a reference to ensure the blob is not released prior
// to the job being started.
- ChromeBlobStorageContext* blob_context =
- GetChromeBlobStorageContextForResourceContext(resource_context);
storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
new_request.get(),
- blob_context->context()->GetBlobDataFromPublicURL(new_request->url()));
+ blob_context->GetBlobDataFromPublicURL(new_request->url()));
}
- // TODO(davidben): Attach ServiceWorkerRequestHandler.
- // TODO(michaeln): Help out with this and that.
+ RequestContextFrameType frame_type =
+ info.is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
+ : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
+ ServiceWorkerRequestHandler::InitializeForNavigation(
+ new_request.get(), service_worker_handle_core, blob_context,
+ info.begin_params.skip_service_worker, resource_type,
+ info.begin_params.request_context_type, frame_type, info.request_body);
+
// TODO(davidben): Attach AppCacheInterceptor.
scoped_ptr<ResourceHandler> handler(new NavigationResourceHandler(
@@ -2101,14 +2221,19 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
// TODO(davidben): Pass in the appropriate appcache_service. Also fix the
// dependency on child_id/route_id. Those are used by the ResourceScheduler;
// currently it's a no-op.
- handler = AddStandardHandlers(new_request.get(), resource_type,
- resource_context,
- nullptr, // appcache_service
- -1, // child_id
- -1, // route_id
- handler.Pass());
+ handler =
+ AddStandardHandlers(new_request.get(), resource_type, resource_context,
+ nullptr, // appcache_service
+ -1, // child_id
+ -1, // route_id
+ std::move(handler));
+
+ BeginRequestInternal(std::move(new_request), std::move(handler));
+}
- BeginRequestInternal(new_request.Pass(), handler.Pass());
+void ResourceDispatcherHostImpl::EnableStaleWhileRevalidateForTesting() {
+ if (!async_revalidation_manager_)
+ async_revalidation_manager_.reset(new AsyncRevalidationManager);
}
// static
@@ -2166,7 +2291,7 @@ void ResourceDispatcherHostImpl::BeginRequestInternal(
}
linked_ptr<ResourceLoader> loader(
- new ResourceLoader(request.Pass(), handler.Pass(), this));
+ new ResourceLoader(std::move(request), std::move(handler), this));
GlobalRoutingID id(info->GetGlobalRoutingID());
BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id);
@@ -2210,11 +2335,11 @@ bool ResourceDispatcherHostImpl::LoadInfoIsMoreInteresting(const LoadInfo& a,
// Set |*_uploading_size| to be the size of the corresponding upload body if
// it's currently being uploaded.
- uint64 a_uploading_size = 0;
+ uint64_t a_uploading_size = 0;
if (a.load_state.state == net::LOAD_STATE_SENDING_REQUEST)
a_uploading_size = a.upload_size;
- uint64 b_uploading_size = 0;
+ uint64_t b_uploading_size = 0;
if (b.load_state.state == net::LOAD_STATE_SENDING_REQUEST)
b_uploading_size = b.upload_size;
@@ -2269,7 +2394,7 @@ ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes() {
(*info_map)[id] = load_info;
}
}
- return info_map.Pass();
+ return info_map;
}
void ResourceDispatcherHostImpl::UpdateLoadInfo() {
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.h b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
index 7772917990c..74922647f29 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
@@ -12,19 +12,22 @@
#ifndef CONTENT_BROWSER_LOADER_RESOURCE_DISPATCHER_HOST_IMPL_H_
#define CONTENT_BROWSER_LOADER_RESOURCE_DISPATCHER_HOST_IMPL_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/browser/download/download_resource_handler.h"
+#include "content/browser/download/save_types.h"
#include "content/browser/loader/global_routing_id.h"
#include "content/browser/loader/resource_loader.h"
#include "content/browser/loader/resource_loader_delegate.h"
@@ -60,6 +63,7 @@ class ShareableFileReference;
namespace content {
class AppCacheService;
+class AsyncRevalidationManager;
class NavigationURLLoaderImplCore;
class ResourceContext;
class ResourceDispatcherHostDelegate;
@@ -67,6 +71,7 @@ class ResourceMessageDelegate;
class ResourceMessageFilter;
class ResourceRequestInfoImpl;
class SaveFileManager;
+class ServiceWorkerNavigationHandleCore;
class WebContentsImpl;
struct CommonNavigationParams;
struct DownloadSaveInfo;
@@ -98,7 +103,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
bool prefer_cache,
bool do_not_prompt_for_login,
scoped_ptr<DownloadSaveInfo> save_info,
- uint32 download_id,
+ uint32_t download_id,
const DownloadStartedCallback& started_callback) override;
void ClearLoginDelegateForRequest(net::URLRequest* request) override;
void BlockRequestsForRoute(int child_id, int route_id) override;
@@ -127,6 +132,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// request from the renderer or another child process).
void BeginSaveFile(const GURL& url,
const Referrer& referrer,
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
int child_id,
int render_view_route_id,
int render_frame_route_id,
@@ -236,7 +243,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
net::URLRequest* request,
bool is_content_initiated,
bool must_download,
- uint32 id,
+ uint32_t id,
scoped_ptr<DownloadSaveInfo> save_info,
const DownloadUrlParameters::OnStartedCallback& started_cb);
@@ -273,9 +280,15 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// PlzNavigate: Begins a request for NavigationURLLoader. |loader| is the
// loader to attach to the leaf resource handler.
- void BeginNavigationRequest(ResourceContext* resource_context,
- const NavigationRequestInfo& info,
- NavigationURLLoaderImplCore* loader);
+ void BeginNavigationRequest(
+ ResourceContext* resource_context,
+ const NavigationRequestInfo& info,
+ NavigationURLLoaderImplCore* loader,
+ ServiceWorkerNavigationHandleCore* service_worker_handle_core);
+
+ // Turns on stale-while-revalidate support, regardless of command-line flags
+ // or experiment status. For unit tests only.
+ void EnableStaleWhileRevalidateForTesting();
private:
friend class ResourceDispatcherHostTest;
@@ -301,8 +314,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
struct LoadInfo {
GURL url;
net::LoadStateWithParam load_state;
- uint64 upload_position;
- uint64 upload_size;
+ uint64_t upload_position;
+ uint64_t upload_size;
};
// Map from ProcessID+RouteID pair to the "most interesting" LoadState.
@@ -585,6 +598,10 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
bool allow_cross_origin_auth_prompt_;
+ // AsyncRevalidationManager is non-NULL if and only if
+ // stale-while-revalidate is enabled.
+ scoped_ptr<AsyncRevalidationManager> async_revalidation_manager_;
+
// http://crbug.com/90971 - Assists in tracking down use-after-frees on
// shutdown.
std::set<const ResourceContext*> active_resource_contexts_;
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
index da62f4a89ad..7fbe3995c21 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/shared_memory.h"
#include "base/pickle.h"
@@ -38,8 +39,8 @@
#include "content/public/browser/resource_throttle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/child_process_host.h"
-#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "content/public/common/resource_response.h"
#include "content/public/test/test_browser_context.h"
@@ -51,6 +52,7 @@
#include "net/base/request_priority.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/http/http_util.h"
+#include "net/test/url_request/url_request_failed_job.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job.h"
@@ -151,7 +153,6 @@ static ResourceHostMsg_Request CreateResourceRequest(const char* method,
request.should_reset_appcache = false;
request.is_main_frame = true;
request.parent_is_main_frame = false;
- request.parent_render_frame_id = -1;
request.transition_type = ui::PAGE_TRANSITION_LINK;
request.allow_download = true;
return request;
@@ -181,6 +182,7 @@ class ResourceIPCAccumulator {
// within the groups will be in the order that they appeared.
// Note that this clears messages_. The caller takes ownership of any
// SharedMemoryHandles in messages placed into |msgs|.
+ // TODO(mmenke): This seems really fragile. Consider reworking ownership.
typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
void GetClassifiedMessages(ClassifiedMessages* msgs);
@@ -253,7 +255,8 @@ class TestFilterSpecifyingChild : public ResourceMessageFilter {
~TestFilterSpecifyingChild() override {}
private:
- void GetContexts(const ResourceHostMsg_Request& request,
+ void GetContexts(ResourceType resource_type,
+ int origin_pid,
ResourceContext** resource_context,
net::URLRequestContext** request_context) {
*resource_context = resource_context_;
@@ -340,12 +343,6 @@ class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
}
URLRequestTestDelayedStartJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- bool auto_advance)
- : net::URLRequestTestJob(request, network_delegate, auto_advance) {
- Init();
- }
- URLRequestTestDelayedStartJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
const std::string& response_headers,
const std::string& response_data,
bool auto_advance)
@@ -534,6 +531,7 @@ class TestURLRequestJobFactory : public net::URLRequestJobFactory {
public:
explicit TestURLRequestJobFactory(ResourceDispatcherHostTest* test_fixture)
: test_fixture_(test_fixture),
+ hang_after_start_(false),
delay_start_(false),
delay_complete_(false),
network_start_notification_(false),
@@ -548,6 +546,11 @@ class TestURLRequestJobFactory : public net::URLRequestJobFactory {
return url_request_jobs_created_count_;
}
+ // When set, jobs will hang eternally once started.
+ void SetHangAfterStartJobGeneration(bool hang_after_start) {
+ hang_after_start_ = hang_after_start;
+ }
+
void SetDelayedStartJobGeneration(bool delay_job_start) {
delay_start_ = delay_job_start;
}
@@ -588,6 +591,7 @@ class TestURLRequestJobFactory : public net::URLRequestJobFactory {
private:
ResourceDispatcherHostTest* test_fixture_;
+ bool hang_after_start_;
bool delay_start_;
bool delay_complete_;
bool network_start_notification_;
@@ -945,6 +949,9 @@ class ResourceDispatcherHostTest : public testing::Test,
ResourceType type);
void MakeWebContentsAssociatedTestRequest(int request_id, const GURL& url);
+ void MakeWebContentsAssociatedTestRequestWithResourceType(int request_id,
+ const GURL& url,
+ ResourceType type);
// Generates a request with the given priority.
void MakeTestRequestWithPriority(int render_view_id,
@@ -974,11 +981,10 @@ class ResourceDispatcherHostTest : public testing::Test,
}
// Sets a particular response for any request from now on. To switch back to
- // the default bahavior, pass an empty |headers|. |headers| should be raw-
- // formatted (NULLs instead of EOLs).
+ // the default bahavior, pass an empty |headers|. |headers| should be CR[LF]
+ // terminated.
void SetResponse(const std::string& headers, const std::string& data) {
- response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
- headers.size());
+ response_headers_ = headers;
response_data_ = data;
}
void SetResponse(const std::string& headers) {
@@ -1070,8 +1076,15 @@ void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
void ResourceDispatcherHostTest::MakeWebContentsAssociatedTestRequest(
int request_id,
const GURL& url) {
- ResourceHostMsg_Request request =
- CreateResourceRequest("GET", RESOURCE_TYPE_SUB_RESOURCE, url);
+ MakeWebContentsAssociatedTestRequestWithResourceType(
+ request_id, url, RESOURCE_TYPE_SUB_RESOURCE);
+}
+
+void ResourceDispatcherHostTest::
+ MakeWebContentsAssociatedTestRequestWithResourceType(int request_id,
+ const GURL& url,
+ ResourceType type) {
+ ResourceHostMsg_Request request = CreateResourceRequest("GET", type, url);
request.origin_pid = web_contents_->GetRenderProcessHost()->GetID();
request.render_frame_id = web_contents_->GetMainFrame()->GetRoutingID();
ResourceHostMsg_RequestResource msg(web_contents_->GetRoutingID(), request_id,
@@ -1100,19 +1113,14 @@ void ResourceDispatcherHostTest::MakeWebContentsAssociatedDownloadRequest(
browser_context_->GetResourceContext()->GetRequestContext();
scoped_ptr<net::URLRequest> request(
request_context->CreateRequest(url, net::DEFAULT_PRIORITY, NULL));
- host_.BeginDownload(
- request.Pass(),
- Referrer(),
- false, // is_content_initiated
- browser_context_->GetResourceContext(),
- web_contents_->GetRenderProcessHost()->GetID(),
- web_contents_->GetRoutingID(),
- web_contents_->GetMainFrame()->GetRoutingID(),
- false,
- false,
- save_info.Pass(),
- DownloadItem::kInvalidId,
- ResourceDispatcherHostImpl::DownloadStartedCallback());
+ host_.BeginDownload(std::move(request), Referrer(),
+ false, // is_content_initiated
+ browser_context_->GetResourceContext(),
+ web_contents_->GetRenderProcessHost()->GetID(),
+ web_contents_->GetRoutingID(),
+ web_contents_->GetMainFrame()->GetRoutingID(), false,
+ false, std::move(save_info), DownloadItem::kInvalidId,
+ ResourceDispatcherHostImpl::DownloadStartedCallback());
}
void ResourceDispatcherHostTest::CancelRequest(int request_id) {
@@ -1669,9 +1677,6 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
child_ids_.insert(test_filter->child_id());
// request 1 goes to the test delegate
- ResourceHostMsg_Request request = CreateResourceRequest(
- "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
-
MakeTestRequestWithResourceType(test_filter.get(), 0, 1,
net::URLRequestTestJob::test_url_1(),
RESOURCE_TYPE_SUB_RESOURCE);
@@ -1741,6 +1746,55 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
EXPECT_EQ(0, network_delegate()->error_count());
}
+// Tests whether the correct requests get canceled when a RenderViewHost is
+// deleted.
+TEST_F(ResourceDispatcherHostTest, CancelRequestsOnRenderViewHostDeleted) {
+ // Requests all hang once started. This prevents requests from being
+ // destroyed due to completion.
+ job_factory_->SetHangAfterStartJobGeneration(true);
+ HandleScheme("http");
+
+ TestResourceDispatcherHostDelegate delegate;
+ host_.SetDelegate(&delegate);
+ host_.OnRenderViewHostCreated(filter_->child_id(), 0, true, false);
+
+ // One RenderView issues a high priority request and a low priority one. Both
+ // should be started.
+ MakeTestRequestWithPriority(0, 1, net::HIGHEST);
+ MakeTestRequestWithPriority(0, 2, net::LOWEST);
+ KickOffRequest();
+ EXPECT_EQ(2, network_delegate_.created_requests());
+ EXPECT_EQ(0, network_delegate_.canceled_requests());
+
+ // The same RenderView issues two more low priority requests. The
+ // ResourceScheduler shouldn't let them start immediately.
+ MakeTestRequestWithPriority(0, 3, net::LOWEST);
+ MakeTestRequestWithPriority(0, 4, net::LOWEST);
+ KickOffRequest();
+ EXPECT_EQ(2, network_delegate_.created_requests());
+ EXPECT_EQ(0, network_delegate_.canceled_requests());
+
+ // Another RenderView in the same process as the old one issues a request,
+ // which is then started.
+ MakeTestRequestWithPriority(1, 5, net::LOWEST);
+ KickOffRequest();
+ EXPECT_EQ(3, network_delegate_.created_requests());
+ EXPECT_EQ(0, network_delegate_.canceled_requests());
+
+ // The first RenderView is destroyed. All 4 of its requests should be
+ // cancelled, and none of the two deferred requests should be started.
+ host_.OnRenderViewHostDeleted(filter_->child_id(), 0);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3, network_delegate_.created_requests());
+ EXPECT_EQ(4, network_delegate_.canceled_requests());
+
+ // No messages should have been sent, since none of the jobs made any
+ // progress.
+ ResourceIPCAccumulator::ClassifiedMessages msgs;
+ accum_.GetClassifiedMessages(&msgs);
+ EXPECT_EQ(0U, msgs.size());
+}
+
TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
MakeTestRequestWithResourceType(filter_.get(), 0, 1,
net::URLRequestTestJob::test_url_4(),
@@ -1989,7 +2043,7 @@ TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
upload_content.data(), upload_content.size()));
req->set_upload(
- net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ net::ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
// Since the upload throttling is disabled, this has no effect on the cost.
EXPECT_EQ(
@@ -2389,7 +2443,6 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
EXPECT_EQ(0, host_.pending_requests());
- int render_view_id = 0;
int request_id = 1;
std::string raw_headers("HTTP/1.1 200 OK\n"
@@ -2399,17 +2452,16 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
SetResponse(raw_headers, response_data);
HandleScheme("http");
- MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
- GURL("http://example.com/blah"),
- RESOURCE_TYPE_MAIN_FRAME);
-
+ MakeWebContentsAssociatedTestRequestWithResourceType(
+ request_id, GURL("http://example.com/blah"), RESOURCE_TYPE_MAIN_FRAME);
- GlobalRequestID global_request_id(filter_->child_id(), request_id);
+ GlobalRequestID global_request_id(web_contents_filter_->child_id(),
+ request_id);
host_.MarkAsTransferredNavigation(global_request_id);
// And now simulate a cancellation coming from the renderer.
ResourceHostMsg_CancelRequest msg(request_id);
- host_.OnMessageReceived(msg, filter_.get());
+ host_.OnMessageReceived(msg, web_contents_filter_.get());
// Since the request is marked as being transferred,
// the cancellation above should have been ignored and the request
@@ -2417,19 +2469,18 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
EXPECT_EQ(1, host_.pending_requests());
// Cancelling by other methods shouldn't work either.
- host_.CancelRequestsForProcess(render_view_id);
+ host_.CancelRequestsForProcess(web_contents_->GetRoutingID());
EXPECT_EQ(1, host_.pending_requests());
// Cancelling by context should work.
- host_.CancelRequestsForContext(filter_->resource_context());
+ host_.CancelRequestsForContext(web_contents_filter_->resource_context());
EXPECT_EQ(0, host_.pending_requests());
}
// Test transferred navigations with text/html, which doesn't trigger any
// content sniffing.
TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
SUCCEED() << "Test is not applicable with browser side navigation enabled";
return;
}
@@ -2503,8 +2554,7 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
// Test transferring two navigations with text/html, to ensure the resource
// accounting works.
TEST_F(ResourceDispatcherHostTest, TransferTwoNavigationsHtml) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
SUCCEED() << "Test is not applicable with browser side navigation enabled";
return;
}
@@ -2591,8 +2641,7 @@ TEST_F(ResourceDispatcherHostTest, TransferTwoNavigationsHtml) {
// MimeTypeResourceHandler to buffer the response to sniff the content before
// the transfer occurs.
TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
SUCCEED() << "Test is not applicable with browser side navigation enabled";
return;
}
@@ -2666,8 +2715,7 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
}
TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
SUCCEED() << "Test is not applicable with browser side navigation enabled";
return;
}
@@ -2757,8 +2805,7 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
}
TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
SUCCEED() << "Test is not applicable with browser side navigation enabled";
return;
}
@@ -3444,10 +3491,14 @@ net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
if (test_fixture_->loader_test_request_info_) {
DCHECK_EQ(test_fixture_->loader_test_request_info_->url, request->url());
scoped_ptr<LoadInfoTestRequestInfo> info =
- test_fixture_->loader_test_request_info_.Pass();
+ std::move(test_fixture_->loader_test_request_info_);
return new URLRequestLoadInfoJob(request, network_delegate,
info->load_state, info->upload_progress);
}
+ if (hang_after_start_) {
+ return new net::URLRequestFailedJob(request, network_delegate,
+ net::ERR_IO_PENDING);
+ }
if (test_fixture_->response_headers_.empty()) {
if (delay_start_) {
return new URLRequestTestDelayedStartJob(request, network_delegate);
diff --git a/chromium/content/browser/loader/resource_loader.cc b/chromium/content/browser/loader/resource_loader.cc
index 64f5e7b341b..eee044c6aaf 100644
--- a/chromium/content/browser/loader/resource_loader.cc
+++ b/chromium/content/browser/loader/resource_loader.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/resource_loader.h"
+#include <utility>
+
#include "base/command_line.h"
#include "base/location.h"
#include "base/metrics/histogram.h"
@@ -35,6 +37,8 @@
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/ssl/client_cert_store.h"
+#include "net/ssl/ssl_platform_key.h"
+#include "net/ssl/ssl_private_key.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request_status.h"
@@ -94,6 +98,10 @@ void PopulateResourceResponse(ResourceRequestInfoImpl* info,
response->head.was_fetched_via_proxy = request->was_fetched_via_proxy();
response->head.proxy_server = response_info.proxy_server;
response->head.socket_address = request->GetSocketAddress();
+ const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo::ForRequest(request);
+ if (request_info)
+ response->head.is_using_lofi = request_info->IsUsingLoFi();
if (ServiceWorkerRequestHandler* handler =
ServiceWorkerRequestHandler::GetHandler(request)) {
handler->GetExtraResponseInfo(&response->head);
@@ -109,6 +117,9 @@ void PopulateResourceResponse(ResourceRequestInfoImpl* info,
GetSSLStatusForRequest(request->url(), request->ssl_info(),
info->GetChildID(), &ssl_status);
response->head.security_info = SerializeSecurityInfo(ssl_status);
+ response->head.has_major_certificate_errors =
+ net::IsCertStatusError(ssl_status.cert_status) &&
+ !net::IsCertStatusMinorError(ssl_status.cert_status);
} else {
// We should not have any SSL state.
DCHECK(!request->ssl_info().cert_status);
@@ -124,8 +135,8 @@ ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request,
scoped_ptr<ResourceHandler> handler,
ResourceLoaderDelegate* delegate)
: deferred_stage_(DEFERRED_NONE),
- request_(request.Pass()),
- handler_(handler.Pass()),
+ request_(std::move(request)),
+ handler_(std::move(handler)),
delegate_(delegate),
is_transferring_(false),
times_cancelled_before_request_start_(0),
@@ -306,19 +317,9 @@ void ResourceLoader::OnSSLCertificateError(net::URLRequest* request,
bool fatal) {
ResourceRequestInfoImpl* info = GetRequestInfo();
- int render_process_id;
- int render_frame_id;
- if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
- NOTREACHED();
-
SSLManager::OnSSLCertificateError(
- weak_ptr_factory_.GetWeakPtr(),
- info->GetResourceType(),
- request_->url(),
- render_process_id,
- render_frame_id,
- ssl_info,
- fatal);
+ weak_ptr_factory_.GetWeakPtr(), info->GetResourceType(), request_->url(),
+ info->GetWebContentsGetterForRequest(), ssl_info, fatal);
}
void ResourceLoader::OnBeforeNetworkStart(net::URLRequest* unused,
@@ -419,7 +420,13 @@ void ResourceLoader::ContinueSSLRequest() {
void ResourceLoader::ContinueWithCertificate(net::X509Certificate* cert) {
DCHECK(ssl_client_auth_handler_);
ssl_client_auth_handler_.reset();
- request_->ContinueWithCertificate(cert);
+ if (!cert) {
+ request_->ContinueWithCertificate(nullptr, nullptr);
+ return;
+ }
+ scoped_refptr<net::SSLPrivateKey> private_key =
+ net::FetchClientCertPrivateKey(cert);
+ request_->ContinueWithCertificate(cert, private_key.get());
}
void ResourceLoader::CancelCertificateSelection() {
@@ -671,6 +678,12 @@ void ResourceLoader::CallDidFinishLoading() {
}
void ResourceLoader::RecordHistograms() {
+ if (request_->response_info().network_accessed) {
+ UMA_HISTOGRAM_ENUMERATION("Net.HttpResponseInfo.ConnectionInfo",
+ request_->response_info().connection_info,
+ net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS);
+ }
+
ResourceRequestInfoImpl* info = GetRequestInfo();
if (info->GetResourceType() == RESOURCE_TYPE_PREFETCH) {
diff --git a/chromium/content/browser/loader/resource_loader.h b/chromium/content/browser/loader/resource_loader.h
index 41f3d7e38b1..5b5ecdb500e 100644
--- a/chromium/content/browser/loader/resource_loader.h
+++ b/chromium/content/browser/loader/resource_loader.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_LOADER_RESOURCE_LOADER_H_
#define CONTENT_BROWSER_LOADER_RESOURCE_LOADER_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
diff --git a/chromium/content/browser/loader/resource_loader_unittest.cc b/chromium/content/browser/loader/resource_loader_unittest.cc
index 90418f3f114..05ed7fc4efb 100644
--- a/chromium/content/browser/loader/resource_loader_unittest.cc
+++ b/chromium/content/browser/loader/resource_loader_unittest.cc
@@ -4,11 +4,16 @@
#include "content/browser/loader/resource_loader.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -38,6 +43,7 @@
#include "net/cert/x509_certificate.h"
#include "net/ssl/client_cert_store.h"
#include "net/ssl/ssl_cert_request_info.h"
+#include "net/ssl/ssl_private_key.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/url_request.h"
@@ -146,7 +152,8 @@ class MockClientCertURLRequestJob : public net::URLRequestTestJob {
public:
MockClientCertURLRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate)
- : net::URLRequestTestJob(request, network_delegate) {}
+ : net::URLRequestTestJob(request, network_delegate),
+ weak_factory_(this) {}
static std::vector<std::string> test_authorities() {
return std::vector<std::string>(1, "dummy");
@@ -160,16 +167,19 @@ class MockClientCertURLRequestJob : public net::URLRequestTestJob {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested,
- this, cert_request_info));
+ weak_factory_.GetWeakPtr(), cert_request_info));
}
- void ContinueWithCertificate(net::X509Certificate* cert) override {
+ void ContinueWithCertificate(net::X509Certificate* cert,
+ net::SSLPrivateKey* private_key) override {
net::URLRequestTestJob::Start();
}
private:
~MockClientCertURLRequestJob() override {}
+ base::WeakPtrFactory<MockClientCertURLRequestJob> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob);
};
@@ -227,9 +237,9 @@ class MockHTTPSURLRequestJob : public net::URLRequestTestJob {
};
const char kRedirectHeaders[] =
- "HTTP/1.1 302 Found\0"
- "Location: https://example.test\0"
- "\0";
+ "HTTP/1.1 302 Found\n"
+ "Location: https://example.test\n"
+ "\n";
class MockHTTPSJobURLRequestInterceptor : public net::URLRequestInterceptor {
public:
@@ -441,7 +451,7 @@ class SelectCertificateBrowserClient : public TestContentBrowserClient {
++call_count_;
passed_certs_ = cert_request_info->client_certs;
- delegate_ = delegate.Pass();
+ delegate_ = std::move(delegate);
select_certificate_run_loop_.Quit();
}
@@ -471,11 +481,11 @@ class ResourceContextStub : public MockResourceContext {
: MockResourceContext(test_request_context) {}
scoped_ptr<net::ClientCertStore> CreateClientCertStore() override {
- return dummy_cert_store_.Pass();
+ return std::move(dummy_cert_store_);
}
void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) {
- dummy_cert_store_ = store.Pass();
+ dummy_cert_store_ = std::move(store);
}
private:
@@ -486,7 +496,7 @@ class ResourceContextStub : public MockResourceContext {
// progress reporting.
class NonChunkedUploadDataStream : public net::UploadDataStream {
public:
- explicit NonChunkedUploadDataStream(uint64 size)
+ explicit NonChunkedUploadDataStream(uint64_t size)
: net::UploadDataStream(false, 0), stream_(0), size_(size) {}
void AppendData(const char* data) {
@@ -510,7 +520,7 @@ class NonChunkedUploadDataStream : public net::UploadDataStream {
void ResetInternal() override { stream_.Reset(); }
net::ChunkedUploadDataStream stream_;
- uint64 size_;
+ uint64_t size_;
DISALLOW_COPY_AND_ASSIGN(NonChunkedUploadDataStream);
};
@@ -552,7 +562,7 @@ class ResourceLoaderTest : public testing::Test,
virtual scoped_ptr<ResourceHandler> WrapResourceHandler(
scoped_ptr<ResourceHandlerStub> leaf_handler,
net::URLRequest* request) {
- return leaf_handler.Pass();
+ return std::move(leaf_handler);
}
// Replaces loader_ with a new one for |request|.
@@ -565,13 +575,13 @@ class ResourceLoaderTest : public testing::Test,
rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(),
rfh->GetRoutingID(), true /* is_main_frame */,
false /* parent_is_main_frame */, true /* allow_download */,
- false /* is_async */);
+ false /* is_async */, false /* is_using_lofi_ */);
scoped_ptr<ResourceHandlerStub> resource_handler(
new ResourceHandlerStub(request.get()));
raw_ptr_resource_handler_ = resource_handler.get();
loader_.reset(new ResourceLoader(
- request.Pass(),
- WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_),
+ std::move(request),
+ WrapResourceHandler(std::move(resource_handler), raw_ptr_to_request_),
this));
}
@@ -589,7 +599,7 @@ class ResourceLoaderTest : public testing::Test,
test_url(),
net::DEFAULT_PRIORITY,
nullptr /* delegate */));
- SetUpResourceLoader(request.Pass());
+ SetUpResourceLoader(std::move(request));
}
void TearDown() override {
@@ -684,7 +694,7 @@ TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) {
new net::X509Certificate("test", "test", base::Time(), base::Time())));
scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub(
dummy_certs, &store_request_count, &store_requested_authorities));
- resource_context_.SetClientCertStore(test_store.Pass());
+ resource_context_.SetClientCertStore(std::move(test_store));
// Plug in test content browser client.
SelectCertificateBrowserClient test_client;
@@ -707,7 +717,7 @@ TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) {
EXPECT_EQ(dummy_certs, test_client.passed_certs());
// Continue the request.
- test_client.ContinueWithCertificate(dummy_certs[0].get());
+ test_client.ContinueWithCertificate(nullptr);
raw_ptr_resource_handler_->WaitForResponseComplete();
EXPECT_EQ(net::OK, raw_ptr_resource_handler_->status().error());
@@ -732,9 +742,7 @@ TEST_F(ClientCertResourceLoaderTest, WithNullStore) {
EXPECT_EQ(net::CertificateList(), test_client.passed_certs());
// Continue the request.
- scoped_refptr<net::X509Certificate> cert(
- new net::X509Certificate("test", "test", base::Time(), base::Time()));
- test_client.ContinueWithCertificate(cert.get());
+ test_client.ContinueWithCertificate(nullptr);
raw_ptr_resource_handler_->WaitForResponseComplete();
EXPECT_EQ(net::OK, raw_ptr_resource_handler_->status().error());
@@ -886,7 +894,7 @@ class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest {
// Create mock file streams and a ShareableFileReference.
scoped_ptr<net::testing::MockFileStream> file_stream(
- new net::testing::MockFileStream(file.Pass(),
+ new net::testing::MockFileStream(std::move(file),
base::ThreadTaskRunnerHandle::Get()));
file_stream_ = file_stream.get();
deletable_file_ = ShareableFileReference::GetOrCreate(
@@ -897,13 +905,13 @@ class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest {
// Inject them into the handler.
scoped_ptr<RedirectToFileResourceHandler> handler(
- new RedirectToFileResourceHandler(leaf_handler.Pass(), request));
+ new RedirectToFileResourceHandler(std::move(leaf_handler), request));
redirect_to_file_resource_handler_ = handler.get();
handler->SetCreateTemporaryFileStreamFunctionForTesting(
base::Bind(&ResourceLoaderRedirectToFileTest::PostCallback,
base::Unretained(this),
base::Passed(&file_stream)));
- return handler.Pass();
+ return std::move(handler);
}
private:
@@ -1074,7 +1082,7 @@ TEST_F(HTTPSSecurityInfoResourceLoaderTest, SecurityInfoOnHTTPSResource) {
scoped_ptr<net::URLRequest> request(
resource_context_.GetRequestContext()->CreateRequest(
test_https_url(), net::DEFAULT_PRIORITY, nullptr /* delegate */));
- SetUpResourceLoader(request.Pass());
+ SetUpResourceLoader(std::move(request));
// Send the request and wait until it completes.
loader_->StartRequest();
@@ -1113,7 +1121,7 @@ TEST_F(HTTPSSecurityInfoResourceLoaderTest,
resource_context_.GetRequestContext()->CreateRequest(
test_https_redirect_url(), net::DEFAULT_PRIORITY,
nullptr /* delegate */));
- SetUpResourceLoader(request.Pass());
+ SetUpResourceLoader(std::move(request));
// Send the request and wait until it completes.
loader_->StartRequest();
diff --git a/chromium/content/browser/loader/resource_message_delegate.h b/chromium/content/browser/loader/resource_message_delegate.h
index 2a5dc45ebc4..f007f1ca356 100644
--- a/chromium/content/browser/loader/resource_message_delegate.h
+++ b/chromium/content/browser/loader/resource_message_delegate.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_LOADER_RESOURCE_MESSAGE_DELEGATE_H_
#define CONTENT_BROWSER_LOADER_RESOURCE_MESSAGE_DELEGATE_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
diff --git a/chromium/content/browser/loader/resource_message_filter.cc b/chromium/content/browser/loader/resource_message_filter.cc
index 4a20d9ac1df..186bf66316e 100644
--- a/chromium/content/browser/loader/resource_message_filter.cc
+++ b/chromium/content/browser/loader/resource_message_filter.cc
@@ -50,10 +50,12 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
}
void ResourceMessageFilter::GetContexts(
- const ResourceHostMsg_Request& request,
+ ResourceType resource_type,
+ int origin_pid,
ResourceContext** resource_context,
net::URLRequestContext** request_context) {
- return get_contexts_callback_.Run(request, resource_context, request_context);
+ return get_contexts_callback_.Run(resource_type, origin_pid, resource_context,
+ request_context);
}
const HostZoomMap* ResourceMessageFilter::GetHostZoomMap() const {
diff --git a/chromium/content/browser/loader/resource_message_filter.h b/chromium/content/browser/loader/resource_message_filter.h
index 1240cb4f5b3..9bac4198f60 100644
--- a/chromium/content/browser/loader/resource_message_filter.h
+++ b/chromium/content/browser/loader/resource_message_filter.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_LOADER_RESOURCE_MESSAGE_FILTER_H_
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
@@ -38,12 +39,18 @@ class ServiceWorkerContextWrapper;
// will not interfere with browser UI.
class CONTENT_EXPORT ResourceMessageFilter : public BrowserMessageFilter {
public:
- typedef base::Callback<void(const ResourceHostMsg_Request&,
+ // TODO(ricea): Remove origin_pid when support for NPAPI plugins is removed.
+ // crbug.com/493212 is the tracking bug for NPAPI removal.
+ typedef base::Callback<void(ResourceType resource_type,
+ int origin_pid,
ResourceContext**,
net::URLRequestContext**)> GetContextsCallback;
// |appcache_service|, |blob_storage_context|, |file_system_context| may be
// NULL in unittests or for requests from the (NPAPI) plugin process.
+ // The |origin_pid| argument to |get_contexts_callback| is not used
+ // (and may be invalid) for requests that are NOT from the NPAPI plugin
+ // process.
ResourceMessageFilter(int child_id,
int process_type,
ChromeAppCacheService* appcache_service,
@@ -57,7 +64,10 @@ class CONTENT_EXPORT ResourceMessageFilter : public BrowserMessageFilter {
void OnChannelClosing() override;
bool OnMessageReceived(const IPC::Message& message) override;
- void GetContexts(const ResourceHostMsg_Request& request,
+ // |origin_pid| is only required for NPAPI plugin processes. Its value is
+ // ignored otherwise.
+ void GetContexts(ResourceType resource_type,
+ int origin_pid,
ResourceContext** resource_context,
net::URLRequestContext** request_context);
diff --git a/chromium/content/browser/loader/resource_request_info_impl.cc b/chromium/content/browser/loader/resource_request_info_impl.cc
index eb400bca9cc..8511653ee50 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.cc
+++ b/chromium/content/browser/loader/resource_request_info_impl.cc
@@ -4,15 +4,33 @@
#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/loader/global_routing_id.h"
#include "content/browser/loader/resource_message_filter.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/net/url_request_user_data.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_request_id.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/process_type.h"
#include "net/url_request/url_request.h"
namespace content {
+namespace {
+
+WebContents* GetWebContentsFromFTNID(int frame_tree_node_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ FrameTreeNode* frame_tree_node =
+ FrameTreeNode::GloballyFindByID(frame_tree_node_id);
+ if (!frame_tree_node)
+ return nullptr;
+
+ return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
+}
+
+} // namespace
+
// ----------------------------------------------------------------------------
// ResourceRequestInfo
@@ -32,7 +50,8 @@ void ResourceRequestInfo::AllocateForTesting(net::URLRequest* request,
bool is_main_frame,
bool parent_is_main_frame,
bool allow_download,
- bool is_async) {
+ bool is_async,
+ bool is_using_lofi) {
// Make sure both |is_main_frame| and |parent_is_main_frame| aren't set at the
// same time.
DCHECK(!(is_main_frame && parent_is_main_frame));
@@ -52,7 +71,6 @@ void ResourceRequestInfo::AllocateForTesting(net::URLRequest* request,
render_frame_id, // render_frame_id
is_main_frame, // is_main_frame
parent_is_main_frame, // parent_is_main_frame
- 0, // parent_render_frame_id
resource_type, // resource_type
ui::PAGE_TRANSITION_LINK, // transition_type
false, // should_replace_current_entry
@@ -68,7 +86,9 @@ void ResourceRequestInfo::AllocateForTesting(net::URLRequest* request,
context, // context
base::WeakPtr<ResourceMessageFilter>(), // filter
false, // report_raw_headers
- is_async); // is_async
+ is_async, // is_async
+ is_using_lofi, // is_using_lofi
+ std::string()); // original_headers
info->AssociateWithRequest(request);
}
@@ -111,7 +131,6 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
int render_frame_id,
bool is_main_frame,
bool parent_is_main_frame,
- int parent_render_frame_id,
ResourceType resource_type,
ui::PageTransition transition_type,
bool should_replace_current_entry,
@@ -127,7 +146,9 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
ResourceContext* context,
base::WeakPtr<ResourceMessageFilter> filter,
bool report_raw_headers,
- bool is_async)
+ bool is_async,
+ bool is_using_lofi,
+ const std::string& original_headers)
: cross_site_handler_(NULL),
detachable_handler_(NULL),
process_type_(process_type),
@@ -139,7 +160,6 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
render_frame_id_(render_frame_id),
is_main_frame_(is_main_frame),
parent_is_main_frame_(parent_is_main_frame),
- parent_render_frame_id_(parent_render_frame_id),
should_replace_current_entry_(should_replace_current_entry),
is_download_(is_download),
is_stream_(is_stream),
@@ -158,12 +178,37 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
context_(context),
filter_(filter),
report_raw_headers_(report_raw_headers),
- is_async_(is_async) {
+ is_async_(is_async),
+ is_using_lofi_(is_using_lofi),
+ original_headers_(original_headers) {
}
ResourceRequestInfoImpl::~ResourceRequestInfoImpl() {
}
+ResourceRequestInfo::WebContentsGetter
+ResourceRequestInfoImpl::GetWebContentsGetterForRequest() const {
+ // PlzNavigate: navigation requests are created with a valid FrameTreeNode ID
+ // and invalid RenderProcessHost and RenderFrameHost IDs. The FrameTreeNode
+ // ID should be used to access the WebContents.
+ if (frame_tree_node_id_ != -1) {
+ DCHECK(IsBrowserSideNavigationEnabled());
+ return base::Bind(&GetWebContentsFromFTNID, frame_tree_node_id_);
+ }
+
+ // In other cases, use the RenderProcessHost ID + RenderFrameHost ID to get
+ // the WebContents.
+ int render_process_host_id = -1;
+ int render_frame_host_id = -1;
+ if (!GetAssociatedRenderFrame(&render_process_host_id,
+ &render_frame_host_id)) {
+ NOTREACHED();
+ }
+
+ return base::Bind(&WebContentsImpl::FromRenderFrameHostID,
+ render_process_host_id, render_frame_host_id);
+}
+
ResourceContext* ResourceRequestInfoImpl::GetContext() const {
return context_;
}
@@ -180,10 +225,6 @@ int ResourceRequestInfoImpl::GetOriginPID() const {
return origin_pid_;
}
-int ResourceRequestInfoImpl::GetRequestID() const {
- return request_id_;
-}
-
int ResourceRequestInfoImpl::GetRenderFrameID() const {
return render_frame_id_;
}
@@ -196,10 +237,6 @@ bool ResourceRequestInfoImpl::ParentIsMainFrame() const {
return parent_is_main_frame_;
}
-int ResourceRequestInfoImpl::GetParentRenderFrameID() const {
- return parent_render_frame_id_;
-}
-
ResourceType ResourceRequestInfoImpl::GetResourceType() const {
return resource_type_;
}
@@ -250,6 +287,10 @@ bool ResourceRequestInfoImpl::IsDownload() const {
return is_download_;
}
+bool ResourceRequestInfoImpl::IsUsingLoFi() const {
+ return is_using_lofi_;
+}
+
bool ResourceRequestInfoImpl::ShouldReportRawHeaders() const {
return report_raw_headers_;
}
@@ -265,6 +306,10 @@ void ResourceRequestInfoImpl::AssociateWithRequest(net::URLRequest* request) {
}
}
+int ResourceRequestInfoImpl::GetRequestID() const {
+ return request_id_;
+}
+
GlobalRequestID ResourceRequestInfoImpl::GetGlobalRequestID() const {
return GlobalRequestID(child_id_, request_id_);
}
@@ -276,15 +321,15 @@ GlobalRoutingID ResourceRequestInfoImpl::GetGlobalRoutingID() const {
void ResourceRequestInfoImpl::UpdateForTransfer(
int child_id,
int route_id,
+ int render_frame_id,
int origin_pid,
int request_id,
- int parent_render_frame_id,
base::WeakPtr<ResourceMessageFilter> filter) {
child_id_ = child_id;
route_id_ = route_id;
+ render_frame_id_ = render_frame_id;
origin_pid_ = origin_pid;
request_id_ = request_id;
- parent_render_frame_id_ = parent_render_frame_id;
filter_ = filter;
}
diff --git a/chromium/content/browser/loader/resource_request_info_impl.h b/chromium/content/browser/loader/resource_request_info_impl.h
index f0251e51325..625e58ca890 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.h
+++ b/chromium/content/browser/loader/resource_request_info_impl.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -49,7 +49,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int render_frame_id,
bool is_main_frame,
bool parent_is_main_frame,
- int parent_render_frame_id,
ResourceType resource_type,
ui::PageTransition transition_type,
bool should_replace_current_entry,
@@ -65,19 +64,20 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
ResourceContext* context,
base::WeakPtr<ResourceMessageFilter> filter,
bool report_raw_headers,
- bool is_async);
+ bool is_async,
+ bool is_using_lofi,
+ const std::string& original_headers);
~ResourceRequestInfoImpl() override;
// ResourceRequestInfo implementation:
+ WebContentsGetter GetWebContentsGetterForRequest() const override;
ResourceContext* GetContext() const override;
int GetChildID() const override;
int GetRouteID() const override;
int GetOriginPID() const override;
- int GetRequestID() const override;
int GetRenderFrameID() const override;
bool IsMainFrame() const override;
bool ParentIsMainFrame() const override;
- int GetParentRenderFrameID() const override;
ResourceType GetResourceType() const override;
int GetProcessType() const override;
blink::WebReferrerPolicy GetReferrerPolicy() const override;
@@ -89,10 +89,12 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int* render_frame_id) const override;
bool IsAsync() const override;
bool IsDownload() const override;
+ bool IsUsingLoFi() const override;
bool ShouldReportRawHeaders() const;
CONTENT_EXPORT void AssociateWithRequest(net::URLRequest* request);
+ CONTENT_EXPORT int GetRequestID() const;
CONTENT_EXPORT GlobalRequestID GetGlobalRequestID() const;
GlobalRoutingID GetGlobalRoutingID() const;
@@ -112,9 +114,9 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
// does not need to be updated.
void UpdateForTransfer(int child_id,
int route_id,
+ int render_frame_id,
int origin_pid,
int request_id,
- int parent_render_frame_id,
base::WeakPtr<ResourceMessageFilter> filter);
// CrossSiteResourceHandler for this request. May be null.
@@ -180,6 +182,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
void set_do_not_prompt_for_login(bool do_not_prompt) {
do_not_prompt_for_login_ = do_not_prompt;
}
+ const std::string& original_headers() const { return original_headers_; }
private:
FRIEND_TEST_ALL_PREFIXES(ResourceDispatcherHostTest,
@@ -199,7 +202,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int render_frame_id_;
bool is_main_frame_;
bool parent_is_main_frame_;
- int parent_render_frame_id_;
bool should_replace_current_entry_;
bool is_download_;
bool is_stream_;
@@ -221,6 +223,8 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
base::WeakPtr<ResourceMessageFilter> filter_;
bool report_raw_headers_;
bool is_async_;
+ bool is_using_lofi_;
+ const std::string original_headers_;
DISALLOW_COPY_AND_ASSIGN(ResourceRequestInfoImpl);
};
diff --git a/chromium/content/browser/loader/resource_scheduler.cc b/chromium/content/browser/loader/resource_scheduler.cc
index 2d9071612a3..690f20f0a03 100644
--- a/chromium/content/browser/loader/resource_scheduler.cc
+++ b/chromium/content/browser/loader/resource_scheduler.cc
@@ -5,11 +5,12 @@
#include "content/browser/loader/resource_scheduler.h"
#include <stdint.h>
-
#include <set>
#include <string>
+#include <utility>
#include <vector>
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/stl_util.h"
@@ -32,6 +33,11 @@ namespace content {
namespace {
+enum StartMode {
+ START_SYNC,
+ START_ASYNC
+};
+
// Field trial constants
const char kThrottleCoalesceFieldTrial[] = "RequestThrottlingAndCoalescing";
const char kThrottleCoalesceFieldTrialThrottle[] = "Throttle";
@@ -162,14 +168,14 @@ class ResourceScheduler::RequestQueue {
private:
typedef std::map<ScheduledResourceRequest*, NetQueue::iterator> PointerMap;
- uint32 MakeFifoOrderingId() {
+ uint32_t MakeFifoOrderingId() {
fifo_ordering_ids_ += 1;
return fifo_ordering_ids_;
}
// Used to create an ordering ID for scheduled resources so that resources
// with same priority/intra_priority stay in fifo order.
- uint32 fifo_ordering_ids_;
+ uint32_t fifo_ordering_ids_;
NetQueue queue_;
PointerMap pointers_;
@@ -193,7 +199,8 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle {
attributes_(kAttributeNone),
scheduler_(scheduler),
priority_(priority),
- fifo_ordering_(0) {
+ fifo_ordering_(0),
+ weak_ptr_factory_(this) {
DCHECK(!request_->GetUserData(kUserDataKey));
request_->SetUserData(kUserDataKey, new UnownedPointer(this));
}
@@ -208,10 +215,39 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle {
->get();
}
- void Start() {
- ready_ = true;
+ // Starts the request. If |start_mode| is START_ASYNC, the request will not
+ // be started immediately.
+ void Start(StartMode start_mode) {
+ DCHECK(!ready_);
+
+ // If the request was cancelled, do nothing.
if (!request_->status().is_success())
return;
+
+ bool was_deferred = deferred_;
+
+ // If the request was deferred, need to start it. Otherwise, will just not
+ // defer starting it in the first place, and the value of |start_mode|
+ // makes no difference.
+ if (deferred_) {
+ // If can't start the request synchronously, post a task to start the
+ // request.
+ if (start_mode == START_ASYNC) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&ScheduledResourceRequest::Start,
+ weak_ptr_factory_.GetWeakPtr(),
+ START_SYNC));
+ return;
+ }
+ deferred_ = false;
+ controller()->Resume();
+ }
+
+ ready_ = true;
+
+ // The rest of this method is just collecting histograms.
+
base::TimeTicks time = base::TimeTicks::Now();
ClientState current_state = scheduler_->GetClientState(client_id_);
// Note: the client state isn't perfectly accurate since it won't capture
@@ -227,11 +263,8 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle {
}
base::TimeDelta time_was_deferred = base::TimeDelta::FromMicroseconds(0);
- if (deferred_) {
- deferred_ = false;
- controller()->Resume();
+ if (was_deferred)
time_was_deferred = time - time_deferred_;
- }
PostHistogram("RequestTimeDeferred", client_state, NULL, time_was_deferred);
PostHistogram("RequestTimeThrottled", client_state, NULL,
time - request_->creation_time());
@@ -250,8 +283,8 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle {
net::URLRequest* url_request() { return request_; }
const net::URLRequest* url_request() const { return request_; }
bool is_async() const { return is_async_; }
- uint32 fifo_ordering() const { return fifo_ordering_; }
- void set_fifo_ordering(uint32 fifo_ordering) {
+ uint32_t fifo_ordering() const { return fifo_ordering_; }
+ void set_fifo_ordering(uint32_t fifo_ordering) {
fifo_ordering_ = fifo_ordering;
}
RequestAttributes attributes() const {
@@ -294,9 +327,12 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle {
RequestAttributes attributes_;
ResourceScheduler* scheduler_;
RequestPriorityParams priority_;
- uint32 fifo_ordering_;
+ uint32_t fifo_ordering_;
base::TimeTicks time_deferred_;
+ base::WeakPtrFactory<ResourceScheduler::ScheduledResourceRequest>
+ weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest);
};
@@ -356,10 +392,12 @@ class ResourceScheduler::Client {
void ScheduleRequest(net::URLRequest* url_request,
ScheduledResourceRequest* request) {
SetRequestAttributes(request, DetermineRequestAttributes(request));
- if (ShouldStartRequest(request) == START_REQUEST)
- StartRequest(request);
- else
+ if (ShouldStartRequest(request) == START_REQUEST) {
+ // New requests can be started synchronously without issue.
+ StartRequest(request, START_SYNC);
+ } else {
pending_requests_.Insert(request);
+ }
}
void RemoveRequest(ScheduledResourceRequest* request) {
@@ -385,8 +423,9 @@ class ResourceScheduler::Client {
ScheduledResourceRequest* request =
*pending_requests_.GetNextHighestIterator();
pending_requests_.Erase(request);
- // StartRequest() may modify pending_requests_. TODO(ricea): Does it?
- StartRequest(request);
+ // Starting requests asynchronously ensures no side effects, and avoids
+ // starting a bunch of requests that may be about to be deleted.
+ StartRequest(request, START_ASYNC);
}
RequestSet unowned_requests;
for (RequestSet::iterator it = in_flight_requests_.begin();
@@ -716,9 +755,10 @@ class ResourceScheduler::Client {
return false;
}
- void StartRequest(ScheduledResourceRequest* request) {
+ void StartRequest(ScheduledResourceRequest* request,
+ StartMode start_mode) {
InsertInFlightRequest(request);
- request->Start();
+ request->Start(start_mode);
}
// ShouldStartRequest is the main scheduling algorithm.
@@ -890,7 +930,7 @@ class ResourceScheduler::Client {
if (query_result == START_REQUEST) {
pending_requests_.Erase(request);
- StartRequest(request);
+ StartRequest(request, START_ASYNC);
// StartRequest can modify the pending list, so we (re)start evaluation
// from the currently highest priority request. Avoid copying a singular
@@ -1043,13 +1083,13 @@ scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
// 2. Most unittests don't send the IPCs needed to register Clients.
// 3. The tab is closed while a RequestResource IPC is in flight.
unowned_requests_.insert(request.get());
- request->Start();
- return request.Pass();
+ request->Start(START_SYNC);
+ return std::move(request);
}
Client* client = it->second;
client->ScheduleRequest(url_request, request.get());
- return request.Pass();
+ return std::move(request);
}
void ResourceScheduler::RemoveRequest(ScheduledResourceRequest* request) {
@@ -1086,7 +1126,7 @@ void ResourceScheduler::OnClientDeleted(int child_id, int route_id) {
DCHECK(CalledOnValidThread());
ClientId client_id = MakeClientId(child_id, route_id);
ClientMap::iterator it = client_map_.find(client_id);
- CHECK(it != client_map_.end());
+ DCHECK(it != client_map_.end());
Client* client = it->second;
// ResourceDispatcherHost cancels all requests except for cross-renderer
diff --git a/chromium/content/browser/loader/resource_scheduler.h b/chromium/content/browser/loader/resource_scheduler.h
index a50324b5a59..444d97d1693 100644
--- a/chromium/content/browser/loader/resource_scheduler.h
+++ b/chromium/content/browser/loader/resource_scheduler.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_LOADER_RESOURCE_SCHEDULER_H_
#define CONTENT_BROWSER_LOADER_RESOURCE_SCHEDULER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <set>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/timer/timer.h"
@@ -218,7 +221,7 @@ class CONTENT_EXPORT ResourceScheduler : public base::NonThreadSafe {
};
class Client;
- typedef int64 ClientId;
+ typedef int64_t ClientId;
typedef std::map<ClientId, Client*> ClientMap;
typedef std::set<ScheduledResourceRequest*> RequestSet;
diff --git a/chromium/content/browser/loader/resource_scheduler_filter.cc b/chromium/content/browser/loader/resource_scheduler_filter.cc
index 2777eaae121..0738ec188fe 100644
--- a/chromium/content/browser/loader/resource_scheduler_filter.cc
+++ b/chromium/content/browser/loader/resource_scheduler_filter.cc
@@ -4,6 +4,9 @@
#include "content/browser/loader/resource_scheduler_filter.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_scheduler.h"
#include "content/common/frame_messages.h"
@@ -12,9 +15,8 @@
namespace content {
namespace {
-const uint32 kFilteredMessageClasses[] = {
- FrameMsgStart,
- ViewMsgStart,
+const uint32_t kFilteredMessageClasses[] = {
+ FrameMsgStart, ViewMsgStart,
};
} // namespace
diff --git a/chromium/content/browser/loader/resource_scheduler_unittest.cc b/chromium/content/browser/loader/resource_scheduler_unittest.cc
index 3aaf23d5977..1399b52dde3 100644
--- a/chromium/content/browser/loader/resource_scheduler_unittest.cc
+++ b/chromium/content/browser/loader/resource_scheduler_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/resource_scheduler.h"
+#include <utility>
+
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
@@ -53,8 +55,8 @@ class TestRequest : public ResourceController {
scoped_ptr<ResourceThrottle> throttle,
ResourceScheduler* scheduler)
: started_(false),
- url_request_(url_request.Pass()),
- throttle_(throttle.Pass()),
+ url_request_(std::move(url_request)),
+ throttle_(std::move(throttle)),
scheduler_(scheduler) {
throttle_->set_controller_for_testing(this);
}
@@ -102,10 +104,10 @@ class CancelingTestRequest : public TestRequest {
CancelingTestRequest(scoped_ptr<net::URLRequest> url_request,
scoped_ptr<ResourceThrottle> throttle,
ResourceScheduler* scheduler)
- : TestRequest(url_request.Pass(), throttle.Pass(), scheduler) {}
+ : TestRequest(std::move(url_request), std::move(throttle), scheduler) {}
void set_request_to_cancel(scoped_ptr<TestRequest> request_to_cancel) {
- request_to_cancel_ = request_to_cancel.Pass();
+ request_to_cancel_ = std::move(request_to_cancel);
}
private:
@@ -181,7 +183,7 @@ class ResourceSchedulerTest : public testing::Test {
int route_id) {
scoped_ptr<net::URLRequest> url_request(
context_.CreateRequest(GURL(url), priority, NULL));
- return url_request.Pass();
+ return url_request;
}
scoped_ptr<net::URLRequest> NewURLRequest(const char* url,
@@ -238,8 +240,8 @@ class ResourceSchedulerTest : public testing::Test {
NewURLRequestWithChildAndRoute(url, priority, child_id, route_id));
scoped_ptr<ResourceThrottle> throttle(scheduler_->ScheduleRequest(
child_id, route_id, is_async, url_request.get()));
- TestRequest* request =
- new TestRequest(url_request.Pass(), throttle.Pass(), scheduler());
+ TestRequest* request = new TestRequest(std::move(url_request),
+ std::move(throttle), scheduler());
request->Start();
return request;
}
@@ -282,7 +284,9 @@ TEST_F(ResourceSchedulerTest, OneLowLoadsUntilIdle) {
EXPECT_TRUE(high->started());
EXPECT_TRUE(low->started());
EXPECT_FALSE(low2->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
}
@@ -293,8 +297,15 @@ TEST_F(ResourceSchedulerTest, OneLowLoadsUntilBodyInserted) {
EXPECT_TRUE(high->started());
EXPECT_TRUE(low->started());
EXPECT_FALSE(low2->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
+ // TODO(mmenke): The name of this test implies this should be false.
+ // Investigate if this is now expected, remove or update this test if it is.
+ EXPECT_TRUE(low2->started());
+
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
}
@@ -305,9 +316,13 @@ TEST_F(ResourceSchedulerTest, OneLowLoadsUntilCriticalComplete) {
EXPECT_TRUE(high->started());
EXPECT_TRUE(low->started());
EXPECT_FALSE(low2->started());
+
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(low2->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
}
@@ -319,7 +334,9 @@ TEST_F(ResourceSchedulerTest, LowDoesNotBlockCriticalComplete) {
EXPECT_TRUE(low->started());
EXPECT_TRUE(lowest->started());
EXPECT_FALSE(lowest2->started());
+
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(lowest2->started());
}
@@ -335,8 +352,10 @@ TEST_F(ResourceSchedulerTest, OneLowLoadsUntilBodyInsertedExceptSpdy) {
EXPECT_TRUE(low_spdy->started());
EXPECT_TRUE(low->started());
EXPECT_FALSE(low2->started());
+
scheduler()->OnWillInsertBody(kChildId, kRouteId);
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
}
@@ -367,9 +386,13 @@ TEST_F(ResourceSchedulerTest, StartMultipleLowRequestsWhenIdle) {
EXPECT_TRUE(high2->started());
EXPECT_TRUE(low->started());
EXPECT_FALSE(low2->started());
+
high1.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(low2->started());
+
high2.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
}
@@ -382,16 +405,18 @@ TEST_F(ResourceSchedulerTest, CancelOtherRequestsWhileResuming) {
scoped_ptr<ResourceThrottle> throttle(scheduler()->ScheduleRequest(
kChildId, kRouteId, true, url_request.get()));
scoped_ptr<CancelingTestRequest> low2(new CancelingTestRequest(
- url_request.Pass(), throttle.Pass(), scheduler()));
+ std::move(url_request), std::move(throttle), scheduler()));
low2->Start();
scoped_ptr<TestRequest> low3(NewRequest("http://host/low3", net::LOWEST));
- low2->set_request_to_cancel(low3.Pass());
+ low2->set_request_to_cancel(std::move(low3));
scoped_ptr<TestRequest> low4(NewRequest("http://host/low4", net::LOWEST));
EXPECT_TRUE(high->started());
EXPECT_FALSE(low2->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low1->started());
EXPECT_TRUE(low2->started());
EXPECT_TRUE(low4->started());
@@ -421,10 +446,14 @@ TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) {
net::LOWEST));
EXPECT_FALSE(second_last_singlehost->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(second_last_singlehost->started());
EXPECT_FALSE(last_singlehost->started());
+
lows_singlehost.erase(lows_singlehost.begin());
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(last_singlehost->started());
// Queue more requests from different hosts until we reach the total limit.
@@ -432,6 +461,7 @@ TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) {
kMaxNumDelayableRequestsPerClient - kMaxNumDelayableRequestsPerHost;
EXPECT_GT(expected_slots_left, 0);
ScopedVector<TestRequest> lows_different_host;
+ base::RunLoop().RunUntilIdle();
for (int i = 0; i < expected_slots_left; ++i) {
string url = "http://host" + base::IntToString(i) + "/low";
lows_different_host.push_back(NewRequest(url.c_str(), net::LOWEST));
@@ -439,7 +469,7 @@ TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) {
}
scoped_ptr<TestRequest> last_different_host(NewRequest("http://host_new/last",
- net::LOWEST));
+ net::LOWEST));
EXPECT_FALSE(last_different_host->started());
}
@@ -452,6 +482,7 @@ TEST_F(ResourceSchedulerTest, RaisePriorityAndStart) {
EXPECT_FALSE(request->started());
ChangeRequestPriority(request.get(), net::HIGHEST);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(request->started());
}
@@ -466,6 +497,7 @@ TEST_F(ResourceSchedulerTest, RaisePriorityInQueue) {
EXPECT_FALSE(idle->started());
ChangeRequestPriority(request.get(), net::LOWEST);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
EXPECT_FALSE(idle->started());
@@ -478,6 +510,7 @@ TEST_F(ResourceSchedulerTest, RaisePriorityInQueue) {
scheduler()->OnWillInsertBody(kChildId, kRouteId);
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(request->started());
EXPECT_FALSE(idle->started());
@@ -494,6 +527,7 @@ TEST_F(ResourceSchedulerTest, LowerPriority) {
EXPECT_FALSE(idle->started());
ChangeRequestPriority(request.get(), net::IDLE);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
EXPECT_FALSE(idle->started());
@@ -509,6 +543,7 @@ TEST_F(ResourceSchedulerTest, LowerPriority) {
scheduler()->OnWillInsertBody(kChildId, kRouteId);
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
EXPECT_TRUE(idle->started());
@@ -532,14 +567,17 @@ TEST_F(ResourceSchedulerTest, ReprioritizedRequestGoesToBackOfQueue) {
}
ChangeRequestPriority(request.get(), net::IDLE);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
EXPECT_FALSE(idle->started());
ChangeRequestPriority(request.get(), net::LOWEST);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
EXPECT_FALSE(idle->started());
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
EXPECT_FALSE(idle->started());
}
@@ -560,10 +598,12 @@ TEST_F(ResourceSchedulerTest, HigherIntraPriorityGoesToFrontOfQueue) {
EXPECT_FALSE(request->started());
ChangeRequestPriority(request.get(), net::IDLE, 1);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
scheduler()->OnWillInsertBody(kChildId, kRouteId);
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(request->started());
}
@@ -617,6 +657,7 @@ TEST_F(ResourceSchedulerTest, SpdyProxySchedulesImmediately) {
EXPECT_FALSE(request->started());
scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(request->started());
scoped_ptr<TestRequest> after(NewRequest("http://host/after", net::IDLE));
@@ -640,9 +681,11 @@ TEST_F(ResourceSchedulerTest, NewSpdyHostInDelayableRequests) {
http_server_properties_.SetSupportsSpdy(
net::HostPortPair("spdyhost1", 8080), true);
low1_spdy.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low1->started());
low1.reset();
+ base::RunLoop().RunUntilIdle();
scoped_ptr<TestRequest> low2_spdy(
NewRequest("http://spdyhost2:8080/low", net::IDLE));
// Reprioritize a request after we learn the server supports SPDY.
@@ -650,6 +693,7 @@ TEST_F(ResourceSchedulerTest, NewSpdyHostInDelayableRequests) {
http_server_properties_.SetSupportsSpdy(
net::HostPortPair("spdyhost2", 8080), true);
ChangeRequestPriority(low2_spdy.get(), net::LOWEST);
+ base::RunLoop().RunUntilIdle();
scoped_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
EXPECT_TRUE(low2->started());
}
@@ -749,9 +793,10 @@ TEST_F(ResourceSchedulerTest, UnthrottleNewlyVisibleClient) {
scheduler()->OnVisibilityChanged(
kBackgroundChildId, kBackgroundRouteId, true);
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
scheduler()->GetClientStateForTesting(kBackgroundChildId,
- kBackgroundRouteId));
+ kBackgroundRouteId));
EXPECT_TRUE(request->started());
}
@@ -770,6 +815,7 @@ TEST_F(ResourceSchedulerTest, UnthrottleNewlyAudibleClient) {
scheduler()->OnAudibilityChanged(
kBackgroundChildId, kBackgroundRouteId, true);
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(ResourceScheduler::ACTIVE_AND_LOADING,
scheduler()->GetClientStateForTesting(kBackgroundChildId,
kBackgroundRouteId));
@@ -843,8 +889,8 @@ TEST_F(ResourceSchedulerTest, ThrottledClientStartsNextHighestPriorityRequest) {
EXPECT_FALSE(low->started());
EXPECT_FALSE(high->started());
- // request->CancelRequest();
request->Cancel();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(high->started());
EXPECT_FALSE(low->started());
}
@@ -864,7 +910,8 @@ TEST_F(ResourceSchedulerTest, ThrottledSpdyProxySchedulesImmediately) {
EXPECT_FALSE(request->started());
scheduler()->OnReceivedSpdyProxiedHttpResponse(kBackgroundChildId,
- kBackgroundRouteId);
+ kBackgroundRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(request->started());
scoped_ptr<TestRequest> after(
@@ -890,7 +937,8 @@ TEST_F(ResourceSchedulerTest, CoalescedClientIssuesNoRequests) {
EXPECT_FALSE(request->started());
scheduler()->OnReceivedSpdyProxiedHttpResponse(kBackgroundChildId,
- kBackgroundRouteId);
+ kBackgroundRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(high->started());
scoped_ptr<TestRequest> after(
@@ -915,7 +963,8 @@ TEST_F(ResourceSchedulerTest, CoalescedSpdyProxyWaits) {
EXPECT_FALSE(request->started());
scheduler()->OnReceivedSpdyProxiedHttpResponse(kBackgroundChildId,
- kBackgroundRouteId);
+ kBackgroundRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request->started());
scoped_ptr<TestRequest> after(
@@ -1687,6 +1736,7 @@ TEST_F(ResourceSchedulerTest, FullVisibleLoadedCorrectlyUnthrottle) {
scheduler()->OnLoadingStateChanged(
kBackgroundChildId2, kBackgroundRouteId2, true);
scheduler()->OnLoadingStateChanged(kChildId2, kRouteId2, true);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(scheduler()->active_clients_loaded());
EXPECT_EQ(ResourceScheduler::THROTTLED,
scheduler()->GetClientStateForTesting(kBackgroundChildId,
@@ -1709,6 +1759,7 @@ TEST_F(ResourceSchedulerTest, FullVisibleLoadedCorrectlyUnthrottle) {
// 2 visible loaded, 1 hidden loading, 1 hidden loaded
scheduler()->OnLoadingStateChanged(kChildId, kRouteId, true);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(scheduler()->active_clients_loaded());
EXPECT_EQ(ResourceScheduler::UNTHROTTLED,
scheduler()->GetClientStateForTesting(kBackgroundChildId,
@@ -1725,6 +1776,7 @@ TEST_F(ResourceSchedulerTest, FullVisibleLoadedCorrectlyUnthrottle) {
// 1 visible and 1 hidden loaded, 1 visible and 1 hidden loading
scheduler()->OnLoadingStateChanged(kChildId, kRouteId, false);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(scheduler()->active_clients_loaded());
EXPECT_EQ(ResourceScheduler::THROTTLED,
scheduler()->GetClientStateForTesting(kBackgroundChildId,
@@ -1801,6 +1853,7 @@ TEST_F(ResourceSchedulerTest, CoalescedClientCreationStartsTimer) {
EXPECT_FALSE(mock_timer_->IsRunning());
scheduler()->OnLoadingStateChanged(
kBackgroundChildId, kBackgroundRouteId, true);
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(ResourceScheduler::COALESCED,
scheduler()->GetClientStateForTesting(kBackgroundChildId,
kBackgroundRouteId));
@@ -2024,6 +2077,7 @@ TEST_F(ResourceSchedulerTest, CoalescedRequestsIssueOnTimer) {
EXPECT_FALSE(low->started());
FireCoalescingTimer();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(high->started());
EXPECT_TRUE(low->started());
@@ -2082,6 +2136,7 @@ TEST_F(ResourceSchedulerTest, CoalescedRequestsUnthrottleCorrectlyOnTimer) {
EXPECT_FALSE(low_spdy->started());
FireCoalescingTimer();
+ base::RunLoop().RunUntilIdle();
// All high priority requests should issue.
EXPECT_TRUE(high->started());
@@ -2115,6 +2170,7 @@ TEST_F(ResourceSchedulerTest, CoalescedRequestsWaitForNextTimer) {
EXPECT_FALSE(high->started());
FireCoalescingTimer();
+ base::RunLoop().RunUntilIdle();
scoped_ptr<TestRequest> high2(
NewBackgroundRequest("http://host/high2", net::HIGHEST));
@@ -2126,6 +2182,7 @@ TEST_F(ResourceSchedulerTest, CoalescedRequestsWaitForNextTimer) {
EXPECT_FALSE(low->started());
FireCoalescingTimer();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(high->started());
EXPECT_TRUE(high2->started());
@@ -2163,14 +2220,14 @@ TEST_F(ResourceSchedulerTest, GetVisualSignalFromRenderViewHost) {
// Check initial visibility is set correctly.
EXPECT_EQ(scheduler->IsClientVisibleForTesting(rvh1->GetProcess()->GetID(),
rvh1->GetRoutingID()),
- !rvh1->is_hidden());
+ !rvh1->GetWidget()->is_hidden());
EXPECT_EQ(scheduler->IsClientVisibleForTesting(rvh2->GetProcess()->GetID(),
rvh1->GetRoutingID()),
- !rvh2->is_hidden());
+ !rvh2->GetWidget()->is_hidden());
- // 1 visible, 1 hidden
- rvh1->WasShown(ui::LatencyInfo());
- rvh2->WasHidden();
+ // 1 visible, 1 hidden.
+ rvh1->GetWidget()->WasShown(ui::LatencyInfo());
+ rvh2->GetWidget()->WasHidden();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(scheduler->IsClientVisibleForTesting(rvh1->GetProcess()->GetID(),
@@ -2179,8 +2236,8 @@ TEST_F(ResourceSchedulerTest, GetVisualSignalFromRenderViewHost) {
rvh2->GetRoutingID()));
// Flip the visibility and check again.
- rvh1->WasHidden();
- rvh2->WasShown(ui::LatencyInfo());
+ rvh1->GetWidget()->WasHidden();
+ rvh2->GetWidget()->WasShown(ui::LatencyInfo());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(scheduler->IsClientVisibleForTesting(rvh1->GetProcess()->GetID(),
@@ -2257,7 +2314,9 @@ TEST_F(ResourceSchedulerTest, OutstandingRequestLimitDelays) {
EXPECT_TRUE(high->started());
EXPECT_FALSE(low->started());
EXPECT_FALSE(low2->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low->started());
EXPECT_TRUE(low2->started());
}
@@ -2274,9 +2333,11 @@ TEST_F(ResourceSchedulerTest, RequestStartedAfterClientDeleted) {
scoped_ptr<TestRequest> lowest2(NewRequestWithChildAndRoute(
"http://host/lowest", net::LOWEST, kChildId2, kRouteId2));
EXPECT_FALSE(lowest2->started());
+
scheduler_->OnClientDeleted(kChildId2, kRouteId2);
high.reset();
lowest1.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(lowest2->started());
}
@@ -2297,9 +2358,11 @@ TEST_F(ResourceSchedulerTest, RequestStartedAfterClientDeletedManyDelayable) {
scoped_ptr<TestRequest> lowest(NewRequestWithChildAndRoute(
"http://host/lowest", net::LOWEST, kChildId2, kRouteId2));
EXPECT_FALSE(lowest->started());
+
scheduler_->OnClientDeleted(kChildId2, kRouteId2);
high.reset();
delayable_requests.clear();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(lowest->started());
}
@@ -2344,7 +2407,9 @@ TEST_F(ResourceSchedulerTest, DefaultLayoutBlockingPriority) {
EXPECT_TRUE(low2->started());
EXPECT_TRUE(lowest->started());
EXPECT_FALSE(lowest2->started());
+
lowest.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(lowest2->started());
}
@@ -2391,14 +2456,20 @@ TEST_F(ResourceSchedulerTest, IncreaseLayoutBlockingPriority) {
EXPECT_FALSE(low2->started());
EXPECT_FALSE(lowest->started());
EXPECT_FALSE(lowest2->started());
+
low.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
EXPECT_FALSE(lowest->started());
EXPECT_FALSE(lowest2->started());
+
low2.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(lowest->started());
EXPECT_FALSE(lowest2->started());
+
lowest.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(lowest2->started());
}
@@ -2432,12 +2503,18 @@ TEST_F(ResourceSchedulerTest, UseLayoutBlockingThresholdOne) {
EXPECT_TRUE(high2->started());
EXPECT_FALSE(low->started());
EXPECT_FALSE(low2->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low->started());
EXPECT_FALSE(low2->started());
+
high2.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(low2->started());
+
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
}
@@ -2473,13 +2550,19 @@ TEST_F(ResourceSchedulerTest, UseLayoutBlockingThresholdTwo) {
EXPECT_TRUE(high3->started());
EXPECT_FALSE(low->started());
EXPECT_FALSE(low2->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low->started());
EXPECT_FALSE(low2->started());
+
high2.reset();
high3.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(low2->started());
+
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low2->started());
}
@@ -2513,8 +2596,10 @@ TEST_F(ResourceSchedulerTest, TwoDelayableLoadsUntilBodyInserted) {
EXPECT_TRUE(low->started());
EXPECT_TRUE(low2->started());
EXPECT_FALSE(low3->started());
+
high.reset();
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low3->started());
}
@@ -2552,12 +2637,16 @@ TEST_F(ResourceSchedulerTest,
EXPECT_FALSE(low->started());
EXPECT_FALSE(low2->started());
EXPECT_FALSE(low3->started());
+
high.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low->started());
EXPECT_TRUE(low2->started());
EXPECT_FALSE(low3->started());
+
high2.reset();
scheduler()->OnWillInsertBody(kChildId, kRouteId);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(low3->started());
}
@@ -2637,7 +2726,7 @@ TEST_F(ResourceSchedulerTest,
}
scoped_ptr<TestRequest> last_different_host(NewRequest("http://host_new/last",
- net::LOWEST));
+ net::LOWEST));
EXPECT_FALSE(last_different_host->started());
}
diff --git a/chromium/content/browser/loader/stream_resource_handler.h b/chromium/content/browser/loader/stream_resource_handler.h
index 37f4d0da2ea..6bc4253a2f3 100644
--- a/chromium/content/browser/loader/stream_resource_handler.h
+++ b/chromium/content/browser/loader/stream_resource_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_LOADER_STREAM_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_LOADER_STREAM_RESOURCE_HANDLER_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/loader/resource_handler.h"
diff --git a/chromium/content/browser/loader/sync_resource_handler.h b/chromium/content/browser/loader/sync_resource_handler.h
index fb028475fbb..49b0d919da0 100644
--- a/chromium/content/browser/loader/sync_resource_handler.h
+++ b/chromium/content/browser/loader/sync_resource_handler.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_LOADER_SYNC_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_LOADER_SYNC_RESOURCE_HANDLER_H_
+#include <stdint.h>
+
#include <string>
#include "content/browser/loader/resource_handler.h"
@@ -56,7 +58,7 @@ class SyncResourceHandler : public ResourceHandler {
SyncLoadResult result_;
IPC::Message* result_message_;
ResourceDispatcherHostImpl* rdh_;
- int64 total_transfer_size_;
+ int64_t total_transfer_size_;
};
} // namespace content
diff --git a/chromium/content/browser/loader/temporary_file_stream.cc b/chromium/content/browser/loader/temporary_file_stream.cc
index fc57c8aad89..c8bb3338f5c 100644
--- a/chromium/content/browser/loader/temporary_file_stream.cc
+++ b/chromium/content/browser/loader/temporary_file_stream.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/temporary_file_stream.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_proxy.h"
@@ -43,7 +45,7 @@ void DidCreateTemporaryFile(
scoped_ptr<net::FileStream> file_stream(
new net::FileStream(file_proxy->TakeFile(), task_runner));
- callback.Run(error_code, file_stream.Pass(), deletable_file.get());
+ callback.Run(error_code, std::move(file_stream), deletable_file.get());
}
} // namespace
diff --git a/chromium/content/browser/loader/temporary_file_stream_unittest.cc b/chromium/content/browser/loader/temporary_file_stream_unittest.cc
index af57f0824ec..a5fe1453312 100644
--- a/chromium/content/browser/loader/temporary_file_stream_unittest.cc
+++ b/chromium/content/browser/loader/temporary_file_stream_unittest.cc
@@ -5,13 +5,13 @@
#include "content/browser/loader/temporary_file_stream.h"
#include <string.h>
-
#include <string>
+#include <utility>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/file_stream.h"
@@ -42,7 +42,7 @@ class WaitForFileStream {
scoped_ptr<net::FileStream> file_stream,
ShareableFileReference* deletable_file) {
error_ = error;
- file_stream_ = file_stream.Pass();
+ file_stream_ = std::move(file_stream);
deletable_file_ = deletable_file;
loop_.Quit();
}
diff --git a/chromium/content/browser/loader/throttling_resource_handler.cc b/chromium/content/browser/loader/throttling_resource_handler.cc
index 0378423ba15..93b9ad74836 100644
--- a/chromium/content/browser/loader/throttling_resource_handler.cc
+++ b/chromium/content/browser/loader/throttling_resource_handler.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/throttling_resource_handler.h"
+#include <utility>
+
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/common/resource_response.h"
@@ -15,9 +17,9 @@ ThrottlingResourceHandler::ThrottlingResourceHandler(
scoped_ptr<ResourceHandler> next_handler,
net::URLRequest* request,
ScopedVector<ResourceThrottle> throttles)
- : LayeredResourceHandler(request, next_handler.Pass()),
+ : LayeredResourceHandler(request, std::move(next_handler)),
deferred_stage_(DEFERRED_NONE),
- throttles_(throttles.Pass()),
+ throttles_(std::move(throttles)),
next_index_(0),
cancelled_by_resource_throttle_(false) {
for (size_t i = 0; i < throttles_.size(); ++i) {
diff --git a/chromium/content/browser/loader/throttling_resource_handler.h b/chromium/content/browser/loader/throttling_resource_handler.h
index 0d1287d644e..6abefc46e04 100644
--- a/chromium/content/browser/loader/throttling_resource_handler.h
+++ b/chromium/content/browser/loader/throttling_resource_handler.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_LOADER_THROTTLING_RESOURCE_HANDLER_H_
#define CONTENT_BROWSER_LOADER_THROTTLING_RESOURCE_HANDLER_H_
+#include <stddef.h>
+
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "content/browser/loader/layered_resource_handler.h"
diff --git a/chromium/content/browser/loader/upload_data_stream_builder.cc b/chromium/content/browser/loader/upload_data_stream_builder.cc
index 2f30f94a7d6..bcabe99484c 100644
--- a/chromium/content/browser/loader/upload_data_stream_builder.cc
+++ b/chromium/content/browser/loader/upload_data_stream_builder.cc
@@ -4,11 +4,14 @@
#include "content/browser/loader/upload_data_stream_builder.h"
+#include <stdint.h>
+
#include <limits>
#include <utility>
#include <vector>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/fileapi/upload_file_system_file_element_reader.h"
#include "content/common/resource_request_body.h"
@@ -77,47 +80,46 @@ scoped_ptr<net::UploadDataStream> UploadDataStreamBuilder::Build(
storage::BlobStorageContext* blob_context,
storage::FileSystemContext* file_system_context,
base::SingleThreadTaskRunner* file_task_runner) {
- ScopedVector<net::UploadElementReader> element_readers;
+ std::vector<scoped_ptr<net::UploadElementReader>> element_readers;
for (const auto& element : *body->elements()) {
switch (element.type()) {
case ResourceRequestBody::Element::TYPE_BYTES:
- element_readers.push_back(new BytesElementReader(body, element));
+ element_readers.push_back(
+ make_scoped_ptr(new BytesElementReader(body, element)));
break;
case ResourceRequestBody::Element::TYPE_FILE:
- element_readers.push_back(
- new FileElementReader(body, file_task_runner, element));
+ element_readers.push_back(make_scoped_ptr(
+ new FileElementReader(body, file_task_runner, element)));
break;
case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
// If |body| contains any filesystem URLs, the caller should have
// supplied a FileSystemContext.
DCHECK(file_system_context);
element_readers.push_back(
- new content::UploadFileSystemFileElementReader(
- file_system_context,
- element.filesystem_url(),
- element.offset(),
- element.length(),
- element.expected_modification_time()));
+ make_scoped_ptr(new content::UploadFileSystemFileElementReader(
+ file_system_context, element.filesystem_url(), element.offset(),
+ element.length(), element.expected_modification_time())));
break;
case ResourceRequestBody::Element::TYPE_BLOB: {
DCHECK_EQ(std::numeric_limits<uint64_t>::max(), element.length());
DCHECK_EQ(0ul, element.offset());
scoped_ptr<storage::BlobDataHandle> handle =
blob_context->GetBlobDataFromUUID(element.blob_uuid());
- element_readers.push_back(new storage::UploadBlobElementReader(
- handle.Pass(), file_system_context, file_task_runner));
+ element_readers.push_back(
+ make_scoped_ptr(new storage::UploadBlobElementReader(
+ std::move(handle), file_system_context, file_task_runner)));
break;
}
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
+ case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
case ResourceRequestBody::Element::TYPE_UNKNOWN:
NOTREACHED();
break;
}
}
- return make_scoped_ptr(
- new net::ElementsUploadDataStream(element_readers.Pass(),
- body->identifier()));
+ return make_scoped_ptr(new net::ElementsUploadDataStream(
+ std::move(element_readers), body->identifier()));
}
} // namespace content
diff --git a/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc b/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
index ae79dd93cf1..fc92cc185aa 100644
--- a/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
+++ b/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
@@ -4,11 +4,14 @@
#include "content/browser/loader/upload_data_stream_builder.h"
+#include <stdint.h>
+
#include <algorithm>
#include <string>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -41,10 +44,10 @@ TEST(UploadDataStreamBuilderTest, CreateUploadDataStream) {
const std::string kBlobData = "blobdata";
const char kData[] = "123";
const base::FilePath::StringType kFilePath = FILE_PATH_LITERAL("abc");
- const uint64 kFileOffset = 10U;
- const uint64 kFileLength = 100U;
+ const uint64_t kFileOffset = 10U;
+ const uint64_t kFileLength = 100U;
const base::Time kFileTime = base::Time::FromDoubleT(999);
- const int64 kIdentifier = 12345;
+ const int64_t kIdentifier = 12345;
BlobStorageContext context;
BlobDataBuilder builder(kBlob);
@@ -81,7 +84,7 @@ TEST(UploadDataStreamBuilderTest, CreateUploadDataStream) {
const storage::UploadBlobElementReader* r3 =
static_cast<storage::UploadBlobElementReader*>(
- (*upload->GetElementReaders())[2]);
+ (*upload->GetElementReaders())[2].get());
ASSERT_TRUE(r3);
EXPECT_EQ("blobuuid", r3->uuid());
}
@@ -158,7 +161,7 @@ TEST(UploadDataStreamBuilderTest, ResetUploadStreamWithBlob) {
const std::string kBlob = "blobuuid";
const std::string kBlobData = "blobdata";
const int kBlobDataLength = 8;
- const int64 kIdentifier = 12345;
+ const int64_t kIdentifier = 12345;
BlobStorageContext blob_storage_context;
BlobDataBuilder builder(kBlob);
diff --git a/chromium/content/browser/mach_broker_mac.h b/chromium/content/browser/mach_broker_mac.h
index a1e47b9ef94..f5d50addc3e 100644
--- a/chromium/content/browser/mach_broker_mac.h
+++ b/chromium/content/browser/mach_broker_mac.h
@@ -12,6 +12,7 @@
#include "base/mac/dispatch_source_mach.h"
#include "base/mac/scoped_mach_port.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/process/port_provider_mac.h"
diff --git a/chromium/content/browser/mach_broker_mac.mm b/chromium/content/browser/mach_broker_mac.mm
index d42bbeedbf4..4cf3bb6c77c 100644
--- a/chromium/content/browser/mach_broker_mac.mm
+++ b/chromium/content/browser/mach_broker_mac.mm
@@ -200,7 +200,7 @@ void MachBroker::HandleRequest() {
options,
0,
sizeof(msg),
- server_port_,
+ server_port_.get(),
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL);
if (kr != KERN_SUCCESS) {
diff --git a/chromium/content/browser/manifest/manifest_browsertest.cc b/chromium/content/browser/manifest/manifest_browsertest.cc
index 0393710aef4..8dab4696ecd 100644
--- a/chromium/content/browser/manifest/manifest_browsertest.cc
+++ b/chromium/content/browser/manifest/manifest_browsertest.cc
@@ -2,7 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <utility>
+
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -32,9 +36,9 @@ class MockWebContentsDelegate : public WebContentsDelegate {
}
bool AddMessageToConsole(WebContents* source,
- int32 level,
+ int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id) override;
private:
@@ -46,13 +50,10 @@ class ManifestBrowserTest : public ContentBrowserTest {
protected:
friend MockWebContentsDelegate;
- ManifestBrowserTest()
- : console_error_count_(0) {
- cors_embedded_test_server_.reset(new net::test_server::EmbeddedTestServer);
- base::FilePath test_data_dir;
- CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
- cors_embedded_test_server_->ServeFilesFromDirectory(
- test_data_dir.AppendASCII("content/test/data/"));
+ ManifestBrowserTest() : console_error_count_(0), has_manifest_(false) {
+ cors_embedded_test_server_.reset(new net::EmbeddedTestServer);
+ cors_embedded_test_server_->ServeFilesFromSourceDirectory(
+ "content/test/data");
}
~ManifestBrowserTest() override {}
@@ -75,15 +76,33 @@ class ManifestBrowserTest : public ContentBrowserTest {
message_loop_runner_->Run();
}
+ void HasManifestAndWait() {
+ shell()->web_contents()->HasManifest(
+ base::Bind(&ManifestBrowserTest::OnHasManifest,
+ base::Unretained(this)));
+
+ message_loop_runner_ = new MessageLoopRunner();
+ message_loop_runner_->Run();
+ }
+
void OnGetManifest(const Manifest& manifest) {
manifest_ = manifest;
message_loop_runner_->Quit();
}
+ void OnHasManifest(bool has_manifest) {
+ has_manifest_ = has_manifest;
+ message_loop_runner_->Quit();
+ }
+
const Manifest& manifest() const {
return manifest_;
}
+ bool has_manifest() const {
+ return has_manifest_;
+ }
+
unsigned int console_error_count() const {
return console_error_count_;
}
@@ -92,16 +111,17 @@ class ManifestBrowserTest : public ContentBrowserTest {
console_error_count_++;
}
- net::test_server::EmbeddedTestServer* cors_embedded_test_server() const {
+ net::EmbeddedTestServer* cors_embedded_test_server() const {
return cors_embedded_test_server_.get();
}
private:
scoped_refptr<MessageLoopRunner> message_loop_runner_;
scoped_ptr<MockWebContentsDelegate> mock_web_contents_delegate_;
- scoped_ptr<net::test_server::EmbeddedTestServer> cors_embedded_test_server_;
+ scoped_ptr<net::EmbeddedTestServer> cors_embedded_test_server_;
Manifest manifest_;
int console_error_count_;
+ bool has_manifest_;
DISALLOW_COPY_AND_ASSIGN(ManifestBrowserTest);
};
@@ -110,9 +130,9 @@ class ManifestBrowserTest : public ContentBrowserTest {
// to know about |test_|.
bool MockWebContentsDelegate::AddMessageToConsole(
WebContents* source,
- int32 level,
+ int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id) {
DCHECK(source == web_contents_);
@@ -132,11 +152,14 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, NoManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_FALSE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
// If a page manifest points to a 404 URL, requesting the manifest should return
-// the empty manifest.
+// the empty manifest. However, HasManifest will return true.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, 404Manifest) {
GURL test_url = GetTestUrl("manifest", "404-manifest.html");
@@ -146,6 +169,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, 404Manifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
@@ -160,6 +186,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, EmptyManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
@@ -174,6 +203,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, ParseErrorManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(1u, console_error_count());
}
@@ -188,6 +220,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DummyManifest) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
@@ -203,6 +238,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DynamicManifest) {
{
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_FALSE(has_manifest());
}
{
@@ -213,6 +251,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DynamicManifest) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
}
{
@@ -223,6 +264,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DynamicManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
}
EXPECT_EQ(0u, console_error_count());
@@ -232,8 +276,8 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DynamicManifest) {
// rules and requesting the manifest should return an empty manifest (unless the
// response contains CORS headers).
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifest) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
- ASSERT_TRUE(cors_embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
+ ASSERT_TRUE(cors_embedded_test_server()->Start());
ASSERT_NE(embedded_test_server()->port(),
cors_embedded_test_server()->port());
@@ -252,6 +296,8 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
// The purpose of this second load is to make sure the first load is fully
@@ -270,8 +316,8 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifest) {
// If a page's manifest lives in a different origin, it should be accessible if
// it has valid access controls headers.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifestWithAcessControls) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
- ASSERT_TRUE(cors_embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
+ ASSERT_TRUE(cors_embedded_test_server()->Start());
ASSERT_NE(embedded_test_server()->port(),
cors_embedded_test_server()->port());
@@ -290,18 +336,19 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifestWithAcessControls) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
// If a page's manifest is in an insecure origin while the page is in a secure
// origin, requesting the manifest should return the empty manifest.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, MixedContentManifest) {
- scoped_ptr<net::SpawnedTestServer> https_server(new net::SpawnedTestServer(
- net::SpawnedTestServer::TYPE_HTTPS,
- net::BaseTestServer::SSLOptions(net::BaseTestServer::SSLOptions::CERT_OK),
- base::FilePath(FILE_PATH_LITERAL("content/test/data"))));
+ scoped_ptr<net::EmbeddedTestServer> https_server(
+ new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
+ https_server->ServeFilesFromSourceDirectory("content/test/data");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
ASSERT_TRUE(https_server->Start());
GURL test_url =
@@ -319,6 +366,8 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, MixedContentManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
@@ -334,12 +383,15 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, ParsingErrorsManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_EQ(6u, console_error_count());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
}
// If a page has a manifest and the page is navigated to a page without a
// manifest, the page's manifest should be updated.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
{
GURL test_url =
embedded_test_server()->GetURL("/manifest/dummy-manifest.html");
@@ -350,6 +402,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
@@ -364,13 +419,16 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_EQ(0u, console_error_count());
+
+ HasManifestAndWait();
+ EXPECT_FALSE(has_manifest());
}
}
// If a page has a manifest and the page is navigated using pushState (ie. same
// page), it should keep its manifest state.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, PushStateNavigation) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url =
embedded_test_server()->GetURL("/manifest/dummy-manifest.html");
@@ -390,13 +448,16 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, PushStateNavigation) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
}
// If a page has a manifest and is navigated using an anchor (ie. same page), it
// should keep its manifest state.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, AnchorNavigation) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url =
embedded_test_server()->GetURL("/manifest/dummy-manifest.html");
@@ -418,6 +479,10 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, AnchorNavigation) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_EQ(0u, console_error_count());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
+ EXPECT_EQ(0u, console_error_count());
}
namespace {
@@ -433,7 +498,7 @@ scoped_ptr<net::test_server::HttpResponse> CustomHandleRequestForCookies(
"<html><head>"
"<link rel=manifest crossorigin='use-credentials' href=/manifest.json>"
"</head></html>");
- return http_response.Pass();
+ return std::move(http_response);
}
const auto& iter = request.headers.find("Cookie");
@@ -447,7 +512,7 @@ scoped_ptr<net::test_server::HttpResponse> CustomHandleRequestForCookies(
http_response->set_content(
base::StringPrintf("{\"name\": \"%s\"}", iter->second.c_str()));
- return http_response.Pass();
+ return std::move(http_response);
}
} // anonymous namespace
@@ -455,12 +520,12 @@ scoped_ptr<net::test_server::HttpResponse> CustomHandleRequestForCookies(
// This tests that when fetching a Manifest with 'use-credentials' set, the
// cookies associated with it are passed along the request.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, UseCredentialsSendCookies) {
- scoped_ptr<net::test_server::EmbeddedTestServer> custom_embedded_test_server(
- new net::test_server::EmbeddedTestServer());
+ scoped_ptr<net::EmbeddedTestServer> custom_embedded_test_server(
+ new net::EmbeddedTestServer());
custom_embedded_test_server->RegisterRequestHandler(
base::Bind(&CustomHandleRequestForCookies));
- ASSERT_TRUE(custom_embedded_test_server->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(custom_embedded_test_server->Start());
ASSERT_TRUE(SetCookie(shell()->web_contents()->GetBrowserContext(),
custom_embedded_test_server->base_url(),
@@ -472,6 +537,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, UseCredentialsSendCookies) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
// The custom embedded test server will fill the name field with the cookie
@@ -490,7 +558,7 @@ scoped_ptr<net::test_server::HttpResponse> CustomHandleRequestForNoCookies(
http_response->set_content_type("text/html");
http_response->set_content(
"<html><head><link rel=manifest href=/manifest.json></head></html>");
- return http_response.Pass();
+ return std::move(http_response);
}
const auto& iter = request.headers.find("Cookie");
@@ -503,7 +571,7 @@ scoped_ptr<net::test_server::HttpResponse> CustomHandleRequestForNoCookies(
http_response->set_content_type("application/json");
http_response->set_content("{\"name\": \"no cookies\"}");
- return http_response.Pass();
+ return std::move(http_response);
}
} // anonymous namespace
@@ -511,12 +579,12 @@ scoped_ptr<net::test_server::HttpResponse> CustomHandleRequestForNoCookies(
// This tests that when fetching a Manifest without 'use-credentials' set, the
// cookies associated with it are not passed along the request.
IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, NoUseCredentialsNoCookies) {
- scoped_ptr<net::test_server::EmbeddedTestServer> custom_embedded_test_server(
- new net::test_server::EmbeddedTestServer());
+ scoped_ptr<net::EmbeddedTestServer> custom_embedded_test_server(
+ new net::EmbeddedTestServer());
custom_embedded_test_server->RegisterRequestHandler(
base::Bind(&CustomHandleRequestForNoCookies));
- ASSERT_TRUE(custom_embedded_test_server->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(custom_embedded_test_server->Start());
ASSERT_TRUE(SetCookie(shell()->web_contents()->GetBrowserContext(),
custom_embedded_test_server->base_url(),
@@ -528,6 +596,9 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, NoUseCredentialsNoCookies) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
+
+ HasManifestAndWait();
+ EXPECT_TRUE(has_manifest());
EXPECT_EQ(0u, console_error_count());
// The custom embedded test server will fill set the name to 'no cookies' if
diff --git a/chromium/content/browser/manifest/manifest_manager_host.cc b/chromium/content/browser/manifest/manifest_manager_host.cc
index a700139edf2..e6c70b5f877 100644
--- a/chromium/content/browser/manifest/manifest_manager_host.cc
+++ b/chromium/content/browser/manifest/manifest_manager_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/manifest/manifest_manager_host.h"
+#include <stdint.h>
+
#include "base/stl_util.h"
#include "content/common/manifest_manager_messages.h"
#include "content/public/browser/render_frame_host.h"
@@ -31,39 +33,69 @@ ManifestManagerHost::ManifestManagerHost(WebContents* web_contents)
}
ManifestManagerHost::~ManifestManagerHost() {
- STLDeleteValues(&pending_callbacks_);
+ STLDeleteValues(&pending_get_callbacks_);
+ STLDeleteValues(&pending_has_callbacks_);
}
-ManifestManagerHost::CallbackMap* ManifestManagerHost::GetCallbackMapForFrame(
+ManifestManagerHost::GetCallbackMap*
+ManifestManagerHost::GetCallbackMapForFrame(
RenderFrameHost* render_frame_host) {
- FrameCallbackMap::iterator it = pending_callbacks_.find(render_frame_host);
- return it != pending_callbacks_.end() ? it->second : 0;
+ FrameGetCallbackMap::iterator it =
+ pending_get_callbacks_.find(render_frame_host);
+ return it != pending_get_callbacks_.end() ? it->second : nullptr;
}
-void ManifestManagerHost::RenderFrameDeleted(
+ManifestManagerHost::HasCallbackMap*
+ManifestManagerHost::HasCallbackMapForFrame(
RenderFrameHost* render_frame_host) {
- CallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
- if (!callbacks)
- return;
+ FrameHasCallbackMap::iterator it =
+ pending_has_callbacks_.find(render_frame_host);
+ return it != pending_has_callbacks_.end() ? it->second : nullptr;
+}
- // Before deleting the callbacks, make sure they are called with a failure
- // state. Do this in a block so the iterator is destroyed before |callbacks|.
+void ManifestManagerHost::RenderFrameDeleted(
+ RenderFrameHost* render_frame_host) {
{
- CallbackMap::const_iterator it(callbacks);
- for (; !it.IsAtEnd(); it.Advance())
- it.GetCurrentValue()->Run(Manifest());
+ GetCallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
+ if (!callbacks)
+ return;
+
+ // Call the callbacks with a failure state before deleting them. Do this in
+ // a block so the iterator is destroyed before |callbacks|.
+ {
+ GetCallbackMap::const_iterator it(callbacks);
+ for (; !it.IsAtEnd(); it.Advance())
+ it.GetCurrentValue()->Run(Manifest());
+ }
+
+ delete callbacks;
+ pending_get_callbacks_.erase(render_frame_host);
}
- delete callbacks;
- pending_callbacks_.erase(render_frame_host);
+ {
+ HasCallbackMap* callbacks = HasCallbackMapForFrame(render_frame_host);
+ if (!callbacks)
+ return;
+
+ // Call the callbacks with a failure state before deleting them. Do this in
+ // a block so the iterator is destroyed before |callbacks|.
+ {
+ HasCallbackMap::const_iterator it(callbacks);
+ for (; !it.IsAtEnd(); it.Advance())
+ it.GetCurrentValue()->Run(false);
+ }
+
+ delete callbacks;
+ pending_has_callbacks_.erase(render_frame_host);
+ }
}
void ManifestManagerHost::GetManifest(RenderFrameHost* render_frame_host,
const GetManifestCallback& callback) {
- CallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
+ GetCallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
if (!callbacks) {
- callbacks = new CallbackMap();
- pending_callbacks_[render_frame_host] = callbacks;
+ callbacks = new GetCallbackMap();
+ pending_get_callbacks_[render_frame_host] = callbacks;
}
int request_id = callbacks->Add(new GetManifestCallback(callback));
@@ -72,6 +104,20 @@ void ManifestManagerHost::GetManifest(RenderFrameHost* render_frame_host,
render_frame_host->GetRoutingID(), request_id));
}
+void ManifestManagerHost::HasManifest(RenderFrameHost* render_frame_host,
+ const HasManifestCallback& callback) {
+ HasCallbackMap* callbacks = HasCallbackMapForFrame(render_frame_host);
+ if (!callbacks) {
+ callbacks = new HasCallbackMap();
+ pending_has_callbacks_[render_frame_host] = callbacks;
+ }
+
+ int request_id = callbacks->Add(new HasManifestCallback(callback));
+
+ render_frame_host->Send(new ManifestManagerMsg_HasManifest(
+ render_frame_host->GetRoutingID(), request_id));
+}
+
bool ManifestManagerHost::OnMessageReceived(
const IPC::Message& message, RenderFrameHost* render_frame_host) {
bool handled = true;
@@ -80,6 +126,8 @@ bool ManifestManagerHost::OnMessageReceived(
render_frame_host)
IPC_MESSAGE_HANDLER(ManifestManagerHostMsg_RequestManifestResponse,
OnRequestManifestResponse)
+ IPC_MESSAGE_HANDLER(ManifestManagerHostMsg_HasManifestResponse,
+ OnHasManifestResponse)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -90,7 +138,7 @@ void ManifestManagerHost::OnRequestManifestResponse(
RenderFrameHost* render_frame_host,
int request_id,
const Manifest& insecure_manifest) {
- CallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
+ GetCallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
if (!callbacks) {
DVLOG(1) << "Unexpected RequestManifestResponse to from renderer. "
"Killing renderer.";
@@ -150,7 +198,35 @@ void ManifestManagerHost::OnRequestManifestResponse(
callbacks->Remove(request_id);
if (callbacks->IsEmpty()) {
delete callbacks;
- pending_callbacks_.erase(render_frame_host);
+ pending_get_callbacks_.erase(render_frame_host);
+ }
+}
+
+void ManifestManagerHost::OnHasManifestResponse(
+ RenderFrameHost* render_frame_host,
+ int request_id,
+ bool has_manifest) {
+ HasCallbackMap* callbacks = HasCallbackMapForFrame(render_frame_host);
+ if (!callbacks) {
+ DVLOG(1) << "Unexpected HasManifestResponse from renderer. "
+ "Killing renderer.";
+ KillRenderer(render_frame_host);
+ return;
+ }
+
+ HasManifestCallback* callback = callbacks->Lookup(request_id);
+ if (!callback) {
+ DVLOG(1) << "Received a request_id (" << request_id << ") from renderer "
+ "with no associated callback. Killing renderer.";
+ KillRenderer(render_frame_host);
+ return;
+ }
+
+ callback->Run(has_manifest);
+ callbacks->Remove(request_id);
+ if (callbacks->IsEmpty()) {
+ delete callbacks;
+ pending_has_callbacks_.erase(render_frame_host);
}
}
diff --git a/chromium/content/browser/manifest/manifest_manager_host.h b/chromium/content/browser/manifest/manifest_manager_host.h
index 5e932df155a..069a5303b83 100644
--- a/chromium/content/browser/manifest/manifest_manager_host.h
+++ b/chromium/content/browser/manifest/manifest_manager_host.h
@@ -7,6 +7,7 @@
#include "base/callback_forward.h"
#include "base/id_map.h"
+#include "base/macros.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
@@ -23,28 +24,39 @@ class ManifestManagerHost : public WebContentsObserver {
explicit ManifestManagerHost(WebContents* web_contents);
~ManifestManagerHost() override;
- typedef base::Callback<void(const Manifest&)> GetManifestCallback;
+ using GetManifestCallback = base::Callback<void(const Manifest&)>;
+ using HasManifestCallback = base::Callback<void(bool)>;
// Calls the given callback with the manifest associated with the
// given RenderFrameHost. If the frame has no manifest or if getting it failed
// the callback will have an empty manifest.
void GetManifest(RenderFrameHost*, const GetManifestCallback&);
+ // Calls the given callback with a bool indicating whether or not the document
+ // associated with the given RenderFrameHost has a manifest.
+ void HasManifest(RenderFrameHost*, const HasManifestCallback&);
+
// WebContentsObserver
bool OnMessageReceived(const IPC::Message&, RenderFrameHost*) override;
void RenderFrameDeleted(RenderFrameHost*) override;
private:
- typedef IDMap<GetManifestCallback, IDMapOwnPointer> CallbackMap;
- typedef base::hash_map<RenderFrameHost*, CallbackMap*> FrameCallbackMap;
+ using GetCallbackMap = IDMap<GetManifestCallback, IDMapOwnPointer>;
+ using HasCallbackMap = IDMap<HasManifestCallback, IDMapOwnPointer>;
+ using FrameGetCallbackMap = base::hash_map<RenderFrameHost*, GetCallbackMap*>;
+ using FrameHasCallbackMap = base::hash_map<RenderFrameHost*, HasCallbackMap*>;
void OnRequestManifestResponse(
RenderFrameHost*, int request_id, const Manifest&);
+ void OnHasManifestResponse(
+ RenderFrameHost*, int request_id, bool);
// Returns the CallbackMap associated with the given RenderFrameHost, or null.
- CallbackMap* GetCallbackMapForFrame(RenderFrameHost*);
+ GetCallbackMap* GetCallbackMapForFrame(RenderFrameHost*);
+ HasCallbackMap* HasCallbackMapForFrame(RenderFrameHost*);
- FrameCallbackMap pending_callbacks_;
+ FrameGetCallbackMap pending_get_callbacks_;
+ FrameHasCallbackMap pending_has_callbacks_;
DISALLOW_COPY_AND_ASSIGN(ManifestManagerHost);
};
diff --git a/chromium/content/browser/media/android/browser_demuxer_android.cc b/chromium/content/browser/media/android/browser_demuxer_android.cc
index 997b43181ac..9da7170b36f 100644
--- a/chromium/content/browser/media/android/browser_demuxer_android.cc
+++ b/chromium/content/browser/media/android/browser_demuxer_android.cc
@@ -4,6 +4,7 @@
#include "content/browser/media/android/browser_demuxer_android.h"
+#include "base/macros.h"
#include "content/common/media/media_player_messages_android.h"
#include "media/base/android/media_task_runner.h"
#include "media/base/media_switches.h"
diff --git a/chromium/content/browser/media/android/browser_demuxer_android.h b/chromium/content/browser/media/android/browser_demuxer_android.h
index 71ebd7f30b4..f1b28d313e6 100644
--- a/chromium/content/browser/media/android/browser_demuxer_android.h
+++ b/chromium/content/browser/media/android/browser_demuxer_android.h
@@ -8,6 +8,7 @@
#include <map>
#include "base/id_map.h"
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
#include "media/base/android/demuxer_android.h"
diff --git a/chromium/content/browser/media/android/browser_media_player_manager.cc b/chromium/content/browser/media/android/browser_media_player_manager.cc
index 37e112096e2..0622043448b 100644
--- a/chromium/content/browser/media/android/browser_media_player_manager.cc
+++ b/chromium/content/browser/media/android/browser_media_player_manager.cc
@@ -4,17 +4,18 @@
#include "content/browser/media/android/browser_media_player_manager.h"
+#include <utility>
+
#include "base/android/scoped_java_ref.h"
-#include "content/browser/android/content_view_core_impl.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/media/android/browser_demuxer_android.h"
#include "content/browser/media/android/media_resource_getter_impl.h"
#include "content/browser/media/android/media_session.h"
#include "content/browser/media/android/media_throttler.h"
-#include "content/browser/media/media_web_contents_observer.h"
+#include "content/browser/media/android/media_web_contents_observer_android.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/web_contents/web_contents_view_android.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/media/media_player_messages_android.h"
-#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/android/external_video_surface_container.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -33,6 +34,11 @@
#include "media/base/android/media_task_runner.h"
#include "media/base/android/media_url_interceptor.h"
+#if !defined(USE_AURA)
+#include "content/browser/android/content_view_core_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_android.h"
+#endif
+
using media::MediaCodecPlayer;
using media::MediaPlayerAndroid;
using media::MediaPlayerBridge;
@@ -97,10 +103,10 @@ void BrowserMediaPlayerManager::SetSurfacePeer(
return;
}
- WebContentsImpl* web_contents =
- static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(frame));
BrowserMediaPlayerManager* player_manager =
- web_contents->media_web_contents_observer()->GetMediaPlayerManager(frame);
+ MediaWebContentsObserverAndroid::FromWebContents(
+ WebContents::FromRenderFrameHost(frame))
+ ->GetMediaPlayerManager(frame);
if (!player_manager) {
DVLOG(1) << "Cannot find the media player manager for frame " << frame;
return;
@@ -114,7 +120,7 @@ void BrowserMediaPlayerManager::SetSurfacePeer(
if (player != player_manager->GetFullscreenPlayer()) {
gfx::ScopedJavaSurface scoped_surface(surface_texture.get());
- player->SetVideoSurface(scoped_surface.Pass());
+ player->SetVideoSurface(std::move(scoped_surface));
}
}
@@ -126,15 +132,18 @@ BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create(
return new BrowserMediaPlayerManager(rfh);
}
+#if !defined(USE_AURA)
ContentViewCore* BrowserMediaPlayerManager::GetContentViewCore() const {
return ContentViewCoreImpl::FromWebContents(web_contents());
}
+#endif
MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
const MediaPlayerHostMsg_Initialize_Params& media_player_params,
bool hide_url_log,
BrowserDemuxerAndroid* demuxer) {
switch (media_player_params.type) {
+ case MEDIA_PLAYER_TYPE_REMOTE_ONLY:
case MEDIA_PLAYER_TYPE_URL: {
const std::string user_agent = GetContentClient()->GetUserAgent();
MediaPlayerBridge* media_player_bridge = new MediaPlayerBridge(
@@ -148,21 +157,34 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
weak_ptr_factory_.GetWeakPtr()),
media_player_params.frame_url,
media_player_params.allow_credentials);
- ContentViewCoreImpl* content_view_core_impl =
- static_cast<ContentViewCoreImpl*>(ContentViewCore::FromWebContents(
- web_contents_));
- if (!content_view_core_impl
+
+ if (media_player_params.type == MEDIA_PLAYER_TYPE_REMOTE_ONLY)
+ return media_player_bridge;
+
+ bool should_block = false;
+ bool extract_metadata =
// Initialize the player will cause MediaMetadataExtractor to decode
// small chunks of data.
- || !RequestDecoderResources(media_player_params.player_id, true)) {
+ RequestDecoderResources(media_player_params.player_id, true);
+#if !defined(USE_AURA)
+ ContentViewCoreImpl* content_view_core_impl =
+ static_cast<ContentViewCoreImpl*>(
+ ContentViewCore::FromWebContents(web_contents_));
+ if (!content_view_core_impl) {
+ extract_metadata = false;
+ } else {
+ should_block = content_view_core_impl->ShouldBlockMediaRequest(
+ media_player_params.url);
+ }
+#endif
+ if (!extract_metadata) {
// May reach here due to prerendering or throttling. Don't extract the
// metadata since it is expensive.
// TODO(qinmin): extract the metadata once the user decided to load
// the page.
- OnMediaMetadataChanged(
- media_player_params.player_id, base::TimeDelta(), 0, 0, false);
- } else if (!content_view_core_impl->ShouldBlockMediaRequest(
- media_player_params.url)) {
+ OnMediaMetadataChanged(media_player_params.player_id, base::TimeDelta(),
+ 0, 0, false);
+ } else if (!should_block) {
media_player_bridge->Initialize();
}
return media_player_bridge;
@@ -216,6 +238,10 @@ BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {
}
void BrowserMediaPlayerManager::ExitFullscreen(bool release_media_player) {
+#if defined(USE_AURA)
+ // TODO(crbug.com/548024)
+ NOTIMPLEMENTED();
+#else
if (WebContentsDelegate* delegate = web_contents_->GetDelegate())
delegate->ExitFullscreenModeForTab(web_contents_);
if (RenderWidgetHostViewAndroid* view_android =
@@ -241,6 +267,7 @@ void BrowserMediaPlayerManager::ExitFullscreen(bool release_media_player) {
ReleaseFullscreenPlayer(player);
else
player->SetVideoSurface(gfx::ScopedJavaSurface());
+#endif // defined(USE_AURA)
}
void BrowserMediaPlayerManager::OnTimeUpdate(
@@ -258,15 +285,17 @@ void BrowserMediaPlayerManager::SetVideoSurface(
return;
bool empty_surface = surface.IsEmpty();
- player->SetVideoSurface(surface.Pass());
+ player->SetVideoSurface(std::move(surface));
if (empty_surface)
return;
+#if !defined(USE_AURA)
if (RenderWidgetHostViewAndroid* view_android =
static_cast<RenderWidgetHostViewAndroid*>(
web_contents_->GetRenderWidgetHostView())) {
view_android->SetOverlayVideoMode(true);
}
+#endif
}
void BrowserMediaPlayerManager::OnMediaMetadataChanged(
@@ -289,15 +318,14 @@ void BrowserMediaPlayerManager::OnPlaybackComplete(int player_id) {
void BrowserMediaPlayerManager::OnMediaInterrupted(int player_id) {
// Tell WebKit that the audio should be paused, then release all resources
Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(), player_id));
- OnReleaseResources(player_id);
+ MediaSession::Get(web_contents())->RemovePlayer(this, player_id);
+ ReleaseResources(player_id);
}
-void BrowserMediaPlayerManager::OnBufferingUpdate(
- int player_id, int percentage) {
- Send(new MediaPlayerMsg_MediaBufferingUpdate(
- RoutingID(), player_id, percentage));
- if (fullscreen_player_id_ == player_id)
- video_view_->OnBufferingUpdate(percentage);
+void BrowserMediaPlayerManager::OnBufferingUpdate(int player_id,
+ int percentage) {
+ Send(new MediaPlayerMsg_MediaBufferingUpdate(RoutingID(), player_id,
+ percentage));
}
void BrowserMediaPlayerManager::OnSeekRequest(
@@ -379,7 +407,11 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) {
}
bool BrowserMediaPlayerManager::RequestPlay(int player_id,
- base::TimeDelta duration) {
+ base::TimeDelta duration,
+ bool has_audio) {
+ if (!has_audio)
+ return true;
+
MediaSession::Type media_session_type =
duration == base::TimeDelta() ||
duration.InSeconds() > kMinimumDurationForContentInSeconds
@@ -489,6 +521,10 @@ void BrowserMediaPlayerManager::ReleaseExternalSurface(int player_id) {
#endif // defined(VIDEO_HOLE)
void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) {
+#if defined(USE_AURA)
+ // TODO(crbug.com/548024)
+ NOTIMPLEMENTED();
+#else
DCHECK_EQ(fullscreen_player_id_, kInvalidMediaPlayerId);
#if defined(VIDEO_HOLE)
// If this fullscreen player is started when another player
@@ -516,6 +552,7 @@ void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) {
// Force the second video to exit fullscreen.
Send(new MediaPlayerMsg_DidExitFullscreen(RoutingID(), player_id));
video_view_.reset();
+#endif // defined(USE_AURA)
}
void BrowserMediaPlayerManager::OnInitialize(
@@ -525,7 +562,7 @@ void BrowserMediaPlayerManager::OnInitialize(
<< "Media source players must have positive demuxer client IDs: "
<< media_player_params.demuxer_client_id;
- RemovePlayer(media_player_params.player_id);
+ DestroyPlayer(media_player_params.player_id);
RenderProcessHostImpl* host = static_cast<RenderProcessHostImpl*>(
web_contents()->GetRenderProcessHost());
@@ -570,8 +607,8 @@ void BrowserMediaPlayerManager::OnPause(
if (player)
player->Pause(is_media_related_action);
- if (is_media_related_action)
- MediaSession::Get(web_contents())->RemovePlayer(this, player_id);
+ if (is_media_related_action && !IsPlayingRemotely(player_id))
+ MediaSession::Get(web_contents())->OnPlayerPaused(this, player_id);
}
void BrowserMediaPlayerManager::OnSetVolume(int player_id, double volume) {
@@ -584,22 +621,13 @@ void BrowserMediaPlayerManager::OnSetPoster(int player_id, const GURL& url) {
// To be overridden by subclasses.
}
-void BrowserMediaPlayerManager::OnReleaseResources(int player_id) {
- MediaPlayerAndroid* player = GetPlayer(player_id);
- if (player) {
- // Videos can't play in the background, so are removed from the media
- // session.
- if (player->GetVideoWidth() > 0)
- MediaSession::Get(web_contents())->RemovePlayer(this, player_id);
-
- ReleasePlayer(player);
- }
- if (player_id == fullscreen_player_id_)
- fullscreen_player_is_released_ = true;
+void BrowserMediaPlayerManager::OnSuspendAndReleaseResources(int player_id) {
+ MediaSession::Get(web_contents())->RemovePlayer(this, player_id);
+ ReleaseResources(player_id);
}
void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) {
- RemovePlayer(player_id);
+ DestroyPlayer(player_id);
if (fullscreen_player_id_ == player_id)
fullscreen_player_id_ = kInvalidMediaPlayerId;
}
@@ -613,12 +641,16 @@ void BrowserMediaPlayerManager::OnRequestRemotePlaybackControl(
// Does nothing if we don't have a remote player
}
+bool BrowserMediaPlayerManager::IsPlayingRemotely(int player_id) {
+ return false;
+}
+
void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) {
DCHECK(!GetPlayer(player->player_id()));
players_.push_back(player);
}
-void BrowserMediaPlayerManager::RemovePlayer(int player_id) {
+void BrowserMediaPlayerManager::DestroyPlayer(int player_id) {
for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
it != players_.end(); ++it) {
if ((*it)->player_id() == player_id) {
@@ -634,6 +666,14 @@ void BrowserMediaPlayerManager::RemovePlayer(int player_id) {
active_players_.erase(player_id);
}
+void BrowserMediaPlayerManager::ReleaseResources(int player_id) {
+ MediaPlayerAndroid* player = GetPlayer(player_id);
+ if (player)
+ ReleasePlayer(player);
+ if (player_id == fullscreen_player_id_)
+ fullscreen_player_is_released_ = true;
+}
+
scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
int player_id, media::MediaPlayerAndroid* player) {
media::MediaPlayerAndroid* previous_player = NULL;
diff --git a/chromium/content/browser/media/android/browser_media_player_manager.h b/chromium/content/browser/media/android/browser_media_player_manager.h
index 450e22d9c72..990d5e1f3c4 100644
--- a/chromium/content/browser/media/android/browser_media_player_manager.h
+++ b/chromium/content/browser/media/android/browser_media_player_manager.h
@@ -7,16 +7,14 @@
#include <map>
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/time/time.h"
#include "content/browser/android/content_video_view.h"
#include "content/browser/media/android/media_session_observer.h"
#include "content/common/content_export.h"
-#include "content/common/media/media_player_messages_enums_android.h"
-#include "content/public/browser/android/content_view_core.h"
#include "ipc/ipc_message.h"
#include "media/base/android/media_player_android.h"
#include "media/base/android/media_player_manager.h"
@@ -32,7 +30,9 @@ struct MediaPlayerHostMsg_Initialize_Params;
namespace content {
class BrowserDemuxerAndroid;
-class ContentViewCoreImpl;
+#if !defined(USE_AURA)
+class ContentViewCore;
+#endif
class ExternalVideoSurfaceContainer;
class RenderFrameHost;
class WebContents;
@@ -64,7 +64,9 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
// Returns a new instance using the registered factory if available.
static BrowserMediaPlayerManager* Create(RenderFrameHost* rfh);
+#if !defined(USE_AURA)
ContentViewCore* GetContentViewCore() const;
+#endif
~BrowserMediaPlayerManager() override;
@@ -101,7 +103,8 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
media::MediaUrlInterceptor* GetMediaUrlInterceptor() override;
media::MediaPlayerAndroid* GetFullscreenPlayer() override;
media::MediaPlayerAndroid* GetPlayer(int player_id) override;
- bool RequestPlay(int player_id, base::TimeDelta duration) override;
+ bool RequestPlay(int player_id, base::TimeDelta duration,
+ bool has_audio) override;
#if defined(VIDEO_HOLE)
void AttachExternalVideoSurface(int player_id, jobject surface);
void DetachExternalVideoSurface(int player_id);
@@ -121,11 +124,13 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual void OnPause(int player_id, bool is_media_related_action);
virtual void OnSetVolume(int player_id, double volume);
virtual void OnSetPoster(int player_id, const GURL& poster);
- virtual void OnReleaseResources(int player_id);
+ virtual void OnSuspendAndReleaseResources(int player_id);
virtual void OnDestroyPlayer(int player_id);
virtual void OnRequestRemotePlayback(int player_id);
virtual void OnRequestRemotePlaybackControl(int player_id);
+ virtual bool IsPlayingRemotely(int player_id);
virtual void ReleaseFullscreenPlayer(media::MediaPlayerAndroid* player);
+
#if defined(VIDEO_HOLE)
void OnNotifyExternalSurface(
int player_id, bool is_request, const gfx::RectF& rect);
@@ -141,7 +146,10 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
void AddPlayer(media::MediaPlayerAndroid* player);
// Removes the player with the specified id.
- void RemovePlayer(int player_id);
+ void DestroyPlayer(int player_id);
+
+ // Release resources associated to a player.
+ virtual void ReleaseResources(int player_id);
// Replaces a player with the specified id with a given MediaPlayerAndroid
// object. This will also return the original MediaPlayerAndroid object that
diff --git a/chromium/content/browser/media/android/browser_media_session_manager.cc b/chromium/content/browser/media/android/browser_media_session_manager.cc
new file mode 100644
index 00000000000..146a60fe970
--- /dev/null
+++ b/chromium/content/browser/media/android/browser_media_session_manager.cc
@@ -0,0 +1,34 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/android/browser_media_session_manager.h"
+
+#include "content/common/media/media_session_messages_android.h"
+#include "content/public/browser/render_frame_host.h"
+
+namespace content {
+
+BrowserMediaSessionManager::BrowserMediaSessionManager(
+ RenderFrameHost* render_frame_host)
+ : render_frame_host_(render_frame_host) {}
+
+void BrowserMediaSessionManager::OnActivate(int session_id, int request_id) {
+ NOTIMPLEMENTED();
+ Send(new MediaSessionMsg_DidActivate(GetRoutingID(), request_id, false));
+}
+
+void BrowserMediaSessionManager::OnDeactivate(int session_id, int request_id) {
+ NOTIMPLEMENTED();
+ Send(new MediaSessionMsg_DidDeactivate(GetRoutingID(), request_id));
+}
+
+int BrowserMediaSessionManager::GetRoutingID() const {
+ return render_frame_host_->GetRoutingID();
+}
+
+bool BrowserMediaSessionManager::Send(IPC::Message* msg) {
+ return render_frame_host_->Send(msg);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/android/browser_media_session_manager.h b/chromium/content/browser/media/android/browser_media_session_manager.h
new file mode 100644
index 00000000000..3b07b295816
--- /dev/null
+++ b/chromium/content/browser/media/android/browser_media_session_manager.h
@@ -0,0 +1,38 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_SESSION_MANAGER_H_
+#define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_SESSION_MANAGER_H_
+
+#include "base/macros.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace content {
+
+class RenderFrameHost;
+
+class BrowserMediaSessionManager {
+ public:
+ BrowserMediaSessionManager(RenderFrameHost* render_frame_host);
+
+ // Message handlers.
+ void OnActivate(int session_id, int request_id);
+ void OnDeactivate(int session_id, int request_id);
+
+ int GetRoutingID() const;
+
+ bool Send(IPC::Message* msg);
+
+ private:
+ RenderFrameHost* const render_frame_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserMediaSessionManager);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_SESSION_MANAGER_H_
diff --git a/chromium/content/browser/media/android/media_drm_credential_manager.cc b/chromium/content/browser/media/android/media_drm_credential_manager.cc
deleted file mode 100644
index 8e62770d3f1..00000000000
--- a/chromium/content/browser/media/android/media_drm_credential_manager.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/media/android/media_drm_credential_manager.h"
-
-#include "base/android/jni_android.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "jni/MediaDrmCredentialManager_jni.h"
-#include "media/base/android/media_drm_bridge.h"
-#include "url/gurl.h"
-
-#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
-
-using base::android::ScopedJavaGlobalRef;
-
-namespace {
-
-void MediaDrmCredentialManagerCallback(
- const ScopedJavaGlobalRef<jobject>& j_media_drm_credential_manager_callback,
- bool succeeded) {
- JNIEnv* env = base::android::AttachCurrentThread();
- content::Java_MediaDrmCredentialManagerCallback_onCredentialResetFinished(
- env, j_media_drm_credential_manager_callback.obj(), succeeded);
-}
-
-} // namespace
-
-namespace content {
-
-MediaDrmCredentialManager::MediaDrmCredentialManager() {};
-
-MediaDrmCredentialManager::~MediaDrmCredentialManager() {};
-
-// static
-MediaDrmCredentialManager* MediaDrmCredentialManager::GetInstance() {
- return base::Singleton<MediaDrmCredentialManager>::get();
-}
-
-void MediaDrmCredentialManager::ResetCredentials(
- const ResetCredentialsCB& reset_credentials_cb) {
- // Ignore reset request if one is already in progress.
- if (!reset_credentials_cb_.is_null())
- return;
-
- reset_credentials_cb_ = reset_credentials_cb;
-
- // First reset the L3 credential.
- if (!ResetCredentialsInternal(media::MediaDrmBridge::SECURITY_LEVEL_3)) {
- // TODO(qinmin): We should post a task instead.
- base::ResetAndReturn(&reset_credentials_cb_).Run(false);
- }
-}
-
-// static
-void ResetCredentials(
- JNIEnv* env,
- const JavaParamRef<jclass>& clazz,
- const JavaParamRef<jobject>& j_media_drm_credential_manager_callback) {
- MediaDrmCredentialManager* media_drm_credential_manager =
- MediaDrmCredentialManager::GetInstance();
-
- ScopedJavaGlobalRef<jobject> j_scoped_media_drm_credential_manager_callback;
- j_scoped_media_drm_credential_manager_callback.Reset(
- env, j_media_drm_credential_manager_callback);
-
- MediaDrmCredentialManager::ResetCredentialsCB callback_runner =
- base::Bind(&MediaDrmCredentialManagerCallback,
- j_scoped_media_drm_credential_manager_callback);
-
- media_drm_credential_manager->ResetCredentials(callback_runner);
-}
-
-void MediaDrmCredentialManager::OnResetCredentialsCompleted(
- SecurityLevel security_level, bool success) {
- if (security_level == media::MediaDrmBridge::SECURITY_LEVEL_3 && success) {
- if (ResetCredentialsInternal(media::MediaDrmBridge::SECURITY_LEVEL_1))
- return;
- success = false;
- }
-
- base::ResetAndReturn(&reset_credentials_cb_).Run(success);
- media_drm_bridge_.reset();
-}
-
-// TODO(ddorwin): The key system should be passed in. http://crbug.com/459400
-bool MediaDrmCredentialManager::ResetCredentialsInternal(
- SecurityLevel security_level) {
- media_drm_bridge_ =
- media::MediaDrmBridge::CreateWithoutSessionSupport(kWidevineKeySystem);
- if (!media_drm_bridge_)
- return false;
-
- ResetCredentialsCB reset_credentials_cb =
- base::Bind(&MediaDrmCredentialManager::OnResetCredentialsCompleted,
- base::Unretained(this), security_level);
-
- if (!media_drm_bridge_->SetSecurityLevel(security_level)) {
- // No need to reset credentials for unsupported |security_level|.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(reset_credentials_cb, true));
- return true;
- }
-
- media_drm_bridge_->ResetDeviceCredentials(reset_credentials_cb);
- return true;
-}
-
-// static
-bool MediaDrmCredentialManager::RegisterMediaDrmCredentialManager(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/android/media_drm_credential_manager.h b/chromium/content/browser/media/android/media_drm_credential_manager.h
deleted file mode 100644
index 97bfe808dd6..00000000000
--- a/chromium/content/browser/media/android/media_drm_credential_manager.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_DRM_CREDENTIAL_MANAGER_H_
-#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_DRM_CREDENTIAL_MANAGER_H_
-
-#include <jni.h>
-#include <string>
-
-#include "base/callback.h"
-#include "base/memory/singleton.h"
-#include "media/base/android/media_drm_bridge.h"
-
-namespace content {
-
-// This class manages the media DRM credentials on Android.
-class MediaDrmCredentialManager {
- public:
- static MediaDrmCredentialManager* GetInstance();
-
- typedef base::Callback<void(bool)> ResetCredentialsCB;
-
- // Called to reset the DRM credentials. (for Java)
- // Only clears credentials for Widevine.
- // TODO(ddorwin): This should accept a key system parameter so that this is
- // clear to the caller, which can call it repeatedly as necessary.
- // http://crbug.com/459400
- static void ResetCredentials(JNIEnv* env, jclass clazz, jobject callback);
-
- // Called to reset the DRM credentials. The result is returned in the
- // |reset_credentials_cb|.
- void ResetCredentials(const ResetCredentialsCB& reset_credentials_cb);
-
- static bool RegisterMediaDrmCredentialManager(JNIEnv* env);
-
- private:
- friend struct base::DefaultSingletonTraits<MediaDrmCredentialManager>;
- typedef media::MediaDrmBridge::SecurityLevel SecurityLevel;
-
- MediaDrmCredentialManager();
- ~MediaDrmCredentialManager();
-
- // Callback function passed to MediaDrmBridge. It is called when credentials
- // reset is completed.
- void OnResetCredentialsCompleted(SecurityLevel security_level, bool success);
-
- // Resets DRM credentials for a particular |security_level|. Returns false if
- // we fail to create the MediaDrmBridge at all, in which case we cannot reset
- // the credentials. Otherwise, the result is returned asynchronously in
- // OnResetCredentialsCompleted() function.
- bool ResetCredentialsInternal(SecurityLevel security_level);
-
- // The MediaDrmBridge object used to perform the credential reset.
- media::ScopedMediaDrmBridgePtr media_drm_bridge_;
-
- // The callback provided by the caller.
- ResetCredentialsCB reset_credentials_cb_;
-
- DISALLOW_COPY_AND_ASSIGN(MediaDrmCredentialManager);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_DRM_CREDENTIAL_MANAGER_H_
diff --git a/chromium/content/browser/media/android/media_resource_getter_impl.cc b/chromium/content/browser/media/android/media_resource_getter_impl.cc
index 3afe5688d48..e0d6aff5129 100644
--- a/chromium/content/browser/media/android/media_resource_getter_impl.cc
+++ b/chromium/content/browser/media/android/media_resource_getter_impl.cc
@@ -4,9 +4,11 @@
#include "content/browser/media/android/media_resource_getter_impl.h"
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
+#include "base/macros.h"
#include "base/path_service.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -21,7 +23,6 @@
#include "jni/MediaResourceGetter_jni.h"
#include "media/base/android/media_url_interceptor.h"
#include "net/base/auth.h"
-#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/http/http_auth.h"
#include "net/http/http_transaction_factory.h"
@@ -135,7 +136,9 @@ static void GetMediaMetadata(
// Gets the metadata from a file descriptor. When finished, a task is posted to
// the UI thread to run the callback function.
static void GetMediaMetadataFromFd(
- const int fd, const int64 offset, const int64 size,
+ const int fd,
+ const int64_t offset,
+ const int64_t size,
const media::MediaResourceGetter::ExtractMediaMetadataCB& callback) {
JNIEnv* env = base::android::AttachCurrentThread();
@@ -239,14 +242,9 @@ void MediaResourceGetterTask::RequestCookies(
return;
}
- net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster();
- if (cookie_monster) {
- cookie_monster->GetAllCookiesForURLAsync(url, base::Bind(
- &MediaResourceGetterTask::CheckPolicyForCookies, this,
- url, first_party_for_cookies, callback));
- } else {
- callback.Run(std::string());
- }
+ cookie_store->GetAllCookiesForURLAsync(
+ url, base::Bind(&MediaResourceGetterTask::CheckPolicyForCookies, this,
+ url, first_party_for_cookies, callback));
}
void MediaResourceGetterTask::CheckPolicyForCookies(
@@ -370,7 +368,9 @@ void MediaResourceGetterImpl::ExtractMediaMetadata(
}
void MediaResourceGetterImpl::ExtractMediaMetadata(
- const int fd, const int64 offset, const int64 size,
+ const int fd,
+ const int64_t offset,
+ const int64_t size,
const ExtractMediaMetadataCB& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
diff --git a/chromium/content/browser/media/android/media_resource_getter_impl.h b/chromium/content/browser/media/android/media_resource_getter_impl.h
index 9a55fcb7c2c..bedf4405358 100644
--- a/chromium/content/browser/media/android/media_resource_getter_impl.h
+++ b/chromium/content/browser/media/android/media_resource_getter_impl.h
@@ -6,8 +6,10 @@
#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_RESOURCE_GETTER_IMPL_H_
#include <jni.h>
+#include <stdint.h>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h"
@@ -56,8 +58,8 @@ class MediaResourceGetterImpl : public media::MediaResourceGetter {
const std::string& user_agent,
const ExtractMediaMetadataCB& callback) override;
void ExtractMediaMetadata(const int fd,
- const int64 offset,
- const int64 size,
+ const int64_t offset,
+ const int64_t size,
const ExtractMediaMetadataCB& callback) override;
static bool RegisterMediaResourceGetter(JNIEnv* env);
diff --git a/chromium/content/browser/media/android/media_session.cc b/chromium/content/browser/media/android/media_session.cc
index 2a4dd1ce988..d6061541e88 100644
--- a/chromium/content/browser/media/android/media_session.cc
+++ b/chromium/content/browser/media/android/media_session.cc
@@ -4,6 +4,7 @@
#include "content/browser/media/android/media_session.h"
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "content/browser/media/android/media_session_observer.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -111,29 +112,46 @@ void MediaSession::RemovePlayers(MediaSessionObserver* observer) {
AbandonSystemAudioFocusIfNeeded();
}
-void MediaSession::OnSuspend(JNIEnv* env, jobject obj, jboolean temporary) {
+void MediaSession::OnSuspend(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean temporary) {
// TODO(mlamouri): this check makes it so that if a MediaSession is paused and
// then loses audio focus, it will still stay in the Suspended state.
// See https://crbug.com/539998
if (audio_focus_state_ != State::ACTIVE)
return;
- OnSuspendInternal(SuspendType::SYSTEM);
- if (!temporary)
- SetAudioFocusState(State::INACTIVE);
+ OnSuspendInternal(SuspendType::SYSTEM,
+ temporary ? State::SUSPENDED : State::INACTIVE);
- uma_helper_.RecordSessionSuspended(
- temporary ? MediaSessionSuspendedSource::SystemTransient
- : MediaSessionSuspendedSource::SystemPermanent);
- UpdateWebContents();
}
-void MediaSession::OnResume(JNIEnv* env, jobject obj) {
+void MediaSession::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) {
if (audio_focus_state_ != State::SUSPENDED)
return;
OnResumeInternal(SuspendType::SYSTEM);
- UpdateWebContents();
+}
+
+void MediaSession::OnPlayerPaused(MediaSessionObserver* observer,
+ int player_id) {
+ // If a playback is completed, BrowserMediaPlayerManager will call
+ // OnPlayerPaused() after RemovePlayer(). This is a workaround.
+ // Also, this method may be called when a player that is not added
+ // to this session (e.g. a silent video) is paused. MediaSession
+ // should ignore the paused player for this case.
+ if (!players_.count(PlayerIdentifier(observer, player_id)))
+ return;
+
+ // If there is more than one observer, remove the paused one from the session.
+ if (players_.size() != 1) {
+ RemovePlayer(observer, player_id);
+ return;
+ }
+
+ // Otherwise, suspend the session.
+ DCHECK(!IsSuspended());
+ OnSuspendInternal(SuspendType::CONTENT, State::SUSPENDED);
}
void MediaSession::Resume() {
@@ -155,14 +173,14 @@ void MediaSession::Resume() {
void MediaSession::Suspend() {
DCHECK(!IsSuspended());
- OnSuspendInternal(SuspendType::UI);
+ OnSuspendInternal(SuspendType::UI, State::SUSPENDED);
}
void MediaSession::Stop() {
DCHECK(audio_focus_state_ != State::INACTIVE);
if (audio_focus_state_ != State::SUSPENDED)
- OnSuspendInternal(SuspendType::UI);
+ OnSuspendInternal(SuspendType::UI, State::SUSPENDED);
DCHECK(audio_focus_state_ == State::SUSPENDED);
players_.clear();
@@ -201,27 +219,59 @@ void MediaSession::RemoveAllPlayersForTest() {
AbandonSystemAudioFocusIfNeeded();
}
-void MediaSession::OnSuspendInternal(SuspendType type) {
- // SuspendType::System will handle the UMA recording at the calling point
- // because there are more than one type.
- if (type == SuspendType::UI)
- uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI);
+void MediaSession::OnSuspendInternal(SuspendType type, State new_state) {
+ DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE);
+ // UI suspend cannot use State::INACTIVE.
+ DCHECK(type == SuspendType::SYSTEM || new_state == State::SUSPENDED);
- SetAudioFocusState(State::SUSPENDED);
+ switch (type) {
+ case SuspendType::UI:
+ uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI);
+ break;
+ case SuspendType::SYSTEM:
+ switch (new_state) {
+ case State::SUSPENDED:
+ uma_helper_.RecordSessionSuspended(
+ MediaSessionSuspendedSource::SystemTransient);
+ break;
+ case State::INACTIVE:
+ uma_helper_.RecordSessionSuspended(
+ MediaSessionSuspendedSource::SystemPermanent);
+ break;
+ case State::ACTIVE:
+ NOTREACHED();
+ break;
+ }
+ break;
+ case SuspendType::CONTENT:
+ uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::CONTENT);
+ break;
+ }
+
+ SetAudioFocusState(new_state);
suspend_type_ = type;
- for (const auto& it : players_)
- it.observer->OnSuspend(it.player_id);
+ if (type != SuspendType::CONTENT) {
+ // SuspendType::CONTENT happens when the suspend action came from
+ // the page in which case the player is already paused.
+ // Otherwise, the players need to be paused.
+ for (const auto& it : players_)
+ it.observer->OnSuspend(it.player_id);
+ }
+
+ UpdateWebContents();
}
void MediaSession::OnResumeInternal(SuspendType type) {
- if (suspend_type_ != type && type != SuspendType::UI)
+ if (type == SuspendType::SYSTEM && suspend_type_ != type)
return;
SetAudioFocusState(State::ACTIVE);
for (const auto& it : players_)
it.observer->OnResume(it.player_id);
+
+ UpdateWebContents();
}
MediaSession::MediaSession(WebContents* web_contents)
@@ -245,8 +295,10 @@ bool MediaSession::RequestSystemAudioFocus(Type type) {
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
- return Java_MediaSession_requestAudioFocus(env, j_media_session_.obj(),
- type == Type::Transient);
+ bool result = Java_MediaSession_requestAudioFocus(env, j_media_session_.obj(),
+ type == Type::Transient);
+ uma_helper_.RecordRequestAudioFocusResult(result);
+ return result;
}
void MediaSession::AbandonSystemAudioFocusIfNeeded() {
diff --git a/chromium/content/browser/media/android/media_session.h b/chromium/content/browser/media/android/media_session.h
index 992ad4f42e5..fa727b0b049 100644
--- a/chromium/content/browser/media/android/media_session.h
+++ b/chromium/content/browser/media/android/media_session.h
@@ -6,9 +6,11 @@
#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_SESSION_H_
#include <jni.h>
+#include <stddef.h>
#include "base/android/scoped_java_ref.h"
#include "base/id_map.h"
+#include "base/macros.h"
#include "content/browser/media/android/media_session_uma_helper.h"
#include "content/common/content_export.h"
#include "content/public/browser/web_contents_observer.h"
@@ -62,11 +64,18 @@ class CONTENT_EXPORT MediaSession
// Called when the Android system requests the MediaSession to be suspended.
// Called by Java through JNI.
- void OnSuspend(JNIEnv* env, jobject obj, jboolean temporary);
+ void OnSuspend(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean temporary);
// Called when the Android system requests the MediaSession to be resumed.
// Called by Java through JNI.
- void OnResume(JNIEnv* env, jobject obj);
+ void OnResume(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+
+ // Called when a player is paused in the content.
+ // If the paused player is the last player, we suspend the MediaSession.
+ // Otherwise, the paused player will be removed from the MediaSession.
+ void OnPlayerPaused(MediaSessionObserver* observer, int player_id);
// Called when the user requests resuming the session. No-op if the session is
// not controllable.
@@ -109,6 +118,8 @@ class CONTENT_EXPORT MediaSession
SYSTEM,
// Suspended by the UI.
UI,
+ // Suspended by the page via script or user interaction.
+ CONTENT,
};
// Representation of a player for the MediaSession.
@@ -134,7 +145,7 @@ class CONTENT_EXPORT MediaSession
// Setup the JNI.
void Initialize();
- void OnSuspendInternal(SuspendType type);
+ void OnSuspendInternal(SuspendType type, State new_state);
void OnResumeInternal(SuspendType type);
// Requests audio focus to Android using |j_media_session_|.
diff --git a/chromium/content/browser/media/android/media_session_browsertest.cc b/chromium/content/browser/media/android/media_session_browsertest.cc
index 99553b4ac9e..a0628ae7093 100644
--- a/chromium/content/browser/media/android/media_session_browsertest.cc
+++ b/chromium/content/browser/media/android/media_session_browsertest.cc
@@ -4,9 +4,12 @@
#include "content/browser/media/android/media_session.h"
+#include <stddef.h>
+
#include <list>
#include <vector>
+#include "base/macros.h"
#include "base/metrics/histogram_samples.h"
#include "base/test/histogram_tester.h"
#include "base/test/simple_test_clock.h"
@@ -142,6 +145,11 @@ class MediaSessionBrowserTest : public content::ContentBrowserTest {
media_session_->RemovePlayers(media_session_observer);
}
+ void OnPlayerPaused(MockMediaSessionObserver* media_session_observer,
+ int player_id) {
+ media_session_->OnPlayerPaused(media_session_observer, player_id);
+ }
+
bool HasAudioFocus() { return media_session_->IsActiveForTest(); }
MediaSession::Type GetSessionType() {
@@ -302,6 +310,17 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, SuspendGivesAwayAudioFocus) {
EXPECT_FALSE(HasAudioFocus());
}
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, StopGivesAwayAudioFocus) {
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
+
+ media_session_->Stop();
+
+ EXPECT_FALSE(HasAudioFocus());
+}
+
IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ResumeGivesBackAudioFocus) {
scoped_ptr<MockMediaSessionObserver> media_session_observer(
new MockMediaSessionObserver);
@@ -587,7 +606,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
- ControlsHideWhenTheLastPlayerIsStopped) {
+ ControlsHideWhenTheLastPlayerIsRemoved) {
Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
MediaSessionStateChanged(true, false));
EXPECT_CALL(*mock_web_contents_observer(),
@@ -631,6 +650,31 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ ControlsNotHideWhenTheLastPlayerIsPaused) {
+ Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(true, false));
+ EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(true, true))
+ .After(showControls);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
+ StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
+
+ OnPlayerPaused(media_session_observer.get(), 0);
+
+ EXPECT_TRUE(IsControllable());
+ EXPECT_FALSE(IsSuspended());
+
+ OnPlayerPaused(media_session_observer.get(), 1);
+
+ EXPECT_TRUE(IsControllable());
+ EXPECT_TRUE(IsSuspended());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
SuspendTemporaryUpdatesControls) {
Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
MediaSessionStateChanged(true, false));
@@ -690,6 +734,28 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
+ ConstrolsHideWhenSessionStops) {
+ Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(true, false));
+ Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(true, true))
+ .After(showControls);
+ EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(false, true))
+ .After(pauseControls);
+
+ scoped_ptr<MockMediaSessionObserver> media_session_observer(
+ new MockMediaSessionObserver);
+
+ StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
+
+ media_session_->Stop();
+
+ EXPECT_FALSE(IsControllable());
+ EXPECT_TRUE(IsSuspended());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
ControlsHideWhenSessionChangesFromContentToTransient) {
Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
MediaSessionStateChanged(true, false));
@@ -763,9 +829,11 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
- ControlsNotUpdatedDueToResumeSessionAction) {
- EXPECT_CALL(*mock_web_contents_observer(),
+ ControlsUpdatedDueToResumeSessionAction) {
+ Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
MediaSessionStateChanged(true, false));
+ EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(true, true)).After(showControls);
scoped_ptr<MockMediaSessionObserver> media_session_observer(
new MockMediaSessionObserver);
@@ -778,9 +846,15 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
- ControlsNotUpdatedDueToSuspendSessionAction) {
+ ControlsUpdatedDueToSuspendSessionAction) {
+ Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(true, false));
+ Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(),
+ MediaSessionStateChanged(true, true))
+ .After(showControls);
EXPECT_CALL(*mock_web_contents_observer(),
- MediaSessionStateChanged(true, false));
+ MediaSessionStateChanged(true, false))
+ .After(pauseControls);
scoped_ptr<MockMediaSessionObserver> media_session_observer(
new MockMediaSessionObserver);
diff --git a/chromium/content/browser/media/android/media_session_uma_helper.cc b/chromium/content/browser/media/android/media_session_uma_helper.cc
index 4752401dd98..35e79dd9d5d 100644
--- a/chromium/content/browser/media/android/media_session_uma_helper.cc
+++ b/chromium/content/browser/media/android/media_session_uma_helper.cc
@@ -4,6 +4,8 @@
#include "content/browser/media/android/media_session_uma_helper.h"
+#include <utility>
+
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/default_clock.h"
@@ -27,6 +29,10 @@ void MediaSessionUmaHelper::RecordSessionSuspended(
static_cast<HistogramBase::Sample>(MediaSessionSuspendedSource::Count));
}
+void MediaSessionUmaHelper::RecordRequestAudioFocusResult(bool result) const {
+ UMA_HISTOGRAM_BOOLEAN("Media.Session.RequestAudioFocusResult", result);
+}
+
void MediaSessionUmaHelper::OnSessionActive() {
current_active_time_ = clock_->Now();
}
@@ -54,7 +60,7 @@ void MediaSessionUmaHelper::OnSessionInactive() {
void MediaSessionUmaHelper::SetClockForTest(
scoped_ptr<base::Clock> testing_clock) {
- clock_ = testing_clock.Pass();
+ clock_ = std::move(testing_clock);
}
} // namespace content
diff --git a/chromium/content/browser/media/android/media_session_uma_helper.h b/chromium/content/browser/media/android/media_session_uma_helper.h
index 35f64566643..69fbaa9363f 100644
--- a/chromium/content/browser/media/android/media_session_uma_helper.h
+++ b/chromium/content/browser/media/android/media_session_uma_helper.h
@@ -23,6 +23,7 @@ class CONTENT_EXPORT MediaSessionUmaHelper {
SystemTransient = 0,
SystemPermanent = 1,
UI = 2,
+ CONTENT = 3,
Count // Leave at the end.
};
@@ -31,6 +32,9 @@ class CONTENT_EXPORT MediaSessionUmaHelper {
void RecordSessionSuspended(MediaSessionSuspendedSource source) const;
+ // Record the result of calling the native requestAudioFocus().
+ void RecordRequestAudioFocusResult(bool result) const;
+
void OnSessionActive();
void OnSessionSuspended();
void OnSessionInactive();
diff --git a/chromium/content/browser/media/android/media_throttler.cc b/chromium/content/browser/media/android/media_throttler.cc
index 04c8030ff5b..e1769ece994 100644
--- a/chromium/content/browser/media/android/media_throttler.cc
+++ b/chromium/content/browser/media/android/media_throttler.cc
@@ -4,6 +4,7 @@
#include "content/browser/media/android/media_throttler.h"
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "jni/MediaThrottler_jni.h"
diff --git a/chromium/content/browser/media/android/media_throttler.h b/chromium/content/browser/media/android/media_throttler.h
index 002dcd77568..ade0b89b7b7 100644
--- a/chromium/content/browser/media/android/media_throttler.h
+++ b/chromium/content/browser/media/android/media_throttler.h
@@ -8,6 +8,7 @@
#include <jni.h>
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
namespace content {
diff --git a/chromium/content/browser/media/android/media_web_contents_observer_android.cc b/chromium/content/browser/media/android/media_web_contents_observer_android.cc
new file mode 100644
index 00000000000..1b48959e9ba
--- /dev/null
+++ b/chromium/content/browser/media/android/media_web_contents_observer_android.cc
@@ -0,0 +1,200 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/android/media_web_contents_observer_android.h"
+
+#include "content/browser/media/android/browser_media_player_manager.h"
+#include "content/browser/media/android/browser_media_session_manager.h"
+#include "content/browser/media/android/media_session_observer.h"
+#include "content/browser/media/cdm/browser_cdm_manager.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/media/media_player_messages_android.h"
+#include "content/common/media/media_session_messages_android.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+#include "ipc/ipc_message_macros.h"
+#include "media/base/android/media_player_android.h"
+
+namespace content {
+
+MediaWebContentsObserverAndroid::MediaWebContentsObserverAndroid(
+ WebContents* web_contents)
+ : MediaWebContentsObserver(web_contents) {}
+
+MediaWebContentsObserverAndroid::~MediaWebContentsObserverAndroid() {}
+
+// static
+MediaWebContentsObserverAndroid*
+MediaWebContentsObserverAndroid::FromWebContents(WebContents* web_contents) {
+ return static_cast<MediaWebContentsObserverAndroid*>(
+ static_cast<WebContentsImpl*>(web_contents)
+ ->media_web_contents_observer());
+}
+
+BrowserMediaPlayerManager*
+MediaWebContentsObserverAndroid::GetMediaPlayerManager(
+ RenderFrameHost* render_frame_host) {
+ auto it = media_player_managers_.find(render_frame_host);
+ if (it != media_player_managers_.end())
+ return it->second;
+
+ BrowserMediaPlayerManager* manager =
+ BrowserMediaPlayerManager::Create(render_frame_host);
+ media_player_managers_.set(render_frame_host, make_scoped_ptr(manager));
+ return manager;
+}
+
+BrowserMediaSessionManager*
+MediaWebContentsObserverAndroid::GetMediaSessionManager(
+ RenderFrameHost* render_frame_host) {
+ auto it = media_session_managers_.find(render_frame_host);
+ if (it != media_session_managers_.end())
+ return it->second;
+
+ BrowserMediaSessionManager* manager =
+ new BrowserMediaSessionManager(render_frame_host);
+ media_session_managers_.set(render_frame_host, make_scoped_ptr(manager));
+ return manager;
+}
+
+#if defined(VIDEO_HOLE)
+void MediaWebContentsObserverAndroid::OnFrameInfoUpdated() {
+ for (auto it = media_player_managers_.begin();
+ it != media_player_managers_.end(); ++it) {
+ it->second->OnFrameInfoUpdated();
+ }
+}
+#endif // defined(VIDEO_HOLE)
+
+void MediaWebContentsObserverAndroid::RenderFrameDeleted(
+ RenderFrameHost* render_frame_host) {
+ MediaWebContentsObserver::RenderFrameDeleted(render_frame_host);
+
+ // Always destroy the media players before CDMs because we do not support
+ // detaching CDMs from media players yet. See http://crbug.com/330324
+ media_player_managers_.erase(render_frame_host);
+ media_session_managers_.erase(render_frame_host);
+
+ // TODO(xhwang): Currently MediaWebContentsObserver, BrowserMediaPlayerManager
+ // and BrowserCdmManager all run on browser UI thread. So this call is okay.
+ // In the future we need to support the case where MediaWebContentsObserver
+ // get notified on browser UI thread, but BrowserMediaPlayerManager and
+ // BrowserCdmManager run on a different thread.
+ BrowserCdmManager* browser_cdm_manager =
+ BrowserCdmManager::FromProcess(render_frame_host->GetProcess()->GetID());
+ if (browser_cdm_manager)
+ browser_cdm_manager->RenderFrameDeleted(render_frame_host->GetRoutingID());
+}
+
+bool MediaWebContentsObserverAndroid::OnMessageReceived(
+ const IPC::Message& msg,
+ RenderFrameHost* render_frame_host) {
+ if (MediaWebContentsObserver::OnMessageReceived(msg, render_frame_host))
+ return true;
+
+ if (OnMediaPlayerMessageReceived(msg, render_frame_host))
+ return true;
+
+ return OnMediaPlayerSetCdmMessageReceived(msg, render_frame_host);
+}
+
+bool MediaWebContentsObserverAndroid::OnMediaPlayerMessageReceived(
+ const IPC::Message& msg,
+ RenderFrameHost* render_frame_host) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserverAndroid, msg)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnEnterFullscreen)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnInitialize)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnStart)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnSeek)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnPause)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnSetVolume)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnSetPoster)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SuspendAndRelease,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnSuspendAndReleaseResources)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnDestroyPlayer)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_RequestRemotePlayback,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnRequestRemotePlayback)
+ IPC_MESSAGE_FORWARD(
+ MediaPlayerHostMsg_RequestRemotePlaybackControl,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnRequestRemotePlaybackControl)
+#if defined(VIDEO_HOLE)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface,
+ GetMediaPlayerManager(render_frame_host),
+ BrowserMediaPlayerManager::OnNotifyExternalSurface)
+#endif // defined(VIDEO_HOLE)
+ IPC_MESSAGE_FORWARD(MediaSessionHostMsg_Activate,
+ GetMediaSessionManager(render_frame_host),
+ BrowserMediaSessionManager::OnActivate)
+ IPC_MESSAGE_FORWARD(MediaSessionHostMsg_Deactivate,
+ GetMediaSessionManager(render_frame_host),
+ BrowserMediaSessionManager::OnDeactivate)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+bool MediaWebContentsObserverAndroid::OnMediaPlayerSetCdmMessageReceived(
+ const IPC::Message& msg,
+ RenderFrameHost* render_frame_host) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MediaWebContentsObserverAndroid, msg,
+ render_frame_host)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetCdm, OnSetCdm)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void MediaWebContentsObserverAndroid::OnSetCdm(
+ RenderFrameHost* render_frame_host,
+ int player_id,
+ int cdm_id) {
+ media::MediaPlayerAndroid* media_player =
+ GetMediaPlayerManager(render_frame_host)->GetPlayer(player_id);
+ if (!media_player) {
+ NOTREACHED() << "OnSetCdm: MediaPlayer not found for " << player_id;
+ return;
+ }
+
+ // MediaPlayerAndroid runs on the same thread as BrowserCdmManager.
+ BrowserCdmManager* browser_cdm_manager =
+ BrowserCdmManager::FromProcess(render_frame_host->GetProcess()->GetID());
+ if (!browser_cdm_manager) {
+ NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id;
+ return;
+ }
+
+ scoped_refptr<media::MediaKeys> cdm =
+ browser_cdm_manager->GetCdm(render_frame_host->GetRoutingID(), cdm_id);
+ if (!cdm) {
+ NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id;
+ return;
+ }
+
+ // TODO(xhwang): This could possibly fail. In that case we should reject the
+ // promise.
+ media_player->SetCdm(cdm);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/android/media_web_contents_observer_android.h b/chromium/content/browser/media/android/media_web_contents_observer_android.h
new file mode 100644
index 00000000000..a95e1615fb6
--- /dev/null
+++ b/chromium/content/browser/media/android/media_web_contents_observer_android.h
@@ -0,0 +1,78 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_WEB_CONTENTS_OBSERVER_ANDROID_H_
+#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_WEB_CONTENTS_OBSERVER_ANDROID_H_
+
+#include <stdint.h>
+
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/browser/media/media_web_contents_observer.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class BrowserCdmManager;
+class BrowserMediaPlayerManager;
+class BrowserMediaSessionManager;
+
+// This class adds Android specific extensions to the MediaWebContentsObserver.
+class CONTENT_EXPORT MediaWebContentsObserverAndroid
+ : public MediaWebContentsObserver {
+ public:
+ explicit MediaWebContentsObserverAndroid(WebContents* web_contents);
+ ~MediaWebContentsObserverAndroid() override;
+
+ // Returns the android specific observer for a given web contents.
+ static MediaWebContentsObserverAndroid* FromWebContents(
+ WebContents* web_contents);
+
+ // Gets the media player or media session manager associated with the given
+ // |render_frame_host| respectively. Creates a new one if it doesn't exist.
+ // The caller doesn't own the returned pointer.
+ BrowserMediaPlayerManager* GetMediaPlayerManager(
+ RenderFrameHost* render_frame_host);
+ BrowserMediaSessionManager* GetMediaSessionManager(
+ RenderFrameHost* render_frame_host);
+
+#if defined(VIDEO_HOLE)
+ void OnFrameInfoUpdated();
+#endif // defined(VIDEO_HOLE)
+
+ // MediaWebContentsObserverAndroid overrides.
+ void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
+ bool OnMessageReceived(const IPC::Message& message,
+ RenderFrameHost* render_frame_host) override;
+
+ private:
+ // Helper functions to handle media player IPC messages. Returns whether the
+ // |message| is handled in the function.
+ bool OnMediaPlayerMessageReceived(const IPC::Message& message,
+ RenderFrameHost* render_frame_host);
+
+ bool OnMediaPlayerSetCdmMessageReceived(const IPC::Message& message,
+ RenderFrameHost* render_frame_host);
+
+ void OnSetCdm(RenderFrameHost* render_frame_host, int player_id, int cdm_id);
+
+ // Map from RenderFrameHost* to BrowserMediaPlayerManager.
+ using MediaPlayerManagerMap =
+ base::ScopedPtrHashMap<RenderFrameHost*,
+ scoped_ptr<BrowserMediaPlayerManager>>;
+ MediaPlayerManagerMap media_player_managers_;
+
+ // Map from RenderFrameHost* to BrowserMediaSessionManager.
+ using MediaSessionManagerMap =
+ base::ScopedPtrHashMap<RenderFrameHost*,
+ scoped_ptr<BrowserMediaSessionManager>>;
+ MediaSessionManagerMap media_session_managers_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserverAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_WEB_CONTENTS_OBSERVER_ANDROID_H_
diff --git a/chromium/content/browser/media/android/provision_fetcher_impl.cc b/chromium/content/browser/media/android/provision_fetcher_impl.cc
new file mode 100644
index 00000000000..8e9f689d5e2
--- /dev/null
+++ b/chromium/content/browser/media/android/provision_fetcher_impl.cc
@@ -0,0 +1,56 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/android/provision_fetcher_impl.h"
+
+#include "content/public/browser/android/provision_fetcher_factory.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace content {
+
+// static
+void ProvisionFetcherImpl::Create(
+ RenderFrameHost* render_frame_host,
+ mojo::InterfaceRequest<media::interfaces::ProvisionFetcher> request) {
+ net::URLRequestContextGetter* context_getter =
+ render_frame_host->GetProcess()->GetBrowserContext()->GetRequestContext();
+ DCHECK(context_getter);
+
+ // The created object is strongly bound to (and owned by) the pipe.
+ new ProvisionFetcherImpl(CreateProvisionFetcher(context_getter),
+ std::move(request));
+}
+
+ProvisionFetcherImpl::ProvisionFetcherImpl(
+ scoped_ptr<media::ProvisionFetcher> provision_fetcher,
+ mojo::InterfaceRequest<ProvisionFetcher> request)
+ : binding_(this, std::move(request)),
+ provision_fetcher_(std::move(provision_fetcher)),
+ weak_factory_(this) {
+ DVLOG(1) << __FUNCTION__;
+}
+
+ProvisionFetcherImpl::~ProvisionFetcherImpl() {}
+
+void ProvisionFetcherImpl::Retrieve(const mojo::String& default_url,
+ const mojo::String& request_data,
+ const RetrieveCallback& callback) {
+ DVLOG(1) << __FUNCTION__ << ": " << default_url;
+ provision_fetcher_->Retrieve(
+ default_url, request_data,
+ base::Bind(&ProvisionFetcherImpl::OnResponse, weak_factory_.GetWeakPtr(),
+ callback));
+}
+
+void ProvisionFetcherImpl::OnResponse(const RetrieveCallback& callback,
+ bool success,
+ const std::string& response) {
+ DVLOG(1) << __FUNCTION__ << ": " << success;
+ callback.Run(success, response);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/android/provision_fetcher_impl.h b/chromium/content/browser/media/android/provision_fetcher_impl.h
new file mode 100644
index 00000000000..3f009fb89d6
--- /dev/null
+++ b/chromium/content/browser/media/android/provision_fetcher_impl.h
@@ -0,0 +1,53 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_ANDROID_PROVISION_FETCHER_IMPL_H_
+#define CONTENT_BROWSER_MEDIA_ANDROID_PROVISION_FETCHER_IMPL_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/android/provision_fetcher_factory.h"
+#include "media/base/android/provision_fetcher.h"
+#include "media/mojo/interfaces/provision_fetcher.mojom.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace content {
+
+class RenderFrameHost;
+
+// An media::interfaces::ProvisionFetcher implementation based on
+// media::ProvisionFetcher.
+class ProvisionFetcherImpl : public media::interfaces::ProvisionFetcher {
+ public:
+ static void Create(
+ RenderFrameHost* render_frame_host,
+ mojo::InterfaceRequest<media::interfaces::ProvisionFetcher> request);
+
+ ProvisionFetcherImpl(scoped_ptr<media::ProvisionFetcher> provision_fetcher,
+ mojo::InterfaceRequest<ProvisionFetcher> request);
+ ~ProvisionFetcherImpl() override;
+
+ // media::interfaces::ProvisionFetcher implementation.
+ void Retrieve(const mojo::String& default_url,
+ const mojo::String& request_data,
+ const RetrieveCallback& callback) final;
+
+ private:
+ // Callback for media::ProvisionFetcher::Retrieve().
+ void OnResponse(const RetrieveCallback& callback,
+ bool success,
+ const std::string& response);
+
+ mojo::StrongBinding<media::interfaces::ProvisionFetcher> binding_;
+ scoped_ptr<media::ProvisionFetcher> provision_fetcher_;
+
+ base::WeakPtrFactory<ProvisionFetcherImpl> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProvisionFetcherImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_ANDROID_PROVISION_FETCHER_IMPL_H_
diff --git a/chromium/content/browser/media/android/url_provision_fetcher.cc b/chromium/content/browser/media/android/url_provision_fetcher.cc
new file mode 100644
index 00000000000..7607480c933
--- /dev/null
+++ b/chromium/content/browser/media/android/url_provision_fetcher.cc
@@ -0,0 +1,77 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/android/url_provision_fetcher.h"
+
+#include "content/public/browser/android/provision_fetcher_factory.h"
+#include "media/base/bind_to_current_loop.h"
+#include "net/url_request/url_fetcher.h"
+
+using net::URLFetcher;
+
+namespace content {
+
+// Implementation of URLProvisionFetcher.
+
+URLProvisionFetcher::URLProvisionFetcher(
+ net::URLRequestContextGetter* context_getter)
+ : context_getter_(context_getter) {}
+
+URLProvisionFetcher::~URLProvisionFetcher() {}
+
+void URLProvisionFetcher::Retrieve(
+ const std::string& default_url,
+ const std::string& request_data,
+ const media::ProvisionFetcher::ResponseCB& response_cb) {
+ response_cb_ = response_cb;
+
+ const std::string request_string =
+ default_url + "&signedRequest=" + request_data;
+ DVLOG(1) << __FUNCTION__ << ": request:" << request_string;
+
+ DCHECK(!request_);
+ request_ = URLFetcher::Create(GURL(request_string), URLFetcher::POST, this);
+
+ // SetUploadData is mandatory even if we are not uploading anything.
+ request_->SetUploadData("", "");
+ request_->AddExtraRequestHeader("User-Agent: Widevine CDM v1.0");
+ request_->AddExtraRequestHeader("Content-Type: application/json");
+
+ DCHECK(context_getter_);
+ request_->SetRequestContext(context_getter_);
+
+ request_->Start();
+}
+
+void URLProvisionFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
+ DCHECK(source);
+
+ int response_code = source->GetResponseCode();
+ DVLOG(1) << __FUNCTION__ << ": response code:" << source->GetResponseCode();
+
+ std::string response;
+ bool success = false;
+ if (response_code == 200) {
+ success = source->GetResponseAsString(&response);
+ DVLOG_IF(1, !success) << __FUNCTION__ << ": GetResponseAsString() failed";
+ } else {
+ DVLOG(1) << "CDM provision: server returned error code " << response_code;
+ }
+
+ request_.reset();
+
+ // URLFetcher implementation calls OnURLFetchComplete() on the same thread
+ // that called Start() and it does this asynchronously.
+ response_cb_.Run(success, response);
+}
+
+// Implementation of content public method CreateProvisionFetcher().
+
+scoped_ptr<media::ProvisionFetcher> CreateProvisionFetcher(
+ net::URLRequestContextGetter* context_getter) {
+ DCHECK(context_getter);
+ return make_scoped_ptr(new URLProvisionFetcher(context_getter));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/android/url_provision_fetcher.h b/chromium/content/browser/media/android/url_provision_fetcher.h
new file mode 100644
index 00000000000..7e3d1397e65
--- /dev/null
+++ b/chromium/content/browser/media/android/url_provision_fetcher.h
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_ANDROID_URL_PROVISION_FETCHER_H_
+#define CONTENT_BROWSER_MEDIA_ANDROID_URL_PROVISION_FETCHER_H_
+
+#include "base/macros.h"
+#include "media/base/android/provision_fetcher.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+
+namespace content {
+
+// The ProvisionFetcher that retrieves the data by HTTP POST request.
+
+class URLProvisionFetcher : public media::ProvisionFetcher,
+ public net::URLFetcherDelegate {
+ public:
+ explicit URLProvisionFetcher(net::URLRequestContextGetter* context_getter);
+ ~URLProvisionFetcher() override;
+
+ // media::ProvisionFetcher implementation.
+ void Retrieve(const std::string& default_url,
+ const std::string& request_data,
+ const ProvisionFetcher::ResponseCB& response_cb) override;
+
+ private:
+ // net::URLFetcherDelegate implementation.
+ void OnURLFetchComplete(const net::URLFetcher* source) override;
+
+ net::URLRequestContextGetter* context_getter_;
+ scoped_ptr<net::URLFetcher> request_;
+ media::ProvisionFetcher::ResponseCB response_cb_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLProvisionFetcher);
+};
+
+} // namespace content
+
+#endif // CHROME_BROWSER_MEDIA_ANDROID_URL_PROVISION_FETCHER_H_
diff --git a/chromium/content/browser/media/audible_metrics.cc b/chromium/content/browser/media/audible_metrics.cc
new file mode 100644
index 00000000000..4a740288e79
--- /dev/null
+++ b/chromium/content/browser/media/audible_metrics.cc
@@ -0,0 +1,79 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/audible_metrics.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/user_metrics.h"
+#include "base/time/default_tick_clock.h"
+
+namespace content {
+
+AudibleMetrics::AudibleMetrics()
+ : max_concurrent_audible_web_contents_in_session_(0),
+ clock_(new base::DefaultTickClock()) {
+}
+
+AudibleMetrics::~AudibleMetrics() {
+}
+
+void AudibleMetrics::UpdateAudibleWebContentsState(
+ const WebContents* web_contents, bool audible) {
+ bool found =
+ audible_web_contents_.find(web_contents) != audible_web_contents_.end();
+ if (found == audible)
+ return;
+
+ if (audible)
+ AddAudibleWebContents(web_contents);
+ else
+ RemoveAudibleWebContents(web_contents);
+}
+
+void AudibleMetrics::SetClockForTest(scoped_ptr<base::TickClock> test_clock) {
+ clock_ = std::move(test_clock);
+}
+
+void AudibleMetrics::AddAudibleWebContents(const WebContents* web_contents) {
+ base::RecordAction(base::UserMetricsAction("Media.Audible.AddTab"));
+
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Media.Audible.ConcurrentTabsWhenStarting", audible_web_contents_.size(),
+ 1, 10, 11);
+
+ audible_web_contents_.insert(web_contents);
+ if (audible_web_contents_.size() > 1 &&
+ concurrent_web_contents_start_time_.is_null()) {
+ concurrent_web_contents_start_time_ = clock_->NowTicks();
+ }
+
+ if (audible_web_contents_.size() >
+ max_concurrent_audible_web_contents_in_session_) {
+ max_concurrent_audible_web_contents_in_session_ =
+ audible_web_contents_.size();
+
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Media.Audible.MaxConcurrentTabsInSession",
+ max_concurrent_audible_web_contents_in_session_,
+ 1, 10, 11);
+ }
+}
+
+void AudibleMetrics::RemoveAudibleWebContents(const WebContents* web_contents) {
+ base::RecordAction(base::UserMetricsAction("Media.Audible.RemoveTab"));
+
+ audible_web_contents_.erase(web_contents);
+
+ if (audible_web_contents_.size() <= 1 &&
+ !concurrent_web_contents_start_time_.is_null()) {
+ base::TimeDelta concurrent_total_time =
+ clock_->NowTicks() - concurrent_web_contents_start_time_;
+ concurrent_web_contents_start_time_ = base::TimeTicks();
+
+ UMA_HISTOGRAM_LONG_TIMES("Media.Audible.ConcurrentTabsTime",
+ concurrent_total_time);
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/audible_metrics.h b/chromium/content/browser/media/audible_metrics.h
new file mode 100644
index 00000000000..408bc8cba27
--- /dev/null
+++ b/chromium/content/browser/media/audible_metrics.h
@@ -0,0 +1,49 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_AUDIBLE_METRICS_H_
+#define CONTENT_BROWSER_MEDIA_AUDIBLE_METRICS_H_
+
+#include <set>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/time/tick_clock.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class WebContents;
+
+// This class handles metrics regarding audible WebContents.
+// It does register three different information:
+// - how many WebContents are audible when a WebContents become audible.
+// - how long multiple WebContents are audible at the same time.
+// - for a browsing session, how often and how many WebContents get audible at
+// the same time.
+class CONTENT_EXPORT AudibleMetrics {
+ public:
+ AudibleMetrics();
+ ~AudibleMetrics();
+
+ void UpdateAudibleWebContentsState(const WebContents* web_contents,
+ bool audible);
+
+ void SetClockForTest(scoped_ptr<base::TickClock> test_clock);
+
+ private:
+ void AddAudibleWebContents(const WebContents* web_contents);
+ void RemoveAudibleWebContents(const WebContents* web_contents);
+
+ base::TimeTicks concurrent_web_contents_start_time_;
+ size_t max_concurrent_audible_web_contents_in_session_;
+ scoped_ptr<base::TickClock> clock_;
+
+ std::set<const WebContents*> audible_web_contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudibleMetrics);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_AUDIBLE_METRICS_H_
diff --git a/chromium/content/browser/media/audible_metrics_unittest.cc b/chromium/content/browser/media/audible_metrics_unittest.cc
new file mode 100644
index 00000000000..1a6216b6459
--- /dev/null
+++ b/chromium/content/browser/media/audible_metrics_unittest.cc
@@ -0,0 +1,397 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/audible_metrics.h"
+
+#include "base/metrics/histogram_samples.h"
+#include "base/test/histogram_tester.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "base/test/user_action_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+static const WebContents* WEB_CONTENTS_0 = reinterpret_cast<WebContents*>(0x00);
+static const WebContents* WEB_CONTENTS_1 = reinterpret_cast<WebContents*>(0x01);
+static const WebContents* WEB_CONTENTS_2 = reinterpret_cast<WebContents*>(0x10);
+static const WebContents* WEB_CONTENTS_3 = reinterpret_cast<WebContents*>(0x11);
+
+static const char* CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM =
+ "Media.Audible.ConcurrentTabsWhenStarting";
+static const char* MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM =
+ "Media.Audible.MaxConcurrentTabsInSession";
+static const char* CONCURRENT_TABS_TIME_HISTOGRAM =
+ "Media.Audible.ConcurrentTabsTime";
+
+static const char* ADD_TAB_USER_ACTION = "Media.Audible.AddTab";
+static const char* REMOVE_TAB_USER_ACTION = "Media.Audible.RemoveTab";
+
+class AudibleMetricsTest : public testing::Test {
+ public:
+ AudibleMetricsTest() = default;
+
+ void SetUp() override {
+ clock_ = new base::SimpleTestTickClock();
+ // Set the clock to a value different than 0 so the time it gives is
+ // recognized as initialized.
+ clock_->Advance(base::TimeDelta::FromMilliseconds(1));
+ audible_metrics_.SetClockForTest(
+ scoped_ptr<base::SimpleTestTickClock>(clock_));
+ }
+
+ void TearDown() override {
+ clock_ = nullptr;
+ }
+
+ base::SimpleTestTickClock* clock() { return clock_; }
+
+ AudibleMetrics* audible_metrics() {
+ return &audible_metrics_;
+ };
+
+ const base::UserActionTester& user_action_tester() const {
+ return user_action_tester_;
+ }
+
+ scoped_ptr<base::HistogramSamples> GetHistogramSamplesSinceTestStart(
+ const std::string& name) {
+ return histogram_tester_.GetHistogramSamplesSinceCreation(name);
+ }
+
+ private:
+ base::SimpleTestTickClock* clock_ = nullptr;
+ AudibleMetrics audible_metrics_;
+ base::HistogramTester histogram_tester_;
+ base::UserActionTester user_action_tester_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudibleMetricsTest);
+};
+
+} // anonymous namespace
+
+TEST_F(AudibleMetricsTest, CreateAndKillDoesNothing) {
+ {
+ scoped_ptr<AudibleMetrics> audible_metrics(new AudibleMetrics());
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(0, samples->TotalCount());
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM));
+ EXPECT_EQ(0, samples->TotalCount());
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(CONCURRENT_TABS_TIME_HISTOGRAM));
+ EXPECT_EQ(0, samples->TotalCount());
+ }
+
+ EXPECT_EQ(0, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(0, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, AudibleStart) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(0));
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1));
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(CONCURRENT_TABS_TIME_HISTOGRAM));
+ EXPECT_EQ(0, samples->TotalCount());
+ }
+
+ EXPECT_EQ(1, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(0, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, AudibleStartAndStop) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(0));
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1));
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(CONCURRENT_TABS_TIME_HISTOGRAM));
+ EXPECT_EQ(0, samples->TotalCount());
+ }
+
+ EXPECT_EQ(1, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(1, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, AddSameTabIsNoOp) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(0));
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1));
+ }
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(CONCURRENT_TABS_TIME_HISTOGRAM));
+ EXPECT_EQ(0, samples->TotalCount());
+ }
+
+ EXPECT_EQ(1, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(0, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, RemoveUnknownTabIsNoOp) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+
+ EXPECT_EQ(0, GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM)->TotalCount());
+ EXPECT_EQ(0, GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM)->TotalCount());
+ EXPECT_EQ(0, GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TABS_TIME_HISTOGRAM)->TotalCount());
+
+ EXPECT_EQ(0, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(0, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, ConcurrentTabsInSessionIsIncremental) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_2, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_3, true);
+
+ scoped_ptr<base::HistogramSamples> samples(GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM));
+ EXPECT_EQ(4, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1));
+ EXPECT_EQ(1, samples->GetCount(2));
+ EXPECT_EQ(1, samples->GetCount(3));
+ EXPECT_EQ(1, samples->GetCount(4));
+
+ EXPECT_EQ(4, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(0, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, ConcurrentTabsInSessionKeepTrackOfRemovedTabs) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_2, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_2, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_3, true);
+
+ scoped_ptr<base::HistogramSamples> samples(GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM));
+ EXPECT_EQ(2, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1));
+ EXPECT_EQ(1, samples->GetCount(2));
+
+ EXPECT_EQ(4, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(3, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, ConcurrentTabsInSessionIsNotCountedTwice) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_2, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_3, true);
+
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_2, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_3, false);
+
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_2, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_3, true);
+
+ scoped_ptr<base::HistogramSamples> samples(GetHistogramSamplesSinceTestStart(
+ MAX_CONCURRENT_TAB_IN_SESSION_HISTOGRAM));
+ EXPECT_EQ(4, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1));
+ EXPECT_EQ(1, samples->GetCount(2));
+ EXPECT_EQ(1, samples->GetCount(3));
+ EXPECT_EQ(1, samples->GetCount(4));
+
+ EXPECT_EQ(8, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(4, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, ConcurrentTabsWhenStartingAddedPerTab) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(2, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(0));
+ EXPECT_EQ(1, samples->GetCount(1));
+ }
+
+ EXPECT_EQ(2, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(0, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+
+ // Added again: ignored.
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(2, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(0));
+ EXPECT_EQ(1, samples->GetCount(1));
+ }
+
+ EXPECT_EQ(2, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(0, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+
+ // Removing both.
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, false);
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(2, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(0));
+ EXPECT_EQ(1, samples->GetCount(1));
+ }
+
+ EXPECT_EQ(2, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(2, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+
+ // Adding them after removed, it is counted.
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TAB_WHEN_STARTING_HISTOGRAM));
+ EXPECT_EQ(4, samples->TotalCount());
+ EXPECT_EQ(2, samples->GetCount(0));
+ EXPECT_EQ(2, samples->GetCount(1));
+ }
+
+ EXPECT_EQ(4, user_action_tester().GetActionCount(ADD_TAB_USER_ACTION));
+ EXPECT_EQ(2, user_action_tester().GetActionCount(REMOVE_TAB_USER_ACTION));
+}
+
+TEST_F(AudibleMetricsTest, ConcurrentTabsTimeRequiresTwoAudibleTabs) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+
+ clock()->Advance(base::TimeDelta::FromMilliseconds(1000));
+
+ // No record because concurrent audible tabs still running.
+ EXPECT_EQ(0, GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TABS_TIME_HISTOGRAM)->TotalCount());
+
+ // No longer concurrent.
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(CONCURRENT_TABS_TIME_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1000));
+ }
+
+ // Stopping the second tab is a no-op.
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, false);
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(CONCURRENT_TABS_TIME_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1000));
+ }
+}
+
+TEST_F(AudibleMetricsTest, ConcurrentTabsTimeRunsAsLongAsTwoAudibleTabs) {
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, true);
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, true);
+
+ clock()->Advance(base::TimeDelta::FromMilliseconds(1000));
+
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_2, true);
+
+ clock()->Advance(base::TimeDelta::FromMilliseconds(500));
+
+ // Mutes one of the three audible tabs.
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_1, false);
+
+ // No record because concurrent audible tabs still running.
+ EXPECT_EQ(0, GetHistogramSamplesSinceTestStart(
+ CONCURRENT_TABS_TIME_HISTOGRAM)->TotalCount());
+
+ // Mutes the first audible tab.
+ audible_metrics()->UpdateAudibleWebContentsState(WEB_CONTENTS_0, false);
+ {
+ scoped_ptr<base::HistogramSamples> samples(
+ GetHistogramSamplesSinceTestStart(CONCURRENT_TABS_TIME_HISTOGRAM));
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(1500));
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/audio_stream_monitor.cc b/chromium/content/browser/media/audio_stream_monitor.cc
index 2f6a7e45ce0..b19e82ff462 100644
--- a/chromium/content/browser/media/audio_stream_monitor.cc
+++ b/chromium/content/browser/media/audio_stream_monitor.cc
@@ -30,7 +30,8 @@ AudioStreamMonitor* AudioStreamMonitorFromRenderFrame(int render_process_id,
AudioStreamMonitor::AudioStreamMonitor(WebContents* contents)
: web_contents_(contents),
clock_(&default_tick_clock_),
- was_recently_audible_(false)
+ was_recently_audible_(false),
+ is_audible_(false)
{
DCHECK(web_contents_);
}
@@ -42,6 +43,11 @@ bool AudioStreamMonitor::WasRecentlyAudible() const {
return was_recently_audible_;
}
+bool AudioStreamMonitor::IsCurrentlyAudible() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return is_audible_;
+}
+
// static
void AudioStreamMonitor::StartMonitoringStream(
int render_process_id,
@@ -124,6 +130,9 @@ void AudioStreamMonitor::StopMonitoringStreamOnUIThread(int render_process_id,
}
void AudioStreamMonitor::Poll() {
+ bool was_audible = is_audible_;
+ is_audible_ = false;
+
for (StreamPollCallbackMap::const_iterator it = poll_callbacks_.begin();
it != poll_callbacks_.end();
++it) {
@@ -132,12 +141,17 @@ void AudioStreamMonitor::Poll() {
// information except for "is it audible?"
const float power_dbfs = it->second.Run().first;
const float kSilenceThresholdDBFS = -72.24719896f;
+
if (power_dbfs >= kSilenceThresholdDBFS) {
last_blurt_time_ = clock_->NowTicks();
+ is_audible_ = true;
MaybeToggle();
break; // No need to poll remaining streams.
}
}
+
+ if (is_audible_ != was_audible)
+ web_contents_->NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
}
void AudioStreamMonitor::MaybeToggle() {
diff --git a/chromium/content/browser/media/audio_stream_monitor.h b/chromium/content/browser/media/audio_stream_monitor.h
index 7756d3ef118..12f06055c54 100644
--- a/chromium/content/browser/media/audio_stream_monitor.h
+++ b/chromium/content/browser/media/audio_stream_monitor.h
@@ -9,6 +9,7 @@
#include <utility>
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
@@ -51,6 +52,11 @@ class CONTENT_EXPORT AudioStreamMonitor {
// the killing of tabs making sounds).
bool WasRecentlyAudible() const;
+ // Returns true if the audio is currently audible from the given WebContents.
+ // The difference from WasRecentlyAudible() is that this method will return
+ // false as soon as the WebContents stop producing sound.
+ bool IsCurrentlyAudible() const;
+
// Starts or stops audio level monitoring respectively for the stream owned by
// the specified renderer. Safe to call from any thread.
//
@@ -138,6 +144,9 @@ class CONTENT_EXPORT AudioStreamMonitor {
// should be turned on.
bool was_recently_audible_;
+ // Whether the WebContents is currently audible.
+ bool is_audible_;
+
// Calls Poll() at regular intervals while |poll_callbacks_| is non-empty.
base::RepeatingTimer poll_timer_;
diff --git a/chromium/content/browser/media/audio_stream_monitor_unittest.cc b/chromium/content/browser/media/audio_stream_monitor_unittest.cc
index f3189af9ed0..9ecee0a5aec 100644
--- a/chromium/content/browser/media/audio_stream_monitor_unittest.cc
+++ b/chromium/content/browser/media/audio_stream_monitor_unittest.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/test/simple_test_tick_clock.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -92,16 +93,37 @@ class AudioStreamMonitorTest : public RenderViewHostTestHarness {
monitor_->off_timer_.IsRunning());
}
- void ExpectWebContentsWillBeNotifiedOnce(bool should_be_audible) {
+ void ExpectIsCurrentlyAudible() const {
+ EXPECT_TRUE(monitor_->IsCurrentlyAudible());
+ }
+
+ void ExpectNotCurrentlyAudible() const {
+ EXPECT_FALSE(monitor_->IsCurrentlyAudible());
+ }
+
+ void ExpectRecentlyAudibleChangeNotification(bool new_recently_audible) {
+ EXPECT_CALL(
+ mock_web_contents_delegate_,
+ NavigationStateChanged(RenderViewHostTestHarness::web_contents(),
+ INVALIDATE_TYPE_TAB))
+ .WillOnce(InvokeWithoutArgs(
+ this,
+ new_recently_audible
+ ? &AudioStreamMonitorTest::ExpectWasRecentlyAudible
+ : &AudioStreamMonitorTest::ExpectNotRecentlyAudible))
+ .RetiresOnSaturation();
+ }
+
+ void ExpectCurrentlyAudibleChangeNotification(bool new_audible) {
EXPECT_CALL(
mock_web_contents_delegate_,
NavigationStateChanged(RenderViewHostTestHarness::web_contents(),
INVALIDATE_TYPE_TAB))
.WillOnce(InvokeWithoutArgs(
this,
- should_be_audible
- ? &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOn
- : &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOff))
+ new_audible
+ ? &AudioStreamMonitorTest::ExpectIsCurrentlyAudible
+ : &AudioStreamMonitorTest::ExpectNotCurrentlyAudible))
.RetiresOnSaturation();
}
@@ -135,11 +157,11 @@ class AudioStreamMonitorTest : public RenderViewHostTestHarness {
return std::make_pair(current_power_[stream_id], false);
}
- void ExpectIsNotifyingForToggleOn() {
+ void ExpectWasRecentlyAudible() const {
EXPECT_TRUE(monitor_->WasRecentlyAudible());
}
- void ExpectIsNotifyingForToggleOff() {
+ void ExpectNotRecentlyAudible() const {
EXPECT_FALSE(monitor_->WasRecentlyAudible());
}
@@ -154,14 +176,17 @@ class AudioStreamMonitorTest : public RenderViewHostTestHarness {
// ReadPowerAndClipCallback, and is not polling at other times.
TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) {
EXPECT_FALSE(monitor_->WasRecentlyAudible());
+ ExpectNotCurrentlyAudible();
ExpectIsPolling(kRenderProcessId, kStreamId, false);
StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
EXPECT_FALSE(monitor_->WasRecentlyAudible());
+ ExpectNotCurrentlyAudible();
ExpectIsPolling(kRenderProcessId, kStreamId, true);
StopMonitoring(kRenderProcessId, kStreamId);
EXPECT_FALSE(monitor_->WasRecentlyAudible());
+ ExpectNotCurrentlyAudible();
ExpectIsPolling(kRenderProcessId, kStreamId, false);
}
@@ -174,13 +199,16 @@ TEST_F(AudioStreamMonitorTest,
// Expect WebContents will get one call form AudioStreamMonitor to toggle the
// indicator on upon the very first poll.
- ExpectWebContentsWillBeNotifiedOnce(true);
+ ExpectRecentlyAudibleChangeNotification(true);
// Loop, each time testing a slightly longer period of polled silence. The
- // indicator should remain on throughout.
- int num_silence_polls = 0;
+ // recently audible state should not change while the currently audible one
+ // should.
+ int num_silence_polls = 1;
base::TimeTicks last_blurt_time;
do {
+ ExpectCurrentlyAudibleChangeNotification(true);
+
// Poll an audible signal, and expect tab indicator state is on.
SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power());
last_blurt_time = GetTestClockTime();
@@ -188,6 +216,8 @@ TEST_F(AudioStreamMonitorTest,
ExpectTabWasRecentlyAudible(true, last_blurt_time);
AdvanceClock(one_polling_interval());
+ ExpectCurrentlyAudibleChangeNotification(false);
+
// Poll a silent signal repeatedly, ensuring that the indicator is being
// held on during the holding period.
SetStreamPower(kStreamId, media::AudioPowerMonitor::zero_power());
@@ -206,7 +236,7 @@ TEST_F(AudioStreamMonitorTest,
// At this point, the clock has just advanced to beyond the holding period, so
// the next firing of the off timer should turn off the tab indicator. Also,
// make sure it stays off for several cycles thereafter.
- ExpectWebContentsWillBeNotifiedOnce(false);
+ ExpectRecentlyAudibleChangeNotification(false);
for (int i = 0; i < 10; ++i) {
SimulateOffTimerFired();
ExpectTabWasRecentlyAudible(false, last_blurt_time);
@@ -223,15 +253,19 @@ TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) {
base::TimeTicks last_blurt_time;
ExpectTabWasRecentlyAudible(false, last_blurt_time);
+ ExpectNotCurrentlyAudible();
// Measure audible sound from the first stream and silence from the second.
- // The indicator turns on (i.e., tab was recently audible).
- ExpectWebContentsWillBeNotifiedOnce(true);
+ // The tab becomes audible.
+ ExpectRecentlyAudibleChangeNotification(true);
+ ExpectCurrentlyAudibleChangeNotification(true);
+
SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power());
SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power());
last_blurt_time = GetTestClockTime();
SimulatePollTimerFired();
ExpectTabWasRecentlyAudible(true, last_blurt_time);
+ ExpectIsCurrentlyAudible();
// Halfway through the holding period, the second stream joins in. The
// indicator stays on.
@@ -241,39 +275,52 @@ TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) {
last_blurt_time = GetTestClockTime();
SimulatePollTimerFired(); // Restarts holding period.
ExpectTabWasRecentlyAudible(true, last_blurt_time);
+ ExpectIsCurrentlyAudible();
// Now, measure silence from both streams. After an entire holding period
- // has passed (since the second stream joined in), the indicator should turn
- // off.
- ExpectWebContentsWillBeNotifiedOnce(false);
+ // has passed (since the second stream joined in), the tab will no longer
+ // become audible nor recently audible.
+ ExpectCurrentlyAudibleChangeNotification(false);
+ ExpectRecentlyAudibleChangeNotification(false);
+
AdvanceClock(holding_period());
SimulateOffTimerFired();
SetStreamPower(kStreamId, media::AudioPowerMonitor::zero_power());
SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power());
SimulatePollTimerFired();
ExpectTabWasRecentlyAudible(false, last_blurt_time);
+ ExpectNotCurrentlyAudible();
// Now, measure silence from the first stream and audible sound from the
- // second. The indicator turns back on.
- ExpectWebContentsWillBeNotifiedOnce(true);
+ // second. The tab becomes audible again.
+ ExpectRecentlyAudibleChangeNotification(true);
+ ExpectCurrentlyAudibleChangeNotification(true);
+
SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::max_power());
last_blurt_time = GetTestClockTime();
SimulatePollTimerFired();
ExpectTabWasRecentlyAudible(true, last_blurt_time);
+ ExpectIsCurrentlyAudible();
// From here onwards, both streams are silent. Halfway through the holding
- // period, the indicator should not have changed.
+ // period, the tab is no longer audible but stays as recently audible.
+ ExpectCurrentlyAudibleChangeNotification(false);
+
SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power());
AdvanceClock(holding_period() / 2);
SimulatePollTimerFired();
SimulateOffTimerFired();
ExpectTabWasRecentlyAudible(true, last_blurt_time);
+ ExpectNotCurrentlyAudible();
+
+ // Just past the holding period, the tab is no longer marked as recently
+ // audible.
+ ExpectRecentlyAudibleChangeNotification(false);
- // Just past the holding period, the indicator should be turned off.
- ExpectWebContentsWillBeNotifiedOnce(false);
AdvanceClock(holding_period() - (GetTestClockTime() - last_blurt_time));
SimulateOffTimerFired();
ExpectTabWasRecentlyAudible(false, last_blurt_time);
+ ExpectNotCurrentlyAudible();
// Polling should not turn the indicator back while both streams are remaining
// silent.
@@ -281,6 +328,7 @@ TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) {
AdvanceClock(one_polling_interval());
SimulatePollTimerFired();
ExpectTabWasRecentlyAudible(false, last_blurt_time);
+ ExpectNotCurrentlyAudible();
}
}
diff --git a/chromium/content/browser/media/capture/DEPS b/chromium/content/browser/media/capture/DEPS
index f3e90f187b3..bc724e16a5d 100644
--- a/chromium/content/browser/media/capture/DEPS
+++ b/chromium/content/browser/media/capture/DEPS
@@ -2,3 +2,11 @@ include_rules = [
"+media/capture/content",
"+third_party/libyuv", # For scaling in desktop_capture_device.cc.
]
+
+specific_include_rules = {
+ ".*test\.cc": [
+ # Allow inclusion of specific components that we depend on for testing
+ "+ui/base/resource/resource_bundle.h",
+ ],
+}
+
diff --git a/chromium/content/browser/media/capture/audio_mirroring_manager.h b/chromium/content/browser/media/capture/audio_mirroring_manager.h
index 441c884ad92..4e44699097a 100644
--- a/chromium/content/browser/media/capture/audio_mirroring_manager.h
+++ b/chromium/content/browser/media/capture/audio_mirroring_manager.h
@@ -36,8 +36,8 @@
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "media/audio/audio_source_diverter.h"
diff --git a/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc b/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc
index 6fece29c09f..0f471c88171 100644
--- a/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc
+++ b/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "content/browser/browser_thread_impl.h"
diff --git a/chromium/content/browser/media/capture/aura_window_capture_machine.cc b/chromium/content/browser/media/capture/aura_window_capture_machine.cc
index eead7d71632..c3405994e94 100644
--- a/chromium/content/browser/media/capture/aura_window_capture_machine.cc
+++ b/chromium/content/browser/media/capture/aura_window_capture_machine.cc
@@ -4,6 +4,9 @@
#include "content/browser/media/capture/aura_window_capture_machine.h"
+#include <algorithm>
+#include <utility>
+
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/timer/timer.h"
@@ -30,97 +33,10 @@
#include "ui/compositor/dip_util.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/screen.h"
+#include "ui/wm/public/activation_client.h"
namespace content {
-namespace {
-
-int clip_byte(int x) {
- return std::max(0, std::min(x, 255));
-}
-
-int alpha_blend(int alpha, int src, int dst) {
- return (src * alpha + dst * (255 - alpha)) / 255;
-}
-
-// Helper function to composite a cursor bitmap on a YUV420 video frame.
-void RenderCursorOnVideoFrame(
- const scoped_refptr<media::VideoFrame>& target,
- const SkBitmap& cursor_bitmap,
- const gfx::Point& cursor_position) {
- DCHECK(target.get());
- DCHECK(!cursor_bitmap.isNull());
-
- gfx::Rect rect = gfx::IntersectRects(
- gfx::Rect(cursor_bitmap.width(), cursor_bitmap.height()) +
- gfx::Vector2d(cursor_position.x(), cursor_position.y()),
- target->visible_rect());
-
- cursor_bitmap.lockPixels();
- for (int y = rect.y(); y < rect.bottom(); ++y) {
- int cursor_y = y - cursor_position.y();
- uint8* yplane = target->data(media::VideoFrame::kYPlane) +
- y * target->row_bytes(media::VideoFrame::kYPlane);
- uint8* uplane = target->data(media::VideoFrame::kUPlane) +
- (y / 2) * target->row_bytes(media::VideoFrame::kUPlane);
- uint8* vplane = target->data(media::VideoFrame::kVPlane) +
- (y / 2) * target->row_bytes(media::VideoFrame::kVPlane);
- for (int x = rect.x(); x < rect.right(); ++x) {
- int cursor_x = x - cursor_position.x();
- SkColor color = cursor_bitmap.getColor(cursor_x, cursor_y);
- int alpha = SkColorGetA(color);
- int color_r = SkColorGetR(color);
- int color_g = SkColorGetG(color);
- int color_b = SkColorGetB(color);
- int color_y = clip_byte(((color_r * 66 + color_g * 129 + color_b * 25 +
- 128) >> 8) + 16);
- yplane[x] = alpha_blend(alpha, color_y, yplane[x]);
-
- // Only sample U and V at even coordinates.
- if ((x % 2 == 0) && (y % 2 == 0)) {
- int color_u = clip_byte(((color_r * -38 + color_g * -74 +
- color_b * 112 + 128) >> 8) + 128);
- int color_v = clip_byte(((color_r * 112 + color_g * -94 +
- color_b * -18 + 128) >> 8) + 128);
- uplane[x / 2] = alpha_blend(alpha, color_u, uplane[x / 2]);
- vplane[x / 2] = alpha_blend(alpha, color_v, vplane[x / 2]);
- }
- }
- }
- cursor_bitmap.unlockPixels();
-}
-
-using CaptureFrameCallback =
- media::ThreadSafeCaptureOracle::CaptureFrameCallback;
-
-void CopyOutputFinishedForVideo(
- base::WeakPtr<AuraWindowCaptureMachine> machine,
- base::TimeTicks start_time,
- const CaptureFrameCallback& capture_frame_cb,
- const scoped_refptr<media::VideoFrame>& target,
- const SkBitmap& cursor_bitmap,
- const gfx::Point& cursor_position,
- scoped_ptr<cc::SingleReleaseCallback> release_callback,
- bool result) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- if (!cursor_bitmap.isNull())
- RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position);
- release_callback->Run(0, false);
-
- // Only deliver the captured frame if the AuraWindowCaptureMachine has not
- // been stopped (i.e., the WeakPtr is still valid).
- if (machine.get())
- capture_frame_cb.Run(target, start_time, result);
-}
-
-void RunSingleReleaseCallback(scoped_ptr<cc::SingleReleaseCallback> cb,
- uint32 sync_point) {
- cb->Run(sync_point, false);
-}
-
-} // namespace
-
AuraWindowCaptureMachine::AuraWindowCaptureMachine()
: desktop_window_(NULL),
timer_(true, true),
@@ -211,6 +127,7 @@ void AuraWindowCaptureMachine::InternalStop(const base::Closure& callback) {
window_host->compositor()->RemoveObserver(this);
desktop_window_->RemoveObserver(this);
desktop_window_ = NULL;
+ cursor_renderer_.reset();
}
// Stop timer.
@@ -224,6 +141,7 @@ void AuraWindowCaptureMachine::SetWindow(aura::Window* window) {
DCHECK(!desktop_window_);
desktop_window_ = window;
+ cursor_renderer_.reset(new CursorRendererAura(window));
// Start observing window events.
desktop_window_->AddObserver(this);
@@ -242,7 +160,7 @@ void AuraWindowCaptureMachine::UpdateCaptureSize() {
oracle_proxy_->UpdateCaptureSize(ui::ConvertSizeToPixel(
layer, layer->bounds().size()));
}
- ClearCursorState();
+ cursor_renderer_->Clear();
}
void AuraWindowCaptureMachine::Capture(bool dirty) {
@@ -272,7 +190,7 @@ void AuraWindowCaptureMachine::Capture(bool dirty) {
gfx::Rect window_rect = gfx::Rect(desktop_window_->bounds().width(),
desktop_window_->bounds().height());
request->set_area(window_rect);
- desktop_window_->layer()->RequestCopyOfOutput(request.Pass());
+ desktop_window_->layer()->RequestCopyOfOutput(std::move(request));
}
}
@@ -286,7 +204,7 @@ void AuraWindowCaptureMachine::DidCopyOutput(
static bool first_call = true;
bool succeeded = ProcessCopyOutputResponse(
- video_frame, start_time, capture_frame_cb, result.Pass());
+ video_frame, start_time, capture_frame_cb, std::move(result));
base::TimeDelta capture_time = base::TimeTicks::Now() - start_time;
@@ -320,30 +238,7 @@ bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
if (result->IsEmpty() || result->size().IsEmpty() || !desktop_window_)
return false;
-
- if (capture_params_.requested_format.pixel_storage ==
- media::PIXEL_STORAGE_TEXTURE) {
- DCHECK_EQ(media::PIXEL_FORMAT_ARGB,
- capture_params_.requested_format.pixel_format);
- DCHECK(!video_frame.get());
- cc::TextureMailbox texture_mailbox;
- scoped_ptr<cc::SingleReleaseCallback> release_callback;
- result->TakeTexture(&texture_mailbox, &release_callback);
- DCHECK(texture_mailbox.IsTexture());
- if (!texture_mailbox.IsTexture())
- return false;
- video_frame = media::VideoFrame::WrapNativeTexture(
- media::PIXEL_FORMAT_ARGB,
- gpu::MailboxHolder(texture_mailbox.mailbox(), texture_mailbox.target(),
- texture_mailbox.sync_point()),
- base::Bind(&RunSingleReleaseCallback, base::Passed(&release_callback)),
- result->size(), gfx::Rect(result->size()), result->size(),
- base::TimeDelta());
- capture_frame_cb.Run(video_frame, start_time, true);
- return true;
- } else {
- DCHECK(video_frame.get());
- }
+ DCHECK(video_frame.get());
// Compute the dest size we want after the letterboxing resize. Make the
// coordinates and sizes even because we letterbox in YUV space
@@ -386,79 +281,38 @@ bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
true));
}
- gfx::Point cursor_position_in_frame = UpdateCursorState(region_in_frame);
+ cursor_renderer_->SnapshotCursorState(region_in_frame);
yuv_readback_pipeline_->ReadbackYUV(
- texture_mailbox.mailbox(),
- texture_mailbox.sync_point(),
- video_frame.get(),
- region_in_frame.origin(),
- base::Bind(&CopyOutputFinishedForVideo,
- weak_factory_.GetWeakPtr(),
- start_time,
- capture_frame_cb,
- video_frame,
- scaled_cursor_bitmap_,
- cursor_position_in_frame,
+ texture_mailbox.mailbox(), texture_mailbox.sync_token(),
+ video_frame.get(), region_in_frame.origin(),
+ base::Bind(&CopyOutputFinishedForVideo, weak_factory_.GetWeakPtr(),
+ start_time, capture_frame_cb, video_frame,
base::Passed(&release_callback)));
return true;
}
-gfx::Point AuraWindowCaptureMachine::UpdateCursorState(
- const gfx::Rect& region_in_frame) {
- const gfx::Rect desktop_bounds = desktop_window_->layer()->bounds();
- if (desktop_bounds.IsEmpty()) {
- // Return early to prevent divide-by-zero in calculations below.
- ClearCursorState();
- return gfx::Point();
- }
+using CaptureFrameCallback =
+ media::ThreadSafeCaptureOracle::CaptureFrameCallback;
- gfx::NativeCursor cursor =
- desktop_window_->GetHost()->last_cursor();
- if (last_cursor_ != cursor ||
- desktop_size_when_cursor_last_updated_ != desktop_bounds.size()) {
- SkBitmap cursor_bitmap;
- if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) {
- const int scaled_width = cursor_bitmap.width() *
- region_in_frame.width() / desktop_bounds.width();
- const int scaled_height = cursor_bitmap.height() *
- region_in_frame.height() / desktop_bounds.height();
- if (scaled_width <= 0 || scaled_height <= 0) {
- ClearCursorState();
- return gfx::Point();
- }
- scaled_cursor_bitmap_ = skia::ImageOperations::Resize(
- cursor_bitmap,
- skia::ImageOperations::RESIZE_BEST,
- scaled_width,
- scaled_height);
- last_cursor_ = cursor;
- desktop_size_when_cursor_last_updated_ = desktop_bounds.size();
- } else {
- // Clear cursor state if ui::GetCursorBitmap failed so that we do not
- // render cursor on the captured frame.
- ClearCursorState();
- }
- }
+void AuraWindowCaptureMachine::CopyOutputFinishedForVideo(
+ base::WeakPtr<AuraWindowCaptureMachine> machine,
+ base::TimeTicks start_time,
+ const CaptureFrameCallback& capture_frame_cb,
+ const scoped_refptr<media::VideoFrame>& target,
+ scoped_ptr<cc::SingleReleaseCallback> release_callback,
+ bool result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- gfx::Point cursor_position = aura::Env::GetInstance()->last_mouse_location();
- aura::client::GetScreenPositionClient(desktop_window_->GetRootWindow())->
- ConvertPointFromScreen(desktop_window_, &cursor_position);
- const gfx::Point hot_point_in_dip = ui::ConvertPointToDIP(
- desktop_window_->layer(), cursor_hot_point_);
- cursor_position.Offset(-desktop_bounds.x() - hot_point_in_dip.x(),
- -desktop_bounds.y() - hot_point_in_dip.y());
- return gfx::Point(
- region_in_frame.x() + cursor_position.x() * region_in_frame.width() /
- desktop_bounds.width(),
- region_in_frame.y() + cursor_position.y() * region_in_frame.height() /
- desktop_bounds.height());
-}
+ release_callback->Run(gpu::SyncToken(), false);
-void AuraWindowCaptureMachine::ClearCursorState() {
- last_cursor_ = ui::Cursor();
- desktop_size_when_cursor_last_updated_ = gfx::Size();
- cursor_hot_point_ = gfx::Point();
- scaled_cursor_bitmap_.reset();
+ // Render the cursor and deliver the captured frame if the
+ // AuraWindowCaptureMachine has not been stopped (i.e., the WeakPtr is
+ // still valid).
+ if (machine.get()) {
+ if (machine->cursor_renderer_ && result)
+ machine->cursor_renderer_->RenderOnVideoFrame(target);
+ capture_frame_cb.Run(target, start_time, result);
+ }
}
void AuraWindowCaptureMachine::OnWindowBoundsChanged(
@@ -479,7 +333,7 @@ void AuraWindowCaptureMachine::OnWindowDestroying(aura::Window* window) {
InternalStop(base::Bind(&base::DoNothing));
- oracle_proxy_->ReportError("OnWindowDestroying()");
+ oracle_proxy_->ReportError(FROM_HERE, "OnWindowDestroying()");
}
void AuraWindowCaptureMachine::OnWindowAddedToRootWindow(
diff --git a/chromium/content/browser/media/capture/aura_window_capture_machine.h b/chromium/content/browser/media/capture/aura_window_capture_machine.h
index dd05f30d1be..c07c72f8c8c 100644
--- a/chromium/content/browser/media/capture/aura_window_capture_machine.h
+++ b/chromium/content/browser/media/capture/aura_window_capture_machine.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_AURA_WINDOW_CAPTURE_MACHINE_H_
#define CONTENT_BROWSER_MEDIA_CAPTURE_AURA_WINDOW_CAPTURE_MACHINE_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
+#include "content/browser/media/capture/cursor_renderer_aura.h"
#include "media/capture/content/screen_capture_device_core.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
@@ -91,14 +93,14 @@ class AuraWindowCaptureMachine
const CaptureFrameCallback& capture_frame_cb,
scoped_ptr<cc::CopyOutputResult> result);
- // Helper function to update cursor state.
- // |region_in_frame| defines where the desktop is rendered in the captured
- // frame.
- // Returns the current cursor position in captured frame.
- gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame);
-
- // Clears cursor state.
- void ClearCursorState();
+ // Renders the cursor if needed and then delivers the captured frame.
+ static void CopyOutputFinishedForVideo(
+ base::WeakPtr<AuraWindowCaptureMachine> machine,
+ base::TimeTicks start_time,
+ const CaptureFrameCallback& capture_frame_cb,
+ const scoped_refptr<media::VideoFrame>& target,
+ scoped_ptr<cc::SingleReleaseCallback> release_callback,
+ bool result);
// The window associated with the desktop.
aura::Window* desktop_window_;
@@ -118,11 +120,8 @@ class AuraWindowCaptureMachine
// YUV readback pipeline.
scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_;
- // Cursor state.
- ui::Cursor last_cursor_;
- gfx::Size desktop_size_when_cursor_last_updated_;
- gfx::Point cursor_hot_point_;
- SkBitmap scaled_cursor_bitmap_;
+ // Renders mouse cursor on frame.
+ scoped_ptr<content::CursorRendererAura> cursor_renderer_;
// TODO(jiayl): Remove power_save_blocker_ when there is an API to keep the
// screen from sleeping for the drive-by web.
diff --git a/chromium/content/browser/media/capture/cursor_renderer.h b/chromium/content/browser/media/capture/cursor_renderer.h
new file mode 100644
index 00000000000..7416413f421
--- /dev/null
+++ b/chromium/content/browser/media/capture/cursor_renderer.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_CURSOR_RENDERER_H_
+#define CONTENT_BROWSER_MEDIA_CAPTURE_CURSOR_RENDERER_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "media/base/video_frame.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace content {
+
+// CursorRenderer is an interface that can be implememented to do cursor
+// rendering on a video frame.
+//
+// In order to track the cursor, the platform-specific implementation
+// will listen to mouse events.
+class CONTENT_EXPORT CursorRenderer {
+ public:
+ virtual ~CursorRenderer() {}
+
+ // Clears the cursor state being tracked. Called when there is a need to
+ // reset the state.
+ virtual void Clear() = 0;
+
+ // Takes a snapshot of the current cursor state and determines whether
+ // the cursor will be rendered, which cursor image to render, and at what
+ // location within |region_in_frame| to render it. Returns true if cursor
+ // needs to be rendered.
+ virtual bool SnapshotCursorState(const gfx::Rect& region_in_frame) = 0;
+
+ // Renders cursor on the |target| video frame.
+ virtual void RenderOnVideoFrame(
+ const scoped_refptr<media::VideoFrame>& target) const = 0;
+
+ // Returns a weak pointer.
+ virtual base::WeakPtr<CursorRenderer> GetWeakPtr() = 0;
+
+ protected:
+ enum {
+ // Minium movement before cursor is rendered on frame.
+ MIN_MOVEMENT_PIXELS = 15,
+ // Maximum idle time allowed before we stop rendering the cursor
+ // on frame.
+ MAX_IDLE_TIME_SECONDS = 2
+ };
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_CAPTURE_CURSOR_RENDERER_H_
diff --git a/chromium/content/browser/media/capture/cursor_renderer_aura.cc b/chromium/content/browser/media/capture/cursor_renderer_aura.cc
new file mode 100644
index 00000000000..238ed9a1e52
--- /dev/null
+++ b/chromium/content/browser/media/capture/cursor_renderer_aura.cc
@@ -0,0 +1,226 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/capture/cursor_renderer_aura.h"
+
+#include <stdint.h>
+
+#include <algorithm>
+#include <cmath>
+
+#include "base/logging.h"
+#include "base/time/default_tick_clock.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/aura/env.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/base/cursor/cursors_aura.h"
+#include "ui/compositor/dip_util.h"
+#include "ui/compositor/layer.h"
+#include "ui/events/event_utils.h"
+#include "ui/wm/public/activation_client.h"
+
+namespace content {
+
+namespace {
+
+inline int clip_byte(int x) {
+ return std::max(0, std::min(x, 255));
+}
+
+inline int alpha_blend(int alpha, int src, int dst) {
+ return (src * alpha + dst * (255 - alpha)) / 255;
+}
+
+} // namespace
+
+CursorRendererAura::CursorRendererAura(aura::Window* window)
+ : window_(window), tick_clock_(&default_tick_clock_), weak_factory_(this) {
+ if (window_) {
+ window_->AddObserver(this);
+ window_->AddPreTargetHandler(this);
+ }
+ Clear();
+}
+
+CursorRendererAura::~CursorRendererAura() {
+ if (window_) {
+ window_->RemoveObserver(this);
+ window_->RemovePreTargetHandler(this);
+ }
+}
+
+base::WeakPtr<CursorRenderer> CursorRendererAura::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+void CursorRendererAura::Clear() {
+ last_cursor_ = ui::Cursor();
+ window_size_when_cursor_last_updated_ = gfx::Size();
+ scaled_cursor_bitmap_.reset();
+ last_mouse_position_x_ = 0;
+ last_mouse_position_y_ = 0;
+ cursor_displayed_ = false;
+}
+
+bool CursorRendererAura::SnapshotCursorState(const gfx::Rect& region_in_frame) {
+ if (!window_) {
+ DVLOG(2) << "Skipping update with no window being tracked";
+ return false;
+ }
+ const gfx::Rect window_bounds = window_->GetBoundsInScreen();
+ gfx::Point cursor_position = aura::Env::GetInstance()->last_mouse_location();
+ if (!window_bounds.Contains(cursor_position)) {
+ // Return early if there is no need to draw the cursor.
+ DVLOG(2) << "Skipping update with cursor outside the window";
+ Clear();
+ return false;
+ }
+
+ // If we are sharing the root window, or namely the whole screen, we will
+ // render the mouse cursor. For ordinary window, we only render the mouse
+ // cursor when the window is active.
+ if (!window_->IsRootWindow()) {
+ aura::client::ActivationClient* activation_client =
+ aura::client::GetActivationClient(window_->GetRootWindow());
+ DCHECK(activation_client);
+ aura::Window* active_window = activation_client->GetActiveWindow();
+ if (!active_window->Contains(window_)) {
+ // Return early if the target window is not active.
+ DVLOG(2) << "Skipping update on an inactive window";
+ Clear();
+ return false;
+ }
+ }
+
+ gfx::NativeCursor cursor = window_->GetHost()->last_cursor();
+ gfx::Point cursor_hot_point;
+ if (last_cursor_ != cursor ||
+ window_size_when_cursor_last_updated_ != window_bounds.size()) {
+ SkBitmap cursor_bitmap;
+ if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point)) {
+ const int scaled_width = cursor_bitmap.width() * region_in_frame.width() /
+ window_bounds.width();
+ const int scaled_height = cursor_bitmap.height() *
+ region_in_frame.height() /
+ window_bounds.height();
+ if (scaled_width <= 0 || scaled_height <= 0) {
+ DVLOG(2) << "scaled_width <= 0";
+ Clear();
+ return false;
+ }
+ scaled_cursor_bitmap_ = skia::ImageOperations::Resize(
+ cursor_bitmap, skia::ImageOperations::RESIZE_BEST, scaled_width,
+ scaled_height);
+ last_cursor_ = cursor;
+ window_size_when_cursor_last_updated_ = window_bounds.size();
+ } else {
+ // Clear cursor state if ui::GetCursorBitmap failed so that we do not
+ // render cursor on the captured frame.
+ Clear();
+ }
+ }
+
+ cursor_position.Offset(-window_bounds.x() - cursor_hot_point.x(),
+ -window_bounds.y() - cursor_hot_point.y());
+ cursor_position_in_frame_ = gfx::Point(
+ region_in_frame.x() +
+ cursor_position.x() * region_in_frame.width() / window_bounds.width(),
+ region_in_frame.y() +
+ cursor_position.y() * region_in_frame.height() /
+ window_bounds.height());
+
+ if (cursor_displayed_) {
+ // Stop displaying cursor if there has been no mouse movement
+ base::TimeDelta now = tick_clock_->NowTicks() - base::TimeTicks();
+ if ((now - last_mouse_movement_timestamp_) >
+ base::TimeDelta::FromSeconds(MAX_IDLE_TIME_SECONDS)) {
+ cursor_displayed_ = false;
+ DVLOG(2) << "Turning off cursor display after idle time";
+ }
+ }
+ return cursor_displayed_;
+}
+
+// Helper function to composite a cursor bitmap on a YUV420 video frame.
+void CursorRendererAura::RenderOnVideoFrame(
+ const scoped_refptr<media::VideoFrame>& target) const {
+ if (scaled_cursor_bitmap_.isNull())
+ return;
+
+ DCHECK(target);
+
+ gfx::Rect rect = gfx::IntersectRects(
+ gfx::Rect(scaled_cursor_bitmap_.width(), scaled_cursor_bitmap_.height()) +
+ gfx::Vector2d(cursor_position_in_frame_.x(),
+ cursor_position_in_frame_.y()),
+ target->visible_rect());
+
+ scaled_cursor_bitmap_.lockPixels();
+ for (int y = rect.y(); y < rect.bottom(); ++y) {
+ int cursor_y = y - cursor_position_in_frame_.y();
+ uint8_t* yplane = target->data(media::VideoFrame::kYPlane) +
+ y * target->row_bytes(media::VideoFrame::kYPlane);
+ uint8_t* uplane = target->data(media::VideoFrame::kUPlane) +
+ (y / 2) * target->row_bytes(media::VideoFrame::kUPlane);
+ uint8_t* vplane = target->data(media::VideoFrame::kVPlane) +
+ (y / 2) * target->row_bytes(media::VideoFrame::kVPlane);
+ for (int x = rect.x(); x < rect.right(); ++x) {
+ int cursor_x = x - cursor_position_in_frame_.x();
+ SkColor color = scaled_cursor_bitmap_.getColor(cursor_x, cursor_y);
+ int alpha = SkColorGetA(color);
+ int color_r = SkColorGetR(color);
+ int color_g = SkColorGetG(color);
+ int color_b = SkColorGetB(color);
+ int color_y = clip_byte(
+ ((color_r * 66 + color_g * 129 + color_b * 25 + 128) >> 8) + 16);
+ yplane[x] = alpha_blend(alpha, color_y, yplane[x]);
+
+ // Only sample U and V at even coordinates.
+ if ((x % 2 == 0) && (y % 2 == 0)) {
+ int color_u = clip_byte(
+ ((color_r * -38 + color_g * -74 + color_b * 112 + 128) >> 8) + 128);
+ int color_v = clip_byte(
+ ((color_r * 112 + color_g * -94 + color_b * -18 + 128) >> 8) + 128);
+ uplane[x / 2] = alpha_blend(alpha, color_u, uplane[x / 2]);
+ vplane[x / 2] = alpha_blend(alpha, color_v, vplane[x / 2]);
+ }
+ }
+ }
+ scaled_cursor_bitmap_.unlockPixels();
+}
+
+void CursorRendererAura::OnMouseEvent(ui::MouseEvent* event) {
+ switch (event->type()) {
+ case ui::ET_MOUSE_MOVED:
+ if (!cursor_displayed_) {
+ if (std::abs(event->x() - last_mouse_position_x_) >
+ MIN_MOVEMENT_PIXELS ||
+ std::abs(event->y() - last_mouse_position_y_) > MIN_MOVEMENT_PIXELS)
+ cursor_displayed_ = true;
+ }
+ break;
+ case ui::ET_MOUSE_PRESSED:
+ case ui::ET_MOUSE_RELEASED:
+ case ui::ET_MOUSEWHEEL:
+ cursor_displayed_ = true;
+ break;
+ default:
+ return;
+ }
+ if (cursor_displayed_) {
+ last_mouse_movement_timestamp_ = event->time_stamp();
+ last_mouse_position_x_ = event->x();
+ last_mouse_position_y_ = event->y();
+ }
+}
+
+void CursorRendererAura::OnWindowDestroying(aura::Window* window) {
+ DCHECK_EQ(window_, window);
+ window_->RemovePreTargetHandler(this);
+ window_->RemoveObserver(this);
+ window_ = nullptr;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/capture/cursor_renderer_aura.h b/chromium/content/browser/media/capture/cursor_renderer_aura.h
new file mode 100644
index 00000000000..42dffa6b392
--- /dev/null
+++ b/chromium/content/browser/media/capture/cursor_renderer_aura.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_CURSOR_RENDERER_AURA_H_
+#define CONTENT_BROWSER_MEDIA_CAPTURE_CURSOR_RENDERER_AURA_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/default_tick_clock.h"
+#include "base/time/tick_clock.h"
+#include "content/browser/media/capture/cursor_renderer.h"
+#include "content/common/content_export.h"
+#include "media/base/video_frame.h"
+#include "skia/ext/image_operations.h"
+#include "ui/aura/window.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/events/event_handler.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace content {
+
+// Tracks state for making decisions on cursor display on a captured video
+// frame.
+class CONTENT_EXPORT CursorRendererAura : public CursorRenderer,
+ public ui::EventHandler,
+ public aura::WindowObserver {
+ public:
+ explicit CursorRendererAura(aura::Window* window);
+ ~CursorRendererAura() final;
+
+ // CursorRender implementation.
+ void Clear() final;
+ bool SnapshotCursorState(const gfx::Rect& region_in_frame) final;
+ void RenderOnVideoFrame(
+ const scoped_refptr<media::VideoFrame>& target) const final;
+ base::WeakPtr<CursorRenderer> GetWeakPtr() final;
+
+ // ui::EventHandler overrides.
+ void OnMouseEvent(ui::MouseEvent* event) final;
+
+ // aura::WindowObserver overrides.
+ void OnWindowDestroying(aura::Window* window) final;
+
+ private:
+ friend class CursorRendererAuraTest;
+
+ aura::Window* window_;
+
+ // Snapshot of cursor, source size, position, and cursor bitmap; as of the
+ // last call to SnapshotCursorState.
+ ui::Cursor last_cursor_;
+ gfx::Size window_size_when_cursor_last_updated_;
+ gfx::Point cursor_position_in_frame_;
+ SkBitmap scaled_cursor_bitmap_;
+
+ // Updated in mouse event listener and used to make a decision on
+ // when the cursor is rendered.
+ base::TimeDelta last_mouse_movement_timestamp_;
+ float last_mouse_position_x_;
+ float last_mouse_position_y_;
+ bool cursor_displayed_;
+
+ // Allows tests to replace the clock.
+ base::DefaultTickClock default_tick_clock_;
+ base::TickClock* tick_clock_;
+
+ base::WeakPtrFactory<CursorRendererAura> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(CursorRendererAura);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_CAPTURE_CURSOR_RENDERER_AURA_H_
diff --git a/chromium/content/browser/media/capture/cursor_renderer_aura_unittest.cc b/chromium/content/browser/media/capture/cursor_renderer_aura_unittest.cc
new file mode 100644
index 00000000000..bb210b9737e
--- /dev/null
+++ b/chromium/content/browser/media/capture/cursor_renderer_aura_unittest.cc
@@ -0,0 +1,203 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/capture/cursor_renderer_aura.h"
+
+#include <stdint.h>
+
+#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "base/time/time.h"
+#include "media/base/video_frame.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/aura/env.h"
+#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/window.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/events/event.h"
+#include "ui/events/event_utils.h"
+#include "ui/wm/core/default_activation_client.h"
+#include "ui/wm/core/window_util.h"
+
+namespace content {
+
+using aura::test::AuraTestBase;
+
+class CursorRendererAuraTest : public AuraTestBase {
+ public:
+ CursorRendererAuraTest() {}
+ ~CursorRendererAuraTest() override {}
+
+ void SetUp() override {
+ AuraTestBase::SetUp();
+ // This is needed to avoid duplicate initialization across tests that leads
+ // to a failure.
+ if (!ui::ResourceBundle::HasSharedInstance()) {
+ // Initialize the shared global resource bundle that has bitmap
+ // resources needed by CursorRenderer
+ base::FilePath pak_file;
+ bool r = PathService::Get(base::DIR_MODULE, &pak_file);
+ DCHECK(r);
+ pak_file = pak_file.Append(FILE_PATH_LITERAL("content_shell.pak"));
+ ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
+ }
+
+ window_.reset(aura::test::CreateTestWindowWithBounds(
+ gfx::Rect(0, 0, 800, 600), root_window()));
+ cursor_renderer_.reset(new CursorRendererAura(window_.get()));
+ new wm::DefaultActivationClient(root_window());
+ }
+
+ void TearDown() override {
+ cursor_renderer_.reset();
+ window_.reset();
+ AuraTestBase::TearDown();
+ }
+
+ void SetTickClock(base::SimpleTestTickClock* clock) {
+ cursor_renderer_->tick_clock_ = clock;
+ }
+
+ base::TimeDelta Now() {
+ return cursor_renderer_->tick_clock_->NowTicks() - base::TimeTicks();
+ }
+
+ bool CursorDisplayed() { return cursor_renderer_->cursor_displayed_; }
+
+ void RenderCursorOnVideoFrame(
+ const scoped_refptr<media::VideoFrame>& target) {
+ cursor_renderer_->RenderOnVideoFrame(target);
+ }
+
+ void SnapshotCursorState(gfx::Rect region_in_frame) {
+ cursor_renderer_->SnapshotCursorState(region_in_frame);
+ }
+
+ void MoveMouseCursorWithinWindow() {
+ gfx::Point point1(20, 20);
+ ui::MouseEvent event1(ui::ET_MOUSE_MOVED, point1, point1, Now(), 0, 0);
+ cursor_renderer_->OnMouseEvent(&event1);
+ gfx::Point point2(60, 60);
+ ui::MouseEvent event2(ui::ET_MOUSE_MOVED, point2, point2, Now(), 0, 0);
+ cursor_renderer_->OnMouseEvent(&event2);
+ aura::Env::GetInstance()->set_last_mouse_location(point2);
+ }
+
+ void MoveMouseCursorWithinWindow(gfx::Point point) {
+ ui::MouseEvent event(ui::ET_MOUSE_MOVED, point, point, Now(), 0, 0);
+ cursor_renderer_->OnMouseEvent(&event);
+ aura::Env::GetInstance()->set_last_mouse_location(point);
+ }
+
+ void MoveMouseCursorOutsideWindow() {
+ gfx::Point point(1000, 1000);
+ ui::MouseEvent event1(ui::ET_MOUSE_MOVED, point, point, Now(), 0, 0);
+ cursor_renderer_->OnMouseEvent(&event1);
+ aura::Env::GetInstance()->set_last_mouse_location(point);
+ }
+
+ // A very simple test of whether there are any non-zero pixels
+ // in the region |rect| within |frame|.
+ bool NonZeroPixelsInRegion(scoped_refptr<media::VideoFrame> frame,
+ gfx::Rect rect) {
+ bool y_found = false, u_found = false, v_found = false;
+ for (int y = rect.y(); y < rect.bottom(); ++y) {
+ uint8_t* yplane = frame->data(media::VideoFrame::kYPlane) +
+ y * frame->row_bytes(media::VideoFrame::kYPlane);
+ uint8_t* uplane = frame->data(media::VideoFrame::kUPlane) +
+ (y / 2) * frame->row_bytes(media::VideoFrame::kUPlane);
+ uint8_t* vplane = frame->data(media::VideoFrame::kVPlane) +
+ (y / 2) * frame->row_bytes(media::VideoFrame::kVPlane);
+ for (int x = rect.x(); x < rect.right(); ++x) {
+ if (yplane[x] != 0)
+ y_found = true;
+ if (uplane[x / 2])
+ u_found = true;
+ if (vplane[x / 2])
+ v_found = true;
+ }
+ }
+ return (y_found && u_found && v_found);
+ }
+
+ protected:
+ scoped_ptr<aura::Window> window_;
+ scoped_ptr<CursorRendererAura> cursor_renderer_;
+};
+
+TEST_F(CursorRendererAuraTest, CursorDuringMouseMovement) {
+ // Keep window activated.
+ wm::ActivateWindow(window_.get());
+
+ EXPECT_FALSE(CursorDisplayed());
+
+ base::SimpleTestTickClock clock;
+ SetTickClock(&clock);
+
+ // Cursor displayed after mouse movement.
+ MoveMouseCursorWithinWindow();
+ EXPECT_TRUE(CursorDisplayed());
+
+ // Cursor not be displayed after idle period.
+ clock.Advance(base::TimeDelta::FromSeconds(5));
+ SnapshotCursorState(gfx::Rect(10, 10, 200, 200));
+ EXPECT_FALSE(CursorDisplayed());
+
+ // Cursor displayed with mouse movement following idle period.
+ MoveMouseCursorWithinWindow();
+ SnapshotCursorState(gfx::Rect(10, 10, 200, 200));
+ EXPECT_TRUE(CursorDisplayed());
+
+ // Cursor not displayed if mouse outside the window
+ MoveMouseCursorOutsideWindow();
+ SnapshotCursorState(gfx::Rect(10, 10, 200, 200));
+ EXPECT_FALSE(CursorDisplayed());
+}
+
+TEST_F(CursorRendererAuraTest, CursorOnActiveWindow) {
+ EXPECT_FALSE(CursorDisplayed());
+
+ // Cursor displayed after mouse movement.
+ MoveMouseCursorWithinWindow();
+ EXPECT_TRUE(CursorDisplayed());
+
+ // Cursor not be displayed if a second window is activated.
+ scoped_ptr<aura::Window> window2(aura::test::CreateTestWindowWithBounds(
+ gfx::Rect(0, 0, 800, 600), root_window()));
+ wm::ActivateWindow(window2.get());
+ SnapshotCursorState(gfx::Rect(10, 10, 200, 200));
+ EXPECT_FALSE(CursorDisplayed());
+
+ // Cursor displayed if window activated again.
+ MoveMouseCursorWithinWindow();
+ wm::ActivateWindow(window_.get());
+ SnapshotCursorState(gfx::Rect(10, 10, 200, 200));
+ EXPECT_TRUE(CursorDisplayed());
+}
+
+TEST_F(CursorRendererAuraTest, CursorRenderedOnFrame) {
+ // Keep window activated.
+ wm::ActivateWindow(window_.get());
+
+ EXPECT_FALSE(CursorDisplayed());
+
+ gfx::Size size(800, 600);
+ scoped_refptr<media::VideoFrame> frame =
+ media::VideoFrame::CreateZeroInitializedFrame(media::PIXEL_FORMAT_YV12,
+ size, gfx::Rect(size), size,
+ base::TimeDelta());
+
+ MoveMouseCursorWithinWindow(gfx::Point(60, 60));
+ SnapshotCursorState(gfx::Rect(size));
+ EXPECT_TRUE(CursorDisplayed());
+
+ EXPECT_FALSE(NonZeroPixelsInRegion(frame, gfx::Rect(50, 50, 70, 70)));
+ RenderCursorOnVideoFrame(frame);
+ EXPECT_TRUE(NonZeroPixelsInRegion(frame, gfx::Rect(50, 50, 70, 70)));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/capture/desktop_capture_device.cc b/chromium/content/browser/media/capture/desktop_capture_device.cc
index 6cc48398447..9359b7c9c34 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device.cc
@@ -4,14 +4,21 @@
#include "content/browser/media/capture/desktop_capture_device.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
@@ -134,11 +141,10 @@ DesktopCaptureDevice::Core::Core(
scoped_ptr<webrtc::DesktopCapturer> capturer,
DesktopMediaID::Type type)
: task_runner_(task_runner),
- desktop_capturer_(capturer.Pass()),
+ desktop_capturer_(std::move(capturer)),
capture_in_progress_(false),
first_capture_returned_(false),
- capturer_type_(type) {
-}
+ capturer_type_(type) {}
DesktopCaptureDevice::Core::~Core() {
DCHECK(task_runner_->BelongsToCurrentThread());
@@ -158,7 +164,7 @@ void DesktopCaptureDevice::Core::AllocateAndStart(
DCHECK(client.get());
DCHECK(!client_.get());
- client_ = client.Pass();
+ client_ = std::move(client);
requested_frame_rate_ = params.requested_format.frame_rate;
resolution_chooser_.reset(new media::CaptureResolutionChooser(
params.requested_format.frame_size,
@@ -206,9 +212,7 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted(
capture_in_progress_ = false;
if (!frame) {
- std::string log("Failed to capture a frame.");
- LOG(ERROR) << log;
- client_->OnError(log);
+ client_->OnError(FROM_HERE, "Failed to capture a frame.");
return;
}
@@ -336,9 +340,9 @@ void DesktopCaptureDevice::Core::CaptureFrameAndScheduleNext() {
// Limit frame-rate to reduce CPU consumption.
base::TimeDelta capture_period = std::max(
- (last_capture_duration * 100) / kMaximumCpuConsumptionPercentage,
- base::TimeDelta::FromMicroseconds(static_cast<int64>(
- 1000000.0 / requested_frame_rate_ + 0.5 /* round to nearest int */)));
+ (last_capture_duration * 100) / kMaximumCpuConsumptionPercentage,
+ base::TimeDelta::FromMicroseconds(static_cast<int64_t>(
+ 1000000.0 / requested_frame_rate_ + 0.5 /* round to nearest int */)));
// Schedule a task for the next frame.
capture_timer_.Start(FROM_HERE, capture_period - last_capture_duration,
@@ -404,9 +408,9 @@ scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
scoped_ptr<media::VideoCaptureDevice> result;
if (capturer)
- result.reset(new DesktopCaptureDevice(capturer.Pass(), source.type));
+ result.reset(new DesktopCaptureDevice(std::move(capturer), source.type));
- return result.Pass();
+ return result;
}
DesktopCaptureDevice::~DesktopCaptureDevice() {
@@ -454,7 +458,7 @@ DesktopCaptureDevice::DesktopCaptureDevice(
thread_.StartWithOptions(base::Thread::Options(thread_type, 0));
- core_.reset(new Core(thread_.task_runner(), capturer.Pass(), type));
+ core_.reset(new Core(thread_.task_runner(), std::move(capturer), type));
}
} // namespace content
diff --git a/chromium/content/browser/media/capture/desktop_capture_device.h b/chromium/content/browser/media/capture/desktop_capture_device.h
index 6b971597b75..7afdedc7f5a 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device.h
+++ b/chromium/content/browser/media/capture/desktop_capture_device.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURE_DEVICE_H_
#define CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURE_DEVICE_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread.h"
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_aura.cc b/chromium/content/browser/media/capture/desktop_capture_device_aura.cc
index 097a5b7ed96..39f7a07edf8 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device_aura.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device_aura.cc
@@ -4,6 +4,8 @@
#include "content/browser/media/capture/desktop_capture_device_aura.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/timer/timer.h"
#include "content/browser/media/capture/aura_window_capture_machine.h"
@@ -52,7 +54,7 @@ void DesktopCaptureDeviceAura::AllocateAndStart(
const media::VideoCaptureParams& params,
scoped_ptr<Client> client) {
DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
- core_->AllocateAndStart(params, client.Pass());
+ core_->AllocateAndStart(params, std::move(client));
}
void DesktopCaptureDeviceAura::StopAndDeAllocate() {
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_aura.h b/chromium/content/browser/media/capture/desktop_capture_device_aura.h
index c2959234793..82ce5956241 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device_aura.h
+++ b/chromium/content/browser/media/capture/desktop_capture_device_aura.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "content/public/browser/desktop_media_id.h"
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc b/chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
index 790334e4023..43ed2aaef7d 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
@@ -4,6 +4,12 @@
#include "content/browser/media/capture/desktop_capture_device_aura.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
+#include "base/location.h"
+#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "content/browser/browser_thread_impl.h"
#include "content/public/browser/desktop_media_id.h"
@@ -36,35 +42,35 @@ const int kFrameRate = 30;
class MockDeviceClient : public media::VideoCaptureDevice::Client {
public:
MOCK_METHOD5(OnIncomingCapturedData,
- void(const uint8* data,
+ void(const uint8_t* data,
int length,
const media::VideoCaptureFormat& frame_format,
int rotation,
const base::TimeTicks& timestamp));
MOCK_METHOD9(OnIncomingCapturedYuvData,
- void (const uint8* y_data,
- const uint8* u_data,
- const uint8* v_data,
- size_t y_stride,
- size_t u_stride,
- size_t v_stride,
- const media::VideoCaptureFormat& frame_format,
- int clockwise_rotation,
- const base::TimeTicks& timestamp));
+ void(const uint8_t* y_data,
+ const uint8_t* u_data,
+ const uint8_t* v_data,
+ size_t y_stride,
+ size_t u_stride,
+ size_t v_stride,
+ const media::VideoCaptureFormat& frame_format,
+ int clockwise_rotation,
+ const base::TimeTicks& timestamp));
MOCK_METHOD0(DoReserveOutputBuffer, void(void));
MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
- MOCK_METHOD1(OnError, void(const std::string& reason));
+ MOCK_METHOD2(OnError,
+ void(const tracked_objects::Location& from_here,
+ const std::string& reason));
// Trampoline methods to workaround GMOCK problems with scoped_ptr<>.
scoped_ptr<Buffer> ReserveOutputBuffer(
const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage) override {
- EXPECT_TRUE((format == media::PIXEL_FORMAT_I420 &&
- storage == media::PIXEL_STORAGE_CPU) ||
- (format == media::PIXEL_FORMAT_ARGB &&
- storage == media::PIXEL_STORAGE_TEXTURE));
+ EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
+ EXPECT_EQ(media::PIXEL_STORAGE_CPU, storage);
DoReserveOutputBuffer();
return scoped_ptr<Buffer>();
}
@@ -142,13 +148,13 @@ TEST_F(DesktopCaptureDeviceAuraTest, StartAndStop) {
ASSERT_TRUE(capture_device.get());
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_)).Times(0);
+ EXPECT_CALL(*client, OnError(_, _)).Times(0);
media::VideoCaptureParams capture_params;
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = kFrameRate;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
- capture_device->AllocateAndStart(capture_params, client.Pass());
+ capture_device->AllocateAndStart(capture_params, std::move(client));
capture_device->StopAndDeAllocate();
}
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc b/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
index afaac445698..c7b7877cc48 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
@@ -4,10 +4,14 @@
#include "content/browser/media/capture/desktop_capture_device.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
#include <algorithm>
#include <string>
+#include <utility>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
@@ -57,25 +61,27 @@ const uint8_t kFakePixelValueFirst = 2;
class MockDeviceClient : public media::VideoCaptureDevice::Client {
public:
MOCK_METHOD5(OnIncomingCapturedData,
- void(const uint8* data,
+ void(const uint8_t* data,
int length,
const media::VideoCaptureFormat& frame_format,
int rotation,
const base::TimeTicks& timestamp));
MOCK_METHOD9(OnIncomingCapturedYuvData,
- void (const uint8* y_data,
- const uint8* u_data,
- const uint8* v_data,
- size_t y_stride,
- size_t u_stride,
- size_t v_stride,
- const media::VideoCaptureFormat& frame_format,
- int clockwise_rotation,
- const base::TimeTicks& timestamp));
+ void(const uint8_t* y_data,
+ const uint8_t* u_data,
+ const uint8_t* v_data,
+ size_t y_stride,
+ size_t u_stride,
+ size_t v_stride,
+ const media::VideoCaptureFormat& frame_format,
+ int clockwise_rotation,
+ const base::TimeTicks& timestamp));
MOCK_METHOD0(DoReserveOutputBuffer, void(void));
MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
- MOCK_METHOD1(OnError, void(const std::string& reason));
+ MOCK_METHOD2(OnError,
+ void(const tracked_objects::Location& from_here,
+ const std::string& reason));
// Trampoline methods to workaround GMOCK problems with scoped_ptr<>.
scoped_ptr<Buffer> ReserveOutputBuffer(
@@ -106,7 +112,7 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
// kFakePixelValueFirst, and the rest of the bytes set to kFakePixelValue, for
// UnpackedFrame and InvertedFrame verification.
webrtc::BasicDesktopFrame* CreateBasicFrame(const webrtc::DesktopSize& size) {
- webrtc::BasicDesktopFrame* frame = new webrtc::BasicDesktopFrame(size);;
+ webrtc::BasicDesktopFrame* frame = new webrtc::BasicDesktopFrame(size);
DCHECK_EQ(frame->size().width() * webrtc::DesktopFrame::kBytesPerPixel,
frame->stride());
memset(frame->data(),
@@ -162,6 +168,7 @@ class UnpackedDesktopFrame : public webrtc::DesktopFrame {
delete[] data_;
}
+ private:
DISALLOW_COPY_AND_ASSIGN(UnpackedDesktopFrame);
};
@@ -196,7 +203,7 @@ class FakeScreenCapturer : public webrtc::ScreenCapturer {
}
frame_index_++;
- webrtc::DesktopFrame* frame = CreateBasicFrame(size);;
+ webrtc::DesktopFrame* frame = CreateBasicFrame(size);
if (generate_inverted_frames_) {
frame = new InvertedDesktopFrame(frame);
@@ -248,8 +255,8 @@ class FormatChecker {
class DesktopCaptureDeviceTest : public testing::Test {
public:
void CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer> capturer) {
- capture_device_.reset(
- new DesktopCaptureDevice(capturer.Pass(), DesktopMediaID::TYPE_SCREEN));
+ capture_device_.reset(new DesktopCaptureDevice(
+ std::move(capturer), DesktopMediaID::TYPE_SCREEN));
}
void CopyFrame(const uint8_t* frame, int size,
@@ -276,14 +283,14 @@ TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) {
scoped_ptr<webrtc::DesktopCapturer> capturer(
webrtc::ScreenCapturer::Create(
webrtc::DesktopCaptureOptions::CreateDefault()));
- CreateScreenCaptureDevice(capturer.Pass());
+ CreateScreenCaptureDevice(std::move(capturer));
media::VideoCaptureFormat format;
base::WaitableEvent done_event(false, false);
int frame_size;
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_)).Times(0);
+ EXPECT_CALL(*client, OnError(_, _)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
DoAll(SaveArg<1>(&frame_size),
SaveArg<2>(&format),
@@ -293,7 +300,7 @@ TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = kFrameRate;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
- capture_device_->AllocateAndStart(capture_params, client.Pass());
+ capture_device_->AllocateAndStart(capture_params, std::move(client));
EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
capture_device_->StopAndDeAllocate();
@@ -317,7 +324,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
base::WaitableEvent done_event(false, false);
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_)).Times(0);
+ EXPECT_CALL(*client, OnError(_, _)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
DoAll(WithArg<2>(Invoke(&format_checker,
&FormatChecker::ExpectAcceptableSize)),
@@ -331,7 +338,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
capture_params.resolution_change_policy =
media::RESOLUTION_POLICY_FIXED_RESOLUTION;
- capture_device_->AllocateAndStart(capture_params, client.Pass());
+ capture_device_->AllocateAndStart(capture_params, std::move(client));
// Capture at least two frames, to ensure that the source frame size has
// changed to two different sizes while capturing. The mock for
@@ -357,7 +364,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeFixedAspectRatio) {
base::WaitableEvent done_event(false, false);
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_)).Times(0);
+ EXPECT_CALL(*client, OnError(_,_)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
DoAll(WithArg<2>(Invoke(&format_checker,
&FormatChecker::ExpectAcceptableSize)),
@@ -375,8 +382,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeFixedAspectRatio) {
capture_params.resolution_change_policy =
media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO;
- capture_device_->AllocateAndStart(
- capture_params, client.Pass());
+ capture_device_->AllocateAndStart(capture_params, std::move(client));
// Capture at least three frames, to ensure that the source frame size has
// changed to two different sizes while capturing. The mock for
@@ -402,7 +408,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
base::WaitableEvent done_event(false, false);
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_)).Times(0);
+ EXPECT_CALL(*client, OnError(_,_)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
DoAll(WithArg<2>(Invoke(&format_checker,
&FormatChecker::ExpectAcceptableSize)),
@@ -420,8 +426,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
capture_params.resolution_change_policy =
media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT;
- capture_device_->AllocateAndStart(
- capture_params, client.Pass());
+ capture_device_->AllocateAndStart(capture_params, std::move(client));
// Capture at least three frames, to ensure that the source frame size has
// changed to two different sizes while capturing. The mock for
@@ -449,7 +454,7 @@ TEST_F(DesktopCaptureDeviceTest, UnpackedFrame) {
webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1)));
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_)).Times(0);
+ EXPECT_CALL(*client, OnError(_,_)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
DoAll(Invoke(this, &DesktopCaptureDeviceTest::CopyFrame),
SaveArg<1>(&frame_size),
@@ -462,7 +467,7 @@ TEST_F(DesktopCaptureDeviceTest, UnpackedFrame) {
capture_params.requested_format.pixel_format =
media::PIXEL_FORMAT_I420;
- capture_device_->AllocateAndStart(capture_params, client.Pass());
+ capture_device_->AllocateAndStart(capture_params, std::move(client));
EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
done_event.Reset();
@@ -492,7 +497,7 @@ TEST_F(DesktopCaptureDeviceTest, InvertedFrame) {
webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1)));
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_)).Times(0);
+ EXPECT_CALL(*client, OnError(_,_)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
DoAll(Invoke(this, &DesktopCaptureDeviceTest::CopyFrame),
SaveArg<1>(&frame_size),
@@ -504,7 +509,7 @@ TEST_F(DesktopCaptureDeviceTest, InvertedFrame) {
capture_params.requested_format.frame_rate = kFrameRate;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
- capture_device_->AllocateAndStart(capture_params, client.Pass());
+ capture_device_->AllocateAndStart(capture_params, std::move(client));
EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
done_event.Reset();
diff --git a/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc b/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc
index 8fd1f976d59..50051a1a8cb 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc
+++ b/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc
@@ -9,14 +9,15 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
-#include "content/browser/media/capture/web_contents_capture_util.h"
#include "content/browser/media/capture/web_contents_tracker.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_media_capture_id.h"
#include "media/audio/virtual_audio_input_stream.h"
#include "media/audio/virtual_audio_output_stream.h"
#include "media/base/bind_to_current_loop.h"
@@ -328,7 +329,7 @@ WebContentsAudioInputStream* WebContentsAudioInputStream::Create(
AudioMirroringManager* audio_mirroring_manager) {
int render_process_id;
int main_render_frame_id;
- if (!WebContentsCaptureUtil::ExtractTabCaptureTarget(
+ if (!WebContentsMediaCaptureId::ExtractTabCaptureTarget(
device_id, &render_process_id, &main_render_frame_id)) {
return NULL;
}
diff --git a/chromium/content/browser/media/capture/web_contents_audio_input_stream.h b/chromium/content/browser/media/capture/web_contents_audio_input_stream.h
index ff8074d4f0e..ef994e83ac9 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_input_stream.h
+++ b/chromium/content/browser/media/capture/web_contents_audio_input_stream.h
@@ -15,6 +15,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "media/audio/audio_io.h"
diff --git a/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc b/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc
index c7c9c84204b..1e8ef1f8f3f 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc
+++ b/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc
@@ -4,11 +4,14 @@
#include "content/browser/media/capture/web_contents_audio_input_stream.h"
+#include <stdint.h>
+
#include <list>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
@@ -162,7 +165,7 @@ class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
MOCK_METHOD4(OnData,
void(AudioInputStream* stream,
const media::AudioBus* src,
- uint32 hardware_delay_bytes,
+ uint32_t hardware_delay_bytes,
double volume));
MOCK_METHOD1(OnError, void(AudioInputStream* stream));
diff --git a/chromium/content/browser/media/capture/web_contents_audio_muter.cc b/chromium/content/browser/media/capture/web_contents_audio_muter.cc
index 6d25d550d18..82a03fa5cf2 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_muter.cc
+++ b/chromium/content/browser/media/capture/web_contents_audio_muter.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
@@ -49,7 +50,7 @@ class AudioDiscarder : public media::AudioOutputStream {
~AudioDiscarder() override {}
void FetchAudioData(AudioSourceCallback* callback) {
- callback->OnMoreData(audio_bus_.get(), 0);
+ callback->OnMoreData(audio_bus_.get(), 0, 0);
}
// Calls FetchAudioData() at regular intervals and discards the data.
diff --git a/chromium/content/browser/media/capture/web_contents_audio_muter.h b/chromium/content/browser/media/capture/web_contents_audio_muter.h
index d9c5f2fcbb2..211f7298764 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_muter.h
+++ b/chromium/content/browser/media/capture/web_contents_audio_muter.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_AUDIO_MUTER_H_
#define CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_AUDIO_MUTER_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
namespace content {
diff --git a/chromium/content/browser/media/capture/web_contents_capture_util.cc b/chromium/content/browser/media/capture/web_contents_capture_util.cc
deleted file mode 100644
index 0edaf4a047d..00000000000
--- a/chromium/content/browser/media/capture/web_contents_capture_util.cc
+++ /dev/null
@@ -1,64 +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/media/capture/web_contents_capture_util.h"
-
-#include "base/basictypes.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_util.h"
-
-namespace content {
-
-bool WebContentsCaptureUtil::IsWebContentsDeviceId(
- const std::string& device_id) {
- int ignored;
- return ExtractTabCaptureTarget(device_id, &ignored, &ignored);
-}
-
-bool WebContentsCaptureUtil::ExtractTabCaptureTarget(
- const std::string& device_id_param,
- int* render_process_id,
- int* main_render_frame_id) {
- static const char kDeviceScheme[] = "web-contents-media-stream://";
- if (!base::StartsWith(device_id_param, kDeviceScheme,
- base::CompareCase::SENSITIVE))
- return false;
-
- const std::string device_id = device_id_param.substr(
- arraysize(kDeviceScheme) - 1);
-
- const size_t sep_pos = device_id.find(':');
- if (sep_pos == std::string::npos)
- return false;
-
- const base::StringPiece component1(device_id.data(), sep_pos);
- size_t end_pos = device_id.find('?');
- if (end_pos == std::string::npos)
- end_pos = device_id.length();
- const base::StringPiece component2(device_id.data() + sep_pos + 1,
- end_pos - sep_pos - 1);
-
- return (base::StringToInt(component1, render_process_id) &&
- base::StringToInt(component2, main_render_frame_id));
-}
-
-bool WebContentsCaptureUtil::IsAutoThrottlingOptionSet(
- const std::string& device_id) {
- if (!IsWebContentsDeviceId(device_id))
- return false;
-
- // Find the option part of the string and just do a naive string compare since
- // there are no other options in the |device_id| to account for (at the time
- // of this writing).
- const size_t option_pos = device_id.find('?');
- if (option_pos == std::string::npos)
- return false;
- const base::StringPiece component(device_id.data() + option_pos,
- device_id.length() - option_pos);
- static const char kEnableFlag[] = "?throttling=auto";
- return component.compare(kEnableFlag) == 0;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/capture/web_contents_capture_util.h b/chromium/content/browser/media/capture/web_contents_capture_util.h
deleted file mode 100644
index 235504a89bb..00000000000
--- a/chromium/content/browser/media/capture/web_contents_capture_util.h
+++ /dev/null
@@ -1,32 +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_MEDIA_CAPTURE_WEB_CONTENTS_CAPTURE_UTIL_H_
-#define CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_CAPTURE_UTIL_H_
-
-#include <string>
-
-#include "content/common/content_export.h"
-
-namespace content {
-
-class CONTENT_EXPORT WebContentsCaptureUtil {
- public:
- // Check whether the device id indicates that this is a web contents stream.
- static bool IsWebContentsDeviceId(const std::string& device_id);
-
- // Function to extract the target render frame id's from a media stream
- // request's device id.
- static bool ExtractTabCaptureTarget(const std::string& device_id,
- int* render_process_id,
- int* main_render_frame_id);
-
- // Parses the media stream request |device_id| and returns true if both 1) the
- // format is valid, and 2) the throttling option is set to auto.
- static bool IsAutoThrottlingOptionSet(const std::string& device_id);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_CAPTURE_UTIL_H_
diff --git a/chromium/content/browser/media/capture/web_contents_tracker.h b/chromium/content/browser/media/capture/web_contents_tracker.h
index 591c5e35a9c..02ba7332899 100644
--- a/chromium/content/browser/media/capture/web_contents_tracker.h
+++ b/chromium/content/browser/media/capture/web_contents_tracker.h
@@ -17,6 +17,7 @@
#define CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_TRACKER_H_
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/web_contents_observer.h"
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device.cc b/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
index 64312d9a7c9..bf2ef5ac662 100644
--- a/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -50,11 +50,15 @@
#include "content/browser/media/capture/web_contents_video_capture_device.h"
-#include "base/basictypes.h"
+#include <stdint.h>
+#include <algorithm>
+#include <utility>
+
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram.h"
@@ -63,8 +67,10 @@
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
-#include "content/browser/media/capture/web_contents_capture_util.h"
+#include "build/build_config.h"
+#include "content/browser/media/capture/cursor_renderer.h"
#include "content/browser/media/capture/web_contents_tracker.h"
+#include "content/browser/media/capture/window_activity_tracker.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/public/browser/browser_thread.h"
@@ -72,7 +78,10 @@
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_media_capture_id.h"
+#include "media/base/bind_to_current_loop.h"
#include "media/base/video_capture_types.h"
+#include "media/base/video_frame_metadata.h"
#include "media/base/video_util.h"
#include "media/capture/content/screen_capture_device_core.h"
#include "media/capture/content/thread_safe_capture_oracle.h"
@@ -84,10 +93,23 @@
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/size_conversions.h"
+#if defined(USE_AURA)
+#include "content/browser/media/capture/cursor_renderer_aura.h"
+#include "content/browser/media/capture/window_activity_tracker_aura.h"
+#endif
+
namespace content {
namespace {
+enum InteractiveModeSettings {
+ // Minimum amount of time for which there should be no animation detected
+ // to consider interactive mode being active. This is to prevent very brief
+ // periods of animated content not being detected (due to CPU fluctations for
+ // example) from causing a flip-flop on interactive mode.
+ kMinPeriodNoAnimationMillis = 3000
+};
+
void DeleteOnWorkerThread(scoped_ptr<base::Thread> render_thread,
const base::Closure& callback) {
render_thread.reset();
@@ -119,10 +141,15 @@ class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
public:
FrameSubscriber(media::VideoCaptureOracle::Event event_type,
const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle,
- VideoFrameDeliveryLog* delivery_log)
+ VideoFrameDeliveryLog* delivery_log,
+ base::WeakPtr<content::CursorRenderer> cursor_renderer,
+ base::WeakPtr<content::WindowActivityTracker> tracker)
: event_type_(event_type),
oracle_proxy_(oracle),
- delivery_log_(delivery_log) {}
+ delivery_log_(delivery_log),
+ cursor_renderer_(cursor_renderer),
+ window_activity_tracker_(tracker),
+ weak_ptr_factory_(this) {}
bool ShouldCaptureFrame(
const gfx::Rect& damage_rect,
@@ -131,10 +158,28 @@ class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback*
deliver_frame_cb) override;
+ static void DidCaptureFrame(
+ base::WeakPtr<FrameSubscriber> frame_subscriber_,
+ const media::ThreadSafeCaptureOracle::CaptureFrameCallback&
+ capture_frame_cb,
+ const scoped_refptr<media::VideoFrame>& frame,
+ base::TimeTicks timestamp,
+ const gfx::Rect& region_in_frame,
+ bool success);
+
+ bool IsUserInteractingWithContent();
+
private:
const media::VideoCaptureOracle::Event event_type_;
scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_;
VideoFrameDeliveryLog* const delivery_log_;
+ // We need a weak pointer since FrameSubscriber is owned externally and
+ // may outlive the cursor renderer.
+ base::WeakPtr<CursorRenderer> cursor_renderer_;
+ // We need a weak pointer since FrameSubscriber is owned externally and
+ // may outlive the ui activity tracker.
+ base::WeakPtr<WindowActivityTracker> window_activity_tracker_;
+ base::WeakPtrFactory<FrameSubscriber> weak_ptr_factory_;
};
// ContentCaptureSubscription is the relationship between a RenderWidgetHost
@@ -177,10 +222,19 @@ class ContentCaptureSubscription {
const int render_widget_id_;
VideoFrameDeliveryLog delivery_log_;
- FrameSubscriber timer_subscriber_;
+ scoped_ptr<FrameSubscriber> timer_subscriber_;
CaptureCallback capture_callback_;
base::Timer timer_;
+ // Responsible for tracking the cursor state and input events to make
+ // decisions and then render the mouse cursor on the video frame after
+ // capture is completed.
+ scoped_ptr<content::CursorRenderer> cursor_renderer_;
+
+ // Responsible for tracking the UI events and making a decision on whether
+ // user is actively interacting with content.
+ scoped_ptr<content::WindowActivityTracker> window_activity_tracker_;
+
DISALLOW_COPY_AND_ASSIGN(ContentCaptureSubscription);
};
@@ -193,9 +247,10 @@ class ContentCaptureSubscription {
// these activities is not possible. This operation may be expensive (tens to
// hundreds of milliseconds), so the caller should ensure that it runs on a
// thread where such a pause would cause UI jank.
-void RenderVideoFrame(const SkBitmap& input,
- const scoped_refptr<media::VideoFrame>& output,
- const base::Callback<void(bool)>& done_cb);
+void RenderVideoFrame(
+ const SkBitmap& input,
+ const scoped_refptr<media::VideoFrame>& output,
+ const base::Callback<void(const gfx::Rect&, bool)>& done_cb);
// Renews capture subscriptions based on feedback from WebContentsTracker, and
// also executes copying of the backing store on the UI BrowserThread.
@@ -249,6 +304,7 @@ class WebContentsCaptureMachine : public media::VideoCaptureMachine {
const base::TimeTicks& start_time,
const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
deliver_frame_cb,
+ const gfx::Rect& region_in_frame,
bool success);
// Remove the old subscription, and attempt to start a new one if |had_target|
@@ -304,16 +360,68 @@ bool FrameSubscriber::ShouldCaptureFrame(
"instance", this);
media::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
+
bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture(
event_type_, damage_rect, present_time, storage, &capture_frame_cb);
if (!capture_frame_cb.is_null())
- *deliver_frame_cb = base::Bind(capture_frame_cb, *storage);
+ *deliver_frame_cb =
+ base::Bind(&FrameSubscriber::DidCaptureFrame,
+ weak_ptr_factory_.GetWeakPtr(), capture_frame_cb, *storage);
if (oracle_decision)
delivery_log_->ChronicleFrameDelivery(present_time);
return oracle_decision;
}
+void FrameSubscriber::DidCaptureFrame(
+ base::WeakPtr<FrameSubscriber> frame_subscriber_,
+ const media::ThreadSafeCaptureOracle::CaptureFrameCallback&
+ capture_frame_cb,
+ const scoped_refptr<media::VideoFrame>& frame,
+ base::TimeTicks timestamp,
+ const gfx::Rect& region_in_frame,
+ bool success) {
+ // We can get a callback in the shutdown sequence for the browser main loop
+ // and this can result in a DCHECK failure. Avoid this by doing DCHECK only
+ // on success.
+ if (success) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // TODO(isheriff): Unclear if taking a snapshot of cursor here affects user
+ // experience in any particular scenarios. Doing it prior to capture may
+ // require evaluating region_in_frame in this file.
+ if (frame_subscriber_ && frame_subscriber_->cursor_renderer_) {
+ CursorRenderer* cursor_renderer =
+ frame_subscriber_->cursor_renderer_.get();
+ if (cursor_renderer->SnapshotCursorState(region_in_frame))
+ cursor_renderer->RenderOnVideoFrame(frame);
+ frame->metadata()->SetBoolean(
+ media::VideoFrameMetadata::INTERACTIVE_CONTENT,
+ frame_subscriber_->IsUserInteractingWithContent());
+ }
+ }
+ capture_frame_cb.Run(frame, timestamp, success);
+}
+
+bool FrameSubscriber::IsUserInteractingWithContent() {
+ bool interactive_mode = false;
+ bool ui_activity = false;
+ if (window_activity_tracker_.get()) {
+ ui_activity = window_activity_tracker_->IsUiInteractionActive();
+ }
+ if (cursor_renderer_.get()) {
+ bool animation_active =
+ (base::TimeTicks::Now() -
+ oracle_proxy_->last_time_animation_was_detected()) <
+ base::TimeDelta::FromMilliseconds(kMinPeriodNoAnimationMillis);
+ if (ui_activity && !animation_active) {
+ interactive_mode = true;
+ } else if (animation_active) {
+ window_activity_tracker_->Reset();
+ }
+ }
+ return interactive_mode;
+}
+
ContentCaptureSubscription::ContentCaptureSubscription(
const RenderWidgetHost& source,
const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
@@ -321,21 +429,46 @@ ContentCaptureSubscription::ContentCaptureSubscription(
: render_process_id_(source.GetProcess()->GetID()),
render_widget_id_(source.GetRoutingID()),
delivery_log_(),
- timer_subscriber_(media::VideoCaptureOracle::kTimerPoll, oracle_proxy,
- &delivery_log_),
capture_callback_(capture_callback),
timer_(true, true) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderWidgetHostView* const view = source.GetView();
+// TODO(isheriff): Cursor resources currently only available on linux. Remove
+// this once we add the necessary resources for windows.
+// https://crbug.com/554280 https://crbug.com/549182
+#if defined(USE_AURA) && defined(OS_LINUX)
+ if (view) {
+ cursor_renderer_.reset(
+ new content::CursorRendererAura(view->GetNativeView()));
+ }
+#endif
+// TODO(isheriff): Needs implementation on non-aura platforms.
+// https://crbug.com/567735
+#if defined(USE_AURA)
+ if (view) {
+ window_activity_tracker_.reset(
+ new content::WindowActivityTrackerAura(view->GetNativeView()));
+ }
+#endif
+ timer_subscriber_.reset(new FrameSubscriber(
+ media::VideoCaptureOracle::kTimerPoll, oracle_proxy, &delivery_log_,
+ cursor_renderer_ ? cursor_renderer_->GetWeakPtr()
+ : base::WeakPtr<CursorRenderer>(),
+ window_activity_tracker_ ? window_activity_tracker_->GetWeakPtr()
+ : base::WeakPtr<WindowActivityTracker>()));
// Subscribe to compositor updates. These will be serviced directly by the
// oracle.
if (view) {
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
- new FrameSubscriber(media::VideoCaptureOracle::kCompositorUpdate,
- oracle_proxy, &delivery_log_));
- view->BeginFrameSubscription(subscriber.Pass());
+ new FrameSubscriber(
+ media::VideoCaptureOracle::kCompositorUpdate, oracle_proxy,
+ &delivery_log_, cursor_renderer_ ? cursor_renderer_->GetWeakPtr()
+ : base::WeakPtr<CursorRenderer>(),
+ window_activity_tracker_ ? window_activity_tracker_->GetWeakPtr()
+ : base::WeakPtr<WindowActivityTracker>()));
+ view->BeginFrameSubscription(std::move(subscriber));
}
// Subscribe to timer events. This instance will service these as well.
@@ -370,18 +503,18 @@ void ContentCaptureSubscription::OnTimer() {
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb;
const base::TimeTicks start_time = base::TimeTicks::Now();
- if (timer_subscriber_.ShouldCaptureFrame(gfx::Rect(),
- start_time,
- &frame,
- &deliver_frame_cb)) {
+ if (timer_subscriber_->ShouldCaptureFrame(gfx::Rect(), start_time, &frame,
+ &deliver_frame_cb)) {
capture_callback_.Run(start_time, frame, deliver_frame_cb);
}
}
-void RenderVideoFrame(const SkBitmap& input,
- const scoped_refptr<media::VideoFrame>& output,
- const base::Callback<void(bool)>& done_cb) {
- base::ScopedClosureRunner failure_handler(base::Bind(done_cb, false));
+void RenderVideoFrame(
+ const SkBitmap& input,
+ const scoped_refptr<media::VideoFrame>& output,
+ const base::Callback<void(const gfx::Rect&, bool)>& done_cb) {
+ base::ScopedClosureRunner failure_handler(
+ base::Bind(done_cb, gfx::Rect(), false));
SkAutoLockPixels locker(input);
@@ -412,7 +545,6 @@ void RenderVideoFrame(const SkBitmap& input,
SkBitmap scaled_bitmap;
if (input.width() != region_in_frame.width() ||
input.height() != region_in_frame.height()) {
-
skia::ImageOperations::ResizeMethod method;
if (input.width() < region_in_frame.width() ||
input.height() < region_in_frame.height()) {
@@ -445,15 +577,13 @@ void RenderVideoFrame(const SkBitmap& input,
SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
media::CopyRGBToVideoFrame(
- reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
- scaled_bitmap.rowBytes(),
- region_in_yv12_frame,
- output.get());
+ reinterpret_cast<uint8_t*>(scaled_bitmap.getPixels()),
+ scaled_bitmap.rowBytes(), region_in_yv12_frame, output.get());
}
// The result is now ready.
ignore_result(failure_handler.Release());
- done_cb.Run(true);
+ done_cb.Run(region_in_frame, true);
}
VideoFrameDeliveryLog::VideoFrameDeliveryLog()
@@ -597,7 +727,7 @@ void WebContentsCaptureMachine::Capture(
RenderWidgetHostViewBase* view =
rwh ? static_cast<RenderWidgetHostViewBase*>(rwh->GetView()) : NULL;
if (!view) {
- deliver_frame_cb.Run(base::TimeTicks(), false);
+ deliver_frame_cb.Run(base::TimeTicks(), gfx::Rect(), false);
return;
}
@@ -717,12 +847,13 @@ void WebContentsCaptureMachine::DidCopyFromBackingStore(
TRACE_EVENT_ASYNC_STEP_INTO0("gpu.capture", "Capture", target.get(),
"Render");
render_thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&RenderVideoFrame, bitmap, target,
- base::Bind(deliver_frame_cb, start_time)));
+ FROM_HERE, media::BindToCurrentLoop(
+ base::Bind(&RenderVideoFrame, bitmap, target,
+ base::Bind(deliver_frame_cb, start_time))));
} else {
// Capture can fail due to transient issues, so just skip this frame.
DVLOG(1) << "CopyFromBackingStore failed; skipping frame.";
- deliver_frame_cb.Run(start_time, false);
+ deliver_frame_cb.Run(start_time, gfx::Rect(), false);
}
}
@@ -730,6 +861,7 @@ void WebContentsCaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame(
const base::TimeTicks& start_time,
const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
deliver_frame_cb,
+ const gfx::Rect& region_in_frame,
bool success) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::TimeTicks now = base::TimeTicks::Now();
@@ -740,7 +872,7 @@ void WebContentsCaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame(
// Capture can fail due to transient issues, so just skip this frame.
DVLOG(1) << "CopyFromCompositingSurface failed; skipping frame.";
}
- deliver_frame_cb.Run(start_time, success);
+ deliver_frame_cb.Run(start_time, region_in_frame, success);
}
void WebContentsCaptureMachine::RenewFrameSubscription(bool had_target) {
@@ -762,7 +894,8 @@ void WebContentsCaptureMachine::RenewFrameSubscription(bool had_target) {
if (IsStarted()) {
// Tracking of WebContents and/or its main frame has failed before Stop()
// was called, so report this as an error:
- oracle_proxy_->ReportError("WebContents and/or main frame are gone.");
+ oracle_proxy_->ReportError(FROM_HERE,
+ "WebContents and/or main frame are gone.");
}
return;
}
@@ -820,22 +953,21 @@ media::VideoCaptureDevice* WebContentsVideoCaptureDevice::Create(
// Parse device_id into render_process_id and main_render_frame_id.
int render_process_id = -1;
int main_render_frame_id = -1;
- if (!WebContentsCaptureUtil::ExtractTabCaptureTarget(
- device_id, &render_process_id, &main_render_frame_id)) {
+ if (!WebContentsMediaCaptureId::ExtractTabCaptureTarget(
+ device_id, &render_process_id, &main_render_frame_id)) {
return NULL;
}
return new WebContentsVideoCaptureDevice(
- render_process_id,
- main_render_frame_id,
- WebContentsCaptureUtil::IsAutoThrottlingOptionSet(device_id));
+ render_process_id, main_render_frame_id,
+ WebContentsMediaCaptureId::IsAutoThrottlingOptionSet(device_id));
}
void WebContentsVideoCaptureDevice::AllocateAndStart(
const media::VideoCaptureParams& params,
scoped_ptr<Client> client) {
DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
- core_->AllocateAndStart(params, client.Pass());
+ core_->AllocateAndStart(params, std::move(client));
}
void WebContentsVideoCaptureDevice::StopAndDeAllocate() {
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device.h b/chromium/content/browser/media/capture/web_contents_video_capture_device.h
index 18c9f4e82d6..ab0e03ad7d4 100644
--- a/chromium/content/browser/media/capture/web_contents_video_capture_device.h
+++ b/chromium/content/browser/media/capture/web_contents_video_capture_device.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "media/capture/content/screen_capture_device_core.h"
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index 4f3fb0a325b..9e3bf83c461 100644
--- a/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -4,15 +4,20 @@
#include "content/browser/media/capture/web_contents_video_capture_device.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind_helpers.h"
#include "base/debug/debugger.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/browser/media/capture/web_contents_capture_util.h"
#include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -20,6 +25,7 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
+#include "content/public/browser/web_contents_media_capture_id.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -64,16 +70,18 @@ void DeadlineExceeded(base::Closure quit_closure) {
void RunCurrentLoopWithDeadline() {
base::Timer deadline(false, false);
- deadline.Start(FROM_HERE, TestTimeouts::action_max_timeout(), base::Bind(
- &DeadlineExceeded, base::MessageLoop::current()->QuitClosure()));
+ deadline.Start(
+ FROM_HERE, TestTimeouts::action_max_timeout(),
+ base::Bind(&DeadlineExceeded,
+ base::MessageLoop::current()->QuitWhenIdleClosure()));
base::MessageLoop::current()->Run();
deadline.Stop();
}
SkColor ConvertRgbToYuv(SkColor rgb) {
- uint8 yuv[3];
- media::ConvertRGB32ToYUV(reinterpret_cast<uint8*>(&rgb),
- yuv, yuv + 1, yuv + 2, 1, 1, 1, 1, 1);
+ uint8_t yuv[3];
+ media::ConvertRGB32ToYUV(reinterpret_cast<uint8_t*>(&rgb), yuv, yuv + 1,
+ yuv + 2, 1, 1, 1, 1, 1);
return SkColorSetRGB(yuv[0], yuv[1], yuv[2]);
}
@@ -141,7 +149,7 @@ class CaptureTestSourceController {
void WaitForNextCopy() {
{
base::AutoLock guard(lock_);
- copy_done_ = base::MessageLoop::current()->QuitClosure();
+ copy_done_ = base::MessageLoop::current()->QuitWhenIdleClosure();
}
RunCurrentLoopWithDeadline();
@@ -164,8 +172,8 @@ class CaptureTestSourceController {
// CaptureTestSourceController.
class CaptureTestView : public TestRenderWidgetHostView {
public:
- explicit CaptureTestView(RenderWidgetHostImpl* rwh,
- CaptureTestSourceController* controller)
+ CaptureTestView(RenderWidgetHostImpl* rwh,
+ CaptureTestSourceController* controller)
: TestRenderWidgetHostView(rwh),
controller_(controller),
fake_bounds_(100, 100, 100 + kTestWidth, 100 + kTestHeight) {}
@@ -192,11 +200,11 @@ class CaptureTestView : public TestRenderWidgetHostView {
void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) override {
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) override {
SkColor c = ConvertRgbToYuv(controller_->GetSolidColor());
media::FillYUV(
target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
- callback.Run(true);
+ callback.Run(gfx::Rect(), true);
controller_->SignalCopy();
}
@@ -217,9 +225,9 @@ class CaptureTestView : public TestRenderWidgetHostView {
SkColor c = ConvertRgbToYuv(controller_->GetSolidColor());
media::FillYUV(
target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(callback, present_time, true));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, present_time, gfx::Rect(), true));
controller_->SignalCopy();
}
}
@@ -232,70 +240,74 @@ class CaptureTestView : public TestRenderWidgetHostView {
DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestView);
};
-#if defined(COMPILER_MSVC)
-// MSVC warns on diamond inheritance. See comment for same warning on
-// RenderViewHostImpl.
-#pragma warning(push)
-#pragma warning(disable: 4250)
-#endif
-
// A stub implementation which returns solid-color bitmaps in calls to
// CopyFromBackingStore(). The behavior is controlled by a
// CaptureTestSourceController.
+class CaptureTestRenderWidgetHost : public RenderWidgetHostImpl {
+ public:
+ CaptureTestRenderWidgetHost(RenderWidgetHostDelegate* delegate,
+ RenderProcessHost* process,
+ int32_t routing_id,
+ CaptureTestSourceController* controller)
+ : RenderWidgetHostImpl(delegate, process, routing_id, false /* hidden */),
+ controller_(controller) {}
+
+ // RenderWidgetHostImpl overrides.
+ void CopyFromBackingStore(const gfx::Rect& src_rect,
+ const gfx::Size& accelerated_dst_size,
+ const ReadbackRequestCallback& callback,
+ const SkColorType color_type) override {
+ gfx::Size size = controller_->GetCopyResultSize();
+ SkColor color = controller_->GetSolidColor();
+
+ SkBitmap output;
+ EXPECT_TRUE(output.tryAllocN32Pixels(size.width(), size.height()));
+ {
+ SkAutoLockPixels locker(output);
+ output.eraseColor(color);
+ }
+ callback.Run(output, content::READBACK_SUCCESS);
+ controller_->SignalCopy();
+ }
+
+ private:
+ CaptureTestSourceController* controller_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderWidgetHost);
+};
+
class CaptureTestRenderViewHost : public TestRenderViewHost {
public:
CaptureTestRenderViewHost(SiteInstance* instance,
RenderViewHostDelegate* delegate,
RenderWidgetHostDelegate* widget_delegate,
- int32 routing_id,
- int32 main_frame_routing_id,
+ int32_t routing_id,
+ int32_t main_frame_routing_id,
bool swapped_out,
CaptureTestSourceController* controller)
: TestRenderViewHost(instance,
+ make_scoped_ptr(new CaptureTestRenderWidgetHost(
+ widget_delegate,
+ instance->GetProcess(),
+ routing_id,
+ controller)),
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.
- RenderWidgetHostView* old_view = GetView();
- SetView(new CaptureTestView(this, controller));
+ RenderWidgetHostView* old_view = GetWidget()->GetView();
+ GetWidget()->SetView(new CaptureTestView(GetWidget(), controller));
delete old_view;
}
- // TestRenderViewHost overrides.
- void CopyFromBackingStore(const gfx::Rect& src_rect,
- const gfx::Size& accelerated_dst_size,
- const ReadbackRequestCallback& callback,
- const SkColorType color_type) override {
- gfx::Size size = controller_->GetCopyResultSize();
- SkColor color = controller_->GetSolidColor();
-
- // Although it's not necessary, use a PlatformBitmap here (instead of a
- // regular SkBitmap) to exercise possible threading issues.
- skia::PlatformBitmap output;
- EXPECT_TRUE(output.Allocate(size.width(), size.height(), false));
- {
- SkAutoLockPixels locker(output.GetBitmap());
- output.GetBitmap().eraseColor(color);
- }
- callback.Run(output.GetBitmap(), content::READBACK_SUCCESS);
- controller_->SignalCopy();
- }
-
private:
CaptureTestSourceController* controller_;
DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHost);
};
-#if defined(COMPILER_MSVC)
-// Re-enable warning 4250
-#pragma warning(pop)
-#endif
-
class CaptureTestRenderViewHostFactory : public RenderViewHostFactory {
public:
explicit CaptureTestRenderViewHostFactory(
@@ -310,8 +322,8 @@ class CaptureTestRenderViewHostFactory : public RenderViewHostFactory {
SiteInstance* instance,
RenderViewHostDelegate* delegate,
RenderWidgetHostDelegate* widget_delegate,
- int32 routing_id,
- int32 main_frame_routing_id,
+ int32_t routing_id,
+ int32_t main_frame_routing_id,
bool swapped_out) override {
return new CaptureTestRenderViewHost(instance, delegate, widget_delegate,
routing_id, main_frame_routing_id,
@@ -338,15 +350,15 @@ class StubClient : public media::VideoCaptureDevice::Client {
~StubClient() override {}
MOCK_METHOD5(OnIncomingCapturedData,
- void(const uint8* data,
+ void(const uint8_t* data,
int length,
const media::VideoCaptureFormat& frame_format,
int rotation,
const base::TimeTicks& timestamp));
MOCK_METHOD9(OnIncomingCapturedYuvData,
- void(const uint8* y_data,
- const uint8* u_data,
- const uint8* v_data,
+ void(const uint8_t* y_data,
+ const uint8_t* u_data,
+ const uint8_t* v_data,
size_t y_stride,
size_t u_stride,
size_t v_stride,
@@ -407,7 +419,10 @@ class StubClient : public media::VideoCaptureDevice::Client {
frame->visible_rect().size());
}
- void OnError(const std::string& reason) override { error_callback_.Run(); }
+ void OnError(const tracked_objects::Location& from_here,
+ const std::string& reason) override {
+ error_callback_.Run();
+ }
double GetBufferPoolUtilization() const override { return 0.0; }
@@ -420,7 +435,7 @@ class StubClient : public media::VideoCaptureDevice::Client {
int buffer_id)
: id_(buffer_id),
pool_(pool),
- buffer_handle_(buffer_handle.Pass()) {
+ buffer_handle_(std::move(buffer_handle)) {
DCHECK(pool_.get());
}
int id() const override { return id_; }
@@ -430,7 +445,7 @@ class StubClient : public media::VideoCaptureDevice::Client {
}
void* data(int plane) override { return buffer_handle_->data(plane); }
ClientBuffer AsClientBuffer(int plane) override { return nullptr; }
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
base::FileDescriptor AsPlatformFile() override {
return base::FileDescriptor();
}
@@ -466,17 +481,17 @@ class StubClientObserver {
virtual ~StubClientObserver() {}
scoped_ptr<media::VideoCaptureDevice::Client> PassClient() {
- return client_.Pass();
+ return std::move(client_);
}
void QuitIfConditionsMet(SkColor color, const gfx::Size& size) {
base::AutoLock guard(lock_);
if (error_encountered_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
else if (wait_color_yuv_ == color && wait_size_.IsEmpty())
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
else if (wait_color_yuv_ == color && wait_size_ == size)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
// Run the current loop until a frame is delivered with the |expected_color|
@@ -648,7 +663,7 @@ class MAYBE_WebContentsVideoCaptureDeviceTest : public testing::Test {
// particular window).
float GetDeviceScaleFactor() const {
RenderWidgetHostView* const view =
- web_contents_->GetRenderViewHost()->GetView();
+ web_contents_->GetRenderViewHost()->GetWidget()->GetView();
CHECK(view);
return ui::GetScaleFactorForNativeView(view->GetNativeView());
}
@@ -657,13 +672,14 @@ class MAYBE_WebContentsVideoCaptureDeviceTest : public testing::Test {
if (source()->CanUseFrameSubscriber()) {
// Print
CaptureTestView* test_view = static_cast<CaptureTestView*>(
- web_contents_->GetRenderViewHost()->GetView());
+ web_contents_->GetRenderViewHost()->GetWidget()->GetView());
test_view->SimulateUpdate();
} else {
// Simulate a non-accelerated paint.
NotificationService::current()->Notify(
NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
- Source<RenderWidgetHost>(web_contents_->GetRenderViewHost()),
+ Source<RenderWidgetHost>(
+ web_contents_->GetRenderViewHost()->GetWidget()),
NotificationService::NoDetails());
}
}
@@ -671,7 +687,7 @@ class MAYBE_WebContentsVideoCaptureDeviceTest : public testing::Test {
void SimulateSourceSizeChange(const gfx::Size& size) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
CaptureTestView* test_view = static_cast<CaptureTestView*>(
- web_contents_->GetRenderViewHost()->GetView());
+ web_contents_->GetRenderViewHost()->GetWidget()->GetView());
test_view->SetSize(size);
// Normally, RenderWidgetHostImpl would notify WebContentsImpl that the size
// has changed. However, in this test setup where there is no render
diff --git a/chromium/content/browser/media/capture/window_activity_tracker.h b/chromium/content/browser/media/capture/window_activity_tracker.h
new file mode 100644
index 00000000000..5fd9f0bc8d9
--- /dev/null
+++ b/chromium/content/browser/media/capture/window_activity_tracker.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_WINDOW_ACTIVITY_TRACKER_H_
+#define CONTENT_BROWSER_MEDIA_CAPTURE_WINDOW_ACTIVITY_TRACKER_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// WindowActivityTracker is an interface that can be implememented to report
+// whether the user is actively interacting with UI.
+class CONTENT_EXPORT WindowActivityTracker {
+ public:
+ virtual ~WindowActivityTracker() {}
+
+ // Returns true if UI interaction is active.
+ virtual bool IsUiInteractionActive() const = 0;
+
+ // Resets any previous UI activity tracked.
+ virtual void Reset() = 0;
+
+ // Returns a weak pointer.
+ virtual base::WeakPtr<WindowActivityTracker> GetWeakPtr() = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_CAPTURE_WINDOW_ACTIVITY_TRACKER_H_
diff --git a/chromium/content/browser/media/capture/window_activity_tracker_aura.cc b/chromium/content/browser/media/capture/window_activity_tracker_aura.cc
new file mode 100644
index 00000000000..e56e4a3f04c
--- /dev/null
+++ b/chromium/content/browser/media/capture/window_activity_tracker_aura.cc
@@ -0,0 +1,71 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/capture/window_activity_tracker_aura.h"
+
+#include "base/logging.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/events/event_utils.h"
+
+namespace content {
+
+namespace {
+// The time period within which a triggered UI event is considered
+// currently active.
+const int kTimePeriodUiEventMicros = 100000; // 100 ms
+
+// Minimum number of user interactions before we consider the user to be in
+// interactive mode. The goal is to prevent user interactions to launch
+// animated content from causing target playout time flip-flop.
+const int kMinUserInteractions = 5;
+} // namespace
+
+WindowActivityTrackerAura::WindowActivityTrackerAura(aura::Window* window)
+ : window_(window),
+ last_time_ui_event_detected_(base::TimeTicks()),
+ ui_events_count_(0),
+ weak_factory_(this) {
+ if (window_) {
+ window_->AddObserver(this);
+ window_->AddPreTargetHandler(this);
+ }
+}
+
+WindowActivityTrackerAura::~WindowActivityTrackerAura() {
+ if (window_) {
+ window_->RemoveObserver(this);
+ window_->RemovePreTargetHandler(this);
+ }
+}
+
+base::WeakPtr<WindowActivityTracker> WindowActivityTrackerAura::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+bool WindowActivityTrackerAura::IsUiInteractionActive() const {
+ return ui_events_count_ > kMinUserInteractions;
+}
+
+void WindowActivityTrackerAura::Reset() {
+ ui_events_count_ = 0;
+ last_time_ui_event_detected_ = base::TimeTicks();
+}
+
+void WindowActivityTrackerAura::OnEvent(ui::Event* event) {
+ if (base::TimeTicks::Now() - last_time_ui_event_detected_ >
+ base::TimeDelta::FromMicroseconds(kTimePeriodUiEventMicros)) {
+ ui_events_count_++;
+ }
+ last_time_ui_event_detected_ = base::TimeTicks::Now();
+}
+
+void WindowActivityTrackerAura::OnWindowDestroying(aura::Window* window) {
+ DCHECK_EQ(window_, window);
+ window_->RemovePreTargetHandler(this);
+ window_->RemoveObserver(this);
+ window_ = nullptr;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/capture/window_activity_tracker_aura.h b/chromium/content/browser/media/capture/window_activity_tracker_aura.h
new file mode 100644
index 00000000000..c382c7a4bf6
--- /dev/null
+++ b/chromium/content/browser/media/capture/window_activity_tracker_aura.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_WINDOW_ACTIVITY_TRACKER_AURA_H_
+#define CONTENT_BROWSER_MEDIA_CAPTURE_WINDOW_ACTIVITY_TRACKER_AURA_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/media/capture/window_activity_tracker.h"
+#include "content/common/content_export.h"
+#include "ui/aura/window.h"
+#include "ui/events/event_handler.h"
+
+namespace content {
+
+// Tracks UI events and makes a decision on whether the user has been
+// actively interacting with a specified window.
+class CONTENT_EXPORT WindowActivityTrackerAura : public WindowActivityTracker,
+ public ui::EventHandler,
+ public aura::WindowObserver {
+ public:
+ explicit WindowActivityTrackerAura(aura::Window* window);
+ ~WindowActivityTrackerAura() final;
+
+ // WindowActivityTracker overrides.
+ bool IsUiInteractionActive() const final;
+ void Reset() final;
+ base::WeakPtr<WindowActivityTracker> GetWeakPtr() final;
+
+ private:
+ // ui::EventHandler overrides.
+ void OnEvent(ui::Event* event) final;
+
+ // aura::WindowObserver overrides.
+ void OnWindowDestroying(aura::Window* window) final;
+
+ aura::Window* window_;
+
+ // The last time a UI event was detected.
+ base::TimeTicks last_time_ui_event_detected_;
+
+ // The number of UI events detected so far. In case of continuous events
+ // such as mouse movement, a single continuous movement is treated
+ // as one event.
+ int ui_events_count_;
+
+ base::WeakPtrFactory<WindowActivityTrackerAura> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowActivityTrackerAura);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_CAPTURE_WINDOW_ACTIVITY_TRACKER_AURA_H_
diff --git a/chromium/content/browser/media/cdm/browser_cdm_manager.cc b/chromium/content/browser/media/cdm/browser_cdm_manager.cc
index 7294ef40c4d..2f997d078ca 100644
--- a/chromium/content/browser/media/cdm/browser_cdm_manager.cc
+++ b/chromium/content/browser/media/cdm/browser_cdm_manager.cc
@@ -4,12 +4,16 @@
#include "content/browser/media/cdm/browser_cdm_manager.h"
+#include <stddef.h>
#include <string>
+#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/task_runner.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
@@ -19,20 +23,20 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/web_contents.h"
-#include "media/base/browser_cdm.h"
-#include "media/base/browser_cdm_factory.h"
+#include "media/base/cdm_config.h"
+#include "media/base/cdm_factory.h"
#include "media/base/cdm_promise.h"
#include "media/base/limits.h"
#if defined(OS_ANDROID)
+#include "content/public/browser/android/provision_fetcher_factory.h"
#include "content/public/common/renderer_preferences.h"
+#include "media/base/android/android_cdm_factory.h"
#endif
namespace content {
-using media::BrowserCdm;
using media::MediaKeys;
-using media::ScopedBrowserCdmPtr;
namespace {
@@ -44,13 +48,13 @@ const size_t kAndroidKeyIdBytes = 128 / 8;
// The ID used in this class is a concatenation of |render_frame_id| and
// |cdm_id|, i.e. (render_frame_id << 32) + cdm_id.
-uint64 GetId(int render_frame_id, int cdm_id) {
- return (static_cast<uint64>(render_frame_id) << 32) +
- static_cast<uint64>(cdm_id);
+uint64_t GetId(int render_frame_id, int cdm_id) {
+ return (static_cast<uint64_t>(render_frame_id) << 32) +
+ static_cast<uint64_t>(cdm_id);
}
-bool IdBelongsToFrame(uint64 id, int render_frame_id) {
- return (id >> 32) == static_cast<uint64>(render_frame_id);
+bool IdBelongsToFrame(uint64_t id, int render_frame_id) {
+ return (id >> 32) == static_cast<uint64_t>(render_frame_id);
}
// media::CdmPromiseTemplate implementation backed by a BrowserCdmManager.
@@ -222,10 +226,11 @@ bool BrowserCdmManager::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
-media::BrowserCdm* BrowserCdmManager::GetCdm(int render_frame_id,
- int cdm_id) const {
+scoped_refptr<MediaKeys> BrowserCdmManager::GetCdm(int render_frame_id,
+ int cdm_id) const {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
- return cdm_map_.get(GetId(render_frame_id, cdm_id));
+ const auto& iter = cdm_map_.find(GetId(render_frame_id, cdm_id));
+ return iter == cdm_map_.end() ? nullptr : iter->second;
}
void BrowserCdmManager::RenderFrameDeleted(int render_frame_id) {
@@ -264,20 +269,42 @@ void BrowserCdmManager::ResolvePromiseWithSession(
void BrowserCdmManager::RejectPromise(int render_frame_id,
int cdm_id,
uint32_t promise_id,
- media::MediaKeys::Exception exception,
+ MediaKeys::Exception exception,
uint32_t system_code,
const std::string& error_message) {
Send(new CdmMsg_RejectPromise(render_frame_id, cdm_id, promise_id, exception,
system_code, error_message));
}
-void BrowserCdmManager::OnSessionMessage(
- int render_frame_id,
- int cdm_id,
- const std::string& session_id,
- media::MediaKeys::MessageType message_type,
- const std::vector<uint8>& message,
- const GURL& legacy_destination_url) {
+media::CdmFactory* BrowserCdmManager::GetCdmFactory() {
+ if (!cdm_factory_) {
+ // Create a new CdmFactory.
+ cdm_factory_ = GetContentClient()->browser()->CreateCdmFactory();
+
+#if defined(OS_ANDROID)
+ if (!cdm_factory_) {
+ // Obtain http request context for the current render process.
+ net::URLRequestContextGetter* context_getter =
+ RenderProcessHost::FromID(render_process_id_)
+ ->GetBrowserContext()
+ ->GetRequestContext();
+ DCHECK(context_getter);
+
+ cdm_factory_.reset(new media::AndroidCdmFactory(
+ base::Bind(&CreateProvisionFetcher, context_getter)));
+ }
+#endif
+ }
+
+ return cdm_factory_.get();
+}
+
+void BrowserCdmManager::OnSessionMessage(int render_frame_id,
+ int cdm_id,
+ const std::string& session_id,
+ MediaKeys::MessageType message_type,
+ const std::vector<uint8_t>& message,
+ const GURL& legacy_destination_url) {
GURL verified_gurl = legacy_destination_url;
if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) {
DLOG(WARNING) << "SessionMessage legacy_destination_url is invalid : "
@@ -301,7 +328,7 @@ void BrowserCdmManager::OnLegacySessionError(
int cdm_id,
const std::string& session_id,
MediaKeys::Exception exception_code,
- uint32 system_code,
+ uint32_t system_code,
const std::string& error_message) {
Send(new CdmMsg_LegacySessionError(render_frame_id, cdm_id, session_id,
exception_code, system_code,
@@ -330,20 +357,52 @@ void BrowserCdmManager::OnSessionExpirationUpdate(
new_expiry_time));
}
+// Use a weak pointer here instead of |this| to avoid circular references.
+#define BROWSER_CDM_MANAGER_CB(func, ...) \
+ base::Bind(&BrowserCdmManager::func, weak_ptr_factory_.GetWeakPtr(), \
+ render_frame_id, cdm_id, ##__VA_ARGS__)
+
void BrowserCdmManager::OnInitializeCdm(
int render_frame_id,
int cdm_id,
uint32_t promise_id,
const CdmHostMsg_InitializeCdm_Params& params) {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+ DCHECK(!GetCdm(render_frame_id, cdm_id));
+
+ scoped_ptr<SimplePromise> promise(new SimplePromise(
+ weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
+
if (params.key_system.size() > media::limits::kMaxKeySystemLength) {
NOTREACHED() << "Invalid key system: " << params.key_system;
- RejectPromise(render_frame_id, cdm_id, promise_id,
- MediaKeys::INVALID_ACCESS_ERROR, 0, "Invalid key system.");
+ promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Invalid key system.");
+ return;
+ }
+
+ if (!GetCdmFactory()) {
+ NOTREACHED() << "CDM not supported.";
+ promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "CDM not supported.");
return;
}
- AddCdm(render_frame_id, cdm_id, promise_id, params.key_system,
- params.security_origin, params.use_hw_secure_codecs);
+ // The render process makes sure |allow_distinctive_identifier| and
+ // |allow_persistent_state| are true. See RenderCdmFactory::Create().
+ // TODO(xhwang): Pass |allow_distinctive_identifier| and
+ // |allow_persistent_state| from the render process.
+ media::CdmConfig cdm_config;
+ cdm_config.allow_distinctive_identifier = true;
+ cdm_config.allow_persistent_state = true;
+ cdm_config.use_hw_secure_codecs = params.use_hw_secure_codecs;
+
+ GetCdmFactory()->Create(
+ params.key_system, params.security_origin, cdm_config,
+ BROWSER_CDM_MANAGER_CB(OnSessionMessage),
+ BROWSER_CDM_MANAGER_CB(OnSessionClosed),
+ BROWSER_CDM_MANAGER_CB(OnLegacySessionError),
+ BROWSER_CDM_MANAGER_CB(OnSessionKeysChange),
+ BROWSER_CDM_MANAGER_CB(OnSessionExpirationUpdate),
+ BROWSER_CDM_MANAGER_CB(OnCdmCreated, params.security_origin,
+ base::Passed(&promise)));
}
void BrowserCdmManager::OnSetServerCertificate(
@@ -356,7 +415,7 @@ void BrowserCdmManager::OnSetServerCertificate(
scoped_ptr<SimplePromise> promise(new SimplePromise(
weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
return;
@@ -367,7 +426,7 @@ void BrowserCdmManager::OnSetServerCertificate(
return;
}
- cdm->SetServerCertificate(certificate, promise.Pass());
+ cdm->SetServerCertificate(certificate, std::move(promise));
}
void BrowserCdmManager::OnCreateSessionAndGenerateRequest(
@@ -376,7 +435,7 @@ void BrowserCdmManager::OnCreateSessionAndGenerateRequest(
int render_frame_id = params.render_frame_id;
int cdm_id = params.cdm_id;
- const std::vector<uint8>& init_data = params.init_data;
+ const std::vector<uint8_t>& init_data = params.init_data;
scoped_ptr<NewSessionPromise> promise(
new NewSessionPromise(weak_ptr_factory_.GetWeakPtr(),
render_frame_id, cdm_id, params.promise_id));
@@ -414,7 +473,7 @@ void BrowserCdmManager::OnCreateSessionAndGenerateRequest(
return;
}
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
DLOG(WARNING) << "No CDM found for: " << render_frame_id << ", " << cdm_id;
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
@@ -439,7 +498,7 @@ void BrowserCdmManager::OnLoadSession(
scoped_ptr<NewSessionPromise> promise(new NewSessionPromise(
weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
DLOG(WARNING) << "No CDM found for: " << render_frame_id << ", " << cdm_id;
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
@@ -457,13 +516,13 @@ void BrowserCdmManager::OnUpdateSession(int render_frame_id,
int cdm_id,
uint32_t promise_id,
const std::string& session_id,
- const std::vector<uint8>& response) {
+ const std::vector<uint8_t>& response) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
scoped_ptr<SimplePromise> promise(new SimplePromise(
weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
return;
@@ -481,7 +540,7 @@ void BrowserCdmManager::OnUpdateSession(int render_frame_id,
return;
}
- cdm->UpdateSession(session_id, response, promise.Pass());
+ cdm->UpdateSession(session_id, response, std::move(promise));
}
void BrowserCdmManager::OnCloseSession(int render_frame_id,
@@ -493,13 +552,13 @@ void BrowserCdmManager::OnCloseSession(int render_frame_id,
scoped_ptr<SimplePromise> promise(new SimplePromise(
weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
return;
}
- cdm->CloseSession(session_id, promise.Pass());
+ cdm->CloseSession(session_id, std::move(promise));
}
void BrowserCdmManager::OnRemoveSession(int render_frame_id,
@@ -511,13 +570,13 @@ void BrowserCdmManager::OnRemoveSession(int render_frame_id,
scoped_ptr<SimplePromise> promise(new SimplePromise(
weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
return;
}
- cdm->RemoveSession(session_id, promise.Pass());
+ cdm->RemoveSession(session_id, std::move(promise));
}
void BrowserCdmManager::OnDestroyCdm(int render_frame_id, int cdm_id) {
@@ -525,39 +584,21 @@ void BrowserCdmManager::OnDestroyCdm(int render_frame_id, int cdm_id) {
RemoveCdm(GetId(render_frame_id, cdm_id));
}
-// Use a weak pointer here instead of |this| to avoid circular references.
-#define BROWSER_CDM_MANAGER_CB(func) \
- base::Bind(&BrowserCdmManager::func, weak_ptr_factory_.GetWeakPtr(), \
- render_frame_id, cdm_id)
-
-void BrowserCdmManager::AddCdm(int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const std::string& key_system,
- const GURL& security_origin,
- bool use_hw_secure_codecs) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
- DCHECK(!GetCdm(render_frame_id, cdm_id));
-
- scoped_ptr<SimplePromise> promise(new SimplePromise(
- weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
-
- ScopedBrowserCdmPtr cdm(media::CreateBrowserCdm(
- key_system, use_hw_secure_codecs,
- BROWSER_CDM_MANAGER_CB(OnSessionMessage),
- BROWSER_CDM_MANAGER_CB(OnSessionClosed),
- BROWSER_CDM_MANAGER_CB(OnLegacySessionError),
- BROWSER_CDM_MANAGER_CB(OnSessionKeysChange),
- BROWSER_CDM_MANAGER_CB(OnSessionExpirationUpdate)));
-
+void BrowserCdmManager::OnCdmCreated(
+ int render_frame_id,
+ int cdm_id,
+ const GURL& security_origin,
+ scoped_ptr<media::SimpleCdmPromise> promise,
+ const scoped_refptr<media::MediaKeys>& cdm,
+ const std::string& error_message) {
if (!cdm) {
- DVLOG(1) << "failed to create CDM.";
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "Failed to create CDM.");
+ DVLOG(1) << "Failed to create CDM: " << error_message;
+ promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, error_message);
return;
}
- uint64 id = GetId(render_frame_id, cdm_id);
- cdm_map_.add(id, cdm.Pass());
+ uint64_t id = GetId(render_frame_id, cdm_id);
+ cdm_map_[id] = cdm;
cdm_security_origin_map_[id] = security_origin;
promise->resolve();
}
@@ -565,17 +606,17 @@ void BrowserCdmManager::AddCdm(int render_frame_id,
void BrowserCdmManager::RemoveAllCdmForFrame(int render_frame_id) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
- std::vector<uint64> ids_to_remove;
- for (CdmMap::iterator it = cdm_map_.begin(); it != cdm_map_.end(); ++it) {
- if (IdBelongsToFrame(it->first, render_frame_id))
- ids_to_remove.push_back(it->first);
+ std::vector<uint64_t> ids_to_remove;
+ for (const auto& entry : cdm_map_) {
+ if (IdBelongsToFrame(entry.first, render_frame_id))
+ ids_to_remove.push_back(entry.first);
}
- for (size_t i = 0; i < ids_to_remove.size(); ++i)
- RemoveCdm(ids_to_remove[i]);
+ for (const auto& id_to_remove : ids_to_remove)
+ RemoveCdm(id_to_remove);
}
-void BrowserCdmManager::RemoveCdm(uint64 id) {
+void BrowserCdmManager::RemoveCdm(uint64_t id) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
cdm_map_.erase(id);
@@ -590,7 +631,7 @@ void BrowserCdmManager::CheckPermissionStatus(
DCHECK(task_runner_->RunsTasksOnCurrentThread());
GURL security_origin;
- std::map<uint64, GURL>::const_iterator iter =
+ std::map<uint64_t, GURL>::const_iterator iter =
cdm_security_origin_map_.find(GetId(render_frame_id, cdm_id));
DCHECK(iter != cdm_security_origin_map_.end());
if (iter != cdm_security_origin_map_.end())
@@ -643,7 +684,7 @@ void BrowserCdmManager::CreateSessionAndGenerateRequestIfPermitted(
int cdm_id,
media::MediaKeys::SessionType session_type,
media::EmeInitDataType init_data_type,
- const std::vector<uint8>& init_data,
+ const std::vector<uint8_t>& init_data,
scoped_ptr<media::NewSessionCdmPromise> promise,
bool permission_was_allowed) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
@@ -653,14 +694,14 @@ void BrowserCdmManager::CreateSessionAndGenerateRequestIfPermitted(
return;
}
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
return;
}
- cdm->CreateSessionAndGenerateRequest(session_type, init_data_type,
- init_data, promise.Pass());
+ cdm->CreateSessionAndGenerateRequest(session_type, init_data_type, init_data,
+ std::move(promise));
}
void BrowserCdmManager::LoadSessionIfPermitted(
@@ -678,13 +719,13 @@ void BrowserCdmManager::LoadSessionIfPermitted(
return;
}
- BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id);
+ scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
if (!cdm) {
promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
return;
}
- cdm->LoadSession(session_type, session_id, promise.Pass());
+ cdm->LoadSession(session_type, session_id, std::move(promise));
}
} // namespace content
diff --git a/chromium/content/browser/media/cdm/browser_cdm_manager.h b/chromium/content/browser/media/cdm/browser_cdm_manager.h
index 857cdd1d202..e3a986a6f7f 100644
--- a/chromium/content/browser/media/cdm/browser_cdm_manager.h
+++ b/chromium/content/browser/media/cdm/browser_cdm_manager.h
@@ -5,13 +5,14 @@
#ifndef CONTENT_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_
#define CONTENT_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
-#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
@@ -20,7 +21,6 @@
#include "content/public/browser/browser_message_filter.h"
#include "content/public/common/permission_status.mojom.h"
#include "ipc/ipc_message.h"
-#include "media/base/browser_cdm.h"
#include "media/base/cdm_promise.h"
#include "media/base/eme_constants.h"
#include "media/base/media_keys.h"
@@ -28,6 +28,10 @@
struct CdmHostMsg_CreateSessionAndGenerateRequest_Params;
+namespace media {
+class CdmFactory;
+}
+
namespace content {
// This class manages all CDM objects. It receives control operations from the
@@ -52,7 +56,9 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
const IPC::Message& message) override;
bool OnMessageReceived(const IPC::Message& message) override;
- media::BrowserCdm* GetCdm(int render_frame_id, int cdm_id) const;
+ // Returns the CDM associated with |render_frame_id| and |cdm_id|. Returns
+ // null if no such CDM exists.
+ scoped_refptr<media::MediaKeys> GetCdm(int render_frame_id, int cdm_id) const;
// Notifies that the render frame has been deleted so that all CDMs belongs
// to this render frame needs to be destroyed as well. This is needed because
@@ -79,12 +85,16 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
~BrowserCdmManager() override;
private:
+ // Returns the CdmFactory that can be used to create CDMs. Returns null if
+ // CDM is not supported.
+ media::CdmFactory* GetCdmFactory();
+
// CDM callbacks.
void OnSessionMessage(int render_frame_id,
int cdm_id,
const std::string& session_id,
media::MediaKeys::MessageType message_type,
- const std::vector<uint8>& message,
+ const std::vector<uint8_t>& message,
const GURL& legacy_destination_url);
void OnSessionClosed(int render_frame_id,
int cdm_id,
@@ -126,7 +136,7 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
int cdm_id,
uint32_t promise_id,
const std::string& session_id,
- const std::vector<uint8>& response);
+ const std::vector<uint8_t>& response);
void OnCloseSession(int render_frame_id,
int cdm_id,
uint32_t promise_id,
@@ -137,20 +147,19 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
const std::string& session_id);
void OnDestroyCdm(int render_frame_id, int cdm_id);
- // Adds a new CDM identified by |cdm_id| for the given |key_system| and
- // |security_origin|.
- void AddCdm(int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const std::string& key_system,
- const GURL& security_origin,
- bool use_hw_secure_codecs);
+ // Callback for CDM creation.
+ void OnCdmCreated(int render_frame_id,
+ int cdm_id,
+ const GURL& security_origin,
+ scoped_ptr<media::SimpleCdmPromise> promise,
+ const scoped_refptr<media::MediaKeys>& cdm,
+ const std::string& error_message);
// Removes all CDMs associated with |render_frame_id|.
void RemoveAllCdmForFrame(int render_frame_id);
// Removes the CDM with the specified id.
- void RemoveCdm(uint64 id);
+ void RemoveCdm(uint64_t id);
using PermissionStatusCB = base::Callback<void(bool)>;
@@ -174,7 +183,7 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
int cdm_id,
media::MediaKeys::SessionType session_type,
media::EmeInitDataType init_data_type,
- const std::vector<uint8>& init_data,
+ const std::vector<uint8_t>& init_data,
scoped_ptr<media::NewSessionCdmPromise> promise,
bool permission_was_allowed);
@@ -193,15 +202,17 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
// dispatched to the browser UI thread.
scoped_refptr<base::TaskRunner> task_runner_;
+ scoped_ptr<media::CdmFactory> cdm_factory_;
+
// The key in the following maps is a combination of |render_frame_id| and
// |cdm_id|.
- // Map of managed BrowserCdms.
- typedef base::ScopedPtrHashMap<uint64, media::ScopedBrowserCdmPtr> CdmMap;
+ // Map of managed CDMs.
+ typedef std::map<uint64_t, scoped_refptr<media::MediaKeys>> CdmMap;
CdmMap cdm_map_;
// Map of CDM's security origin.
- std::map<uint64, GURL> cdm_security_origin_map_;
+ std::map<uint64_t, GURL> cdm_security_origin_map_;
base::WeakPtrFactory<BrowserCdmManager> weak_ptr_factory_;
diff --git a/chromium/content/browser/media/encrypted_media_browsertest.cc b/chromium/content/browser/media/encrypted_media_browsertest.cc
index 9bcc7e56632..0f5316302d3 100644
--- a/chromium/content/browser/media/encrypted_media_browsertest.cc
+++ b/chromium/content/browser/media/encrypted_media_browsertest.cc
@@ -5,6 +5,7 @@
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
+#include "build/build_config.h"
#include "content/browser/media/media_browsertest.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
diff --git a/chromium/content/browser/media/media_browsertest.cc b/chromium/content/browser/media/media_browsertest.cc
index f47c4a506a9..43db9ad4f72 100644
--- a/chromium/content/browser/media/media_browsertest.cc
+++ b/chromium/content/browser/media/media_browsertest.cc
@@ -6,12 +6,13 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "media/base/test_data_util.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
namespace content {
@@ -26,14 +27,12 @@ void MediaBrowserTest::RunMediaTestPage(const std::string& html_page,
bool http) {
GURL gurl;
std::string query = media::GetURLQueryString(query_params);
- scoped_ptr<net::SpawnedTestServer> http_test_server;
+ scoped_ptr<net::EmbeddedTestServer> http_test_server;
if (http) {
- http_test_server.reset(
- new net::SpawnedTestServer(net::SpawnedTestServer::TYPE_HTTP,
- net::SpawnedTestServer::kLocalhost,
- media::GetTestDataPath()));
+ http_test_server.reset(new net::EmbeddedTestServer);
+ http_test_server->ServeFilesFromSourceDirectory(media::GetTestDataPath());
CHECK(http_test_server->Start());
- gurl = http_test_server->GetURL("files/" + html_page + "?" + query);
+ gurl = http_test_server->GetURL("/" + html_page + "?" + query);
} else {
gurl = content::GetFileUrlWithQuery(media::GetTestDataFilePath(html_page),
query);
diff --git a/chromium/content/browser/media/media_browsertest.h b/chromium/content/browser/media/media_browsertest.h
index caf5d147c76..180cc2c28e4 100644
--- a/chromium/content/browser/media/media_browsertest.h
+++ b/chromium/content/browser/media/media_browsertest.h
@@ -15,8 +15,8 @@ namespace content {
class TitleWatcher;
// Class used to automate running media related browser tests. The functions
-// assume that media files are located under files/media/ folder known to
-// the test http server.
+// assume that media files are located under media/ folder known to the test
+// http server.
class MediaBrowserTest : public ContentBrowserTest {
public:
// Common test results.
diff --git a/chromium/content/browser/media/media_canplaytype_browsertest.cc b/chromium/content/browser/media/media_canplaytype_browsertest.cc
index 8629e0169b7..83493ccc317 100644
--- a/chromium/content/browser/media/media_canplaytype_browsertest.cc
+++ b/chromium/content/browser/media/media_canplaytype_browsertest.cc
@@ -4,10 +4,13 @@
#include <string>
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/media/media_browsertest.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
+#include "media/media_features.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
@@ -39,12 +42,32 @@ const char kOggOpusProbably[] = "";
const char kMpeg2AacProbably[] = "";
#endif // !OS_ANDROID
-#if defined(ENABLE_HEVC_DEMUXING)
+#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
const char* kHevcSupported = kPropProbably;
#else
const char* kHevcSupported = kNot;
#endif
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+const char* kMp2tsMaybe = kPropMaybe;
+const char* kMp2tsProbably = kPropProbably;
+#else
+const char* kMp2tsMaybe = kNot;
+const char* kMp2tsProbably = kNot;
+#endif
+
+#if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
+const char* kAc3Eac3Probably = kPropProbably;
+#else
+const char* kAc3Eac3Probably = kNot;
+#endif
+
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) && \
+ BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
+const char* kMp2tsAc3Eac3Probably = kPropProbably;
+#else
+const char* kMp2tsAc3Eac3Probably = kNot;
+#endif
namespace content {
@@ -88,6 +111,32 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.1234x6\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.12345x\"'"));
+ // Old-style avc1 codecs must be followed by two dot-separated decimal
+ // numbers (H.264 profile and level)
+ // Invalid formats
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1..\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66.\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66.30.\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.x66.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66x.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66.x30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66.30x\"'"));
+ // Invalid level values
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66.300\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66.-1\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.66.x\"'"));
+ // Invalid profile values
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.0.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.65.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.67.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.76.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.78.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.99.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.101.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.300.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.-1.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc1.x.30\"'"));
+
// AAC codecs must be followed by one or two valid hexadecimal numbers.
EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.no\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.0k\"'"));
@@ -184,6 +233,23 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"avc3x\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4ax\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac-\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec-\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac-2\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec-2\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac-4\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec-4\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a4\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a7\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a5.\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a6.\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a5.1\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a6.1\"'"));
+
EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"unknown\"'"));
// Don't allow incomplete/ambiguous codec ids for HEVC.
@@ -247,6 +313,7 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1, vorbis\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3, vorbis\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1, opus\"'"));
@@ -263,6 +330,13 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"theora, mp4a.40.2\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"theora, mp4a.40.02\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.A6\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a6\"'"));
+
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"1\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"theora, 1\"'"));
@@ -293,6 +367,7 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1, vorbis\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3, vorbis\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1, opus\"'"));
@@ -311,6 +386,13 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"vp8.0, mp4a.40\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"vp9.0, mp4a.40\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.A6\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a6\"'"));
+
// Codecs are case sensitive.
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"VP8, Vorbis\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"VP8.0, Opus\"'"));
@@ -337,6 +419,7 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc1, 1\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"avc3, 1\"'"));
@@ -349,6 +432,13 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"mp4a.40.2\"'"));
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"mp4a.40.02\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.A6\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'" + mime + "; codecs=\"mp4a.a6\"'"));
+
// Unknown codec.
EXPECT_EQ(kNot, CanPlay("'" + mime +"; codecs=\"unknown\"'"));
}
@@ -482,6 +572,7 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp3) {
EXPECT_EQ(kNot, CanPlay("'audio/mpeg; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mpeg; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'audio/mpeg; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mpeg; codecs=\"mp4a.40.2\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mpeg; codecs=\"mp4a.40.02\"'"));
@@ -496,6 +587,7 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp3) {
EXPECT_EQ(kNot, CanPlay("'audio/mp3; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp3; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'audio/mp3; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp3; codecs=\"mp4a.40.2\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp3; codecs=\"mp4a.40.02\"'"));
@@ -510,6 +602,7 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp3) {
EXPECT_EQ(kNot, CanPlay("'audio/x-mp3; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/x-mp3; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'audio/x-mp3; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/x-mp3; codecs=\"mp4a.40.2\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/x-mp3; codecs=\"mp4a.40.02\"'"));
@@ -532,6 +625,10 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc3.42801E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc3.42C01E\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/mp4; codecs=\"avc1.66.13\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/mp4; codecs=\"avc1.77.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/mp4; codecs=\"avc1.100.40\"'"));
+
EXPECT_EQ(kPropMaybe, CanPlay("'video/mp4; codecs=\"avc1.42E11E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc1.42101E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc1.42701E\"'"));
@@ -550,6 +647,31 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kPropProbably,
CanPlay("'video/mp4; codecs=\"avc3.42E01E, mp4a.40.29\"'"));
+ // AC3 and EAC3 (aka Dolby Digital Plus, DD+) audio codecs.
+ // TODO(servolk): Strictly speaking only mp4a.A5 and mp4a.A6 codec ids are
+ // valid according to RFC 6381 section 3.3, 3.4. Lower-case oti (mp4a.a5 and
+ // mp4a.a6) should be rejected. But we used to allow those in older versions
+ // of Chromecast firmware and some apps (notably MPL) depend on those codec
+ // types being supported, so they should be allowed for now (crbug.com/564960)
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/mp4; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/mp4; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/mp4; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/mp4; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/mp4; codecs=\"mp4a.a6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/mp4; codecs=\"mp4a.A6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/mp4; codecs=\"avc1.640028,ac-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/mp4; codecs=\"avc1.640028,mp4a.a5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/mp4; codecs=\"avc1.640028,mp4a.A5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/mp4; codecs=\"avc1.640028,ec-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/mp4; codecs=\"avc1.640028,mp4a.a6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/mp4; codecs=\"avc1.640028,mp4a.A6\"'"));
+
EXPECT_EQ(kPropMaybe, CanPlay("'video/mp4; codecs=\"avc1, mp4a.40.2\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/mp4; codecs=\"avc1, mp4a.40.02\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/mp4; codecs=\"avc3, mp4a.40.2\"'"));
@@ -584,6 +706,10 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc3.42801E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc3.42C01E\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/x-m4v; codecs=\"avc1.66.13\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/x-m4v; codecs=\"avc1.77.30\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/x-m4v; codecs=\"avc1.100.40\"'"));
+
EXPECT_EQ(kPropMaybe, CanPlay("'video/x-m4v; codecs=\"avc1.42E11E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc1.42101E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc1.42701E\"'"));
@@ -620,6 +746,25 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kHevcSupported,
CanPlay("'video/x-m4v; codecs=\"hvc1.1.6.L93.B0, mp4a.40.5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/x-m4v; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/x-m4v; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/x-m4v; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/x-m4v; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/x-m4v; codecs=\"mp4a.a6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'video/x-m4v; codecs=\"mp4a.A6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/x-m4v; codecs=\"avc1.640028,ac-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/x-m4v; codecs=\"avc1.640028,mp4a.a5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/x-m4v; codecs=\"avc1.640028,mp4a.A5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/x-m4v; codecs=\"avc1.640028,ec-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/x-m4v; codecs=\"avc1.640028,mp4a.a6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably,
+ CanPlay("'video/x-m4v; codecs=\"avc1.640028,mp4a.A6\"'"));
+
TestMPEGUnacceptableCombinations("video/x-m4v");
EXPECT_EQ(kPropMaybe, CanPlay("'audio/mp4'"));
@@ -637,12 +782,20 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kNot, CanPlay("'audio/mp4; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp4; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'audio/mp4; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp4; codecs=\"hev1.1.6.L93.B0\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp4; codecs=\"hvc1.1.6.L93.B0\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp4; codecs=\"hev1.1.6.L93.B0,mp4a.40.5\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/mp4; codecs=\"hvc1.1.6.L93.B0,mp4a.40.5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/mp4; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/mp4; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/mp4; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/mp4; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/mp4; codecs=\"mp4a.a6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/mp4; codecs=\"mp4a.A6\"'"));
+
TestMPEGUnacceptableCombinations("audio/mp4");
EXPECT_EQ(kPropMaybe, CanPlay("'audio/x-m4a'"));
@@ -660,6 +813,7 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kNot, CanPlay("'audio/x-m4a; codecs=\"avc1.4D401E\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/x-m4a; codecs=\"avc3.64001F\"'"));
+ EXPECT_EQ(kNot, CanPlay("'audio/x-m4a; codecs=\"avc1.66.30\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/x-m4a; codecs=\"hev1.1.6.L93.B0\"'"));
EXPECT_EQ(kNot, CanPlay("'audio/x-m4a; codecs=\"hvc1.1.6.L93.B0\"'"));
@@ -668,6 +822,13 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kNot,
CanPlay("'audio/x-m4a; codecs=\"hvc1.1.6.L93.B0, mp4a.40.5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/x-m4a; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/x-m4a; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/x-m4a; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/x-m4a; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/x-m4a; codecs=\"mp4a.a6\"'"));
+ EXPECT_EQ(kAc3Eac3Probably, CanPlay("'audio/x-m4a; codecs=\"mp4a.A6\"'"));
+
TestMPEGUnacceptableCombinations("audio/x-m4a");
}
@@ -1054,6 +1215,13 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_HLS) {
EXPECT_EQ(kNot,
CanPlay("'application/x-mpegurl; codecs=\"hvc1.1.6.L93.B0,mp4a.40.5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/x-mpegurl; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/x-mpegurl; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/x-mpegurl; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/x-mpegurl; codecs=\"mp4a.A6\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/x-mpegurl; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/x-mpegurl; codecs=\"mp4a.a6\"'"));
+
EXPECT_EQ(maybeCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc1, mp4a.40.2\"'"));
EXPECT_EQ(maybeCanPlayHLS,
@@ -1137,6 +1305,17 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_HLS) {
CanPlay("'application/vnd.apple.mpegurl; "
"codecs=\"hvc1.1.6.L93.B0,mp4a.40.5\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/vnd.apple.mpegurl; codecs=\"ac-3\"'"));
+ EXPECT_EQ(kNot, CanPlay("'application/vnd.apple.mpegurl; codecs=\"ec-3\"'"));
+ EXPECT_EQ(kNot,
+ CanPlay("'application/vnd.apple.mpegurl; codecs=\"mp4a.A5\"'"));
+ EXPECT_EQ(kNot,
+ CanPlay("'application/vnd.apple.mpegurl; codecs=\"mp4a.A6\"'"));
+ EXPECT_EQ(kNot,
+ CanPlay("'application/vnd.apple.mpegurl; codecs=\"mp4a.a5\"'"));
+ EXPECT_EQ(kNot,
+ CanPlay("'application/vnd.apple.mpegurl; codecs=\"mp4a.a6\"'"));
+
TestMPEGUnacceptableCombinations("application/vnd.apple.mpegurl");
}
@@ -1149,4 +1328,88 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_AAC_ADTS) {
EXPECT_EQ(kNot, CanPlay("'audio/aac; codecs=\"mp4a.40.2\"'"));
}
+IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_Mpeg2Ts) {
+ EXPECT_EQ(kMp2tsMaybe, CanPlay("'video/mp2t'"));
+
+ // video/mp2t must support standard RFC 6381 compliant H.264 / AAC codec ids.
+ // H.264 baseline, main, high profiles
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.42E01E\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.4D401E\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.640028\"'"));
+ // AAC LC audio
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"mp4a.40.2\"'"));
+ // H.264 + AAC audio combinations
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.42E01E,mp4a.40.2\"'"));
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.4D401E,mp4a.40.2\"'"));
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.640028,mp4a.40.2\"'"));
+ // H.264 + AC3/EAC3 audio combinations
+ EXPECT_EQ(kMp2tsAc3Eac3Probably,
+ CanPlay("'video/mp2t; codecs=\"avc1.640028,ac-3\"'"));
+ EXPECT_EQ(kMp2tsAc3Eac3Probably,
+ CanPlay("'video/mp2t; codecs=\"avc1.640028,ec-3\"'"));
+ EXPECT_EQ(kMp2tsAc3Eac3Probably,
+ CanPlay("'video/mp2t; codecs=\"avc1.640028,mp4a.A5\"'"));
+ EXPECT_EQ(kMp2tsAc3Eac3Probably,
+ CanPlay("'video/mp2t; codecs=\"avc1.640028,mp4a.A6\"'"));
+ EXPECT_EQ(kMp2tsAc3Eac3Probably,
+ CanPlay("'video/mp2t; codecs=\"avc1.640028,mp4a.a5\"'"));
+ EXPECT_EQ(kMp2tsAc3Eac3Probably,
+ CanPlay("'video/mp2t; codecs=\"avc1.640028,mp4a.a6\"'"));
+
+ TestMPEGUnacceptableCombinations("video/mp2t");
+}
+
+IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest,
+ CodecSupportTest_Mpeg2Ts_LegacyAvc1_codec_ids) {
+ // Old-style avc1/H.264 codec ids that are still being used by some HLS
+ // streaming apps for backward compatibility.
+ // H.264 baseline profile
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.10\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.13\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.20\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.22\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.30\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.32\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.40\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.66.42\"'"));
+ // H.264 main profile
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.10\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.13\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.20\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.22\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.30\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.32\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.40\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.77.42\"'"));
+ // H.264 high profile
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.10\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.13\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.20\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.22\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.30\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.32\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.40\"'"));
+ EXPECT_EQ(kMp2tsProbably, CanPlay("'video/mp2t; codecs=\"avc1.100.42\"'"));
+
+ // H.264 + AAC audio combinations
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.66.10,mp4a.40.2\"'"));
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.66.30,mp4a.40.2\"'"));
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.77.10,mp4a.40.2\"'"));
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.77.30,mp4a.40.2\"'"));
+ EXPECT_EQ(kMp2tsProbably,
+ CanPlay("'video/mp2t; codecs=\"avc1.100.40,mp4a.40.2\"'"));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_Mpeg2TsAudio) {
+ // audio/mp2t is currently not supported (see also crbug.com/556837).
+ EXPECT_EQ(kNot, CanPlay("'audio/mp2t; codecs=\"mp4a.40.2\"'"));
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/media_internals.cc b/chromium/content/browser/media/media_internals.cc
index 4b4d6cd6b3d..c6455766ce2 100644
--- a/chromium/content/browser/media/media_internals.cc
+++ b/chromium/content/browser/media/media_internals.cc
@@ -4,10 +4,15 @@
#include "content/browser/media/media_internals.h"
+#include <stddef.h>
+#include <utility>
+
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
@@ -17,9 +22,12 @@
#include "content/public/browser/web_ui.h"
#include "media/audio/audio_parameters.h"
#include "media/base/media_log_event.h"
-#include "media/filters/decrypting_video_decoder.h"
#include "media/filters/gpu_video_decoder.h"
+#if !defined(OS_ANDROID)
+#include "media/filters/decrypting_video_decoder.h"
+#endif
+
namespace {
static base::LazyInstance<content::MediaInternals>::Leaky g_media_internals =
@@ -202,7 +210,7 @@ void AudioLogImpl::SendWebContentsTitle(int component_id,
int render_frame_id) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
StoreComponentMetadata(component_id, dict.get());
- SendWebContentsTitleHelper(FormatCacheKey(component_id), dict.Pass(),
+ SendWebContentsTitleHelper(FormatCacheKey(component_id), std::move(dict),
render_process_id, render_frame_id);
}
@@ -374,10 +382,12 @@ std::string MediaInternals::MediaInternalsUMAHandler::GetUMANameForAVStream(
return uma_name + "Other";
}
+#if !defined(OS_ANDROID)
if (player_info.video_decoder ==
media::DecryptingVideoDecoder::kDecoderName) {
return uma_name + "DVD";
}
+#endif
if (player_info.video_dds) {
uma_name += "DDS.";
@@ -579,6 +589,10 @@ void MediaInternals::UpdateVideoCaptureDeviceCapabilities(
for (const auto& video_capture_device_info : video_capture_device_infos) {
base::ListValue* format_list = new base::ListValue();
+ // TODO(nisse): Representing format information as a string, to be
+ // parsed by the javascript handler, is brittle. Consider passing
+ // a list of mappings instead.
+
for (const auto& format : video_capture_device_info.supported_formats)
format_list->AppendString(media::VideoCaptureFormat::ToString(format));
diff --git a/chromium/content/browser/media/media_internals.h b/chromium/content/browser/media/media_internals.h
index 4ff545fe4e7..e4869281ed5 100644
--- a/chromium/content/browser/media/media_internals.h
+++ b/chromium/content/browser/media/media_internals.h
@@ -13,6 +13,7 @@
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
#include "base/values.h"
diff --git a/chromium/content/browser/media/media_internals_handler.h b/chromium/content/browser/media/media_internals_handler.h
index d984a96d1a2..6fc290bff32 100644
--- a/chromium/content/browser/media/media_internals_handler.h
+++ b/chromium/content/browser/media/media_internals_handler.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_HANDLER_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/public/browser/web_ui_message_handler.h"
diff --git a/chromium/content/browser/media/media_internals_proxy.cc b/chromium/content/browser/media/media_internals_proxy.cc
index 6e338ed5da8..0ff34cf51af 100644
--- a/chromium/content/browser/media/media_internals_proxy.cc
+++ b/chromium/content/browser/media/media_internals_proxy.cc
@@ -4,8 +4,11 @@
#include "content/browser/media/media_internals_proxy.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "content/browser/media/media_internals_handler.h"
diff --git a/chromium/content/browser/media/media_internals_proxy.h b/chromium/content/browser/media/media_internals_proxy.h
index f12e24e7c7d..5eb9294f14f 100644
--- a/chromium/content/browser/media/media_internals_proxy.h
+++ b/chromium/content/browser/media/media_internals_proxy.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_PROXY_H_
#define CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_PROXY_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner_helpers.h"
#include "content/browser/media/media_internals.h"
diff --git a/chromium/content/browser/media/media_internals_ui.h b/chromium/content/browser/media/media_internals_ui.h
index f7a17a6765a..3ec014ce310 100644
--- a/chromium/content/browser/media/media_internals_ui.h
+++ b/chromium/content/browser/media/media_internals_ui.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_UI_H_
#define CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_UI_H_
+#include "base/macros.h"
#include "content/public/browser/web_ui_controller.h"
namespace content {
diff --git a/chromium/content/browser/media/media_internals_unittest.cc b/chromium/content/browser/media/media_internals_unittest.cc
index 37ac3e050df..2ab0539fdb2 100644
--- a/chromium/content/browser/media/media_internals_unittest.cc
+++ b/chromium/content/browser/media/media_internals_unittest.cc
@@ -4,12 +4,15 @@
#include "content/browser/media/media_internals.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/json/json_reader.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/audio/audio_parameters.h"
#include "media/base/channel_layout.h"
@@ -157,7 +160,7 @@ TEST_F(MediaInternalsVideoCaptureDeviceTest,
const media::VideoCaptureFormat capture_format(kFrameSize, kFrameRate,
kPixelFormat, kPixelStorage);
const std::string expected_string = base::StringPrintf(
- "(%s)@%.3ffps, pixel format: %s storage: %s.",
+ "(%s)@%.3ffps, pixel format: %s, storage: %s",
kFrameSize.ToString().c_str(), kFrameRate,
media::VideoPixelFormatToString(kPixelFormat).c_str(),
media::VideoCaptureFormat::PixelStorageToString(kPixelStorage).c_str());
diff --git a/chromium/content/browser/media/media_source_browsertest.cc b/chromium/content/browser/media/media_source_browsertest.cc
index 33dd0adcfde..90d11ba5933 100644
--- a/chromium/content/browser/media/media_source_browsertest.cc
+++ b/chromium/content/browser/media/media_source_browsertest.cc
@@ -3,8 +3,10 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "build/build_config.h"
#include "content/browser/media/media_browsertest.h"
#include "content/public/common/content_switches.h"
+#include "media/media_features.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
#endif
@@ -20,9 +22,11 @@ const char kWebMOpusAudioOnly[] = "audio/webm; codecs=\"opus\"";
const char kWebMVideoOnly[] = "video/webm; codecs=\"vp8\"";
const char kWebMAudioVideo[] = "video/webm; codecs=\"vorbis, vp8\"";
-#if defined(USE_PROPRIETARY_CODECS) && defined(ENABLE_MPEG2TS_STREAM_PARSER)
+#if defined(USE_PROPRIETARY_CODECS)
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
const char kMp2tAudioVideo[] = "video/mp2t; codecs=\"mp4a.40.2, avc1.42E01E\"";
#endif
+#endif
namespace content {
@@ -126,9 +130,11 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_WEBM_Audio_MP4) {
}
#endif
-#if defined(USE_PROPRIETARY_CODECS) && defined(ENABLE_MPEG2TS_STREAM_PARSER)
+#if defined(USE_PROPRIETARY_CODECS)
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_AudioVideo_Mp2t) {
TestSimplePlayback("bear-1280x720.ts", kMp2tAudioVideo, kEnded);
}
#endif
+#endif
} // namespace content
diff --git a/chromium/content/browser/media/media_web_contents_observer.cc b/chromium/content/browser/media/media_web_contents_observer.cc
index 8e48e6878fc..67ef0368680 100644
--- a/chromium/content/browser/media/media_web_contents_observer.cc
+++ b/chromium/content/browser/media/media_web_contents_observer.cc
@@ -4,176 +4,232 @@
#include "content/browser/media/media_web_contents_observer.h"
+#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
-#include "base/stl_util.h"
-#include "content/browser/media/cdm/browser_cdm_manager.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "build/build_config.h"
+#include "content/browser/media/audible_metrics.h"
+#include "content/browser/media/audio_stream_monitor.h"
+#include "content/browser/power_save_blocker_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/frame_messages.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_macros.h"
-#if defined(OS_ANDROID)
-#include "content/browser/media/android/browser_media_player_manager.h"
-#include "content/common/media/media_player_messages_android.h"
-#include "media/base/android/media_player_android.h"
-#endif // defined(OS_ANDROID)
-
namespace content {
-MediaWebContentsObserver::MediaWebContentsObserver(
- WebContents* web_contents)
- : WebContentsObserver(web_contents)
-{
-}
+namespace {
+
+static base::LazyInstance<AudibleMetrics>::Leaky g_audible_metrics =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // anonymous namespace
+
+MediaWebContentsObserver::MediaWebContentsObserver(WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+MediaWebContentsObserver::~MediaWebContentsObserver() {}
-MediaWebContentsObserver::~MediaWebContentsObserver() {
+void MediaWebContentsObserver::WebContentsDestroyed() {
+ g_audible_metrics.Get().UpdateAudibleWebContentsState(web_contents(), false);
}
void MediaWebContentsObserver::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
-#if defined(OS_ANDROID)
- uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
- // Always destroy the media players before CDMs because we do not support
- // detaching CDMs from media players yet. See http://crbug.com/330324
- media_player_managers_.erase(key);
-#endif
- // TODO(xhwang): Currently MediaWebContentsObserver, BrowserMediaPlayerManager
- // and BrowserCdmManager all run on browser UI thread. So this call is okay.
- // In the future we need to support the case where MediaWebContentsObserver
- // get notified on browser UI thread, but BrowserMediaPlayerManager and
- // BrowserCdmManager run on a different thread.
- BrowserCdmManager* browser_cdm_manager =
- BrowserCdmManager::FromProcess(render_frame_host->GetProcess()->GetID());
- if (browser_cdm_manager)
- browser_cdm_manager->RenderFrameDeleted(render_frame_host->GetRoutingID());
+ ClearPowerSaveBlockers(render_frame_host);
}
-#if defined(OS_ANDROID)
-
-bool MediaWebContentsObserver::OnMessageReceived(
- const IPC::Message& msg,
- RenderFrameHost* render_frame_host) {
- if (OnMediaPlayerMessageReceived(msg, render_frame_host))
- return true;
+void MediaWebContentsObserver::MaybeUpdateAudibleState() {
+ if (!AudioStreamMonitor::monitoring_available())
+ return;
- if (OnMediaPlayerSetCdmMessageReceived(msg, render_frame_host))
- return true;
+ AudioStreamMonitor* audio_stream_monitor =
+ static_cast<WebContentsImpl*>(web_contents())->audio_stream_monitor();
- return false;
-}
+ if (audio_stream_monitor->WasRecentlyAudible()) {
+ if (!audio_power_save_blocker_)
+ CreateAudioPowerSaveBlocker();
+ } else {
+ audio_power_save_blocker_.reset();
+ }
-bool MediaWebContentsObserver::OnMediaPlayerMessageReceived(
- const IPC::Message& msg,
- RenderFrameHost* render_frame_host) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnEnterFullscreen)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnInitialize)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnStart)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnSeek)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnPause)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnSetVolume)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnSetPoster)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Release,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnReleaseResources)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnDestroyPlayer)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_RequestRemotePlayback,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnRequestRemotePlayback)
- IPC_MESSAGE_FORWARD(
- MediaPlayerHostMsg_RequestRemotePlaybackControl,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnRequestRemotePlaybackControl)
-#if defined(VIDEO_HOLE)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface,
- GetMediaPlayerManager(render_frame_host),
- BrowserMediaPlayerManager::OnNotifyExternalSurface)
-#endif // defined(VIDEO_HOLE)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
+ g_audible_metrics.Get().UpdateAudibleWebContentsState(
+ web_contents(), audio_stream_monitor->IsCurrentlyAudible());
}
-bool MediaWebContentsObserver::OnMediaPlayerSetCdmMessageReceived(
+bool MediaWebContentsObserver::OnMessageReceived(
const IPC::Message& msg,
RenderFrameHost* render_frame_host) {
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(
- MediaWebContentsObserver, msg, render_frame_host)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetCdm, OnSetCdm)
+ // TODO(dalecurtis): These should no longer be FrameHostMsg.
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MediaWebContentsObserver, msg,
+ render_frame_host)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification,
+ OnMediaPlayingNotification)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification,
+ OnMediaPausedNotification)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
-void MediaWebContentsObserver::OnSetCdm(RenderFrameHost* render_frame_host,
- int player_id,
- int cdm_id) {
- media::MediaPlayerAndroid* media_player =
- GetMediaPlayerManager(render_frame_host)->GetPlayer(player_id);
- if (!media_player) {
- NOTREACHED() << "OnSetCdm: MediaPlayer not found for " << player_id;
+void MediaWebContentsObserver::OnMediaPlayingNotification(
+ RenderFrameHost* render_frame_host,
+ int64_t player_cookie,
+ bool has_video,
+ bool has_audio,
+ bool is_remote) {
+ // Ignore the videos playing remotely and don't hold the wake lock for the
+ // screen. TODO(dalecurtis): Is this correct? It means observers will not
+ // receive play and pause messages.
+ if (is_remote)
return;
- }
- // MediaPlayerAndroid runs on the same thread as BrowserCdmManager.
- BrowserCdmManager* browser_cdm_manager =
- BrowserCdmManager::FromProcess(render_frame_host->GetProcess()->GetID());
- if (!browser_cdm_manager) {
- NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id;
- return;
+ const MediaPlayerId id(render_frame_host, player_cookie);
+ if (has_audio) {
+ AddMediaPlayerEntry(id, &active_audio_players_);
+
+ // If we don't have audio stream monitoring, allocate the audio power save
+ // blocker here instead of during NotifyNavigationStateChanged().
+ if (!audio_power_save_blocker_ &&
+ !AudioStreamMonitor::monitoring_available()) {
+ CreateAudioPowerSaveBlocker();
+ }
}
- media::BrowserCdm* cdm =
- browser_cdm_manager->GetCdm(render_frame_host->GetRoutingID(), cdm_id);
- if (!cdm) {
- NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id;
- return;
+ if (has_video) {
+ AddMediaPlayerEntry(id, &active_video_players_);
+
+ // If we're not hidden and have just created a player, create a blocker.
+ if (!video_power_save_blocker_ &&
+ !static_cast<WebContentsImpl*>(web_contents())->IsHidden()) {
+ CreateVideoPowerSaveBlocker();
+ }
}
- // TODO(xhwang): This could possibly fail. In that case we should reject the
- // promise.
- media_player->SetCdm(cdm);
+ // Notify observers of the new player.
+ DCHECK(has_audio || has_video);
+ static_cast<WebContentsImpl*>(web_contents())->MediaStartedPlaying(id);
}
-BrowserMediaPlayerManager* MediaWebContentsObserver::GetMediaPlayerManager(
- RenderFrameHost* render_frame_host) {
- uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
- if (!media_player_managers_.contains(key)) {
- media_player_managers_.set(
- key,
- make_scoped_ptr(BrowserMediaPlayerManager::Create(render_frame_host)));
+void MediaWebContentsObserver::OnMediaPausedNotification(
+ RenderFrameHost* render_frame_host,
+ int64_t player_cookie) {
+ const MediaPlayerId id(render_frame_host, player_cookie);
+ const bool removed_audio = RemoveMediaPlayerEntry(id, &active_audio_players_);
+ const bool removed_video = RemoveMediaPlayerEntry(id, &active_video_players_);
+ MaybeReleasePowerSaveBlockers();
+
+ if (removed_audio || removed_video) {
+ // Notify observers the player has been "paused".
+ static_cast<WebContentsImpl*>(web_contents())->MediaStoppedPlaying(id);
}
- return media_player_managers_.get(key);
}
-#if defined(VIDEO_HOLE)
-void MediaWebContentsObserver::OnFrameInfoUpdated() {
- for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin();
- iter != media_player_managers_.end(); ++iter) {
- BrowserMediaPlayerManager* manager = iter->second;
- manager->OnFrameInfoUpdated();
+void MediaWebContentsObserver::ClearPowerSaveBlockers(
+ RenderFrameHost* render_frame_host) {
+ std::set<MediaPlayerId> removed_players;
+ RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_,
+ &removed_players);
+ RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_,
+ &removed_players);
+ MaybeReleasePowerSaveBlockers();
+
+ // Notify all observers the player has been "paused".
+ WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents());
+ for (const auto& id : removed_players)
+ wci->MediaStoppedPlaying(id);
+}
+
+void MediaWebContentsObserver::CreateAudioPowerSaveBlocker() {
+ DCHECK(!audio_power_save_blocker_);
+ audio_power_save_blocker_ = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
+ PowerSaveBlocker::kReasonAudioPlayback, "Playing audio");
+}
+
+void MediaWebContentsObserver::CreateVideoPowerSaveBlocker() {
+ DCHECK(!video_power_save_blocker_);
+ DCHECK(!active_video_players_.empty());
+ video_power_save_blocker_ = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
+ PowerSaveBlocker::kReasonVideoPlayback, "Playing video");
+// TODO(mfomitchev): Support PowerSaveBlocker on Aura - crbug.com/546718.
+#if defined(OS_ANDROID) && !defined(USE_AURA)
+ static_cast<PowerSaveBlockerImpl*>(video_power_save_blocker_.get())
+ ->InitDisplaySleepBlocker(web_contents());
+#endif
+}
+
+void MediaWebContentsObserver::WasShown() {
+ // Restore power save blocker if there are active video players running.
+ if (!active_video_players_.empty() && !video_power_save_blocker_)
+ CreateVideoPowerSaveBlocker();
+}
+
+void MediaWebContentsObserver::WasHidden() {
+ // If there are entities capturing screenshots or video (e.g., mirroring),
+ // don't release the power save blocker.
+ if (!web_contents()->GetCapturerCount())
+ video_power_save_blocker_.reset();
+}
+
+void MediaWebContentsObserver::MaybeReleasePowerSaveBlockers() {
+ // If there are no more audio players and we don't have audio stream
+ // monitoring, release the audio power save blocker here instead of during
+ // NotifyNavigationStateChanged().
+ if (active_audio_players_.empty() &&
+ !AudioStreamMonitor::monitoring_available()) {
+ audio_power_save_blocker_.reset();
}
+
+ // If there are no more video players, clear the video power save blocker.
+ if (active_video_players_.empty())
+ video_power_save_blocker_.reset();
+}
+
+void MediaWebContentsObserver::AddMediaPlayerEntry(
+ const MediaPlayerId& id,
+ ActiveMediaPlayerMap* player_map) {
+ DCHECK(std::find((*player_map)[id.first].begin(),
+ (*player_map)[id.first].end(),
+ id.second) == (*player_map)[id.first].end());
+ (*player_map)[id.first].push_back(id.second);
}
-#endif // defined(VIDEO_HOLE)
-#endif // defined(OS_ANDROID)
+bool MediaWebContentsObserver::RemoveMediaPlayerEntry(
+ const MediaPlayerId& id,
+ ActiveMediaPlayerMap* player_map) {
+ auto it = player_map->find(id.first);
+ if (it == player_map->end())
+ return false;
+
+ // Remove the player.
+ auto player_for_removal =
+ std::remove(it->second.begin(), it->second.end(), id.second);
+ if (player_for_removal == it->second.end())
+ return false;
+ it->second.erase(player_for_removal);
+
+ // If there are no players left, remove the map entry.
+ if (it->second.empty())
+ player_map->erase(it);
+
+ return true;
+}
+
+void MediaWebContentsObserver::RemoveAllMediaPlayerEntries(
+ RenderFrameHost* render_frame_host,
+ ActiveMediaPlayerMap* player_map,
+ std::set<MediaPlayerId>* removed_players) {
+ auto it = player_map->find(render_frame_host);
+ if (it == player_map->end())
+ return;
+
+ for (int64_t player_cookie : it->second)
+ removed_players->insert(MediaPlayerId(render_frame_host, player_cookie));
+
+ player_map->erase(it);
+}
} // namespace content
diff --git a/chromium/content/browser/media/media_web_contents_observer.h b/chromium/content/browser/media/media_web_contents_observer.h
index 382dcdf772f..1f76029cf4e 100644
--- a/chromium/content/browser/media/media_web_contents_observer.h
+++ b/chromium/content/browser/media/media_web_contents_observer.h
@@ -5,15 +5,19 @@
#ifndef CONTENT_BROWSER_MEDIA_MEDIA_WEB_CONTENTS_OBSERVER_H_
#define CONTENT_BROWSER_MEDIA_MEDIA_WEB_CONTENTS_OBSERVER_H_
-#include "base/compiler_specific.h"
-#include "base/containers/scoped_ptr_hash_map.h"
+#include <stdint.h>
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
-
-class BrowserCdmManager;
-class BrowserMediaPlayerManager;
+class PowerSaveBlocker;
// This class manages all RenderFrame based media related managers at the
// browser side. It receives IPC messages from media RenderFrameObservers and
@@ -24,40 +28,66 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
explicit MediaWebContentsObserver(WebContents* web_contents);
~MediaWebContentsObserver() override;
- // WebContentsObserver implementations.
- void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
+ // Called by WebContentsImpl when the audible state may have changed.
+ void MaybeUpdateAudibleState();
-#if defined(OS_ANDROID)
+ // WebContentsObserver implementation.
+ void WebContentsDestroyed() override;
+ void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
bool OnMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host) override;
+ void WasShown() override;
+ void WasHidden() override;
- // Helper functions to handle media player IPC messages. Returns whether the
- // |message| is handled in the function.
- bool OnMediaPlayerMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host);
- bool OnMediaPlayerSetCdmMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host);
+ bool has_audio_power_save_blocker_for_testing() const {
+ return audio_power_save_blocker_;
+ }
- // Gets the media player manager associated with |render_frame_host|. Creates
- // a new one if it doesn't exist. The caller doesn't own the returned pointer.
- BrowserMediaPlayerManager* GetMediaPlayerManager(
- RenderFrameHost* render_frame_host);
+ bool has_video_power_save_blocker_for_testing() const {
+ return video_power_save_blocker_;
+ }
- void OnSetCdm(RenderFrameHost* render_frame_host, int player_id, int cdm_id);
+ private:
+ void OnMediaPlayingNotification(RenderFrameHost* render_frame_host,
+ int64_t player_cookie,
+ bool has_video,
+ bool has_audio,
+ bool is_remote);
+ void OnMediaPausedNotification(RenderFrameHost* render_frame_host,
+ int64_t player_cookie);
-#if defined(VIDEO_HOLE)
- void OnFrameInfoUpdated();
-#endif // defined(VIDEO_HOLE)
+ // Clear |render_frame_host|'s tracking entry for its power save blockers.
+ void ClearPowerSaveBlockers(RenderFrameHost* render_frame_host);
- private:
- // Map from RenderFrameHost* to BrowserMediaPlayerManager.
- typedef base::ScopedPtrHashMap<uintptr_t,
- scoped_ptr<BrowserMediaPlayerManager>>
- MediaPlayerManagerMap;
- MediaPlayerManagerMap media_player_managers_;
-#endif // defined(OS_ANDROID)
+ // Creates an audio or video power save blocker respectively.
+ void CreateAudioPowerSaveBlocker();
+ void CreateVideoPowerSaveBlocker();
+
+ // Releases the audio power save blockers if |active_audio_players_| is empty.
+ // Likewise, releases the video power save blockers if |active_video_players_|
+ // is empty.
+ void MaybeReleasePowerSaveBlockers();
+
+ // Helper methods for adding or removing player entries in |player_map|.
+ using PlayerList = std::vector<int64_t>;
+ using ActiveMediaPlayerMap = std::map<RenderFrameHost*, PlayerList>;
+ void AddMediaPlayerEntry(const MediaPlayerId& id,
+ ActiveMediaPlayerMap* player_map);
+ // Returns true if an entry is actually removed.
+ bool RemoveMediaPlayerEntry(const MediaPlayerId& id,
+ ActiveMediaPlayerMap* player_map);
+ // Removes all entries from |player_map| for |render_frame_host|. Removed
+ // entries are added to |removed_players|.
+ void RemoveAllMediaPlayerEntries(RenderFrameHost* render_frame_host,
+ ActiveMediaPlayerMap* player_map,
+ std::set<MediaPlayerId>* removed_players);
+
+ // Tracking variables and associated power save blockers for media playback.
+ ActiveMediaPlayerMap active_audio_players_;
+ ActiveMediaPlayerMap active_video_players_;
+ scoped_ptr<PowerSaveBlocker> audio_power_save_blocker_;
+ scoped_ptr<PowerSaveBlocker> video_power_save_blocker_;
- private:
DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserver);
};
diff --git a/chromium/content/browser/media/midi_host.cc b/chromium/content/browser/media/midi_host.cc
index c26a7194718..30261ef7f35 100644
--- a/chromium/content/browser/media/midi_host.cc
+++ b/chromium/content/browser/media/midi_host.cc
@@ -33,11 +33,11 @@ const size_t kMaxInFlightBytes = 10 * 1024 * 1024; // 10 MB.
// how many bytes will be sent before reporting back to the renderer.
const size_t kAcknowledgementThresholdBytes = 1024 * 1024; // 1 MB.
-bool IsDataByte(uint8 data) {
+bool IsDataByte(uint8_t data) {
return (data & 0x80) == 0;
}
-bool IsSystemRealTimeMessage(uint8 data) {
+bool IsSystemRealTimeMessage(uint8_t data) {
return 0xf8 <= data && data <= 0xff;
}
@@ -56,13 +56,22 @@ MidiHost::MidiHost(int renderer_process_id,
sent_bytes_in_flight_(0),
bytes_sent_since_last_acknowledgement_(0),
output_port_count_(0) {
- CHECK(midi_manager_);
+ DCHECK(midi_manager_);
}
-MidiHost::~MidiHost() {
- // Close an open session, or abort opening a session.
- if (is_session_requested_)
+MidiHost::~MidiHost() = default;
+
+void MidiHost::OnChannelClosing() {
+ // If we get here the MidiHost is going to be destroyed soon. Prevent any
+ // subsequent calls from MidiManager by closing our session.
+ // If Send() is called from a different thread (e.g. a separate thread owned
+ // by the MidiManager implementation), it will get posted to the IO thread.
+ // There is a race condition here if our refcount is 0 and we're about to or
+ // have already entered OnDestruct().
+ if (is_session_requested_ && midi_manager_) {
midi_manager_->EndSession(this);
+ is_session_requested_ = false;
+ }
}
void MidiHost::OnDestruct() const {
@@ -84,11 +93,12 @@ bool MidiHost::OnMessageReceived(const IPC::Message& message) {
void MidiHost::OnStartSession() {
is_session_requested_ = true;
- midi_manager_->StartSession(this);
+ if (midi_manager_)
+ midi_manager_->StartSession(this);
}
-void MidiHost::OnSendData(uint32 port,
- const std::vector<uint8>& data,
+void MidiHost::OnSendData(uint32_t port,
+ const std::vector<uint8_t>& data,
double timestamp) {
{
base::AutoLock auto_lock(output_port_count_lock_);
@@ -122,12 +132,14 @@ void MidiHost::OnSendData(uint32 port,
return;
sent_bytes_in_flight_ += data.size();
}
- midi_manager_->DispatchSendMidiData(this, port, data, timestamp);
+ if (midi_manager_)
+ midi_manager_->DispatchSendMidiData(this, port, data, timestamp);
}
void MidiHost::OnEndSession() {
is_session_requested_ = false;
- midi_manager_->EndSession(this);
+ if (midi_manager_)
+ midi_manager_->EndSession(this);
}
void MidiHost::CompleteStartSession(media::midi::Result result) {
@@ -154,21 +166,20 @@ void MidiHost::AddOutputPort(const media::midi::MidiPortInfo& info) {
Send(new MidiMsg_AddOutputPort(info));
}
-void MidiHost::SetInputPortState(uint32 port,
+void MidiHost::SetInputPortState(uint32_t port,
media::midi::MidiPortState state) {
Send(new MidiMsg_SetInputPortState(port, state));
}
-void MidiHost::SetOutputPortState(uint32 port,
+void MidiHost::SetOutputPortState(uint32_t port,
media::midi::MidiPortState state) {
Send(new MidiMsg_SetOutputPortState(port, state));
}
-void MidiHost::ReceiveMidiData(
- uint32 port,
- const uint8* data,
- size_t length,
- double timestamp) {
+void MidiHost::ReceiveMidiData(uint32_t port,
+ const uint8_t* data,
+ size_t length,
+ double timestamp) {
TRACE_EVENT0("midi", "MidiHost::ReceiveMidiData");
base::AutoLock auto_lock(messages_queues_lock_);
@@ -180,7 +191,7 @@ void MidiHost::ReceiveMidiData(
received_messages_queues_[port] = new media::midi::MidiMessageQueue(true);
received_messages_queues_[port]->Add(data, length);
- std::vector<uint8> message;
+ std::vector<uint8_t> message;
while (true) {
received_messages_queues_[port]->Get(&message);
if (message.empty())
@@ -216,12 +227,16 @@ void MidiHost::AccumulateMidiBytesSent(size_t n) {
}
}
+void MidiHost::Detach() {
+ midi_manager_ = nullptr;
+}
+
// static
-bool MidiHost::IsValidWebMIDIData(const std::vector<uint8>& data) {
+bool MidiHost::IsValidWebMIDIData(const std::vector<uint8_t>& 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];
+ const uint8_t current = data[i];
if (IsSystemRealTimeMessage(current))
continue; // Real time message can be placed at any point.
if (waiting_data_length > 0) {
diff --git a/chromium/content/browser/media/midi_host.h b/chromium/content/browser/media/midi_host.h
index c6ff3ea857d..ca3706cbcda 100644
--- a/chromium/content/browser/media/midi_host.h
+++ b/chromium/content/browser/media/midi_host.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_BROWSER_MEDIA_MIDI_HOST_H_
#define CONTENT_BROWSER_MEDIA_MIDI_HOST_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
@@ -34,6 +38,7 @@ class CONTENT_EXPORT MidiHost : public BrowserMessageFilter,
MidiHost(int renderer_process_id, media::midi::MidiManager* midi_manager);
// BrowserMessageFilter implementation.
+ void OnChannelClosing() override;
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
@@ -41,22 +46,23 @@ class CONTENT_EXPORT MidiHost : public BrowserMessageFilter,
void CompleteStartSession(media::midi::Result result) override;
void AddInputPort(const media::midi::MidiPortInfo& info) override;
void AddOutputPort(const media::midi::MidiPortInfo& info) override;
- void SetInputPortState(uint32 port,
+ void SetInputPortState(uint32_t port,
media::midi::MidiPortState state) override;
- void SetOutputPortState(uint32 port,
+ void SetOutputPortState(uint32_t port,
media::midi::MidiPortState state) override;
- void ReceiveMidiData(uint32 port,
- const uint8* data,
+ void ReceiveMidiData(uint32_t port,
+ const uint8_t* data,
size_t length,
double timestamp) override;
void AccumulateMidiBytesSent(size_t n) override;
+ void Detach() override;
// Start session to access MIDI hardware.
void OnStartSession();
// Data to be sent to a MIDI output port.
- void OnSendData(uint32 port,
- const std::vector<uint8>& data,
+ void OnSendData(uint32_t port,
+ const std::vector<uint8_t>& data,
double timestamp);
void OnEndSession();
@@ -70,11 +76,11 @@ class CONTENT_EXPORT MidiHost : public BrowserMessageFilter,
friend class BrowserThread;
// Returns true if |data| fulfills the requirements of MidiOutput.send API
- // defined in the WebMIDI spec.
+ // defined in the Web MIDI 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);
+ static bool IsValidWebMIDIData(const std::vector<uint8_t>& data);
int renderer_process_id_;
@@ -90,7 +96,7 @@ class CONTENT_EXPORT MidiHost : public BrowserMessageFilter,
// does not support MIDI. If not supported then a call to
// OnRequestAccess() will always refuse access and a call to
// OnSendData() will do nothing.
- media::midi::MidiManager* const midi_manager_;
+ media::midi::MidiManager* midi_manager_;
// Buffers where data sent from each MIDI input port is stored.
ScopedVector<media::midi::MidiMessageQueue> received_messages_queues_;
@@ -110,7 +116,7 @@ class CONTENT_EXPORT MidiHost : public BrowserMessageFilter,
base::Lock in_flight_lock_;
// How many output port exists.
- uint32 output_port_count_;
+ uint32_t output_port_count_;
// Protects access to |output_port_count_|.
base::Lock output_port_count_lock_;
diff --git a/chromium/content/browser/media/midi_host_unittest.cc b/chromium/content/browser/media/midi_host_unittest.cc
index bfe0c2f051b..655414e858e 100644
--- a/chromium/content/browser/media/midi_host_unittest.cc
+++ b/chromium/content/browser/media/midi_host_unittest.cc
@@ -4,6 +4,10 @@
#include "content/browser/media/midi_host.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
@@ -15,23 +19,23 @@
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_t kGMOn[] = {0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7};
+const uint8_t 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_t kNoteOn[] = {0x90, 0x3c, 0x7f};
+const uint8_t kNoteOnWithRunningStatus[] = {
+ 0x90, 0x3c, 0x7f, 0x3c, 0x7f, 0x3c, 0x7f,
};
-const uint8 kChannelPressure[] = { 0xd0, 0x01 };
-const uint8 kChannelPressureWithRunningStatus[] = {
- 0xd0, 0x01, 0x01, 0x01,
+const uint8_t kChannelPressure[] = {0xd0, 0x01};
+const uint8_t 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 };
+const uint8_t kTimingClock[] = {0xf8};
+const uint8_t kBrokenData1[] = {0x90};
+const uint8_t kBrokenData2[] = {0xf7};
+const uint8_t kBrokenData3[] = {0xf2, 0x00};
+const uint8_t kDataByte0[] = {0x00};
const int kRenderProcessId = 0;
@@ -53,8 +57,8 @@ enum MidiEventType {
struct MidiEvent {
MidiEvent(MidiEventType in_type,
- uint32 in_port_index,
- const std::vector<uint8>& in_data,
+ uint32_t in_port_index,
+ const std::vector<uint8_t>& in_data,
double in_timestamp)
: type(in_type),
port_index(in_port_index),
@@ -62,16 +66,16 @@ struct MidiEvent {
timestamp(in_timestamp) {}
MidiEventType type;
- uint32 port_index;
- std::vector<uint8> data;
+ uint32_t port_index;
+ std::vector<uint8_t> data;
double timestamp;
};
class FakeMidiManager : public media::midi::MidiManager {
public:
void DispatchSendMidiData(media::midi::MidiManagerClient* client,
- uint32 port_index,
- const std::vector<uint8>& data,
+ uint32_t port_index,
+ const std::vector<uint8_t>& data,
double timestamp) override {
events_.push_back(MidiEvent(DISPATCH_SEND_MIDI_DATA,
port_index,
@@ -104,6 +108,10 @@ class MidiHostTest : public testing::Test {
host_(new MidiHostForTesting(kRenderProcessId, &manager_)),
data_(kNoteOn, kNoteOn + arraysize(kNoteOn)),
port_id_(0) {}
+ ~MidiHostTest() override {
+ manager_.Shutdown();
+ RunLoopUntilIdle();
+ }
protected:
void AddOutputPort() {
@@ -117,7 +125,7 @@ class MidiHostTest : public testing::Test {
host_->AddOutputPort(info);
}
- void OnSendData(uint32 port) {
+ void OnSendData(uint32_t port) {
scoped_ptr<IPC::Message> message(
new MidiHostMsg_SendData(port, data_, 0.0));
host_->OnMessageReceived(*message.get());
@@ -127,7 +135,7 @@ class MidiHostTest : public testing::Test {
return manager_.events_.size();
}
- void CheckSendEventAt(size_t at, uint32 port) {
+ void CheckSendEventAt(size_t at, uint32_t port) {
EXPECT_EQ(DISPATCH_SEND_MIDI_DATA, manager_.events_[at].type);
EXPECT_EQ(port, manager_.events_[at].port_index);
EXPECT_EQ(data_, manager_.events_[at].data);
@@ -145,8 +153,8 @@ class MidiHostTest : public testing::Test {
FakeMidiManager manager_;
scoped_refptr<MidiHostForTesting> host_;
- std::vector<uint8> data_;
- int32 port_id_;
+ std::vector<uint8_t> data_;
+ int32_t port_id_;
DISALLOW_COPY_AND_ASSIGN(MidiHostTest);
};
@@ -173,7 +181,7 @@ TEST_F(MidiHostTest, IsValidWebMIDIData) {
// Multiple messages are allowed as long as each of them is complete.
{
- std::vector<uint8> buffer;
+ std::vector<uint8_t> buffer;
PushToVector(kGMOn, &buffer);
PushToVector(kNoteOn, &buffer);
PushToVector(kGSOn, &buffer);
@@ -186,14 +194,14 @@ TEST_F(MidiHostTest, IsValidWebMIDIData) {
// MIDI realtime message can be placed at any position.
{
- const uint8 kNoteOnWithRealTimeClock[] = {
- 0x90, 0xf8, 0x3c, 0x7f, 0x90, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8,
+ const uint8_t 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,
+ const uint8_t kGMOnWithRealTimeClock[] = {
+ 0xf0, 0xf8, 0x7e, 0x7f, 0x09, 0x01, 0xf8, 0xf7,
};
EXPECT_TRUE(MidiHost::IsValidWebMIDIData(
AsVector(kGMOnWithRealTimeClock)));
@@ -206,14 +214,14 @@ TEST_F(MidiHostTest, OutputPortCheck) {
AddOutputPort();
// Sending data to port 0 should be delivered.
- uint32 port0 = 0;
+ uint32_t port0 = 0;
OnSendData(port0);
RunLoopUntilIdle();
EXPECT_EQ(1U, GetEventSize());
CheckSendEventAt(0, port0);
// Sending data to port 1 should not be delivered.
- uint32 port1 = 1;
+ uint32_t port1 = 1;
OnSendData(port1);
RunLoopUntilIdle();
EXPECT_EQ(1U, GetEventSize());
diff --git a/chromium/content/browser/media/webrtc_audio_debug_recordings_browsertest.cc b/chromium/content/browser/media/webrtc_audio_debug_recordings_browsertest.cc
index 222d37f0f10..f42aed10011 100644
--- a/chromium/content/browser/media/webrtc_audio_debug_recordings_browsertest.cc
+++ b/chromium/content/browser/media/webrtc_audio_debug_recordings_browsertest.cc
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "content/browser/media/webrtc_internals.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/browser_test_utils.h"
@@ -65,7 +68,10 @@ namespace content {
class WebRtcAudioDebugRecordingsBrowserTest : public WebRtcContentBrowserTest {
public:
- WebRtcAudioDebugRecordingsBrowserTest() {}
+ WebRtcAudioDebugRecordingsBrowserTest() {
+ // Automatically grant device permission.
+ AppendUseFakeUIForMediaStreamFlag();
+ }
~WebRtcAudioDebugRecordingsBrowserTest() override {}
};
@@ -75,6 +81,9 @@ class WebRtcAudioDebugRecordingsBrowserTest : public WebRtcContentBrowserTest {
#elif defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
// Renderer crashes under Android ASAN: https://crbug.com/408496.
#define MAYBE_CallWithAudioDebugRecordings DISABLED_CallWithAudioDebugRecordings
+#elif defined(OS_ANDROID)
+// Renderer crashes on Android M. https://crbug.com/535728.
+#define MAYBE_CallWithAudioDebugRecordings DISABLED_CallWithAudioDebugRecordings
#else
#define MAYBE_CallWithAudioDebugRecordings CallWithAudioDebugRecordings
#endif
@@ -92,7 +101,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
return;
}
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
// We must navigate somewhere first so that the render process is created.
NavigateToURL(shell(), GURL(""));
@@ -118,7 +127,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
render_process_id);
EXPECT_TRUE(base::PathExists(aec_dump_file));
- int64 file_size = 0;
+ int64_t file_size = 0;
EXPECT_TRUE(base::GetFileSize(aec_dump_file, &file_size));
EXPECT_GT(file_size, 0);
@@ -158,7 +167,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
return;
}
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
// We must navigate somewhere first so that the render process is created.
NavigateToURL(shell(), GURL(""));
@@ -205,7 +214,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
return;
}
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
// We must navigate somewhere first so that the render process is created.
NavigateToURL(shell(), GURL(""));
@@ -249,7 +258,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
GetExpectedAecDumpFileName(base_file, render_process_id);
EXPECT_TRUE(base::PathExists(aec_dump_file));
- int64 file_size = 0;
+ int64_t file_size = 0;
EXPECT_TRUE(base::GetFileSize(aec_dump_file, &file_size));
EXPECT_GT(file_size, 0);
diff --git a/chromium/content/browser/media/webrtc_browsertest.cc b/chromium/content/browser/media/webrtc_browsertest.cc
index 25b00273ba6..7dd174f7f13 100644
--- a/chromium/content/browser/media/webrtc_browsertest.cc
+++ b/chromium/content/browser/media/webrtc_browsertest.cc
@@ -5,8 +5,10 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/webrtc_ip_handling_policy.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
@@ -24,20 +26,24 @@ namespace content {
#define MAYBE_WebRtcBrowserTest WebRtcBrowserTest
#endif
+// This class tests the scenario when permission to access mic or camera is
+// granted.
class MAYBE_WebRtcBrowserTest : public WebRtcContentBrowserTest {
public:
MAYBE_WebRtcBrowserTest() {}
~MAYBE_WebRtcBrowserTest() override {}
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+ // Automatically grant device permission.
+ AppendUseFakeUIForMediaStreamFlag();
+ }
+
+ protected:
// Convenience function since most peerconnection-call.html tests just load
// the page, kick off some javascript and wait for the title to change to OK.
void MakeTypicalPeerConnectionCall(const std::string& javascript) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
- GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
- NavigateToURL(shell(), url);
-
- ExecuteJavascriptAndWaitForOk(javascript);
+ MakeTypicalCall(javascript, "/media/peerconnection-call.html");
}
// Convenience method for making calls that detect if audio os playing (which
@@ -108,7 +114,16 @@ IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
}
-IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CanSetupCallAndSendDtmf) {
+
+#if defined(OS_WIN) && !defined(NVALGRIND)
+// Times out on Dr. Memory bots: https://crbug.com/545740
+#define MAYBE_CanSetupCallAndSendDtmf DISABLED_CanSetupCallAndSendDtmf
+#else
+#define MAYBE_CanSetupCallAndSendDtmf CanSetupCallAndSendDtmf
+#endif
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
+ MAYBE_CanSetupCallAndSendDtmf) {
MakeTypicalPeerConnectionCall("callAndSendDtmf(\'123,abc\');");
}
@@ -136,8 +151,8 @@ IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
// This test makes a call between pc1 and pc2 where a video only stream is sent
// from pc1 to pc2. The stream sent from pc1 to pc2 is cloned from the stream
-// received on pc2 to test that cloning of remote video tracks works as
-// intended and is sent back to pc1.
+// received on pc2 to test that cloning of remote video and audio tracks works
+// as intended and is sent back to pc1.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CanForwardRemoteStream) {
#if defined (OS_ANDROID)
// This test fails on Nexus 5 devices.
@@ -147,7 +162,7 @@ IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CanForwardRemoteStream) {
switches::kDisableWebRtcHWDecoding);
#endif
MakeTypicalPeerConnectionCall(
- "callAndForwardRemoteStream({video: true, audio: false});");
+ "callAndForwardRemoteStream({video: true, audio: true});");
}
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
diff --git a/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc b/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc
index 15d9ca52d38..0645511ffd3 100644
--- a/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc
+++ b/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/strings/stringprintf.h"
#include "base/test/trace_event_analyzer.h"
#include "base/trace_event/trace_event_impl.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/browser/media/webrtc_internals.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/common/content_switches.h"
@@ -77,7 +80,10 @@ namespace content {
class WebRtcGetUserMediaBrowserTest: public WebRtcContentBrowserTest {
public:
- WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) {}
+ WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) {
+ // Automatically grant device permission.
+ AppendUseFakeUIForMediaStreamFlag();
+ }
~WebRtcGetUserMediaBrowserTest() override {}
void StartTracing() {
@@ -118,7 +124,7 @@ class WebRtcGetUserMediaBrowserTest: public WebRtcContentBrowserTest {
void RunGetUserMediaAndCollectMeasures(const int time_to_sample_secs,
const std::string& measure_filter,
const std::string& graph_name) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -176,7 +182,7 @@ class WebRtcGetUserMediaBrowserTest: public WebRtcContentBrowserTest {
const std::string& constraints1,
const std::string& constraints2,
const std::string& expected_result) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -246,7 +252,7 @@ class WebRtcGetUserMediaBrowserTest: public WebRtcContentBrowserTest {
#endif
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
MAYBE_GetVideoStreamAndStop) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -265,7 +271,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
#endif
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
MAYBE_RenderSameTrackMediastreamAndStop) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -277,7 +283,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
RenderClonedMediastreamAndStop) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -290,7 +296,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
kRenderClonedTrackMediastreamAndStop) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -302,7 +308,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
kRenderDuplicatedMediastreamAndStop) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -314,7 +320,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
GetAudioAndVideoStreamAndStop) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -325,7 +331,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
GetAudioAndVideoStreamAndClone) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -337,8 +343,8 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
// Test fails under MSan
// Flaky everywhere else: http://crbug.com/523152
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
- DISABLED_RenderVideoTrackInMultipleTagsAndPause) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ RenderVideoTrackInMultipleTagsAndPause) {
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -348,7 +354,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
GetUserMediaWithMandatorySourceID) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
std::vector<std::string> audio_ids;
std::vector<std::string> video_ids;
@@ -373,7 +379,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
GetUserMediaWithInvalidMandatorySourceID) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
std::vector<std::string> audio_ids;
std::vector<std::string> video_ids;
@@ -406,7 +412,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
GetUserMediaWithInvalidOptionalSourceID) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
std::vector<std::string> audio_ids;
std::vector<std::string> video_ids;
@@ -439,7 +445,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
TwoGetUserMediaAndStop) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -518,7 +524,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
#endif
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
MAYBE_TwoGetUserMediaAndVerifyFrameRate) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -537,7 +543,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
GetUserMediaWithTooHighVideoConstraintsValues) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -560,7 +566,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
// verifies getUserMedia can succeed after being given impossible constraints.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
TwoGetUserMediaAndCheckCallbackAfterFailure) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -598,17 +604,10 @@ IN_PROC_BROWSER_TEST_F(
"VideoCaptureDeviceClient");
}
-// Test fails under MSan, http://crbug.com/445745
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_TestGetUserMediaAspectRatio4To3 \
- DISABLED_TestGetUserMediaAspectRatio4To3
-#else
-#define MAYBE_TestGetUserMediaAspectRatio4To3 TestGetUserMediaAspectRatio4To3
-#endif
// This test calls getUserMedia and checks for aspect ratio behavior.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
- MAYBE_TestGetUserMediaAspectRatio4To3) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ TestGetUserMediaAspectRatio4To3) {
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -620,17 +619,10 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
ExecuteJavascriptAndReturnResult(constraints_4_3));
}
-// Test fails under MSan, http://crbug.com/445745
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_TestGetUserMediaAspectRatio16To9 \
- DISABLED_TestGetUserMediaAspectRatio16To9
-#else
-#define MAYBE_TestGetUserMediaAspectRatio16To9 TestGetUserMediaAspectRatio16To9
-#endif
// This test calls getUserMedia and checks for aspect ratio behavior.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
- MAYBE_TestGetUserMediaAspectRatio16To9) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ TestGetUserMediaAspectRatio16To9) {
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -642,17 +634,10 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
ExecuteJavascriptAndReturnResult(constraints_16_9));
}
-// Test fails under MSan, http://crbug.com/445745
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_TestGetUserMediaAspectRatio1To1 \
- DISABLED_TestGetUserMediaAspectRatio1To1
-#else
-#define MAYBE_TestGetUserMediaAspectRatio1To1 TestGetUserMediaAspectRatio1To1
-#endif
// This test calls getUserMedia and checks for aspect ratio behavior.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
- MAYBE_TestGetUserMediaAspectRatio1To1) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ TestGetUserMediaAspectRatio1To1) {
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -668,7 +653,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
// in the scope of the success callback.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
AudioInIFrameAndCloseInSuccessCb) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -680,7 +665,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
VideoInIFrameAndCloseInSuccessCb) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -694,7 +679,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
// in the scope of the failure callback.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
VideoWithBadConstraintsInIFrameAndCloseInFailureCb) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -714,7 +699,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
InvalidSourceIdInIFrameAndCloseInFailureCb) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -743,7 +728,10 @@ class WebRtcConstraintsBrowserTest
: public WebRtcContentBrowserTest,
public testing::WithParamInterface<UserMediaSizes> {
public:
- WebRtcConstraintsBrowserTest() : user_media_(GetParam()) {}
+ WebRtcConstraintsBrowserTest() : user_media_(GetParam()) {
+ // Automatically grant device permission.
+ AppendUseFakeUIForMediaStreamFlag();
+ }
const UserMediaSizes& user_media() const { return user_media_; }
private:
@@ -759,7 +747,7 @@ class WebRtcConstraintsBrowserTest
// This test calls getUserMedia in sequence with different constraints.
IN_PROC_BROWSER_TEST_P(WebRtcConstraintsBrowserTest,
MAYBE_GetUserMediaConstraints) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
diff --git a/chromium/content/browser/media/webrtc_identity_store.cc b/chromium/content/browser/media/webrtc_identity_store.cc
index 9867a2f69c6..2ada2a15f40 100644
--- a/chromium/content/browser/media/webrtc_identity_store.cc
+++ b/chromium/content/browser/media/webrtc_identity_store.cc
@@ -4,11 +4,15 @@
#include "content/browser/media/webrtc_identity_store.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/rand_util.h"
#include "base/threading/worker_pool.h"
#include "content/browser/media/webrtc_identity_store_backend.h"
@@ -55,7 +59,7 @@ static void GenerateIdentityWorker(const std::string& common_name,
return;
}
- std::vector<uint8> private_key_info;
+ std::vector<uint8_t> private_key_info;
if (!key->ExportPrivateKey(&private_key_info)) {
DLOG(ERROR) << "Unable to export private key";
result->error = net::ERR_PRIVATE_KEY_EXPORT_FAILED;
@@ -133,7 +137,7 @@ class WebRTCIdentityRequestHandle {
WebRTCIdentityRequestHandle(
WebRTCIdentityStore* store,
const WebRTCIdentityStore::CompletionCallback& callback)
- : store_(store), request_(NULL), callback_(callback) {}
+ : request_(NULL), callback_(callback) {}
private:
friend class WebRTCIdentityStore;
@@ -168,7 +172,6 @@ class WebRTCIdentityRequestHandle {
base::ResetAndReturn(&callback_).Run(error, certificate, private_key);
}
- WebRTCIdentityStore* store_;
WebRTCIdentityRequest* request_;
WebRTCIdentityStore::CompletionCallback callback_;
diff --git a/chromium/content/browser/media/webrtc_identity_store.h b/chromium/content/browser/media/webrtc_identity_store.h
index 7e5d8139c01..c788d0dd70d 100644
--- a/chromium/content/browser/media/webrtc_identity_store.h
+++ b/chromium/content/browser/media/webrtc_identity_store.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/media/webrtc_identity_store_backend.cc b/chromium/content/browser/media/webrtc_identity_store_backend.cc
index 59ee8167e07..76d4827d121 100644
--- a/chromium/content/browser/media/webrtc_identity_store_backend.cc
+++ b/chromium/content/browser/media/webrtc_identity_store_backend.cc
@@ -4,8 +4,14 @@
#include "content/browser/media/webrtc_identity_store_backend.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include <tuple>
+
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/string_util.h"
#include "content/public/browser/browser_thread.h"
@@ -53,8 +59,8 @@ struct WebRTCIdentityStoreBackend::IdentityKey {
: origin(origin), identity_name(identity_name) {}
bool operator<(const IdentityKey& other) const {
- return origin < other.origin ||
- (origin == other.origin && identity_name < other.identity_name);
+ return std::tie(origin, identity_name) <
+ std::tie(other.origin, other.identity_name);
}
GURL origin;
@@ -73,7 +79,7 @@ struct WebRTCIdentityStoreBackend::Identity {
Identity(const std::string& common_name,
const std::string& certificate,
const std::string& private_key,
- int64 creation_time)
+ int64_t creation_time)
: common_name(common_name),
certificate(certificate),
private_key(private_key),
@@ -82,7 +88,7 @@ struct WebRTCIdentityStoreBackend::Identity {
std::string common_name;
std::string certificate;
std::string private_key;
- int64 creation_time;
+ int64_t creation_time;
};
struct WebRTCIdentityStoreBackend::PendingFindRequest {
@@ -411,7 +417,7 @@ void WebRTCIdentityStoreBackend::SqlLiteStorage::Load(IdentityMap* out_map) {
std::string cert, private_key;
stmt.ColumnBlobAsString(3, &cert);
stmt.ColumnBlobAsString(4, &private_key);
- int64 creation_time = stmt.ColumnInt64(5);
+ int64_t creation_time = stmt.ColumnInt64(5);
std::pair<IdentityMap::iterator, bool> result =
out_map->insert(std::pair<IdentityKey, Identity>(
key, Identity(common_name, cert, private_key, creation_time)));
diff --git a/chromium/content/browser/media/webrtc_identity_store_backend.h b/chromium/content/browser/media/webrtc_identity_store_backend.h
index 57c16ab39b5..906f71a6e34 100644
--- a/chromium/content/browser/media/webrtc_identity_store_backend.h
+++ b/chromium/content/browser/media/webrtc_identity_store_backend.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
diff --git a/chromium/content/browser/media/webrtc_identity_store_unittest.cc b/chromium/content/browser/media/webrtc_identity_store_unittest.cc
index 4e52288dd25..025e2f3231b 100644
--- a/chromium/content/browser/media/webrtc_identity_store_unittest.cc
+++ b/chromium/content/browser/media/webrtc_identity_store_unittest.cc
@@ -49,8 +49,6 @@ class WebRtcIdentityStoreTest : public testing::Test {
webrtc_identity_store_->SetTaskRunnerForTesting(pool_owner_->pool());
}
- ~WebRtcIdentityStoreTest() override { pool_owner_->pool()->Shutdown(); }
-
void SetValidityPeriod(base::TimeDelta validity_period) {
webrtc_identity_store_->SetValidityPeriodForTesting(validity_period);
}
@@ -82,6 +80,8 @@ class WebRtcIdentityStoreTest : public testing::Test {
webrtc_identity_store_->SetTaskRunnerForTesting(pool_owner_->pool());
}
+ void Stop() { webrtc_identity_store_ = nullptr; }
+
protected:
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
@@ -355,6 +355,7 @@ TEST_F(WebRtcIdentityStoreTest, IdentityPersistentAcrossRestart) {
EXPECT_TRUE(completed_2);
EXPECT_EQ(cert_1, cert_2);
EXPECT_EQ(key_1, key_2);
+ Stop();
}
TEST_F(WebRtcIdentityStoreTest, HandleDBErrors) {
@@ -386,6 +387,8 @@ TEST_F(WebRtcIdentityStoreTest, HandleDBErrors) {
scoped_ptr<sql::Connection> db(new sql::Connection());
EXPECT_TRUE(db->Open(db_path));
EXPECT_EQ(0U, sql::test::CountSQLTables(db.get()));
+
+ Stop();
}
} // namespace content
diff --git a/chromium/content/browser/media/webrtc_internals.cc b/chromium/content/browser/media/webrtc_internals.cc
index 03f6cd04899..40aa91baaec 100644
--- a/chromium/content/browser/media/webrtc_internals.cc
+++ b/chromium/content/browser/media/webrtc_internals.cc
@@ -4,7 +4,10 @@
#include "content/browser/media/webrtc_internals.h"
+#include <stddef.h>
+
#include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
#include "content/browser/media/webrtc_internals_ui_observer.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/public/browser/browser_thread.h"
@@ -37,12 +40,16 @@ static base::ListValue* EnsureLogList(base::DictionaryValue* dict) {
} // namespace
WebRTCInternals::WebRTCInternals()
- : audio_debug_recordings_(false) {
+ : audio_debug_recordings_(false),
+ event_log_recordings_(false),
+ selecting_event_log_(false) {
// TODO(grunell): Shouldn't all the webrtc_internals* files be excluded from the
// build if WebRTC is disabled?
#if defined(ENABLE_WEBRTC)
audio_debug_recordings_file_path_ =
GetContentClient()->browser()->GetDefaultDownloadDirectory();
+ event_log_recordings_file_path_ = audio_debug_recordings_file_path_;
+
if (audio_debug_recordings_file_path_.empty()) {
// In this case the default path (|audio_debug_recordings_file_path_|) will
// be empty and the platform default path will be used in the file dialog
@@ -53,6 +60,8 @@ WebRTCInternals::WebRTCInternals()
audio_debug_recordings_file_path_ =
audio_debug_recordings_file_path_.Append(
FILE_PATH_LITERAL("audio_debug"));
+ event_log_recordings_file_path_ =
+ event_log_recordings_file_path_.Append(FILE_PATH_LITERAL("event_log"));
}
#endif // defined(ENABLE_WEBRTC)
}
@@ -247,6 +256,8 @@ void WebRTCInternals::EnableAudioDebugRecordings(
#if defined(OS_ANDROID)
EnableAudioDebugRecordingsOnAllRenderProcessHosts();
#else
+ selecting_event_log_ = false;
+ DCHECK(select_file_dialog_ == nullptr);
select_file_dialog_ = ui::SelectFileDialog::Create(this, NULL);
select_file_dialog_->SelectFile(
ui::SelectFileDialog::SELECT_SAVEAS_FILE,
@@ -288,6 +299,50 @@ const base::FilePath& WebRTCInternals::GetAudioDebugRecordingsFilePath() const {
return audio_debug_recordings_file_path_;
}
+void WebRTCInternals::SetEventLogRecordings(
+ bool enable,
+ content::WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+#if defined(ENABLE_WEBRTC)
+ if (enable) {
+#if defined(OS_ANDROID)
+ EnableEventLogRecordingsOnAllRenderProcessHosts();
+#else
+ DCHECK(web_contents);
+ DCHECK(select_file_dialog_ == nullptr);
+ selecting_event_log_ = true;
+ select_file_dialog_ = ui::SelectFileDialog::Create(this, nullptr);
+ select_file_dialog_->SelectFile(
+ ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(),
+ event_log_recordings_file_path_, nullptr, 0, FILE_PATH_LITERAL(""),
+ web_contents->GetTopLevelNativeWindow(), nullptr);
+#endif
+ } else {
+ event_log_recordings_ = false;
+ // Tear down the dialog since the user has unchecked the audio debug
+ // recordings box.
+ select_file_dialog_ = nullptr;
+ DCHECK(select_file_dialog_->HasOneRef());
+
+ for (RenderProcessHost::iterator i(
+ content::RenderProcessHost::AllHostsIterator());
+ !i.IsAtEnd(); i.Advance()) {
+ i.GetCurrentValue()->DisableEventLogRecordings();
+ }
+ }
+#endif
+}
+
+bool WebRTCInternals::IsEventLogRecordingsEnabled() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return event_log_recordings_;
+}
+
+const base::FilePath& WebRTCInternals::GetEventLogRecordingsFilePath() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return event_log_recordings_file_path_;
+}
+
void WebRTCInternals::ResetForTesting() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
observers_.Clear();
@@ -318,15 +373,24 @@ void WebRTCInternals::FileSelected(const base::FilePath& path,
void* /*unused_params */) {
#if defined(ENABLE_WEBRTC)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- audio_debug_recordings_file_path_ = path;
- EnableAudioDebugRecordingsOnAllRenderProcessHosts();
+ if (selecting_event_log_) {
+ event_log_recordings_file_path_ = path;
+ EnableEventLogRecordingsOnAllRenderProcessHosts();
+ } else {
+ audio_debug_recordings_file_path_ = path;
+ EnableAudioDebugRecordingsOnAllRenderProcessHosts();
+ }
#endif
}
void WebRTCInternals::FileSelectionCanceled(void* params) {
#if defined(ENABLE_WEBRTC)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SendUpdate("audioDebugRecordingsFileSelectionCancelled", NULL);
+ if (selecting_event_log_) {
+ SendUpdate("eventLogRecordingsFileSelectionCancelled", nullptr);
+ } else {
+ SendUpdate("audioDebugRecordingsFileSelectionCancelled", nullptr);
+ }
#endif
}
@@ -393,6 +457,18 @@ void WebRTCInternals::EnableAudioDebugRecordingsOnAllRenderProcessHosts() {
audio_debug_recordings_file_path_);
}
}
+
+void WebRTCInternals::EnableEventLogRecordingsOnAllRenderProcessHosts() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ event_log_recordings_ = true;
+ for (RenderProcessHost::iterator i(
+ content::RenderProcessHost::AllHostsIterator());
+ !i.IsAtEnd(); i.Advance()) {
+ i.GetCurrentValue()->EnableEventLogRecordings(
+ event_log_recordings_file_path_);
+ }
+}
#endif
void WebRTCInternals::CreateOrReleasePowerSaveBlocker() {
@@ -405,11 +481,9 @@ void WebRTCInternals::CreateOrReleasePowerSaveBlocker() {
} else if (!peer_connection_data_.empty() && !power_save_blocker_) {
DVLOG(1) << ("Preventing the application from being suspended while one or "
"more PeerConnections are active.");
- power_save_blocker_ =
- content::PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
- PowerSaveBlocker::kReasonOther,
- "WebRTC has active PeerConnections").Pass();
+ power_save_blocker_ = content::PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
+ PowerSaveBlocker::kReasonOther, "WebRTC has active PeerConnections");
}
}
diff --git a/chromium/content/browser/media/webrtc_internals.h b/chromium/content/browser/media/webrtc_internals.h
index a1d7cdf0839..f6470008dd4 100644
--- a/chromium/content/browser/media/webrtc_internals.h
+++ b/chromium/content/browser/media/webrtc_internals.h
@@ -94,6 +94,12 @@ class CONTENT_EXPORT WebRTCInternals : public RenderProcessHostObserver,
bool IsAudioDebugRecordingsEnabled() const;
const base::FilePath& GetAudioDebugRecordingsFilePath() const;
+ // Enables or disables diagnostic event log.
+ void SetEventLogRecordings(bool enable, content::WebContents* web_contents);
+
+ bool IsEventLogRecordingsEnabled() const;
+ const base::FilePath& GetEventLogRecordingsFilePath() const;
+
void ResetForTesting();
private:
@@ -128,6 +134,10 @@ class CONTENT_EXPORT WebRTCInternals : public RenderProcessHostObserver,
// Enables diagnostic audio recordings on all render process hosts using
// |audio_debug_recordings_file_path_|.
void EnableAudioDebugRecordingsOnAllRenderProcessHosts();
+
+ // Enables event log recordings on all render process hosts using
+ // |event_log_recordings_file_path_|.
+ void EnableEventLogRecordingsOnAllRenderProcessHosts();
#endif
// Called whenever an element is added to or removed from
@@ -169,6 +179,11 @@ class CONTENT_EXPORT WebRTCInternals : public RenderProcessHostObserver,
bool audio_debug_recordings_;
base::FilePath audio_debug_recordings_file_path_;
+ // Diagnostic event log recording state.
+ bool event_log_recordings_;
+ bool selecting_event_log_;
+ base::FilePath event_log_recordings_file_path_;
+
// While |peer_connection_data_| is non-empty, hold an instance of
// PowerSaveBlocker. This prevents the application from being suspended while
// remoting.
diff --git a/chromium/content/browser/media/webrtc_internals_browsertest.cc b/chromium/content/browser/media/webrtc_internals_browsertest.cc
index b481559b942..a266d03a7f5 100644
--- a/chromium/content/browser/media/webrtc_internals_browsertest.cc
+++ b/chromium/content/browser/media/webrtc_internals_browsertest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -63,7 +67,7 @@ struct StatsUnit {
return ss.str();
}
- int64 timestamp;
+ int64_t timestamp;
std::map<string, string> values;
};
@@ -137,7 +141,7 @@ class UserMediaRequestEntry {
std::string video_constraints;
};
-static const int64 FAKE_TIME_STAMP = 3600000;
+static const int64_t FAKE_TIME_STAMP = 3600000;
#if defined(OS_WIN)
// All tests are flaky on Windows: crbug.com/277322.
@@ -152,9 +156,8 @@ class MAYBE_WebRtcInternalsBrowserTest: public ContentBrowserTest {
~MAYBE_WebRtcInternalsBrowserTest() override {}
void SetUpOnMainThread() override {
- // Assume this is set by the content test launcher.
- ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kUseFakeUIForMediaStream));
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kUseFakeUIForMediaStream);
ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeDeviceForMediaStream));
}
@@ -682,7 +685,7 @@ IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, ConvertedGraphs) {
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
DISABLED_WithRealPeerConnectionCall) {
// Start a peerconnection call in the first window.
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
NavigateToURL(shell(), url);
ASSERT_TRUE(ExecuteJavascript("call({video:true});"));
diff --git a/chromium/content/browser/media/webrtc_internals_message_handler.cc b/chromium/content/browser/media/webrtc_internals_message_handler.cc
index 59025921969..33a69effdc9 100644
--- a/chromium/content/browser/media/webrtc_internals_message_handler.cc
+++ b/chromium/content/browser/media/webrtc_internals_message_handler.cc
@@ -11,6 +11,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
+#include "content/public/common/url_constants.h"
namespace content {
@@ -39,11 +40,38 @@ void WebRTCInternalsMessageHandler::RegisterMessages() {
base::Unretained(this),
false));
+ web_ui()->RegisterMessageCallback(
+ "enableEventLogRecordings",
+ base::Bind(&WebRTCInternalsMessageHandler::OnSetEventLogRecordingsEnabled,
+ base::Unretained(this), true));
+
+ web_ui()->RegisterMessageCallback(
+ "disableEventLogRecordings",
+ base::Bind(&WebRTCInternalsMessageHandler::OnSetEventLogRecordingsEnabled,
+ base::Unretained(this), false));
+
web_ui()->RegisterMessageCallback("finishedDOMLoad",
base::Bind(&WebRTCInternalsMessageHandler::OnDOMLoadDone,
base::Unretained(this)));
}
+RenderFrameHost* WebRTCInternalsMessageHandler::GetWebRTCInternalsHost() const {
+ RenderFrameHost* host = web_ui()->GetWebContents()->GetMainFrame();
+ if (host) {
+ // Make sure we only ever execute the script in the webrtc-internals page.
+ const GURL url(host->GetLastCommittedURL());
+ if (!url.SchemeIs(kChromeUIScheme) ||
+ url.host() != kChromeUIWebRTCInternalsHost) {
+ // Some other page is currently loaded even though we might be in the
+ // process of loading webrtc-internals. So, the current RFH is not the
+ // one we're waiting for.
+ host = nullptr;
+ }
+ }
+
+ return host;
+}
+
void WebRTCInternalsMessageHandler::OnGetAllStats(
const base::ListValue* /* unused_list */) {
for (RenderProcessHost::iterator i(
@@ -63,31 +91,43 @@ void WebRTCInternalsMessageHandler::OnSetAudioDebugRecordingsEnabled(
}
}
+void WebRTCInternalsMessageHandler::OnSetEventLogRecordingsEnabled(
+ bool enable,
+ const base::ListValue* /* unused_list */) {
+ WebRTCInternals::GetInstance()->SetEventLogRecordings(
+ enable, enable ? web_ui()->GetWebContents() : nullptr);
+}
+
void WebRTCInternalsMessageHandler::OnDOMLoadDone(
const base::ListValue* /* unused_list */) {
WebRTCInternals::GetInstance()->UpdateObserver(this);
if (WebRTCInternals::GetInstance()->IsAudioDebugRecordingsEnabled()) {
+ RenderFrameHost* host = GetWebRTCInternalsHost();
+ if (!host)
+ return;
+
std::vector<const base::Value*> args_vector;
base::string16 script =
WebUI::GetJavascriptCall("setAudioDebugRecordingsEnabled", args_vector);
- RenderFrameHost* host = web_ui()->GetWebContents()->GetMainFrame();
- if (host)
- host->ExecuteJavaScript(script);
+ host->ExecuteJavaScript(script);
}
}
void WebRTCInternalsMessageHandler::OnUpdate(const std::string& command,
const base::Value* args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ RenderFrameHost* host = GetWebRTCInternalsHost();
+ if (!host)
+ return;
+
std::vector<const base::Value*> args_vector;
if (args)
args_vector.push_back(args);
- base::string16 update = WebUI::GetJavascriptCall(command, args_vector);
- RenderFrameHost* host = web_ui()->GetWebContents()->GetMainFrame();
- if (host)
- host->ExecuteJavaScript(update);
+ base::string16 update = WebUI::GetJavascriptCall(command, args_vector);
+ host->ExecuteJavaScript(update);
}
} // namespace content
diff --git a/chromium/content/browser/media/webrtc_internals_message_handler.h b/chromium/content/browser/media/webrtc_internals_message_handler.h
index ef5514e82e8..1b42f219a1d 100644
--- a/chromium/content/browser/media/webrtc_internals_message_handler.h
+++ b/chromium/content/browser/media/webrtc_internals_message_handler.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_WEBRTC_INTERNALS_MESSAGE_HANDLER_H_
#define CONTENT_BROWSER_MEDIA_WEBRTC_INTERNALS_MESSAGE_HANDLER_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/media/webrtc_internals_ui_observer.h"
#include "content/public/browser/web_ui_message_handler.h"
@@ -15,6 +16,8 @@ class ListValue;
namespace content {
+class RenderFrameHost;
+
// This class handles messages to and from WebRTCInternalsUI.
// It delegates all its work to WebRTCInternalsProxy on the IO thread.
class WebRTCInternalsMessageHandler : public WebUIMessageHandler,
@@ -30,10 +33,15 @@ class WebRTCInternalsMessageHandler : public WebUIMessageHandler,
void OnUpdate(const std::string& command, const base::Value* args) override;
private:
+ // Returns a pointer to the RFH iff it is currently hosting the
+ // webrtc-internals page.
+ RenderFrameHost* GetWebRTCInternalsHost() const;
+
// Javascript message handler.
void OnGetAllStats(const base::ListValue* list);
void OnSetAudioDebugRecordingsEnabled(bool enable,
const base::ListValue* list);
+ void OnSetEventLogRecordingsEnabled(bool enable, const base::ListValue* list);
void OnDOMLoadDone(const base::ListValue* list);
DISALLOW_COPY_AND_ASSIGN(WebRTCInternalsMessageHandler);
diff --git a/chromium/content/browser/media/webrtc_internals_ui.h b/chromium/content/browser/media/webrtc_internals_ui.h
index 29745b18681..541af020e49 100644
--- a/chromium/content/browser/media/webrtc_internals_ui.h
+++ b/chromium/content/browser/media/webrtc_internals_ui.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_WEBRTC_INTERNALS_UI_H_
#define CONTENT_BROWSER_MEDIA_WEBRTC_INTERNALS_UI_H_
+#include "base/macros.h"
#include "content/public/browser/web_ui_controller.h"
namespace content {
diff --git a/chromium/content/browser/media/webrtc_ip_permissions_browsertest.cc b/chromium/content/browser/media/webrtc_ip_permissions_browsertest.cc
new file mode 100644
index 00000000000..9b05019e40f
--- /dev/null
+++ b/chromium/content/browser/media/webrtc_ip_permissions_browsertest.cc
@@ -0,0 +1,180 @@
+// 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 "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/webrtc_ip_handling_policy.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/test/webrtc_content_browsertest_base.h"
+#include "media/audio/audio_manager.h"
+#include "media/base/media_switches.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace content {
+
+namespace {
+const char kPeerConnectionHtml[] = "/media/peerconnection-call.html";
+} // namespace
+
+// Disable these test cases for Android since in some bots, there exists only
+// the loopback interface.
+#if defined(OS_ANDROID)
+#define MAYBE_WebRtcBrowserIPPermissionGrantedTest \
+ DISABLED_WebRtcBrowserIPPermissionGrantedTest
+#define MAYBE_WebRtcBrowserIPPermissionDeniedTest \
+ DISABLED_WebRtcBrowserIPPermissionDeniedTest
+#define MAYBE_WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest \
+ DISABLED_WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest
+#define MAYBE_WebRtcBrowserIPPolicyPublicInterfaceOnlyTest \
+ DISABLED_WebRtcBrowserIPPolicyPublicInterfaceOnlyTest
+#define MAYBE_WebRtcBrowserIPPolicyDisableUdpTest \
+ DISABLED_WebRtcBrowserIPPolicyDisableUdpTest
+#else
+#define MAYBE_WebRtcBrowserIPPermissionGrantedTest \
+ WebRtcBrowserIPPermissionGrantedTest
+#define MAYBE_WebRtcBrowserIPPermissionDeniedTest \
+ WebRtcBrowserIPPermissionDeniedTest
+#define MAYBE_WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest \
+ WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest
+#define MAYBE_WebRtcBrowserIPPolicyPublicInterfaceOnlyTest \
+ WebRtcBrowserIPPolicyPublicInterfaceOnlyTest
+#define MAYBE_WebRtcBrowserIPPolicyDisableUdpTest \
+ WebRtcBrowserIPPolicyDisableUdpTest
+#endif
+
+// This class tests the scenario when permission to access mic or camera is
+// denied.
+class MAYBE_WebRtcBrowserIPPermissionGrantedTest
+ : public WebRtcContentBrowserTest {
+ public:
+ MAYBE_WebRtcBrowserIPPermissionGrantedTest() {}
+ ~MAYBE_WebRtcBrowserIPPermissionGrantedTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+ AppendUseFakeUIForMediaStreamFlag();
+ command_line->AppendSwitchASCII(switches::kForceWebRtcIPHandlingPolicy,
+ kWebRTCIPHandlingDefault);
+ }
+};
+
+// Loopback interface is the non-default private interface. Test that when
+// device permission is granted, we should have loopback candidates.
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserIPPermissionGrantedTest,
+ GatherLocalCandidates) {
+ // Disable this test on XP, crbug.com/542416.
+ if (OnWinXp())
+ return;
+ MakeTypicalCall("callWithDevicePermissionGranted();", kPeerConnectionHtml);
+}
+
+// This class tests the scenario when permission to access mic or camera is
+// denied.
+class MAYBE_WebRtcBrowserIPPermissionDeniedTest
+ : public WebRtcContentBrowserTest {
+ public:
+ MAYBE_WebRtcBrowserIPPermissionDeniedTest() {}
+ ~MAYBE_WebRtcBrowserIPPermissionDeniedTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitchASCII(switches::kForceWebRtcIPHandlingPolicy,
+ kWebRTCIPHandlingDefault);
+ }
+};
+
+// Test that when device permission is denied, only non-default interfaces are
+// gathered even if the policy is "default".
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserIPPermissionDeniedTest,
+ GatherLocalCandidates) {
+ // Disable this test on XP, crbug.com/542416.
+ if (OnWinXp())
+ return;
+ MakeTypicalCall("callAndExpectNonLoopbackCandidates();", kPeerConnectionHtml);
+}
+
+// This class tests the scenario when ip handling policy is set to "public and
+// private interfaces", the non-default private candidate is not gathered.
+class MAYBE_WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest
+ : public WebRtcContentBrowserTest {
+ public:
+ MAYBE_WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest() {}
+ ~MAYBE_WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+ AppendUseFakeUIForMediaStreamFlag();
+ command_line->AppendSwitchASCII(
+ switches::kForceWebRtcIPHandlingPolicy,
+ kWebRTCIPHandlingDefaultPublicAndPrivateInterfaces);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(
+ MAYBE_WebRtcBrowserIPPolicyPublicAndPrivateInterfacesTest,
+ GatherLocalCandidates) {
+ // Disable this test on XP, crbug.com/542416.
+ if (OnWinXp())
+ return;
+ MakeTypicalCall("callAndExpectNonLoopbackCandidates();", kPeerConnectionHtml);
+}
+
+// This class tests the scenario when ip handling policy is set to "public
+// interface only", there is no candidate gathered as there is no stun server
+// specified.
+class MAYBE_WebRtcBrowserIPPolicyPublicInterfaceOnlyTest
+ : public WebRtcContentBrowserTest {
+ public:
+ MAYBE_WebRtcBrowserIPPolicyPublicInterfaceOnlyTest() {}
+ ~MAYBE_WebRtcBrowserIPPolicyPublicInterfaceOnlyTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+ AppendUseFakeUIForMediaStreamFlag();
+ command_line->AppendSwitchASCII(
+ switches::kForceWebRtcIPHandlingPolicy,
+ kWebRTCIPHandlingDefaultPublicInterfaceOnly);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserIPPolicyPublicInterfaceOnlyTest,
+ GatherLocalCandidates) {
+ // Disable this test on XP, crbug.com/542416.
+ if (OnWinXp())
+ return;
+ MakeTypicalCall("callWithNoCandidateExpected();", kPeerConnectionHtml);
+}
+
+// This class tests the scenario when ip handling policy is set to "disable
+// non-proxied udp", there is no candidate gathered as there is no stun server
+// specified.
+class MAYBE_WebRtcBrowserIPPolicyDisableUdpTest
+ : public WebRtcContentBrowserTest {
+ public:
+ MAYBE_WebRtcBrowserIPPolicyDisableUdpTest() {}
+ ~MAYBE_WebRtcBrowserIPPolicyDisableUdpTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+ AppendUseFakeUIForMediaStreamFlag();
+ command_line->AppendSwitchASCII(switches::kForceWebRtcIPHandlingPolicy,
+ kWebRTCIPHandlingDisableNonProxiedUdp);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserIPPolicyDisableUdpTest,
+ GatherLocalCandidates) {
+ // Disable this test on XP, crbug.com/542416.
+ if (OnWinXp())
+ return;
+ MakeTypicalCall("callWithNoCandidateExpected();", kPeerConnectionHtml);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/webrtc_media_recorder_browsertest.cc b/chromium/content/browser/media/webrtc_media_recorder_browsertest.cc
new file mode 100644
index 00000000000..00f8454dee2
--- /dev/null
+++ b/chromium/content/browser/media/webrtc_media_recorder_browsertest.cc
@@ -0,0 +1,153 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/test/webrtc_content_browsertest_base.h"
+#include "media/base/media_switches.h"
+
+#if defined(OS_ANDROID)
+// TODO(cpaulin): when crbug.com/561068 is fixed, enable this test
+// on android platform.
+#define MAYBE_WebRtcMediaRecorderTest DISABLED_WebRtcMediaRecorderTest
+#else
+#define MAYBE_WebRtcMediaRecorderTest WebRtcMediaRecorderTest
+#endif
+
+namespace {
+
+static const char kBlinkFeaturesNeeded[] = "GetUserMedia";
+
+static const char kMediaRecorderHtmlFile[] = "/media/mediarecorder_test.html";
+
+} // namespace
+
+namespace content {
+// This class tests the recording of a media stream.
+class MAYBE_WebRtcMediaRecorderTest : public WebRtcContentBrowserTest {
+ public:
+ MAYBE_WebRtcMediaRecorderTest() {}
+ ~MAYBE_WebRtcMediaRecorderTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+
+ // Turn on the flags we need.
+ AppendUseFakeUIForMediaStreamFlag();
+
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kUseFakeDeviceForMediaStream);
+
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kEnableBlinkFeatures, kBlinkFeaturesNeeded);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MAYBE_WebRtcMediaRecorderTest);
+};
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest, MediaRecorderStart) {
+ MakeTypicalCall("testStartAndRecorderState();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderStartAndStop) {
+ MakeTypicalCall("testStartStopAndRecorderState();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderStartAndDataAvailable) {
+ MakeTypicalCall("testStartAndDataAvailable();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderStartWithTimeSlice) {
+ MakeTypicalCall("testStartWithTimeSlice();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest, MediaRecorderResume) {
+ MakeTypicalCall("testResumeAndRecorderState();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderNoResumeWhenRecorderInactive) {
+ MakeTypicalCall("testIllegalResumeThrowsDOMError();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderResumeAndDataAvailable) {
+ MakeTypicalCall("testResumeAndDataAvailable();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderPause) {
+ MakeTypicalCall("testPauseAndRecorderState();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderPauseStop) {
+ MakeTypicalCall("testPauseStopAndRecorderState();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderPausePreventsDataavailableFromBeingFired) {
+ MakeTypicalCall("testPausePreventsDataavailableFromBeingFired();",
+ kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderIllegalPauseThrowsDOMError) {
+ MakeTypicalCall("testIllegalPauseThrowsDOMError();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderTwoChannelAudioRecording) {
+ MakeTypicalCall("testTwoChannelAudio();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderIllegalStopThrowsDOMError) {
+ MakeTypicalCall("testIllegalStopThrowsDOMError();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderIllegalStartWhileRecordingThrowsDOMError) {
+ MakeTypicalCall("testIllegalStartInRecordingStateThrowsDOMError();",
+ kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderIllegalStartWhilePausedThrowsDOMError) {
+ MakeTypicalCall("testIllegalStartInPausedStateThrowsDOMError();",
+ kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderIllegalRequestDataThrowsDOMError) {
+ MakeTypicalCall("testIllegalRequestDataThrowsDOMError();",
+ kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ MediaRecorderPeerConnection) {
+ MakeTypicalCall("testRecordRemotePeerConnection();", kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ AddingTrackToMediaStreamFiresErrorEvent) {
+ MakeTypicalCall("testAddingTrackToMediaStreamFiresErrorEvent();",
+ kMediaRecorderHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
+ RemovingTrackFromMediaStreamFiresErrorEvent) {
+ MakeTypicalCall("testRemovingTrackFromMediaStreamFiresErrorEvent();",
+ kMediaRecorderHtmlFile);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/webrtc_webcam_browsertest.cc b/chromium/content/browser/media/webrtc_webcam_browsertest.cc
index 3c65ed9f784..32eeb111532 100644
--- a/chromium/content/browser/media/webrtc_webcam_browsertest.cc
+++ b/chromium/content/browser/media/webrtc_webcam_browsertest.cc
@@ -4,6 +4,7 @@
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
@@ -47,7 +48,7 @@ class WebRtcWebcamBrowserTest: public ContentBrowserTest {
~WebRtcWebcamBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
- ASSERT_TRUE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream));
+ command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
// The content_browsertests run with this flag by default, and this test is
// the only current exception to that rule, so just remove the flag
@@ -71,7 +72,7 @@ class WebRtcWebcamBrowserTest: public ContentBrowserTest {
// want here since the bot runs tests sequentially on the device.
IN_PROC_BROWSER_TEST_F(WebRtcWebcamBrowserTest,
MANUAL_CanAcquireVgaOnRealWebcam) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL(
"/media/getusermedia-real-webcam.html"));
NavigateToURL(shell(), url);
diff --git a/chromium/content/browser/memory/memory_message_filter.cc b/chromium/content/browser/memory/memory_message_filter.cc
index 8f6fe489bfe..110f8396aae 100644
--- a/chromium/content/browser/memory/memory_message_filter.cc
+++ b/chromium/content/browser/memory/memory_message_filter.cc
@@ -9,8 +9,20 @@
namespace content {
-MemoryMessageFilter::MemoryMessageFilter()
- : BrowserMessageFilter(MemoryMsgStart) {}
+MemoryMessageFilter::MemoryMessageFilter(
+ const BrowserChildProcessHost* child_process_host,
+ ProcessType process_type)
+ : BrowserMessageFilter(MemoryMsgStart),
+ process_host_(child_process_host),
+ process_type_(process_type) {
+ DCHECK_NE(process_type_, PROCESS_TYPE_RENDERER);
+}
+
+MemoryMessageFilter::MemoryMessageFilter(
+ const RenderProcessHost* render_process_host)
+ : BrowserMessageFilter(MemoryMsgStart),
+ process_host_(render_process_host),
+ process_type_(PROCESS_TYPE_RENDERER) {}
MemoryMessageFilter::~MemoryMessageFilter() {}
@@ -36,4 +48,9 @@ void MemoryMessageFilter::SendSimulatePressureNotification(
Send(new MemoryMsg_SimulatePressureNotification(level));
}
+void MemoryMessageFilter::SendPressureNotification(
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ Send(new MemoryMsg_PressureNotification(level));
+}
+
} // namespace content
diff --git a/chromium/content/browser/memory/memory_message_filter.h b/chromium/content/browser/memory/memory_message_filter.h
index d489c257adf..ad13662477e 100644
--- a/chromium/content/browser/memory/memory_message_filter.h
+++ b/chromium/content/browser/memory/memory_message_filter.h
@@ -5,17 +5,24 @@
#ifndef CONTENT_BROWSER_MEMORY_MEMORY_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_MEMORY_MEMORY_MESSAGE_FILTER_H_
+#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/common/process_type.h"
namespace content {
+class BrowserChildProcessHost;
+class RenderProcessHost;
+
// This class sends memory messages from the browser process.
// See also: child_memory_message_filter.h
class CONTENT_EXPORT MemoryMessageFilter : public BrowserMessageFilter {
public:
- MemoryMessageFilter();
+ MemoryMessageFilter(const BrowserChildProcessHost* child_process_host,
+ ProcessType process_type);
+ MemoryMessageFilter(const RenderProcessHost* render_process_host);
// BrowserMessageFilter implementation.
void OnFilterAdded(IPC::Sender* sender) override;
@@ -25,11 +32,25 @@ class CONTENT_EXPORT MemoryMessageFilter : public BrowserMessageFilter {
void SendSetPressureNotificationsSuppressed(bool suppressed);
void SendSimulatePressureNotification(
base::MemoryPressureListener::MemoryPressureLevel level);
+ void SendPressureNotification(
+ base::MemoryPressureListener::MemoryPressureLevel level);
protected:
+ friend class MemoryPressureController;
+
~MemoryMessageFilter() override;
+ const void* process_host() const { return process_host_; }
+ ProcessType process_type() const { return process_type_; }
+
private:
+ // The untyped process host and ProcessType associated with this filter
+ // instance. The process host is stored as untyped because it is only used as
+ // a key in MemoryPressureController; at no point is it ever deferenced to
+ // invoke any members on a process host.
+ const void* process_host_;
+ ProcessType process_type_;
+
DISALLOW_COPY_AND_ASSIGN(MemoryMessageFilter);
};
diff --git a/chromium/content/browser/memory/memory_pressure_controller.cc b/chromium/content/browser/memory/memory_pressure_controller.cc
index 67f31b4a169..11cdbe53714 100644
--- a/chromium/content/browser/memory/memory_pressure_controller.cc
+++ b/chromium/content/browser/memory/memory_pressure_controller.cc
@@ -20,7 +20,10 @@ void MemoryPressureController::OnMemoryMessageFilterAdded(
// Add the message filter to the set of all memory message filters and check
// that it wasn't there beforehand.
- const bool success = memory_message_filters_.insert(filter).second;
+ const bool success =
+ memory_message_filters_.insert(
+ std::make_pair(filter->process_host(), filter))
+ .second;
DCHECK(success);
// There's no need to send a message to the child process if memory pressure
@@ -33,10 +36,12 @@ void MemoryPressureController::OnMemoryMessageFilterRemoved(
MemoryMessageFilter* filter) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Remove the message filter from the set of all memory message filters and
- // check that it was there beforehand.
- const bool success = memory_message_filters_.erase(filter) == 1u;
- DCHECK(success);
+ // Remove the message filter from the set of all memory message filters,
+ // ensuring that it was there beforehand.
+ auto it = memory_message_filters_.find(filter->process_host());
+ DCHECK(it != memory_message_filters_.end());
+ DCHECK_EQ(filter, it->second);
+ memory_message_filters_.erase(it);
}
// static
@@ -63,9 +68,8 @@ void MemoryPressureController::SetPressureNotificationsSuppressedInAllProcesses(
base::MemoryPressureListener::SetNotificationsSuppressed(suppressed);
// Enable/disable suppressing memory notifications in all child processes.
- for (const scoped_refptr<MemoryMessageFilter>& filter :
- memory_message_filters_)
- filter->SendSetPressureNotificationsSuppressed(suppressed);
+ for (const auto& filter_pair : memory_message_filters_)
+ filter_pair.second->SendSetPressureNotificationsSuppressed(suppressed);
}
void MemoryPressureController::SimulatePressureNotificationInAllProcesses(
@@ -87,9 +91,44 @@ void MemoryPressureController::SimulatePressureNotificationInAllProcesses(
base::MemoryPressureListener::SimulatePressureNotification(level);
// Simulate memory pressure notification in all child processes.
- for (const scoped_refptr<MemoryMessageFilter>& filter :
- memory_message_filters_)
- filter->SendSimulatePressureNotification(level);
+ for (const auto& filter_pair : memory_message_filters_)
+ filter_pair.second->SendSimulatePressureNotification(level);
+}
+
+void MemoryPressureController::SendPressureNotification(
+ const BrowserChildProcessHost* child_process_host,
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ SendPressureNotificationImpl(child_process_host, level);
+}
+
+void MemoryPressureController::SendPressureNotification(
+ const RenderProcessHost* render_process_host,
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ SendPressureNotificationImpl(render_process_host, level);
+}
+
+void MemoryPressureController::SendPressureNotificationImpl(
+ const void* child_process_host,
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ // Note that passing base::Unretained(this) is safe here because the
+ // controller is a leaky singleton. It's also safe to pass an untyped
+ // child process pointer as the address is only used as a key for lookup in
+ // a map; at no point is it dereferenced.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&MemoryPressureController::SendPressureNotificationImpl,
+ base::Unretained(this), child_process_host, level));
+ return;
+ }
+
+ if (base::MemoryPressureListener::AreNotificationsSuppressed())
+ return;
+
+ // Find the appropriate message filter and dispatch the message.
+ auto it = memory_message_filters_.find(child_process_host);
+ if (it != memory_message_filters_.end())
+ it->second->SendPressureNotification(level);
}
} // namespace content
diff --git a/chromium/content/browser/memory/memory_pressure_controller.h b/chromium/content/browser/memory/memory_pressure_controller.h
index 934f847c16e..f81540957d7 100644
--- a/chromium/content/browser/memory/memory_pressure_controller.h
+++ b/chromium/content/browser/memory/memory_pressure_controller.h
@@ -5,16 +5,19 @@
#ifndef CONTENT_BROWSER_MEMORY_MEMORY_PRESSURE_CONTROLLER_H_
#define CONTENT_BROWSER_MEMORY_MEMORY_PRESSURE_CONTROLLER_H_
-#include <set>
+#include <map>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/singleton.h"
#include "content/common/content_export.h"
namespace content {
+class BrowserChildProcessHost;
class MemoryMessageFilter;
+class RenderProcessHost;
class CONTENT_EXPORT MemoryPressureController {
public:
@@ -26,6 +29,12 @@ class CONTENT_EXPORT MemoryPressureController {
void SetPressureNotificationsSuppressedInAllProcesses(bool suppressed);
void SimulatePressureNotificationInAllProcesses(
base::MemoryPressureListener::MemoryPressureLevel level);
+ void SendPressureNotification(
+ const BrowserChildProcessHost* child_process_host,
+ base::MemoryPressureListener::MemoryPressureLevel level);
+ void SendPressureNotification(
+ const RenderProcessHost* render_process_host,
+ base::MemoryPressureListener::MemoryPressureLevel level);
// This method can be called from any thread.
static MemoryPressureController* GetInstance();
@@ -38,10 +47,16 @@ class CONTENT_EXPORT MemoryPressureController {
MemoryPressureController();
- // Set of all memory message filters in the browser process. Always accessed
- // on the IO thread.
- typedef std::set<scoped_refptr<MemoryMessageFilter>> MemoryMessageFilterSet;
- MemoryMessageFilterSet memory_message_filters_;
+ // Implementation of the various SendPressureNotification methods.
+ void SendPressureNotificationImpl(
+ const void* child_process_host,
+ base::MemoryPressureListener::MemoryPressureLevel level);
+
+ // Map from untyped process host pointers to the associated memory message
+ // filters in the browser process. Always accessed on the IO thread.
+ typedef std::map<const void*, scoped_refptr<MemoryMessageFilter>>
+ MemoryMessageFilterMap;
+ MemoryMessageFilterMap memory_message_filters_;
DISALLOW_COPY_AND_ASSIGN(MemoryPressureController);
};
diff --git a/chromium/content/browser/memory/memory_pressure_controller_browsertest.cc b/chromium/content/browser/memory/memory_pressure_controller_browsertest.cc
index c0d4069c694..5b08a665373 100644
--- a/chromium/content/browser/memory/memory_pressure_controller_browsertest.cc
+++ b/chromium/content/browser/memory/memory_pressure_controller_browsertest.cc
@@ -38,8 +38,25 @@ MATCHER_P(IsSimulateMessage, level, "") {
return level == base::get<0>(param);
}
+MATCHER_P(IsPressureMessage, level, "") {
+ // Ensure that the message is deleted upon return.
+ scoped_ptr<IPC::Message> message(arg);
+ if (message == nullptr)
+ return false;
+ MemoryMsg_PressureNotification::Param param;
+ if (!MemoryMsg_PressureNotification::Read(message.get(), &param))
+ return false;
+ return level == base::get<0>(param);
+}
+
class MemoryMessageFilterForTesting : public MemoryMessageFilter {
public:
+ // Use this object itself as a fake RenderProcessHost pointer. The address is
+ // only used for looking up the message filter in the controller and is never
+ // actually dereferenced, so this is safe.
+ MemoryMessageFilterForTesting()
+ : MemoryMessageFilter(reinterpret_cast<RenderProcessHost*>(this)) {}
+
MOCK_METHOD1(Send, bool(IPC::Message* message));
void Add() {
@@ -91,8 +108,21 @@ class MemoryPressureControllerBrowserTest : public ContentBrowserTest {
->SimulatePressureNotificationInAllProcesses(level);
RunAllPendingInMessageLoop(BrowserThread::IO);
}
+
+ void SendPressureNotificationAndWait(
+ const void* fake_process_host,
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ MemoryPressureController::GetInstance()->SendPressureNotification(
+ reinterpret_cast<const RenderProcessHost*>(fake_process_host), level);
+ RunAllPendingInMessageLoop(BrowserThread::IO);
+ }
};
+const auto MEMORY_PRESSURE_LEVEL_MODERATE =
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
+const auto MEMORY_PRESSURE_LEVEL_CRITICAL =
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
+
IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
SetPressureNotificationsSuppressedInAllProcesses) {
scoped_refptr<MemoryMessageFilterForTesting> filter1(
@@ -108,6 +138,7 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
EXPECT_CALL(*filter2, Send(testing::_)).Times(0);
filter1->Add();
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
+ testing::Mock::VerifyAndClearExpectations(this);
// Enable suppressing memory pressure notifications in all processes. The
// first filter should send a message.
@@ -115,12 +146,22 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
EXPECT_CALL(*filter2, Send(testing::_)).Times(0);
SetPressureNotificationsSuppressedInAllProcessesAndWait(true);
EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed());
+ testing::Mock::VerifyAndClearExpectations(this);
// Add the second filter. It should send a message because notifications are
// suppressed.
EXPECT_CALL(*filter1, Send(testing::_)).Times(0);
EXPECT_CALL(*filter2, Send(IsSetSuppressedMessage(true))).Times(1);
filter2->Add();
+ testing::Mock::VerifyAndClearExpectations(this);
+
+ // Send a memory pressure event to the first child process. No messages should
+ // be sent as the notifications are suppressed.
+ EXPECT_CALL(*filter1, Send(testing::_)).Times(0);
+ EXPECT_CALL(*filter2, Send(testing::_)).Times(0);
+ SendPressureNotificationAndWait(filter1.get(),
+ MEMORY_PRESSURE_LEVEL_MODERATE);
+ testing::Mock::VerifyAndClearExpectations(this);
// Disable suppressing memory pressure notifications in all processes. Both
// filters should send a message.
@@ -128,11 +169,30 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
EXPECT_CALL(*filter2, Send(IsSetSuppressedMessage(false))).Times(1);
SetPressureNotificationsSuppressedInAllProcessesAndWait(false);
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
+ testing::Mock::VerifyAndClearExpectations(this);
+
+ // Send a memory pressure event to the first child process. A message should
+ // be received as messages are not being suppressed.
+ EXPECT_CALL(*filter1, Send(IsPressureMessage(MEMORY_PRESSURE_LEVEL_MODERATE)))
+ .Times(1);
+ EXPECT_CALL(*filter2, Send(testing::_)).Times(0);
+ SendPressureNotificationAndWait(filter1.get(),
+ MEMORY_PRESSURE_LEVEL_MODERATE);
+ testing::Mock::VerifyAndClearExpectations(this);
+
+ // Send a memory pressure event to a non-existing child process. No message
+ // should be sent.
+ EXPECT_CALL(*filter1, Send(testing::_)).Times(0);
+ EXPECT_CALL(*filter2, Send(testing::_)).Times(0);
+ SendPressureNotificationAndWait(reinterpret_cast<const void*>(0xF005BA11),
+ MEMORY_PRESSURE_LEVEL_MODERATE);
+ testing::Mock::VerifyAndClearExpectations(this);
// Remove the first filter. No messages should be sent.
EXPECT_CALL(*filter1, Send(testing::_)).Times(0);
EXPECT_CALL(*filter2, Send(testing::_)).Times(0);
filter1->Remove();
+ testing::Mock::VerifyAndClearExpectations(this);
// Enable suppressing memory pressure notifications in all processes. The
// second filter should send a message.
@@ -140,6 +200,7 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
EXPECT_CALL(*filter2, Send(IsSetSuppressedMessage(true))).Times(1);
SetPressureNotificationsSuppressedInAllProcessesAndWait(true);
EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed());
+ testing::Mock::VerifyAndClearExpectations(this);
// Remove the second filter and disable suppressing memory pressure
// notifications in all processes. No messages should be sent.
@@ -148,15 +209,11 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
filter2->Remove();
SetPressureNotificationsSuppressedInAllProcessesAndWait(false);
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
+ testing::Mock::VerifyAndClearExpectations(this);
}
IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
SimulatePressureNotificationInAllProcesses) {
- const auto MEMORY_PRESSURE_LEVEL_MODERATE =
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
- const auto MEMORY_PRESSURE_LEVEL_CRITICAL =
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
-
scoped_refptr<MemoryMessageFilterForTesting> filter(
new MemoryMessageFilterForTesting);
scoped_ptr<base::MemoryPressureListener> listener(
@@ -168,17 +225,26 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
filter->Add();
+ // Send a memory pressure event to the first child process. It should send a
+ // pressure notification message.
+ EXPECT_CALL(*filter, Send(IsPressureMessage(MEMORY_PRESSURE_LEVEL_MODERATE)))
+ .Times(1);
+ SendPressureNotificationAndWait(filter.get(), MEMORY_PRESSURE_LEVEL_MODERATE);
+ testing::Mock::VerifyAndClearExpectations(this);
+
EXPECT_CALL(*filter, Send(IsSimulateMessage(MEMORY_PRESSURE_LEVEL_CRITICAL)))
.Times(1);
EXPECT_CALL(*this, OnMemoryPressure(MEMORY_PRESSURE_LEVEL_CRITICAL)).Times(1);
SimulatePressureNotificationInAllProcessesAndWait(
MEMORY_PRESSURE_LEVEL_CRITICAL);
RunAllPendingInMessageLoop(); // Wait for the listener to run.
+ testing::Mock::VerifyAndClearExpectations(this);
// Enable suppressing memory pressure notifications in all processes. This
// should have no impact on simulating memory pressure notifications.
EXPECT_CALL(*filter, Send(IsSetSuppressedMessage(true))).Times(1);
SetPressureNotificationsSuppressedInAllProcessesAndWait(true);
+ testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*filter, Send(IsSimulateMessage(MEMORY_PRESSURE_LEVEL_MODERATE)))
.Times(1);
@@ -186,11 +252,13 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
SimulatePressureNotificationInAllProcessesAndWait(
MEMORY_PRESSURE_LEVEL_MODERATE);
RunAllPendingInMessageLoop(); // Wait for the listener to run.
+ testing::Mock::VerifyAndClearExpectations(this);
// Disable suppressing memory pressure notifications in all processes. This
// should have no impact on simulating memory pressure notifications.
EXPECT_CALL(*filter, Send(IsSetSuppressedMessage(false))).Times(1);
SetPressureNotificationsSuppressedInAllProcessesAndWait(false);
+ testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*filter, Send(IsSimulateMessage(MEMORY_PRESSURE_LEVEL_MODERATE)))
.Times(1);
@@ -198,6 +266,7 @@ IN_PROC_BROWSER_TEST_F(MemoryPressureControllerBrowserTest,
SimulatePressureNotificationInAllProcessesAndWait(
MEMORY_PRESSURE_LEVEL_MODERATE);
RunAllPendingInMessageLoop(); // Wait for the listener to run.
+ testing::Mock::VerifyAndClearExpectations(this);
filter->Remove();
}
diff --git a/chromium/content/browser/message_port_message_filter.cc b/chromium/content/browser/message_port_message_filter.cc
index 5ff0319d6ea..a0949fa26c1 100644
--- a/chromium/content/browser/message_port_message_filter.cc
+++ b/chromium/content/browser/message_port_message_filter.cc
@@ -4,6 +4,8 @@
#include "content/browser/message_port_message_filter.h"
+#include <stddef.h>
+
#include "content/browser/message_port_service.h"
#include "content/common/frame_messages.h"
#include "content/common/message_port_messages.h"
diff --git a/chromium/content/browser/message_port_message_filter.h b/chromium/content/browser/message_port_message_filter.h
index be6bfde7095..14a5cf7d806 100644
--- a/chromium/content/browser/message_port_message_filter.h
+++ b/chromium/content/browser/message_port_message_filter.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_MESSAGE_PORT_MESSAGE_FILTER_H_
#include "base/callback.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/message_port_delegate.h"
diff --git a/chromium/content/browser/message_port_provider.cc b/chromium/content/browser/message_port_provider.cc
index 989925b7855..ec465f382ed 100644
--- a/chromium/content/browser/message_port_provider.cc
+++ b/chromium/content/browser/message_port_provider.cc
@@ -4,7 +4,6 @@
#include "content/public/browser/message_port_provider.h"
-#include "base/basictypes.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/message_port_message_filter.h"
#include "content/browser/message_port_service.h"
diff --git a/chromium/content/browser/message_port_provider_browsertest.cc b/chromium/content/browser/message_port_provider_browsertest.cc
index 425e08fa954..010600300da 100644
--- a/chromium/content/browser/message_port_provider_browsertest.cc
+++ b/chromium/content/browser/message_port_provider_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/bind.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "content/browser/message_port_service.h"
diff --git a/chromium/content/browser/message_port_service.cc b/chromium/content/browser/message_port_service.cc
index d5e5b23f3a3..21fc76d40bc 100644
--- a/chromium/content/browser/message_port_service.cc
+++ b/chromium/content/browser/message_port_service.cc
@@ -4,6 +4,8 @@
#include "content/browser/message_port_service.h"
+#include <stddef.h>
+
#include "content/common/message_port_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/message_port_delegate.h"
diff --git a/chromium/content/browser/message_port_service.h b/chromium/content/browser/message_port_service.h
index 1c9a6a116c3..c3aeadb50a3 100644
--- a/chromium/content/browser/message_port_service.h
+++ b/chromium/content/browser/message_port_service.h
@@ -9,7 +9,7 @@
#include <utility>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/string16.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/mime_registry_message_filter.cc b/chromium/content/browser/mime_registry_message_filter.cc
index 0a823af2a9f..1b6987e7876 100644
--- a/chromium/content/browser/mime_registry_message_filter.cc
+++ b/chromium/content/browser/mime_registry_message_filter.cc
@@ -28,8 +28,6 @@ bool MimeRegistryMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(MimeRegistryMessageFilter, message)
IPC_MESSAGE_HANDLER(MimeRegistryMsg_GetMimeTypeFromExtension,
OnGetMimeTypeFromExtension)
- IPC_MESSAGE_HANDLER(MimeRegistryMsg_GetMimeTypeFromFile,
- OnGetMimeTypeFromFile)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -40,9 +38,4 @@ void MimeRegistryMessageFilter::OnGetMimeTypeFromExtension(
net::GetMimeTypeFromExtension(ext, mime_type);
}
-void MimeRegistryMessageFilter::OnGetMimeTypeFromFile(
- const base::FilePath& file_path, std::string* mime_type) {
- net::GetMimeTypeFromFile(file_path, mime_type);
-}
-
} // namespace content
diff --git a/chromium/content/browser/mojo/OWNERS b/chromium/content/browser/mojo/OWNERS
new file mode 100644
index 00000000000..570120fdbb9
--- /dev/null
+++ b/chromium/content/browser/mojo/OWNERS
@@ -0,0 +1,13 @@
+# Changes to the renderer capability filter require a security review to avoid
+# exposing new sandbox escapes and undesirable services.
+per-file renderer_capability_filter.cc=set noparent
+per-file renderer_capability_filter.cc=dcheng@chromium.org
+per-file renderer_capability_filter.cc=inferno@chromium.org
+per-file renderer_capability_filter.cc=jln@chromium.org
+per-file renderer_capability_filter.cc=jschuh@chromium.org
+per-file renderer_capability_filter.cc=kenrb@chromium.org
+per-file renderer_capability_filter.cc=mkwst@chromium.org
+per-file renderer_capability_filter.cc=nasko@chromium.org
+per-file renderer_capability_filter.cc=palmer@chromium.org
+per-file renderer_capability_filter.cc=tsepez@chromium.org
+per-file renderer_capability_filter.cc=wfh@chromium.org
diff --git a/chromium/content/browser/mojo/mojo_app_connection_impl.cc b/chromium/content/browser/mojo/mojo_app_connection_impl.cc
index ca8d5a5f824..2f55450eb12 100644
--- a/chromium/content/browser/mojo/mojo_app_connection_impl.cc
+++ b/chromium/content/browser/mojo/mojo_app_connection_impl.cc
@@ -4,6 +4,9 @@
#include "content/browser/mojo/mojo_app_connection_impl.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "content/browser/mojo/mojo_shell_context.h"
#include "mojo/shell/capability_filter.h"
@@ -38,7 +41,7 @@ MojoAppConnectionImpl::~MojoAppConnectionImpl() {
void MojoAppConnectionImpl::ConnectToService(
const std::string& service_name,
mojo::ScopedMessagePipeHandle handle) {
- services_->ConnectToService(service_name, handle.Pass());
+ services_->ConnectToService(service_name, std::move(handle));
}
} // namespace content
diff --git a/chromium/content/browser/mojo/mojo_app_connection_impl.h b/chromium/content/browser/mojo/mojo_app_connection_impl.h
index 6fc4ea39c56..3cdfc591818 100644
--- a/chromium/content/browser/mojo/mojo_app_connection_impl.h
+++ b/chromium/content/browser/mojo/mojo_app_connection_impl.h
@@ -7,7 +7,7 @@
#include "base/macros.h"
#include "content/public/browser/mojo_app_connection.h"
-#include "mojo/application/public/interfaces/service_provider.mojom.h"
+#include "mojo/shell/public/interfaces/service_provider.mojom.h"
class GURL;
diff --git a/chromium/content/browser/mojo/mojo_application_host.cc b/chromium/content/browser/mojo/mojo_application_host.cc
index b1a9382f9ad..12895d5c353 100644
--- a/chromium/content/browser/mojo/mojo_application_host.cc
+++ b/chromium/content/browser/mojo/mojo_application_host.cc
@@ -4,6 +4,9 @@
#include "content/browser/mojo/mojo_application_host.h"
+#include <utility>
+
+#include "build/build_config.h"
#include "content/common/mojo/mojo_messages.h"
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_sender.h"
@@ -25,9 +28,8 @@ class ApplicationSetupImpl : public ApplicationSetup {
public:
ApplicationSetupImpl(ServiceRegistryImpl* service_registry,
mojo::InterfaceRequest<ApplicationSetup> request)
- : binding_(this, request.Pass()),
- service_registry_(service_registry) {
- }
+ : binding_(this, std::move(request)),
+ service_registry_(service_registry) {}
~ApplicationSetupImpl() override {
}
@@ -37,8 +39,8 @@ class ApplicationSetupImpl : public ApplicationSetup {
void ExchangeServiceProviders(
mojo::InterfaceRequest<mojo::ServiceProvider> services,
mojo::ServiceProviderPtr exposed_services) override {
- service_registry_->Bind(services.Pass());
- service_registry_->BindRemoteServiceProvider(exposed_services.Pass());
+ service_registry_->Bind(std::move(services));
+ service_registry_->BindRemoteServiceProvider(std::move(exposed_services));
}
mojo::Binding<ApplicationSetup> binding_;
@@ -83,7 +85,7 @@ bool MojoApplicationHost::Init() {
application_setup_.reset(new ApplicationSetupImpl(
&service_registry_,
- mojo::MakeRequest<ApplicationSetup>(message_pipe.Pass())));
+ mojo::MakeRequest<ApplicationSetup>(std::move(message_pipe))));
return true;
}
@@ -93,7 +95,7 @@ void MojoApplicationHost::Activate(IPC::Sender* sender,
DCHECK(client_handle_.is_valid());
base::PlatformFile client_file =
- PlatformFileFromScopedPlatformHandle(client_handle_.Pass());
+ PlatformFileFromScopedPlatformHandle(std::move(client_handle_));
did_activate_ = sender->Send(new MojoMsg_Activate(
IPC::GetFileHandleForProcess(client_file, process_handle, true)));
}
@@ -102,11 +104,6 @@ void MojoApplicationHost::WillDestroySoon() {
channel_init_.WillDestroySoon();
}
-void MojoApplicationHost::ShutdownOnIOThread() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- channel_init_.ShutdownOnIOThread();
-}
-
void MojoApplicationHost::OverrideIOTaskRunnerForTest(
scoped_refptr<base::TaskRunner> io_task_runner) {
io_task_runner_override_ = io_task_runner;
diff --git a/chromium/content/browser/mojo/mojo_application_host.h b/chromium/content/browser/mojo/mojo_application_host.h
index fffb59e05c6..0ed8ec917ba 100644
--- a/chromium/content/browser/mojo/mojo_application_host.h
+++ b/chromium/content/browser/mojo/mojo_application_host.h
@@ -5,8 +5,10 @@
#ifndef CONTENT_BROWSER_MOJO_MOJO_APPLICATION_HOST_H_
#define CONTENT_BROWSER_MOJO_MOJO_APPLICATION_HOST_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process_handle.h"
+#include "build/build_config.h"
#include "content/common/application_setup.mojom.h"
#include "content/common/mojo/channel_init.h"
#include "content/common/mojo/service_registry_impl.h"
@@ -40,9 +42,6 @@ class CONTENT_EXPORT MojoApplicationHost {
void WillDestroySoon();
- // Shuts down the Mojo channel. Must be called from the IO thread.
- void ShutdownOnIOThread();
-
ServiceRegistry* service_registry() { return &service_registry_; }
#if defined(OS_ANDROID)
diff --git a/chromium/content/browser/mojo/mojo_shell_client_host.cc b/chromium/content/browser/mojo/mojo_shell_client_host.cc
new file mode 100644
index 00000000000..326afebb051
--- /dev/null
+++ b/chromium/content/browser/mojo/mojo_shell_client_host.cc
@@ -0,0 +1,219 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/mojo/mojo_shell_client_host.h"
+
+#include <stdint.h>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/strings/stringprintf.h"
+#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "content/common/mojo/mojo_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_process_host_observer.h"
+#include "content/public/common/mojo_shell_connection.h"
+#include "ipc/ipc_sender.h"
+#include "mojo/converters/network/network_type_converters.h"
+#include "mojo/shell/public/cpp/application_impl.h"
+#include "mojo/shell/public/interfaces/application_manager.mojom.h"
+#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
+#include "third_party/mojo/src/mojo/edk/embedder/platform_channel_pair.h"
+#include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h"
+
+namespace content {
+namespace {
+
+const char kMojoShellInstanceURL[] = "mojo_shell_instance_url";
+const char kMojoPlatformFile[] = "mojo_platform_file";
+
+void DidCreateChannel(mojo::embedder::ChannelInfo* info) {}
+
+base::PlatformFile PlatformFileFromScopedPlatformHandle(
+ mojo::embedder::ScopedPlatformHandle handle) {
+#if defined(OS_POSIX)
+ return handle.release().fd;
+#elif defined(OS_WIN)
+ return handle.release().handle;
+#endif
+}
+
+class InstanceURL : public base::SupportsUserData::Data {
+ public:
+ InstanceURL(const std::string& instance_url) : instance_url_(instance_url) {}
+ ~InstanceURL() override {}
+
+ std::string get() const { return instance_url_; }
+
+ private:
+ std::string instance_url_;
+
+ DISALLOW_COPY_AND_ASSIGN(InstanceURL);
+};
+
+class InstanceShellHandle : public base::SupportsUserData::Data {
+ public:
+ InstanceShellHandle(base::PlatformFile shell_handle)
+ : shell_handle_(shell_handle) {}
+ ~InstanceShellHandle() override {}
+
+ base::PlatformFile get() const { return shell_handle_; }
+
+ private:
+ base::PlatformFile shell_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(InstanceShellHandle);
+};
+
+void SetMojoApplicationInstanceURL(RenderProcessHost* render_process_host,
+ const std::string& instance_url) {
+ render_process_host->SetUserData(kMojoShellInstanceURL,
+ new InstanceURL(instance_url));
+}
+
+void SetMojoPlatformFile(RenderProcessHost* render_process_host,
+ base::PlatformFile platform_file) {
+ render_process_host->SetUserData(kMojoPlatformFile,
+ new InstanceShellHandle(platform_file));
+}
+
+void CallRegisterProcessWithBroker(base::ProcessId pid,
+ MojoHandle client_pipe) {
+ mojo::shell::mojom::ApplicationManagerPtr application_manager;
+ MojoShellConnection::Get()->GetApplication()->ConnectToService(
+ "mojo:shell", &application_manager);
+ application_manager->RegisterProcessWithBroker(
+ static_cast<uint32_t>(pid),
+ mojo::ScopedHandle(mojo::Handle(client_pipe)));
+}
+
+class PIDSender : public RenderProcessHostObserver {
+ public:
+ PIDSender(
+ RenderProcessHost* host,
+ mojo::shell::mojom::PIDReceiverPtr pid_receiver)
+ : host_(host),
+ pid_receiver_(std::move(pid_receiver)) {
+ pid_receiver_.set_connection_error_handler([this]() { delete this; });
+ DCHECK(!host_->IsReady());
+ host_->AddObserver(this);
+ }
+ ~PIDSender() override {
+ if (host_)
+ host_->RemoveObserver(this);
+ }
+
+ private:
+ // Overridden from RenderProcessHostObserver:
+ void RenderProcessReady(RenderProcessHost* host) override {
+ pid_receiver_->SetPID(base::GetProcId(host->GetHandle()));
+ delete this;
+ }
+
+ void RenderProcessHostDestroyed(RenderProcessHost* host) override {
+ DCHECK_EQ(host_, host);
+ host_ = nullptr;
+ }
+
+ RenderProcessHost* host_;
+ mojo::shell::mojom::PIDReceiverPtr pid_receiver_;
+
+ DISALLOW_COPY_AND_ASSIGN(PIDSender);
+};
+
+} // namespace
+
+void RegisterChildWithExternalShell(int child_process_id,
+ RenderProcessHost* render_process_host) {
+ // Some process types get created before the main message loop.
+ if (!MojoShellConnection::Get())
+ return;
+
+ // Create the channel to be shared with the target process.
+ mojo::embedder::HandlePassingInformation handle_passing_info;
+ mojo::embedder::PlatformChannelPair platform_channel_pair;
+
+ // Give one end to the shell so that it can create an instance.
+ mojo::embedder::ScopedPlatformHandle platform_channel =
+ platform_channel_pair.PassServerHandle();
+ mojo::ScopedMessagePipeHandle handle(mojo::embedder::CreateChannel(
+ std::move(platform_channel), base::Bind(&DidCreateChannel),
+ base::ThreadTaskRunnerHandle::Get()));
+ mojo::shell::mojom::ApplicationManagerPtr application_manager;
+ MojoShellConnection::Get()->GetApplication()->ConnectToService(
+ "mojo:shell", &application_manager);
+ // The content of the URL/qualifier we pass is actually meaningless, it's only
+ // important that they're unique per process.
+ // TODO(beng): We need to specify a restrictive CapabilityFilter here that
+ // matches the needs of the target process. Figure out where that
+ // specification is best determined (not here, this is a common
+ // chokepoint for all process types) and how to wire it through.
+ // http://crbug.com/555393
+ std::string url =
+ base::StringPrintf("exe:chrome_renderer%d", child_process_id);
+
+ mojo::shell::mojom::PIDReceiverPtr pid_receiver;
+ mojo::InterfaceRequest<mojo::shell::mojom::PIDReceiver> request =
+ GetProxy(&pid_receiver);
+ new PIDSender(render_process_host, std::move(pid_receiver));
+
+ application_manager->CreateInstanceForHandle(
+ mojo::ScopedHandle(mojo::Handle(handle.release().value())),
+ url,
+ CreateCapabilityFilterForRenderer(),
+ std::move(request));
+
+ // Send the other end to the child via Chrome IPC.
+ base::PlatformFile client_file = PlatformFileFromScopedPlatformHandle(
+ platform_channel_pair.PassClientHandle());
+ SetMojoPlatformFile(render_process_host, client_file);
+
+ // Store the URL on the RPH so client code can access it later via
+ // GetMojoApplicationInstanceURL().
+ SetMojoApplicationInstanceURL(render_process_host, url);
+}
+
+std::string GetMojoApplicationInstanceURL(
+ RenderProcessHost* render_process_host) {
+ InstanceURL* instance_url = static_cast<InstanceURL*>(
+ render_process_host->GetUserData(kMojoShellInstanceURL));
+ return instance_url ? instance_url->get() : std::string();
+}
+
+void SendExternalMojoShellHandleToChild(
+ base::ProcessHandle process_handle,
+ RenderProcessHost* render_process_host) {
+ InstanceShellHandle* client_file = static_cast<InstanceShellHandle*>(
+ render_process_host->GetUserData(kMojoPlatformFile));
+ if (!client_file)
+ return;
+ render_process_host->Send(new MojoMsg_BindExternalMojoShellHandle(
+ IPC::GetFileHandleForProcess(client_file->get(), process_handle, true)));
+}
+
+mojo::embedder::ScopedPlatformHandle RegisterProcessWithBroker(
+ base::ProcessId pid) {
+ mojo::embedder::PlatformChannelPair platform_channel_pair;
+
+ MojoHandle platform_handle_wrapper;
+ MojoResult rv = mojo::embedder::CreatePlatformHandleWrapper(
+ platform_channel_pair.PassServerHandle(), &platform_handle_wrapper);
+ CHECK_EQ(rv, MOJO_RESULT_OK);
+
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ CallRegisterProcessWithBroker(pid, platform_handle_wrapper);
+ } else {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(CallRegisterProcessWithBroker, pid,
+ platform_handle_wrapper));
+ }
+
+ return platform_channel_pair.PassClientHandle();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/mojo/mojo_shell_client_host.h b/chromium/content/browser/mojo/mojo_shell_client_host.h
new file mode 100644
index 00000000000..5624643a8e7
--- /dev/null
+++ b/chromium/content/browser/mojo/mojo_shell_client_host.h
@@ -0,0 +1,48 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MOJO_MOJO_SHELL_CLIENT_HOST_H_
+#define CONTENT_BROWSER_MOJO_MOJO_SHELL_CLIENT_HOST_H_
+
+#include <string>
+
+#include "base/process/process_handle.h"
+#include "mojo/shell/public/interfaces/shell.mojom.h"
+#include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h"
+
+namespace content {
+
+class RenderProcessHost;
+
+// Creates a communication channel between the external Mojo shell and the
+// child. The server handle of this channel is shared with the external shell
+// via Mojo IPC. |child_process_id| is used to uniquify the child in the
+// external shell's instance map.
+void RegisterChildWithExternalShell(int child_process_id,
+ RenderProcessHost* render_process_host);
+
+// Returns the URL associated with an instance corresponding to the renderer
+// process in the external shell. This URL can be passed to
+// ConnectToApplication() to open a new connection to this renderer.
+std::string GetMojoApplicationInstanceURL(
+ RenderProcessHost* render_process_host);
+
+// Shares a client handle to the Mojo Shell with the child via Chrome IPC.
+void SendExternalMojoShellHandleToChild(base::ProcessHandle process_handle,
+ RenderProcessHost* render_process_host);
+
+// Constructs a Capability Filter for the renderer's application instance in the
+// external shell. This contains the restrictions imposed on what applications
+// and interfaces the renderer can see. The implementation lives in
+// renderer_capability_filter.cc so that it can be subject to specific security
+// review.
+mojo::CapabilityFilterPtr CreateCapabilityFilterForRenderer();
+
+// Used for the broker in the new EDK.
+mojo::embedder::ScopedPlatformHandle RegisterProcessWithBroker(
+ base::ProcessId pid);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MOJO_MOJO_SHELL_CLIENT_HOST_H_
diff --git a/chromium/content/browser/mojo/mojo_shell_context.cc b/chromium/content/browser/mojo/mojo_shell_context.cc
index db77c35f4e5..199744d3cb6 100644
--- a/chromium/content/browser/mojo/mojo_shell_context.cc
+++ b/chromium/content/browser/mojo/mojo_shell_context.cc
@@ -4,11 +4,15 @@
#include "content/browser/mojo/mojo_shell_context.h"
+#include <utility>
+
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/common/process_control.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
@@ -16,17 +20,18 @@
#include "content/public/browser/utility_process_host_client.h"
#include "content/public/common/content_client.h"
#include "content/public/common/service_registry.h"
-#include "mojo/application/public/cpp/application_delegate.h"
#include "mojo/common/url_type_converters.h"
-#include "mojo/package_manager/package_manager_impl.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/string.h"
#include "mojo/shell/application_loader.h"
#include "mojo/shell/connect_to_application_params.h"
#include "mojo/shell/identity.h"
+#include "mojo/shell/package_manager/package_manager_impl.h"
+#include "mojo/shell/public/cpp/application_delegate.h"
#include "mojo/shell/static_application_loader.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/string.h"
-#if defined(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
+#if defined(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) || \
+ defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
#include "media/mojo/services/mojo_media_application.h"
#endif
@@ -37,9 +42,10 @@ namespace {
// An extra set of apps to register on initialization, if set by a test.
const MojoShellContext::StaticApplicationMap* g_applications_for_test;
-void StartProcessOnIOThread(mojo::InterfaceRequest<ProcessControl> request,
- const base::string16& process_name,
- bool use_sandbox) {
+void StartUtilityProcessOnIOThread(
+ mojo::InterfaceRequest<ProcessControl> request,
+ const base::string16& process_name,
+ bool use_sandbox) {
UtilityProcessHost* process_host =
UtilityProcessHost::Create(nullptr, nullptr);
process_host->SetName(process_name);
@@ -48,7 +54,7 @@ void StartProcessOnIOThread(mojo::InterfaceRequest<ProcessControl> request,
process_host->StartMojoMode();
ServiceRegistry* services = process_host->GetServiceRegistry();
- services->ConnectToRemoteService(request.Pass());
+ services->ConnectToRemoteService(std::move(request));
}
void OnApplicationLoaded(const GURL& url, bool success) {
@@ -88,11 +94,11 @@ class UtilityProcessLoader : public mojo::shell::ApplicationLoader {
mojo::InterfaceRequest<mojo::Application> application_request) override {
ProcessControlPtr process_control;
auto process_request = mojo::GetProxy(&process_control);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&StartProcessOnIOThread, base::Passed(&process_request),
- process_name_, use_sandbox_));
- process_control->LoadApplication(url.spec(), application_request.Pass(),
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&StartUtilityProcessOnIOThread,
+ base::Passed(&process_request),
+ process_name_, use_sandbox_));
+ process_control->LoadApplication(url.spec(), std::move(application_request),
base::Bind(&OnApplicationLoaded, url));
}
@@ -102,6 +108,47 @@ class UtilityProcessLoader : public mojo::shell::ApplicationLoader {
DISALLOW_COPY_AND_ASSIGN(UtilityProcessLoader);
};
+// Request ProcessControl from GPU process host. Must be called on IO thread.
+void RequestGpuProcessControl(mojo::InterfaceRequest<ProcessControl> request) {
+ BrowserChildProcessHostDelegate* process_host =
+ GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ CAUSE_FOR_GPU_LAUNCH_MOJO_SETUP);
+ if (!process_host) {
+ DLOG(ERROR) << "GPU process host not available.";
+ return;
+ }
+
+ // TODO(xhwang): It's possible that |process_host| is non-null, but the actual
+ // process is dead. In that case, |request| will be dropped and application
+ // load requests through ProcessControl will also fail. Make sure we handle
+ // these cases correctly.
+ process_host->GetServiceRegistry()->ConnectToRemoteService(
+ std::move(request));
+}
+
+// Forwards the load request to the GPU process.
+class GpuProcessLoader : public mojo::shell::ApplicationLoader {
+ public:
+ GpuProcessLoader() {}
+ ~GpuProcessLoader() override {}
+
+ private:
+ // mojo::shell::ApplicationLoader:
+ void Load(
+ const GURL& url,
+ mojo::InterfaceRequest<mojo::Application> application_request) override {
+ ProcessControlPtr process_control;
+ auto process_request = mojo::GetProxy(&process_control);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&RequestGpuProcessControl, base::Passed(&process_request)));
+ process_control->LoadApplication(url.spec(), std::move(application_request),
+ base::Bind(&OnApplicationLoaded, url));
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(GpuProcessLoader);
+};
+
} // namespace
// Thread-safe proxy providing access to the shell context from any thread.
@@ -123,8 +170,8 @@ class MojoShellContext::Proxy {
if (task_runner_ == base::ThreadTaskRunnerHandle::Get()) {
if (shell_context_) {
shell_context_->ConnectToApplicationOnOwnThread(
- url, requestor_url, request.Pass(), exposed_services.Pass(), filter,
- callback);
+ url, requestor_url, std::move(request), std::move(exposed_services),
+ filter, callback);
}
} else {
// |shell_context_| outlives the main MessageLoop, so it's safe for it to
@@ -159,10 +206,10 @@ MojoShellContext::MojoShellContext() {
// Construct with an empty filepath since mojo: urls can't be registered now
// the url scheme registry is locked.
- scoped_ptr<mojo::package_manager::PackageManagerImpl> package_manager(
- new mojo::package_manager::PackageManagerImpl(base::FilePath(), nullptr));
+ scoped_ptr<mojo::shell::PackageManagerImpl> package_manager(
+ new mojo::shell::PackageManagerImpl(base::FilePath(), nullptr));
application_manager_.reset(
- new mojo::shell::ApplicationManager(package_manager.Pass()));
+ new mojo::shell::ApplicationManager(std::move(package_manager)));
application_manager_->set_default_loader(
scoped_ptr<mojo::shell::ApplicationLoader>(new DefaultApplicationLoader));
@@ -209,7 +256,11 @@ MojoShellContext::MojoShellContext() {
scoped_ptr<mojo::shell::ApplicationLoader>(
new mojo::shell::StaticApplicationLoader(
base::Bind(&media::MojoMediaApplication::CreateApp))),
- media::MojoMediaApplication::AppUrl());
+ GURL("mojo:media"));
+#elif(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
+ application_manager_->SetLoaderForURL(
+ scoped_ptr<mojo::shell::ApplicationLoader>(new GpuProcessLoader()),
+ GURL("mojo:media"));
#endif
}
@@ -224,8 +275,9 @@ void MojoShellContext::ConnectToApplication(
mojo::ServiceProviderPtr exposed_services,
const mojo::shell::CapabilityFilter& filter,
const mojo::Shell::ConnectToApplicationCallback& callback) {
- proxy_.Get()->ConnectToApplication(url, requestor_url, request.Pass(),
- exposed_services.Pass(), filter, callback);
+ proxy_.Get()->ConnectToApplication(url, requestor_url, std::move(request),
+ std::move(exposed_services), filter,
+ callback);
}
void MojoShellContext::ConnectToApplicationOnOwnThread(
@@ -241,11 +293,11 @@ void MojoShellContext::ConnectToApplicationOnOwnThread(
mojo::shell::Identity(requestor_url, std::string(),
mojo::shell::GetPermissiveCapabilityFilter()));
params->SetTarget(mojo::shell::Identity(url, std::string(), filter));
- params->set_services(request.Pass());
- params->set_exposed_services(exposed_services.Pass());
+ params->set_services(std::move(request));
+ params->set_exposed_services(std::move(exposed_services));
params->set_on_application_end(base::Bind(&base::DoNothing));
params->set_connect_callback(callback);
- application_manager_->ConnectToApplication(params.Pass());
+ application_manager_->ConnectToApplication(std::move(params));
}
} // namespace content
diff --git a/chromium/content/browser/mojo/mojo_shell_context.h b/chromium/content/browser/mojo/mojo_shell_context.h
index b838781837b..e45ab88433f 100644
--- a/chromium/content/browser/mojo/mojo_shell_context.h
+++ b/chromium/content/browser/mojo/mojo_shell_context.h
@@ -13,8 +13,8 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
-#include "mojo/application/public/interfaces/shell.mojom.h"
#include "mojo/shell/application_manager.h"
+#include "mojo/shell/public/interfaces/shell.mojom.h"
class GURL;
diff --git a/chromium/content/browser/mojo/renderer_capability_filter.cc b/chromium/content/browser/mojo/renderer_capability_filter.cc
new file mode 100644
index 00000000000..01a8e626dd7
--- /dev/null
+++ b/chromium/content/browser/mojo/renderer_capability_filter.cc
@@ -0,0 +1,22 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <utility>
+
+#include "components/mus/public/interfaces/gpu.mojom.h"
+#include "content/browser/mojo/mojo_shell_client_host.h"
+
+namespace content {
+
+mojo::CapabilityFilterPtr CreateCapabilityFilterForRenderer() {
+ // See https://goo.gl/gkBtCR for a description of what this is and what to
+ // think about when changing it.
+ mojo::CapabilityFilterPtr filter(mojo::CapabilityFilter::New());
+ mojo::Array<mojo::String> window_manager_interfaces;
+ window_manager_interfaces.push_back(mus::mojom::Gpu::Name_);
+ filter->filter.insert("mojo:mus", std::move(window_manager_interfaces));
+ return filter;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/mojo/service_registrar_android.cc b/chromium/content/browser/mojo/service_registrar_android.cc
index 30ea7421019..e29d7f328c3 100644
--- a/chromium/content/browser/mojo/service_registrar_android.cc
+++ b/chromium/content/browser/mojo/service_registrar_android.cc
@@ -4,6 +4,7 @@
#include "content/browser/mojo/service_registrar_android.h"
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "content/browser/mojo/service_registry_android.h"
#include "jni/ServiceRegistrar_jni.h"
diff --git a/chromium/content/browser/mojo/service_registry_android.cc b/chromium/content/browser/mojo/service_registry_android.cc
index 269c8be61f4..0e80e0842b5 100644
--- a/chromium/content/browser/mojo/service_registry_android.cc
+++ b/chromium/content/browser/mojo/service_registry_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/mojo/service_registry_android.h"
+#include <utility>
+
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/callback.h"
@@ -55,11 +57,12 @@ ServiceRegistryAndroid::~ServiceRegistryAndroid() {
}
// Methods called from Java.
-void ServiceRegistryAndroid::AddService(JNIEnv* env,
- jobject j_service_registry,
- jobject j_manager,
- jobject j_factory,
- jstring j_name) {
+void ServiceRegistryAndroid::AddService(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& j_service_registry,
+ const JavaParamRef<jobject>& j_manager,
+ const JavaParamRef<jobject>& j_factory,
+ const JavaParamRef<jstring>& j_name) {
std::string name(ConvertJavaStringToUTF8(env, j_name));
ScopedJavaGlobalRef<jobject> j_scoped_service_registry;
@@ -78,20 +81,22 @@ void ServiceRegistryAndroid::AddService(JNIEnv* env,
j_scoped_factory));
}
-void ServiceRegistryAndroid::RemoveService(JNIEnv* env,
- jobject j_service_registry,
- jstring j_name) {
+void ServiceRegistryAndroid::RemoveService(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& j_service_registry,
+ const JavaParamRef<jstring>& j_name) {
std::string name(ConvertJavaStringToUTF8(env, j_name));
service_registry_->RemoveService(name);
}
-void ServiceRegistryAndroid::ConnectToRemoteService(JNIEnv* env,
- jobject j_service_registry,
- jstring j_name,
- jint j_handle) {
+void ServiceRegistryAndroid::ConnectToRemoteService(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& j_service_registry,
+ const JavaParamRef<jstring>& j_name,
+ jint j_handle) {
std::string name(ConvertJavaStringToUTF8(env, j_name));
mojo::ScopedMessagePipeHandle handle((mojo::MessagePipeHandle(j_handle)));
- service_registry_->ConnectToRemoteService(name, handle.Pass());
+ service_registry_->ConnectToRemoteService(name, std::move(handle));
}
} // namespace content
diff --git a/chromium/content/browser/mojo/service_registry_android.h b/chromium/content/browser/mojo/service_registry_android.h
index 37ec10a4be8..17d2cb07bdc 100644
--- a/chromium/content/browser/mojo/service_registry_android.h
+++ b/chromium/content/browser/mojo/service_registry_android.h
@@ -26,16 +26,21 @@ class CONTENT_EXPORT ServiceRegistryAndroid {
virtual ~ServiceRegistryAndroid();
// Methods called from Java.
- void AddService(JNIEnv* env,
- jobject j_service_registry,
- jobject j_manager,
- jobject j_factory,
- jstring j_name);
- void RemoveService(JNIEnv* env, jobject j_service_registry, jstring j_name);
- void ConnectToRemoteService(JNIEnv* env,
- jobject j_service_registry,
- jstring j_name,
- jint handle);
+ void AddService(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_service_registry,
+ const base::android::JavaParamRef<jobject>& j_manager,
+ const base::android::JavaParamRef<jobject>& j_factory,
+ const base::android::JavaParamRef<jstring>& j_name);
+ void RemoveService(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_service_registry,
+ const base::android::JavaParamRef<jstring>& j_name);
+ void ConnectToRemoteService(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_service_registry,
+ const base::android::JavaParamRef<jstring>& j_name,
+ jint handle);
const base::android::ScopedJavaGlobalRef<jobject>& GetObj() { return obj_; }
diff --git a/chromium/content/browser/navigator_connect/navigator_connect_context_impl.cc b/chromium/content/browser/navigator_connect/navigator_connect_context_impl.cc
index 553ba64785d..c393c4bf45a 100644
--- a/chromium/content/browser/navigator_connect/navigator_connect_context_impl.cc
+++ b/chromium/content/browser/navigator_connect/navigator_connect_context_impl.cc
@@ -4,6 +4,9 @@
#include "content/browser/navigator_connect/navigator_connect_context_impl.h"
+#include <stdint.h>
+
+#include "base/stl_util.h"
#include "content/browser/message_port_service.h"
#include "content/browser/navigator_connect/service_port_service_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -11,6 +14,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigator_connect_service_factory.h"
#include "content/public/common/navigator_connect_client.h"
+#include "mojo/common/url_type_converters.h"
namespace content {
@@ -30,7 +34,7 @@ struct NavigatorConnectContextImpl::Port {
// If this port is associated with a service worker, these fields store that
// information.
- int64 service_worker_registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t service_worker_registration_id = kInvalidServiceWorkerRegistrationId;
GURL service_worker_registration_origin;
};
@@ -80,7 +84,7 @@ void NavigatorConnectContextImpl::Connect(
service_port.client_origin = origin;
// Find the right service worker to service this connection.
- service_worker_context_->FindRegistrationForDocument(
+ service_worker_context_->FindReadyRegistrationForDocument(
target_url,
base::Bind(&NavigatorConnectContextImpl::GotServiceWorkerRegistration,
this, callback, client_port_id, service_port_id));
@@ -110,7 +114,7 @@ void NavigatorConnectContextImpl::PostMessage(
for (const auto& sent_port : sent_message_ports)
MessagePortService::GetInstance()->HoldMessages(sent_port.id);
- service_worker_context_->FindRegistrationForId(
+ service_worker_context_->FindReadyRegistrationForId(
port.service_worker_registration_id,
port.service_worker_registration_origin,
base::Bind(&NavigatorConnectContextImpl::DeliverMessage, this, port.id,
@@ -137,28 +141,49 @@ void NavigatorConnectContextImpl::GotServiceWorkerRegistration(
if (status != SERVICE_WORKER_OK) {
// No service worker found, reject connection attempt.
- OnConnectResult(callback, client_port_id, service_port_id, registration,
- status, false, base::string16(), base::string16());
+ OnConnectError(callback, client_port_id, service_port_id, status);
return;
}
ServiceWorkerVersion* active_version = registration->active_version();
- if (!active_version) {
- // No active version, reject connection attempt.
- OnConnectResult(callback, client_port_id, service_port_id, registration,
- status, false, base::string16(), base::string16());
- return;
- }
+ DCHECK(active_version);
Port& service_port = ports_[service_port_id];
service_port.service_worker_registration_id = registration->id();
service_port.service_worker_registration_origin =
registration->pattern().GetOrigin();
- active_version->DispatchServicePortConnectEvent(
+ active_version->RunAfterStartWorker(
+ base::Bind(&NavigatorConnectContextImpl::OnConnectError, this, callback,
+ client_port_id, service_port_id),
+ base::Bind(&NavigatorConnectContextImpl::DispatchConnectEvent, this,
+ callback, client_port_id, service_port_id, registration,
+ make_scoped_refptr(active_version)));
+}
+
+void NavigatorConnectContextImpl::DispatchConnectEvent(
+ const ConnectCallback& callback,
+ int client_port_id,
+ int service_port_id,
+ const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
+ const scoped_refptr<ServiceWorkerVersion>& worker) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(ContainsKey(ports_, client_port_id));
+ DCHECK(ContainsKey(ports_, service_port_id));
+
+ const Port& service_port = ports_[service_port_id];
+ int request_id = worker->StartRequest(
+ ServiceWorkerMetrics::EventType::SERVICE_PORT_CONNECT,
+ base::Bind(&NavigatorConnectContextImpl::OnConnectError, this, callback,
+ client_port_id, service_port_id));
+ base::WeakPtr<ServicePortDispatcher> dispatcher =
+ worker->GetMojoServiceForRequest<ServicePortDispatcher>(request_id);
+ dispatcher->Connect(
+ mojo::String::From(service_port.target_url),
+ mojo::String::From(service_port.client_origin), service_port_id,
base::Bind(&NavigatorConnectContextImpl::OnConnectResult, this, callback,
- client_port_id, service_port_id, registration),
- service_port.target_url, service_port.client_origin, service_port_id);
+ client_port_id, service_port_id, service_worker_registration,
+ worker, request_id));
}
void NavigatorConnectContextImpl::ServicePortServiceDestroyed(
@@ -174,26 +199,42 @@ void NavigatorConnectContextImpl::ServicePortServiceDestroyed(
}
}
+void NavigatorConnectContextImpl::OnConnectError(
+ const ConnectCallback& callback,
+ int client_port_id,
+ int service_port_id,
+ ServiceWorkerStatusCode status) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Destroy ports since connection failed.
+ ports_.erase(service_port_id);
+ ports_.erase(client_port_id);
+ callback.Run(MSG_ROUTING_NONE, false);
+}
+
void NavigatorConnectContextImpl::OnConnectResult(
const ConnectCallback& callback,
int client_port_id,
int service_port_id,
const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
- ServiceWorkerStatusCode status,
- bool accept_connection,
- const base::string16& name,
- const base::string16& data) {
+ const scoped_refptr<ServiceWorkerVersion>& worker,
+ int request_id,
+ ServicePortConnectResult result,
+ const mojo::String& name,
+ const mojo::String& data) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (accept_connection) {
- // TODO(mek): Might have to do something else if the client connection got
- // severed while the service side connection was being set up.
- callback.Run(client_port_id, true);
- } else {
- // Destroy ports since connection failed.
- ports_.erase(service_port_id);
- ports_.erase(client_port_id);
- callback.Run(MSG_ROUTING_NONE, false);
+
+ if (!worker->FinishRequest(request_id))
+ return;
+
+ if (result != SERVICE_PORT_CONNECT_RESULT_ACCEPT) {
+ OnConnectError(callback, client_port_id, service_port_id,
+ SERVICE_WORKER_ERROR_FAILED);
+ return;
}
+
+ // TODO(mek): Might have to do something else if the client connection got
+ // severed while the service side connection was being set up.
+ callback.Run(client_port_id, true);
}
void NavigatorConnectContextImpl::DeliverMessage(
@@ -213,10 +254,7 @@ void NavigatorConnectContextImpl::DeliverMessage(
ServiceWorkerVersion* active_version =
service_worker_registration->active_version();
- if (!active_version) {
- // TODO(mek): Do something when no active version exists.
- return;
- }
+ DCHECK(active_version);
const Port& port = ports_[port_id];
NavigatorConnectClient client(port.target_url, port.client_origin, port_id);
diff --git a/chromium/content/browser/navigator_connect/navigator_connect_context_impl.h b/chromium/content/browser/navigator_connect/navigator_connect_context_impl.h
index e57c2e804a7..5337a338203 100644
--- a/chromium/content/browser/navigator_connect/navigator_connect_context_impl.h
+++ b/chromium/content/browser/navigator_connect/navigator_connect_context_impl.h
@@ -9,6 +9,7 @@
#include "base/callback_forward.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/string16.h"
+#include "content/common/service_port_service.mojom.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/navigator_connect_context.h"
@@ -23,6 +24,7 @@ struct NavigatorConnectClient;
class ServicePortServiceImpl;
class ServiceWorkerContextWrapper;
class ServiceWorkerRegistration;
+class ServiceWorkerVersion;
struct TransferredMessagePort;
// Tracks all active navigator.services connections, as well as available
@@ -81,16 +83,30 @@ class NavigatorConnectContextImpl : public NavigatorConnectContext {
ServiceWorkerStatusCode status,
const scoped_refptr<ServiceWorkerRegistration>& registration);
- // Callback called by service factories when a connection succeeded or failed.
+ void DispatchConnectEvent(const ConnectCallback& callback,
+ int client_port_id,
+ int service_port_id,
+ const scoped_refptr<ServiceWorkerRegistration>&
+ service_worker_registration,
+ const scoped_refptr<ServiceWorkerVersion>& worker);
+
+ // Callback called when dispatching a connect event failed.
+ void OnConnectError(const ConnectCallback& calback,
+ int client_port_id,
+ int service_port_id,
+ ServiceWorkerStatusCode status);
+
+ // Callback called with the response to a connect event.
void OnConnectResult(const ConnectCallback& callback,
int client_port_id,
int service_port_id,
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration,
- ServiceWorkerStatusCode status,
- bool accept_connection,
- const base::string16& name,
- const base::string16& data);
+ const scoped_refptr<ServiceWorkerVersion>& worker,
+ int request_id,
+ ServicePortConnectResult result,
+ const mojo::String& name,
+ const mojo::String& data);
// Callback called when a ServiceWorkerRegistration has been located to
// deliver a message to.
diff --git a/chromium/content/browser/navigator_connect/service_port_service_impl.cc b/chromium/content/browser/navigator_connect/service_port_service_impl.cc
index c8847a7f5b4..310c304ab3e 100644
--- a/chromium/content/browser/navigator_connect/service_port_service_impl.cc
+++ b/chromium/content/browser/navigator_connect/service_port_service_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/navigator_connect/service_port_service_impl.h"
+#include <utility>
+
#include "content/browser/message_port_message_filter.h"
#include "content/browser/message_port_service.h"
#include "content/browser/navigator_connect/navigator_connect_context_impl.h"
@@ -52,7 +54,7 @@ void ServicePortServiceImpl::PostMessageToClient(
std::vector<int> new_routing_ids;
message_port_message_filter_->UpdateMessagePortsWithNewRoutes(
sent_message_ports, &new_routing_ids);
- client_->PostMessage(
+ client_->PostMessageToPort(
port_id, mojo::String::From(message.message_as_string),
mojo::Array<MojoTransferredMessagePortPtr>::From(sent_message_ports),
mojo::Array<int32_t>::From(new_routing_ids));
@@ -65,14 +67,14 @@ void ServicePortServiceImpl::CreateOnIOThread(
mojo::InterfaceRequest<ServicePortService> request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
new ServicePortServiceImpl(navigator_connect_context,
- message_port_message_filter, request.Pass());
+ message_port_message_filter, std::move(request));
}
ServicePortServiceImpl::ServicePortServiceImpl(
const scoped_refptr<NavigatorConnectContextImpl>& navigator_connect_context,
const scoped_refptr<MessagePortMessageFilter>& message_port_message_filter,
mojo::InterfaceRequest<ServicePortService> request)
- : binding_(this, request.Pass()),
+ : binding_(this, std::move(request)),
navigator_connect_context_(navigator_connect_context),
message_port_message_filter_(message_port_message_filter),
weak_ptr_factory_(this) {
@@ -82,7 +84,7 @@ ServicePortServiceImpl::ServicePortServiceImpl(
void ServicePortServiceImpl::SetClient(ServicePortServiceClientPtr client) {
DCHECK(!client_.get());
// TODO(mek): Set ErrorHandler to listen for errors.
- client_ = client.Pass();
+ client_ = std::move(client);
}
void ServicePortServiceImpl::Connect(const mojo::String& target_url,
@@ -94,7 +96,7 @@ void ServicePortServiceImpl::Connect(const mojo::String& target_url,
weak_ptr_factory_.GetWeakPtr(), callback));
}
-void ServicePortServiceImpl::PostMessage(
+void ServicePortServiceImpl::PostMessageToPort(
int32_t port_id,
const mojo::String& message,
mojo::Array<MojoTransferredMessagePortPtr> ports) {
diff --git a/chromium/content/browser/navigator_connect/service_port_service_impl.h b/chromium/content/browser/navigator_connect/service_port_service_impl.h
index c599b8690ed..be1815ed3ed 100644
--- a/chromium/content/browser/navigator_connect/service_port_service_impl.h
+++ b/chromium/content/browser/navigator_connect/service_port_service_impl.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_NAVIGATOR_CONNECT_SERVICE_PORT_SERVICE_IMPL_H_
#define CONTENT_BROWSER_NAVIGATOR_CONNECT_SERVICE_PORT_SERVICE_IMPL_H_
+#include <stdint.h>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/service_port_service.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
namespace content {
struct MessagePortMessage;
@@ -57,9 +59,10 @@ class ServicePortServiceImpl : public ServicePortService {
void Connect(const mojo::String& target_url,
const mojo::String& origin,
const ConnectCallback& callback) override;
- void PostMessage(int32_t port_id,
- const mojo::String& message,
- mojo::Array<MojoTransferredMessagePortPtr> ports) override;
+ void PostMessageToPort(
+ int32_t port_id,
+ const mojo::String& message,
+ mojo::Array<MojoTransferredMessagePortPtr> ports) override;
void ClosePort(int32_t port_id) override;
// Callback called when a connection to a service has been establised or
diff --git a/chromium/content/browser/net/browser_online_state_observer.cc b/chromium/content/browser/net/browser_online_state_observer.cc
index 23071d68161..9b457f9b75d 100644
--- a/chromium/content/browser/net/browser_online_state_observer.cc
+++ b/chromium/content/browser/net/browser_online_state_observer.cc
@@ -6,11 +6,15 @@
#include "content/common/view_messages.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
namespace content {
BrowserOnlineStateObserver::BrowserOnlineStateObserver() {
net::NetworkChangeNotifier::AddMaxBandwidthObserver(this);
+ registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+ content::NotificationService::AllSources());
}
BrowserOnlineStateObserver::~BrowserOnlineStateObserver() {
@@ -27,4 +31,20 @@ void BrowserOnlineStateObserver::OnMaxBandwidthChanged(
}
}
+void BrowserOnlineStateObserver::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
+
+ content::RenderProcessHost* rph =
+ content::Source<content::RenderProcessHost>(source).ptr();
+ double max_bandwidth_mbps;
+ net::NetworkChangeNotifier::ConnectionType connection_type;
+ net::NetworkChangeNotifier::GetMaxBandwidthAndConnectionType(
+ &max_bandwidth_mbps, &connection_type);
+ rph->Send(new ViewMsg_NetworkConnectionChanged(connection_type,
+ max_bandwidth_mbps));
+}
+
} // namespace content
diff --git a/chromium/content/browser/net/browser_online_state_observer.h b/chromium/content/browser/net/browser_online_state_observer.h
index b722effe73a..10eb28a53cc 100644
--- a/chromium/content/browser/net/browser_online_state_observer.h
+++ b/chromium/content/browser/net/browser_online_state_observer.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_NET_BROWSER_ONLINE_STATE_OBSERVER_H_
#define CONTENT_BROWSER_NET_BROWSER_ONLINE_STATE_OBSERVER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
#include "net/base/network_change_notifier.h"
namespace content {
@@ -13,17 +15,25 @@ namespace content {
// Listens for changes to the online state and manages sending
// updates to each RenderProcess via RenderProcessHost IPC.
class BrowserOnlineStateObserver
- : public net::NetworkChangeNotifier::MaxBandwidthObserver {
+ : public net::NetworkChangeNotifier::MaxBandwidthObserver,
+ public content::NotificationObserver {
public:
BrowserOnlineStateObserver();
~BrowserOnlineStateObserver() override;
- // MaxBandwidthObserver implementation.
+ // MaxBandwidthObserver implementation
void OnMaxBandwidthChanged(
double max_bandwidth_mbps,
net::NetworkChangeNotifier::ConnectionType type) override;
+ // NotificationObserver implementation
+ void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) override;
+
private:
+ content::NotificationRegistrar registrar_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserOnlineStateObserver);
};
diff --git a/chromium/content/browser/net/network_errors_listing_ui.cc b/chromium/content/browser/net/network_errors_listing_ui.cc
new file mode 100644
index 00000000000..cacb3d0e305
--- /dev/null
+++ b/chromium/content/browser/net/network_errors_listing_ui.cc
@@ -0,0 +1,94 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/net/network_errors_listing_ui.h"
+
+#include "base/bind.h"
+#include "base/json/json_writer.h"
+#include "base/values.h"
+#include "content/grit/content_resources.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/url_constants.h"
+#include "net/base/net_errors.h"
+#include "net/log/net_log_util.h"
+
+static const char kDataFile[] = "network-error-data.json";
+static const char kErrorCodeField[] = "errorCode";
+static const char kErrorCodesDataName[] = "errorCodes";
+static const char kErrorIdField[] = "errorId";
+static const char kNetworkErrorKey[] = "netError";
+
+namespace content {
+
+namespace {
+
+scoped_ptr<base::ListValue> GetNetworkErrorData() {
+ scoped_ptr<base::DictionaryValue> error_codes = net::GetNetConstants();
+ const base::DictionaryValue* net_error_codes_dict = nullptr;
+
+ for (base::DictionaryValue::Iterator itr(*error_codes); !itr.IsAtEnd();
+ itr.Advance()) {
+ if (itr.key() == kNetworkErrorKey) {
+ itr.value().GetAsDictionary(&net_error_codes_dict);
+ break;
+ }
+ }
+
+ scoped_ptr<base::ListValue> error_list(new base::ListValue());
+
+ for (base::DictionaryValue::Iterator itr(*net_error_codes_dict);
+ !itr.IsAtEnd(); itr.Advance()) {
+ int error_code;
+ itr.value().GetAsInteger(&error_code);
+ // Exclude the aborted and pending codes as these don't return a page.
+ if (error_code != net::Error::ERR_IO_PENDING &&
+ error_code != net::Error::ERR_ABORTED) {
+ base::DictionaryValue* error = new base::DictionaryValue();
+ error->SetInteger(kErrorIdField, error_code);
+ error->SetString(kErrorCodeField, itr.key());
+ error_list->Append(error);
+ }
+ }
+ return error_list;
+}
+
+bool HandleRequestCallback(BrowserContext* current_context,
+ const std::string& path,
+ const WebUIDataSource::GotDataCallback& callback) {
+ if (path != kDataFile)
+ return false;
+
+ base::DictionaryValue data;
+ data.Set(kErrorCodesDataName, GetNetworkErrorData().release());
+ std::string json_string;
+ base::JSONWriter::Write(data, &json_string);
+ callback.Run(base::RefCountedString::TakeString(&json_string));
+ return true;
+}
+
+} // namespace
+
+NetworkErrorsListingUI::NetworkErrorsListingUI(WebUI* web_ui)
+ : WebUIController(web_ui) {
+ // Set up the chrome://network-errors source.
+ WebUIDataSource* html_source =
+ WebUIDataSource::Create(kChromeUINetworkErrorsListingHost);
+
+ // Add required resources.
+ html_source->SetJsonPath("strings.js");
+ html_source->AddResourcePath("network_errors_listing.css",
+ IDR_NETWORK_ERROR_LISTING_CSS);
+ html_source->AddResourcePath("network_errors_listing.js",
+ IDR_NETWORK_ERROR_LISTING_JS);
+ html_source->SetDefaultResource(IDR_NETWORK_ERROR_LISTING_HTML);
+ html_source->SetRequestFilter(
+ base::Bind(&HandleRequestCallback,
+ web_ui->GetWebContents()->GetBrowserContext()));
+
+ BrowserContext* browser_context =
+ web_ui->GetWebContents()->GetBrowserContext();
+ WebUIDataSource::Add(browser_context, html_source);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/net/network_errors_listing_ui.h b/chromium/content/browser/net/network_errors_listing_ui.h
new file mode 100644
index 00000000000..d3022cdc890
--- /dev/null
+++ b/chromium/content/browser/net/network_errors_listing_ui.h
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_NET_NETWORK_ERRORS_LISTING_UI_H_
+#define CONTENT_BROWSER_NET_NETWORK_ERRORS_LISTING_UI_H_
+
+#include "base/macros.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+namespace content {
+
+class NetworkErrorsListingUI : public WebUIController {
+ public:
+ explicit NetworkErrorsListingUI(WebUI* web_ui);
+ ~NetworkErrorsListingUI() override {};
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkErrorsListingUI);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_NET_NETWORK_ERRORS_LISTING_UI_H_
diff --git a/chromium/content/browser/net/quota_policy_cookie_store.cc b/chromium/content/browser/net/quota_policy_cookie_store.cc
index 6c941312de7..9404981fb60 100644
--- a/chromium/content/browser/net/quota_policy_cookie_store.cc
+++ b/chromium/content/browser/net/quota_policy_cookie_store.cc
@@ -6,7 +6,6 @@
#include <list>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
@@ -155,7 +154,7 @@ net::CookieStore* CreateCookieStore(const CookieStoreConfig& config) {
if (!background_task_runner.get()) {
background_task_runner =
BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
- BrowserThread::GetBlockingPool()->GetSequenceToken());
+ base::SequencedWorkerPool::GetSequenceToken());
}
scoped_refptr<net::SQLitePersistentCookieStore> sqlite_store(
diff --git a/chromium/content/browser/net/quota_policy_cookie_store.h b/chromium/content/browser/net/quota_policy_cookie_store.h
index 4790cc81102..6aee20f97de 100644
--- a/chromium/content/browser/net/quota_policy_cookie_store.h
+++ b/chromium/content/browser/net/quota_policy_cookie_store.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_NET_QUOTA_POLICY_COOKIE_STORE_H_
#define CONTENT_BROWSER_NET_QUOTA_POLICY_COOKIE_STORE_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "net/cookies/cookie_monster.h"
diff --git a/chromium/content/browser/net/quota_policy_cookie_store_unittest.cc b/chromium/content/browser/net/quota_policy_cookie_store_unittest.cc
index f7987c55351..ca33d6ecbd3 100644
--- a/chromium/content/browser/net/quota_policy_cookie_store_unittest.cc
+++ b/chromium/content/browser/net/quota_policy_cookie_store_unittest.cc
@@ -109,7 +109,6 @@ class QuotaPolicyCookieStoreTest : public testing::Test {
// tasks that block pool shutdown (e.g. |store_|'s cleanup) have run before
// yielding control.
pool_owner_->pool()->FlushForTesting();
- pool_owner_->pool()->Shutdown();
pool_owner_.reset(new base::SequencedWorkerPoolOwner(3, "Background Pool"));
}
@@ -119,7 +118,6 @@ class QuotaPolicyCookieStoreTest : public testing::Test {
void TearDown() override {
DestroyStore();
- pool_owner_->pool()->Shutdown();
}
TestBrowserThreadBundle bundle_;
diff --git a/chromium/content/browser/net/view_http_cache_job_factory.cc b/chromium/content/browser/net/view_http_cache_job_factory.cc
index 6b46b618ea2..d08626f0525 100644
--- a/chromium/content/browser/net/view_http_cache_job_factory.cc
+++ b/chromium/content/browser/net/view_http_cache_job_factory.cc
@@ -4,12 +4,16 @@
#include "content/browser/net/view_http_cache_job_factory.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
@@ -44,8 +48,8 @@ class ViewHttpCacheJob : public net::URLRequestJob {
bool GetCharset(std::string* charset) override {
return core_->GetCharset(charset);
}
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override {
- return core_->ReadRawData(buf, buf_size, bytes_read);
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override {
+ return core_->ReadRawData(buf, buf_size);
}
private:
@@ -65,7 +69,7 @@ class ViewHttpCacheJob : public net::URLRequestJob {
bool GetMimeType(std::string* mime_type) const;
bool GetCharset(std::string* charset);
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read);
+ int ReadRawData(net::IOBuffer* buf, int buf_size);
private:
friend class base::RefCounted<Core>;
@@ -76,7 +80,7 @@ class ViewHttpCacheJob : public net::URLRequestJob {
void OnIOComplete(int result);
std::string data_;
- int data_offset_;
+ size_t data_offset_;
net::ViewCacheHelper cache_helper_;
net::CompletionCallback callback_;
base::Closure user_callback_;
@@ -164,17 +168,14 @@ bool ViewHttpCacheJob::Core::GetCharset(std::string* charset) {
return true;
}
-bool ViewHttpCacheJob::Core::ReadRawData(net::IOBuffer* buf,
- int buf_size,
- int* bytes_read) {
- DCHECK(bytes_read);
- int remaining = static_cast<int>(data_.size()) - data_offset_;
+int ViewHttpCacheJob::Core::ReadRawData(net::IOBuffer* buf, int buf_size) {
+ DCHECK_LE(data_offset_, data_.size());
+ int remaining = base::checked_cast<int>(data_.size() - data_offset_);
if (buf_size > remaining)
buf_size = remaining;
memcpy(buf->data(), data_.data() + data_offset_, buf_size);
data_offset_ += buf_size;
- *bytes_read = buf_size;
- return true;
+ return buf_size;
}
void ViewHttpCacheJob::Core::OnIOComplete(int result) {
diff --git a/chromium/content/browser/net_info_browsertest.cc b/chromium/content/browser/net_info_browsertest.cc
index 5701787b2b7..5a845561db2 100644
--- a/chromium/content/browser/net_info_browsertest.cc
+++ b/chromium/content/browser/net_info_browsertest.cc
@@ -5,6 +5,7 @@
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -76,6 +77,18 @@ class NetInfoBrowserTest : public content::ContentBrowserTest {
}
};
+// Make sure the type is correct when the page is first opened.
+IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, VerifyNetworkStateInitialized) {
+ SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET,
+ net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET);
+ NavigateToURL(shell(), content::GetTestUrl("", "net_info.html"));
+ EXPECT_TRUE(RunScriptExtractBool("getOnLine()"));
+ EXPECT_EQ("ethernet", RunScriptExtractString("getType()"));
+ EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype(
+ net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET),
+ RunScriptExtractDouble("getDownlinkMax()"));
+}
+
// Make sure that type changes in the browser make their way to
// navigator.connection.type.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkChangePlumbsToNavigator) {
@@ -110,4 +123,25 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, IsOnline) {
EXPECT_TRUE(RunScriptExtractBool("getOnLine()"));
}
+// Creating a new render view shouldn't reinitialize Blink's
+// NetworkStateNotifier. See https://crbug.com/535081.
+IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, TwoRenderViewsInOneProcess) {
+ SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET,
+ net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET);
+ NavigateToURL(shell(), content::GetTestUrl("", "net_info.html"));
+ EXPECT_TRUE(RunScriptExtractBool("getOnLine()"));
+
+ SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE,
+ net::NetworkChangeNotifier::SUBTYPE_NONE);
+ EXPECT_FALSE(RunScriptExtractBool("getOnLine()"));
+
+ // Open the same page in a new window on the same process.
+ EXPECT_TRUE(
+ ExecuteScript(shell()->web_contents(), "window.open(\"net_info.html\")"));
+
+ // The network state should not have reinitialized to what it was when opening
+ // the first window (online).
+ EXPECT_FALSE(RunScriptExtractBool("getOnLine()"));
+}
+
} // namespace content
diff --git a/chromium/content/browser/notification_service_impl.h b/chromium/content/browser/notification_service_impl.h
index 8a74c750144..bd04f74cbe0 100644
--- a/chromium/content/browser/notification_service_impl.h
+++ b/chromium/content/browser/notification_service_impl.h
@@ -7,6 +7,7 @@
#include <map>
+#include "base/macros.h"
#include "base/observer_list.h"
#include "content/common/content_export.h"
#include "content/public/browser/notification_service.h"
diff --git a/chromium/content/browser/notifications/PRESUBMIT.py b/chromium/content/browser/notifications/PRESUBMIT.py
new file mode 100644
index 00000000000..4fbc9a7f259
--- /dev/null
+++ b/chromium/content/browser/notifications/PRESUBMIT.py
@@ -0,0 +1,12 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Top-level presubmit script for notifications.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+def CheckChangeOnUpload(input_api, output_api):
+ return input_api.canned_checks.CheckPatchFormatted(input_api, output_api)
diff --git a/chromium/content/browser/notifications/notification_database.cc b/chromium/content/browser/notifications/notification_database.cc
index 9e64693b835..4d9f42e0e50 100644
--- a/chromium/content/browser/notifications/notification_database.cc
+++ b/chromium/content/browser/notifications/notification_database.cc
@@ -54,7 +54,12 @@ NotificationDatabase::Status LevelDBStatusToStatus(
return NotificationDatabase::STATUS_ERROR_NOT_FOUND;
else if (status.IsCorruption())
return NotificationDatabase::STATUS_ERROR_CORRUPTED;
+ else if (status.IsIOError())
+ return NotificationDatabase::STATUS_IO_ERROR;
+ else if (status.IsNotSupportedError())
+ return NotificationDatabase::STATUS_NOT_SUPPORTED;
+ // TODO(cmumford): Once leveldb 1.19 is released add IsInvalidArgument().
return NotificationDatabase::STATUS_ERROR_FAILED;
}
@@ -63,8 +68,7 @@ std::string CreateDataPrefix(const GURL& origin) {
if (!origin.is_valid())
return kDataKeyPrefix;
- return base::StringPrintf("%s%s%c",
- kDataKeyPrefix,
+ return base::StringPrintf("%s%s%c", kDataKeyPrefix,
storage::GetIdentifierFromOrigin(origin).c_str(),
kKeySeparator);
}
@@ -93,8 +97,7 @@ NotificationDatabase::Status DeserializedNotificationData(
} // namespace
NotificationDatabase::NotificationDatabase(const base::FilePath& path)
- : path_(path) {
-}
+ : path_(path) {}
NotificationDatabase::~NotificationDatabase() {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
@@ -106,8 +109,7 @@ NotificationDatabase::Status NotificationDatabase::Open(
DCHECK_EQ(STATE_UNINITIALIZED, state_);
if (!create_if_missing) {
- if (IsInMemoryDatabase() ||
- !base::PathExists(path_) ||
+ if (IsInMemoryDatabase() || !base::PathExists(path_) ||
base::IsDirectoryEmpty(path_)) {
return NotificationDatabase::STATUS_ERROR_NOT_FOUND;
}
@@ -159,8 +161,7 @@ NotificationDatabase::Status NotificationDatabase::ReadNotificationData(
notification_database_data);
}
-NotificationDatabase::Status
-NotificationDatabase::ReadAllNotificationData(
+NotificationDatabase::Status NotificationDatabase::ReadAllNotificationData(
std::vector<NotificationDatabaseData>* notification_data_vector) const {
return ReadAllNotificationDataInternal(GURL() /* origin */,
kInvalidServiceWorkerRegistrationId,
@@ -171,9 +172,8 @@ NotificationDatabase::Status
NotificationDatabase::ReadAllNotificationDataForOrigin(
const GURL& origin,
std::vector<NotificationDatabaseData>* notification_data_vector) const {
- return ReadAllNotificationDataInternal(origin,
- kInvalidServiceWorkerRegistrationId,
- notification_data_vector);
+ return ReadAllNotificationDataInternal(
+ origin, kInvalidServiceWorkerRegistrationId, notification_data_vector);
}
NotificationDatabase::Status
@@ -181,8 +181,7 @@ NotificationDatabase::ReadAllNotificationDataForServiceWorkerRegistration(
const GURL& origin,
int64_t service_worker_registration_id,
std::vector<NotificationDatabaseData>* notification_data_vector) const {
- return ReadAllNotificationDataInternal(origin,
- service_worker_registration_id,
+ return ReadAllNotificationDataInternal(origin, service_worker_registration_id,
notification_data_vector);
}
@@ -201,8 +200,7 @@ NotificationDatabase::Status NotificationDatabase::WriteNotificationData(
storage_data.notification_id = next_notification_id_;
std::string serialized_data;
- if (!SerializeNotificationDatabaseData(storage_data,
- &serialized_data)) {
+ if (!SerializeNotificationDatabaseData(storage_data, &serialized_data)) {
DLOG(ERROR) << "Unable to serialize data for a notification belonging "
<< "to: " << origin;
return STATUS_ERROR_FAILED;
@@ -213,8 +211,8 @@ NotificationDatabase::Status NotificationDatabase::WriteNotificationData(
batch.Put(kNextNotificationIdKey,
base::Int64ToString(next_notification_id_ + 1));
- Status status = LevelDBStatusToStatus(
- db_->Write(leveldb::WriteOptions(), &batch));
+ Status status =
+ LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch));
if (status != STATUS_OK)
return status;
@@ -238,9 +236,8 @@ NotificationDatabase::Status
NotificationDatabase::DeleteAllNotificationDataForOrigin(
const GURL& origin,
std::set<int64_t>* deleted_notification_set) {
- return DeleteAllNotificationDataInternal(origin,
- kInvalidServiceWorkerRegistrationId,
- deleted_notification_set);
+ return DeleteAllNotificationDataInternal(
+ origin, kInvalidServiceWorkerRegistrationId, deleted_notification_set);
}
NotificationDatabase::Status
@@ -248,9 +245,8 @@ NotificationDatabase::DeleteAllNotificationDataForServiceWorkerRegistration(
const GURL& origin,
int64_t service_worker_registration_id,
std::set<int64_t>* deleted_notification_set) {
- return DeleteAllNotificationDataInternal(origin,
- service_worker_registration_id,
- deleted_notification_set);
+ return DeleteAllNotificationDataInternal(
+ origin, service_worker_registration_id, deleted_notification_set);
}
NotificationDatabase::Status NotificationDatabase::Destroy() {
@@ -354,7 +350,7 @@ NotificationDatabase::DeleteAllNotificationDataInternal(
return status;
if (notification_database_data.service_worker_registration_id !=
- service_worker_registration_id) {
+ service_worker_registration_id) {
continue;
}
}
diff --git a/chromium/content/browser/notifications/notification_database.h b/chromium/content/browser/notifications/notification_database.h
index 1404e63501a..4f230a11c86 100644
--- a/chromium/content/browser/notifications/notification_database.h
+++ b/chromium/content/browser/notifications/notification_database.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/sequence_checker.h"
#include "content/common/content_export.h"
@@ -52,9 +53,15 @@ class CONTENT_EXPORT NotificationDatabase {
// General failure code. More specific failures should be used if available.
STATUS_ERROR_FAILED = 3,
+ // leveldb failed due to I/O error (read-only, full disk, etc.).
+ STATUS_IO_ERROR = 4,
+
+ // leveldb operation not supported
+ STATUS_NOT_SUPPORTED = 5,
+
// Number of entries in the status enumeration. Used by UMA. Must always be
// one higher than the otherwise highest value in this enumeration.
- STATUS_COUNT = 4
+ STATUS_COUNT = 6
};
explicit NotificationDatabase(const base::FilePath& path);
diff --git a/chromium/content/browser/notifications/notification_database_data_conversions.cc b/chromium/content/browser/notifications/notification_database_data_conversions.cc
index c6095e4055a..cf19704f9dc 100644
--- a/chromium/content/browser/notifications/notification_database_data_conversions.cc
+++ b/chromium/content/browser/notifications/notification_database_data_conversions.cc
@@ -4,6 +4,8 @@
#include "content/browser/notifications/notification_database_data_conversions.h"
+#include <stddef.h>
+
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/notifications/notification_database_data.pb.h"
@@ -51,8 +53,7 @@ bool DeserializeNotificationDatabaseData(const std::string& input,
if (payload.vibration_pattern().size() > 0) {
notification_data->vibration_pattern.assign(
- payload.vibration_pattern().begin(),
- payload.vibration_pattern().end());
+ payload.vibration_pattern().begin(), payload.vibration_pattern().end());
}
notification_data->silent = payload.silent();
diff --git a/chromium/content/browser/notifications/notification_database_data_unittest.cc b/chromium/content/browser/notifications/notification_database_data_unittest.cc
index e2bf7d4c08e..a080ae4d558 100644
--- a/chromium/content/browser/notifications/notification_database_data_unittest.cc
+++ b/chromium/content/browser/notifications/notification_database_data_unittest.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/notifications/notification_database_data.pb.h"
@@ -22,8 +26,8 @@ const char kNotificationLang[] = "nl";
const char kNotificationBody[] = "Hello, world!";
const char kNotificationTag[] = "my_tag";
const char kNotificationIconUrl[] = "https://example.com/icon.png";
-const int kNotificationVibrationPattern[] = { 100, 200, 300 };
-const unsigned char kNotificationData[] = { 0xdf, 0xff, 0x0, 0x0, 0xff, 0xdf };
+const int kNotificationVibrationPattern[] = {100, 200, 300};
+const unsigned char kNotificationData[] = {0xdf, 0xff, 0x0, 0x0, 0xff, 0xdf};
TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
std::vector<int> vibration_pattern(
@@ -61,14 +65,14 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
std::string serialized_data;
// Serialize the data in |notification_data| to the string |serialized_data|.
- ASSERT_TRUE(SerializeNotificationDatabaseData(database_data,
- &serialized_data));
+ ASSERT_TRUE(
+ SerializeNotificationDatabaseData(database_data, &serialized_data));
NotificationDatabaseData copied_data;
// Deserialize the data in |serialized_data| to |copied_data|.
- ASSERT_TRUE(DeserializeNotificationDatabaseData(serialized_data,
- &copied_data));
+ ASSERT_TRUE(
+ DeserializeNotificationDatabaseData(serialized_data, &copied_data));
EXPECT_EQ(database_data.notification_id, copied_data.notification_id);
EXPECT_EQ(database_data.origin, copied_data.origin);
@@ -86,7 +90,7 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
EXPECT_EQ(notification_data.icon, copied_notification_data.icon);
EXPECT_THAT(copied_notification_data.vibration_pattern,
- testing::ElementsAreArray(kNotificationVibrationPattern));
+ testing::ElementsAreArray(kNotificationVibrationPattern));
EXPECT_EQ(notification_data.silent, copied_notification_data.silent);
EXPECT_EQ(notification_data.require_interaction,
@@ -108,10 +112,9 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
TEST(NotificationDatabaseDataTest, SerializeAndDeserializeDirections) {
PlatformNotificationData::Direction directions[] = {
- PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT,
- PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT,
- PlatformNotificationData::DIRECTION_AUTO
- };
+ PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT,
+ PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT,
+ PlatformNotificationData::DIRECTION_AUTO};
for (size_t i = 0; i < arraysize(directions); ++i) {
PlatformNotificationData notification_data;
@@ -121,12 +124,12 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeDirections) {
database_data.notification_data = notification_data;
std::string serialized_data;
- ASSERT_TRUE(SerializeNotificationDatabaseData(database_data,
- &serialized_data));
+ ASSERT_TRUE(
+ SerializeNotificationDatabaseData(database_data, &serialized_data));
NotificationDatabaseData copied_data;
- ASSERT_TRUE(DeserializeNotificationDatabaseData(serialized_data,
- &copied_data));
+ ASSERT_TRUE(
+ DeserializeNotificationDatabaseData(serialized_data, &copied_data));
EXPECT_EQ(directions[i], copied_data.notification_data.direction);
}
diff --git a/chromium/content/browser/notifications/notification_database_unittest.cc b/chromium/content/browser/notifications/notification_database_unittest.cc
index a4dbff33b23..40b6950f66b 100644
--- a/chromium/content/browser/notifications/notification_database_unittest.cc
+++ b/chromium/content/browser/notifications/notification_database_unittest.cc
@@ -4,7 +4,11 @@
#include "content/browser/notifications/notification_database.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/notification_database_data.h"
@@ -22,14 +26,13 @@ const struct {
const char* origin;
int64_t service_worker_registration_id;
} kExampleNotificationData[] = {
- { "https://example.com", 0 },
- { "https://example.com", kExampleServiceWorkerRegistrationId },
- { "https://example.com", kExampleServiceWorkerRegistrationId },
- { "https://example.com", kExampleServiceWorkerRegistrationId + 1 },
- { "https://chrome.com", 0 },
- { "https://chrome.com", 0 },
- { "https://chrome.com", kExampleServiceWorkerRegistrationId }
-};
+ {"https://example.com", 0},
+ {"https://example.com", kExampleServiceWorkerRegistrationId},
+ {"https://example.com", kExampleServiceWorkerRegistrationId},
+ {"https://example.com", kExampleServiceWorkerRegistrationId + 1},
+ {"https://chrome.com", 0},
+ {"https://chrome.com", 0},
+ {"https://chrome.com", kExampleServiceWorkerRegistrationId}};
class NotificationDatabaseTest : public ::testing::Test {
protected:
@@ -39,8 +42,7 @@ class NotificationDatabaseTest : public ::testing::Test {
}
// Creates a new NotificationDatabase instance in |path|.
- NotificationDatabase* CreateDatabaseOnFileSystem(
- const base::FilePath& path) {
+ NotificationDatabase* CreateDatabaseOnFileSystem(const base::FilePath& path) {
return new NotificationDatabase(path);
}
@@ -57,8 +59,7 @@ class NotificationDatabaseTest : public ::testing::Test {
service_worker_registration_id;
ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin,
- database_data,
+ database->WriteNotificationData(origin, database_data,
notification_id));
}
@@ -68,8 +69,7 @@ class NotificationDatabaseTest : public ::testing::Test {
int64_t notification_id;
for (size_t i = 0; i < arraysize(kExampleNotificationData); ++i) {
ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
- database,
- GURL(kExampleNotificationData[i].origin),
+ database, GURL(kExampleNotificationData[i].origin),
kExampleNotificationData[i].service_worker_registration_id,
&notification_id));
}
@@ -210,15 +210,13 @@ TEST_F(NotificationDatabaseTest, NotificationIdIncrementsStorage) {
database_data.notification_id = -1;
int64_t notification_id = 0;
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin,
- database_data,
- &notification_id));
+ ASSERT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->WriteNotificationData(origin, database_data, &notification_id));
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->ReadNotificationData(notification_id,
- origin,
- &database_data));
+ ASSERT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->ReadNotificationData(notification_id, origin, &database_data));
EXPECT_EQ(notification_id, database_data.notification_id);
}
@@ -238,18 +236,16 @@ TEST_F(NotificationDatabaseTest, NotificationIdCorruption) {
NotificationDatabaseData database_data;
int64_t notification_id = 0;
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin,
- database_data,
- &notification_id));
+ ASSERT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->WriteNotificationData(origin, database_data, &notification_id));
EXPECT_EQ(notification_id, 1);
// Deliberately write an invalid value as the next notification id. When
// re-opening the database, the Open() method should realize that an invalid
// value is being read, and mark the database as corrupted.
- ASSERT_NO_FATAL_FAILURE(WriteLevelDBKeyValuePair(database.get(),
- "NEXT_NOTIFICATION_ID",
- "-42"));
+ ASSERT_NO_FATAL_FAILURE(
+ WriteLevelDBKeyValuePair(database.get(), "NEXT_NOTIFICATION_ID", "-42"));
database.reset(CreateDatabaseOnFileSystem(database_dir.path()));
EXPECT_EQ(NotificationDatabase::STATUS_ERROR_CORRUPTED,
@@ -266,8 +262,7 @@ TEST_F(NotificationDatabaseTest, ReadInvalidNotificationData) {
// Reading the notification data for a notification that does not exist should
// return the ERROR_NOT_FOUND status code.
EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
- database->ReadNotificationData(9001,
- GURL("https://chrome.com"),
+ database->ReadNotificationData(9001, GURL("https://chrome.com"),
&database_data));
}
@@ -282,23 +277,21 @@ TEST_F(NotificationDatabaseTest, ReadNotificationDataDifferentOrigin) {
NotificationDatabaseData database_data, read_database_data;
database_data.notification_data.title = base::UTF8ToUTF16("My Notification");
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin,
- database_data,
- &notification_id));
+ ASSERT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->WriteNotificationData(origin, database_data, &notification_id));
// Reading the notification from the database when given a different origin
// should return the ERROR_NOT_FOUND status code.
- EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
- database->ReadNotificationData(notification_id,
- GURL("https://chrome.com"),
- &read_database_data));
+ EXPECT_EQ(
+ NotificationDatabase::STATUS_ERROR_NOT_FOUND,
+ database->ReadNotificationData(
+ notification_id, GURL("https://chrome.com"), &read_database_data));
// However, reading the notification from the database with the same origin
// should return STATUS_OK and the associated notification data.
ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->ReadNotificationData(notification_id,
- origin,
+ database->ReadNotificationData(notification_id, origin,
&read_database_data));
EXPECT_EQ(database_data.notification_data.title,
@@ -332,15 +325,13 @@ TEST_F(NotificationDatabaseTest, ReadNotificationDataReflection) {
// Write the constructed notification to the database, and then immediately
// read it back from the database again as well.
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin,
- database_data,
- &notification_id));
+ ASSERT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->WriteNotificationData(origin, database_data, &notification_id));
NotificationDatabaseData read_database_data;
ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->ReadNotificationData(notification_id,
- origin,
+ database->ReadNotificationData(notification_id, origin,
&read_database_data));
// Verify that all members retrieved from the database are exactly the same
@@ -386,8 +377,7 @@ TEST_F(NotificationDatabaseTest, ReadWriteMultipleNotificationData) {
// of each of them matches with how they were created.
for (int i = 1; i <= 10; ++i) {
ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->ReadNotificationData(i /* notification_id */,
- origin,
+ database->ReadNotificationData(i /* notification_id */, origin,
&database_data));
EXPECT_EQ(i, database_data.service_worker_registration_id);
@@ -401,8 +391,7 @@ TEST_F(NotificationDatabaseTest, DeleteInvalidNotificationData) {
// Deleting non-existing notifications is not considered to be a failure.
ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->DeleteNotificationData(9001,
- GURL("https://chrome.com")));
+ database->DeleteNotificationData(9001, GURL("https://chrome.com")));
}
TEST_F(NotificationDatabaseTest, DeleteNotificationDataSameOrigin) {
@@ -415,25 +404,22 @@ TEST_F(NotificationDatabaseTest, DeleteNotificationDataSameOrigin) {
NotificationDatabaseData database_data;
GURL origin("https://example.com");
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin,
- database_data,
- &notification_id));
+ ASSERT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->WriteNotificationData(origin, database_data, &notification_id));
// Reading a notification after writing one should succeed.
- EXPECT_EQ(NotificationDatabase::STATUS_OK,
- database->ReadNotificationData(notification_id,
- origin,
- &database_data));
+ EXPECT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->ReadNotificationData(notification_id, origin, &database_data));
// Delete the notification which was just written to the database, and verify
// that reading it again will fail.
EXPECT_EQ(NotificationDatabase::STATUS_OK,
database->DeleteNotificationData(notification_id, origin));
- EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
- database->ReadNotificationData(notification_id,
- origin,
- &database_data));
+ EXPECT_EQ(
+ NotificationDatabase::STATUS_ERROR_NOT_FOUND,
+ database->ReadNotificationData(notification_id, origin, &database_data));
}
TEST_F(NotificationDatabaseTest, DeleteNotificationDataDifferentOrigin) {
@@ -446,10 +432,9 @@ TEST_F(NotificationDatabaseTest, DeleteNotificationDataDifferentOrigin) {
NotificationDatabaseData database_data;
GURL origin("https://example.com");
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin,
- database_data,
- &notification_id));
+ ASSERT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->WriteNotificationData(origin, database_data, &notification_id));
// Attempting to delete the notification with a different origin, but with the
// same |notification_id|, should not return an error (the notification could
@@ -459,10 +444,9 @@ TEST_F(NotificationDatabaseTest, DeleteNotificationDataDifferentOrigin) {
database->DeleteNotificationData(notification_id,
GURL("https://chrome.com")));
- EXPECT_EQ(NotificationDatabase::STATUS_OK,
- database->ReadNotificationData(notification_id,
- origin,
- &database_data));
+ EXPECT_EQ(
+ NotificationDatabase::STATUS_OK,
+ database->ReadNotificationData(notification_id, origin, &database_data));
}
TEST_F(NotificationDatabaseTest, ReadAllNotificationData) {
@@ -575,8 +559,7 @@ TEST_F(NotificationDatabaseTest,
std::set<int64_t> deleted_notification_set;
ASSERT_EQ(NotificationDatabase::STATUS_OK,
database->DeleteAllNotificationDataForServiceWorkerRegistration(
- origin,
- kExampleServiceWorkerRegistrationId,
+ origin, kExampleServiceWorkerRegistrationId,
&deleted_notification_set));
EXPECT_EQ(2u, deleted_notification_set.size());
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
index f5e8409fd2e..d48491ce2b8 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -5,6 +5,7 @@
#include "content/browser/notifications/notification_event_dispatcher_impl.h"
#include "base/callback.h"
+#include "build/build_config.h"
#include "content/browser/notifications/platform_notification_context_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h"
@@ -29,6 +30,14 @@ void NotificationClickEventFinished(
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+#if defined(OS_ANDROID)
+ // This LOG(INFO) deliberately exists to help track down the cause of
+ // https://crbug.com/534537, where notifications sometimes do not react to
+ // the user clicking on them. It should be removed once that's fixed.
+ LOG(INFO) << "The notificationclick event has finished: "
+ << service_worker_status;
+#endif
+
PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
switch (service_worker_status) {
case SERVICE_WORKER_OK:
@@ -59,8 +68,7 @@ void NotificationClickEventFinished(
break;
}
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(dispatch_complete_callback, status));
}
@@ -74,19 +82,23 @@ void DispatchNotificationClickEventOnRegistration(
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+#if defined(OS_ANDROID)
+ // This LOG(INFO) deliberately exists to help track down the cause of
+ // https://crbug.com/534537, where notifications sometimes do not react to
+ // the user clicking on them. It should be removed once that's fixed.
+ LOG(INFO) << "Trying to dispatch notification for SW with status: "
+ << service_worker_status << " action_index: " << action_index;
+#endif
if (service_worker_status == SERVICE_WORKER_OK) {
base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback =
- base::Bind(&NotificationClickEventFinished,
- dispatch_complete_callback,
+ base::Bind(&NotificationClickEventFinished, dispatch_complete_callback,
service_worker_registration);
DCHECK(service_worker_registration->active_version());
- service_worker_registration->active_version()->
- DispatchNotificationClickEvent(
- dispatch_event_callback,
- notification_database_data.notification_id,
- notification_database_data.notification_data,
- action_index);
+ service_worker_registration->active_version()
+ ->DispatchNotificationClickEvent(
+ dispatch_event_callback, notification_database_data.notification_id,
+ notification_database_data.notification_data, action_index);
return;
}
@@ -120,8 +132,7 @@ void DispatchNotificationClickEventOnRegistration(
break;
}
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(dispatch_complete_callback, status));
}
@@ -135,18 +146,24 @@ void FindServiceWorkerRegistration(
bool success,
const NotificationDatabaseData& notification_database_data) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+#if defined(OS_ANDROID)
+ // This LOG(INFO) deliberately exists to help track down the cause of
+ // https://crbug.com/534537, where notifications sometimes do not react to
+ // the user clicking on them. It should be removed once that's fixed.
+ LOG(INFO) << "Lookup for ServiceWoker Registration: success:" << success
+ << " action_index: " << action_index;
+#endif
if (!success) {
BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
+ BrowserThread::UI, FROM_HERE,
base::Bind(dispatch_complete_callback,
PERSISTENT_NOTIFICATION_STATUS_DATABASE_ERROR));
return;
}
service_worker_context->FindReadyRegistrationForId(
- notification_database_data.service_worker_registration_id,
- origin,
+ notification_database_data.service_worker_registration_id, origin,
base::Bind(&DispatchNotificationClickEventOnRegistration,
notification_database_data, action_index,
dispatch_complete_callback));
@@ -163,11 +180,9 @@ void ReadNotificationDatabaseData(
scoped_refptr<PlatformNotificationContextImpl> notification_context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
notification_context->ReadNotificationData(
- persistent_notification_id,
- origin,
- base::Bind(&FindServiceWorkerRegistration,
- origin, action_index, dispatch_complete_callback,
- service_worker_context));
+ persistent_notification_id, origin,
+ base::Bind(&FindServiceWorkerRegistration, origin, action_index,
+ dispatch_complete_callback, service_worker_context));
}
} // namespace
@@ -209,15 +224,10 @@ void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
partition->GetPlatformNotificationContext());
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&ReadNotificationDatabaseData,
- persistent_notification_id,
- origin,
- action_index,
- dispatch_complete_callback,
- service_worker_context,
- notification_context));
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ReadNotificationDatabaseData, persistent_notification_id,
+ origin, action_index, dispatch_complete_callback,
+ service_worker_context, notification_context));
}
} // namespace content
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl.h b/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
index e9fcc3016c5..fbc5d429f27 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_NOTIFICATIONS_NOTIFICATION_EVENT_DISPATCHER_IMPL_H_
#define CONTENT_BROWSER_NOTIFICATIONS_NOTIFICATION_EVENT_DISPATCHER_IMPL_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/notification_event_dispatcher.h"
diff --git a/chromium/content/browser/notifications/notification_id_generator.cc b/chromium/content/browser/notifications/notification_id_generator.cc
index 252aae478d0..2bbc19fdb2a 100644
--- a/chromium/content/browser/notifications/notification_id_generator.cc
+++ b/chromium/content/browser/notifications/notification_id_generator.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/sha1.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_context.h"
#include "url/gurl.h"
diff --git a/chromium/content/browser/notifications/notification_id_generator_unittest.cc b/chromium/content/browser/notifications/notification_id_generator_unittest.cc
index 770822f0247..aeef6bbf0a1 100644
--- a/chromium/content/browser/notifications/notification_id_generator_unittest.cc
+++ b/chromium/content/browser/notifications/notification_id_generator_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/notifications/notification_id_generator.h"
#include "content/public/test/test_browser_context.h"
@@ -37,9 +40,7 @@ class NotificationIdGeneratorTest : public ::testing::Test {
NotificationIdGeneratorTest()
: generator_(&browser_context_, kRenderProcessId) {}
- void SetUp() override {
-
- }
+ void SetUp() override {}
protected:
GURL origin() const { return GURL("https://example.com"); }
@@ -65,30 +66,26 @@ class NotificationIdGeneratorTest : public ::testing::Test {
// in exactly the same notification ids being generated.
TEST_F(NotificationIdGeneratorTest, DeterministicGeneration) {
// Persistent notifications.
- EXPECT_EQ(
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId));
-
- EXPECT_EQ(
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
+ EXPECT_EQ(generator()->GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId),
+ generator()->GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId));
- // Non-persistent notifications.
- EXPECT_EQ(
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId),
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId));
+ EXPECT_EQ(generator()->GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId),
+ generator()->GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId));
- EXPECT_EQ(
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId));
+ // Non-persistent notifications.
+ EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId),
+ generator()->GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId));
+
+ EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId),
+ generator()->GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId));
}
// Uniqueness of notification ids will be impacted by the browser context.
@@ -98,30 +95,26 @@ TEST_F(NotificationIdGeneratorTest, DifferentBrowserContexts) {
kRenderProcessId);
// Persistent notifications.
- EXPECT_NE(
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- second_generator.GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId),
+ second_generator.GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId));
- EXPECT_NE(
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
- second_generator.GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId),
+ second_generator.GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId),
- second_generator.GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId));
-
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId),
- second_generator.GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId),
+ second_generator.GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId));
+
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId),
+ second_generator.GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId));
}
// Uniqueness of notification ids will be impacted by the fact whether the
@@ -131,15 +124,15 @@ TEST_F(NotificationIdGeneratorTest, DifferentIncognitoStates) {
// Persistent notifications.
std::string normal_persistent_notification_id =
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId);
+ generator()->GenerateForPersistentNotification(origin(), kExampleTag,
+ kPersistentNotificationId);
browser_context()->set_incognito(true);
ASSERT_TRUE(browser_context()->IsOffTheRecord());
std::string incognito_persistent_notification_id =
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId);
+ generator()->GenerateForPersistentNotification(origin(), kExampleTag,
+ kPersistentNotificationId);
EXPECT_NE(normal_persistent_notification_id,
incognito_persistent_notification_id);
@@ -169,18 +162,16 @@ TEST_F(NotificationIdGeneratorTest, DifferentOrigins) {
GURL different_origin("https://example2.com");
// Persistent notifications.
- EXPECT_NE(
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- different_origin, kExampleTag, kPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId),
+ generator()->GenerateForPersistentNotification(
+ different_origin, kExampleTag, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId),
- generator()->GenerateForNonPersistentNotification(
- different_origin, kExampleTag, kNonPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId),
+ generator()->GenerateForNonPersistentNotification(
+ different_origin, kExampleTag, kNonPersistentNotificationId));
}
// The tag, when non-empty, will impact the generated notification id.
@@ -188,18 +179,16 @@ TEST_F(NotificationIdGeneratorTest, DifferentTags) {
const std::string& different_tag = std::string(kExampleTag) + "2";
// Persistent notifications.
- EXPECT_NE(
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), different_tag, kPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId),
+ generator()->GenerateForPersistentNotification(
+ origin(), different_tag, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId),
- generator()->GenerateForNonPersistentNotification(
- origin(), different_tag, kNonPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId),
+ generator()->GenerateForNonPersistentNotification(
+ origin(), different_tag, kNonPersistentNotificationId));
}
// The persistent or non-persistent notification id will impact the generated
@@ -209,47 +198,40 @@ TEST_F(NotificationIdGeneratorTest, DifferentIds) {
kRenderProcessId + 1);
// Persistent notifications.
- EXPECT_NE(
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId + 1));
+ EXPECT_NE(generator()->GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId),
+ generator()->GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId + 1));
// Non-persistent notifications.
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId + 1));
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId),
+ generator()->GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId + 1));
// Non-persistent when a tag is being used.
- EXPECT_EQ(
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId),
- second_generator.GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId));
+ EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId),
+ second_generator.GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId));
}
// Using a numeric tag that could resemble a persistent notification id should
// not be equal to a notification without a tag, but with that id.
TEST_F(NotificationIdGeneratorTest, NumericTagAmbiguity) {
// Persistent notifications.
- EXPECT_NE(
- generator()->GenerateForPersistentNotification(
- origin(),
- base::Int64ToString(kPersistentNotificationId),
- kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForPersistentNotification(
+ origin(), base::Int64ToString(kPersistentNotificationId),
+ kPersistentNotificationId),
+ generator()->GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(),
- base::IntToString(kNonPersistentNotificationId),
- kNonPersistentNotificationId),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin(), base::IntToString(kNonPersistentNotificationId),
+ kNonPersistentNotificationId),
+ generator()->GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId));
}
// Using port numbers and a tag which, when concatenated, could end up being
@@ -259,18 +241,16 @@ TEST_F(NotificationIdGeneratorTest, OriginPortAmbiguity) {
GURL origin_8051("https://example.com:8051");
// Persistent notifications.
- EXPECT_NE(
- generator()->GenerateForPersistentNotification(
- origin_805, "17", kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin_8051, "7", kPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForPersistentNotification(
+ origin_805, "17", kPersistentNotificationId),
+ generator()->GenerateForPersistentNotification(
+ origin_8051, "7", kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin_805, "17", kNonPersistentNotificationId),
- generator()->GenerateForNonPersistentNotification(
- origin_8051, "7", kNonPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin_805, "17", kNonPersistentNotificationId),
+ generator()->GenerateForNonPersistentNotification(
+ origin_8051, "7", kNonPersistentNotificationId));
}
// -----------------------------------------------------------------------------
@@ -283,17 +263,15 @@ TEST_F(NotificationIdGeneratorTest, PersistentDifferentRenderProcessIds) {
NotificationIdGenerator second_generator(browser_context(),
kRenderProcessId + 1);
- EXPECT_EQ(
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- second_generator.GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId));
-
- EXPECT_EQ(
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
- second_generator.GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
+ EXPECT_EQ(generator()->GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId),
+ second_generator.GenerateForPersistentNotification(
+ origin(), kExampleTag, kPersistentNotificationId));
+
+ EXPECT_EQ(generator()->GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId),
+ second_generator.GenerateForPersistentNotification(
+ origin(), "" /* tag */, kPersistentNotificationId));
}
// -----------------------------------------------------------------------------
@@ -308,17 +286,15 @@ TEST_F(NotificationIdGeneratorTest, NonPersistentDifferentRenderProcessIds) {
NotificationIdGenerator second_generator(browser_context(),
kRenderProcessId + 1);
- EXPECT_EQ(
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId),
- second_generator.GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId));
+ EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId),
+ second_generator.GenerateForNonPersistentNotification(
+ origin(), kExampleTag, kNonPersistentNotificationId));
- EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId),
- second_generator.GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId));
+ EXPECT_NE(generator()->GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId),
+ second_generator.GenerateForNonPersistentNotification(
+ origin(), "" /* tag */, kNonPersistentNotificationId));
}
// Concatenation of the render process id and the non-persistent notification
diff --git a/chromium/content/browser/notifications/notification_message_filter.cc b/chromium/content/browser/notifications/notification_message_filter.cc
index 32691565d7f..f8c3ba89435 100644
--- a/chromium/content/browser/notifications/notification_message_filter.cc
+++ b/chromium/content/browser/notifications/notification_message_filter.cc
@@ -4,6 +4,8 @@
#include "content/browser/notifications/notification_message_filter.h"
+#include <utility>
+
#include "base/callback.h"
#include "content/browser/bad_message.h"
#include "content/browser/notifications/page_notification_delegate.h"
@@ -23,7 +25,7 @@ namespace content {
namespace {
-const int kMinimumVibrationDurationMs = 1; // 1 millisecond
+const int kMinimumVibrationDurationMs = 1; // 1 millisecond
const int kMaximumVibrationDurationMs = 10000; // 10 seconds
PlatformNotificationData SanitizeNotificationData(
@@ -33,7 +35,7 @@ PlatformNotificationData SanitizeNotificationData(
// Make sure that the vibration values are within reasonable bounds.
for (int& pattern : sanitized_data.vibration_pattern) {
pattern = std::min(kMaximumVibrationDurationMs,
- std::max(kMinimumVibrationDurationMs, pattern));
+ std::max(kMinimumVibrationDurationMs, pattern));
}
// Ensure there aren't more actions than supported.
@@ -124,12 +126,9 @@ void NotificationMessageFilter::OnShowPlatformNotification(
return;
base::Closure close_closure;
- service->DisplayNotification(browser_context_,
- origin,
- icon,
+ service->DisplayNotification(browser_context_, origin, icon,
SanitizeNotificationData(notification_data),
- delegate.Pass(),
- &close_closure);
+ std::move(delegate), &close_closure);
if (!close_closure.is_null())
close_closures_[notification_id] = close_closure;
@@ -137,13 +136,13 @@ void NotificationMessageFilter::OnShowPlatformNotification(
void NotificationMessageFilter::OnShowPersistentNotification(
int request_id,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const GURL& origin,
const SkBitmap& icon,
const PlatformNotificationData& notification_data) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (GetPermissionForOriginOnIO(origin) !=
- blink::WebNotificationPermissionAllowed) {
+ blink::WebNotificationPermissionAllowed) {
bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_SHOW);
return;
}
@@ -159,13 +158,9 @@ void NotificationMessageFilter::OnShowPersistentNotification(
// TODO(peter): Significantly reduce the amount of information we need to
// retain outside of the database for displaying notifications.
notification_context_->WriteNotificationData(
- origin,
- database_data,
+ origin, database_data,
base::Bind(&NotificationMessageFilter::DidWritePersistentNotificationData,
- weak_factory_io_.GetWeakPtr(),
- request_id,
- origin,
- icon,
+ weak_factory_io_.GetWeakPtr(), request_id, origin, icon,
sanitized_notification_data));
}
@@ -180,18 +175,14 @@ void NotificationMessageFilter::DidWritePersistentNotificationData(
if (success) {
PlatformNotificationService* service =
- GetContentClient()->browser()->GetPlatformNotificationService();
+ GetContentClient()->browser()->GetPlatformNotificationService();
DCHECK(service);
BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
+ BrowserThread::UI, FROM_HERE,
base::Bind(&PlatformNotificationService::DisplayPersistentNotification,
base::Unretained(service), // The service is a singleton.
- browser_context_,
- persistent_notification_id,
- origin,
- icon,
+ browser_context_, persistent_notification_id, origin, icon,
notification_data));
}
@@ -205,7 +196,7 @@ void NotificationMessageFilter::OnGetNotifications(
const std::string& filter_tag) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (GetPermissionForOriginOnIO(origin) !=
- blink::WebNotificationPermissionAllowed) {
+ blink::WebNotificationPermissionAllowed) {
// No permission has been granted for the given origin. It is harmless to
// try to get notifications without permission, so return an empty vector
// indicating that no (accessible) notifications exist at this time.
@@ -215,12 +206,9 @@ void NotificationMessageFilter::OnGetNotifications(
}
notification_context_->ReadAllNotificationDataForServiceWorkerRegistration(
- origin,
- service_worker_registration_id,
+ origin, service_worker_registration_id,
base::Bind(&NotificationMessageFilter::DidGetNotifications,
- weak_factory_io_.GetWeakPtr(),
- request_id,
- filter_tag));
+ weak_factory_io_.GetWeakPtr(), request_id, filter_tag));
}
void NotificationMessageFilter::DidGetNotifications(
@@ -262,7 +250,7 @@ void NotificationMessageFilter::OnClosePersistentNotification(
int64_t persistent_notification_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (GetPermissionForOriginOnIO(origin) !=
- blink::WebNotificationPermissionAllowed) {
+ blink::WebNotificationPermissionAllowed) {
bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_CLOSE);
return;
}
@@ -274,19 +262,16 @@ void NotificationMessageFilter::OnClosePersistentNotification(
// There's no point in waiting until the database data has been removed before
// closing the notification presented to the user. Post that task immediately.
BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
+ BrowserThread::UI, FROM_HERE,
base::Bind(&PlatformNotificationService::ClosePersistentNotification,
base::Unretained(service), // The service is a singleton.
- browser_context_,
- persistent_notification_id));
+ browser_context_, persistent_notification_id));
notification_context_->DeleteNotificationData(
- persistent_notification_id,
- origin,
- base::Bind(&NotificationMessageFilter::
- DidDeletePersistentNotificationData,
- weak_factory_io_.GetWeakPtr()));
+ persistent_notification_id, origin,
+ base::Bind(
+ &NotificationMessageFilter::DidDeletePersistentNotificationData,
+ weak_factory_io_.GetWeakPtr()));
}
void NotificationMessageFilter::DidDeletePersistentNotificationData(
@@ -306,8 +291,7 @@ NotificationMessageFilter::GetPermissionForOriginOnIO(
if (!service)
return blink::WebNotificationPermissionDenied;
- return service->CheckPermissionOnIOThread(resource_context_,
- origin,
+ return service->CheckPermissionOnIOThread(resource_context_, origin,
process_id_);
}
@@ -317,9 +301,7 @@ bool NotificationMessageFilter::VerifyNotificationPermissionGranted(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
blink::WebNotificationPermission permission =
- service->CheckPermissionOnUIThread(browser_context_,
- origin,
- process_id_);
+ service->CheckPermissionOnUIThread(browser_context_, origin, process_id_);
if (permission == blink::WebNotificationPermissionAllowed)
return true;
diff --git a/chromium/content/browser/notifications/notification_message_filter.h b/chromium/content/browser/notifications/notification_message_filter.h
index c5ad0a4ac69..74ecf2f441d 100644
--- a/chromium/content/browser/notifications/notification_message_filter.h
+++ b/chromium/content/browser/notifications/notification_message_filter.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_NOTIFICATIONS_NOTIFICATION_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_NOTIFICATIONS_NOTIFICATION_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include <map>
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/notification_database_data.h"
@@ -39,8 +42,8 @@ class NotificationMessageFilter : public BrowserMessageFilter {
// BrowserMessageFilter implementation. Called on the UI thread.
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
- void OverrideThreadForMessage(
- const IPC::Message& message, content::BrowserThread::ID* thread) override;
+ void OverrideThreadForMessage(const IPC::Message& message,
+ content::BrowserThread::ID* thread) override;
protected:
~NotificationMessageFilter() override;
@@ -58,7 +61,7 @@ class NotificationMessageFilter : public BrowserMessageFilter {
const PlatformNotificationData& notification_data);
void OnShowPersistentNotification(
int request_id,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const GURL& origin,
const SkBitmap& icon,
const PlatformNotificationData& notification_data);
@@ -67,9 +70,8 @@ class NotificationMessageFilter : public BrowserMessageFilter {
const GURL& origin,
const std::string& filter_tag);
void OnClosePlatformNotification(int notification_id);
- void OnClosePersistentNotification(
- const GURL& origin,
- int64_t persistent_notification_id);
+ void OnClosePersistentNotification(const GURL& origin,
+ int64_t persistent_notification_id);
// Callback to be invoked by the notification context when the notification
// data for the persistent notification may have been written, as indicated by
@@ -107,9 +109,8 @@ class NotificationMessageFilter : public BrowserMessageFilter {
// cases where the renderer shouldn't send messages if it weren't the case. If
// no permission has been granted, a bad message has been received and the
// renderer should be killed accordingly.
- bool VerifyNotificationPermissionGranted(
- PlatformNotificationService* service,
- const GURL& origin);
+ bool VerifyNotificationPermissionGranted(PlatformNotificationService* service,
+ const GURL& origin);
int process_id_;
scoped_refptr<PlatformNotificationContextImpl> notification_context_;
diff --git a/chromium/content/browser/notifications/page_notification_delegate.cc b/chromium/content/browser/notifications/page_notification_delegate.cc
index fdf085d7c7c..03f5b588e69 100644
--- a/chromium/content/browser/notifications/page_notification_delegate.cc
+++ b/chromium/content/browser/notifications/page_notification_delegate.cc
@@ -33,7 +33,8 @@ void PageNotificationDelegate::NotificationClosed() {
sender->Send(new PlatformNotificationMsg_DidClose(notification_id_));
static_cast<RenderProcessHostImpl*>(sender)
- ->notification_message_filter()->DidCloseNotification(notification_id_);
+ ->notification_message_filter()
+ ->DidCloseNotification(notification_id_);
}
void PageNotificationDelegate::NotificationClick() {
diff --git a/chromium/content/browser/notifications/platform_notification_context_impl.cc b/chromium/content/browser/notifications/platform_notification_context_impl.cc
index c2ce26d3521..99c9591c1fb 100644
--- a/chromium/content/browser/notifications/platform_notification_context_impl.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_impl.cc
@@ -72,8 +72,7 @@ void PlatformNotificationContextImpl::Initialize() {
}
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::IO, FROM_HERE,
base::Bind(&PlatformNotificationContextImpl::InitializeOnIO, this));
}
@@ -88,8 +87,7 @@ void PlatformNotificationContextImpl::InitializeOnIO() {
void PlatformNotificationContextImpl::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::IO, FROM_HERE,
base::Bind(&PlatformNotificationContextImpl::ShutdownOnIO, this));
}
@@ -107,9 +105,9 @@ void PlatformNotificationContextImpl::ReadNotificationData(
const ReadResultCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LazyInitialize(
- base::Bind(&PlatformNotificationContextImpl::DoReadNotificationData,
- this, notification_id, origin, callback),
- base::Bind(callback, false /* success */, NotificationDatabaseData()));
+ base::Bind(&PlatformNotificationContextImpl::DoReadNotificationData, this,
+ notification_id, origin, callback),
+ base::Bind(callback, false /* success */, NotificationDatabaseData()));
}
void PlatformNotificationContextImpl::DoReadNotificationData(
@@ -120,19 +118,15 @@ void PlatformNotificationContextImpl::DoReadNotificationData(
NotificationDatabaseData database_data;
NotificationDatabase::Status status =
- database_->ReadNotificationData(notification_id,
- origin,
- &database_data);
+ database_->ReadNotificationData(notification_id, origin, &database_data);
- UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadResult",
- status, NotificationDatabase::STATUS_COUNT);
+ UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadResult", status,
+ NotificationDatabase::STATUS_COUNT);
if (status == NotificationDatabase::STATUS_OK) {
- BrowserThread::PostTask(BrowserThread::IO,
- FROM_HERE,
- base::Bind(callback,
- true /* success */,
- database_data));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, true /* success */, database_data));
return;
}
@@ -141,31 +135,29 @@ void PlatformNotificationContextImpl::DoReadNotificationData(
DestroyDatabase();
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::IO, FROM_HERE,
base::Bind(callback, false /* success */, NotificationDatabaseData()));
}
void PlatformNotificationContextImpl::
ReadAllNotificationDataForServiceWorkerRegistration(
- const GURL& origin,
- int64_t service_worker_registration_id,
- const ReadAllResultCallback& callback) {
+ const GURL& origin,
+ int64_t service_worker_registration_id,
+ const ReadAllResultCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LazyInitialize(
- base::Bind(&PlatformNotificationContextImpl::
- DoReadAllNotificationDataForServiceWorkerRegistration,
- this, origin, service_worker_registration_id, callback),
- base::Bind(callback,
- false /* success */,
- std::vector<NotificationDatabaseData>()));
+ base::Bind(&PlatformNotificationContextImpl::
+ DoReadAllNotificationDataForServiceWorkerRegistration,
+ this, origin, service_worker_registration_id, callback),
+ base::Bind(callback, false /* success */,
+ std::vector<NotificationDatabaseData>()));
}
void PlatformNotificationContextImpl::
DoReadAllNotificationDataForServiceWorkerRegistration(
- const GURL& origin,
- int64_t service_worker_registration_id,
- const ReadAllResultCallback& callback) {
+ const GURL& origin,
+ int64_t service_worker_registration_id,
+ const ReadAllResultCallback& callback) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
std::vector<NotificationDatabaseData> notification_datas;
@@ -178,11 +170,9 @@ void PlatformNotificationContextImpl::
status, NotificationDatabase::STATUS_COUNT);
if (status == NotificationDatabase::STATUS_OK) {
- BrowserThread::PostTask(BrowserThread::IO,
- FROM_HERE,
- base::Bind(callback,
- true /* success */,
- notification_datas));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, true /* success */, notification_datas));
return;
}
@@ -190,12 +180,9 @@ void PlatformNotificationContextImpl::
if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
DestroyDatabase();
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(callback,
- false /* success */,
- std::vector<NotificationDatabaseData>()));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, false /* success */,
+ std::vector<NotificationDatabaseData>()));
}
void PlatformNotificationContextImpl::WriteNotificationData(
@@ -204,9 +191,9 @@ void PlatformNotificationContextImpl::WriteNotificationData(
const WriteResultCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LazyInitialize(
- base::Bind(&PlatformNotificationContextImpl::DoWriteNotificationData,
- this, origin, database_data, callback),
- base::Bind(callback, false /* success */, 0 /* notification_id */));
+ base::Bind(&PlatformNotificationContextImpl::DoWriteNotificationData,
+ this, origin, database_data, callback),
+ base::Bind(callback, false /* success */, 0 /* notification_id */));
}
void PlatformNotificationContextImpl::DoWriteNotificationData(
@@ -217,20 +204,16 @@ void PlatformNotificationContextImpl::DoWriteNotificationData(
int64_t notification_id = 0;
NotificationDatabase::Status status =
- database_->WriteNotificationData(origin,
- database_data,
- &notification_id);
+ database_->WriteNotificationData(origin, database_data, &notification_id);
- UMA_HISTOGRAM_ENUMERATION("Notifications.Database.WriteResult",
- status, NotificationDatabase::STATUS_COUNT);
+ UMA_HISTOGRAM_ENUMERATION("Notifications.Database.WriteResult", status,
+ NotificationDatabase::STATUS_COUNT);
if (status == NotificationDatabase::STATUS_OK) {
DCHECK_GT(notification_id, 0);
- BrowserThread::PostTask(BrowserThread::IO,
- FROM_HERE,
- base::Bind(callback,
- true /* success */,
- notification_id));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, true /* success */, notification_id));
return;
}
@@ -239,8 +222,7 @@ void PlatformNotificationContextImpl::DoWriteNotificationData(
DestroyDatabase();
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::IO, FROM_HERE,
base::Bind(callback, false /* success */, 0 /* notification_id */));
}
@@ -250,9 +232,9 @@ void PlatformNotificationContextImpl::DeleteNotificationData(
const DeleteResultCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LazyInitialize(
- base::Bind(&PlatformNotificationContextImpl::DoDeleteNotificationData,
- this, notification_id, origin, callback),
- base::Bind(callback, false /* success */));
+ base::Bind(&PlatformNotificationContextImpl::DoDeleteNotificationData,
+ this, notification_id, origin, callback),
+ base::Bind(callback, false /* success */));
}
void PlatformNotificationContextImpl::DoDeleteNotificationData(
@@ -264,8 +246,8 @@ void PlatformNotificationContextImpl::DoDeleteNotificationData(
NotificationDatabase::Status status =
database_->DeleteNotificationData(notification_id, origin);
- UMA_HISTOGRAM_ENUMERATION("Notifications.Database.DeleteResult",
- status, NotificationDatabase::STATUS_COUNT);
+ UMA_HISTOGRAM_ENUMERATION("Notifications.Database.DeleteResult", status,
+ NotificationDatabase::STATUS_COUNT);
bool success = status == NotificationDatabase::STATUS_OK;
@@ -277,8 +259,7 @@ void PlatformNotificationContextImpl::DoDeleteNotificationData(
success = true;
}
- BrowserThread::PostTask(BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(callback, success));
}
@@ -302,11 +283,11 @@ void PlatformNotificationContextImpl::
std::set<int64_t> deleted_notifications_set;
NotificationDatabase::Status status =
database_->DeleteAllNotificationDataForServiceWorkerRegistration(
- origin, service_worker_registration_id, &deleted_notifications_set);
+ origin, service_worker_registration_id, &deleted_notifications_set);
UMA_HISTOGRAM_ENUMERATION(
- "Notifications.Database.DeleteServiceWorkerRegistrationResult",
- status, NotificationDatabase::STATUS_COUNT);
+ "Notifications.Database.DeleteServiceWorkerRegistrationResult", status,
+ NotificationDatabase::STATUS_COUNT);
// Blow away the database if a corruption error occurred during the deletion.
if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
@@ -319,8 +300,9 @@ void PlatformNotificationContextImpl::
void PlatformNotificationContextImpl::OnStorageWiped() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LazyInitialize(
- base::Bind(base::IgnoreResult(
- &PlatformNotificationContextImpl::DestroyDatabase), this),
+ base::Bind(
+ base::IgnoreResult(&PlatformNotificationContextImpl::DestroyDatabase),
+ this),
base::Bind(&DoNothing));
}
@@ -337,9 +319,8 @@ void PlatformNotificationContextImpl::LazyInitialize(
}
task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&PlatformNotificationContextImpl::OpenDatabase,
- this, success_closure, failure_closure));
+ FROM_HERE, base::Bind(&PlatformNotificationContextImpl::OpenDatabase,
+ this, success_closure, failure_closure));
}
void PlatformNotificationContextImpl::OpenDatabase(
@@ -356,8 +337,8 @@ void PlatformNotificationContextImpl::OpenDatabase(
NotificationDatabase::Status status =
database_->Open(true /* create_if_missing */);
- UMA_HISTOGRAM_ENUMERATION("Notifications.Database.OpenResult",
- status, NotificationDatabase::STATUS_COUNT);
+ UMA_HISTOGRAM_ENUMERATION("Notifications.Database.OpenResult", status,
+ NotificationDatabase::STATUS_COUNT);
// TODO(peter): Do finer-grained synchronization here.
if (prune_database_on_open_) {
@@ -379,8 +360,8 @@ void PlatformNotificationContextImpl::OpenDatabase(
status = database_->Open(true /* create_if_missing */);
UMA_HISTOGRAM_ENUMERATION(
- "Notifications.Database.OpenAfterCorruptionResult",
- status, NotificationDatabase::STATUS_COUNT);
+ "Notifications.Database.OpenAfterCorruptionResult", status,
+ NotificationDatabase::STATUS_COUNT);
}
}
@@ -399,8 +380,8 @@ bool PlatformNotificationContextImpl::DestroyDatabase() {
DCHECK(database_);
NotificationDatabase::Status status = database_->Destroy();
- UMA_HISTOGRAM_ENUMERATION("Notifications.Database.DestroyResult",
- status, NotificationDatabase::STATUS_COUNT);
+ UMA_HISTOGRAM_ENUMERATION("Notifications.Database.DestroyResult", status,
+ NotificationDatabase::STATUS_COUNT);
database_.reset();
diff --git a/chromium/content/browser/notifications/platform_notification_context_impl.h b/chromium/content/browser/notifications/platform_notification_context_impl.h
index 98e781856fb..250a2d83598 100644
--- a/chromium/content/browser/notifications/platform_notification_context_impl.h
+++ b/chromium/content/browser/notifications/platform_notification_context_impl.h
@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/service_worker/service_worker_context_observer.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/notifications/platform_notification_context_unittest.cc b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
index 4560f7d5c18..c3a2e543a2b 100644
--- a/chromium/content/browser/notifications/platform_notification_context_unittest.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
@@ -19,21 +21,17 @@
namespace content {
-// Fake render process id to use in tests requiring one.
-const int kFakeRenderProcessId = 99;
-
// Fake Service Worker registration id to use in tests requiring one.
const int64_t kFakeServiceWorkerRegistrationId = 42;
class PlatformNotificationContextTest : public ::testing::Test {
public:
PlatformNotificationContextTest()
- : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- success_(false) {}
+ : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), success_(false) {}
// Callback to provide when reading a single notification from the database.
- void DidReadNotificationData(
- bool success, const NotificationDatabaseData& database_data) {
+ void DidReadNotificationData(bool success,
+ const NotificationDatabaseData& database_data) {
success_ = success;
database_data_ = database_data;
}
@@ -45,9 +43,7 @@ class PlatformNotificationContextTest : public ::testing::Test {
}
// Callback to provide when deleting notification data from the database.
- void DidDeleteNotificationData(bool success) {
- success_ = success;
- }
+ void DidDeleteNotificationData(bool success) { success_ = success; }
// Callback to provide when registering a Service Worker with a Service
// Worker Context. Will write the registration id to |store_registration_id|.
@@ -88,8 +84,7 @@ class PlatformNotificationContextTest : public ::testing::Test {
// current message loop proxy will be used as the task runner.
PlatformNotificationContextImpl* CreatePlatformNotificationContext() {
PlatformNotificationContextImpl* context =
- new PlatformNotificationContextImpl(base::FilePath(),
- &browser_context_,
+ new PlatformNotificationContextImpl(base::FilePath(), &browser_context_,
nullptr);
context->Initialize();
@@ -132,8 +127,7 @@ TEST_F(PlatformNotificationContextTest, ReadNonExistentNotification) {
CreatePlatformNotificationContext();
context->ReadNotificationData(
- 42 /* notification_id */,
- GURL("https://example.com"),
+ 42 /* notification_id */, GURL("https://example.com"),
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -152,8 +146,7 @@ TEST_F(PlatformNotificationContextTest, WriteReadNotification) {
notification_database_data.origin = origin;
context->WriteNotificationData(
- origin,
- notification_database_data,
+ origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -164,8 +157,7 @@ TEST_F(PlatformNotificationContextTest, WriteReadNotification) {
EXPECT_GT(notification_id(), 0);
context->ReadNotificationData(
- notification_id(),
- origin,
+ notification_id(), origin,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -183,8 +175,7 @@ TEST_F(PlatformNotificationContextTest, DeleteInvalidNotification) {
CreatePlatformNotificationContext();
context->DeleteNotificationData(
- 42 /* notification_id */,
- GURL("https://example.com"),
+ 42 /* notification_id */, GURL("https://example.com"),
base::Bind(&PlatformNotificationContextTest::DidDeleteNotificationData,
base::Unretained(this)));
@@ -204,8 +195,7 @@ TEST_F(PlatformNotificationContextTest, DeleteNotification) {
NotificationDatabaseData notification_database_data;
context->WriteNotificationData(
- origin,
- notification_database_data,
+ origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -216,8 +206,7 @@ TEST_F(PlatformNotificationContextTest, DeleteNotification) {
EXPECT_GT(notification_id(), 0);
context->DeleteNotificationData(
- notification_id(),
- origin,
+ notification_id(), origin,
base::Bind(&PlatformNotificationContextTest::DidDeleteNotificationData,
base::Unretained(this)));
@@ -227,8 +216,7 @@ TEST_F(PlatformNotificationContextTest, DeleteNotification) {
ASSERT_TRUE(success());
context->ReadNotificationData(
- notification_id(),
- origin,
+ notification_id(), origin,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -241,14 +229,13 @@ TEST_F(PlatformNotificationContextTest, DeleteNotification) {
TEST_F(PlatformNotificationContextTest, ServiceWorkerUnregistered) {
scoped_ptr<EmbeddedWorkerTestHelper> embedded_worker_test_helper(
- new EmbeddedWorkerTestHelper(base::FilePath(), kFakeRenderProcessId));
+ new EmbeddedWorkerTestHelper(base::FilePath()));
// Manually create the PlatformNotificationContextImpl so that the Service
// Worker context wrapper can be passed in.
scoped_refptr<PlatformNotificationContextImpl> notification_context(
new PlatformNotificationContextImpl(
- base::FilePath(),
- browser_context(),
+ base::FilePath(), browser_context(),
embedded_worker_test_helper->context_wrapper()));
notification_context->Initialize();
@@ -261,9 +248,7 @@ TEST_F(PlatformNotificationContextTest, ServiceWorkerUnregistered) {
// Register a Service Worker to get a valid registration id.
embedded_worker_test_helper->context()->RegisterServiceWorker(
- origin,
- script_url,
- nullptr /* provider_host */,
+ origin, script_url, nullptr /* provider_host */,
base::Bind(&PlatformNotificationContextTest::DidRegisterServiceWorker,
base::Unretained(this), &service_worker_registration_id));
@@ -275,8 +260,7 @@ TEST_F(PlatformNotificationContextTest, ServiceWorkerUnregistered) {
// Create a notification for that Service Worker registration.
notification_context->WriteNotificationData(
- origin,
- notification_database_data,
+ origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -298,8 +282,7 @@ TEST_F(PlatformNotificationContextTest, ServiceWorkerUnregistered) {
// And verify that the associated notification has indeed been dropped.
notification_context->ReadNotificationData(
- notification_id(),
- origin,
+ notification_id(), origin,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -316,8 +299,7 @@ TEST_F(PlatformNotificationContextTest, DestroyDatabaseOnStorageWiped) {
NotificationDatabaseData notification_database_data;
context->WriteNotificationData(
- origin,
- notification_database_data,
+ origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -335,8 +317,7 @@ TEST_F(PlatformNotificationContextTest, DestroyDatabaseOnStorageWiped) {
// exist anymore. Deliberately omit RunUntilIdle(), since this is unlikely to
// be the case when OnStorageWiped gets called in production.
context->ReadNotificationData(
- notification_id(),
- origin,
+ notification_id(), origin,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -353,15 +334,13 @@ TEST_F(PlatformNotificationContextTest, DestroyOnDiskDatabase) {
// requires the database to be created on the filesystem.
scoped_refptr<PlatformNotificationContextImpl> context(
new PlatformNotificationContextImpl(database_dir.path(),
- browser_context(),
- nullptr));
+ browser_context(), nullptr));
OverrideTaskRunnerForTesting(context.get());
// Trigger a read-operation to force creating the database.
context->ReadNotificationData(
- 42 /* notification_id */,
- GURL("https://example.com"),
+ 42 /* notification_id */, GURL("https://example.com"),
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -387,11 +366,9 @@ TEST_F(PlatformNotificationContextTest, ReadAllServiceWorkerDataEmpty) {
std::vector<NotificationDatabaseData> notification_database_datas;
context->ReadAllNotificationDataForServiceWorkerRegistration(
- origin,
- kFakeServiceWorkerRegistrationId,
+ origin, kFakeServiceWorkerRegistrationId,
base::Bind(&PlatformNotificationContextTest::DidReadAllNotificationDatas,
- base::Unretained(this),
- &notification_database_datas));
+ base::Unretained(this), &notification_database_datas));
base::RunLoop().RunUntilIdle();
@@ -414,8 +391,7 @@ TEST_F(PlatformNotificationContextTest, ReadAllServiceWorkerDataFilled) {
// test Service Worker Registration id.
for (int i = 0; i < 10; ++i) {
context->WriteNotificationData(
- origin,
- notification_database_data,
+ origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -428,11 +404,9 @@ TEST_F(PlatformNotificationContextTest, ReadAllServiceWorkerDataFilled) {
// all set with the correct origin and Service Worker Registration id.
std::vector<NotificationDatabaseData> notification_database_datas;
context->ReadAllNotificationDataForServiceWorkerRegistration(
- origin,
- kFakeServiceWorkerRegistrationId,
+ origin, kFakeServiceWorkerRegistrationId,
base::Bind(&PlatformNotificationContextTest::DidReadAllNotificationDatas,
- base::Unretained(this),
- &notification_database_datas));
+ base::Unretained(this), &notification_database_datas));
base::RunLoop().RunUntilIdle();
diff --git a/chromium/content/browser/pepper_flash_settings_helper_impl.h b/chromium/content/browser/pepper_flash_settings_helper_impl.h
index 9a5887ba31f..8d4edb6c22e 100644
--- a/chromium/content/browser/pepper_flash_settings_helper_impl.h
+++ b/chromium/content/browser/pepper_flash_settings_helper_impl.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_PEPPER_FLASH_SETTINGS_HELPER_IMPL_H_
#define CONTENT_BROWSER_PEPPER_FLASH_SETTINGS_HELPER_IMPL_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/public/browser/pepper_flash_settings_helper.h"
diff --git a/chromium/content/browser/permissions/permission_service_context.cc b/chromium/content/browser/permissions/permission_service_context.cc
index ec8c386b03f..91bd4d04ac1 100644
--- a/chromium/content/browser/permissions/permission_service_context.cc
+++ b/chromium/content/browser/permissions/permission_service_context.cc
@@ -4,6 +4,8 @@
#include "content/browser/permissions/permission_service_context.h"
+#include <utility>
+
#include "content/browser/permissions/permission_service_impl.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/render_frame_host.h"
@@ -31,7 +33,7 @@ PermissionServiceContext::~PermissionServiceContext() {
void PermissionServiceContext::CreateService(
mojo::InterfaceRequest<PermissionService> request) {
- services_.push_back(new PermissionServiceImpl(this, request.Pass()));
+ services_.push_back(new PermissionServiceImpl(this, std::move(request)));
}
void PermissionServiceContext::ServiceHadConnectionError(
diff --git a/chromium/content/browser/permissions/permission_service_context.h b/chromium/content/browser/permissions/permission_service_context.h
index ac54efb73ff..0534ae1b61d 100644
--- a/chromium/content/browser/permissions/permission_service_context.h
+++ b/chromium/content/browser/permissions/permission_service_context.h
@@ -8,7 +8,7 @@
#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "content/public/browser/web_contents_observer.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
namespace content {
diff --git a/chromium/content/browser/permissions/permission_service_impl.cc b/chromium/content/browser/permissions/permission_service_impl.cc
index 4d16c06c43b..ce1f25f92ad 100644
--- a/chromium/content/browser/permissions/permission_service_impl.cc
+++ b/chromium/content/browser/permissions/permission_service_impl.cc
@@ -4,6 +4,9 @@
#include "content/browser/permissions/permission_service_impl.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/bind.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/permission_manager.h"
@@ -39,21 +42,33 @@ PermissionType PermissionNameToPermissionType(PermissionName name) {
return PermissionType::NUM;
}
+// This function allows the usage of the the multiple request map
+// with single requests.
+void PermissionRequestResponseCallbackWrapper(
+ const mojo::Callback<void(PermissionStatus)>& callback,
+ const mojo::Array<PermissionStatus>& vector) {
+ DCHECK_EQ(vector.size(), 1ul);
+ callback.Run(vector[0]);
+}
+
} // anonymous namespace
PermissionServiceImpl::PendingRequest::PendingRequest(
- PermissionType permission,
- const GURL& origin,
- const PermissionStatusCallback& callback)
- : id(PermissionManager::kNoPendingOperation),
- permission(permission),
- origin(origin),
- callback(callback) {
+ const PermissionsStatusCallback& callback,
+ int request_count)
+ : callback(callback),
+ request_count(request_count) {
}
PermissionServiceImpl::PendingRequest::~PendingRequest() {
- if (!callback.is_null())
- callback.Run(PERMISSION_STATUS_ASK);
+ if (callback.is_null())
+ return;
+
+ mojo::Array<PermissionStatus> result =
+ mojo::Array<PermissionStatus>::New(request_count);
+ for (int i = 0; i < request_count; ++i)
+ result[i] = PERMISSION_STATUS_DENIED;
+ callback.Run(std::move(result));
}
PermissionServiceImpl::PendingSubscription::PendingSubscription(
@@ -75,7 +90,7 @@ PermissionServiceImpl::PermissionServiceImpl(
PermissionServiceContext* context,
mojo::InterfaceRequest<PermissionService> request)
: context_(context),
- binding_(this, request.Pass()),
+ binding_(this, std::move(request)),
weak_factory_(this) {
binding_.set_connection_error_handler(
base::Bind(&PermissionServiceImpl::OnConnectionError,
@@ -103,26 +118,18 @@ void PermissionServiceImpl::RequestPermission(
// can. Even if the call comes from a context where it is not possible to show
// any UI, we want to still return something relevant so the current
// permission status is returned.
- if (!context_->render_frame_host()) {
- // There is no way to show a UI so the call will simply return the current
- // permission.
- HasPermission(permission, origin, callback);
- return;
- }
-
BrowserContext* browser_context = context_->GetBrowserContext();
DCHECK(browser_context);
- if (!browser_context->GetPermissionManager()) {
- callback.Run(content::PERMISSION_STATUS_DENIED);
+ if (!context_->render_frame_host() ||
+ !browser_context->GetPermissionManager()) {
+ callback.Run(GetPermissionStatusFromName(permission, GURL(origin)));
return;
}
- PermissionType permission_type = PermissionNameToPermissionType(permission);
- int pending_request_id = pending_requests_.Add(
- new PendingRequest(permission_type, GURL(origin), callback));
-
+ int pending_request_id = pending_requests_.Add(new PendingRequest(
+ base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1));
int id = browser_context->GetPermissionManager()->RequestPermission(
- permission_type,
+ PermissionNameToPermissionType(permission),
context_->render_frame_host(),
GURL(origin),
user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
@@ -139,28 +146,73 @@ void PermissionServiceImpl::RequestPermission(
pending_request->id = id;
}
+void PermissionServiceImpl::OnRequestPermissionResponse(
+ int pending_request_id,
+ PermissionStatus status) {
+ OnRequestPermissionsResponse(pending_request_id,
+ std::vector<PermissionStatus>(1, status));
+}
+
void PermissionServiceImpl::RequestPermissions(
mojo::Array<PermissionName> permissions,
const mojo::String& origin,
bool user_gesture,
const PermissionsStatusCallback& callback) {
- // TODO(lalitm,mlamouri): this is returning the current permission statuses
- // in order for the call to successfully return. It will be changed later.
- // See https://crbug.com/516626
- mojo::Array<PermissionStatus> result(permissions.size());
- for (size_t i = 0; i < permissions.size(); ++i)
- result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin));
- callback.Run(result.Pass());
+ if (permissions.is_null()) {
+ callback.Run(mojo::Array<PermissionStatus>());
+ return;
+ }
+
+ // This condition is valid if the call is coming from a ChildThread instead of
+ // a RenderFrame. Some consumers of the service run in Workers and some in
+ // Frames. In the context of a Worker, it is not possible to show a
+ // permission prompt because there is no tab. In the context of a Frame, we
+ // can. Even if the call comes from a context where it is not possible to show
+ // any UI, we want to still return something relevant so the current
+ // permission status is returned for each permission.
+ BrowserContext* browser_context = context_->GetBrowserContext();
+ DCHECK(browser_context);
+ if (!context_->render_frame_host() ||
+ !browser_context->GetPermissionManager()) {
+ mojo::Array<PermissionStatus> result(permissions.size());
+ for (size_t i = 0; i < permissions.size(); ++i)
+ result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin));
+ callback.Run(std::move(result));
+ return;
+ }
+
+ std::vector<PermissionType> types(permissions.size());
+ for (size_t i = 0; i < types.size(); ++i)
+ types[i] = PermissionNameToPermissionType(permissions[i]);
+
+ int pending_request_id = pending_requests_.Add(
+ new PendingRequest(callback, permissions.size()));
+ int id = browser_context->GetPermissionManager()->RequestPermissions(
+ types,
+ context_->render_frame_host(),
+ GURL(origin),
+ user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
+ base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse,
+ weak_factory_.GetWeakPtr(),
+ pending_request_id));
+
+ // Check if the request still exists. It may have been removed by the
+ // the response callback.
+ PendingRequest* pending_request = pending_requests_.Lookup(
+ pending_request_id);
+ if (!pending_request)
+ return;
+ pending_request->id = id;
}
-void PermissionServiceImpl::OnRequestPermissionResponse(
- int request_id,
- PermissionStatus status) {
- PendingRequest* request = pending_requests_.Lookup(request_id);
- PermissionStatusCallback callback(request->callback);
+void PermissionServiceImpl::OnRequestPermissionsResponse(
+ int pending_request_id,
+ const std::vector<PermissionStatus>& result) {
+ PendingRequest* request = pending_requests_.Lookup(pending_request_id);
+ PermissionsStatusCallback callback(request->callback);
request->callback.reset();
- pending_requests_.Remove(request_id);
- callback.Run(status);
+ pending_requests_.Remove(pending_request_id);
+ callback.Run(mojo::Array<PermissionStatus>::From(result));
}
void PermissionServiceImpl::CancelPendingOperations() {
diff --git a/chromium/content/browser/permissions/permission_service_impl.h b/chromium/content/browser/permissions/permission_service_impl.h
index 26321870d3d..13761daca2f 100644
--- a/chromium/content/browser/permissions/permission_service_impl.h
+++ b/chromium/content/browser/permissions/permission_service_impl.h
@@ -10,7 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "content/browser/permissions/permission_service_context.h"
#include "content/common/permission_service.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding.h"
namespace content {
@@ -44,15 +44,14 @@ class PermissionServiceImpl : public PermissionService {
mojo::Callback<void(mojo::Array<PermissionStatus>)>;
struct PendingRequest {
- PendingRequest(PermissionType permission, const GURL& origin,
- const PermissionStatusCallback& callback);
+ PendingRequest(const PermissionsStatusCallback& callback,
+ int request_count);
~PendingRequest();
// Request ID received from the PermissionManager.
int id;
- PermissionType permission;
- GURL origin;
- PermissionStatusCallback callback;
+ PermissionsStatusCallback callback;
+ int request_count;
};
using RequestsMap = IDMap<PendingRequest, IDMapOwnPointer>;
@@ -92,7 +91,12 @@ class PermissionServiceImpl : public PermissionService {
void OnConnectionError();
- void OnRequestPermissionResponse(int request_id, PermissionStatus status);
+ void OnRequestPermissionResponse(
+ int pending_request_id,
+ PermissionStatus status);
+ void OnRequestPermissionsResponse(
+ int pending_request_id,
+ const std::vector<PermissionStatus>& result);
PermissionStatus GetPermissionStatusFromName(PermissionName permission,
const GURL& origin);
diff --git a/chromium/content/browser/plugin_content_origin_whitelist.h b/chromium/content/browser/plugin_content_origin_whitelist.h
index beaab513c3d..fbeab395647 100644
--- a/chromium/content/browser/plugin_content_origin_whitelist.h
+++ b/chromium/content/browser/plugin_content_origin_whitelist.h
@@ -7,6 +7,7 @@
#include <set>
+#include "base/macros.h"
#include "content/public/browser/web_contents_observer.h"
#include "url/origin.h"
diff --git a/chromium/content/browser/plugin_data_remover_impl.cc b/chromium/content/browser/plugin_data_remover_impl.cc
index d0cb9acb2bf..fa0aab250c0 100644
--- a/chromium/content/browser/plugin_data_remover_impl.cc
+++ b/chromium/content/browser/plugin_data_remover_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/plugin_data_remover_impl.h"
+#include <stdint.h>
+
#include <limits>
#include "base/bind.h"
@@ -12,6 +14,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/version.h"
+#include "build/build_config.h"
#include "content/browser/plugin_process_host.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h"
@@ -30,8 +33,8 @@ namespace {
// The minimum Flash Player version that implements NPP_ClearSiteData.
const char kMinFlashVersion[] = "10.3";
-const int64 kRemovalTimeoutMs = 10000;
-const uint64 kClearAllData = 0;
+const int64_t kRemovalTimeoutMs = 10000;
+const uint64_t kClearAllData = 0;
} // namespace
@@ -200,7 +203,7 @@ class PluginDataRemoverImpl::Context
friend class base::DeleteHelper<Context>;
~Context() override {}
- IPC::Message* CreatePpapiClearSiteDataMsg(uint64 max_age) {
+ IPC::Message* CreatePpapiClearSiteDataMsg(uint64_t max_age) {
base::FilePath profile_path =
PepperFlashFileMessageFilter::GetDataDirName(browser_context_path_);
// TODO(vtl): This "duplicates" logic in webkit/plugins/ppapi/file_path.cc
@@ -234,9 +237,9 @@ class PluginDataRemoverImpl::Context
return;
}
- uint64 max_age = begin_time_.is_null() ?
- std::numeric_limits<uint64>::max() :
- (base::Time::Now() - begin_time_).InSeconds();
+ uint64_t max_age = begin_time_.is_null()
+ ? std::numeric_limits<uint64_t>::max()
+ : (base::Time::Now() - begin_time_).InSeconds();
IPC::Message* msg;
if (is_ppapi) {
@@ -254,7 +257,7 @@ class PluginDataRemoverImpl::Context
// Handles the PpapiHostMsg_ClearSiteDataResult message by delegating to the
// PluginProcessHostMsg_ClearSiteDataResult handler.
- void OnPpapiClearSiteDataResult(uint32 request_id, bool success) {
+ void OnPpapiClearSiteDataResult(uint32_t request_id, bool success) {
DCHECK_EQ(0u, request_id);
OnClearSiteDataResult(success);
}
diff --git a/chromium/content/browser/plugin_data_remover_impl.h b/chromium/content/browser/plugin_data_remover_impl.h
index ed2b7ea3163..7baa087c963 100644
--- a/chromium/content/browser/plugin_data_remover_impl.h
+++ b/chromium/content/browser/plugin_data_remover_impl.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "content/public/browser/plugin_data_remover.h"
diff --git a/chromium/content/browser/plugin_loader_posix.cc b/chromium/content/browser/plugin_loader_posix.cc
index 65f42a9e2e6..dcfb55812ef 100644
--- a/chromium/content/browser/plugin_loader_posix.cc
+++ b/chromium/content/browser/plugin_loader_posix.cc
@@ -161,7 +161,7 @@ void PluginLoaderPosix::GetPluginsWrapper(
GetPlugins(callback);
}
-void PluginLoaderPosix::OnPluginLoaded(uint32 index,
+void PluginLoaderPosix::OnPluginLoaded(uint32_t index,
const WebPluginInfo& plugin) {
if (index != next_load_index_) {
LOG(ERROR) << "Received unexpected plugin load message for "
@@ -183,7 +183,7 @@ void PluginLoaderPosix::OnPluginLoaded(uint32 index,
FinishedLoadingPlugins();
}
-void PluginLoaderPosix::OnPluginLoadFailed(uint32 index,
+void PluginLoaderPosix::OnPluginLoadFailed(uint32_t index,
const base::FilePath& plugin_path) {
if (index != next_load_index_) {
LOG(ERROR) << "Received unexpected plugin load failure message for "
diff --git a/chromium/content/browser/plugin_loader_posix.h b/chromium/content/browser/plugin_loader_posix.h
index 2db16341b0d..51814131fcf 100644
--- a/chromium/content/browser/plugin_loader_posix.h
+++ b/chromium/content/browser/plugin_loader_posix.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_PLUGIN_LOADER_POSIX_H_
#define CONTENT_BROWSER_PLUGIN_LOADER_POSIX_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "content/browser/plugin_service_impl.h"
@@ -74,8 +77,8 @@ class CONTENT_EXPORT PluginLoaderPosix
const std::vector<WebPluginInfo>& plugins_unused);
// Message handlers.
- void OnPluginLoaded(uint32 index, const WebPluginInfo& plugin);
- void OnPluginLoadFailed(uint32 index, const base::FilePath& plugin_path);
+ void OnPluginLoaded(uint32_t index, const WebPluginInfo& plugin);
+ void OnPluginLoadFailed(uint32_t index, const base::FilePath& plugin_path);
// Returns an iterator to the plugin in |internal_plugins_| whose path
// matches |plugin_path|.
diff --git a/chromium/content/browser/plugin_loader_posix_unittest.cc b/chromium/content/browser/plugin_loader_posix_unittest.cc
index 9b7e29b8248..ec1fa0b51f7 100644
--- a/chromium/content/browser/plugin_loader_posix_unittest.cc
+++ b/chromium/content/browser/plugin_loader_posix_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/plugin_loader_posix.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/at_exit.h"
#include "base/bind.h"
#include "base/files/file_path.h"
@@ -54,11 +57,11 @@ class MockPluginLoaderPosix : public PluginLoaderPosix {
return false;
}
- void TestOnPluginLoaded(uint32 index, const WebPluginInfo& plugin) {
+ void TestOnPluginLoaded(uint32_t index, const WebPluginInfo& plugin) {
OnPluginLoaded(index, plugin);
}
- void TestOnPluginLoadFailed(uint32 index, const base::FilePath& path) {
+ void TestOnPluginLoadFailed(uint32_t index, const base::FilePath& path) {
OnPluginLoadFailed(index, path);
}
diff --git a/chromium/content/browser/plugin_process_host.cc b/chromium/content/browser/plugin_process_host.cc
index 7cc5d8730db..9ede7a2cf42 100644
--- a/chromium/content/browser/plugin_process_host.cc
+++ b/chromium/content/browser/plugin_process_host.cc
@@ -4,12 +4,9 @@
#include "content/browser/plugin_process_host.h"
-#if defined(OS_WIN)
-#include <windows.h>
-#elif defined(OS_POSIX)
-#include <utility> // for pair<>
-#endif
+#include <stddef.h>
+#include <utility>
#include <vector>
#include "base/base_switches.h"
@@ -18,11 +15,13 @@
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
+#include "build/build_config.h"
#include "components/tracing/tracing_switches.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
@@ -46,6 +45,10 @@
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "ui/gfx/geometry/rect.h"
@@ -112,7 +115,7 @@ class PluginSandboxedProcessLauncherDelegate
}
#elif defined(OS_POSIX)
- base::ScopedFD TakeIpcFd() override { return ipc_fd_.Pass(); }
+ base::ScopedFD TakeIpcFd() override { return std::move(ipc_fd_); }
#endif // OS_WIN
private:
@@ -299,7 +302,7 @@ bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
-void PluginProcessHost::OnChannelConnected(int32 peer_pid) {
+void PluginProcessHost::OnChannelConnected(int32_t peer_pid) {
for (size_t i = 0; i < pending_requests_.size(); ++i) {
RequestPluginChannel(pending_requests_[i]);
}
@@ -422,11 +425,12 @@ void PluginProcessHost::OnChannelDestroyed(int renderer_id) {
resource_context_map_.erase(renderer_id);
}
-void PluginProcessHost::GetContexts(const ResourceHostMsg_Request& request,
+void PluginProcessHost::GetContexts(ResourceType resource_type,
+ int origin_pid,
ResourceContext** resource_context,
net::URLRequestContext** request_context) {
*resource_context =
- resource_context_map_[request.origin_pid].resource_context;
+ resource_context_map_[origin_pid].resource_context;
*request_context = (*resource_context)->GetRequestContext();
}
diff --git a/chromium/content/browser/plugin_process_host.h b/chromium/content/browser/plugin_process_host.h
index 1e8b67812ac..66ec73dfd8d 100644
--- a/chromium/content/browser/plugin_process_host.h
+++ b/chromium/content/browser/plugin_process_host.h
@@ -7,14 +7,16 @@
#include "build/build_config.h"
+#include <stdint.h>
+
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/process/process_handle.h"
#include "content/common/content_export.h"
@@ -88,7 +90,7 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHostDelegate,
void ForceShutdown();
bool OnMessageReceived(const IPC::Message& msg) override;
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
// Tells the plugin process to create a new channel for communication with a
@@ -141,9 +143,10 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHostDelegate,
#endif
#if defined(OS_MACOSX)
- void OnPluginShowWindow(uint32 window_id, gfx::Rect window_rect,
+ void OnPluginShowWindow(uint32_t window_id,
+ gfx::Rect window_rect,
bool modal);
- void OnPluginHideWindow(uint32 window_id, gfx::Rect window_rect);
+ void OnPluginHideWindow(uint32_t window_id, gfx::Rect window_rect);
void OnPluginSetCursorVisibility(bool visible);
#endif
@@ -153,7 +156,8 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHostDelegate,
void CancelRequests();
// Callback for ResourceMessageFilter.
- void GetContexts(const ResourceHostMsg_Request& request,
+ void GetContexts(ResourceType resource_type,
+ int origin_pid,
ResourceContext** resource_context,
net::URLRequestContext** request_context);
@@ -177,11 +181,11 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHostDelegate,
#endif
#if defined(OS_MACOSX)
// Tracks plugin windows currently visible.
- std::set<uint32> plugin_visible_windows_set_;
+ std::set<uint32_t> plugin_visible_windows_set_;
// Tracks full screen windows currently visible.
- std::set<uint32> plugin_fullscreen_windows_set_;
+ std::set<uint32_t> plugin_fullscreen_windows_set_;
// Tracks modal windows currently visible.
- std::set<uint32> plugin_modal_windows_set_;
+ std::set<uint32_t> plugin_modal_windows_set_;
// Tracks the current visibility of the cursor.
bool plugin_cursor_visible_;
#endif
diff --git a/chromium/content/browser/plugin_process_host_mac.cc b/chromium/content/browser/plugin_process_host_mac.cc
index c7ece477fbd..8bd04433bf9 100644
--- a/chromium/content/browser/plugin_process_host_mac.cc
+++ b/chromium/content/browser/plugin_process_host_mac.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <Carbon/Carbon.h>
+#include <stdint.h>
#include "build/build_config.h"
@@ -19,7 +20,7 @@
namespace content {
-void PluginProcessHost::OnPluginShowWindow(uint32 window_id,
+void PluginProcessHost::OnPluginShowWindow(uint32_t window_id,
gfx::Rect window_rect,
bool modal) {
plugin_visible_windows_set_.insert(window_id);
@@ -57,7 +58,7 @@ static void ReleasePluginFullScreen(pid_t plugin_pid) {
}
}
-void PluginProcessHost::OnPluginHideWindow(uint32 window_id,
+void PluginProcessHost::OnPluginHideWindow(uint32_t window_id,
gfx::Rect window_rect) {
bool had_windows = !plugin_visible_windows_set_.empty();
plugin_visible_windows_set_.erase(window_id);
diff --git a/chromium/content/browser/plugin_service_impl.cc b/chromium/content/browser/plugin_service_impl.cc
index 6fba93b7210..700d30428c7 100644
--- a/chromium/content/browser/plugin_service_impl.cc
+++ b/chromium/content/browser/plugin_service_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/plugin_service_impl.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
@@ -15,6 +17,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
+#include "build/build_config.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -174,7 +177,7 @@ PluginServiceImpl::~PluginServiceImpl() {
}
void PluginServiceImpl::Init() {
- plugin_list_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken();
+ plugin_list_token_ = base::SequencedWorkerPool::GetSequenceToken();
PluginList::Singleton()->set_will_load_plugins_callback(
base::Bind(&WillLoadPluginsCallback, plugin_list_token_));
diff --git a/chromium/content/browser/plugin_service_impl.h b/chromium/content/browser/plugin_service_impl.h
index 9f462ad54dc..644a26230a5 100644
--- a/chromium/content/browser/plugin_service_impl.h
+++ b/chromium/content/browser/plugin_service_impl.h
@@ -16,8 +16,8 @@
#include <set>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/singleton.h"
#include "base/synchronization/waitable_event_watcher.h"
diff --git a/chromium/content/browser/power_monitor_message_broadcaster.h b/chromium/content/browser/power_monitor_message_broadcaster.h
index 3221fadc690..4d81e0c4db4 100644
--- a/chromium/content/browser/power_monitor_message_broadcaster.h
+++ b/chromium/content/browser/power_monitor_message_broadcaster.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_
#define CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/power_monitor/power_observer.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/power_monitor_message_broadcaster_unittest.cc b/chromium/content/browser/power_monitor_message_broadcaster_unittest.cc
index 32deb1ea09b..72e272926ea 100644
--- a/chromium/content/browser/power_monitor_message_broadcaster_unittest.cc
+++ b/chromium/content/browser/power_monitor_message_broadcaster_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/test/power_monitor_test_base.h"
#include "content/browser/power_monitor_message_broadcaster.h"
#include "content/common/power_monitor_messages.h"
diff --git a/chromium/content/browser/power_profiler/power_data_provider.h b/chromium/content/browser/power_profiler/power_data_provider.h
deleted file mode 100644
index 897bc9b636c..00000000000
--- a/chromium/content/browser/power_profiler/power_data_provider.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_POWER_PROFILER_POWER_DATA_PROVIDER_H_
-#define CONTENT_BROWSER_POWER_PROFILER_POWER_DATA_PROVIDER_H_
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "content/browser/power_profiler/power_event.h"
-
-namespace base {
-class TimeDelta;
-} // namespace base
-
-namespace content {
-
-typedef std::vector<PowerEvent> PowerEventVector;
-
-// A class used to get power usage.
-class PowerDataProvider {
- public:
- enum AccuracyLevel {
- High,
- Moderate,
- Low
- };
-
- static scoped_ptr<PowerDataProvider> Create();
-
- PowerDataProvider() {}
- virtual ~PowerDataProvider() {}
-
- // Returns a vector of power events, one per type, for the types it supports.
- virtual PowerEventVector GetData() = 0;
-
- // Returns sampling rate at which the provider can operate.
- virtual base::TimeDelta GetSamplingRate() = 0;
-
- // Returns accuracy level of the provider.
- virtual AccuracyLevel GetAccuracyLevel() = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_POWER_PROFILER_POWER_DATA_PROVIDER_H_
diff --git a/chromium/content/browser/power_profiler/power_data_provider_dummy.cc b/chromium/content/browser/power_profiler/power_data_provider_dummy.cc
deleted file mode 100644
index 749f7c5066d..00000000000
--- a/chromium/content/browser/power_profiler/power_data_provider_dummy.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/power_profiler/power_data_provider.h"
-
-namespace content {
-
-scoped_ptr<PowerDataProvider> PowerDataProvider::Create() {
- return make_scoped_ptr<PowerDataProvider>(NULL);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/power_profiler/power_data_provider_ia_win.cc b/chromium/content/browser/power_profiler/power_data_provider_ia_win.cc
deleted file mode 100644
index e6509ea31f7..00000000000
--- a/chromium/content/browser/power_profiler/power_data_provider_ia_win.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/power_profiler/power_data_provider_ia_win.h"
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-
-namespace content {
-
-// Default sampling period, as recommended by Intel Power Gadget.
-// Section 3.1 of
-// http://software.intel.com/en-us/blogs/2013/10/03/using-the-intel-power-gadget-api-on-windows
-const int kDefaultSamplePeriodMs = 50;
-
-scoped_ptr<PowerDataProvider> PowerDataProvider::Create() {
- scoped_ptr<PowerDataProviderIA> provider(new PowerDataProviderIA());
- if (provider->Initialize())
- return make_scoped_ptr<PowerDataProvider>(provider.release());
-
- return make_scoped_ptr<PowerDataProvider>(NULL);
-}
-
-PowerDataProviderIA::PowerDataProviderIA()
- : sockets_number_(0),
- is_open_(false) {
- for (int i = 0; i < PowerEvent::ID_COUNT; i++ )
- power_msr_ids_[i] = -1;
-}
-
-PowerDataProviderIA::~PowerDataProviderIA() {
-}
-
-PowerEventVector PowerDataProviderIA::GetData() {
- PowerEventVector events;
-
- if (!energy_lib_.ReadSample())
- return events;
-
- PowerEvent event;
- double package_power = 0.0;
- double power[3];
- int data_count;
-
- for (int i = 0; i < sockets_number_; i++) {
- if (power_msr_ids_[PowerEvent::SOC_PACKAGE] == -1)
- break;
-
- energy_lib_.GetPowerData(i,
- power_msr_ids_[PowerEvent::SOC_PACKAGE], power, &data_count);
- package_power += power[0];
- }
-
- event.type = PowerEvent::SOC_PACKAGE;
- event.value = package_power;
- event.time = base::TimeTicks::Now();
- events.push_back(event);
-
- return events;
-}
-
-base::TimeDelta PowerDataProviderIA::GetSamplingRate() {
- return base::TimeDelta::FromMilliseconds(kDefaultSamplePeriodMs);
-}
-
-PowerDataProvider::AccuracyLevel PowerDataProviderIA::GetAccuracyLevel() {
- return High;
-}
-
-bool PowerDataProviderIA::Initialize() {
- if (is_open_)
- return true;
-
- if (!energy_lib_.IntelEnergyLibInitialize()) {
- LOG(ERROR) << "Power Data Provider initialize failed!";
- return false;
- }
-
- energy_lib_.GetNumNodes(&sockets_number_);
-
- const std::wstring package_msr_name = L"Processor";
-
- int msr_number;
- energy_lib_.GetNumMsrs(&msr_number);
-
- int func_id;
- wchar_t name[32];
- for(int i = 0; i < msr_number; i++) {
- energy_lib_.GetMsrFunc(i, &func_id);
- energy_lib_.GetMsrName(i, name);
-
- if (func_id != 1)
- continue;
-
- if (package_msr_name.compare(name) == 0)
- power_msr_ids_[PowerEvent::SOC_PACKAGE] = i;
- }
-
- is_open_ = true;
- return true;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/power_profiler/power_data_provider_ia_win.h b/chromium/content/browser/power_profiler/power_data_provider_ia_win.h
deleted file mode 100644
index 8356fecc538..00000000000
--- a/chromium/content/browser/power_profiler/power_data_provider_ia_win.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_POWER_PROFILER_POWER_DATA_PROVIDER_IA_WIN_H_
-#define CONTENT_BROWSER_POWER_PROFILER_POWER_DATA_PROVIDER_IA_WIN_H_
-
-#include "content/browser/power_profiler/power_data_provider.h"
-#include "third_party/power_gadget/PowerGadgetLib.h"
-
-namespace content {
-
-// A class used to get power usage via Power Gadget API.
-class PowerDataProviderIA : public PowerDataProvider {
- public:
- PowerDataProviderIA();
-
- ~PowerDataProviderIA() override;
-
- bool Initialize();
-
- // PowerDataProvider:
- PowerEventVector GetData() override;
- base::TimeDelta GetSamplingRate() override;
- AccuracyLevel GetAccuracyLevel() override;
-
- private:
- CIntelPowerGadgetLib energy_lib_;
-
- int sockets_number_;
- int power_msr_ids_[PowerEvent::ID_COUNT];
- bool is_open_;
- DISALLOW_COPY_AND_ASSIGN(PowerDataProviderIA);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_POWER_PROFILER_POWER_DATA_PROVIDER_IA_WIN_H_
diff --git a/chromium/content/browser/power_profiler/power_event.cc b/chromium/content/browser/power_profiler/power_event.cc
deleted file mode 100644
index f8c3eab15df..00000000000
--- a/chromium/content/browser/power_profiler/power_event.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/power_profiler/power_event.h"
-
-namespace content {
-
-const char* kPowerTypeNames[] = {
- "SoC_Package",
- "Device"
-};
-
-static_assert(arraysize(kPowerTypeNames) == PowerEvent::ID_COUNT,
- "kPowerTypeNames array has incorrect size");
-
-} // namespace content
diff --git a/chromium/content/browser/power_profiler/power_event.h b/chromium/content/browser/power_profiler/power_event.h
deleted file mode 100644
index b4031327a4f..00000000000
--- a/chromium/content/browser/power_profiler/power_event.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_POWER_PROFILER_POWER_EVENT_H_
-#define CONTENT_BROWSER_POWER_PROFILER_POWER_EVENT_H_
-
-#include "base/time/time.h"
-
-namespace content {
-
-struct PowerEvent {
- enum Type {
- // Total power of SoC. including CPU, GT and others on the chip,
- // modules which aren't part of the SoC such as the screen are not included.
- SOC_PACKAGE,
-
- // Whole device power.
- DEVICE,
-
- // Keep this at the end.
- ID_COUNT
- };
-
- Type type;
-
- base::TimeTicks time; // Time that power data was read.
-
- // Power value between last event and this one, in watts.
- // E.g, event1 {t1, v1}; event2 {t2, v2}; event3 {t3, v3}.
- // Suppose event1 is the first event the observer received, then event2,
- // event3. Then v2 is the average power from t1 to t2, v3 is the average
- // power from t2 to t3. v1 should be ignored since event1 only means the
- // start point of power profiling.
- double value;
-};
-
-extern const char* kPowerTypeNames[];
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_POWER_PROFILER_POWER_EVENT_H_
diff --git a/chromium/content/browser/power_profiler/power_profiler_observer.h b/chromium/content/browser/power_profiler/power_profiler_observer.h
deleted file mode 100644
index 027aa3a5606..00000000000
--- a/chromium/content/browser/power_profiler/power_profiler_observer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_POWER_PROFILER_POWER_PROFILER_OBSERVER_H_
-#define CONTENT_BROWSER_POWER_PROFILER_POWER_PROFILER_OBSERVER_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-struct PowerEvent;
-typedef std::vector<PowerEvent> PowerEventVector;
-
-// A class used to monitor power usage data.
-class CONTENT_EXPORT PowerProfilerObserver {
- public:
- PowerProfilerObserver() {}
- virtual ~PowerProfilerObserver() {}
-
- // This method will be called on the UI thread.
- virtual void OnPowerEvent(const PowerEventVector&) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PowerProfilerObserver);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_POWER_PROFILER_POWER_PROFILER_OBSERVER_H_
diff --git a/chromium/content/browser/power_profiler/power_profiler_service.cc b/chromium/content/browser/power_profiler/power_profiler_service.cc
deleted file mode 100644
index 97042386a7b..00000000000
--- a/chromium/content/browser/power_profiler/power_profiler_service.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/power_profiler/power_profiler_service.h"
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace content {
-
-PowerProfilerService::PowerProfilerService()
- : status_(UNINITIALIZED),
- data_provider_(PowerDataProvider::Create()) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // No provider supported for current platform.
- if (!data_provider_.get())
- return;
- sample_period_ = data_provider_->GetSamplingRate();
- status_ = INITIALIZED;
- task_runner_ = BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
- BrowserThread::GetBlockingPool()->GetSequenceToken());
-}
-
-PowerProfilerService::PowerProfilerService(
- scoped_ptr<PowerDataProvider> provider,
- scoped_refptr<base::TaskRunner> task_runner,
- const base::TimeDelta& sample_period)
- : task_runner_(task_runner),
- status_(UNINITIALIZED),
- sample_period_(sample_period),
- data_provider_(provider.Pass()) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- if (data_provider_.get())
- status_ = INITIALIZED;
-}
-
-PowerProfilerService::~PowerProfilerService() {
-}
-
-bool PowerProfilerService::IsAvailable() const {
- return status_ != UNINITIALIZED;
-}
-
-std::string PowerProfilerService::GetAccuracyLevel() const {
- DCHECK(IsAvailable());
- switch (data_provider_->GetAccuracyLevel()) {
- case PowerDataProvider::High:
- return "High";
- case PowerDataProvider::Moderate:
- return "Moderate";
- case PowerDataProvider::Low:
- return "Low";
- }
- return "";
-}
-
-PowerProfilerService* PowerProfilerService::GetInstance() {
- return base::Singleton<PowerProfilerService>::get();
-}
-
-void PowerProfilerService::AddObserver(PowerProfilerObserver* observer) {
- if (status_ == UNINITIALIZED)
- return;
-
- observers_.AddObserver(observer);
- if (status_ != PROFILING)
- Start();
-}
-
-void PowerProfilerService::RemoveObserver(PowerProfilerObserver* observer) {
- observers_.RemoveObserver(observer);
-
- if (status_ == PROFILING && !observers_.might_have_observers())
- Stop();
-}
-
-void PowerProfilerService::Start() {
- DCHECK(status_ == INITIALIZED);
- status_ = PROFILING;
-
- // Send out power events immediately.
- QueryData();
-
- query_power_timer_.Start(FROM_HERE,
- sample_period_, this, &PowerProfilerService::QueryData);
-}
-
-void PowerProfilerService::Stop() {
- DCHECK(status_ == PROFILING);
-
- query_power_timer_.Stop();
- status_ = INITIALIZED;
-}
-
-void PowerProfilerService::QueryData() {
- task_runner_->PostTask(
- FROM_HERE, base::Bind(&PowerProfilerService::QueryDataOnTaskRunner,
- base::Unretained(this)));
-}
-
-void PowerProfilerService::Notify(const PowerEventVector& events) {
- FOR_EACH_OBSERVER(PowerProfilerObserver, observers_, OnPowerEvent(events));
-}
-
-void PowerProfilerService::QueryDataOnTaskRunner() {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
- DCHECK(status_ == PROFILING);
-
- // Get data and notify.
- PowerEventVector events = data_provider_->GetData();
- if (events.size() != 0) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
- &PowerProfilerService::Notify, base::Unretained(this), events));
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/power_profiler/power_profiler_service.h b/chromium/content/browser/power_profiler/power_profiler_service.h
deleted file mode 100644
index c6f2ca6629e..00000000000
--- a/chromium/content/browser/power_profiler/power_profiler_service.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_POWER_PROFILER_POWER_PROFILER_SERVICE_H_
-#define CONTENT_BROWSER_POWER_PROFILER_POWER_PROFILER_SERVICE_H_
-
-#include "base/basictypes.h"
-#include "base/memory/singleton.h"
-#include "base/observer_list.h"
-#include "base/task_runner.h"
-#include "base/timer/timer.h"
-#include "content/browser/power_profiler/power_data_provider.h"
-#include "content/browser/power_profiler/power_profiler_observer.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// A class used to query power information and notify the observers.
-class CONTENT_EXPORT PowerProfilerService {
- public:
- static PowerProfilerService* GetInstance();
-
- // Add and remove an observer.
- void AddObserver(PowerProfilerObserver* observer);
- void RemoveObserver(PowerProfilerObserver* observer);
-
- bool IsAvailable() const;
- std::string GetAccuracyLevel() const;
-
- virtual ~PowerProfilerService();
-
- private:
- enum Status {
- UNINITIALIZED,
- INITIALIZED, // Initialized, profiling has not started.
- PROFILING
- };
-
- friend struct base::DefaultSingletonTraits<PowerProfilerService>;
- friend class PowerProfilerServiceTest;
-
- PowerProfilerService();
-
- PowerProfilerService(scoped_ptr<PowerDataProvider> provider,
- scoped_refptr<base::TaskRunner> task_runner,
- const base::TimeDelta& sample_period);
-
- void Start();
- void Stop();
-
- // Query power data from PowerDataProvider, executes on the WorkerPool thread.
- void QueryDataOnTaskRunner();
-
- // Initiate the query on the UI thread, the task is delegated to
- // QueryDataOnTaskRunner.
- void QueryData();
-
- // Executes on the UI thread.
- void Notify(const PowerEventVector&);
-
- base::RepeatingTimer query_power_timer_;
- scoped_refptr<base::TaskRunner> task_runner_;
-
- Status status_;
-
- // Sampling period of power data measurement.
- base::TimeDelta sample_period_;
- base::ObserverList<PowerProfilerObserver> observers_;
-
- scoped_ptr<PowerDataProvider> data_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(PowerProfilerService);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_POWER_PROFILER_POWER_PROFILER_SERVICE_H_
diff --git a/chromium/content/browser/power_profiler/power_profiler_service_unittest.cc b/chromium/content/browser/power_profiler/power_profiler_service_unittest.cc
deleted file mode 100644
index 96e96d14ac6..00000000000
--- a/chromium/content/browser/power_profiler/power_profiler_service_unittest.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/run_loop.h"
-#include "content/browser/browser_thread_impl.h"
-#include "content/browser/power_profiler/power_profiler_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-const int kNumEvents = 3;
-const int kDefaultSamplePeriodMs = 50;
-
-// Provide a set number of power events.
-class TestPowerDataProvider : public PowerDataProvider {
- public:
- TestPowerDataProvider(int count) : num_events_to_send_(count) {}
- ~TestPowerDataProvider() override {}
-
- PowerEventVector GetData() override {
- PowerEventVector events;
- if (num_events_to_send_ == 0)
- return events;
-
- PowerEvent event;
- event.type = PowerEvent::SOC_PACKAGE;
- event.time = base::TimeTicks::Now();
- event.value = 1.0;
- events.push_back(event);
-
- num_events_to_send_--;
- return events;
- }
-
- base::TimeDelta GetSamplingRate() override {
- return base::TimeDelta::FromMilliseconds(kDefaultSamplePeriodMs);
- }
-
- AccuracyLevel GetAccuracyLevel() override { return High; }
-
- private:
- int num_events_to_send_;
- DISALLOW_COPY_AND_ASSIGN(TestPowerDataProvider);
-};
-
-class TestPowerProfilerObserver : public PowerProfilerObserver {
- public:
- TestPowerProfilerObserver()
- : valid_event_count_(0),
- total_num_events_received_(0) {}
- ~TestPowerProfilerObserver() override {}
-
- void OnPowerEvent(const PowerEventVector& events) override {
- if (IsValidEvent(events[0]))
- ++valid_event_count_;
-
- total_num_events_received_++;
- if (total_num_events_received_ >= kNumEvents) {
- // All expected events received, exiting.
- quit_closure_.Run();
- }
- }
-
- int valid_event_count() const { return valid_event_count_; }
- void set_quit_closure(base::Closure closure) { quit_closure_ = closure; }
-
- private:
- bool IsValidEvent(const PowerEvent& event) {
- return event.type == PowerEvent::SOC_PACKAGE &&
- !event.time.is_null() &&
- event.value > 0;
- }
-
- int valid_event_count_;
- int total_num_events_received_;
- base::Closure quit_closure_;
-
- DISALLOW_COPY_AND_ASSIGN(TestPowerProfilerObserver);
-};
-
-} // namespace
-
-class PowerProfilerServiceTest : public testing::Test {
- public:
- void ServiceStartTest() {
- service_.reset(new PowerProfilerService(
- make_scoped_ptr<PowerDataProvider>(
- new TestPowerDataProvider(kNumEvents)),
- message_loop_.task_runner(), base::TimeDelta::FromMilliseconds(1)));
- EXPECT_TRUE(service_->IsAvailable());
- }
-
- void AddObserverTest() {
- service_->AddObserver(&observer_);
-
- // No PowerEvents received.
- EXPECT_EQ(observer_.valid_event_count(), 0);
- }
-
- void RemoveObserverTest() {
- service_->RemoveObserver(&observer_);
-
- // Received |kNumEvents| events.
- EXPECT_EQ(observer_.valid_event_count(), kNumEvents);
- }
-
- protected:
- PowerProfilerServiceTest() : ui_thread_(BrowserThread::UI, &message_loop_) {}
- ~PowerProfilerServiceTest() override {}
-
- void RegisterQuitClosure(base::Closure closure) {
- observer_.set_quit_closure(closure);
- }
-
- private:
- scoped_ptr<PowerProfilerService> service_;
- TestPowerProfilerObserver observer_;
-
- // UI thread.
- base::MessageLoopForUI message_loop_;
- BrowserThreadImpl ui_thread_;
-
- DISALLOW_COPY_AND_ASSIGN(PowerProfilerServiceTest);
-};
-
-// Test whether PowerProfilerService dispatches power events to observer
-// properly.
-TEST_F(PowerProfilerServiceTest, AvailableService) {
- base::RunLoop run_loop;
- RegisterQuitClosure(run_loop.QuitClosure());
-
- ServiceStartTest();
- AddObserverTest();
-
- run_loop.Run();
-
- RemoveObserverTest();
-}
-
-} // namespace content
diff --git a/chromium/content/browser/power_save_blocker_android.cc b/chromium/content/browser/power_save_blocker_android.cc
index 20ea63ccc58..0adcd290d5e 100644
--- a/chromium/content/browser/power_save_blocker_android.cc
+++ b/chromium/content/browser/power_save_blocker_android.cc
@@ -4,6 +4,7 @@
#include "base/android/jni_android.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/power_save_blocker_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
diff --git a/chromium/content/browser/power_save_blocker_chromeos.cc b/chromium/content/browser/power_save_blocker_chromeos.cc
index 83c6e8aab23..bf50c898451 100644
--- a/chromium/content/browser/power_save_blocker_chromeos.cc
+++ b/chromium/content/browser/power_save_blocker_chromeos.cc
@@ -6,10 +6,10 @@
#include <string>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "chromeos/dbus/power_policy_controller.h"
#include "content/public/browser/browser_thread.h"
diff --git a/chromium/content/browser/power_save_blocker_impl.cc b/chromium/content/browser/power_save_blocker_impl.cc
index 416ddb334c4..b3f15fb58c7 100644
--- a/chromium/content/browser/power_save_blocker_impl.cc
+++ b/chromium/content/browser/power_save_blocker_impl.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "build/build_config.h"
#include "content/browser/power_save_blocker_impl.h"
namespace content {
@@ -13,8 +14,12 @@ scoped_ptr<PowerSaveBlocker> PowerSaveBlocker::Create(
PowerSaveBlockerType type,
Reason reason,
const std::string& description) {
+#if defined(OS_ANDROID) && defined(USE_AURA)
+ return nullptr;
+#else
return scoped_ptr<PowerSaveBlocker>(
new PowerSaveBlockerImpl(type, reason, description));
+#endif
}
} // namespace content
diff --git a/chromium/content/browser/power_save_blocker_impl.h b/chromium/content/browser/power_save_blocker_impl.h
index a30422646fe..a01fc60928a 100644
--- a/chromium/content/browser/power_save_blocker_impl.h
+++ b/chromium/content/browser/power_save_blocker_impl.h
@@ -7,7 +7,9 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "build/build_config.h"
#include "content/public/browser/power_save_blocker.h"
namespace content {
@@ -43,6 +45,13 @@ class PowerSaveBlockerImpl : public PowerSaveBlocker {
// };
scoped_refptr<Delegate> delegate_;
+#if defined(USE_X11)
+ // Since display sleep prevention also implies system suspend prevention, for
+ // the Linux FreeDesktop API case, there needs to be a second delegate to
+ // block system suspend when screen saver / display sleep is blocked.
+ scoped_refptr<Delegate> freedesktop_suspend_delegate_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerImpl);
};
diff --git a/chromium/content/browser/power_save_blocker_ozone.cc b/chromium/content/browser/power_save_blocker_ozone.cc
index 0ec03b1af19..c3102351774 100644
--- a/chromium/content/browser/power_save_blocker_ozone.cc
+++ b/chromium/content/browser/power_save_blocker_ozone.cc
@@ -4,6 +4,7 @@
#include "content/browser/power_save_blocker_impl.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
namespace content {
diff --git a/chromium/content/browser/power_save_blocker_win.cc b/chromium/content/browser/power_save_blocker_win.cc
index 6d2841146ba..32c61f29fb5 100644
--- a/chromium/content/browser/power_save_blocker_win.cc
+++ b/chromium/content/browser/power_save_blocker_win.cc
@@ -7,6 +7,7 @@
#include <windows.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
diff --git a/chromium/content/browser/power_save_blocker_x11.cc b/chromium/content/browser/power_save_blocker_x11.cc
index ef2acd16a12..97eefef9519 100644
--- a/chromium/content/browser/power_save_blocker_x11.cc
+++ b/chromium/content/browser/power_save_blocker_x11.cc
@@ -5,19 +5,20 @@
#include "content/browser/power_save_blocker_impl.h"
#include <X11/Xlib.h>
+#include <stdint.h>
#include <X11/extensions/dpms.h>
// Xlib #defines Status, but we can't have that for some of our headers.
#ifdef Status
#undef Status
#endif
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
@@ -52,12 +53,17 @@ const char kGnomeAPIServiceName[] = "org.gnome.SessionManager";
const char kGnomeAPIInterfaceName[] = "org.gnome.SessionManager";
const char kGnomeAPIObjectPath[] = "/org/gnome/SessionManager";
-const char kFreeDesktopAPIServiceName[] = "org.freedesktop.PowerManagement";
-const char kFreeDesktopAPIInterfaceName[] =
+const char kFreeDesktopAPIPowerServiceName[] =
+ "org.freedesktop.PowerManagement";
+const char kFreeDesktopAPIPowerInterfaceName[] =
"org.freedesktop.PowerManagement.Inhibit";
-const char kFreeDesktopAPIObjectPath[] =
+const char kFreeDesktopAPIPowerObjectPath[] =
"/org/freedesktop/PowerManagement/Inhibit";
+const char kFreeDesktopAPIScreenServiceName[] = "org.freedesktop.ScreenSaver";
+const char kFreeDesktopAPIScreenInterfaceName[] = "org.freedesktop.ScreenSaver";
+const char kFreeDesktopAPIScreenObjectPath[] = "/org/freedesktop/ScreenSaver";
+
} // namespace
namespace content {
@@ -66,7 +72,9 @@ class PowerSaveBlockerImpl::Delegate
: public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> {
public:
// Picks an appropriate D-Bus API to use based on the desktop environment.
- Delegate(PowerSaveBlockerType type, const std::string& description);
+ Delegate(PowerSaveBlockerType type,
+ const std::string& description,
+ bool freedesktop_only);
// Post a task to initialize the delegate on the UI thread, which will itself
// then post a task to apply the power save block on the FILE thread.
@@ -86,15 +94,18 @@ class PowerSaveBlockerImpl::Delegate
// enqueue_apply_ below.
void InitOnUIThread();
+ // Returns true if ApplyBlock() / RemoveBlock() should be called.
+ bool ShouldBlock() const;
+
// Apply or remove the power save block, respectively. These methods should be
// called once each, on the same thread, per instance. They block waiting for
// the action to complete (with a timeout); the thread must thus allow I/O.
- void ApplyBlock(DBusAPI api);
- void RemoveBlock(DBusAPI api);
+ void ApplyBlock();
+ void RemoveBlock();
// Asynchronous callback functions for ApplyBlock and RemoveBlock.
// Functions do not receive ownership of |response|.
- void ApplyBlockFinished(DBusAPI api, dbus::Response* response);
+ void ApplyBlockFinished(dbus::Response* response);
void RemoveBlockFinished(dbus::Response* response);
// If DPMS (the power saving system in X11) is not enabled, then we don't want
@@ -109,6 +120,7 @@ class PowerSaveBlockerImpl::Delegate
const PowerSaveBlockerType type_;
const std::string description_;
+ const bool freedesktop_only_;
// Initially, we post a message to the UI thread to select an API. When it
// finishes, it will post a message to the FILE thread to perform the actual
@@ -132,15 +144,17 @@ class PowerSaveBlockerImpl::Delegate
// The cookie that identifies our inhibit request,
// or 0 if there is no active inhibit request.
- uint32 inhibit_cookie_;
+ uint32_t inhibit_cookie_;
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
PowerSaveBlockerImpl::Delegate::Delegate(PowerSaveBlockerType type,
- const std::string& description)
+ const std::string& description,
+ bool freedesktop_only)
: type_(type),
description_(description),
+ freedesktop_only_(freedesktop_only),
api_(NO_API),
enqueue_apply_(false),
inhibit_cookie_(0) {
@@ -166,9 +180,9 @@ void PowerSaveBlockerImpl::Delegate::CleanUp() {
// initializing on the UI thread, then just cancel it. We don't need to
// remove the block because we haven't even applied it yet.
enqueue_apply_ = false;
- } else if (api_ != NO_API) {
+ } else if (ShouldBlock()) {
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&Delegate::RemoveBlock, this, api_));
+ base::Bind(&Delegate::RemoveBlock, this));
}
}
@@ -176,17 +190,21 @@ void PowerSaveBlockerImpl::Delegate::InitOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::AutoLock lock(lock_);
api_ = SelectAPI();
- if (enqueue_apply_ && api_ != NO_API) {
+ if (enqueue_apply_ && ShouldBlock()) {
// The thread we use here becomes the origin and D-Bus thread for the D-Bus
// library, so we need to use the same thread above for RemoveBlock(). It
// must be a thread that allows I/O operations, so we use the FILE thread.
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&Delegate::ApplyBlock, this, api_));
+ base::Bind(&Delegate::ApplyBlock, this));
}
enqueue_apply_ = false;
}
-void PowerSaveBlockerImpl::Delegate::ApplyBlock(DBusAPI api) {
+bool PowerSaveBlockerImpl::Delegate::ShouldBlock() const {
+ return freedesktop_only_ ? api_ == FREEDESKTOP_API : api_ != NO_API;
+}
+
+void PowerSaveBlockerImpl::Delegate::ApplyBlock() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(!bus_); // ApplyBlock() should only be called once.
DCHECK(!block_inflight_);
@@ -200,7 +218,7 @@ void PowerSaveBlockerImpl::Delegate::ApplyBlock(DBusAPI api) {
scoped_ptr<dbus::MethodCall> method_call;
scoped_ptr<dbus::MessageWriter> message_writer;
- switch (api) {
+ switch (api_) {
case NO_API:
NOTREACHED(); // We should never call this method with this value.
return;
@@ -221,7 +239,7 @@ void PowerSaveBlockerImpl::Delegate::ApplyBlock(DBusAPI api) {
message_writer->AppendUint32(0); // should be toplevel_xid
message_writer->AppendString(description_);
{
- uint32 flags = 0;
+ uint32_t flags = 0;
switch (type_) {
case kPowerSaveBlockPreventDisplaySleep:
flags |= INHIBIT_MARK_SESSION_IDLE;
@@ -235,11 +253,22 @@ void PowerSaveBlockerImpl::Delegate::ApplyBlock(DBusAPI api) {
}
break;
case FREEDESKTOP_API:
- object_proxy = bus_->GetObjectProxy(
- kFreeDesktopAPIServiceName,
- dbus::ObjectPath(kFreeDesktopAPIObjectPath));
- method_call.reset(
- new dbus::MethodCall(kFreeDesktopAPIInterfaceName, "Inhibit"));
+ switch (type_) {
+ case kPowerSaveBlockPreventDisplaySleep:
+ object_proxy = bus_->GetObjectProxy(
+ kFreeDesktopAPIScreenServiceName,
+ dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath));
+ method_call.reset(new dbus::MethodCall(
+ kFreeDesktopAPIScreenInterfaceName, "Inhibit"));
+ break;
+ case kPowerSaveBlockPreventAppSuspension:
+ object_proxy = bus_->GetObjectProxy(
+ kFreeDesktopAPIPowerServiceName,
+ dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath));
+ method_call.reset(new dbus::MethodCall(
+ kFreeDesktopAPIPowerInterfaceName, "Inhibit"));
+ break;
+ }
message_writer.reset(new dbus::MessageWriter(method_call.get()));
// The arguments of the method are:
// app_id: The application identifier
@@ -253,12 +282,10 @@ void PowerSaveBlockerImpl::Delegate::ApplyBlock(DBusAPI api) {
block_inflight_ = true;
object_proxy->CallMethod(
method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
- base::Bind(&PowerSaveBlockerImpl::Delegate::ApplyBlockFinished, this,
- api));
+ base::Bind(&PowerSaveBlockerImpl::Delegate::ApplyBlockFinished, this));
}
void PowerSaveBlockerImpl::Delegate::ApplyBlockFinished(
- DBusAPI api,
dbus::Response* response) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(bus_);
@@ -281,11 +308,11 @@ void PowerSaveBlockerImpl::Delegate::ApplyBlockFinished(
// RemoveBlock() was called while the Inhibit operation was in flight,
// so go ahead and remove the block now.
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&Delegate::RemoveBlock, this, api_));
+ base::Bind(&Delegate::RemoveBlock, this));
}
}
-void PowerSaveBlockerImpl::Delegate::RemoveBlock(DBusAPI api) {
+void PowerSaveBlockerImpl::Delegate::RemoveBlock() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(bus_); // RemoveBlock() should only be called once.
DCHECK(!unblock_inflight_);
@@ -301,7 +328,7 @@ void PowerSaveBlockerImpl::Delegate::RemoveBlock(DBusAPI api) {
scoped_refptr<dbus::ObjectProxy> object_proxy;
scoped_ptr<dbus::MethodCall> method_call;
- switch (api) {
+ switch (api_) {
case NO_API:
NOTREACHED(); // We should never call this method with this value.
return;
@@ -313,11 +340,22 @@ void PowerSaveBlockerImpl::Delegate::RemoveBlock(DBusAPI api) {
new dbus::MethodCall(kGnomeAPIInterfaceName, "Uninhibit"));
break;
case FREEDESKTOP_API:
- object_proxy = bus_->GetObjectProxy(
- kFreeDesktopAPIServiceName,
- dbus::ObjectPath(kFreeDesktopAPIObjectPath));
- method_call.reset(
- new dbus::MethodCall(kFreeDesktopAPIInterfaceName, "UnInhibit"));
+ switch (type_) {
+ case kPowerSaveBlockPreventDisplaySleep:
+ object_proxy = bus_->GetObjectProxy(
+ kFreeDesktopAPIScreenServiceName,
+ dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath));
+ method_call.reset(new dbus::MethodCall(
+ kFreeDesktopAPIScreenInterfaceName, "UnInhibit"));
+ break;
+ case kPowerSaveBlockPreventAppSuspension:
+ object_proxy = bus_->GetObjectProxy(
+ kFreeDesktopAPIPowerServiceName,
+ dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath));
+ method_call.reset(new dbus::MethodCall(
+ kFreeDesktopAPIPowerInterfaceName, "UnInhibit"));
+ break;
+ }
break;
}
@@ -342,11 +380,12 @@ void PowerSaveBlockerImpl::Delegate::RemoveBlockFinished(
inhibit_cookie_ = 0;
bus_->ShutdownAndBlock();
- bus_ = NULL;
+ bus_ = nullptr;
}
// static
bool PowerSaveBlockerImpl::Delegate::DPMSEnabled() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
XDisplay* display = gfx::GetXDisplay();
BOOL enabled = false;
int dummy;
@@ -359,6 +398,7 @@ bool PowerSaveBlockerImpl::Delegate::DPMSEnabled() {
// static
DBusAPI PowerSaveBlockerImpl::Delegate::SelectAPI() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
scoped_ptr<base::Environment> env(base::Environment::Create());
switch (base::nix::GetDesktopEnvironment(env.get())) {
case base::nix::DESKTOP_ENVIRONMENT_GNOME:
@@ -383,12 +423,21 @@ DBusAPI PowerSaveBlockerImpl::Delegate::SelectAPI() {
PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type,
Reason reason,
const std::string& description)
- : delegate_(new Delegate(type, description)) {
+ : delegate_(new Delegate(type, description, false /* freedesktop_only */)) {
delegate_->Init();
+
+ if (type == kPowerSaveBlockPreventDisplaySleep) {
+ freedesktop_suspend_delegate_ =
+ new Delegate(kPowerSaveBlockPreventAppSuspension, description,
+ true /* freedesktop_only */);
+ freedesktop_suspend_delegate_->Init();
+ }
}
PowerSaveBlockerImpl::~PowerSaveBlockerImpl() {
delegate_->CleanUp();
+ if (freedesktop_suspend_delegate_)
+ freedesktop_suspend_delegate_->CleanUp();
}
} // namespace content
diff --git a/chromium/content/browser/power_usage_monitor_impl.cc b/chromium/content/browser/power_usage_monitor_impl.cc
index fb294f3e0ca..65d4d9dd7a5 100644
--- a/chromium/content/browser/power_usage_monitor_impl.cc
+++ b/chromium/content/browser/power_usage_monitor_impl.cc
@@ -4,6 +4,9 @@
#include "content/browser/power_usage_monitor_impl.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
@@ -136,8 +139,7 @@ void PowerUsageMonitor::Start() {
// Delay initialization until the system has been up for a while.
// This is to mitigate the effect of increased power draw during system start.
- base::TimeDelta uptime =
- base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime());
+ base::TimeDelta uptime = base::SysInfo::Uptime();
base::TimeDelta min_uptime = base::TimeDelta::FromMinutes(kMinUptimeMinutes);
if (uptime < min_uptime) {
base::TimeDelta delay = min_uptime - uptime;
@@ -248,7 +250,7 @@ void PowerUsageMonitor::OnRenderProcessNotification(int type, int rph_id) {
void PowerUsageMonitor::SetSystemInterfaceForTest(
scoped_ptr<SystemInterface> interface) {
- system_interface_ = interface.Pass();
+ system_interface_ = std::move(interface);
}
void PowerUsageMonitor::OnPowerStateChange(bool on_battery_power) {
diff --git a/chromium/content/browser/power_usage_monitor_impl.h b/chromium/content/browser/power_usage_monitor_impl.h
index 9b95ae4d4ae..0e3b4e30274 100644
--- a/chromium/content/browser/power_usage_monitor_impl.h
+++ b/chromium/content/browser/power_usage_monitor_impl.h
@@ -5,9 +5,9 @@
#ifndef CONTENT_BROWSER_POWER_USAGE_MONITOR_IMPL_H_
#define CONTENT_BROWSER_POWER_USAGE_MONITOR_IMPL_H_
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/power_monitor/power_monitor.h"
#include "base/time/time.h"
diff --git a/chromium/content/browser/power_usage_monitor_impl_unittest.cc b/chromium/content/browser/power_usage_monitor_impl_unittest.cc
index efa46f2593a..2aac5859489 100644
--- a/chromium/content/browser/power_usage_monitor_impl_unittest.cc
+++ b/chromium/content/browser/power_usage_monitor_impl_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/power_usage_monitor_impl.h"
+#include <utility>
+
#include "content/public/browser/notification_types.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "device/battery/battery_monitor.mojom.h"
@@ -66,7 +68,7 @@ class PowerUsageMonitorTest : public testing::Test {
scoped_ptr<SystemInterfaceForTest> test_interface(
new SystemInterfaceForTest());
system_interface_ = test_interface.get();
- monitor_->SetSystemInterfaceForTest(test_interface.Pass());
+ monitor_->SetSystemInterfaceForTest(std::move(test_interface));
// Without live renderers, the monitor won't do anything.
monitor_->OnRenderProcessNotification(NOTIFICATION_RENDERER_PROCESS_CREATED,
diff --git a/chromium/content/browser/ppapi_plugin_process_host.cc b/chromium/content/browser/ppapi_plugin_process_host.cc
index 794a5a10803..74c6e0f75e2 100644
--- a/chromium/content/browser/ppapi_plugin_process_host.cc
+++ b/chromium/content/browser/ppapi_plugin_process_host.cc
@@ -4,14 +4,19 @@
#include "content/browser/ppapi_plugin_process_host.h"
+#include <stddef.h>
+
#include <string>
+#include <utility>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/renderer_host/render_message_filter.h"
@@ -31,6 +36,7 @@
#include "ui/base/ui_base_switches.h"
#if defined(OS_WIN)
+#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
#include "content/common/sandbox_win.h"
#include "sandbox/win/src/process_mitigations.h"
#include "sandbox/win/src/sandbox_policy.h"
@@ -46,7 +52,10 @@ class PpapiPluginSandboxedProcessLauncherDelegate
PpapiPluginSandboxedProcessLauncherDelegate(bool is_broker,
const PepperPluginInfo& info,
ChildProcessHost* host)
- : info_(info),
+ :
+#if defined(OS_WIN)
+ info_(info),
+#endif // OS_WIN
#if defined(OS_POSIX)
ipc_fd_(host->TakeClientFileDescriptor()),
#endif // OS_POSIX
@@ -59,10 +68,10 @@ class PpapiPluginSandboxedProcessLauncherDelegate
return !is_broker_;
}
- void PreSpawnTarget(sandbox::TargetPolicy* policy, bool* success) override {
+ bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
if (is_broker_)
- return;
- *success = false;
+ return true;
+
// The Pepper process is as locked-down as a renderer except that it can
// create the server side of Chrome pipes.
sandbox::ResultCode result;
@@ -70,12 +79,13 @@ class PpapiPluginSandboxedProcessLauncherDelegate
sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
L"\\\\.\\pipe\\chrome.*");
if (result != sandbox::SBOX_ALL_OK)
- return;
+ return false;
+
#if !defined(NACL_WIN64)
for (const auto& mime_type : info_.mime_types) {
if (IsWin32kLockdownEnabledForMimeType(mime_type.mime_type)) {
if (!AddWin32kLockdownPolicy(policy))
- return;
+ return false;
break;
}
}
@@ -86,7 +96,7 @@ class PpapiPluginSandboxedProcessLauncherDelegate
if (!sid.empty())
AddAppContainerPolicy(policy, sid.c_str());
- *success = true;
+ return true;
}
#elif defined(OS_POSIX)
@@ -97,7 +107,7 @@ class PpapiPluginSandboxedProcessLauncherDelegate
.GetSwitchValueNative(switches::kPpapiPluginLauncher);
return !is_broker_ && plugin_launcher.empty();
}
- base::ScopedFD TakeIpcFd() override { return ipc_fd_.Pass(); }
+ base::ScopedFD TakeIpcFd() override { return std::move(ipc_fd_); }
#endif // OS_WIN
SandboxType GetSandboxType() override {
@@ -105,7 +115,9 @@ class PpapiPluginSandboxedProcessLauncherDelegate
}
private:
+#if defined(OS_WIN)
const PepperPluginInfo& info_;
+#endif // OS_WIN
#if defined(OS_POSIX)
base::ScopedFD ipc_fd_;
#endif // OS_POSIX
@@ -186,7 +198,7 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreateBrokerHost(
// static
void PpapiPluginProcessHost::DidCreateOutOfProcessInstance(
int plugin_process_id,
- int32 pp_instance,
+ int32_t pp_instance,
const PepperRendererInstanceData& instance_data) {
for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
if (iter->process_.get() &&
@@ -209,7 +221,7 @@ void PpapiPluginProcessHost::DidCreateOutOfProcessInstance(
// static
void PpapiPluginProcessHost::DidDeleteOutOfProcessInstance(
int plugin_process_id,
- int32 pp_instance) {
+ int32_t pp_instance) {
for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
if (iter->process_.get() &&
iter->process_->GetData().id == plugin_process_id) {
@@ -226,7 +238,7 @@ void PpapiPluginProcessHost::DidDeleteOutOfProcessInstance(
// static
void PpapiPluginProcessHost::OnPluginInstanceThrottleStateChange(
int plugin_process_id,
- int32 pp_instance,
+ int32_t pp_instance,
bool is_throttled) {
for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
if (iter->process_.get() &&
@@ -273,7 +285,7 @@ PpapiPluginProcessHost::PpapiPluginProcessHost(
const base::FilePath& profile_data_directory)
: profile_data_directory_(profile_data_directory),
is_broker_(false) {
- uint32 base_permissions = info.permissions;
+ uint32_t base_permissions = info.permissions;
// We don't have to do any whitelisting for APIs in this process host, so
// don't bother passing a browser context or document url here.
@@ -293,6 +305,9 @@ PpapiPluginProcessHost::PpapiPluginProcessHost(
filter_ = new PepperMessageFilter();
process_->AddFilter(filter_.get());
process_->GetHost()->AddFilter(host_impl_->message_filter().get());
+#if defined(OS_WIN)
+ process_->AddFilter(new DWriteFontProxyMessageFilter());
+#endif
GetContentClient()->browser()->DidCreatePpapiPlugin(host_impl_.get());
@@ -375,20 +390,8 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
// Copy any flash args over and introduce field trials if necessary.
// TODO(vtl): Stop passing flash args in the command line, or windows is
// going to explode.
- std::string field_trial =
- base::FieldTrialList::FindFullName(kFlashHwVideoDecodeFieldTrialName);
std::string existing_args =
browser_command_line.GetSwitchValueASCII(switches::kPpapiFlashArgs);
- if (field_trial == kFlashHwVideoDecodeFieldTrialEnabledName) {
- // Arguments passed to Flash are comma delimited.
- if (!existing_args.empty())
- existing_args.append(",");
- existing_args.append("enable_hw_video_decode=1");
-#if defined(OS_MACOSX)
- // TODO(ihf): Remove this once Flash newer than 15.0.0.223 is released.
- existing_args.append(",enable_hw_video_decode_mac=1");
-#endif
- }
cmd_line->AppendSwitchASCII(switches::kPpapiFlashArgs, existing_args);
}
@@ -460,7 +463,7 @@ bool PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
}
// Called when the browser <--> plugin channel has been established.
-void PpapiPluginProcessHost::OnChannelConnected(int32 peer_pid) {
+void PpapiPluginProcessHost::OnChannelConnected(int32_t peer_pid) {
// This will actually load the plugin. Errors will actually not be reported
// back at this point. Instead, the plugin will fail to establish the
// connections when we request them on behalf of the renderer(s).
diff --git a/chromium/content/browser/ppapi_plugin_process_host.h b/chromium/content/browser/ppapi_plugin_process_host.h
index e4c58a9b33b..96593494cd2 100644
--- a/chromium/content/browser/ppapi_plugin_process_host.h
+++ b/chromium/content/browser/ppapi_plugin_process_host.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_PPAPI_PLUGIN_PROCESS_HOST_H_
#define CONTENT_BROWSER_PPAPI_PLUGIN_PROCESS_HOST_H_
+#include <stdint.h>
+
#include <queue>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process.h"
@@ -83,16 +85,16 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate,
// the plugin.
static void DidCreateOutOfProcessInstance(
int plugin_process_id,
- int32 pp_instance,
+ int32_t pp_instance,
const PepperRendererInstanceData& instance_data);
// The opposite of DIdCreate... above.
static void DidDeleteOutOfProcessInstance(int plugin_process_id,
- int32 pp_instance);
+ int32_t pp_instance);
// Notification that a Plugin instance has been throttled or unthrottled.
static void OnPluginInstanceThrottleStateChange(int plugin_process_id,
- int32 pp_instance,
+ int32_t pp_instance,
bool is_throttled);
// Returns the instances that match the specified process name.
@@ -135,7 +137,7 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate,
void OnProcessCrashed(int exit_code) override;
bool OnMessageReceived(const IPC::Message& msg) override;
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void CancelRequests();
diff --git a/chromium/content/browser/presentation/presentation_service_impl.cc b/chromium/content/browser/presentation/presentation_service_impl.cc
index 89f89d4fd67..07644589a40 100644
--- a/chromium/content/browser/presentation/presentation_service_impl.cc
+++ b/chromium/content/browser/presentation/presentation_service_impl.cc
@@ -4,8 +4,11 @@
#include "content/browser/presentation/presentation_service_impl.h"
+#include <stddef.h>
+#include <stdint.h>
#include <algorithm>
#include <string>
+#include <utility>
#include <vector>
#include "base/logging.h"
@@ -61,7 +64,7 @@ presentation::SessionMessagePtr ToMojoSessionMessage(
output->message = input->message;
}
}
- return output.Pass();
+ return output;
}
scoped_ptr<PresentationSessionMessage> GetPresentationSessionMessage(
@@ -74,41 +77,41 @@ scoped_ptr<PresentationSessionMessage> GetPresentationSessionMessage(
DCHECK(input->data.is_null());
// Return null PresentationSessionMessage if size exceeds.
if (input->message.size() > content::kMaxPresentationSessionMessageSize)
- return output.Pass();
+ return output;
output.reset(
new PresentationSessionMessage(PresentationMessageType::TEXT));
input->message.Swap(&output->message);
- return output.Pass();
+ return output;
}
case presentation::PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER: {
DCHECK(!input->data.is_null());
DCHECK(input->message.is_null());
if (input->data.size() > content::kMaxPresentationSessionMessageSize)
- return output.Pass();
+ return output;
output.reset(new PresentationSessionMessage(
PresentationMessageType::ARRAY_BUFFER));
output->data.reset(new std::vector<uint8_t>);
input->data.Swap(output->data.get());
- return output.Pass();
+ return output;
}
case presentation::PRESENTATION_MESSAGE_TYPE_BLOB: {
DCHECK(!input->data.is_null());
DCHECK(input->message.is_null());
if (input->data.size() > content::kMaxPresentationSessionMessageSize)
- return output.Pass();
+ return output;
output.reset(
new PresentationSessionMessage(PresentationMessageType::BLOB));
output->data.reset(new std::vector<uint8_t>);
input->data.Swap(output->data.get());
- return output.Pass();
+ return output;
}
}
NOTREACHED() << "Invalid presentation message type " << input->type;
- return output.Pass();
+ return output;
}
void InvokeNewSessionMojoCallbackWithError(
@@ -162,13 +165,13 @@ void PresentationServiceImpl::CreateMojoService(
web_contents,
GetContentClient()->browser()->GetPresentationServiceDelegate(
web_contents));
- impl->Bind(request.Pass());
+ impl->Bind(std::move(request));
}
void PresentationServiceImpl::Bind(
mojo::InterfaceRequest<presentation::PresentationService> request) {
binding_.reset(new mojo::Binding<presentation::PresentationService>(
- this, request.Pass()));
+ this, std::move(request)));
binding_->set_connection_error_handler([this]() {
DVLOG(1) << "Connection error";
delete this;
@@ -179,7 +182,7 @@ void PresentationServiceImpl::SetClient(
presentation::PresentationServiceClientPtr client) {
DCHECK(!client_.get());
// TODO(imcheng): Set ErrorHandler to listen for errors.
- client_ = client.Pass();
+ client_ = std::move(client);
}
void PresentationServiceImpl::ListenForScreenAvailability(
@@ -200,7 +203,7 @@ void PresentationServiceImpl::ListenForScreenAvailability(
render_process_id_,
render_frame_id_,
listener.get())) {
- screen_availability_listeners_.set(availability_url, listener.Pass());
+ screen_availability_listeners_[availability_url] = std::move(listener);
} else {
DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request.";
}
@@ -218,19 +221,10 @@ void PresentationServiceImpl::StopListeningForScreenAvailability(
return;
delegate_->RemoveScreenAvailabilityListener(
- render_process_id_,
- render_frame_id_,
- listener_it->second);
+ render_process_id_, render_frame_id_, listener_it->second.get());
screen_availability_listeners_.erase(listener_it);
}
-void PresentationServiceImpl::ListenForDefaultSessionStart(
- const DefaultSessionMojoCallback& callback) {
- if (!default_session_start_context_.get())
- default_session_start_context_.reset(new DefaultSessionStartContext);
- default_session_start_context_->AddCallback(callback);
-}
-
void PresentationServiceImpl::StartSession(
const mojo::String& presentation_url,
const NewSessionMojoCallback& callback) {
@@ -302,39 +296,53 @@ int PresentationServiceImpl::RegisterJoinSessionCallback(
return request_id;
}
+void PresentationServiceImpl::ListenForConnectionStateChange(
+ const PresentationSessionInfo& connection) {
+ if (delegate_) {
+ delegate_->ListenForConnectionStateChange(
+ render_process_id_, render_frame_id_, connection,
+ base::Bind(&PresentationServiceImpl::OnConnectionStateChanged,
+ weak_factory_.GetWeakPtr(), connection));
+ }
+}
+
void PresentationServiceImpl::OnStartSessionSucceeded(
int request_session_id,
const PresentationSessionInfo& session_info) {
- if (request_session_id == start_session_request_id_) {
- CHECK(pending_start_session_cb_.get());
- pending_start_session_cb_->Run(
- presentation::PresentationSessionInfo::From(session_info),
- presentation::PresentationErrorPtr());
- pending_start_session_cb_.reset();
- start_session_request_id_ = kInvalidRequestSessionId;
- }
+ if (request_session_id != start_session_request_id_)
+ return;
+
+ CHECK(pending_start_session_cb_.get());
+ pending_start_session_cb_->Run(
+ presentation::PresentationSessionInfo::From(session_info),
+ presentation::PresentationErrorPtr());
+ ListenForConnectionStateChange(session_info);
+ pending_start_session_cb_.reset();
+ start_session_request_id_ = kInvalidRequestSessionId;
}
void PresentationServiceImpl::OnStartSessionError(
int request_session_id,
const PresentationError& error) {
- if (request_session_id == start_session_request_id_) {
- CHECK(pending_start_session_cb_.get());
- pending_start_session_cb_->Run(
- presentation::PresentationSessionInfoPtr(),
- presentation::PresentationError::From(error));
- pending_start_session_cb_.reset();
- start_session_request_id_ = kInvalidRequestSessionId;
- }
+ if (request_session_id != start_session_request_id_)
+ return;
+
+ CHECK(pending_start_session_cb_.get());
+ pending_start_session_cb_->Run(presentation::PresentationSessionInfoPtr(),
+ presentation::PresentationError::From(error));
+ pending_start_session_cb_.reset();
+ start_session_request_id_ = kInvalidRequestSessionId;
}
void PresentationServiceImpl::OnJoinSessionSucceeded(
int request_session_id,
const PresentationSessionInfo& session_info) {
- RunAndEraseJoinSessionMojoCallback(
- request_session_id,
- presentation::PresentationSessionInfo::From(session_info),
- presentation::PresentationErrorPtr());
+ if (RunAndEraseJoinSessionMojoCallback(
+ request_session_id,
+ presentation::PresentationSessionInfo::From(session_info),
+ presentation::PresentationErrorPtr())) {
+ ListenForConnectionStateChange(session_info);
+ }
}
void PresentationServiceImpl::OnJoinSessionError(
@@ -346,17 +354,18 @@ void PresentationServiceImpl::OnJoinSessionError(
presentation::PresentationError::From(error));
}
-void PresentationServiceImpl::RunAndEraseJoinSessionMojoCallback(
+bool PresentationServiceImpl::RunAndEraseJoinSessionMojoCallback(
int request_session_id,
presentation::PresentationSessionInfoPtr session,
presentation::PresentationErrorPtr error) {
auto it = pending_join_session_cbs_.find(request_session_id);
if (it == pending_join_session_cbs_.end())
- return;
+ return false;
DCHECK(it->second.get());
- it->second->Run(session.Pass(), error.Pass());
+ it->second->Run(std::move(session), std::move(error));
pending_join_session_cbs_.erase(it);
+ return true;
}
void PresentationServiceImpl::SetDefaultPresentationURL(
@@ -368,11 +377,12 @@ void PresentationServiceImpl::SetDefaultPresentationURL(
const std::string& new_default_url = url.get();
if (default_presentation_url_ == new_default_url)
return;
- delegate_->SetDefaultPresentationUrl(
- render_process_id_,
- render_frame_id_,
- new_default_url);
+
default_presentation_url_ = new_default_url;
+ delegate_->SetDefaultPresentationUrl(
+ render_process_id_, render_frame_id_, new_default_url,
+ base::Bind(&PresentationServiceImpl::OnDefaultPresentationStarted,
+ weak_factory_.GetWeakPtr()));
}
void PresentationServiceImpl::SendSessionMessage(
@@ -392,7 +402,7 @@ void PresentationServiceImpl::SendSessionMessage(
delegate_->SendMessage(
render_process_id_, render_frame_id_,
session.To<PresentationSessionInfo>(),
- GetPresentationSessionMessage(session_message.Pass()),
+ GetPresentationSessionMessage(std::move(session_message)),
base::Bind(&PresentationServiceImpl::OnSendMessageCallback,
weak_factory_.GetWeakPtr()));
}
@@ -406,32 +416,29 @@ void PresentationServiceImpl::OnSendMessageCallback(bool sent) {
}
}
-void PresentationServiceImpl::CloseSession(
+void PresentationServiceImpl::CloseConnection(
const mojo::String& presentation_url,
const mojo::String& presentation_id) {
- DVLOG(2) << "CloseSession " << presentation_id;
+ DVLOG(2) << "CloseConnection " << presentation_id;
if (delegate_)
- delegate_->CloseSession(render_process_id_, render_frame_id_,
- presentation_id);
+ delegate_->CloseConnection(render_process_id_, render_frame_id_,
+ presentation_id);
}
-void PresentationServiceImpl::ListenForSessionStateChange() {
- if (!delegate_)
- return;
-
- delegate_->ListenForSessionStateChange(
- render_process_id_, render_frame_id_,
- base::Bind(&PresentationServiceImpl::OnSessionStateChanged,
- weak_factory_.GetWeakPtr()));
+void PresentationServiceImpl::Terminate(const mojo::String& presentation_url,
+ const mojo::String& presentation_id) {
+ DVLOG(2) << "Terminate " << presentation_id;
+ if (delegate_)
+ delegate_->Terminate(render_process_id_, render_frame_id_, presentation_id);
}
-void PresentationServiceImpl::OnSessionStateChanged(
- const PresentationSessionInfo& session_info,
- PresentationSessionState session_state) {
+void PresentationServiceImpl::OnConnectionStateChanged(
+ const PresentationSessionInfo& connection,
+ PresentationConnectionState state) {
DCHECK(client_.get());
- client_->OnSessionStateChanged(
- presentation::PresentationSessionInfo::From(session_info),
- PresentationSessionStateToMojo(session_state));
+ client_->OnConnectionStateChanged(
+ presentation::PresentationSessionInfo::From(connection),
+ PresentationConnectionStateToMojo(state));
}
bool PresentationServiceImpl::FrameMatches(
@@ -469,7 +476,7 @@ void PresentationServiceImpl::OnSessionMessages(
client_->OnSessionMessagesReceived(
presentation::PresentationSessionInfo::From(session),
- mojoMessages.Pass());
+ std::move(mojoMessages));
}
void PresentationServiceImpl::DidNavigateAnyFrame(
@@ -521,8 +528,6 @@ void PresentationServiceImpl::Reset() {
pending_join_session_cbs_.clear();
- default_session_start_context_.reset();
-
if (on_session_messages_callback_.get()) {
on_session_messages_callback_->Run(
mojo::Array<presentation::SessionMessagePtr>());
@@ -544,9 +549,11 @@ void PresentationServiceImpl::OnDelegateDestroyed() {
}
void PresentationServiceImpl::OnDefaultPresentationStarted(
- const PresentationSessionInfo& session) {
- if (default_session_start_context_.get())
- default_session_start_context_->set_session(session);
+ const PresentationSessionInfo& connection) {
+ DCHECK(client_.get());
+ client_->OnDefaultSessionStarted(
+ presentation::PresentationSessionInfo::From(connection));
+ ListenForConnectionStateChange(connection);
}
PresentationServiceImpl::ScreenAvailabilityListenerImpl
@@ -593,49 +600,8 @@ void PresentationServiceImpl::NewSessionMojoCallbackWrapper::Run(
presentation::PresentationSessionInfoPtr session,
presentation::PresentationErrorPtr error) {
DCHECK(!callback_.is_null());
- callback_.Run(session.Pass(), error.Pass());
+ callback_.Run(std::move(session), std::move(error));
callback_.reset();
}
-PresentationServiceImpl::DefaultSessionStartContext
-::DefaultSessionStartContext() {
-}
-
-PresentationServiceImpl::DefaultSessionStartContext
-::~DefaultSessionStartContext() {
- Reset();
-}
-
-void PresentationServiceImpl::DefaultSessionStartContext::AddCallback(
- const DefaultSessionMojoCallback& callback) {
- if (session_.get()) {
- DCHECK(callbacks_.empty());
- callback.Run(presentation::PresentationSessionInfo::From(*session_));
- session_.reset();
- } else {
- callbacks_.push_back(new DefaultSessionMojoCallback(callback));
- }
-}
-
-void PresentationServiceImpl::DefaultSessionStartContext::set_session(
- const PresentationSessionInfo& session) {
- if (callbacks_.empty()) {
- session_.reset(new PresentationSessionInfo(session));
- } else {
- DCHECK(!session_.get());
- ScopedVector<DefaultSessionMojoCallback> callbacks;
- callbacks.swap(callbacks_);
- for (const auto& callback : callbacks)
- callback->Run(presentation::PresentationSessionInfo::From(session));
- }
-}
-
-void PresentationServiceImpl::DefaultSessionStartContext::Reset() {
- ScopedVector<DefaultSessionMojoCallback> callbacks;
- callbacks.swap(callbacks_);
- for (const auto& callback : callbacks)
- callback->Run(presentation::PresentationSessionInfoPtr());
- session_.reset();
-}
-
} // namespace content
diff --git a/chromium/content/browser/presentation/presentation_service_impl.h b/chromium/content/browser/presentation/presentation_service_impl.h
index cbea133b094..88a70546780 100644
--- a/chromium/content/browser/presentation/presentation_service_impl.h
+++ b/chromium/content/browser/presentation/presentation_service_impl.h
@@ -9,10 +9,8 @@
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_map.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
@@ -26,7 +24,7 @@
#include "content/public/browser/presentation_service_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/frame_navigate_params.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding.h"
namespace content {
@@ -90,15 +88,13 @@ class CONTENT_EXPORT PresentationServiceImpl
FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
MaxPendingJoinSessionRequests);
FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
- ListenForSessionStateChange);
+ ListenForConnectionStateChange);
+
// Maximum number of pending JoinSession requests at any given time.
static const int kMaxNumQueuedSessionRequests = 10;
- using DefaultSessionMojoCallback =
+ using PresentationSessionMojoCallback =
mojo::Callback<void(presentation::PresentationSessionInfoPtr)>;
- using SessionStateCallback =
- mojo::Callback<void(presentation::PresentationSessionInfoPtr,
- presentation::PresentationSessionState)>;
using SessionMessagesCallback =
mojo::Callback<void(mojo::Array<presentation::SessionMessagePtr>)>;
using SendMessageMojoCallback = mojo::Callback<void(bool)>;
@@ -125,27 +121,6 @@ class CONTENT_EXPORT PresentationServiceImpl
PresentationServiceImpl* const service_;
};
- class CONTENT_EXPORT DefaultSessionStartContext {
- public:
- DefaultSessionStartContext();
- ~DefaultSessionStartContext();
-
- // Adds a callback. May invoke the callback immediately if |session| using
- // default presentation URL was already started.
- void AddCallback(const DefaultSessionMojoCallback& callback);
-
- // Sets the session info. Maybe invoke callbacks queued with AddCallback().
- void set_session(const PresentationSessionInfo& session);
-
- private:
- // Flush all queued callbacks by invoking them with null
- // PresentationSessionInfoPtr.
- void Reset();
-
- ScopedVector<DefaultSessionMojoCallback> callbacks_;
- scoped_ptr<PresentationSessionInfo> session_;
- };
-
// Ensures the provided NewSessionMojoCallback is invoked exactly once
// before it goes out of scope.
class NewSessionMojoCallbackWrapper {
@@ -177,8 +152,6 @@ class CONTENT_EXPORT PresentationServiceImpl
void SetClient(presentation::PresentationServiceClientPtr client) override;
void ListenForScreenAvailability(const mojo::String& url) override;
void StopListeningForScreenAvailability(const mojo::String& url) override;
- void ListenForDefaultSessionStart(
- const DefaultSessionMojoCallback& callback) override;
void StartSession(
const mojo::String& presentation_url,
const NewSessionMojoCallback& callback) override;
@@ -189,10 +162,10 @@ class CONTENT_EXPORT PresentationServiceImpl
void SendSessionMessage(presentation::PresentationSessionInfoPtr session_info,
presentation::SessionMessagePtr session_message,
const SendMessageMojoCallback& callback) override;
- void CloseSession(
- const mojo::String& presentation_url,
- const mojo::String& presentation_id) override;
- void ListenForSessionStateChange() override;
+ void CloseConnection(const mojo::String& presentation_url,
+ const mojo::String& presentation_id) override;
+ void Terminate(const mojo::String& presentation_url,
+ const mojo::String& presentation_id) override;
void ListenForSessionMessages(
presentation::PresentationSessionInfoPtr session) override;
@@ -208,14 +181,18 @@ class CONTENT_EXPORT PresentationServiceImpl
// PresentationServiceDelegate::Observer
void OnDelegateDestroyed() override;
- void OnDefaultPresentationStarted(const PresentationSessionInfo& session)
- override;
+
+ // Passed to embedder's implementation of PresentationServiceDelegate for
+ // later invocation when default presentation has started.
+ void OnDefaultPresentationStarted(
+ const PresentationSessionInfo& session_info);
// Finds the callback from |pending_join_session_cbs_| using
// |request_session_id|.
// If it exists, invoke it with |session| and |error|, then erase it from
// |pending_join_session_cbs_|.
- void RunAndEraseJoinSessionMojoCallback(
+ // Returns true if the callback was found.
+ bool RunAndEraseJoinSessionMojoCallback(
int request_session_id,
presentation::PresentationSessionInfoPtr session,
presentation::PresentationErrorPtr error);
@@ -241,6 +218,11 @@ class CONTENT_EXPORT PresentationServiceImpl
const PresentationError& error);
void OnSendMessageCallback(bool sent);
+ // Calls to |delegate_| to start listening for state changes for |connection|.
+ // State changes will be returned via |OnConnectionStateChanged|.
+ void ListenForConnectionStateChange(
+ const PresentationSessionInfo& connection);
+
// Passed to embedder's implementation of PresentationServiceDelegate for
// later invocation when session messages arrive.
void OnSessionMessages(
@@ -254,9 +236,9 @@ class CONTENT_EXPORT PresentationServiceImpl
int RegisterJoinSessionCallback(const NewSessionMojoCallback& callback);
// Invoked by the embedder's PresentationServiceDelegate when a
- // presentation session's state has changed.
- void OnSessionStateChanged(const PresentationSessionInfo& session_info,
- PresentationSessionState session_state);
+ // PresentationConnection's state has changed.
+ void OnConnectionStateChanged(const PresentationSessionInfo& connection,
+ PresentationConnectionState state);
// Returns true if this object is associated with |render_frame_host|.
bool FrameMatches(content::RenderFrameHost* render_frame_host) const;
@@ -272,7 +254,7 @@ class CONTENT_EXPORT PresentationServiceImpl
std::string default_presentation_url_;
using ScreenAvailabilityListenerMap =
- base::ScopedPtrMap<std::string, scoped_ptr<ScreenAvailabilityListenerImpl>>;
+ std::map<std::string, scoped_ptr<ScreenAvailabilityListenerImpl>>;
ScreenAvailabilityListenerMap screen_availability_listeners_;
// For StartSession requests.
@@ -284,8 +266,6 @@ class CONTENT_EXPORT PresentationServiceImpl
base::hash_map<int, linked_ptr<NewSessionMojoCallbackWrapper>>
pending_join_session_cbs_;
- scoped_ptr<DefaultSessionStartContext> default_session_start_context_;
-
// RAII binding of |this| to an Presentation interface request.
// The binding is removed when binding_ is cleared or goes out of scope.
scoped_ptr<mojo::Binding<presentation::PresentationService>> binding_;
diff --git a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
index be53cdaaeb0..cc98878e95c 100644
--- a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
+++ b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -2,7 +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/presentation/presentation_service_impl.h"
+
+#include <stddef.h>
+#include <stdint.h>
#include <string>
+#include <utility>
#include <vector>
#include "base/location.h"
@@ -11,7 +16,6 @@
#include "base/single_thread_task_runner.h"
#include "base/test/test_timeouts.h"
#include "base/thread_task_runner_handle.h"
-#include "content/browser/presentation/presentation_service_impl.h"
#include "content/public/browser/presentation_service_delegate.h"
#include "content/public/browser/presentation_session.h"
#include "content/public/common/presentation_constants.h"
@@ -41,12 +45,6 @@ MATCHER_P(Equals, expected, "") {
const char *const kPresentationId = "presentationId";
const char *const kPresentationUrl = "http://foo.com/index.html";
-bool ArePresentationSessionsEqual(
- const presentation::PresentationSessionInfo& expected,
- const presentation::PresentationSessionInfo& actual) {
- return expected.url == actual.url && expected.id == actual.id;
-}
-
bool ArePresentationSessionMessagesEqual(
const presentation::SessionMessage* expected,
const presentation::SessionMessage* actual) {
@@ -91,27 +89,29 @@ class MockPresentationServiceDelegate : public PresentationServiceDelegate {
void(
int render_process_id,
int routing_id));
- MOCK_METHOD3(SetDefaultPresentationUrl,
- void(
- int render_process_id,
- int routing_id,
- const std::string& default_presentation_url));
+ MOCK_METHOD4(SetDefaultPresentationUrl,
+ void(int render_process_id,
+ int routing_id,
+ const std::string& default_presentation_url,
+ const PresentationSessionStartedCallback& callback));
MOCK_METHOD5(StartSession,
- void(
- int render_process_id,
- int render_frame_id,
- const std::string& presentation_url,
- const PresentationSessionSuccessCallback& success_cb,
- const PresentationSessionErrorCallback& error_cb));
+ void(int render_process_id,
+ int render_frame_id,
+ const std::string& presentation_url,
+ const PresentationSessionStartedCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb));
MOCK_METHOD6(JoinSession,
- void(
- int render_process_id,
- int render_frame_id,
- const std::string& presentation_url,
- const std::string& presentation_id,
- const PresentationSessionSuccessCallback& success_cb,
- const PresentationSessionErrorCallback& error_cb));
- MOCK_METHOD3(CloseSession,
+ void(int render_process_id,
+ int render_frame_id,
+ const std::string& presentation_url,
+ const std::string& presentation_id,
+ const PresentationSessionStartedCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb));
+ MOCK_METHOD3(CloseConnection,
+ void(int render_process_id,
+ int render_frame_id,
+ const std::string& presentation_id));
+ MOCK_METHOD3(Terminate,
void(int render_process_id,
int render_frame_id,
const std::string& presentation_id));
@@ -134,11 +134,12 @@ class MockPresentationServiceDelegate : public PresentationServiceDelegate {
SendMessageRawPtr(render_process_id, render_frame_id, session,
message_request.release(), send_message_cb);
}
- MOCK_METHOD3(
- ListenForSessionStateChange,
- void(int render_process_id,
- int render_frame_id,
- const content::SessionStateChangedCallback& state_changed_cb));
+ MOCK_METHOD4(ListenForConnectionStateChange,
+ void(int render_process_id,
+ int render_frame_id,
+ const content::PresentationSessionInfo& connection,
+ const content::PresentationConnectionStateChangedCallback&
+ state_changed_cb));
void set_screen_availability_listening_supported(bool value) {
screen_availability_listening_supported_ = value;
@@ -153,25 +154,32 @@ class MockPresentationServiceClient :
public:
MOCK_METHOD2(OnScreenAvailabilityUpdated,
void(const mojo::String& url, bool available));
- void OnSessionStateChanged(
- presentation::PresentationSessionInfoPtr session_info,
- presentation::PresentationSessionState new_state) override {
- OnSessionStateChanged(*session_info, new_state);
+ void OnConnectionStateChanged(
+ presentation::PresentationSessionInfoPtr connection,
+ presentation::PresentationConnectionState new_state) override {
+ OnConnectionStateChanged(*connection, new_state);
}
- MOCK_METHOD2(OnSessionStateChanged,
- void(const presentation::PresentationSessionInfo& session_info,
- presentation::PresentationSessionState new_state));
+ MOCK_METHOD2(OnConnectionStateChanged,
+ void(const presentation::PresentationSessionInfo& connection,
+ presentation::PresentationConnectionState new_state));
MOCK_METHOD1(OnScreenAvailabilityNotSupported, void(const mojo::String& url));
void OnSessionMessagesReceived(
presentation::PresentationSessionInfoPtr session_info,
mojo::Array<presentation::SessionMessagePtr> messages) override {
- messages_received_ = messages.Pass();
+ messages_received_ = std::move(messages);
MessagesReceived();
}
MOCK_METHOD0(MessagesReceived, void());
+ void OnDefaultSessionStarted(
+ presentation::PresentationSessionInfoPtr session_info) override {
+ OnDefaultSessionStarted(*session_info);
+ }
+ MOCK_METHOD1(OnDefaultSessionStarted,
+ void(const presentation::PresentationSessionInfo& session_info));
+
mojo::Array<presentation::SessionMessagePtr> messages_received_;
};
@@ -186,13 +194,13 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
service_impl_.reset(new PresentationServiceImpl(
contents()->GetMainFrame(), contents(), &mock_delegate_));
- service_impl_->Bind(request.Pass());
+ service_impl_->Bind(std::move(request));
presentation::PresentationServiceClientPtr client_ptr;
client_binding_.reset(
new mojo::Binding<presentation::PresentationServiceClient>(
&mock_client_, mojo::GetProxy(&client_ptr)));
- service_impl_->SetClient(client_ptr.Pass());
+ service_impl_->SetClient(std::move(client_ptr));
}
void TearDown() override {
@@ -257,7 +265,6 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
EXPECT_EQ(
service_impl_->screen_availability_listeners_.find(kPresentationUrl),
service_impl_->screen_availability_listeners_.end());
- EXPECT_FALSE(service_impl_->default_session_start_context_.get());
EXPECT_FALSE(service_impl_->on_session_messages_callback_.get());
}
@@ -279,25 +286,6 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
run_loop_quit_closure_.Run();
}
- void ExpectDefaultSessionStarted(
- const presentation::PresentationSessionInfo& expected_session,
- presentation::PresentationSessionInfoPtr actual_session) {
- ASSERT_TRUE(!actual_session.is_null());
- EXPECT_TRUE(ArePresentationSessionsEqual(
- expected_session, *actual_session));
- ++default_session_started_count_;
- if (!run_loop_quit_closure_.is_null())
- run_loop_quit_closure_.Run();
- }
-
- void ExpectDefaultSessionNull(
- presentation::PresentationSessionInfoPtr actual_session) {
- EXPECT_TRUE(actual_session.is_null());
- ++default_session_started_count_;
- if (!run_loop_quit_closure_.is_null())
- run_loop_quit_closure_.Run();
- }
-
void ExpectSessionMessages(
const mojo::Array<presentation::SessionMessagePtr>& expected_msgs,
const mojo::Array<presentation::SessionMessagePtr>& actual_msgs) {
@@ -348,18 +336,18 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
message.reset(
new content::PresentationSessionMessage(PresentationMessageType::TEXT));
message->message = text_msg;
- messages.push_back(message.Pass());
+ messages.push_back(std::move(message));
message.reset(new content::PresentationSessionMessage(
PresentationMessageType::ARRAY_BUFFER));
message->data.reset(new std::vector<uint8_t>(binary_data));
- messages.push_back(message.Pass());
+ messages.push_back(std::move(message));
std::vector<presentation::SessionMessagePtr> actual_msgs;
{
base::RunLoop run_loop;
EXPECT_CALL(mock_client_, MessagesReceived())
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
- message_cb.Run(messages.Pass(), pass_ownership);
+ message_cb.Run(std::move(messages), pass_ownership);
run_loop.Run();
}
ExpectSessionMessages(expected_msgs, mock_client_.messages_received_);
@@ -450,24 +438,54 @@ TEST_F(PresentationServiceImplTest, DelegateFails) {
TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrl) {
std::string url1("http://fooUrl");
- EXPECT_CALL(mock_delegate_,
- SetDefaultPresentationUrl(_, _, Eq(url1)))
+ EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrl(_, _, Eq(url1), _))
.Times(1);
service_impl_->SetDefaultPresentationURL(url1);
EXPECT_EQ(url1, service_impl_->default_presentation_url_);
std::string url2("http://barUrl");
// Sets different DPU.
- EXPECT_CALL(mock_delegate_,
- SetDefaultPresentationUrl(_, _, Eq(url2)))
- .Times(1);
+ content::PresentationSessionStartedCallback callback;
+ EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrl(_, _, Eq(url2), _))
+ .WillOnce(SaveArg<3>(&callback));
service_impl_->SetDefaultPresentationURL(url2);
EXPECT_EQ(url2, service_impl_->default_presentation_url_);
+
+ presentation::PresentationSessionInfo session_info;
+ session_info.url = url2;
+ session_info.id = kPresentationId;
+ base::RunLoop run_loop;
+ EXPECT_CALL(mock_client_, OnDefaultSessionStarted(Equals(session_info)))
+ .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
+ callback.Run(content::PresentationSessionInfo(url2, kPresentationId));
+ run_loop.Run();
+}
+
+TEST_F(PresentationServiceImplTest, ListenForConnectionStateChange) {
+ content::PresentationSessionInfo connection(kPresentationUrl,
+ kPresentationId);
+ content::PresentationConnectionStateChangedCallback state_changed_cb;
+ EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
+ .WillOnce(SaveArg<3>(&state_changed_cb));
+ service_impl_->ListenForConnectionStateChange(connection);
+
+ // Trigger state change. It should be propagated back up to |mock_client_|.
+ presentation::PresentationSessionInfo presentation_connection;
+ presentation_connection.url = kPresentationUrl;
+ presentation_connection.id = kPresentationId;
+ base::RunLoop run_loop;
+ EXPECT_CALL(mock_client_,
+ OnConnectionStateChanged(
+ Equals(presentation_connection),
+ presentation::PRESENTATION_CONNECTION_STATE_CLOSED))
+ .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
+ state_changed_cb.Run(content::PRESENTATION_CONNECTION_STATE_CLOSED);
+ run_loop.Run();
}
TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrl) {
EXPECT_CALL(mock_delegate_,
- SetDefaultPresentationUrl(_, _, Eq(kPresentationUrl)))
+ SetDefaultPresentationUrl(_, _, Eq(kPresentationUrl), _))
.Times(1);
service_impl_->SetDefaultPresentationURL(kPresentationUrl);
EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
@@ -492,6 +510,9 @@ TEST_F(PresentationServiceImplTest, StartSessionSuccess) {
InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
SaveArg<3>(&success_cb)));
run_loop.Run();
+
+ EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
+ .Times(1);
success_cb.Run(PresentationSessionInfo(kPresentationUrl, kPresentationId));
SaveQuitClosureAndRunLoop();
}
@@ -528,6 +549,9 @@ TEST_F(PresentationServiceImplTest, JoinSessionSuccess) {
InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
SaveArg<4>(&success_cb)));
run_loop.Run();
+
+ EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
+ .Times(1);
success_cb.Run(PresentationSessionInfo(kPresentationUrl, kPresentationId));
SaveQuitClosureAndRunLoop();
}
@@ -551,10 +575,18 @@ TEST_F(PresentationServiceImplTest, JoinSessionError) {
SaveQuitClosureAndRunLoop();
}
-TEST_F(PresentationServiceImplTest, CloseSession) {
- service_ptr_->CloseSession(kPresentationUrl, kPresentationId);
+TEST_F(PresentationServiceImplTest, CloseConnection) {
+ service_ptr_->CloseConnection(kPresentationUrl, kPresentationId);
+ base::RunLoop run_loop;
+ EXPECT_CALL(mock_delegate_, CloseConnection(_, _, Eq(kPresentationId)))
+ .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
+ run_loop.Run();
+}
+
+TEST_F(PresentationServiceImplTest, Terminate) {
+ service_ptr_->Terminate(kPresentationUrl, kPresentationId);
base::RunLoop run_loop;
- EXPECT_CALL(mock_delegate_, CloseSession(_, _, Eq(kPresentationId)))
+ EXPECT_CALL(mock_delegate_, Terminate(_, _, Eq(kPresentationId)))
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
run_loop.Run();
}
@@ -580,8 +612,11 @@ TEST_F(PresentationServiceImplTest, ListenForSessionMessagesWithEmptyMsg) {
TEST_F(PresentationServiceImplTest, StartSessionInProgress) {
std::string presentation_url1("http://fooUrl");
std::string presentation_url2("http://barUrl");
+ EXPECT_CALL(mock_delegate_, StartSession(_, _, Eq(presentation_url1), _, _))
+ .Times(1);
service_ptr_->StartSession(presentation_url1,
base::Bind(&DoNothing));
+
// This request should fail immediately, since there is already a StartSession
// in progress.
service_ptr_->StartSession(
@@ -592,59 +627,6 @@ TEST_F(PresentationServiceImplTest, StartSessionInProgress) {
SaveQuitClosureAndRunLoop();
}
-TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStart) {
- presentation::PresentationSessionInfo expected_session;
- expected_session.url = kPresentationUrl;
- expected_session.id = kPresentationId;
- service_ptr_->ListenForDefaultSessionStart(
- base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
- base::Unretained(this),
- expected_session));
- RunLoopFor(base::TimeDelta::FromMilliseconds(50));
- service_impl_->OnDefaultPresentationStarted(
- content::PresentationSessionInfo(kPresentationUrl, kPresentationId));
- SaveQuitClosureAndRunLoop();
- EXPECT_EQ(1, default_session_started_count_);
-}
-
-TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStartAfterSet) {
- // Note that the callback will only pick up presentation_url2/id2 since
- // ListenForDefaultSessionStart wasn't called yet when the DPU was still
- // presentation_url1.
- std::string presentation_url1("http://fooUrl1");
- std::string presentation_id1("presentationId1");
- std::string presentation_url2("http://fooUrl2");
- std::string presentation_id2("presentationId2");
- service_impl_->OnDefaultPresentationStarted(
- content::PresentationSessionInfo(presentation_url1, presentation_id1));
-
- presentation::PresentationSessionInfo expected_session;
- expected_session.url = presentation_url2;
- expected_session.id = presentation_id2;
- service_ptr_->ListenForDefaultSessionStart(
- base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
- base::Unretained(this),
- expected_session));
- RunLoopFor(base::TimeDelta::FromMilliseconds(50));
- service_impl_->OnDefaultPresentationStarted(
- content::PresentationSessionInfo(presentation_url2, presentation_id2));
- SaveQuitClosureAndRunLoop();
- EXPECT_EQ(1, default_session_started_count_);
-}
-
-TEST_F(PresentationServiceImplTest, DefaultSessionStartReset) {
- service_ptr_->ListenForDefaultSessionStart(
- base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionNull,
- base::Unretained(this)));
- RunLoopFor(TestTimeouts::tiny_timeout());
-
- ExpectReset();
- service_impl_->Reset();
- ExpectCleanState();
- SaveQuitClosureAndRunLoop();
- EXPECT_EQ(1, default_session_started_count_);
-}
-
TEST_F(PresentationServiceImplTest, SendStringMessage) {
std::string message("Test presentation session message");
@@ -658,7 +640,7 @@ TEST_F(PresentationServiceImplTest, SendStringMessage) {
PRESENTATION_MESSAGE_TYPE_TEXT;
message_request->message = message;
service_ptr_->SendSessionMessage(
- session.Pass(), message_request.Pass(),
+ std::move(session), std::move(message_request),
base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
base::Unretained(this)));
@@ -683,8 +665,8 @@ TEST_F(PresentationServiceImplTest, SendStringMessage) {
TEST_F(PresentationServiceImplTest, SendArrayBuffer) {
// Test Array buffer data.
- const uint8 buffer[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
- std::vector<uint8> data;
+ const uint8_t buffer[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
+ std::vector<uint8_t> data;
data.assign(buffer, buffer + sizeof(buffer));
presentation::PresentationSessionInfoPtr session(
@@ -695,9 +677,9 @@ TEST_F(PresentationServiceImplTest, SendArrayBuffer) {
presentation::SessionMessage::New());
message_request->type = presentation::PresentationMessageType::
PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
- message_request->data = mojo::Array<uint8>::From(data);
+ message_request->data = mojo::Array<uint8_t>::From(data);
service_ptr_->SendSessionMessage(
- session.Pass(), message_request.Pass(),
+ std::move(session), std::move(message_request),
base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
base::Unretained(this)));
@@ -727,9 +709,9 @@ TEST_F(PresentationServiceImplTest, SendArrayBufferWithExceedingLimit) {
// Create buffer with size exceeding the limit.
// Use same size as in content::kMaxPresentationSessionMessageSize.
const size_t kMaxBufferSizeInBytes = 64 * 1024; // 64 KB.
- uint8 buffer[kMaxBufferSizeInBytes+1];
+ uint8_t buffer[kMaxBufferSizeInBytes + 1];
memset(buffer, 0, kMaxBufferSizeInBytes+1);
- std::vector<uint8> data;
+ std::vector<uint8_t> data;
data.assign(buffer, buffer + sizeof(buffer));
presentation::PresentationSessionInfoPtr session(
@@ -740,9 +722,9 @@ TEST_F(PresentationServiceImplTest, SendArrayBufferWithExceedingLimit) {
presentation::SessionMessage::New());
message_request->type = presentation::PresentationMessageType::
PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
- message_request->data = mojo::Array<uint8>::From(data);
+ message_request->data = mojo::Array<uint8_t>::From(data);
service_ptr_->SendSessionMessage(
- session.Pass(), message_request.Pass(),
+ std::move(session), std::move(message_request),
base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
base::Unretained(this)));
@@ -760,8 +742,8 @@ TEST_F(PresentationServiceImplTest, SendArrayBufferWithExceedingLimit) {
}
TEST_F(PresentationServiceImplTest, SendBlobData) {
- const uint8 buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
- std::vector<uint8> data;
+ const uint8_t buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+ std::vector<uint8_t> data;
data.assign(buffer, buffer + sizeof(buffer));
presentation::PresentationSessionInfoPtr session(
@@ -772,9 +754,9 @@ TEST_F(PresentationServiceImplTest, SendBlobData) {
presentation::SessionMessage::New());
message_request->type =
presentation::PresentationMessageType::PRESENTATION_MESSAGE_TYPE_BLOB;
- message_request->data = mojo::Array<uint8>::From(data);
+ message_request->data = mojo::Array<uint8_t>::From(data);
service_ptr_->SendSessionMessage(
- session.Pass(), message_request.Pass(),
+ std::move(session), std::move(message_request),
base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
base::Unretained(this)));
@@ -824,26 +806,6 @@ TEST_F(PresentationServiceImplTest, MaxPendingJoinSessionRequests) {
SaveQuitClosureAndRunLoop();
}
-TEST_F(PresentationServiceImplTest, ListenForSessionStateChange) {
- base::RunLoop run_loop;
- EXPECT_CALL(mock_delegate_, ListenForSessionStateChange(_, _, _))
- .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
- service_ptr_->ListenForSessionStateChange();
- run_loop.Run();
-
- presentation::PresentationSessionInfo session_info;
- session_info.url = kPresentationUrl;
- session_info.id = kPresentationId;
-
- EXPECT_CALL(mock_client_,
- OnSessionStateChanged(
- Equals(session_info),
- presentation::PRESENTATION_SESSION_STATE_CONNECTED));
- service_impl_->OnSessionStateChanged(
- content::PresentationSessionInfo(kPresentationUrl, kPresentationId),
- content::PRESENTATION_SESSION_STATE_CONNECTED);
-}
-
TEST_F(PresentationServiceImplTest, ScreenAvailabilityNotSupported) {
mock_delegate_.set_screen_availability_listening_supported(false);
EXPECT_CALL(mock_client_,
diff --git a/chromium/content/browser/presentation/presentation_type_converters.cc b/chromium/content/browser/presentation/presentation_type_converters.cc
index c39f8c86978..cd649976d5f 100644
--- a/chromium/content/browser/presentation/presentation_type_converters.cc
+++ b/chromium/content/browser/presentation/presentation_type_converters.cc
@@ -19,18 +19,25 @@ presentation::PresentationErrorType PresentationErrorTypeToMojo(
return presentation::PRESENTATION_ERROR_TYPE_NO_PRESENTATION_FOUND;
case content::PRESENTATION_ERROR_UNKNOWN:
return presentation::PRESENTATION_ERROR_TYPE_UNKNOWN;
- default:
- NOTREACHED();
- return presentation::PRESENTATION_ERROR_TYPE_UNKNOWN;
}
+ NOTREACHED();
+ return presentation::PRESENTATION_ERROR_TYPE_UNKNOWN;
}
-presentation::PresentationSessionState PresentationSessionStateToMojo(
- content::PresentationSessionState state) {
- if (state == content::PRESENTATION_SESSION_STATE_CONNECTED)
- return presentation::PRESENTATION_SESSION_STATE_CONNECTED;
- else
- return presentation::PRESENTATION_SESSION_STATE_DISCONNECTED;
+presentation::PresentationConnectionState PresentationConnectionStateToMojo(
+ content::PresentationConnectionState state) {
+ switch (state) {
+ case content::PRESENTATION_CONNECTION_STATE_CONNECTING:
+ return presentation::PRESENTATION_CONNECTION_STATE_CONNECTING;
+ case content::PRESENTATION_CONNECTION_STATE_CONNECTED:
+ return presentation::PRESENTATION_CONNECTION_STATE_CONNECTED;
+ case content::PRESENTATION_CONNECTION_STATE_CLOSED:
+ return presentation::PRESENTATION_CONNECTION_STATE_CLOSED;
+ case content::PRESENTATION_CONNECTION_STATE_TERMINATED:
+ return presentation::PRESENTATION_CONNECTION_STATE_TERMINATED;
+ }
+ NOTREACHED();
+ return presentation::PRESENTATION_CONNECTION_STATE_TERMINATED;
}
} // namespace content
diff --git a/chromium/content/browser/presentation/presentation_type_converters.h b/chromium/content/browser/presentation/presentation_type_converters.h
index f66c3230aba..c707f4fa5e8 100644
--- a/chromium/content/browser/presentation/presentation_type_converters.h
+++ b/chromium/content/browser/presentation/presentation_type_converters.h
@@ -14,8 +14,8 @@ namespace content {
CONTENT_EXPORT presentation::PresentationErrorType PresentationErrorTypeToMojo(
PresentationErrorType input);
-CONTENT_EXPORT presentation::PresentationSessionState
-PresentationSessionStateToMojo(PresentationSessionState state);
+CONTENT_EXPORT presentation::PresentationConnectionState
+PresentationConnectionStateToMojo(PresentationConnectionState state);
} // namespace content
@@ -30,7 +30,7 @@ struct TypeConverter<presentation::PresentationSessionInfoPtr,
presentation::PresentationSessionInfo::New());
output->url = input.presentation_url;
output->id = input.presentation_id;
- return output.Pass();
+ return output;
}
};
@@ -52,7 +52,7 @@ struct TypeConverter<presentation::PresentationErrorPtr,
presentation::PresentationError::New());
output->error_type = PresentationErrorTypeToMojo(input.error_type);
output->message = input.message;
- return output.Pass();
+ return output;
}
};
diff --git a/chromium/content/browser/profiler_controller_impl.h b/chromium/content/browser/profiler_controller_impl.h
index 0939d857c3c..3248d9293eb 100644
--- a/chromium/content/browser/profiler_controller_impl.h
+++ b/chromium/content/browser/profiler_controller_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_PROFILER_CONTROLLER_IMPL_H_
#define CONTENT_BROWSER_PROFILER_CONTROLLER_IMPL_H_
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/process/process.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/profiler_message_filter.cc b/chromium/content/browser/profiler_message_filter.cc
index 4bd85e21a54..b94c0e9bed1 100644
--- a/chromium/content/browser/profiler_message_filter.cc
+++ b/chromium/content/browser/profiler_message_filter.cc
@@ -6,7 +6,6 @@
#include "base/tracked_objects.h"
#include "content/browser/profiler_controller_impl.h"
-#include "content/browser/tcmalloc_internals_request_job.h"
#include "content/common/child_process_messages.h"
namespace content {
@@ -15,7 +14,7 @@ ProfilerMessageFilter::ProfilerMessageFilter(content::ProcessType process_type)
: BrowserMessageFilter(ChildProcessMsgStart), process_type_(process_type) {
}
-void ProfilerMessageFilter::OnChannelConnected(int32 peer_pid) {
+void ProfilerMessageFilter::OnChannelConnected(int32_t peer_pid) {
tracked_objects::ThreadData::Status status =
tracked_objects::ThreadData::status();
Send(new ChildProcessMsg_SetProfilerStatus(status));
@@ -26,9 +25,6 @@ bool ProfilerMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(ProfilerMessageFilter, message)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ChildProfilerData,
OnChildProfilerData)
-#if defined(USE_TCMALLOC)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_TcmallocStats, OnTcmallocStats)
-#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -43,11 +39,4 @@ void ProfilerMessageFilter::OnChildProfilerData(
sequence_number, profiler_data, process_type_);
}
-#if defined(USE_TCMALLOC)
-void ProfilerMessageFilter::OnTcmallocStats(const std::string& output) {
- AboutTcmallocOutputs::GetInstance()->OnStatsForChildProcess(
- peer_pid(), process_type_, output);
-}
-#endif
-
}
diff --git a/chromium/content/browser/profiler_message_filter.h b/chromium/content/browser/profiler_message_filter.h
index 875e45d0aa6..d29f97136bd 100644
--- a/chromium/content/browser/profiler_message_filter.h
+++ b/chromium/content/browser/profiler_message_filter.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_PROFILER_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_PROFILER_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/common/process_type.h"
@@ -22,7 +25,7 @@ class ProfilerMessageFilter : public BrowserMessageFilter {
explicit ProfilerMessageFilter(content::ProcessType process_type);
// BrowserMessageFilter implementation.
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
// BrowserMessageFilter implementation.
bool OnMessageReceived(const IPC::Message& message) override;
@@ -36,10 +39,6 @@ class ProfilerMessageFilter : public BrowserMessageFilter {
int sequence_number,
const tracked_objects::ProcessDataSnapshot& profiler_data);
-#if defined(USE_TCMALLOC)
- void OnTcmallocStats(const std::string& output);
-#endif
-
content::ProcessType process_type_;
DISALLOW_COPY_AND_ASSIGN(ProfilerMessageFilter);
diff --git a/chromium/content/browser/push_messaging/OWNERS b/chromium/content/browser/push_messaging/OWNERS
index d08448c9a60..da9d25a0d4d 100644
--- a/chromium/content/browser/push_messaging/OWNERS
+++ b/chromium/content/browser/push_messaging/OWNERS
@@ -1,8 +1,14 @@
# Push Messaging OWNERS
#
# This file also covers ownership of the following directories:
+# //chrome/android/java/src/org/chromium/chrome/browser/services/gcm/
+# //chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/
+# //chrome/browser/push_messaging/
+# //components/gcm_driver/
# //content/child/push_messaging/
# //content/renderer/push_messaging/
+# //third_party/WebKit/Source/modules/push_messaging/
+# //third_party/WebKit/public/platform/modules/push_messaging/
johnme@chromium.org
mvanouwerkerk@chromium.org
diff --git a/chromium/content/browser/push_messaging/PRESUBMIT.py b/chromium/content/browser/push_messaging/PRESUBMIT.py
new file mode 100644
index 00000000000..aa4ae97d1ae
--- /dev/null
+++ b/chromium/content/browser/push_messaging/PRESUBMIT.py
@@ -0,0 +1,12 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Top-level presubmit script for Push Messaging.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+def CheckChangeOnUpload(input_api, output_api):
+ return input_api.canned_checks.CheckPatchFormatted(input_api, output_api)
diff --git a/chromium/content/browser/push_messaging/push_messaging_message_filter.cc b/chromium/content/browser/push_messaging/push_messaging_message_filter.cc
index aa8cea5cc59..c3ccfe3f3fc 100644
--- a/chromium/content/browser/push_messaging/push_messaging_message_filter.cc
+++ b/chromium/content/browser/push_messaging/push_messaging_message_filter.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -45,34 +46,32 @@ const char kIncognitoPushUnsupportedMessage[] =
// https://groups.google.com/a/chromium.org/d/msg/chromium-dev/FNzZRJtN2aw/Aw0CWAXJJ1kJ
void RecordRegistrationStatus(PushRegistrationStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- UMA_HISTOGRAM_ENUMERATION("PushMessaging.RegistrationStatus",
- status,
+ UMA_HISTOGRAM_ENUMERATION("PushMessaging.RegistrationStatus", status,
PUSH_REGISTRATION_STATUS_LAST + 1);
}
void RecordUnregistrationStatus(PushUnregistrationStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationStatus",
- status,
+ UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationStatus", status,
PUSH_UNREGISTRATION_STATUS_LAST + 1);
}
void RecordGetRegistrationStatus(PushGetRegistrationStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- UMA_HISTOGRAM_ENUMERATION("PushMessaging.GetRegistrationStatus",
- status,
+ UMA_HISTOGRAM_ENUMERATION("PushMessaging.GetRegistrationStatus", status,
PUSH_GETREGISTRATION_STATUS_LAST + 1);
}
-// Curries the |success| and |curve25519dh| parameters over to |callback| and
+// Curries the |success| and |p256dh| parameters over to |callback| and
// posts a task to invoke |callback| on the IO thread.
-void ForwardPublicEncryptionKeysToIOThreadProxy(
- const PushMessagingService::PublicKeyCallback& callback,
+void ForwardEncryptionInfoToIOThreadProxy(
+ const PushMessagingService::EncryptionInfoCallback& callback,
bool success,
- const std::vector<uint8_t>& curve25519dh) {
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback, success, curve25519dh));
+ base::Bind(callback, success, p256dh, auth));
}
// Concatenates the subscription id with the endpoint base to create a new
@@ -96,7 +95,6 @@ struct PushMessagingMessageFilter::RegisterData {
int render_frame_id;
};
-
// Inner core of this message filter which lives on the UI thread.
class PushMessagingMessageFilter::Core {
public:
@@ -127,10 +125,10 @@ class PushMessagingMessageFilter::Core {
// Called via PostTask from IO thread. The |io_thread_callback| callback
// will be invoked on the IO thread.
- void GetPublicEncryptionKeyOnUI(
+ void GetEncryptionInfoOnUI(
const GURL& origin,
int64_t service_worker_registration_id,
- const PushMessagingService::PublicKeyCallback& io_thread_callback);
+ const PushMessagingService::EncryptionInfoCallback& io_thread_callback);
// Called (directly) from both the UI and IO threads.
bool is_incognito() const { return is_incognito_; }
@@ -148,7 +146,8 @@ class PushMessagingMessageFilter::Core {
void DidRegister(const RegisterData& data,
const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh,
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth,
PushRegistrationStatus status);
// Private Unregister methods on UI thread -----------------------------------
@@ -173,13 +172,11 @@ class PushMessagingMessageFilter::Core {
DISALLOW_COPY_AND_ASSIGN(Core);
};
-
PushMessagingMessageFilter::RegisterData::RegisterData()
: request_id(0),
service_worker_registration_id(0),
user_visible(false),
- render_frame_id(ChildProcessHost::kInvalidUniqueID) {
-}
+ render_frame_id(ChildProcessHost::kInvalidUniqueID) {}
bool PushMessagingMessageFilter::RegisterData::FromDocument() const {
return render_frame_id != ChildProcessHost::kInvalidUniqueID;
@@ -210,8 +207,8 @@ PushMessagingMessageFilter::PushMessagingMessageFilter(
// Normally, it would be unsafe to obtain a weak pointer from the UI thread,
// but it's ok in the constructor since we can't be destroyed before our
// constructor finishes.
- ui_core_.reset(new Core(weak_factory_io_to_io_.GetWeakPtr(),
- render_process_id));
+ ui_core_.reset(
+ new Core(weak_factory_io_to_io_.GetWeakPtr(), render_process_id));
PushMessagingService* push_service = ui_core_->service();
if (push_service)
push_endpoint_base_ = push_service->GetPushEndpoint();
@@ -231,9 +228,8 @@ bool PushMessagingMessageFilter::OnMessageReceived(
OnSubscribeFromDocument)
IPC_MESSAGE_HANDLER(PushMessagingHostMsg_SubscribeFromWorker,
OnSubscribeFromWorker)
- IPC_MESSAGE_HANDLER(PushMessagingHostMsg_Unsubscribe,
- OnUnsubscribe)
- IPC_MESSAGE_HANDLER(PushMessagingHostMsg_GetRegistration, OnGetRegistration)
+ IPC_MESSAGE_HANDLER(PushMessagingHostMsg_Unsubscribe, OnUnsubscribe)
+ IPC_MESSAGE_HANDLER(PushMessagingHostMsg_GetSubscription, OnGetSubscription)
IPC_MESSAGE_HANDLER(PushMessagingHostMsg_GetPermissionStatus,
OnGetPermissionStatus)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -264,19 +260,16 @@ void PushMessagingMessageFilter::OnSubscribeFromDocument(
service_worker_registration_id);
if (!service_worker_registration ||
!service_worker_registration->active_version()) {
- SendRegisterError(data, PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER);
+ SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER);
return;
}
data.requesting_origin = service_worker_registration->pattern().GetOrigin();
service_worker_context_->StoreRegistrationUserData(
- service_worker_registration_id,
- data.requesting_origin,
- kPushSenderIdServiceWorkerKey,
- sender_id,
+ service_worker_registration_id, data.requesting_origin,
+ kPushSenderIdServiceWorkerKey, sender_id,
base::Bind(&PushMessagingMessageFilter::DidPersistSenderId,
- weak_factory_io_to_io_.GetWeakPtr(),
- data, sender_id));
+ weak_factory_io_to_io_.GetWeakPtr(), data, sender_id));
}
void PushMessagingMessageFilter::OnSubscribeFromWorker(
@@ -293,7 +286,7 @@ void PushMessagingMessageFilter::OnSubscribeFromWorker(
service_worker_context_->GetLiveRegistration(
service_worker_registration_id);
if (!service_worker_registration) {
- SendRegisterError(data, PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER);
+ SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER);
return;
}
data.requesting_origin = service_worker_registration->pattern().GetOrigin();
@@ -308,7 +301,7 @@ void PushMessagingMessageFilter::DidPersistSenderId(
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (service_worker_status != SERVICE_WORKER_OK)
- SendRegisterError(data, PUSH_REGISTRATION_STATUS_STORAGE_ERROR);
+ SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_STORAGE_ERROR);
else
CheckForExistingRegistration(data, sender_id);
}
@@ -318,8 +311,7 @@ void PushMessagingMessageFilter::CheckForExistingRegistration(
const std::string& sender_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_context_->GetRegistrationUserData(
- data.service_worker_registration_id,
- kPushRegistrationIdServiceWorkerKey,
+ data.service_worker_registration_id, kPushRegistrationIdServiceWorkerKey,
base::Bind(&PushMessagingMessageFilter::DidCheckForExistingRegistration,
weak_factory_io_to_io_.GetWeakPtr(), data, sender_id));
}
@@ -331,14 +323,13 @@ void PushMessagingMessageFilter::DidCheckForExistingRegistration(
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (service_worker_status == SERVICE_WORKER_OK) {
- auto callback =
- base::Bind(&PushMessagingMessageFilter::DidGetEncryptionKeys,
- weak_factory_io_to_io_.GetWeakPtr(), data,
- push_registration_id);
+ auto callback = base::Bind(
+ &PushMessagingMessageFilter::DidGetEncryptionKeys,
+ weak_factory_io_to_io_.GetWeakPtr(), data, push_registration_id);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&Core::GetPublicEncryptionKeyOnUI,
+ base::Bind(&Core::GetEncryptionInfoOnUI,
base::Unretained(ui_core_.get()), data.requesting_origin,
data.service_worker_registration_id, callback));
return;
@@ -351,12 +342,11 @@ void PushMessagingMessageFilter::DidCheckForExistingRegistration(
if (data.FromDocument()) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&Core::RegisterOnUI, base::Unretained(ui_core_.get()),
- data, sender_id));
+ base::Bind(&Core::RegisterOnUI, base::Unretained(ui_core_.get()), data,
+ sender_id));
} else {
service_worker_context_->GetRegistrationUserData(
- data.service_worker_registration_id,
- kPushSenderIdServiceWorkerKey,
+ data.service_worker_registration_id, kPushSenderIdServiceWorkerKey,
base::Bind(&PushMessagingMessageFilter::DidGetSenderIdFromStorage,
weak_factory_io_to_io_.GetWeakPtr(), data));
}
@@ -366,15 +356,17 @@ void PushMessagingMessageFilter::DidGetEncryptionKeys(
const RegisterData& data,
const std::string& push_registration_id,
bool success,
- const std::vector<uint8_t>& curve25519dh) {
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!success) {
- SendRegisterError(data, PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE);
+ SendSubscriptionError(
+ data, PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE);
return;
}
- SendRegisterSuccess(data, PUSH_REGISTRATION_STATUS_SUCCESS_FROM_CACHE,
- push_registration_id, curve25519dh);
+ SendSubscriptionSuccess(data, PUSH_REGISTRATION_STATUS_SUCCESS_FROM_CACHE,
+ push_registration_id, p256dh, auth);
}
void PushMessagingMessageFilter::DidGetSenderIdFromStorage(
@@ -383,13 +375,13 @@ void PushMessagingMessageFilter::DidGetSenderIdFromStorage(
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (service_worker_status != SERVICE_WORKER_OK) {
- SendRegisterError(data, PUSH_REGISTRATION_STATUS_NO_SENDER_ID);
+ SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_NO_SENDER_ID);
return;
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&Core::RegisterOnUI, base::Unretained(ui_core_.get()),
- data, sender_id));
+ base::Bind(&Core::RegisterOnUI, base::Unretained(ui_core_.get()), data,
+ sender_id));
}
void PushMessagingMessageFilter::Core::RegisterOnUI(
@@ -402,7 +394,7 @@ void PushMessagingMessageFilter::Core::RegisterOnUI(
// TODO(johnme): Might be better not to expose the API in this case.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&PushMessagingMessageFilter::SendRegisterError,
+ base::Bind(&PushMessagingMessageFilter::SendSubscriptionError,
io_parent_,
data, PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE));
} else {
@@ -412,9 +404,8 @@ void PushMessagingMessageFilter::Core::RegisterOnUI(
// Throw a permission denied error under the same circumstances.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&PushMessagingMessageFilter::SendRegisterError,
- io_parent_,
- data,
+ base::Bind(&PushMessagingMessageFilter::SendSubscriptionError,
+ io_parent_, data,
PUSH_REGISTRATION_STATUS_INCOGNITO_PERMISSION_DENIED));
} else {
// Leave the promise hanging forever, to simulate a user ignoring the
@@ -451,54 +442,55 @@ void PushMessagingMessageFilter::Core::RegisterOnUI(
void PushMessagingMessageFilter::Core::DidRegister(
const RegisterData& data,
const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh,
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth,
PushRegistrationStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (status == PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&PushMessagingMessageFilter::PersistRegistrationOnIO,
- io_parent_, data, push_registration_id, curve25519dh));
+ io_parent_, data, push_registration_id, p256dh, auth));
} else {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&PushMessagingMessageFilter::SendRegisterError, io_parent_,
- data, status));
+ base::Bind(&PushMessagingMessageFilter::SendSubscriptionError,
+ io_parent_, data, status));
}
}
void PushMessagingMessageFilter::PersistRegistrationOnIO(
const RegisterData& data,
const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh) {
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_context_->StoreRegistrationUserData(
- data.service_worker_registration_id,
- data.requesting_origin,
- kPushRegistrationIdServiceWorkerKey,
- push_registration_id,
+ data.service_worker_registration_id, data.requesting_origin,
+ kPushRegistrationIdServiceWorkerKey, push_registration_id,
base::Bind(&PushMessagingMessageFilter::DidPersistRegistrationOnIO,
- weak_factory_io_to_io_.GetWeakPtr(),
- data, push_registration_id, curve25519dh));
+ weak_factory_io_to_io_.GetWeakPtr(), data,
+ push_registration_id, p256dh, auth));
}
void PushMessagingMessageFilter::DidPersistRegistrationOnIO(
const RegisterData& data,
const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh,
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth,
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (service_worker_status == SERVICE_WORKER_OK) {
- SendRegisterSuccess(data,
- PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE,
- push_registration_id, curve25519dh);
+ SendSubscriptionSuccess(data,
+ PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE,
+ push_registration_id, p256dh, auth);
} else {
// TODO(johnme): Unregister, so PushMessagingServiceImpl can decrease count.
- SendRegisterError(data, PUSH_REGISTRATION_STATUS_STORAGE_ERROR);
+ SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_STORAGE_ERROR);
}
}
-void PushMessagingMessageFilter::SendRegisterError(
+void PushMessagingMessageFilter::SendSubscriptionError(
const RegisterData& data, PushRegistrationStatus status) {
// Only called from IO thread, but would be safe to call from UI thread.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -506,37 +498,37 @@ void PushMessagingMessageFilter::SendRegisterError(
Send(new PushMessagingMsg_SubscribeFromDocumentError(
data.render_frame_id, data.request_id, status));
} else {
- Send(new PushMessagingMsg_SubscribeFromWorkerError(
- data.request_id, status));
+ Send(
+ new PushMessagingMsg_SubscribeFromWorkerError(data.request_id, status));
}
RecordRegistrationStatus(status);
}
-void PushMessagingMessageFilter::SendRegisterSuccess(
+void PushMessagingMessageFilter::SendSubscriptionSuccess(
const RegisterData& data,
PushRegistrationStatus status,
- const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh) {
+ const std::string& push_subscription_id,
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth) {
// Only called from IO thread, but would be safe to call from UI thread.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (push_endpoint_base_.is_empty()) {
// This shouldn't be possible in incognito mode, since we've already checked
// that we have an existing registration. Hence it's ok to throw an error.
DCHECK(!ui_core_->is_incognito());
- SendRegisterError(data, PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE);
+ SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE);
return;
}
if (data.FromDocument()) {
Send(new PushMessagingMsg_SubscribeFromDocumentSuccess(
- data.render_frame_id,
- data.request_id,
- CreatePushEndpoint(push_endpoint_base_, push_registration_id),
- curve25519dh));
+ data.render_frame_id, data.request_id,
+ CreatePushEndpoint(push_endpoint_base_, push_subscription_id), p256dh,
+ auth));
} else {
Send(new PushMessagingMsg_SubscribeFromWorkerSuccess(
data.request_id,
- CreatePushEndpoint(push_endpoint_base_, push_registration_id),
- curve25519dh));
+ CreatePushEndpoint(push_endpoint_base_, push_subscription_id), p256dh,
+ auth));
}
RecordRegistrationStatus(status);
}
@@ -547,7 +539,7 @@ void PushMessagingMessageFilter::SendRegisterSuccess(
void PushMessagingMessageFilter::OnUnsubscribe(
int request_id, int64_t service_worker_registration_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
ServiceWorkerRegistration* service_worker_registration =
service_worker_context_->GetLiveRegistration(
service_worker_registration_id);
@@ -557,8 +549,7 @@ void PushMessagingMessageFilter::OnUnsubscribe(
}
service_worker_context_->GetRegistrationUserData(
- service_worker_registration_id,
- kPushRegistrationIdServiceWorkerKey,
+ service_worker_registration_id, kPushRegistrationIdServiceWorkerKey,
base::Bind(&PushMessagingMessageFilter::
UnsubscribeHavingGottenPushSubscriptionId,
weak_factory_io_to_io_.GetWeakPtr(), request_id,
@@ -576,21 +567,16 @@ void PushMessagingMessageFilter::UnsubscribeHavingGottenPushSubscriptionId(
if (service_worker_status == SERVICE_WORKER_OK) {
service_worker_context_->GetRegistrationUserData(
- service_worker_registration_id,
- kPushSenderIdServiceWorkerKey,
- base::Bind(
- &PushMessagingMessageFilter::UnsubscribeHavingGottenSenderId,
- weak_factory_io_to_io_.GetWeakPtr(),
- request_id,
- service_worker_registration_id,
- requesting_origin));
+ service_worker_registration_id, kPushSenderIdServiceWorkerKey,
+ base::Bind(&PushMessagingMessageFilter::UnsubscribeHavingGottenSenderId,
+ weak_factory_io_to_io_.GetWeakPtr(), request_id,
+ service_worker_registration_id, requesting_origin));
} else {
// Errors are handled the same, whether we were trying to get the
// push_subscription_id or the sender_id.
- UnsubscribeHavingGottenSenderId(request_id, service_worker_registration_id,
- requesting_origin,
- std::string() /* sender_id */,
- service_worker_status);
+ UnsubscribeHavingGottenSenderId(
+ request_id, service_worker_registration_id, requesting_origin,
+ std::string() /* sender_id */, service_worker_status);
}
}
@@ -618,8 +604,7 @@ void PushMessagingMessageFilter::UnsubscribeHavingGottenSenderId(
PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
break;
case SERVICE_WORKER_ERROR_FAILED:
- DidUnregister(request_id,
- PUSH_UNREGISTRATION_STATUS_STORAGE_ERROR);
+ DidUnregister(request_id, PUSH_UNREGISTRATION_STATUS_STORAGE_ERROR);
break;
case SERVICE_WORKER_ERROR_ABORT:
case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
@@ -667,8 +652,8 @@ void PushMessagingMessageFilter::Core::UnregisterFromService(
push_service->Unsubscribe(
requesting_origin, service_worker_registration_id, sender_id,
base::Bind(&Core::DidUnregisterFromService,
- weak_factory_ui_to_ui_.GetWeakPtr(),
- request_id, service_worker_registration_id));
+ weak_factory_ui_to_ui_.GetWeakPtr(), request_id,
+ service_worker_registration_id));
}
void PushMessagingMessageFilter::Core::DidUnregisterFromService(
@@ -704,11 +689,10 @@ void PushMessagingMessageFilter::ClearRegistrationData(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_context_->ClearRegistrationUserData(
- service_worker_registration_id,
- kPushRegistrationIdServiceWorkerKey,
+ service_worker_registration_id, kPushRegistrationIdServiceWorkerKey,
base::Bind(&PushMessagingMessageFilter::DidClearRegistrationData,
- weak_factory_io_to_io_.GetWeakPtr(),
- request_id, unregistration_status));
+ weak_factory_io_to_io_.GetWeakPtr(), request_id,
+ unregistration_status));
}
void PushMessagingMessageFilter::DidClearRegistrationData(
@@ -755,27 +739,26 @@ void PushMessagingMessageFilter::DidUnregister(
RecordUnregistrationStatus(unregistration_status);
}
-// GetRegistration methods on both IO and UI threads, merged in order of use
+// GetSubscription methods on both IO and UI threads, merged in order of use
// from PushMessagingMessageFilter and Core.
// -----------------------------------------------------------------------------
-void PushMessagingMessageFilter::OnGetRegistration(
+void PushMessagingMessageFilter::OnGetSubscription(
int request_id,
int64_t service_worker_registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(johnme): Validate arguments?
service_worker_context_->GetRegistrationUserData(
- service_worker_registration_id,
- kPushRegistrationIdServiceWorkerKey,
- base::Bind(&PushMessagingMessageFilter::DidGetRegistration,
+ service_worker_registration_id, kPushRegistrationIdServiceWorkerKey,
+ base::Bind(&PushMessagingMessageFilter::DidGetSubscription,
weak_factory_io_to_io_.GetWeakPtr(), request_id,
service_worker_registration_id));
}
-void PushMessagingMessageFilter::DidGetRegistration(
+void PushMessagingMessageFilter::DidGetSubscription(
int request_id,
int64_t service_worker_registration_id,
- const std::string& push_registration_id,
+ const std::string& push_subscription_id,
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
PushGetRegistrationStatus get_status =
@@ -786,23 +769,26 @@ void PushMessagingMessageFilter::DidGetRegistration(
// Return not found in incognito mode, so websites can't detect it.
get_status =
ui_core_->is_incognito()
- ? PUSH_GETREGISTRATION_STATUS_INCOGNITO_REGISTRATION_NOT_FOUND
- : PUSH_GETREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
+ ? PUSH_GETREGISTRATION_STATUS_INCOGNITO_REGISTRATION_NOT_FOUND
+ : PUSH_GETREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
break;
}
- const GURL origin = service_worker_context_->GetLiveRegistration(
- service_worker_registration_id)->pattern().GetOrigin();
+ ServiceWorkerRegistration* registration =
+ service_worker_context_->GetLiveRegistration(
+ service_worker_registration_id);
+
+ const GURL origin = registration->pattern().GetOrigin();
const GURL endpoint =
- CreatePushEndpoint(push_endpoint_base_, push_registration_id);
+ CreatePushEndpoint(push_endpoint_base_, push_subscription_id);
auto callback =
- base::Bind(&PushMessagingMessageFilter::DidGetRegistrationKeys,
+ base::Bind(&PushMessagingMessageFilter::DidGetSubscriptionKeys,
weak_factory_io_to_io_.GetWeakPtr(), request_id, endpoint);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&Core::GetPublicEncryptionKeyOnUI,
+ base::Bind(&Core::GetEncryptionInfoOnUI,
base::Unretained(ui_core_.get()), origin,
service_worker_registration_id, callback));
@@ -839,28 +825,29 @@ void PushMessagingMessageFilter::DidGetRegistration(
break;
}
}
- Send(new PushMessagingMsg_GetRegistrationError(request_id, get_status));
+ Send(new PushMessagingMsg_GetSubscriptionError(request_id, get_status));
RecordGetRegistrationStatus(get_status);
}
-void PushMessagingMessageFilter::DidGetRegistrationKeys(
+void PushMessagingMessageFilter::DidGetSubscriptionKeys(
int request_id,
const GURL& endpoint,
bool success,
- const std::vector<uint8_t>& curve25519dh) {
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!success) {
PushGetRegistrationStatus status =
PUSH_GETREGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE;
- Send(new PushMessagingMsg_GetRegistrationError(request_id, status));
+ Send(new PushMessagingMsg_GetSubscriptionError(request_id, status));
RecordGetRegistrationStatus(status);
return;
}
- Send(new PushMessagingMsg_GetRegistrationSuccess(request_id, endpoint,
- curve25519dh));
+ Send(new PushMessagingMsg_GetSubscriptionSuccess(request_id, endpoint,
+ p256dh, auth));
RecordGetRegistrationStatus(PUSH_GETREGISTRATION_STATUS_SUCCESS);
}
@@ -903,9 +890,8 @@ void PushMessagingMessageFilter::Core::GetPermissionStatusOnUI(
return;
}
GURL embedding_origin = requesting_origin;
- permission_status = push_service->GetPermissionStatus(requesting_origin,
- embedding_origin,
- user_visible);
+ permission_status = push_service->GetPermissionStatus(
+ requesting_origin, embedding_origin, user_visible);
} else if (is_incognito()) {
// Return prompt, so the website can't detect incognito mode.
permission_status = blink::WebPushPermissionStatusPrompt;
@@ -922,24 +908,23 @@ void PushMessagingMessageFilter::Core::GetPermissionStatusOnUI(
// PushMessagingMessageFilter and Core.
// -----------------------------------------------------------------------------
-void PushMessagingMessageFilter::Core::GetPublicEncryptionKeyOnUI(
+void PushMessagingMessageFilter::Core::GetEncryptionInfoOnUI(
const GURL& origin,
int64_t service_worker_registration_id,
- const PushMessagingService::PublicKeyCallback& io_thread_callback) {
+ const PushMessagingService::EncryptionInfoCallback& io_thread_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
PushMessagingService* push_service = service();
if (push_service) {
- push_service->GetPublicEncryptionKey(
+ push_service->GetEncryptionInfo(
origin, service_worker_registration_id,
- base::Bind(&ForwardPublicEncryptionKeysToIOThreadProxy,
- io_thread_callback));
+ base::Bind(&ForwardEncryptionInfoToIOThreadProxy, io_thread_callback));
return;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(io_thread_callback, false /* success */,
- std::vector<uint8_t>()));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(io_thread_callback, false /* success */,
+ std::vector<uint8_t>() /* p256dh */,
+ std::vector<uint8_t>() /* auth */));
}
void PushMessagingMessageFilter::Core::Send(IPC::Message* message) {
@@ -958,8 +943,8 @@ PushMessagingService* PushMessagingMessageFilter::Core::service() {
RenderProcessHost* process_host =
RenderProcessHost::FromID(render_process_id_);
return process_host
- ? process_host->GetBrowserContext()->GetPushMessagingService()
- : nullptr;
+ ? process_host->GetBrowserContext()->GetPushMessagingService()
+ : nullptr;
}
} // namespace content
diff --git a/chromium/content/browser/push_messaging/push_messaging_message_filter.h b/chromium/content/browser/push_messaging/push_messaging_message_filter.h
index c95d4772ed2..aba0b348abc 100644
--- a/chromium/content/browser/push_messaging/push_messaging_message_filter.h
+++ b/chromium/content/browser/push_messaging/push_messaging_message_filter.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -62,9 +63,8 @@ class PushMessagingMessageFilter : public BrowserMessageFilter {
ServiceWorkerStatusCode service_worker_status);
// sender_id is ignored if data.FromDocument() is false.
- void CheckForExistingRegistration(
- const RegisterData& data,
- const std::string& sender_id);
+ void CheckForExistingRegistration(const RegisterData& data,
+ const std::string& sender_id);
// sender_id is ignored if data.FromDocument() is false.
void DidCheckForExistingRegistration(
@@ -76,7 +76,8 @@ class PushMessagingMessageFilter : public BrowserMessageFilter {
void DidGetEncryptionKeys(const RegisterData& data,
const std::string& push_registration_id,
bool success,
- const std::vector<uint8_t>& curve25519dh);
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth);
void DidGetSenderIdFromStorage(const RegisterData& data,
const std::string& sender_id,
@@ -85,22 +86,25 @@ class PushMessagingMessageFilter : public BrowserMessageFilter {
// Called via PostTask from UI thread.
void PersistRegistrationOnIO(const RegisterData& data,
const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh);
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth);
void DidPersistRegistrationOnIO(
const RegisterData& data,
const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh,
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth,
ServiceWorkerStatusCode service_worker_status);
// Called both from IO thread, and via PostTask from UI thread.
- void SendRegisterError(const RegisterData& data,
- PushRegistrationStatus status);
+ void SendSubscriptionError(const RegisterData& data,
+ PushRegistrationStatus status);
// Called both from IO thread, and via PostTask from UI thread.
- void SendRegisterSuccess(const RegisterData& data,
- PushRegistrationStatus status,
- const std::string& push_registration_id,
- const std::vector<uint8_t>& curve25519dh);
+ void SendSubscriptionSuccess(const RegisterData& data,
+ PushRegistrationStatus status,
+ const std::string& push_subscription_id,
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth);
// Unsubscribe methods on IO thread ------------------------------------------
@@ -133,27 +137,28 @@ class PushMessagingMessageFilter : public BrowserMessageFilter {
void DidUnregister(int request_id,
PushUnregistrationStatus unregistration_status);
- // GetRegistration methods on IO thread --------------------------------------
+ // GetSubscription methods on IO thread --------------------------------------
- void OnGetRegistration(int request_id,
+ void OnGetSubscription(int request_id,
int64_t service_worker_registration_id);
- void DidGetRegistration(int request_id,
+ void DidGetSubscription(int request_id,
int64_t service_worker_registration_id,
- const std::string& push_registration_id,
+ const std::string& push_subscription_id,
ServiceWorkerStatusCode status);
+ void DidGetSubscriptionKeys(int request_id,
+ const GURL& endpoint,
+ bool success,
+ const std::vector<uint8_t>& p256dh,
+ const std::vector<uint8_t>& auth);
+
// GetPermission methods on IO thread ----------------------------------------
void OnGetPermissionStatus(int request_id,
int64_t service_worker_registration_id,
bool user_visible);
- void DidGetRegistrationKeys(int request_id,
- const GURL& endpoint,
- bool success,
- const std::vector<uint8_t>& curve25519dh);
-
// Helper methods on IO thread -----------------------------------------------
// Called via PostTask from UI thread.
diff --git a/chromium/content/browser/push_messaging/push_messaging_router.cc b/chromium/content/browser/push_messaging/push_messaging_router.cc
index 6385feb8da2..bc95216ad07 100644
--- a/chromium/content/browser/push_messaging/push_messaging_router.cc
+++ b/chromium/content/browser/push_messaging/push_messaging_router.cc
@@ -33,7 +33,7 @@ void RunDeliverCallback(
void PushMessagingRouter::DeliverMessage(
BrowserContext* browser_context,
const GURL& origin,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& data,
const DeliverMessageCallback& deliver_message_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -43,32 +43,26 @@ void PushMessagingRouter::DeliverMessage(
static_cast<ServiceWorkerContextWrapper*>(
partition->GetServiceWorkerContext());
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&PushMessagingRouter::FindServiceWorkerRegistration,
- origin,
- service_worker_registration_id,
- data,
- deliver_message_callback,
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&PushMessagingRouter::FindServiceWorkerRegistration, origin,
+ service_worker_registration_id, data, deliver_message_callback,
service_worker_context));
}
// static
void PushMessagingRouter::FindServiceWorkerRegistration(
const GURL& origin,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& data,
const DeliverMessageCallback& deliver_message_callback,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Try to acquire the registration from storage. If it's already live we'll
// receive it right away. If not, it will be revived from storage.
- service_worker_context->FindRegistrationForId(
- service_worker_registration_id,
- origin,
+ service_worker_context->FindReadyRegistrationForId(
+ service_worker_registration_id, origin,
base::Bind(&PushMessagingRouter::FindServiceWorkerRegistrationCallback,
- data,
- deliver_message_callback));
+ data, deliver_message_callback));
}
// static
@@ -82,27 +76,12 @@ void PushMessagingRouter::FindServiceWorkerRegistrationCallback(
// TODO(mvanouwerkerk): UMA logging.
if (service_worker_status != SERVICE_WORKER_OK) {
RunDeliverCallback(deliver_message_callback,
- PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER);
+ PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER);
return;
}
ServiceWorkerVersion* version = service_worker_registration->active_version();
- if (!version) {
- // Using NO_SERVICE_WORKER status will unsubscribe with GCM, so don't use it
- // if we have a waiting version in the hopper. On the other hand, if there
- // is no waiting version, it's an unexpected error case: we should have been
- // informed the registration went away (but we may not have been:
- // crbug.com/402458)
- // TODO(falken): Promote the waiting version instead of returning error.
- if (service_worker_registration->waiting_version()) {
- RunDeliverCallback(deliver_message_callback,
- PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR);
- } else {
- RunDeliverCallback(deliver_message_callback,
- PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER);
- }
- return;
- }
+ DCHECK(version);
// Hold on to the service worker registration in the callback to keep it
// alive until the callback dies. Otherwise the registration could be
@@ -111,6 +90,7 @@ void PushMessagingRouter::FindServiceWorkerRegistrationCallback(
base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback =
base::Bind(&PushMessagingRouter::DeliverMessageEnd,
deliver_message_callback, service_worker_registration);
+
version->DispatchPushEvent(dispatch_event_callback, data);
}
diff --git a/chromium/content/browser/push_messaging/push_messaging_router.h b/chromium/content/browser/push_messaging/push_messaging_router.h
index d9f25cc3868..dae9973de26 100644
--- a/chromium/content/browser/push_messaging/push_messaging_router.h
+++ b/chromium/content/browser/push_messaging/push_messaging_router.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_ROUTER_H_
#define CONTENT_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_ROUTER_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/service_worker/service_worker_status_code.h"
@@ -19,8 +22,7 @@ class ServiceWorkerRegistration;
class PushMessagingRouter {
public:
- typedef base::Callback<void(PushDeliveryStatus)>
- DeliverMessageCallback;
+ typedef base::Callback<void(PushDeliveryStatus)> DeliverMessageCallback;
// Delivers a push message with |data| to the Service Worker identified by
// |origin| and |service_worker_registration_id|. Must be called on the UI
@@ -28,7 +30,7 @@ class PushMessagingRouter {
static void DeliverMessage(
BrowserContext* browser_context,
const GURL& origin,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& data,
const DeliverMessageCallback& deliver_message_callback);
@@ -37,7 +39,7 @@ class PushMessagingRouter {
// dispatched. Must be called on the IO thread.
static void FindServiceWorkerRegistration(
const GURL& origin,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const std::string& data,
const DeliverMessageCallback& deliver_message_callback,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
diff --git a/chromium/content/browser/quota/mock_quota_manager.cc b/chromium/content/browser/quota/mock_quota_manager.cc
index 47bc304537e..90674081e0c 100644
--- a/chromium/content/browser/quota/mock_quota_manager.cc
+++ b/chromium/content/browser/quota/mock_quota_manager.cc
@@ -4,6 +4,8 @@
#include "content/browser/quota/mock_quota_manager.h"
+#include <limits>
+
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -28,7 +30,8 @@ MockQuotaManager::OriginInfo::OriginInfo(
MockQuotaManager::OriginInfo::~OriginInfo() {}
-MockQuotaManager::StorageInfo::StorageInfo() : usage(0), quota(kint64max) {}
+MockQuotaManager::StorageInfo::StorageInfo()
+ : usage(0), quota(std::numeric_limits<int64_t>::max()) {}
MockQuotaManager::StorageInfo::~StorageInfo() {}
MockQuotaManager::MockQuotaManager(
@@ -53,8 +56,9 @@ void MockQuotaManager::GetUsageAndQuota(
callback.Run(storage::kQuotaStatusOk, info.usage, info.quota);
}
-void MockQuotaManager::SetQuota(const GURL& origin, StorageType type,
- int64 quota) {
+void MockQuotaManager::SetQuota(const GURL& origin,
+ StorageType type,
+ int64_t quota) {
usage_and_quota_map_[std::make_pair(origin, type)].quota = quota;
}
@@ -125,8 +129,9 @@ void MockQuotaManager::DeleteOriginData(
MockQuotaManager::~MockQuotaManager() {}
-void MockQuotaManager::UpdateUsage(
- const GURL& origin, StorageType type, int64 delta) {
+void MockQuotaManager::UpdateUsage(const GURL& origin,
+ StorageType type,
+ int64_t delta) {
usage_and_quota_map_[std::make_pair(origin, type)].usage += delta;
}
diff --git a/chromium/content/browser/quota/mock_quota_manager.h b/chromium/content/browser/quota/mock_quota_manager.h
index a6bba10e985..9dfd779c944 100644
--- a/chromium/content/browser/quota/mock_quota_manager.h
+++ b/chromium/content/browser/quota/mock_quota_manager.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_QUOTA_MOCK_QUOTA_MANAGER_H_
#define CONTENT_BROWSER_QUOTA_MOCK_QUOTA_MANAGER_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <utility>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "storage/browser/quota/quota_client.h"
#include "storage/browser/quota/quota_manager.h"
@@ -74,7 +77,7 @@ class MockQuotaManager : public QuotaManager {
const StatusCallback& callback) override;
// Helper method for updating internal quota info.
- void SetQuota(const GURL& origin, StorageType type, int64 quota);
+ void SetQuota(const GURL& origin, StorageType type, int64_t quota);
// Helper methods for timed-deletion testing:
// Adds an origin to the canned list that will be searched through via
@@ -123,15 +126,15 @@ class MockQuotaManager : public QuotaManager {
struct StorageInfo {
StorageInfo();
~StorageInfo();
- int64 usage;
- int64 quota;
+ int64_t usage;
+ int64_t quota;
};
typedef std::pair<GURL, StorageType> OriginAndType;
typedef std::map<OriginAndType, StorageInfo> UsageAndQuotaMap;
// This must be called via MockQuotaManagerProxy.
- void UpdateUsage(const GURL& origin, StorageType type, int64 delta);
+ void UpdateUsage(const GURL& origin, StorageType type, int64_t delta);
void DidGetModifiedSince(const GetOriginsCallback& callback,
std::set<GURL>* origins,
StorageType storage_type);
diff --git a/chromium/content/browser/quota/mock_quota_manager_proxy.cc b/chromium/content/browser/quota/mock_quota_manager_proxy.cc
index 2e26e32c0f3..a8b955d894c 100644
--- a/chromium/content/browser/quota/mock_quota_manager_proxy.cc
+++ b/chromium/content/browser/quota/mock_quota_manager_proxy.cc
@@ -43,9 +43,10 @@ void MockQuotaManagerProxy::NotifyStorageAccessed(
last_notified_type_ = type;
}
-void MockQuotaManagerProxy::NotifyStorageModified(
- QuotaClient::ID client_id, const GURL& origin,
- StorageType type, int64 delta) {
+void MockQuotaManagerProxy::NotifyStorageModified(QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType type,
+ int64_t delta) {
++storage_modified_count_;
last_notified_origin_ = origin;
last_notified_type_ = type;
diff --git a/chromium/content/browser/quota/mock_quota_manager_proxy.h b/chromium/content/browser/quota/mock_quota_manager_proxy.h
index 0f52f6dcc8e..118761de5c9 100644
--- a/chromium/content/browser/quota/mock_quota_manager_proxy.h
+++ b/chromium/content/browser/quota/mock_quota_manager_proxy.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_QUOTA_MOCK_QUOTA_MANAGER_PROXY_H_
#define CONTENT_BROWSER_QUOTA_MOCK_QUOTA_MANAGER_PROXY_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/browser/quota/mock_quota_manager.h"
#include "storage/browser/quota/quota_client.h"
#include "storage/browser/quota/quota_manager_proxy.h"
@@ -55,13 +58,13 @@ class MockQuotaManagerProxy : public QuotaManagerProxy {
void NotifyStorageModified(QuotaClient::ID client_id,
const GURL& origin,
StorageType type,
- int64 delta) override;
+ int64_t delta) override;
int notify_storage_accessed_count() const { return storage_accessed_count_; }
int notify_storage_modified_count() const { return storage_modified_count_; }
GURL last_notified_origin() const { return last_notified_origin_; }
StorageType last_notified_type() const { return last_notified_type_; }
- int64 last_notified_delta() const { return last_notified_delta_; }
+ int64_t last_notified_delta() const { return last_notified_delta_; }
protected:
~MockQuotaManagerProxy() override;
@@ -75,7 +78,7 @@ class MockQuotaManagerProxy : public QuotaManagerProxy {
int storage_modified_count_;
GURL last_notified_origin_;
StorageType last_notified_type_;
- int64 last_notified_delta_;
+ int64_t last_notified_delta_;
QuotaClient* registered_client_;
diff --git a/chromium/content/browser/quota/mock_quota_manager_unittest.cc b/chromium/content/browser/quota/mock_quota_manager_unittest.cc
index e5e170cb998..9a46cf38833 100644
--- a/chromium/content/browser/quota/mock_quota_manager_unittest.cc
+++ b/chromium/content/browser/quota/mock_quota_manager_unittest.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
diff --git a/chromium/content/browser/quota/quota_backend_impl_unittest.cc b/chromium/content/browser/quota/quota_backend_impl_unittest.cc
index 6139e8a0075..516cab3e1bd 100644
--- a/chromium/content/browser/quota/quota_backend_impl_unittest.cc
+++ b/chromium/content/browser/quota/quota_backend_impl_unittest.cc
@@ -4,9 +4,12 @@
#include "storage/browser/fileapi/quota/quota_backend_impl.h"
+#include <stdint.h>
+
#include <string>
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/thread_task_runner_handle.h"
#include "storage/browser/fileapi/file_system_usage_cache.h"
#include "storage/browser/fileapi/obfuscated_file_util.h"
@@ -28,9 +31,9 @@ const char kOrigin[] = "http://example.com";
bool DidReserveQuota(bool accepted,
base::File::Error* error_out,
- int64* delta_out,
+ int64_t* delta_out,
base::File::Error error,
- int64 delta) {
+ int64_t delta) {
DCHECK(error_out);
DCHECK(delta_out);
*error_out = error;
@@ -56,7 +59,7 @@ class MockQuotaManagerProxy : public storage::QuotaManagerProxy {
void NotifyStorageModified(storage::QuotaClient::ID client_id,
const GURL& origin,
storage::StorageType type,
- int64 delta) override {
+ int64_t delta) override {
++storage_modified_count_;
usage_ += delta;
ASSERT_LE(usage_, quota_);
@@ -70,17 +73,17 @@ class MockQuotaManagerProxy : public storage::QuotaManagerProxy {
}
int storage_modified_count() { return storage_modified_count_; }
- int64 usage() { return usage_; }
- void set_usage(int64 usage) { usage_ = usage; }
- void set_quota(int64 quota) { quota_ = quota; }
+ int64_t usage() { return usage_; }
+ void set_usage(int64_t usage) { usage_ = usage; }
+ void set_quota(int64_t quota) { quota_ = quota; }
protected:
~MockQuotaManagerProxy() override {}
private:
int storage_modified_count_;
- int64 usage_;
- int64 quota_;
+ int64_t usage_;
+ int64_t quota_;
DISALLOW_COPY_AND_ASSIGN(MockQuotaManagerProxy);
};
@@ -159,9 +162,9 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_Basic) {
InitializeForOriginAndType(GURL(kOrigin), type);
quota_manager_proxy_->set_quota(10000);
- int64 delta = 0;
+ int64_t delta = 0;
- const int64 kDelta1 = 1000;
+ const int64_t kDelta1 = 1000;
base::File::Error error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta1,
base::Bind(&DidReserveQuota, true, &error, &delta));
@@ -169,7 +172,7 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_Basic) {
EXPECT_EQ(kDelta1, delta);
EXPECT_EQ(kDelta1, quota_manager_proxy_->usage());
- const int64 kDelta2 = -300;
+ const int64_t kDelta2 = -300;
error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta2,
base::Bind(&DidReserveQuota, true, &error, &delta));
@@ -185,9 +188,9 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_NoSpace) {
InitializeForOriginAndType(GURL(kOrigin), type);
quota_manager_proxy_->set_quota(100);
- int64 delta = 0;
+ int64_t delta = 0;
- const int64 kDelta = 1000;
+ const int64_t kDelta = 1000;
base::File::Error error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta,
base::Bind(&DidReserveQuota, true, &error, &delta));
@@ -203,9 +206,9 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_Revert) {
InitializeForOriginAndType(GURL(kOrigin), type);
quota_manager_proxy_->set_quota(10000);
- int64 delta = 0;
+ int64_t delta = 0;
- const int64 kDelta = 1000;
+ const int64_t kDelta = 1000;
base::File::Error error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta,
base::Bind(&DidReserveQuota, false, &error, &delta));
@@ -219,11 +222,11 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_Revert) {
TEST_F(QuotaBackendImplTest, ReleaseReservedQuota) {
storage::FileSystemType type = storage::kFileSystemTypeTemporary;
InitializeForOriginAndType(GURL(kOrigin), type);
- const int64 kInitialUsage = 2000;
+ const int64_t kInitialUsage = 2000;
quota_manager_proxy_->set_usage(kInitialUsage);
quota_manager_proxy_->set_quota(10000);
- const int64 kSize = 1000;
+ const int64_t kSize = 1000;
backend_->ReleaseReservedQuota(GURL(kOrigin), type, kSize);
EXPECT_EQ(kInitialUsage - kSize, quota_manager_proxy_->usage());
@@ -236,14 +239,14 @@ TEST_F(QuotaBackendImplTest, CommitQuotaUsage) {
quota_manager_proxy_->set_quota(10000);
base::FilePath path = GetUsageCachePath(GURL(kOrigin), type);
- const int64 kDelta1 = 1000;
+ const int64_t kDelta1 = 1000;
backend_->CommitQuotaUsage(GURL(kOrigin), type, kDelta1);
EXPECT_EQ(kDelta1, quota_manager_proxy_->usage());
- int64 usage = 0;
+ int64_t usage = 0;
EXPECT_TRUE(file_system_usage_cache_.GetUsage(path, &usage));
EXPECT_EQ(kDelta1, usage);
- const int64 kDelta2 = -300;
+ const int64_t kDelta2 = -300;
backend_->CommitQuotaUsage(GURL(kOrigin), type, kDelta2);
EXPECT_EQ(kDelta1 + kDelta2, quota_manager_proxy_->usage());
usage = 0;
@@ -259,7 +262,7 @@ TEST_F(QuotaBackendImplTest, DirtyCount) {
base::FilePath path = GetUsageCachePath(GURL(kOrigin), type);
backend_->IncrementDirtyCount(GURL(kOrigin), type);
- uint32 dirty = 0;
+ uint32_t dirty = 0;
ASSERT_TRUE(file_system_usage_cache_.GetDirty(path, &dirty));
EXPECT_EQ(1u, dirty);
diff --git a/chromium/content/browser/quota/quota_database_unittest.cc b/chromium/content/browser/quota/quota_database_unittest.cc
index 84af01707c2..026a46a45a4 100644
--- a/chromium/content/browser/quota/quota_database_unittest.cc
+++ b/chromium/content/browser/quota/quota_database_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <algorithm>
#include <iterator>
#include <set>
@@ -10,6 +13,7 @@
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "content/public/test/mock_special_storage_policy.h"
#include "sql/connection.h"
@@ -56,7 +60,7 @@ class QuotaDatabaseTest : public testing::Test {
EXPECT_TRUE(kDbFile.empty() || base::PathExists(kDbFile));
}
- void UpgradeSchemaV2toV3(const base::FilePath& kDbFile) {
+ void UpgradeSchemaV2toV5(const base::FilePath& kDbFile) {
const QuotaTableEntry entries[] = {
QuotaTableEntry("a", kStorageTypeTemporary, 1),
QuotaTableEntry("b", kStorageTypeTemporary, 2),
@@ -74,6 +78,9 @@ class QuotaDatabaseTest : public testing::Test {
EXPECT_TRUE(db.DumpQuotaTable(
base::Bind(&Verifier::Run, base::Unretained(&verifier))));
EXPECT_TRUE(verifier.table.empty());
+
+ EXPECT_TRUE(db.db_->DoesTableExist("EvictionInfoTable"));
+ EXPECT_TRUE(db.db_->DoesIndexExist("sqlite_autoindex_EvictionInfoTable_1"));
}
void HostQuota(const base::FilePath& kDbFile) {
@@ -84,7 +91,7 @@ class QuotaDatabaseTest : public testing::Test {
const int kQuota1 = 13579;
const int kQuota2 = kQuota1 + 1024;
- int64 quota = -1;
+ int64_t quota = -1;
EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, &quota));
EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypePersistent, &quota));
@@ -113,9 +120,9 @@ class QuotaDatabaseTest : public testing::Test {
const char* kTempQuotaKey = QuotaDatabase::kTemporaryQuotaOverrideKey;
const char* kAvailSpaceKey = QuotaDatabase::kDesiredAvailableSpaceKey;
- int64 value = 0;
- const int64 kValue1 = 456;
- const int64 kValue2 = 123000;
+ int64_t value = 0;
+ const int64_t kValue1 = 456;
+ const int64_t kValue2 = 123000;
EXPECT_FALSE(db.GetQuotaConfigValue(kTempQuotaKey, &value));
EXPECT_FALSE(db.GetQuotaConfigValue(kAvailSpaceKey, &value));
@@ -294,6 +301,61 @@ class QuotaDatabaseTest : public testing::Test {
EXPECT_EQ(0U, origins.count(kOrigin3));
}
+ void OriginLastEvicted(const base::FilePath& kDbFile) {
+ QuotaDatabase db(kDbFile);
+ ASSERT_TRUE(db.LazyOpen(true));
+
+ const GURL kOrigin1("http://a/");
+ const GURL kOrigin2("http://b/");
+ const GURL kOrigin3("http://c/");
+
+ base::Time last_eviction_time;
+ EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary,
+ &last_eviction_time));
+ EXPECT_EQ(base::Time(), last_eviction_time);
+
+ // Report last eviction time for the test origins.
+ EXPECT_TRUE(db.SetOriginLastEvictionTime(
+ kOrigin1, kStorageTypeTemporary, base::Time::FromInternalValue(10)));
+ EXPECT_TRUE(db.SetOriginLastEvictionTime(
+ kOrigin2, kStorageTypeTemporary, base::Time::FromInternalValue(20)));
+ EXPECT_TRUE(db.SetOriginLastEvictionTime(
+ kOrigin3, kStorageTypeTemporary, base::Time::FromInternalValue(30)));
+
+ EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary,
+ &last_eviction_time));
+ EXPECT_EQ(base::Time::FromInternalValue(10), last_eviction_time);
+ EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin2, kStorageTypeTemporary,
+ &last_eviction_time));
+ EXPECT_EQ(base::Time::FromInternalValue(20), last_eviction_time);
+ EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary,
+ &last_eviction_time));
+ EXPECT_EQ(base::Time::FromInternalValue(30), last_eviction_time);
+
+ // Delete last eviction times for the test origins.
+ EXPECT_TRUE(
+ db.DeleteOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary));
+ EXPECT_TRUE(
+ db.DeleteOriginLastEvictionTime(kOrigin2, kStorageTypeTemporary));
+ EXPECT_TRUE(
+ db.DeleteOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary));
+
+ last_eviction_time = base::Time();
+ EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary,
+ &last_eviction_time));
+ EXPECT_EQ(base::Time(), last_eviction_time);
+ EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin2, kStorageTypeTemporary,
+ &last_eviction_time));
+ EXPECT_EQ(base::Time(), last_eviction_time);
+ EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary,
+ &last_eviction_time));
+ EXPECT_EQ(base::Time(), last_eviction_time);
+
+ // Deleting an origin that is not present should not fail.
+ EXPECT_TRUE(db.DeleteOriginLastEvictionTime(GURL("http://notpresent.com"),
+ kStorageTypeTemporary));
+ }
+
void RegisterInitialOriginInfo(const base::FilePath& kDbFile) {
QuotaDatabase db(kDbFile);
@@ -305,28 +367,26 @@ class QuotaDatabaseTest : public testing::Test {
EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kStorageTypeTemporary));
- int used_count = -1;
- EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"),
- kStorageTypeTemporary,
- &used_count));
- EXPECT_EQ(0, used_count);
+ QuotaDatabase::OriginInfoTableEntry info;
+ info.used_count = -1;
+ EXPECT_TRUE(db.GetOriginInfo(
+ GURL("http://a/"), kStorageTypeTemporary, &info));
+ EXPECT_EQ(0, info.used_count);
EXPECT_TRUE(db.SetOriginLastAccessTime(
GURL("http://a/"), kStorageTypeTemporary,
base::Time::FromDoubleT(1.0)));
- used_count = -1;
- EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"),
- kStorageTypeTemporary,
- &used_count));
- EXPECT_EQ(1, used_count);
+ info.used_count = -1;
+ EXPECT_TRUE(db.GetOriginInfo(
+ GURL("http://a/"), kStorageTypeTemporary, &info));
+ EXPECT_EQ(1, info.used_count);
EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kStorageTypeTemporary));
- used_count = -1;
- EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"),
- kStorageTypeTemporary,
- &used_count));
- EXPECT_EQ(1, used_count);
+ info.used_count = -1;
+ EXPECT_TRUE(db.GetOriginInfo(
+ GURL("http://a/"), kStorageTypeTemporary, &info));
+ EXPECT_EQ(1, info.used_count);
}
template <typename EntryType>
@@ -387,6 +447,36 @@ class QuotaDatabaseTest : public testing::Test {
EXPECT_TRUE(verifier.table.empty());
}
+ void GetOriginInfo(const base::FilePath& kDbFile) {
+ const GURL kOrigin = GURL("http://go/");
+ typedef QuotaDatabase::OriginInfoTableEntry Entry;
+ Entry kTableEntries[] = {
+ Entry(kOrigin, kStorageTypeTemporary, 100, base::Time(), base::Time())};
+ Entry* begin = kTableEntries;
+ Entry* end = kTableEntries + arraysize(kTableEntries);
+
+ QuotaDatabase db(kDbFile);
+ EXPECT_TRUE(db.LazyOpen(true));
+ AssignOriginInfoTable(db.db_.get(), begin, end);
+ db.Commit();
+
+ {
+ Entry entry;
+ EXPECT_TRUE(db.GetOriginInfo(kOrigin, kStorageTypeTemporary, &entry));
+ EXPECT_EQ(kTableEntries[0].type, entry.type);
+ EXPECT_EQ(kTableEntries[0].origin, entry.origin);
+ EXPECT_EQ(kTableEntries[0].used_count, entry.used_count);
+ EXPECT_EQ(kTableEntries[0].last_access_time, entry.last_access_time);
+ EXPECT_EQ(kTableEntries[0].last_modified_time, entry.last_modified_time);
+ }
+
+ {
+ Entry entry;
+ EXPECT_FALSE(db.GetOriginInfo(GURL("http://notpresent.org/"),
+ kStorageTypeTemporary, &entry));
+ }
+ }
+
private:
template <typename Iterator>
void AssignQuotaTable(sql::Connection* db, Iterator itr, Iterator end) {
@@ -506,7 +596,7 @@ TEST_F(QuotaDatabaseTest, UpgradeSchema) {
base::ScopedTempDir data_dir;
ASSERT_TRUE(data_dir.CreateUniqueTempDir());
const base::FilePath kDbFile = data_dir.path().AppendASCII(kDBFileName);
- UpgradeSchemaV2toV3(kDbFile);
+ UpgradeSchemaV2toV5(kDbFile);
}
TEST_F(QuotaDatabaseTest, HostQuota) {
@@ -541,6 +631,14 @@ TEST_F(QuotaDatabaseTest, OriginLastModifiedSince) {
OriginLastModifiedSince(base::FilePath());
}
+TEST_F(QuotaDatabaseTest, OriginLastEvicted) {
+ base::ScopedTempDir data_dir;
+ ASSERT_TRUE(data_dir.CreateUniqueTempDir());
+ const base::FilePath kDbFile = data_dir.path().AppendASCII(kDBFileName);
+ OriginLastEvicted(kDbFile);
+ OriginLastEvicted(base::FilePath());
+}
+
TEST_F(QuotaDatabaseTest, BootstrapFlag) {
base::ScopedTempDir data_dir;
ASSERT_TRUE(data_dir.CreateUniqueTempDir());
@@ -579,6 +677,10 @@ TEST_F(QuotaDatabaseTest, DumpOriginInfoTable) {
DumpOriginInfoTable(base::FilePath());
}
+TEST_F(QuotaDatabaseTest, GetOriginInfo) {
+ GetOriginInfo(base::FilePath());
+}
+
TEST_F(QuotaDatabaseTest, OpenCorruptedDatabase) {
base::ScopedTempDir data_dir;
ASSERT_TRUE(data_dir.CreateUniqueTempDir());
diff --git a/chromium/content/browser/quota/quota_manager_unittest.cc b/chromium/content/browser/quota/quota_manager_unittest.cc
index 39c2315689f..80889ba8b30 100644
--- a/chromium/content/browser/quota/quota_manager_unittest.cc
+++ b/chromium/content/browser/quota/quota_manager_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <algorithm>
#include <set>
#include <sstream>
@@ -10,11 +13,13 @@
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/sys_info.h"
+#include "base/test/histogram_tester.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "content/public/test/mock_special_storage_policy.h"
@@ -53,16 +58,35 @@ const StorageType kSync = kStorageTypeSyncable;
const int kAllClients = QuotaClient::kAllClientsMask;
-const int64 kAvailableSpaceForApp = 13377331U;
+const int64_t kAvailableSpaceForApp = 13377331U;
-const int64 kMinimumPreserveForSystem = QuotaManager::kMinimumPreserveForSystem;
+const int64_t kMinimumPreserveForSystem =
+ QuotaManager::kMinimumPreserveForSystem;
const int kPerHostTemporaryPortion = QuotaManager::kPerHostTemporaryPortion;
+const GURL kTestEvictionOrigin = GURL("http://test.eviction.policy/result");
+
// Returns a deterministic value for the amount of available disk space.
-int64 GetAvailableDiskSpaceForTest(const base::FilePath&) {
+int64_t GetAvailableDiskSpaceForTest(const base::FilePath&) {
return kAvailableSpaceForApp + kMinimumPreserveForSystem;
}
+class TestEvictionPolicy : public storage::QuotaEvictionPolicy {
+ public:
+ TestEvictionPolicy() {}
+ ~TestEvictionPolicy() override {}
+
+ // Overridden from storage::QuotaEvictionPolicy:
+ void GetEvictionOrigin(const scoped_refptr<storage::SpecialStoragePolicy>&
+ special_storage_policy,
+ const std::set<GURL>& exceptions,
+ const std::map<GURL, int64_t>& usage_map,
+ int64_t global_quota,
+ const storage::GetOriginCallback& callback) override {
+ callback.Run(kTestEvictionOrigin);
+ }
+};
+
} // namespace
class QuotaManagerTest : public testing::Test {
@@ -149,7 +173,7 @@ class QuotaManagerTest : public testing::Test {
weak_factory_.GetWeakPtr()));
}
- void SetTemporaryGlobalQuota(int64 new_quota) {
+ void SetTemporaryGlobalQuota(int64_t new_quota) {
quota_status_ = kQuotaStatusUnknown;
quota_ = -1;
quota_manager_->SetTemporaryGlobalOverrideQuota(
@@ -167,7 +191,7 @@ class QuotaManagerTest : public testing::Test {
weak_factory_.GetWeakPtr()));
}
- void SetPersistentHostQuota(const std::string& host, int64 new_quota) {
+ void SetPersistentHostQuota(const std::string& host, int64_t new_quota) {
quota_status_ = kQuotaStatusUnknown;
quota_ = -1;
quota_manager_->SetPersistentHostQuota(
@@ -265,6 +289,12 @@ class QuotaManagerTest : public testing::Test {
quota_manager_->GetCachedOrigins(type, origins);
}
+ bool GetVolumeInfo(const base::FilePath& path,
+ uint64_t* available_space,
+ uint64_t* total_size) {
+ return QuotaManager::GetVolumeInfo(path, available_space, total_size);
+ }
+
void NotifyStorageAccessed(QuotaClient* client,
const GURL& origin,
StorageType type) {
@@ -274,14 +304,16 @@ class QuotaManagerTest : public testing::Test {
}
void DeleteOriginFromDatabase(const GURL& origin, StorageType type) {
- quota_manager_->DeleteOriginFromDatabase(origin, type);
+ quota_manager_->DeleteOriginFromDatabase(origin, type, false);
}
- void GetLRUOrigin(StorageType type) {
- lru_origin_ = GURL();
- quota_manager_->GetLRUOrigin(
- type,
- base::Bind(&QuotaManagerTest::DidGetLRUOrigin,
+ void GetEvictionOrigin(StorageType type) {
+ eviction_origin_ = GURL();
+ // The quota manager's default eviction policy is to use an LRU eviction
+ // policy.
+ quota_manager_->GetEvictionOrigin(
+ type, std::set<GURL>(), 0,
+ base::Bind(&QuotaManagerTest::DidGetEvictionOrigin,
weak_factory_.GetWeakPtr()));
}
@@ -320,38 +352,35 @@ class QuotaManagerTest : public testing::Test {
usage_info_.insert(usage_info_.begin(), entries.begin(), entries.end());
}
- void DidGetUsageAndQuota(QuotaStatusCode status, int64 usage, int64 quota) {
+ void DidGetUsageAndQuota(QuotaStatusCode status,
+ int64_t usage,
+ int64_t quota) {
quota_status_ = status;
usage_ = usage;
quota_ = quota;
}
- void DidGetQuota(QuotaStatusCode status,
- int64 quota) {
+ void DidGetQuota(QuotaStatusCode status, int64_t quota) {
quota_status_ = status;
quota_ = quota;
}
- void DidGetAvailableSpace(QuotaStatusCode status, int64 available_space) {
+ void DidGetAvailableSpace(QuotaStatusCode status, int64_t available_space) {
quota_status_ = status;
available_space_ = available_space;
}
- void DidGetHostQuota(QuotaStatusCode status,
- int64 quota) {
+ void DidGetHostQuota(QuotaStatusCode status, int64_t quota) {
quota_status_ = status;
quota_ = quota;
}
- void DidGetGlobalUsage(int64 usage,
- int64 unlimited_usage) {
+ void DidGetGlobalUsage(int64_t usage, int64_t unlimited_usage) {
usage_ = usage;
unlimited_usage_ = unlimited_usage;
}
- void DidGetHostUsage(int64 usage) {
- usage_ = usage;
- }
+ void DidGetHostUsage(int64_t usage) { usage_ = usage; }
void StatusCallback(QuotaStatusCode status) {
++status_callback_count_;
@@ -366,8 +395,8 @@ class QuotaManagerTest : public testing::Test {
available_space_ = usage_and_quota.available_disk_space;
}
- void DidGetLRUOrigin(const GURL& origin) {
- lru_origin_ = origin;
+ void DidGetEvictionOrigin(const GURL& origin) {
+ eviction_origin_ = origin;
}
void DidGetModifiedOrigins(const std::set<GURL>& origins, StorageType type) {
@@ -387,8 +416,9 @@ class QuotaManagerTest : public testing::Test {
void set_additional_callback_count(int c) { additional_callback_count_ = c; }
int additional_callback_count() const { return additional_callback_count_; }
- void DidGetUsageAndQuotaAdditional(
- QuotaStatusCode status, int64 usage, int64 quota) {
+ void DidGetUsageAndQuotaAdditional(QuotaStatusCode status,
+ int64_t usage,
+ int64_t quota) {
++additional_callback_count_;
}
@@ -403,12 +433,12 @@ class QuotaManagerTest : public testing::Test {
QuotaStatusCode status() const { return quota_status_; }
const UsageInfoEntries& usage_info() const { return usage_info_; }
- int64 usage() const { return usage_; }
- int64 limited_usage() const { return limited_usage_; }
- int64 unlimited_usage() const { return unlimited_usage_; }
- int64 quota() const { return quota_; }
- int64 available_space() const { return available_space_; }
- const GURL& lru_origin() const { return lru_origin_; }
+ int64_t usage() const { return usage_; }
+ int64_t limited_usage() const { return limited_usage_; }
+ int64_t unlimited_usage() const { return unlimited_usage_; }
+ int64_t quota() const { return quota_; }
+ int64_t available_space() const { return available_space_; }
+ const GURL& eviction_origin() const { return eviction_origin_; }
const std::set<GURL>& modified_origins() const { return modified_origins_; }
StorageType modified_origins_type() const { return modified_origins_type_; }
const QuotaTableEntries& quota_entries() const { return quota_entries_; }
@@ -433,12 +463,12 @@ class QuotaManagerTest : public testing::Test {
QuotaStatusCode quota_status_;
UsageInfoEntries usage_info_;
- int64 usage_;
- int64 limited_usage_;
- int64 unlimited_usage_;
- int64 quota_;
- int64 available_space_;
- GURL lru_origin_;
+ int64_t usage_;
+ int64_t limited_usage_;
+ int64_t unlimited_usage_;
+ int64_t quota_;
+ int64_t available_space_;
+ GURL eviction_origin_;
std::set<GURL> modified_origins_;
StorageType modified_origins_type_;
QuotaTableEntries quota_entries_;
@@ -512,7 +542,7 @@ TEST_F(QuotaManagerTest, GetUsageAndQuota_Simple) {
EXPECT_EQ(kQuotaStatusOk, status());
EXPECT_EQ(10, usage());
EXPECT_LE(0, quota());
- int64 quota_returned_for_foo = quota();
+ int64_t quota_returned_for_foo = quota();
GetUsageAndQuotaForWebApps(GURL("http://bar.com/"), kTemp);
base::RunLoop().RunUntilIdle();
@@ -639,7 +669,7 @@ TEST_F(QuotaManagerTest, GetUsage_MultipleClients) {
RegisterClient(CreateClient(kData2, arraysize(kData2),
QuotaClient::kDatabase));
- const int64 kTempQuotaBase =
+ const int64_t kTempQuotaBase =
GetAvailableDiskSpaceForTest(base::FilePath()) / kPerHostTemporaryPortion;
GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kTemp);
@@ -1228,15 +1258,15 @@ TEST_F(QuotaManagerTest, GetUsage_WithDeleteOrigin) {
GetGlobalUsage(kTemp);
base::RunLoop().RunUntilIdle();
- int64 predelete_global_tmp = usage();
+ int64_t predelete_global_tmp = usage();
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_tmp = usage();
+ int64_t predelete_host_tmp = usage();
GetHostUsage("foo.com", kPerm);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_pers = usage();
+ int64_t predelete_host_pers = usage();
DeleteClientOriginData(client, GURL("http://foo.com/"),
kTemp);
@@ -1263,6 +1293,15 @@ TEST_F(QuotaManagerTest, GetAvailableSpaceTest) {
EXPECT_LE(0, available_space());
}
+TEST_F(QuotaManagerTest, SetTemporaryStorageEvictionPolicy) {
+ quota_manager()->SetTemporaryStorageEvictionPolicy(
+ make_scoped_ptr(new TestEvictionPolicy));
+
+ GetEvictionOrigin(kTemp);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(kTestEvictionOrigin, eviction_origin());
+}
+
TEST_F(QuotaManagerTest, EvictOriginData) {
static const MockOriginData kData1[] = {
{ "http://foo.com/", kTemp, 1 },
@@ -1286,15 +1325,15 @@ TEST_F(QuotaManagerTest, EvictOriginData) {
GetGlobalUsage(kTemp);
base::RunLoop().RunUntilIdle();
- int64 predelete_global_tmp = usage();
+ int64_t predelete_global_tmp = usage();
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_tmp = usage();
+ int64_t predelete_host_tmp = usage();
GetHostUsage("foo.com", kPerm);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_pers = usage();
+ int64_t predelete_host_pers = usage();
for (size_t i = 0; i < arraysize(kData1); ++i)
quota_manager()->NotifyStorageAccessed(QuotaClient::kUnknown,
@@ -1331,6 +1370,72 @@ TEST_F(QuotaManagerTest, EvictOriginData) {
EXPECT_EQ(predelete_host_pers, usage());
}
+TEST_F(QuotaManagerTest, EvictOriginDataHistogram) {
+ const GURL kOrigin = GURL("http://foo.com/");
+ static const MockOriginData kData[] = {
+ {"http://foo.com/", kTemp, 1},
+ };
+
+ base::HistogramTester histograms;
+ MockStorageClient* client =
+ CreateClient(kData, arraysize(kData), QuotaClient::kFileSystem);
+ RegisterClient(client);
+
+ GetGlobalUsage(kTemp);
+ base::RunLoop().RunUntilIdle();
+
+ EvictOriginData(kOrigin, kTemp);
+ base::RunLoop().RunUntilIdle();
+
+ // Ensure used count and time since access are recorded.
+ histograms.ExpectTotalCount(
+ QuotaManager::kEvictedOriginAccessedCountHistogram, 1);
+ histograms.ExpectBucketCount(
+ QuotaManager::kEvictedOriginAccessedCountHistogram, 0, 1);
+ histograms.ExpectTotalCount(
+ QuotaManager::kEvictedOriginTimeSinceAccessHistogram, 1);
+
+ // First eviction has no 'last' time to compare to.
+ histograms.ExpectTotalCount(
+ QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, 0);
+
+ client->AddOriginAndNotify(kOrigin, kTemp, 100);
+
+ // Change the used count of the origin.
+ quota_manager()->NotifyStorageAccessed(QuotaClient::kUnknown, GURL(kOrigin),
+ kTemp);
+ base::RunLoop().RunUntilIdle();
+
+ GetGlobalUsage(kTemp);
+ base::RunLoop().RunUntilIdle();
+
+ EvictOriginData(kOrigin, kTemp);
+ base::RunLoop().RunUntilIdle();
+
+ // The new used count should be logged.
+ histograms.ExpectTotalCount(
+ QuotaManager::kEvictedOriginAccessedCountHistogram, 2);
+ histograms.ExpectBucketCount(
+ QuotaManager::kEvictedOriginAccessedCountHistogram, 1, 1);
+ histograms.ExpectTotalCount(
+ QuotaManager::kEvictedOriginTimeSinceAccessHistogram, 2);
+
+ // Second eviction should log a 'time between repeated eviction' sample.
+ histograms.ExpectTotalCount(
+ QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, 1);
+
+ client->AddOriginAndNotify(kOrigin, kTemp, 100);
+
+ GetGlobalUsage(kTemp);
+ base::RunLoop().RunUntilIdle();
+
+ DeleteOriginFromDatabase(kOrigin, kTemp);
+
+ // Deletion from non-eviction source should not log a histogram sample.
+ histograms.ExpectTotalCount(
+ QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, 1);
+}
+
TEST_F(QuotaManagerTest, EvictOriginDataWithDeletionError) {
static const MockOriginData kData[] = {
{ "http://foo.com/", kTemp, 1 },
@@ -1345,15 +1450,15 @@ TEST_F(QuotaManagerTest, EvictOriginDataWithDeletionError) {
GetGlobalUsage(kTemp);
base::RunLoop().RunUntilIdle();
- int64 predelete_global_tmp = usage();
+ int64_t predelete_global_tmp = usage();
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_tmp = usage();
+ int64_t predelete_host_tmp = usage();
GetHostUsage("foo.com", kPerm);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_pers = usage();
+ int64_t predelete_host_pers = usage();
for (size_t i = 0; i < arraysize(kData); ++i)
NotifyStorageAccessed(client, GURL(kData[i].origin), kData[i].type);
@@ -1387,19 +1492,19 @@ TEST_F(QuotaManagerTest, EvictOriginDataWithDeletionError) {
EXPECT_TRUE(found_origin_in_database);
for (size_t i = 0; i < kNumberOfTemporaryOrigins - 1; ++i) {
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(lru_origin().is_empty());
+ EXPECT_FALSE(eviction_origin().is_empty());
// The origin "http://foo.com/" should not be in the LRU list.
- EXPECT_NE(std::string("http://foo.com/"), lru_origin().spec());
- DeleteOriginFromDatabase(lru_origin(), kTemp);
+ EXPECT_NE(std::string("http://foo.com/"), eviction_origin().spec());
+ DeleteOriginFromDatabase(eviction_origin(), kTemp);
base::RunLoop().RunUntilIdle();
}
// Now the LRU list must be empty.
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(lru_origin().is_empty());
+ EXPECT_TRUE(eviction_origin().is_empty());
// Deleting origins from the database should not affect the results of the
// following checks.
@@ -1450,15 +1555,15 @@ TEST_F(QuotaManagerTest, DeleteHostDataSimple) {
GetGlobalUsage(kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_global_tmp = usage();
+ const int64_t predelete_global_tmp = usage();
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_tmp = usage();
+ int64_t predelete_host_tmp = usage();
GetHostUsage("foo.com", kPerm);
base::RunLoop().RunUntilIdle();
- int64 predelete_host_pers = usage();
+ int64_t predelete_host_pers = usage();
DeleteHostData(std::string(), kTemp, kAllClients);
base::RunLoop().RunUntilIdle();
@@ -1516,23 +1621,23 @@ TEST_F(QuotaManagerTest, DeleteHostDataMultiple) {
GetGlobalUsage(kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_global_tmp = usage();
+ const int64_t predelete_global_tmp = usage();
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_tmp = usage();
+ const int64_t predelete_foo_tmp = usage();
GetHostUsage("bar.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_bar_tmp = usage();
+ const int64_t predelete_bar_tmp = usage();
GetHostUsage("foo.com", kPerm);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_pers = usage();
+ const int64_t predelete_foo_pers = usage();
GetHostUsage("bar.com", kPerm);
base::RunLoop().RunUntilIdle();
- const int64 predelete_bar_pers = usage();
+ const int64_t predelete_bar_pers = usage();
reset_status_callback_count();
DeleteHostData("foo.com", kTemp, kAllClients);
@@ -1604,23 +1709,23 @@ TEST_F(QuotaManagerTest, DeleteOriginDataMultiple) {
GetGlobalUsage(kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_global_tmp = usage();
+ const int64_t predelete_global_tmp = usage();
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_tmp = usage();
+ const int64_t predelete_foo_tmp = usage();
GetHostUsage("bar.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_bar_tmp = usage();
+ const int64_t predelete_bar_tmp = usage();
GetHostUsage("foo.com", kPerm);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_pers = usage();
+ const int64_t predelete_foo_pers = usage();
GetHostUsage("bar.com", kPerm);
base::RunLoop().RunUntilIdle();
- const int64 predelete_bar_pers = usage();
+ const int64_t predelete_bar_pers = usage();
for (size_t i = 0; i < arraysize(kData1); ++i)
quota_manager()->NotifyStorageAccessed(QuotaClient::kUnknown,
@@ -1728,31 +1833,31 @@ TEST_F(QuotaManagerTest, NotifyAndLRUOrigin) {
RegisterClient(client);
GURL origin;
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(lru_origin().is_empty());
+ EXPECT_TRUE(eviction_origin().is_empty());
NotifyStorageAccessed(client, GURL("http://a.com/"), kTemp);
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ("http://a.com/", lru_origin().spec());
+ EXPECT_EQ("http://a.com/", eviction_origin().spec());
NotifyStorageAccessed(client, GURL("http://b.com/"), kPerm);
NotifyStorageAccessed(client, GURL("https://a.com/"), kTemp);
NotifyStorageAccessed(client, GURL("http://c.com/"), kTemp);
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ("http://a.com/", lru_origin().spec());
+ EXPECT_EQ("http://a.com/", eviction_origin().spec());
- DeleteOriginFromDatabase(lru_origin(), kTemp);
- GetLRUOrigin(kTemp);
+ DeleteOriginFromDatabase(eviction_origin(), kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ("https://a.com/", lru_origin().spec());
+ EXPECT_EQ("https://a.com/", eviction_origin().spec());
- DeleteOriginFromDatabase(lru_origin(), kTemp);
- GetLRUOrigin(kTemp);
+ DeleteOriginFromDatabase(eviction_origin(), kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ("http://c.com/", lru_origin().spec());
+ EXPECT_EQ("http://c.com/", eviction_origin().spec());
}
TEST_F(QuotaManagerTest, GetLRUOriginWithOriginInUse) {
@@ -1768,46 +1873,46 @@ TEST_F(QuotaManagerTest, GetLRUOriginWithOriginInUse) {
RegisterClient(client);
GURL origin;
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(lru_origin().is_empty());
+ EXPECT_TRUE(eviction_origin().is_empty());
NotifyStorageAccessed(client, GURL("http://a.com/"), kTemp);
NotifyStorageAccessed(client, GURL("http://b.com/"), kPerm);
NotifyStorageAccessed(client, GURL("https://a.com/"), kTemp);
NotifyStorageAccessed(client, GURL("http://c.com/"), kTemp);
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ("http://a.com/", lru_origin().spec());
+ EXPECT_EQ("http://a.com/", eviction_origin().spec());
// Notify origin http://a.com is in use.
NotifyOriginInUse(GURL("http://a.com/"));
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ("https://a.com/", lru_origin().spec());
+ EXPECT_EQ("https://a.com/", eviction_origin().spec());
- // Notify origin https://a.com is in use while GetLRUOrigin is running.
- GetLRUOrigin(kTemp);
+ // Notify origin https://a.com is in use while GetEvictionOrigin is running.
+ GetEvictionOrigin(kTemp);
NotifyOriginInUse(GURL("https://a.com/"));
base::RunLoop().RunUntilIdle();
// Post-filtering must have excluded the returned origin, so we will
// see empty result here.
- EXPECT_TRUE(lru_origin().is_empty());
+ EXPECT_TRUE(eviction_origin().is_empty());
- // Notify access for http://c.com while GetLRUOrigin is running.
- GetLRUOrigin(kTemp);
+ // Notify access for http://c.com while GetEvictionOrigin is running.
+ GetEvictionOrigin(kTemp);
NotifyStorageAccessed(client, GURL("http://c.com/"), kTemp);
base::RunLoop().RunUntilIdle();
// Post-filtering must have excluded the returned origin, so we will
// see empty result here.
- EXPECT_TRUE(lru_origin().is_empty());
+ EXPECT_TRUE(eviction_origin().is_empty());
NotifyOriginNoLongerInUse(GURL("http://a.com/"));
NotifyOriginNoLongerInUse(GURL("https://a.com/"));
- GetLRUOrigin(kTemp);
+ GetEvictionOrigin(kTemp);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ("http://a.com/", lru_origin().spec());
+ EXPECT_EQ("http://a.com/", eviction_origin().spec());
}
TEST_F(QuotaManagerTest, GetOriginsModifiedSince) {
@@ -1972,7 +2077,7 @@ TEST_F(QuotaManagerTest, DeleteSpecificClientTypeSingleOrigin) {
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_tmp = usage();
+ const int64_t predelete_foo_tmp = usage();
DeleteOriginData(GURL("http://foo.com/"), kTemp, QuotaClient::kFileSystem);
base::RunLoop().RunUntilIdle();
@@ -2028,7 +2133,7 @@ TEST_F(QuotaManagerTest, DeleteSpecificClientTypeSingleHost) {
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_tmp = usage();
+ const int64_t predelete_foo_tmp = usage();
DeleteHostData("foo.com", kTemp, QuotaClient::kFileSystem);
base::RunLoop().RunUntilIdle();
@@ -2083,7 +2188,7 @@ TEST_F(QuotaManagerTest, DeleteMultipleClientTypesSingleOrigin) {
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_tmp = usage();
+ const int64_t predelete_foo_tmp = usage();
DeleteOriginData(GURL("http://foo.com/"), kTemp,
QuotaClient::kFileSystem | QuotaClient::kDatabase);
@@ -2128,7 +2233,7 @@ TEST_F(QuotaManagerTest, DeleteMultipleClientTypesSingleHost) {
GetHostUsage("foo.com", kTemp);
base::RunLoop().RunUntilIdle();
- const int64 predelete_foo_tmp = usage();
+ const int64_t predelete_foo_tmp = usage();
DeleteHostData("foo.com", kTemp,
QuotaClient::kFileSystem | QuotaClient::kAppcache);
@@ -2166,8 +2271,9 @@ TEST_F(QuotaManagerTest, GetUsageAndQuota_Incognito) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(kQuotaStatusOk, status());
EXPECT_EQ(10, usage());
- EXPECT_LE(std::min(static_cast<int64>(100 / kPerHostTemporaryPortion),
- QuotaManager::kIncognitoDefaultQuotaLimit), quota());
+ EXPECT_LE(std::min(static_cast<int64_t>(100 / kPerHostTemporaryPortion),
+ QuotaManager::kIncognitoDefaultQuotaLimit),
+ quota());
mock_special_storage_policy()->AddUnlimited(GURL("http://foo.com/"));
GetUsageAndQuotaForWebApps(GURL("http://foo.com/"), kPerm);
@@ -2183,4 +2289,15 @@ TEST_F(QuotaManagerTest, GetUsageAndQuota_Incognito) {
EXPECT_EQ(QuotaManager::kIncognitoDefaultQuotaLimit, quota());
}
+TEST_F(QuotaManagerTest, GetVolumeInfo) {
+ // We aren't actually testing that it's correct, just that it's sane.
+ base::FilePath tmp_dir;
+ ASSERT_TRUE(base::GetTempDir(&tmp_dir));
+ uint64_t available_space = 0;
+ uint64_t total_size = 0;
+ EXPECT_TRUE(GetVolumeInfo(tmp_dir, &available_space, &total_size));
+ EXPECT_GT(available_space, 0u) << tmp_dir.value();
+ EXPECT_GT(total_size, 0u) << tmp_dir.value();
+}
+
} // namespace content
diff --git a/chromium/content/browser/quota/quota_reservation_manager_unittest.cc b/chromium/content/browser/quota/quota_reservation_manager_unittest.cc
index 05fff80b609..d2588e168e7 100644
--- a/chromium/content/browser/quota/quota_reservation_manager_unittest.cc
+++ b/chromium/content/browser/quota/quota_reservation_manager_unittest.cc
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "storage/browser/fileapi/quota/quota_reservation_manager.h"
+#include <stdint.h>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -10,11 +11,13 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "storage/browser/fileapi/quota/open_file_handle.h"
#include "storage/browser/fileapi/quota/quota_reservation.h"
+#include "storage/browser/fileapi/quota/quota_reservation_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
using storage::kFileSystemTypeTemporary;
@@ -28,17 +31,17 @@ namespace {
const char kOrigin[] = "http://example.com";
const storage::FileSystemType kType = kFileSystemTypeTemporary;
-const int64 kInitialFileSize = 1;
+const int64_t kInitialFileSize = 1;
typedef QuotaReservationManager::ReserveQuotaCallback ReserveQuotaCallback;
-int64 GetFileSize(const base::FilePath& path) {
- int64 size = 0;
+int64_t GetFileSize(const base::FilePath& path) {
+ int64_t size = 0;
base::GetFileSize(path, &size);
return size;
}
-void SetFileSize(const base::FilePath& path, int64 size) {
+void SetFileSize(const base::FilePath& path, int64_t size) {
base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
ASSERT_TRUE(file.IsValid());
ASSERT_TRUE(file.SetLength(size));
@@ -53,7 +56,7 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
void ReserveQuota(const GURL& origin,
storage::FileSystemType type,
- int64 delta,
+ int64_t delta,
const ReserveQuotaCallback& callback) override {
EXPECT_EQ(GURL(kOrigin), origin);
EXPECT_EQ(kType, type);
@@ -65,7 +68,7 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
void ReleaseReservedQuota(const GURL& origin,
storage::FileSystemType type,
- int64 size) override {
+ int64_t size) override {
EXPECT_LE(0, size);
EXPECT_EQ(GURL(kOrigin), origin);
EXPECT_EQ(kType, type);
@@ -74,7 +77,7 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
void CommitQuotaUsage(const GURL& origin,
storage::FileSystemType type,
- int64 delta) override {
+ int64_t delta) override {
EXPECT_EQ(GURL(kOrigin), origin);
EXPECT_EQ(kType, type);
on_disk_usage_ += delta;
@@ -86,12 +89,12 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
void DecrementDirtyCount(const GURL& origin,
storage::FileSystemType type) override {}
- int64 on_memory_usage() { return on_memory_usage_; }
- int64 on_disk_usage() { return on_disk_usage_; }
+ int64_t on_memory_usage() { return on_memory_usage_; }
+ int64_t on_disk_usage() { return on_disk_usage_; }
private:
- int64 on_memory_usage_;
- int64 on_disk_usage_;
+ int64_t on_memory_usage_;
+ int64_t on_disk_usage_;
DISALLOW_COPY_AND_ASSIGN(FakeBackend);
};
@@ -99,20 +102,19 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
class FakeWriter {
public:
explicit FakeWriter(scoped_ptr<OpenFileHandle> handle)
- : handle_(handle.Pass()),
+ : handle_(std::move(handle)),
path_(handle_->platform_path()),
max_written_offset_(handle_->GetEstimatedFileSize()),
append_mode_write_amount_(0),
- dirty_(false) {
- }
+ dirty_(false) {}
~FakeWriter() {
if (handle_)
EXPECT_FALSE(dirty_);
}
- int64 Truncate(int64 length) {
- int64 consumed = 0;
+ int64_t Truncate(int64_t length) {
+ int64_t consumed = 0;
if (max_written_offset_ < length) {
consumed = length - max_written_offset_;
@@ -122,10 +124,10 @@ class FakeWriter {
return consumed;
}
- int64 Write(int64 max_offset) {
+ int64_t Write(int64_t max_offset) {
dirty_ = true;
- int64 consumed = 0;
+ int64_t consumed = 0;
if (max_written_offset_ < max_offset) {
consumed = max_offset - max_written_offset_;
max_written_offset_ = max_offset;
@@ -135,7 +137,7 @@ class FakeWriter {
return consumed;
}
- int64 Append(int64 amount) {
+ int64_t Append(int64_t amount) {
dirty_ = true;
append_mode_write_amount_ += amount;
SetFileSize(path_, GetFileSize(path_) + amount);
@@ -157,8 +159,8 @@ class FakeWriter {
private:
scoped_ptr<OpenFileHandle> handle_;
base::FilePath path_;
- int64 max_written_offset_;
- int64 append_mode_write_amount_;
+ int64_t max_written_offset_;
+ int64_t append_mode_write_amount_;
bool dirty_;
};
@@ -168,7 +170,7 @@ void ExpectSuccess(bool* done, base::File::Error error) {
EXPECT_EQ(base::File::FILE_OK, error);
}
-void RefreshReservation(QuotaReservation* reservation, int64 size) {
+void RefreshReservation(QuotaReservation* reservation, int64_t size) {
DCHECK(reservation);
bool done = false;
@@ -190,7 +192,7 @@ class QuotaReservationManagerTest : public testing::Test {
SetFileSize(file_path_, kInitialFileSize);
scoped_ptr<QuotaReservationManager::QuotaBackend> backend(new FakeBackend);
- reservation_manager_.reset(new QuotaReservationManager(backend.Pass()));
+ reservation_manager_.reset(new QuotaReservationManager(std::move(backend)));
}
void TearDown() override { reservation_manager_.reset(); }
@@ -222,7 +224,7 @@ TEST_F(QuotaReservationManagerTest, BasicTest) {
{
RefreshReservation(reservation.get(), 10 + 20 + 3);
- int64 cached_reserved_quota = reservation->remaining_quota();
+ int64_t cached_reserved_quota = reservation->remaining_quota();
FakeWriter writer(reservation->GetOpenFileHandle(file_path()));
cached_reserved_quota -= writer.Write(kInitialFileSize + 10);
@@ -263,7 +265,7 @@ TEST_F(QuotaReservationManagerTest, MultipleWriter) {
{
RefreshReservation(reservation.get(), 10 + 20 + 30 + 40 + 5);
- int64 cached_reserved_quota = reservation->remaining_quota();
+ int64_t cached_reserved_quota = reservation->remaining_quota();
FakeWriter writer1(reservation->GetOpenFileHandle(file_path()));
FakeWriter writer2(reservation->GetOpenFileHandle(file_path()));
FakeWriter writer3(reservation->GetOpenFileHandle(file_path()));
@@ -295,12 +297,12 @@ TEST_F(QuotaReservationManagerTest, MultipleClient) {
scoped_refptr<QuotaReservation> reservation1 =
reservation_manager()->CreateReservation(GURL(kOrigin), kType);
RefreshReservation(reservation1.get(), 10);
- int64 cached_reserved_quota1 = reservation1->remaining_quota();
+ int64_t cached_reserved_quota1 = reservation1->remaining_quota();
scoped_refptr<QuotaReservation> reservation2 =
reservation_manager()->CreateReservation(GURL(kOrigin), kType);
RefreshReservation(reservation2.get(), 20);
- int64 cached_reserved_quota2 = reservation2->remaining_quota();
+ int64_t cached_reserved_quota2 = reservation2->remaining_quota();
scoped_ptr<FakeWriter> writer1(
new FakeWriter(reservation1->GetOpenFileHandle(file_path())));
diff --git a/chromium/content/browser/quota/quota_temporary_storage_evictor_unittest.cc b/chromium/content/browser/quota/quota_temporary_storage_evictor_unittest.cc
index 2d63362ceff..21478c3c635 100644
--- a/chromium/content/browser/quota/quota_temporary_storage_evictor_unittest.cc
+++ b/chromium/content/browser/quota/quota_temporary_storage_evictor_unittest.cc
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <list>
#include <map>
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
@@ -41,7 +44,7 @@ class MockQuotaEvictionHandler : public storage::QuotaEvictionHandler {
callback.Run(storage::kQuotaErrorInvalidModification);
return;
}
- int64 origin_usage = EnsureOriginRemoved(origin);
+ int64_t origin_usage = EnsureOriginRemoved(origin);
if (origin_usage >= 0)
available_space_ += origin_usage;
callback.Run(storage::kQuotaStatusOk);
@@ -60,6 +63,8 @@ class MockQuotaEvictionHandler : public storage::QuotaEvictionHandler {
}
void GetEvictionOrigin(StorageType type,
+ const std::set<GURL>& exceptions,
+ int64_t global_quota,
const storage::GetOriginCallback& callback) override {
if (origin_order_.empty())
callback.Run(GURL());
@@ -67,19 +72,16 @@ class MockQuotaEvictionHandler : public storage::QuotaEvictionHandler {
callback.Run(GURL(origin_order_.front()));
}
- int64 GetUsage() const {
- int64 total_usage = 0;
- for (std::map<GURL, int64>::const_iterator p = origins_.begin();
- p != origins_.end();
- ++p)
+ int64_t GetUsage() const {
+ int64_t total_usage = 0;
+ for (std::map<GURL, int64_t>::const_iterator p = origins_.begin();
+ p != origins_.end(); ++p)
total_usage += p->second;
return total_usage;
}
- void set_quota(int64 quota) {
- quota_ = quota;
- }
- void set_available_space(int64 available_space) {
+ void set_quota(int64_t quota) { quota_ = quota; }
+ void set_available_space(int64_t available_space) {
available_space_ = available_space;
}
void set_task_for_get_usage_and_quota(const base::Closure& task) {
@@ -95,7 +97,7 @@ class MockQuotaEvictionHandler : public storage::QuotaEvictionHandler {
// Simulates an access to |origin|. It reorders the internal LRU list.
// It internally uses AddOrigin().
void AccessOrigin(const GURL& origin) {
- std::map<GURL, int64>::iterator found = origins_.find(origin);
+ std::map<GURL, int64_t>::iterator found = origins_.find(origin);
EXPECT_TRUE(origins_.end() != found);
AddOrigin(origin, found->second);
}
@@ -103,15 +105,15 @@ class MockQuotaEvictionHandler : public storage::QuotaEvictionHandler {
// Simulates adding or overwriting the |origin| to the internal origin set
// with the |usage|. It also adds or moves the |origin| to the end of the
// LRU list.
- void AddOrigin(const GURL& origin, int64 usage) {
+ void AddOrigin(const GURL& origin, int64_t usage) {
EnsureOriginRemoved(origin);
origin_order_.push_back(origin);
origins_[origin] = usage;
}
private:
- int64 EnsureOriginRemoved(const GURL& origin) {
- int64 origin_usage;
+ int64_t EnsureOriginRemoved(const GURL& origin) {
+ int64_t origin_usage;
if (origins_.find(origin) == origins_.end())
return -1;
else
@@ -122,10 +124,10 @@ class MockQuotaEvictionHandler : public storage::QuotaEvictionHandler {
return origin_usage;
}
- int64 quota_;
- int64 available_space_;
+ int64_t quota_;
+ int64_t available_space_;
std::list<GURL> origin_order_;
- std::map<GURL, int64> origins_;
+ std::map<GURL, int64_t> origins_;
bool error_on_evict_origin_data_;
bool error_on_get_usage_and_quota_;
@@ -155,7 +157,7 @@ class QuotaTemporaryStorageEvictorTest : public testing::Test {
}
void TaskForRepeatedEvictionTest(
- const std::pair<GURL, int64>& origin_to_be_added,
+ const std::pair<GURL, int64_t>& origin_to_be_added,
const GURL& origin_to_be_accessed,
int expected_usage_after_first,
int expected_usage_after_second) {
@@ -201,11 +203,11 @@ class QuotaTemporaryStorageEvictorTest : public testing::Test {
return num_get_usage_and_quota_for_eviction_;
}
- int64 default_min_available_disk_space_to_start_eviction() const {
+ int64_t default_min_available_disk_space_to_start_eviction() const {
return 1000 * 1000 * 500;
}
- void set_min_available_disk_space_to_start_eviction(int64 value) const {
+ void set_min_available_disk_space_to_start_eviction(int64_t value) const {
temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction(
value);
}
@@ -266,12 +268,12 @@ TEST_F(QuotaTemporaryStorageEvictorTest, MultipleEvictionTest) {
}
TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionTest) {
- const int64 a_size = 400;
- const int64 b_size = 150;
- const int64 c_size = 120;
- const int64 d_size = 292;
- const int64 initial_total_size = a_size + b_size + c_size + d_size;
- const int64 e_size = 275;
+ const int64_t a_size = 400;
+ const int64_t b_size = 150;
+ const int64_t c_size = 120;
+ const int64_t d_size = 292;
+ const int64_t initial_total_size = a_size + b_size + c_size + d_size;
+ const int64_t e_size = 275;
quota_eviction_handler()->AddOrigin(GURL("http://www.d.com"), d_size);
quota_eviction_handler()->AddOrigin(GURL("http://www.c.com"), c_size);
@@ -300,11 +302,11 @@ TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionTest) {
}
TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionSkippedTest) {
- const int64 a_size = 400;
- const int64 b_size = 150;
- const int64 c_size = 120;
- const int64 d_size = 292;
- const int64 initial_total_size = a_size + b_size + c_size + d_size;
+ const int64_t a_size = 400;
+ const int64_t b_size = 150;
+ const int64_t c_size = 120;
+ const int64_t d_size = 292;
+ const int64_t initial_total_size = a_size + b_size + c_size + d_size;
quota_eviction_handler()->AddOrigin(GURL("http://www.d.com"), d_size);
quota_eviction_handler()->AddOrigin(GURL("http://www.c.com"), c_size);
@@ -331,12 +333,12 @@ TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionSkippedTest) {
}
TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionWithAccessOriginTest) {
- const int64 a_size = 400;
- const int64 b_size = 150;
- const int64 c_size = 120;
- const int64 d_size = 292;
- const int64 initial_total_size = a_size + b_size + c_size + d_size;
- const int64 e_size = 275;
+ const int64_t a_size = 400;
+ const int64_t b_size = 150;
+ const int64_t c_size = 120;
+ const int64_t d_size = 292;
+ const int64_t initial_total_size = a_size + b_size + c_size + d_size;
+ const int64_t e_size = 275;
quota_eviction_handler()->AddOrigin(GURL("http://www.d.com"), d_size);
quota_eviction_handler()->AddOrigin(GURL("http://www.c.com"), c_size);
diff --git a/chromium/content/browser/quota/storage_monitor_unittest.cc b/chromium/content/browser/quota/storage_monitor_unittest.cc
index 0edd49eb60d..002e860b9df 100644
--- a/chromium/content/browser/quota/storage_monitor_unittest.cc
+++ b/chromium/content/browser/quota/storage_monitor_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <vector>
#include "base/files/scoped_temp_dir.h"
@@ -72,7 +74,7 @@ class UsageMockQuotaManager : public QuotaManager {
callback_status_(kQuotaStatusOk),
initialized_(false) {}
- void SetCallbackParams(int64 usage, int64 quota, QuotaStatusCode status) {
+ void SetCallbackParams(int64_t usage, int64_t quota, QuotaStatusCode status) {
initialized_ = true;
callback_quota_ = quota;
callback_usage_ = usage;
@@ -97,8 +99,8 @@ class UsageMockQuotaManager : public QuotaManager {
~UsageMockQuotaManager() override {}
private:
- int64 callback_usage_;
- int64 callback_quota_;
+ int64_t callback_usage_;
+ int64_t callback_quota_;
QuotaStatusCode callback_status_;
bool initialized_;
GetUsageAndQuotaCallback delayed_callback_;
@@ -321,8 +323,8 @@ TEST_F(HostStorageObserversTest, InitializeOnUsageChange) {
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
- const int64 kUsage = 324554;
- const int64 kQuota = 234354354;
+ const int64_t kUsage = 324554;
+ const int64_t kQuota = 234354354;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
MockObserver mock_observer;
@@ -338,7 +340,7 @@ TEST_F(HostStorageObserversTest, InitializeOnUsageChange) {
// Verify that HostStorageObservers handles subsequent usage changes
// correctly.
- const int64 kDelta = 2345;
+ const int64_t kDelta = 2345;
expected_event.usage += kDelta;
SetLastNotificationTime(host_observers, &mock_observer);
host_observers.NotifyUsageChange(params.filter, kDelta);
@@ -349,8 +351,8 @@ TEST_F(HostStorageObserversTest, InitializeOnUsageChange) {
// Verify that HostStorageObservers is initialized after the adding the first
// observer that elected to receive the initial state.
TEST_F(HostStorageObserversTest, InitializeOnObserver) {
- const int64 kUsage = 74387;
- const int64 kQuota = 92834743;
+ const int64_t kUsage = 74387;
+ const int64_t kQuota = 92834743;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
HostStorageObservers host_observers(quota_manager_.get());
@@ -379,7 +381,7 @@ TEST_F(HostStorageObserversTest, InitializeOnObserver) {
EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
// Verify that both observers will receive events after a usage change.
- const int64 kDelta = 2345;
+ const int64_t kDelta = 2345;
expected_event.usage += kDelta;
SetLastNotificationTime(host_observers, &mock_observer2);
host_observers.NotifyUsageChange(params.filter, kDelta);
@@ -407,8 +409,8 @@ TEST_F(HostStorageObserversTest, NegativeUsageAndQuota) {
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
- const int64 kUsage = -324554;
- const int64 kQuota = -234354354;
+ const int64_t kUsage = -324554;
+ const int64_t kQuota = -234354354;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
MockObserver mock_observer;
@@ -431,8 +433,8 @@ TEST_F(HostStorageObserversTest, RecoverFromBadUsageInit) {
host_observers.AddObserver(&mock_observer, params);
// Set up the quota manager to return an error status.
- const int64 kUsage = 6656;
- const int64 kQuota = 99585556;
+ const int64_t kUsage = 6656;
+ const int64_t kQuota = 99585556;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaErrorNotSupported);
// Verify that |host_observers| is not initialized and an event has not been
@@ -473,9 +475,9 @@ TEST_F(HostStorageObserversTest, AsyncInitialization) {
// Simulate notifying |host_observers| of a usage change before initialization
// is complete.
- const int64 kUsage = 6656;
- const int64 kQuota = 99585556;
- const int64 kDelta = 327643;
+ const int64_t kUsage = 6656;
+ const int64_t kQuota = 99585556;
+ const int64_t kDelta = 327643;
host_observers.NotifyUsageChange(params.filter, kDelta);
EXPECT_EQ(0, mock_observer.EventCount());
EXPECT_FALSE(host_observers.is_initialized());
@@ -613,8 +615,8 @@ TEST_F(StorageMonitorTest, AddObservers) {
// Test dispatching events to storage observers.
TEST_F(StorageMonitorTest, EventDispatch) {
// Verify dispatch of events.
- const int64 kUsage = 5325;
- const int64 kQuota = 903845;
+ const int64_t kUsage = 5325;
+ const int64_t kQuota = 903845;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
storage_monitor_->NotifyUsageChange(params1_.filter, 9048543);
@@ -675,7 +677,7 @@ class StorageMonitorIntegrationTest : public testing::Test {
// storage observer will receive a storage event.
TEST_F(StorageMonitorIntegrationTest, NotifyUsageEvent) {
const StorageType kTestStorageType = kStorageTypePersistent;
- const int64 kTestUsage = 234743;
+ const int64_t kTestUsage = 234743;
// Register the observer.
StorageObserver::MonitorParams params(kTestStorageType,
diff --git a/chromium/content/browser/quota/usage_tracker_unittest.cc b/chromium/content/browser/quota/usage_tracker_unittest.cc
index 3cfdf2cb103..78d19b2de3d 100644
--- a/chromium/content/browser/quota/usage_tracker_unittest.cc
+++ b/chromium/content/browser/quota/usage_tracker_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -25,19 +28,17 @@ namespace content {
namespace {
void DidGetGlobalUsage(bool* done,
- int64* usage_out,
- int64* unlimited_usage_out,
- int64 usage,
- int64 unlimited_usage) {
+ int64_t* usage_out,
+ int64_t* unlimited_usage_out,
+ int64_t usage,
+ int64_t unlimited_usage) {
EXPECT_FALSE(*done);
*done = true;
*usage_out = usage;
*unlimited_usage_out = unlimited_usage;
}
-void DidGetUsage(bool* done,
- int64* usage_out,
- int64 usage) {
+void DidGetUsage(bool* done, int64_t* usage_out, int64_t usage) {
EXPECT_FALSE(*done);
*done = true;
*usage_out = usage;
@@ -58,7 +59,7 @@ class MockQuotaClient : public QuotaClient {
StorageType type,
const GetUsageCallback& callback) override {
EXPECT_EQ(kStorageTypeTemporary, type);
- int64 usage = GetUsage(origin);
+ int64_t usage = GetUsage(origin);
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
base::Bind(callback, usage));
}
@@ -102,23 +103,23 @@ class MockQuotaClient : public QuotaClient {
return type == storage::kStorageTypeTemporary;
}
- int64 GetUsage(const GURL& origin) {
+ int64_t GetUsage(const GURL& origin) {
UsageMap::const_iterator found = usage_map_.find(origin);
if (found == usage_map_.end())
return 0;
return found->second;
}
- void SetUsage(const GURL& origin, int64 usage) {
+ void SetUsage(const GURL& origin, int64_t usage) {
usage_map_[origin] = usage;
}
- int64 UpdateUsage(const GURL& origin, int64 delta) {
+ int64_t UpdateUsage(const GURL& origin, int64_t delta) {
return usage_map_[origin] += delta;
}
private:
- typedef std::map<GURL, int64> UsageMap;
+ typedef std::map<GURL, int64_t> UsageMap;
UsageMap usage_map_;
@@ -139,17 +140,17 @@ class UsageTrackerTest : public testing::Test {
return &usage_tracker_;
}
- void UpdateUsage(const GURL& origin, int64 delta) {
+ void UpdateUsage(const GURL& origin, int64_t delta) {
quota_client_.UpdateUsage(origin, delta);
usage_tracker_.UpdateUsageCache(quota_client_.id(), origin, delta);
base::RunLoop().RunUntilIdle();
}
- void UpdateUsageWithoutNotification(const GURL& origin, int64 delta) {
+ void UpdateUsageWithoutNotification(const GURL& origin, int64_t delta) {
quota_client_.UpdateUsage(origin, delta);
}
- void GetGlobalLimitedUsage(int64* limited_usage) {
+ void GetGlobalLimitedUsage(int64_t* limited_usage) {
bool done = false;
usage_tracker_.GetGlobalLimitedUsage(base::Bind(
&DidGetUsage, &done, limited_usage));
@@ -158,7 +159,7 @@ class UsageTrackerTest : public testing::Test {
EXPECT_TRUE(done);
}
- void GetGlobalUsage(int64* usage, int64* unlimited_usage) {
+ void GetGlobalUsage(int64_t* usage, int64_t* unlimited_usage) {
bool done = false;
usage_tracker_.GetGlobalUsage(base::Bind(
&DidGetGlobalUsage,
@@ -168,7 +169,7 @@ class UsageTrackerTest : public testing::Test {
EXPECT_TRUE(done);
}
- void GetHostUsage(const std::string& host, int64* usage) {
+ void GetHostUsage(const std::string& host, int64_t* usage) {
bool done = false;
usage_tracker_.GetHostUsage(host, base::Bind(&DidGetUsage, &done, usage));
base::RunLoop().RunUntilIdle();
@@ -214,9 +215,9 @@ class UsageTrackerTest : public testing::Test {
};
TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
- int64 usage = 0;
- int64 unlimited_usage = 0;
- int64 host_usage = 0;
+ int64_t usage = 0;
+ int64_t unlimited_usage = 0;
+ int64_t host_usage = 0;
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(0, usage);
EXPECT_EQ(0, unlimited_usage);
@@ -247,9 +248,9 @@ TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
}
TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
- int64 usage = 0;
- int64 unlimited_usage = 0;
- int64 host_usage = 0;
+ int64_t usage = 0;
+ int64_t unlimited_usage = 0;
+ int64_t host_usage = 0;
const GURL origin("http://example.com");
const std::string host(net::GetHostOrSpecFromURL(origin));
@@ -313,9 +314,9 @@ TEST_F(UsageTrackerTest, LimitedGlobalUsageTest) {
UpdateUsageWithoutNotification(kNonCached, 4);
UpdateUsageWithoutNotification(kNonCachedUnlimited, 8);
- int64 limited_usage = 0;
- int64 total_usage = 0;
- int64 unlimited_usage = 0;
+ int64_t limited_usage = 0;
+ int64_t total_usage = 0;
+ int64_t unlimited_usage = 0;
GetGlobalLimitedUsage(&limited_usage);
GetGlobalUsage(&total_usage, &unlimited_usage);
diff --git a/chromium/content/browser/quota_dispatcher_host.cc b/chromium/content/browser/quota_dispatcher_host.cc
index 3cbfee2c24d..8f2043bb4e4 100644
--- a/chromium/content/browser/quota_dispatcher_host.cc
+++ b/chromium/content/browser/quota_dispatcher_host.cc
@@ -4,9 +4,12 @@
#include "content/browser/quota_dispatcher_host.h"
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_conversions.h"
+#include "base/trace_event/trace_event.h"
#include "content/common/quota_messages.h"
#include "content/public/browser/quota_permission_context.h"
#include "net/base/net_util.h"
@@ -71,6 +74,11 @@ class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher
~QueryUsageAndQuotaDispatcher() override {}
void QueryStorageUsageAndQuota(const GURL& origin, StorageType type) {
+ // crbug.com/349708
+ TRACE_EVENT0("io",
+ "QuotaDispatcherHost::QueryUsageAndQuotaDispatcher"
+ "::QueryStorageUsageAndQuota");
+
quota_manager()->GetUsageAndQuotaForWebApps(
origin, type,
base::Bind(&QueryUsageAndQuotaDispatcher::DidQueryStorageUsageAndQuota,
@@ -78,10 +86,15 @@ class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher
}
private:
- void DidQueryStorageUsageAndQuota(
- QuotaStatusCode status, int64 usage, int64 quota) {
+ void DidQueryStorageUsageAndQuota(QuotaStatusCode status,
+ int64_t usage,
+ int64_t quota) {
if (!dispatcher_host())
return;
+ // crbug.com/349708
+ TRACE_EVENT0("io", "QuotaDispatcherHost::RequestQuotaDispatcher"
+ "::DidQueryStorageUsageAndQuota");
+
if (status != storage::kQuotaStatusOk) {
dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status));
} else {
@@ -107,15 +120,18 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
current_quota_(0),
requested_quota_(0),
weak_factory_(this) {
- // Convert the requested size from uint64 to int64 since the quota backend
- // requires int64 values.
- // TODO(nhiroki): The backend should accept uint64 values.
- requested_quota_ = base::saturated_cast<int64>(params_.requested_size);
+ // Convert the requested size from uint64_t to int64_t since the quota
+ // backend
+ // requires int64_t values.
+ // TODO(nhiroki): The backend should accept uint64_t values.
+ requested_quota_ = base::saturated_cast<int64_t>(params_.requested_size);
}
~RequestQuotaDispatcher() override {}
void Start() {
DCHECK(dispatcher_host());
+ // crbug.com/349708
+ TRACE_EVENT0("io", "QuotaDispatcherHost::RequestQuotaDispatcher::Start");
DCHECK(params_.storage_type == storage::kStorageTypeTemporary ||
params_.storage_type == storage::kStorageTypePersistent);
@@ -134,8 +150,8 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
private:
void DidGetPersistentUsageAndQuota(QuotaStatusCode status,
- int64 usage,
- int64 quota) {
+ int64_t usage,
+ int64_t quota) {
if (!dispatcher_host())
return;
if (status != storage::kQuotaStatusOk) {
@@ -162,8 +178,8 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
}
void DidGetTemporaryUsageAndQuota(QuotaStatusCode status,
- int64 usage,
- int64 quota) {
+ int64_t usage,
+ int64_t quota) {
DidFinish(status, usage, std::min(requested_quota_, quota));
}
@@ -182,13 +198,11 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
base::Bind(&self_type::DidSetHostQuota, weak_factory_.GetWeakPtr()));
}
- void DidSetHostQuota(QuotaStatusCode status, int64 new_quota) {
+ void DidSetHostQuota(QuotaStatusCode status, int64_t new_quota) {
DidFinish(status, current_usage_, new_quota);
}
- void DidFinish(QuotaStatusCode status,
- int64 usage,
- int64 granted_quota) {
+ void DidFinish(QuotaStatusCode status, int64_t usage, int64_t granted_quota) {
if (!dispatcher_host())
return;
DCHECK(dispatcher_host());
@@ -202,9 +216,9 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
}
StorageQuotaParams params_;
- int64 current_usage_;
- int64 current_quota_;
- int64 requested_quota_;
+ int64_t current_usage_;
+ int64_t current_quota_;
+ int64_t requested_quota_;
base::WeakPtrFactory<self_type> weak_factory_;
};
diff --git a/chromium/content/browser/quota_dispatcher_host.h b/chromium/content/browser/quota_dispatcher_host.h
index 8a30f229f81..5b8cf87bb65 100644
--- a/chromium/content/browser/quota_dispatcher_host.h
+++ b/chromium/content/browser/quota_dispatcher_host.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_QUOTA_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_QUOTA_DISPATCHER_HOST_H_
-#include "base/basictypes.h"
#include "base/id_map.h"
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
#include "storage/common/quota/quota_types.h"
diff --git a/chromium/content/browser/renderer_host/DEPS b/chromium/content/browser/renderer_host/DEPS
index 85fd36e6559..e20b55810dc 100644
--- a/chromium/content/browser/renderer_host/DEPS
+++ b/chromium/content/browser/renderer_host/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+cc/switches.h", # For cc command line switches.
+ "+components/mus/public",
"+media/base", # For media command line switches.
"+media/audio/audio_util.h", # For audio hardware sample-rate.
"+third_party/zlib",
@@ -20,7 +21,7 @@ specific_include_rules = {
"+content/browser/web_contents",
"+content/public/browser/web_contents.h",
"+content/public/browser/web_contents_view.h",
- "+media/blink",
+ "+media/renderers",
],
"sandbox_ipc_linux\.cc": [
"+third_party/WebKit/public/platform/linux/WebFontInfo.h",
diff --git a/chromium/content/browser/renderer_host/OWNERS b/chromium/content/browser/renderer_host/OWNERS
index 8cac44c5df7..b3ee6fca8b9 100644
--- a/chromium/content/browser/renderer_host/OWNERS
+++ b/chromium/content/browser/renderer_host/OWNERS
@@ -18,7 +18,7 @@ aelias@chromium.org
# For touch/gesture specific changes
rjkroege@chromium.org
sadrul@chromium.org
-jdduke@chromium.org
+tdresser@chromium.org
# WebSocket
per-file *websocket*=ricea@chromium.org
diff --git a/chromium/content/browser/renderer_host/begin_frame_observer_proxy.h b/chromium/content/browser/renderer_host/begin_frame_observer_proxy.h
index 291d8bb8a96..a5fa2e6cba5 100644
--- a/chromium/content/browser/renderer_host/begin_frame_observer_proxy.h
+++ b/chromium/content/browser/renderer_host/begin_frame_observer_proxy.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_BEGIN_FRAME_OBSERVER_PROXY_H_
#define CONTENT_BROWSER_RENDERER_HOST_BEGIN_FRAME_OBSERVER_PROXY_H_
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_observer.h"
diff --git a/chromium/content/browser/renderer_host/begin_frame_observer_proxy_unittest.cc b/chromium/content/browser/renderer_host/begin_frame_observer_proxy_unittest.cc
index fe2b5289c00..9ba78c4af48 100644
--- a/chromium/content/browser/renderer_host/begin_frame_observer_proxy_unittest.cc
+++ b/chromium/content/browser/renderer_host/begin_frame_observer_proxy_unittest.cc
@@ -5,7 +5,6 @@
#include <algorithm>
#include <list>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/test/test_simple_task_runner.h"
@@ -40,8 +39,7 @@ class BeginFrameObserverProxyTest : public testing::Test {
compositor_task_runner_ = new base::TestSimpleTaskRunner();
compositor_.reset(
new ui::Compositor(context_factory, compositor_task_runner_));
- compositor_->SetAcceleratedWidgetAndStartCompositor(
- gfx::kNullAcceleratedWidget);
+ compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
}
void TearDown() override {
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter.cc b/chromium/content/browser/renderer_host/clipboard_message_filter.cc
index e270b7c97a4..dea3d127604 100644
--- a/chromium/content/browser/renderer_host/clipboard_message_filter.cc
+++ b/chromium/content/browser/renderer_host/clipboard_message_filter.cc
@@ -10,8 +10,8 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
-#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/common/clipboard_messages.h"
#include "content/public/browser/browser_context.h"
#include "ipc/ipc_message_macros.h"
@@ -95,7 +95,7 @@ ClipboardMessageFilter::~ClipboardMessageFilter() {
}
void ClipboardMessageFilter::OnGetSequenceNumber(ui::ClipboardType type,
- uint64* sequence_number) {
+ uint64_t* sequence_number) {
*sequence_number = GetClipboard()->GetSequenceNumber(type);
}
@@ -157,8 +157,8 @@ void ClipboardMessageFilter::OnReadText(ui::ClipboardType type,
void ClipboardMessageFilter::OnReadHTML(ui::ClipboardType type,
base::string16* markup,
GURL* url,
- uint32* fragment_start,
- uint32* fragment_end) {
+ uint32_t* fragment_start,
+ uint32_t* fragment_end) {
std::string src_url_str;
GetClipboard()->ReadHTML(type, markup, &src_url_str, fragment_start,
fragment_end);
@@ -187,13 +187,13 @@ void ClipboardMessageFilter::OnReadImage(ui::ClipboardType type,
void ClipboardMessageFilter::OnReadImageReply(
const SkBitmap& bitmap, IPC::Message* reply_msg) {
base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle();
- uint32 image_size = 0;
+ uint32_t image_size = 0;
if (!bitmap.isNull()) {
std::vector<unsigned char> png_data;
if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) {
base::SharedMemory buffer;
if (buffer.CreateAndMapAnonymous(png_data.size())) {
- memcpy(buffer.memory(), vector_as_array(&png_data), png_data.size());
+ memcpy(buffer.memory(), png_data.data(), png_data.size());
if (buffer.GiveToProcess(PeerHandle(), &image_handle)) {
image_size = png_data.size();
}
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter.h b/chromium/content/browser/renderer_host/clipboard_message_filter.h
index f563ed51432..9e9aabe659f 100644
--- a/chromium/content/browser/renderer_host/clipboard_message_filter.h
+++ b/chromium/content/browser/renderer_host/clipboard_message_filter.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/shared_memory.h"
+#include "build/build_config.h"
#include "content/common/clipboard_format.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
@@ -39,7 +42,7 @@ class CONTENT_EXPORT ClipboardMessageFilter : public BrowserMessageFilter {
~ClipboardMessageFilter() override;
void OnGetSequenceNumber(const ui::ClipboardType type,
- uint64* sequence_number);
+ uint64_t* sequence_number);
void OnIsFormatAvailable(ClipboardFormat format,
ui::ClipboardType type,
bool* result);
@@ -51,8 +54,8 @@ class CONTENT_EXPORT ClipboardMessageFilter : public BrowserMessageFilter {
void OnReadHTML(ui::ClipboardType type,
base::string16* markup,
GURL* url,
- uint32* fragment_start,
- uint32* fragment_end);
+ uint32_t* fragment_start,
+ uint32_t* fragment_end);
void OnReadRTF(ui::ClipboardType type, std::string* result);
void OnReadImage(ui::ClipboardType type, IPC::Message* reply_msg);
void OnReadImageReply(const SkBitmap& bitmap, IPC::Message* reply_msg);
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm b/chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm
index 3c59d31f40f..18a908a2e73 100644
--- a/chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm
+++ b/chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm
@@ -5,11 +5,12 @@
#include "content/browser/renderer_host/clipboard_message_filter.h"
#import <Cocoa/Cocoa.h>
+#include <stddef.h>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
#include "base/strings/sys_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#import "ui/base/cocoa/find_pasteboard.h"
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc b/chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc
index ecaaf69d283..2f0c8abed3e 100644
--- a/chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc
+++ b/chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/clipboard_message_filter.h"
+#include <stddef.h>
+#include <stdint.h>
#include <string.h>
#include "base/memory/ref_counted.h"
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.cc b/chromium/content/browser/renderer_host/compositor_impl_android.cc
index c9f123ffb3f..74f1e70e44e 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.cc
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.cc
@@ -6,6 +6,8 @@
#include <android/bitmap.h>
#include <android/native_window_jni.h>
+#include <stdint.h>
+#include <utility>
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
@@ -30,7 +32,7 @@
#include "cc/output/context_provider.h"
#include "cc/output/output_surface.h"
#include "cc/output/output_surface_client.h"
-#include "cc/raster/task_graph_runner.h"
+#include "cc/raster/single_thread_task_graph_runner.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/surfaces/onscreen_display_client.h"
#include "cc/surfaces/surface_display_output_surface.h"
@@ -39,6 +41,7 @@
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_settings.h"
#include "content/browser/android/child_process_launcher_android.h"
+#include "content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/compositor_util.h"
@@ -68,7 +71,6 @@ namespace content {
namespace {
-const unsigned int kMaxUiSwapBuffers = 1U;
const unsigned int kMaxDisplaySwapBuffers = 1U;
// Used to override capabilities_.adjust_deadline_for_parent to false
@@ -85,7 +87,9 @@ class OutputSurfaceWithoutParent : public cc::OutputSurface,
populate_gpu_capabilities_callback_(populate_gpu_capabilities_callback),
swap_buffers_completion_callback_(
base::Bind(&OutputSurfaceWithoutParent::OnSwapBuffersCompleted,
- base::Unretained(this))) {
+ base::Unretained(this))),
+ overlay_candidate_validator_(
+ new BrowserCompositorOverlayCandidateValidatorAndroid()) {
capabilities_.adjust_deadline_for_parent = false;
capabilities_.max_frames_pending = kMaxDisplaySwapBuffers;
}
@@ -94,9 +98,13 @@ class OutputSurfaceWithoutParent : public cc::OutputSurface,
void SwapBuffers(cc::CompositorFrame* frame) override {
GetCommandBufferProxy()->SetLatencyInfo(frame->metadata.latency_info);
- DCHECK(frame->gl_frame_data->sub_buffer_rect ==
- gfx::Rect(frame->gl_frame_data->size));
- context_provider_->ContextSupport()->Swap();
+ if (frame->gl_frame_data->sub_buffer_rect.IsEmpty()) {
+ context_provider_->ContextSupport()->CommitOverlayPlanes();
+ } else {
+ DCHECK(frame->gl_frame_data->sub_buffer_rect ==
+ gfx::Rect(frame->gl_frame_data->size));
+ context_provider_->ContextSupport()->Swap();
+ }
client_->DidSwapBuffers();
}
@@ -114,6 +122,10 @@ class OutputSurfaceWithoutParent : public cc::OutputSurface,
return true;
}
+ cc::OverlayCandidateValidator* GetOverlayCandidateValidator() const override {
+ return overlay_candidate_validator_.get();
+ }
+
private:
CommandBufferProxyImpl* GetCommandBufferProxy() {
ContextProviderCommandBuffer* provider_command_buffer =
@@ -131,8 +143,7 @@ class OutputSurfaceWithoutParent : public cc::OutputSurface,
OutputSurface::OnSwapBuffersComplete();
}
- void OnUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) override {
+ void OnVSync(base::TimeTicks timebase, base::TimeDelta interval) override {
CommitVSyncParameters(timebase, interval);
}
@@ -141,6 +152,37 @@ class OutputSurfaceWithoutParent : public cc::OutputSurface,
base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&,
gfx::SwapResult)>
swap_buffers_completion_callback_;
+ scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator_;
+};
+
+class ExternalBeginFrameSource : public cc::BeginFrameSourceBase,
+ public CompositorImpl::VSyncObserver {
+ public:
+ ExternalBeginFrameSource(CompositorImpl* compositor)
+ : compositor_(compositor) {
+ compositor_->AddObserver(this);
+ }
+
+ ~ExternalBeginFrameSource() override {
+ compositor_->RemoveObserver(this);
+ }
+
+ // cc::BeginFrameSourceBase implementation:
+ void OnNeedsBeginFramesChange(
+ bool needs_begin_frames) override {
+ compositor_->OnNeedsBeginFramesChange(needs_begin_frames);
+ }
+
+ // CompositorImpl::VSyncObserver implementation:
+ void OnVSync(base::TimeTicks frame_time,
+ base::TimeDelta vsync_period) override {
+ CallOnBeginFrame(cc::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, frame_time, base::TimeTicks::Now(), vsync_period,
+ cc::BeginFrameArgs::NORMAL));
+ }
+
+ private:
+ CompositorImpl* compositor_;
};
static bool g_initialized = false;
@@ -149,40 +191,24 @@ bool g_use_surface_manager = false;
base::LazyInstance<cc::SurfaceManager> g_surface_manager =
LAZY_INSTANCE_INITIALIZER;
-
int g_surface_id_namespace = 0;
-class SingleThreadTaskGraphRunner
- : public cc::TaskGraphRunner,
- public base::DelegateSimpleThread::Delegate {
+class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner {
public:
- SingleThreadTaskGraphRunner()
- : worker_thread_(
- this,
- "CompositorTileWorker1",
- base::SimpleThread::Options(base::ThreadPriority::BACKGROUND)) {
- worker_thread_.Start();
+ SingleThreadTaskGraphRunner() {
+ Start("CompositorTileWorker1",
+ base::SimpleThread::Options(base::ThreadPriority::BACKGROUND));
}
~SingleThreadTaskGraphRunner() override {
Shutdown();
- worker_thread_.Join();
}
-
- private:
- // Overridden from base::DelegateSimpleThread::Delegate:
- void Run() override { cc::TaskGraphRunner::Run(); }
-
- base::DelegateSimpleThread worker_thread_;
};
base::LazyInstance<SingleThreadTaskGraphRunner> g_task_graph_runner =
LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<cc::LayerSettings> g_layer_settings =
- LAZY_INSTANCE_INITIALIZER;
-
-} // anonymous namespace
+} // anonymous namespace
// static
Compositor* Compositor::Create(CompositorClient* client,
@@ -199,12 +225,12 @@ void Compositor::Initialize() {
// static
const cc::LayerSettings& Compositor::LayerSettings() {
- return g_layer_settings.Get();
+ return ui::WindowAndroidCompositor::LayerSettings();
}
// static
void Compositor::SetLayerSettings(const cc::LayerSettings& settings) {
- g_layer_settings.Get() = settings;
+ ui::WindowAndroidCompositor::SetLayerSettings(settings);
}
// static
@@ -226,12 +252,13 @@ scoped_ptr<cc::SurfaceIdAllocator> CompositorImpl::CreateSurfaceIdAllocator() {
cc::SurfaceManager* manager = GetSurfaceManager();
DCHECK(manager);
allocator->RegisterSurfaceIdNamespace(manager);
- return allocator.Pass();
+ return allocator;
}
CompositorImpl::CompositorImpl(CompositorClient* client,
gfx::NativeWindow root_window)
: root_layer_(cc::Layer::Create(Compositor::LayerSettings())),
+ resource_manager_(root_window),
surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator()
: nullptr),
has_transparent_background_(false),
@@ -240,15 +267,11 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
surface_id_(0),
client_(client),
root_window_(root_window),
- did_post_swapbuffers_(false),
- ignore_schedule_composite_(false),
- needs_composite_(false),
needs_animate_(false),
- will_composite_immediately_(false),
- composite_on_vsync_trigger_(DO_NOT_COMPOSITE),
pending_swapbuffers_(0U),
num_successive_context_creation_failures_(0),
output_surface_request_pending_(false),
+ needs_begin_frames_(false),
weak_factory_(this) {
DCHECK(client);
DCHECK(root_window);
@@ -263,111 +286,6 @@ CompositorImpl::~CompositorImpl() {
SetSurface(NULL);
}
-void CompositorImpl::PostComposite(CompositingTrigger trigger) {
- DCHECK(host_->visible());
- DCHECK(needs_composite_);
- DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY);
-
- if (will_composite_immediately_ ||
- (trigger == COMPOSITE_EVENTUALLY && WillComposite())) {
- // We will already composite soon enough.
- DCHECK(WillComposite());
- return;
- }
-
- if (DidCompositeThisFrame()) {
- DCHECK(!WillCompositeThisFrame());
- if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) {
- composite_on_vsync_trigger_ = trigger;
- root_window_->RequestVSyncUpdate();
- }
- DCHECK(WillComposite());
- return;
- }
-
- base::TimeDelta delay;
- if (trigger == COMPOSITE_IMMEDIATELY) {
- will_composite_immediately_ = true;
- composite_on_vsync_trigger_ = DO_NOT_COMPOSITE;
- } else {
- DCHECK(!WillComposite());
- const base::TimeDelta estimated_composite_time = vsync_period_ / 4;
- const base::TimeTicks now = base::TimeTicks::Now();
-
- if (!last_vsync_.is_null() && (now - last_vsync_) < vsync_period_) {
- base::TimeTicks next_composite =
- last_vsync_ + vsync_period_ - estimated_composite_time;
- if (next_composite < now) {
- // It's too late, we will reschedule composite as needed on the next
- // vsync.
- composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY;
- root_window_->RequestVSyncUpdate();
- DCHECK(WillComposite());
- return;
- }
-
- delay = next_composite - now;
- }
- }
- TRACE_EVENT2("cc,benchmark", "CompositorImpl::PostComposite",
- "trigger", trigger,
- "delay", delay.InMillisecondsF());
-
- DCHECK(composite_on_vsync_trigger_ == DO_NOT_COMPOSITE);
- if (current_composite_task_)
- current_composite_task_->Cancel();
-
- // Unretained because we cancel the task on shutdown.
- current_composite_task_.reset(new base::CancelableClosure(
- base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger)));
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, current_composite_task_->callback(), delay);
-}
-
-void CompositorImpl::Composite(CompositingTrigger trigger) {
- if (trigger == COMPOSITE_IMMEDIATELY)
- will_composite_immediately_ = false;
-
- DCHECK(host_->visible());
- DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY);
- DCHECK(needs_composite_);
- DCHECK(!DidCompositeThisFrame());
-
- DCHECK_LE(pending_swapbuffers_, kMaxUiSwapBuffers);
- // Swap Ack accounting is unreliable if the OutputSurface was lost.
- // In that case still attempt to composite, which will cause creation of a
- // new OutputSurface and reset pending_swapbuffers_.
- if (pending_swapbuffers_ == kMaxUiSwapBuffers &&
- !host_->output_surface_lost()) {
- TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit");
- return;
- }
-
- // Reset state before Layout+Composite since that might create more
- // requests to Composite that we need to respect.
- needs_composite_ = false;
-
- // Only allow compositing once per vsync.
- current_composite_task_->Cancel();
- DCHECK(DidCompositeThisFrame() && !WillComposite());
-
- const base::TimeTicks frame_time = base::TimeTicks::Now();
- if (needs_animate_) {
- base::AutoReset<bool> auto_reset_ignore_schedule(
- &ignore_schedule_composite_, true);
- needs_animate_ = false;
- root_window_->Animate(frame_time);
- }
-
- did_post_swapbuffers_ = false;
- host_->Composite(frame_time);
- if (did_post_swapbuffers_)
- pending_swapbuffers_++;
-
- // Need to track vsync to avoid compositing more than once per frame.
- root_window_->RequestVSyncUpdate();
-}
-
ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
return *this;
}
@@ -428,31 +346,23 @@ void CompositorImpl::SetSurface(jobject surface) {
void CompositorImpl::CreateLayerTreeHost() {
DCHECK(!host_);
- DCHECK(!WillCompositeThisFrame());
-
- // Just in case, since we immediately hide the LTH in this function,
- // and we do not want to end up with a pending Composite task when the
- // host is hidden.
- base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_,
- true);
cc::LayerTreeSettings settings;
settings.renderer_settings.refresh_rate = 60.0;
settings.renderer_settings.allow_antialiasing = false;
settings.renderer_settings.highp_threshold_min = 2048;
settings.use_zero_copy = true;
+ settings.use_external_begin_frame_source = true;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
settings.initial_debug_state.SetRecordRenderingStats(
command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
- settings.initial_debug_state.show_fps_counter =
- command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
- // TODO(enne): Update this this compositor to use the scheduler.
- settings.single_thread_proxy_scheduler = false;
+ if (command_line->HasSwitch(cc::switches::kDisableCompositorPropertyTrees))
+ settings.use_property_trees = false;
+ settings.single_thread_proxy_scheduler = true;
- if (command_line->HasSwitch(
- switches::kEnableAndroidCompositorAnimationTimelines))
- settings.use_compositor_animation_timelines = true;
+ settings.use_compositor_animation_timelines = !command_line->HasSwitch(
+ switches::kDisableAndroidCompositorAnimationTimelines);
cc::LayerTreeHost::InitParams params;
params.client = this;
@@ -461,10 +371,12 @@ void CompositorImpl::CreateLayerTreeHost() {
params.task_graph_runner = g_task_graph_runner.Pointer();
params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
params.settings = &settings;
+ params.external_begin_frame_source.reset(new ExternalBeginFrameSource(this));
host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
- host_->SetVisible(false);
+ DCHECK(!host_->visible());
host_->SetRootLayer(root_layer_);
- host_->SetLayerTreeHostClientReady();
+ if (surface_id_allocator_)
+ host_->set_surface_id_namespace(surface_id_allocator_->id_namespace());
host_->SetViewportSize(size_);
host_->set_has_transparent_background(has_transparent_background_);
host_->SetDeviceScaleFactor(device_scale_factor_);
@@ -477,39 +389,16 @@ void CompositorImpl::SetVisible(bool visible) {
TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible);
if (!visible) {
DCHECK(host_->visible());
- // Look for any layers that were attached to the root for readback
- // and are waiting for Composite() to happen.
- bool readback_pending = false;
- for (size_t i = 0; i < root_layer_->children().size(); ++i) {
- if (root_layer_->children()[i]->HasCopyRequest()) {
- readback_pending = true;
- break;
- }
- }
- if (readback_pending) {
- base::AutoReset<bool> auto_reset_ignore_schedule(
- &ignore_schedule_composite_, true);
- host_->Composite(base::TimeTicks::Now());
- }
- if (WillComposite())
- CancelComposite();
host_->SetVisible(false);
if (!host_->output_surface_lost())
host_->ReleaseOutputSurface();
pending_swapbuffers_ = 0;
- needs_composite_ = false;
- composite_on_vsync_trigger_ = DO_NOT_COMPOSITE;
establish_gpu_channel_timeout_.Stop();
display_client_.reset();
- if (current_composite_task_) {
- current_composite_task_->Cancel();
- current_composite_task_.reset();
- }
} else {
host_->SetVisible(true);
if (output_surface_request_pending_)
RequestNewOutputSurface();
- SetNeedsComposite();
}
}
@@ -540,10 +429,7 @@ void CompositorImpl::SetHasTransparentBackground(bool flag) {
void CompositorImpl::SetNeedsComposite() {
if (!host_->visible())
return;
- DCHECK(!needs_composite_ || WillComposite());
-
- needs_composite_ = true;
- PostComposite(COMPOSITE_IMMEDIATELY);
+ host_->SetNeedsAnimate();
}
static scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
@@ -576,10 +462,12 @@ CreateGpuProcessViewContext(
NULL));
}
-void CompositorImpl::Layout() {
- base::AutoReset<bool> auto_reset_ignore_schedule(&ignore_schedule_composite_,
- true);
- client_->Layout();
+void CompositorImpl::UpdateLayerTreeHost() {
+ client_->UpdateLayerTreeHost();
+ if (needs_animate_) {
+ needs_animate_ = false;
+ root_window_->Animate(base::TimeTicks::Now());
+ }
}
void CompositorImpl::OnGpuChannelEstablished() {
@@ -596,9 +484,9 @@ void CompositorImpl::RequestNewOutputSurface() {
#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
defined(SYZYASAN) || defined(CYGPROFILE_INSTRUMENTATION)
- const int64 kGpuChannelTimeoutInSeconds = 40;
+ const int64_t kGpuChannelTimeoutInSeconds = 40;
#else
- const int64 kGpuChannelTimeoutInSeconds = 10;
+ const int64_t kGpuChannelTimeoutInSeconds = 10;
#endif
BrowserGpuChannelHostFactory* factory =
@@ -665,11 +553,12 @@ void CompositorImpl::CreateOutputSurface() {
cc::SurfaceManager* manager = GetSurfaceManager();
if (manager) {
- display_client_.reset(new cc::OnscreenDisplayClient(
- real_output_surface.Pass(), manager, HostSharedBitmapManager::current(),
- BrowserGpuMemoryBufferManager::current(),
- host_->settings().renderer_settings,
- base::ThreadTaskRunnerHandle::Get()));
+ display_client_.reset(
+ new cc::OnscreenDisplayClient(std::move(real_output_surface), manager,
+ HostSharedBitmapManager::current(),
+ BrowserGpuMemoryBufferManager::current(),
+ host_->settings().renderer_settings,
+ base::ThreadTaskRunnerHandle::Get()));
scoped_ptr<cc::SurfaceDisplayOutputSurface> surface_output_surface(
new cc::SurfaceDisplayOutputSurface(
manager, surface_id_allocator_.get(), context_provider, nullptr));
@@ -677,9 +566,9 @@ void CompositorImpl::CreateOutputSurface() {
display_client_->set_surface_output_surface(surface_output_surface.get());
surface_output_surface->set_display_client(display_client_.get());
display_client_->display()->Resize(size_);
- host_->SetOutputSurface(surface_output_surface.Pass());
+ host_->SetOutputSurface(std::move(surface_output_surface));
} else {
- host_->SetOutputSurface(real_output_surface.Pass());
+ host_->SetOutputSurface(std::move(real_output_surface));
}
}
@@ -709,44 +598,15 @@ bool CompositorImpl::SupportsETC1NonPowerOfTwo() const {
return gpu_capabilities_.texture_format_etc1_npot;
}
-void CompositorImpl::ScheduleComposite() {
- if (ignore_schedule_composite_ || !host_->visible())
- return;
-
- DCHECK_IMPLIES(needs_composite_, WillComposite());
- needs_composite_ = true;
- // We currently expect layer tree invalidations at most once per frame
- // during normal operation and therefore try to composite immediately
- // to minimize latency.
- PostComposite(COMPOSITE_IMMEDIATELY);
-}
-
-void CompositorImpl::ScheduleAnimation() {
- needs_animate_ = true;
-
- if (!host_->visible())
- return;
-
- if (needs_composite_) {
- DCHECK(WillComposite());
- return;
- }
-
- TRACE_EVENT0("cc", "CompositorImpl::ScheduleAnimation");
- needs_composite_ = true;
- PostComposite(COMPOSITE_EVENTUALLY);
-}
-
void CompositorImpl::DidPostSwapBuffers() {
TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers");
- did_post_swapbuffers_ = true;
+ pending_swapbuffers_++;
}
void CompositorImpl::DidCompleteSwapBuffers() {
TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers");
DCHECK_GT(pending_swapbuffers_, 0U);
- if (pending_swapbuffers_-- == kMaxUiSwapBuffers && needs_composite_)
- PostComposite(COMPOSITE_IMMEDIATELY);
+ pending_swapbuffers_--;
client_->OnSwapBuffersCompleted(pending_swapbuffers_);
}
@@ -755,7 +615,8 @@ void CompositorImpl::DidAbortSwapBuffers() {
// This really gets called only once from
// SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the
// context was lost.
- ScheduleComposite();
+ if (host_->visible())
+ host_->SetNeedsCommit();
client_->OnSwapBuffersCompleted(0);
}
@@ -769,33 +630,24 @@ void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) {
void CompositorImpl::RequestCopyOfOutputOnRootLayer(
scoped_ptr<cc::CopyOutputRequest> request) {
- root_layer_->RequestCopyOfOutput(request.Pass());
+ root_layer_->RequestCopyOfOutput(std::move(request));
}
void CompositorImpl::OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) {
- vsync_period_ = vsync_period;
- last_vsync_ = frame_time;
-
- if (WillCompositeThisFrame()) {
- // We somehow missed the last vsync interval, so reschedule for deadline.
- // We cannot schedule immediately, or will get us out-of-phase with new
- // renderer frames.
- CancelComposite();
- composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY;
- } else {
- current_composite_task_.reset();
- }
+ FOR_EACH_OBSERVER(VSyncObserver, observer_list_,
+ OnVSync(frame_time, vsync_period));
+ if (needs_begin_frames_)
+ root_window_->RequestVSyncUpdate();
+}
- DCHECK(!DidCompositeThisFrame() && !WillCompositeThisFrame());
- if (composite_on_vsync_trigger_ != DO_NOT_COMPOSITE) {
- CompositingTrigger trigger = composite_on_vsync_trigger_;
- composite_on_vsync_trigger_ = DO_NOT_COMPOSITE;
- PostComposite(trigger);
- }
+void CompositorImpl::OnNeedsBeginFramesChange(bool needs_begin_frames) {
+ if (needs_begin_frames_ == needs_begin_frames)
+ return;
- FOR_EACH_OBSERVER(VSyncObserver, observer_list_,
- OnUpdateVSyncParameters(frame_time, vsync_period));
+ needs_begin_frames_ = needs_begin_frames;
+ if (needs_begin_frames_)
+ root_window_->RequestVSyncUpdate();
}
void CompositorImpl::SetNeedsAnimate() {
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.h b/chromium/content/browser/renderer_host/compositor_impl_android.h
index 223ae08117c..9b1a60eb0e9 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.h
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITOR_IMPL_ANDROID_H_
#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITOR_IMPL_ANDROID_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
#include "base/cancelable_callback.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
@@ -48,8 +50,8 @@ class CONTENT_EXPORT CompositorImpl
public:
class VSyncObserver {
public:
- virtual void OnUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) = 0;
+ virtual void OnVSync(base::TimeTicks timebase,
+ base::TimeDelta interval) = 0;
};
CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window);
@@ -64,6 +66,7 @@ class CONTENT_EXPORT CompositorImpl
void AddObserver(VSyncObserver* observer);
void RemoveObserver(VSyncObserver* observer);
+ void OnNeedsBeginFramesChange(bool needs_begin_frames);
// ui::ResourceProvider implementation.
cc::UIResourceId CreateUIResource(cc::UIResourceClient* client) override;
@@ -86,7 +89,7 @@ class CONTENT_EXPORT CompositorImpl
void DidBeginMainFrame() override {}
void BeginMainFrame(const cc::BeginFrameArgs& args) override {}
void BeginMainFrameNotExpectedSoon() override {}
- void Layout() override;
+ void UpdateLayerTreeHost() override;
void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
const gfx::Vector2dF& outer_delta,
const gfx::Vector2dF& elastic_overscroll_delta,
@@ -106,8 +109,6 @@ class CONTENT_EXPORT CompositorImpl
override {}
// LayerTreeHostSingleThreadClient implementation.
- void ScheduleComposite() override;
- void ScheduleAnimation() override;
void DidPostSwapBuffers() override;
void DidAbortSwapBuffers() override;
@@ -118,38 +119,8 @@ class CONTENT_EXPORT CompositorImpl
void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) override;
void SetNeedsAnimate() override;
-
void SetVisible(bool visible);
-
- enum CompositingTrigger {
- DO_NOT_COMPOSITE,
- COMPOSITE_IMMEDIATELY,
- COMPOSITE_EVENTUALLY,
- };
- void PostComposite(CompositingTrigger trigger);
- void Composite(CompositingTrigger trigger);
void CreateOutputSurface();
-
- bool WillCompositeThisFrame() const {
- return current_composite_task_ &&
- !current_composite_task_->callback().is_null();
- }
- bool DidCompositeThisFrame() const {
- return current_composite_task_ &&
- current_composite_task_->callback().is_null();
- }
- bool WillComposite() const {
- return WillCompositeThisFrame() ||
- composite_on_vsync_trigger_ != DO_NOT_COMPOSITE;
- }
- void CancelComposite() {
- DCHECK(WillComposite());
- if (WillCompositeThisFrame())
- current_composite_task_->Cancel();
- current_composite_task_.reset();
- composite_on_vsync_trigger_ = DO_NOT_COMPOSITE;
- will_composite_immediately_ = false;
- }
void CreateLayerTreeHost();
void OnGpuChannelEstablished();
@@ -160,6 +131,8 @@ class CONTENT_EXPORT CompositorImpl
scoped_refptr<cc::Layer> root_layer_;
scoped_refptr<cc::Layer> subroot_layer_;
+ // Destruction order matters here:
+ base::ObserverList<VSyncObserver, true> observer_list_;
scoped_ptr<cc::LayerTreeHost> host_;
ui::ResourceManagerImpl resource_manager_;
@@ -177,38 +150,15 @@ class CONTENT_EXPORT CompositorImpl
gfx::NativeWindow root_window_;
- // Used locally to track whether a call to LTH::Composite() did result in
- // a posted SwapBuffers().
- bool did_post_swapbuffers_;
-
- // Used locally to inhibit ScheduleComposite() during Layout().
- bool ignore_schedule_composite_;
-
- // Whether we need to composite in general because of any invalidation or
- // explicit request.
- bool needs_composite_;
-
// Whether we need to update animations on the next composite.
bool needs_animate_;
- // Whether we posted a task and are about to composite.
- bool will_composite_immediately_;
-
- // How we should schedule Composite during the next vsync.
- CompositingTrigger composite_on_vsync_trigger_;
-
- // The Composite operation scheduled for the current vsync interval.
- scoped_ptr<base::CancelableClosure> current_composite_task_;
-
// The number of SwapBuffer calls that have not returned and ACK'd from
// the GPU thread.
unsigned int pending_swapbuffers_;
size_t num_successive_context_creation_failures_;
- base::TimeDelta vsync_period_;
- base::TimeTicks last_vsync_;
-
base::OneShotTimer establish_gpu_channel_timeout_;
// Whether there is an OutputSurface request pending from the current
@@ -218,9 +168,7 @@ class CONTENT_EXPORT CompositorImpl
bool output_surface_request_pending_;
gpu::Capabilities gpu_capabilities_;
-
- base::ObserverList<VSyncObserver, true> observer_list_;
-
+ bool needs_begin_frames_;
base::WeakPtrFactory<CompositorImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CompositorImpl);
diff --git a/chromium/content/browser/renderer_host/compositor_resize_lock_aura.h b/chromium/content/browser/renderer_host/compositor_resize_lock_aura.h
index ad706904812..981694f329c 100644
--- a/chromium/content/browser/renderer_host/compositor_resize_lock_aura.h
+++ b/chromium/content/browser/renderer_host/compositor_resize_lock_aura.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITOR_RESIZE_LOCK_AURA_H_
#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITOR_RESIZE_LOCK_AURA_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
diff --git a/chromium/content/browser/renderer_host/database_message_filter.cc b/chromium/content/browser/renderer_host/database_message_filter.cc
index cf0e228c1e2..9c9f16ea45e 100644
--- a/chromium/content/browser/renderer_host/database_message_filter.cc
+++ b/chromium/content/browser/renderer_host/database_message_filter.cc
@@ -5,12 +5,15 @@
#include "content/browser/renderer_host/database_message_filter.h"
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
+#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/common/database_messages.h"
#include "content/public/browser/user_metrics.h"
@@ -145,8 +148,8 @@ void DatabaseMessageFilter::OnDatabaseOpenFile(
VfsBackend::OpenFile(db_file,
desired_flags | SQLITE_OPEN_DELETEONCLOSE);
if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE)) {
- tracked_file = db_tracker_->SaveIncognitoFile(vfs_file_name,
- file.Pass());
+ tracked_file =
+ db_tracker_->SaveIncognitoFile(vfs_file_name, std::move(file));
}
}
} else {
@@ -160,7 +163,7 @@ void DatabaseMessageFilter::OnDatabaseOpenFile(
// database tracker.
*handle = IPC::InvalidPlatformFileForTransit();
if (file.IsValid()) {
- *handle = IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle());
+ *handle = IPC::TakeFileHandleForProcess(std::move(file), PeerHandle());
} else if (tracked_file) {
DCHECK(tracked_file->IsValid());
*handle =
@@ -226,7 +229,7 @@ void DatabaseMessageFilter::DatabaseDeleteFile(
void DatabaseMessageFilter::OnDatabaseGetFileAttributes(
const base::string16& vfs_file_name,
- int32* attributes) {
+ int32_t* attributes) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
*attributes = -1;
base::FilePath db_file =
@@ -237,7 +240,7 @@ void DatabaseMessageFilter::OnDatabaseGetFileAttributes(
void DatabaseMessageFilter::OnDatabaseGetFileSize(
const base::string16& vfs_file_name,
- int64* size) {
+ int64_t* size) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
*size = 0;
base::FilePath db_file =
@@ -256,11 +259,14 @@ void DatabaseMessageFilter::OnDatabaseGetSpaceAvailable(
if (!quota_manager) {
NOTREACHED(); // The system is shutting down, messages are unexpected.
DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(
- reply_msg, static_cast<int64>(0));
+ reply_msg, static_cast<int64_t>(0));
Send(reply_msg);
return;
}
+ // crbug.com/349708
+ TRACE_EVENT0("io", "DatabaseMessageFilter::OnDatabaseGetSpaceAvailable");
+
quota_manager->GetUsageAndQuota(
storage::GetOriginFromIdentifier(origin_identifier),
storage::kStorageTypeTemporary,
@@ -271,9 +277,9 @@ void DatabaseMessageFilter::OnDatabaseGetSpaceAvailable(
void DatabaseMessageFilter::OnDatabaseGetUsageAndQuota(
IPC::Message* reply_msg,
storage::QuotaStatusCode status,
- int64 usage,
- int64 quota) {
- int64 available = 0;
+ int64_t usage,
+ int64_t quota) {
+ int64_t available = 0;
if ((status == storage::kQuotaStatusOk) && (usage < quota))
available = quota - usage;
DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(reply_msg, available);
@@ -281,7 +287,9 @@ void DatabaseMessageFilter::OnDatabaseGetUsageAndQuota(
}
void DatabaseMessageFilter::OnDatabaseSetFileSize(
- const base::string16& vfs_file_name, int64 size, bool* success) {
+ const base::string16& vfs_file_name,
+ int64_t size,
+ bool* success) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
*success = false;
base::FilePath db_file =
@@ -294,7 +302,7 @@ void DatabaseMessageFilter::OnDatabaseOpened(
const std::string& origin_identifier,
const base::string16& database_name,
const base::string16& description,
- int64 estimated_size) {
+ int64_t estimated_size) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) {
@@ -307,7 +315,7 @@ void DatabaseMessageFilter::OnDatabaseOpened(
"websql.OpenDatabase",
IsOriginSecure(storage::GetOriginFromIdentifier(origin_identifier)));
- int64 database_size = 0;
+ int64_t database_size = 0;
db_tracker_->DatabaseOpened(origin_identifier, database_name, description,
estimated_size, &database_size);
database_connections_.AddConnection(origin_identifier, database_name);
@@ -361,7 +369,7 @@ void DatabaseMessageFilter::OnHandleSqliteError(
void DatabaseMessageFilter::OnDatabaseSizeChanged(
const std::string& origin_identifier,
const base::string16& database_name,
- int64 database_size) {
+ int64_t database_size) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
if (database_connections_.IsOriginUsed(origin_identifier)) {
Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
diff --git a/chromium/content/browser/renderer_host/database_message_filter.h b/chromium/content/browser/renderer_host/database_message_filter.h
index 13f27bcda3a..4cf4e92fb80 100644
--- a/chromium/content/browser/renderer_host/database_message_filter.h
+++ b/chromium/content/browser/renderer_host/database_message_filter.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_DATABASE_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_DATABASE_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include "base/containers/hash_tables.h"
#include "base/strings/string16.h"
#include "content/public/browser/browser_message_filter.h"
@@ -46,11 +48,11 @@ class DatabaseMessageFilter : public BrowserMessageFilter,
const bool& sync_dir,
IPC::Message* reply_msg);
void OnDatabaseGetFileAttributes(const base::string16& vfs_file_name,
- int32* attributes);
+ int32_t* attributes);
void OnDatabaseGetFileSize(const base::string16& vfs_file_name,
- int64* size);
+ int64_t* size);
void OnDatabaseSetFileSize(const base::string16& vfs_file_name,
- int64 size,
+ int64_t size,
bool* success);
// Quota message handler (io thread)
@@ -58,14 +60,14 @@ class DatabaseMessageFilter : public BrowserMessageFilter,
IPC::Message* reply_msg);
void OnDatabaseGetUsageAndQuota(IPC::Message* reply_msg,
storage::QuotaStatusCode status,
- int64 usage,
- int64 quota);
+ int64_t usage,
+ int64_t quota);
// Database tracker message handlers (file thread)
void OnDatabaseOpened(const std::string& origin_identifier,
const base::string16& database_name,
const base::string16& description,
- int64 estimated_size);
+ int64_t estimated_size);
void OnDatabaseModified(const std::string& origin_identifier,
const base::string16& database_name);
void OnDatabaseClosed(const std::string& origin_identifier,
@@ -77,7 +79,7 @@ class DatabaseMessageFilter : public BrowserMessageFilter,
// DatabaseTracker::Observer callbacks (file thread)
void OnDatabaseSizeChanged(const std::string& origin_identifier,
const base::string16& database_name,
- int64 database_size) override;
+ int64_t database_size) override;
void OnDatabaseScheduledForDeletion(
const std::string& origin_identifier,
const base::string16& database_name) override;
diff --git a/chromium/content/browser/renderer_host/delegated_frame_evictor.h b/chromium/content/browser/renderer_host/delegated_frame_evictor.h
index 9e9f68a61ad..c1bd50ede1b 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_evictor.h
+++ b/chromium/content/browser/renderer_host/delegated_frame_evictor.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_DELEGATED_FRAME_EVICTOR_H_
#define CONTENT_BROWSER_RENDERER_HOST_DELEGATED_FRAME_EVICTOR_H_
+#include "base/macros.h"
#include "content/browser/renderer_host/renderer_frame_manager.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
new file mode 100644
index 00000000000..5d186424b66
--- /dev/null
+++ b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
@@ -0,0 +1,347 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
+
+#include <dwrite.h>
+#include <shlobj.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <set>
+#include <utility>
+
+#include "base/callback_helpers.h"
+#include "base/i18n/case_conversion.h"
+#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/common/dwrite_font_proxy_messages.h"
+#include "ipc/ipc_message_macros.h"
+#include "ui/gfx/win/direct_write.h"
+
+namespace mswr = Microsoft::WRL;
+
+namespace content {
+
+namespace {
+
+// This enum is used to define the buckets for an enumerated UMA histogram.
+// Hence,
+// (a) existing enumerated constants should never be deleted or reordered, and
+// (b) new constants should only be appended at the end of the enumeration.
+enum DirectWriteFontLoaderType {
+ FILE_SYSTEM_FONT_DIR = 0,
+ FILE_OUTSIDE_SANDBOX = 1,
+ OTHER_LOADER = 2,
+
+ FONT_LOADER_TYPE_MAX_VALUE
+};
+
+void LogLoaderType(DirectWriteFontLoaderType loader_type) {
+ UMA_HISTOGRAM_ENUMERATION("DirectWrite.Fonts.Proxy.LoaderType", loader_type,
+ FONT_LOADER_TYPE_MAX_VALUE);
+}
+
+const wchar_t* kFontsToIgnore[] = {
+ // "Gill Sans Ultra Bold" turns into an Ultra Bold weight "Gill Sans" in
+ // DirectWrite, but most users don't have any other weights. The regular
+ // weight font is named "Gill Sans MT", but that ends up in a different
+ // family with that name. On Mac, there's a "Gill Sans" with various
+ // weights, so CSS authors use { 'font-family': 'Gill Sans',
+ // 'Gill Sans MT', ... } and because of the DirectWrite family futzing,
+ // they end up with an Ultra Bold font, when they just wanted "Gill Sans".
+ // Mozilla implemented a more complicated hack where they effectively
+ // rename the Ultra Bold font to "Gill Sans MT Ultra Bold", but because the
+ // Ultra Bold font is so ugly anyway, we simply ignore it. See
+ // http://www.microsoft.com/typography/fonts/font.aspx?FMID=978 for a
+ // picture of the font, and the file name. We also ignore "Gill Sans Ultra
+ // Bold Condensed".
+ L"gilsanub.ttf", L"gillubcd.ttf",
+};
+
+base::string16 GetWindowsFontsPath() {
+ std::vector<base::char16> font_path_chars;
+ // SHGetSpecialFolderPath requires at least MAX_PATH characters.
+ font_path_chars.resize(MAX_PATH);
+ BOOL result = SHGetSpecialFolderPath(nullptr /* hwndOwner - reserved */,
+ font_path_chars.data(), CSIDL_FONTS,
+ FALSE /* fCreate */);
+ DCHECK(result);
+ return base::i18n::FoldCase(font_path_chars.data());
+}
+
+} // namespace
+
+DWriteFontProxyMessageFilter::DWriteFontProxyMessageFilter()
+ : BrowserMessageFilter(DWriteFontProxyMsgStart),
+ windows_fonts_path_(GetWindowsFontsPath()) {}
+
+DWriteFontProxyMessageFilter::~DWriteFontProxyMessageFilter() = default;
+
+bool DWriteFontProxyMessageFilter::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(DWriteFontProxyMessageFilter, message)
+ IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_FindFamily, OnFindFamily)
+ IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyCount, OnGetFamilyCount)
+ IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyNames, OnGetFamilyNames)
+ IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFontFiles, OnGetFontFiles)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void DWriteFontProxyMessageFilter::OverrideThreadForMessage(
+ const IPC::Message& message,
+ content::BrowserThread::ID* thread) {
+ if (IPC_MESSAGE_CLASS(message) == DWriteFontProxyMsgStart)
+ *thread = BrowserThread::FILE;
+}
+
+void DWriteFontProxyMessageFilter::OnFindFamily(
+ const base::string16& family_name,
+ UINT32* family_index) {
+ InitializeDirectWrite();
+ TRACE_EVENT0("dwrite", "FontProxyHost::OnFindFamily");
+ DCHECK(collection_);
+ *family_index = UINT32_MAX;
+ if (collection_) {
+ BOOL exists = FALSE;
+ UINT32 index = UINT32_MAX;
+ HRESULT hr =
+ collection_->FindFamilyName(family_name.data(), &index, &exists);
+ if (SUCCEEDED(hr) && exists)
+ *family_index = index;
+ }
+}
+
+void DWriteFontProxyMessageFilter::OnGetFamilyCount(UINT32* count) {
+ InitializeDirectWrite();
+ TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyCount");
+ DCHECK(collection_);
+ if (!collection_)
+ *count = 0;
+ else
+ *count = collection_->GetFontFamilyCount();
+}
+
+void DWriteFontProxyMessageFilter::OnGetFamilyNames(
+ UINT32 family_index,
+ std::vector<DWriteStringPair>* family_names) {
+ InitializeDirectWrite();
+ TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyNames");
+ DCHECK(collection_);
+ if (!collection_)
+ return;
+
+ TRACE_EVENT0("dwrite", "FontProxyHost::DoGetFamilyNames");
+
+ mswr::ComPtr<IDWriteFontFamily> family;
+ HRESULT hr = collection_->GetFontFamily(family_index, &family);
+ if (!SUCCEEDED(hr))
+ return;
+
+ mswr::ComPtr<IDWriteLocalizedStrings> localized_names;
+ hr = family->GetFamilyNames(&localized_names);
+ if (!SUCCEEDED(hr))
+ return;
+
+ size_t string_count = localized_names->GetCount();
+
+ std::vector<base::char16> locale;
+ std::vector<base::char16> name;
+ for (size_t index = 0; index < string_count; ++index) {
+ UINT32 length = 0;
+ hr = localized_names->GetLocaleNameLength(index, &length);
+ if (!SUCCEEDED(hr))
+ return;
+ ++length; // Reserve space for the null terminator.
+ locale.resize(length);
+ hr = localized_names->GetLocaleName(index, locale.data(), length);
+ if (!SUCCEEDED(hr))
+ return;
+ DCHECK_EQ(L'\0', locale[length - 1]);
+
+ length = 0;
+ hr = localized_names->GetStringLength(index, &length);
+ if (!SUCCEEDED(hr))
+ return;
+ ++length; // Reserve space for the null terminator.
+ name.resize(length);
+ hr = localized_names->GetString(index, name.data(), length);
+ if (!SUCCEEDED(hr))
+ return;
+ DCHECK_EQ(L'\0', name[length - 1]);
+
+ // Would be great to use emplace_back instead.
+ family_names->push_back(std::pair<base::string16, base::string16>(
+ base::string16(locale.data()), base::string16(name.data())));
+ }
+}
+
+void DWriteFontProxyMessageFilter::OnGetFontFiles(
+ uint32_t family_index,
+ std::vector<base::string16>* file_paths) {
+ InitializeDirectWrite();
+ TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFontFiles");
+ DCHECK(collection_);
+ if (!collection_)
+ return;
+
+ mswr::ComPtr<IDWriteFontFamily> family;
+ HRESULT hr = collection_->GetFontFamily(family_index, &family);
+ if (!SUCCEEDED(hr))
+ return;
+
+ UINT32 font_count = family->GetFontCount();
+
+ std::set<base::string16> path_set;
+ // Iterate through all the fonts in the family, and all the files for those
+ // fonts. If anything goes wrong, bail on the entire family to avoid having
+ // a partially-loaded font family.
+ for (UINT32 font_index = 0; font_index < font_count; ++font_index) {
+ mswr::ComPtr<IDWriteFont> font;
+ hr = family->GetFont(font_index, &font);
+ if (!SUCCEEDED(hr))
+ return;
+
+ AddFilesForFont(&path_set, font.Get());
+ }
+
+ file_paths->assign(path_set.begin(), path_set.end());
+}
+
+void DWriteFontProxyMessageFilter::InitializeDirectWrite() {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ if (direct_write_initialized_)
+ return;
+ direct_write_initialized_ = true;
+
+ mswr::ComPtr<IDWriteFactory> factory;
+ gfx::win::CreateDWriteFactory(&factory);
+ if (factory == nullptr) {
+ // We won't be able to load fonts, but we should still return messages so
+ // renderers don't hang if they for some reason send us a font message.
+ return;
+ }
+
+ HRESULT hr = factory->GetSystemFontCollection(&collection_);
+ DCHECK(SUCCEEDED(hr));
+}
+
+bool DWriteFontProxyMessageFilter::AddFilesForFont(
+ std::set<base::string16>* path_set,
+ IDWriteFont* font) {
+ mswr::ComPtr<IDWriteFontFace> font_face;
+ HRESULT hr;
+ hr = font->CreateFontFace(&font_face);
+ if (!SUCCEEDED(hr))
+ return false;
+
+ UINT32 file_count;
+ hr = font_face->GetFiles(&file_count, nullptr);
+ if (!SUCCEEDED(hr))
+ return false;
+
+ std::vector<mswr::ComPtr<IDWriteFontFile>> font_files;
+ font_files.resize(file_count);
+ hr = font_face->GetFiles(
+ &file_count, reinterpret_cast<IDWriteFontFile**>(font_files.data()));
+ if (!SUCCEEDED(hr))
+ return false;
+
+ for (unsigned int file_index = 0; file_index < file_count; ++file_index) {
+ mswr::ComPtr<IDWriteFontFileLoader> loader;
+ hr = font_files[file_index]->GetLoader(&loader);
+ if (!SUCCEEDED(hr))
+ return false;
+
+ mswr::ComPtr<IDWriteLocalFontFileLoader> local_loader;
+ hr = loader.CopyTo(local_loader.GetAddressOf()); // QueryInterface.
+
+ if (hr == E_NOINTERFACE) {
+ // We could get here if the system font collection contains fonts that
+ // are backed by something other than files in the system fonts folder.
+ // I don't think that is actually possible, so for now we'll just
+ // ignore it (result will be that we'll be unable to match any styles
+ // for this font, forcing blink/skia to fall back to whatever font is
+ // next). If we get telemetry indicating that this case actually
+ // happens, we can implement this by exposing the loader via ipc. That
+ // will likely by loading the font data into shared memory, although we
+ // could proxy the stream reads directly instead.
+ LogLoaderType(OTHER_LOADER);
+ DCHECK(false);
+ return false;
+ } else if (!SUCCEEDED(hr)) {
+ return false;
+ }
+
+ if (!AddLocalFile(path_set, local_loader.Get(),
+ font_files[file_index].Get())) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool DWriteFontProxyMessageFilter::AddLocalFile(
+ std::set<base::string16>* path_set,
+ IDWriteLocalFontFileLoader* local_loader,
+ IDWriteFontFile* font_file) {
+ HRESULT hr;
+ const void* key;
+ UINT32 key_size;
+ hr = font_file->GetReferenceKey(&key, &key_size);
+ if (!SUCCEEDED(hr))
+ return false;
+
+ UINT32 path_length = 0;
+ hr = local_loader->GetFilePathLengthFromKey(key, key_size, &path_length);
+ if (!SUCCEEDED(hr))
+ return false;
+ ++path_length; // Reserve space for the null terminator.
+ std::vector<base::char16> file_path_chars;
+ file_path_chars.resize(path_length);
+ hr = local_loader->GetFilePathFromKey(key, key_size, file_path_chars.data(),
+ path_length);
+ if (!SUCCEEDED(hr))
+ return false;
+
+ base::string16 file_path = base::i18n::FoldCase(file_path_chars.data());
+ if (!base::StartsWith(file_path, windows_fonts_path_,
+ base::CompareCase::SENSITIVE)) {
+ // Skip loading fonts from outside the system fonts directory, since
+ // these families will not be accessible to the renderer process. If
+ // this turns out to be a common case, we can either grant the renderer
+ // access to these files (not sure if this is actually possible), or
+ // load the file data ourselves and hand it to the renderer.
+ LogLoaderType(FILE_OUTSIDE_SANDBOX);
+ NOTREACHED(); // Not yet implemented.
+ return false;
+ }
+
+ // Refer to comments in kFontsToIgnore for this block.
+ for (const auto& file_to_ignore : kFontsToIgnore) {
+ // Ok to do ascii comparison since the strings we are looking for are
+ // all ascii.
+ if (base::EndsWith(file_path, file_to_ignore,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ // Unlike most other cases in this function, we do not abort loading
+ // the entire family, since we want to specifically ignore particular
+ // font styles and load the rest of the family if it exists. The
+ // renderer can deal with a family with zero files if that ends up
+ // being the case.
+ return true;
+ }
+ }
+
+ LogLoaderType(FILE_SYSTEM_FONT_DIR);
+ path_set->insert(file_path);
+ return true;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h
new file mode 100644
index 00000000000..25ef9b6015c
--- /dev/null
+++ b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h
@@ -0,0 +1,65 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_DWRITE_FONT_PROXY_MESSAGE_FILTER_WIN_H_
+#define CONTENT_BROWSER_RENDERER_HOST_DWRITE_FONT_PROXY_MESSAGE_FILTER_WIN_H_
+
+#include <dwrite.h>
+#include <wrl.h>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+// Implements a message filter that handles the dwrite font proxy messages.
+// If DWrite is enabled, calls into the system font collection to obtain
+// results. Otherwise, acts as if the system collection contains no fonts.
+class CONTENT_EXPORT DWriteFontProxyMessageFilter
+ : public BrowserMessageFilter {
+ public:
+ DWriteFontProxyMessageFilter();
+
+ // BrowserMessageFilter:
+ bool OnMessageReceived(const IPC::Message& message) override;
+ void OverrideThreadForMessage(const IPC::Message& message,
+ content::BrowserThread::ID* thread) override;
+
+ protected:
+ ~DWriteFontProxyMessageFilter() override;
+
+ void OnFindFamily(const base::string16& family_name, UINT32* family_index);
+ void OnGetFamilyCount(UINT32* count);
+ void OnGetFamilyNames(
+ UINT32 family_index,
+ std::vector<std::pair<base::string16, base::string16>>* family_names);
+ void OnGetFontFiles(UINT32 family_index,
+ std::vector<base::string16>* file_paths);
+
+ void InitializeDirectWrite();
+
+ private:
+ bool AddFilesForFont(std::set<base::string16>* path_set, IDWriteFont* font);
+ bool AddLocalFile(std::set<base::string16>* path_set,
+ IDWriteLocalFontFileLoader* local_loader,
+ IDWriteFontFile* font_file);
+
+ private:
+ bool direct_write_initialized_ = false;
+ Microsoft::WRL::ComPtr<IDWriteFontCollection> collection_;
+ base::string16 windows_fonts_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(DWriteFontProxyMessageFilter);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_DWRITE_FONT_PROXY_MESSAGE_FILTER_WIN_H_
diff --git a/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc
new file mode 100644
index 00000000000..65359e9b923
--- /dev/null
+++ b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc
@@ -0,0 +1,145 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
+
+#include <dwrite.h>
+
+#include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "content/common/dwrite_font_proxy_messages.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "ipc/ipc_message_macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/win/direct_write.h"
+
+namespace mswr = Microsoft::WRL;
+
+namespace content {
+
+namespace {
+
+class FilterWithFakeSender : public DWriteFontProxyMessageFilter {
+ public:
+ bool Send(IPC::Message* msg) override {
+ EXPECT_EQ(nullptr, reply_message_.get());
+ reply_message_.reset(msg);
+ return true;
+ }
+
+ IPC::Message* GetReply() { return reply_message_.get(); }
+
+ void ResetReply() { reply_message_.reset(nullptr); }
+
+ private:
+ ~FilterWithFakeSender() override = default;
+
+ scoped_ptr<IPC::Message> reply_message_;
+};
+
+class DWriteFontProxyMessageFilterUnitTest : public testing::Test {
+ public:
+ DWriteFontProxyMessageFilterUnitTest() {
+ filter_ = new FilterWithFakeSender();
+ }
+
+ void Send(IPC::SyncMessage* message) {
+ std::unique_ptr<IPC::SyncMessage> deleter(message);
+ scoped_ptr<IPC::MessageReplyDeserializer> serializer(
+ message->GetReplyDeserializer());
+ filter_->OnMessageReceived(*message);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_NE(nullptr, filter_->GetReply());
+ serializer->SerializeOutputParameters(*(filter_->GetReply()));
+ }
+
+ scoped_refptr<FilterWithFakeSender> filter_;
+ content::TestBrowserThreadBundle thread_bundle_;
+};
+
+TEST_F(DWriteFontProxyMessageFilterUnitTest, GetFamilyCount) {
+ if (!gfx::win::ShouldUseDirectWrite())
+ return;
+ UINT32 family_count = 0;
+ Send(new DWriteFontProxyMsg_GetFamilyCount(&family_count));
+ EXPECT_NE(0u, family_count); // Assume there's some fonts on the test system.
+}
+
+TEST_F(DWriteFontProxyMessageFilterUnitTest, FindFamily) {
+ if (!gfx::win::ShouldUseDirectWrite())
+ return;
+ UINT32 arial_index = 0;
+ Send(new DWriteFontProxyMsg_FindFamily(L"Arial", &arial_index));
+ EXPECT_NE(UINT_MAX, arial_index);
+
+ filter_->ResetReply();
+ UINT32 times_index = 0;
+ Send(new DWriteFontProxyMsg_FindFamily(L"Times New Roman", &times_index));
+ EXPECT_NE(UINT_MAX, times_index);
+ EXPECT_NE(arial_index, times_index);
+
+ filter_->ResetReply();
+ UINT32 unknown_index = 0;
+ Send(new DWriteFontProxyMsg_FindFamily(L"Not a font family", &unknown_index));
+ EXPECT_EQ(UINT_MAX, unknown_index);
+}
+
+TEST_F(DWriteFontProxyMessageFilterUnitTest, GetFamilyNames) {
+ if (!gfx::win::ShouldUseDirectWrite())
+ return;
+ UINT32 arial_index = 0;
+ Send(new DWriteFontProxyMsg_FindFamily(L"Arial", &arial_index));
+ filter_->ResetReply();
+
+ std::vector<DWriteStringPair> names;
+ Send(new DWriteFontProxyMsg_GetFamilyNames(arial_index, &names));
+
+ EXPECT_LT(0u, names.size());
+ for (const auto& pair : names) {
+ EXPECT_STRNE(L"", pair.first.c_str());
+ EXPECT_STRNE(L"", pair.second.c_str());
+ }
+}
+
+TEST_F(DWriteFontProxyMessageFilterUnitTest, GetFamilyNamesIndexOutOfBounds) {
+ if (!gfx::win::ShouldUseDirectWrite())
+ return;
+ std::vector<DWriteStringPair> names;
+ UINT32 invalid_index = 1000000;
+ Send(new DWriteFontProxyMsg_GetFamilyNames(invalid_index, &names));
+
+ EXPECT_EQ(0u, names.size());
+}
+
+TEST_F(DWriteFontProxyMessageFilterUnitTest, GetFontFiles) {
+ if (!gfx::win::ShouldUseDirectWrite())
+ return;
+ UINT32 arial_index = 0;
+ Send(new DWriteFontProxyMsg_FindFamily(L"Arial", &arial_index));
+ filter_->ResetReply();
+
+ std::vector<base::string16> files;
+ Send(new DWriteFontProxyMsg_GetFontFiles(arial_index, &files));
+
+ EXPECT_LT(0u, files.size());
+ for (const base::string16& file : files) {
+ EXPECT_STRNE(L"", file.c_str());
+ }
+}
+
+TEST_F(DWriteFontProxyMessageFilterUnitTest, GetFontFilesIndexOutOfBounds) {
+ if (!gfx::win::ShouldUseDirectWrite())
+ return;
+ std::vector<base::string16> files;
+ UINT32 invalid_index = 1000000;
+ Send(new DWriteFontProxyMsg_GetFontFiles(invalid_index, &files));
+
+ EXPECT_EQ(0u, files.size());
+}
+
+} // namespace
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/file_utilities_message_filter.h b/chromium/content/browser/renderer_host/file_utilities_message_filter.h
index 54a5830a6d4..ccbc739a82e 100644
--- a/chromium/content/browser/renderer_host/file_utilities_message_filter.h
+++ b/chromium/content/browser/renderer_host/file_utilities_message_filter.h
@@ -5,9 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_FILE_UTILITIES_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_FILE_UTILITIES_MESSAGE_FILTER_H_
-#include "base/basictypes.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
namespace IPC {
diff --git a/chromium/content/browser/renderer_host/font_utils_linux.cc b/chromium/content/browser/renderer_host/font_utils_linux.cc
index 2ee84e1f403..715923d6b88 100644
--- a/chromium/content/browser/renderer_host/font_utils_linux.cc
+++ b/chromium/content/browser/renderer_host/font_utils_linux.cc
@@ -4,6 +4,8 @@
#include <fcntl.h>
#include <fontconfig/fontconfig.h>
+#include <stddef.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -119,8 +121,8 @@ namespace content {
int MatchFontFaceWithFallback(const std::string& face,
bool is_bold,
bool is_italic,
- uint32 charset,
- uint32 fallback_family) {
+ uint32_t charset,
+ uint32_t fallback_family) {
FcLangSet* langset = FcLangSetCreate();
bool is_lgc = MSCharSetToFontconfig(langset, charset);
FcPattern* pattern = FcPatternCreate();
diff --git a/chromium/content/browser/renderer_host/font_utils_linux.h b/chromium/content/browser/renderer_host/font_utils_linux.h
index 669f816984c..33b31af68d7 100644
--- a/chromium/content/browser/renderer_host/font_utils_linux.h
+++ b/chromium/content/browser/renderer_host/font_utils_linux.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_
#define CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_
+#include <stdint.h>
+
#include <string>
namespace content {
@@ -12,8 +14,8 @@ namespace content {
int MatchFontFaceWithFallback(const std::string& face,
bool is_bold,
bool is_italic,
- uint32 charset,
- uint32 fallback_family);
+ uint32_t charset,
+ uint32_t fallback_family);
} // namespace content
diff --git a/chromium/content/browser/renderer_host/gamepad_browser_message_filter.h b/chromium/content/browser/renderer_host/gamepad_browser_message_filter.h
index e5dc8aefd7b..343c2ac807a 100644
--- a/chromium/content/browser/renderer_host/gamepad_browser_message_filter.h
+++ b/chromium/content/browser/renderer_host/gamepad_browser_message_filter.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_GAMEPAD_BROWSER_MESSAGE_FILTER_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/shared_memory.h"
#include "content/browser/gamepad/gamepad_consumer.h"
#include "content/public/browser/browser_message_filter.h"
diff --git a/chromium/content/browser/renderer_host/gpu_message_filter.cc b/chromium/content/browser/renderer_host/gpu_message_filter.cc
index 910c91205ad..95355b3e3e1 100644
--- a/chromium/content/browser/renderer_host/gpu_message_filter.cc
+++ b/chromium/content/browser/renderer_host/gpu_message_filter.cc
@@ -9,25 +9,18 @@
#include "content/browser/renderer_host/gpu_message_filter.h"
#include "base/bind.h"
-#include "base/command_line.h"
-#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
-#include "content/browser/gpu/gpu_data_manager_impl_private.h"
+#include "build/build_config.h"
+#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
-#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/gpu/gpu_messages.h"
-#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
-#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/service/gpu_switches.h"
namespace content {
-GpuMessageFilter::GpuMessageFilter(int render_process_id,
- RenderWidgetHelper* render_widget_helper)
+GpuMessageFilter::GpuMessageFilter(int render_process_id)
: BrowserMessageFilter(GpuMsgStart),
gpu_process_id_(0),
render_process_id_(render_process_id),
- render_widget_helper_(render_widget_helper),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
@@ -41,8 +34,6 @@ bool GpuMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(GpuMessageFilter, message)
IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_EstablishGpuChannel,
OnEstablishGpuChannel)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_CreateViewCommandBuffer,
- OnCreateViewCommandBuffer)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -54,13 +45,16 @@ void GpuMessageFilter::OnEstablishGpuChannel(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
scoped_ptr<IPC::Message> reply(reply_ptr);
- // TODO(apatrick): Eventually, this will return the route ID of a
- // GpuProcessStub, from which the renderer process will create a
- // GpuProcessProxy. The renderer will use the proxy for all subsequent
- // communication with the GPU process. This means if the GPU process
- // terminates, the renderer process will not find itself unknowingly sending
- // IPCs to a newly launched GPU process. Also, I will rename this function
- // to something like OnCreateGpuProcess.
+#if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
+ // TODO(jbauman): Remove this when we know why renderer processes are
+ // hanging on x86-64. https://crbug.com/577127
+ if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) {
+ reply->set_reply_error();
+ Send(reply.release());
+ return;
+ }
+#endif
+
GpuProcessHost* host = GpuProcessHost::FromID(gpu_process_id_);
if (!host) {
host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
@@ -87,32 +81,6 @@ void GpuMessageFilter::OnEstablishGpuChannel(
weak_ptr_factory_.GetWeakPtr(), base::Passed(&reply)));
}
-void GpuMessageFilter::OnCreateViewCommandBuffer(
- const GPUCreateCommandBufferConfig& init_params,
- int32 route_id,
- IPC::Message* reply_ptr) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- scoped_ptr<IPC::Message> reply(reply_ptr);
-
- // For the renderer to fall back to software also.
- GpuProcessHost* host = nullptr;
- if (GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) {
- host = GpuProcessHost::FromID(gpu_process_id_);
- }
-
- if (!host) {
- reply->set_reply_error();
- Send(reply.release());
- return;
- }
-
- host->CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NULL_TRANSPORT),
- render_process_id_, init_params, route_id,
- base::Bind(&GpuMessageFilter::CreateCommandBufferCallback,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&reply)));
-}
-
void GpuMessageFilter::EstablishChannelCallback(
scoped_ptr<IPC::Message> reply,
const IPC::ChannelHandle& channel,
@@ -124,11 +92,4 @@ void GpuMessageFilter::EstablishChannelCallback(
Send(reply.release());
}
-void GpuMessageFilter::CreateCommandBufferCallback(
- scoped_ptr<IPC::Message> reply, CreateCommandBufferResult result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- GpuHostMsg_CreateViewCommandBuffer::WriteReplyParams(reply.get(), result);
- Send(reply.release());
-}
-
} // namespace content
diff --git a/chromium/content/browser/renderer_host/gpu_message_filter.h b/chromium/content/browser/renderer_host/gpu_message_filter.h
index 6e216d6aeca..393d0babdc6 100644
--- a/chromium/content/browser/renderer_host/gpu_message_filter.h
+++ b/chromium/content/browser/renderer_host/gpu_message_filter.h
@@ -5,36 +5,24 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_GPU_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_GPU_MESSAGE_FILTER_H_
-#include <vector>
-
-#include "base/memory/linked_ptr.h"
-#include "base/memory/ref_counted.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner_helpers.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
-#include "content/common/gpu/gpu_result_codes.h"
#include "content/public/browser/browser_message_filter.h"
-#include "ui/gfx/native_widget_types.h"
-
-class GpuProcessHost;
-struct GPUCreateCommandBufferConfig;
namespace gpu {
struct GPUInfo;
}
namespace content {
-class RenderWidgetHelper;
-class RenderWidgetHostViewFrameSubscriber;
-// A message filter for messages from the renderer to the GpuProcessHost(UIShim)
+// A message filter for messages from the renderer to the GpuProcessHost
// in the browser. Such messages are typically destined for the GPU process,
// but need to be mediated by the browser.
class GpuMessageFilter : public BrowserMessageFilter {
public:
- GpuMessageFilter(int render_process_id,
- RenderWidgetHelper* render_widget_helper);
+ GpuMessageFilter(int render_process_id);
// BrowserMessageFilter methods:
bool OnMessageReceived(const IPC::Message& message) override;
@@ -42,30 +30,20 @@ class GpuMessageFilter : public BrowserMessageFilter {
private:
friend class BrowserThread;
friend class base::DeleteHelper<GpuMessageFilter>;
- struct CreateViewCommandBufferRequest;
- struct FrameSubscription;
~GpuMessageFilter() override;
// Message handlers called on the browser IO thread:
void OnEstablishGpuChannel(CauseForGpuLaunch,
IPC::Message* reply);
- void OnCreateViewCommandBuffer(
- const GPUCreateCommandBufferConfig& init_params,
- int32 route_id,
- IPC::Message* reply);
// Helper callbacks for the message handlers.
void EstablishChannelCallback(scoped_ptr<IPC::Message> reply,
const IPC::ChannelHandle& channel,
const gpu::GPUInfo& gpu_info);
- void CreateCommandBufferCallback(scoped_ptr<IPC::Message> reply,
- CreateCommandBufferResult result);
int gpu_process_id_;
int render_process_id_;
- scoped_refptr<RenderWidgetHelper> render_widget_helper_;
-
base::WeakPtrFactory<GpuMessageFilter> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(GpuMessageFilter);
diff --git a/chromium/content/browser/renderer_host/ime_adapter_android.cc b/chromium/content/browser/renderer_host/ime_adapter_android.cc
index dbad05cf8b6..d70d4969d2e 100644
--- a/chromium/content/browser/renderer_host/ime_adapter_android.cc
+++ b/chromium/content/browser/renderer_host/ime_adapter_android.cc
@@ -124,7 +124,7 @@ ImeAdapterAndroid::~ImeAdapterAndroid() {
}
bool ImeAdapterAndroid::SendSyntheticKeyEvent(JNIEnv*,
- jobject,
+ const JavaParamRef<jobject>&,
int type,
long time_ms,
int key_code,
@@ -137,12 +137,17 @@ bool ImeAdapterAndroid::SendSyntheticKeyEvent(JNIEnv*,
return true;
}
-bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject,
- jobject original_key_event,
- int action, int modifiers,
- long time_ms, int key_code,
- int scan_code, bool is_system_key,
- int unicode_char) {
+bool ImeAdapterAndroid::SendKeyEvent(
+ JNIEnv* env,
+ const JavaParamRef<jobject>&,
+ const JavaParamRef<jobject>& original_key_event,
+ int action,
+ int modifiers,
+ long time_ms,
+ int key_code,
+ int scan_code,
+ bool is_system_key,
+ int unicode_char) {
NativeWebKeyboardEvent event = NativeWebKeyboardEventFromKeyEvent(
env, original_key_event, action, modifiers,
time_ms, key_code, scan_code, is_system_key, unicode_char);
@@ -167,9 +172,9 @@ bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject,
}
void ImeAdapterAndroid::SetComposingText(JNIEnv* env,
- jobject obj,
- jobject text,
- jstring text_str,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& text,
+ const JavaParamRef<jstring>& text_str,
int new_cursor_pos) {
RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl();
if (!rwhi)
@@ -201,7 +206,9 @@ void ImeAdapterAndroid::SetComposingText(JNIEnv* env,
rwhi->ImeSetComposition(text16, underlines, new_cursor_pos, new_cursor_pos);
}
-void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text_str) {
+void ImeAdapterAndroid::CommitText(JNIEnv* env,
+ const JavaParamRef<jobject>&,
+ const JavaParamRef<jstring>& text_str) {
RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl();
if (!rwhi)
return;
@@ -210,7 +217,8 @@ void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text_str) {
rwhi->ImeConfirmComposition(text16, gfx::Range::InvalidRange(), false);
}
-void ImeAdapterAndroid::FinishComposingText(JNIEnv* env, jobject) {
+void ImeAdapterAndroid::FinishComposingText(JNIEnv* env,
+ const JavaParamRef<jobject>&) {
RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl();
if (!rwhi)
return;
@@ -219,7 +227,9 @@ void ImeAdapterAndroid::FinishComposingText(JNIEnv* env, jobject) {
true);
}
-void ImeAdapterAndroid::AttachImeAdapter(JNIEnv* env, jobject java_object) {
+void ImeAdapterAndroid::AttachImeAdapter(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& java_object) {
java_ime_adapter_ = JavaObjectWeakGlobalRef(env, java_object);
}
@@ -240,8 +250,11 @@ void ImeAdapterAndroid::FocusedNodeChanged(bool is_editable_node) {
}
}
-void ImeAdapterAndroid::SetEditableSelectionOffsets(JNIEnv*, jobject,
- int start, int end) {
+void ImeAdapterAndroid::SetEditableSelectionOffsets(
+ JNIEnv*,
+ const JavaParamRef<jobject>&,
+ int start,
+ int end) {
RenderFrameHost* rfh = GetFocusedFrame();
if (!rfh)
return;
@@ -250,8 +263,10 @@ void ImeAdapterAndroid::SetEditableSelectionOffsets(JNIEnv*, jobject,
start, end));
}
-void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, jobject,
- int start, int end) {
+void ImeAdapterAndroid::SetComposingRegion(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ int start,
+ int end) {
RenderFrameHost* rfh = GetFocusedFrame();
if (!rfh)
return;
@@ -264,15 +279,18 @@ void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, jobject,
rfh->GetRoutingID(), start, end, underlines));
}
-void ImeAdapterAndroid::DeleteSurroundingText(JNIEnv*, jobject,
- int before, int after) {
+void ImeAdapterAndroid::DeleteSurroundingText(JNIEnv*,
+ const JavaParamRef<jobject>&,
+ int before,
+ int after) {
RenderFrameHostImpl* rfh =
static_cast<RenderFrameHostImpl*>(GetFocusedFrame());
if (rfh)
rfh->ExtendSelectionAndDelete(before, after);
}
-void ImeAdapterAndroid::ResetImeAdapter(JNIEnv* env, jobject) {
+void ImeAdapterAndroid::ResetImeAdapter(JNIEnv* env,
+ const JavaParamRef<jobject>&) {
java_ime_adapter_.reset();
}
@@ -281,7 +299,7 @@ RenderWidgetHostImpl* ImeAdapterAndroid::GetRenderWidgetHostImpl() {
DCHECK(rwhva_);
RenderWidgetHost* rwh = rwhva_->GetRenderWidgetHost();
if (!rwh)
- return NULL;
+ return nullptr;
return RenderWidgetHostImpl::From(rwh);
}
@@ -289,14 +307,14 @@ RenderWidgetHostImpl* ImeAdapterAndroid::GetRenderWidgetHostImpl() {
RenderFrameHost* ImeAdapterAndroid::GetFocusedFrame() {
RenderWidgetHostImpl* rwh = GetRenderWidgetHostImpl();
if (!rwh)
- return NULL;
- if (!rwh->IsRenderView())
- return NULL;
+ return nullptr;
RenderViewHost* rvh = RenderViewHost::From(rwh);
+ if (!rvh)
+ return nullptr;
FrameTreeNode* focused_frame =
rvh->GetDelegate()->GetFrameTree()->GetFocusedFrame();
if (!focused_frame)
- return NULL;
+ return nullptr;
return focused_frame->current_frame_host();
}
@@ -304,9 +322,7 @@ RenderFrameHost* ImeAdapterAndroid::GetFocusedFrame() {
WebContents* ImeAdapterAndroid::GetWebContents() {
RenderWidgetHostImpl* rwh = GetRenderWidgetHostImpl();
if (!rwh)
- return NULL;
- if (!rwh->IsRenderView())
- return NULL;
+ return nullptr;
return WebContents::FromRenderViewHost(RenderViewHost::From(rwh));
}
diff --git a/chromium/content/browser/renderer_host/ime_adapter_android.h b/chromium/content/browser/renderer_host/ime_adapter_android.h
index f6b57fdbfed..0830f27254d 100644
--- a/chromium/content/browser/renderer_host/ime_adapter_android.h
+++ b/chromium/content/browser/renderer_host/ime_adapter_android.h
@@ -30,32 +30,51 @@ class ImeAdapterAndroid {
// Called from java -> native
// The java side is responsible to translate android KeyEvent various enums
// and values into the corresponding blink::WebInputEvent.
- bool SendKeyEvent(JNIEnv* env, jobject,
- jobject original_key_event,
- int action, int meta_state,
- long event_time, int key_code,
- int scan_code, bool is_system_key,
- int unicode_text);
+ bool SendKeyEvent(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>&,
+ const base::android::JavaParamRef<jobject>& original_key_event,
+ int action,
+ int meta_state,
+ long event_time,
+ int key_code,
+ int scan_code,
+ bool is_system_key,
+ int unicode_text);
// |event_type| is a value of WebInputEvent::Type.
bool SendSyntheticKeyEvent(JNIEnv*,
- jobject,
+ const base::android::JavaParamRef<jobject>&,
int event_type,
long timestamp_ms,
int native_key_code,
int modifiers,
int unicode_char);
void SetComposingText(JNIEnv*,
- jobject obj,
- jobject text,
- jstring text_str,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& text,
+ const base::android::JavaParamRef<jstring>& text_str,
int new_cursor_pos);
- void CommitText(JNIEnv*, jobject, jstring text_str);
- void FinishComposingText(JNIEnv* env, jobject);
- void AttachImeAdapter(JNIEnv*, jobject java_object);
- void SetEditableSelectionOffsets(JNIEnv*, jobject, int start, int end);
- void SetComposingRegion(JNIEnv*, jobject, int start, int end);
- void DeleteSurroundingText(JNIEnv*, jobject, int before, int after);
- void ResetImeAdapter(JNIEnv*, jobject);
+ void CommitText(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ const base::android::JavaParamRef<jstring>& text_str);
+ void FinishComposingText(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>&);
+ void AttachImeAdapter(
+ JNIEnv*,
+ const base::android::JavaParamRef<jobject>& java_object);
+ void SetEditableSelectionOffsets(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ int start,
+ int end);
+ void SetComposingRegion(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ int start,
+ int end);
+ void DeleteSurroundingText(JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ int before,
+ int after);
+ void ResetImeAdapter(JNIEnv*, const base::android::JavaParamRef<jobject>&);
// Called from native -> java
void CancelComposition();
diff --git a/chromium/content/browser/renderer_host/input/OWNERS b/chromium/content/browser/renderer_host/input/OWNERS
index f2dd9a38a25..6039fc41d10 100644
--- a/chromium/content/browser/renderer_host/input/OWNERS
+++ b/chromium/content/browser/renderer_host/input/OWNERS
@@ -1,3 +1,2 @@
aelias@chromium.org
-jdduke@chromium.org
tdresser@chromium.org
diff --git a/chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc b/chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
new file mode 100644
index 00000000000..cbf48e8ae7a
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
@@ -0,0 +1,171 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+#include "cc/base/math_util.h"
+#include "content/browser/renderer_host/input/synthetic_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.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_gesture_params.h"
+#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+
+namespace {
+
+const char kCompositedScrollingDataURL[] =
+ "data:text/html;charset=utf-8,"
+ "<!DOCTYPE html>"
+ "<meta name='viewport' content='width=device-width'/>"
+ "<style>"
+ "#scroller {"
+ " width:500px;"
+ " height:500px;"
+ " overflow:scroll;"
+ " transform: rotateX(-30deg);"
+ "}"
+
+ "#content {"
+ " background-color:red;"
+ " width:1000px;"
+ " height:1000px;"
+ "}"
+ "</style>"
+ "<div id='scroller'>"
+ " <div id='content'>"
+ " </div>"
+ "</div>"
+ "<script>"
+ " document.title='ready';"
+ "</script>";
+
+} // namespace
+
+namespace content {
+
+
+class CompositedScrollingBrowserTest : public ContentBrowserTest {
+ public:
+ CompositedScrollingBrowserTest() {}
+ ~CompositedScrollingBrowserTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* cmd) override {
+ cmd->AppendSwitch(switches::kEnablePreferCompositingToLCDText);
+ }
+
+ RenderWidgetHostImpl* GetWidgetHost() {
+ return RenderWidgetHostImpl::From(
+ shell()->web_contents()->GetRenderViewHost()->GetWidget());
+ }
+
+ void OnSyntheticGestureCompleted(SyntheticGesture::Result result) {
+ EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
+ runner_->Quit();
+ }
+
+ protected:
+ void LoadURL() {
+ const GURL data_url(kCompositedScrollingDataURL);
+ NavigateToURL(shell(), data_url);
+
+ RenderWidgetHostImpl* host = GetWidgetHost();
+ scoped_refptr<FrameWatcher> frame_watcher(new FrameWatcher());
+ host->GetProcess()->AddFilter(frame_watcher.get());
+ host->GetView()->SetSize(gfx::Size(400, 400));
+
+ base::string16 ready_title(base::ASCIIToUTF16("ready"));
+ TitleWatcher watcher(shell()->web_contents(), ready_title);
+ ignore_result(watcher.WaitAndGetTitle());
+
+ // We need to wait until at least one frame has been composited
+ // otherwise the injection of the synthetic gestures may get
+ // dropped because of MainThread/Impl thread sync of touch event
+ // regions.
+ frame_watcher->WaitFrames(1);
+ }
+
+ // ContentBrowserTest:
+ int ExecuteScriptAndExtractInt(const std::string& script) {
+ int value = 0;
+ EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
+ shell()->web_contents(),
+ "domAutomationController.send(" + script + ")",
+ &value));
+ return value;
+ }
+
+ int GetScrollTop() {
+ return ExecuteScriptAndExtractInt(
+ "document.getElementById(\"scroller\").scrollTop");
+ }
+
+ // Generate touch events for a synthetic scroll from |point| for |distance|.
+ // Returns the distance scrolled.
+ int DoTouchScroll(const gfx::Point& point, const gfx::Vector2d& distance) {
+ EXPECT_EQ(0, GetScrollTop());
+
+ int scrollHeight = ExecuteScriptAndExtractInt(
+ "document.getElementById('scroller').scrollHeight");
+ EXPECT_EQ(1000, scrollHeight);
+
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.anchor = gfx::PointF(point);
+ params.distances.push_back(-distance);
+
+ runner_ = new MessageLoopRunner();
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ GetWidgetHost()->QueueSyntheticGesture(
+ std::move(gesture),
+ base::Bind(&CompositedScrollingBrowserTest::OnSyntheticGestureCompleted,
+ base::Unretained(this)));
+
+ // Runs until we get the OnSyntheticGestureCompleted callback
+ runner_->Run();
+ runner_ = NULL;
+
+ return GetScrollTop();
+ }
+
+ private:
+ scoped_refptr<MessageLoopRunner> runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositedScrollingBrowserTest);
+};
+
+// Verify transforming a scroller doesn't prevent it from scrolling. See
+// crbug.com/543655 for a case where this was broken.
+// Disabled on MacOS because it doesn't support touch input.
+// Disabled on Android due to flakiness, see https://crbug.com/376668.
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#define MAYBE_Scroll3DTransformedScroller DISABLED_Scroll3DTransformedScroller
+#else
+#define MAYBE_Scroll3DTransformedScroller Scroll3DTransformedScroller
+#endif
+IN_PROC_BROWSER_TEST_F(CompositedScrollingBrowserTest,
+ MAYBE_Scroll3DTransformedScroller) {
+ LoadURL();
+ int scrollDistance =
+ DoTouchScroll(gfx::Point(50, 150), gfx::Vector2d(0, 100));
+ // The scroll distance is increased due to the rotation of the scroller.
+ EXPECT_EQ(std::floor(100 / std::cos(cc::MathUtil::Deg2Rad(30.f))) - 1,
+ scrollDistance);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/gesture_event_queue.cc b/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
index e23d0b278e3..15cda746b21 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -207,7 +207,6 @@ void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result,
// It's possible that the ack for the second event in an in-flight, coalesced
// Gesture{Scroll,Pinch}Update pair is received prior to the first event ack.
- // TODO(jdduke): Unify GSU/GPU pairs into a single event, crbug.com/359115.
size_t event_index = 0;
if (ignore_next_ack_ &&
coalesced_gesture_events_.size() > 1 &&
@@ -248,7 +247,6 @@ void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result,
const GestureEventWithLatencyInfo& first_gesture_event =
coalesced_gesture_events_.front();
- // TODO(jdduke): Unify GSU/GPU pairs into a single event, crbug.com/359115.
// Check for the coupled GesturePinchUpdate before sending either event,
// handling the case where the first GestureScrollUpdate ack is synchronous.
GestureEventWithLatencyInfo second_gesture_event;
diff --git a/chromium/content/browser/renderer_host/input/gesture_event_queue.h b/chromium/content/browser/renderer_host/input/gesture_event_queue.h
index 2a4b4526874..457a9ecb4cf 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue.h
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_GESTURE_EVENT_QUEUE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_GESTURE_EVENT_QUEUE_H_
+#include <stddef.h>
+
#include <deque>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
diff --git a/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
index 7e7a6ead498..44087274c4b 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
@@ -2,9 +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/gesture_event_queue.h"
+
+#include <stddef.h>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -12,7 +15,6 @@
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
@@ -52,7 +54,7 @@ class GestureEventQueueTest : public testing::Test,
const GestureEventWithLatencyInfo& event) override {
++sent_gesture_event_count_;
if (sync_ack_result_) {
- scoped_ptr<InputEventAckState> ack_result = sync_ack_result_.Pass();
+ scoped_ptr<InputEventAckState> ack_result = std::move(sync_ack_result_);
SendInputEventACK(event.event.type, *ack_result);
}
}
@@ -62,7 +64,7 @@ class GestureEventQueueTest : public testing::Test,
++acked_gesture_event_count_;
last_acked_event_ = event.event;
if (sync_followup_event_) {
- auto sync_followup_event = sync_followup_event_.Pass();
+ auto sync_followup_event = std::move(sync_followup_event_);
SimulateGestureEvent(*sync_followup_event);
}
}
@@ -1087,7 +1089,7 @@ TEST_F(GestureEventQueueTest, DebounceDefersFollowingGestureEvents) {
EXPECT_EQ(3U, GestureEventDebouncingQueueSize());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMilliseconds(5));
base::MessageLoop::current()->Run();
diff --git a/chromium/content/browser/renderer_host/input/input_ack_handler.h b/chromium/content/browser/renderer_host/input/input_ack_handler.h
index 14daa35b716..22686816004 100644
--- a/chromium/content/browser/renderer_host/input/input_ack_handler.h
+++ b/chromium/content/browser/renderer_host/input/input_ack_handler.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ACK_HANDLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ACK_HANDLER_H_
-#include "base/basictypes.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/native_web_keyboard_event.h"
diff --git a/chromium/content/browser/renderer_host/input/input_router.h b/chromium/content/browser/renderer_host/input/input_router.h
index 027f9fedfcd..5d64568962c 100644
--- a/chromium/content/browser/renderer_host/input/input_router.h
+++ b/chromium/content/browser/renderer_host/input/input_router.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_H_
-#include "base/basictypes.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -35,8 +34,7 @@ class InputRouter : public IPC::Listener {
virtual void SendWheelEvent(
const MouseWheelEventWithLatencyInfo& wheel_event) = 0;
virtual void SendKeyboardEvent(
- const NativeWebKeyboardEventWithLatencyInfo& key_event,
- bool is_shortcut) = 0;
+ const NativeWebKeyboardEventWithLatencyInfo& key_event) = 0;
virtual void SendGestureEvent(
const GestureEventWithLatencyInfo& gesture_event) = 0;
virtual void SendTouchEvent(
@@ -56,6 +54,10 @@ class InputRouter : public IPC::Listener {
// Whether there are any events pending dispatch to or ack from the renderer.
virtual bool HasPendingEvents() const = 0;
+
+ // A scale factor to scale the coordinate in WebInputEvent from DIP
+ // to viewport.
+ virtual void SetDeviceScaleFactor(float device_scale_factor) = 0;
};
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/input_router_config_helper.cc b/chromium/content/browser/renderer_host/input/input_router_config_helper.cc
index 24a4354a60f..53aaee3f880 100644
--- a/chromium/content/browser/renderer_host/input/input_router_config_helper.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_config_helper.cc
@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/input/input_router_config_helper.h"
#include "base/command_line.h"
+#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "ui/events/gesture_detection/gesture_configuration.h"
#include "ui/events/gesture_detection/gesture_detector.h"
diff --git a/chromium/content/browser/renderer_host/input/input_router_impl.cc b/chromium/content/browser/renderer_host/input/input_router_impl.cc
index b0198962fe2..dcae7142ff7 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.cc
@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/input/input_router_impl.h"
#include <math.h>
+#include <utility>
#include "base/auto_reset.h"
#include "base/command_line.h"
@@ -15,6 +16,7 @@
#include "content/browser/renderer_host/input/input_router_client.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
+#include "content/browser/renderer_host/input/web_input_event_util.h"
#include "content/common/content_constants_internal.h"
#include "content/common/edit_command.h"
#include "content/common/input/input_event_ack_state.h"
@@ -77,7 +79,8 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
flush_requested_(false),
active_renderer_fling_count_(0),
touch_event_queue_(this, config.touch_config),
- gesture_event_queue_(this, this, config.gesture_config) {
+ gesture_event_queue_(this, this, config.gesture_config),
+ device_scale_factor_(1.f) {
DCHECK(sender);
DCHECK(client);
DCHECK(ack_handler);
@@ -94,9 +97,9 @@ bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) {
// Check for types that require an ACK.
case InputMsg_SelectRange::ID:
case InputMsg_MoveRangeSelectionExtent::ID:
- return SendSelectMessage(message.Pass());
+ return SendSelectMessage(std::move(message));
case InputMsg_MoveCaret::ID:
- return SendMoveCaret(message.Pass());
+ return SendMoveCaret(std::move(message));
case InputMsg_HandleInputEvent::ID:
NOTREACHED() << "WebInputEvents should never be sent via SendInput.";
return false;
@@ -152,12 +155,11 @@ void InputRouterImpl::SendWheelEvent(
LOCAL_HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize",
coalesced_mouse_wheel_events_.size());
- FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false);
+ FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency);
}
void InputRouterImpl::SendKeyboardEvent(
- const NativeWebKeyboardEventWithLatencyInfo& key_event,
- bool is_keyboard_shortcut) {
+ const NativeWebKeyboardEventWithLatencyInfo& key_event) {
// Put all WebKeyboardEvent objects in a queue since we can't trust the
// renderer and we need to give something to the HandleKeyboardEvent
// handler.
@@ -167,9 +169,7 @@ void InputRouterImpl::SendKeyboardEvent(
gesture_event_queue_.FlingHasBeenHalted();
// Only forward the non-native portions of our event.
- FilterAndSendWebInputEvent(key_event.event,
- key_event.latency,
- is_keyboard_shortcut);
+ FilterAndSendWebInputEvent(key_event.event, key_event.latency);
}
void InputRouterImpl::SendGestureEvent(
@@ -213,7 +213,7 @@ void InputRouterImpl::SendMouseEventImmediately(
current_mouse_move_ = mouse_event;
}
- FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false);
+ FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency);
}
void InputRouterImpl::SendTouchEventImmediately(
@@ -227,12 +227,12 @@ void InputRouterImpl::SendTouchEventImmediately(
UpdateTouchAckTimeoutEnabled();
}
- FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false);
+ FilterAndSendWebInputEvent(touch_event.event, touch_event.latency);
}
void InputRouterImpl::SendGestureEventImmediately(
const GestureEventWithLatencyInfo& gesture_event) {
- FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
+ FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency);
}
const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const {
@@ -261,6 +261,10 @@ bool InputRouterImpl::HasPendingEvents() const {
active_renderer_fling_count_ > 0;
}
+void InputRouterImpl::SetDeviceScaleFactor(float device_scale_factor) {
+ device_scale_factor_ = device_scale_factor;
+}
+
bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(InputRouterImpl, message)
@@ -325,7 +329,7 @@ bool InputRouterImpl::SendSelectMessage(
bool InputRouterImpl::SendMoveCaret(scoped_ptr<IPC::Message> message) {
DCHECK(message->type() == InputMsg_MoveCaret::ID);
if (move_caret_pending_) {
- next_move_caret_ = message.Pass();
+ next_move_caret_ = std::move(message);
return true;
}
@@ -339,8 +343,7 @@ bool InputRouterImpl::Send(IPC::Message* message) {
void InputRouterImpl::FilterAndSendWebInputEvent(
const WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut) {
+ const ui::LatencyInfo& latency_info) {
TRACE_EVENT1("input",
"InputRouterImpl::FilterAndSendWebInputEvent",
"type",
@@ -354,18 +357,17 @@ void InputRouterImpl::FilterAndSendWebInputEvent(
// Any input event cancels a pending mouse move event.
next_mouse_move_.reset();
- OfferToHandlers(input_event, latency_info, is_keyboard_shortcut);
+ OfferToHandlers(input_event, latency_info);
}
void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut) {
+ const ui::LatencyInfo& latency_info) {
output_stream_validator_.Validate(input_event);
if (OfferToClient(input_event, latency_info))
return;
- OfferToRenderer(input_event, latency_info, is_keyboard_shortcut);
+ OfferToRenderer(input_event, latency_info);
// Touch events should always indicate in the event whether they are
// cancelable (respect ACK disposition) or not except touchmove.
@@ -416,14 +418,18 @@ bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event,
}
bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut) {
- if (Send(new InputMsg_HandleInputEvent(
- routing_id(), &input_event, latency_info, is_keyboard_shortcut))) {
+ const ui::LatencyInfo& latency_info) {
+ scoped_ptr<blink::WebInputEvent> event_in_viewport =
+ ConvertWebInputEventToViewport(input_event, device_scale_factor_);
+ const WebInputEvent* event_to_send =
+ event_in_viewport ? event_in_viewport.get() : &input_event;
+
+ if (Send(new InputMsg_HandleInputEvent(routing_id(), event_to_send,
+ latency_info))) {
// Ack messages for ignored ack event types should never be sent by the
// renderer. Consequently, such event types should not affect event time
// or in-flight event count metrics.
- if (WebInputEventTraits::WillReceiveAckFromRenderer(input_event)) {
+ if (WebInputEventTraits::WillReceiveAckFromRenderer(*event_to_send)) {
input_event_start_time_ = TimeTicks::Now();
client_->IncrementInFlightEventCount();
}
@@ -455,7 +461,7 @@ void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) {
void InputRouterImpl::OnMsgMoveCaretAck() {
move_caret_pending_ = false;
if (next_move_caret_)
- SendMoveCaret(next_move_caret_.Pass());
+ SendMoveCaret(std::move(next_move_caret_));
}
void InputRouterImpl::OnSelectMessageAck() {
@@ -465,7 +471,7 @@ void InputRouterImpl::OnSelectMessageAck() {
make_scoped_ptr(pending_select_messages_.front());
pending_select_messages_.pop_front();
- SendSelectMessage(next_message.Pass());
+ SendSelectMessage(std::move(next_message));
}
}
@@ -477,8 +483,6 @@ void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
// modifiers or that all its touch-action modifiers are auto. Resetting the
// touch-action here allows forwarding of subsequent gestures even if the
// underlying touches never reach the router.
- // TODO(jdduke): Reset touch-action only at the end of a touch sequence to
- // prevent potentially strange mid-sequence behavior, crbug.com/375940.
if (!has_handlers)
touch_action_filter_.ResetTouchAction();
@@ -512,7 +516,7 @@ void InputRouterImpl::OnDidStopFlinging() {
void InputRouterImpl::ProcessInputEventAck(WebInputEvent::Type event_type,
InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
- uint32 unique_touch_event_id,
+ uint32_t unique_touch_event_id,
AckSource ack_source) {
TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck",
"type", WebInputEventTraits::GetName(event_type),
@@ -582,8 +586,8 @@ void InputRouterImpl::ProcessMouseAck(blink::WebInputEvent::Type type,
if (next_mouse_move_) {
DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove);
- scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move
- = next_mouse_move_.Pass();
+ scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move =
+ std::move(next_mouse_move_);
SendMouseEvent(*next_mouse_move);
}
}
@@ -627,7 +631,7 @@ void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type,
void InputRouterImpl::ProcessTouchAck(InputEventAckState ack_result,
const ui::LatencyInfo& latency,
- uint32 unique_touch_event_id) {
+ uint32_t unique_touch_event_id) {
// |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
touch_event_queue_.ProcessTouchAck(ack_result, latency,
unique_touch_event_id);
diff --git a/chromium/content/browser/renderer_host/input/input_router_impl.h b/chromium/content/browser/renderer_host/input/input_router_impl.h
index f42adfade71..36f62b29256 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.h
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
+#include <stdint.h>
+
#include <queue>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
@@ -59,8 +61,8 @@ class CONTENT_EXPORT InputRouterImpl
void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override;
void SendWheelEvent(
const MouseWheelEventWithLatencyInfo& wheel_event) override;
- void SendKeyboardEvent(const NativeWebKeyboardEventWithLatencyInfo& key_event,
- bool is_keyboard_shortcut) override;
+ void SendKeyboardEvent(
+ const NativeWebKeyboardEventWithLatencyInfo& key_event) override;
void SendGestureEvent(
const GestureEventWithLatencyInfo& gesture_event) override;
void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override;
@@ -68,6 +70,7 @@ class CONTENT_EXPORT InputRouterImpl
void NotifySiteIsMobileOptimized(bool is_mobile_optimized) override;
void RequestNotificationWhenFlushed() override;
bool HasPendingEvents() const override;
+ void SetDeviceScaleFactor(float device_scale_factor) override;
// IPC::Listener
bool OnMessageReceived(const IPC::Message& message) override;
@@ -97,19 +100,13 @@ private:
// Filters and forwards |input_event| to the appropriate handler.
void FilterAndSendWebInputEvent(const blink::WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut);
+ const ui::LatencyInfo& latency_info);
// Utility routine for filtering and forwarding |input_event| to the
// appropriate handler. |input_event| will be offered to the overscroll
// controller, client and renderer, in that order.
void OfferToHandlers(const blink::WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut);
-
- // Returns true if |input_event| was consumed by the overscroll controller.
- bool OfferToOverscrollController(const blink::WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info);
+ const ui::LatencyInfo& latency_info);
// Returns true if |input_event| was consumed by the client.
bool OfferToClient(const blink::WebInputEvent& input_event,
@@ -118,8 +115,7 @@ private:
// Returns true if |input_event| was successfully sent to the renderer
// as an async IPC Message.
bool OfferToRenderer(const blink::WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut);
+ const ui::LatencyInfo& latency_info);
// IPC message handlers
void OnInputEventAck(const InputEventAck& ack);
@@ -143,7 +139,7 @@ private:
void ProcessInputEventAck(blink::WebInputEvent::Type event_type,
InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
- uint32 unique_touch_event_id,
+ uint32_t unique_touch_event_id,
AckSource ack_source);
// Dispatches the ack'ed event to |ack_handler_|.
@@ -171,7 +167,7 @@ private:
// dispatch of queued touch events, or the creation of gesture events.
void ProcessTouchAck(InputEventAckState ack_result,
const ui::LatencyInfo& latency,
- uint32 unique_touch_event_id);
+ uint32_t unique_touch_event_id);
// Called when a touch timeout-affecting bit has changed, in turn toggling the
// touch ack timeout feature of the |touch_event_queue_| as appropriate. Input
@@ -258,6 +254,8 @@ private:
InputEventStreamValidator input_stream_validator_;
InputEventStreamValidator output_stream_validator_;
+ float device_scale_factor_;
+
DISALLOW_COPY_AND_ASSIGN(InputRouterImpl);
};
diff --git a/chromium/content/browser/renderer_host/input/input_router_impl_perftest.cc b/chromium/content/browser/renderer_host/input/input_router_impl_perftest.cc
index 48def2af907..edf67f109a6 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl_perftest.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_impl_perftest.cc
@@ -2,7 +2,10 @@
// 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 <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/input/input_ack_handler.h"
#include "content/browser/renderer_host/input/input_router_client.h"
@@ -109,7 +112,6 @@ class NullIPCSender : public IPC::Sender {
size_t sent_count_;
};
-// TODO(jdduke): Use synthetic gesture pipeline, crbug.com/344598.
typedef std::vector<WebGestureEvent> Gestures;
Gestures BuildScrollSequence(size_t steps,
const gfx::Vector2dF& origin,
@@ -173,7 +175,7 @@ Touches BuildTouchSequence(size_t steps,
class InputEventTimer {
public:
- InputEventTimer(const char* test_name, int64 event_count)
+ InputEventTimer(const char* test_name, int64_t event_count)
: test_name_(test_name),
event_count_(event_count),
start_(base::TimeTicks::Now()) {}
@@ -191,7 +193,7 @@ class InputEventTimer {
private:
const char* test_name_;
- int64 event_count_;
+ int64_t event_count_;
base::TimeTicks start_;
DISALLOW_COPY_AND_ASSIGN(InputEventTimer);
};
@@ -257,7 +259,7 @@ class InputRouterImplPerfTest : public testing::Test {
size_t AckCount() const { return ack_handler_->ack_count(); }
- int64 NextLatencyID() { return ++last_input_id_; }
+ int64_t NextLatencyID() { return ++last_input_id_; }
ui::LatencyInfo CreateLatencyInfo() {
ui::LatencyInfo latency;
@@ -268,7 +270,6 @@ class InputRouterImplPerfTest : public testing::Test {
return latency;
}
- // TODO(jdduke): Use synthetic gesture pipeline, crbug.com/344598.
template <typename EventType>
void SimulateEventSequence(const char* test_name,
const std::vector<EventType>& events,
@@ -331,7 +332,7 @@ class InputRouterImplPerfTest : public testing::Test {
}
private:
- int64 last_input_id_;
+ int64_t last_input_id_;
scoped_ptr<NullIPCSender> sender_;
scoped_ptr<NullInputRouterClient> client_;
scoped_ptr<NullInputAckHandler> ack_handler_;
diff --git a/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc b/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc
index 034eb5ba27b..26b69e97c51 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -3,14 +3,17 @@
// found in the LICENSE file.
#include <math.h>
+#include <stddef.h>
+#include <stdint.h>
-#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/input_router_client.h"
#include "content/browser/renderer_host/input/input_router_impl.h"
@@ -80,12 +83,6 @@ WebInputEvent& GetEventWithType(WebInputEvent::Type type) {
return *event;
}
-bool GetIsShortcutFromHandleInputEventMessage(const IPC::Message* msg) {
- InputMsg_HandleInputEvent::Schema::Param param;
- InputMsg_HandleInputEvent::Read(msg, &param);
- return base::get<2>(param);
-}
-
template<typename MSG_T, typename ARG_T1>
void ExpectIPCMessageWithArg1(const IPC::Message* msg, const ARG_T1& arg1) {
ASSERT_EQ(MSG_T::ID, msg->type());
@@ -182,17 +179,23 @@ class InputRouterImplTest : public testing::Test {
input_router()->NotifySiteIsMobileOptimized(false);
}
- void SimulateKeyboardEvent(WebInputEvent::Type type, bool is_shortcut) {
+ void SimulateKeyboardEvent(WebInputEvent::Type type) {
WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
NativeWebKeyboardEvent native_event;
memcpy(&native_event, &event, sizeof(event));
NativeWebKeyboardEventWithLatencyInfo key_event(native_event);
- input_router_->SendKeyboardEvent(key_event, is_shortcut);
+ input_router_->SendKeyboardEvent(key_event);
}
- void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
+ void SimulateWheelEvent(float x,
+ float y,
+ float dX,
+ float dY,
+ int modifiers,
+ bool precise) {
input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise)));
+ SyntheticWebMouseWheelEventBuilder::Build(x, y, dX, dY, modifiers,
+ precise)));
}
void SimulateMouseEvent(WebInputEvent::Type type, int x, int y) {
@@ -252,8 +255,8 @@ class InputRouterImplTest : public testing::Test {
touch_event_.SetTimestamp(timestamp);
}
- uint32 SendTouchEvent() {
- uint32 touch_event_id = touch_event_.uniqueTouchEventId;
+ uint32_t SendTouchEvent() {
+ uint32_t touch_event_id = touch_event_.uniqueTouchEventId;
input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_));
touch_event_.ResetPoints();
return touch_event_id;
@@ -284,7 +287,7 @@ class InputRouterImplTest : public testing::Test {
void SendTouchEventACK(blink::WebInputEvent::Type type,
InputEventAckState ack_result,
- uint32 touch_event_id) {
+ uint32_t touch_event_id) {
DCHECK(WebInputEvent::isTouchEventType(type));
InputEventAck ack(type, ack_result, touch_event_id);
input_router_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
@@ -332,7 +335,7 @@ class InputRouterImplTest : public testing::Test {
static void RunTasksAndWait(base::TimeDelta delay) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(), delay);
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), delay);
base::MessageLoop::current()->Run();
}
@@ -617,7 +620,7 @@ TEST_F(InputRouterImplTest, HandledInputEvent) {
client_->set_filter_state(INPUT_EVENT_ACK_STATE_CONSUMED);
// Simulate a keyboard event.
- SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
// Make sure no input event is sent to the renderer.
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
@@ -634,7 +637,7 @@ TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
client_->set_filter_state(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
// Simulate a keyboard event that has no consumer.
- SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
// Make sure no input event is sent to the renderer.
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
@@ -643,27 +646,15 @@ TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
// Simulate a keyboard event that should be dropped.
client_->set_filter_state(INPUT_EVENT_ACK_STATE_UNKNOWN);
- SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
// Make sure no input event is sent to the renderer, and no ack is sent.
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
}
-TEST_F(InputRouterImplTest, ShortcutKeyboardEvent) {
- SimulateKeyboardEvent(WebInputEvent::RawKeyDown, true);
- EXPECT_TRUE(GetIsShortcutFromHandleInputEventMessage(
- process_->sink().GetMessageAt(0)));
-
- process_->sink().ClearMessages();
-
- SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
- EXPECT_FALSE(GetIsShortcutFromHandleInputEventMessage(
- process_->sink().GetMessageAt(0)));
-}
-
TEST_F(InputRouterImplTest, NoncorrespondingKeyEvents) {
- SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
SendInputEventACK(WebInputEvent::KeyUp,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
@@ -674,7 +665,7 @@ TEST_F(InputRouterImplTest, NoncorrespondingKeyEvents) {
TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) {
// Simulate a keyboard event.
- SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
ASSERT_TRUE(input_router_->GetLastKeyboardEvent());
EXPECT_EQ(WebInputEvent::RawKeyDown,
input_router_->GetLastKeyboardEvent()->type);
@@ -702,11 +693,11 @@ TEST_F(InputRouterImplTest, IgnoreKeyEventsWeDidntSend) {
TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
// Simulate wheel events.
- SimulateWheelEvent(0, -5, 0, false); // sent directly
- SimulateWheelEvent(0, -10, 0, false); // enqueued
- SimulateWheelEvent(8, -6, 0, false); // coalesced into previous event
- SimulateWheelEvent(9, -7, 1, false); // enqueued, different modifiers
- SimulateWheelEvent(0, -10, 0, false); // enqueued, different modifiers
+ SimulateWheelEvent(0, 0, 0, -5, 0, false); // sent directly
+ SimulateWheelEvent(0, 0, 0, -10, 0, false); // enqueued
+ SimulateWheelEvent(0, 0, 8, -6, 0, false); // coalesced into previous event
+ SimulateWheelEvent(0, 0, 9, -7, 1, false); // enqueued, different modifiers
+ SimulateWheelEvent(0, 0, 0, -10, 0, false); // enqueued, different modifiers
// Explicitly verify that PhaseEnd isn't coalesced to avoid bugs like
// https://crbug.com/154740.
SimulateWheelEventWithPhase(WebMouseWheelEvent::PhaseEnded); // enqueued
@@ -794,14 +785,14 @@ TEST_F(InputRouterImplTest, TouchEventQueue) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
- uint32 touch_press_event_id = SendTouchEvent();
+ uint32_t touch_press_event_id = SendTouchEvent();
EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_FALSE(TouchEventQueueEmpty());
// The second touch should not be sent since one is already in queue.
MoveTouchPoint(0, 5, 5);
- uint32 touch_move_event_id = SendTouchEvent();
+ uint32_t touch_move_event_id = SendTouchEvent();
EXPECT_FALSE(client_->GetAndResetFilterEventCalled());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_FALSE(TouchEventQueueEmpty());
@@ -834,7 +825,7 @@ TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
// Send a touch-press event.
PressTouchPoint(1, 1);
- uint32 touch_press_event_id = SendTouchEvent();
+ uint32_t touch_press_event_id = SendTouchEvent();
MoveTouchPoint(0, 2, 2);
MoveTouchPoint(0, 3, 3);
EXPECT_FALSE(TouchEventQueueEmpty());
@@ -874,40 +865,40 @@ TEST_F(InputRouterImplTest, AckedTouchEventState) {
// Press the first finger.
PressTouchPoint(1, 1);
SetTouchTimestamp(timestamp);
- uint32 touch_press_event_id1 = SendTouchEvent();
+ uint32_t touch_press_event_id1 = SendTouchEvent();
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
- gfx::Point(1, 1), 0, timestamp));
+ expected_events.push_back(
+ new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(1, 1), 0, timestamp));
// Move the finger.
timestamp += base::TimeDelta::FromSeconds(10);
MoveTouchPoint(0, 500, 500);
SetTouchTimestamp(timestamp);
- uint32 touch_move_event_id1 = SendTouchEvent();
+ uint32_t touch_move_event_id1 = SendTouchEvent();
EXPECT_FALSE(TouchEventQueueEmpty());
- expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
- gfx::Point(500, 500), 0, timestamp));
+ expected_events.push_back(new ui::TouchEvent(
+ ui::ET_TOUCH_MOVED, gfx::Point(500, 500), 0, timestamp));
// Now press a second finger.
timestamp += base::TimeDelta::FromSeconds(10);
PressTouchPoint(2, 2);
SetTouchTimestamp(timestamp);
- uint32 touch_press_event_id2 = SendTouchEvent();
+ uint32_t touch_press_event_id2 = SendTouchEvent();
EXPECT_FALSE(TouchEventQueueEmpty());
- expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
- gfx::Point(2, 2), 1, timestamp));
+ expected_events.push_back(
+ new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(2, 2), 1, timestamp));
// Move both fingers.
timestamp += base::TimeDelta::FromSeconds(10);
MoveTouchPoint(0, 10, 10);
MoveTouchPoint(1, 20, 20);
SetTouchTimestamp(timestamp);
- uint32 touch_move_event_id2 = SendTouchEvent();
+ uint32_t touch_move_event_id2 = SendTouchEvent();
EXPECT_FALSE(TouchEventQueueEmpty());
- expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
- gfx::Point(10, 10), 0, timestamp));
- expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
- gfx::Point(20, 20), 1, timestamp));
+ expected_events.push_back(
+ new ui::TouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(10, 10), 0, timestamp));
+ expected_events.push_back(
+ new ui::TouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 1, timestamp));
// Receive the ACKs and make sure the generated events from the acked events
// are correct.
@@ -916,10 +907,8 @@ TEST_F(InputRouterImplTest, AckedTouchEventState) {
WebInputEvent::TouchStart,
WebInputEvent::TouchMove };
- uint32 touch_event_ids[] = {touch_press_event_id1,
- touch_move_event_id1,
- touch_press_event_id2,
- touch_move_event_id2};
+ uint32_t touch_event_ids[] = {touch_press_event_id1, touch_move_event_id1,
+ touch_press_event_id2, touch_move_event_id2};
TouchEventCoordinateSystem coordinate_system = LOCAL_COORDINATES;
#if !defined(OS_WIN)
@@ -948,8 +937,8 @@ TEST_F(InputRouterImplTest, AckedTouchEventState) {
TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
// Simulate wheel events.
- SimulateWheelEvent(0, -5, 0, false); // sent directly
- SimulateWheelEvent(0, -10, 0, false); // enqueued
+ SimulateWheelEvent(0, 0, 0, -5, 0, false); // sent directly
+ SimulateWheelEvent(0, 0, 0, -10, 0, false); // enqueued
// Check that only the first event was sent.
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
@@ -986,7 +975,7 @@ TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
// Precede the TouchCancel with an appropriate TouchStart;
PressTouchPoint(1, 1);
- uint32 touch_press_event_id = SendTouchEvent();
+ uint32_t touch_press_event_id = SendTouchEvent();
SendTouchEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_press_event_id);
ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
@@ -995,7 +984,7 @@ TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
// The TouchCancel ack is always ignored.
CancelTouchPoint(0);
- uint32 touch_cancel_event_id = SendTouchEvent();
+ uint32_t touch_cancel_event_id = SendTouchEvent();
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
@@ -1083,7 +1072,7 @@ TEST_F(InputRouterImplTest, MouseTypesIgnoringAck) {
if (expected_in_flight_event_count) {
SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
- uint32 expected_ack_count = type == WebInputEvent::MouseMove ? 1 : 0;
+ uint32_t expected_ack_count = type == WebInputEvent::MouseMove ? 1 : 0;
EXPECT_EQ(expected_ack_count, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}
@@ -1236,7 +1225,7 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
// Verify that the touch ack timeout fires upon the delayed ack.
PressTouchPoint(1, 1);
- uint32 touch_press_event_id1 = SendTouchEvent();
+ uint32_t touch_press_event_id1 = SendTouchEvent();
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
RunTasksAndWait(base::TimeDelta::FromMilliseconds(kDesktopTimeoutMs + 1));
@@ -1269,22 +1258,22 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
// TOUCH_ACTION_NONE (and no other touch-action) should disable the timeout.
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
- uint32 touch_press_event_id2 = SendTouchEvent();
+ uint32_t touch_press_event_id2 = SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_PAN_Y);
EXPECT_TRUE(TouchEventTimeoutEnabled());
ReleaseTouchPoint(0);
- uint32 touch_release_event_id2 = SendTouchEvent();
+ uint32_t touch_release_event_id2 = SendTouchEvent();
SendTouchEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_press_event_id2);
SendTouchEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_release_event_id2);
PressTouchPoint(1, 1);
- uint32 touch_press_event_id3 = SendTouchEvent();
+ uint32_t touch_press_event_id3 = SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
EXPECT_FALSE(TouchEventTimeoutEnabled());
ReleaseTouchPoint(0);
- uint32 touch_release_event_id3 = SendTouchEvent();
+ uint32_t touch_release_event_id3 = SendTouchEvent();
SendTouchEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_press_event_id3);
SendTouchEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED,
@@ -1309,7 +1298,7 @@ TEST_F(InputRouterImplTest,
// Start a touch sequence.
PressTouchPoint(1, 1);
- uint32 touch_press_event_id = SendTouchEvent();
+ uint32_t touch_press_event_id = SendTouchEvent();
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
// TOUCH_ACTION_NONE should disable the timeout.
@@ -1320,7 +1309,7 @@ TEST_F(InputRouterImplTest,
EXPECT_FALSE(TouchEventTimeoutEnabled());
MoveTouchPoint(0, 1, 2);
- uint32 touch_move_event_id = SendTouchEvent();
+ uint32_t touch_move_event_id = SendTouchEvent();
EXPECT_FALSE(TouchEventTimeoutEnabled());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
@@ -1334,7 +1323,7 @@ TEST_F(InputRouterImplTest,
// End the touch sequence.
ReleaseTouchPoint(0);
- uint32 touch_release_event_id = SendTouchEvent();
+ uint32_t touch_release_event_id = SendTouchEvent();
SendTouchEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_release_event_id);
EXPECT_FALSE(TouchEventTimeoutEnabled());
@@ -1360,20 +1349,20 @@ TEST_F(InputRouterImplTest, TouchActionResetBeforeEventReachesRenderer) {
// Sequence 1.
PressTouchPoint(1, 1);
- uint32 touch_press_event_id1 = SendTouchEvent();
+ uint32_t touch_press_event_id1 = SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
MoveTouchPoint(0, 50, 50);
- uint32 touch_move_event_id1 = SendTouchEvent();
+ uint32_t touch_move_event_id1 = SendTouchEvent();
ReleaseTouchPoint(0);
- uint32 touch_release_event_id1 = SendTouchEvent();
+ uint32_t touch_release_event_id1 = SendTouchEvent();
// Sequence 2.
PressTouchPoint(1, 1);
- uint32 touch_press_event_id2 = SendTouchEvent();
+ uint32_t touch_press_event_id2 = SendTouchEvent();
MoveTouchPoint(0, 50, 50);
- uint32 touch_move_event_id2 = SendTouchEvent();
+ uint32_t touch_move_event_id2 = SendTouchEvent();
ReleaseTouchPoint(0);
- uint32 touch_release_event_id2 = SendTouchEvent();
+ uint32_t touch_release_event_id2 = SendTouchEvent();
SendTouchEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_press_event_id1);
@@ -1418,9 +1407,9 @@ TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHasNoConsumer) {
// Sequence 1.
PressTouchPoint(1, 1);
- uint32 touch_press_event_id1 = SendTouchEvent();
+ uint32_t touch_press_event_id1 = SendTouchEvent();
MoveTouchPoint(0, 50, 50);
- uint32 touch_move_event_id1 = SendTouchEvent();
+ uint32_t touch_move_event_id1 = SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
SendTouchEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_press_event_id1);
@@ -1428,11 +1417,11 @@ TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHasNoConsumer) {
touch_move_event_id1);
ReleaseTouchPoint(0);
- uint32 touch_release_event_id1 = SendTouchEvent();
+ uint32_t touch_release_event_id1 = SendTouchEvent();
// Sequence 2
PressTouchPoint(1, 1);
- uint32 touch_press_event_id2 = SendTouchEvent();
+ uint32_t touch_press_event_id2 = SendTouchEvent();
MoveTouchPoint(0, 50, 50);
SendTouchEvent();
ReleaseTouchPoint(0);
@@ -1470,12 +1459,12 @@ TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHandlerRemoved) {
// Touch sequence with touch handler.
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
- uint32 touch_press_event_id = SendTouchEvent();
+ uint32_t touch_press_event_id = SendTouchEvent();
MoveTouchPoint(0, 50, 50);
- uint32 touch_move_event_id = SendTouchEvent();
+ uint32_t touch_move_event_id = SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
ReleaseTouchPoint(0);
- uint32 touch_release_event_id = SendTouchEvent();
+ uint32_t touch_release_event_id = SendTouchEvent();
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
// Ensure we have touch-action:none, suppressing scroll events.
@@ -1516,17 +1505,17 @@ TEST_F(InputRouterImplTest, DoubleTapGestureDependsOnFirstTap) {
// Sequence 1.
PressTouchPoint(1, 1);
- uint32 touch_press_event_id1 = SendTouchEvent();
+ uint32_t touch_press_event_id1 = SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
SendTouchEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_press_event_id1);
ReleaseTouchPoint(0);
- uint32 touch_release_event_id = SendTouchEvent();
+ uint32_t touch_release_event_id = SendTouchEvent();
// Sequence 2
PressTouchPoint(1, 1);
- uint32 touch_press_event_id2 = SendTouchEvent();
+ uint32_t touch_press_event_id2 = SendTouchEvent();
// First tap.
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
@@ -1590,7 +1579,7 @@ TEST_F(InputRouterImplTest, InputFlush) {
// Queue a TouchStart.
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
- uint32 touch_press_event_id = SendTouchEvent();
+ uint32_t touch_press_event_id = SendTouchEvent();
EXPECT_TRUE(HasPendingEvents());
// DidFlush should be called only after the event is ack'ed.
@@ -1603,7 +1592,7 @@ TEST_F(InputRouterImplTest, InputFlush) {
// Ensure different types of enqueued events will prevent the DidFlush call
// until all such events have been fully dispatched.
MoveTouchPoint(0, 50, 50);
- uint32 touch_move_event_id = SendTouchEvent();
+ uint32_t touch_move_event_id = SendTouchEvent();
ASSERT_TRUE(HasPendingEvents());
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
blink::WebGestureDeviceTouchscreen);
@@ -1820,7 +1809,7 @@ TEST_F(InputRouterImplTest, OverscrollDispatch) {
wheel_overscroll.latest_overscroll_delta = gfx::Vector2dF(3, 0);
wheel_overscroll.current_fling_velocity = gfx::Vector2dF(1, 0);
- SimulateWheelEvent(3, 0, 0, false);
+ SimulateWheelEvent(0, 0, 3, 0, 0, false);
InputEventAck ack(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ack.overscroll.reset(new DidOverscrollParams(wheel_overscroll));
@@ -1835,4 +1824,428 @@ TEST_F(InputRouterImplTest, OverscrollDispatch) {
client_overscroll.current_fling_velocity);
}
+namespace {
+
+class InputRouterImplScaleEventTest : public InputRouterImplTest {
+ public:
+ InputRouterImplScaleEventTest() {}
+
+ void SetUp() override {
+ InputRouterImplTest::SetUp();
+ input_router_->SetDeviceScaleFactor(2.f);
+ }
+
+ template <typename T>
+ const T* GetSentWebInputEvent() const {
+ EXPECT_EQ(1u, process_->sink().message_count());
+
+ InputMsg_HandleInputEvent::Schema::Param param;
+ InputMsg_HandleInputEvent::Read(process_->sink().GetMessageAt(0), &param);
+ return static_cast<const T*>(base::get<0>(param));
+ }
+
+ template <typename T>
+ const T* GetFilterWebInputEvent() const {
+ return static_cast<const T*>(client_->last_filter_event());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleEventTest);
+};
+
+class InputRouterImplScaleMouseEventTest
+ : public InputRouterImplScaleEventTest {
+ public:
+ InputRouterImplScaleMouseEventTest() {}
+
+ void RunMouseEventTest(const std::string& name, WebInputEvent::Type type) {
+ SCOPED_TRACE(name);
+ SimulateMouseEvent(type, 10, 10);
+ const WebMouseEvent* sent_event = GetSentWebInputEvent<WebMouseEvent>();
+ EXPECT_EQ(20, sent_event->x);
+ EXPECT_EQ(20, sent_event->y);
+
+ const WebMouseEvent* filter_event = GetFilterWebInputEvent<WebMouseEvent>();
+ EXPECT_EQ(10, filter_event->x);
+ EXPECT_EQ(10, filter_event->y);
+
+ process_->sink().ClearMessages();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleMouseEventTest);
+};
+
+} // namespace
+
+TEST_F(InputRouterImplScaleMouseEventTest, ScaleMouseEventTest) {
+ RunMouseEventTest("Enter", WebInputEvent::MouseEnter);
+ RunMouseEventTest("Down", WebInputEvent::MouseDown);
+ RunMouseEventTest("Move", WebInputEvent::MouseMove);
+ RunMouseEventTest("Up", WebInputEvent::MouseUp);
+}
+
+TEST_F(InputRouterImplScaleEventTest, ScaleMouseWheelEventTest) {
+ ASSERT_EQ(0u, process_->sink().message_count());
+ SimulateWheelEvent(5, 5, 10, 10, 0, false);
+ ASSERT_EQ(1u, process_->sink().message_count());
+
+ const WebMouseWheelEvent* sent_event =
+ GetSentWebInputEvent<WebMouseWheelEvent>();
+ EXPECT_EQ(10, sent_event->x);
+ EXPECT_EQ(10, sent_event->y);
+ EXPECT_EQ(20, sent_event->deltaX);
+ EXPECT_EQ(20, sent_event->deltaY);
+ EXPECT_EQ(2, sent_event->wheelTicksX);
+ EXPECT_EQ(2, sent_event->wheelTicksY);
+
+ const WebMouseWheelEvent* filter_event =
+ GetFilterWebInputEvent<WebMouseWheelEvent>();
+ EXPECT_EQ(5, filter_event->x);
+ EXPECT_EQ(5, filter_event->y);
+ EXPECT_EQ(10, filter_event->deltaX);
+ EXPECT_EQ(10, filter_event->deltaY);
+ EXPECT_EQ(1, filter_event->wheelTicksX);
+ EXPECT_EQ(1, filter_event->wheelTicksY);
+
+ EXPECT_EQ(sent_event->accelerationRatioX, filter_event->accelerationRatioX);
+ EXPECT_EQ(sent_event->accelerationRatioY, filter_event->accelerationRatioY);
+}
+
+namespace {
+
+class InputRouterImplScaleTouchEventTest
+ : public InputRouterImplScaleEventTest {
+ public:
+ InputRouterImplScaleTouchEventTest() {}
+
+ // Test tests if two finger touch event at (10, 20) and (100, 200) are
+ // properly scaled. The touch event must be generated ans flushed into
+ // the message sink prior to this method.
+ void RunTouchEventTest(const std::string& name, WebTouchPoint::State state) {
+ SCOPED_TRACE(name);
+ ASSERT_EQ(1u, process_->sink().message_count());
+ const WebTouchEvent* sent_event = GetSentWebInputEvent<WebTouchEvent>();
+ ASSERT_EQ(2u, sent_event->touchesLength);
+ EXPECT_EQ(state, sent_event->touches[0].state);
+ EXPECT_EQ(20, sent_event->touches[0].position.x);
+ EXPECT_EQ(40, sent_event->touches[0].position.y);
+ EXPECT_EQ(10, sent_event->touches[0].screenPosition.x);
+ EXPECT_EQ(20, sent_event->touches[0].screenPosition.y);
+ EXPECT_EQ(2, sent_event->touches[0].radiusX);
+ EXPECT_EQ(2, sent_event->touches[0].radiusY);
+
+ EXPECT_EQ(200, sent_event->touches[1].position.x);
+ EXPECT_EQ(400, sent_event->touches[1].position.y);
+ EXPECT_EQ(100, sent_event->touches[1].screenPosition.x);
+ EXPECT_EQ(200, sent_event->touches[1].screenPosition.y);
+ EXPECT_EQ(2, sent_event->touches[1].radiusX);
+ EXPECT_EQ(2, sent_event->touches[1].radiusY);
+
+ const WebTouchEvent* filter_event = GetFilterWebInputEvent<WebTouchEvent>();
+ ASSERT_EQ(2u, filter_event->touchesLength);
+ EXPECT_EQ(10, filter_event->touches[0].position.x);
+ EXPECT_EQ(20, filter_event->touches[0].position.y);
+ EXPECT_EQ(10, filter_event->touches[0].screenPosition.x);
+ EXPECT_EQ(20, filter_event->touches[0].screenPosition.y);
+ EXPECT_EQ(1, filter_event->touches[0].radiusX);
+ EXPECT_EQ(1, filter_event->touches[0].radiusY);
+
+ EXPECT_EQ(100, filter_event->touches[1].position.x);
+ EXPECT_EQ(200, filter_event->touches[1].position.y);
+ EXPECT_EQ(100, filter_event->touches[1].screenPosition.x);
+ EXPECT_EQ(200, filter_event->touches[1].screenPosition.y);
+ EXPECT_EQ(1, filter_event->touches[1].radiusX);
+ EXPECT_EQ(1, filter_event->touches[1].radiusY);
+ }
+
+ void FlushTouchEvent(WebInputEvent::Type type) {
+ uint32_t touch_event_id = SendTouchEvent();
+ SendTouchEventACK(type, INPUT_EVENT_ACK_STATE_CONSUMED, touch_event_id);
+ ASSERT_TRUE(TouchEventQueueEmpty());
+ ASSERT_NE(0u, process_->sink().message_count());
+ }
+
+ void ReleaseTouchPointAndAck(int index) {
+ ReleaseTouchPoint(index);
+ int release_event_id = SendTouchEvent();
+ SendTouchEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED,
+ release_event_id);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleTouchEventTest);
+};
+
+} // namespace
+
+TEST_F(InputRouterImplScaleTouchEventTest, ScaleTouchEventTest) {
+ // Press
+ PressTouchPoint(10, 20);
+ PressTouchPoint(100, 200);
+ FlushTouchEvent(WebInputEvent::TouchStart);
+
+ RunTouchEventTest("Press", WebTouchPoint::StatePressed);
+ ReleaseTouchPointAndAck(1);
+ ReleaseTouchPointAndAck(0);
+ EXPECT_EQ(3u, GetSentMessageCountAndResetSink());
+
+ // Move
+ PressTouchPoint(0, 0);
+ PressTouchPoint(0, 0);
+ FlushTouchEvent(WebInputEvent::TouchStart);
+ process_->sink().ClearMessages();
+
+ MoveTouchPoint(0, 10, 20);
+ MoveTouchPoint(1, 100, 200);
+ FlushTouchEvent(WebInputEvent::TouchMove);
+ RunTouchEventTest("Move", WebTouchPoint::StateMoved);
+ ReleaseTouchPointAndAck(1);
+ ReleaseTouchPointAndAck(0);
+ EXPECT_EQ(3u, GetSentMessageCountAndResetSink());
+
+ // Release
+ PressTouchPoint(10, 20);
+ PressTouchPoint(100, 200);
+ FlushTouchEvent(WebInputEvent::TouchMove);
+ process_->sink().ClearMessages();
+
+ ReleaseTouchPoint(0);
+ ReleaseTouchPoint(1);
+ FlushTouchEvent(WebInputEvent::TouchEnd);
+ RunTouchEventTest("Release", WebTouchPoint::StateReleased);
+
+ // Cancel
+ PressTouchPoint(10, 20);
+ PressTouchPoint(100, 200);
+ FlushTouchEvent(WebInputEvent::TouchStart);
+ process_->sink().ClearMessages();
+
+ CancelTouchPoint(0);
+ CancelTouchPoint(1);
+ FlushTouchEvent(WebInputEvent::TouchCancel);
+ RunTouchEventTest("Cancel", WebTouchPoint::StateCancelled);
+}
+
+namespace {
+
+class InputRouterImplScaleGestureEventTest
+ : public InputRouterImplScaleEventTest {
+ public:
+ InputRouterImplScaleGestureEventTest() {}
+
+ WebGestureEvent BuildGestureEvent(WebInputEvent::Type type,
+ const gfx::Point& point) {
+ WebGestureEvent event = SyntheticWebGestureEventBuilder::Build(
+ type, blink::WebGestureDeviceTouchpad);
+ event.globalX = event.x = point.x();
+ event.globalY = event.y = point.y();
+ return event;
+ }
+
+ void TestTap(const std::string& name, WebInputEvent::Type type) {
+ SCOPED_TRACE(name);
+ const gfx::Point orig(10, 20), scaled(20, 40);
+ WebGestureEvent event = BuildGestureEvent(type, orig);
+ event.data.tap.width = 30;
+ event.data.tap.height = 40;
+ SimulateGestureEvent(event);
+ FlushGestureEvent(type);
+
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ TestLocationInSentEvent(sent_event, orig, scaled);
+ EXPECT_EQ(60, sent_event->data.tap.width);
+ EXPECT_EQ(80, sent_event->data.tap.height);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ TestLocationInFilterEvent(filter_event, orig);
+ EXPECT_EQ(30, filter_event->data.tap.width);
+ EXPECT_EQ(40, filter_event->data.tap.height);
+ process_->sink().ClearMessages();
+ }
+
+ void TestLongPress(const std::string& name, WebInputEvent::Type type) {
+ const gfx::Point orig(10, 20), scaled(20, 40);
+ WebGestureEvent event = BuildGestureEvent(type, orig);
+ event.data.longPress.width = 30;
+ event.data.longPress.height = 40;
+ SimulateGestureEvent(event);
+ FlushGestureEvent(type);
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ TestLocationInSentEvent(sent_event, orig, scaled);
+ EXPECT_EQ(60, sent_event->data.longPress.width);
+ EXPECT_EQ(80, sent_event->data.longPress.height);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ TestLocationInFilterEvent(filter_event, orig);
+ EXPECT_EQ(30, filter_event->data.longPress.width);
+ EXPECT_EQ(40, filter_event->data.longPress.height);
+ process_->sink().ClearMessages();
+ }
+
+ void FlushGestureEvent(WebInputEvent::Type type) {
+ SendInputEventACK(type, INPUT_EVENT_ACK_STATE_CONSUMED);
+ ASSERT_NE(0u, process_->sink().message_count());
+ }
+
+ void TestLocationInSentEvent(const WebGestureEvent* sent_event,
+ const gfx::Point& orig,
+ const gfx::Point& scaled) {
+ EXPECT_EQ(20, sent_event->x);
+ EXPECT_EQ(40, sent_event->y);
+ EXPECT_EQ(10, sent_event->globalX);
+ EXPECT_EQ(20, sent_event->globalY);
+ }
+
+ void TestLocationInFilterEvent(const WebGestureEvent* filter_event,
+ const gfx::Point& point) {
+ EXPECT_EQ(10, filter_event->x);
+ EXPECT_EQ(20, filter_event->y);
+ EXPECT_EQ(10, filter_event->globalX);
+ EXPECT_EQ(20, filter_event->globalY);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleGestureEventTest);
+};
+
+} // namespace
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureScrollUpdate) {
+ SimulateGestureScrollUpdateEvent(10.f, 20, 0,
+ blink::WebGestureDeviceTouchpad);
+ FlushGestureEvent(WebInputEvent::GestureScrollUpdate);
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+
+ EXPECT_EQ(20.f, sent_event->data.scrollUpdate.deltaX);
+ EXPECT_EQ(40.f, sent_event->data.scrollUpdate.deltaY);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ EXPECT_EQ(10.f, filter_event->data.scrollUpdate.deltaX);
+ EXPECT_EQ(20.f, filter_event->data.scrollUpdate.deltaY);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureScrollBegin) {
+ SimulateGestureEvent(
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(10.f, 20.f));
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ EXPECT_EQ(20.f, sent_event->data.scrollBegin.deltaXHint);
+ EXPECT_EQ(40.f, sent_event->data.scrollBegin.deltaYHint);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ EXPECT_EQ(10.f, filter_event->data.scrollBegin.deltaXHint);
+ EXPECT_EQ(20.f, filter_event->data.scrollBegin.deltaYHint);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GesturePinchUpdate) {
+ const gfx::Point orig(10, 20), scaled(20, 40);
+ SimulateGesturePinchUpdateEvent(1.5f, orig.x(), orig.y(), 0,
+ blink::WebGestureDeviceTouchpad);
+ FlushGestureEvent(WebInputEvent::GesturePinchUpdate);
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ TestLocationInSentEvent(sent_event, orig, scaled);
+ EXPECT_EQ(1.5f, sent_event->data.pinchUpdate.scale);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ TestLocationInFilterEvent(filter_event, orig);
+ EXPECT_EQ(1.5f, filter_event->data.pinchUpdate.scale);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureTapDown) {
+ const gfx::Point orig(10, 20), scaled(20, 40);
+ WebGestureEvent event =
+ BuildGestureEvent(WebInputEvent::GestureTapDown, orig);
+ event.data.tapDown.width = 30;
+ event.data.tapDown.height = 40;
+ SimulateGestureEvent(event);
+ // FlushGestureEvent(WebInputEvent::GestureTapDown);
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ TestLocationInSentEvent(sent_event, orig, scaled);
+ EXPECT_EQ(60, sent_event->data.tapDown.width);
+ EXPECT_EQ(80, sent_event->data.tapDown.height);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ TestLocationInFilterEvent(filter_event, orig);
+ EXPECT_EQ(30, filter_event->data.tapDown.width);
+ EXPECT_EQ(40, filter_event->data.tapDown.height);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureTapOthers) {
+ TestTap("GestureDoubleTap", WebInputEvent::GestureDoubleTap);
+ TestTap("GestureTap", WebInputEvent::GestureTap);
+ TestTap("GestureTapUnconfirmed", WebInputEvent::GestureTapUnconfirmed);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureShowPress) {
+ const gfx::Point orig(10, 20), scaled(20, 40);
+ WebGestureEvent event =
+ BuildGestureEvent(WebInputEvent::GestureShowPress, orig);
+ event.data.showPress.width = 30;
+ event.data.showPress.height = 40;
+ SimulateGestureEvent(event);
+
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ TestLocationInSentEvent(sent_event, orig, scaled);
+ EXPECT_EQ(60, sent_event->data.showPress.width);
+ EXPECT_EQ(80, sent_event->data.showPress.height);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ TestLocationInFilterEvent(filter_event, orig);
+ EXPECT_EQ(30, filter_event->data.showPress.width);
+ EXPECT_EQ(40, filter_event->data.showPress.height);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureLongPress) {
+ TestLongPress("LongPress", WebInputEvent::GestureLongPress);
+ TestLongPress("LongPap", WebInputEvent::GestureLongTap);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureTwoFingerTap) {
+ WebGestureEvent event =
+ BuildGestureEvent(WebInputEvent::GestureTwoFingerTap, gfx::Point(10, 20));
+ event.data.twoFingerTap.firstFingerWidth = 30;
+ event.data.twoFingerTap.firstFingerHeight = 40;
+ SimulateGestureEvent(event);
+
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ EXPECT_EQ(20, sent_event->x);
+ EXPECT_EQ(40, sent_event->y);
+ EXPECT_EQ(60, sent_event->data.twoFingerTap.firstFingerWidth);
+ EXPECT_EQ(80, sent_event->data.twoFingerTap.firstFingerHeight);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ EXPECT_EQ(10, filter_event->x);
+ EXPECT_EQ(20, filter_event->y);
+ EXPECT_EQ(30, filter_event->data.twoFingerTap.firstFingerWidth);
+ EXPECT_EQ(40, filter_event->data.twoFingerTap.firstFingerHeight);
+}
+
+TEST_F(InputRouterImplScaleGestureEventTest, GestureFlingStart) {
+ const gfx::Point orig(10, 20), scaled(20, 40);
+ WebGestureEvent event = BuildGestureEvent(
+ WebInputEvent::GestureFlingStart, orig);
+ event.data.flingStart.velocityX = 30;
+ event.data.flingStart.velocityY = 40;
+ SimulateGestureEvent(event);
+
+ const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
+ TestLocationInSentEvent(sent_event, orig, scaled);
+ EXPECT_EQ(60, sent_event->data.flingStart.velocityX);
+ EXPECT_EQ(80, sent_event->data.flingStart.velocityY);
+
+ const WebGestureEvent* filter_event =
+ GetFilterWebInputEvent<WebGestureEvent>();
+ TestLocationInFilterEvent(filter_event, orig);
+ EXPECT_EQ(30, filter_event->data.flingStart.velocityX);
+ EXPECT_EQ(40, filter_event->data.flingStart.velocityY);
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/mock_input_ack_handler.h b/chromium/content/browser/renderer_host/input/mock_input_ack_handler.h
index a4aaf7f2a5d..4753a151350 100644
--- a/chromium/content/browser/renderer_host/input/mock_input_ack_handler.h
+++ b/chromium/content/browser/renderer_host/input/mock_input_ack_handler.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_MOCK_INPUT_ACK_HANDLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOCK_INPUT_ACK_HANDLER_H_
+#include <stddef.h>
+#include <utility>
+
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/input/input_ack_handler.h"
@@ -37,11 +40,11 @@ class MockInputAckHandler : public InputAckHandler {
}
void set_followup_touch_event(scoped_ptr<GestureEventWithLatencyInfo> event) {
- gesture_followup_event_ = event.Pass();
+ gesture_followup_event_ = std::move(event);
}
void set_followup_touch_event(scoped_ptr<TouchEventWithLatencyInfo> event) {
- touch_followup_event_ = event.Pass();
+ touch_followup_event_ = std::move(event);
}
bool unexpected_event_ack_called() const {
diff --git a/chromium/content/browser/renderer_host/input/mock_input_router_client.cc b/chromium/content/browser/renderer_host/input/mock_input_router_client.cc
index fcb5de1a049..07d3d17946e 100644
--- a/chromium/content/browser/renderer_host/input/mock_input_router_client.cc
+++ b/chromium/content/browser/renderer_host/input/mock_input_router_client.cc
@@ -33,7 +33,7 @@ InputEventAckState MockInputRouterClient::FilterInputEvent(
const WebInputEvent& input_event,
const ui::LatencyInfo& latency_info) {
filter_input_event_called_ = true;
- last_filter_event_.reset(new InputEvent(input_event, latency_info, false));
+ last_filter_event_.reset(new InputEvent(input_event, latency_info));
return filter_state_;
}
diff --git a/chromium/content/browser/renderer_host/input/mock_input_router_client.h b/chromium/content/browser/renderer_host/input/mock_input_router_client.h
index c4938a4a4e2..3ae88350626 100644
--- a/chromium/content/browser/renderer_host/input/mock_input_router_client.h
+++ b/chromium/content/browser/renderer_host/input/mock_input_router_client.h
@@ -5,13 +5,15 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_MOCK_INPUT_ROUTER_CLIENT_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOCK_INPUT_ROUTER_CLIENT_H_
+#include <stddef.h>
+
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/input/input_router_client.h"
#include "content/common/input/did_overscroll_params.h"
+#include "content/common/input/input_event.h"
namespace content {
-class InputEvent;
class InputRouter;
class MockInputRouterClient : public InputRouterClient {
@@ -48,6 +50,9 @@ class MockInputRouterClient : public InputRouterClient {
void set_allow_send_event(bool allow) {
filter_state_ = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
}
+ const blink::WebInputEvent* last_filter_event() const {
+ return last_filter_event_->web_event.get();
+ }
private:
InputRouter* input_router_;
diff --git a/chromium/content/browser/renderer_host/input/motion_event_android.cc b/chromium/content/browser/renderer_host/input/motion_event_android.cc
deleted file mode 100644
index 4d30a3f13bb..00000000000
--- a/chromium/content/browser/renderer_host/input/motion_event_android.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/input/motion_event_android.h"
-
-#include <android/input.h>
-
-#include <cmath>
-
-#include "base/android/jni_android.h"
-#include "jni/MotionEvent_jni.h"
-#include "ui/events/base_event_utils.h"
-#include "ui/events/event_constants.h"
-
-using base::android::AttachCurrentThread;
-using namespace JNI_MotionEvent;
-
-namespace content {
-namespace {
-
-MotionEventAndroid::Action FromAndroidAction(int android_action) {
- switch (android_action) {
- case ACTION_DOWN:
- return MotionEventAndroid::ACTION_DOWN;
- case ACTION_UP:
- return MotionEventAndroid::ACTION_UP;
- case ACTION_MOVE:
- return MotionEventAndroid::ACTION_MOVE;
- case ACTION_CANCEL:
- return MotionEventAndroid::ACTION_CANCEL;
- case ACTION_POINTER_DOWN:
- return MotionEventAndroid::ACTION_POINTER_DOWN;
- case ACTION_POINTER_UP:
- return MotionEventAndroid::ACTION_POINTER_UP;
- default:
- NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: "
- << android_action;
- };
- return MotionEventAndroid::ACTION_CANCEL;
-}
-
-MotionEventAndroid::ToolType FromAndroidToolType(int android_tool_type) {
- switch (android_tool_type) {
- case TOOL_TYPE_UNKNOWN:
- return MotionEventAndroid::TOOL_TYPE_UNKNOWN;
- case TOOL_TYPE_FINGER:
- return MotionEventAndroid::TOOL_TYPE_FINGER;
- case TOOL_TYPE_STYLUS:
- return MotionEventAndroid::TOOL_TYPE_STYLUS;
- case TOOL_TYPE_MOUSE:
- return MotionEventAndroid::TOOL_TYPE_MOUSE;
- case TOOL_TYPE_ERASER:
- return MotionEventAndroid::TOOL_TYPE_ERASER;
- default:
- NOTREACHED() << "Invalid Android MotionEvent tool type: "
- << android_tool_type;
- };
- return MotionEventAndroid::TOOL_TYPE_UNKNOWN;
-}
-
-int FromAndroidButtonState(int button_state) {
- int result = 0;
- if ((button_state & BUTTON_BACK) != 0)
- result |= MotionEventAndroid::BUTTON_BACK;
- if ((button_state & BUTTON_FORWARD) != 0)
- result |= MotionEventAndroid::BUTTON_FORWARD;
- if ((button_state & BUTTON_PRIMARY) != 0)
- result |= MotionEventAndroid::BUTTON_PRIMARY;
- if ((button_state & BUTTON_SECONDARY) != 0)
- result |= MotionEventAndroid::BUTTON_SECONDARY;
- if ((button_state & BUTTON_TERTIARY) != 0)
- result |= MotionEventAndroid::BUTTON_TERTIARY;
- if ((button_state & BUTTON_STYLUS_PRIMARY) != 0)
- result |= MotionEventAndroid::BUTTON_STYLUS_PRIMARY;
- if ((button_state & BUTTON_STYLUS_SECONDARY) != 0)
- result |= MotionEventAndroid::BUTTON_STYLUS_SECONDARY;
- return result;
-}
-
-int FromAndroidMetaState(int meta_state) {
- int flags = ui::EF_NONE;
- if ((meta_state & AMETA_SHIFT_ON) != 0)
- flags |= ui::EF_SHIFT_DOWN;
- if ((meta_state & AMETA_CTRL_ON) != 0)
- flags |= ui::EF_CONTROL_DOWN;
- if ((meta_state & AMETA_ALT_ON) != 0)
- flags |= ui::EF_ALT_DOWN;
- if ((meta_state & AMETA_META_ON) != 0)
- flags |= ui::EF_COMMAND_DOWN;
- if ((meta_state & AMETA_CAPS_LOCK_ON) != 0)
- flags |= ui::EF_CAPS_LOCK_DOWN;
- return flags;
-}
-
-base::TimeTicks FromAndroidTime(int64 time_ms) {
- return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms);
-}
-
-float ToValidFloat(float x) {
- if (std::isnan(x))
- return 0.f;
-
- // Wildly large orientation values have been observed in the wild after device
- // rotation. There's not much we can do in that case other than simply
- // sanitize results beyond an absurd and arbitrary threshold.
- if (std::abs(x) > 1e5f)
- return 0.f;
-
- return x;
-}
-
-size_t ToValidHistorySize(jint history_size, ui::MotionEvent::Action action) {
- DCHECK_GE(history_size, 0);
- // While the spec states that only ACTION_MOVE events should contain
- // historical entries, it's possible that an embedder could repurpose an
- // ACTION_MOVE event into a different kind of event. In that case, the
- // historical values are meaningless, and should not be exposed.
- if (action != ui::MotionEvent::ACTION_MOVE)
- return 0;
- return history_size;
-}
-
-} // namespace
-
-MotionEventAndroid::Pointer::Pointer(jint id,
- jfloat pos_x_pixels,
- jfloat pos_y_pixels,
- jfloat touch_major_pixels,
- jfloat touch_minor_pixels,
- jfloat orientation_rad,
- jint tool_type)
- : id(id),
- pos_x_pixels(pos_x_pixels),
- pos_y_pixels(pos_y_pixels),
- touch_major_pixels(touch_major_pixels),
- touch_minor_pixels(touch_minor_pixels),
- orientation_rad(orientation_rad),
- tool_type(tool_type) {
-}
-
-MotionEventAndroid::CachedPointer::CachedPointer()
- : id(0),
- touch_major(0),
- touch_minor(0),
- orientation(0),
- tool_type(TOOL_TYPE_UNKNOWN) {
-}
-
-MotionEventAndroid::MotionEventAndroid(float pix_to_dip,
- JNIEnv* env,
- jobject event,
- jlong time_ms,
- jint android_action,
- jint pointer_count,
- jint history_size,
- jint action_index,
- jint android_button_state,
- jint meta_state,
- jfloat raw_offset_x_pixels,
- jfloat raw_offset_y_pixels,
- const Pointer& pointer0,
- const Pointer& pointer1)
- : pix_to_dip_(pix_to_dip),
- cached_time_(FromAndroidTime(time_ms)),
- cached_action_(FromAndroidAction(android_action)),
- cached_pointer_count_(pointer_count),
- cached_history_size_(ToValidHistorySize(history_size, cached_action_)),
- cached_action_index_(action_index),
- cached_button_state_(FromAndroidButtonState(android_button_state)),
- cached_flags_(FromAndroidMetaState(meta_state)),
- cached_raw_position_offset_(ToDips(raw_offset_x_pixels),
- ToDips(raw_offset_y_pixels)),
- unique_event_id_(ui::GetNextTouchEventId()) {
- DCHECK_GT(pointer_count, 0);
-
- event_.Reset(env, event);
- if (cached_pointer_count_ > MAX_POINTERS_TO_CACHE || cached_history_size_ > 0)
- DCHECK(event_.obj());
-
- cached_pointers_[0] = FromAndroidPointer(pointer0);
- cached_pointers_[1] = FromAndroidPointer(pointer1);
-}
-
-MotionEventAndroid::~MotionEventAndroid() {
-}
-
-uint32 MotionEventAndroid::GetUniqueEventId() const {
- return unique_event_id_;
-}
-
-MotionEventAndroid::Action MotionEventAndroid::GetAction() const {
- return cached_action_;
-}
-
-int MotionEventAndroid::GetActionIndex() const {
- DCHECK(cached_action_ == ACTION_POINTER_UP ||
- cached_action_ == ACTION_POINTER_DOWN)
- << "Invalid action for GetActionIndex(): " << cached_action_;
- DCHECK_GE(cached_action_index_, 0);
- DCHECK_LT(cached_action_index_, static_cast<int>(cached_pointer_count_));
- return cached_action_index_;
-}
-
-size_t MotionEventAndroid::GetPointerCount() const {
- return cached_pointer_count_;
-}
-
-int MotionEventAndroid::GetPointerId(size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- if (pointer_index < MAX_POINTERS_TO_CACHE)
- return cached_pointers_[pointer_index].id;
- return Java_MotionEvent_getPointerId(
- AttachCurrentThread(), event_.obj(), pointer_index);
-}
-
-float MotionEventAndroid::GetX(size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- if (pointer_index < MAX_POINTERS_TO_CACHE)
- return cached_pointers_[pointer_index].position.x();
- return ToDips(Java_MotionEvent_getXF_I(
- AttachCurrentThread(), event_.obj(), pointer_index));
-}
-
-float MotionEventAndroid::GetY(size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- if (pointer_index < MAX_POINTERS_TO_CACHE)
- return cached_pointers_[pointer_index].position.y();
- return ToDips(Java_MotionEvent_getYF_I(
- AttachCurrentThread(), event_.obj(), pointer_index));
-}
-
-float MotionEventAndroid::GetRawX(size_t pointer_index) const {
- return GetX(pointer_index) + cached_raw_position_offset_.x();
-}
-
-float MotionEventAndroid::GetRawY(size_t pointer_index) const {
- return GetY(pointer_index) + cached_raw_position_offset_.y();
-}
-
-float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- if (pointer_index < MAX_POINTERS_TO_CACHE)
- return cached_pointers_[pointer_index].touch_major;
- return ToDips(Java_MotionEvent_getTouchMajorF_I(
- AttachCurrentThread(), event_.obj(), pointer_index));
-}
-
-float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- if (pointer_index < MAX_POINTERS_TO_CACHE)
- return cached_pointers_[pointer_index].touch_minor;
- return ToDips(Java_MotionEvent_getTouchMinorF_I(
- AttachCurrentThread(), event_.obj(), pointer_index));
-}
-
-float MotionEventAndroid::GetOrientation(size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- if (pointer_index < MAX_POINTERS_TO_CACHE)
- return cached_pointers_[pointer_index].orientation;
- return ToValidFloat(Java_MotionEvent_getOrientationF_I(
- AttachCurrentThread(), event_.obj(), pointer_index));
-}
-
-float MotionEventAndroid::GetPressure(size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- // Note that this early return is a special case exercised only in testing, as
- // caching the pressure values is not a worthwhile optimization (they're
- // accessed at most once per event instance).
- if (!event_.obj())
- return 0.f;
- return Java_MotionEvent_getPressureF_I(
- AttachCurrentThread(), event_.obj(), pointer_index);
-}
-
-base::TimeTicks MotionEventAndroid::GetEventTime() const {
- return cached_time_;
-}
-
-size_t MotionEventAndroid::GetHistorySize() const {
- return cached_history_size_;
-}
-
-base::TimeTicks MotionEventAndroid::GetHistoricalEventTime(
- size_t historical_index) const {
- return FromAndroidTime(Java_MotionEvent_getHistoricalEventTime(
- AttachCurrentThread(), event_.obj(), historical_index));
-}
-
-float MotionEventAndroid::GetHistoricalTouchMajor(
- size_t pointer_index,
- size_t historical_index) const {
- return ToDips(Java_MotionEvent_getHistoricalTouchMajorF_I_I(
- AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
-}
-
-float MotionEventAndroid::GetHistoricalX(size_t pointer_index,
- size_t historical_index) const {
- return ToDips(Java_MotionEvent_getHistoricalXF_I_I(
- AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
-}
-
-float MotionEventAndroid::GetHistoricalY(size_t pointer_index,
- size_t historical_index) const {
- return ToDips(Java_MotionEvent_getHistoricalYF_I_I(
- AttachCurrentThread(), event_.obj(), pointer_index, historical_index));
-}
-
-ui::MotionEvent::ToolType MotionEventAndroid::GetToolType(
- size_t pointer_index) const {
- DCHECK_LT(pointer_index, cached_pointer_count_);
- if (pointer_index < MAX_POINTERS_TO_CACHE)
- return cached_pointers_[pointer_index].tool_type;
- return FromAndroidToolType(Java_MotionEvent_getToolType(
- AttachCurrentThread(), event_.obj(), pointer_index));
-}
-
-int MotionEventAndroid::GetButtonState() const {
- return cached_button_state_;
-}
-
-int MotionEventAndroid::GetFlags() const {
- return cached_flags_;
-}
-
-float MotionEventAndroid::ToDips(float pixels) const {
- return pixels * pix_to_dip_;
-}
-
-MotionEventAndroid::CachedPointer MotionEventAndroid::FromAndroidPointer(
- const Pointer& pointer) const {
- CachedPointer result;
- result.id = pointer.id;
- result.position =
- gfx::PointF(ToDips(pointer.pos_x_pixels), ToDips(pointer.pos_y_pixels));
- result.touch_major = ToDips(pointer.touch_major_pixels);
- result.touch_minor = ToDips(pointer.touch_minor_pixels);
- result.orientation = ToValidFloat(pointer.orientation_rad);
- result.tool_type = FromAndroidToolType(pointer.tool_type);
- return result;
-}
-
-// static
-bool MotionEventAndroid::RegisterMotionEventAndroid(JNIEnv* env) {
- return JNI_MotionEvent::RegisterNativesImpl(env);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/motion_event_android.h b/chromium/content/browser/renderer_host/input/motion_event_android.h
deleted file mode 100644
index bf4dfed040e..00000000000
--- a/chromium/content/browser/renderer_host/input/motion_event_android.h
+++ /dev/null
@@ -1,134 +0,0 @@
-
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_ANDROID_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_ANDROID_H_
-
-#include <jni.h>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-#include "ui/events/gesture_detection/motion_event.h"
-#include "ui/gfx/geometry/point_f.h"
-
-namespace content {
-
-// Implementation of ui::MotionEvent wrapping a native Android MotionEvent.
-// All *input* coordinates are in device pixels (as with Android MotionEvent),
-// while all *output* coordinates are in DIPs (as with WebTouchEvent).
-class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
- public:
- struct Pointer {
- Pointer(jint id,
- jfloat pos_x_pixels,
- jfloat pos_y_pixels,
- jfloat touch_major_pixels,
- jfloat touch_minor_pixels,
- jfloat orientation_rad,
- jint tool_type);
- jint id;
- jfloat pos_x_pixels;
- jfloat pos_y_pixels;
- jfloat touch_major_pixels;
- jfloat touch_minor_pixels;
- jfloat orientation_rad;
- jint tool_type;
- };
-
- // Forcing the caller to provide all cached values upon construction
- // eliminates the need to perform a JNI call to retrieve values individually.
- MotionEventAndroid(float pix_to_dip,
- JNIEnv* env,
- jobject event,
- jlong time_ms,
- jint android_action,
- jint pointer_count,
- jint history_size,
- jint action_index,
- jint android_button_state,
- jint meta_state,
- jfloat raw_offset_x_pixels,
- jfloat raw_offset_y_pixels,
- const Pointer& pointer0,
- const Pointer& pointer1);
- ~MotionEventAndroid() override;
-
- // ui::MotionEvent methods.
- uint32 GetUniqueEventId() const override;
- Action GetAction() const override;
- int GetActionIndex() const override;
- size_t GetPointerCount() const override;
- int GetPointerId(size_t pointer_index) const override;
- float GetX(size_t pointer_index) const override;
- float GetY(size_t pointer_index) const override;
- float GetRawX(size_t pointer_index) const override;
- float GetRawY(size_t pointer_index) const override;
- float GetTouchMajor(size_t pointer_index) const override;
- float GetTouchMinor(size_t pointer_index) const override;
- float GetOrientation(size_t pointer_index) const override;
- float GetPressure(size_t pointer_index) const override;
- base::TimeTicks GetEventTime() const override;
- size_t GetHistorySize() const override;
- base::TimeTicks GetHistoricalEventTime(
- size_t historical_index) const override;
- float GetHistoricalTouchMajor(size_t pointer_index,
- size_t historical_index) const override;
- float GetHistoricalX(size_t pointer_index,
- size_t historical_index) const override;
- float GetHistoricalY(size_t pointer_index,
- size_t historical_index) const override;
- ToolType GetToolType(size_t pointer_index) const override;
- int GetButtonState() const override;
- int GetFlags() const override;
-
- static bool RegisterMotionEventAndroid(JNIEnv* env);
-
- private:
- struct CachedPointer;
-
- float ToDips(float pixels) const;
- CachedPointer FromAndroidPointer(const Pointer& pointer) const;
-
- // Cache pointer coords, id's and major lengths for the most common
- // touch-related scenarios, i.e., scrolling and pinching. This prevents
- // redundant JNI fetches for the same bits.
- enum { MAX_POINTERS_TO_CACHE = 2 };
-
- // The Java reference to the underlying MotionEvent.
- base::android::ScopedJavaGlobalRef<jobject> event_;
-
- // Used to convert pixel coordinates from the Java-backed MotionEvent to
- // DIP coordinates cached/returned by the MotionEventAndroid.
- const float pix_to_dip_;
-
- const base::TimeTicks cached_time_;
- const Action cached_action_;
- const size_t cached_pointer_count_;
- const size_t cached_history_size_;
- const int cached_action_index_;
- const int cached_button_state_;
- const int cached_flags_;
- const gfx::Vector2dF cached_raw_position_offset_;
- struct CachedPointer {
- CachedPointer();
- int id;
- gfx::PointF position;
- float touch_major;
- float touch_minor;
- float orientation;
- ToolType tool_type;
- } cached_pointers_[MAX_POINTERS_TO_CACHE];
-
- // A unique identifier for the Android motion event.
- const uint32 unique_event_id_;
-
- DISALLOW_COPY_AND_ASSIGN(MotionEventAndroid);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_ANDROID_H_
diff --git a/chromium/content/browser/renderer_host/input/motion_event_android_unittest.cc b/chromium/content/browser/renderer_host/input/motion_event_android_unittest.cc
deleted file mode 100644
index 9a33b318ab5..00000000000
--- a/chromium/content/browser/renderer_host/input/motion_event_android_unittest.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <android/input.h>
-
-#include "base/android/jni_android.h"
-#include "content/browser/renderer_host/input/motion_event_android.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/events/event_constants.h"
-#include "ui/events/test/motion_event_test_utils.h"
-
-using ui::MotionEvent;
-
-namespace content {
-namespace {
-const float kPixToDip = 0.5f;
-
-int kAndroidActionDown = AMOTION_EVENT_ACTION_DOWN;
-int kAndroidActionPointerDown = AMOTION_EVENT_ACTION_POINTER_DOWN;
-int kAndroidAltKeyDown = AMETA_ALT_ON;
-
-// Corresponds to TOOL_TYPE_FINGER, see
-// developer.android.com/reference/android/view/MotionEvent.html
-// #TOOL_TYPE_FINGER.
-int kAndroidToolTypeFinger = 1;
-
-// Corresponds to BUTTON_PRIMARY, see
-// developer.android.com/reference/android/view/MotionEvent.html#BUTTON_PRIMARY.
-int kAndroidButtonPrimary = 1;
-
-} // namespace
-
-// Note that these tests avoid creating a Java instance of the MotionEvent, as
-// we're primarily testing caching behavior, and the code necessary to
-// construct a Java-backed MotionEvent itself adds unnecessary complexity.
-TEST(MotionEventAndroidTest, Constructor) {
- int event_time_ms = 5;
- base::TimeTicks event_time =
- base::TimeTicks() + base::TimeDelta::FromMilliseconds(event_time_ms);
- MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
- MotionEventAndroid::Pointer p1(
- 2, -13.7f, 7.13f, 3.5f, 12.1f, -0.1f, kAndroidToolTypeFinger);
- float raw_offset = -3.f;
- int pointer_count = 2;
- int history_size = 0;
- int action_index = -1;
- MotionEventAndroid event(kPixToDip,
- base::android::AttachCurrentThread(),
- nullptr,
- event_time_ms,
- kAndroidActionDown,
- pointer_count,
- history_size,
- action_index,
- kAndroidButtonPrimary,
- kAndroidAltKeyDown,
- raw_offset,
- -raw_offset,
- p0,
- p1);
-
- EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
- EXPECT_EQ(event_time, event.GetEventTime());
- EXPECT_EQ(p0.pos_x_pixels * kPixToDip, event.GetX(0));
- EXPECT_EQ(p0.pos_y_pixels * kPixToDip, event.GetY(0));
- EXPECT_EQ(p1.pos_x_pixels * kPixToDip, event.GetX(1));
- EXPECT_EQ(p1.pos_y_pixels * kPixToDip, event.GetY(1));
- EXPECT_FLOAT_EQ((p0.pos_x_pixels + raw_offset) * kPixToDip, event.GetRawX(0));
- EXPECT_FLOAT_EQ((p0.pos_y_pixels - raw_offset) * kPixToDip, event.GetRawY(0));
- EXPECT_FLOAT_EQ((p1.pos_x_pixels + raw_offset) * kPixToDip, event.GetRawX(1));
- EXPECT_FLOAT_EQ((p1.pos_y_pixels - raw_offset) * kPixToDip, event.GetRawY(1));
- EXPECT_EQ(p0.touch_major_pixels * kPixToDip, event.GetTouchMajor(0));
- EXPECT_EQ(p1.touch_major_pixels * kPixToDip, event.GetTouchMajor(1));
- EXPECT_EQ(p0.touch_minor_pixels * kPixToDip, event.GetTouchMinor(0));
- EXPECT_EQ(p1.touch_minor_pixels * kPixToDip, event.GetTouchMinor(1));
- EXPECT_EQ(p0.orientation_rad, event.GetOrientation(0));
- EXPECT_EQ(p1.orientation_rad, event.GetOrientation(1));
- EXPECT_EQ(p0.id, event.GetPointerId(0));
- EXPECT_EQ(p1.id, event.GetPointerId(1));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(0));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(1));
- EXPECT_EQ(MotionEvent::BUTTON_PRIMARY, event.GetButtonState());
- EXPECT_EQ(ui::EF_ALT_DOWN, event.GetFlags());
- EXPECT_EQ(static_cast<size_t>(pointer_count), event.GetPointerCount());
- EXPECT_EQ(static_cast<size_t>(history_size), event.GetHistorySize());
-}
-
-TEST(MotionEventAndroidTest, Clone) {
- const int pointer_count = 1;
- MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
- MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
- MotionEventAndroid event(kPixToDip,
- base::android::AttachCurrentThread(),
- nullptr,
- 0,
- kAndroidActionDown,
- pointer_count,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- p0,
- p1);
-
- scoped_ptr<MotionEvent> clone = event.Clone();
- EXPECT_EQ(ui::test::ToString(event), ui::test::ToString(*clone));
-}
-
-TEST(MotionEventAndroidTest, Cancel) {
- const int event_time_ms = 5;
- const int pointer_count = 1;
- MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
- MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
- MotionEventAndroid event(kPixToDip,
- base::android::AttachCurrentThread(),
- nullptr,
- event_time_ms,
- kAndroidActionDown,
- pointer_count,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- p0,
- p1);
-
- scoped_ptr<MotionEvent> cancel_event = event.Cancel();
- EXPECT_EQ(MotionEvent::ACTION_CANCEL, cancel_event->GetAction());
- EXPECT_EQ(
- base::TimeTicks() + base::TimeDelta::FromMilliseconds(event_time_ms),
- cancel_event->GetEventTime());
- EXPECT_EQ(p0.pos_x_pixels * kPixToDip, cancel_event->GetX(0));
- EXPECT_EQ(p0.pos_y_pixels * kPixToDip, cancel_event->GetY(0));
- EXPECT_EQ(static_cast<size_t>(pointer_count),
- cancel_event->GetPointerCount());
- EXPECT_EQ(0U, cancel_event->GetHistorySize());
-}
-
-TEST(MotionEventAndroidTest, InvalidOrientationsSanitized) {
- int pointer_count = 2;
- float orientation0 = 1e10f;
- float orientation1 = std::numeric_limits<float>::quiet_NaN();
- MotionEventAndroid::Pointer p0(0, 0, 0, 0, 0, orientation0, 0);
- MotionEventAndroid::Pointer p1(1, 0, 0, 0, 0, orientation1, 0);
- MotionEventAndroid event(kPixToDip,
- base::android::AttachCurrentThread(),
- nullptr,
- 0,
- kAndroidActionDown,
- pointer_count,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- p0,
- p1);
-
- EXPECT_EQ(0.f, event.GetOrientation(0));
- EXPECT_EQ(0.f, event.GetOrientation(1));
-}
-
-TEST(MotionEventAndroidTest, NonEmptyHistoryForNonMoveEventsSanitized) {
- int pointer_count = 1;
- size_t history_size = 5;
- MotionEventAndroid::Pointer p0(0, 0, 0, 0, 0, 0, 0);
- MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
- MotionEventAndroid event(kPixToDip,
- base::android::AttachCurrentThread(),
- nullptr,
- 0,
- kAndroidActionDown,
- pointer_count,
- history_size,
- 0,
- 0,
- 0,
- 0,
- 0,
- p0,
- p1);
-
- EXPECT_EQ(0U, event.GetHistorySize());
-}
-
-TEST(MotionEventAndroidTest, ActionIndexForPointerDown) {
- MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
- MotionEventAndroid::Pointer p1(
- 2, -13.7f, 7.13f, 3.5f, 12.1f, -0.1f, kAndroidToolTypeFinger);
- int pointer_count = 2;
- int history_size = 0;
- int action_index = 1;
- MotionEventAndroid event(kPixToDip,
- base::android::AttachCurrentThread(),
- nullptr,
- 0,
- kAndroidActionPointerDown,
- pointer_count,
- history_size,
- action_index,
- 0,
- 0,
- 0,
- 0,
- p0,
- p1);
-
- EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
- EXPECT_EQ(action_index, event.GetActionIndex());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/motion_event_web.cc b/chromium/content/browser/renderer_host/input/motion_event_web.cc
index 82b6ed7861b..13dd027fa40 100644
--- a/chromium/content/browser/renderer_host/input/motion_event_web.cc
+++ b/chromium/content/browser/renderer_host/input/motion_event_web.cc
@@ -71,7 +71,7 @@ MotionEventWeb::MotionEventWeb(const WebTouchEvent& event)
MotionEventWeb::~MotionEventWeb() {}
-uint32 MotionEventWeb::GetUniqueEventId() const {
+uint32_t MotionEventWeb::GetUniqueEventId() const {
return unique_event_id_;
}
@@ -130,26 +130,62 @@ float MotionEventWeb::GetTouchMinor(size_t pointer_index) const {
float MotionEventWeb::GetOrientation(size_t pointer_index) const {
DCHECK_LT(pointer_index, GetPointerCount());
- float rotation_angle_rad = event_.touches[pointer_index].rotationAngle
+ float orientation_rad = event_.touches[pointer_index].rotationAngle
* M_PI / 180.f;
- DCHECK(0 <= rotation_angle_rad && rotation_angle_rad <= M_PI_2)
+ DCHECK(0 <= orientation_rad && orientation_rad <= M_PI_2)
<< "Unexpected touch rotation angle";
- if (event_.touches[pointer_index].radiusX
- > event_.touches[pointer_index].radiusY) {
+ if (GetToolType(pointer_index) == TOOL_TYPE_STYLUS) {
+ const WebPointerProperties& pointer = event_.touches[pointer_index];
+
+ if (pointer.tiltY <= 0 && pointer.tiltX < 0) {
+ // Stylus is tilted to the left away from the user or straight
+ // to the left thus the orientation should be within [pi/2,pi).
+ orientation_rad += static_cast<float>(M_PI_2);
+ } else if (pointer.tiltY < 0 && pointer.tiltX >= 0) {
+ // Stylus is tilted to the right away from the user or straight away
+ // from the user thus the orientation should be within [-pi,-pi/2).
+ orientation_rad -= static_cast<float>(M_PI);
+ } else if (pointer.tiltY >= 0 && pointer.tiltX > 0) {
+ // Stylus is tilted to the right towards the user or straight
+ // to the right thus the orientation should be within [-pi/2,0).
+ orientation_rad -= static_cast<float>(M_PI_2);
+ }
+ } else if (event_.touches[pointer_index].radiusX
+ > event_.touches[pointer_index].radiusY) {
// The case radiusX == radiusY is omitted from here on purpose: for circles,
// we want to pass the angle (which could be any value in such cases but
- // always seem to be set to zero) unchanged.
- rotation_angle_rad -= (float) M_PI_2;
+ // always seems to be set to zero) unchanged.
+ orientation_rad -= static_cast<float>(M_PI_2);
}
- return rotation_angle_rad;
+ return orientation_rad;
}
float MotionEventWeb::GetPressure(size_t pointer_index) const {
return 0.f;
}
+float MotionEventWeb::GetTilt(size_t pointer_index) const {
+ DCHECK_LT(pointer_index, GetPointerCount());
+
+ if (GetToolType(pointer_index) != TOOL_TYPE_STYLUS)
+ return 0.f;
+
+ const WebPointerProperties& pointer = event_.touches[pointer_index];
+
+ float tilt_x_r = sin(pointer.tiltX * M_PI / 180.f);
+ float tilt_x_z = cos(pointer.tiltX * M_PI / 180.f);
+ float tilt_y_r = sin(pointer.tiltY * M_PI / 180.f);
+ float tilt_y_z = cos(pointer.tiltY * M_PI / 180.f);
+ float r_x = tilt_x_r * tilt_y_z;
+ float r_y = tilt_y_r * tilt_x_z;
+ float r = sqrt(r_x * r_x + r_y * r_y);
+ float z = tilt_x_z * tilt_y_z;
+
+ return atan2(r, z);
+}
+
base::TimeTicks MotionEventWeb::GetEventTime() const {
return base::TimeTicks() +
base::TimeDelta::FromMicroseconds(event_.timeStampSeconds *
@@ -163,18 +199,17 @@ ui::MotionEvent::ToolType MotionEventWeb::GetToolType(
const WebPointerProperties& pointer = event_.touches[pointer_index];
switch (pointer.pointerType) {
- case WebPointerProperties::PointerTypeUnknown:
+ case WebPointerProperties::PointerType::Unknown:
return TOOL_TYPE_UNKNOWN;
- case WebPointerProperties::PointerTypeMouse:
+ case WebPointerProperties::PointerType::Mouse:
return TOOL_TYPE_MOUSE;
- case WebPointerProperties::PointerTypePen:
+ case WebPointerProperties::PointerType::Pen:
return TOOL_TYPE_STYLUS;
- case WebPointerProperties::PointerTypeTouch:
+ case WebPointerProperties::PointerType::Touch:
return TOOL_TYPE_FINGER;
- default:
- NOTREACHED() << "Unhandled pointer type " << pointer.pointerType;
- return TOOL_TYPE_UNKNOWN;
}
+ NOTREACHED() << "Unexpected pointerType";
+ return TOOL_TYPE_UNKNOWN;
}
int MotionEventWeb::GetButtonState() const {
diff --git a/chromium/content/browser/renderer_host/input/motion_event_web.h b/chromium/content/browser/renderer_host/input/motion_event_web.h
index 34e954168b8..320e31b081b 100644
--- a/chromium/content/browser/renderer_host/input/motion_event_web.h
+++ b/chromium/content/browser/renderer_host/input/motion_event_web.h
@@ -5,19 +5,24 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_WEB_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_WEB_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/events/gesture_detection/motion_event.h"
namespace content {
// Implementation of ui::MotionEvent wrapping a WebTouchEvent.
-class MotionEventWeb : public ui::MotionEvent {
+class CONTENT_EXPORT MotionEventWeb : public ui::MotionEvent {
public:
explicit MotionEventWeb(const blink::WebTouchEvent& event);
~MotionEventWeb() override;
// ui::MotionEvent
- uint32 GetUniqueEventId() const override;
+ uint32_t GetUniqueEventId() const override;
Action GetAction() const override;
int GetActionIndex() const override;
size_t GetPointerCount() const override;
@@ -30,6 +35,7 @@ class MotionEventWeb : public ui::MotionEvent {
float GetTouchMinor(size_t pointer_index) const override;
float GetOrientation(size_t pointer_index) const override;
float GetPressure(size_t pointer_index) const override;
+ float GetTilt(size_t pointer_index) const override;
base::TimeTicks GetEventTime() const override;
ToolType GetToolType(size_t pointer_index) const override;
int GetButtonState() const override;
@@ -39,7 +45,7 @@ class MotionEventWeb : public ui::MotionEvent {
blink::WebTouchEvent event_;
Action cached_action_;
int cached_action_index_;
- const uint32 unique_event_id_;
+ const uint32_t unique_event_id_;
DISALLOW_COPY_AND_ASSIGN(MotionEventWeb);
};
diff --git a/chromium/content/browser/renderer_host/input/motion_event_web_unittest.cc b/chromium/content/browser/renderer_host/input/motion_event_web_unittest.cc
new file mode 100644
index 00000000000..df2f2305f51
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/motion_event_web_unittest.cc
@@ -0,0 +1,80 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// MSVC++ requires this to be set before any other includes to get M_PI.
+#define _USE_MATH_DEFINES
+
+#include <stddef.h>
+
+#include <cmath>
+
+#include "content/browser/renderer_host/input/motion_event_web.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/blink/blink_event_util.h"
+#include "ui/events/gesture_detection/motion_event_generic.h"
+#include "ui/events/test/motion_event_test_utils.h"
+
+using ui::MotionEvent;
+using ui::MotionEventGeneric;
+using ui::PointerProperties;
+
+namespace content {
+
+TEST(MotionEventWebTest, Constructor) {
+ const float pi = static_cast<float>(M_PI);
+ const float orientations[] = {
+ -pi, -2.f * pi / 3, -pi / 2, -pi / 3, 0.f, pi / 3, pi / 2, 2.f * pi / 3};
+ const float tilts[] = {0.f, pi / 4, pi / 3};
+ const MotionEvent::ToolType tool_types[] = {MotionEvent::TOOL_TYPE_FINGER,
+ MotionEvent::TOOL_TYPE_STYLUS,
+ MotionEvent::TOOL_TYPE_MOUSE};
+
+ base::TimeTicks event_time = base::TimeTicks::Now();
+ PointerProperties pp;
+ MotionEventGeneric generic_event(MotionEvent::ACTION_MOVE, event_time, pp);
+
+ for (MotionEvent::ToolType tool_type : tool_types) {
+ for (float orientation : orientations) {
+ for (float tilt : tilts) {
+ PointerProperties pp2;
+ pp2.orientation = orientation;
+ pp2.tilt = tilt;
+ pp2.tool_type = tool_type;
+ size_t pointer_index = generic_event.PushPointer(pp2);
+ EXPECT_GT(pointer_index, 0u);
+
+ blink::WebTouchEvent web_touch_event =
+ CreateWebTouchEventFromMotionEvent(generic_event, true);
+
+ MotionEventWeb event(web_touch_event);
+ EXPECT_EQ(tool_type, event.GetToolType(pointer_index));
+ if (tool_type == MotionEvent::TOOL_TYPE_STYLUS) {
+ // Web touch event touch point tilt plane angles are stored as ints,
+ // thus the tilt precision is 1 degree and the error should not be
+ // greater than 0.5 degrees.
+ EXPECT_NEAR(tilt, event.GetTilt(pointer_index), 0.5f * M_PI / 180.f)
+ << " orientation=" << orientation;
+ } else {
+ EXPECT_EQ(0.f, event.GetTilt(pointer_index));
+ }
+ if (tool_type == MotionEvent::TOOL_TYPE_STYLUS && tilt > 0.f) {
+ // Full stylus tilt orientation information survives above event
+ // conversions only if there is a non-zero stylus tilt angle.
+ // See: http://crbug.com/251330
+ EXPECT_NEAR(orientation, event.GetOrientation(pointer_index), 1e-4)
+ << " tilt=" << tilt;
+ } else {
+ // For non-stylus pointers and for styluses with a zero tilt angle,
+ // orientation quadrant information is lost.
+ EXPECT_NEAR(fmod(orientation + M_PI + 1e-4, M_PI_2) - 1e-4,
+ event.GetOrientation(pointer_index), 1e-4);
+ }
+
+ generic_event.RemovePointerAt(pointer_index);
+ }
+ }
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
index 8ce73ea8119..8fc03c71376 100644
--- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
+++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
@@ -4,8 +4,11 @@
#include "content/browser/renderer_host/input/render_widget_host_latency_tracker.h"
+#include <stddef.h>
+
#include "base/logging.h"
#include "base/metrics/histogram.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
using blink::WebGestureEvent;
@@ -21,7 +24,7 @@ namespace {
void UpdateLatencyCoordinatesImpl(const blink::WebTouchEvent& touch,
LatencyInfo* latency,
float device_scale_factor) {
- for (uint32 i = 0; i < touch.touchesLength; ++i) {
+ for (uint32_t i = 0; i < touch.touchesLength; ++i) {
LatencyInfo::InputCoordinate coordinate(
touch.touches[i].position.x * device_scale_factor,
touch.touches[i].position.y * device_scale_factor);
@@ -73,7 +76,7 @@ void UpdateLatencyCoordinates(const WebInputEvent& event,
}
void ComputeInputLatencyHistograms(WebInputEvent::Type type,
- int64 latency_component_id,
+ int64_t latency_component_id,
const LatencyInfo& latency) {
LatencyInfo::LatencyComponent rwh_component;
if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
@@ -152,7 +155,7 @@ void ComputeInputLatencyHistograms(WebInputEvent::Type type,
void ComputeScrollLatencyHistograms(
const LatencyInfo::LatencyComponent& gpu_swap_begin_component,
const LatencyInfo::LatencyComponent& gpu_swap_end_component,
- int64 latency_component_id,
+ int64_t latency_component_id,
const LatencyInfo& latency) {
DCHECK(!gpu_swap_begin_component.event_time.is_null());
DCHECK(!gpu_swap_end_component.event_time.is_null());
@@ -256,8 +259,8 @@ void ComputeScrollLatencyHistograms(
// provided to them by the browser process. This function adds the correct
// component ID where necessary.
void AddLatencyInfoComponentIds(LatencyInfo* latency,
- int64 latency_component_id) {
- std::vector<std::pair<ui::LatencyComponentType, int64>> new_components_key;
+ int64_t latency_component_id) {
+ std::vector<std::pair<ui::LatencyComponentType, int64_t>> new_components_key;
std::vector<LatencyInfo::LatencyComponent> new_components_value;
for (const auto& lc : latency->latency_components()) {
ui::LatencyComponentType component_type = lc.first.first;
@@ -299,7 +302,7 @@ void RenderWidgetHostLatencyTracker::Initialize(int routing_id,
int process_id) {
DCHECK_EQ(0, last_event_id_);
DCHECK_EQ(0, latency_component_id_);
- last_event_id_ = static_cast<int64>(process_id) << 32;
+ last_event_id_ = static_cast<int64_t>(process_id) << 32;
latency_component_id_ = routing_id | last_event_id_;
}
@@ -318,21 +321,6 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
base::TimeTicks timestamp_now = base::TimeTicks::Now();
base::TimeTicks timestamp_original = base::TimeTicks() +
base::TimeDelta::FromSecondsD(event.timeStampSeconds);
- // |event.timeStampSeconds| is the event's creation timestamp given
- // by the OS. On Windows, for non-touch input events the timestamp is
- // most likely from timeGetTime(), while in platform independent code
- // path we usually get timestamps by calling TimeTicks::Now(), which,
- // if using high-resolution timer as underlying implementation, could
- // have different time origin than timeGetTime(). To avoid the mismatching,
- // lets use TimeTicks::Now() instead of |event.timeStampSeconds| for
- // INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT so to be consistent with
- // other components.
- // TODO(miletus): Remove this hack. crbug.com/527128.
-#if defined(OS_WIN)
- if (!(blink::WebInputEvent::isTouchEventType(event.type) ||
- blink::WebInputEvent::isGestureEventType(event.type)))
- timestamp_original = timestamp_now;
-#endif // defined(OS_WIN)
// Timestamp from platform input can wrap, e.g. 32 bits timestamp
// for Xserver and Window MSG time will wrap about 49.6 days. Do a
diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h
index 32537d1a0b1..6df155fe792 100644
--- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h
+++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_RENDER_WIDGET_HOST_LATENCY_TRACKER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_RENDER_WIDGET_HOST_LATENCY_TRACKER_H_
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
#include "ui/events/latency_info.h"
@@ -56,11 +58,11 @@ class CONTENT_EXPORT RenderWidgetHostLatencyTracker {
// Returns the ID that uniquely describes this component to the latency
// subsystem.
- int64 latency_component_id() const { return latency_component_id_; }
+ int64_t latency_component_id() const { return latency_component_id_; }
private:
- int64 last_event_id_;
- int64 latency_component_id_;
+ int64_t last_event_id_;
+ int64_t latency_component_id_;
float device_scale_factor_;
bool has_seent_first_gesture_scroll_update_;
diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
index ebb3839c39d..baeb15cb755 100644
--- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
@@ -134,7 +134,8 @@ TEST(RenderWidgetHostLatencyTrackerTest, InputCoordinatesPopulated) {
tracker.Initialize(kTestRoutingId, kTestProcessId);
{
- auto event = SyntheticWebMouseWheelEventBuilder::Build(-5, 0, 0, true);
+ auto event =
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, -5, 0, 0, true);
event.x = 100;
event.y = 200;
ui::LatencyInfo latency_info;
diff --git a/chromium/content/browser/renderer_host/input/stylus_text_selector.cc b/chromium/content/browser/renderer_host/input/stylus_text_selector.cc
index 11cace7e825..20eee8216a7 100644
--- a/chromium/content/browser/renderer_host/input/stylus_text_selector.cc
+++ b/chromium/content/browser/renderer_host/input/stylus_text_selector.cc
@@ -30,7 +30,7 @@ scoped_ptr<GestureDetector> CreateGestureDetector(
detector->set_longpress_enabled(false);
detector->set_showpress_enabled(false);
- return detector.Pass();
+ return detector;
}
} // namespace
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture.cc
index 2e25288dc13..ebe8712e15c 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture.cc
@@ -47,10 +47,4 @@ scoped_ptr<SyntheticGesture> SyntheticGesture::Create(
return scoped_ptr<SyntheticGesture>();
}
-// static
-double SyntheticGesture::ConvertTimestampToSeconds(
- const base::TimeTicks& timestamp) {
- return (timestamp - base::TimeTicks()).InSecondsF();
-}
-
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_gesture.h
index 1d605ff9383..626bd15aa65 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
@@ -40,6 +41,8 @@ class CONTENT_EXPORT SyntheticGesture {
GESTURE_RESULT_MAX = GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED
};
+ enum PointerActionType { PRESS, MOVE, RELEASE };
+
// Update the state of the gesture and forward the appropriate events to the
// platform. This function is called repeatedly by the synthetic gesture
// controller until it stops returning GESTURE_RUNNING.
@@ -47,8 +50,6 @@ class CONTENT_EXPORT SyntheticGesture {
const base::TimeTicks& timestamp, SyntheticGestureTarget* target) = 0;
protected:
- static double ConvertTimestampToSeconds(const base::TimeTicks& timestamp);
-
DISALLOW_COPY_AND_ASSIGN(SyntheticGesture);
};
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc
index 536426b71db..109ce3465bd 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
+#include <utility>
+
#include "base/trace_event/trace_event.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
@@ -14,7 +16,7 @@ namespace content {
SyntheticGestureController::SyntheticGestureController(
scoped_ptr<SyntheticGestureTarget> gesture_target)
- : gesture_target_(gesture_target.Pass()) {}
+ : gesture_target_(std::move(gesture_target)) {}
SyntheticGestureController::~SyntheticGestureController() {}
@@ -25,7 +27,8 @@ void SyntheticGestureController::QueueSyntheticGesture(
bool was_empty = pending_gesture_queue_.IsEmpty();
- pending_gesture_queue_.Push(synthetic_gesture.Pass(), completion_callback);
+ pending_gesture_queue_.Push(std::move(synthetic_gesture),
+ completion_callback);
if (was_empty)
StartGesture(*pending_gesture_queue_.FrontGesture());
@@ -61,7 +64,7 @@ void SyntheticGestureController::OnDidFlushInput() {
return;
DCHECK(!pending_gesture_queue_.IsEmpty());
- auto pending_gesture_result = pending_gesture_result_.Pass();
+ auto pending_gesture_result = std::move(pending_gesture_result_);
StopGesture(*pending_gesture_queue_.FrontGesture(),
pending_gesture_queue_.FrontCallback(),
*pending_gesture_result);
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h
index 0a42f316756..aeef18f5024 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h
@@ -9,6 +9,7 @@
#include <utility>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/time/time.h"
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
index b639d32f39e..9369bfdfdc8 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
@@ -2,17 +2,24 @@
// 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_gesture_controller.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.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/synthetic_pinch_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_pointer_action.h"
#include "content/browser/renderer_host/input/synthetic_smooth_drag_gesture.h"
#include "content/browser/renderer_host/input/synthetic_smooth_move_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/input/synthetic_touch_pointer.h"
#include "content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h"
#include "content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
@@ -34,6 +41,7 @@ using blink::WebInputEvent;
using blink::WebMouseEvent;
using blink::WebMouseWheelEvent;
using blink::WebTouchEvent;
+using blink::WebTouchPoint;
namespace content {
@@ -43,6 +51,7 @@ const int kFlushInputRateInMs = 16;
const int kPointerAssumedStoppedTimeMs = 43;
const float kTouchSlopInDips = 7.0f;
const float kMinScalingSpanInDips = 27.5f;
+const int kTouchPointersLength = 16;
enum TouchGestureType { TOUCH_SCROLL, TOUCH_DRAG };
@@ -163,7 +172,7 @@ class MockMoveTouchTarget : public MockMoveGestureTarget {
ASSERT_EQ(touch_event.type, WebInputEvent::TouchStart);
start_.SetPoint(touch_event.touches[0].position.x,
touch_event.touches[0].position.y);
- last_touch_point_ = start_;
+ last_touch_point_ = gfx::PointF(start_);
started_ = true;
} else {
ASSERT_NE(touch_event.type, WebInputEvent::TouchStart);
@@ -175,7 +184,7 @@ class MockMoveTouchTarget : public MockMoveGestureTarget {
total_abs_move_distance_length_ += delta.Length();
if (touch_event.type == WebInputEvent::TouchEnd)
- start_to_end_distance_ = touch_point - start_;
+ start_to_end_distance_ = touch_point - gfx::PointF(start_);
last_touch_point_ = touch_point;
}
@@ -411,14 +420,14 @@ class MockSyntheticTapTouchTarget : public MockSyntheticTapGestureTarget {
EXPECT_EQ(touch_event.type, WebInputEvent::TouchStart);
position_ = gfx::PointF(touch_event.touches[0].position);
start_time_ = base::TimeDelta::FromMilliseconds(
- static_cast<int64>(touch_event.timeStampSeconds * 1000));
+ static_cast<int64_t>(touch_event.timeStampSeconds * 1000));
state_ = STARTED;
break;
case STARTED:
EXPECT_EQ(touch_event.type, WebInputEvent::TouchEnd);
EXPECT_EQ(position_, gfx::PointF(touch_event.touches[0].position));
stop_time_ = base::TimeDelta::FromMilliseconds(
- static_cast<int64>(touch_event.timeStampSeconds * 1000));
+ static_cast<int64_t>(touch_event.timeStampSeconds * 1000));
state_ = FINISHED;
break;
case FINISHED:
@@ -444,7 +453,7 @@ class MockSyntheticTapMouseTarget : public MockSyntheticTapGestureTarget {
EXPECT_EQ(mouse_event.clickCount, 1);
position_ = gfx::PointF(mouse_event.x, mouse_event.y);
start_time_ = base::TimeDelta::FromMilliseconds(
- static_cast<int64>(mouse_event.timeStampSeconds * 1000));
+ static_cast<int64_t>(mouse_event.timeStampSeconds * 1000));
state_ = STARTED;
break;
case STARTED:
@@ -453,7 +462,7 @@ class MockSyntheticTapMouseTarget : public MockSyntheticTapGestureTarget {
EXPECT_EQ(mouse_event.clickCount, 1);
EXPECT_EQ(position_, gfx::PointF(mouse_event.x, mouse_event.y));
stop_time_ = base::TimeDelta::FromMilliseconds(
- static_cast<int64>(mouse_event.timeStampSeconds * 1000));
+ static_cast<int64_t>(mouse_event.timeStampSeconds * 1000));
state_ = FINISHED;
break;
case FINISHED:
@@ -463,6 +472,44 @@ class MockSyntheticTapMouseTarget : public MockSyntheticTapGestureTarget {
}
};
+class MockSyntheticPointerActionTarget : public MockSyntheticGestureTarget {
+ public:
+ MockSyntheticPointerActionTarget() {}
+ ~MockSyntheticPointerActionTarget() override {}
+
+ gfx::PointF positions(int index) const { return positions_[index]; }
+ int indexes(int index) const { return indexes_[index]; }
+ WebTouchPoint::State states(int index) { return states_[index]; }
+ unsigned touch_length() const { return touch_length_; }
+ WebInputEvent::Type type() const { return type_; }
+
+ protected:
+ gfx::PointF positions_[kTouchPointersLength];
+ unsigned touch_length_;
+ int indexes_[kTouchPointersLength];
+ WebTouchPoint::State states_[kTouchPointersLength];
+ WebInputEvent::Type type_;
+};
+
+class MockSyntheticPointerTouchActionTarget
+ : public MockSyntheticPointerActionTarget {
+ public:
+ MockSyntheticPointerTouchActionTarget() {}
+ ~MockSyntheticPointerTouchActionTarget() override {}
+
+ void DispatchInputEventToPlatform(const WebInputEvent& event) override {
+ ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type));
+ const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
+ type_ = touch_event.type;
+ for (size_t i = 0; i < touch_event.touchesLength; ++i) {
+ indexes_[i] = touch_event.touches[i].id;
+ positions_[i] = gfx::PointF(touch_event.touches[i].position);
+ states_[i] = touch_event.touches[i].state;
+ }
+ touch_length_ = touch_event.touchesLength;
+ }
+};
+
class SyntheticGestureControllerTestBase {
public:
SyntheticGestureControllerTestBase() {}
@@ -478,7 +525,7 @@ class SyntheticGestureControllerTestBase {
void QueueSyntheticGesture(scoped_ptr<SyntheticGesture> gesture) {
controller_->QueueSyntheticGesture(
- gesture.Pass(),
+ std::move(gesture),
base::Bind(
&SyntheticGestureControllerTestBase::OnSyntheticGestureCompleted,
base::Unretained(this)));
@@ -555,7 +602,7 @@ TEST_F(SyntheticGestureControllerTest, SingleGesture) {
bool finished = false;
scoped_ptr<MockSyntheticGesture> gesture(
new MockSyntheticGesture(&finished, 3));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
EXPECT_TRUE(finished);
@@ -569,7 +616,7 @@ TEST_F(SyntheticGestureControllerTest, GestureFailed) {
bool finished = false;
scoped_ptr<MockSyntheticGesture> gesture(
new MockSyntheticGesture(&finished, 0));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
EXPECT_TRUE(finished);
@@ -588,7 +635,7 @@ TEST_F(SyntheticGestureControllerTest, SuccessiveGestures) {
new MockSyntheticGesture(&finished_2, 4));
// Queue first gesture and wait for it to finish
- QueueSyntheticGesture(gesture_1.Pass());
+ QueueSyntheticGesture(std::move(gesture_1));
FlushInputUntilComplete();
EXPECT_TRUE(finished_1);
@@ -596,7 +643,7 @@ TEST_F(SyntheticGestureControllerTest, SuccessiveGestures) {
EXPECT_EQ(0, num_failure_);
// Queue second gesture.
- QueueSyntheticGesture(gesture_2.Pass());
+ QueueSyntheticGesture(std::move(gesture_2));
FlushInputUntilComplete();
EXPECT_TRUE(finished_2);
@@ -614,8 +661,8 @@ TEST_F(SyntheticGestureControllerTest, TwoGesturesInFlight) {
scoped_ptr<MockSyntheticGesture> gesture_2(
new MockSyntheticGesture(&finished_2, 4));
- QueueSyntheticGesture(gesture_1.Pass());
- QueueSyntheticGesture(gesture_2.Pass());
+ QueueSyntheticGesture(std::move(gesture_1));
+ QueueSyntheticGesture(std::move(gesture_2));
FlushInputUntilComplete();
EXPECT_TRUE(finished_1);
@@ -634,8 +681,8 @@ TEST_F(SyntheticGestureControllerTest, GestureCompletedOnDidFlushInput) {
scoped_ptr<MockSyntheticGesture> gesture_2(
new MockSyntheticGesture(&finished_2, 4));
- QueueSyntheticGesture(gesture_1.Pass());
- QueueSyntheticGesture(gesture_2.Pass());
+ QueueSyntheticGesture(std::move(gesture_1));
+ QueueSyntheticGesture(std::move(gesture_2));
while (target_->flush_requested()) {
target_->ClearFlushRequest();
@@ -689,7 +736,7 @@ TEST_P(SyntheticGestureControllerTestWithParam,
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -718,7 +765,7 @@ TEST_P(SyntheticGestureControllerTestWithParam,
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -763,7 +810,7 @@ TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchDiagonal) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -789,7 +836,7 @@ TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchLongStop) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -817,7 +864,7 @@ TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchFling) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -843,7 +890,7 @@ TEST_P(SyntheticGestureControllerTestWithParam,
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -863,7 +910,7 @@ TEST_F(SyntheticGestureControllerTest, SingleScrollGestureMouseVertical) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -883,7 +930,7 @@ TEST_F(SyntheticGestureControllerTest, SingleScrollGestureMouseHorizontal) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -903,7 +950,7 @@ TEST_F(SyntheticGestureControllerTest, SingleScrollGestureMouseDiagonal) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -924,7 +971,7 @@ TEST_F(SyntheticGestureControllerTest, MultiScrollGestureMouse) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -946,7 +993,7 @@ TEST_F(SyntheticGestureControllerTest, MultiScrollGestureMouseHorizontal) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -992,7 +1039,7 @@ TEST_F(SyntheticGestureControllerTest, MultiScrollGestureTouch) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -1020,7 +1067,7 @@ TEST_P(SyntheticGestureControllerTestWithParam,
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* scroll_target =
@@ -1057,7 +1104,7 @@ TEST_F(SyntheticGestureControllerTest, SingleDragGestureMouseDiagonal) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* drag_target =
@@ -1077,7 +1124,7 @@ TEST_F(SyntheticGestureControllerTest, SingleDragGestureMouseZeroDistance) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* drag_target =
@@ -1098,7 +1145,7 @@ TEST_F(SyntheticGestureControllerTest, MultiDragGestureMouse) {
scoped_ptr<SyntheticSmoothMoveGesture> gesture(
new SyntheticSmoothMoveGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockMoveGestureTarget* drag_target =
@@ -1180,7 +1227,7 @@ TEST_F(SyntheticGestureControllerTest,
scoped_ptr<SyntheticTouchscreenPinchGesture> gesture(
new SyntheticTouchscreenPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTouchscreenPinchTouchTarget* pinch_target =
@@ -1203,7 +1250,7 @@ TEST_F(SyntheticGestureControllerTest,
scoped_ptr<SyntheticTouchscreenPinchGesture> gesture(
new SyntheticTouchscreenPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTouchscreenPinchTouchTarget* pinch_target =
@@ -1225,7 +1272,7 @@ TEST_F(SyntheticGestureControllerTest,
scoped_ptr<SyntheticTouchscreenPinchGesture> gesture(
new SyntheticTouchscreenPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTouchscreenPinchTouchTarget* pinch_target =
@@ -1247,7 +1294,7 @@ TEST_F(SyntheticGestureControllerTest, TouchpadPinchGestureTouchZoomIn) {
scoped_ptr<SyntheticTouchpadPinchGesture> gesture(
new SyntheticTouchpadPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTouchpadPinchTouchTarget* pinch_target =
@@ -1269,7 +1316,7 @@ TEST_F(SyntheticGestureControllerTest, TouchpadPinchGestureTouchZoomOut) {
scoped_ptr<SyntheticTouchpadPinchGesture> gesture(
new SyntheticTouchpadPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTouchpadPinchTouchTarget* pinch_target =
@@ -1290,7 +1337,7 @@ TEST_F(SyntheticGestureControllerTest, TouchpadPinchGestureTouchNoScaling) {
scoped_ptr<SyntheticTouchpadPinchGesture> gesture(
new SyntheticTouchpadPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTouchpadPinchTouchTarget* pinch_target =
@@ -1313,7 +1360,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureExplicitTouch) {
params.anchor.SetPoint(54, 89);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
// Gesture target will fail expectations if the wrong underlying
@@ -1331,7 +1378,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureExplicitMouse) {
params.anchor.SetPoint(54, 89);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
// Gesture target will fail expectations if the wrong underlying
@@ -1349,7 +1396,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureDefaultTouch) {
params.anchor.SetPoint(54, 89);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
// Gesture target will fail expectations if the wrong underlying
@@ -1367,7 +1414,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureDefaultMouse) {
params.anchor.SetPoint(54, 89);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
// Gesture target will fail expectations if the wrong underlying
@@ -1383,7 +1430,7 @@ TEST_F(SyntheticGestureControllerTest, TapGestureTouch) {
params.position.SetPoint(87, -124);
scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTapTouchTarget* tap_target =
@@ -1406,7 +1453,7 @@ TEST_F(SyntheticGestureControllerTest, TapGestureMouse) {
params.position.SetPoint(98, 123);
scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
- QueueSyntheticGesture(gesture.Pass());
+ QueueSyntheticGesture(std::move(gesture));
FlushInputUntilComplete();
MockSyntheticTapMouseTarget* tap_target =
@@ -1420,6 +1467,67 @@ TEST_F(SyntheticGestureControllerTest, TapGestureMouse) {
base::TimeDelta::FromMilliseconds(params.duration_ms));
}
+TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
+ CreateControllerAndTarget<MockSyntheticPointerTouchActionTarget>();
+
+ SyntheticTouchPointer synthetic_pointer;
+
+ gfx::PointF position(54, 89);
+ scoped_ptr<SyntheticPointerAction> gesture(new SyntheticPointerAction(
+ SyntheticGestureParams::TOUCH_INPUT, SyntheticGesture::PRESS,
+ &synthetic_pointer, position));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ MockSyntheticPointerTouchActionTarget* pointer_touch_target =
+ static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart);
+ EXPECT_EQ(pointer_touch_target->positions(0), position);
+ EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed);
+ ASSERT_EQ(pointer_touch_target->touch_length(), 1U);
+
+ position.SetPoint(79, 132);
+ gesture.reset(new SyntheticPointerAction(SyntheticGestureParams::TOUCH_INPUT,
+ SyntheticGesture::PRESS,
+ &synthetic_pointer, position));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ pointer_touch_target =
+ static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart);
+ EXPECT_EQ(pointer_touch_target->indexes(1), 1);
+ EXPECT_EQ(pointer_touch_target->positions(1), position);
+ EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StatePressed);
+ ASSERT_EQ(pointer_touch_target->touch_length(), 2U);
+
+ int index = 1;
+ position.SetPoint(133, 156);
+ gesture.reset(new SyntheticPointerAction(
+ SyntheticGestureParams::TOUCH_INPUT, SyntheticGesture::MOVE,
+ &synthetic_pointer, position, index));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ pointer_touch_target =
+ static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchMove);
+ EXPECT_EQ(pointer_touch_target->positions(1), position);
+ EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateMoved);
+ ASSERT_EQ(pointer_touch_target->touch_length(), 2U);
+
+ gesture.reset(new SyntheticPointerAction(
+ SyntheticGestureParams::TOUCH_INPUT, SyntheticGesture::RELEASE,
+ &synthetic_pointer, position, index));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ pointer_touch_target =
+ static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchEnd);
+ EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateReleased);
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h
index 14724bf67f9..da44ba2e3be 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h
@@ -6,7 +6,6 @@
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_H_
#include "base/time/time.h"
-#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/common/content_export.h"
#include "content/common/input/synthetic_gesture_params.h"
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
index aca0ab677c7..475f6c112a9 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
@@ -44,8 +44,10 @@ void SyntheticGestureTargetAndroid::TouchSetScrollDeltas(
env, touch_event_synthesizer_.obj(), x, y, dx, dy);
}
-void SyntheticGestureTargetAndroid::TouchInject(
- JNIEnv* env, Action action, int pointer_count, int64 time_in_ms) {
+void SyntheticGestureTargetAndroid::TouchInject(JNIEnv* env,
+ Action action,
+ int pointer_count,
+ int64_t time_in_ms) {
TRACE_EVENT0("input", "SyntheticGestureTargetAndroid::TouchInject");
Java_MotionEventSynthesizer_inject(env, touch_event_synthesizer_.obj(),
static_cast<int>(action), pointer_count,
@@ -81,7 +83,7 @@ void SyntheticGestureTargetAndroid::DispatchWebTouchEventToPlatform(
}
TouchInject(env, action, num_touches,
- static_cast<int64>(web_touch.timeStampSeconds * 1000.0));
+ static_cast<int64_t>(web_touch.timeStampSeconds * 1000.0));
}
void SyntheticGestureTargetAndroid::DispatchWebMouseWheelEventToPlatform(
@@ -91,8 +93,8 @@ void SyntheticGestureTargetAndroid::DispatchWebMouseWheelEventToPlatform(
web_wheel.deltaY);
Java_MotionEventSynthesizer_inject(
env, touch_event_synthesizer_.obj(),
- static_cast<int>(SyntheticGestureTargetAndroid::ActionScroll),
- 1, static_cast<int64>(web_wheel.timeStampSeconds * 1000.0));
+ static_cast<int>(SyntheticGestureTargetAndroid::ActionScroll), 1,
+ static_cast<int64_t>(web_wheel.timeStampSeconds * 1000.0));
}
void SyntheticGestureTargetAndroid::DispatchWebMouseEventToPlatform(
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h
index aa1236d63b4..1e00539fd29 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.h
@@ -5,7 +5,10 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_ANDROID_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_ANDROID_H_
+#include <stdint.h>
+
#include "base/android/jni_android.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
@@ -57,7 +60,7 @@ class SyntheticGestureTargetAndroid : public SyntheticGestureTargetBase {
void TouchInject(JNIEnv* env,
Action action,
int pointer_count,
- int64 time_in_ms);
+ int64_t time_in_ms);
base::android::ScopedJavaGlobalRef<jobject> touch_event_synthesizer_;
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
index 8bcda99627d..d7b47ba423c 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
+#include <stddef.h>
+
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/renderer_host/ui_events_helper.h"
@@ -57,10 +59,12 @@ void SyntheticGestureTargetAura::DispatchWebTouchEventToPlatform(
void SyntheticGestureTargetAura::DispatchWebMouseWheelEventToPlatform(
const blink::WebMouseWheelEvent& web_wheel,
const ui::LatencyInfo&) {
+ ui::MouseEvent mouse_event(ui::ET_MOUSEWHEEL, gfx::Point(), gfx::Point(),
+ ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
gfx::PointF location(web_wheel.x * device_scale_factor_,
web_wheel.y * device_scale_factor_);
- ui::MouseEvent mouse_event(ui::ET_MOUSEWHEEL, location, location,
- ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
+ mouse_event.set_location_f(location);
+ mouse_event.set_root_location_f(location);
ui::MouseWheelEvent wheel_event(
mouse_event, web_wheel.deltaX, web_wheel.deltaY);
@@ -126,12 +130,14 @@ int WebMouseEventButtonToFlags(blink::WebMouseEvent::Button button) {
void SyntheticGestureTargetAura::DispatchWebMouseEventToPlatform(
const blink::WebMouseEvent& web_mouse,
const ui::LatencyInfo& latency_info) {
- gfx::PointF location(web_mouse.x * device_scale_factor_,
- web_mouse.y * device_scale_factor_);
ui::EventType event_type = WebMouseEventTypeToEventType(web_mouse.type);
int flags = WebMouseEventButtonToFlags(web_mouse.button);
- ui::MouseEvent mouse_event(event_type, location, location,
+ ui::MouseEvent mouse_event(event_type, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), flags, flags);
+ gfx::PointF location(web_mouse.x * device_scale_factor_,
+ web_mouse.y * device_scale_factor_);
+ mouse_event.set_location_f(location);
+ mouse_event.set_root_location_f(location);
aura::Window* window = GetWindow();
mouse_event.ConvertLocationToTarget(window, window->GetRootWindow());
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
index 42303f271bf..a4964bab259 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_AURA_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_AURA_H_
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
#include "content/common/input/synthetic_gesture_params.h"
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h
index 8063ae00683..3d01549cbd3 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_BASE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_BASE_H_
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_mac.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_mac.h
index 87b2939bf68..4ecf50fbd15 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_mac.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_mac.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_MAC_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_MAC_H_
+#include "base/macros.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
#include "content/common/input/synthetic_gesture_params.h"
diff --git a/chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.cc b/chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.cc
new file mode 100644
index 00000000000..042603fe5fb
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.cc
@@ -0,0 +1,49 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/synthetic_mouse_pointer.h"
+
+#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+
+namespace content {
+
+SyntheticMousePointer::SyntheticMousePointer() {}
+
+SyntheticMousePointer::~SyntheticMousePointer() {}
+
+void SyntheticMousePointer::DispatchEvent(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ mouse_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
+ target->DispatchInputEventToPlatform(mouse_event_);
+}
+
+int SyntheticMousePointer::Press(float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ mouse_event_ = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::MouseDown, x, y, 0);
+ mouse_event_.clickCount = 1;
+ return 0;
+}
+
+void SyntheticMousePointer::Move(int index,
+ float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ mouse_event_ = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::MouseMove, x, y, 0);
+ mouse_event_.button = blink::WebMouseEvent::ButtonLeft;
+}
+
+void SyntheticMousePointer::Release(int index,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ mouse_event_ = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::MouseUp, mouse_event_.x, mouse_event_.y, 0);
+ mouse_event_.clickCount = 1;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.h b/chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.h
new file mode 100644
index 00000000000..9f806f3b5f8
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_mouse_pointer.h
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_MOUSE_POINTER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_MOUSE_POINTER_H_
+
+#include "base/macros.h"
+#include "content/browser/renderer_host/input/synthetic_pointer.h"
+#include "content/common/content_export.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
+
+namespace content {
+
+class CONTENT_EXPORT SyntheticMousePointer : public SyntheticPointer {
+ public:
+ SyntheticMousePointer();
+ ~SyntheticMousePointer() override;
+
+ void DispatchEvent(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+
+ int Press(float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+ void Move(int index,
+ float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+ void Release(int index,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+
+ private:
+ SyntheticGestureParams::GestureSourceType gesture_source_type_;
+ blink::WebMouseEvent mouse_event_;
+ DISALLOW_COPY_AND_ASSIGN(SyntheticMousePointer);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_MOUSE_POINTER_H_
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.h
index e0444438244..970bd87d576 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_PINCH_GESTURE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_PINCH_GESTURE_H_
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer.cc b/chromium/content/browser/renderer_host/input/synthetic_pointer.cc
new file mode 100644
index 00000000000..29228fceb0b
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer.cc
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/synthetic_pointer.h"
+
+#include "content/browser/renderer_host/input/synthetic_mouse_pointer.h"
+#include "content/browser/renderer_host/input/synthetic_touch_pointer.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+
+namespace content {
+
+SyntheticPointer::SyntheticPointer() {}
+SyntheticPointer::~SyntheticPointer() {}
+
+// static
+scoped_ptr<SyntheticPointer> SyntheticPointer::Create(
+ SyntheticGestureParams::GestureSourceType gesture_source_type) {
+ if (gesture_source_type == SyntheticGestureParams::TOUCH_INPUT) {
+ return make_scoped_ptr(new SyntheticTouchPointer());
+ } else if (gesture_source_type == SyntheticGestureParams::MOUSE_INPUT) {
+ return make_scoped_ptr(new SyntheticMousePointer());
+ } else {
+ NOTREACHED() << "Invalid gesture source type";
+ return scoped_ptr<SyntheticPointer>();
+ }
+}
+
+// static
+double SyntheticPointer::ConvertTimestampToSeconds(
+ const base::TimeTicks& timestamp) {
+ return (timestamp - base::TimeTicks()).InSecondsF();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer.h b/chromium/content/browser/renderer_host/input/synthetic_pointer.h
new file mode 100644
index 00000000000..ae4fd35bab5
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer.h
@@ -0,0 +1,51 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_POINTER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_POINTER_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/common/content_export.h"
+#include "content/common/input/synthetic_gesture_params.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
+
+namespace content {
+
+class SyntheticGestureTarget;
+
+class CONTENT_EXPORT SyntheticPointer {
+ public:
+ SyntheticPointer();
+ virtual ~SyntheticPointer();
+
+ static scoped_ptr<SyntheticPointer> Create(
+ SyntheticGestureParams::GestureSourceType gesture_source_type);
+
+ virtual void DispatchEvent(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) = 0;
+
+ virtual int Press(float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) = 0;
+ virtual void Move(int index,
+ float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) = 0;
+ virtual void Release(int index,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) = 0;
+
+ protected:
+ static double ConvertTimestampToSeconds(const base::TimeTicks& timestamp);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyntheticPointer);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_POINTER_H_
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
new file mode 100644
index 00000000000..2577e3f5497
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
@@ -0,0 +1,58 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/synthetic_pointer_action.h"
+
+#include "base/logging.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/events/latency_info.h"
+
+namespace content {
+
+SyntheticPointerAction::SyntheticPointerAction(
+ SyntheticGestureParams::GestureSourceType gesture_source_type,
+ PointerActionType pointer_action_type,
+ SyntheticPointer* synthetic_pointer,
+ gfx::PointF position,
+ int index)
+ : gesture_source_type_(gesture_source_type),
+ pointer_action_type_(pointer_action_type),
+ position_(position),
+ index_(index),
+ synthetic_pointer_(synthetic_pointer) {}
+
+SyntheticPointerAction::~SyntheticPointerAction() {}
+
+SyntheticGesture::Result SyntheticPointerAction::ForwardInputEvents(
+ const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target) {
+ if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT)
+ gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType();
+
+ DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
+
+ ForwardTouchOrMouseInputEvents(timestamp, target);
+ return SyntheticGesture::GESTURE_FINISHED;
+}
+
+void SyntheticPointerAction::ForwardTouchOrMouseInputEvents(
+ const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target) {
+ switch (pointer_action_type_) {
+ case SyntheticGesture::PRESS:
+ synthetic_pointer_->Press(position_.x(), position_.y(), target,
+ timestamp);
+ break;
+ case SyntheticGesture::MOVE:
+ synthetic_pointer_->Move(index_, position_.x(), position_.y(), target,
+ timestamp);
+ break;
+ case SyntheticGesture::RELEASE:
+ synthetic_pointer_->Release(index_, target, timestamp);
+ break;
+ }
+ synthetic_pointer_->DispatchEvent(target, timestamp);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.h b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.h
new file mode 100644
index 00000000000..d1907764c8a
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_POINTER_ACTION_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_POINTER_ACTION_H_
+
+#include "base/macros.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_pointer.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class CONTENT_EXPORT SyntheticPointerAction : public SyntheticGesture {
+ public:
+ SyntheticPointerAction(
+ SyntheticGestureParams::GestureSourceType gesture_source_type,
+ PointerActionType pointer_action_type,
+ SyntheticPointer* synthetic_pointer,
+ gfx::PointF position,
+ int index = 0);
+ ~SyntheticPointerAction() override;
+
+ SyntheticGesture::Result ForwardInputEvents(
+ const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target) override;
+
+ void ForwardTouchOrMouseInputEvents(const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target);
+
+ private:
+ SyntheticGestureParams::GestureSourceType gesture_source_type_;
+ PointerActionType pointer_action_type_;
+ gfx::PointF position_;
+ int index_;
+ SyntheticPointer* synthetic_pointer_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyntheticPointerAction);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_POINTER_ACTION_H_
diff --git a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
index 80f3ef76c66..3ddb0a34caf 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/input/synthetic_smooth_move_gesture.h"
+#include <stdint.h>
+
#include "base/logging.h"
#include "ui/gfx/geometry/point_f.h"
@@ -27,6 +29,10 @@ gfx::Vector2dF ProjectScalarOntoVector(float scalar,
return gfx::ScaleVector2d(vector, scalar / vector.Length());
}
+double ConvertTimestampToSeconds(const base::TimeTicks& timestamp) {
+ return (timestamp - base::TimeTicks()).InSecondsF();
+}
+
const int kDefaultSpeedInPixelsPerSec = 800;
} // namespace
@@ -58,9 +64,15 @@ SyntheticGesture::Result SyntheticSmoothMoveGesture::ForwardInputEvents(
switch (params_.input_type) {
case SyntheticSmoothMoveGestureParams::TOUCH_INPUT:
+ if (!synthetic_pointer_)
+ synthetic_pointer_ =
+ SyntheticPointer::Create(SyntheticGestureParams::TOUCH_INPUT);
ForwardTouchInputEvents(timestamp, target);
break;
case SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT:
+ if (!synthetic_pointer_)
+ synthetic_pointer_ =
+ SyntheticPointer::Create(SyntheticGestureParams::MOUSE_INPUT);
ForwardMouseClickInputEvents(timestamp, target);
break;
case SyntheticSmoothMoveGestureParams::MOUSE_WHEEL_INPUT:
@@ -92,13 +104,13 @@ void SyntheticSmoothMoveGesture::ForwardTouchInputEvents(
if (params_.add_slop)
AddTouchSlopToFirstDistance(target);
ComputeNextMoveSegment();
- PressTouchPoint(target, event_timestamp);
+ PressPoint(target, event_timestamp);
state_ = MOVING;
break;
case MOVING: {
event_timestamp = ClampTimestamp(timestamp);
gfx::Vector2dF delta = GetPositionDeltaAtTime(event_timestamp);
- MoveTouchPoint(target, delta, event_timestamp);
+ MovePoint(target, delta, event_timestamp);
if (FinishedCurrentMoveSegment(event_timestamp)) {
if (!IsLastMoveSegment()) {
@@ -108,7 +120,7 @@ void SyntheticSmoothMoveGesture::ForwardTouchInputEvents(
} else if (params_.prevent_fling) {
state_ = STOPPING;
} else {
- ReleaseTouchPoint(target, event_timestamp);
+ ReleasePoint(target, event_timestamp);
state_ = DONE;
}
}
@@ -118,7 +130,7 @@ void SyntheticSmoothMoveGesture::ForwardTouchInputEvents(
target->PointerAssumedStoppedTime()) {
event_timestamp = current_move_segment_stop_time_ +
target->PointerAssumedStoppedTime();
- ReleaseTouchPoint(target, event_timestamp);
+ ReleasePoint(target, event_timestamp);
state_ = DONE;
}
break;
@@ -191,13 +203,13 @@ void SyntheticSmoothMoveGesture::ForwardMouseClickInputEvents(
break;
}
ComputeNextMoveSegment();
- PressMousePoint(target, event_timestamp);
+ PressPoint(target, event_timestamp);
state_ = MOVING;
break;
case MOVING: {
base::TimeTicks event_timestamp = ClampTimestamp(timestamp);
gfx::Vector2dF delta = GetPositionDeltaAtTime(event_timestamp);
- MoveMousePoint(target, delta, event_timestamp);
+ MovePoint(target, delta, event_timestamp);
if (FinishedCurrentMoveSegment(event_timestamp)) {
if (!IsLastMoveSegment()) {
@@ -205,7 +217,7 @@ void SyntheticSmoothMoveGesture::ForwardMouseClickInputEvents(
params_.distances[current_move_segment_];
ComputeNextMoveSegment();
} else {
- ReleaseMousePoint(target, event_timestamp);
+ ReleasePoint(target, event_timestamp);
state_ = DONE;
}
}
@@ -222,20 +234,13 @@ void SyntheticSmoothMoveGesture::ForwardMouseClickInputEvents(
}
}
-void SyntheticSmoothMoveGesture::ForwardTouchEvent(
- SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp) {
- touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
-
- target->DispatchInputEventToPlatform(touch_event_);
-}
-
void SyntheticSmoothMoveGesture::ForwardMouseWheelEvent(
SyntheticGestureTarget* target,
const gfx::Vector2dF& delta,
const base::TimeTicks& timestamp) const {
blink::WebMouseWheelEvent mouse_wheel_event =
- SyntheticWebMouseWheelEventBuilder::Build(delta.x(), delta.y(), 0, false);
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, delta.x(), delta.y(), 0,
+ false);
mouse_wheel_event.x = current_move_segment_start_position_.x();
mouse_wheel_event.y = current_move_segment_start_position_.y();
@@ -245,74 +250,39 @@ void SyntheticSmoothMoveGesture::ForwardMouseWheelEvent(
target->DispatchInputEventToPlatform(mouse_wheel_event);
}
-void SyntheticSmoothMoveGesture::PressTouchPoint(
- SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp) {
+void SyntheticSmoothMoveGesture::PressPoint(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
DCHECK_EQ(current_move_segment_, 0);
- touch_event_.PressPoint(current_move_segment_start_position_.x(),
- current_move_segment_start_position_.y());
- ForwardTouchEvent(target, timestamp);
+ synthetic_pointer_->Press(current_move_segment_start_position_.x(),
+ current_move_segment_start_position_.y(), target,
+ timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
}
-void SyntheticSmoothMoveGesture::MoveTouchPoint(
- SyntheticGestureTarget* target,
- const gfx::Vector2dF& delta,
- const base::TimeTicks& timestamp) {
+void SyntheticSmoothMoveGesture::MovePoint(SyntheticGestureTarget* target,
+ const gfx::Vector2dF& delta,
+ const base::TimeTicks& timestamp) {
DCHECK_GE(current_move_segment_, 0);
DCHECK_LT(current_move_segment_, static_cast<int>(params_.distances.size()));
- gfx::PointF touch_position = current_move_segment_start_position_ + delta;
- touch_event_.MovePoint(0, touch_position.x(), touch_position.y());
- ForwardTouchEvent(target, timestamp);
+ gfx::PointF new_position = current_move_segment_start_position_ + delta;
+ synthetic_pointer_->Move(0, new_position.x(), new_position.y(), target,
+ timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
}
-void SyntheticSmoothMoveGesture::ReleaseTouchPoint(
+void SyntheticSmoothMoveGesture::ReleasePoint(
SyntheticGestureTarget* target,
const base::TimeTicks& timestamp) {
DCHECK_EQ(current_move_segment_,
static_cast<int>(params_.distances.size()) - 1);
- touch_event_.ReleasePoint(0);
- ForwardTouchEvent(target, timestamp);
-}
-
-void SyntheticSmoothMoveGesture::PressMousePoint(
- SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp) {
- DCHECK_EQ(params_.input_type,
- SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT);
- blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build(
- blink::WebInputEvent::MouseDown, current_move_segment_start_position_.x(),
- current_move_segment_start_position_.y(), 0);
- mouse_event.clickCount = 1;
- mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(mouse_event);
-}
-
-void SyntheticSmoothMoveGesture::ReleaseMousePoint(
- SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp) {
- DCHECK_EQ(params_.input_type,
- SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT);
- gfx::PointF mouse_position =
- current_move_segment_start_position_ + GetPositionDeltaAtTime(timestamp);
- blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build(
- blink::WebInputEvent::MouseUp, mouse_position.x(), mouse_position.y(), 0);
- mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(mouse_event);
-}
-
-void SyntheticSmoothMoveGesture::MoveMousePoint(
- SyntheticGestureTarget* target,
- const gfx::Vector2dF& delta,
- const base::TimeTicks& timestamp) {
- gfx::PointF mouse_position = current_move_segment_start_position_ + delta;
- DCHECK_EQ(params_.input_type,
- SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT);
- blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build(
- blink::WebInputEvent::MouseMove, mouse_position.x(), mouse_position.y(),
- 0);
- mouse_event.button = blink::WebMouseEvent::ButtonLeft;
- mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(mouse_event);
+ gfx::PointF position;
+ if (params_.input_type ==
+ SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT) {
+ position = current_move_segment_start_position_ +
+ GetPositionDeltaAtTime(timestamp);
+ }
+ synthetic_pointer_->Release(0, target, timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
}
void SyntheticSmoothMoveGesture::AddTouchSlopToFirstDistance(
@@ -341,7 +311,7 @@ gfx::Vector2dF SyntheticSmoothMoveGesture::GetPositionDeltaAtTime(
void SyntheticSmoothMoveGesture::ComputeNextMoveSegment() {
current_move_segment_++;
DCHECK_LT(current_move_segment_, static_cast<int>(params_.distances.size()));
- int64 total_duration_in_us = static_cast<int64>(
+ int64_t total_duration_in_us = static_cast<int64_t>(
1e6 * (params_.distances[current_move_segment_].Length() /
params_.speed_in_pixels_s));
DCHECK_GT(total_duration_in_us, 0);
diff --git a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h
index 201dfcf8d76..577a8c03e81 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.h
@@ -7,13 +7,14 @@
#include <vector>
+#include "base/macros.h"
#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_pointer.h"
#include "content/common/content_export.h"
#include "content/common/input/synthetic_smooth_drag_gesture_params.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/geometry/vector2d.h"
#include "ui/gfx/geometry/vector2d_f.h"
@@ -69,27 +70,17 @@ class CONTENT_EXPORT SyntheticSmoothMoveGesture : public SyntheticGesture {
void ForwardMouseClickInputEvents(
const base::TimeTicks& timestamp, SyntheticGestureTarget* target);
- void ForwardTouchEvent(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp);
void ForwardMouseWheelEvent(SyntheticGestureTarget* target,
const gfx::Vector2dF& delta,
const base::TimeTicks& timestamp) const;
- void PressTouchPoint(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp);
- void MoveTouchPoint(SyntheticGestureTarget* target,
- const gfx::Vector2dF& delta,
- const base::TimeTicks& timestamp);
- void ReleaseTouchPoint(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp);
-
- void PressMousePoint(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp);
- void ReleaseMousePoint(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp);
- void MoveMousePoint(SyntheticGestureTarget* target,
- const gfx::Vector2dF& delta,
- const base::TimeTicks& timestamp);
+ void PressPoint(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp);
+ void MovePoint(SyntheticGestureTarget* target,
+ const gfx::Vector2dF& delta,
+ const base::TimeTicks& timestamp);
+ void ReleasePoint(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp);
void AddTouchSlopToFirstDistance(SyntheticGestureTarget* target);
gfx::Vector2dF GetPositionDeltaAtTime(const base::TimeTicks& timestamp) const;
@@ -100,11 +91,11 @@ class CONTENT_EXPORT SyntheticSmoothMoveGesture : public SyntheticGesture {
bool MoveIsNoOp() const;
SyntheticSmoothMoveGestureParams params_;
+ scoped_ptr<SyntheticPointer> synthetic_pointer_;
// Used for mouse input.
gfx::Vector2d current_move_segment_total_delta_discrete_;
// Used for touch input.
gfx::PointF current_move_segment_start_position_;
- SyntheticWebTouchEvent touch_event_;
GestureState state_;
int current_move_segment_;
base::TimeTicks current_move_segment_start_time_;
diff --git a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc
index e20412a0fcf..46dc23aeab4 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc
@@ -31,6 +31,10 @@ SyntheticGesture::Result SyntheticTapGesture::ForwardInputEvents(
}
DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
+
+ if (!synthetic_pointer_)
+ synthetic_pointer_ = SyntheticPointer::Create(gesture_source_type_);
+
if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT ||
gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT)
ForwardTouchOrMouseInputEvents(timestamp, target);
@@ -45,10 +49,13 @@ void SyntheticTapGesture::ForwardTouchOrMouseInputEvents(
const base::TimeTicks& timestamp, SyntheticGestureTarget* target) {
switch (state_) {
case PRESS:
- Press(target, timestamp);
+ synthetic_pointer_->Press(params_.position.x(), params_.position.y(),
+ target, timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
// Release immediately if duration is 0.
if (params_.duration_ms == 0) {
- Release(target, timestamp);
+ synthetic_pointer_->Release(0, target, timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
state_ = DONE;
} else {
start_time_ = timestamp;
@@ -57,7 +64,8 @@ void SyntheticTapGesture::ForwardTouchOrMouseInputEvents(
break;
case WAITING_TO_RELEASE:
if (timestamp - start_time_ >= GetDuration()) {
- Release(target, start_time_ + GetDuration());
+ synthetic_pointer_->Release(0, target, start_time_ + GetDuration());
+ synthetic_pointer_->DispatchEvent(target, start_time_ + GetDuration());
state_ = DONE;
}
break;
@@ -68,46 +76,6 @@ void SyntheticTapGesture::ForwardTouchOrMouseInputEvents(
}
}
-void SyntheticTapGesture::Press(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp) {
- if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) {
- touch_event_.PressPoint(params_.position.x(), params_.position.y());
- touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(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;
- mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(mouse_event);
- } else {
- NOTREACHED() << "Invalid gesture source type for synthetic tap gesture.";
- }
-}
-
-void SyntheticTapGesture::Release(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp) {
- if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) {
- touch_event_.ReleasePoint(0);
- touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(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;
- mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(mouse_event);
- } else {
- NOTREACHED() << "Invalid gesture source type for synthetic tap gesture.";
- }
-}
-
base::TimeDelta SyntheticTapGesture::GetDuration() const {
return base::TimeDelta::FromMilliseconds(params_.duration_ms);
}
diff --git a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h
index a42b2dd17ed..4f746306b38 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h
@@ -5,11 +5,12 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TAP_GESTURE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TAP_GESTURE_H_
+#include "base/macros.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_pointer.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 {
@@ -33,15 +34,11 @@ class CONTENT_EXPORT SyntheticTapGesture : public SyntheticGesture {
void ForwardTouchOrMouseInputEvents(const base::TimeTicks& timestamp,
SyntheticGestureTarget* target);
- void Press(SyntheticGestureTarget* target, const base::TimeTicks& timestamp);
- void Release(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp);
-
base::TimeDelta GetDuration() const;
SyntheticTapGestureParams params_;
+ scoped_ptr<SyntheticPointer> synthetic_pointer_;
base::TimeTicks start_time_;
- SyntheticWebTouchEvent touch_event_;
SyntheticGestureParams::GestureSourceType gesture_source_type_;
GestureState state_;
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touch_pointer.cc b/chromium/content/browser/renderer_host/input/synthetic_touch_pointer.cc
new file mode 100644
index 00000000000..ca4637a6711
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_touch_pointer.cc
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/synthetic_touch_pointer.h"
+
+#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+
+namespace content {
+
+SyntheticTouchPointer::SyntheticTouchPointer() {}
+
+SyntheticTouchPointer::SyntheticTouchPointer(SyntheticWebTouchEvent touch_event)
+ : touch_event_(touch_event) {}
+
+SyntheticTouchPointer::~SyntheticTouchPointer() {}
+
+void SyntheticTouchPointer::DispatchEvent(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
+ target->DispatchInputEventToPlatform(touch_event_);
+}
+
+int SyntheticTouchPointer::Press(float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ int index = touch_event_.PressPoint(x, y);
+ return index;
+}
+
+void SyntheticTouchPointer::Move(int index,
+ float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ touch_event_.MovePoint(index, x, y);
+}
+
+void SyntheticTouchPointer::Release(int index,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ touch_event_.ReleasePoint(index);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touch_pointer.h b/chromium/content/browser/renderer_host/input/synthetic_touch_pointer.h
new file mode 100644
index 00000000000..abd579e47d6
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/synthetic_touch_pointer.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TOUCH_POINTER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TOUCH_POINTER_H_
+
+#include "base/macros.h"
+#include "content/browser/renderer_host/input/synthetic_pointer.h"
+#include "content/common/content_export.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
+
+namespace content {
+
+class CONTENT_EXPORT SyntheticTouchPointer : public SyntheticPointer {
+ public:
+ SyntheticTouchPointer();
+ explicit SyntheticTouchPointer(SyntheticWebTouchEvent touch_event);
+ ~SyntheticTouchPointer() override;
+
+ void DispatchEvent(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+
+ int Press(float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+ void Move(int index,
+ float x,
+ float y,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+ void Release(int index,
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) override;
+
+ private:
+ SyntheticWebTouchEvent touch_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyntheticTouchPointer);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_INPUT_SYNTHETIC_TOUCH_POINTER_H_
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc
index 0bf75acb6a6..c47694a1e75 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h"
namespace content {
@@ -129,9 +131,9 @@ void SyntheticTouchpadPinchGesture::CalculateEndTime(
float scale_factor_delta =
(scale_factor - 1.0f) * kPixelsNeededToDoubleOrHalve;
- int64 total_duration_in_us =
- static_cast<int64>(1e6 * (static_cast<double>(scale_factor_delta) /
- params_.relative_pointer_speed_in_pixels_s));
+ int64_t total_duration_in_us =
+ static_cast<int64_t>(1e6 * (static_cast<double>(scale_factor_delta) /
+ params_.relative_pointer_speed_in_pixels_s));
DCHECK_GT(total_duration_in_us, 0);
stop_time_ =
start_time_ + base::TimeDelta::FromMicroseconds(total_duration_in_us);
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h
index b5a88c28514..d2097634e43 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TOUCHPAD_PINCH_GESTURE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TOUCHPAD_PINCH_GESTURE_H_
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc
index b3eb9f061ef..3a317822b9c 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h"
+#include <stdint.h>
+
#include <cmath>
#include "base/logging.h"
@@ -37,6 +39,10 @@ SyntheticGesture::Result SyntheticTouchscreenPinchGesture::ForwardInputEvents(
}
DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
+
+ if (!synthetic_pointer_)
+ synthetic_pointer_ = SyntheticPointer::Create(gesture_source_type_);
+
if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) {
ForwardTouchInputEvents(timestamp, target);
} else {
@@ -80,9 +86,9 @@ void SyntheticTouchscreenPinchGesture::ForwardTouchInputEvents(
void SyntheticTouchscreenPinchGesture::PressTouchPoints(
SyntheticGestureTarget* target,
const base::TimeTicks& timestamp) {
- touch_event_.PressPoint(params_.anchor.x(), start_y_0_);
- touch_event_.PressPoint(params_.anchor.x(), start_y_1_);
- ForwardTouchEvent(target, timestamp);
+ synthetic_pointer_->Press(params_.anchor.x(), start_y_0_, target, timestamp);
+ synthetic_pointer_->Press(params_.anchor.x(), start_y_1_, target, timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
}
void SyntheticTouchscreenPinchGesture::MoveTouchPoints(
@@ -93,24 +99,19 @@ void SyntheticTouchscreenPinchGesture::MoveTouchPoints(
float current_y_0 = start_y_0_ + delta;
float current_y_1 = start_y_1_ - delta;
- touch_event_.MovePoint(0, params_.anchor.x(), current_y_0);
- touch_event_.MovePoint(1, params_.anchor.x(), current_y_1);
- ForwardTouchEvent(target, timestamp);
+ synthetic_pointer_->Move(0, params_.anchor.x(), current_y_0, target,
+ timestamp);
+ synthetic_pointer_->Move(1, params_.anchor.x(), current_y_1, target,
+ timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
}
void SyntheticTouchscreenPinchGesture::ReleaseTouchPoints(
SyntheticGestureTarget* target,
const base::TimeTicks& timestamp) {
- touch_event_.ReleasePoint(0);
- touch_event_.ReleasePoint(1);
- ForwardTouchEvent(target, timestamp);
-}
-
-void SyntheticTouchscreenPinchGesture::ForwardTouchEvent(
- SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp) {
- touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
- target->DispatchInputEventToPlatform(touch_event_);
+ synthetic_pointer_->Release(0, target, timestamp);
+ synthetic_pointer_->Release(1, target, timestamp);
+ synthetic_pointer_->DispatchEvent(target, timestamp);
}
void SyntheticTouchscreenPinchGesture::SetupCoordinatesAndStopTime(
@@ -137,7 +138,7 @@ void SyntheticTouchscreenPinchGesture::SetupCoordinatesAndStopTime(
max_pointer_delta_0_ = initial_distance_to_anchor - final_distance_to_anchor;
- int64 total_duration_in_us = static_cast<int64>(
+ int64_t total_duration_in_us = static_cast<int64_t>(
1e6 * (static_cast<double>(std::abs(2 * max_pointer_delta_0_)) /
params_.relative_pointer_speed_in_pixels_s));
DCHECK_GT(total_duration_in_us, 0);
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h
index a549db0caad..c42e608a918 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TOUCHSCREEN_PINCH_GESTURE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TOUCHSCREEN_PINCH_GESTURE_H_
+#include "base/macros.h"
#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_pointer.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"
@@ -32,7 +34,6 @@ class CONTENT_EXPORT SyntheticTouchscreenPinchGesture
void ForwardTouchInputEvents(const base::TimeTicks& timestamp,
SyntheticGestureTarget* target);
- void UpdateTouchPoints(const base::TimeTicks& timestamp);
void PressTouchPoints(SyntheticGestureTarget* target,
const base::TimeTicks& timestamp);
void MoveTouchPoints(SyntheticGestureTarget* target,
@@ -40,8 +41,6 @@ class CONTENT_EXPORT SyntheticTouchscreenPinchGesture
const base::TimeTicks& timestamp);
void ReleaseTouchPoints(SyntheticGestureTarget* target,
const base::TimeTicks& timestamp);
- void ForwardTouchEvent(SyntheticGestureTarget* target,
- const base::TimeTicks& timestamp);
void SetupCoordinatesAndStopTime(SyntheticGestureTarget* target);
float GetDeltaForPointer0AtTime(const base::TimeTicks& timestamp) const;
@@ -49,12 +48,12 @@ class CONTENT_EXPORT SyntheticTouchscreenPinchGesture
bool HasReachedTarget(const base::TimeTicks& timestamp) const;
SyntheticPinchGestureParams params_;
+ scoped_ptr<SyntheticPointer> synthetic_pointer_;
float start_y_0_;
float start_y_1_;
float max_pointer_delta_0_;
SyntheticGestureParams::GestureSourceType gesture_source_type_;
GestureState state_;
- SyntheticWebTouchEvent touch_event_;
base::TimeTicks start_time_;
base::TimeTicks stop_time_;
diff --git a/chromium/content/browser/renderer_host/input/tap_suppression_controller.h b/chromium/content/browser/renderer_host/input/tap_suppression_controller.h
index bec962a0507..dc0def55e03 100644
--- a/chromium/content/browser/renderer_host/input/tap_suppression_controller.h
+++ b/chromium/content/browser/renderer_host/input/tap_suppression_controller.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_
+#include "base/macros.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/input/tap_suppression_controller_client.h b/chromium/content/browser/renderer_host/input/tap_suppression_controller_client.h
index 075fa08d3b5..d55613c9014 100644
--- a/chromium/content/browser/renderer_host/input/tap_suppression_controller_client.h
+++ b/chromium/content/browser/renderer_host/input/tap_suppression_controller_client.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_CLIENT_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_CLIENT_H_
+#include "base/macros.h"
+
namespace content {
// This class provides an interface for callbacks made by
diff --git a/chromium/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc b/chromium/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
index 0c2e94f07e0..c8e30c90db9 100644
--- a/chromium/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/tap_suppression_controller_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 "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/input/tap_suppression_controller.h"
#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
diff --git a/chromium/content/browser/renderer_host/input/timeout_monitor.h b/chromium/content/browser/renderer_host/input/timeout_monitor.h
index 4cccbec2521..f2d96f259ac 100644
--- a/chromium/content/browser/renderer_host/input/timeout_monitor.h
+++ b/chromium/content/browser/renderer_host/input/timeout_monitor.h
@@ -5,8 +5,8 @@
#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/macros.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
index 02d53e8a4cf..72c8bc99086 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.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"
@@ -74,8 +78,8 @@ class TouchActionBrowserTest : public ContentBrowserTest {
~TouchActionBrowserTest() override {}
RenderWidgetHostImpl* GetWidgetHost() {
- return RenderWidgetHostImpl::From(shell()->web_contents()->
- GetRenderViewHost());
+ return RenderWidgetHostImpl::From(
+ shell()->web_contents()->GetRenderViewHost()->GetWidget());
}
void OnSyntheticGestureCompleted(SyntheticGesture::Result result) {
@@ -138,7 +142,7 @@ class TouchActionBrowserTest : public ContentBrowserTest {
SyntheticSmoothScrollGestureParams params;
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
- params.anchor = point;
+ params.anchor = gfx::PointF(point);
params.distances.push_back(-distance);
runner_ = new MessageLoopRunner();
@@ -146,7 +150,7 @@ class TouchActionBrowserTest : public ContentBrowserTest {
scoped_ptr<SyntheticSmoothScrollGesture> gesture(
new SyntheticSmoothScrollGesture(params));
GetWidgetHost()->QueueSyntheticGesture(
- gesture.Pass(),
+ std::move(gesture),
base::Bind(&TouchActionBrowserTest::OnSyntheticGestureCompleted,
base::Unretained(this)));
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.cc b/chromium/content/browser/renderer_host/input/touch_action_filter.cc
index b12f283c3e1..75523f1e7c2 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter.cc
@@ -87,8 +87,7 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
case WebInputEvent::GesturePinchBegin:
DCHECK(!drop_pinch_gesture_events_);
- if (allowed_touch_action_ == TOUCH_ACTION_AUTO ||
- allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) {
+ if (allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) {
// Pinch events are always bracketed by scroll events, and the W3C
// standard touch-action provides no way to disable scrolling without
// also disabling pinching (validated by the IPC ENUM traits).
@@ -124,7 +123,7 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
case WebInputEvent::GestureTapUnconfirmed:
DCHECK_EQ(1, gesture_event->data.tap.tapCount);
allow_current_double_tap_event_ =
- allowed_touch_action_ == TOUCH_ACTION_AUTO;
+ (allowed_touch_action_ & TOUCH_ACTION_DOUBLE_TAP_ZOOM) != 0;
if (!allow_current_double_tap_event_) {
gesture_event->type = WebInputEvent::GestureTap;
drop_current_tap_ending_event_ = true;
@@ -133,7 +132,7 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
case WebInputEvent::GestureTap:
allow_current_double_tap_event_ =
- allowed_touch_action_ == TOUCH_ACTION_AUTO;
+ (allowed_touch_action_ & TOUCH_ACTION_DOUBLE_TAP_ZOOM) != 0;
// Fall through.
case WebInputEvent::GestureTapCancel:
if (drop_current_tap_ending_event_) {
@@ -176,7 +175,7 @@ void TouchActionFilter::OnSetTouchAction(TouchAction touch_action) {
// down "at once" will be deterministic.
// 2. Only subtractive - eg. can't trigger scrolling on a element that
// otherwise has scrolling disabling by the addition of a finger.
- allowed_touch_action_ = Intersect(allowed_touch_action_, touch_action);
+ allowed_touch_action_ &= touch_action;
}
void TouchActionFilter::ResetTouchAction() {
@@ -188,9 +187,11 @@ void TouchActionFilter::ResetTouchAction() {
bool TouchActionFilter::ShouldSuppressScroll(
const blink::WebGestureEvent& gesture_event) {
DCHECK_EQ(gesture_event.type, WebInputEvent::GestureScrollBegin);
- if (allowed_touch_action_ == TOUCH_ACTION_AUTO)
+ if ((allowed_touch_action_ & TOUCH_ACTION_PAN) == TOUCH_ACTION_PAN)
+ // All possible panning is enabled.
return false;
- if (allowed_touch_action_ == TOUCH_ACTION_NONE)
+ if (!(allowed_touch_action_ & TOUCH_ACTION_PAN))
+ // No panning is enabled.
return true;
// If there's no hint or it's perfectly diagonal, then allow the scroll.
@@ -224,18 +225,4 @@ bool TouchActionFilter::ShouldSuppressScroll(
}
}
-TouchAction TouchActionFilter::Intersect(TouchAction ta1, TouchAction ta2) {
- if (ta1 == TOUCH_ACTION_NONE || ta2 == TOUCH_ACTION_NONE)
- return TOUCH_ACTION_NONE;
- if (ta1 == TOUCH_ACTION_AUTO)
- return ta2;
- if (ta2 == TOUCH_ACTION_AUTO)
- return ta1;
-
- // Only the true flags are left - take their intersection.
- if (!(ta1 & ta2))
- return TOUCH_ACTION_NONE;
- return static_cast<TouchAction>(ta1 & ta2);
-}
-
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.h b/chromium/content/browser/renderer_host/input/touch_action_filter.h
index 4e27eaaa668..34e32d5abbf 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter.h
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter.h
@@ -5,7 +5,7 @@
#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 "base/macros.h"
#include "content/common/content_export.h"
#include "content/common/input/touch_action.h"
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc
index c435d1e67e8..a114b79f7db 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -299,7 +299,7 @@ TEST(TouchActionFilterTest, PanXY) {
{
// Scrolls hinted in the X axis are permitted and unmodified.
filter.ResetTouchAction();
- filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+ filter.OnSetTouchAction(TOUCH_ACTION_PAN);
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6);
EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
@@ -321,7 +321,7 @@ TEST(TouchActionFilterTest, PanXY) {
{
// Scrolls hinted in the Y axis are permitted and unmodified.
filter.ResetTouchAction();
- filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+ filter.OnSetTouchAction(TOUCH_ACTION_PAN);
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7);
EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
@@ -342,25 +342,17 @@ TEST(TouchActionFilterTest, PanXY) {
filter.ResetTouchAction();
}
-TEST(TouchActionFilterTest, Intersect) {
- EXPECT_EQ(TOUCH_ACTION_NONE,
- TouchActionFilter::Intersect(TOUCH_ACTION_NONE, TOUCH_ACTION_AUTO));
- EXPECT_EQ(TOUCH_ACTION_NONE,
- TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_NONE));
- EXPECT_EQ(TOUCH_ACTION_PAN_X,
- TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_PAN_X));
- EXPECT_EQ(TOUCH_ACTION_PAN_Y,
- TouchActionFilter::Intersect(TOUCH_ACTION_PAN_Y, TOUCH_ACTION_AUTO));
+TEST(TouchActionFilterTest, BitMath) {
+ // Verify that the simple flag mixing properties we depend on are now
+ // trivially true.
+ EXPECT_EQ(TOUCH_ACTION_NONE, TOUCH_ACTION_NONE & TOUCH_ACTION_AUTO);
+ EXPECT_EQ(TOUCH_ACTION_NONE, TOUCH_ACTION_PAN_Y & TOUCH_ACTION_PAN_X);
+ EXPECT_EQ(TOUCH_ACTION_PAN, TOUCH_ACTION_AUTO & TOUCH_ACTION_PAN);
+ EXPECT_EQ(TOUCH_ACTION_MANIPULATION,
+ TOUCH_ACTION_AUTO & ~TOUCH_ACTION_DOUBLE_TAP_ZOOM);
+ EXPECT_EQ(TOUCH_ACTION_PAN_X, TOUCH_ACTION_PAN_LEFT | TOUCH_ACTION_PAN_RIGHT);
EXPECT_EQ(TOUCH_ACTION_AUTO,
- TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_AUTO));
- EXPECT_EQ(TOUCH_ACTION_PAN_X,
- TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X_Y, TOUCH_ACTION_PAN_X));
- EXPECT_EQ(TOUCH_ACTION_PAN_Y,
- TouchActionFilter::Intersect(TOUCH_ACTION_PAN_Y, TOUCH_ACTION_PAN_X_Y));
- EXPECT_EQ(TOUCH_ACTION_PAN_X_Y,
- TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X_Y, TOUCH_ACTION_AUTO));
- EXPECT_EQ(TOUCH_ACTION_NONE,
- TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X, TOUCH_ACTION_PAN_Y));
+ TOUCH_ACTION_MANIPULATION | TOUCH_ACTION_DOUBLE_TAP_ZOOM);
}
TEST(TouchActionFilterTest, MultiTouch) {
@@ -391,7 +383,7 @@ TEST(TouchActionFilterTest, MultiTouch) {
filter.ResetTouchAction();
filter.OnSetTouchAction(TOUCH_ACTION_PAN_X);
filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y);
- filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+ filter.OnSetTouchAction(TOUCH_ACTION_PAN);
EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
@@ -433,7 +425,7 @@ TEST(TouchActionFilterTest, Pinch) {
// Pinch is not allowed with touch-action: pan-x pan-y.
filter.ResetTouchAction();
- filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+ filter.OnSetTouchAction(TOUCH_ACTION_PAN);
EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin));
EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update));
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator.cc b/chromium/content/browser/renderer_host/input/touch_emulator.cc
index 460716d7b06..af8e6031918 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator.cc
+++ b/chromium/content/browser/renderer_host/input/touch_emulator.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/input/touch_emulator.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/input/motion_event_web.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
#include "content/common/input/web_touch_event_traits.h"
@@ -285,7 +286,7 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
return;
case WebInputEvent::GestureScrollBegin:
- client_->ForwardGestureEvent(gesture_event);
+ client_->ForwardEmulatedGestureEvent(gesture_event);
// PinchBegin must always follow ScrollBegin.
if (InPinchGestureMode())
PinchBegin(gesture_event);
@@ -302,7 +303,7 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
// Pass scroll update further. If shift was released, end the pinch.
if (pinch_gesture_active_)
PinchEnd(gesture_event);
- client_->ForwardGestureEvent(gesture_event);
+ client_->ForwardEmulatedGestureEvent(gesture_event);
}
break;
@@ -310,7 +311,7 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
// PinchEnd must precede ScrollEnd.
if (pinch_gesture_active_)
PinchEnd(gesture_event);
- client_->ForwardGestureEvent(gesture_event);
+ client_->ForwardEmulatedGestureEvent(gesture_event);
break;
case WebInputEvent::GestureFlingStart:
@@ -323,20 +324,20 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
ScrollEnd(gesture_event);
} else {
suppress_next_fling_cancel_ = false;
- client_->ForwardGestureEvent(gesture_event);
+ client_->ForwardEmulatedGestureEvent(gesture_event);
}
break;
case WebInputEvent::GestureFlingCancel:
// If fling start was suppressed, we should not send fling cancel either.
if (!suppress_next_fling_cancel_)
- client_->ForwardGestureEvent(gesture_event);
+ client_->ForwardEmulatedGestureEvent(gesture_event);
suppress_next_fling_cancel_ = false;
break;
default:
// Everything else goes through.
- client_->ForwardGestureEvent(gesture_event);
+ client_->ForwardEmulatedGestureEvent(gesture_event);
}
}
@@ -376,7 +377,7 @@ void TouchEmulator::PinchBegin(const WebGestureEvent& event) {
pinch_scale_ = 1.f;
FillPinchEvent(event);
pinch_event_.type = WebInputEvent::GesturePinchBegin;
- client_->ForwardGestureEvent(pinch_event_);
+ client_->ForwardEmulatedGestureEvent(pinch_event_);
}
void TouchEmulator::PinchUpdate(const WebGestureEvent& event) {
@@ -386,7 +387,7 @@ void TouchEmulator::PinchUpdate(const WebGestureEvent& event) {
FillPinchEvent(event);
pinch_event_.type = WebInputEvent::GesturePinchUpdate;
pinch_event_.data.pinchUpdate.scale = scale / pinch_scale_;
- client_->ForwardGestureEvent(pinch_event_);
+ client_->ForwardEmulatedGestureEvent(pinch_event_);
pinch_scale_ = scale;
}
@@ -395,7 +396,7 @@ void TouchEmulator::PinchEnd(const WebGestureEvent& event) {
pinch_gesture_active_ = false;
FillPinchEvent(event);
pinch_event_.type = WebInputEvent::GesturePinchEnd;
- client_->ForwardGestureEvent(pinch_event_);
+ client_->ForwardEmulatedGestureEvent(pinch_event_);
}
void TouchEmulator::FillPinchEvent(const WebInputEvent& event) {
@@ -412,7 +413,7 @@ void TouchEmulator::ScrollEnd(const WebGestureEvent& event) {
scroll_event.modifiers = event.modifiers;
scroll_event.sourceDevice = blink::WebGestureDeviceTouchscreen;
scroll_event.type = WebInputEvent::GestureScrollEnd;
- client_->ForwardGestureEvent(scroll_event);
+ client_->ForwardEmulatedGestureEvent(scroll_event);
}
void TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) {
@@ -446,6 +447,8 @@ void TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) {
point.screenPosition.x = mouse_event.globalX;
point.position.y = mouse_event.y;
point.screenPosition.y = mouse_event.globalY;
+ point.tiltX = 0;
+ point.tiltY = 0;
}
bool TouchEmulator::InPinchGestureMode() const {
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator.h b/chromium/content/browser/renderer_host/input/touch_emulator.h
index e21287f2cac..d02494547a6 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator.h
+++ b/chromium/content/browser/renderer_host/input/touch_emulator.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EMULATOR_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EMULATOR_H_
+#include "base/macros.h"
#include "content/browser/renderer_host/input/touch_emulator_client.h"
#include "content/common/cursors/webcursor.h"
#include "content/common/input/input_event_ack_state.h"
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator_client.h b/chromium/content/browser/renderer_host/input/touch_emulator_client.h
index 7f807368dcb..89ce509ab98 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator_client.h
+++ b/chromium/content/browser/renderer_host/input/touch_emulator_client.h
@@ -16,7 +16,8 @@ class CONTENT_EXPORT TouchEmulatorClient {
public:
virtual ~TouchEmulatorClient() {}
- virtual void ForwardGestureEvent(const blink::WebGestureEvent& event) = 0;
+ virtual void ForwardEmulatedGestureEvent(
+ const blink::WebGestureEvent& event) = 0;
virtual void ForwardEmulatedTouchEvent(const blink::WebTouchEvent& event) = 0;
virtual void SetCursor(const WebCursor& cursor) = 0;
virtual void ShowContextMenuAtPoint(const gfx::Point& point) = 0;
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator_unittest.cc b/chromium/content/browser/renderer_host/input/touch_emulator_unittest.cc
index f46703ca4e8..0062a2f6b52 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_emulator_unittest.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <vector>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
@@ -51,7 +52,8 @@ class TouchEmulatorTest : public testing::Test,
EXPECT_EQ("", ExpectedEvents());
}
- void ForwardGestureEvent(const blink::WebGestureEvent& event) override {
+ void ForwardEmulatedGestureEvent(
+ const blink::WebGestureEvent& event) override {
forwarded_events_.push_back(event.type);
}
diff --git a/chromium/content/browser/renderer_host/input/touch_event_queue.cc b/chromium/content/browser/renderer_host/input/touch_event_queue.cc
index 9de8093dabb..550b46bfc47 100644
--- a/chromium/content/browser/renderer_host/input/touch_event_queue.cc
+++ b/chromium/content/browser/renderer_host/input/touch_event_queue.cc
@@ -4,7 +4,10 @@
#include "content/browser/renderer_host/input/touch_event_queue.h"
+#include <utility>
+
#include "base/auto_reset.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
@@ -56,7 +59,9 @@ bool HasPointChanged(const WebTouchPoint& point_1,
point_1.radiusX != point_2.radiusX ||
point_1.radiusY != point_2.radiusY ||
point_1.rotationAngle != point_2.rotationAngle ||
- point_1.force != point_2.force) {
+ point_1.force != point_2.force ||
+ point_1.tiltX != point_2.tiltX ||
+ point_1.tiltY != point_2.tiltY) {
return true;
}
return false;
@@ -488,7 +493,7 @@ void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result,
const LatencyInfo& latency_info,
- const uint32 unique_touch_event_id) {
+ const uint32_t unique_touch_event_id) {
TRACE_EVENT0("input", "TouchEventQueue::ProcessTouchAck");
// We receive an ack for async touchmove from render.
@@ -616,7 +621,8 @@ void TouchEventQueue::ForwardNextEventToRenderer() {
void TouchEventQueue::FlushPendingAsyncTouchmove() {
DCHECK(!dispatching_touch_);
- scoped_ptr<TouchEventWithLatencyInfo> touch = pending_async_touchmove_.Pass();
+ scoped_ptr<TouchEventWithLatencyInfo> touch =
+ std::move(pending_async_touchmove_);
touch->event.cancelable = false;
touch_queue_.push_front(new CoalescedWebTouchEvent(*touch, true));
SendTouchEventImmediately(touch.get());
@@ -738,7 +744,7 @@ scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() {
DCHECK(!touch_queue_.empty());
scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front());
touch_queue_.pop_front();
- return event.Pass();
+ return event;
}
void TouchEventQueue::SendTouchEventImmediately(
diff --git a/chromium/content/browser/renderer_host/input/touch_event_queue.h b/chromium/content/browser/renderer_host/input/touch_event_queue.h
index 3a4bbdf4355..4b69d98bbcc 100644
--- a/chromium/content/browser/renderer_host/input/touch_event_queue.h
+++ b/chromium/content/browser/renderer_host/input/touch_event_queue.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
@@ -71,7 +74,7 @@ class CONTENT_EXPORT TouchEventQueue {
// more gesture events and/or additional queued touch-events to the renderer.
void ProcessTouchAck(InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
- const uint32 unique_touch_event_id);
+ const uint32_t unique_touch_event_id);
// When GestureScrollBegin is received, we send a touch cancel to renderer,
// route all the following touch events directly to client, and ignore the
@@ -230,7 +233,7 @@ class CONTENT_EXPORT TouchEventQueue {
// uncancelable touchmoves which are still waiting for their acks back from
// render. We do not put them back to the front the touch_event_queue any
// more.
- std::deque<uint32> ack_pending_async_touchmove_ids_;
+ std::deque<uint32_t> ack_pending_async_touchmove_ids_;
double last_sent_touch_timestamp_sec_;
diff --git a/chromium/content/browser/renderer_host/input/touch_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/touch_event_queue_unittest.cc
index e322a5f23f9..f1091d48172 100644
--- a/chromium/content/browser/renderer_host/input/touch_event_queue_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_event_queue_unittest.cc
@@ -2,7 +2,11 @@
// 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 "content/browser/renderer_host/input/touch_event_queue.h"
+
+#include <stddef.h>
+#include <utility>
+
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -10,7 +14,6 @@
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.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 "content/common/input/web_touch_event_traits.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -57,7 +60,7 @@ class TouchEventQueueTest : public testing::Test,
sent_events_.push_back(event.event);
sent_events_ids_.push_back(event.event.uniqueTouchEventId);
if (sync_ack_result_) {
- auto sync_ack_result = sync_ack_result_.Pass();
+ auto sync_ack_result = std::move(sync_ack_result_);
SendTouchEventAck(*sync_ack_result);
}
}
@@ -69,12 +72,12 @@ class TouchEventQueueTest : public testing::Test,
last_acked_event_state_ = ack_result;
if (followup_touch_event_) {
scoped_ptr<WebTouchEvent> followup_touch_event =
- followup_touch_event_.Pass();
+ std::move(followup_touch_event_);
SendTouchEvent(*followup_touch_event);
}
if (followup_gesture_event_) {
scoped_ptr<WebGestureEvent> followup_gesture_event =
- followup_gesture_event_.Pass();
+ std::move(followup_gesture_event_);
queue_->OnGestureScrollEvent(
GestureEventWithLatencyInfo(*followup_gesture_event,
ui::LatencyInfo()));
@@ -297,7 +300,7 @@ class TouchEventQueueTest : public testing::Test,
static void RunTasksAndWait(base::TimeDelta delay) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(), delay);
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), delay);
base::MessageLoop::current()->Run();
}
diff --git a/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
index de959b5b40a..2c68ac71ac2 100644
--- a/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
@@ -5,9 +5,11 @@
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -140,8 +142,8 @@ class TouchInputBrowserTest : public ContentBrowserTest {
~TouchInputBrowserTest() override {}
RenderWidgetHostImpl* GetWidgetHost() {
- return RenderWidgetHostImpl::From(shell()->web_contents()->
- GetRenderViewHost());
+ return RenderWidgetHostImpl::From(
+ shell()->web_contents()->GetRenderViewHost()->GetWidget());
}
InputEventMessageFilter* filter() { return filter_.get(); }
@@ -153,8 +155,8 @@ class TouchInputBrowserTest : public ContentBrowserTest {
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
- RenderWidgetHostImpl* host =
- RenderWidgetHostImpl::From(web_contents->GetRenderViewHost());
+ RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(
+ web_contents->GetRenderViewHost()->GetWidget());
host->GetView()->SetSize(gfx::Size(400, 400));
// The page is loaded in the renderer, wait for a new frame to arrive.
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
index ada3e9f2fc7..88e96636d6b 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
@@ -4,11 +4,13 @@
#include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h"
+#include "base/macros.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/render_widget_host_view_aura.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/common/context_menu_params.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
@@ -116,6 +118,7 @@ TouchSelectionControllerClientAura::TouchSelectionControllerClientAura(
base::Bind(&TouchSelectionControllerClientAura::ShowQuickMenu,
base::Unretained(this)),
false),
+ quick_menu_requested_(false),
touch_down_(false),
scroll_in_progress_(false),
handle_drag_in_progress_(false) {
@@ -151,8 +154,21 @@ void TouchSelectionControllerClientAura::OnScrollCompleted() {
UpdateQuickMenu();
}
-bool TouchSelectionControllerClientAura::IsQuickMenuAllowed() const {
- return !touch_down_ && !scroll_in_progress_ && !handle_drag_in_progress_;
+bool TouchSelectionControllerClientAura::HandleContextMenu(
+ const ContextMenuParams& params) {
+ if (params.source_type == ui::MENU_SOURCE_TOUCH && params.is_editable &&
+ params.selection_text.empty() && IsQuickMenuAvailable()) {
+ quick_menu_requested_ = true;
+ UpdateQuickMenu();
+ return true;
+ }
+ rwhva_->selection_controller()->HideAndDisallowShowingAutomatically();
+ return false;
+}
+
+bool TouchSelectionControllerClientAura::IsQuickMenuAvailable() const {
+ return ui::TouchSelectionMenuRunner::GetInstance() &&
+ ui::TouchSelectionMenuRunner::GetInstance()->IsMenuAvailable(this);
}
void TouchSelectionControllerClientAura::ShowQuickMenu() {
@@ -165,7 +181,7 @@ void TouchSelectionControllerClientAura::ShowQuickMenu() {
// bounds.
gfx::PointF origin = rect.origin();
gfx::PointF bottom_right = rect.bottom_right();
- gfx::Rect client_bounds = rwhva_->GetNativeView()->bounds();
+ auto client_bounds = gfx::RectF(rwhva_->GetNativeView()->bounds());
origin.SetToMax(client_bounds.origin());
bottom_right.SetToMin(client_bounds.bottom_right());
if (origin.x() > bottom_right.x() || origin.y() > bottom_right.y())
@@ -191,9 +207,6 @@ void TouchSelectionControllerClientAura::UpdateQuickMenu() {
bool menu_is_showing =
ui::TouchSelectionMenuRunner::GetInstance() &&
ui::TouchSelectionMenuRunner::GetInstance()->IsRunning();
- bool menu_should_show = rwhva_->selection_controller()->active_status() !=
- ui::TouchSelectionController::INACTIVE &&
- IsQuickMenuAllowed();
// Hide the quick menu if there is any. This should happen even if the menu
// should be shown again, in order to update its location or content.
@@ -202,8 +215,12 @@ void TouchSelectionControllerClientAura::UpdateQuickMenu() {
else
quick_menu_timer_.Stop();
+ bool should_show_menu = quick_menu_requested_ && !touch_down_ &&
+ !scroll_in_progress_ && !handle_drag_in_progress_ &&
+ IsQuickMenuAvailable();
+
// Start timer to show quick menu if necessary.
- if (menu_should_show) {
+ if (should_show_menu) {
if (show_quick_menu_immediately_for_test_)
ShowQuickMenu();
else
@@ -249,6 +266,8 @@ void TouchSelectionControllerClientAura::OnSelectionEvent(
ui::SelectionEventType event) {
switch (event) {
case ui::SELECTION_HANDLES_SHOWN:
+ quick_menu_requested_ = true;
+ // Fall through.
case ui::INSERTION_HANDLE_SHOWN:
UpdateQuickMenu();
env_pre_target_handler_.reset(new EnvPreTargetHandler(
@@ -257,6 +276,7 @@ void TouchSelectionControllerClientAura::OnSelectionEvent(
case ui::SELECTION_HANDLES_CLEARED:
case ui::INSERTION_HANDLE_CLEARED:
env_pre_target_handler_.reset();
+ quick_menu_requested_ = false;
UpdateQuickMenu();
break;
case ui::SELECTION_HANDLE_DRAG_STARTED:
@@ -274,6 +294,9 @@ void TouchSelectionControllerClientAura::OnSelectionEvent(
UpdateQuickMenu();
break;
case ui::INSERTION_HANDLE_TAPPED:
+ quick_menu_requested_ = !quick_menu_requested_;
+ UpdateQuickMenu();
+ break;
case ui::SELECTION_ESTABLISHED:
case ui::SELECTION_DISSOLVED:
break;
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
index bb9dd6665f6..feeefece656 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
@@ -5,12 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_SELECTION_CONTROLLER_CLIENT_AURA_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_SELECTION_CONTROLLER_CLIENT_AURA_H_
+#include "base/macros.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
#include "ui/touch_selection/touch_selection_controller.h"
#include "ui/touch_selection/touch_selection_menu_runner.h"
namespace content {
+struct ContextMenuParams;
class RenderWidgetHostViewAura;
// An implementation of |TouchSelectionControllerClient| to be used in Aura's
@@ -35,11 +37,20 @@ class CONTENT_EXPORT TouchSelectionControllerClientAura
void OnScrollStarted();
void OnScrollCompleted();
+ // Gives an opportunity to the client to handle context menu request and show
+ // the quick menu instead, if appropriate. Returns |true| to indicate that no
+ // further handling is needed.
+ // TODO(mohsen): This is to match Chrome on Android behavior. However, it is
+ // better not to send context menu request from the renderer in this case and
+ // instead decide in the client about showing the quick menu in response to
+ // selection events. (http://crbug.com/548245)
+ bool HandleContextMenu(const ContextMenuParams& params);
+
private:
friend class TestTouchSelectionControllerClientAura;
class EnvPreTargetHandler;
- bool IsQuickMenuAllowed() const;
+ bool IsQuickMenuAvailable() const;
void ShowQuickMenu();
void UpdateQuickMenu();
@@ -62,6 +73,7 @@ class CONTENT_EXPORT TouchSelectionControllerClientAura
RenderWidgetHostViewAura* rwhva_;
base::Timer quick_menu_timer_;
+ bool quick_menu_requested_;
bool touch_down_;
bool scroll_in_progress_;
bool handle_drag_in_progress_;
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
index 999b1cd0b41..b59cc2bd010 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h"
#include "base/json/json_reader.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -46,6 +47,11 @@ class TestTouchSelectionMenuRunner : public ui::TouchSelectionMenuRunner {
~TestTouchSelectionMenuRunner() override {}
private:
+ bool IsMenuAvailable(
+ const ui::TouchSelectionMenuClient* client) const override {
+ return true;
+ }
+
void OpenMenu(ui::TouchSelectionMenuClient* client,
const gfx::Rect& anchor_rect,
const gfx::Size& handle_image_size,
@@ -117,8 +123,8 @@ class TouchSelectionControllerClientAuraTest : public ContentBrowserTest {
// size to the root window. Returns after the navigation to the url is
// complete.
void StartTestWithPage(const std::string& url) {
- ASSERT_TRUE(test_server()->Start());
- GURL test_url(test_server()->GetURL(url));
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL test_url(embedded_test_server()->GetURL(url));
NavigateToURL(shell(), test_url);
aura::Window* content = shell()->web_contents()->GetContentNativeView();
content->GetHost()->SetBounds(gfx::Rect(800, 600));
@@ -142,6 +148,11 @@ class TouchSelectionControllerClientAuraTest : public ContentBrowserTest {
return false;
}
+ bool EmptyTextfield() {
+ return ExecuteScript(shell()->web_contents()->GetMainFrame(),
+ "empty_textfield()");
+ }
+
private:
void SetUpOnMainThread() override {
ContentBrowserTest::SetUpOnMainThread();
@@ -159,11 +170,11 @@ class TouchSelectionControllerClientAuraTest : public ContentBrowserTest {
DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientAuraTest);
};
-// Tests if long-pressing on a text brings up selection handles and the quick
+// Tests that long-pressing on a text brings up selection handles and the quick
// menu properly.
IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicSelection) {
// Set the test page up.
- ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html"));
WebContents* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
@@ -190,17 +201,19 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicSelection) {
selection_controller_client->Wait();
- // Check if selection is active and the quick menu is showing.
+ // Check that selection is active and the quick menu is showing.
EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
rwhva->selection_controller()->active_status());
EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
}
-// Tests if tapping in a textfield brings up the insertion handle and the quick
-// menu properly.
-IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicInsertion) {
+// Tests that tapping in a textfield brings up the insertion handle, but not the
+// quick menu, initially. Then, successive taps on the insertion handle toggle
+// the quick menu visibility.
+IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
+ BasicInsertionFollowedByTapsOnHandle) {
// Set the test page up.
- ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html"));
WebContents* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
@@ -214,10 +227,68 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicInsertion) {
rwhva->selection_controller()->active_status());
EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+ ui::test::EventGeneratorDelegate* generator_delegate =
+ ui::test::EventGenerator::default_delegate;
+ ui::test::EventGenerator generator(
+ web_contents->GetContentNativeView()->GetRootWindow());
+
// Tap inside the textfield and wait for the insertion handle to appear.
selection_controller_client->InitWaitForSelectionEvent(
ui::INSERTION_HANDLE_SHOWN);
+ gfx::PointF point_f;
+ ASSERT_TRUE(GetPointInsideTextfield(&point_f));
+ gfx::Point point = gfx::ToRoundedPoint(point_f);
+ generator_delegate->ConvertPointFromTarget(
+ web_contents->GetContentNativeView(), &point);
+ generator.GestureTapAt(point);
+
+ selection_controller_client->Wait();
+
+ // Check that insertion is active, but the quick menu is not showing.
+ EXPECT_EQ(ui::TouchSelectionController::INSERTION_ACTIVE,
+ rwhva->selection_controller()->active_status());
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+
+ // Tap on the insertion handle; the quick menu should appear.
+ gfx::Point handle_center = gfx::ToRoundedPoint(
+ rwhva->selection_controller()->GetStartHandleRect().CenterPoint());
+ generator_delegate->ConvertPointFromTarget(
+ web_contents->GetContentNativeView(), &handle_center);
+ generator.GestureTapAt(handle_center);
+ EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+
+ // Tap once more on the insertion handle; the quick menu should disappear.
+ generator.GestureTapAt(handle_center);
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+}
+
+// Tests that tapping in an empty textfield does not bring up the insertion
+// handle.
+IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
+ EmptyTextfieldInsertionOnTap) {
+ // Set the test page up.
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html"));
+ WebContents* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
+ web_contents->GetRenderWidgetHostView());
+ TestTouchSelectionControllerClientAura* selection_controller_client =
+ new TestTouchSelectionControllerClientAura(rwhva);
+ rwhva->SetSelectionControllerClientForTest(
+ make_scoped_ptr(selection_controller_client));
+
+ // Clear textfield contents.
+ ASSERT_TRUE(EmptyTextfield());
+
+ EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
+ rwhva->selection_controller()->active_status());
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+
+ // Tap inside the textfield and wait for the insertion cursor.
+ selection_controller_client->InitWaitForSelectionEvent(
+ ui::SELECTION_ESTABLISHED);
+
gfx::PointF point;
ASSERT_TRUE(GetPointInsideTextfield(&point));
ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
@@ -228,17 +299,17 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicInsertion) {
selection_controller_client->Wait();
- // Check if insertion is active and the quick menu is showing.
- EXPECT_EQ(ui::TouchSelectionController::INSERTION_ACTIVE,
+ // Check that insertion is not active and the quick menu is not showing.
+ EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
rwhva->selection_controller()->active_status());
- EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
}
-// Tests if the quick menu is hidden whenever a touch point is active.
+// Tests that the quick menu is hidden whenever a touch point is active.
IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
QuickMenuHiddenOnTouch) {
// Set the test page up.
- ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html"));
WebContents* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
@@ -298,10 +369,10 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
}
-// Tests if the quick menu and touch handles are hidden during an scroll.
+// Tests that the quick menu and touch handles are hidden during an scroll.
IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, HiddenOnScroll) {
// Set the test page up.
- ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html"));
WebContents* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
@@ -337,7 +408,7 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, HiddenOnScroll) {
// Put a finger down: the quick menu should go away, while touch handles stay
// there.
- ui::TouchEvent touch_down(ui::ET_TOUCH_PRESSED, gfx::PointF(10, 10), 0,
+ ui::TouchEvent touch_down(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0,
ui::EventTimeForNow());
rwhva->OnTouchEvent(&touch_down);
EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
@@ -367,7 +438,7 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, HiddenOnScroll) {
EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
// Lift the finger up: the quick menu should re-appear.
- ui::TouchEvent touch_up(ui::ET_TOUCH_RELEASED, gfx::PointF(10, 10), 0,
+ ui::TouchEvent touch_up(ui::ET_TOUCH_RELEASED, gfx::Point(10, 10), 0,
ui::EventTimeForNow());
rwhva->OnTouchEvent(&touch_up);
EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
@@ -376,11 +447,11 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, HiddenOnScroll) {
EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
}
-// Tests if touch selection gets deactivated after an overscroll completes.
+// Tests that touch selection gets deactivated after an overscroll completes.
IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
HiddenAfterOverscroll) {
// Set the page up.
- ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html"));
WebContents* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
diff --git a/chromium/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h b/chromium/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
index 64e5d472e6f..49719639452 100644
--- a/chromium/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
+++ b/chromium/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_TAP_SUPPRESSION_CONTROLLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_TAP_SUPPRESSION_CONTROLLER_H_
+#include "base/macros.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/input/tap_suppression_controller.h"
#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
diff --git a/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc b/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
index 872cfb05b6b..791422d38de 100644
--- a/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
+++ b/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
+#include <utility>
+
#include "content/browser/renderer_host/input/gesture_event_queue.h"
using blink::WebInputEvent;
@@ -63,8 +65,8 @@ void TouchscreenTapSuppressionController::DropStashedTapDown() {
void TouchscreenTapSuppressionController::ForwardStashedTapDown() {
DCHECK(stashed_tap_down_);
- ScopedGestureEvent tap_down = stashed_tap_down_.Pass();
- ScopedGestureEvent show_press = stashed_show_press_.Pass();
+ ScopedGestureEvent tap_down = std::move(stashed_tap_down_);
+ ScopedGestureEvent show_press = std::move(stashed_show_press_);
gesture_event_queue_->ForwardGestureEvent(*tap_down);
if (show_press)
gesture_event_queue_->ForwardGestureEvent(*show_press);
diff --git a/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h b/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
index 35ff274356f..0f07f7290eb 100644
--- a/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
+++ b/chromium/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHSCREEN_TAP_SUPPRESSION_CONTROLLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHSCREEN_TAP_SUPPRESSION_CONTROLLER_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/input/tap_suppression_controller.h"
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc
index 1d240fab8b8..3fb06bb9082 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc
@@ -5,8 +5,8 @@
#include "content/browser/renderer_host/input/web_input_event_builders_android.h"
#include "base/logging.h"
-#include "content/browser/renderer_host/input/motion_event_android.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
+#include "ui/events/android/motion_event_android.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h
index 33d77337e44..5ade65a3cbf 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h
@@ -9,9 +9,11 @@
#include "third_party/WebKit/public/web/WebInputEvent.h"
-namespace content {
-
+namespace ui {
class MotionEventAndroid;
+}
+
+namespace content {
class WebMouseEventBuilder {
public:
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm
index 00d34f87541..82386ed5450 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm
@@ -33,6 +33,8 @@
#import <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
+#include <stdint.h>
+
#include "base/mac/sdk_forward_declarations.h"
#include "base/strings/string_util.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
@@ -117,16 +119,34 @@ bool IsKeyUpEvent(NSEvent* event) {
return false;
}
+inline NSString* FilterSpecialCharacter(NSString* str) {
+ if ([str length] != 1)
+ return str;
+ unichar c = [str characterAtIndex:0];
+ NSString* result = str;
+ if (c == 0x7F) {
+ // Backspace should be 8
+ result = @"\x8";
+ } else if (c >= 0xF700 && c <= 0xF7FF) {
+ // Mac private use characters should be @"\0" (@"" won't work)
+ // NSDeleteFunctionKey will also go into here
+ // Use the range 0xF700~0xF7FF to match
+ // http://www.opensource.apple.com/source/WebCore/WebCore-7601.1.55/platform/mac/KeyEventMac.mm
+ result = @"\0";
+ }
+ return result;
+}
+
inline NSString* TextFromEvent(NSEvent* event) {
if ([event type] == NSFlagsChanged)
return @"";
- return [event characters];
+ return FilterSpecialCharacter([event characters]);
}
inline NSString* UnmodifiedTextFromEvent(NSEvent* event) {
if ([event type] == NSFlagsChanged)
return @"";
- return [event charactersIgnoringModifiers];
+ return FilterSpecialCharacter([event charactersIgnoringModifiers]);
}
NSString* KeyIdentifierForKeyEvent(NSEvent* event) {
@@ -502,7 +522,7 @@ void SetWebEventLocationFromEventInView(blink::WebMouseEvent* result,
result->globalX = screen_local.x;
// Flip y.
NSScreen* primary_screen = ([[NSScreen screens] count] > 0)
- ? [[NSScreen screens] objectAtIndex:0]
+ ? [[NSScreen screens] firstObject]
: nil;
if (primary_screen)
result->globalY = [primary_screen frame].size.height - screen_local.y;
@@ -614,14 +634,6 @@ blink::WebKeyboardEvent WebKeyboardEventBuilder::Build(NSEvent* event) {
unmodified_str = @"\r";
}
- // The adjustments below are only needed in backward compatibility mode,
- // but we cannot tell what mode we are in from here.
-
- // Turn 0x7F into 8, because backspace needs to always be 8.
- if ([text_str isEqualToString:@"\x7F"])
- text_str = @"\x8";
- if ([unmodified_str isEqualToString:@"\x7F"])
- unmodified_str = @"\x8";
// Always use 9 for tab -- we don't want to use AppKit's different character
// for shift-tab.
if (result.windowsKeyCode == 9) {
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
index 2c550651e5c..3c8c5a284b5 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
@@ -4,9 +4,11 @@
#include "content/browser/renderer_host/input/web_input_event_builders_mac.h"
-#import <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
+#import <Cocoa/Cocoa.h>
+#include <stddef.h>
+#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc b/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc
index 9d417016c0d..33701fb1ab2 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_win.cc
@@ -6,6 +6,8 @@
#include "base/logging.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
+#include "ui/events/blink/blink_event_util.h"
+#include "ui/events/event_utils.h"
#include "ui/gfx/win/dpi.h"
using blink::WebInputEvent;
@@ -18,23 +20,14 @@ namespace content {
static const unsigned long kDefaultScrollLinesPerWheelDelta = 3;
static const unsigned long kDefaultScrollCharsPerWheelDelta = 1;
-// Loads the state for toggle keys into the event.
-static void SetToggleKeyState(WebInputEvent* event) {
- // Low bit set from GetKeyState indicates "toggled".
- if (::GetKeyState(VK_NUMLOCK) & 1)
- event->modifiers |= WebInputEvent::NumLockOn;
- if (::GetKeyState(VK_CAPITAL) & 1)
- event->modifiers |= WebInputEvent::CapsLockOn;
-}
-
WebKeyboardEvent WebKeyboardEventBuilder::Build(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam,
- DWORD time_ms) {
+ double time_stamp) {
WebKeyboardEvent result;
- result.timeStampSeconds = time_ms / 1000.0;
+ result.timeStampSeconds = time_stamp;
result.windowsKeyCode = static_cast<int>(wparam);
// Record the scan code (along with other context bits) for this key event.
@@ -69,15 +62,10 @@ WebKeyboardEvent WebKeyboardEventBuilder::Build(HWND hwnd,
result.text[0] = result.windowsKeyCode;
result.unmodifiedText[0] = result.windowsKeyCode;
}
- if (result.type != WebInputEvent::Char)
- result.setKeyIdentifierFromWindowsKeyCode();
+ result.setKeyIdentifierFromWindowsKeyCode();
- if (::GetKeyState(VK_SHIFT) & 0x8000)
- result.modifiers |= WebInputEvent::ShiftKey;
- if (::GetKeyState(VK_CONTROL) & 0x8000)
- result.modifiers |= WebInputEvent::ControlKey;
- if (::GetKeyState(VK_MENU) & 0x8000)
- result.modifiers |= WebInputEvent::AltKey;
+ result.modifiers =
+ ui::EventFlagsToWebEventModifiers(ui::GetModifiersFromKeyState());
// NOTE: There doesn't seem to be a way to query the mouse button state in
// this case.
@@ -87,7 +75,6 @@ WebKeyboardEvent WebKeyboardEventBuilder::Build(HWND hwnd,
if ((result.type == WebInputEvent::RawKeyDown) && (lparam & 0x40000000))
result.modifiers |= WebInputEvent::IsAutoRepeat;
- SetToggleKeyState(&result);
return result;
}
@@ -107,7 +94,7 @@ WebMouseEvent WebMouseEventBuilder::Build(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam,
- DWORD time_ms) {
+ double time_stamp) {
WebMouseEvent result;
switch (message) {
@@ -163,7 +150,7 @@ WebMouseEvent WebMouseEventBuilder::Build(HWND hwnd,
NOTREACHED();
}
- result.timeStampSeconds = time_ms / 1000.0;
+ result.timeStampSeconds = time_stamp;
// set position fields:
@@ -220,13 +207,12 @@ WebMouseEvent WebMouseEventBuilder::Build(HWND hwnd,
result.clickCount = g_last_click_count;
// set modifiers:
-
+ result.modifiers =
+ ui::EventFlagsToWebEventModifiers(ui::GetModifiersFromKeyState());
if (wparam & MK_CONTROL)
result.modifiers |= WebInputEvent::ControlKey;
if (wparam & MK_SHIFT)
result.modifiers |= WebInputEvent::ShiftKey;
- if (::GetKeyState(VK_MENU) & 0x8000)
- result.modifiers |= WebInputEvent::AltKey;
if (wparam & MK_LBUTTON)
result.modifiers |= WebInputEvent::LeftButtonDown;
if (wparam & MK_MBUTTON)
@@ -234,7 +220,6 @@ WebMouseEvent WebMouseEventBuilder::Build(HWND hwnd,
if (wparam & MK_RBUTTON)
result.modifiers |= WebInputEvent::RightButtonDown;
- SetToggleKeyState(&result);
return result;
}
@@ -244,18 +229,16 @@ WebMouseWheelEvent WebMouseWheelEventBuilder::Build(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam,
- DWORD time_ms) {
+ double time_stamp) {
WebMouseWheelEvent result;
result.type = WebInputEvent::MouseWheel;
- result.timeStampSeconds = time_ms / 1000.0;
+ result.timeStampSeconds = time_stamp;
result.button = WebMouseEvent::ButtonNone;
// Get key state, coordinates, and wheel delta from event.
- typedef SHORT (WINAPI *GetKeyStateFunction)(int key);
- GetKeyStateFunction get_key_state_func;
UINT key_state;
float wheel_delta;
bool horizontal_scroll = false;
@@ -263,11 +246,10 @@ WebMouseWheelEvent WebMouseWheelEventBuilder::Build(HWND hwnd,
// Synthesize mousewheel event from a scroll event. This is needed to
// simulate middle mouse scrolling in some laptops. Use GetAsyncKeyState
// for key state since we are synthesizing the input event.
- get_key_state_func = GetAsyncKeyState;
key_state = 0;
- if (get_key_state_func(VK_SHIFT) & 0x8000)
+ if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
key_state |= MK_SHIFT;
- if (get_key_state_func(VK_CONTROL) & 0x8000)
+ if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
key_state |= MK_CONTROL;
// NOTE: There doesn't seem to be a way to query the mouse button state
// in this case.
@@ -301,13 +283,16 @@ WebMouseWheelEvent WebMouseWheelEventBuilder::Build(HWND hwnd,
horizontal_scroll = true;
} else {
// Non-synthesized event; we can just read data off the event.
- get_key_state_func = ::GetKeyState;
key_state = GET_KEYSTATE_WPARAM(wparam);
result.globalX = static_cast<short>(LOWORD(lparam));
result.globalY = static_cast<short>(HIWORD(lparam));
+ // Currently we leave hasPreciseScrollingDeltas false, even for trackpad
+ // scrolls that generate WM_MOUSEWHEEL, since we don't have a good way to
+ // distinguish these from real mouse wheels (crbug.com/545234).
wheel_delta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam));
+
if (message == WM_MOUSEHWHEEL) {
horizontal_scroll = true;
wheel_delta = -wheel_delta; // Windows is <- -/+ ->, WebKit <- +/- ->.
@@ -317,12 +302,12 @@ WebMouseWheelEvent WebMouseWheelEventBuilder::Build(HWND hwnd,
horizontal_scroll = true;
// Set modifiers based on key state.
+ result.modifiers =
+ ui::EventFlagsToWebEventModifiers(ui::GetModifiersFromKeyState());
if (key_state & MK_SHIFT)
result.modifiers |= WebInputEvent::ShiftKey;
if (key_state & MK_CONTROL)
result.modifiers |= WebInputEvent::ControlKey;
- if (get_key_state_func(VK_MENU) & 0x8000)
- result.modifiers |= WebInputEvent::AltKey;
if (key_state & MK_LBUTTON)
result.modifiers |= WebInputEvent::LeftButtonDown;
if (key_state & MK_MBUTTON)
@@ -330,8 +315,6 @@ WebMouseWheelEvent WebMouseWheelEventBuilder::Build(HWND hwnd,
if (key_state & MK_RBUTTON)
result.modifiers |= WebInputEvent::RightButtonDown;
- SetToggleKeyState(&result);
-
// Set coordinates by translating event coordinates from screen to client.
POINT client_point = { result.globalX, result.globalY };
MapWindowPoints(0, hwnd, &client_point, 1);
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_win.h b/chromium/content/browser/renderer_host/input/web_input_event_builders_win.h
index 21aa7d3bf68..8bef1bdbac4 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_win.h
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_win.h
@@ -18,7 +18,7 @@ class CONTENT_EXPORT WebKeyboardEventBuilder {
UINT message,
WPARAM wparam,
LPARAM lparam,
- DWORD time_ms);
+ double time_stamp);
};
class CONTENT_EXPORT WebMouseEventBuilder {
@@ -27,7 +27,7 @@ class CONTENT_EXPORT WebMouseEventBuilder {
UINT message,
WPARAM wparam,
LPARAM lparam,
- DWORD time_ms);
+ double time_stamp);
};
class CONTENT_EXPORT WebMouseWheelEventBuilder {
@@ -36,7 +36,7 @@ class CONTENT_EXPORT WebMouseWheelEventBuilder {
UINT message,
WPARAM wparam,
LPARAM lparam,
- DWORD time_ms);
+ double time_stamp);
};
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_unittest.cc b/chromium/content/browser/renderer_host/input/web_input_event_unittest.cc
index f7814365019..b05608fafef 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/web_input_event_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/events/event_constants.h"
@@ -15,6 +16,7 @@
#endif
using blink::WebMouseEvent;
+using blink::WebMouseWheelEvent;
namespace content {
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_util.cc b/chromium/content/browser/renderer_host/input/web_input_event_util.cc
index 4265577aa11..579e243e274 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_util.cc
+++ b/chromium/content/browser/renderer_host/input/web_input_event_util.cc
@@ -37,15 +37,18 @@ int WebEventModifiersToEventFlags(int modifiers) {
flags |= ui::EF_ALT_DOWN;
if (modifiers & blink::WebInputEvent::MetaKey)
flags |= ui::EF_COMMAND_DOWN;
-
+ if (modifiers & blink::WebInputEvent::CapsLockOn)
+ flags |= ui::EF_CAPS_LOCK_ON;
+ if (modifiers & blink::WebInputEvent::NumLockOn)
+ flags |= ui::EF_NUM_LOCK_ON;
+ if (modifiers & blink::WebInputEvent::ScrollLockOn)
+ flags |= ui::EF_SCROLL_LOCK_ON;
if (modifiers & blink::WebInputEvent::LeftButtonDown)
flags |= ui::EF_LEFT_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::MiddleButtonDown)
flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::RightButtonDown)
flags |= ui::EF_RIGHT_MOUSE_BUTTON;
- if (modifiers & blink::WebInputEvent::CapsLockOn)
- flags |= ui::EF_CAPS_LOCK_DOWN;
if (modifiers & blink::WebInputEvent::IsAutoRepeat)
flags |= ui::EF_IS_REPEAT;
@@ -67,4 +70,112 @@ blink::WebInputEvent::Modifiers DomCodeToWebInputEventModifiers(
return static_cast<blink::WebInputEvent::Modifiers>(0);
}
+// This coversino is temporary. WebInputEvent should be generated
+// directly fromui::Event with the viewport coordinates. See
+// crbug.com/563730.
+scoped_ptr<blink::WebInputEvent> ConvertWebInputEventToViewport(
+ const blink::WebInputEvent& event,
+ float scale) {
+ scoped_ptr<blink::WebInputEvent> scaled_event;
+ if (scale == 1.f)
+ return scaled_event;
+ if (event.type == blink::WebMouseEvent::MouseWheel) {
+ blink::WebMouseWheelEvent* wheel_event = new blink::WebMouseWheelEvent;
+ scaled_event.reset(wheel_event);
+ *wheel_event = static_cast<const blink::WebMouseWheelEvent&>(event);
+ wheel_event->x *= scale;
+ wheel_event->y *= scale;
+ wheel_event->deltaX *= scale;
+ wheel_event->deltaY *= scale;
+ wheel_event->wheelTicksX *= scale;
+ wheel_event->wheelTicksY *= scale;
+ } else if (blink::WebInputEvent::isMouseEventType(event.type)) {
+ blink::WebMouseEvent* mouse_event = new blink::WebMouseEvent;
+ scaled_event.reset(mouse_event);
+ *mouse_event = static_cast<const blink::WebMouseEvent&>(event);
+ mouse_event->x *= scale;
+ mouse_event->y *= scale;
+ mouse_event->windowX = mouse_event->x;
+ mouse_event->windowY = mouse_event->y;
+ mouse_event->movementX *= scale;
+ mouse_event->movementY *= scale;
+ } else if (blink::WebInputEvent::isTouchEventType(event.type)) {
+ blink::WebTouchEvent* touch_event = new blink::WebTouchEvent;
+ scaled_event.reset(touch_event);
+ *touch_event = static_cast<const blink::WebTouchEvent&>(event);
+ for (unsigned i = 0; i < touch_event->touchesLength; i++) {
+ touch_event->touches[i].position.x *= scale;
+ touch_event->touches[i].position.y *= scale;
+ touch_event->touches[i].radiusX *= scale;
+ touch_event->touches[i].radiusY *= scale;
+ }
+ } else if (blink::WebInputEvent::isGestureEventType(event.type)) {
+ blink::WebGestureEvent* gesture_event = new blink::WebGestureEvent;
+ scaled_event.reset(gesture_event);
+ *gesture_event = static_cast<const blink::WebGestureEvent&>(event);
+ gesture_event->x *= scale;
+ gesture_event->y *= scale;
+ switch (gesture_event->type) {
+ case blink::WebInputEvent::GestureScrollUpdate:
+ gesture_event->data.scrollUpdate.deltaX *= scale;
+ gesture_event->data.scrollUpdate.deltaY *= scale;
+ break;
+ case blink::WebInputEvent::GestureScrollBegin:
+ gesture_event->data.scrollBegin.deltaXHint *= scale;
+ gesture_event->data.scrollBegin.deltaYHint *= scale;
+ break;
+
+ case blink::WebInputEvent::GesturePinchUpdate:
+ // Scale in pinch gesture is DSF agnostic.
+ break;
+
+ case blink::WebInputEvent::GestureDoubleTap:
+ case blink::WebInputEvent::GestureTap:
+ case blink::WebInputEvent::GestureTapUnconfirmed:
+ gesture_event->data.tap.width *= scale;
+ gesture_event->data.tap.height *= scale;
+ break;
+
+ case blink::WebInputEvent::GestureTapDown:
+ gesture_event->data.tapDown.width *= scale;
+ gesture_event->data.tapDown.height *= scale;
+ break;
+
+ case blink::WebInputEvent::GestureShowPress:
+ gesture_event->data.showPress.width *= scale;
+ gesture_event->data.showPress.height *= scale;
+ break;
+
+ case blink::WebInputEvent::GestureLongPress:
+ case blink::WebInputEvent::GestureLongTap:
+ gesture_event->data.longPress.width *= scale;
+ gesture_event->data.longPress.height *= scale;
+ break;
+
+ case blink::WebInputEvent::GestureTwoFingerTap:
+ gesture_event->data.twoFingerTap.firstFingerWidth *= scale;
+ gesture_event->data.twoFingerTap.firstFingerHeight *= scale;
+ break;
+
+ case blink::WebInputEvent::GestureFlingStart:
+ gesture_event->data.flingStart.velocityX *= scale;
+ gesture_event->data.flingStart.velocityY *= scale;
+ break;
+
+ // These event does not have location data.
+ case blink::WebInputEvent::GesturePinchBegin:
+ case blink::WebInputEvent::GesturePinchEnd:
+ case blink::WebInputEvent::GestureTapCancel:
+ case blink::WebInputEvent::GestureFlingCancel:
+ case blink::WebInputEvent::GestureScrollEnd:
+ break;
+
+ // TODO(oshima): Find out if ContextMenu needs to be scaled.
+ default:
+ break;
+ }
+ }
+ return scaled_event;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_util.h b/chromium/content/browser/renderer_host/input/web_input_event_util.h
index 812a2274a3b..8cc3e45af40 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_util.h
+++ b/chromium/content/browser/renderer_host/input/web_input_event_util.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_WEB_INPUT_EVENT_UTIL_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_WEB_INPUT_EVENT_UTIL_H_
+#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -24,6 +25,10 @@ int WebEventModifiersToEventFlags(int modifiers);
blink::WebInputEvent::Modifiers DomCodeToWebInputEventModifiers(
ui::DomCode code);
+CONTENT_EXPORT scoped_ptr<blink::WebInputEvent> ConvertWebInputEventToViewport(
+ const blink::WebInputEvent& event,
+ float scale);
+
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_WEB_INPUT_EVENT_UTIL_H_
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc b/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc
index 862d6c14863..77810308059 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/web_input_event_util_unittest.cc
@@ -7,9 +7,12 @@
#define _USE_MATH_DEFINES
#endif
+#include <stddef.h>
+
#include <cmath>
#include "content/browser/renderer_host/input/web_input_event_util.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/input/web_input_event_traits.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/blink/blink_event_util.h"
@@ -28,6 +31,10 @@ using ui::MotionEventGeneric;
namespace content {
TEST(WebInputEventUtilTest, MotionEventConversion) {
+
+ const MotionEvent::ToolType tool_types[] = {MotionEvent::TOOL_TYPE_FINGER,
+ MotionEvent::TOOL_TYPE_STYLUS,
+ MotionEvent::TOOL_TYPE_MOUSE};
ui::PointerProperties pointer(5, 10, 40);
pointer.id = 15;
pointer.raw_x = 20;
@@ -35,34 +42,45 @@ TEST(WebInputEventUtilTest, MotionEventConversion) {
pointer.pressure = 30;
pointer.touch_minor = 35;
pointer.orientation = static_cast<float>(-M_PI / 2);
- MotionEventGeneric event(
- MotionEvent::ACTION_DOWN, base::TimeTicks::Now(), pointer);
- event.set_flags(ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
- event.set_unique_event_id(123456U);
+ pointer.tilt = static_cast<float>(-M_PI / 3);
+ for (MotionEvent::ToolType tool_type : tool_types) {
+ pointer.tool_type = tool_type;
+ MotionEventGeneric event(
+ MotionEvent::ACTION_DOWN, base::TimeTicks::Now(), pointer);
+ event.set_flags(ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
+ event.set_unique_event_id(123456U);
- WebTouchEvent expected_event;
- expected_event.type = WebInputEvent::TouchStart;
- expected_event.touchesLength = 1;
- expected_event.timeStampSeconds =
- (event.GetEventTime() - base::TimeTicks()).InSecondsF();
- expected_event.modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
- WebTouchPoint expected_pointer;
- expected_pointer.id = pointer.id;
- expected_pointer.state = WebTouchPoint::StatePressed;
- expected_pointer.position = blink::WebFloatPoint(pointer.x, pointer.y);
- expected_pointer.screenPosition =
- blink::WebFloatPoint(pointer.raw_x, pointer.raw_y);
- expected_pointer.radiusX = pointer.touch_major / 2.f;
- expected_pointer.radiusY = pointer.touch_minor / 2.f;
- expected_pointer.rotationAngle = 0.f;
- expected_pointer.force = pointer.pressure;
- expected_event.touches[0] = expected_pointer;
- expected_event.uniqueTouchEventId = 123456U;
+ WebTouchEvent expected_event;
+ expected_event.type = WebInputEvent::TouchStart;
+ expected_event.touchesLength = 1;
+ expected_event.timeStampSeconds =
+ (event.GetEventTime() - base::TimeTicks()).InSecondsF();
+ expected_event.modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
+ WebTouchPoint expected_pointer;
+ expected_pointer.id = pointer.id;
+ expected_pointer.state = WebTouchPoint::StatePressed;
+ expected_pointer.position = blink::WebFloatPoint(pointer.x, pointer.y);
+ expected_pointer.screenPosition =
+ blink::WebFloatPoint(pointer.raw_x, pointer.raw_y);
+ expected_pointer.radiusX = pointer.touch_major / 2.f;
+ expected_pointer.radiusY = pointer.touch_minor / 2.f;
+ expected_pointer.rotationAngle = 0.f;
+ expected_pointer.force = pointer.pressure;
+ if (tool_type == MotionEvent::TOOL_TYPE_STYLUS) {
+ expected_pointer.tiltX = -60;
+ expected_pointer.tiltY = 0;
+ } else {
+ expected_pointer.tiltX = 0;
+ expected_pointer.tiltY = 0;
+ }
+ expected_event.touches[0] = expected_pointer;
+ expected_event.uniqueTouchEventId = 123456U;
- WebTouchEvent actual_event =
- ui::CreateWebTouchEventFromMotionEvent(event, false);
- EXPECT_EQ(WebInputEventTraits::ToString(expected_event),
- WebInputEventTraits::ToString(actual_event));
+ WebTouchEvent actual_event =
+ ui::CreateWebTouchEventFromMotionEvent(event, false);
+ EXPECT_EQ(WebInputEventTraits::ToString(expected_event),
+ WebInputEventTraits::ToString(actual_event));
+ }
}
TEST(WebInputEventUtilTest, ScrollUpdateConversion) {
@@ -107,4 +125,12 @@ TEST(WebInputEventUtilTest, ScrollUpdateConversion) {
EXPECT_TRUE(web_event.data.scrollUpdate.previousUpdateInSequencePrevented);
}
+TEST(WebInputEventUtilTest, NoScalingWith1DSF) {
+ auto event =
+ SyntheticWebMouseEventBuilder::Build(blink::WebInputEvent::MouseMove,
+ 10, 10, 0);
+ EXPECT_FALSE(ConvertWebInputEventToViewport(event, 1.f));
+ EXPECT_TRUE(ConvertWebInputEventToViewport(event, 2.f));
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc
index bd0101d1007..9e2305747a5 100644
--- a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc
+++ b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -166,7 +166,7 @@ LRESULT LegacyRenderWidgetHostHWND::OnGetObject(UINT message,
return static_cast<LRESULT>(0L);
}
- if (OBJID_CLIENT != obj_id || !host_)
+ if (static_cast<DWORD>(OBJID_CLIENT) != obj_id || !host_)
return static_cast<LRESULT>(0L);
RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
diff --git a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h
index 7733facd453..09b1d821c14 100644
--- a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h
+++ b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h
@@ -10,7 +10,7 @@
#include <atlcrack.h>
#include <oleacc.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/scoped_comptr.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/media/audio_input_debug_writer.cc b/chromium/content/browser/renderer_host/media/audio_input_debug_writer.cc
index 9bbbefea396..5a500b49365 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_debug_writer.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_debug_writer.cc
@@ -4,16 +4,15 @@
#include "content/browser/renderer_host/media/audio_input_debug_writer.h"
+#include <utility>
+
#include "content/public/browser/browser_thread.h"
#include "media/base/audio_bus.h"
namespace content {
AudioInputDebugWriter::AudioInputDebugWriter(base::File file)
- : file_(file.Pass()),
- interleaved_data_size_(0),
- weak_factory_(this) {
-}
+ : file_(std::move(file)), interleaved_data_size_(0), weak_factory_(this) {}
AudioInputDebugWriter::~AudioInputDebugWriter() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
@@ -34,7 +33,7 @@ void AudioInputDebugWriter::DoWrite(scoped_ptr<media::AudioBus> data) {
// Convert to 16 bit audio and write to file.
int data_size = data->frames() * data->channels();
if (!interleaved_data_ || interleaved_data_size_ < data_size) {
- interleaved_data_.reset(new int16[data_size]);
+ interleaved_data_.reset(new int16_t[data_size]);
interleaved_data_size_ = data_size;
}
data->ToInterleaved(data->frames(), sizeof(interleaved_data_[0]),
diff --git a/chromium/content/browser/renderer_host/media/audio_input_debug_writer.h b/chromium/content/browser/renderer_host/media/audio_input_debug_writer.h
index 68332110594..13977756877 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_debug_writer.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_debug_writer.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DEBUG_WRITER_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DEBUG_WRITER_H_
+#include <stdint.h>
+
#include "base/files/file.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -43,7 +45,7 @@ class AudioInputDebugWriter : public media::AudioInputWriter {
base::File file_;
// Intermediate buffer to be written to file. Interleaved 16 bit audio data.
- scoped_ptr<int16[]> interleaved_data_;
+ scoped_ptr<int16_t[]> interleaved_data_;
int interleaved_data_size_;
base::WeakPtrFactory<AudioInputDebugWriter> weak_factory_;
diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc b/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc
index 5b231b05555..65148e04e90 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_input_ipc.h"
diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager.h b/chromium/content/browser/renderer_host/media/audio_input_device_manager.h
index b123ce482f5..d3f01b35f78 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_device_manager.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager.h
@@ -15,9 +15,10 @@
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/media_stream_provider.h"
#include "content/common/content_export.h"
#include "content/common/media/media_stream_options.h"
diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
index 498806b7d8b..4fac69d7dda 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
@@ -2,14 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <string>
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/public/common/media_stream_request.h"
diff --git a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc
index d6011ffc64c..60f64596171 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/media/audio_input_renderer_host.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file.h"
#include "base/memory/ref_counted.h"
@@ -13,14 +15,15 @@
#include "base/process/process.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "content/browser/media/capture/web_contents_audio_input_stream.h"
-#include "content/browser/media/capture/web_contents_capture_util.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/media/webrtc_internals.h"
#include "content/browser/renderer_host/media/audio_input_debug_writer.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/audio_input_sync_writer.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/web_contents_media_capture_id.h"
#include "media/audio/audio_manager_base.h"
#include "media/base/audio_bus.h"
@@ -53,7 +56,7 @@ base::File CreateDebugRecordingFile(base::FilePath file_path) {
PLOG_IF(ERROR, !recording_file.IsValid())
<< "Could not open debug recording file, error="
<< recording_file.error_details();
- return recording_file.Pass();
+ return recording_file;
}
void CloseFile(base::File file) {
@@ -113,7 +116,7 @@ AudioInputRendererHost::AudioEntry::~AudioEntry() {
AudioInputRendererHost::AudioInputRendererHost(
int render_process_id,
- int32 renderer_pid,
+ int32_t renderer_pid,
media::AudioManager* audio_manager,
MediaStreamManager* media_stream_manager,
AudioMirroringManager* audio_mirroring_manager,
@@ -211,7 +214,7 @@ void AudioInputRendererHost::OnLog(media::AudioInputController* controller,
message));
}
-void AudioInputRendererHost::set_renderer_pid(int32 renderer_pid) {
+void AudioInputRendererHost::set_renderer_pid(int32_t renderer_pid) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
renderer_pid_ = renderer_pid;
}
@@ -409,14 +412,14 @@ void AudioInputRendererHost::DoCreateStream(
// Create a new AudioEntry structure.
scoped_ptr<AudioEntry> entry(new AudioEntry());
- const uint32 segment_size =
+ const uint32_t segment_size =
(sizeof(media::AudioInputBufferParameters) +
media::AudioBus::CalculateMemorySize(audio_params));
entry->shared_memory_segment_count = config.shared_memory_count;
// Create the shared memory and share it with the renderer process
// using a new SyncWriter object.
- base::CheckedNumeric<uint32> size = segment_size;
+ base::CheckedNumeric<uint32_t> size = segment_size;
size *= entry->shared_memory_segment_count;
if (!size.IsValid() ||
!entry->shared_memory.CreateAndMapAnonymous(size.ValueOrDie())) {
@@ -439,7 +442,7 @@ void AudioInputRendererHost::DoCreateStream(
// If we have successfully created the SyncWriter then assign it to the
// entry and construct an AudioInputController.
entry->writer.reset(writer.release());
- if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_id)) {
+ if (WebContentsMediaCaptureId::IsWebContentsDeviceId(device_id)) {
entry->controller = media::AudioInputController::CreateForStream(
audio_manager_->GetTaskRunner(),
this,
@@ -584,10 +587,9 @@ void AudioInputRendererHost::DeleteEntry(AudioEntry* entry) {
#if defined(ENABLE_WEBRTC)
if (entry->input_debug_writer.get()) {
BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
+ BrowserThread::FILE, FROM_HERE,
base::Bind(&DeleteInputDebugWriterOnFileThread,
- base::Passed(entry->input_debug_writer.Pass())));
+ base::Passed(std::move(entry->input_debug_writer))));
}
#endif
@@ -699,15 +701,11 @@ void AudioInputRendererHost::DoEnableDebugRecording(
return;
AudioEntry* entry = LookupById(stream_id);
if (!entry) {
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(
- &CloseFile,
- Passed(file.Pass())));
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&CloseFile, Passed(std::move(file))));
return;
}
- entry->input_debug_writer.reset(new AudioInputDebugWriter(file.Pass()));
+ entry->input_debug_writer.reset(new AudioInputDebugWriter(std::move(file)));
entry->controller->EnableDebugRecording(entry->input_debug_writer.get());
}
@@ -722,10 +720,9 @@ void AudioInputRendererHost::DeleteDebugWriter(int stream_id) {
if (entry->input_debug_writer.get()) {
BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
+ BrowserThread::FILE, FROM_HERE,
base::Bind(&DeleteInputDebugWriterOnFileThread,
- base::Passed(entry->input_debug_writer.Pass())));
+ base::Passed(std::move(entry->input_debug_writer))));
}
}
#endif // defined(ENABLE_WEBRTC)
diff --git a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h
index 586e4d97f76..dd549965446 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h
@@ -27,7 +27,10 @@
#include <map>
#include <string>
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -101,7 +104,7 @@ class CONTENT_EXPORT AudioInputRendererHost
// Called from UI thread from the owner of this object.
// |user_input_monitor| is used for typing detection and can be NULL.
AudioInputRendererHost(int render_process_id,
- int32 renderer_pid,
+ int32_t renderer_pid,
media::AudioManager* audio_manager,
MediaStreamManager* media_stream_manager,
AudioMirroringManager* audio_mirroring_manager,
@@ -130,7 +133,7 @@ class CONTENT_EXPORT AudioInputRendererHost
// Sets the PID renderer. This is used for constructing the debug recording
// filename.
- void set_renderer_pid(int32 renderer_pid);
+ void set_renderer_pid(int32_t renderer_pid);
private:
// TODO(henrika): extend test suite (compare AudioRenderHost)
@@ -240,7 +243,7 @@ class CONTENT_EXPORT AudioInputRendererHost
// PID of the render process connected to the RenderProcessHost that owns this
// instance.
- int32 renderer_pid_;
+ int32_t renderer_pid_;
// Used to create an AudioInputController.
media::AudioManager* audio_manager_;
diff --git a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc
index ce32946df71..1ddc66c1e29 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc
@@ -8,6 +8,7 @@
#include "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/public/browser/browser_thread.h"
@@ -33,7 +34,7 @@ AudioInputSyncWriter::AudioInputSyncWriter(void* shared_memory,
size_t shared_memory_size,
int shared_memory_segment_count,
const media::AudioParameters& params)
- : shared_memory_(static_cast<uint8*>(shared_memory)),
+ : shared_memory_(static_cast<uint8_t*>(shared_memory)),
shared_memory_segment_count_(shared_memory_segment_count),
current_segment_id_(0),
creation_time_(base::Time::Now()),
@@ -55,7 +56,7 @@ AudioInputSyncWriter::AudioInputSyncWriter(void* shared_memory,
DVLOG(1) << "audio_bus_memory_size: " << audio_bus_memory_size_;
// Create vector of audio buses by wrapping existing blocks of memory.
- uint8* ptr = shared_memory_;
+ uint8_t* ptr = shared_memory_;
for (int i = 0; i < shared_memory_segment_count; ++i) {
CHECK_EQ(0U, reinterpret_cast<uintptr_t>(ptr) &
(AudioBus::kChannelAlignment - 1));
@@ -121,7 +122,7 @@ AudioInputSyncWriter::~AudioInputSyncWriter() {
void AudioInputSyncWriter::Write(const AudioBus* data,
double volume,
bool key_pressed,
- uint32 hardware_delay_bytes) {
+ uint32_t hardware_delay_bytes) {
++write_count_;
CheckTimeSinceLastWrite();
@@ -223,30 +224,13 @@ void AudioInputSyncWriter::CheckTimeSinceLastWrite() {
}
void AudioInputSyncWriter::AddToNativeLog(const std::string& message) {
-#if defined(OS_ANDROID)
- // MediaStreamManager::SendMessageToNativeLog will hop to the UI thread which
- // on Android will attach the current thread. The audio thread than we're on
- // now may be a native thread which we don't want to attach, so to avoid this
- // we first hop to the IO thread.
- // TODO(tommi): Make a nicer solution, preferably avoiding the many thread
- // hops in MediaStreamManager and later when adding a log message.
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&MediaStreamManager::SendMessageToNativeLog,
- message));
- return;
- }
-#endif
MediaStreamManager::SendMessageToNativeLog(message);
}
-bool AudioInputSyncWriter::PushDataToFifo(
- const AudioBus* data,
- double volume,
- bool key_pressed,
- uint32 hardware_delay_bytes) {
+bool AudioInputSyncWriter::PushDataToFifo(const AudioBus* data,
+ double volume,
+ bool key_pressed,
+ uint32_t hardware_delay_bytes) {
if (overflow_buses_.size() == kMaxOverflowBusesSize) {
const std::string error_message = "AISW: No room in fifo.";
LOG(ERROR) << error_message;
@@ -261,8 +245,7 @@ bool AudioInputSyncWriter::PushDataToFifo(
}
// Push parameters to fifo.
- AudioInputBufferParameters params =
- { volume, 0, hardware_delay_bytes, 0, key_pressed };
+ OverflowParams params = { volume, hardware_delay_bytes, key_pressed };
overflow_params_.push_back(params);
// Push audio data to fifo.
@@ -322,8 +305,8 @@ bool AudioInputSyncWriter::WriteDataFromFifoToSharedMemory() {
void AudioInputSyncWriter::WriteParametersToCurrentSegment(
double volume,
bool key_pressed,
- uint32 hardware_delay_bytes) {
- uint8* ptr = shared_memory_;
+ uint32_t hardware_delay_bytes) {
+ uint8_t* ptr = shared_memory_;
ptr += current_segment_id_ * shared_memory_segment_size_;
AudioInputBuffer* buffer = reinterpret_cast<AudioInputBuffer*>(ptr);
buffer->params.volume = volume;
diff --git a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h
index 896a0d84eb3..8429e44ee73 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h
@@ -5,13 +5,18 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_SYNC_WRITER_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_SYNC_WRITER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/process/process.h"
#include "base/sync_socket.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "media/audio/audio_input_controller.h"
#include "media/audio/audio_parameters.h"
@@ -45,7 +50,7 @@ class CONTENT_EXPORT AudioInputSyncWriter
void Write(const media::AudioBus* data,
double volume,
bool key_pressed,
- uint32 hardware_delay_bytes) override;
+ uint32_t hardware_delay_bytes) override;
void Close() override;
bool Init();
@@ -78,7 +83,7 @@ class CONTENT_EXPORT AudioInputSyncWriter
bool PushDataToFifo(const media::AudioBus* data,
double volume,
bool key_pressed,
- uint32 hardware_delay_bytes);
+ uint32_t hardware_delay_bytes);
// Writes as much data as possible from the fifo (|overflow_buses_|) to the
// shared memory ring buffer. Returns true if all operations were successful,
@@ -88,17 +93,17 @@ class CONTENT_EXPORT AudioInputSyncWriter
// Write audio parameters to current segment in shared memory.
void WriteParametersToCurrentSegment(double volume,
bool key_pressed,
- uint32 hardware_delay_bytes);
+ uint32_t hardware_delay_bytes);
// Signals over the socket that data has been written to the current segment.
// Updates counters and returns true if successful. Logs error and returns
// false if failure.
bool SignalDataWrittenAndUpdateCounters();
- uint8* shared_memory_;
- uint32 shared_memory_segment_size_;
- uint32 shared_memory_segment_count_;
- uint32 current_segment_id_;
+ uint8_t* shared_memory_;
+ uint32_t shared_memory_segment_size_;
+ uint32_t shared_memory_segment_count_;
+ uint32_t current_segment_id_;
// Socket to be used by the renderer. The reference is released after
// PrepareForeignSocketHandle() is called and ran successfully.
@@ -152,7 +157,12 @@ class CONTENT_EXPORT AudioInputSyncWriter
// since audio processing such as echo cancelling requires that to perform
// properly.
ScopedVector<media::AudioBus> overflow_buses_;
- std::deque<media::AudioInputBufferParameters> overflow_params_;
+ struct OverflowParams {
+ double volume;
+ uint32_t hardware_delay_bytes;
+ bool key_pressed;
+ };
+ std::deque<OverflowParams> overflow_params_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AudioInputSyncWriter);
};
diff --git a/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc
index 26b05ed5aac..d691b22d342 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc
@@ -2,10 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/sync_socket.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/audio_input_sync_writer.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/audio/audio_parameters.h"
@@ -34,11 +39,11 @@ const int bits_per_sample = 16;
// Faked ring buffer. Must be aligned.
#define DATA_ALIGNMENT 16
-COMPILE_ASSERT(AudioBus::kChannelAlignment == DATA_ALIGNMENT,
- Data_alignment_not_same_as_AudioBus);
-ALIGNAS(DATA_ALIGNMENT) uint8 data[kSegments *
- (sizeof(media::AudioInputBufferParameters) + frames * channels *
- sizeof(float))];
+static_assert(AudioBus::kChannelAlignment == DATA_ALIGNMENT,
+ "Data alignment not same as AudioBus");
+ALIGNAS(DATA_ALIGNMENT)
+uint8_t data[kSegments * (sizeof(media::AudioInputBufferParameters) +
+ frames * channels * sizeof(float))];
} // namespace
@@ -137,9 +142,8 @@ class AudioInputSyncWriterTest : public testing::Test {
AudioParameters::AUDIO_FAKE, layout, sampling_frequency_hz,
bits_per_sample, frames);
- const uint32 segment_size =
- sizeof(media::AudioInputBufferParameters) +
- AudioBus::CalculateMemorySize(audio_params);
+ const uint32_t segment_size = sizeof(media::AudioInputBufferParameters) +
+ AudioBus::CalculateMemorySize(audio_params);
size_t data_size = kSegments * segment_size;
EXPECT_LE(data_size, sizeof(data));
diff --git a/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.cc b/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.cc
index 13f875f64a7..54c05311e1f 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.cc
+++ b/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.cc
@@ -23,16 +23,19 @@ AudioOutputDeviceEnumeration EnumerateDevicesOnDeviceThread(
media::AudioDeviceNames device_names;
audio_manager->GetAudioOutputDeviceNames(&device_names);
+ snapshot.has_actual_devices = !device_names.empty();
+
// If no devices in enumeration, return a list with a default device
- if (device_names.empty()) {
- snapshot.push_back({media::AudioManagerBase::kDefaultDeviceId,
- media::AudioManager::GetDefaultDeviceName(),
- audio_manager->GetDefaultOutputStreamParameters()});
+ if (!snapshot.has_actual_devices) {
+ snapshot.devices.push_back(
+ {media::AudioManagerBase::kDefaultDeviceId,
+ media::AudioManager::GetDefaultDeviceName(),
+ audio_manager->GetDefaultOutputStreamParameters()});
return snapshot;
}
for (const media::AudioDeviceName& name : device_names) {
- snapshot.push_back(
+ snapshot.devices.push_back(
{name.unique_id, name.device_name,
name.unique_id == media::AudioManagerBase::kDefaultDeviceId
? audio_manager->GetDefaultOutputStreamParameters()
@@ -43,6 +46,16 @@ AudioOutputDeviceEnumeration EnumerateDevicesOnDeviceThread(
} // namespace
+AudioOutputDeviceEnumeration::AudioOutputDeviceEnumeration(
+ const std::vector<AudioOutputDeviceInfo>& devices,
+ bool has_actual_devices)
+ : devices(devices), has_actual_devices(has_actual_devices) {}
+
+AudioOutputDeviceEnumeration::AudioOutputDeviceEnumeration()
+ : has_actual_devices(false) {}
+
+AudioOutputDeviceEnumeration::~AudioOutputDeviceEnumeration() {}
+
AudioOutputDeviceEnumerator::AudioOutputDeviceEnumerator(
media::AudioManager* audio_manager,
CachePolicy cache_policy)
@@ -91,6 +104,11 @@ void AudioOutputDeviceEnumerator::SetCachePolicy(CachePolicy policy) {
cache_policy_ = policy;
}
+bool AudioOutputDeviceEnumerator::IsCacheEnabled() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return cache_policy_ != CACHE_POLICY_NO_CACHING;
+}
+
void AudioOutputDeviceEnumerator::DoEnumerateDevices() {
DCHECK(thread_checker_.CalledOnValidThread());
is_enumeration_ongoing_ = true;
diff --git a/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.h b/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.h
index 9ca251ed3db..bf223a9bccd 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.h
+++ b/chromium/content/browser/renderer_host/media/audio_output_device_enumerator.h
@@ -43,7 +43,19 @@ struct AudioOutputDeviceInfo {
media::AudioParameters output_params;
};
-typedef std::vector<AudioOutputDeviceInfo> AudioOutputDeviceEnumeration;
+// The result of an enumeration. It is used only in the browser side.
+struct AudioOutputDeviceEnumeration {
+ public:
+ AudioOutputDeviceEnumeration(
+ const std::vector<AudioOutputDeviceInfo>& devices,
+ bool has_actual_devices);
+ AudioOutputDeviceEnumeration();
+ ~AudioOutputDeviceEnumeration();
+
+ std::vector<AudioOutputDeviceInfo> devices;
+ bool has_actual_devices;
+};
+
typedef base::Callback<void(const AudioOutputDeviceEnumeration&)>
AudioOutputDeviceEnumerationCB;
@@ -59,11 +71,15 @@ class CONTENT_EXPORT AudioOutputDeviceEnumerator {
// Does an enumeration and provides the results to the callback.
// If there are no physical devices, the result contains a single entry with
- // the default parameters provided by the underlying audio manager.
+ // the default parameters provided by the underlying audio manager and with
+ // the |has_actual_devices| field set to false.
// The behavior with no physical devices is there to ease the transition
// from the use of RenderThreadImpl::GetAudioHardwareConfig(), which always
// provides default parameters, even if there are no devices.
// See https://crbug.com/549125.
+ // Some audio managers always report a single device, regardless of the
+ // physical devices in the system. In this case the |has_actual_devices| field
+ // is set to true to differentiate from the case of no physical devices.
void Enumerate(const AudioOutputDeviceEnumerationCB& callback);
// Invalidates the current cache.
@@ -72,6 +88,10 @@ class CONTENT_EXPORT AudioOutputDeviceEnumerator {
// Sets the cache policy.
void SetCachePolicy(CachePolicy cache_policy);
+ // Returns true if the caching policy is different from
+ // CACHE_POLICY_NO_CACHING, false otherwise.
+ bool IsCacheEnabled();
+
private:
void InitializeOnIOThread();
void DoEnumerateDevices();
diff --git a/chromium/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc b/chromium/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
index d5091534e80..ac6140cbb01 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
@@ -6,10 +6,12 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -24,24 +26,62 @@ using testing::_;
namespace content {
namespace {
+
class MockAudioManager : public media::FakeAudioManager {
public:
- MockAudioManager() : FakeAudioManager(&fake_audio_log_factory_) {}
+ MockAudioManager(size_t num_devices)
+ : FakeAudioManager(&fake_audio_log_factory_), num_devices_(num_devices) {}
+ MockAudioManager() : MockAudioManager(0) {}
~MockAudioManager() override {}
- MOCK_METHOD1(GetAudioOutputDeviceNames, void(media::AudioDeviceNames*));
+
+ MOCK_METHOD1(MockGetAudioOutputDeviceNames, void(media::AudioDeviceNames*));
+
+ void GetAudioOutputDeviceNames(
+ media::AudioDeviceNames* device_names) override {
+ DCHECK(device_names->empty());
+ MockGetAudioOutputDeviceNames(device_names);
+ if (num_devices_ > 0) {
+ device_names->push_back(
+ media::AudioDeviceName(AudioManager::GetDefaultDeviceName(),
+ AudioManagerBase::kDefaultDeviceId));
+ for (size_t i = 0; i < num_devices_; i++) {
+ device_names->push_back(
+ media::AudioDeviceName("FakeDeviceName_" + base::IntToString(i),
+ "FakeDeviceId_" + base::IntToString(i)));
+ }
+ }
+ }
private:
media::FakeAudioLogFactory fake_audio_log_factory_;
+ size_t num_devices_;
DISALLOW_COPY_AND_ASSIGN(MockAudioManager);
};
+
+// Fake audio manager that exposes only the default device
+class OnlyDefaultDeviceAudioManager : public MockAudioManager {
+ public:
+ OnlyDefaultDeviceAudioManager() {}
+ ~OnlyDefaultDeviceAudioManager() override {}
+ void GetAudioOutputDeviceNames(
+ media::AudioDeviceNames* device_names) override {
+ DCHECK(device_names->empty());
+ MockGetAudioOutputDeviceNames(device_names);
+ device_names->push_front(
+ media::AudioDeviceName(AudioManager::GetDefaultDeviceName(),
+ AudioManagerBase::kDefaultDeviceId));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OnlyDefaultDeviceAudioManager);
+};
+
} // namespace
class AudioOutputDeviceEnumeratorTest : public ::testing::Test {
public:
AudioOutputDeviceEnumeratorTest()
- : thread_bundle_(), task_runner_(base::ThreadTaskRunnerHandle::Get()) {
- audio_manager_.reset(new MockAudioManager());
- }
+ : thread_bundle_(), task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
~AudioOutputDeviceEnumeratorTest() override {}
@@ -64,6 +104,14 @@ class AudioOutputDeviceEnumeratorTest : public ::testing::Test {
}
}
+ void EnumerateCountCallback(size_t num_entries_expected,
+ bool actual_devices_expected,
+ const AudioOutputDeviceEnumeration& result) {
+ EXPECT_EQ(actual_devices_expected, result.has_actual_devices);
+ EXPECT_EQ(num_entries_expected, result.devices.size());
+ task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure());
+ }
+
void QuitCallback(const AudioOutputDeviceEnumeration& result) {
MockCallback(result);
task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure());
@@ -81,7 +129,8 @@ class AudioOutputDeviceEnumeratorTest : public ::testing::Test {
TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateWithCache) {
const int num_calls = 10;
- EXPECT_CALL(*audio_manager_, GetAudioOutputDeviceNames(_)).Times(1);
+ audio_manager_.reset(new MockAudioManager());
+ EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(1);
EXPECT_CALL(*this, MockCallback(_)).Times(num_calls);
AudioOutputDeviceEnumerator enumerator(
audio_manager_.get(),
@@ -94,7 +143,9 @@ TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateWithCache) {
TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateWithNoCache) {
const int num_calls = 10;
- EXPECT_CALL(*audio_manager_, GetAudioOutputDeviceNames(_)).Times(num_calls);
+ audio_manager_.reset(new MockAudioManager());
+ EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_))
+ .Times(num_calls);
EXPECT_CALL(*this, MockCallback(_)).Times(num_calls);
AudioOutputDeviceEnumerator enumerator(
audio_manager_.get(),
@@ -105,4 +156,54 @@ TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateWithNoCache) {
run_loop_.Run();
}
+TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateNoDevices) {
+ audio_manager_.reset(new MockAudioManager());
+ EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
+ AudioOutputDeviceEnumerator enumerator(
+ audio_manager_.get(),
+ AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
+ enumerator.Enumerate(
+ base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
+ base::Unretained(this), 1, false));
+ run_loop_.Run();
+}
+
+TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateOnlyDefaultDevice) {
+ audio_manager_.reset(new OnlyDefaultDeviceAudioManager());
+ EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
+ AudioOutputDeviceEnumerator enumerator(
+ audio_manager_.get(),
+ AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
+ enumerator.Enumerate(
+ base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
+ base::Unretained(this), 1, true));
+ run_loop_.Run();
+}
+
+TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateOneDevice) {
+ size_t num_devices = 1;
+ audio_manager_.reset(new MockAudioManager(num_devices));
+ EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
+ AudioOutputDeviceEnumerator enumerator(
+ audio_manager_.get(),
+ AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
+ enumerator.Enumerate(
+ base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
+ base::Unretained(this), num_devices + 1, true));
+ run_loop_.Run();
+}
+
+TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateMultipleDevices) {
+ size_t num_devices = 5;
+ audio_manager_.reset(new MockAudioManager(num_devices));
+ EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
+ AudioOutputDeviceEnumerator enumerator(
+ audio_manager_.get(),
+ AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
+ enumerator.Enumerate(
+ base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
+ base::Unretained(this), num_devices + 1, true));
+ run_loop_.Run();
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/audio_renderer_host.cc b/chromium/content/browser/renderer_host/media/audio_renderer_host.cc
index df16bce5d96..d469d342433 100644
--- a/chromium/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/chromium/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -4,8 +4,12 @@
#include "content/browser/renderer_host/media/audio_renderer_host.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram.h"
@@ -31,6 +35,7 @@
#include "content/public/common/content_switches.h"
#include "media/audio/audio_device_name.h"
#include "media/audio/audio_manager_base.h"
+#include "media/audio/audio_streams_tracker.h"
#include "media/base/audio_bus.h"
#include "media/base/limits.h"
@@ -40,6 +45,12 @@ using media::AudioManager;
namespace content {
namespace {
+
+// Tracks the maximum number of simultaneous output streams browser-wide.
+// Accessed on IO thread.
+base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker =
+ LAZY_INSTANCE_INITIALIZER;
+
// TODO(aiolos): This is a temporary hack until the resource scheduler is
// migrated to RenderFrames for the Site Isolation project. It's called in
// response to low frequency playback state changes. http://crbug.com/472869
@@ -62,9 +73,10 @@ void NotifyResourceDispatcherOfAudioStateChange(int render_process_id,
}
media::AudioParameters DummyParams() {
- return media::AudioParameters(media::AudioParameters::AUDIO_PCM_LINEAR,
- media::CHANNEL_LAYOUT_STEREO,
- media::limits::kMinSampleRate, 1, 1);
+ return media::AudioParameters(
+ media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
+ media::AudioParameters::kAudioCDSampleRate, 16,
+ media::AudioParameters::kAudioCDSampleRate / 10);
}
std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData(
@@ -99,9 +111,43 @@ bool IsValidDeviceId(const std::string& device_id) {
return true;
}
-std::string TranslateDefaultId(const std::string& device_id) {
- return device_id.empty() ? media::AudioManagerBase::kDefaultDeviceId
- : device_id;
+bool IsDefaultDeviceId(const std::string& device_id) {
+ return device_id.empty() ||
+ device_id == media::AudioManagerBase::kDefaultDeviceId;
+}
+
+AudioOutputDeviceInfo GetDefaultDeviceInfoOnDeviceThread(
+ media::AudioManager* audio_manager) {
+ DCHECK(audio_manager->GetWorkerTaskRunner()->BelongsToCurrentThread());
+ AudioOutputDeviceInfo default_device_info = {
+ media::AudioManagerBase::kDefaultDeviceId,
+ audio_manager->GetDefaultDeviceName(),
+ audio_manager->GetDefaultOutputStreamParameters()};
+
+ return default_device_info;
+}
+
+void NotifyRenderProcessHostThatAudioStateChanged(int render_process_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ RenderProcessHost* render_process_host =
+ RenderProcessHost::FromID(render_process_id);
+
+ if (render_process_host)
+ render_process_host->AudioStateChanged();
+}
+
+void MaybeFixAudioParameters(media::AudioParameters* params) {
+ // If the number of output channels is greater than the maximum, use the
+ // maximum allowed value. Hardware channels are ignored upstream, so it is
+ // better to report a valid value if this is the only problem.
+ if (params->channels() > media::limits::kMaxChannels)
+ params->set_channels_for_discrete(media::limits::kMaxChannels);
+
+ // If hardware parameters are still invalid, use dummy parameters with
+ // fake audio path and let the client handle the error.
+ if (!params->IsValid())
+ *params = DummyParams();
}
} // namespace
@@ -173,8 +219,8 @@ AudioRendererHost::AudioEntry::AudioEntry(
: host_(host),
stream_id_(stream_id),
render_frame_id_(render_frame_id),
- shared_memory_(shared_memory.Pass()),
- reader_(reader.Pass()),
+ shared_memory_(std::move(shared_memory)),
+ reader_(std::move(reader)),
controller_(media::AudioOutputController::Create(host->audio_manager_,
this,
params,
@@ -204,13 +250,28 @@ AudioRendererHost::AudioRendererHost(
media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)),
media_stream_manager_(media_stream_manager),
num_playing_streams_(0),
- salt_callback_(salt_callback) {
+ salt_callback_(salt_callback),
+ max_simultaneous_streams_(0) {
DCHECK(audio_manager_);
DCHECK(media_stream_manager_);
}
AudioRendererHost::~AudioRendererHost() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(audio_entries_.empty());
+
+ // If we had any streams, report UMA stats for the maximum number of
+ // simultaneous streams for this render process and for the whole browser
+ // process since last reported.
+ if (max_simultaneous_streams_ > 0) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Media.AudioRendererIpcStreams",
+ max_simultaneous_streams_, 1, 50, 51);
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Media.AudioRendererIpcStreamsTotal",
+ g_audio_streams_tracker.Get().max_stream_count(),
+ 1, 100, 101);
+ g_audio_streams_tracker.Get().ResetMaxStreamCount();
+ }
}
void AudioRendererHost::GetOutputControllers(
@@ -365,7 +426,6 @@ bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream)
IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream)
IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume)
- IPC_MESSAGE_HANDLER(AudioHostMsg_SwitchOutputDevice, OnSwitchOutputDevice)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -394,10 +454,13 @@ void AudioRendererHost::OnRequestDeviceAuthorization(
return;
}
- // If attempting to use the output device associated to an opened input
- // device and the output device is found, reuse the input device
+ // If |device_id| is not empty, ignore |session_id| and select the device
+ // indicated by |device_id|.
+ // If |device_id| is empty and |session_id| is nonzero, try to use the
+ // output device associated with the opened input device designated by
+ // |session_id| and, if such output device is found, reuse the input device
// permissions.
- if (session_id != 0) {
+ if (session_id != 0 && device_id.empty()) {
const StreamDeviceInfo* info =
media_stream_manager_->audio_input_device_manager()
->GetOpenedDeviceInfoById(session_id);
@@ -411,6 +474,7 @@ void AudioRendererHost::OnRequestDeviceAuthorization(
output_params.set_effects(info->device.matched_output.effects);
authorizations_.insert(MakeAuthorizationData(
stream_id, true, info->device.matched_output_device_id));
+ MaybeFixAudioParameters(&output_params);
Send(new AudioMsg_NotifyDeviceAuthorized(
stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params));
return;
@@ -445,10 +509,25 @@ void AudioRendererHost::OnDeviceAuthorized(int stream_id,
return;
}
- media_stream_manager_->audio_output_device_enumerator()->Enumerate(base::Bind(
- &AudioRendererHost::TranslateDeviceID, this, device_id,
- gurl_security_origin,
- base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this, stream_id)));
+ // If enumerator caching is disabled, avoid the enumeration if the default
+ // device is requested, since no device ID translation is needed.
+ // If enumerator caching is enabled, it is better to use its cache, even
+ // for the default device.
+ if (IsDefaultDeviceId(device_id) &&
+ !media_stream_manager_->audio_output_device_enumerator()
+ ->IsCacheEnabled()) {
+ base::PostTaskAndReplyWithResult(
+ audio_manager_->GetWorkerTaskRunner().get(), FROM_HERE,
+ base::Bind(&GetDefaultDeviceInfoOnDeviceThread, audio_manager_),
+ base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this, stream_id,
+ true));
+ } else {
+ media_stream_manager_->audio_output_device_enumerator()->Enumerate(
+ base::Bind(&AudioRendererHost::TranslateDeviceID, this, device_id,
+ gurl_security_origin,
+ base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this,
+ stream_id)));
+ }
}
void AudioRendererHost::OnDeviceIDTranslated(
@@ -471,8 +550,11 @@ void AudioRendererHost::OnDeviceIDTranslated(
auth_data->second.first = true;
auth_data->second.second = device_info.unique_id;
+
+ media::AudioParameters output_params = device_info.output_params;
+ MaybeFixAudioParameters(&output_params);
Send(new AudioMsg_NotifyDeviceAuthorized(
- stream_id, media::OUTPUT_DEVICE_STATUS_OK, device_info.output_params));
+ stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params));
}
void AudioRendererHost::OnCreateStream(int stream_id,
@@ -508,7 +590,8 @@ void AudioRendererHost::DoCreateStream(int stream_id,
}
// Create the shared memory and share with the renderer process.
- uint32 shared_memory_size = AudioBus::CalculateMemorySize(params);
+ uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) +
+ AudioBus::CalculateMemorySize(params);
scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) {
SendErrorMessage(stream_id);
@@ -529,16 +612,20 @@ void AudioRendererHost::DoCreateStream(int stream_id,
scoped_ptr<AudioEntry> entry(
new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id,
- shared_memory.Pass(), reader.Pass()));
+ std::move(shared_memory), std::move(reader)));
if (mirroring_manager_) {
mirroring_manager_->AddDiverter(
render_process_id_, entry->render_frame_id(), entry->controller());
}
audio_entries_.insert(std::make_pair(stream_id, entry.release()));
+ g_audio_streams_tracker.Get().IncreaseStreamCount();
audio_log_->OnCreated(stream_id, params, device_unique_id);
MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
stream_id, render_process_id_, render_frame_id, audio_log_.get());
+
+ if (audio_entries_.size() > max_simultaneous_streams_)
+ max_simultaneous_streams_ = audio_entries_.size();
}
void AudioRendererHost::OnPlayStream(int stream_id) {
@@ -583,106 +670,6 @@ void AudioRendererHost::OnSetVolume(int stream_id, double volume) {
audio_log_->OnSetVolume(stream_id, volume);
}
-void AudioRendererHost::OnSwitchOutputDevice(
- int stream_id,
- int render_frame_id,
- const std::string& device_id,
- const url::Origin& security_origin) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DVLOG(1) << "AudioRendererHost@" << this
- << "::OnSwitchOutputDevice(stream_id=" << stream_id
- << ", render_frame_id=" << render_frame_id
- << ", device_id=" << device_id
- << ", security_origin=" << security_origin << ")";
- if (!LookupById(stream_id)) {
- Send(new AudioMsg_NotifyOutputDeviceSwitched(
- stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL));
- return;
- }
-
- if (!IsValidDeviceId(device_id)) {
- Send(new AudioMsg_NotifyOutputDeviceSwitched(
- stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND));
- return;
- }
-
- GURL gurl_security_origin = ConvertToGURL(security_origin);
- CheckOutputDeviceAccess(
- render_frame_id, device_id, gurl_security_origin,
- base::Bind(&AudioRendererHost::OnSwitchDeviceAuthorized, this, stream_id,
- device_id, gurl_security_origin));
-}
-
-void AudioRendererHost::OnSwitchDeviceAuthorized(
- int stream_id,
- const std::string& device_id,
- const GURL& gurl_security_origin,
- bool have_access) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!have_access) {
- Send(new AudioMsg_NotifyOutputDeviceSwitched(
- stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED));
- return;
- }
-
- AudioEntry* entry = LookupById(stream_id);
- if (!entry) {
- Send(new AudioMsg_NotifyOutputDeviceSwitched(
- stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL));
- return;
- }
-
- entry->controller()->GetOutputDeviceId(
- base::Bind(&AudioRendererHost::OnSwitchDeviceCurrentName, this, device_id,
- gurl_security_origin, stream_id));
-}
-
-void AudioRendererHost::OnSwitchDeviceCurrentName(
- const std::string& device_id,
- const GURL& gurl_security_origin,
- int stream_id,
- const std::string& current_device_unique_id) {
- media_stream_manager_->audio_output_device_enumerator()->Enumerate(base::Bind(
- &AudioRendererHost::TranslateDeviceIDAndCheckParams, this, device_id,
- gurl_security_origin, current_device_unique_id,
- base::Bind(&AudioRendererHost::OnSwitchDeviceIDTranslatedAndParamsChecked,
- this, stream_id)));
-}
-
-void AudioRendererHost::OnSwitchDeviceIDTranslatedAndParamsChecked(
- int stream_id,
- bool success,
- const AudioOutputDeviceInfo& device_info) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!success) {
- media::OutputDeviceStatus result =
- device_info.unique_id.empty()
- ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND
- : media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL;
-
- Send(new AudioMsg_NotifyOutputDeviceSwitched(stream_id, result));
- return;
- }
-
- AudioEntry* entry = LookupById(stream_id);
- if (!entry) {
- Send(new AudioMsg_NotifyOutputDeviceSwitched(
- stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL));
- return;
- }
-
- entry->controller()->SwitchOutputDevice(
- device_info.unique_id,
- base::Bind(&AudioRendererHost::OnDeviceSwitched, this, stream_id));
- audio_log_->OnSwitchOutputDevice(entry->stream_id(), device_info.unique_id);
-}
-
-void AudioRendererHost::OnDeviceSwitched(int stream_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- Send(new AudioMsg_NotifyOutputDeviceSwitched(stream_id,
- media::OUTPUT_DEVICE_STATUS_OK));
-}
-
void AudioRendererHost::SendErrorMessage(int stream_id) {
Send(new AudioMsg_NotifyStreamStateChanged(
stream_id, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR));
@@ -699,6 +686,7 @@ void AudioRendererHost::OnCloseStream(int stream_id) {
return;
scoped_ptr<AudioEntry> entry(i->second);
audio_entries_.erase(i);
+ g_audio_streams_tracker.Get().DecreaseStreamCount();
media::AudioOutputController* const controller = entry->controller();
controller->Close(
@@ -756,11 +744,27 @@ void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry,
!RenderFrameHasActiveAudio(entry->render_frame_id());
entry->set_playing(true);
base::AtomicRefCountInc(&num_playing_streams_);
+
+ // Inform the RenderProcessHost when audio starts playing for the first
+ // time.
+ if (base::AtomicRefCountIsOne(&num_playing_streams_)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&NotifyRenderProcessHostThatAudioStateChanged,
+ render_process_id_));
+ }
} else {
entry->set_playing(false);
should_alert_resource_scheduler =
!RenderFrameHasActiveAudio(entry->render_frame_id());
- base::AtomicRefCountDec(&num_playing_streams_);
+
+ // Inform the RenderProcessHost when there is no more audio playing.
+ if (!base::AtomicRefCountDec(&num_playing_streams_)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&NotifyRenderProcessHostThatAudioStateChanged,
+ render_process_id_));
+ }
}
if (should_alert_resource_scheduler && ResourceDispatcherHostImpl::Get()) {
@@ -836,9 +840,9 @@ void AudioRendererHost::TranslateDeviceID(
const std::string& device_id,
const GURL& security_origin,
const OutputDeviceInfoCB& callback,
- const AudioOutputDeviceEnumeration& device_infos) {
+ const AudioOutputDeviceEnumeration& enumeration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- for (const AudioOutputDeviceInfo& device_info : device_infos) {
+ for (const AudioOutputDeviceInfo& device_info : enumeration.devices) {
if (device_id.empty()) {
if (device_info.unique_id == media::AudioManagerBase::kDefaultDeviceId) {
callback.Run(true, device_info);
@@ -857,59 +861,6 @@ void AudioRendererHost::TranslateDeviceID(
callback.Run(false, device_info);
}
-void AudioRendererHost::TranslateDeviceIDAndCheckParams(
- const std::string& device_id,
- const GURL& gurl_security_origin,
- const std::string& current_device_unique_id,
- const OutputDeviceInfoCB& callback,
- const AudioOutputDeviceEnumeration& device_infos) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- std::string current_unique_id = TranslateDefaultId(current_device_unique_id);
- bool use_default_device =
- device_id.empty() ||
- device_id == media::AudioManagerBase::kDefaultDeviceId;
- AudioOutputDeviceEnumeration::const_iterator current_info =
- device_infos.end();
- AudioOutputDeviceEnumeration::const_iterator new_info = device_infos.end();
-
- for (AudioOutputDeviceEnumeration::const_iterator it = device_infos.begin();
- it != device_infos.end(); ++it) {
- if (it->unique_id == current_unique_id)
- current_info = it;
-
- if (use_default_device) {
- if (it->unique_id == media::AudioManagerBase::kDefaultDeviceId)
- new_info = it;
- } else if (content::DoesMediaDeviceIDMatchHMAC(salt_callback_,
- gurl_security_origin,
- device_id, it->unique_id)) {
- new_info = it;
- }
-
- if (current_info != device_infos.end() && new_info != device_infos.end())
- break;
- }
-
- // Use empty unique ID to indicate that |device_id| was not found
- if (new_info == device_infos.end()) {
- AudioOutputDeviceInfo dummy_info = {std::string(), std::string(),
- DummyParams()};
- callback.Run(false, dummy_info);
- return;
- }
-
- bool success = current_info != device_infos.end() &&
- new_info->output_params.sample_rate() ==
- current_info->output_params.sample_rate() &&
- new_info->output_params.frames_per_buffer() ==
- current_info->output_params.frames_per_buffer() &&
- new_info->output_params.bits_per_sample() ==
- current_info->output_params.bits_per_sample();
-
- callback.Run(success, *new_info);
-}
-
bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
const auto& i = authorizations_.find(stream_id);
diff --git a/chromium/content/browser/renderer_host/media/audio_renderer_host.h b/chromium/content/browser/renderer_host/media/audio_renderer_host.h
index cfda5ec10c4..e549df20cc9 100644
--- a/chromium/content/browser/renderer_host/media/audio_renderer_host.h
+++ b/chromium/content/browser/renderer_host/media/audio_renderer_host.h
@@ -44,8 +44,11 @@
#include <string>
#include <utility>
+#include <stddef.h>
+
#include "base/atomic_ref_count.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process.h"
@@ -165,12 +168,6 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
// Set the volume of the audio stream referenced by |stream_id|.
void OnSetVolume(int stream_id, double volume);
- // Set the output device of the audio stream referenced by |stream_id|.
- void OnSwitchOutputDevice(int stream_id,
- int render_frame_id,
- const std::string& device_id,
- const url::Origin& gurl_security_origin);
-
// Helper methods.
// Proceed with device authorization after checking permissions.
@@ -199,31 +196,6 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
// Send playing/paused status to the renderer.
void DoNotifyStreamStateChanged(int stream_id, bool is_playing);
- // Proceed with output device switching after checking permissions.
- void OnSwitchDeviceAuthorized(int stream_id,
- const std::string& device_id,
- const GURL& security_origin,
- bool have_access);
-
- // Proceed with output device switching after getting the name of the current
- // device from the audio controller.
- void OnSwitchDeviceCurrentName(const std::string& device_id,
- const GURL& security_origin,
- int stream_id,
- const std::string& current_device_unique_id);
-
- // Proceed with output device switching after translating the ID of the new
- // device and checking that output parameters are compatible with the current
- // device.
- void OnSwitchDeviceIDTranslatedAndParamsChecked(
- int stream_id,
- bool success,
- const AudioOutputDeviceInfo& device_info);
-
- // Finish handling the output device switch request, after the device has
- // been switched.
- void OnDeviceSwitched(int stream_id);
-
RenderProcessHost::AudioOutputControllerList DoGetOutputControllers() const;
// Send an error message to the renderer.
@@ -259,24 +231,7 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
void TranslateDeviceID(const std::string& device_id,
const GURL& gurl_security_origin,
const OutputDeviceInfoCB& callback,
- const AudioOutputDeviceEnumeration& device_infos);
-
- // Translate the hashed |device_id| to a unique device ID and compare
- // output parameters for both devices.
- // |callback| is invoked with the following arguments:
- // bool: true if |device_id| was found and its parameters match the
- // parmeters of the current device.
- // AudioOutputDeviceInfo: info for |device_id| if it was found, or dummy
- // info with empty unique ID and name otherwise.
- // TODO(guidou): Remove this method once all clients select the output device
- // in the initial creation/authorization process instead of by issuing
- // switch output device IPCs . http://crbug.com/531468
- void TranslateDeviceIDAndCheckParams(
- const std::string& device_id,
- const GURL& gurl_security_origin,
- const std::string& current_device_unique_id,
- const OutputDeviceInfoCB& callback,
- const AudioOutputDeviceEnumeration& device_infos);
+ const AudioOutputDeviceEnumeration& enumeration);
// Helper method to check if the authorization procedure for stream
// |stream_id| has started.
@@ -295,7 +250,8 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
// A map of stream IDs to audio sources.
AudioEntryMap audio_entries_;
- // The number of streams in the playing state.
+ // The number of streams in the playing state. Atomic read safe from any
+ // thread, but should only be updated from the IO thread.
base::AtomicRefCount num_playing_streams_;
// Salt required to translate renderer device IDs to raw device unique IDs
@@ -307,6 +263,10 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
// The second element contains the unique ID of the authorized device.
std::map<int, std::pair<bool, std::string>> authorizations_;
+ // The maximum number of simultaneous streams during the lifetime of this
+ // host. Reported as UMA stat at shutdown.
+ size_t max_simultaneous_streams_;
+
DISALLOW_COPY_AND_ASSIGN(AudioRendererHost);
};
diff --git a/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
index 4e9c3cdd57f..396d9239507 100644
--- a/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/sync_socket.h"
@@ -31,13 +34,11 @@ namespace {
const int kRenderProcessId = 1;
const int kRenderFrameId = 5;
const int kStreamId = 50;
-const int kBadStreamId = 99;
-const url::Origin kSecurityOrigin(GURL("http://localhost"));
-const url::Origin kDefaultSecurityOrigin;
-const std::string kDefaultDeviceID;
-const std::string kBadDeviceID =
+const char kSecurityOrigin[] = "http://localhost";
+const char kDefaultDeviceId[] = "";
+const char kBadDeviceId[] =
"badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1";
-const std::string kInvalidDeviceID = "invalid-device-id";
+const char kInvalidDeviceId[] = "invalid-device-id";
} // namespace
namespace content {
@@ -81,8 +82,6 @@ class MockAudioRendererHost : public AudioRendererHost {
MOCK_METHOD1(OnStreamPlaying, void(int stream_id));
MOCK_METHOD1(OnStreamPaused, void(int stream_id));
MOCK_METHOD1(OnStreamError, void(int stream_id));
- MOCK_METHOD2(OnOutputDeviceSwitched,
- void(int stream_id, media::OutputDeviceStatus result));
private:
virtual ~MockAudioRendererHost() {
@@ -106,8 +105,6 @@ class MockAudioRendererHost : public AudioRendererHost {
OnNotifyStreamCreated)
IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamStateChanged,
OnNotifyStreamStateChanged)
- IPC_MESSAGE_HANDLER(AudioMsg_NotifyOutputDeviceSwitched,
- OnNotifyOutputDeviceSwitched)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
EXPECT_TRUE(handled);
@@ -123,8 +120,10 @@ class MockAudioRendererHost : public AudioRendererHost {
}
void OnNotifyStreamCreated(
- int stream_id, base::SharedMemoryHandle handle,
- base::SyncSocket::TransitDescriptor socket_descriptor, uint32 length) {
+ int stream_id,
+ base::SharedMemoryHandle handle,
+ base::SyncSocket::TransitDescriptor socket_descriptor,
+ uint32_t length) {
// Maps the shared memory.
shared_memory_.reset(new base::SharedMemory(handle, false));
CHECK(shared_memory_->Map(length));
@@ -158,24 +157,9 @@ class MockAudioRendererHost : public AudioRendererHost {
}
}
- void OnNotifyOutputDeviceSwitched(int stream_id,
- media::OutputDeviceStatus result) {
- switch (result) {
- case media::OUTPUT_DEVICE_STATUS_OK:
- case media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND:
- case media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED:
- case media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL:
- OnOutputDeviceSwitched(stream_id, result);
- break;
- default:
- FAIL() << "Unknown SwitchOutputDevice result";
- break;
- }
- }
-
scoped_ptr<base::SharedMemory> shared_memory_;
scoped_ptr<base::SyncSocket> sync_socket_;
- uint32 shared_memory_length_;
+ uint32_t shared_memory_length_;
DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost);
};
@@ -233,15 +217,27 @@ class AudioRendererHostTest : public testing::Test {
}
protected:
- void Create(bool unified_stream) {
- EXPECT_CALL(
- *host_.get(),
- OnDeviceAuthorized(kStreamId, media::OUTPUT_DEVICE_STATUS_OK, _));
- EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _));
+ void Create() { Create(false, kDefaultDeviceId, url::Origin()); }
+
+ void Create(bool unified_stream,
+ const std::string& device_id,
+ const url::Origin& security_origin) {
+ media::OutputDeviceStatus expected_device_status =
+ device_id == kDefaultDeviceId
+ ? media::OUTPUT_DEVICE_STATUS_OK
+ : device_id == kBadDeviceId
+ ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED
+ : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND;
- EXPECT_CALL(mirroring_manager_,
- AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()))
- .RetiresOnSaturation();
+ EXPECT_CALL(*host_.get(),
+ OnDeviceAuthorized(kStreamId, expected_device_status, _));
+
+ if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) {
+ EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _));
+ EXPECT_CALL(mirroring_manager_,
+ AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()))
+ .RetiresOnSaturation();
+ }
// Send a create stream message to the audio output stream and wait until
// we receive the created message.
@@ -256,14 +252,15 @@ class AudioRendererHostTest : public testing::Test {
session_id = AudioInputDeviceManager::kFakeOpenSessionId;
}
host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id,
- kDefaultDeviceID,
- kDefaultSecurityOrigin);
- host_->OnCreateStream(kStreamId, kRenderFrameId, params);
-
- // At some point in the future, a corresponding RemoveDiverter() call must
- // be made.
- EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()))
- .RetiresOnSaturation();
+ device_id, security_origin);
+ if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) {
+ host_->OnCreateStream(kStreamId, kRenderFrameId, params);
+
+ // At some point in the future, a corresponding RemoveDiverter() call must
+ // be made.
+ EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()))
+ .RetiresOnSaturation();
+ }
SyncWithAudioThread();
}
@@ -291,17 +288,6 @@ class AudioRendererHostTest : public testing::Test {
SyncWithAudioThread();
}
- void SwitchOutputDevice(int stream_id,
- const std::string& device_id,
- const url::Origin& security_origin,
- media::OutputDeviceStatus expected_result) {
- EXPECT_CALL(*host_.get(),
- OnOutputDeviceSwitched(stream_id, expected_result));
- host_->OnSwitchOutputDevice(stream_id, kRenderFrameId, device_id,
- security_origin);
- SyncWithAudioThread();
- }
-
void SimulateError() {
EXPECT_EQ(1u, host_->audio_entries_.size())
<< "Calls Create() before calling this method";
@@ -343,79 +329,51 @@ class AudioRendererHostTest : public testing::Test {
};
TEST_F(AudioRendererHostTest, CreateAndClose) {
- Create(false);
+ Create();
Close();
}
// Simulate the case where a stream is not properly closed.
TEST_F(AudioRendererHostTest, CreateAndShutdown) {
- Create(false);
+ Create();
}
TEST_F(AudioRendererHostTest, CreatePlayAndClose) {
- Create(false);
+ Create();
Play();
Close();
}
TEST_F(AudioRendererHostTest, CreatePlayPauseAndClose) {
- Create(false);
+ Create();
Play();
Pause();
Close();
}
TEST_F(AudioRendererHostTest, SetVolume) {
- Create(false);
+ Create();
SetVolume(0.5);
Play();
Pause();
Close();
}
-TEST_F(AudioRendererHostTest, SwitchOutputDevice) {
- Create(false);
- SwitchOutputDevice(kStreamId, kDefaultDeviceID, kDefaultSecurityOrigin,
- media::OUTPUT_DEVICE_STATUS_OK);
- Close();
-}
-
-TEST_F(AudioRendererHostTest, SwitchOutputDeviceNotAuthorized) {
- Create(false);
- SwitchOutputDevice(kStreamId, kBadDeviceID, kSecurityOrigin,
- media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED);
- Close();
-}
-
-TEST_F(AudioRendererHostTest, SwitchOutputDeviceInvalidDeviceId) {
- Create(false);
- SwitchOutputDevice(kStreamId, kInvalidDeviceID, kSecurityOrigin,
- media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND);
- Close();
-}
-
-TEST_F(AudioRendererHostTest, SwitchOutputDeviceNoStream) {
- Create(false);
- SwitchOutputDevice(kBadStreamId, kDefaultDeviceID, kDefaultSecurityOrigin,
- media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
- Close();
-}
-
// Simulate the case where a stream is not properly closed.
TEST_F(AudioRendererHostTest, CreatePlayAndShutdown) {
- Create(false);
+ Create();
Play();
}
// Simulate the case where a stream is not properly closed.
TEST_F(AudioRendererHostTest, CreatePlayPauseAndShutdown) {
- Create(false);
+ Create();
Play();
Pause();
}
TEST_F(AudioRendererHostTest, SimulateError) {
- Create(false);
+ Create();
Play();
SimulateError();
}
@@ -424,14 +382,24 @@ TEST_F(AudioRendererHostTest, SimulateError) {
// the audio device is closed but the render process try to close the
// audio stream again.
TEST_F(AudioRendererHostTest, SimulateErrorAndClose) {
- Create(false);
+ Create();
Play();
SimulateError();
Close();
}
TEST_F(AudioRendererHostTest, CreateUnifiedStreamAndClose) {
- Create(true);
+ Create(true, kDefaultDeviceId, url::Origin());
+ Close();
+}
+
+TEST_F(AudioRendererHostTest, CreateUnauthorizedDevice) {
+ Create(false, kBadDeviceId, url::Origin(GURL(kSecurityOrigin)));
+ Close();
+}
+
+TEST_F(AudioRendererHostTest, CreateInvalidDevice) {
+ Create(false, kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)));
Close();
}
diff --git a/chromium/content/browser/renderer_host/media/audio_sync_reader.cc b/chromium/content/browser/renderer_host/media/audio_sync_reader.cc
index 7c493e1c68c..85b13f8453c 100644
--- a/chromium/content/browser/renderer_host/media/audio_sync_reader.cc
+++ b/chromium/content/browser/renderer_host/media/audio_sync_reader.cc
@@ -10,11 +10,13 @@
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/public/common/content_switches.h"
#include "media/audio/audio_parameters.h"
using media::AudioBus;
+using media::AudioOutputBuffer;
namespace {
@@ -51,8 +53,12 @@ AudioSyncReader::AudioSyncReader(base::SharedMemory* shared_memory,
maximum_wait_time_(base::TimeDelta::FromMilliseconds(20)),
#endif
buffer_index_(0) {
- DCHECK_EQ(packet_size_, AudioBus::CalculateMemorySize(params));
- output_bus_ = AudioBus::WrapMemory(params, shared_memory->memory());
+ DCHECK_EQ(static_cast<size_t>(packet_size_),
+ sizeof(media::AudioOutputBufferParameters) +
+ AudioBus::CalculateMemorySize(params));
+ AudioOutputBuffer* buffer =
+ reinterpret_cast<AudioOutputBuffer*>(shared_memory_->memory());
+ output_bus_ = AudioBus::WrapMemory(params, buffer->audio);
output_bus_->Zero();
}
@@ -81,10 +87,19 @@ AudioSyncReader::~AudioSyncReader() {
}
// media::AudioOutputController::SyncReader implementations.
-void AudioSyncReader::UpdatePendingBytes(uint32 bytes) {
+void AudioSyncReader::UpdatePendingBytes(uint32_t bytes,
+ uint32_t frames_skipped) {
+ // Increase the number of skipped frames stored in shared memory. We don't
+ // send it over the socket since sending more than 4 bytes might lead to being
+ // descheduled. The reading side will zero it when consumed.
+ AudioOutputBuffer* buffer =
+ reinterpret_cast<AudioOutputBuffer*>(shared_memory_->memory());
+ buffer->params.frames_skipped += frames_skipped;
+
// Zero out the entire output buffer to avoid stuttering/repeating-buffers
// in the anomalous case if the renderer is unable to keep up with real-time.
output_bus_->Zero();
+
socket_->Send(&bytes, sizeof(bytes));
++buffer_index_;
}
@@ -93,6 +108,12 @@ void AudioSyncReader::Read(AudioBus* dest) {
++renderer_callback_count_;
if (!WaitUntilDataIsReady()) {
++renderer_missed_callback_count_;
+ if (renderer_missed_callback_count_ <= 100) {
+ LOG(WARNING) << "AudioSyncReader::Read timed out, audio glitch count="
+ << renderer_missed_callback_count_;
+ if (renderer_missed_callback_count_ == 100)
+ LOG(WARNING) << "(log cap reached, suppressing further logs)";
+ }
dest->Zero();
return;
}
@@ -139,7 +160,7 @@ bool AudioSyncReader::WaitUntilDataIsReady() {
// catch up at some point, which means discarding counter values read from the
// SyncSocket which don't match our current buffer index.
size_t bytes_received = 0;
- uint32 renderer_buffer_index = 0;
+ uint32_t renderer_buffer_index = 0;
while (timeout.InMicroseconds() > 0) {
bytes_received = socket_->ReceiveWithTimeout(
&renderer_buffer_index, sizeof(renderer_buffer_index), timeout);
diff --git a/chromium/content/browser/renderer_host/media/audio_sync_reader.h b/chromium/content/browser/renderer_host/media/audio_sync_reader.h
index 16af1921894..6e07e5129b6 100644
--- a/chromium/content/browser/renderer_host/media/audio_sync_reader.h
+++ b/chromium/content/browser/renderer_host/media/audio_sync_reader.h
@@ -5,10 +5,15 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_SYNC_READER_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_SYNC_READER_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/process/process.h"
#include "base/sync_socket.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "media/audio/audio_output_controller.h"
#include "media/base/audio_bus.h"
@@ -34,7 +39,7 @@ class AudioSyncReader : public media::AudioOutputController::SyncReader {
~AudioSyncReader() override;
// media::AudioOutputController::SyncReader implementations.
- void UpdatePendingBytes(uint32 bytes) override;
+ void UpdatePendingBytes(uint32_t bytes, uint32_t frames_skipped) override;
void Read(media::AudioBus* dest) override;
void Close() override;
@@ -77,7 +82,7 @@ class AudioSyncReader : public media::AudioOutputController::SyncReader {
// The index of the audio buffer we're expecting to be sent from the renderer;
// used to block with timeout for audio data.
- uint32 buffer_index_;
+ uint32_t buffer_index_;
DISALLOW_COPY_AND_ASSIGN(AudioSyncReader);
};
diff --git a/chromium/content/browser/renderer_host/media/media_capture_devices_impl.h b/chromium/content/browser/renderer_host/media/media_capture_devices_impl.h
index d40a34ccce2..28d155c8770 100644
--- a/chromium/content/browser/renderer_host/media/media_capture_devices_impl.h
+++ b/chromium/content/browser/renderer_host/media/media_capture_devices_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_CAPTURE_DEVICES_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_CAPTURE_DEVICES_IMPL_H_
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/media_capture_devices.h"
diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 2b0a385f8f9..033dbb65a6d 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -121,27 +121,23 @@ void MediaStreamDispatcherHost::OnChannelClosing() {
MediaStreamDispatcherHost::~MediaStreamDispatcherHost() {
}
-void MediaStreamDispatcherHost::OnGenerateStream(
- int render_frame_id,
- int page_request_id,
- const StreamOptions& components,
- const GURL& security_origin,
- bool user_gesture) {
- DVLOG(1) << "MediaStreamDispatcherHost::OnGenerateStream("
- << render_frame_id << ", "
- << page_request_id << ", ["
- << " audio:" << components.audio_requested
- << " video:" << components.video_requested
- << " ], "
- << security_origin.spec()
- << ", " << user_gesture << ")";
+void MediaStreamDispatcherHost::OnGenerateStream(int render_frame_id,
+ int page_request_id,
+ const StreamControls& controls,
+ const GURL& security_origin,
+ bool user_gesture) {
+ DVLOG(1) << "MediaStreamDispatcherHost::OnGenerateStream(" << render_frame_id
+ << ", " << page_request_id << ", ["
+ << " audio:" << controls.audio.requested
+ << " video:" << controls.video.requested << " ], "
+ << security_origin.spec() << ", " << user_gesture << ")";
if (!IsURLAllowed(security_origin))
return;
media_stream_manager_->GenerateStream(
this, render_process_id_, render_frame_id, salt_callback_,
- page_request_id, components, security_origin, user_gesture);
+ page_request_id, controls, security_origin, user_gesture);
}
void MediaStreamDispatcherHost::OnCancelGenerateStream(int render_frame_id,
diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h
index f35ae26e992..a101067c67a 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h
+++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -9,6 +9,7 @@
#include <string>
#include <utility>
+#include "base/macros.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/media_stream_requester.h"
#include "content/common/content_export.h"
@@ -66,7 +67,7 @@ class CONTENT_EXPORT MediaStreamDispatcherHost : public BrowserMessageFilter,
void OnGenerateStream(int render_frame_id,
int page_request_id,
- const StreamOptions& components,
+ const StreamControls& controls,
const GURL& security_origin,
bool user_gesture);
void OnCancelGenerateStream(int render_frame_id,
diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index 22f000ed0af..9fee099443a 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -2,8 +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/media/media_stream_dispatcher_host.h"
+
+#include <stddef.h>
#include <queue>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/callback_helpers.h"
@@ -12,9 +16,9 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
-#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
@@ -76,12 +80,12 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
// Accessor to private functions.
void OnGenerateStream(int render_frame_id,
int page_request_id,
- const StreamOptions& components,
+ const StreamControls& controls,
const GURL& security_origin,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
MediaStreamDispatcherHost::OnGenerateStream(
- render_frame_id, page_request_id, components, security_origin, false);
+ render_frame_id, page_request_id, controls, security_origin, false);
}
void OnStopStreamDevice(int render_frame_id,
@@ -289,19 +293,17 @@ class MediaStreamDispatcherHostTest : public testing::Test {
void GenerateStreamAndWaitForResult(int render_frame_id,
int page_request_id,
- const StreamOptions& options) {
+ const StreamControls& controls) {
base::RunLoop run_loop;
int expected_audio_array_size =
- (options.audio_requested &&
- physical_audio_devices_.size() > 0) ? 1 : 0;
+ (controls.audio.requested && !physical_audio_devices_.empty()) ? 1 : 0;
int expected_video_array_size =
- (options.video_requested &&
- physical_video_devices_.size() > 0) ? 1 : 0;
+ (controls.video.requested && !physical_video_devices_.empty()) ? 1 : 0;
EXPECT_CALL(*host_.get(), OnStreamGenerated(render_frame_id,
page_request_id,
expected_audio_array_size,
expected_video_array_size));
- host_->OnGenerateStream(render_frame_id, page_request_id, options, origin_,
+ host_->OnGenerateStream(render_frame_id, page_request_id, controls, origin_,
run_loop.QuitClosure());
run_loop.Run();
EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
@@ -311,16 +313,16 @@ class MediaStreamDispatcherHostTest : public testing::Test {
}
void GenerateStreamAndWaitForFailure(
- int render_frame_id,
- int page_request_id,
- const StreamOptions& options,
- MediaStreamRequestResult expected_result) {
+ int render_frame_id,
+ int page_request_id,
+ const StreamControls& controls,
+ MediaStreamRequestResult expected_result) {
base::RunLoop run_loop;
EXPECT_CALL(*host_.get(),
OnStreamGenerationFailed(render_frame_id,
page_request_id,
expected_result));
- host_->OnGenerateStream(render_frame_id, page_request_id, options,
+ host_->OnGenerateStream(render_frame_id, page_request_id, controls,
origin_, run_loop.QuitClosure());
run_loop.Run();
}
@@ -419,12 +421,6 @@ class MediaStreamDispatcherHostTest : public testing::Test {
return true;
}
- void AddSourceIdConstraint(const std::string& source_id,
- StreamOptions::Constraints* constraints) {
- constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
- source_id));
- }
-
scoped_refptr<MockMediaStreamDispatcherHost> host_;
scoped_ptr<media::AudioManager> audio_manager_;
scoped_ptr<MediaStreamManager> media_stream_manager_;
@@ -440,20 +436,20 @@ class MediaStreamDispatcherHostTest : public testing::Test {
};
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_.size(), 0u);
EXPECT_EQ(host_->video_devices_.size(), 1u);
}
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
- StreamOptions options(true, false);
+ StreamControls controls(true, false);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_.size(), 1u);
EXPECT_EQ(host_->video_devices_.size(), 0u);
@@ -463,20 +459,17 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
// MediaStreamManager, so it will create an ordinary one which will not find
// a RenderFrameHostDelegate. This normally should only be the case at shutdown.
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
- StreamOptions options(false, false);
+ StreamControls controls(false, false);
- GenerateStreamAndWaitForFailure(
- kRenderId,
- kPageRequestId,
- options,
- MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN);
+ GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, controls,
+ MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN);
}
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
- StreamOptions options(true, true);
+ StreamControls controls(true, true);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_.size(), 1u);
EXPECT_EQ(host_->video_devices_.size(), 1u);
@@ -486,11 +479,11 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
// id. The same capture device with the same device and session id is expected
// to be used.
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
// Generate first stream.
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
// Check the latest generated stream.
EXPECT_EQ(host_->audio_devices_.size(), 0u);
@@ -501,7 +494,7 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
// Generate second stream.
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, controls);
// Check the latest generated stream.
EXPECT_EQ(host_->audio_devices_.size(), 0u);
@@ -516,11 +509,11 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
TEST_F(MediaStreamDispatcherHostTest,
GenerateStreamAndOpenDeviceFromSameRenderId) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
// Generate first stream.
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_.size(), 0u);
EXPECT_EQ(host_->video_devices_.size(), 1u);
@@ -544,11 +537,11 @@ TEST_F(MediaStreamDispatcherHostTest,
// This test generates two streams with video only using two separate render
// frame ids. The same device id but different session ids are expected.
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
// Generate first stream.
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
// Check the latest generated stream.
EXPECT_EQ(host_->audio_devices_.size(), 0u);
@@ -559,7 +552,7 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
// Generate second stream from another render frame.
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
+ GenerateStreamAndWaitForResult(kRenderId + 1, kPageRequestId + 1, controls);
// Check the latest generated stream.
EXPECT_EQ(host_->audio_devices_.size(), 0u);
@@ -576,7 +569,7 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
// stream to be generated before requesting the second.
// The same device id and session ids are expected.
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
// Generate first stream.
SetupFakeUI(true);
@@ -591,9 +584,9 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
}
base::RunLoop run_loop1;
base::RunLoop run_loop2;
- host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId, controls, origin_,
run_loop1.QuitClosure());
- host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + 1, controls, origin_,
run_loop2.QuitClosure());
run_loop1.Run();
@@ -614,11 +607,11 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
origin_,
audio_it->unique_id);
ASSERT_FALSE(source_id.empty());
- StreamOptions options(true, true);
- AddSourceIdConstraint(source_id, &options.mandatory_audio);
+ StreamControls controls(true, true);
+ controls.audio.device_ids.push_back(source_id);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
}
@@ -630,11 +623,11 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
origin_,
video_it->id());
ASSERT_FALSE(source_id.empty());
- StreamOptions options(true, true);
- AddSourceIdConstraint(source_id, &options.mandatory_video);
+ StreamControls controls(true, true);
+ controls.video.device_ids.push_back(source_id);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
}
}
@@ -653,11 +646,11 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
origin_,
audio_it->unique_id);
ASSERT_FALSE(source_id.empty());
- StreamOptions options(true, true);
- AddSourceIdConstraint(source_id, &options.optional_audio);
+ StreamControls controls(true, true);
+ controls.audio.device_ids.push_back(source_id);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
}
@@ -669,11 +662,11 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
origin_,
video_it->id());
ASSERT_FALSE(source_id.empty());
- StreamOptions options(true, true);
- AddSourceIdConstraint(source_id, &options.optional_video);
+ StreamControls controls(true, true);
+ controls.video.device_ids.push_back(source_id);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
}
}
@@ -681,59 +674,53 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
// Test that generating a stream with an invalid mandatory video source id fail.
TEST_F(MediaStreamDispatcherHostTest,
GenerateStreamsWithInvalidMandatoryVideoSourceId) {
- StreamOptions options(true, true);
- AddSourceIdConstraint("invalid source id", &options.mandatory_video);
-
- GenerateStreamAndWaitForFailure(
- kRenderId,
- kPageRequestId,
- options,
- MEDIA_DEVICE_NO_HARDWARE);
+ StreamControls controls(true, true);
+ controls.video.device_ids.push_back("invalid source id");
+
+ GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, controls,
+ MEDIA_DEVICE_NO_HARDWARE);
}
// Test that generating a stream with an invalid mandatory audio source id fail.
TEST_F(MediaStreamDispatcherHostTest,
GenerateStreamsWithInvalidMandatoryAudioSourceId) {
- StreamOptions options(true, true);
- AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
-
- GenerateStreamAndWaitForFailure(
- kRenderId,
- kPageRequestId,
- options,
- MEDIA_DEVICE_NO_HARDWARE);
+ StreamControls controls(true, true);
+ controls.audio.device_ids.push_back("invalid source id");
+
+ GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, controls,
+ MEDIA_DEVICE_NO_HARDWARE);
}
// Test that generating a stream with an invalid optional video source id
// succeed.
TEST_F(MediaStreamDispatcherHostTest,
GenerateStreamsWithInvalidOptionalVideoSourceId) {
- StreamOptions options(true, true);
- AddSourceIdConstraint("invalid source id", &options.optional_video);
+ StreamControls controls(true, true);
+ controls.video.alternate_device_ids.push_back("invalid source id");
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
}
// Test that generating a stream with an invalid optional audio source id
// succeed.
TEST_F(MediaStreamDispatcherHostTest,
GenerateStreamsWithInvalidOptionalAudioSourceId) {
- StreamOptions options(true, true);
- AddSourceIdConstraint("invalid source id", &options.optional_audio);
+ StreamControls controls(true, true);
+ controls.video.alternate_device_ids.push_back("invalid source id");
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
}
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
physical_video_devices_.clear();
video_capture_device_factory_->set_number_of_devices(0);
video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
- StreamOptions options(true, true);
+ StreamControls controls(true, true);
SetupFakeUI(false);
- GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
+ GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, controls,
MEDIA_DEVICE_NO_HARDWARE);
}
@@ -741,10 +728,10 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
// been opened in a MediaStream and by pepper, the device is only stopped for
// the MediaStream.
TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
std::string stream_request_label = host_->label_;
StreamDeviceInfo video_device_info = host_->video_devices_.front();
@@ -766,10 +753,10 @@ TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
}
TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
- StreamOptions options(true, true);
+ StreamControls controls(true, true);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
std::string request_label1 = host_->label_;
StreamDeviceInfo video_device_info = host_->video_devices_.front();
@@ -781,7 +768,7 @@ TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
request_label1).size());
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
std::string request_label2 = host_->label_;
StreamDeviceInfoArray request1_devices =
@@ -801,10 +788,10 @@ TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
TEST_F(MediaStreamDispatcherHostTest,
GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->video_devices_.size(), 1u);
// Generate a second stream.
@@ -812,7 +799,7 @@ TEST_F(MediaStreamDispatcherHostTest,
OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
base::RunLoop run_loop1;
- host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + 1, controls, origin_,
run_loop1.QuitClosure());
// Stop the video stream device from stream 1 while waiting for the
@@ -824,14 +811,14 @@ TEST_F(MediaStreamDispatcherHostTest,
}
TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
base::RunLoop run_loop;
// Create multiple GenerateStream requests.
size_t streams = 5;
for (size_t i = 1; i <= streams; ++i) {
- host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + i, controls, origin_,
run_loop.QuitClosure());
}
@@ -841,13 +828,13 @@ TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
}
TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
// Create first group of streams.
size_t generated_streams = 3;
for (size_t i = 0; i < generated_streams; ++i) {
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, controls);
}
// Calling OnChannelClosing() to cancel all the pending/generated streams.
@@ -856,15 +843,15 @@ TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
}
TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
- StreamOptions options(false, true);
+ StreamControls controls(false, true);
base::Closure close_callback;
scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
EXPECT_CALL(*stream_ui, OnStarted(_, _))
.WillOnce(SaveArg<0>(&close_callback));
- media_stream_manager_->UseFakeUIForTests(stream_ui.Pass());
+ media_stream_manager_->UseFakeUIForTests(std::move(stream_ui));
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_.size(), 0u);
EXPECT_EQ(host_->video_devices_.size(), 1u);
@@ -878,9 +865,9 @@ TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
// Test that the dispatcher is notified if a video device that is in use is
// being unplugged.
TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
- StreamOptions options(true, true);
+ StreamControls controls(true, true);
SetupFakeUI(true);
- GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
EXPECT_EQ(host_->audio_devices_.size(), 1u);
EXPECT_EQ(host_->video_devices_.size(), 1u);
diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager.cc b/chromium/content/browser/renderer_host/media/media_stream_manager.cc
index fe40223219d..f602e8d26b1 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager.cc
@@ -4,14 +4,19 @@
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
#include <cctype>
#include <list>
+#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/power_monitor/power_monitor.h"
#include "base/profiler/scoped_tracker.h"
#include "base/rand_util.h"
@@ -20,8 +25,9 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
+#include "base/threading/thread_local.h"
+#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
-#include "content/browser/media/capture/web_contents_capture_util.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
#include "content/browser/renderer_host/media/media_capture_devices_impl.h"
@@ -34,6 +40,7 @@
#include "content/public/browser/media_observer.h"
#include "content/public/browser/media_request_state.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents_media_capture_id.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/media_stream_request.h"
@@ -55,6 +62,9 @@
namespace content {
+base::LazyInstance<base::ThreadLocalPointer<MediaStreamManager>>::Leaky
+ g_media_stream_manager_tls_ptr = LAZY_INSTANCE_INITIALIZER;
+
// Forward declaration of DeviceMonitorMac and its only useable method.
class DeviceMonitorMac {
public:
@@ -84,22 +94,17 @@ std::string RandomLabel() {
return label;
}
-void ParseStreamType(const StreamOptions& options,
+void ParseStreamType(const StreamControls& controls,
MediaStreamType* audio_type,
MediaStreamType* video_type) {
*audio_type = MEDIA_NO_SERVICE;
*video_type = MEDIA_NO_SERVICE;
- if (options.audio_requested) {
- std::string audio_stream_source;
- bool mandatory = false;
- if (options.GetFirstAudioConstraintByName(kMediaStreamSource,
- &audio_stream_source,
- &mandatory)) {
- DCHECK(mandatory);
+ if (controls.audio.requested) {
+ if (!controls.audio.stream_source.empty()) {
// This is tab or screen capture.
- if (audio_stream_source == kMediaStreamSourceTab) {
+ if (controls.audio.stream_source == kMediaStreamSourceTab) {
*audio_type = content::MEDIA_TAB_AUDIO_CAPTURE;
- } else if (audio_stream_source == kMediaStreamSourceSystem) {
+ } else if (controls.audio.stream_source == kMediaStreamSourceSystem) {
*audio_type = content::MEDIA_DESKTOP_AUDIO_CAPTURE;
}
} else {
@@ -107,43 +112,36 @@ void ParseStreamType(const StreamOptions& options,
*audio_type = MEDIA_DEVICE_AUDIO_CAPTURE;
}
}
- if (options.video_requested) {
- std::string video_stream_source;
- bool mandatory = false;
- if (options.GetFirstVideoConstraintByName(kMediaStreamSource,
- &video_stream_source,
- &mandatory)) {
- DCHECK(mandatory);
- // This is tab or screen capture.
- if (video_stream_source == kMediaStreamSourceTab) {
- *video_type = content::MEDIA_TAB_VIDEO_CAPTURE;
- } else if (video_stream_source == kMediaStreamSourceScreen) {
- *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE;
- } else if (video_stream_source == kMediaStreamSourceDesktop) {
- *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE;
- }
- } else {
- // This is normal video device capture.
- *video_type = MEDIA_DEVICE_VIDEO_CAPTURE;
- }
+ if (controls.video.requested) {
+ if (!controls.video.stream_source.empty()) {
+ // This is tab or screen capture.
+ if (controls.video.stream_source == kMediaStreamSourceTab) {
+ *video_type = content::MEDIA_TAB_VIDEO_CAPTURE;
+ } else if (controls.video.stream_source == kMediaStreamSourceScreen) {
+ *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE;
+ } else if (controls.video.stream_source == kMediaStreamSourceDesktop) {
+ *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE;
+ }
+ } else {
+ // This is normal video device capture.
+ *video_type = MEDIA_DEVICE_VIDEO_CAPTURE;
+ }
}
}
// Turns off available audio effects (removes the flag) if the options
// explicitly turn them off.
-void FilterAudioEffects(const StreamOptions& options, int* effects) {
+void FilterAudioEffects(const StreamControls& controls, int* effects) {
DCHECK(effects);
// TODO(ajm): Should we handle ECHO_CANCELLER here?
}
// Unlike other effects, hotword is off by default, so turn it on if it's
// requested and available.
-void EnableHotwordEffect(const StreamOptions& options, int* effects) {
+void EnableHotwordEffect(const StreamControls& controls, int* effects) {
DCHECK(effects);
+ if (controls.hotword_enabled) {
#if defined(OS_CHROMEOS)
- std::string value;
- if (options.GetFirstAudioConstraintByName(
- kMediaStreamAudioHotword, &value, NULL) && value == "true") {
chromeos::AudioDeviceList devices;
chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices);
// Only enable if a hotword device exists.
@@ -153,29 +151,8 @@ void EnableHotwordEffect(const StreamOptions& options, int* effects) {
*effects |= media::AudioParameters::HOTWORD;
}
}
- }
#endif
-}
-
-// Private helper method for SendMessageToNativeLog() that obtains the global
-// MediaStreamManager instance on the UI thread before sending |message| to the
-// webrtcLoggingPrivate API.
-void DoAddLogMessage(const std::string& message) {
- // Must be on the UI thread to access BrowserMainLoop.
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- // May be null in tests.
- // TODO(vrk): Handle this more elegantly by having native log messages become
- // no-ops until MediaStreamManager is aware that a renderer process has
- // started logging. crbug.com/333894
- const BrowserMainLoop* browser_main_loop =
- content::BrowserMainLoop::GetInstance();
- if (!browser_main_loop)
- return;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&MediaStreamManager::AddLogMessageOnIOThread,
- base::Unretained(browser_main_loop->media_stream_manager()),
- message));
+ }
}
// Private helper method to generate a string for the log message that lists the
@@ -202,27 +179,6 @@ void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) {
device_info.device.name.clear();
}
-// Helper method that sends log messages to the render process hosts whose
-// corresponding render processes are in |render_process_ids|, to be used by
-// the webrtcLoggingPrivate API if requested.
-void AddLogMessageOnUIThread(const std::set<int>& requesting_process_ids,
- const std::string& message) {
-#if defined(ENABLE_WEBRTC)
- // Must be on the UI thread to access RenderProcessHost from process ID.
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- for (const int& requesting_process_id : requesting_process_ids) {
- // Log the message to all renderers that are requesting a MediaStream or
- // have a MediaStream running.
- content::RenderProcessHostImpl* const render_process_host_impl =
- static_cast<content::RenderProcessHostImpl*>(
- content::RenderProcessHost::FromID(requesting_process_id));
- if (render_process_host_impl)
- render_process_host_impl->WebRtcLogMessage(message);
- }
-#endif
-}
-
bool CalledOnIOThread() {
// Check if this function call is on the IO thread, except for unittests where
// an IO thread might not have been created.
@@ -230,8 +186,6 @@ bool CalledOnIOThread() {
!BrowserThread::IsMessageLoopValid(BrowserThread::IO);
}
-void DummyEnumerationCallback(const AudioOutputDeviceEnumeration& e) {}
-
} // namespace
@@ -250,7 +204,7 @@ class MediaStreamManager::DeviceRequest {
const GURL& security_origin,
bool user_gesture,
MediaStreamRequestType request_type,
- const StreamOptions& options,
+ const StreamControls& controls,
const ResourceContext::SaltCallback& salt_callback)
: requester(requester),
requesting_process_id(requesting_process_id),
@@ -259,14 +213,13 @@ class MediaStreamManager::DeviceRequest {
security_origin(security_origin),
user_gesture(user_gesture),
request_type(request_type),
- options(options),
+ controls(controls),
salt_callback(salt_callback),
state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED),
audio_type_(MEDIA_NO_SERVICE),
video_type_(MEDIA_NO_SERVICE),
target_process_id_(-1),
- target_frame_id_(-1) {
- }
+ target_frame_id_(-1) {}
~DeviceRequest() {}
@@ -326,7 +279,7 @@ class MediaStreamManager::DeviceRequest {
bool HasUIRequest() const { return ui_request_.get() != nullptr; }
scoped_ptr<MediaStreamRequest> DetachUIRequest() {
- return ui_request_.Pass();
+ return std::move(ui_request_);
}
// Update the request state and notify observers.
@@ -378,7 +331,7 @@ class MediaStreamManager::DeviceRequest {
const MediaStreamRequestType request_type;
- const StreamOptions options;
+ const StreamControls controls;
ResourceContext::SaltCallback salt_callback;
@@ -411,8 +364,19 @@ MediaStreamManager::EnumerationCache::~EnumerationCache() {
// static
void MediaStreamManager::SendMessageToNativeLog(const std::string& message) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(DoAddLogMessage, message));
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&MediaStreamManager::SendMessageToNativeLog, message));
+ return;
+ }
+
+ MediaStreamManager* msm = g_media_stream_manager_tls_ptr.Pointer()->Get();
+ if (!msm) {
+ DLOG(ERROR) << "No MediaStreamManager on the IO thread. " << message;
+ return;
+ }
+
+ msm->AddLogMessageOnIOThread(message);
}
MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
@@ -421,9 +385,6 @@ MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
video_capture_thread_("VideoCaptureThread"),
#endif
monitoring_started_(false),
-#if defined(OS_CHROMEOS)
- has_checked_keyboard_mic_(false),
-#endif
use_fake_ui_(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeUIForMediaStream)) {
DCHECK(audio_manager_);
@@ -449,6 +410,7 @@ MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
}
MediaStreamManager::~MediaStreamManager() {
+ DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::IO));
DVLOG(1) << "~MediaStreamManager";
DCHECK(requests_.empty());
DCHECK(!device_task_runner_.get());
@@ -483,22 +445,18 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
int render_process_id,
int render_frame_id,
int page_request_id,
- const StreamOptions& options,
+ const StreamControls& controls,
const GURL& security_origin,
const MediaRequestResponseCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// 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,
- render_process_id,
- render_frame_id,
- page_request_id,
- security_origin,
- false, // user gesture
- MEDIA_DEVICE_ACCESS,
- options,
- base::Bind(&ReturnEmptySalt));
+ DeviceRequest* request = new DeviceRequest(
+ NULL, render_process_id, render_frame_id, page_request_id,
+ security_origin,
+ false, // user gesture
+ MEDIA_DEVICE_ACCESS, controls, base::Bind(&ReturnEmptySalt));
const std::string& label = AddRequest(request);
@@ -520,21 +478,15 @@ void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
- const StreamOptions& options,
+ const StreamControls& controls,
const GURL& security_origin,
bool user_gesture) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "GenerateStream()";
- DeviceRequest* request = new DeviceRequest(requester,
- render_process_id,
- render_frame_id,
- page_request_id,
- security_origin,
- user_gesture,
- MEDIA_GENERATE_STREAM,
- options,
- sc);
+ DeviceRequest* request = new DeviceRequest(
+ requester, render_process_id, render_frame_id, page_request_id,
+ security_origin, user_gesture, MEDIA_GENERATE_STREAM, controls, sc);
const std::string& label = AddRequest(request);
@@ -714,15 +666,11 @@ std::string MediaStreamManager::EnumerateDevices(
type == MEDIA_DEVICE_VIDEO_CAPTURE ||
type == MEDIA_DEVICE_AUDIO_OUTPUT);
- DeviceRequest* request = new DeviceRequest(requester,
- render_process_id,
- render_frame_id,
- page_request_id,
- security_origin,
- false, // user gesture
- MEDIA_ENUMERATE_DEVICES,
- StreamOptions(),
- sc);
+ DeviceRequest* request =
+ new DeviceRequest(requester, render_process_id, render_frame_id,
+ page_request_id, security_origin,
+ false, // user gesture
+ MEDIA_ENUMERATE_DEVICES, StreamControls(), sc);
if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT)
request->SetAudioType(type);
else if (IsVideoMediaType(type))
@@ -791,10 +739,8 @@ void MediaStreamManager::AudioOutputDevicesEnumerated(
DVLOG(1) << "AudioOutputDevicesEnumerated()";
StreamDeviceInfoArray device_infos;
- // If the enumeration contains only one entry, it means there are no devices.
- // The single entry contains default parameters from the audio manager.
- if (device_enumeration.size() > 1) {
- for (const auto& entry : device_enumeration) {
+ if (device_enumeration.has_actual_devices) {
+ for (const auto& entry : device_enumeration.devices) {
StreamDeviceInfo device_info(MEDIA_DEVICE_AUDIO_OUTPUT, entry.device_name,
entry.unique_id);
device_infos.push_back(device_info);
@@ -835,27 +781,21 @@ void MediaStreamManager::OpenDevice(MediaStreamRequester* requester,
DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
type == MEDIA_DEVICE_VIDEO_CAPTURE);
DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id << "})";
- StreamOptions options;
+ StreamControls controls;
if (IsAudioInputMediaType(type)) {
- options.audio_requested = true;
- options.mandatory_audio.push_back(
- StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id));
+ controls.audio.requested = true;
+ controls.audio.device_ids.push_back(device_id);
} else if (IsVideoMediaType(type)) {
- options.video_requested = true;
- options.mandatory_video.push_back(
- StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id));
+ controls.video.requested = true;
+ controls.video.device_ids.push_back(device_id);
} else {
NOTREACHED();
}
- DeviceRequest* request = new DeviceRequest(requester,
- render_process_id,
- render_frame_id,
- page_request_id,
- security_origin,
- false, // user gesture
- MEDIA_OPEN_DEVICE,
- options,
- sc);
+ DeviceRequest* request =
+ new DeviceRequest(requester, render_process_id, render_frame_id,
+ page_request_id, security_origin,
+ false, // user gesture
+ MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, sc);
const std::string& label = AddRequest(request);
// Post a task and handle the request asynchronously. The reason is that the
@@ -966,13 +906,6 @@ void MediaStreamManager::StartMonitoring() {
monitoring_started_ = true;
base::SystemMonitor::Get()->AddDevicesChangedObserver(this);
- // Enable caching for audio output device enumerations and do an enumeration
- // to populate the cache.
- audio_output_device_enumerator_->SetCachePolicy(
- AudioOutputDeviceEnumerator::CACHE_POLICY_MANUAL_INVALIDATION);
- audio_output_device_enumerator_->Enumerate(
- base::Bind(&DummyEnumerationCallback));
-
// Enumerate both the audio and video input devices to cache the device lists
// and send them to media observer.
++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE];
@@ -1027,56 +960,55 @@ void MediaStreamManager::StartMonitoringOnUIThread() {
}
#endif
-bool MediaStreamManager::GetRequestedDeviceCaptureId(
- const DeviceRequest* request,
+// Pick the first valid (translatable) device ID from lists of required
+// and optional IDs.
+bool MediaStreamManager::PickDeviceId(
MediaStreamType type,
+ const ResourceContext::SaltCallback& salt_callback,
+ const GURL& security_origin,
+ const TrackControls& controls,
std::string* device_id) const {
- DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
- type == MEDIA_DEVICE_VIDEO_CAPTURE);
- const StreamOptions::Constraints* mandatory =
- (type == MEDIA_DEVICE_AUDIO_CAPTURE) ?
- &request->options.mandatory_audio : &request->options.mandatory_video;
- const StreamOptions::Constraints* optional =
- (type == MEDIA_DEVICE_AUDIO_CAPTURE) ?
- &request->options.optional_audio : &request->options.optional_video;
-
- std::vector<std::string> source_ids;
- StreamOptions::GetConstraintsByName(*mandatory,
- kMediaStreamSourceInfoId, &source_ids);
- if (source_ids.size() > 1) {
- LOG(ERROR) << "Only one mandatory " << kMediaStreamSourceInfoId
- << " is supported.";
- return false;
- }
- // If a specific device has been requested we need to find the real device
- // id.
- if (source_ids.size() == 1 &&
- !TranslateSourceIdToDeviceId(type,
- request->salt_callback,
- request->security_origin,
- source_ids[0], device_id)) {
- LOG(WARNING) << "Invalid mandatory " << kMediaStreamSourceInfoId
- << " = " << source_ids[0] << ".";
- return false;
+ if (!controls.device_ids.empty()) {
+ if (controls.device_ids.size() > 1) {
+ LOG(ERROR) << "Only one required device ID is supported";
+ return false;
+ }
+ const std::string& candidate_id = controls.device_ids[0];
+ if (!TranslateSourceIdToDeviceId(type, salt_callback, security_origin,
+ candidate_id, device_id)) {
+ LOG(WARNING) << "Invalid mandatory capture ID = " << candidate_id;
+ return false;
+ }
+ return true;
}
- // Check for optional audio sourceIDs.
- if (device_id->empty()) {
- StreamOptions::GetConstraintsByName(*optional,
- kMediaStreamSourceInfoId,
- &source_ids);
- // Find the first sourceID that translates to device. Note that only one
- // device per type can call to GenerateStream is ever opened.
- for (const std::string& source_id : source_ids) {
- if (TranslateSourceIdToDeviceId(type,
- request->salt_callback,
- request->security_origin,
- source_id,
- device_id)) {
- break;
- }
+ // We don't have a required ID. Look at the alternates.
+ for (const std::string& candidate_id : controls.alternate_device_ids) {
+ if (TranslateSourceIdToDeviceId(type, salt_callback, security_origin,
+ candidate_id, device_id)) {
+ return true;
+ } else {
+ LOG(WARNING) << "Invalid optional capture ID = " << candidate_id;
}
}
- return true;
+ return true; // If we get here, device_id is empty.
+}
+
+bool MediaStreamManager::GetRequestedDeviceCaptureId(
+ const DeviceRequest* request,
+ MediaStreamType type,
+ std::string* device_id) const {
+ if (type == MEDIA_DEVICE_AUDIO_CAPTURE) {
+ return PickDeviceId(type, request->salt_callback, request->security_origin,
+ request->controls.audio,
+ device_id);
+ } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) {
+ return PickDeviceId(type, request->salt_callback, request->security_origin,
+ request->controls.video,
+ device_id);
+ } else {
+ NOTREACHED();
+ }
+ return false;
}
void MediaStreamManager::TranslateDeviceIdToSourceId(
@@ -1212,7 +1144,7 @@ void MediaStreamManager::PostRequestToUI(const std::string& label,
fake_ui_->SetAvailableDevices(devices);
- request->ui_proxy = fake_ui_.Pass();
+ request->ui_proxy = std::move(fake_ui_);
} else {
request->ui_proxy = MediaStreamUIProxy::Create();
}
@@ -1241,7 +1173,7 @@ void MediaStreamManager::SetupRequest(const std::string& label) {
MediaStreamType audio_type = MEDIA_NO_SERVICE;
MediaStreamType video_type = MEDIA_NO_SERVICE;
- ParseStreamType(request->options, &audio_type, &video_type);
+ ParseStreamType(request->controls, &audio_type, &video_type);
request->SetAudioType(audio_type);
request->SetVideoType(video_type);
@@ -1262,10 +1194,6 @@ void MediaStreamManager::SetupRequest(const std::string& label) {
return;
}
-#if defined(OS_CHROMEOS)
- EnsureKeyboardMicChecked();
-#endif
-
if (!is_web_contents_capture && !is_screen_capture) {
if (EnumerationRequired(&audio_enumeration_cache_, audio_type) ||
EnumerationRequired(&video_enumeration_cache_, video_type)) {
@@ -1302,22 +1230,22 @@ bool MediaStreamManager::SetupDeviceCaptureRequest(DeviceRequest* request) {
(request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE ||
request->video_type() == MEDIA_NO_SERVICE));
std::string audio_device_id;
- if (request->options.audio_requested &&
+ if (request->controls.audio.requested &&
!GetRequestedDeviceCaptureId(request, request->audio_type(),
- &audio_device_id)) {
+ &audio_device_id)) {
return false;
}
std::string video_device_id;
- if (request->options.video_requested &&
+ if (request->controls.video.requested &&
!GetRequestedDeviceCaptureId(request, request->video_type(),
&video_device_id)) {
return false;
}
request->CreateUIRequest(audio_device_id, video_device_id);
- DVLOG(3) << "Audio requested " << request->options.audio_requested
- << " device id = " << audio_device_id
- << "Video requested " << request->options.video_requested
+ DVLOG(3) << "Audio requested " << request->controls.audio.requested
+ << " device id = " << audio_device_id << "Video requested "
+ << request->controls.video.requested
<< " device id = " << video_device_id;
return true;
}
@@ -1327,23 +1255,19 @@ bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) {
request->video_type() == MEDIA_TAB_VIDEO_CAPTURE);
std::string capture_device_id;
- bool mandatory_audio = false;
- bool mandatory_video = false;
- if (!request->options.GetFirstAudioConstraintByName(kMediaStreamSourceId,
- &capture_device_id,
- &mandatory_audio) &&
- !request->options.GetFirstVideoConstraintByName(kMediaStreamSourceId,
- &capture_device_id,
- &mandatory_video)) {
+ if (!request->controls.audio.device_ids.empty()) {
+ capture_device_id = request->controls.audio.device_ids[0];
+ } else if (!request->controls.video.device_ids.empty()) {
+ capture_device_id = request->controls.video.device_ids[0];
+ } else {
return false;
}
- DCHECK(mandatory_audio || mandatory_video);
- // Customize options for a WebContents based capture.
+ // Customize controls for a WebContents based capture.
int target_render_process_id = 0;
int target_render_frame_id = 0;
- bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget(
+ bool has_valid_device_id = WebContentsMediaCaptureId::ExtractTabCaptureTarget(
capture_device_id, &target_render_process_id, &target_render_frame_id);
if (!has_valid_device_id ||
(request->audio_type() != MEDIA_TAB_AUDIO_CAPTURE &&
@@ -1381,26 +1305,12 @@ bool MediaStreamManager::SetupScreenCaptureRequest(DeviceRequest* request) {
std::string video_device_id;
if (request->video_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) {
- std::string video_stream_source;
- bool mandatory = false;
- if (!request->options.GetFirstVideoConstraintByName(
- kMediaStreamSource,
- &video_stream_source,
- &mandatory)) {
- LOG(ERROR) << kMediaStreamSource << " not found.";
- return false;
- }
- DCHECK(mandatory);
-
- if (video_stream_source == kMediaStreamSourceDesktop) {
- if (!request->options.GetFirstVideoConstraintByName(
- kMediaStreamSourceId,
- &video_device_id,
- &mandatory)) {
- LOG(ERROR) << kMediaStreamSourceId << " not found.";
- return false;
- }
- DCHECK(mandatory);
+ const std::string& video_stream_source =
+ request->controls.video.stream_source;
+
+ if (video_stream_source == kMediaStreamSourceDesktop &&
+ !request->controls.video.device_ids.empty()) {
+ video_device_id = request->controls.video.device_ids[0];
}
}
@@ -1439,9 +1349,9 @@ bool MediaStreamManager::FindExistingRequestedDeviceInfo(
*existing_device_info = device_info;
// Make sure that the audio |effects| reflect what the request
// is set to and not what the capabilities are.
- FilterAudioEffects(request->options,
- &existing_device_info->device.input.effects);
- EnableHotwordEffect(request->options,
+ FilterAudioEffects(request->controls,
+ &existing_device_info->device.input.effects);
+ EnableHotwordEffect(request->controls,
&existing_device_info->device.input.effects);
*existing_request_state = request->state(device_info.device.type);
return true;
@@ -1483,7 +1393,7 @@ void MediaStreamManager::FinalizeRequestFailed(
if (request->request_type == MEDIA_DEVICE_ACCESS &&
!request->callback.is_null()) {
- request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass());
+ request->callback.Run(MediaStreamDevices(), std::move(request->ui_proxy));
}
DeleteRequest(label);
@@ -1517,7 +1427,7 @@ void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label,
if (use_fake_ui_) {
if (!fake_ui_)
fake_ui_.reset(new FakeMediaStreamUIProxy());
- request->ui_proxy = fake_ui_.Pass();
+ request->ui_proxy = std::move(fake_ui_);
} else {
request->ui_proxy = MediaStreamUIProxy::Create();
}
@@ -1595,13 +1505,21 @@ void MediaStreamManager::FinalizeMediaAccessRequest(
DeviceRequest* request,
const MediaStreamDevices& devices) {
if (!request->callback.is_null())
- request->callback.Run(devices, request->ui_proxy.Pass());
+ request->callback.Run(devices, std::move(request->ui_proxy));
// Delete the request since it is done.
DeleteRequest(label);
}
void MediaStreamManager::InitializeDeviceManagersOnIOThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Store a pointer to |this| on the IO thread to avoid having to jump to the
+ // UI thread to fetch a pointer to the MSM. In particular on Android, it can
+ // be problematic to post to a UI thread from arbitrary worker threads since
+ // attaching to the VM is required and we may have to access the MSM from
+ // callback threads that we don't own and don't want to attach.
+ g_media_stream_manager_tls_ptr.Pointer()->Set(this);
+
// TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is
// fixed.
tracked_objects::ScopedTracker tracking_profile1(
@@ -1688,9 +1606,9 @@ void MediaStreamManager::Opened(MediaStreamType stream_type,
// parameters to the default settings (including supported effects),
// we need to adjust those settings here according to what the
// request asks for.
- FilterAudioEffects(request->options,
+ FilterAudioEffects(request->controls,
&device_info.device.input.effects);
- EnableHotwordEffect(request->options,
+ EnableHotwordEffect(request->controls,
&device_info.device.input.effects);
device_info.device.matched_output = info->device.matched_output;
@@ -1711,7 +1629,7 @@ void MediaStreamManager::HandleRequestDone(const std::string& label,
<< ", {label = " << label << "})";
switch (request->request_type) {
- case MEDIA_OPEN_DEVICE:
+ case MEDIA_OPEN_DEVICE_PEPPER_ONLY:
FinalizeOpenDevice(label, request);
break;
case MEDIA_GENERATE_STREAM: {
@@ -1839,31 +1757,35 @@ void MediaStreamManager::UseFakeUIForTests(
scoped_ptr<FakeMediaStreamUIProxy> fake_ui) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
use_fake_ui_ = true;
- fake_ui_ = fake_ui.Pass();
+ fake_ui_ = std::move(fake_ui);
+}
+
+void MediaStreamManager::RegisterNativeLogCallback(
+ int renderer_host_id,
+ const base::Callback<void(const std::string&)>& callback) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&MediaStreamManager::DoNativeLogCallbackRegistration,
+ base::Unretained(this), renderer_host_id, callback));
+}
+
+void MediaStreamManager::UnregisterNativeLogCallback(int renderer_host_id) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&MediaStreamManager::DoNativeLogCallbackUnregistration,
+ base::Unretained(this), renderer_host_id));
}
void MediaStreamManager::AddLogMessageOnIOThread(const std::string& message) {
// Get render process ids on the IO thread.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Grab all unique process ids that request a MediaStream or have a
- // MediaStream running.
- std::set<int> requesting_process_ids;
for (const LabeledDeviceRequest& labeled_request : requests_) {
DeviceRequest* const request = labeled_request.second;
- if (request->request_type == MEDIA_GENERATE_STREAM)
- requesting_process_ids.insert(request->requesting_process_id);
+ if (request->request_type == MEDIA_GENERATE_STREAM) {
+ const auto& found = log_callbacks_.find(request->requesting_process_id);
+ if (found != log_callbacks_.end())
+ found->second.Run(message);
+ }
}
-
- // MediaStreamManager is a singleton in BrowserMainLoop, which owns the UI
- // thread. MediaStreamManager has the same lifetime as the UI thread, so it is
- // safe to use base::Unretained.
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(AddLogMessageOnUIThread,
- requesting_process_ids,
- message));
}
void MediaStreamManager::HandleAccessRequestResponse(
@@ -2002,6 +1924,7 @@ void MediaStreamManager::WillDestroyCurrentMessageLoop() {
audio_input_device_manager_ = NULL;
video_capture_manager_ = NULL;
audio_output_device_enumerator_ = NULL;
+ g_media_stream_manager_tls_ptr.Pointer()->Set(NULL);
}
void MediaStreamManager::NotifyDevicesChanged(
@@ -2074,7 +1997,6 @@ void MediaStreamManager::OnDevicesChanged(
MediaStreamType stream_type;
if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) {
stream_type = MEDIA_DEVICE_AUDIO_CAPTURE;
- audio_output_device_enumerator_->InvalidateCache();
} else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) {
stream_type = MEDIA_DEVICE_VIDEO_CAPTURE;
} else {
@@ -2106,37 +2028,19 @@ void MediaStreamManager::OnMediaStreamUIWindowId(MediaStreamType video_type,
}
}
-#if defined(OS_CHROMEOS)
-void MediaStreamManager::EnsureKeyboardMicChecked() {
+void MediaStreamManager::DoNativeLogCallbackRegistration(
+ int renderer_host_id,
+ const base::Callback<void(const std::string&)>& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!has_checked_keyboard_mic_) {
- has_checked_keyboard_mic_ = true;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&MediaStreamManager::CheckKeyboardMicOnUIThread,
- base::Unretained(this)));
- }
-}
-
-void MediaStreamManager::CheckKeyboardMicOnUIThread() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // We will post this on the device thread before the media media access
- // request is posted on the UI thread, so setting the keyboard mic info will
- // be done before any stream is created.
- if (chromeos::CrasAudioHandler::Get()->HasKeyboardMic()) {
- device_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&MediaStreamManager::SetKeyboardMicOnDeviceThread,
- base::Unretained(this)));
- }
+ // Re-registering (overwriting) is allowed and happens in some tests.
+ log_callbacks_[renderer_host_id] = callback;
}
-void MediaStreamManager::SetKeyboardMicOnDeviceThread() {
- DCHECK(device_task_runner_->BelongsToCurrentThread());
- audio_manager_->SetHasKeyboardMic();
+void MediaStreamManager::DoNativeLogCallbackUnregistration(
+ int renderer_host_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ log_callbacks_.erase(renderer_host_id);
}
-#endif
// static
std::string MediaStreamManager::GetHMACForMediaDeviceID(
@@ -2152,7 +2056,7 @@ std::string MediaStreamManager::GetHMACForMediaDeviceID(
crypto::HMAC hmac(crypto::HMAC::SHA256);
const size_t digest_length = hmac.DigestLength();
- std::vector<uint8> digest(digest_length);
+ std::vector<uint8_t> digest(digest_length);
std::string salt = sc.Run();
bool result = hmac.Init(security_origin.spec()) &&
hmac.Sign(raw_unique_id + salt, &digest[0], digest.size());
diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager.h b/chromium/content/browser/renderer_host/media/media_stream_manager.h
index af0658a5ce3..21d4f2f4050 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager.h
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager.h
@@ -27,17 +27,18 @@
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_
#include <list>
-#include <set>
+#include <map>
#include <string>
#include <utility>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_observer.h"
#include "base/system_monitor/system_monitor.h"
#include "base/threading/thread.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
#include "content/browser/renderer_host/media/media_stream_provider.h"
#include "content/common/content_export.h"
@@ -102,7 +103,7 @@ class CONTENT_EXPORT MediaStreamManager
int render_process_id,
int render_frame_id,
int page_request_id,
- const StreamOptions& options,
+ const StreamControls& controls,
const GURL& security_origin,
const MediaRequestResponseCallback& callback);
@@ -115,7 +116,7 @@ class CONTENT_EXPORT MediaStreamManager
int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
- const StreamOptions& components,
+ const StreamControls& controls,
const GURL& security_origin,
bool user_gesture);
@@ -213,6 +214,14 @@ class CONTENT_EXPORT MediaStreamManager
// generated stream (or when using --use-fake-ui-for-media-stream).
void UseFakeUIForTests(scoped_ptr<FakeMediaStreamUIProxy> fake_ui);
+ // Register and unregister a new callback for receiving native log entries.
+ // The registered callback will be invoked on the IO thread.
+ // The registration and unregistration will be done asynchronously so it is
+ // not guaranteed that when the call returns the operation has completed.
+ void RegisterNativeLogCallback(int renderer_host_id,
+ const base::Callback<void(const std::string&)>& callback);
+ void UnregisterNativeLogCallback(int renderer_host_id);
+
// Generates a hash of a device's unique ID usable by one
// particular security origin.
static std::string GetHMACForMediaDeviceID(
@@ -298,15 +307,15 @@ class CONTENT_EXPORT MediaStreamManager
void SetupRequest(const std::string& label);
// Prepare |request| of type MEDIA_DEVICE_AUDIO_CAPTURE and/or
// MEDIA_DEVICE_VIDEO_CAPTURE for being posted to the UI by parsing
- // StreamOptions::Constraints for requested device IDs.
+ // StreamControls for requested device IDs.
bool SetupDeviceCaptureRequest(DeviceRequest* request);
// Prepare |request| of type MEDIA_TAB_AUDIO_CAPTURE and/or
// MEDIA_TAB_VIDEO_CAPTURE for being posted to the UI by parsing
- // StreamOptions::Constraints for requested tab capture IDs.
+ // StreamControls for requested tab capture IDs.
bool SetupTabCaptureRequest(DeviceRequest* request);
// Prepare |request| of type MEDIA_DESKTOP_AUDIO_CAPTURE and/or
// MEDIA_DESKTOP_VIDEO_CAPTURE for being posted to the UI by parsing
- // StreamOptions::Constraints for the requested desktop ID.
+ // StreamControls for the requested desktop ID.
bool SetupScreenCaptureRequest(DeviceRequest* request);
// Called when a request has been setup and devices have been enumerated if
// needed.
@@ -352,7 +361,19 @@ class CONTENT_EXPORT MediaStreamManager
void StartMonitoringOnUIThread();
#endif
- // Finds the requested device id from constraints. The requested device type
+ // Picks a device ID from a list of required and alternate device IDs,
+ // presented as part of a TrackControls structure.
+ // Either the required device ID is picked (if present), or the first
+ // valid alternate device ID.
+ // Returns false if the required device ID is present and invalid.
+ // Otherwise, if no valid device is found, device_id is unchanged.
+ bool PickDeviceId(MediaStreamType type,
+ const ResourceContext::SaltCallback& salt_callback,
+ const GURL& security_origin,
+ const TrackControls& controls,
+ std::string* device_id) const;
+
+ // Finds the requested device id from request. The requested device type
// must be MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
bool GetRequestedDeviceCaptureId(const DeviceRequest* request,
MediaStreamType type,
@@ -367,19 +388,10 @@ class CONTENT_EXPORT MediaStreamManager
StreamDeviceInfoArray devices,
gfx::NativeViewId window_id);
-#if defined(OS_CHROMEOS)
- // Ensures that we have checked for presence of a keyboard mic. This is only
- // done once. This function should be called before posting a request on the
- // UI thread.
- void EnsureKeyboardMicChecked();
-
- // Checks if the system has a keyboard mic, and if so, inform the audio
- // manager via SetKeyboardMicOnDeviceThread().
- void CheckKeyboardMicOnUIThread();
-
- // Tells the audio mananger that the system supports a keyboard mic.
- void SetKeyboardMicOnDeviceThread();
-#endif
+ // Runs on the IO thread and does the actual [un]registration of callbacks.
+ void DoNativeLogCallbackRegistration(int renderer_host_id,
+ const base::Callback<void(const std::string&)>& callback);
+ void DoNativeLogCallbackUnregistration(int renderer_host_id);
// Task runner shared by VideoCaptureManager and AudioInputDeviceManager and
// used for enumerating audio output devices.
@@ -398,14 +410,6 @@ class CONTENT_EXPORT MediaStreamManager
// Indicator of device monitoring state.
bool monitoring_started_;
-#if defined(OS_CHROMEOS)
- // Flag that's set when we have checked if the system has a keyboard mic. We
- // only need to check it once, and not when constructing since that will
- // affect startup time.
- // Must be accessed on the IO thread;
- bool has_checked_keyboard_mic_;
-#endif
-
// Stores most recently enumerated device lists. The cache is cleared when
// monitoring is stopped or there is no request for that type of device.
EnumerationCache audio_enumeration_cache_;
@@ -421,6 +425,9 @@ class CONTENT_EXPORT MediaStreamManager
bool use_fake_ui_;
scoped_ptr<FakeMediaStreamUIProxy> fake_ui_;
+ // Maps render process hosts to log callbacks. Used on the IO thread.
+ std::map<int, base::Callback<void(const std::string&)>> log_callbacks_;
+
DISALLOW_COPY_AND_ASSIGN(MediaStreamManager);
};
diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index 9ef2bd395fc..9f7fadb0755 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -2,16 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <string>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/browser/renderer_host/media/media_stream_requester.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/common/media/media_stream_options.h"
#include "content/public/common/content_switches.h"
@@ -60,14 +66,14 @@ ResourceContext::SaltCallback GetMockSaltCallback() {
return base::Bind(&ReturnMockSalt);
}
-} // namespace
-
// This class mocks the audio manager and overrides the
// GetAudioInputDeviceNames() method to ensure that we can run our tests on
// the buildbots. media::AudioManagerBase
class MockAudioManager : public AudioManagerPlatform {
public:
- MockAudioManager() : AudioManagerPlatform(&fake_audio_log_factory_) {}
+ MockAudioManager()
+ : AudioManagerPlatform(&fake_audio_log_factory_),
+ num_output_devices_(2) {}
~MockAudioManager() override {}
void GetAudioInputDeviceNames(
@@ -81,11 +87,81 @@ class MockAudioManager : public AudioManagerPlatform {
}
}
+ void GetAudioOutputDeviceNames(
+ media::AudioDeviceNames* device_names) override {
+ DCHECK(device_names->empty());
+
+ // AudioManagers add a default device when there is at least one real device
+ if (num_output_devices_ > 0) {
+ device_names->push_back(media::AudioDeviceName(
+ "Default", AudioManagerBase::kDefaultDeviceId));
+ }
+ for (size_t i = 0; i < num_output_devices_; i++) {
+ device_names->push_back(media::AudioDeviceName(
+ std::string("fake_device_name_") + base::SizeTToString(i),
+ std::string("fake_device_id_") + base::SizeTToString(i)));
+ }
+ }
+
+ void SetNumAudioOutputDevices(size_t num_devices) {
+ num_output_devices_ = num_devices;
+ }
+
private:
media::FakeAudioLogFactory fake_audio_log_factory_;
+ size_t num_output_devices_;
DISALLOW_COPY_AND_ASSIGN(MockAudioManager);
};
+class MockMediaStreamRequester : public MediaStreamRequester {
+ public:
+ MockMediaStreamRequester(base::RunLoop* run_loop, size_t num_expected_devices)
+ : run_loop_(run_loop), num_expected_devices_(num_expected_devices) {}
+ virtual ~MockMediaStreamRequester() {}
+
+ // MediaStreamRequester implementation.
+ MOCK_METHOD5(StreamGenerated,
+ void(int render_frame_id,
+ int page_request_id,
+ const std::string& label,
+ const StreamDeviceInfoArray& audio_devices,
+ const StreamDeviceInfoArray& video_devices));
+ MOCK_METHOD3(StreamGenerationFailed,
+ void(int render_frame_id,
+ int page_request_id,
+ content::MediaStreamRequestResult result));
+ MOCK_METHOD3(DeviceStopped,
+ void(int render_frame_id,
+ const std::string& label,
+ const StreamDeviceInfo& device));
+ void DevicesEnumerated(int render_frame_id,
+ int page_request_id,
+ const std::string& label,
+ const StreamDeviceInfoArray& devices) override {
+ MockDevicesEnumerated(render_frame_id, page_request_id, label, devices);
+ EXPECT_EQ(num_expected_devices_, devices.size());
+
+ run_loop_->Quit();
+ }
+ MOCK_METHOD4(MockDevicesEnumerated,
+ void(int render_frame_id,
+ int page_request_id,
+ const std::string& label,
+ const StreamDeviceInfoArray& devices));
+ MOCK_METHOD4(DeviceOpened,
+ void(int render_frame_id,
+ int page_request_id,
+ const std::string& label,
+ const StreamDeviceInfo& device_info));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockMediaStreamRequester);
+ base::RunLoop* run_loop_;
+ size_t num_expected_devices_;
+};
+
+} // namespace
+
class MediaStreamManagerTest : public ::testing::Test {
public:
MediaStreamManagerTest()
@@ -118,16 +194,13 @@ class MediaStreamManagerTest : public ::testing::Test {
MediaStreamManager::MediaRequestResponseCallback callback =
base::Bind(&MediaStreamManagerTest::ResponseCallback,
base::Unretained(this), index);
- StreamOptions options(true, true);
- return media_stream_manager_->MakeMediaAccessRequest(render_process_id,
- render_frame_id,
- page_request_id,
- options,
- security_origin,
- callback);
+ StreamControls controls(true, true);
+ return media_stream_manager_->MakeMediaAccessRequest(
+ render_process_id, render_frame_id, page_request_id, controls,
+ security_origin, callback);
}
- scoped_ptr<media::AudioManager> audio_manager_;
+ scoped_ptr<MockAudioManager> audio_manager_;
scoped_ptr<MediaStreamManager> media_stream_manager_;
content::TestBrowserThreadBundle thread_bundle_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -162,17 +235,13 @@ TEST_F(MediaStreamManagerTest, MakeMultipleRequests) {
int render_frame_id = 2;
int page_request_id = 2;
GURL security_origin;
- StreamOptions options(true, true);
+ StreamControls controls(true, true);
MediaStreamManager::MediaRequestResponseCallback callback =
base::Bind(&MediaStreamManagerTest::ResponseCallback,
base::Unretained(this), 1);
std::string label2 = media_stream_manager_->MakeMediaAccessRequest(
- render_process_id,
- render_frame_id,
- page_request_id,
- options,
- security_origin,
- callback);
+ render_process_id, render_frame_id, page_request_id, controls,
+ security_origin, callback);
// Expecting the callbackS from requests will be triggered and quit the test.
// Note, the callbacks might come in a different order depending on the
@@ -228,4 +297,25 @@ TEST_F(MediaStreamManagerTest, DeviceID) {
EXPECT_TRUE((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'));
}
+TEST_F(MediaStreamManagerTest, EnumerationOutputDevices) {
+ for (size_t num_devices = 0; num_devices < 3; num_devices++) {
+ audio_manager_->SetNumAudioOutputDevices(num_devices);
+ base::RunLoop run_loop;
+ MockMediaStreamRequester requester(&run_loop,
+ num_devices == 0 ? 0 : num_devices + 1);
+ const int render_process_id = 1;
+ const int render_frame_id = 1;
+ const int page_request_id = 1;
+ const GURL security_origin("http://localhost");
+ EXPECT_CALL(requester,
+ MockDevicesEnumerated(render_frame_id, page_request_id, _, _));
+ std::string label = media_stream_manager_->EnumerateDevices(
+ &requester, render_process_id, render_frame_id, GetMockSaltCallback(),
+ page_request_id, MEDIA_DEVICE_AUDIO_OUTPUT, security_origin);
+ run_loop.Run();
+ // CancelRequest is necessary for enumeration requests.
+ media_stream_manager_->CancelRequest(label);
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc b/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc
index 328d60e28ac..3b74b40f140 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc
@@ -46,7 +46,7 @@ bool MediaStreamTrackMetricsHost::OnMessageReceived(
return handled;
}
-void MediaStreamTrackMetricsHost::OnAddTrack(uint64 id,
+void MediaStreamTrackMetricsHost::OnAddTrack(uint64_t id,
bool is_audio,
bool is_remote) {
if (tracks_.find(id) != tracks_.end())
@@ -56,7 +56,7 @@ void MediaStreamTrackMetricsHost::OnAddTrack(uint64 id,
tracks_[id] = info;
}
-void MediaStreamTrackMetricsHost::OnRemoveTrack(uint64 id) {
+void MediaStreamTrackMetricsHost::OnRemoveTrack(uint64_t id) {
if (tracks_.find(id) == tracks_.end())
return;
diff --git a/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.h b/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.h
index 35235dba611..c800f3a5824 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.h
+++ b/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_TRACK_METRICS_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_TRACK_METRICS_HOST_H_
+#include <stdint.h>
+
#include <map>
#include <string>
@@ -37,8 +39,8 @@ class MediaStreamTrackMetricsHost
bool OnMessageReceived(const IPC::Message& message) override;
private:
- void OnAddTrack(uint64 id, bool is_audio, bool is_remote);
- void OnRemoveTrack(uint64 id);
+ void OnAddTrack(uint64_t id, bool is_audio, bool is_remote);
+ void OnRemoveTrack(uint64_t id);
// Information for a track we're keeping in |tracks_|. |is_audio|
// specifies whether it's an audio or video track, |is_remote|
@@ -54,7 +56,7 @@ class MediaStreamTrackMetricsHost
void ReportDuration(const TrackInfo& info);
// Values are unique (per renderer) track IDs.
- typedef std::map<uint64, TrackInfo> TrackMap;
+ typedef std::map<uint64_t, TrackInfo> TrackMap;
TrackMap tracks_;
};
diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc
index 990471f94bc..f21618f484e 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc
@@ -5,6 +5,7 @@
#include <string>
#include "base/bind.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/media/media_stream_settings_requester.h"
diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc
index 6d79ab45727..6cecbec2feb 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc
@@ -4,7 +4,10 @@
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
+#include <utility>
+
#include "base/command_line.h"
+#include "base/macros.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -129,7 +132,7 @@ void MediaStreamUIProxy::Core::ProcessAccessRequestResponse(
scoped_ptr<MediaStreamUI> stream_ui) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ui_ = stream_ui.Pass();
+ ui_ = std::move(stream_ui);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse,
diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.h b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.h
index 117f7c4a666..0c2eaeae196 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.h
+++ b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_UI_PROXY_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_UI_PROXY_H_
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_thread.h"
diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
index 373de9d2480..eae9607c600 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
+#include <utility>
+
#include "base/message_loop/message_loop.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/public/test/test_browser_thread.h"
@@ -95,8 +97,9 @@ TEST_F(MediaStreamUIProxyTest, Deny) {
MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess(
- request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
- base::Unretained(&response_callback_)));
+ std::move(request),
+ base::Bind(&MockResponseCallback::OnAccessRequestResponse,
+ base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
_))
@@ -125,8 +128,9 @@ TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess(
- request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
- base::Unretained(&response_callback_)));
+ std::move(request),
+ base::Bind(&MockResponseCallback::OnAccessRequestResponse,
+ base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
_))
@@ -139,7 +143,7 @@ TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(0));
- callback.Run(devices, MEDIA_DEVICE_OK, ui.Pass());
+ callback.Run(devices, MEDIA_DEVICE_OK, std::move(ui));
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
@@ -163,8 +167,9 @@ TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess(
- request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
- base::Unretained(&response_callback_)));
+ std::move(request),
+ base::Bind(&MockResponseCallback::OnAccessRequestResponse,
+ base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr)
, _))
@@ -176,7 +181,7 @@ TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
MediaStreamDevices devices;
scoped_ptr<MediaStreamUI> ui;
- callback.Run(devices, MEDIA_DEVICE_OK, ui.Pass());
+ callback.Run(devices, MEDIA_DEVICE_OK, std::move(ui));
}
TEST_F(MediaStreamUIProxyTest, StopFromUI) {
@@ -189,8 +194,9 @@ TEST_F(MediaStreamUIProxyTest, StopFromUI) {
MEDIA_DEVICE_VIDEO_CAPTURE));
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess(
- request.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse,
- base::Unretained(&response_callback_)));
+ std::move(request),
+ base::Bind(&MockResponseCallback::OnAccessRequestResponse,
+ base::Unretained(&response_callback_)));
MediaResponseCallback callback;
EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr)
, _))
@@ -206,7 +212,7 @@ TEST_F(MediaStreamUIProxyTest, StopFromUI) {
scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_))
.WillOnce(testing::DoAll(SaveArg<0>(&stop_callback), Return(0)));
- callback.Run(devices, MEDIA_DEVICE_OK, ui.Pass());
+ callback.Run(devices, MEDIA_DEVICE_OK, std::move(ui));
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
@@ -238,7 +244,7 @@ TEST_F(MediaStreamUIProxyTest, WindowIdCallbackCalled) {
MediaStreamRequest* request_ptr = request.get();
proxy_->RequestAccess(
- request.Pass(),
+ std::move(request),
base::Bind(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
@@ -251,7 +257,7 @@ TEST_F(MediaStreamUIProxyTest, WindowIdCallbackCalled) {
scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(kWindowId));
- callback.Run(MediaStreamDevices(), MEDIA_DEVICE_OK, ui.Pass());
+ callback.Run(MediaStreamDevices(), MEDIA_DEVICE_OK, std::move(ui));
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _));
MockStopStreamHandler handler;
diff --git a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
index e3accebb63a..41580ebe9c7 100644
--- a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
+++ b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
@@ -41,7 +41,7 @@ void PeerConnectionTrackerHost::OverrideThreadForMessage(
PeerConnectionTrackerHost::~PeerConnectionTrackerHost() {
}
-void PeerConnectionTrackerHost::OnChannelConnected(int32 peer_pid) {
+void PeerConnectionTrackerHost::OnChannelConnected(int32_t peer_pid) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Add PowerMonitor when connected to channel rather than in constructor due
// to thread safety concerns. Observers of PowerMonitor must be added and
diff --git a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h
index 788af93ce61..53a96302e04 100644
--- a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h
+++ b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_PEER_CONNECTION_TRACKER_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_PEER_CONNECTION_TRACKER_HOST_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/power_monitor/power_observer.h"
#include "content/public/browser/browser_message_filter.h"
@@ -29,7 +32,7 @@ class PeerConnectionTrackerHost : public BrowserMessageFilter,
bool OnMessageReceived(const IPC::Message& message) override;
void OverrideThreadForMessage(const IPC::Message& message,
BrowserThread::ID* thread) override;
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnChannelClosing() override;
// base::PowerObserver override.
diff --git a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.cc b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.cc
index f3a2c48055a..a934a40cf81 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.cc
@@ -6,8 +6,8 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/stl_util.h"
+#include "build/build_config.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/public/browser/browser_thread.h"
#include "ui/gfx/buffer_format_util.h"
@@ -24,7 +24,7 @@ class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle {
base::SharedMemoryHandle handle)
: data_(data),
mapped_size_(mapped_size)
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
,
handle_(handle)
#endif
@@ -45,20 +45,16 @@ class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle {
NOTREACHED();
return nullptr;
}
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
base::FileDescriptor AsPlatformFile() override {
-#if defined(OS_MACOSX)
- return handle_.GetFileDescriptor();
-#else
return handle_;
-#endif // defined(OS_MACOSX)
}
#endif
private:
void* const data_;
const size_t mapped_size_;
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
const base::SharedMemoryHandle handle_;
#endif
};
@@ -68,33 +64,28 @@ class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle {
class GpuMemoryBufferBufferHandle final
: public VideoCaptureBufferPool::BufferHandle {
public:
- GpuMemoryBufferBufferHandle(std::vector<void*>* data,
- const gfx::Size& dimensions,
- ScopedVector<gfx::GpuMemoryBuffer>* gmbs)
- : data_(data), dimensions_(dimensions), gmbs_(gmbs) {
-#ifndef NDEBUG
- DCHECK_EQ(data->size(), gmbs->size());
- for (const auto& gmb : *gmbs)
- DCHECK(gmb && gmb->IsMapped());
- for (const auto& data_ptr : *data)
- DCHECK(data_ptr);
-#endif
+ GpuMemoryBufferBufferHandle(const gfx::Size& dimensions,
+ std::vector<
+ scoped_ptr<gfx::GpuMemoryBuffer>>* gmbs)
+ : dimensions_(dimensions), gmbs_(gmbs) {
+ DCHECK(gmbs);
}
~GpuMemoryBufferBufferHandle() override {}
gfx::Size dimensions() const override { return dimensions_; }
size_t mapped_size() const override { return dimensions_.GetArea(); }
void* data(int plane) override {
- DCHECK_GE(plane, media::VideoFrame::kYPlane);
- DCHECK_LT(plane, static_cast<int>(data_->size()));
- return data_->at(plane);
+ DCHECK_GE(plane, 0);
+ DCHECK_LT(plane, static_cast<int>(gmbs_->size()));
+ DCHECK((*gmbs_)[plane]);
+ return (*gmbs_)[plane]->memory(0);
}
ClientBuffer AsClientBuffer(int plane) override {
- DCHECK_GE(plane, media::VideoFrame::kYPlane);
+ DCHECK_GE(plane, 0);
DCHECK_LT(plane, static_cast<int>(gmbs_->size()));
return (*gmbs_)[plane]->AsClientBuffer();
}
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
base::FileDescriptor AsPlatformFile() override {
NOTREACHED();
return base::FileDescriptor();
@@ -102,9 +93,8 @@ class GpuMemoryBufferBufferHandle final
#endif
private:
- std::vector<void*>* data_;
const gfx::Size dimensions_;
- ScopedVector<gfx::GpuMemoryBuffer>* const gmbs_;
+ std::vector<scoped_ptr<gfx::GpuMemoryBuffer>>* const gmbs_;
};
// Tracker specifics for SharedMemory.
@@ -113,7 +103,8 @@ class VideoCaptureBufferPool::SharedMemTracker final : public Tracker {
SharedMemTracker();
bool Init(media::VideoPixelFormat format,
media::VideoPixelStorage storage_type,
- const gfx::Size& dimensions) override;
+ const gfx::Size& dimensions,
+ base::Lock* lock) override;
scoped_ptr<BufferHandle> GetBufferHandle() override {
return make_scoped_ptr(new SimpleBufferHandle(
@@ -143,12 +134,15 @@ class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker {
GpuMemoryBufferTracker();
bool Init(media::VideoPixelFormat format,
media::VideoPixelStorage storage_type,
- const gfx::Size& dimensions) override;
+ const gfx::Size& dimensions,
+ base::Lock* lock) override;
~GpuMemoryBufferTracker() override;
scoped_ptr<BufferHandle> GetBufferHandle() override {
- return make_scoped_ptr(new GpuMemoryBufferBufferHandle(
- &data_, dimensions_, &gpu_memory_buffers_));
+ DCHECK_EQ(gpu_memory_buffers_.size(),
+ media::VideoFrame::NumPlanes(pixel_format()));
+ return make_scoped_ptr(
+ new GpuMemoryBufferBufferHandle(dimensions_, &gpu_memory_buffers_));
}
bool ShareToProcess(base::ProcessHandle process_handle,
base::SharedMemoryHandle* new_handle) override {
@@ -160,10 +154,9 @@ class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker {
gfx::GpuMemoryBufferHandle* new_handle) override;
private:
- std::vector<void*> data_;
gfx::Size dimensions_;
// Owned references to GpuMemoryBuffers.
- ScopedVector<gfx::GpuMemoryBuffer> gpu_memory_buffers_;
+ std::vector<scoped_ptr<gfx::GpuMemoryBuffer>> gpu_memory_buffers_;
};
VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {}
@@ -171,7 +164,8 @@ VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {}
bool VideoCaptureBufferPool::SharedMemTracker::Init(
media::VideoPixelFormat format,
media::VideoPixelStorage storage_type,
- const gfx::Size& dimensions) {
+ const gfx::Size& dimensions,
+ base::Lock* lock) {
DVLOG(2) << "allocating ShMem of " << dimensions.ToString();
set_pixel_format(format);
set_storage_type(storage_type);
@@ -190,16 +184,15 @@ VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker()
}
VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() {
- for (const auto& gmb : gpu_memory_buffers_) {
- if (gmb->IsMapped())
- gmb->Unmap();
- }
+ for (const auto& gmb : gpu_memory_buffers_)
+ gmb->Unmap();
}
bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init(
media::VideoPixelFormat format,
media::VideoPixelStorage storage_type,
- const gfx::Size& dimensions) {
+ const gfx::Size& dimensions,
+ base::Lock* lock) {
DVLOG(2) << "allocating GMB for " << dimensions.ToString();
// BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread.
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -215,26 +208,21 @@ bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init(
return true;
dimensions_ = dimensions;
- const media::VideoPixelFormat video_format = media::PIXEL_FORMAT_I420;
- const size_t num_planes = media::VideoFrame::NumPlanes(video_format);
+ lock->Release();
+ const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format());
for (size_t i = 0; i < num_planes; ++i) {
const gfx::Size& size =
- media::VideoFrame::PlaneSize(video_format, i, dimensions);
+ media::VideoFrame::PlaneSize(pixel_format(), i, dimensions);
gpu_memory_buffers_.push_back(
BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer(
- size,
- gfx::BufferFormat::R_8,
- gfx::BufferUsage::MAP));
+ size, gfx::BufferFormat::R_8,
+ gfx::BufferUsage::GPU_READ_CPU_READ_WRITE));
DLOG_IF(ERROR, !gpu_memory_buffers_[i]) << "Allocating GpuMemoryBuffer";
- if (!gpu_memory_buffers_[i])
+ if (!gpu_memory_buffers_[i] || !gpu_memory_buffers_[i]->Map())
return false;
-
- void* temp_data = nullptr;
- gpu_memory_buffers_[i]->Map(&temp_data);
- DCHECK(temp_data);
- data_.push_back(temp_data);
}
+ lock->Acquire();
return true;
}
@@ -244,38 +232,43 @@ bool VideoCaptureBufferPool::GpuMemoryBufferTracker::ShareToProcess2(
gfx::GpuMemoryBufferHandle* new_handle) {
DCHECK_LE(plane, static_cast<int>(gpu_memory_buffers_.size()));
- const auto& current_gmb_handle = gpu_memory_buffers_[plane]->GetHandle();
- switch (current_gmb_handle.type) {
- case gfx::EMPTY_BUFFER:
- NOTREACHED();
- return false;
- case gfx::SHARED_MEMORY_BUFFER: {
- DCHECK(base::SharedMemory::IsHandleValid(current_gmb_handle.handle));
- base::SharedMemory shared_memory(
- base::SharedMemory::DuplicateHandle(current_gmb_handle.handle),
- false);
- shared_memory.ShareToProcess(process_handle, &new_handle->handle);
- DCHECK(base::SharedMemory::IsHandleValid(new_handle->handle));
- new_handle->type = gfx::SHARED_MEMORY_BUFFER;
- return true;
- }
- case gfx::IO_SURFACE_BUFFER:
- case gfx::SURFACE_TEXTURE_BUFFER:
- case gfx::OZONE_NATIVE_PIXMAP:
- *new_handle = current_gmb_handle;
- return true;
- }
- NOTREACHED();
- return true;
- }
+ const auto& current_gmb_handle = gpu_memory_buffers_[plane]->GetHandle();
+ switch (current_gmb_handle.type) {
+ case gfx::EMPTY_BUFFER:
+ NOTREACHED();
+ return false;
+ case gfx::SHARED_MEMORY_BUFFER: {
+ DCHECK(base::SharedMemory::IsHandleValid(current_gmb_handle.handle));
+ base::SharedMemory shared_memory(
+ base::SharedMemory::DuplicateHandle(current_gmb_handle.handle),
+ false);
+ shared_memory.ShareToProcess(process_handle, &new_handle->handle);
+ DCHECK(base::SharedMemory::IsHandleValid(new_handle->handle));
+ new_handle->type = gfx::SHARED_MEMORY_BUFFER;
+ return true;
+ }
+ case gfx::IO_SURFACE_BUFFER:
+ case gfx::SURFACE_TEXTURE_BUFFER:
+ case gfx::OZONE_NATIVE_PIXMAP:
+ *new_handle = current_gmb_handle;
+ return true;
+ }
+ NOTREACHED();
+ return true;
+}
// static
scoped_ptr<VideoCaptureBufferPool::Tracker>
-VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) {
- if (!use_gmb)
- return make_scoped_ptr(new SharedMemTracker());
- else
- return make_scoped_ptr(new GpuMemoryBufferTracker());
+VideoCaptureBufferPool::Tracker::CreateTracker(
+ media::VideoPixelStorage storage) {
+ switch (storage) {
+ case media::PIXEL_STORAGE_GPUMEMORYBUFFER:
+ return make_scoped_ptr(new GpuMemoryBufferTracker());
+ case media::PIXEL_STORAGE_CPU:
+ return make_scoped_ptr(new SharedMemTracker());
+ }
+ NOTREACHED();
+ return scoped_ptr<VideoCaptureBufferPool::Tracker>();
}
VideoCaptureBufferPool::Tracker::~Tracker() {}
@@ -409,7 +402,6 @@ int VideoCaptureBufferPool::ReserveForProducerInternal(
const gfx::Size& dimensions,
int* buffer_id_to_drop) {
lock_.AssertAcquired();
- *buffer_id_to_drop = kInvalidId;
const size_t size_in_pixels = dimensions.GetArea();
// Look for a tracker that's allocated, big enough, and not in use. Track the
@@ -450,12 +442,14 @@ int VideoCaptureBufferPool::ReserveForProducerInternal(
// Create the new tracker.
const int buffer_id = next_buffer_id_++;
- scoped_ptr<Tracker> tracker = Tracker::CreateTracker(
- storage_type == media::PIXEL_STORAGE_GPUMEMORYBUFFER);
- if (!tracker->Init(pixel_format, storage_type, dimensions)) {
+ scoped_ptr<Tracker> tracker = Tracker::CreateTracker(storage_type);
+ // TODO(emircan): We pass the lock here to solve GMB allocation issue, see
+ // crbug.com/545238.
+ if (!tracker->Init(pixel_format, storage_type, dimensions, &lock_)) {
DLOG(ERROR) << "Error initializing Tracker";
return kInvalidId;
}
+
tracker->set_held_by_producer(true);
trackers_[buffer_id] = tracker.release();
diff --git a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.h b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.h
index defd2af6631..c69a842a79b 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool.h
@@ -5,14 +5,17 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_
+#include <stddef.h>
+
#include <map>
-#include "base/basictypes.h"
#include "base/files/file.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "base/process/process.h"
#include "base/synchronization/lock.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "media/base/video_capture_types.h"
#include "media/base/video_frame.h"
@@ -55,7 +58,7 @@ class CONTENT_EXPORT VideoCaptureBufferPool
virtual size_t mapped_size() const = 0;
virtual void* data(int plane) = 0;
virtual ClientBuffer AsClientBuffer(int plane) = 0;
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
virtual base::FileDescriptor AsPlatformFile() = 0;
#endif
};
@@ -119,13 +122,14 @@ class CONTENT_EXPORT VideoCaptureBufferPool
// Tracker carries indication of pixel format and storage type.
class Tracker {
public:
- static scoped_ptr<Tracker> CreateTracker(bool use_gmb);
+ static scoped_ptr<Tracker> CreateTracker(media::VideoPixelStorage storage);
Tracker()
: pixel_count_(0), held_by_producer_(false), consumer_hold_count_(0) {}
virtual bool Init(media::VideoPixelFormat format,
media::VideoPixelStorage storage_type,
- const gfx::Size& dimensions) = 0;
+ const gfx::Size& dimensions,
+ base::Lock* lock) = 0;
virtual ~Tracker();
size_t pixel_count() const { return pixel_count_; }
diff --git a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
index 90b2d492085..21c61326024 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
@@ -6,17 +6,23 @@
#include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <utility>
+
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
+#include "build/build_config.h"
#include "cc/test/test_context_provider.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "content/browser/compositor/buffer_queue.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "media/base/video_frame.h"
-#include "media/base/video_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -30,7 +36,6 @@ struct PixelFormatAndStorage {
static const PixelFormatAndStorage kCapturePixelFormatAndStorages[] = {
{media::PIXEL_FORMAT_I420, media::PIXEL_STORAGE_CPU},
{media::PIXEL_FORMAT_ARGB, media::PIXEL_STORAGE_CPU},
- {media::PIXEL_FORMAT_ARGB, media::PIXEL_STORAGE_TEXTURE},
#if !defined(OS_ANDROID)
{media::PIXEL_FORMAT_I420,
media::PIXEL_STORAGE_GPUMEMORYBUFFER},
@@ -48,26 +53,32 @@ class VideoCaptureBufferPoolTest
class MockGpuMemoryBuffer : public gfx::GpuMemoryBuffer {
public:
explicit MockGpuMemoryBuffer(const gfx::Size& size)
- : size_(size), data_(new uint8[size_.GetArea() * 4]), mapped_(false) {}
+ : size_(size),
+ data_(new uint8_t[size_.GetArea() * 4]),
+ mapped_(false) {}
~MockGpuMemoryBuffer() override { delete[] data_; }
- bool Map(void** data) override {
- EXPECT_EQ(mapped_, false);
+ bool Map() override {
+ EXPECT_FALSE(mapped_);
mapped_ = true;
- data[0] = static_cast<void*>(data_);
return true;
}
+ void* memory(size_t plane) override {
+ EXPECT_TRUE(mapped_);
+ EXPECT_EQ(0u, plane);
+ return static_cast<void*>(data_);
+ }
void Unmap() override {
- EXPECT_EQ(mapped_, true);
+ EXPECT_TRUE(mapped_);
mapped_ = false;
}
- bool IsMapped() const override { return mapped_; }
+ gfx::Size GetSize() const override { return size_; }
gfx::BufferFormat GetFormat() const override {
return gfx::BufferFormat::BGRA_8888;
}
- void GetStride(int* stride) const override {
- *stride = size_.width() * 4;
- return;
+ int stride(size_t plane) const override {
+ EXPECT_EQ(0u, plane);
+ return size_.width() * 4;
}
gfx::GpuMemoryBufferId GetId() const override {
return gfx::GpuMemoryBufferId(0);
@@ -79,7 +90,7 @@ class VideoCaptureBufferPoolTest
private:
const gfx::Size size_;
- uint8* const data_;
+ uint8_t* const data_;
bool mapped_;
};
@@ -121,7 +132,7 @@ class VideoCaptureBufferPoolTest
Buffer(const scoped_refptr<VideoCaptureBufferPool> pool,
scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle,
int id)
- : id_(id), pool_(pool), buffer_handle_(buffer_handle.Pass()) {}
+ : id_(id), pool_(pool), buffer_handle_(std::move(buffer_handle)) {}
~Buffer() { pool_->RelinquishProducerReservation(id()); }
int id() const { return id_; }
size_t mapped_size() { return buffer_handle_->mapped_size(); }
@@ -173,7 +184,7 @@ class VideoCaptureBufferPoolTest
scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle =
pool_->GetBufferHandle(buffer_id);
return scoped_ptr<Buffer>(
- new Buffer(pool_, buffer_handle.Pass(), buffer_id));
+ new Buffer(pool_, std::move(buffer_handle), buffer_id));
}
base::MessageLoop loop_;
@@ -221,12 +232,10 @@ TEST_P(VideoCaptureBufferPoolTest, BufferPool) {
ASSERT_LE(format_lo.ImageAllocationSize(), buffer3->mapped_size());
}
- // Texture backed Frames cannot be manipulated via mapping.
- if (GetParam().pixel_storage != media::PIXEL_STORAGE_TEXTURE) {
- ASSERT_NE(nullptr, buffer1->data());
- ASSERT_NE(nullptr, buffer2->data());
- ASSERT_NE(nullptr, buffer3->data());
- }
+ ASSERT_NE(nullptr, buffer1->data());
+ ASSERT_NE(nullptr, buffer2->data());
+ ASSERT_NE(nullptr, buffer3->data());
+
// Touch the memory.
if (buffer1->data() != nullptr)
memset(buffer1->data(), 0x11, buffer1->mapped_size());
diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller.cc b/chromium/content/browser/renderer_host/media/video_capture_controller.cc
index 53c2110d807..6cde5f0d671 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller.cc
@@ -4,6 +4,9 @@
#include "content/browser/renderer_host/media/video_capture_controller.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <set>
@@ -12,6 +15,7 @@
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/stl_util.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
#include "content/browser/renderer_host/media/video_capture_device_client.h"
@@ -19,7 +23,6 @@
#include "content/common/gpu/client/gl_helper.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/common/mailbox_holder.h"
#include "media/base/video_frame.h"
#if !defined(OS_ANDROID)
@@ -41,13 +44,15 @@ static const int kInfiniteRatio = 99999;
name, \
(height) ? ((width) * 100) / (height) : kInfiniteRatio);
-class SyncPointClientImpl : public VideoFrame::SyncPointClient {
+class SyncTokenClientImpl : public VideoFrame::SyncTokenClient {
public:
- explicit SyncPointClientImpl(GLHelper* gl_helper) : gl_helper_(gl_helper) {}
- ~SyncPointClientImpl() override {}
- uint32 InsertSyncPoint() override { return gl_helper_->InsertSyncPoint(); }
- void WaitSyncPoint(uint32 sync_point) override {
- gl_helper_->WaitSyncPoint(sync_point);
+ explicit SyncTokenClientImpl(GLHelper* gl_helper) : gl_helper_(gl_helper) {}
+ ~SyncTokenClientImpl() override {}
+ void GenerateSyncToken(gpu::SyncToken* sync_token) override {
+ gl_helper_->GenerateSyncToken(sync_token);
+ }
+ void WaitSyncToken(const gpu::SyncToken& sync_token) override {
+ gl_helper_->WaitSyncToken(sync_token);
}
private:
@@ -55,18 +60,18 @@ class SyncPointClientImpl : public VideoFrame::SyncPointClient {
};
void ReturnVideoFrame(const scoped_refptr<VideoFrame>& video_frame,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(OS_ANDROID)
NOTREACHED();
#else
GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
- // UpdateReleaseSyncPoint() creates a new sync_point using |gl_helper|, so
- // wait the given |sync_point| using |gl_helper|.
+ // UpdateReleaseSyncToken() creates a new sync_token using |gl_helper|, so
+ // wait the given |sync_token| using |gl_helper|.
if (gl_helper) {
- gl_helper->WaitSyncPoint(sync_point);
- SyncPointClientImpl client(gl_helper);
- video_frame->UpdateReleaseSyncPoint(&client);
+ gl_helper->WaitSyncToken(sync_token);
+ SyncTokenClientImpl client(gl_helper);
+ video_frame->UpdateReleaseSyncToken(&client);
}
#endif
}
@@ -101,7 +106,7 @@ struct VideoCaptureController::ControllerClient {
// Buffers that are currently known to this client.
std::set<int> known_buffers;
- // Buffers currently held by this client, and syncpoint callback to call when
+ // Buffers currently held by this client, and sync token callback to call when
// they are returned from the client.
typedef std::map<int, scoped_refptr<VideoFrame>> ActiveBufferMap;
ActiveBufferMap active_buffers;
@@ -137,11 +142,10 @@ VideoCaptureController::GetWeakPtrForIOThread() {
}
scoped_ptr<media::VideoCaptureDevice::Client>
-VideoCaptureController::NewDeviceClient(
- const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner) {
+VideoCaptureController::NewDeviceClient() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return make_scoped_ptr(new VideoCaptureDeviceClient(
- this->GetWeakPtrForIOThread(), buffer_pool_, capture_task_runner));
+ this->GetWeakPtrForIOThread(), buffer_pool_));
}
void VideoCaptureController::AddClient(
@@ -151,11 +155,25 @@ void VideoCaptureController::AddClient(
media::VideoCaptureSessionId session_id,
const media::VideoCaptureParams& params) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DVLOG(1) << "VideoCaptureController::AddClient, id " << id
- << ", " << params.requested_format.frame_size.ToString()
- << ", " << params.requested_format.frame_rate
- << ", " << session_id
- << ")";
+ DVLOG(1) << "VideoCaptureController::AddClient() -- id=" << id
+ << ", session_id=" << session_id
+ << ", params.requested_format="
+ << media::VideoCaptureFormat::ToString(params.requested_format);
+
+ // Check that requested VideoCaptureParams are valid and supported. If not,
+ // report an error immediately and punt.
+ if (!params.IsValid() ||
+ params.requested_format.pixel_format != media::PIXEL_FORMAT_I420 ||
+ (params.requested_format.pixel_storage != media::PIXEL_STORAGE_CPU &&
+ params.requested_format.pixel_storage !=
+ media::PIXEL_STORAGE_GPUMEMORYBUFFER)) {
+ // Crash in debug builds since the renderer should not have asked for
+ // invalid or unsupported parameters.
+ LOG(DFATAL) << "Invalid or unsupported video capture parameters requested: "
+ << media::VideoCaptureFormat::ToString(params.requested_format);
+ event_handler->OnError(id);
+ return;
+ }
// If this is the first client added to the controller, cache the parameters.
if (!controller_clients_.size())
@@ -237,6 +255,21 @@ bool VideoCaptureController::ResumeClient(
return true;
}
+int VideoCaptureController::GetClientCount() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return controller_clients_.size();
+}
+
+int VideoCaptureController::GetActiveClientCount() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ int active_client_count = 0;
+ for (ControllerClient* client : controller_clients_) {
+ if (!client->paused)
+ ++active_client_count;
+ }
+ return active_client_count;
+}
+
void VideoCaptureController::StopSession(int session_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id;
@@ -253,7 +286,7 @@ void VideoCaptureController::ReturnBuffer(
VideoCaptureControllerID id,
VideoCaptureControllerEventHandler* event_handler,
int buffer_id,
- uint32 sync_point,
+ const gpu::SyncToken& sync_token,
double consumer_resource_utilization) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -292,12 +325,11 @@ void VideoCaptureController::ReturnBuffer(
buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
#if defined(OS_ANDROID)
- DCHECK_EQ(0u, sync_point);
+ DCHECK(!sync_token.HasData());
#endif
- if (sync_point)
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(&ReturnVideoFrame, frame, sync_point));
+ if (sync_token.HasData())
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&ReturnVideoFrame, frame, sync_token));
}
const media::VideoCaptureFormat&
@@ -328,12 +360,20 @@ void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread(
scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue());
frame->metadata()->MergeInternalValuesInto(metadata.get());
- DCHECK(
- (frame->IsMappable() && frame->format() == media::PIXEL_FORMAT_I420) ||
- (frame->HasTextures() && (frame->format() == media::PIXEL_FORMAT_ARGB ||
- frame->format() == media::PIXEL_FORMAT_I420)))
- << "Format and/or storage type combination not supported (received: "
- << media::VideoPixelFormatToString(frame->format()) << ")";
+ // Only I420 pixel format is currently supported.
+ DCHECK_EQ(frame->format(), media::PIXEL_FORMAT_I420)
+ << "Unsupported pixel format: "
+ << media::VideoPixelFormatToString(frame->format());
+
+ // Sanity-checks to confirm |frame| is actually being backed by |buffer|.
+ DCHECK(frame->storage_type() == media::VideoFrame::STORAGE_SHMEM ||
+ (frame->storage_type() ==
+ media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS));
+ DCHECK(frame->data(media::VideoFrame::kYPlane) >= buffer->data(0) &&
+ (frame->data(media::VideoFrame::kYPlane) <
+ (reinterpret_cast<const uint8_t*>(buffer->data(0)) +
+ buffer->mapped_size())))
+ << "VideoFrame does not appear to be backed by Buffer";
for (const auto& client : controller_clients_) {
if (client->session_closed || client->paused)
@@ -341,35 +381,8 @@ void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread(
// On the first use of a buffer on a client, share the memory handles.
const bool is_new_buffer = client->known_buffers.insert(buffer_id).second;
- if (is_new_buffer) {
- if (frame->HasTextures()) {
- DCHECK(frame->coded_size() == frame->visible_rect().size())
- << "Textures are always supposed to be tightly packed.";
-
- if (frame->format() == media::PIXEL_FORMAT_I420) {
- std::vector<gfx::GpuMemoryBufferHandle> handles(
- VideoFrame::NumPlanes(frame->format()));
- for (size_t i = 0; i < handles.size(); ++i)
- buffer_pool_->ShareToProcess2(
- buffer_id, i, client->render_process_handle, &handles[i]);
-
- client->event_handler->OnBufferCreated2(
- client->controller_id, handles, buffer->dimensions(),
- buffer_id);
- } else {
- DCHECK_EQ(frame->format(), media::PIXEL_FORMAT_ARGB);
- }
- } else if (frame->IsMappable()) {
- DCHECK_EQ(frame->format(), media::PIXEL_FORMAT_I420);
- base::SharedMemoryHandle remote_handle;
- buffer_pool_->ShareToProcess(
- buffer_id, client->render_process_handle, &remote_handle);
-
- client->event_handler->OnBufferCreated(
- client->controller_id, remote_handle, buffer->mapped_size(),
- buffer_id);
- }
- }
+ if (is_new_buffer)
+ DoNewBufferOnIOThread(client, buffer.get(), frame);
client->event_handler->OnBufferReady(client->controller_id,
buffer_id,
@@ -434,6 +447,42 @@ void VideoCaptureController::DoBufferDestroyedOnIOThread(
}
}
+void VideoCaptureController::DoNewBufferOnIOThread(
+ ControllerClient* client,
+ media::VideoCaptureDevice::Client::Buffer* buffer,
+ const scoped_refptr<media::VideoFrame>& frame) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const int buffer_id = buffer->id();
+
+ switch (frame->storage_type()) {
+ case media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS: {
+ std::vector<gfx::GpuMemoryBufferHandle> handles;
+ const size_t num_planes = media::VideoFrame::NumPlanes(frame->format());
+ for (size_t i = 0; i < num_planes; ++i) {
+ gfx::GpuMemoryBufferHandle remote_handle;
+ buffer_pool_->ShareToProcess2(
+ buffer_id, i, client->render_process_handle, &remote_handle);
+ handles.push_back(remote_handle);
+ }
+ client->event_handler->OnBufferCreated2(client->controller_id, handles,
+ buffer->dimensions(), buffer_id);
+ break;
+ }
+ case media::VideoFrame::STORAGE_SHMEM: {
+ base::SharedMemoryHandle remote_handle;
+ buffer_pool_->ShareToProcess(buffer_id, client->render_process_handle,
+ &remote_handle);
+ client->event_handler->OnBufferCreated(
+ client->controller_id, remote_handle, buffer->mapped_size(),
+ buffer_id);
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
VideoCaptureControllerID id,
VideoCaptureControllerEventHandler* handler,
@@ -455,19 +504,4 @@ VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
return NULL;
}
-int VideoCaptureController::GetClientCount() const {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return controller_clients_.size();
-}
-
-int VideoCaptureController::GetActiveClientCount() const {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- int active_client_count = 0;
- for (ControllerClient* client : controller_clients_) {
- if (!client->paused)
- ++active_client_count;
- }
- return active_client_count;
-}
-
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller.h b/chromium/content/browser/renderer_host/media/video_capture_controller.h
index 82690e7c11b..66611445963 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller.h
@@ -43,6 +43,7 @@
#include <list>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -69,10 +70,8 @@ class CONTENT_EXPORT VideoCaptureController {
base::WeakPtr<VideoCaptureController> GetWeakPtrForIOThread();
// Return a new VideoCaptureDeviceClient to forward capture events to this
- // instance. Some device clients need to allocate resources for the given
- // capture |format| and/or work on Capture Thread (|capture_task_runner|).
- scoped_ptr<media::VideoCaptureDevice::Client> NewDeviceClient(
- const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner);
+ // instance.
+ scoped_ptr<media::VideoCaptureDevice::Client> NewDeviceClient();
// Start video capturing and try to use the resolution specified in |params|.
// Buffers will be shared to the client as necessary. The client will continue
@@ -109,14 +108,14 @@ class CONTENT_EXPORT VideoCaptureController {
// Return a buffer with id |buffer_id| previously given in
// VideoCaptureControllerEventHandler::OnBufferReady. In the case that the
- // buffer was backed by a texture, |sync_point| will be waited on before
+ // buffer was backed by a texture, |sync_token| will be waited on before
// destroying or recycling the texture, to synchronize with texture users in
// the renderer process. If the consumer provided resource utilization
// feedback, this will be passed here (-1.0 indicates no feedback).
void ReturnBuffer(VideoCaptureControllerID id,
VideoCaptureControllerEventHandler* event_handler,
int buffer_id,
- uint32 sync_point,
+ const gpu::SyncToken& sync_token,
double consumer_resource_utilization);
const media::VideoCaptureFormat& GetVideoCaptureFormat() const;
@@ -136,6 +135,11 @@ class CONTENT_EXPORT VideoCaptureController {
struct ControllerClient;
typedef std::list<ControllerClient*> ControllerClients;
+ // Notify renderer that a new buffer has been created.
+ void DoNewBufferOnIOThread(ControllerClient* client,
+ media::VideoCaptureDevice::Client::Buffer* buffer,
+ const scoped_refptr<media::VideoFrame>& frame);
+
// Find a client of |id| and |handler| in |clients|.
ControllerClient* FindClient(VideoCaptureControllerID id,
VideoCaptureControllerEventHandler* handler,
diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index e376b90ee3c..99e563f50a1 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -4,34 +4,33 @@
// Unit test for VideoCaptureController.
+#include "content/browser/renderer_host/media/video_capture_controller.h"
+
+#include <stdint.h>
+#include <string.h>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "content/browser/renderer_host/media/media_stream_provider.h"
-#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
-#include "content/common/gpu/client/gl_helper.h"
#include "content/common/media/media_stream_options.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "gpu/command_buffer/common/mailbox_holder.h"
#include "media/base/video_capture_types.h"
#include "media/base/video_frame_metadata.h"
#include "media/base/video_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if !defined(OS_ANDROID)
-#include "content/browser/compositor/test/no_transport_image_transport_factory.h"
-#endif
-
using ::testing::_;
using ::testing::InSequence;
using ::testing::Mock;
@@ -55,8 +54,6 @@ class MockVideoCaptureControllerEventHandler
MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID));
MOCK_METHOD2(DoI420BufferReady,
void(VideoCaptureControllerID, const gfx::Size&));
- MOCK_METHOD2(DoTextureBufferReady,
- void(VideoCaptureControllerID, const gfx::Size&));
MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID));
MOCK_METHOD1(DoError, void(VideoCaptureControllerID));
@@ -82,22 +79,13 @@ class MockVideoCaptureControllerEventHandler
int buffer_id,
const scoped_refptr<media::VideoFrame>& frame,
const base::TimeTicks& timestamp) override {
- if (!frame->HasTextures()) {
EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420);
DoI420BufferReady(id, frame->coded_size());
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&VideoCaptureController::ReturnBuffer,
- base::Unretained(controller_), id, this,
- buffer_id, 0, resource_utilization_));
- } else {
- EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_ARGB);
- DoTextureBufferReady(id, frame->coded_size());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&VideoCaptureController::ReturnBuffer,
- base::Unretained(controller_), id, this,
- buffer_id, frame->mailbox_holder(0).sync_point,
- resource_utilization_));
- }
+ FROM_HERE,
+ base::Bind(&VideoCaptureController::ReturnBuffer,
+ base::Unretained(controller_), id, this, buffer_id,
+ gpu::SyncToken(), resource_utilization_));
}
void OnEnded(VideoCaptureControllerID id) override {
DoEnded(id);
@@ -123,8 +111,7 @@ class VideoCaptureControllerTest : public testing::Test {
void SetUp() override {
controller_.reset(new VideoCaptureController(kPoolSize));
- device_ = controller_->NewDeviceClient(
- base::ThreadTaskRunnerHandle::Get());
+ device_ = controller_->NewDeviceClient();
client_a_.reset(new MockVideoCaptureControllerEventHandler(
controller_.get()));
client_b_.reset(new MockVideoCaptureControllerEventHandler(
@@ -134,21 +121,15 @@ class VideoCaptureControllerTest : public testing::Test {
void TearDown() override { base::RunLoop().RunUntilIdle(); }
scoped_refptr<media::VideoFrame> WrapI420Buffer(gfx::Size dimensions,
- uint8* data) {
- return media::VideoFrame::WrapExternalData(
- media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions), dimensions,
- data,
- media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, dimensions),
- base::TimeDelta());
- }
-
- scoped_refptr<media::VideoFrame> WrapMailboxBuffer(
- const gpu::MailboxHolder& holder,
- const media::VideoFrame::ReleaseMailboxCB& release_cb,
- gfx::Size dimensions) {
- return media::VideoFrame::WrapNativeTexture(
- media::PIXEL_FORMAT_ARGB, holder, release_cb, dimensions,
- gfx::Rect(dimensions), dimensions, base::TimeDelta());
+ uint8_t* data) {
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::WrapExternalSharedMemory(
+ media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions),
+ dimensions, data, media::VideoFrame::AllocationSize(
+ media::PIXEL_FORMAT_I420, dimensions),
+ base::SharedMemory::NULLHandle(), 0u, base::TimeDelta());
+ EXPECT_TRUE(video_frame);
+ return video_frame;
}
TestBrowserThreadBundle bundle_;
@@ -261,21 +242,10 @@ TEST_F(VideoCaptureControllerTest, AddAndRemoveClients) {
<< "Client count should return to zero after all clients are gone.";
}
-static void CacheSyncPoint(uint32* called_release_sync_point,
- uint32 release_sync_point) {
- *called_release_sync_point = release_sync_point;
-}
-
// This test will connect and disconnect several clients while simulating an
// active capture device being started and generating frames. It runs on one
// thread and is intended to behave deterministically.
TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
-// VideoCaptureController::ReturnBuffer() uses ImageTransportFactory.
-#if !defined(OS_ANDROID)
- ImageTransportFactory::InitializeForUnitTests(
- scoped_ptr<ImageTransportFactory>(new NoTransportImageTransportFactory));
-#endif
-
media::VideoCaptureParams session_100;
session_100.requested_format = media::VideoCaptureFormat(
gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
@@ -318,7 +288,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
// Now, simulate an incoming captured buffer from the capture device. As a
// side effect this will cause the first buffer to be shared with clients.
- uint8 buffer_no = 1;
+ uint8_t buffer_no = 1;
ASSERT_EQ(0.0, device_->GetBufferPoolUtilization());
scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer(
device_->ReserveOutputBuffer(capture_resolution,
@@ -349,12 +319,13 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
.Times(1);
}
scoped_refptr<media::VideoFrame> video_frame =
- WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
+ WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data()));
+ ASSERT_TRUE(video_frame);
ASSERT_FALSE(video_frame->metadata()->HasKey(
media::VideoFrameMetadata::RESOURCE_UTILIZATION));
client_a_->resource_utilization_ = 0.5;
client_b_->resource_utilization_ = -1.0;
- device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+ device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame,
base::TimeTicks());
base::RunLoop().RunUntilIdle();
@@ -377,13 +348,14 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
media::PIXEL_STORAGE_CPU);
ASSERT_TRUE(buffer2.get());
memset(buffer2->data(), buffer_no++, buffer2->mapped_size());
- video_frame =
- WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer2->data()));
+ video_frame = WrapI420Buffer(capture_resolution,
+ static_cast<uint8_t*>(buffer2->data()));
+ ASSERT_TRUE(video_frame);
ASSERT_FALSE(video_frame->metadata()->HasKey(
media::VideoFrameMetadata::RESOURCE_UTILIZATION));
client_a_->resource_utilization_ = 0.5;
client_b_->resource_utilization_ = 3.14;
- device_->OnIncomingCapturedVideoFrame(buffer2.Pass(), video_frame,
+ device_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame,
base::TimeTicks());
// The buffer should be delivered to the clients in any order.
@@ -423,9 +395,10 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
media::PIXEL_STORAGE_CPU);
ASSERT_TRUE(buffer.get());
memset(buffer->data(), buffer_no++, buffer->mapped_size());
- video_frame =
- WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
- device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+ video_frame = WrapI420Buffer(capture_resolution,
+ static_cast<uint8_t*>(buffer->data()));
+ ASSERT_TRUE(video_frame);
+ device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame,
base::TimeTicks());
}
// ReserveOutputBuffer ought to fail now, because the pool is depleted.
@@ -471,9 +444,10 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
media::PIXEL_STORAGE_CPU);
ASSERT_TRUE(buffer3.get());
memset(buffer3->data(), buffer_no++, buffer3->mapped_size());
- video_frame =
- WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer3->data()));
- device_->OnIncomingCapturedVideoFrame(buffer3.Pass(), video_frame,
+ video_frame = WrapI420Buffer(capture_resolution,
+ static_cast<uint8_t*>(buffer3->data()));
+ ASSERT_TRUE(video_frame);
+ device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame,
base::TimeTicks());
scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 =
@@ -488,9 +462,10 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
}
ASSERT_TRUE(buffer4.get());
memset(buffer4->data(), buffer_no++, buffer4->mapped_size());
- video_frame =
- WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer4->data()));
- device_->OnIncomingCapturedVideoFrame(buffer4.Pass(), video_frame,
+ video_frame = WrapI420Buffer(capture_resolution,
+ static_cast<uint8_t*>(buffer4->data()));
+ ASSERT_TRUE(video_frame);
+ device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame,
base::TimeTicks());
// B2 is the only client left, and is the only one that should
// get the buffer.
@@ -500,83 +475,6 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(client_a_.get());
Mock::VerifyAndClearExpectations(client_b_.get());
-
- // Allocate all buffers from the buffer pool, half as SHM buffer and half as
- // mailbox buffers. Make sure of different counts though.
-#if defined(OS_ANDROID)
- int mailbox_buffers = 0;
-#else
- int mailbox_buffers = kPoolSize / 2;
-#endif
- int shm_buffers = kPoolSize - mailbox_buffers;
- if (shm_buffers == mailbox_buffers) {
- shm_buffers--;
- mailbox_buffers++;
- }
-
- for (int i = 0; i < shm_buffers; ++i) {
- scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
- device_->ReserveOutputBuffer(capture_resolution,
- media::PIXEL_FORMAT_I420,
- media::PIXEL_STORAGE_CPU);
- ASSERT_TRUE(buffer.get());
- video_frame =
- WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
- device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
- base::TimeTicks());
- }
- std::vector<uint32> mailbox_syncpoints(mailbox_buffers);
- std::vector<uint32> release_syncpoints(mailbox_buffers);
- for (int i = 0; i < mailbox_buffers; ++i) {
- scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
- device_->ReserveOutputBuffer(capture_resolution,
- media::PIXEL_FORMAT_ARGB,
- media::PIXEL_STORAGE_TEXTURE);
- ASSERT_TRUE(buffer.get());
-#if !defined(OS_ANDROID)
- mailbox_syncpoints[i] =
- ImageTransportFactory::GetInstance()->GetGLHelper()->InsertSyncPoint();
-#endif
- device_->OnIncomingCapturedVideoFrame(
- buffer.Pass(),
- WrapMailboxBuffer(gpu::MailboxHolder(gpu::Mailbox::Generate(), 0,
- mailbox_syncpoints[i]),
- base::Bind(&CacheSyncPoint, &release_syncpoints[i]),
- capture_resolution),
- base::TimeTicks());
- }
- // ReserveOutputBuffers ought to fail now regardless of buffer format, because
- // the pool is depleted.
- ASSERT_FALSE(
- device_->ReserveOutputBuffer(capture_resolution,
- media::PIXEL_FORMAT_I420,
- media::PIXEL_STORAGE_CPU).get());
- ASSERT_FALSE(
- device_->ReserveOutputBuffer(capture_resolution,
- media::PIXEL_FORMAT_ARGB,
- media::PIXEL_STORAGE_TEXTURE).get());
- EXPECT_CALL(*client_b_,
- DoI420BufferReady(client_b_route_2, capture_resolution))
- .Times(shm_buffers);
- EXPECT_CALL(*client_b_,
- DoTextureBufferReady(client_b_route_2, capture_resolution))
- .Times(mailbox_buffers);
-#if !defined(OS_ANDROID)
- EXPECT_CALL(*client_b_, DoBufferDestroyed(client_b_route_2));
-#endif
- base::RunLoop().RunUntilIdle();
- for (size_t i = 0; i < mailbox_syncpoints.size(); ++i) {
- // A new release sync point must be inserted when the video frame is
- // returned to the Browser process.
- // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and
- // VideoCaptureController::ReturnBuffer()
- ASSERT_NE(mailbox_syncpoints[i], release_syncpoints[i]);
- }
- Mock::VerifyAndClearExpectations(client_b_.get());
-
-#if !defined(OS_ANDROID)
- ImageTransportFactory::Terminate();
-#endif
}
// Exercises the OnError() codepath of VideoCaptureController, and tests the
@@ -595,7 +493,7 @@ TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) {
// Start with one client.
controller_->AddClient(
route_id, client_a_.get(), base::kNullProcessHandle, 100, session_100);
- device_->OnError("Test Error");
+ device_->OnError(FROM_HERE, "Test Error");
EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(client_a_.get());
@@ -614,8 +512,9 @@ TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) {
media::PIXEL_STORAGE_CPU));
ASSERT_TRUE(buffer.get());
scoped_refptr<media::VideoFrame> video_frame =
- WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data()));
- device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+ WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data()));
+ ASSERT_TRUE(video_frame);
+ device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame,
base::TimeTicks());
base::RunLoop().RunUntilIdle();
@@ -651,9 +550,10 @@ TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) {
ASSERT_TRUE(buffer.get());
scoped_refptr<media::VideoFrame> video_frame =
- WrapI420Buffer(dims, static_cast<uint8*>(buffer->data()));
- device_->OnError("Test Error");
- device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
+ WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data()));
+ ASSERT_TRUE(video_frame);
+ device_->OnError(FROM_HERE, "Test Error");
+ device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame,
base::TimeTicks());
EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
diff --git a/chromium/content/browser/renderer_host/media/video_capture_device_client.cc b/chromium/content/browser/renderer_host/media/video_capture_device_client.cc
index fe7c623fcbf..b4d142e99ff 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_device_client.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_device_client.cc
@@ -5,30 +5,22 @@
#include "content/browser/renderer_host/media/video_capture_device_client.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/location.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
-#include "content/browser/compositor/image_transport_factory.h"
-#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
-#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
-#include "content/browser/gpu/gpu_data_manager_impl.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
-#include "content/common/gpu/client/context_provider_command_buffer.h"
-#include "content/common/gpu/client/gl_helper.h"
-#include "content/common/gpu/client/gpu_channel_host.h"
-#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 "gpu/command_buffer/common/mailbox_holder.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/media_switches.h"
#include "media/base/video_capture_types.h"
#include "media/base/video_frame.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/libyuv/include/libyuv.h"
using media::VideoCaptureFormat;
@@ -37,73 +29,6 @@ using media::VideoFrameMetadata;
namespace content {
-namespace {
-
-#if !defined(OS_ANDROID)
-// Modelled after GpuProcessTransportFactory::CreateContextCommon().
-scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl> CreateContextCommon(
- scoped_refptr<content::GpuChannelHost> gpu_channel_host) {
- if (!content::GpuDataManagerImpl::GetInstance()->
- CanUseGpuBrowserCompositor()) {
- DLOG(ERROR) << "No accelerated graphics found. Check chrome://gpu";
- return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
- }
- blink::WebGraphicsContext3D::Attributes attrs;
- attrs.shareResources = true;
- attrs.depth = false;
- attrs.stencil = false;
- attrs.antialias = false;
- attrs.noAutomaticFlushes = true;
-
- if (!gpu_channel_host.get()) {
- DLOG(ERROR) << "Failed to establish GPU channel.";
- return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
- }
- GURL url("chrome://gpu/GpuProcessTransportFactory::CreateCaptureContext");
- return make_scoped_ptr(new WebGraphicsContext3DCommandBufferImpl(
- 0, url, gpu_channel_host.get(), attrs,
- true /* lose_context_when_out_of_memory */,
- content::WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
- NULL));
-}
-
-// Modelled after
-// GpuProcessTransportFactory::CreateOffscreenCommandBufferContext().
-scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>
-CreateOffscreenCommandBufferContext() {
- content::CauseForGpuLaunch cause = content::CAUSE_FOR_GPU_LAUNCH_CANVAS_2D;
- // Android does not support synchronous opening of GPU channels. Should use
- // EstablishGpuChannel() instead.
- if (!content::BrowserGpuChannelHostFactory::instance())
- return scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl>();
- scoped_refptr<content::GpuChannelHost> gpu_channel_host(
- content::BrowserGpuChannelHostFactory::instance()->
- EstablishGpuChannelSync(cause));
- DCHECK(gpu_channel_host);
- return CreateContextCommon(gpu_channel_host);
-}
-#endif
-
-typedef base::Callback<void(scoped_refptr<ContextProviderCommandBuffer>)>
- ProcessContextCallback;
-
-void CreateContextOnUIThread(ProcessContextCallback bottom_half) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-#if !defined(OS_ANDROID)
- bottom_half.Run(ContextProviderCommandBuffer::Create(
- CreateOffscreenCommandBufferContext(), OFFSCREEN_VIDEO_CAPTURE_CONTEXT));
- return;
-#endif
-}
-
-void ResetLostContextCallback(
- const scoped_refptr<ContextProviderCommandBuffer>& capture_thread_context) {
- capture_thread_context->SetLostContextCallback(
- cc::ContextProvider::LostContextCallback());
-}
-
-} // anonymous namespace
-
// Class combining a Client::Buffer interface implementation and a pool buffer
// implementation to guarantee proper cleanup on destruction on our side.
class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
@@ -112,7 +37,7 @@ class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
int buffer_id)
: id_(buffer_id),
pool_(pool),
- buffer_handle_(pool_->GetBufferHandle(buffer_id).Pass()) {
+ buffer_handle_(pool_->GetBufferHandle(buffer_id)) {
DCHECK(pool_.get());
}
int id() const override { return id_; }
@@ -122,7 +47,7 @@ class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
ClientBuffer AsClientBuffer(int plane) override {
return buffer_handle_->AsClientBuffer(plane);
}
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
base::FileDescriptor AsPlatformFile() override {
return buffer_handle_->AsPlatformFile();
}
@@ -136,75 +61,14 @@ class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_;
};
-// Internal ref-counted class wrapping an incoming GpuMemoryBuffer into a
-// Texture backed VideoFrame. This VideoFrame creation is balanced by a waiting
-// on the associated |sync_point|. After VideoFrame consumption the inserted
-// ReleaseCallback() will be called, where the Texture is destroyed.
-//
-// This class jumps between threads due to GPU-related thread limitations, i.e.
-// some objects cannot be accessed from IO Thread whereas others need to be
-// constructed on UI Thread. For this reason most of the operations are carried
-// out on Capture Thread (|capture_task_runner_|).
-class VideoCaptureDeviceClient::TextureWrapHelper final
- : public base::RefCountedThreadSafe<TextureWrapHelper> {
- public:
- TextureWrapHelper(
- const base::WeakPtr<VideoCaptureController>& controller,
- const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner);
-
- // Wraps the GpuMemoryBuffer-backed |buffer| into a Texture, and sends it to
- // |controller_| wrapped in a VideoFrame.
- void OnIncomingCapturedGpuMemoryBuffer(
- scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
- const media::VideoCaptureFormat& frame_format,
- const base::TimeTicks& timestamp);
-
- private:
- friend class base::RefCountedThreadSafe<TextureWrapHelper>;
- ~TextureWrapHelper();
-
- // Creates some necessary members in |capture_task_runner_|.
- void Init();
- // Runs the bottom half of the GlHelper creation.
- void CreateGlHelper(
- scoped_refptr<ContextProviderCommandBuffer> capture_thread_context);
-
- // Recycles |memory_buffer|, deletes Image and Texture on VideoFrame release.
- void ReleaseCallback(const std::vector<GLuint>& image_ids,
- const std::vector<GLuint>& texture_ids,
- uint32 sync_point);
-
- // The Command Buffer lost the GL context, f.i. GPU process crashed. Signal
- // error to our owner so the capture can be torn down.
- void LostContextCallback();
-
- // Prints the error |message| and notifies |controller_| of an error.
- void OnError(const std::string& message);
-
- // |controller_| should only be used on IO thread.
- const base::WeakPtr<VideoCaptureController> controller_;
- const scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
-
- // Command buffer reference, needs to be destroyed when unused. It is created
- // on UI Thread and bound to Capture Thread. In particular, it cannot be used
- // from IO Thread.
- scoped_refptr<ContextProviderCommandBuffer> capture_thread_context_;
- // Created and used from Capture Thread. Cannot be used from IO Thread.
- scoped_ptr<GLHelper> gl_helper_;
-
- DISALLOW_COPY_AND_ASSIGN(TextureWrapHelper);
-};
-
VideoCaptureDeviceClient::VideoCaptureDeviceClient(
const base::WeakPtr<VideoCaptureController>& controller,
- const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
- const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner)
+ const scoped_refptr<VideoCaptureBufferPool>& buffer_pool)
: controller_(controller),
external_jpeg_decoder_initialized_(false),
buffer_pool_(buffer_pool),
use_gpu_memory_buffers_(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseGpuMemoryBuffersForCapture)),
- capture_task_runner_(capture_task_runner),
last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
@@ -216,7 +80,7 @@ VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {
}
void VideoCaptureDeviceClient::OnIncomingCapturedData(
- const uint8* data,
+ const uint8_t* data,
int length,
const VideoCaptureFormat& frame_format,
int rotation,
@@ -268,7 +132,7 @@ void VideoCaptureDeviceClient::OnIncomingCapturedData(
const media::VideoPixelStorage output_pixel_storage =
use_gpu_memory_buffers_ ? media::PIXEL_STORAGE_GPUMEMORYBUFFER
: media::PIXEL_STORAGE_CPU;
- uint8 *y_plane_data, *u_plane_data, *v_plane_data;
+ uint8_t *y_plane_data, *u_plane_data, *v_plane_data;
scoped_ptr<Buffer> buffer(
ReserveI420OutputBuffer(dimensions, output_pixel_storage, &y_plane_data,
&u_plane_data, &v_plane_data));
@@ -360,7 +224,7 @@ void VideoCaptureDeviceClient::OnIncomingCapturedData(
frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG &&
rotation == 0 && !flip) {
external_jpeg_decoder_->DecodeCapturedData(data, length, frame_format,
- timestamp, buffer.Pass());
+ timestamp, std::move(buffer));
return;
}
}
@@ -389,14 +253,13 @@ void VideoCaptureDeviceClient::OnIncomingCapturedData(
const VideoCaptureFormat output_format = VideoCaptureFormat(
dimensions, frame_format.frame_rate,
media::PIXEL_FORMAT_I420, output_pixel_storage);
- OnIncomingCapturedBuffer(buffer.Pass(), output_format, timestamp);
+ OnIncomingCapturedBuffer(std::move(buffer), output_format, timestamp);
}
-void
-VideoCaptureDeviceClient::OnIncomingCapturedYuvData(
- const uint8* y_data,
- const uint8* u_data,
- const uint8* v_data,
+void VideoCaptureDeviceClient::OnIncomingCapturedYuvData(
+ const uint8_t* y_data,
+ const uint8_t* u_data,
+ const uint8_t* v_data,
size_t y_stride,
size_t u_stride,
size_t v_stride,
@@ -408,7 +271,7 @@ VideoCaptureDeviceClient::OnIncomingCapturedYuvData(
DCHECK_EQ(media::PIXEL_STORAGE_CPU, frame_format.pixel_storage);
DCHECK_EQ(0, clockwise_rotation) << "Rotation not supported";
- uint8 *y_plane_data, *u_plane_data, *v_plane_data;
+ uint8_t *y_plane_data, *u_plane_data, *v_plane_data;
scoped_ptr<Buffer> buffer(ReserveI420OutputBuffer(
frame_format.frame_size, frame_format.pixel_storage, &y_plane_data,
&u_plane_data, &v_plane_data));
@@ -440,7 +303,7 @@ VideoCaptureDeviceClient::OnIncomingCapturedYuvData(
return;
}
- OnIncomingCapturedBuffer(buffer.Pass(), frame_format, timestamp);
+ OnIncomingCapturedBuffer(std::move(buffer), frame_format, timestamp);
};
scoped_ptr<media::VideoCaptureDevice::Client::Buffer>
@@ -448,17 +311,10 @@ VideoCaptureDeviceClient::ReserveOutputBuffer(
const gfx::Size& frame_size,
media::VideoPixelFormat pixel_format,
media::VideoPixelStorage pixel_storage) {
- DCHECK(pixel_format == media::PIXEL_FORMAT_I420 ||
- pixel_format == media::PIXEL_FORMAT_ARGB);
DCHECK_GT(frame_size.width(), 0);
DCHECK_GT(frame_size.height(), 0);
-
- if (pixel_storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER &&
- !texture_wrap_helper_) {
- DCHECK(pixel_format == media::PIXEL_FORMAT_I420);
- texture_wrap_helper_ =
- new TextureWrapHelper(controller_, capture_task_runner_);
- }
+ // Currently, only I420 pixel format is supported.
+ DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format);
// TODO(mcasas): For PIXEL_STORAGE_GPUMEMORYBUFFER, find a way to indicate if
// it's a ShMem GMB or a DmaBuf GMB.
@@ -478,40 +334,45 @@ VideoCaptureDeviceClient::ReserveOutputBuffer(
controller_, buffer_id_to_drop));
}
- return output_buffer.Pass();
+ return output_buffer;
}
void VideoCaptureDeviceClient::OnIncomingCapturedBuffer(
scoped_ptr<Buffer> buffer,
const VideoCaptureFormat& frame_format,
const base::TimeTicks& timestamp) {
- if (frame_format.pixel_storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER) {
- capture_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&TextureWrapHelper::OnIncomingCapturedGpuMemoryBuffer,
- texture_wrap_helper_,
- base::Passed(&buffer),
- frame_format,
- timestamp));
- } else {
-#ifndef NDEBUG
- media::VideoPixelFormat pixel_format = frame_format.pixel_format;
- DCHECK(pixel_format == media::PIXEL_FORMAT_I420 ||
- pixel_format == media::PIXEL_FORMAT_ARGB);
-#endif
+ // Currently, only I420 pixel format is supported.
+ DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format);
- scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalData(
- media::PIXEL_FORMAT_I420, frame_format.frame_size,
- gfx::Rect(frame_format.frame_size), frame_format.frame_size,
- reinterpret_cast<uint8*>(buffer->data()),
- VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
- frame_format.frame_size),
- base::TimeDelta());
- DCHECK(video_frame.get());
- video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
- frame_format.frame_rate);
- OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, timestamp);
+ scoped_refptr<VideoFrame> frame;
+ switch (frame_format.pixel_storage) {
+ case media::PIXEL_STORAGE_GPUMEMORYBUFFER: {
+ // Create a VideoFrame to set the correct storage_type and pixel_format.
+ gfx::GpuMemoryBufferHandle handle;
+ frame = VideoFrame::WrapExternalYuvGpuMemoryBuffers(
+ media::PIXEL_FORMAT_I420, frame_format.frame_size,
+ gfx::Rect(frame_format.frame_size), frame_format.frame_size, 0, 0, 0,
+ reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kYPlane)),
+ reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kUPlane)),
+ reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kVPlane)),
+ handle, handle, handle, base::TimeDelta());
+ break;
+ }
+ case media::PIXEL_STORAGE_CPU:
+ frame = VideoFrame::WrapExternalSharedMemory(
+ media::PIXEL_FORMAT_I420, frame_format.frame_size,
+ gfx::Rect(frame_format.frame_size), frame_format.frame_size,
+ reinterpret_cast<uint8_t*>(buffer->data()),
+ VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
+ frame_format.frame_size),
+ base::SharedMemory::NULLHandle(), 0u, base::TimeDelta());
+ break;
}
+ if (!frame)
+ return;
+ frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
+ frame_format.frame_rate);
+ OnIncomingCapturedVideoFrame(std::move(buffer), frame, timestamp);
}
void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
@@ -530,12 +391,13 @@ void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
}
void VideoCaptureDeviceClient::OnError(
+ const tracked_objects::Location& from_here,
const std::string& reason) {
const std::string log_message = base::StringPrintf(
- "Error on video capture: %s, OS message: %s",
+ "error@ %s, %s, OS message: %s", from_here.ToString().c_str(),
reason.c_str(),
- logging::SystemErrorCodeToString(
- logging::GetLastSystemErrorCode()).c_str());
+ logging::SystemErrorCodeToString(logging::GetLastSystemErrorCode())
+ .c_str());
DLOG(ERROR) << log_message;
OnLog(log_message);
BrowserThread::PostTask(BrowserThread::IO,
@@ -559,9 +421,9 @@ scoped_ptr<media::VideoCaptureDevice::Client::Buffer>
VideoCaptureDeviceClient::ReserveI420OutputBuffer(
const gfx::Size& dimensions,
media::VideoPixelStorage storage,
- uint8** y_plane_data,
- uint8** u_plane_data,
- uint8** v_plane_data) {
+ uint8_t** y_plane_data,
+ uint8_t** u_plane_data,
+ uint8_t** v_plane_data) {
DCHECK(storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER ||
storage == media::PIXEL_STORAGE_CPU);
DCHECK(dimensions.height());
@@ -573,198 +435,31 @@ VideoCaptureDeviceClient::ReserveI420OutputBuffer(
if (!buffer)
return scoped_ptr<Buffer>();
- if (storage == media::PIXEL_STORAGE_CPU) {
- // TODO(emircan): See http://crbug.com/521068, move this pointer arithmetic
- // inside Buffer::data() when this bug is resolved.
- *y_plane_data = reinterpret_cast<uint8*>(buffer->data());
- *u_plane_data =
- *y_plane_data +
- VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions)
- .GetArea();
- *v_plane_data =
- *u_plane_data +
- VideoFrame::PlaneSize(format, VideoFrame::kUPlane, dimensions)
- .GetArea();
- } else if (storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER) {
- *y_plane_data = reinterpret_cast<uint8*>(buffer->data(VideoFrame::kYPlane));
- *u_plane_data = reinterpret_cast<uint8*>(buffer->data(VideoFrame::kUPlane));
- *v_plane_data = reinterpret_cast<uint8*>(buffer->data(VideoFrame::kVPlane));
- }
-
- return buffer.Pass();
-}
-
-VideoCaptureDeviceClient::TextureWrapHelper::TextureWrapHelper(
- const base::WeakPtr<VideoCaptureController>& controller,
- const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner)
- : controller_(controller),
- capture_task_runner_(capture_task_runner) {
- capture_task_runner_->PostTask(FROM_HERE,
- base::Bind(&TextureWrapHelper::Init, this));
-}
-
-void
-VideoCaptureDeviceClient::TextureWrapHelper::OnIncomingCapturedGpuMemoryBuffer(
- scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
- const media::VideoCaptureFormat& frame_format,
- const base::TimeTicks& timestamp) {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
- DCHECK(media::PIXEL_FORMAT_I420 == frame_format.pixel_format);
- DCHECK_EQ(media::PIXEL_STORAGE_GPUMEMORYBUFFER, frame_format.pixel_storage);
- if (!gl_helper_) {
- // |gl_helper_| might not exist due to asynchronous initialization not
- // finished or due to termination in process after a context loss.
- DVLOG(1) << " Skipping ingress frame, no GL context.";
- return;
+ switch (storage) {
+ case media::PIXEL_STORAGE_CPU:
+ // TODO(emircan): See http://crbug.com/521068, move this pointer
+ // arithmetic inside Buffer::data() when this bug is resolved.
+ *y_plane_data = reinterpret_cast<uint8_t*>(buffer->data());
+ *u_plane_data =
+ *y_plane_data +
+ VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions)
+ .GetArea();
+ *v_plane_data =
+ *u_plane_data +
+ VideoFrame::PlaneSize(format, VideoFrame::kUPlane, dimensions)
+ .GetArea();
+ return buffer;
+ case media::PIXEL_STORAGE_GPUMEMORYBUFFER:
+ *y_plane_data =
+ reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kYPlane));
+ *u_plane_data =
+ reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kUPlane));
+ *v_plane_data =
+ reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kVPlane));
+ return buffer;
}
-
- gpu::gles2::GLES2Interface* gl = capture_thread_context_->ContextGL();
- std::vector<gpu::MailboxHolder> mailbox_holders;
- std::vector<GLuint> image_ids;
- std::vector<GLuint> texture_ids;
-
- media::VideoPixelFormat format = media::PIXEL_FORMAT_I420;
- for (size_t i = 0; i < VideoFrame::NumPlanes(format); ++i) {
- const size_t width =
- media::VideoFrame::Columns(i, format, frame_format.frame_size.width());
- const size_t height =
- media::VideoFrame::Rows(i, format, frame_format.frame_size.height());
- const GLuint image_id = gl->CreateImageCHROMIUM(buffer->AsClientBuffer(i),
- width, height, GL_R8_EXT);
- DCHECK(image_id);
- image_ids.push_back(image_id);
-
- const GLuint texture_id = gl_helper_->CreateTexture();
- DCHECK(texture_id);
- {
- content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl,
- texture_id);
- gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
- }
- texture_ids.push_back(texture_id);
-
- const gpu::MailboxHolder& mailbox_holder(
- gl_helper_->ProduceMailboxHolderFromTexture(texture_id));
- DCHECK(!mailbox_holder.mailbox.IsZero());
- DCHECK(mailbox_holder.mailbox.Verify());
- DCHECK(mailbox_holder.texture_target);
- DCHECK(mailbox_holder.sync_point);
- mailbox_holders.push_back(mailbox_holder);
- }
-
- scoped_refptr<media::VideoFrame> video_frame =
- VideoFrame::WrapYUV420NativeTextures(
- mailbox_holders[VideoFrame::kYPlane],
- mailbox_holders[VideoFrame::kUPlane],
- mailbox_holders[VideoFrame::kVPlane],
- media::BindToCurrentLoop(base::Bind(
- &VideoCaptureDeviceClient::TextureWrapHelper::ReleaseCallback,
- this, image_ids, texture_ids)),
- frame_format.frame_size, gfx::Rect(frame_format.frame_size),
- frame_format.frame_size, base::TimeDelta());
- video_frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true);
- video_frame->metadata()->SetDouble(VideoFrameMetadata::FRAME_RATE,
- frame_format.frame_rate);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(
- &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
- controller_, base::Passed(&buffer), video_frame, timestamp));
-}
-
-VideoCaptureDeviceClient::TextureWrapHelper::~TextureWrapHelper() {
- // Might not be running on capture_task_runner_'s thread. Ensure owned objects
- // are destroyed on the correct threads.
- if (gl_helper_)
- capture_task_runner_->DeleteSoon(FROM_HERE, gl_helper_.release());
-
- if (capture_thread_context_) {
- capture_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&ResetLostContextCallback, capture_thread_context_));
- capture_thread_context_->AddRef();
- ContextProviderCommandBuffer* raw_capture_thread_context =
- capture_thread_context_.get();
- capture_thread_context_ = nullptr;
- capture_task_runner_->ReleaseSoon(FROM_HERE, raw_capture_thread_context);
- }
-}
-
-void VideoCaptureDeviceClient::TextureWrapHelper::Init() {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
- // In threaded compositing mode, we have to create our own context for Capture
- // to avoid using the GPU command queue from multiple threads. Context
- // creation must happen on UI thread; then the context needs to be bound to
- // the appropriate thread, which is done in CreateGlHelper().
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(
- &CreateContextOnUIThread,
- media::BindToCurrentLoop(base::Bind(
- &VideoCaptureDeviceClient::TextureWrapHelper::CreateGlHelper,
- this))));
-}
-
-void VideoCaptureDeviceClient::TextureWrapHelper::CreateGlHelper(
- scoped_refptr<ContextProviderCommandBuffer> capture_thread_context) {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
- if (!capture_thread_context.get()) {
- DLOG(ERROR) << "No offscreen GL Context!";
- return;
- }
- // This may not happen in IO Thread. The destructor resets the context lost
- // callback, so base::Unretained is safe; otherwise it'd be a circular ref
- // counted dependency.
- capture_thread_context->SetLostContextCallback(media::BindToCurrentLoop(
- base::Bind(
- &VideoCaptureDeviceClient::TextureWrapHelper::LostContextCallback,
- base::Unretained(this))));
- if (!capture_thread_context->BindToCurrentThread()) {
- capture_thread_context = NULL;
- DLOG(ERROR) << "Couldn't bind the Capture Context to the Capture Thread.";
- return;
- }
- DCHECK(capture_thread_context);
- capture_thread_context_ = capture_thread_context;
-
- // At this point, |capture_thread_context| is a cc::ContextProvider. Creation
- // of our GLHelper should happen on Capture Thread.
- gl_helper_.reset(new GLHelper(capture_thread_context->ContextGL(),
- capture_thread_context->ContextSupport()));
- DCHECK(gl_helper_);
-}
-
-void VideoCaptureDeviceClient::TextureWrapHelper::ReleaseCallback(
- const std::vector<GLuint>& image_ids,
- const std::vector<GLuint>& texture_ids,
- uint32 sync_point) {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
- DCHECK_EQ(image_ids.size(), texture_ids.size());
-
- if (!gl_helper_)
- return;
- for (size_t i = 0; i < image_ids.size(); ++i) {
- gl_helper_->DeleteTexture(texture_ids[i]);
- capture_thread_context_->ContextGL()->DestroyImageCHROMIUM(image_ids[i]);
- }
-}
-
-void VideoCaptureDeviceClient::TextureWrapHelper::LostContextCallback() {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
- // Prevent incoming frames from being processed while OnError gets groked.
- gl_helper_.reset();
- OnError("GLContext lost");
-}
-
-void VideoCaptureDeviceClient::TextureWrapHelper::OnError(
- const std::string& message) {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
- DLOG(ERROR) << message;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
+ NOTREACHED();
+ return scoped_ptr<Buffer>();
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/video_capture_device_client.h b/chromium/content/browser/renderer_host/media/video_capture_device_client.h
index 80838ee3287..8215f5642a2 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_device_client.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_device_client.h
@@ -5,6 +5,10 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEVICE_CLIENT_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEVICE_CLIENT_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -36,19 +40,18 @@ class CONTENT_EXPORT VideoCaptureDeviceClient
public:
VideoCaptureDeviceClient(
const base::WeakPtr<VideoCaptureController>& controller,
- const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
- const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner);
+ const scoped_refptr<VideoCaptureBufferPool>& buffer_pool);
~VideoCaptureDeviceClient() override;
// VideoCaptureDevice::Client implementation.
- void OnIncomingCapturedData(const uint8* data,
+ void OnIncomingCapturedData(const uint8_t* data,
int length,
const media::VideoCaptureFormat& frame_format,
int rotation,
const base::TimeTicks& timestamp) override;
- void OnIncomingCapturedYuvData(const uint8* y_data,
- const uint8* u_data,
- const uint8* v_data,
+ void OnIncomingCapturedYuvData(const uint8_t* y_data,
+ const uint8_t* u_data,
+ const uint8_t* v_data,
size_t y_stride,
size_t u_stride,
size_t v_stride,
@@ -66,7 +69,8 @@ class CONTENT_EXPORT VideoCaptureDeviceClient
scoped_ptr<Buffer> buffer,
const scoped_refptr<media::VideoFrame>& frame,
const base::TimeTicks& timestamp) override;
- void OnError(const std::string& reason) override;
+ void OnError(const tracked_objects::Location& from_here,
+ const std::string& reason) override;
void OnLog(const std::string& message) override;
double GetBufferPoolUtilization() const override;
@@ -85,9 +89,9 @@ class CONTENT_EXPORT VideoCaptureDeviceClient
// are destroyed or returned.
scoped_ptr<Buffer> ReserveI420OutputBuffer(const gfx::Size& dimensions,
media::VideoPixelStorage storage,
- uint8** y_plane_data,
- uint8** u_plane_data,
- uint8** v_plane_data);
+ uint8_t** y_plane_data,
+ uint8_t** u_plane_data,
+ uint8_t** v_plane_data);
// The controller to which we post events.
const base::WeakPtr<VideoCaptureController> controller_;
@@ -105,13 +109,6 @@ class CONTENT_EXPORT VideoCaptureDeviceClient
// GpuMemoryBuffers.
const bool use_gpu_memory_buffers_;
- // Internal delegate for GpuMemoryBuffer-into-VideoFrame wrapping.
- class TextureWrapHelper;
- scoped_refptr<TextureWrapHelper> texture_wrap_helper_;
- // Reference to Capture Thread task runner, where |texture_wrap_helper_|
- // lives.
- const scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
-
media::VideoPixelFormat last_captured_pixel_format_;
DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceClient);
diff --git a/chromium/content/browser/renderer_host/media/video_capture_device_client_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_device_client_unittest.cc
index f6e6446a3a2..56c0a120345 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_device_client_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_device_client_unittest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "content/browser/renderer_host/media/video_capture_device_client.h"
@@ -49,9 +53,7 @@ class VideoCaptureDeviceClientTest : public ::testing::Test {
VideoCaptureDeviceClientTest()
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
controller_(new MockVideoCaptureController(1)),
- device_client_(
- controller_->NewDeviceClient(base::ThreadTaskRunnerHandle::Get())) {
- }
+ device_client_(controller_->NewDeviceClient()) {}
~VideoCaptureDeviceClientTest() override {}
void TearDown() override { base::RunLoop().RunUntilIdle(); }
diff --git a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
index 12ead3c6a71..c48181acdb5 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
@@ -12,6 +14,7 @@
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h"
#include "content/public/browser/browser_thread.h"
@@ -43,10 +46,8 @@ void VideoCaptureGpuJpegDecoder::Initialize() {
DCHECK(CalledOnValidThread());
base::AutoLock lock(lock_);
- // TODO(henryhsu): enable on ARM platform after V4L2 JpegDecodeAccelerator is
- // ready.
bool is_platform_supported = false;
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
+#if defined(OS_CHROMEOS)
// Non-ChromeOS platforms do not support HW JPEG decode now. Do not establish
// gpu channel to avoid introducing overhead.
is_platform_supported = true;
@@ -212,7 +213,7 @@ void VideoCaptureGpuJpegDecoder::GpuChannelEstablishedOnUIThread(
BrowserGpuChannelHostFactory::instance()->GetGpuChannel());
task_runner->PostTask(
FROM_HERE, base::Bind(&VideoCaptureGpuJpegDecoder::FinishInitialization,
- weak_this, base::Passed(&gpu_channel_host)));
+ weak_this, std::move(gpu_channel_host)));
}
void VideoCaptureGpuJpegDecoder::FinishInitialization(
@@ -222,7 +223,7 @@ void VideoCaptureGpuJpegDecoder::FinishInitialization(
if (!gpu_channel_host) {
LOG(ERROR) << "Failed to establish GPU channel for JPEG decoder";
} else if (gpu_channel_host->gpu_info().jpeg_decode_accelerator_supported) {
- gpu_channel_host_ = gpu_channel_host.Pass();
+ gpu_channel_host_ = std::move(gpu_channel_host);
decoder_ = gpu_channel_host_->CreateJpegDecoder(this);
}
decoder_status_ = decoder_ ? INIT_PASSED : FAILED;
diff --git a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
index c7040cee02e..554cb104614 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -53,7 +57,7 @@ class CONTENT_EXPORT VideoCaptureGpuJpegDecoder
// |decode_done_cb| is called on the IO thread when decode succeed. This can
// be on any thread. |decode_done_cb| is never called after
// VideoCaptureGpuJpegDecoder is destroyed.
- VideoCaptureGpuJpegDecoder(const DecodeDoneCB& decode_done_cb);
+ explicit VideoCaptureGpuJpegDecoder(const DecodeDoneCB& decode_done_cb);
~VideoCaptureGpuJpegDecoder() override;
// Creates and intializes decoder asynchronously.
diff --git a/chromium/content/browser/renderer_host/media/video_capture_host.cc b/chromium/content/browser/renderer_host/media/video_capture_host.cc
index 130a2896180..ed3fea64858 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_host.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_host.cc
@@ -105,12 +105,6 @@ void VideoCaptureHost::OnBufferReady(
params.storage_type = video_frame->storage_type();
params.coded_size = video_frame->coded_size();
params.visible_rect = video_frame->visible_rect();
- if (video_frame->HasTextures()) {
- for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format());
- ++i) {
- params.mailbox_holders.push_back(video_frame->mailbox_holder(i));
- }
- }
Send(new VideoCaptureMsg_BufferReady(params));
}
@@ -271,7 +265,7 @@ void VideoCaptureHost::OnResumeCapture(
void VideoCaptureHost::OnRendererFinishedWithBuffer(
int device_id,
int buffer_id,
- uint32 sync_point,
+ const gpu::SyncToken& sync_token,
double consumer_resource_utilization) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -280,10 +274,7 @@ void VideoCaptureHost::OnRendererFinishedWithBuffer(
if (it != entries_.end()) {
const base::WeakPtr<VideoCaptureController>& controller = it->second;
if (controller) {
- controller->ReturnBuffer(controller_id,
- this,
- buffer_id,
- sync_point,
+ controller->ReturnBuffer(controller_id, this, buffer_id, sync_token,
consumer_resource_utilization);
}
}
diff --git a/chromium/content/browser/renderer_host/media/video_capture_host.h b/chromium/content/browser/renderer_host/media/video_capture_host.h
index f2709123e1b..c35153f106b 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_host.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_host.h
@@ -53,6 +53,7 @@
#include <map>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner_helpers.h"
@@ -130,7 +131,7 @@ class CONTENT_EXPORT VideoCaptureHost
// the controller.
void OnRendererFinishedWithBuffer(int device_id,
int buffer_id,
- uint32 sync_point,
+ const gpu::SyncToken& sync_token,
double consumer_resource_utilization);
// IPC message: Get supported formats referenced by |capture_session_id|.
diff --git a/chromium/content/browser/renderer_host/media/video_capture_host_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_host_unittest.cc
index 70c6112c097..b1d991a95fe 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_host_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <map>
#include <string>
@@ -10,12 +12,14 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/media_stream_requester.h"
@@ -151,7 +155,8 @@ class MockVideoCaptureHost : public VideoCaptureHost {
void ReturnReceivedDibs(int device_id) {
int handle = GetReceivedDib();
while (handle) {
- this->OnRendererFinishedWithBuffer(device_id, handle, 0, -1.0);
+ this->OnRendererFinishedWithBuffer(device_id, handle, gpu::SyncToken(),
+ -1.0);
handle = GetReceivedDib();
}
}
@@ -198,7 +203,7 @@ class MockVideoCaptureHost : public VideoCaptureHost {
// These handler methods do minimal things and delegate to the mock methods.
void OnNewBufferCreatedDispatch(int device_id,
base::SharedMemoryHandle handle,
- uint32 length,
+ uint32_t length,
int buffer_id) {
OnNewBufferCreated(device_id, handle, length, buffer_id);
base::SharedMemory* dib = new base::SharedMemory(handle, false);
@@ -231,7 +236,7 @@ class MockVideoCaptureHost : public VideoCaptureHost {
OnBufferFilled(params.device_id);
if (return_buffers_) {
VideoCaptureHost::OnRendererFinishedWithBuffer(
- params.device_id, params.buffer_id, 0, -1.0);
+ params.device_id, params.buffer_id, gpu::SyncToken(), -1.0);
}
}
diff --git a/chromium/content/browser/renderer_host/media/video_capture_manager.cc b/chromium/content/browser/renderer_host/media/video_capture_manager.cc
index 5a92f1921f9..dcee567489c 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_manager.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <set>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -15,9 +16,11 @@
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
#include "base/task_runner_util.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "build/build_config.h"
#include "content/browser/media/capture/web_contents_video_capture_device.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
@@ -37,6 +40,10 @@
#endif
#endif
+#if defined(OS_MACOSX)
+#include "media/base/mac/avfoundation_glue.h"
+#endif
+
namespace {
// Compares two VideoCaptureFormat by checking smallest frame_size area, then
@@ -114,7 +121,7 @@ VideoCaptureManager::DeviceEntry::DeviceEntry(
: serial_id(g_device_start_id++),
stream_type(stream_type),
id(id),
- video_capture_controller_(controller.Pass()) {}
+ video_capture_controller_(std::move(controller)) {}
VideoCaptureManager::DeviceEntry::~DeviceEntry() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -133,7 +140,7 @@ void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice(
scoped_ptr<media::VideoCaptureDevice>
VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() {
DCHECK(thread_checker_.CalledOnValidThread());
- return video_capture_device_.Pass();
+ return std::move(video_capture_device_);
}
VideoCaptureController*
@@ -162,8 +169,7 @@ VideoCaptureManager::VideoCaptureManager(
scoped_ptr<media::VideoCaptureDeviceFactory> factory)
: listener_(NULL),
new_capture_session_id_(1),
- video_capture_device_factory_(factory.Pass()) {
-}
+ video_capture_device_factory_(std::move(factory)) {}
VideoCaptureManager::~VideoCaptureManager() {
DCHECK(devices_.empty());
@@ -191,6 +197,14 @@ void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) {
DCHECK(listener_);
DCHECK_EQ(stream_type, MEDIA_DEVICE_VIDEO_CAPTURE);
+#if defined(OS_MACOSX)
+ if (NeedToInitializeCaptureDeviceApi(stream_type)) {
+ InitializeCaptureDeviceApiOnUIThread(
+ base::Bind(&VideoCaptureManager::EnumerateDevices, this, stream_type));
+ return;
+ }
+#endif
+
// Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument
// for another callback to OnDevicesInfoEnumerated() to be run in the current
// loop, i.e. IO loop. Pass a timer for UMA histogram collection.
@@ -296,6 +310,9 @@ void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) {
DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id
<< " serial_id = " << entry->serial_id << ".";
+ entry->video_capture_controller()->DoLogOnIOThread(
+ base::StringPrintf("Stopping device: id: %s\n", entry->id.c_str()));
+
if (entry->video_capture_device()) {
// |entry->video_capture_device| can be null if creating the device fails.
device_task_runner_->PostTask(
@@ -325,20 +342,77 @@ void VideoCaptureManager::HandleQueuedStartRequest() {
DCHECK(entry_it != devices_.end());
DeviceEntry* entry = (*entry_it);
+#if defined(OS_MACOSX)
+ if (NeedToInitializeCaptureDeviceApi(entry->stream_type)) {
+ InitializeCaptureDeviceApiOnUIThread(
+ base::Bind(&VideoCaptureManager::HandleQueuedStartRequest, this));
+ return;
+ }
+#endif
+
DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = "
<< entry->id << " start id = " << entry->serial_id;
+
+ base::Callback<scoped_ptr<media::VideoCaptureDevice>(void)>
+ start_capture_function;
+
+ switch (entry->stream_type) {
+ case MEDIA_DEVICE_VIDEO_CAPTURE: {
+ // We look up the device id from the renderer in our local enumeration
+ // since the renderer does not have all the information that might be
+ // held in the browser-side VideoCaptureDevice::Name structure.
+ const media::VideoCaptureDeviceInfo* found =
+ FindDeviceInfoById(entry->id, devices_info_cache_);
+ if (found) {
+ entry->video_capture_controller()->DoLogOnIOThread(base::StringPrintf(
+ "Starting device: id: %s, name: %s, api: %s",
+ found->name.id().c_str(), found->name.GetNameAndModel().c_str(),
+ found->name.GetCaptureApiTypeString()));
+
+ start_capture_function = base::Bind(
+ &VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, this,
+ found->name, request->params(),
+ base::Passed(entry->video_capture_controller()->NewDeviceClient()));
+ } else {
+ // Errors from DoStartDeviceCaptureOnDeviceThread go via
+ // VideoCaptureDeviceClient::OnError, which needs some thread
+ // dancing to get errors processed on the IO thread. But since
+ // we're on that thread, we call VideoCaptureController
+ // methods directly.
+ const std::string log_message = base::StringPrintf(
+ "Error on %s:%d: device %s unknown. Maybe recently disconnected?",
+ __FILE__, __LINE__, entry->id.c_str());
+ DLOG(ERROR) << log_message;
+ entry->video_capture_controller()->DoLogOnIOThread(log_message);
+ entry->video_capture_controller()->DoErrorOnIOThread();
+ // Drop the failed start request.
+ device_start_queue_.pop_front();
+
+ return;
+ }
+ break;
+ }
+ case MEDIA_TAB_VIDEO_CAPTURE:
+ start_capture_function = base::Bind(
+ &VideoCaptureManager::DoStartTabCaptureOnDeviceThread, this,
+ entry->id, request->params(),
+ base::Passed(entry->video_capture_controller()->NewDeviceClient()));
+ break;
+
+ case MEDIA_DESKTOP_VIDEO_CAPTURE:
+ start_capture_function = base::Bind(
+ &VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, this,
+ entry->id, request->params(),
+ base::Passed(entry->video_capture_controller()->NewDeviceClient()));
+ break;
+
+ default: {
+ NOTIMPLEMENTED();
+ return;
+ }
+ }
base::PostTaskAndReplyWithResult(
- device_task_runner_.get(),
- FROM_HERE,
- base::Bind(
- &VideoCaptureManager::DoStartDeviceOnDeviceThread,
- this,
- request->session_id(),
- entry->id,
- entry->stream_type,
- request->params(),
- base::Passed(entry->video_capture_controller()->NewDeviceClient(
- device_task_runner_))),
+ device_task_runner_.get(), FROM_HERE, start_capture_function,
base::Bind(&VideoCaptureManager::OnDeviceStarted, this,
request->serial_id()));
}
@@ -350,7 +424,8 @@ void VideoCaptureManager::OnDeviceStarted(
DCHECK(serial_id == device_start_queue_.begin()->serial_id());
DVLOG(3) << "OnDeviceStarted";
if (device_start_queue_.front().abort_start()) {
- // |device| can be null if creation failed in DoStartDeviceOnDeviceThread.
+ // |device| can be null if creation failed in
+ // DoStartDeviceCaptureOnDeviceThread.
// The device is no longer wanted. Stop the device again.
DVLOG(3) << "OnDeviceStarted but start request have been aborted.";
media::VideoCaptureDevice* device_ptr = device.get();
@@ -370,7 +445,7 @@ void VideoCaptureManager::OnDeviceStarted(
DCHECK(entry_it != devices_.end());
DeviceEntry* entry = *entry_it;
DCHECK(!entry->video_capture_device());
- entry->SetVideoCaptureDevice(device.Pass());
+ entry->SetVideoCaptureDevice(std::move(device));
if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
const media::VideoCaptureSessionId session_id =
@@ -384,60 +459,72 @@ void VideoCaptureManager::OnDeviceStarted(
}
scoped_ptr<media::VideoCaptureDevice>
-VideoCaptureManager::DoStartDeviceOnDeviceThread(
- media::VideoCaptureSessionId session_id,
+VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread(
+ const media::VideoCaptureDevice::Name& name,
+ const media::VideoCaptureParams& params,
+ scoped_ptr<media::VideoCaptureDevice::Client> device_client) {
+ SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
+ DCHECK(IsOnDeviceThread());
+
+ scoped_ptr<media::VideoCaptureDevice> video_capture_device;
+ video_capture_device = video_capture_device_factory_->Create(name);
+
+ if (!video_capture_device) {
+ device_client->OnError(FROM_HERE, "Could not create capture device");
+ return nullptr;
+ }
+
+ video_capture_device->AllocateAndStart(params, std::move(device_client));
+ return video_capture_device;
+}
+
+scoped_ptr<media::VideoCaptureDevice>
+VideoCaptureManager::DoStartTabCaptureOnDeviceThread(
+ const std::string& id,
+ const media::VideoCaptureParams& params,
+ scoped_ptr<media::VideoCaptureDevice::Client> device_client) {
+ SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
+ DCHECK(IsOnDeviceThread());
+
+ scoped_ptr<media::VideoCaptureDevice> video_capture_device;
+ video_capture_device.reset(WebContentsVideoCaptureDevice::Create(id));
+
+ if (!video_capture_device) {
+ device_client->OnError(FROM_HERE, "Could not create capture device");
+ return nullptr;
+ }
+
+ video_capture_device->AllocateAndStart(params, std::move(device_client));
+ return video_capture_device;
+}
+
+scoped_ptr<media::VideoCaptureDevice>
+VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread(
const std::string& id,
- MediaStreamType stream_type,
const media::VideoCaptureParams& params,
scoped_ptr<media::VideoCaptureDevice::Client> device_client) {
SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
DCHECK(IsOnDeviceThread());
scoped_ptr<media::VideoCaptureDevice> video_capture_device;
- switch (stream_type) {
- case MEDIA_DEVICE_VIDEO_CAPTURE: {
- // We look up the device id from the renderer in our local enumeration
- // since the renderer does not have all the information that might be
- // held in the browser-side VideoCaptureDevice::Name structure.
- const media::VideoCaptureDeviceInfo* found =
- FindDeviceInfoById(id, devices_info_cache_);
- if (found) {
- video_capture_device =
- video_capture_device_factory_->Create(found->name);
- }
- break;
- }
- case MEDIA_TAB_VIDEO_CAPTURE: {
- video_capture_device.reset(
- WebContentsVideoCaptureDevice::Create(id));
- break;
- }
- case MEDIA_DESKTOP_VIDEO_CAPTURE: {
#if defined(ENABLE_SCREEN_CAPTURE)
- DesktopMediaID desktop_id = DesktopMediaID::Parse(id);
- if (!desktop_id.is_null()) {
+ DesktopMediaID desktop_id = DesktopMediaID::Parse(id);
+ if (!desktop_id.is_null()) {
#if defined(USE_AURA)
- video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id);
+ video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id);
#endif
- if (!video_capture_device)
- video_capture_device = DesktopCaptureDevice::Create(desktop_id);
- }
-#endif // defined(ENABLE_SCREEN_CAPTURE)
- break;
- }
- default: {
- NOTIMPLEMENTED();
- break;
- }
+ if (!video_capture_device)
+ video_capture_device = DesktopCaptureDevice::Create(desktop_id);
}
+#endif // defined(ENABLE_SCREEN_CAPTURE)
if (!video_capture_device) {
- device_client->OnError("Could not create capture device");
+ device_client->OnError(FROM_HERE, "Could not create capture device");
return nullptr;
}
- video_capture_device->AllocateAndStart(params, device_client.Pass());
- return video_capture_device.Pass();
+ video_capture_device->AllocateAndStart(params, std::move(device_client));
+ return video_capture_device;
}
void VideoCaptureManager::StartCaptureForClient(
@@ -837,9 +924,8 @@ VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
kMaxNumberOfBuffersForTabCapture : kMaxNumberOfBuffers;
scoped_ptr<VideoCaptureController> video_capture_controller(
new VideoCaptureController(max_buffers));
- DeviceEntry* new_device = new DeviceEntry(device_info.type,
- device_info.id,
- video_capture_controller.Pass());
+ DeviceEntry* new_device = new DeviceEntry(
+ device_info.type, device_info.id, std::move(video_capture_controller));
devices_.push_back(new_device);
return new_device;
}
@@ -866,4 +952,30 @@ void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread(
#endif
}
+#if defined(OS_MACOSX)
+void VideoCaptureManager::OnDeviceLayerInitialized(
+ const base::Closure& and_then) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ capture_device_api_initialized_ = true;
+ and_then.Run();
+}
+
+bool VideoCaptureManager::NeedToInitializeCaptureDeviceApi(
+ MediaStreamType stream_type) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return !capture_device_api_initialized_ &&
+ stream_type == MEDIA_DEVICE_VIDEO_CAPTURE;
+}
+
+void VideoCaptureManager::InitializeCaptureDeviceApiOnUIThread(
+ const base::Closure& and_then) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&AVFoundationGlue::InitializeAVFoundation),
+ base::Bind(&VideoCaptureManager::OnDeviceLayerInitialized, this,
+ and_then));
+}
+#endif
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/video_capture_manager.h b/chromium/content/browser/renderer_host/media/video_capture_manager.h
index 7a93e4a365b..6a5fc9c36f8 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_manager.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_manager.h
@@ -17,6 +17,7 @@
#include <set>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
@@ -24,6 +25,7 @@
#include "base/process/process_handle.h"
#include "base/threading/thread_checker.h"
#include "base/timer/elapsed_timer.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/media_stream_provider.h"
#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
#include "content/common/content_export.h"
@@ -208,10 +210,18 @@ class CONTENT_EXPORT VideoCaptureManager : public MediaStreamProvider {
// VideoCaptureDevice is returned to the IO-thread and stored in
// a DeviceEntry in |devices_|. Ownership of |client| passes to
// the device.
- scoped_ptr<media::VideoCaptureDevice> DoStartDeviceOnDeviceThread(
- media::VideoCaptureSessionId session_id,
+ scoped_ptr<media::VideoCaptureDevice> DoStartDeviceCaptureOnDeviceThread(
+ const media::VideoCaptureDevice::Name& name,
+ const media::VideoCaptureParams& params,
+ scoped_ptr<media::VideoCaptureDevice::Client> client);
+
+ scoped_ptr<media::VideoCaptureDevice> DoStartTabCaptureOnDeviceThread(
+ const std::string& device_id,
+ const media::VideoCaptureParams& params,
+ scoped_ptr<media::VideoCaptureDevice::Client> client);
+
+ scoped_ptr<media::VideoCaptureDevice> DoStartDesktopCaptureOnDeviceThread(
const std::string& device_id,
- MediaStreamType stream_type,
const media::VideoCaptureParams& params,
scoped_ptr<media::VideoCaptureDevice::Client> client);
@@ -228,6 +238,26 @@ class CONTENT_EXPORT VideoCaptureManager : public MediaStreamProvider {
media::VideoCaptureDevice* device,
gfx::NativeViewId window_id);
+#if defined(OS_MACOSX)
+ // Called on the IO thread after the device layer has been initialized on Mac.
+ // Sets |capture_device_api_initialized_| to true and then executes and_then.
+ void OnDeviceLayerInitialized(const base::Closure& and_then);
+
+ // Returns true if the current operation needs to be preempted by a call to
+ // InitializeCaptureDeviceApiOnUIThread.
+ // Called on the IO thread.
+ bool NeedToInitializeCaptureDeviceApi(MediaStreamType stream_type);
+
+ // Called on the IO thread to do async initialization of the capture api.
+ // Once initialization is done, and_then will be run on the IO thread.
+ void InitializeCaptureDeviceApiOnUIThread(const base::Closure& and_then);
+
+ // Due to initialization issues with AVFoundation and QTKit on Mac, we need
+ // to make sure we initialize the APIs on the UI thread before we can reliably
+ // use them. This variable is only checked and set on the IO thread.
+ bool capture_device_api_initialized_ = false;
+#endif
+
// The message loop of media stream device thread, where VCD's live.
scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
diff --git a/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc
index ccfaafacf80..954544c6b62 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc
@@ -4,9 +4,12 @@
// Unit test for VideoCaptureManager.
+#include <stdint.h>
+
#include <string>
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
@@ -21,7 +24,9 @@
using ::testing::_;
using ::testing::AnyNumber;
+using ::testing::DoAll;
using ::testing::InSequence;
+using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using ::testing::SaveArg;
@@ -72,6 +77,8 @@ class VideoCaptureManagerTest : public testing::Test {
void SetUp() override {
listener_.reset(new MockMediaStreamProviderListener());
message_loop_.reset(new base::MessageLoopForIO);
+ ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
+ message_loop_.get()));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
message_loop_.get()));
vcm_ = new VideoCaptureManager(scoped_ptr<media::VideoCaptureDeviceFactory>(
@@ -79,7 +86,7 @@ class VideoCaptureManagerTest : public testing::Test {
video_capture_device_factory_ =
static_cast<media::FakeVideoCaptureDeviceFactory*>(
vcm_->video_capture_device_factory());
- const int32 kNumberOfFakeDevices = 2;
+ const int32_t kNumberOfFakeDevices = 2;
video_capture_device_factory_->set_number_of_devices(kNumberOfFakeDevices);
vcm_->Register(listener_.get(), message_loop_->task_runner().get());
frame_observer_.reset(new MockFrameObserver());
@@ -156,6 +163,7 @@ class VideoCaptureManagerTest : public testing::Test {
scoped_refptr<VideoCaptureManager> vcm_;
scoped_ptr<MockMediaStreamProviderListener> listener_;
scoped_ptr<base::MessageLoop> message_loop_;
+ scoped_ptr<BrowserThreadImpl> ui_thread_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_ptr<MockFrameObserver> frame_observer_;
media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
@@ -465,8 +473,8 @@ TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
InSequence s;
EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
.WillOnce(SaveArg<1>(&devices));
- EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
EXPECT_CALL(*frame_observer_, OnError(_));
+ EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
@@ -503,18 +511,21 @@ TEST_F(VideoCaptureManagerTest, StartInvalidSession) {
// Open and start a device, close it before calling Stop.
TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
StreamDeviceInfoArray devices;
+ base::RunLoop run_loop;
InSequence s;
EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
- .WillOnce(SaveArg<1>(&devices));
+ .WillOnce(
+ DoAll(SaveArg<1>(&devices),
+ InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)));
EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
// Wait to get device callback.
- message_loop_->RunUntilIdle();
-
+ run_loop.Run();
+ ASSERT_FALSE(devices.empty());
int video_session_id = vcm_->Open(devices.front());
VideoCaptureControllerID client_id = StartClient(video_session_id, true);
diff --git a/chromium/content/browser/renderer_host/media/webrtc_identity_service_host.h b/chromium/content/browser/renderer_host/media/webrtc_identity_service_host.h
index 2b2a4af9d9f..51744f49352 100644
--- a/chromium/content/browser/renderer_host/media/webrtc_identity_service_host.h
+++ b/chromium/content/browser/renderer_host/media/webrtc_identity_service_host.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
diff --git a/chromium/content/browser/renderer_host/memory_benchmark_message_filter.cc b/chromium/content/browser/renderer_host/memory_benchmark_message_filter.cc
index 607325376f7..9125a8c0873 100644
--- a/chromium/content/browser/renderer_host/memory_benchmark_message_filter.cc
+++ b/chromium/content/browser/renderer_host/memory_benchmark_message_filter.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/memory_benchmark_message_filter.h"
+#include "build/build_config.h"
#include "content/common/memory_benchmark_messages.h"
#if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID))
diff --git a/chromium/content/browser/renderer_host/memory_benchmark_message_filter.h b/chromium/content/browser/renderer_host/memory_benchmark_message_filter.h
index d30e3a78fb1..0bafa73b49e 100644
--- a/chromium/content/browser/renderer_host/memory_benchmark_message_filter.h
+++ b/chromium/content/browser/renderer_host/memory_benchmark_message_filter.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
namespace content {
diff --git a/chromium/content/browser/renderer_host/native_web_keyboard_event_aura.cc b/chromium/content/browser/renderer_host/native_web_keyboard_event_aura.cc
index 5f3d8bd96eb..b84c879b074 100644
--- a/chromium/content/browser/renderer_host/native_web_keyboard_event_aura.cc
+++ b/chromium/content/browser/renderer_host/native_web_keyboard_event_aura.cc
@@ -19,14 +19,6 @@ ui::Event* CopyEvent(const ui::Event* event) {
return event ? ui::Event::Clone(*event).release() : nullptr;
}
-int EventFlagsToWebInputEventModifiers(int flags) {
- return
- (flags & ui::EF_SHIFT_DOWN ? blink::WebInputEvent::ShiftKey : 0) |
- (flags & ui::EF_CONTROL_DOWN ? blink::WebInputEvent::ControlKey : 0) |
- (flags & ui::EF_CAPS_LOCK_DOWN ? blink::WebInputEvent::CapsLockOn : 0) |
- (flags & ui::EF_ALT_DOWN ? blink::WebInputEvent::AltKey : 0);
-}
-
} // namespace
using blink::WebKeyboardEvent;
@@ -58,34 +50,16 @@ NativeWebKeyboardEvent::NativeWebKeyboardEvent(
match_edit_command(false) {
}
-NativeWebKeyboardEvent::NativeWebKeyboardEvent(
- ui::EventType key_event_type,
- bool is_char,
- wchar_t character,
- int state,
- double time_stamp_seconds)
- : os_event(NULL),
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(const ui::KeyEvent& key_event,
+ base::char16 character)
+ : WebKeyboardEvent(MakeWebKeyboardEvent(key_event)),
+ os_event(NULL),
skip_in_browser(false),
match_edit_command(false) {
- switch (key_event_type) {
- case ui::ET_KEY_PRESSED:
- type = is_char ? blink::WebInputEvent::Char :
- blink::WebInputEvent::RawKeyDown;
- break;
- case ui::ET_KEY_RELEASED:
- type = blink::WebInputEvent::KeyUp;
- break;
- default:
- NOTREACHED();
- }
-
- modifiers = EventFlagsToWebInputEventModifiers(state);
- timeStampSeconds = time_stamp_seconds;
+ type = blink::WebInputEvent::Char;
windowsKeyCode = character;
- nativeKeyCode = character;
text[0] = character;
unmodifiedText[0] = character;
- isSystemKey = ui::IsSystemKeyModifier(state);
setKeyIdentifierFromWindowsKeyCode();
}
diff --git a/chromium/content/browser/renderer_host/overscroll_configuration.cc b/chromium/content/browser/renderer_host/overscroll_configuration.cc
index f7c5579f56f..9faf0060657 100644
--- a/chromium/content/browser/renderer_host/overscroll_configuration.cc
+++ b/chromium/content/browser/renderer_host/overscroll_configuration.cc
@@ -22,42 +22,6 @@ float g_vert_resist_after = 30.f;
namespace content {
-void SetOverscrollConfig(OverscrollConfig config, float value) {
- switch (config) {
- case OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE:
- g_horiz_threshold_complete = value;
- break;
-
- case OVERSCROLL_CONFIG_VERT_THRESHOLD_COMPLETE:
- g_vert_threshold_complete = value;
- break;
-
- case OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN:
- g_horiz_threshold_start_touchscreen = value;
- break;
-
- case OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD:
- g_horiz_threshold_start_touchpad = value;
- break;
-
- case OVERSCROLL_CONFIG_VERT_THRESHOLD_START:
- g_vert_threshold_start = value;
- break;
-
- case OVERSCROLL_CONFIG_HORIZ_RESIST_AFTER:
- g_horiz_resist_after = value;
- break;
-
- case OVERSCROLL_CONFIG_VERT_RESIST_AFTER:
- g_vert_resist_after = value;
- break;
-
- case OVERSCROLL_CONFIG_NONE:
- case OVERSCROLL_CONFIG_COUNT:
- NOTREACHED();
- }
-}
-
float GetOverscrollConfig(OverscrollConfig config) {
switch (config) {
case OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE:
diff --git a/chromium/content/browser/renderer_host/overscroll_controller.h b/chromium/content/browser/renderer_host/overscroll_controller.h
index 6ea77e60d46..92fa093bf13 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller.h
+++ b/chromium/content/browser/renderer_host/overscroll_controller.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
namespace ui {
diff --git a/chromium/content/browser/renderer_host/overscroll_controller_delegate.h b/chromium/content/browser/renderer_host/overscroll_controller_delegate.h
index b3d4757933f..0533cde23aa 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller_delegate.h
+++ b/chromium/content/browser/renderer_host/overscroll_controller_delegate.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_DELEGATE_H_
#define CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_DELEGATE_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/rect.h"
diff --git a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
index c450d31964a..784a808edfa 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -4,18 +4,24 @@
#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/stl_util.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
#include "content/common/p2p_messages.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
+#include "net/base/ip_address_number.h"
#include "net/base/net_errors.h"
#include "net/base/network_interfaces.h"
#include "net/base/sys_addrinfo.h"
#include "net/dns/single_request_host_resolver.h"
#include "net/log/net_log.h"
+#include "net/socket/client_socket_factory.h"
+#include "net/udp/datagram_client_socket.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserMessageFilter;
@@ -23,16 +29,25 @@ using content::BrowserThread;
namespace content {
+namespace {
+
+// Used by GetDefaultLocalAddress as the target to connect to for getting the
+// default local address. They are public DNS servers on the internet.
+const uint8_t kPublicIPv4Host[] = {8, 8, 8, 8};
+const uint8_t kPublicIPv6Host[] = {
+ 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0, 0, 0, 0, 0, 0, 0, 0, 0x88, 0x88};
+const int kPublicPort = 53; // DNS port.
+
+} // namespace
+
const size_t kMaximumPacketSize = 32768;
class P2PSocketDispatcherHost::DnsRequest {
public:
typedef base::Callback<void(const net::IPAddressList&)> DoneCallback;
- DnsRequest(int32 request_id, net::HostResolver* host_resolver)
- : request_id_(request_id),
- resolver_(host_resolver) {
- }
+ DnsRequest(int32_t request_id, net::HostResolver* host_resolver)
+ : request_id_(request_id), resolver_(host_resolver) {}
void Resolve(const std::string& host_name,
const DoneCallback& done_callback) {
@@ -65,7 +80,7 @@ class P2PSocketDispatcherHost::DnsRequest {
OnDone(result);
}
- int32 request_id() { return request_id_; }
+ int32_t request_id() { return request_id_; }
private:
void OnDone(int result) {
@@ -85,7 +100,7 @@ class P2PSocketDispatcherHost::DnsRequest {
done_callback_.Run(list);
}
- int32 request_id_;
+ int32_t request_id_;
net::AddressList addresses_;
std::string host_name_;
@@ -213,7 +228,7 @@ void P2PSocketDispatcherHost::OnStopNetworkNotifications() {
}
void P2PSocketDispatcherHost::OnGetHostAddress(const std::string& host_name,
- int32 request_id) {
+ int32_t request_id) {
DnsRequest* request = new DnsRequest(request_id,
resource_context_->GetHostResolver());
dns_requests_.insert(request);
@@ -277,7 +292,7 @@ void P2PSocketDispatcherHost::OnSend(int socket_id,
const net::IPEndPoint& socket_address,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) {
+ uint64_t packet_id) {
P2PSocketHost* socket = LookupSocket(socket_id);
if (!socket) {
LOG(ERROR) << "Received P2PHostMsg_Send for invalid socket_id.";
@@ -321,14 +336,53 @@ void P2PSocketDispatcherHost::OnDestroySocket(int socket_id) {
void P2PSocketDispatcherHost::DoGetNetworkList() {
net::NetworkInterfaceList list;
net::GetNetworkList(&list, net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
+ default_ipv4_local_address_ = GetDefaultLocalAddress(AF_INET);
+ default_ipv6_local_address_ = GetDefaultLocalAddress(AF_INET6);
BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE, base::Bind(
- &P2PSocketDispatcherHost::SendNetworkList, this, list));
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&P2PSocketDispatcherHost::SendNetworkList, this, list,
+ default_ipv4_local_address_, default_ipv6_local_address_));
}
void P2PSocketDispatcherHost::SendNetworkList(
- const net::NetworkInterfaceList& list) {
- Send(new P2PMsg_NetworkListChanged(list));
+ const net::NetworkInterfaceList& list,
+ const net::IPAddressNumber& default_ipv4_local_address,
+ const net::IPAddressNumber& default_ipv6_local_address) {
+ Send(new P2PMsg_NetworkListChanged(list, default_ipv4_local_address,
+ default_ipv6_local_address));
+}
+
+net::IPAddressNumber P2PSocketDispatcherHost::GetDefaultLocalAddress(
+ int family) {
+ DCHECK(family == AF_INET || family == AF_INET6);
+
+ // Creation and connection of a UDP socket might be janky.
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+
+ scoped_ptr<net::DatagramClientSocket> socket(
+ net::ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket(
+ net::DatagramSocket::DEFAULT_BIND, net::RandIntCallback(), NULL,
+ net::NetLog::Source()));
+
+ net::IPAddressNumber ip_address_number;
+ if (family == AF_INET) {
+ ip_address_number.assign(kPublicIPv4Host,
+ kPublicIPv4Host + net::kIPv4AddressSize);
+ } else {
+ ip_address_number.assign(kPublicIPv6Host,
+ kPublicIPv6Host + net::kIPv6AddressSize);
+ }
+
+ if (socket->Connect(net::IPEndPoint(ip_address_number, kPublicPort)) !=
+ net::OK) {
+ return net::IPAddressNumber();
+ }
+
+ net::IPEndPoint local_address;
+ if (socket->GetLocalAddress(&local_address) != net::OK)
+ return net::IPAddressNumber();
+
+ return local_address.address();
}
void P2PSocketDispatcherHost::OnAddressResolved(
diff --git a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
index 18b18df2272..d783e1fbfed 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_DISPATCHER_HOST_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "base/macros.h"
#include "content/browser/renderer_host/p2p/socket_host_throttler.h"
#include "content/common/p2p_socket_type.h"
#include "content/public/browser/browser_message_filter.h"
@@ -71,8 +74,7 @@ class P2PSocketDispatcherHost
// Handlers for the messages coming from the renderer.
void OnStartNetworkNotifications();
void OnStopNetworkNotifications();
- void OnGetHostAddress(const std::string& host_name,
- int32 request_id);
+ void OnGetHostAddress(const std::string& host_name, int32_t request_id);
void OnCreateSocket(P2PSocketType type,
int socket_id,
@@ -85,12 +87,19 @@ class P2PSocketDispatcherHost
const net::IPEndPoint& socket_address,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id);
+ uint64_t packet_id);
void OnSetOption(int socket_id, P2PSocketOption option, int value);
void OnDestroySocket(int socket_id);
void DoGetNetworkList();
- void SendNetworkList(const net::NetworkInterfaceList& list);
+ void SendNetworkList(const net::NetworkInterfaceList& list,
+ const net::IPAddressNumber& default_ipv4_local_address,
+ const net::IPAddressNumber& default_ipv6_local_address);
+
+ // This connects a UDP socket to a public IP address and gets local
+ // address. Since it binds to the "any" address (0.0.0.0 or ::) internally, it
+ // retrieves the default local address.
+ net::IPAddressNumber GetDefaultLocalAddress(int family);
void OnAddressResolved(DnsRequest* request,
const net::IPAddressList& addresses);
@@ -107,6 +116,9 @@ class P2PSocketDispatcherHost
std::set<DnsRequest*> dns_requests_;
P2PMessageThrottler throttler_;
+ net::IPAddressNumber default_ipv4_local_address_;
+ net::IPAddressNumber default_ipv6_local_address_;
+
bool dump_incoming_rtp_packet_;
bool dump_outgoing_rtp_packet_;
RenderProcessHost::WebRtcRtpPacketCallback packet_callback_;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host.cc b/chromium/content/browser/renderer_host/p2p/socket_host.cc
index f2e76c37163..ef6b58820c1 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host.cc
@@ -19,7 +19,7 @@
namespace {
-const uint32 kStunMagicCookie = 0x2112A442;
+const uint32_t kStunMagicCookie = 0x2112A442;
const size_t kMinRtpHeaderLength = 12;
const size_t kMinRtcpHeaderLength = 8;
const size_t kRtpExtensionHeaderLength = 4;
@@ -41,7 +41,7 @@ bool IsTurnChannelData(const char* data, size_t length) {
}
bool IsDtlsPacket(const char* data, size_t length) {
- const uint8* u = reinterpret_cast<const uint8*>(data);
+ const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
return (length >= kDtlsRecordHeaderLength && (u[0] > 19 && u[0] < 64));
}
@@ -50,7 +50,7 @@ bool IsRtcpPacket(const char* data, size_t length) {
return false;
}
- int type = (static_cast<uint8>(data[1]) & 0x7F);
+ int type = (static_cast<uint8_t>(data[1]) & 0x7F);
return (type >= 64 && type < 96);
}
@@ -59,7 +59,7 @@ bool IsTurnSendIndicationPacket(const char* data, size_t length) {
return false;
}
- uint16 type = rtc::GetBE16(data);
+ uint16_t type = rtc::GetBE16(data);
return (type == cricket::TURN_SEND_INDICATION);
}
@@ -100,7 +100,7 @@ bool ValidateRtpHeader(const char* rtp, size_t length, size_t* header_length) {
// Getting extension profile length.
// Length is in 32 bit words.
- uint16 extension_length_in_32bits = rtc::GetBE16(rtp + 2);
+ uint16_t extension_length_in_32bits = rtc::GetBE16(rtp + 2);
size_t extension_length = extension_length_in_32bits * 4;
size_t rtp_header_length = extension_length +
@@ -120,7 +120,7 @@ bool ValidateRtpHeader(const char* rtp, size_t length, size_t* header_length) {
void UpdateAbsSendTimeExtensionValue(char* extension_data,
size_t length,
- uint32 abs_send_time) {
+ uint32_t abs_send_time) {
// Absolute send time in RTP streams.
//
// The absolute send time is signaled to the receiver in-band using the
@@ -142,18 +142,18 @@ void UpdateAbsSendTimeExtensionValue(char* extension_data,
}
// Now() has resolution ~1-15ms
- uint32 now_second = abs_send_time;
+ uint32_t now_second = abs_send_time;
if (!now_second) {
- uint64 now_us =
+ uint64_t now_us =
(base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds();
// Convert second to 24-bit unsigned with 18 bit fractional part
now_second =
((now_us << 18) / base::Time::kMicrosecondsPerSecond) & 0x00FFFFFF;
}
// TODO(mallinath) - Add SetBE24 to byteorder.h in libjingle.
- extension_data[0] = static_cast<uint8>(now_second >> 16);
- extension_data[1] = static_cast<uint8>(now_second >> 8);
- extension_data[2] = static_cast<uint8>(now_second);
+ extension_data[0] = static_cast<uint8_t>(now_second >> 16);
+ extension_data[1] = static_cast<uint8_t>(now_second >> 8);
+ extension_data[2] = static_cast<uint8_t>(now_second);
}
// Assumes |length| is actual packet length + tag length. Updates HMAC at end of
@@ -218,7 +218,7 @@ namespace packet_processing_helpers {
bool ApplyPacketOptions(char* data,
size_t length,
const rtc::PacketOptions& options,
- uint32 abs_send_time) {
+ uint32_t abs_send_time) {
DCHECK(data != NULL);
DCHECK(length > 0);
// if there is no valid |rtp_sendtime_extension_id| and |srtp_auth_key| in
@@ -311,7 +311,7 @@ bool GetRtpPacketStartPositionAndLength(const char* packet,
// is not a multiple of 4 bytes are padded with 1, 2, or 3 bytes of
// padding so that its value contains a multiple of 4 bytes. The
// padding bits are ignored, and may be any value.
- uint16 attr_type, attr_length;
+ uint16_t attr_type, attr_length;
const int kAttrHeaderLength = sizeof(attr_type) + sizeof(attr_length);
if (length < rtp_begin + kAttrHeaderLength) {
@@ -372,7 +372,7 @@ bool GetRtpPacketStartPositionAndLength(const char* packet,
bool UpdateRtpAbsSendTimeExtension(char* rtp,
size_t length,
int extension_id,
- uint32 abs_send_time) {
+ uint32_t abs_send_time) {
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -397,9 +397,9 @@ bool UpdateRtpAbsSendTimeExtension(char* rtp,
rtp += header_length_without_extension;
// Getting extension profile ID and length.
- uint16 profile_id = rtc::GetBE16(rtp);
+ uint16_t profile_id = rtc::GetBE16(rtp);
// Length is in 32 bit words.
- uint16 extension_length_in_32bits = rtc::GetBE16(rtp + 2);
+ uint16_t extension_length_in_32bits = rtc::GetBE16(rtp + 2);
size_t extension_length = extension_length_in_32bits * 4;
rtp += kRtpExtensionHeaderLength; // Moving past extension header.
@@ -500,17 +500,20 @@ bool P2PSocketHost::GetStunPacketType(
return false;
}
- uint32 cookie = base::NetToHost32(*reinterpret_cast<const uint32*>(data + 4));
+ uint32_t cookie =
+ base::NetToHost32(*reinterpret_cast<const uint32_t*>(data + 4));
if (cookie != kStunMagicCookie) {
return false;
}
- uint16 length = base::NetToHost16(*reinterpret_cast<const uint16*>(data + 2));
+ uint16_t length =
+ base::NetToHost16(*reinterpret_cast<const uint16_t*>(data + 2));
if (length != data_size - kStunHeaderSize) {
return false;
}
- int message_type = base::NetToHost16(*reinterpret_cast<const uint16*>(data));
+ int message_type =
+ base::NetToHost16(*reinterpret_cast<const uint16_t*>(data));
// Verify that the type is known:
switch (message_type) {
@@ -633,22 +636,19 @@ void P2PSocketHost::DumpRtpPacket(const char* packet,
return;
}
- scoped_ptr<uint8[]> header_buffer(new uint8[header_length]);
+ scoped_ptr<uint8_t[]> header_buffer(new uint8_t[header_length]);
memcpy(header_buffer.get(), packet, header_length);
// Posts to the IO thread as the data members should be accessed on the IO
// thread only.
- BrowserThread::PostTask(BrowserThread::IO,
- FROM_HERE,
- base::Bind(&P2PSocketHost::DumpRtpPacketOnIOThread,
- weak_ptr_factory_.GetWeakPtr(),
- Passed(&header_buffer),
- header_length,
- rtp_packet_length,
- incoming));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&P2PSocketHost::DumpRtpPacketOnIOThread,
+ weak_ptr_factory_.GetWeakPtr(), base::Passed(&header_buffer),
+ header_length, rtp_packet_length, incoming));
}
-void P2PSocketHost::DumpRtpPacketOnIOThread(scoped_ptr<uint8[]> packet_header,
+void P2PSocketHost::DumpRtpPacketOnIOThread(scoped_ptr<uint8_t[]> packet_header,
size_t header_length,
size_t packet_length,
bool incoming) {
@@ -661,13 +661,10 @@ void P2PSocketHost::DumpRtpPacketOnIOThread(scoped_ptr<uint8[]> packet_header,
}
// |packet_dump_callback_| must be called on the UI thread.
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(packet_dump_callback_,
- Passed(&packet_header),
- header_length,
- packet_length,
- incoming));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(packet_dump_callback_, base::Passed(&packet_header),
+ header_length, packet_length, incoming));
}
void P2PSocketHost::IncrementDelayedPackets() {
@@ -678,14 +675,14 @@ void P2PSocketHost::IncrementTotalSentPackets() {
send_packets_total_++;
}
-void P2PSocketHost::IncrementDelayedBytes(uint32 size) {
+void P2PSocketHost::IncrementDelayedBytes(uint32_t size) {
send_bytes_delayed_cur_ += size;
if (send_bytes_delayed_cur_ > send_bytes_delayed_max_) {
send_bytes_delayed_max_ = send_bytes_delayed_cur_;
}
}
-void P2PSocketHost::DecrementDelayedBytes(uint32 size) {
+void P2PSocketHost::DecrementDelayedBytes(uint32_t size) {
send_bytes_delayed_cur_ -= size;
DCHECK_GE(send_bytes_delayed_cur_, 0);
}
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host.h b/chromium/content/browser/renderer_host/p2p/socket_host.h
index b569a0a1041..37ffddbf8cb 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_host.h
@@ -5,6 +5,10 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
@@ -36,7 +40,7 @@ namespace packet_processing_helpers {
CONTENT_EXPORT bool ApplyPacketOptions(char* data,
size_t length,
const rtc::PacketOptions& options,
- uint32 abs_send_time);
+ uint32_t abs_send_time);
// Helper method which finds RTP ofset and length if the packet is encapsulated
// in a TURN Channel Message or TURN Send Indication message.
@@ -50,7 +54,7 @@ CONTENT_EXPORT bool GetRtpPacketStartPositionAndLength(
CONTENT_EXPORT bool UpdateRtpAbsSendTimeExtension(char* rtp,
size_t length,
int extension_id,
- uint32 abs_send_time);
+ uint32_t abs_send_time);
} // packet_processing_helpers
@@ -75,7 +79,7 @@ class CONTENT_EXPORT P2PSocketHost {
virtual void Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) = 0;
+ uint64_t packet_id) = 0;
virtual P2PSocketHost* AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address, int id) = 0;
@@ -142,7 +146,7 @@ class CONTENT_EXPORT P2PSocketHost {
void DumpRtpPacket(const char* packet, size_t length, bool incoming);
// A helper to dump the packet on the IO thread.
- void DumpRtpPacketOnIOThread(scoped_ptr<uint8[]> packet_header,
+ void DumpRtpPacketOnIOThread(scoped_ptr<uint8_t[]> packet_header,
size_t header_length,
size_t packet_length,
bool incoming);
@@ -150,8 +154,8 @@ class CONTENT_EXPORT P2PSocketHost {
// Used by subclasses to track the metrics of delayed bytes and packets.
void IncrementDelayedPackets();
void IncrementTotalSentPackets();
- void IncrementDelayedBytes(uint32 size);
- void DecrementDelayedBytes(uint32 size);
+ void IncrementDelayedBytes(uint32_t size);
+ void DecrementDelayedBytes(uint32_t size);
IPC::Sender* message_sender_;
int id_;
@@ -165,13 +169,13 @@ class CONTENT_EXPORT P2PSocketHost {
private:
// Track total delayed packets for calculating how many packets are
// delayed by system at the end of call.
- uint32 send_packets_delayed_total_;
- uint32 send_packets_total_;
+ uint32_t send_packets_delayed_total_;
+ uint32_t send_packets_total_;
// Track the maximum of consecutive delayed bytes caused by system's
// EWOULDBLOCK.
- int32 send_bytes_delayed_max_;
- int32 send_bytes_delayed_cur_;
+ int32_t send_bytes_delayed_max_;
+ int32_t send_bytes_delayed_cur_;
base::WeakPtrFactory<P2PSocketHost> weak_ptr_factory_;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
index 0273b646cbc..cd93a129370 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
@@ -4,6 +4,9 @@
#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/sys_byteorder.h"
@@ -24,7 +27,7 @@
namespace {
-typedef uint16 PacketLength;
+typedef uint16_t PacketLength;
const int kPacketHeaderSize = sizeof(PacketLength);
const int kReadBufferSize = 4096;
const int kPacketLengthOffset = 2;
@@ -154,9 +157,9 @@ void P2PSocketHostTcpBase::OnConnected(int result) {
state_ = STATE_TLS_CONNECTING;
StartTls();
} else if (IsPseudoTlsClientSocket(type_)) {
- scoped_ptr<net::StreamSocket> transport_socket = socket_.Pass();
+ scoped_ptr<net::StreamSocket> transport_socket = std::move(socket_);
socket_.reset(
- new jingle_glue::FakeSSLClientSocket(transport_socket.Pass()));
+ new jingle_glue::FakeSSLClientSocket(std::move(transport_socket)));
state_ = STATE_TLS_CONNECTING;
int status = socket_->Connect(
base::Bind(&P2PSocketHostTcpBase::ProcessTlsSslConnectDone,
@@ -167,7 +170,7 @@ void P2PSocketHostTcpBase::OnConnected(int result) {
} else {
// If we are not doing TLS, we are ready to send data now.
// In case of TLS, SignalConnect will be sent only after TLS handshake is
- // successfull. So no buffering will be done at socket handlers if any
+ // successful. So no buffering will be done at socket handlers if any
// packets sent before that by the application.
OnOpen();
}
@@ -179,7 +182,7 @@ void P2PSocketHostTcpBase::StartTls() {
scoped_ptr<net::ClientSocketHandle> socket_handle(
new net::ClientSocketHandle());
- socket_handle->SetSocket(socket_.Pass());
+ socket_handle->SetSocket(std::move(socket_));
net::SSLClientSocketContext context;
context.cert_verifier = url_context_->GetURLRequestContext()->cert_verifier();
@@ -206,7 +209,7 @@ void P2PSocketHostTcpBase::StartTls() {
DCHECK(socket_factory);
socket_ = socket_factory->CreateSSLClientSocket(
- socket_handle.Pass(), dest_host_port_pair, ssl_config, context);
+ std::move(socket_handle), dest_host_port_pair, ssl_config, context);
int status = socket_->Connect(
base::Bind(&P2PSocketHostTcpBase::ProcessTlsSslConnectDone,
base::Unretained(this)));
@@ -349,7 +352,7 @@ void P2PSocketHostTcpBase::OnPacket(const std::vector<char>& data) {
void P2PSocketHostTcpBase::Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) {
+ uint64_t packet_id) {
if (!socket_) {
// The Send message may be sent after the an OnError message was
// sent by hasn't been processed the renderer.
@@ -504,7 +507,7 @@ P2PSocketHostTcp::~P2PSocketHostTcp() {
int P2PSocketHostTcp::ProcessInput(char* input, int input_len) {
if (input_len < kPacketHeaderSize)
return 0;
- int packet_size = base::NetToHost16(*reinterpret_cast<uint16*>(input));
+ int packet_size = base::NetToHost16(*reinterpret_cast<uint16_t*>(input));
if (input_len < packet_size + kPacketHeaderSize)
return 0;
@@ -522,7 +525,7 @@ void P2PSocketHostTcp::DoSend(const net::IPEndPoint& to,
int size = kPacketHeaderSize + data.size();
scoped_refptr<net::DrainableIOBuffer> buffer =
new net::DrainableIOBuffer(new net::IOBuffer(size), size);
- *reinterpret_cast<uint16*>(buffer->data()) = base::HostToNet16(data.size());
+ *reinterpret_cast<uint16_t*>(buffer->data()) = base::HostToNet16(data.size());
memcpy(buffer->data() + kPacketHeaderSize, &data[0], data.size());
packet_processing_helpers::ApplyPacketOptions(
@@ -616,11 +619,12 @@ int P2PSocketHostStunTcp::GetExpectedPacketSize(
const char* data, int len, int* pad_bytes) {
DCHECK_LE(kTurnChannelDataHeaderSize, len);
// Both stun and turn had length at offset 2.
- int packet_size = base::NetToHost16(*reinterpret_cast<const uint16*>(
- data + kPacketLengthOffset));
+ int packet_size = base::NetToHost16(
+ *reinterpret_cast<const uint16_t*>(data + kPacketLengthOffset));
// Get packet type (STUN or TURN).
- uint16 msg_type = base::NetToHost16(*reinterpret_cast<const uint16*>(data));
+ uint16_t msg_type =
+ base::NetToHost16(*reinterpret_cast<const uint16_t*>(data));
*pad_bytes = 0;
// Add heder length to packet length.
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.h b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.h
index 4c2bb313f93..fb4b9957bf9 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TCP_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TCP_H_
+#include <stdint.h>
+
#include <queue>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -43,7 +46,7 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
void Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) override;
+ uint64_t packet_id) override;
P2PSocketHost* AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) override;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.cc b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.cc
index 0976b22ad2b..dc49bfdca9f 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.cc
@@ -120,7 +120,7 @@ void P2PSocketHostTcpServer::OnAccepted(int result) {
void P2PSocketHostTcpServer::Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) {
+ uint64_t packet_id) {
NOTREACHED();
OnError();
}
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.h b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.h
index df2053224fa..c709177e613 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TCP_SERVER_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TCP_SERVER_H_
+#include <stdint.h>
+
#include <map>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
@@ -39,7 +42,7 @@ class CONTENT_EXPORT P2PSocketHostTcpServer : public P2PSocketHost {
void Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) override;
+ uint64_t packet_id) override;
P2PSocketHost* AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) override;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc
index 64b420b8b8b..e11c0c07d51 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
+#include <stdint.h>
+
#include <list>
#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
@@ -95,8 +97,9 @@ class P2PSocketHostTcpServerTest : public testing::Test {
new P2PSocketHostTcpServer(&sender_, 0, P2P_SOCKET_TCP_CLIENT));
socket_host_->socket_.reset(socket_);
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSocketCreated::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
P2PHostAndIPEndPoint dest;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
index cd5a9093aa7..59aa336b927 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
@@ -4,8 +4,12 @@
#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
+#include "base/macros.h"
#include "base/sys_byteorder.h"
#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
#include "net/socket/stream_socket.h"
@@ -26,8 +30,9 @@ class P2PSocketHostTcpTestBase : public testing::Test {
}
void SetUp() override {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSocketCreated::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
if (socket_type_ == P2P_SOCKET_TCP_CLIENT) {
@@ -53,7 +58,7 @@ class P2PSocketHostTcpTestBase : public testing::Test {
std::string IntToSize(int size) {
std::string result;
- uint16 size16 = base::HostToNet16(size);
+ uint16_t size16 = base::HostToNet16(size);
result.resize(sizeof(size16));
memcpy(&result[0], &size16, sizeof(size16));
return result;
@@ -84,8 +89,9 @@ class P2PSocketHostStunTcpTest : public P2PSocketHostTcpTestBase {
// Verify that we can send STUN message and that they are formatted
// properly.
TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(3)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
@@ -116,8 +122,9 @@ TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
// Verify that we can receive STUN messages from the socket, and that
// the messages are parsed properly.
TEST_F(P2PSocketHostTcpTest, ReceiveStun) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(3)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
@@ -164,8 +171,8 @@ TEST_F(P2PSocketHostTcpTest, ReceiveStun) {
// Verify that we can't send data before we've received STUN response
// from the other side.
TEST_F(P2PSocketHostTcpTest, SendDataNoAuth) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
+ EXPECT_CALL(sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnError::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
rtc::PacketOptions options;
@@ -187,8 +194,9 @@ TEST_F(P2PSocketHostTcpTest, SendAfterStunRequest) {
received_data.append(IntToSize(request_packet.size()));
received_data.append(request_packet.begin(), request_packet.end());
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
@@ -213,8 +221,9 @@ TEST_F(P2PSocketHostTcpTest, AsyncWrites) {
socket_->set_async_write(true);
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(2)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
@@ -247,8 +256,9 @@ TEST_F(P2PSocketHostTcpTest, SendDataWithPacketOptions) {
received_data.append(IntToSize(request_packet.size()));
received_data.append(request_packet.begin(), request_packet.end());
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
@@ -260,7 +270,7 @@ TEST_F(P2PSocketHostTcpTest, SendDataWithPacketOptions) {
std::vector<char> packet;
CreateRandomPacket(&packet);
// Make it a RTP packet.
- *reinterpret_cast<uint16*>(&*packet.begin()) = base::HostToNet16(0x8000);
+ *reinterpret_cast<uint16_t*>(&*packet.begin()) = base::HostToNet16(0x8000);
socket_host_->Send(dest_.ip_address, packet, options, 0);
std::string expected_data;
@@ -273,8 +283,9 @@ TEST_F(P2PSocketHostTcpTest, SendDataWithPacketOptions) {
// Verify that we can send STUN message and that they are formatted
// properly.
TEST_F(P2PSocketHostStunTcpTest, SendStunNoAuth) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(3)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
@@ -302,8 +313,9 @@ TEST_F(P2PSocketHostStunTcpTest, SendStunNoAuth) {
// Verify that we can receive STUN messages from the socket, and that
// the messages are parsed properly.
TEST_F(P2PSocketHostStunTcpTest, ReceiveStun) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(3)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
@@ -347,8 +359,8 @@ TEST_F(P2PSocketHostStunTcpTest, ReceiveStun) {
// Verify that we can't send data before we've received STUN response
// from the other side.
TEST_F(P2PSocketHostStunTcpTest, SendDataNoAuth) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
+ EXPECT_CALL(sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnError::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
rtc::PacketOptions options;
@@ -365,8 +377,9 @@ TEST_F(P2PSocketHostStunTcpTest, AsyncWrites) {
socket_->set_async_write(true);
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(2)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.cc b/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.cc
index cc37c022082..dce2bd60ddb 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.cc
@@ -4,16 +4,19 @@
#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
+#include <stddef.h>
+
+#include "base/logging.h"
#include "base/sys_byteorder.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
const int kStunHeaderSize = 20;
-const uint16 kStunBindingRequest = 0x0001;
-const uint16 kStunBindingResponse = 0x0102;
-const uint16 kStunBindingError = 0x0111;
-const uint32 kStunMagicCookie = 0x2112A442;
+const uint16_t kStunBindingRequest = 0x0001;
+const uint16_t kStunBindingResponse = 0x0102;
+const uint16_t kStunBindingError = 0x0111;
+const uint32_t kStunMagicCookie = 0x2112A442;
MockIPCSender::MockIPCSender() { }
MockIPCSender::~MockIPCSender() { }
@@ -103,12 +106,12 @@ void FakeSocket::DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len,
callback.Run(buf_len);
}
-int FakeSocket::SetReceiveBufferSize(int32 size) {
+int FakeSocket::SetReceiveBufferSize(int32_t size) {
NOTIMPLEMENTED();
return net::ERR_NOT_IMPLEMENTED;
}
-int FakeSocket::SetSendBufferSize(int32 size) {
+int FakeSocket::SetSendBufferSize(int32_t size) {
NOTIMPLEMENTED();
return net::ERR_NOT_IMPLEMENTED;
}
@@ -176,6 +179,11 @@ void FakeSocket::GetConnectionAttempts(net::ConnectionAttempts* out) const {
out->clear();
}
+int64_t FakeSocket::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
void CreateRandomPacket(std::vector<char>* packet) {
size_t size = kStunHeaderSize + rand() % 1000;
packet->resize(size);
@@ -187,12 +195,12 @@ void CreateRandomPacket(std::vector<char>* packet) {
(*packet)[0] = (*packet)[0] | 0x80;
}
-static void CreateStunPacket(std::vector<char>* packet, uint16 type) {
+static void CreateStunPacket(std::vector<char>* packet, uint16_t type) {
CreateRandomPacket(packet);
- *reinterpret_cast<uint16*>(&*packet->begin()) = base::HostToNet16(type);
- *reinterpret_cast<uint16*>(&*packet->begin() + 2) =
+ *reinterpret_cast<uint16_t*>(&*packet->begin()) = base::HostToNet16(type);
+ *reinterpret_cast<uint16_t*>(&*packet->begin() + 2) =
base::HostToNet16(packet->size() - kStunHeaderSize);
- *reinterpret_cast<uint32*>(&*packet->begin() + 4) =
+ *reinterpret_cast<uint32_t*>(&*packet->begin() + 4) =
base::HostToNet32(kStunMagicCookie);
}
@@ -208,7 +216,7 @@ void CreateStunError(std::vector<char>* packet) {
CreateStunPacket(packet, kStunBindingError);
}
-net::IPEndPoint ParseAddress(const std::string& ip_str, uint16 port) {
+net::IPEndPoint ParseAddress(const std::string& ip_str, uint16_t port) {
net::IPAddressNumber ip;
EXPECT_TRUE(net::ParseIPLiteralToNumber(ip_str, &ip));
return net::IPEndPoint(ip, port);
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.h b/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.h
index 17172e6f79c..77a8319b263 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_test_utils.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
+#include <stdint.h>
+
#include <vector>
#include "content/common/p2p_messages.h"
@@ -16,9 +18,9 @@
const char kTestLocalIpAddress[] = "123.44.22.4";
const char kTestIpAddress1[] = "123.44.22.31";
-const uint16 kTestPort1 = 234;
+const uint16_t kTestPort1 = 234;
const char kTestIpAddress2[] = "133.11.22.33";
-const uint16 kTestPort2 = 543;
+const uint16_t kTestPort2 = 543;
class MockIPCSender : public IPC::Sender {
public:
@@ -47,8 +49,8 @@ class FakeSocket : public net::StreamSocket {
int Write(net::IOBuffer* buf,
int buf_len,
const net::CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
int Connect(const net::CompletionCallback& callback) override;
void Disconnect() override;
bool IsConnected() const override;
@@ -67,6 +69,7 @@ class FakeSocket : public net::StreamSocket {
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const net::ConnectionAttempts& attempts) override {
}
+ int64_t GetTotalReceivedBytes() const override;
private:
void DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len,
@@ -95,7 +98,7 @@ void CreateStunRequest(std::vector<char>* packet);
void CreateStunResponse(std::vector<char>* packet);
void CreateStunError(std::vector<char>* packet);
-net::IPEndPoint ParseAddress(const std::string& ip_str, uint16 port);
+net::IPEndPoint ParseAddress(const std::string& ip_str, uint16_t port);
MATCHER_P(MatchMessage, type, "") {
return arg->type() == type;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_throttler.cc b/chromium/content/browser/renderer_host/p2p/socket_host_throttler.cc
index 0ef92eb8a6f..daefbcc797d 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_throttler.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_throttler.cc
@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "content/browser/renderer_host/p2p/socket_host_throttler.h"
+
+#include <utility>
+
#include "third_party/webrtc/base/ratelimiter.h"
#include "third_party/webrtc/base/timing.h"
@@ -24,7 +27,7 @@ P2PMessageThrottler::~P2PMessageThrottler() {
}
void P2PMessageThrottler::SetTiming(scoped_ptr<rtc::Timing> timing) {
- timing_ = timing.Pass();
+ timing_ = std::move(timing);
}
void P2PMessageThrottler::SetSendIceBandwidth(int bandwidth_kbps) {
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_throttler.h b/chromium/content/browser/renderer_host/p2p/socket_host_throttler.h
index a28a5885621..0ab1e9dbda8 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_throttler.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_throttler.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_THROTTLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_THROTTLER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc b/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc
index 5137972ebb0..0dbfcec4265 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc
@@ -10,6 +10,7 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/p2p/socket_host_throttler.h"
#include "content/common/p2p_messages.h"
#include "content/public/browser/content_browser_client.h"
@@ -75,7 +76,7 @@ P2PSocketHostUdp::PendingPacket::PendingPacket(
const net::IPEndPoint& to,
const std::vector<char>& content,
const rtc::PacketOptions& options,
- uint64 id)
+ uint64_t id)
: to(to),
data(new net::IOBuffer(content.size())),
size(content.size()),
@@ -133,7 +134,8 @@ bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
int result = socket_->Listen(local_address);
if (result < 0) {
- LOG(ERROR) << "bind() failed: " << result;
+ LOG(ERROR) << "bind() to " << local_address.ToString()
+ << " failed: " << result;
OnError();
return false;
}
@@ -232,7 +234,7 @@ void P2PSocketHostUdp::HandleReadResult(int result) {
void P2PSocketHostUdp::Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) {
+ uint64_t packet_id) {
if (!socket_) {
// The Send message may be sent after the an OnError message was
// sent by hasn't been processed the renderer.
@@ -291,50 +293,45 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) {
}
}
- uint64 tick_received = base::TimeTicks::Now().ToInternalValue();
+ base::TimeTicks send_time = base::TimeTicks::Now();
packet_processing_helpers::ApplyPacketOptions(
packet.data->data(), packet.size, packet.packet_options, 0);
- int result = socket_->SendTo(packet.data.get(),
- packet.size,
- packet.to,
- base::Bind(&P2PSocketHostUdp::OnSend,
- base::Unretained(this),
- packet.id,
- tick_received));
+ auto callback_binding =
+ base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this), packet.id,
+ packet.packet_options.packet_id, send_time);
+ int result = socket_->SendTo(packet.data.get(), packet.size, packet.to,
+ callback_binding);
// sendto() may return an error, e.g. if we've received an ICMP Destination
// Unreachable message. When this happens try sending the same packet again,
// and just drop it if it fails again.
if (IsTransientError(result)) {
- result = socket_->SendTo(packet.data.get(),
- packet.size,
- packet.to,
- base::Bind(&P2PSocketHostUdp::OnSend,
- base::Unretained(this),
- packet.id,
- tick_received));
+ result = socket_->SendTo(packet.data.get(), packet.size, packet.to,
+ callback_binding);
}
if (result == net::ERR_IO_PENDING) {
send_pending_ = true;
} else {
- HandleSendResult(packet.id, tick_received, result);
+ HandleSendResult(packet.id, packet.packet_options.packet_id, send_time,
+ result);
}
if (dump_outgoing_rtp_packet_)
DumpRtpPacket(packet.data->data(), packet.size, false);
}
-void P2PSocketHostUdp::OnSend(uint64 packet_id,
- uint64 tick_received,
+void P2PSocketHostUdp::OnSend(uint64_t packet_id,
+ int32_t transport_sequence_number,
+ base::TimeTicks send_time,
int result) {
DCHECK(send_pending_);
DCHECK_NE(result, net::ERR_IO_PENDING);
send_pending_ = false;
- HandleSendResult(packet_id, tick_received, result);
+ HandleSendResult(packet_id, transport_sequence_number, send_time, result);
// Send next packets if we have them waiting in the buffer.
while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) {
@@ -345,8 +342,9 @@ void P2PSocketHostUdp::OnSend(uint64 packet_id,
}
}
-void P2PSocketHostUdp::HandleSendResult(uint64 packet_id,
- uint64 tick_received,
+void P2PSocketHostUdp::HandleSendResult(uint64_t packet_id,
+ int32_t transport_sequence_number,
+ base::TimeTicks send_time,
int result) {
TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id,
"result", result);
@@ -363,13 +361,12 @@ void P2PSocketHostUdp::HandleSendResult(uint64 packet_id,
// UMA to track the histograms from 1ms to 1 sec for how long a packet spends
// in the browser process.
- UMA_HISTOGRAM_TIMES(
- "WebRTC.SystemSendPacketDuration_UDP" /* name */,
- base::TimeTicks::Now() -
- base::TimeTicks::FromInternalValue(tick_received) /* sample */);
+ UMA_HISTOGRAM_TIMES("WebRTC.SystemSendPacketDuration_UDP" /* name */,
+ base::TimeTicks::Now() - send_time /* sample */);
- message_sender_->Send(
- new P2PMsg_OnSendComplete(id_, P2PSendPacketMetrics(packet_id)));
+ message_sender_->Send(new P2PMsg_OnSendComplete(
+ id_,
+ P2PSendPacketMetrics(packet_id, transport_sequence_number, send_time)));
}
P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection(
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_udp.h b/chromium/content/browser/renderer_host/p2p/socket_host_udp.h
index 1839663637b..93fb6335458 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_udp.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_udp.h
@@ -5,11 +5,15 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_UDP_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_UDP_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <set>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -17,6 +21,7 @@
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
#include "net/base/ip_endpoint.h"
+#include "net/udp/diff_serv_code_point.h"
#include "net/udp/udp_server_socket.h"
#include "third_party/webrtc/base/asyncpacketsocket.h"
@@ -37,7 +42,7 @@ class CONTENT_EXPORT P2PSocketHostUdp : public P2PSocketHost {
void Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
- uint64 packet_id) override;
+ uint64_t packet_id) override;
P2PSocketHost* AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) override;
@@ -52,13 +57,13 @@ class CONTENT_EXPORT P2PSocketHostUdp : public P2PSocketHost {
PendingPacket(const net::IPEndPoint& to,
const std::vector<char>& content,
const rtc::PacketOptions& options,
- uint64 id);
+ uint64_t id);
~PendingPacket();
net::IPEndPoint to;
scoped_refptr<net::IOBuffer> data;
int size;
rtc::PacketOptions packet_options;
- uint64 id;
+ uint64_t id;
};
void OnError();
@@ -70,8 +75,14 @@ class CONTENT_EXPORT P2PSocketHostUdp : public P2PSocketHost {
void HandleReadResult(int result);
void DoSend(const PendingPacket& packet);
- void OnSend(uint64 packet_id, uint64 tick_received, int result);
- void HandleSendResult(uint64 packet_id, uint64 tick_received, int result);
+ void OnSend(uint64_t packet_id,
+ int32_t transport_sequence_number,
+ base::TimeTicks send_time,
+ int result);
+ void HandleSendResult(uint64_t packet_id,
+ int32_t transport_sequence_number,
+ base::TimeTicks send_time,
+ int result);
scoped_ptr<net::DatagramServerSocket> socket_;
scoped_refptr<net::IOBuffer> recv_buffer_;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 5d67a24fc33..7bf0944514b 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -4,7 +4,9 @@
#include "content/browser/renderer_host/p2p/socket_host_udp.h"
+#include <stdint.h>
#include <deque>
+#include <utility>
#include <vector>
#include "base/logging.h"
@@ -95,9 +97,9 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
return buf_len;
}
- int SetReceiveBufferSize(int32 size) override { return net::OK; }
+ int SetReceiveBufferSize(int32_t size) override { return net::OK; }
- int SetSendBufferSize(int32 size) override { return net::OK; }
+ int SetSendBufferSize(int32_t size) override { return net::OK; }
void ReceivePacket(const net::IPEndPoint& address, std::vector<char> data) {
if (!recv_callback_.is_null()) {
@@ -129,7 +131,7 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
return net::ERR_NOT_IMPLEMENTED;
}
- int SetMulticastInterface(uint32 interface_index) override {
+ int SetMulticastInterface(uint32_t interface_index) override {
NOTIMPLEMENTED();
return net::ERR_NOT_IMPLEMENTED;
}
@@ -170,8 +172,9 @@ namespace content {
class P2PSocketHostUdpTest : public testing::Test {
protected:
void SetUp() override {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSocketCreated::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_host_.reset(new P2PSocketHostUdp(&sender_, 0, &throttler_));
@@ -185,7 +188,7 @@ class P2PSocketHostUdpTest : public testing::Test {
dest2_ = ParseAddress(kTestIpAddress2, kTestPort2);
scoped_ptr<rtc::Timing> timing(new FakeTiming());
- throttler_.SetTiming(timing.Pass());
+ throttler_.SetTiming(std::move(timing));
}
P2PMessageThrottler throttler_;
@@ -203,8 +206,9 @@ class P2PSocketHostUdpTest : public testing::Test {
// Verify that we can send STUN messages before we receive anything
// from the other side.
TEST_F(P2PSocketHostUdpTest, SendStunNoAuth) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(3)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
@@ -230,8 +234,8 @@ TEST_F(P2PSocketHostUdpTest, SendStunNoAuth) {
// Verify that no data packets can be sent before STUN binding has
// finished.
TEST_F(P2PSocketHostUdpTest, SendDataNoAuth) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
+ EXPECT_CALL(sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnError::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
rtc::PacketOptions options;
@@ -254,8 +258,9 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunRequest) {
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
rtc::PacketOptions options;
@@ -279,8 +284,9 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunResponse) {
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
rtc::PacketOptions options;
@@ -307,8 +313,8 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunResponseDifferentHost) {
rtc::PacketOptions options;
std::vector<char> packet;
CreateRandomPacket(&packet);
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
+ EXPECT_CALL(sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnError::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_host_->Send(dest2_, packet, options, 0);
}
@@ -316,8 +322,9 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunResponseDifferentHost) {
// Verify throttler not allowing unlimited sending of ICE messages to
// any destination.
TEST_F(P2PSocketHostUdpTest, ThrottleAfterLimit) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(2)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
@@ -345,8 +352,9 @@ TEST_F(P2PSocketHostUdpTest, ThrottleAfterLimitAfterReceive) {
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_->ReceivePacket(dest1_, request_packet);
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ EXPECT_CALL(
+ sender_,
+ Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSendComplete::ID))))
.Times(4)
.WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_unittest.cc b/chromium/content/browser/renderer_host/p2p/socket_host_unittest.cc
index 7e9393fd96c..c92e9d75630 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/p2p/socket_host.h"
+#include <stddef.h>
+
#include <vector>
#include "base/memory/scoped_ptr.h"
diff --git a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
index d8514347eb6..ca8c6ce9c8c 100644
--- a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
+++ b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
@@ -7,11 +7,12 @@
#include <map>
#include <string>
+#include <utility>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
@@ -78,7 +79,7 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost {
bool IsPotentiallySecurePluginContext(PP_Instance instance);
void set_plugin_process(base::Process process) {
- plugin_process_ = process.Pass();
+ plugin_process_ = std::move(process);
}
bool external_plugin() const { return external_plugin_; }
diff --git a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_test.h b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_test.h
index 3f375eea107..b7ca9d47017 100644
--- a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_test.h
+++ b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_test.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_BROWSER_PPAPI_HOST_TEST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_BROWSER_PPAPI_HOST_TEST_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "ppapi/proxy/resource_message_test_sink.h"
diff --git a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
index f52a2016aad..9ad8d5b8ce3 100644
--- a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
+++ b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
@@ -4,6 +4,9 @@
#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
+#include <stddef.h>
+#include <utility>
+
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h"
#include "content/browser/renderer_host/pepper/pepper_file_io_host.h"
@@ -134,7 +137,7 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost(
scoped_ptr<PepperPrintSettingsManager> manager(
new PepperPrintSettingsManagerImpl());
return scoped_ptr<ResourceHost>(new PepperPrintingHost(
- host_->GetPpapiHost(), instance, resource, manager.Pass()));
+ host_->GetPpapiHost(), instance, resource, std::move(manager)));
}
case PpapiHostMsg_TrueTypeFont_Create::ID: {
SerializedTrueTypeFontDesc desc;
@@ -230,8 +233,8 @@ ContentBrowserPepperHostFactory::CreateAcceptedTCPSocket(
if (!CanCreateSocket())
return scoped_ptr<ResourceHost>();
scoped_refptr<ResourceMessageFilter> tcp_socket(
- new PepperTCPSocketMessageFilter(
- host_, instance, version, socket.Pass()));
+ new PepperTCPSocketMessageFilter(host_, instance, version,
+ std::move(socket)));
return scoped_ptr<ResourceHost>(
new MessageFilterHost(host_->GetPpapiHost(), instance, 0, tcp_socket));
}
diff --git a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
index dffa7fe83db..c8e98fa0d45 100644
--- a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
+++ b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_CONTENT_BROWSER_PEPPER_HOST_FACTORY_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/socket/tcp_socket.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc
index e2c909c9ae5..5a4db2304c5 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc
@@ -4,6 +4,10 @@
#include "content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/values.h"
#include "content/common/font_list.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h b/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h
index 643be703b9d..b438e003d93 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROWSER_FONT_SINGLETON_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROWSER_FONT_SINGLETON_HOST_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "ppapi/host/resource_host.h"
namespace content {
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc b/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc
index d4913da4ce8..d97070af391 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h"
+#include <string.h>
+
#include "base/files/file_path.h"
#include "base/files/file_util_proxy.h"
#include "content/browser/child_process_security_policy_impl.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h b/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h
index f3c3c947d57..2a95284f05f 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_EXTERNAL_FILE_REF_BACKEND_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_EXTERNAL_FILE_REF_BACKEND_H_
+#include <stdint.h>
+
#include <string>
#include "base/files/file.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/task_runner.h"
#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
index 78228911867..faead267821 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_file_io_host.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
@@ -91,7 +93,7 @@ void DidOpenFile(base::WeakPtr<PepperFileIOHost> file_host,
base::File file,
const base::Closure& on_close_callback) {
if (file_host) {
- callback.Run(file.Pass(), on_close_callback);
+ callback.Run(std::move(file), on_close_callback);
} else {
BrowserThread::PostTaskAndReply(
BrowserThread::FILE,
@@ -284,7 +286,7 @@ void PepperFileIOHost::DidOpenInternalFile(
DCHECK(!file_.IsValid());
base::File::Error error =
file.IsValid() ? base::File::FILE_OK : file.error_details();
- file_.SetFile(file.Pass());
+ file_.SetFile(std::move(file));
OnOpenProxyCallback(reply_context, error);
}
@@ -390,7 +392,7 @@ void PepperFileIOHost::DidOpenQuotaFile(
DCHECK(!file_.IsValid());
DCHECK(file.IsValid());
max_written_offset_ = max_written_offset;
- file_.SetFile(file.Pass());
+ file_.SetFile(std::move(file));
OnOpenProxyCallback(reply_context, base::File::FILE_OK);
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.h b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.h
index bae9a54b6cf..90de1da7b43 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.h
@@ -5,12 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_IO_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_IO_HOST_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/files/file.h"
#include "base/files/file_proxy.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "ipc/ipc_listener.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.h b/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.h
index 5f6d11eb119..cd8f67b71f0 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_REF_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_REF_HOST_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "ppapi/c/pp_file_info.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
index bdb25140070..70e29a73411 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
@@ -233,7 +233,7 @@ void PepperFileSystemBrowserHost::OpenFileSystemComplete(
const GURL& root,
const std::string& /* unused */,
base::File::Error error) {
- int32 pp_error = ppapi::FileErrorToPepperError(error);
+ int32_t pp_error = ppapi::FileErrorToPepperError(error);
if (pp_error == PP_OK) {
opened_ = true;
root_url_ = root;
@@ -319,7 +319,7 @@ void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete(
ppapi::host::ReplyMessageContext reply_context,
const std::string& fsid,
base::File::Error error) {
- int32 pp_error = ppapi::FileErrorToPepperError(error);
+ int32_t pp_error = ppapi::FileErrorToPepperError(error);
if (pp_error == PP_OK)
opened_ = true;
SendReplyForIsolatedFileSystem(reply_context, fsid, pp_error);
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
index 669adde14c7..bf56a1ad2f6 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
@@ -5,12 +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 <stdint.h>
+
#include <queue>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/pepper/quota_reservation.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host_unittest.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host_unittest.cc
index ccc9c610d21..bbc5a14b0a6 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host_unittest.cc
@@ -6,7 +6,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_test.h"
#include "ppapi/c/pp_instance.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
index 48da55d5ae7..3059dd7780e 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
@@ -134,7 +136,7 @@ int32_t PepperFlashFileMessageFilter::OnOpenFile(
}
IPC::PlatformFileForTransit transit_file =
- IPC::TakeFileHandleForProcess(file.Pass(), plugin_process_.Handle());
+ IPC::TakeFileHandleForProcess(std::move(file), plugin_process_.Handle());
ppapi::host::ReplyMessageContext reply_context =
context->MakeReplyMessageContext();
reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle(
@@ -256,7 +258,7 @@ int32_t PepperFlashFileMessageFilter::OnCreateTemporaryFile(
return ppapi::FileErrorToPepperError(file.error_details());
IPC::PlatformFileForTransit transit_file =
- IPC::TakeFileHandleForProcess(file.Pass(), plugin_process_.Handle());
+ IPC::TakeFileHandleForProcess(std::move(file), plugin_process_.Handle());
ppapi::host::ReplyMessageContext reply_context =
context->MakeReplyMessageContext();
reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle(
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h
index fa6bb6ff9b8..a488a558e12 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_FILE_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_FILE_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
#include "ppapi/c/pp_instance.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.h b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.h
index 8d6ee7346fa..963f7901340 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.h
@@ -5,7 +5,10 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_GAMEPAD_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_GAMEPAD_HOST_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/gamepad/gamepad_consumer.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
index ca94c7fa7a2..a325e7a3914 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
#include <string.h>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "content/browser/gamepad/gamepad_test_helpers.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_test.h"
#include "content/browser/renderer_host/pepper/pepper_gamepad_host.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
index 3789ffa8593..c841981c21b 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h"
+#include <stddef.h>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
index a5321845b8a..42f75696e13 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
@@ -5,11 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_HOST_RESOLVER_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_HOST_RESOLVER_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/common/process_type.h"
#include "ppapi/c/pp_instance.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc b/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
index ddab7c00822..1f9d27bafa0 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h"
+#include <string.h>
+
#include <string>
#include "base/callback.h"
@@ -170,9 +172,11 @@ int32_t PepperInternalFileRefBackend::Query(
GetFileSystemContext()->operation_runner()->GetMetadata(
GetFileSystemURL(),
+ storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY |
+ storage::FileSystemOperation::GET_METADATA_FIELD_SIZE |
+ storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED,
base::Bind(&PepperInternalFileRefBackend::GetMetadataComplete,
- weak_factory_.GetWeakPtr(),
- reply_context));
+ weak_factory_.GetWeakPtr(), reply_context));
return PP_OK_COMPLETIONPENDING;
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h b/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
index e210763c810..95734fe723a 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_INTERNAL_FILE_REF_BACKEND_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_INTERNAL_FILE_REF_BACKEND_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_lookup_request.h b/chromium/content/browser/renderer_host/pepper/pepper_lookup_request.h
index b36bd5e2f4e..ecbf6468407 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_lookup_request.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_lookup_request.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_LOOKUP_REQUEST_H_
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_message_filter.h
index 02a89adf016..04cd1208275 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_message_filter.h
@@ -7,8 +7,8 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_message_filter.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc
index bc5795b6e41..2d07e2a54f6 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_network_monitor_host.h"
+#include <stddef.h>
+
#include "base/task_runner_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
@@ -34,7 +36,7 @@ bool CanUseNetworkMonitor(bool external_plugin,
scoped_ptr<net::NetworkInterfaceList> GetNetworkList() {
scoped_ptr<net::NetworkInterfaceList> list(new net::NetworkInterfaceList());
net::GetNetworkList(list.get(), net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
- return list.Pass();
+ return list;
}
} // namespace
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
index 2225a938df6..ef1b305eeae 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_NETWORK_MONITOR_HOST_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "net/base/network_change_notifier.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.h b/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
index eddbc89a1bd..0992c9fc68d 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_NETWORK_PROXY_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_NETWORK_PROXY_HOST_H_
+#include <stdint.h>
+
#include <queue>
#include <string>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "net/proxy/proxy_service.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.h b/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.h
index 9199e72655b..8c53edef760 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_PRINT_SETTINGS_MANAGER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_PRINT_SETTINGS_MANAGER_H_
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "ppapi/c/dev/pp_print_settings_dev.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_printing_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_printing_host.cc
index 047f1203d72..5f9fcaabdff 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_printing_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_printing_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_printing_host.h"
+#include <utility>
+
#include "ppapi/c/dev/pp_print_settings_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
@@ -19,7 +21,7 @@ PepperPrintingHost::PepperPrintingHost(
PP_Resource resource,
scoped_ptr<PepperPrintSettingsManager> print_settings_manager)
: ResourceHost(host, instance, resource),
- print_settings_manager_(print_settings_manager.Pass()),
+ print_settings_manager_(std::move(print_settings_manager)),
weak_factory_(this) {}
PepperPrintingHost::~PepperPrintingHost() {}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_printing_host.h b/chromium/content/browser/renderer_host/pepper/pepper_printing_host.h
index fb2536d9945..fc022f18239 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_printing_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_printing_host.h
@@ -5,7 +5,10 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_PRINTING_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_PRINTING_HOST_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_printing_host_unittest.cc b/chromium/content/browser/renderer_host/pepper/pepper_printing_host_unittest.cc
index e61f75f4a76..b54ec0473a7 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_printing_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_printing_host_unittest.cc
@@ -2,9 +2,14 @@
// 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/pepper_printing_host.h"
+
+#include <stdint.h>
+#include <utility>
+
+#include "base/macros.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_test.h"
#include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
-#include "content/browser/renderer_host/pepper/pepper_printing_host.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
@@ -79,14 +84,12 @@ TEST_F(PepperPrintingHostTest, GetDefaultPrintSettings) {
scoped_ptr<PepperPrintSettingsManager> manager(
new MockPepperPrintSettingsManager(expected_settings));
PepperPrintingHost printing(GetBrowserPpapiHost()->GetPpapiHost(),
- pp_instance,
- pp_resource,
- manager.Pass());
+ pp_instance, pp_resource, std::move(manager));
// Simulate a message being received.
ppapi::proxy::ResourceMessageCallParams call_params(pp_resource, 1);
ppapi::host::HostMessageContext context(call_params);
- int32 result = printing.OnResourceMessageReceived(
+ int32_t result = printing.OnResourceMessageReceived(
PpapiHostMsg_Printing_GetDefaultPrintSettings(), &context);
EXPECT_EQ(PP_OK_COMPLETIONPENDING, result);
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc b/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
index 1e03a8470d5..da171c23420 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
@@ -4,15 +4,20 @@
#include "content/browser/renderer_host/pepper/pepper_renderer_connection.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
-#include "content/common/frame_messages.h"
-#include "content/common/pepper_renderer_instance_data.h"
#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/common/frame_messages.h"
+#include "content/common/pepper_renderer_instance_data.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "ipc/ipc_message_macros.h"
@@ -25,9 +30,8 @@ namespace content {
namespace {
-const uint32 kFilteredMessageClasses[] = {
- PpapiMsgStart,
- FrameMsgStart,
+const uint32_t kFilteredMessageClasses[] = {
+ PpapiMsgStart, FrameMsgStart,
};
// Responsible for creating the pending resource hosts, holding their IDs until
@@ -79,7 +83,7 @@ void PendingHostCreator::AddPendingResourceHost(
size_t index,
scoped_ptr<ppapi::host::ResourceHost> resource_host) {
pending_resource_host_ids_[index] =
- host_->GetPpapiHost()->AddPendingResourceHost(resource_host.Pass());
+ host_->GetPpapiHost()->AddPendingResourceHost(std::move(resource_host));
}
PendingHostCreator::~PendingHostCreator() {
@@ -215,7 +219,7 @@ void PepperRendererConnection::OnMsgCreateResourceHostsFromHost(
}
if (resource_host.get())
- creator->AddPendingResourceHost(i, resource_host.Pass());
+ creator->AddPendingResourceHost(i, std::move(resource_host));
}
// Note: All of the pending host IDs that were added as part of this
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.h b/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.h
index 109da1f2856..37c5a07ffe4 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.h
@@ -7,8 +7,8 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_message_filter.h"
#include "ppapi/c/pp_instance.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc b/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc
index 4b70dedd2c8..94ee8d71c81 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_util.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
@@ -33,7 +34,7 @@ SocketPermissionRequest CreateSocketPermissionRequest(
const PP_NetAddress_Private& net_addr) {
std::string host =
ppapi::NetAddressPrivateImpl::DescribeNetAddress(net_addr, false);
- uint16 port = 0;
+ uint16_t port = 0;
std::vector<unsigned char> address;
ppapi::NetAddressPrivateImpl::NetAddressToIPEndPoint(
net_addr, &address, &port);
@@ -145,7 +146,7 @@ const unsigned char kIPv6Empty[] =
const unsigned char kIPv6Loopback[] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-bool isLoopbackAddress(const net::IPAddressNumber& address) {
+bool IsLoopbackAddress(const net::IPAddressNumber& address) {
if (address.size() == net::kIPv4AddressSize) {
// The entire IPv4 subnet 127.0.0.0/8 is for loopback. See RFC3330.
return address[0] == 0x7f;
@@ -157,7 +158,7 @@ bool isLoopbackAddress(const net::IPAddressNumber& address) {
return false;
}
-std::string addressToFirewallString(const net::IPAddressNumber& address) {
+std::string AddressToFirewallString(const net::IPAddressNumber& address) {
if (address.empty()) {
return std::string();
}
@@ -180,11 +181,11 @@ std::string addressToFirewallString(const net::IPAddressNumber& address) {
void OpenFirewallHole(const net::IPEndPoint& address,
chromeos::FirewallHole::PortType type,
FirewallHoleOpenCallback callback) {
- if (isLoopbackAddress(address.address())) {
+ if (IsLoopbackAddress(address.address())) {
callback.Run(nullptr);
return;
}
- std::string address_string = addressToFirewallString(address.address());
+ std::string address_string = AddressToFirewallString(address.address());
chromeos::FirewallHole::Open(type, address.port(), address_string, callback);
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.h b/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.h
index 6061cc349f4..ce33b0289c6 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SOCKET_UTILS_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SOCKET_UTILS_H_
+#include "build/build_config.h"
#include "content/public/common/socket_permission_request.h"
#include "ppapi/c/pp_stdint.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
index 93e18041e9b..e342c233ba1 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
@@ -4,9 +4,12 @@
#include "content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
@@ -170,7 +173,7 @@ void PepperTCPServerSocketMessageFilter::DoListen(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
net::IPAddressNumber address;
- uint16 port;
+ uint16_t port;
if (state_ != STATE_BEFORE_LISTENING ||
!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
SendListenError(context, PP_ERROR_FAILED);
@@ -312,12 +315,13 @@ void PepperTCPServerSocketMessageFilter::OnAcceptCompleted(
scoped_ptr<ppapi::host::ResourceHost> host =
factory_->CreateAcceptedTCPSocket(instance_,
ppapi::TCP_SOCKET_VERSION_PRIVATE,
- accepted_socket_.Pass());
+ std::move(accepted_socket_));
if (!host) {
SendAcceptError(context, PP_ERROR_NOSPACE);
return;
}
- int pending_resource_id = ppapi_host_->AddPendingResourceHost(host.Pass());
+ int pending_resource_id =
+ ppapi_host_->AddPendingResourceHost(std::move(host));
if (pending_resource_id) {
SendAcceptReply(
context, PP_OK, pending_resource_id, local_addr, remote_addr);
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
index eded1beb8be..f633ccb023f 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
@@ -5,10 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SERVER_SOCKET_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SERVER_SOCKET_MESSAGE_FILTER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "net/base/ip_endpoint.h"
#include "net/socket/tcp_socket.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
deleted file mode 100644
index 16b19b23bb8..00000000000
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
+++ /dev/null
@@ -1,543 +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/pepper/pepper_tcp_socket.h"
-
-#include <string.h>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/strings/string_util.h"
-#include "content/browser/renderer_host/pepper/pepper_message_filter.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/io_buffer.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/cert/cert_verifier.h"
-#include "net/cert/x509_certificate.h"
-#include "net/dns/host_resolver.h"
-#include "net/dns/single_request_host_resolver.h"
-#include "net/socket/client_socket_factory.h"
-#include "net/socket/client_socket_handle.h"
-#include "net/socket/ssl_client_socket.h"
-#include "net/socket/tcp_client_socket.h"
-#include "ppapi/host/error_conversion.h"
-#include "ppapi/proxy/ppapi_messages.h"
-#include "ppapi/shared_impl/private/net_address_private_impl.h"
-#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
-#include "ppapi/shared_impl/socket_option_data.h"
-#include "ppapi/shared_impl/tcp_socket_shared.h"
-
-using ppapi::host::NetErrorToPepperError;
-using ppapi::NetAddressPrivateImpl;
-
-namespace content {
-
-PepperTCPSocket::PepperTCPSocket(PepperMessageFilter* manager,
- int32 routing_id,
- uint32 plugin_dispatcher_id,
- uint32 socket_id,
- bool private_api)
- : manager_(manager),
- routing_id_(routing_id),
- plugin_dispatcher_id_(plugin_dispatcher_id),
- socket_id_(socket_id),
- private_api_(private_api),
- connection_state_(BEFORE_CONNECT),
- end_of_file_reached_(false) {
- DCHECK(manager);
-}
-
-PepperTCPSocket::PepperTCPSocket(PepperMessageFilter* manager,
- int32 routing_id,
- uint32 plugin_dispatcher_id,
- uint32 socket_id,
- net::StreamSocket* socket,
- bool private_api)
- : manager_(manager),
- routing_id_(routing_id),
- plugin_dispatcher_id_(plugin_dispatcher_id),
- socket_id_(socket_id),
- private_api_(private_api),
- connection_state_(CONNECTED),
- end_of_file_reached_(false),
- socket_(socket) {
- DCHECK(manager);
-}
-
-PepperTCPSocket::~PepperTCPSocket() {
- // Make sure no further callbacks from socket_.
- if (socket_)
- socket_->Disconnect();
-}
-
-void PepperTCPSocket::Connect(const std::string& host, uint16_t port) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (connection_state_ != BEFORE_CONNECT) {
- SendConnectACKError(PP_ERROR_FAILED);
- return;
- }
-
- connection_state_ = CONNECT_IN_PROGRESS;
- net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port));
- resolver_.reset(
- new net::SingleRequestHostResolver(manager_->GetHostResolver()));
- int net_result = resolver_->Resolve(
- request_info,
- net::DEFAULT_PRIORITY,
- &address_list_,
- base::Bind(&PepperTCPSocket::OnResolveCompleted, base::Unretained(this)),
- net::BoundNetLog());
- if (net_result != net::ERR_IO_PENDING)
- OnResolveCompleted(net_result);
-}
-
-void PepperTCPSocket::ConnectWithNetAddress(
- const PP_NetAddress_Private& net_addr) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (connection_state_ != BEFORE_CONNECT) {
- SendConnectACKError(PP_ERROR_FAILED);
- return;
- }
-
- net::IPAddressNumber address;
- uint16 port;
- if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(
- net_addr, &address, &port)) {
- SendConnectACKError(PP_ERROR_ADDRESS_INVALID);
- return;
- }
-
- // Copy the single IPEndPoint to address_list_.
- address_list_.clear();
- address_list_.push_back(net::IPEndPoint(address, port));
- connection_state_ = CONNECT_IN_PROGRESS;
- StartConnect(address_list_);
-}
-
-void PepperTCPSocket::SSLHandshake(
- const std::string& server_name,
- uint16_t server_port,
- const std::vector<std::vector<char> >& trusted_certs,
- const std::vector<std::vector<char> >& untrusted_certs) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- // Allow to do SSL handshake only if currently the socket has been connected
- // and there isn't pending read or write.
- // IsConnected() includes the state that SSL handshake has been finished and
- // therefore isn't suitable here.
- if (connection_state_ != CONNECTED || read_buffer_.get() ||
- write_buffer_base_.get() || write_buffer_.get()) {
- SendSSLHandshakeACK(false);
- return;
- }
-
- connection_state_ = SSL_HANDSHAKE_IN_PROGRESS;
- // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting.
-
- scoped_ptr<net::ClientSocketHandle> handle(new net::ClientSocketHandle());
- handle->SetSocket(socket_.Pass());
- net::ClientSocketFactory* factory =
- net::ClientSocketFactory::GetDefaultFactory();
- net::HostPortPair host_port_pair(server_name, server_port);
- net::SSLClientSocketContext ssl_context;
- ssl_context.cert_verifier = manager_->GetCertVerifier();
- ssl_context.transport_security_state = manager_->GetTransportSecurityState();
- socket_ = factory->CreateSSLClientSocket(
- handle.Pass(), host_port_pair, manager_->ssl_config(), ssl_context);
- if (!socket_) {
- LOG(WARNING) << "Failed to create an SSL client socket.";
- OnSSLHandshakeCompleted(net::ERR_UNEXPECTED);
- return;
- }
-
- int net_result = socket_->Connect(base::Bind(
- &PepperTCPSocket::OnSSLHandshakeCompleted, base::Unretained(this)));
- if (net_result != net::ERR_IO_PENDING)
- OnSSLHandshakeCompleted(net_result);
-}
-
-void PepperTCPSocket::Read(int32 bytes_to_read) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!IsConnected() || end_of_file_reached_) {
- SendReadACKError(PP_ERROR_FAILED);
- return;
- }
-
- if (read_buffer_.get()) {
- SendReadACKError(PP_ERROR_INPROGRESS);
- return;
- }
-
- if (bytes_to_read <= 0 ||
- bytes_to_read > ppapi::TCPSocketShared::kMaxReadSize) {
- SendReadACKError(PP_ERROR_BADARGUMENT);
- return;
- }
-
- read_buffer_ = new net::IOBuffer(bytes_to_read);
- int net_result = socket_->Read(
- read_buffer_.get(),
- bytes_to_read,
- base::Bind(&PepperTCPSocket::OnReadCompleted, base::Unretained(this)));
- if (net_result != net::ERR_IO_PENDING)
- OnReadCompleted(net_result);
-}
-
-void PepperTCPSocket::Write(const std::string& data) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!IsConnected()) {
- SendWriteACKError(PP_ERROR_FAILED);
- return;
- }
-
- if (write_buffer_base_.get() || write_buffer_.get()) {
- SendWriteACKError(PP_ERROR_INPROGRESS);
- return;
- }
-
- size_t data_size = data.size();
- if (data_size == 0 ||
- data_size > static_cast<size_t>(ppapi::TCPSocketShared::kMaxWriteSize)) {
- SendWriteACKError(PP_ERROR_BADARGUMENT);
- return;
- }
-
- write_buffer_base_ = new net::IOBuffer(data_size);
- memcpy(write_buffer_base_->data(), data.data(), data_size);
- write_buffer_ =
- new net::DrainableIOBuffer(write_buffer_base_.get(), data_size);
- DoWrite();
-}
-
-void PepperTCPSocket::SetOption(PP_TCPSocket_Option name,
- const ppapi::SocketOptionData& value) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!IsConnected() || IsSsl()) {
- SendSetOptionACK(PP_ERROR_FAILED);
- return;
- }
-
- net::TCPClientSocket* tcp_socket =
- static_cast<net::TCPClientSocket*>(socket_.get());
- DCHECK(tcp_socket);
-
- switch (name) {
- case PP_TCPSOCKET_OPTION_NO_DELAY: {
- bool boolean_value = false;
- if (!value.GetBool(&boolean_value)) {
- SendSetOptionACK(PP_ERROR_BADARGUMENT);
- return;
- }
-
- SendSetOptionACK(tcp_socket->SetNoDelay(boolean_value) ? PP_OK
- : PP_ERROR_FAILED);
- return;
- }
- case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE:
- case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: {
- int32_t integer_value = 0;
- if (!value.GetInt32(&integer_value) || integer_value <= 0) {
- SendSetOptionACK(PP_ERROR_BADARGUMENT);
- return;
- }
-
- int net_result = net::OK;
- if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) {
- if (integer_value > ppapi::TCPSocketShared::kMaxSendBufferSize) {
- SendSetOptionACK(PP_ERROR_BADARGUMENT);
- return;
- }
- net_result = tcp_socket->SetSendBufferSize(integer_value);
- } else {
- if (integer_value > ppapi::TCPSocketShared::kMaxReceiveBufferSize) {
- SendSetOptionACK(PP_ERROR_BADARGUMENT);
- return;
- }
- net_result = tcp_socket->SetReceiveBufferSize(integer_value);
- }
- // TODO(wtc): Add error mapping.
- SendSetOptionACK((net_result == net::OK) ? PP_OK : PP_ERROR_FAILED);
- return;
- }
- default: {
- NOTREACHED();
- SendSetOptionACK(PP_ERROR_BADARGUMENT);
- return;
- }
- }
-}
-
-void PepperTCPSocket::StartConnect(const net::AddressList& addresses) {
- DCHECK(connection_state_ == CONNECT_IN_PROGRESS);
-
- socket_.reset(
- new net::TCPClientSocket(addresses, NULL, net::NetLog::Source()));
- int net_result = socket_->Connect(
- base::Bind(&PepperTCPSocket::OnConnectCompleted, base::Unretained(this)));
- if (net_result != net::ERR_IO_PENDING)
- OnConnectCompleted(net_result);
-}
-
-void PepperTCPSocket::SendConnectACKError(int32_t error) {
- manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK(
- routing_id_,
- plugin_dispatcher_id_,
- socket_id_,
- error,
- NetAddressPrivateImpl::kInvalidNetAddress,
- NetAddressPrivateImpl::kInvalidNetAddress));
-}
-
-// static
-bool PepperTCPSocket::GetCertificateFields(
- const net::X509Certificate& cert,
- ppapi::PPB_X509Certificate_Fields* fields) {
- const net::CertPrincipal& issuer = cert.issuer();
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COMMON_NAME,
- new base::StringValue(issuer.common_name));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_LOCALITY_NAME,
- new base::StringValue(issuer.locality_name));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_STATE_OR_PROVINCE_NAME,
- new base::StringValue(issuer.state_or_province_name));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COUNTRY_NAME,
- new base::StringValue(issuer.country_name));
- fields->SetField(
- PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_NAME,
- new base::StringValue(base::JoinString(issuer.organization_names, "\n")));
- fields->SetField(
- PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_UNIT_NAME,
- new base::StringValue(
- base::JoinString(issuer.organization_unit_names, "\n")));
-
- const net::CertPrincipal& subject = cert.subject();
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COMMON_NAME,
- new base::StringValue(subject.common_name));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_LOCALITY_NAME,
- new base::StringValue(subject.locality_name));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_STATE_OR_PROVINCE_NAME,
- new base::StringValue(subject.state_or_province_name));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COUNTRY_NAME,
- new base::StringValue(subject.country_name));
- fields->SetField(
- PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_NAME,
- new base::StringValue(
- base::JoinString(subject.organization_names, "\n")));
- fields->SetField(
- PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_UNIT_NAME,
- new base::StringValue(
- base::JoinString(subject.organization_unit_names, "\n")));
-
- const std::string& serial_number = cert.serial_number();
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_SERIAL_NUMBER,
- base::BinaryValue::CreateWithCopiedBuffer(
- serial_number.data(), serial_number.length()));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_BEFORE,
- new base::FundamentalValue(cert.valid_start().ToDoubleT()));
- fields->SetField(PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_AFTER,
- new base::FundamentalValue(cert.valid_expiry().ToDoubleT()));
- std::string der;
- net::X509Certificate::GetDEREncoded(cert.os_cert_handle(), &der);
- fields->SetField(
- PP_X509CERTIFICATE_PRIVATE_RAW,
- base::BinaryValue::CreateWithCopiedBuffer(der.data(), der.length()));
- return true;
-}
-
-// static
-bool PepperTCPSocket::GetCertificateFields(
- const char* der,
- uint32_t length,
- ppapi::PPB_X509Certificate_Fields* fields) {
- scoped_refptr<net::X509Certificate> cert =
- net::X509Certificate::CreateFromBytes(der, length);
- if (!cert.get())
- return false;
- return GetCertificateFields(*cert.get(), fields);
-}
-
-void PepperTCPSocket::SendReadACKError(int32_t error) {
- manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, error, std::string()));
-}
-
-void PepperTCPSocket::SendWriteACKError(int32_t error) {
- DCHECK_GT(0, error);
- manager_->Send(new PpapiMsg_PPBTCPSocket_WriteACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, error));
-}
-
-void PepperTCPSocket::SendSSLHandshakeACK(bool succeeded) {
- ppapi::PPB_X509Certificate_Fields certificate_fields;
- if (succeeded) {
- // Our socket is guaranteed to be an SSL socket if we get here.
- net::SSLClientSocket* ssl_socket =
- static_cast<net::SSLClientSocket*>(socket_.get());
- net::SSLInfo ssl_info;
- ssl_socket->GetSSLInfo(&ssl_info);
- if (ssl_info.cert.get())
- GetCertificateFields(*ssl_info.cert.get(), &certificate_fields);
- }
- manager_->Send(
- new PpapiMsg_PPBTCPSocket_SSLHandshakeACK(routing_id_,
- plugin_dispatcher_id_,
- socket_id_,
- succeeded,
- certificate_fields));
-}
-
-void PepperTCPSocket::SendSetOptionACK(int32_t result) {
- manager_->Send(new PpapiMsg_PPBTCPSocket_SetOptionACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, result));
-}
-
-void PepperTCPSocket::OnResolveCompleted(int net_result) {
- DCHECK(connection_state_ == CONNECT_IN_PROGRESS);
-
- if (net_result != net::OK) {
- SendConnectACKError(NetErrorToPepperError(net_result));
- connection_state_ = BEFORE_CONNECT;
- return;
- }
-
- StartConnect(address_list_);
-}
-
-void PepperTCPSocket::OnConnectCompleted(int net_result) {
- DCHECK(connection_state_ == CONNECT_IN_PROGRESS && socket_.get());
-
- int32_t pp_result = NetErrorToPepperError(net_result);
- do {
- if (pp_result != PP_OK)
- break;
-
- net::IPEndPoint ip_end_point_local;
- net::IPEndPoint ip_end_point_remote;
- pp_result =
- NetErrorToPepperError(socket_->GetLocalAddress(&ip_end_point_local));
- if (pp_result != PP_OK)
- break;
- pp_result =
- NetErrorToPepperError(socket_->GetPeerAddress(&ip_end_point_remote));
- if (pp_result != PP_OK)
- break;
-
- PP_NetAddress_Private local_addr =
- NetAddressPrivateImpl::kInvalidNetAddress;
- PP_NetAddress_Private remote_addr =
- NetAddressPrivateImpl::kInvalidNetAddress;
- if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
- ip_end_point_local.address(),
- ip_end_point_local.port(),
- &local_addr) ||
- !NetAddressPrivateImpl::IPEndPointToNetAddress(
- ip_end_point_remote.address(),
- ip_end_point_remote.port(),
- &remote_addr)) {
- pp_result = PP_ERROR_ADDRESS_INVALID;
- break;
- }
-
- manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK(routing_id_,
- plugin_dispatcher_id_,
- socket_id_,
- PP_OK,
- local_addr,
- remote_addr));
- connection_state_ = CONNECTED;
- return;
- } while (false);
-
- SendConnectACKError(pp_result);
- connection_state_ = BEFORE_CONNECT;
-}
-
-void PepperTCPSocket::OnSSLHandshakeCompleted(int net_result) {
- DCHECK(connection_state_ == SSL_HANDSHAKE_IN_PROGRESS);
-
- bool succeeded = net_result == net::OK;
- SendSSLHandshakeACK(succeeded);
- connection_state_ = succeeded ? SSL_CONNECTED : SSL_HANDSHAKE_FAILED;
-}
-
-void PepperTCPSocket::OnReadCompleted(int net_result) {
- DCHECK(read_buffer_.get());
-
- if (net_result > 0) {
- manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK(
- routing_id_,
- plugin_dispatcher_id_,
- socket_id_,
- PP_OK,
- std::string(read_buffer_->data(), net_result)));
- } else if (net_result == 0) {
- end_of_file_reached_ = true;
- manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, PP_OK, std::string()));
- } else {
- SendReadACKError(NetErrorToPepperError(net_result));
- }
- read_buffer_ = NULL;
-}
-
-void PepperTCPSocket::OnWriteCompleted(int net_result) {
- DCHECK(write_buffer_base_.get());
- DCHECK(write_buffer_.get());
-
- // Note: For partial writes of 0 bytes, don't continue writing to avoid a
- // likely infinite loop.
- if (net_result > 0) {
- write_buffer_->DidConsume(net_result);
- if (write_buffer_->BytesRemaining() > 0) {
- DoWrite();
- return;
- }
- }
-
- if (net_result >= 0) {
- manager_->Send(
- new PpapiMsg_PPBTCPSocket_WriteACK(routing_id_,
- plugin_dispatcher_id_,
- socket_id_,
- write_buffer_->BytesConsumed()));
- } else {
- SendWriteACKError(NetErrorToPepperError(net_result));
- }
-
- write_buffer_ = NULL;
- write_buffer_base_ = NULL;
-}
-
-bool PepperTCPSocket::IsConnected() const {
- return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
-}
-
-bool PepperTCPSocket::IsSsl() const {
- return connection_state_ == SSL_HANDSHAKE_IN_PROGRESS ||
- connection_state_ == SSL_CONNECTED ||
- connection_state_ == SSL_HANDSHAKE_FAILED;
-}
-
-void PepperTCPSocket::DoWrite() {
- DCHECK(write_buffer_base_.get());
- DCHECK(write_buffer_.get());
- DCHECK_GT(write_buffer_->BytesRemaining(), 0);
-
- int net_result = socket_->Write(
- write_buffer_.get(),
- write_buffer_->BytesRemaining(),
- base::Bind(&PepperTCPSocket::OnWriteCompleted, base::Unretained(this)));
- if (net_result != net::ERR_IO_PENDING)
- OnWriteCompleted(net_result);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
index 7f98861339c..91a851228a7 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h"
#include <cstring>
+#include <utility>
#include "base/bind.h"
#include "base/location.h"
@@ -108,7 +109,7 @@ PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter(
rcvbuf_size_(0),
sndbuf_size_(0),
address_index_(0),
- socket_(socket.Pass()),
+ socket_(std::move(socket)),
ssl_context_helper_(host->ssl_context_helper()),
pending_accept_(false),
pending_read_on_unthrottle_(false),
@@ -321,7 +322,7 @@ int32_t PepperTCPSocketMessageFilter::OnMsgSSLHandshake(
scoped_ptr<net::ClientSocketHandle> handle(new net::ClientSocketHandle());
handle->SetSocket(make_scoped_ptr<net::StreamSocket>(
- new net::TCPClientSocket(socket_.Pass(), peer_address)));
+ new net::TCPClientSocket(std::move(socket_), peer_address)));
net::ClientSocketFactory* factory =
net::ClientSocketFactory::GetDefaultFactory();
net::HostPortPair host_port_pair(server_name, server_port);
@@ -329,11 +330,9 @@ int32_t PepperTCPSocketMessageFilter::OnMsgSSLHandshake(
ssl_context.cert_verifier = ssl_context_helper_->GetCertVerifier();
ssl_context.transport_security_state =
ssl_context_helper_->GetTransportSecurityState();
- ssl_socket_ =
- factory->CreateSSLClientSocket(handle.Pass(),
- host_port_pair,
- ssl_context_helper_->ssl_config(),
- ssl_context);
+ ssl_socket_ = factory->CreateSSLClientSocket(
+ std::move(handle), host_port_pair, ssl_context_helper_->ssl_config(),
+ ssl_context);
if (!ssl_socket_) {
LOG(WARNING) << "Failed to create an SSL client socket.";
state_.CompletePendingTransition(false);
@@ -575,7 +574,7 @@ void PepperTCPSocketMessageFilter::DoBind(
int pp_result = PP_OK;
do {
net::IPAddressNumber address;
- uint16 port;
+ uint16_t port;
if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(
net_addr, &address, &port)) {
pp_result = PP_ERROR_ADDRESS_INVALID;
@@ -665,7 +664,7 @@ void PepperTCPSocketMessageFilter::DoConnectWithNetAddress(
state_.SetPendingTransition(TCPSocketState::CONNECT);
net::IPAddressNumber address;
- uint16 port;
+ uint16_t port;
if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(
net_addr, &address, &port)) {
state_.CompletePendingTransition(false);
@@ -1023,14 +1022,14 @@ void PepperTCPSocketMessageFilter::OnAcceptCompleted(
// in CONNECTED state have a NULL |factory_|, while getting here requires
// LISTENING state.
scoped_ptr<ppapi::host::ResourceHost> host =
- factory_->CreateAcceptedTCPSocket(
- instance_, version_, accepted_socket_.Pass());
+ factory_->CreateAcceptedTCPSocket(instance_, version_,
+ std::move(accepted_socket_));
if (!host) {
SendAcceptError(context, PP_ERROR_NOSPACE);
return;
}
int pending_host_id =
- host_->GetPpapiHost()->AddPendingResourceHost(host.Pass());
+ host_->GetPpapiHost()->AddPendingResourceHost(std::move(host));
if (pending_host_id)
SendAcceptReply(context, PP_OK, pending_host_id, local_addr, remote_addr);
else
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
index 51443ebb53b..8fe42c1bdcb 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
@@ -5,13 +5,17 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/ssl_context_helper.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font.h b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font.h
index f26b9bd9b79..63ed2c6ef8c 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TRUETYPE_FONT_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TRUETYPE_FONT_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.h b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.h
index b449547010a..f574c317c82 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TRUETYPE_FONT_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TRUETYPE_FONT_HOST_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc
index ebfacb87b30..4c51d6f2804 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/files/scoped_file.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/sys_byteorder.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc
index 3730724aa25..4c72d4d9a42 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc
@@ -4,8 +4,11 @@
#include "content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h"
+#include <stdint.h>
+
#include <algorithm>
+#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/renderer_host/pepper/pepper_truetype_font_list.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h
index 19999ca1f59..46a975bfdab 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TRUETYPE_FONT_LIST_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TRUETYPE_FONT_LIST_HOST_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "ppapi/host/resource_host.h"
namespace content {
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
index 761572305ab..c59c4a87da2 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
@@ -7,6 +7,7 @@
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/macros.h"
#include "base/strings/sys_string_conversions.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/proxy/serialized_structs.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
index e271dbbb08a..231c8ca14f2 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/pepper/pepper_truetype_font_list.h"
#include <windows.h>
+#include <string.h>
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_hdc.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_mac.mm b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_mac.mm
index 1e52e172bbf..db8a8b51070 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_mac.mm
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_mac.mm
@@ -5,6 +5,8 @@
#include "content/browser/renderer_host/pepper/pepper_truetype_font.h"
#import <ApplicationServices/ApplicationServices.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
@@ -12,6 +14,7 @@
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "base/sys_byteorder.h"
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_win.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_win.cc
index 633a3266e1b..194decd8e36 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_win.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_win.cc
@@ -5,9 +5,12 @@
#include "content/browser/renderer_host/pepper/pepper_truetype_font.h"
#include <windows.h>
+#include <stdint.h>
+#include <algorithm>
#include <set>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
@@ -75,25 +78,26 @@ int32_t PepperTrueTypeFontWin::Initialize(
}
// TODO(bbudge) support widths (extended, condensed).
- font_.Set(CreateFont(0 /* height */,
- 0 /* width */,
- 0 /* escapement */,
- 0 /* orientation */,
- desc->weight, // our weight enum matches Windows.
- (desc->style & PP_TRUETYPEFONTSTYLE_ITALIC) ? 1 : 0,
- 0 /* underline */,
- 0 /* strikeout */,
- desc->charset, // our charset enum matches Windows.
- OUT_OUTLINE_PRECIS, // truetype and other outline fonts
- CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY,
- pitch_and_family,
- base::UTF8ToUTF16(desc->family).c_str()));
- if (!font_.Get())
+ font_.reset(CreateFont(
+ 0 /* height */,
+ 0 /* width */,
+ 0 /* escapement */,
+ 0 /* orientation */,
+ desc->weight, // our weight enum matches Windows.
+ (desc->style & PP_TRUETYPEFONTSTYLE_ITALIC) ? 1 : 0,
+ 0 /* underline */,
+ 0 /* strikeout */,
+ desc->charset, // our charset enum matches Windows.
+ OUT_OUTLINE_PRECIS, // truetype and other outline fonts
+ CLIP_DEFAULT_PRECIS,
+ DEFAULT_QUALITY,
+ pitch_and_family,
+ base::UTF8ToUTF16(desc->family).c_str()));
+ if (!font_.is_valid())
return PP_ERROR_FAILED;
LOGFONT font_desc;
- if (!::GetObject(font_.Get(), sizeof(LOGFONT), &font_desc))
+ if (!::GetObject(font_.get(), sizeof(LOGFONT), &font_desc))
return PP_ERROR_FAILED;
switch (font_desc.lfPitchAndFamily & 0xF0) { // Top 4 bits are family.
@@ -124,7 +128,7 @@ int32_t PepperTrueTypeFontWin::Initialize(
// doesn't fill in the name field of the LOGFONT structure.
base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
if (hdc.IsValid()) {
- base::win::ScopedSelectObject select_object(hdc.Get(), font_.Get());
+ base::win::ScopedSelectObject select_object(hdc.Get(), font_.get());
WCHAR name[LF_FACESIZE];
GetTextFace(hdc.Get(), LF_FACESIZE, name);
desc->family = base::UTF16ToUTF8(name);
@@ -134,14 +138,14 @@ int32_t PepperTrueTypeFontWin::Initialize(
}
int32_t PepperTrueTypeFontWin::GetTableTags(std::vector<uint32_t>* tags) {
- if (!font_.Get())
+ if (!font_.is_valid())
return PP_ERROR_FAILED;
base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
if (!hdc.IsValid())
return PP_ERROR_FAILED;
- base::win::ScopedSelectObject select_object(hdc.Get(), font_.Get());
+ base::win::ScopedSelectObject select_object(hdc.Get(), font_.get());
// Get the whole font header.
static const DWORD kFontHeaderSize = 12;
@@ -180,14 +184,14 @@ int32_t PepperTrueTypeFontWin::GetTable(uint32_t table_tag,
int32_t offset,
int32_t max_data_length,
std::string* data) {
- if (!font_.Get())
+ if (!font_.is_valid())
return PP_ERROR_FAILED;
base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
if (!hdc.IsValid())
return PP_ERROR_FAILED;
- base::win::ScopedSelectObject select_object(hdc.Get(), font_.Get());
+ base::win::ScopedSelectObject select_object(hdc.Get(), font_.get());
// Tags are byte swapped on Windows.
table_tag = base::ByteSwap(table_tag);
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc
index 547483121a5..2dc256b3dae 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc
@@ -5,10 +5,12 @@
#include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h"
#include <cstring>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
#include "content/public/browser/browser_thread.h"
@@ -65,8 +67,7 @@ PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter(
BrowserPpapiHostImpl* host,
PP_Instance instance,
bool private_api)
- : host_(host),
- socket_options_(0),
+ : socket_options_(0),
rcvbuf_size_(0),
sndbuf_size_(0),
multicast_ttl_(0),
@@ -361,7 +362,7 @@ int32_t PepperUDPSocketMessageFilter::OnMsgJoinGroup(
return PP_ERROR_FAILED;
net::IPAddressNumber group;
- uint16 port;
+ uint16_t port;
if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port))
return PP_ERROR_ADDRESS_INVALID;
@@ -382,7 +383,7 @@ int32_t PepperUDPSocketMessageFilter::OnMsgLeaveGroup(
return PP_ERROR_FAILED;
net::IPAddressNumber group;
- uint16 port;
+ uint16_t port;
if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port))
return PP_ERROR_ADDRESS_INVALID;
@@ -405,7 +406,7 @@ void PepperUDPSocketMessageFilter::DoBind(
NULL, net::NetLog::Source()));
net::IPAddressNumber address;
- uint16 port;
+ uint16_t port;
if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
SendBindError(context, PP_ERROR_ADDRESS_INVALID);
return;
@@ -502,7 +503,7 @@ void PepperUDPSocketMessageFilter::DoBind(
base::Bind(&PepperUDPSocketMessageFilter::OnBindComplete, this,
base::Passed(&socket), context, net_address));
#else
- OnBindComplete(socket.Pass(), context, net_address);
+ OnBindComplete(std::move(socket), context, net_address);
#endif
}
@@ -585,7 +586,7 @@ void PepperUDPSocketMessageFilter::DoSendTo(
}
net::IPAddressNumber address;
- uint16 port;
+ uint16_t port;
if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
SendSendToError(context, PP_ERROR_ADDRESS_INVALID);
return;
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
index a4ea58c8828..314599beedf 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
@@ -5,14 +5,17 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_MESSAGE_FILTER_H_
+#include <stddef.h>
+
#include <queue>
#include <string>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/process_type.h"
#include "net/base/completion_callback.h"
@@ -147,8 +150,6 @@ class CONTENT_EXPORT PepperUDPSocketMessageFilter
int32_t CanUseMulticastAPI(const PP_NetAddress_Private& addr);
- BrowserPpapiHostImpl* host_;
-
// Bitwise-or of SocketOption flags. This stores the state about whether
// each option is set before Bind() is called.
int socket_options_;
diff --git a/chromium/content/browser/renderer_host/pepper/quota_reservation.h b/chromium/content/browser/renderer_host/pepper/quota_reservation.h
index 7ea637c2b8f..84a5f90e45e 100644
--- a/chromium/content/browser/renderer_host/pepper/quota_reservation.h
+++ b/chromium/content/browser/renderer_host/pepper/quota_reservation.h
@@ -7,8 +7,8 @@
#include <map>
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
#include "ppapi/c/pp_stdint.h" // For int64_t on Windows.
#include "ppapi/shared_impl/file_growth.h"
diff --git a/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc b/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
index 5d7445b4fde..c1068db228b 100644
--- a/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
@@ -4,12 +4,15 @@
#include "content/browser/renderer_host/pepper/quota_reservation.h"
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -40,7 +43,7 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
void ReserveQuota(
const GURL& origin,
storage::FileSystemType type,
- int64 delta,
+ int64_t delta,
const QuotaReservationManager::ReserveQuotaCallback& callback) override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -49,11 +52,11 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
void ReleaseReservedQuota(const GURL& origin,
storage::FileSystemType type,
- int64 size) override {}
+ int64_t size) override {}
void CommitQuotaUsage(const GURL& origin,
storage::FileSystemType type,
- int64 delta) override {}
+ int64_t delta) override {}
void IncrementDirtyCount(const GURL& origin,
storage::FileSystemType type) override {}
@@ -102,7 +105,7 @@ class QuotaReservationTest : public testing::Test {
new QuotaReservation(reservation, origin, type));
}
- void SetFileSize(const base::FilePath::StringType& file_name, int64 size) {
+ void SetFileSize(const base::FilePath::StringType& file_name, int64_t size) {
base::File file(MakeFilePath(file_name),
base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
ASSERT_TRUE(file.IsValid());
@@ -121,9 +124,9 @@ class QuotaReservationTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(QuotaReservationTest);
};
-void GotReservedQuota(int64* reserved_quota_ptr,
+void GotReservedQuota(int64_t* reserved_quota_ptr,
ppapi::FileGrowthMap* file_growths_ptr,
- int64 reserved_quota,
+ int64_t reserved_quota,
const ppapi::FileSizeMap& maximum_written_offsets) {
*reserved_quota_ptr = reserved_quota;
@@ -135,8 +138,8 @@ void GotReservedQuota(int64* reserved_quota_ptr,
}
void ReserveQuota(scoped_refptr<QuotaReservation> quota_reservation,
- int64 amount,
- int64* reserved_quota,
+ int64_t amount,
+ int64_t* reserved_quota,
ppapi::FileGrowthMap* file_growths) {
quota_reservation->ReserveQuota(
amount,
@@ -158,17 +161,17 @@ TEST_F(QuotaReservationTest, ReserveQuota) {
CreateQuotaReservation(reservation, origin, type);
// Reserve quota with no files open.
- int64 amount = 100;
- int64 reserved_quota;
+ int64_t amount = 100;
+ int64_t reserved_quota;
ppapi::FileGrowthMap file_growths;
ReserveQuota(test, amount, &reserved_quota, &file_growths);
EXPECT_EQ(amount, reserved_quota);
EXPECT_EQ(0U, file_growths.size());
// Open a file, refresh the reservation, extend the file, and close it.
- int64 file_size = 10;
+ int64_t file_size = 10;
SetFileSize(file1_name, file_size);
- int64 open_file_size =
+ int64_t open_file_size =
test->OpenFile(kFile1ID, MakeFileSystemURL(file1_name));
EXPECT_EQ(file_size, open_file_size);
@@ -178,7 +181,7 @@ TEST_F(QuotaReservationTest, ReserveQuota) {
EXPECT_EQ(1U, file_growths.size());
EXPECT_EQ(file_size, file_growths[kFile1ID].max_written_offset);
- int64 new_file_size = 30;
+ int64_t new_file_size = 30;
SetFileSize(file1_name, new_file_size);
EXPECT_EQ(amount, reservation->remaining_quota());
@@ -199,25 +202,25 @@ TEST_F(QuotaReservationTest, MultipleFiles) {
CreateQuotaReservation(reservation, origin, type);
// Open some files of different sizes.
- int64 file1_size = 10;
+ int64_t file1_size = 10;
SetFileSize(file1_name, file1_size);
- int64 open_file1_size =
+ int64_t open_file1_size =
test->OpenFile(kFile1ID, MakeFileSystemURL(file1_name));
EXPECT_EQ(file1_size, open_file1_size);
- int64 file2_size = 20;
+ int64_t file2_size = 20;
SetFileSize(file2_name, file2_size);
- int64 open_file2_size =
+ int64_t open_file2_size =
test->OpenFile(kFile2ID, MakeFileSystemURL(file2_name));
EXPECT_EQ(file2_size, open_file2_size);
- int64 file3_size = 30;
+ int64_t file3_size = 30;
SetFileSize(file3_name, file3_size);
- int64 open_file3_size =
+ int64_t open_file3_size =
test->OpenFile(kFile3ID, MakeFileSystemURL(file3_name));
EXPECT_EQ(file3_size, open_file3_size);
// Reserve quota.
- int64 amount = 100;
- int64 reserved_quota;
+ int64_t amount = 100;
+ int64_t reserved_quota;
ppapi::FileGrowthMap file_growths;
file_growths[kFile1ID] = ppapi::FileGrowth(file1_size, 0); // 3 files open.
file_growths[kFile2ID] = ppapi::FileGrowth(file2_size, 0);
diff --git a/chromium/content/browser/renderer_host/pepper/ssl_context_helper.h b/chromium/content/browser/renderer_host/pepper/ssl_context_helper.h
index f1da2a6ee1d..f9795292b85 100644
--- a/chromium/content/browser/renderer_host/pepper/ssl_context_helper.h
+++ b/chromium/content/browser/renderer_host/pepper/ssl_context_helper.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/ssl/ssl_config_service.h"
diff --git a/chromium/content/browser/renderer_host/render_message_filter.cc b/chromium/content/browser/renderer_host/render_message_filter.cc
index efe1ce65b76..cec7b8b1225 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.cc
+++ b/chromium/content/browser/renderer_host/render_message_filter.cc
@@ -4,17 +4,22 @@
#include "content/browser/renderer_host/render_message_filter.h"
+#include <errno.h>
+#include <string.h>
#include <map>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/debug/alias.h"
+#include "base/macros.h"
#include "base/numerics/safe_math.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/worker_pool.h"
+#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
@@ -74,7 +79,6 @@
#if defined(OS_ANDROID)
#include "content/browser/media/android/media_throttler.h"
-#include "media/base/android/webaudio_media_codec_bridge.h"
#endif
#if defined(OS_MACOSX)
@@ -84,10 +88,8 @@
namespace content {
namespace {
-const uint32 kFilteredMessageClasses[] = {
- ChildProcessMsgStart,
- RenderProcessMsgStart,
- ViewMsgStart,
+const uint32_t kFilteredMessageClasses[] = {
+ ChildProcessMsgStart, RenderProcessMsgStart, ViewMsgStart,
};
#if defined(OS_WIN)
@@ -98,13 +100,6 @@ base::LazyInstance<gfx::ColorProfile>::Leaky g_color_profile =
LAZY_INSTANCE_INITIALIZER;
#endif
-#if defined(OS_ANDROID)
-void CloseWebAudioFileDescriptor(int fd) {
- if (close(fd))
- VLOG(1) << "Couldn't close output webaudio fd: " << strerror(errno);
-}
-#endif
-
} // namespace
RenderMessageFilter::RenderMessageFilter(
@@ -146,8 +141,6 @@ RenderMessageFilter::~RenderMessageFilter() {
bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderMessageFilter, message)
- IPC_MESSAGE_HANDLER(RenderProcessHostMsg_GetProcessMemorySizes,
- OnGetProcessMemorySizes)
IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnCreateWidget)
@@ -201,9 +194,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnGetMonitorColorProfile)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents)
-#if defined(OS_ANDROID)
- IPC_MESSAGE_HANDLER(ViewHostMsg_RunWebAudioMediaCodec, OnWebAudioMediaCodec)
-#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -211,6 +201,7 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
}
void RenderMessageFilter::OnDestruct() const {
+ const_cast<RenderMessageFilter*>(this)->resource_context_ = nullptr;
BrowserThread::DeleteOnIOThread::Destruct(this);
}
@@ -235,9 +226,7 @@ base::TaskRunner* RenderMessageFilter::OverrideTaskRunnerForMessage(
void RenderMessageFilter::OnCreateWindow(
const ViewHostMsg_CreateWindow_Params& params,
- int* route_id,
- int* main_frame_route_id,
- int64* cloned_session_storage_namespace_id) {
+ ViewHostMsg_CreateWindow_Reply* reply) {
bool no_javascript_access;
bool can_create_window =
@@ -259,9 +248,10 @@ void RenderMessageFilter::OnCreateWindow(
&no_javascript_access);
if (!can_create_window) {
- *route_id = MSG_ROUTING_NONE;
- *main_frame_route_id = MSG_ROUTING_NONE;
- *cloned_session_storage_namespace_id = 0;
+ reply->route_id = MSG_ROUTING_NONE;
+ reply->main_frame_route_id = MSG_ROUTING_NONE;
+ reply->main_frame_widget_route_id = MSG_ROUTING_NONE;
+ reply->cloned_session_storage_namespace_id = 0;
return;
}
@@ -269,14 +259,12 @@ void RenderMessageFilter::OnCreateWindow(
scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace =
new SessionStorageNamespaceImpl(dom_storage_context_.get(),
params.session_storage_namespace_id);
- *cloned_session_storage_namespace_id = cloned_namespace->id();
+ reply->cloned_session_storage_namespace_id = cloned_namespace->id();
- render_widget_helper_->CreateNewWindow(params,
- no_javascript_access,
- PeerHandle(),
- route_id,
- main_frame_route_id,
- cloned_namespace.get());
+ render_widget_helper_->CreateNewWindow(
+ params, no_javascript_access, PeerHandle(), &reply->route_id,
+ &reply->main_frame_route_id, &reply->main_frame_widget_route_id,
+ cloned_namespace.get());
}
void RenderMessageFilter::OnCreateWidget(int opener_id,
@@ -290,24 +278,6 @@ void RenderMessageFilter::OnCreateFullscreenWidget(int opener_id,
render_widget_helper_->CreateNewFullscreenWidget(opener_id, route_id);
}
-void RenderMessageFilter::OnGetProcessMemorySizes(size_t* private_bytes,
- size_t* shared_bytes) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- using base::ProcessMetrics;
-#if !defined(OS_MACOSX) || defined(OS_IOS)
- scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
- PeerHandle()));
-#else
- scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
- PeerHandle(), BrowserChildProcessHost::GetPortProvider()));
-#endif
- if (!metrics->GetMemoryBytes(private_bytes, shared_bytes)) {
- *private_bytes = 0;
- *shared_bytes = 0;
- }
-}
-
-
void RenderMessageFilter::OnGenerateRoutingID(int* route_id) {
*route_id = render_widget_helper_->GetNextRoutingID();
}
@@ -399,6 +369,9 @@ void RenderMessageFilter::DownloadUrl(int render_view_id,
const Referrer& referrer,
const base::string16& suggested_name,
const bool use_prompt) const {
+ if (!resource_context_)
+ return;
+
scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
save_info->suggested_name = suggested_name;
save_info->prompt_for_save_location = use_prompt;
@@ -407,17 +380,10 @@ void RenderMessageFilter::DownloadUrl(int render_view_id,
url, net::DEFAULT_PRIORITY, NULL));
RecordDownloadSource(INITIATED_BY_RENDERER);
resource_dispatcher_host_->BeginDownload(
- request.Pass(),
- referrer,
+ std::move(request), referrer,
true, // is_content_initiated
- resource_context_,
- render_process_id_,
- render_view_id,
- render_frame_id,
- false,
- false,
- save_info.Pass(),
- DownloadItem::kInvalidId,
+ resource_context_, render_process_id_, render_view_id, render_frame_id,
+ false, false, std::move(save_info), DownloadItem::kInvalidId,
ResourceDispatcherHostImpl::DownloadStartedCallback());
}
@@ -446,7 +412,7 @@ void RenderMessageFilter::OnSaveImageFromDataURL(int render_view_id,
}
void RenderMessageFilter::AllocateSharedMemoryOnFileThread(
- uint32 buffer_size,
+ uint32_t buffer_size,
IPC::Message* reply_msg) {
base::SharedMemoryHandle handle;
ChildProcessHostImpl::AllocateSharedMemory(buffer_size, PeerHandle(),
@@ -456,7 +422,7 @@ void RenderMessageFilter::AllocateSharedMemoryOnFileThread(
Send(reply_msg);
}
-void RenderMessageFilter::OnAllocateSharedMemory(uint32 buffer_size,
+void RenderMessageFilter::OnAllocateSharedMemory(uint32_t buffer_size,
IPC::Message* reply_msg) {
BrowserThread::PostTask(
BrowserThread::FILE_USER_BLOCKING, FROM_HERE,
@@ -465,7 +431,7 @@ void RenderMessageFilter::OnAllocateSharedMemory(uint32 buffer_size,
}
void RenderMessageFilter::AllocateSharedBitmapOnFileThread(
- uint32 buffer_size,
+ uint32_t buffer_size,
const cc::SharedBitmapId& id,
IPC::Message* reply_msg) {
base::SharedMemoryHandle handle;
@@ -476,7 +442,7 @@ void RenderMessageFilter::AllocateSharedBitmapOnFileThread(
Send(reply_msg);
}
-void RenderMessageFilter::OnAllocateSharedBitmap(uint32 buffer_size,
+void RenderMessageFilter::OnAllocateSharedBitmap(uint32_t buffer_size,
const cc::SharedBitmapId& id,
IPC::Message* reply_msg) {
BrowserThread::PostTask(
@@ -502,7 +468,7 @@ void RenderMessageFilter::OnDeletedSharedBitmap(const cc::SharedBitmapId& id) {
}
void RenderMessageFilter::AllocateLockedDiscardableSharedMemoryOnFileThread(
- uint32 size,
+ uint32_t size,
DiscardableSharedMemoryId id,
IPC::Message* reply_msg) {
base::SharedMemoryHandle handle;
@@ -515,7 +481,7 @@ void RenderMessageFilter::AllocateLockedDiscardableSharedMemoryOnFileThread(
}
void RenderMessageFilter::OnAllocateLockedDiscardableSharedMemory(
- uint32 size,
+ uint32_t size,
DiscardableSharedMemoryId id,
IPC::Message* reply_msg) {
BrowserThread::PostTask(
@@ -540,19 +506,6 @@ void RenderMessageFilter::OnDeletedDiscardableSharedMemory(
this, id));
}
-net::URLRequestContext* RenderMessageFilter::GetRequestContextForURL(
- const GURL& url) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- net::URLRequestContext* context =
- GetContentClient()->browser()->OverrideRequestContextForURL(
- url, resource_context_);
- if (!context)
- context = request_context_->GetURLRequestContext();
-
- return context;
-}
-
void RenderMessageFilter::OnCacheableMetadataAvailable(
const GURL& url,
base::Time expected_response_time,
@@ -575,10 +528,14 @@ void RenderMessageFilter::OnCacheableMetadataAvailable(
data.size());
}
-void RenderMessageFilter::OnKeygen(uint32 key_size_index,
+void RenderMessageFilter::OnKeygen(uint32_t key_size_index,
const std::string& challenge_string,
const GURL& url,
+ const GURL& top_origin,
IPC::Message* reply_msg) {
+ if (!resource_context_)
+ return;
+
// Map displayed strings indicating level of keysecurity in the <keygen>
// menu to the key size in bits. (See SSLKeyGeneratorChromium.cpp in WebCore.)
int key_size_in_bits;
@@ -596,6 +553,13 @@ void RenderMessageFilter::OnKeygen(uint32 key_size_index,
return;
}
+ if (!GetContentClient()->browser()->AllowKeygen(top_origin,
+ resource_context_)) {
+ RenderProcessHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
+ Send(reply_msg);
+ return;
+ }
+
resource_context_->CreateKeygenHandler(
key_size_in_bits,
challenge_string,
@@ -643,35 +607,9 @@ void RenderMessageFilter::OnMediaLogEvents(
media_internals_->OnMediaEvents(render_process_id_, events);
}
-#if defined(OS_ANDROID)
-void RenderMessageFilter::OnWebAudioMediaCodec(
- base::SharedMemoryHandle encoded_data_handle,
- base::FileDescriptor pcm_output,
- uint32_t data_size) {
- if (!MediaThrottler::GetInstance()->RequestDecoderResources()) {
- base::WorkerPool::PostTask(
- FROM_HERE,
- base::Bind(&CloseWebAudioFileDescriptor, pcm_output.fd),
- true);
- VLOG(1) << "Cannot decode audio data due to throttling";
- } else {
- // Let a WorkerPool handle this request since the WebAudio
- // MediaCodec bridge is slow and can block while sending the data to
- // the renderer.
- base::WorkerPool::PostTask(
- FROM_HERE,
- base::Bind(&media::WebAudioMediaCodecBridge::RunWebAudioMediaCodec,
- encoded_data_handle, pcm_output, data_size,
- base::Bind(&MediaThrottler::OnDecodeRequestFinished,
- base::Unretained(MediaThrottler::GetInstance()))),
- true);
- }
-}
-#endif
-
void RenderMessageFilter::OnAllocateGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- uint32 width,
- uint32 height,
+ uint32_t width,
+ uint32_t height,
gfx::BufferFormat format,
gfx::BufferUsage usage,
IPC::Message* reply) {
@@ -703,11 +641,11 @@ void RenderMessageFilter::GpuMemoryBufferAllocated(
void RenderMessageFilter::OnDeletedGpuMemoryBuffer(
gfx::GpuMemoryBufferId id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
DCHECK(BrowserGpuMemoryBufferManager::current());
BrowserGpuMemoryBufferManager::current()->ChildProcessDeletedGpuMemoryBuffer(
- id, PeerHandle(), render_process_id_, sync_point);
+ id, PeerHandle(), render_process_id_, sync_token);
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_message_filter.h b/chromium/content/browser/renderer_host/render_message_filter.h
index d27b013c545..ce07dfee796 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.h
+++ b/chromium/content/browser/renderer_host/render_message_filter.h
@@ -5,14 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_MESSAGE_FILTER_H_
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
+#include <stddef.h>
+#include <stdint.h>
#include <string>
#include <vector>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/sequenced_task_runner_helpers.h"
@@ -31,6 +31,10 @@
#include "ui/gfx/native_widget_types.h"
#include "ui/surface/transport_dib.h"
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
#if defined(OS_MACOSX)
#include <IOSurface/IOSurface.h>
#include "content/common/mac/font_loader.h"
@@ -43,6 +47,7 @@
class GURL;
struct FontDescriptor;
struct ViewHostMsg_CreateWindow_Params;
+struct ViewHostMsg_CreateWindow_Reply;
namespace blink {
struct WebScreenInfo;
@@ -58,6 +63,10 @@ namespace gfx {
struct GpuMemoryBufferHandle;
}
+namespace gpu {
+struct SyncToken;
+}
+
namespace media {
class AudioManager;
struct MediaLogEvent;
@@ -101,11 +110,6 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
int render_process_id() const { return render_process_id_; }
- // Returns the correct net::URLRequestContext depending on what type of url is
- // given.
- // Only call on the IO thread.
- net::URLRequestContext* GetRequestContextForURL(const GURL& url);
-
protected:
~RenderMessageFilter() override;
@@ -123,9 +127,7 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
void OnGetProcessMemorySizes(size_t* private_bytes, size_t* shared_bytes);
void OnCreateWindow(const ViewHostMsg_CreateWindow_Params& params,
- int* route_id,
- int* main_frame_route_id,
- int64* cloned_session_storage_namespace_id);
+ ViewHostMsg_CreateWindow_Reply* reply);
void OnCreateWidget(int opener_id,
blink::WebPopupType popup_type,
int* route_id);
@@ -161,13 +163,13 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
// Used to ask the browser to allocate a block of shared memory for the
// renderer to send back data in, since shared memory can't be created
// in the renderer on POSIX due to the sandbox.
- void AllocateSharedMemoryOnFileThread(uint32 buffer_size,
+ void AllocateSharedMemoryOnFileThread(uint32_t buffer_size,
IPC::Message* reply_msg);
- void OnAllocateSharedMemory(uint32 buffer_size, IPC::Message* reply_msg);
- void AllocateSharedBitmapOnFileThread(uint32 buffer_size,
+ void OnAllocateSharedMemory(uint32_t buffer_size, IPC::Message* reply_msg);
+ void AllocateSharedBitmapOnFileThread(uint32_t buffer_size,
const cc::SharedBitmapId& id,
IPC::Message* reply_msg);
- void OnAllocateSharedBitmap(uint32 buffer_size,
+ void OnAllocateSharedBitmap(uint32_t buffer_size,
const cc::SharedBitmapId& id,
IPC::Message* reply_msg);
void OnAllocatedSharedBitmap(size_t buffer_size,
@@ -178,10 +180,10 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
// Browser side discardable shared memory allocation.
void AllocateLockedDiscardableSharedMemoryOnFileThread(
- uint32 size,
+ uint32_t size,
DiscardableSharedMemoryId id,
IPC::Message* reply_message);
- void OnAllocateLockedDiscardableSharedMemory(uint32 size,
+ void OnAllocateLockedDiscardableSharedMemory(uint32_t size,
DiscardableSharedMemoryId id,
IPC::Message* reply_message);
void DeletedDiscardableSharedMemoryOnFileThread(DiscardableSharedMemoryId id);
@@ -190,8 +192,11 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
void OnCacheableMetadataAvailable(const GURL& url,
base::Time expected_response_time,
const std::vector<char>& data);
- void OnKeygen(uint32 key_size_index, const std::string& challenge_string,
- const GURL& url, IPC::Message* reply_msg);
+ void OnKeygen(uint32_t key_size_index,
+ const std::string& challenge_string,
+ const GURL& url,
+ const GURL& top_origin,
+ IPC::Message* reply_msg);
void PostKeygenToWorkerThread(IPC::Message* reply_msg,
scoped_ptr<net::KeygenHandler> keygen_handler);
void OnKeygenOnWorkerThread(scoped_ptr<net::KeygenHandler> keygen_handler,
@@ -201,22 +206,16 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
bool CheckBenchmarkingEnabled() const;
bool CheckPreparsedJsCachingEnabled() const;
-#if defined(OS_ANDROID)
- void OnWebAudioMediaCodec(base::SharedMemoryHandle encoded_data_handle,
- base::FileDescriptor pcm_output,
- uint32_t data_size);
-#endif
-
void OnAllocateGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- uint32 width,
- uint32 height,
+ uint32_t width,
+ uint32_t height,
gfx::BufferFormat format,
gfx::BufferUsage usage,
IPC::Message* reply);
void GpuMemoryBufferAllocated(IPC::Message* reply,
const gfx::GpuMemoryBufferHandle& handle);
void OnDeletedGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
// Cached resource request dispatcher host, guaranteed to be non-null. We do
// not own it; it is managed by the BrowserProcess, which has a wider scope
diff --git a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
index 1d5ed5532b5..e0c4d27a236 100644
--- a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/common/child_process_messages.h"
#include "content/public/browser/render_process_host.h"
@@ -62,7 +63,7 @@ class RenderProcessHostTest : public ContentBrowserTest,
// http://crbug.com/87176.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
ShutdownRequestFromActiveTabIgnored) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
NavigateToURL(shell(), test_url);
@@ -90,7 +91,7 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
// Set max renderers to 1 to force running out of processes.
content::RenderProcessHost::SetMaxRendererProcessCount(1);
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
NavigateToURL(shell(), test_url);
@@ -160,7 +161,7 @@ class ObserverLogger : public RenderProcessHostObserver {
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
AllProcessExitedCallsBeforeAnyHostDestroyedCalls) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
NavigateToURL(shell(), test_url);
diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.cc b/chromium/content/browser/renderer_host/render_process_host_impl.cc
index 194c8a2788e..67f45e6b528 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include <limits>
+#include <utility>
#include <vector>
#include "base/base_switches.h"
@@ -17,14 +18,15 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug/dump_without_crashing.h"
+#include "base/feature_list.h"
#include "base/files/file.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/process/process_handle.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -35,7 +37,9 @@
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event.h"
#include "base/tracked_objects.h"
+#include "build/build_config.h"
#include "cc/base/switches.h"
+#include "components/scheduler/common/scheduler_switches.h"
#include "components/tracing/tracing_switches.h"
#include "content/browser/appcache/appcache_dispatcher_host.h"
#include "content/browser/appcache/chrome_appcache_service.h"
@@ -51,10 +55,10 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/device_sensors/device_light_message_filter.h"
#include "content/browser/device_sensors/device_motion_message_filter.h"
+#include "content/browser/device_sensors/device_orientation_absolute_message_filter.h"
#include "content/browser/device_sensors/device_orientation_message_filter.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/dom_storage_message_filter.h"
-#include "content/browser/download/mhtml_generation_manager.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/browser/fileapi/fileapi_message_filter.h"
#include "content/browser/frame_host/render_frame_message_filter.h"
@@ -140,6 +144,7 @@
#include "content/public/browser/worker_service.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_constants.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_channel_switches.h"
#include "content/public/common/process_type.h"
@@ -153,6 +158,8 @@
#include "gpu/command_buffer/client/gpu_switches.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "ipc/attachment_broker.h"
+#include "ipc/attachment_broker_privileged.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_logging.h"
#include "ipc/ipc_switches.h"
@@ -163,6 +170,7 @@
#include "storage/browser/fileapi/sandbox_file_system_backend.h"
#include "third_party/icu/source/common/unicode/unistr.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
+#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/event_switches.h"
@@ -176,11 +184,13 @@
#include "content/browser/media/android/browser_demuxer_android.h"
#include "content/browser/mojo/service_registrar_android.h"
#include "content/browser/screen_orientation/screen_orientation_message_filter_android.h"
+#include "ipc/ipc_sync_channel.h"
#endif
#if defined(OS_WIN)
#include "base/win/scoped_com_initializer.h"
#include "base/win/windows_version.h"
+#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
#include "content/common/font_cache_dispatcher_win.h"
#include "content/common/sandbox_win.h"
#include "sandbox/win/src/sandbox_policy.h"
@@ -189,7 +199,7 @@
#if defined(OS_MACOSX) && !defined(OS_IOS)
#include "content/browser/bootstrap_sandbox_manager_mac.h"
-#include "content/browser/browser_io_surface_manager_mac.h"
+#include "content/browser/mach_broker_mac.h"
#endif
#if defined(USE_OZONE)
@@ -215,6 +225,11 @@
#include "content/common/media/media_stream_messages.h"
#endif
+#if defined(MOJO_SHELL_CLIENT)
+#include "content/browser/mojo/mojo_shell_client_host.h"
+#include "content/common/mojo/mojo_shell_connection_impl.h"
+#endif
+
#if defined(OS_WIN)
#define IntToStringType base::IntToString16
#else
@@ -229,13 +244,15 @@ const char kSiteProcessMapKeyName[] = "content_site_process_map";
#ifdef ENABLE_WEBRTC
const base::FilePath::CharType kAecDumpFileNameAddition[] =
FILE_PATH_LITERAL("aec_dump");
+const base::FilePath::CharType kEventLogFileNameAddition[] =
+ FILE_PATH_LITERAL("event_log");
#endif
-void CacheShaderInfo(int32 id, base::FilePath path) {
+void CacheShaderInfo(int32_t id, base::FilePath path) {
ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path);
}
-void RemoveShaderInfo(int32 id) {
+void RemoveShaderInfo(int32_t id) {
ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id);
}
@@ -255,36 +272,34 @@ void GetContexts(
ResourceContext* resource_context,
scoped_refptr<net::URLRequestContextGetter> request_context,
scoped_refptr<net::URLRequestContextGetter> media_request_context,
- const ResourceHostMsg_Request& request,
+ ResourceType resource_type,
+ int origin_pid,
ResourceContext** resource_context_out,
net::URLRequestContext** request_context_out) {
*resource_context_out = resource_context;
*request_context_out =
- GetRequestContext(request_context, media_request_context,
- request.resource_type);
+ GetRequestContext(request_context, media_request_context, resource_type);
}
#if defined(ENABLE_WEBRTC)
-// Allow us to only run the trial in the first renderer.
-bool has_done_stun_trials = false;
-
-// Creates a file used for diagnostic echo canceller recordings for handing
-// over to the renderer.
-IPC::PlatformFileForTransit CreateAecDumpFileForProcess(
- base::FilePath file_path,
- base::ProcessHandle process) {
+// Creates a file used for handing over to the renderer.
+IPC::PlatformFileForTransit CreateFileForProcess(base::FilePath file_path,
+ base::ProcessHandle process) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::File dump_file(file_path,
base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND);
if (!dump_file.IsValid()) {
- VLOG(1) << "Could not open AEC dump file, error=" <<
- dump_file.error_details();
+ VLOG(1) << "Could not open AEC dump file, error="
+ << dump_file.error_details();
return IPC::InvalidPlatformFileForTransit();
}
- return IPC::TakeFileHandleForProcess(dump_file.Pass(), process);
+ return IPC::TakeFileHandleForProcess(std::move(dump_file), process);
}
+// Allow us to only run the trial in the first renderer.
+bool has_done_stun_trials = false;
+
// Does nothing. Just to avoid races between enable and disable.
void DisableAecDumpOnFileThread() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
@@ -292,8 +307,8 @@ void DisableAecDumpOnFileThread() {
#endif
// the global list of all renderer processes
-base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
- g_all_hosts = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<IDMap<RenderProcessHost>>::Leaky g_all_hosts =
+ LAZY_INSTANCE_INITIALIZER;
// Map of site to process, to ensure we only have one RenderProcessHost per
// site in process-per-site mode. Each map is specific to a BrowserContext.
@@ -317,14 +332,12 @@ class SiteProcessMap : public base::SupportsUserData::Data {
// Find all instances of this process in the map, then separately remove
// them.
std::set<std::string> sites;
- for (SiteToProcessMap::const_iterator i = map_.begin();
- i != map_.end();
+ for (SiteToProcessMap::const_iterator i = map_.begin(); i != map_.end();
i++) {
if (i->second == host)
sites.insert(i->first);
}
- for (std::set<std::string>::iterator i = sites.begin();
- i != sites.end();
+ for (std::set<std::string>::iterator i = sites.begin(); i != sites.end();
i++) {
SiteToProcessMap::iterator iter = map_.find(*i);
if (iter != map_.end()) {
@@ -358,12 +371,13 @@ class RendererSandboxedProcessLauncherDelegate
#if defined(OS_POSIX)
: ipc_fd_(channel->TakeClientFileDescriptor())
#endif // OS_POSIX
- {}
+ {
+ }
~RendererSandboxedProcessLauncherDelegate() override {}
#if defined(OS_WIN)
- void PreSpawnTarget(sandbox::TargetPolicy* policy, bool* success) override {
+ bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
AddBaseHandleClosePolicy(policy);
const base::string16& sid =
@@ -372,7 +386,7 @@ class RendererSandboxedProcessLauncherDelegate
if (!sid.empty())
AddAppContainerPolicy(policy, sid.c_str());
- GetContentClient()->browser()->PreSpawnRenderer(policy, success);
+ return GetContentClient()->browser()->PreSpawnRenderer(policy);
}
#elif defined(OS_POSIX)
@@ -383,12 +397,10 @@ class RendererSandboxedProcessLauncherDelegate
browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
return renderer_prefix.empty();
}
- base::ScopedFD TakeIpcFd() override { return ipc_fd_.Pass(); }
+ base::ScopedFD TakeIpcFd() override { return std::move(ipc_fd_); }
#endif // OS_WIN
- SandboxType GetSandboxType() override {
- return SANDBOX_TYPE_RENDERER;
- }
+ SandboxType GetSandboxType() override { return SANDBOX_TYPE_RENDERER; }
private:
#if defined(OS_POSIX)
@@ -412,7 +424,7 @@ class SessionStorageHolder : public base::SupportsUserData::Data {
}
private:
- std::map<int, SessionStorageNamespaceMap >
+ std::map<int, SessionStorageNamespaceMap>
session_storage_namespaces_awaiting_close_;
DISALLOW_COPY_AND_ASSIGN(SessionStorageHolder);
};
@@ -427,6 +439,24 @@ std::string UintVectorToString(const std::vector<unsigned>& vector) {
return str;
}
+// Copies kEnableFeatures and kDisableFeatures to the renderer command line.
+// Generates them from the FeatureList override state, to take into account
+// overrides from FieldTrials.
+void CopyEnableDisableFeatureFlagsToRenderer(base::CommandLine* renderer_cmd) {
+ std::string enabled_features;
+ std::string disabled_features;
+ base::FeatureList::GetInstance()->GetFeatureOverrides(&enabled_features,
+ &disabled_features);
+ if (!enabled_features.empty()) {
+ renderer_cmd->AppendSwitchASCII(switches::kEnableFeatures,
+ enabled_features);
+ }
+ if (!disabled_features.empty()) {
+ renderer_cmd->AppendSwitchASCII(switches::kDisableFeatures,
+ disabled_features);
+ }
+}
+
} // namespace
RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
@@ -434,7 +464,7 @@ RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
base::MessageLoop* g_in_process_thread;
base::MessageLoop*
- RenderProcessHostImpl::GetInProcessRendererThreadForTesting() {
+RenderProcessHostImpl::GetInProcessRendererThreadForTesting() {
return g_in_process_thread;
}
@@ -508,7 +538,7 @@ RenderProcessHostImpl::RenderProcessHostImpl(
pending_views_(0),
mojo_application_host_(new MojoApplicationHost),
visible_widgets_(0),
- backgrounded_(true),
+ is_process_backgrounded_(false),
is_initialized_(false),
id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
browser_context_(browser_context),
@@ -527,6 +557,9 @@ RenderProcessHostImpl::RenderProcessHostImpl(
subscribe_uniform_enabled_(false),
channel_connected_(false),
sent_render_process_ready_(false),
+#if defined(OS_ANDROID)
+ never_signaled_(true, false),
+#endif
weak_factory_(this) {
widget_helper_ = new RenderWidgetHelper();
@@ -554,10 +587,22 @@ RenderProcessHostImpl::RenderProcessHostImpl(
AddObserver(BootstrapSandboxManager::GetInstance());
#endif
- // Note: When we create the RenderProcessHostImpl, it's technically
- // backgrounded, because it has no visible listeners. But the process
- // doesn't actually exist yet, so we'll Background it later, after
- // creation.
+#if USE_ATTACHMENT_BROKER
+ // Construct the privileged attachment broker early in the life cycle of a
+ // render process. This ensures that when a test is being run in one of the
+ // single process modes, the global attachment broker is the privileged
+ // attachment broker, rather than an unprivileged attachment broker.
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded(
+ MachBroker::GetInstance());
+#else
+ IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded();
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
+#endif // USE_ATTACHMENT_BROKER
+
+#if defined(MOJO_SHELL_CLIENT)
+ RegisterChildWithExternalShell(id_, this);
+#endif
}
// static
@@ -570,8 +615,7 @@ void RenderProcessHostImpl::ShutDownInProcessRenderer() {
case 1: {
RenderProcessHostImpl* host = static_cast<RenderProcessHostImpl*>(
AllHostsIterator().GetCurrentValue());
- FOR_EACH_OBSERVER(RenderProcessHostObserver,
- host->observers_,
+ FOR_EACH_OBSERVER(RenderProcessHostObserver, host->observers_,
RenderProcessHostDestroyed(host));
#ifndef NDEBUG
host->is_self_deleted_ = true;
@@ -607,6 +651,10 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
gpu_observer_registered_ = false;
}
+#if USE_ATTACHMENT_BROKER
+ IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel(
+ channel_.get());
+#endif
// We may have some unsent messages at this point, but that's OK.
channel_.reset();
while (!queued_messages_.empty()) {
@@ -617,7 +665,7 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
UnregisterHost(GetID());
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuShaderDiskCache)) {
+ switches::kDisableGpuShaderDiskCache)) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&RemoveShaderInfo, GetID()));
}
@@ -642,8 +690,8 @@ bool RenderProcessHostImpl::Init() {
browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
#if defined(OS_LINUX)
- int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
- ChildProcessHost::CHILD_NORMAL;
+ int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF
+ : ChildProcessHost::CHILD_NORMAL;
#else
int flags = ChildProcessHost::CHILD_NORMAL;
#endif
@@ -661,6 +709,10 @@ bool RenderProcessHostImpl::Init() {
const std::string channel_id =
IPC::Channel::GenerateVerifiedChannelID(std::string());
channel_ = CreateChannelProxy(channel_id);
+#if USE_ATTACHMENT_BROKER
+ IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel(
+ channel_.get());
+#endif
// Setup the Mojo channel.
mojo_application_host_->Init();
@@ -681,8 +733,9 @@ bool RenderProcessHostImpl::Init() {
// on separate threads.
in_process_renderer_.reset(
g_renderer_main_thread_factory(InProcessChildThreadParams(
- channel_id, BrowserThread::UnsafeGetMessageLoopForThread(
- BrowserThread::IO)->task_runner())));
+ channel_id,
+ BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)
+ ->task_runner())));
base::Thread::Options options;
#if defined(OS_WIN) && !defined(OS_MACOSX)
@@ -717,10 +770,8 @@ bool RenderProcessHostImpl::Init() {
// As long as there's no renderer prefix, we can use the zygote process
// at this stage.
child_process_launcher_.reset(new ChildProcessLauncher(
- new RendererSandboxedProcessLauncherDelegate(channel_.get()),
- cmd_line,
- GetID(),
- this));
+ new RendererSandboxedProcessLauncherDelegate(channel_.get()), cmd_line,
+ GetID(), this));
fast_shutdown_started_ = false;
}
@@ -743,15 +794,37 @@ scoped_ptr<IPC::ChannelProxy> RenderProcessHostImpl::CreateChannelProxy(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
scoped_refptr<base::SequencedTaskRunner> mojo_task_runner =
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)
- ->task_runner();
+ ->task_runner();
if (ShouldUseMojoChannel()) {
VLOG(1) << "Mojo Channel is enabled on host";
+ // Do NOT expand ifdef or run time condition checks here! Synchronous
+ // IPCs from browser process are banned. It is only narrowly allowed
+ // for Android WebView to maintain backward compatibility.
+ // See crbug.com/526842 for details.
+#if defined(OS_ANDROID)
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kIPCSyncCompositing)) {
+ return IPC::SyncChannel::Create(
+ IPC::ChannelMojo::CreateServerFactory(mojo_task_runner, channel_id),
+ this, runner.get(), true, &never_signaled_);
+ }
+#endif // OS_ANDROID
+
return IPC::ChannelProxy::Create(
IPC::ChannelMojo::CreateServerFactory(mojo_task_runner, channel_id),
this, runner.get());
}
+ // Do NOT expand ifdef or run time condition checks here! See comment above.
+#if defined(OS_ANDROID)
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kIPCSyncCompositing)) {
+ return IPC::SyncChannel::Create(channel_id, IPC::Channel::MODE_SERVER, this,
+ runner.get(), true, &never_signaled_);
+ }
+#endif // OS_ANDROID
+
return IPC::ChannelProxy::Create(channel_id, IPC::Channel::MODE_SERVER, this,
runner.get());
}
@@ -772,12 +845,9 @@ void RenderProcessHostImpl::CreateMessageFilters() {
scoped_refptr<RenderMessageFilter> render_message_filter(
new RenderMessageFilter(
- GetID(),
- GetBrowserContext(),
+ GetID(), GetBrowserContext(),
GetBrowserContext()->GetRequestContextForRenderProcess(GetID()),
- widget_helper_.get(),
- audio_manager,
- media_internals,
+ widget_helper_.get(), audio_manager, media_internals,
storage_partition_impl_->GetDOMStorageContext()));
AddFilter(render_message_filter.get());
AddFilter(new RenderFrameMessageFilter(
@@ -817,48 +887,38 @@ void RenderProcessHostImpl::CreateMessageFilters() {
// The AudioInputRendererHost and AudioRendererHost needs to be available for
// lookup, so it's stashed in a member variable.
audio_input_renderer_host_ = new AudioInputRendererHost(
- GetID(),
- base::GetProcId(GetHandle()),
- audio_manager,
- media_stream_manager,
- AudioMirroringManager::GetInstance(),
+ GetID(), base::GetProcId(GetHandle()), audio_manager,
+ media_stream_manager, AudioMirroringManager::GetInstance(),
BrowserMainLoop::GetInstance()->user_input_monitor());
AddFilter(audio_input_renderer_host_.get());
audio_renderer_host_ = new AudioRendererHost(
- GetID(),
- audio_manager,
- AudioMirroringManager::GetInstance(),
- media_internals,
- media_stream_manager,
+ GetID(), audio_manager, AudioMirroringManager::GetInstance(),
+ media_internals, media_stream_manager,
browser_context->GetResourceContext()->GetMediaDeviceIDSalt());
AddFilter(audio_renderer_host_.get());
AddFilter(
new MidiHost(GetID(), BrowserMainLoop::GetInstance()->midi_manager()));
AddFilter(new VideoCaptureHost(media_stream_manager));
AddFilter(new AppCacheDispatcherHost(
- storage_partition_impl_->GetAppCacheService(),
- GetID()));
+ storage_partition_impl_->GetAppCacheService(), GetID()));
AddFilter(new ClipboardMessageFilter);
AddFilter(new DOMStorageMessageFilter(
storage_partition_impl_->GetDOMStorageContext()));
AddFilter(new IndexedDBDispatcherHost(
- GetID(),
- storage_partition_impl_->GetURLRequestContext(),
+ GetID(), storage_partition_impl_->GetURLRequestContext(),
storage_partition_impl_->GetIndexedDBContext(),
ChromeBlobStorageContext::GetFor(browser_context)));
- gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get());
+ gpu_message_filter_ = new GpuMessageFilter(GetID());
AddFilter(gpu_message_filter_);
#if defined(ENABLE_WEBRTC)
AddFilter(new WebRTCIdentityServiceHost(
- GetID(),
- storage_partition_impl_->GetWebRTCIdentityStore(),
+ GetID(), storage_partition_impl_->GetWebRTCIdentityStore(),
resource_context));
peer_connection_tracker_host_ = new PeerConnectionTrackerHost(GetID());
AddFilter(peer_connection_tracker_host_.get());
AddFilter(new MediaStreamDispatcherHost(
- GetID(),
- browser_context->GetResourceContext()->GetMediaDeviceIDSalt(),
+ GetID(), browser_context->GetResourceContext()->GetMediaDeviceIDSalt(),
media_stream_manager));
AddFilter(new MediaStreamTrackMetricsHost());
#endif
@@ -868,18 +928,19 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(new SpeechRecognitionDispatcherHost(
GetID(), storage_partition_impl_->GetURLRequestContext()));
AddFilter(new FileAPIMessageFilter(
- GetID(),
- storage_partition_impl_->GetURLRequestContext(),
+ GetID(), storage_partition_impl_->GetURLRequestContext(),
storage_partition_impl_->GetFileSystemContext(),
ChromeBlobStorageContext::GetFor(browser_context),
StreamContext::GetFor(browser_context)));
AddFilter(new FileUtilitiesMessageFilter(GetID()));
AddFilter(new MimeRegistryMessageFilter());
- AddFilter(new DatabaseMessageFilter(
- storage_partition_impl_->GetDatabaseTracker()));
+ AddFilter(
+ new DatabaseMessageFilter(storage_partition_impl_->GetDatabaseTracker()));
#if defined(OS_MACOSX)
AddFilter(new TextInputClientMessageFilter(GetID()));
#elif defined(OS_WIN)
+ AddFilter(new DWriteFontProxyMessageFilter());
+
// The FontCacheDispatcher is required only when we're using GDI rendering.
// TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
// GDI fonts (http://crbug.com/383227), even when using DirectWrite. This
@@ -895,8 +956,8 @@ void RenderProcessHostImpl::CreateMessageFilters() {
WebSocketDispatcherHost::GetRequestContextCallback
websocket_request_context_callback(
- base::Bind(&GetRequestContext, request_context,
- media_request_context, RESOURCE_TYPE_SUB_RESOURCE));
+ base::Bind(&GetRequestContext, request_context, media_request_context,
+ RESOURCE_TYPE_SUB_RESOURCE));
AddFilter(
new WebSocketDispatcherHost(GetID(), websocket_request_context_callback));
@@ -919,8 +980,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(service_worker_filter.get());
AddFilter(new SharedWorkerMessageFilter(
- GetID(),
- resource_context,
+ GetID(), resource_context,
WorkerStoragePartition(
storage_partition_impl_->GetURLRequestContext(),
storage_partition_impl_->GetMediaURLRequestContext(),
@@ -943,31 +1003,29 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(new ResolveProxyMsgHelper(
browser_context->GetRequestContextForRenderProcess(GetID())));
AddFilter(new QuotaDispatcherHost(
- GetID(),
- storage_partition_impl_->GetQuotaManager(),
+ GetID(), storage_partition_impl_->GetQuotaManager(),
GetContentClient()->browser()->CreateQuotaPermissionContext()));
notification_message_filter_ = new NotificationMessageFilter(
- GetID(),
- storage_partition_impl_->GetPlatformNotificationContext(),
- resource_context,
- browser_context);
+ GetID(), storage_partition_impl_->GetPlatformNotificationContext(),
+ resource_context, browser_context);
AddFilter(notification_message_filter_.get());
AddFilter(new GamepadBrowserMessageFilter());
AddFilter(new DeviceLightMessageFilter());
AddFilter(new DeviceMotionMessageFilter());
AddFilter(new DeviceOrientationMessageFilter());
+ AddFilter(new DeviceOrientationAbsoluteMessageFilter());
AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER));
AddFilter(new HistogramMessageFilter());
#if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID))
if (browser_command_line.HasSwitch(switches::kEnableMemoryBenchmarking))
AddFilter(new MemoryBenchmarkMessageFilter());
#endif
- AddFilter(new MemoryMessageFilter());
+ AddFilter(new MemoryMessageFilter(this));
AddFilter(new PushMessagingMessageFilter(
GetID(), storage_partition_impl_->GetServiceWorkerContext()));
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
AddFilter(new ScreenOrientationMessageFilterAndroid());
#endif
AddFilter(new GeofencingDispatcherHost(
@@ -1054,10 +1112,9 @@ void RenderProcessHostImpl::SendUpdateValueState(unsigned int target,
const gpu::ValueState& state) {
DCHECK(subscribe_uniform_enabled_);
if (subscription_set_.find(target) != subscription_set_.end()) {
- GpuProcessHost::SendOnIO(
- GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
- CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
- new GpuMsg_UpdateValueState(id_, target, state));
+ GpuProcessHost::SendOnIO(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
+ new GpuMsg_UpdateValueState(id_, target, state));
} else {
// Store the ValueState locally in case a Valuebuffer subscribes to it later
pending_valuebuffer_state_->UpdateState(target, state);
@@ -1065,8 +1122,9 @@ void RenderProcessHostImpl::SendUpdateValueState(unsigned int target,
}
#if defined(ENABLE_BROWSER_CDMS)
-media::BrowserCdm* RenderProcessHostImpl::GetBrowserCdm(int render_frame_id,
- int cdm_id) const {
+scoped_refptr<media::MediaKeys> RenderProcessHostImpl::GetCdm(
+ int render_frame_id,
+ int cdm_id) const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserCdmManager* manager = BrowserCdmManager::FromProcess(GetID());
if (!manager)
@@ -1075,15 +1133,33 @@ media::BrowserCdm* RenderProcessHostImpl::GetBrowserCdm(int render_frame_id,
}
#endif
-void RenderProcessHostImpl::AddRoute(
- int32 routing_id,
- IPC::Listener* listener) {
- CHECK(!listeners_.Lookup(routing_id))
- << "Found Routing ID Conflict: " << routing_id;
+bool RenderProcessHostImpl::IsProcessBackgrounded() const {
+ return is_process_backgrounded_;
+}
+
+void RenderProcessHostImpl::IncrementWorkerRefCount() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ++worker_ref_count_;
+ if (worker_ref_count_ > max_worker_count_)
+ max_worker_count_ = worker_ref_count_;
+}
+
+void RenderProcessHostImpl::DecrementWorkerRefCount() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_GT(worker_ref_count_, 0);
+ --worker_ref_count_;
+ if (worker_ref_count_ == 0)
+ Cleanup();
+}
+
+void RenderProcessHostImpl::AddRoute(int32_t routing_id,
+ IPC::Listener* listener) {
+ CHECK(!listeners_.Lookup(routing_id)) << "Found Routing ID Conflict: "
+ << routing_id;
listeners_.AddWithID(listener, routing_id);
}
-void RenderProcessHostImpl::RemoveRoute(int32 routing_id) {
+void RenderProcessHostImpl::RemoveRoute(int32_t routing_id) {
DCHECK(listeners_.Lookup(routing_id) != NULL);
listeners_.Remove(routing_id);
@@ -1117,23 +1193,20 @@ void RenderProcessHostImpl::ShutdownForBadMessage() {
}
void RenderProcessHostImpl::WidgetRestored() {
- // Verify we were properly backgrounded.
- DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
visible_widgets_++;
- SetBackgrounded(false);
+ UpdateProcessPriority();
+ DCHECK(!is_process_backgrounded_);
}
void RenderProcessHostImpl::WidgetHidden() {
- // On startup, the browser will call Hide
- if (backgrounded_)
+ // On startup, the browser will call Hide. We ignore this call.
+ if (visible_widgets_ == 0)
return;
- DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
- visible_widgets_--;
- DCHECK_GE(visible_widgets_, 0);
+ --visible_widgets_;
if (visible_widgets_ == 0) {
- DCHECK(!backgrounded_);
- SetBackgrounded(true);
+ DCHECK(!is_process_backgrounded_);
+ UpdateProcessPriority();
}
}
@@ -1141,6 +1214,10 @@ int RenderProcessHostImpl::VisibleWidgetCount() const {
return visible_widgets_;
}
+void RenderProcessHostImpl::AudioStateChanged() {
+ UpdateProcessPriority();
+}
+
bool RenderProcessHostImpl::IsForGuestsOnly() const {
return is_for_guests_only_;
}
@@ -1162,22 +1239,30 @@ static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
int msaa_sample_count = GpuRasterizationMSAASampleCount();
if (msaa_sample_count >= 0) {
- command_line->AppendSwitchASCII(
- switches::kGpuRasterizationMSAASampleCount,
- base::IntToString(msaa_sample_count));
+ command_line->AppendSwitchASCII(switches::kGpuRasterizationMSAASampleCount,
+ base::IntToString(msaa_sample_count));
}
if (IsZeroCopyUploadEnabled())
command_line->AppendSwitch(switches::kEnableZeroCopy);
- if (IsPersistentGpuMemoryBufferEnabled())
- command_line->AppendSwitch(switches::kEnablePersistentGpuMemoryBuffer);
+ if (IsPartialRasterEnabled())
+ command_line->AppendSwitch(switches::kEnablePartialRaster);
if (IsForceGpuRasterizationEnabled())
command_line->AppendSwitch(switches::kForceGpuRasterization);
- gfx::BufferUsage buffer_usage = IsPersistentGpuMemoryBufferEnabled()
- ? gfx::BufferUsage::PERSISTENT_MAP
- : gfx::BufferUsage::MAP;
+ if (IsGpuMemoryBufferCompositorResourcesEnabled()) {
+ command_line->AppendSwitch(
+ switches::kEnableGpuMemoryBufferCompositorResources);
+ }
+
+ // Persistent buffers may come at a performance hit (not all platform specific
+ // buffers support it), so only enable them if partial raster is enabled and
+ // we are actually going to use them.
+ gfx::BufferUsage buffer_usage =
+ IsPartialRasterEnabled()
+ ? gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT
+ : gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;
std::vector<unsigned> image_targets(
static_cast<size_t>(gfx::BufferFormat::LAST) + 1, GL_TEXTURE_2D);
for (size_t format = 0;
@@ -1192,7 +1277,7 @@ static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
command_line->AppendSwitchASCII(
switches::kVideoImageTextureTarget,
base::UintToString(BrowserGpuMemoryBufferManager::GetImageTextureTarget(
- gfx::BufferFormat::R_8, gfx::BufferUsage::MAP)));
+ gfx::BufferFormat::R_8, gfx::BufferUsage::GPU_READ_CPU_READ_WRITE)));
// Appending disable-gpu-feature switches due to software rendering list.
GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
@@ -1226,8 +1311,8 @@ void RenderProcessHostImpl::AppendRendererCommandLine(
field_trial_states);
}
- GetContentClient()->browser()->AppendExtraCommandLineSwitches(
- command_line, GetID());
+ GetContentClient()->browser()->AppendExtraCommandLineSwitches(command_line,
+ GetID());
if (IsPinchToZoomEnabled())
command_line->AppendSwitch(switches::kEnablePinch);
@@ -1246,6 +1331,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
// Propagate the following switches to the renderer command line (along
// with any associated values) if present in the browser command line.
static const char* const kSwitchNames[] = {
+ switches::kAgcStartupMinVolume,
switches::kAllowLoopbackInPeerConnection,
switches::kAudioBufferSize,
switches::kBlinkPlatformLogChannels,
@@ -1257,6 +1343,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableAcceleratedVideoDecode,
switches::kDisableBlinkFeatures,
switches::kDisableBreakpad,
+ switches::kDisableCompositorAnimationTimelines,
switches::kDisablePreferCompositingToLCDText,
switches::kDisableDatabases,
switches::kDisableDelayAgnosticAec,
@@ -1264,7 +1351,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableDisplayList2dCanvas,
switches::kDisableDistanceFieldText,
switches::kDisableEncryptedMedia,
- switches::kDisableFeatures,
switches::kDisableFileSystem,
switches::kDisableGestureRequirementForMediaPlayback,
switches::kDisableGpuCompositing,
@@ -1277,6 +1363,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableLocalStorage,
switches::kDisableLogging,
switches::kDisableMediaSource,
+ switches::kDisableMediaSuspend,
switches::kDisableMojoChannel,
switches::kDisableNotifications,
switches::kDisableOverlayScrollbar,
@@ -1284,27 +1371,25 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisablePresentationAPI,
switches::kDisablePinch,
switches::kDisableRGBA4444Textures,
+ switches::kDisableRTCSmoothnessAlgorithm,
switches::kDisableSeccompFilterSandbox,
switches::kDisableSharedWorkers,
+ switches::kDisableSmoothScrolling,
switches::kDisableSpeechAPI,
- switches::kDisableSVG1DOM,
switches::kDisableThreadedCompositing,
switches::kDisableThreadedScrolling,
switches::kDisableTouchAdjustment,
switches::kDisableTouchDragDrop,
- switches::kDisableTouchEditing,
switches::kDisableV8IdleTasks,
switches::kDomAutomationController,
- switches::kEnableBleedingEdgeRenderingFastPaths,
switches::kEnableBlinkFeatures,
switches::kEnableBrowserSideNavigation,
- switches::kEnableCompositorAnimationTimelines,
switches::kEnableCredentialManagerAPI,
switches::kEnableDisplayList2dCanvas,
switches::kEnableDistanceFieldText,
switches::kEnableExperimentalCanvasFeatures,
switches::kEnableExperimentalWebPlatformFeatures,
- switches::kEnableFeatures,
+ switches::kEnableHeapProfiling,
switches::kEnableGPUClientLogging,
switches::kEnableGpuClientTracing,
switches::kEnableGpuMemoryBufferVideoFrames,
@@ -1312,6 +1397,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnableIconNtp,
switches::kEnableLinkDisambiguationPopup,
switches::kEnableLowResTiling,
+ switches::kEnableMediaSuspend,
switches::kEnableInbandTextTracks,
switches::kEnableLCDText,
switches::kEnableLogging,
@@ -1323,19 +1409,16 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnablePreciseMemoryInfo,
switches::kEnablePreferCompositingToLCDText,
switches::kEnablePrefixedEncryptedMedia,
- switches::kEnablePushMessagePayload,
switches::kEnableRGBA4444Textures,
switches::kEnableRendererMojoChannel,
- switches::kEnableRTCSmoothnessAlgorithm,
- switches::kEnableSeccompFilterSandbox,
switches::kEnableSkiaBenchmarking,
switches::kEnableSlimmingPaintV2,
switches::kEnableSmoothScrolling,
switches::kEnableStatsTable,
switches::kEnableThreadedCompositing,
switches::kEnableTouchDragDrop,
- switches::kEnableTouchEditing,
switches::kEnableUnsafeES3APIs,
+ switches::kEnableUseZoomForDSF,
switches::kEnableViewport,
switches::kEnableVtune,
switches::kEnableWebBluetooth,
@@ -1347,7 +1430,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kForceDisplayList2dCanvas,
switches::kForceOverlayFullscreenVideo,
switches::kFullMemoryCrashReport,
- switches::kInertVisualViewport,
switches::kIPCConnectionTimeout,
switches::kJavaScriptFlags,
switches::kLoggingLevel,
@@ -1373,25 +1455,30 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kTouchTextSelectionStrategy,
switches::kTraceConfigFile,
switches::kTraceToConsole,
+ switches::kUseCrossProcessFramesForGuests,
+ switches::kUseFakeUIForMediaStream,
// This flag needs to be propagated to the renderer process for
// --in-process-webgl.
switches::kUseGL,
switches::kUseMobileUserAgent,
+ switches::kUseNewMediaCache,
switches::kUseNormalPriorityForTileTaskWorkerThreads,
+ switches::kUseRemoteCompositing,
switches::kV,
switches::kVideoThreads,
switches::kVideoUnderflowThresholdMs,
switches::kVModule,
// Please keep these in alphabetical order. Compositor switches here should
// also be added to chrome/browser/chromeos/login/chrome_restart_request.cc.
+ cc::switches::kDisableCachedPictureRaster,
cc::switches::kDisableCompositedAntialiasing,
+ cc::switches::kDisableCompositorPropertyTrees,
cc::switches::kDisableMainFrameBeforeActivation,
cc::switches::kDisableThreadedAnimation,
cc::switches::kEnableBeginFrameScheduling,
cc::switches::kEnableGpuBenchmarking,
cc::switches::kEnableMainFrameBeforeActivation,
cc::switches::kShowCompositedLayerBorders,
- cc::switches::kShowFPSCounter,
cc::switches::kShowLayerAnimationBounds,
cc::switches::kShowPropertyChangedRects,
cc::switches::kShowReplicaScreenSpaceRects,
@@ -1402,6 +1489,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
cc::switches::kTopControlsHideThreshold,
cc::switches::kTopControlsShowThreshold,
+ scheduler::switches::kEnableVirtualizedTime,
+ scheduler::switches::kDisableBackgroundTimerThrottling,
+
#if defined(ENABLE_PLUGINS)
switches::kEnablePepperTesting,
#endif
@@ -1411,12 +1501,16 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnableWebRtcDtls12,
switches::kEnableWebRtcHWH264Encoding,
switches::kEnableWebRtcStunOrigin,
+ switches::kEnforceWebRtcIPPermissionCheck,
+ switches::kForceWebRtcIPHandlingPolicy,
switches::kWebRtcMaxCaptureFramerate,
#endif
switches::kEnableLowEndDeviceMode,
switches::kDisableLowEndDeviceMode,
#if defined(OS_ANDROID)
switches::kDisableWebAudio,
+ switches::kEnableUnifiedMediaPipeline,
+ switches::kIPCSyncCompositing,
switches::kRendererWaitForJavaDebugger,
#endif
#if defined(OS_MACOSX)
@@ -1439,6 +1533,8 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
arraysize(kSwitchNames));
+ CopyEnableDisableFeatureFlagsToRenderer(renderer_cmd);
+
if (browser_cmd.HasSwitch(switches::kTraceStartup) &&
BrowserMainLoop::GetInstance()->is_tracing_startup_for_duration()) {
// Pass kTraceStartup switch to renderer only if startup tracing has not
@@ -1475,6 +1571,11 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
renderer_cmd->AppendSwitch(switches::kWaitForDebugger);
}
}
+
+#if defined(MOJO_SHELL_CLIENT)
+ if (IsRunningInMojoShell())
+ renderer_cmd->AppendSwitch(switches::kEnableMojoShellConnection);
+#endif
}
base::ProcessHandle RenderProcessHostImpl::GetHandle() const {
@@ -1516,8 +1617,7 @@ bool RenderProcessHostImpl::FastShutdownIfPossible() {
if (!GetContentClient()->browser()->IsFastShutdownPossible())
return false;
- if (!child_process_launcher_.get() ||
- child_process_launcher_->IsStarting() ||
+ if (!child_process_launcher_.get() || child_process_launcher_->IsStarting() ||
!GetHandle())
return false; // Render process hasn't started or is probably crashed.
@@ -1547,6 +1647,7 @@ bool RenderProcessHostImpl::Send(IPC::Message* msg) {
TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send");
if (!channel_) {
if (!is_initialized_) {
+ DCHECK(!msg->is_sync());
queued_messages_.push(msg);
return true;
} else {
@@ -1580,17 +1681,20 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
SuddenTerminationChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
OnUserMetricsRecordAction)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
IPC_MESSAGE_HANDLER(ViewHostMsg_Close_ACK, OnCloseACK)
#if defined(ENABLE_WEBRTC)
IPC_MESSAGE_HANDLER(AecDumpMsg_RegisterAecDumpConsumer,
OnRegisterAecDumpConsumer)
+ IPC_MESSAGE_HANDLER(WebRTCEventLogMsg_RegisterEventLogConsumer,
+ OnRegisterEventLogConsumer)
IPC_MESSAGE_HANDLER(AecDumpMsg_UnregisterAecDumpConsumer,
OnUnregisterAecDumpConsumer)
+ IPC_MESSAGE_HANDLER(WebRTCEventLogMsg_UnregisterEventLogConsumer,
+ OnUnregisterEventLogConsumer)
#endif
- // Adding single handlers for your service here is fine, but once your
- // service needs more than one handler, please extract them into a new
- // message filter and add that filter to CreateMessageFilters().
+ // Adding single handlers for your service here is fine, but once your
+ // service needs more than one handler, please extract them into a new
+ // message filter and add that filter to CreateMessageFilters().
IPC_END_MESSAGE_MAP()
return true;
@@ -1611,7 +1715,7 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
return listener->OnMessageReceived(msg);
}
-void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
+void RenderProcessHostImpl::OnChannelConnected(int32_t peer_pid) {
channel_connected_ = true;
if (IsReady()) {
DCHECK(!sent_render_process_ready_);
@@ -1631,13 +1735,6 @@ void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
tracked_objects::ThreadData::status();
Send(new ChildProcessMsg_SetProfilerStatus(status));
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- io_surface_manager_token_ =
- BrowserIOSurfaceManager::GetInstance()->GenerateChildProcessToken(
- GetID());
- Send(new ChildProcessMsg_SetIOSurfaceManagerToken(io_surface_manager_token_));
-#endif
-
#if defined(USE_OZONE)
Send(new ChildProcessMsg_InitializeClientNativePixmapFactory(
base::FileDescriptor(
@@ -1645,13 +1742,11 @@ void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
#endif
// Inform AudioInputRendererHost about the new render process PID.
- // AudioInputRendererHost is reference counted, so it's lifetime is
- // guarantueed during the lifetime of the closure.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&AudioInputRendererHost::set_renderer_pid,
- audio_input_renderer_host_,
- peer_pid));
+ // AudioInputRendererHost is reference counted, so its lifetime is
+ // guaranteed during the lifetime of the closure.
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&AudioInputRendererHost::set_renderer_pid,
+ audio_input_renderer_host_, peer_pid));
}
void RenderProcessHostImpl::OnChannelError() {
@@ -1718,6 +1813,13 @@ void RenderProcessHostImpl::Cleanup() {
survive_for_worker_start_time_ = base::TimeTicks::Now();
}
+#if defined(ENABLE_WEBRTC)
+ if (is_initialized_) {
+ BrowserMainLoop::GetInstance()->media_stream_manager()->
+ UnregisterNativeLogCallback(GetID());
+ }
+#endif
+
// When there are no other owners of this object, we can delete ourselves.
if (listeners_.IsEmpty() && worker_ref_count_ == 0) {
if (!survive_for_worker_start_time_.is_null()) {
@@ -1738,19 +1840,34 @@ void RenderProcessHostImpl::Cleanup() {
DCHECK(!deleting_soon_);
DCHECK_EQ(0, pending_views_);
- FOR_EACH_OBSERVER(RenderProcessHostObserver,
- observers_,
+
+ // If |channel_| is still valid, the process associated with this
+ // RenderProcessHost is still alive. Notify all observers that the process
+ // has exited cleanly, even though it will be destroyed a bit later.
+ // Observers shouldn't rely on this process anymore.
+ if (channel_.get()) {
+ FOR_EACH_OBSERVER(
+ RenderProcessHostObserver, observers_,
+ RenderProcessExited(this, base::TERMINATION_STATUS_NORMAL_TERMINATION,
+ 0));
+ }
+ FOR_EACH_OBSERVER(RenderProcessHostObserver, observers_,
RenderProcessHostDestroyed(this));
NotificationService::current()->Notify(
NOTIFICATION_RENDERER_PROCESS_TERMINATED,
- Source<RenderProcessHost>(this),
- NotificationService::NoDetails());
+ Source<RenderProcessHost>(this), NotificationService::NoDetails());
#ifndef NDEBUG
is_self_deleted_ = true;
#endif
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
deleting_soon_ = true;
+
+#if USE_ATTACHMENT_BROKER
+ IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel(
+ channel_.get());
+#endif
+
// It's important not to wait for the DeleteTask to delete the channel
// proxy. Kill it off now. That way, in case the profile is going away, the
// rest of the objects attached to this RenderProcessHost start going
@@ -1764,17 +1881,17 @@ void RenderProcessHostImpl::Cleanup() {
RemoveUserData(kSessionStorageHolderKey);
+ // On shutdown, |this| may not be deleted because the deleter is posted to
+ // the current MessageLoop, but MessageLoop deletes all its pending
+ // callbacks on shutdown. Since the deleter takes |this| as a raw pointer,
+ // deleting the callback doesn't delete |this| resulting in a memory leak.
+ // Valgrind complains, so delete |mojo_application_host_| explicitly here to
+ // stop valgrind from complaining.
+ mojo_application_host_.reset();
+
// Remove ourself from the list of renderer processes so that we can't be
// reused in between now and when the Delete task runs.
UnregisterHost(GetID());
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- if (!io_surface_manager_token_.IsZero()) {
- BrowserIOSurfaceManager::GetInstance()->InvalidateChildProcessToken(
- io_surface_manager_token_);
- io_surface_manager_token_.SetZero();
- }
-#endif
}
}
@@ -1813,20 +1930,21 @@ void RenderProcessHostImpl::EnableAudioDebugRecordings(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Enable AEC dump for each registered consumer.
- base::FilePath file_with_extensions =
- GetAecDumpFilePathWithExtensions(file);
+ base::FilePath file_with_extensions = GetAecDumpFilePathWithExtensions(file);
for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
it != aec_dump_consumers_.end(); ++it) {
EnableAecDumpForId(file_with_extensions, *it);
}
// Enable mic input recording. AudioInputRendererHost is reference counted, so
- // it's lifetime is guarantueed during the lifetime of the closure.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&AudioInputRendererHost::EnableDebugRecording,
- audio_input_renderer_host_,
- file));
+ // its lifetime is guaranteed during the lifetime of the closure.
+ if (audio_input_renderer_host_) {
+ // Not null if RenderProcessHostImpl::Init has already been called.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&AudioInputRendererHost::EnableDebugRecording,
+ audio_input_renderer_host_, file));
+ }
}
void RenderProcessHostImpl::DisableAudioDebugRecordings() {
@@ -1836,23 +1954,49 @@ void RenderProcessHostImpl::DisableAudioDebugRecordings() {
// for avoiding races between enable and disable. Nothing is done on the FILE
// thread.
BrowserThread::PostTaskAndReply(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&DisableAecDumpOnFileThread),
+ BrowserThread::FILE, FROM_HERE, base::Bind(&DisableAecDumpOnFileThread),
base::Bind(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
weak_factory_.GetWeakPtr()));
// AudioInputRendererHost is reference counted, so it's lifetime is
// guaranteed during the lifetime of the closure.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(
- &AudioInputRendererHost::DisableDebugRecording,
- audio_input_renderer_host_));
+ if (audio_input_renderer_host_) {
+ // Not null if RenderProcessHostImpl::Init has already been called.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&AudioInputRendererHost::DisableDebugRecording,
+ audio_input_renderer_host_));
+ }
+}
+
+void RenderProcessHostImpl::EnableEventLogRecordings(
+ const base::FilePath& file) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Enable Event log for each registered consumer.
+ base::FilePath file_with_extensions = GetEventLogFilePathWithExtensions(file);
+ for (int id : aec_dump_consumers_)
+ EnableEventLogForId(file_with_extensions, id);
+}
+
+void RenderProcessHostImpl::DisableEventLogRecordings() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Posting on the FILE thread and then replying back on the UI thread is only
+ // for avoiding races between enable and disable. Nothing is done on the FILE
+ // thread.
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE, FROM_HERE, base::Bind(&DisableAecDumpOnFileThread),
+ base::Bind(&RenderProcessHostImpl::SendDisableEventLogToRenderer,
+ weak_factory_.GetWeakPtr()));
}
void RenderProcessHostImpl::SetWebRtcLogMessageCallback(
base::Callback<void(const std::string&)> callback) {
- webrtc_log_message_callback_ = callback;
+#if defined(ENABLE_WEBRTC)
+ BrowserMainLoop::GetInstance()->media_stream_manager()->
+ RegisterNativeLogCallback(GetID(), callback);
+#endif
}
RenderProcessHostImpl::WebRtcStopRtpDumpCallback
@@ -1863,13 +2007,10 @@ RenderProcessHostImpl::StartRtpDump(
if (!p2p_socket_dispatcher_host_.get())
return WebRtcStopRtpDumpCallback();
- BrowserThread::PostTask(BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&P2PSocketDispatcherHost::StartRtpDump,
- p2p_socket_dispatcher_host_,
- incoming,
- outgoing,
- packet_callback));
+ p2p_socket_dispatcher_host_, incoming,
+ outgoing, packet_callback));
if (stop_rtp_dump_callback_.is_null()) {
stop_rtp_dump_callback_ =
@@ -1951,7 +2092,8 @@ void RenderProcessHostImpl::FilterURL(RenderProcessHost* rph,
// Do not allow browser plugin guests to navigate to non-web URLs, since they
// cannot swap processes or grant bindings.
- bool non_web_url_in_guest = rph->IsForGuestsOnly() &&
+ bool non_web_url_in_guest =
+ rph->IsForGuestsOnly() &&
!(url->is_valid() && policy->IsWebSafeScheme(url->scheme()));
if (non_web_url_in_guest || !policy->CanRequestURL(rph->GetID(), *url)) {
@@ -1964,10 +2106,9 @@ void RenderProcessHostImpl::FilterURL(RenderProcessHost* rph,
}
// static
-bool RenderProcessHostImpl::IsSuitableHost(
- RenderProcessHost* host,
- BrowserContext* browser_context,
- const GURL& site_url) {
+bool RenderProcessHostImpl::IsSuitableHost(RenderProcessHost* host,
+ BrowserContext* browser_context,
+ const GURL& site_url) {
if (run_renderer_in_process())
return true;
@@ -2039,19 +2180,22 @@ RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
// static
bool RenderProcessHost::ShouldTryToUseExistingProcessHost(
- BrowserContext* browser_context, const GURL& url) {
+ BrowserContext* browser_context,
+ const GURL& url) {
+ // This needs to be checked first to ensure that --single-process
+ // and --site-per-process can be used together.
+ if (run_renderer_in_process())
+ return true;
+
// If --site-per-process is enabled, do not try to reuse renderer processes
// when over the limit.
// TODO(nick): This is overly conservative and isn't launchable. Move this
// logic into IsSuitableHost, and check |url| against the URL the process is
// dedicated to. This will allow pages from the same site to share, and will
// also allow non-isolated sites to share processes. https://crbug.com/513036
- if (SiteIsolationPolicy::AreCrossProcessFramesPossible())
+ if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites())
return false;
- if (run_renderer_in_process())
- return true;
-
// NOTE: Sometimes it's necessary to create more render processes than
// GetMaxRendererProcessCount(), for instance when we want to create
// a renderer process for a browser context that has no existing
@@ -2060,8 +2204,8 @@ bool RenderProcessHost::ShouldTryToUseExistingProcessHost(
if (g_all_hosts.Get().size() >= GetMaxRendererProcessCount())
return true;
- return GetContentClient()->browser()->
- ShouldTryToUseExistingProcessHost(browser_context, url);
+ return GetContentClient()->browser()->ShouldTryToUseExistingProcessHost(
+ browser_context, url);
}
// static
@@ -2075,9 +2219,8 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
iterator iter(AllHostsIterator());
while (!iter.IsAtEnd()) {
if (GetContentClient()->browser()->MayReuseHost(iter.GetCurrentValue()) &&
- RenderProcessHostImpl::IsSuitableHost(
- iter.GetCurrentValue(),
- browser_context, site_url)) {
+ RenderProcessHostImpl::IsSuitableHost(iter.GetCurrentValue(),
+ browser_context, site_url)) {
suitable_renderers.push_back(iter.GetCurrentValue());
}
iter.Advance();
@@ -2094,9 +2237,8 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
}
// static
-bool RenderProcessHost::ShouldUseProcessPerSite(
- BrowserContext* browser_context,
- const GURL& url) {
+bool RenderProcessHost::ShouldUseProcessPerSite(BrowserContext* browser_context,
+ const GURL& url) {
// Returns true if we should use the process-per-site model. This will be
// the case if the --process-per-site switch is specified, or in
// process-per-site-instance for particular sites (e.g., WebUI).
@@ -2125,13 +2267,12 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite(
BrowserContext* browser_context,
const GURL& url) {
// Look up the map of site to process for the given browser_context.
- SiteProcessMap* map =
- GetSiteProcessMapForBrowserContext(browser_context);
+ SiteProcessMap* map = GetSiteProcessMapForBrowserContext(browser_context);
// See if we have an existing process with appropriate bindings for this site.
// If not, the caller should create a new process and register it.
- std::string site = SiteInstance::GetSiteForURL(browser_context, url)
- .possibly_invalid_spec();
+ std::string site =
+ SiteInstance::GetSiteForURL(browser_context, url).possibly_invalid_spec();
RenderProcessHost* host = map->FindProcess(site);
if (host && (!GetContentClient()->browser()->MayReuseHost(host) ||
!IsSuitableHost(host, browser_context, url))) {
@@ -2151,14 +2292,13 @@ void RenderProcessHostImpl::RegisterProcessHostForSite(
RenderProcessHost* process,
const GURL& url) {
// Look up the map of site to process for the given browser_context.
- SiteProcessMap* map =
- GetSiteProcessMapForBrowserContext(browser_context);
+ SiteProcessMap* map = GetSiteProcessMapForBrowserContext(browser_context);
// Only register valid, non-empty sites. Empty or invalid sites will not
// use process-per-site mode. We cannot check whether the process has
// appropriate bindings here, because the bindings have not yet been granted.
- std::string site = SiteInstance::GetSiteForURL(browser_context, url)
- .possibly_invalid_spec();
+ std::string site =
+ SiteInstance::GetSiteForURL(browser_context, url).possibly_invalid_spec();
if (!site.empty())
map->RegisterProcess(site, process);
}
@@ -2203,19 +2343,28 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
mojo_application_host_->WillDestroySoon();
child_process_launcher_.reset();
+#if USE_ATTACHMENT_BROKER
+ IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel(
+ channel_.get());
+#endif
channel_.reset();
while (!queued_messages_.empty()) {
delete queued_messages_.front();
queued_messages_.pop();
}
+ UpdateProcessPriority();
+ DCHECK(!is_process_backgrounded_);
+
+ // RenderProcessExited observers and RenderProcessGone handlers might
+ // navigate or perform other actions that require a connection. Ensure that
+ // there is one before calling them.
+ mojo_application_host_.reset(new MojoApplicationHost);
within_process_died_observer_ = true;
NotificationService::current()->Notify(
- NOTIFICATION_RENDERER_PROCESS_CLOSED,
- Source<RenderProcessHost>(this),
+ NOTIFICATION_RENDERER_PROCESS_CLOSED, Source<RenderProcessHost>(this),
Details<RendererClosedDetails>(&details));
- FOR_EACH_OBSERVER(RenderProcessHostObserver,
- observers_,
+ FOR_EACH_OBSERVER(RenderProcessHostObserver, observers_,
RenderProcessExited(this, status, exit_code));
within_process_died_observer_ = false;
@@ -2223,16 +2372,10 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
message_port_message_filter_ = NULL;
RemoveUserData(kSessionStorageHolderKey);
- // RenderProcessGone handlers might navigate or perform other actions that
- // require a connection. Ensure that there is one before calling them.
- mojo_application_host_.reset(new MojoApplicationHost);
-
IDMap<IPC::Listener>::iterator iter(&listeners_);
while (!iter.IsAtEnd()) {
- iter.GetCurrentValue()->OnMessageReceived(
- FrameHostMsg_RenderProcessGone(iter.GetCurrentKey(),
- static_cast<int>(status),
- exit_code));
+ iter.GetCurrentValue()->OnMessageReceived(FrameHostMsg_RenderProcessGone(
+ iter.GetCurrentKey(), static_cast<int>(status), exit_code));
iter.Advance();
}
@@ -2257,14 +2400,6 @@ size_t RenderProcessHost::GetActiveViewCount() {
return num_active_views;
}
-#if defined(ENABLE_WEBRTC)
-void RenderProcessHostImpl::WebRtcLogMessage(const std::string& message) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!webrtc_log_message_callback_.is_null())
- webrtc_log_message_callback_.Run(message);
-}
-#endif
-
void RenderProcessHostImpl::ReleaseOnCloseACK(
RenderProcessHost* host,
const SessionStorageNamespaceMap& sessions,
@@ -2272,13 +2407,11 @@ void RenderProcessHostImpl::ReleaseOnCloseACK(
DCHECK(host);
if (sessions.empty())
return;
- SessionStorageHolder* holder = static_cast<SessionStorageHolder*>
- (host->GetUserData(kSessionStorageHolderKey));
+ SessionStorageHolder* holder = static_cast<SessionStorageHolder*>(
+ host->GetUserData(kSessionStorageHolderKey));
if (!holder) {
holder = new SessionStorageHolder();
- host->SetUserData(
- kSessionStorageHolderKey,
- holder);
+ host->SetUserData(kSessionStorageHolderKey, holder);
}
holder->Hold(sessions, view_route_id);
}
@@ -2304,24 +2437,29 @@ void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) {
SetSuddenTerminationAllowed(enabled);
}
-void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
- TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::SetBackgrounded",
- "backgrounded", backgrounded);
- // Note: we always set the backgrounded_ value. If the process is NULL
- // (and hence hasn't been created yet), we will set the process priority
- // later when we create the process.
- backgrounded_ = backgrounded;
- if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
+void RenderProcessHostImpl::UpdateProcessPriority() {
+ if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) {
+ is_process_backgrounded_ = false;
return;
+ }
- // Don't background processes which have active audio streams.
- if (backgrounded_ && audio_renderer_host_->HasActiveAudio())
- return;
+ // We background a process as soon as it hosts no active audio streams and no
+ // visible widgets -- the callers must call this function whenever we
+ // transition in/out of those states.
+ const bool should_background =
+ visible_widgets_ == 0 && !audio_renderer_host_->HasActiveAudio() &&
+ !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableRendererBackgrounding);
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDisableRendererBackgrounding))
+// TODO(sebsg): Remove this ifdef when https://crbug.com/537671 is fixed.
+#if !defined(OS_ANDROID)
+ if (is_process_backgrounded_ == should_background)
return;
+#endif
+
+ TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::UpdateProcessPriority",
+ "should_background", should_background);
+ is_process_backgrounded_ = should_background;
#if defined(OS_WIN)
// The cbstext.dll loads as a global GetMessage hook in the browser process
@@ -2339,18 +2477,13 @@ void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
// tasks executing at lowered priority ahead of it or simply by not being
// swiftly scheduled by the OS per the low process priority
// (http://crbug.com/398103).
- child_process_launcher_->SetProcessBackgrounded(backgrounded);
+ child_process_launcher_->SetProcessBackgrounded(should_background);
// Notify the child process of background state.
- Send(new ChildProcessMsg_SetProcessBackgrounded(backgrounded));
+ Send(new ChildProcessMsg_SetProcessBackgrounded(should_background));
}
void RenderProcessHostImpl::OnProcessLaunched() {
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile1(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 RenderProcessHostImpl::OnProcessLaunched::Start"));
// No point doing anything, since this object will be destructed soon. We
// especially don't want to send the RENDERER_PROCESS_CREATED notification,
// since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to
@@ -2359,20 +2492,28 @@ void RenderProcessHostImpl::OnProcessLaunched() {
return;
if (child_process_launcher_) {
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile2(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded"));
DCHECK(child_process_launcher_->GetProcess().IsValid());
- SetBackgrounded(backgrounded_);
+ DCHECK(!is_process_backgrounded_);
+
+ // Not all platforms launch processes in the same backgrounded state. Make
+ // sure |is_process_backgrounded_| reflects this platform's initial process
+ // state.
+ is_process_backgrounded_ =
+ child_process_launcher_->GetProcess().IsProcessBackgrounded();
+
+#if defined(OS_WIN)
+ // Experiment with not setting the initial priority of a renderer, as this
+ // might be a visible tab but since no widgets are currently present, it
+ // will get backgrounded. See https://crbug.com/560446.
+ if (base::FeatureList::IsEnabled(
+ features::kUpdateRendererPriorityOnStartup)) {
+ UpdateProcessPriority();
+ }
+#else
+ UpdateProcessPriority();
+#endif
}
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile3(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 RenderProcessHostImpl::OnProcessLaunched::Notify"));
// NOTE: This needs to be before sending queued messages because
// ExtensionService uses this notification to initialize the renderer process
// with state that must be there before any JavaScript executes.
@@ -2380,33 +2521,44 @@ void RenderProcessHostImpl::OnProcessLaunched() {
// The queued messages contain such things as "navigate". If this notification
// was after, we can end up executing JavaScript before the initialization
// happens.
- NotificationService::current()->Notify(
- NOTIFICATION_RENDERER_PROCESS_CREATED,
- Source<RenderProcessHost>(this),
- NotificationService::NoDetails());
-
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile4(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 RenderProcessHostImpl::OnProcessLaunched::MojoActivate"));
+ NotificationService::current()->Notify(NOTIFICATION_RENDERER_PROCESS_CREATED,
+ Source<RenderProcessHost>(this),
+ NotificationService::NoDetails());
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk") &&
+ child_process_launcher_.get()) {
+ base::ProcessHandle process_handle =
+ child_process_launcher_->GetProcess().Handle();
+ mojo::embedder::ScopedPlatformHandle client_pipe;
+#if defined(MOJO_SHELL_CLIENT)
+ if (IsRunningInMojoShell()) {
+ client_pipe = RegisterProcessWithBroker(
+ child_process_launcher_->GetProcess().Pid());
+ } else
+#endif
+ {
+ client_pipe = mojo::embedder::ChildProcessLaunched(process_handle);
+ }
+ Send(new ChildProcessMsg_SetMojoParentPipeHandle(
+ IPC::GetFileHandleForProcess(
+#if defined(OS_WIN)
+ client_pipe.release().handle,
+#else
+ client_pipe.release().fd,
+#endif
+ process_handle, true)));
+ }
+
+#if defined(MOJO_SHELL_CLIENT)
+ // Send the mojo shell handle to the renderer.
+ SendExternalMojoShellHandleToChild(GetHandle(), this);
+#endif
+
// Allow Mojo to be setup before the renderer sees any Chrome IPC messages.
// This way, Mojo can be safely used from the renderer in response to any
// Chrome IPC message.
mojo_application_host_->Activate(this, GetHandle());
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile5(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 RenderProcessHostImpl::OnProcessLaunched::MojoClientLaunch"));
-
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile6(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 "
- "RenderProcessHostImpl::OnProcessLaunched::SendQueuedMessages"));
while (!queued_messages_.empty()) {
Send(queued_messages_.front());
queued_messages_.pop();
@@ -2422,11 +2574,6 @@ void RenderProcessHostImpl::OnProcessLaunched() {
}
#if defined(ENABLE_WEBRTC)
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile7(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "465841 RenderProcessHostImpl::OnProcessLaunched::EnableAec"));
if (WebRTCInternals::GetInstance()->IsAudioDebugRecordingsEnabled()) {
EnableAudioDebugRecordings(
WebRTCInternals::GetInstance()->GetAudioDebugRecordingsFilePath());
@@ -2442,13 +2589,12 @@ void RenderProcessHostImpl::OnProcessLaunchFailed() {
return;
// TODO(wfh): Fill in the real error code here see crbug.com/526198.
- RendererClosedDetails details { base::TERMINATION_STATUS_LAUNCH_FAILED,
- -1 };
+ RendererClosedDetails details{base::TERMINATION_STATUS_LAUNCH_FAILED, -1};
ProcessDied(true, &details);
}
-scoped_refptr<AudioRendererHost>
-RenderProcessHostImpl::audio_renderer_host() const {
+scoped_refptr<AudioRendererHost> RenderProcessHostImpl::audio_renderer_host()
+ const {
return audio_renderer_host_;
}
@@ -2458,30 +2604,26 @@ void RenderProcessHostImpl::OnUserMetricsRecordAction(
}
void RenderProcessHostImpl::OnCloseACK(int old_route_id) {
- SessionStorageHolder* holder = static_cast<SessionStorageHolder*>
- (GetUserData(kSessionStorageHolderKey));
+ SessionStorageHolder* holder =
+ static_cast<SessionStorageHolder*>(GetUserData(kSessionStorageHolderKey));
if (!holder)
return;
holder->Release(old_route_id);
}
-void RenderProcessHostImpl::OnSavedPageAsMHTML(int job_id, int64 data_size) {
- MHTMLGenerationManager::GetInstance()->MHTMLGenerated(job_id, data_size);
-}
-
void RenderProcessHostImpl::OnGpuSwitched() {
// We are updating all widgets including swapped out ones.
scoped_ptr<RenderWidgetHostIterator> widgets(
RenderWidgetHostImpl::GetAllRenderWidgetHosts());
while (RenderWidgetHost* widget = widgets->GetNextHost()) {
- if (!widget->IsRenderView())
+ RenderViewHost* rvh = RenderViewHost::From(widget);
+ if (!rvh)
continue;
// Skip widgets in other processes.
- if (widget->GetProcess()->GetID() != GetID())
+ if (rvh->GetProcess()->GetID() != GetID())
continue;
- RenderViewHost* rvh = RenderViewHost::From(widget);
rvh->OnWebkitPreferencesChanged();
}
}
@@ -2489,22 +2631,30 @@ void RenderProcessHostImpl::OnGpuSwitched() {
#if defined(ENABLE_WEBRTC)
void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
- weak_factory_.GetWeakPtr(),
- id));
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
+ weak_factory_.GetWeakPtr(), id));
+}
+
+void RenderProcessHostImpl::OnRegisterEventLogConsumer(int id) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RenderProcessHostImpl::RegisterEventLogConsumerOnUIThread,
+ weak_factory_.GetWeakPtr(), id));
}
void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread,
- weak_factory_.GetWeakPtr(),
- id));
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread,
+ weak_factory_.GetWeakPtr(), id));
+}
+
+void RenderProcessHostImpl::OnUnregisterEventLogConsumer(int id) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RenderProcessHostImpl::UnregisterEventLogConsumerOnUIThread,
+ weak_factory_.GetWeakPtr(), id));
}
void RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread(int id) {
@@ -2518,6 +2668,17 @@ void RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread(int id) {
}
}
+void RenderProcessHostImpl::RegisterEventLogConsumerOnUIThread(int id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ aec_dump_consumers_.push_back(id);
+
+ if (WebRTCInternals::GetInstance()->IsEventLogRecordingsEnabled()) {
+ base::FilePath file_with_extensions = GetEventLogFilePathWithExtensions(
+ WebRTCInternals::GetInstance()->GetEventLogRecordingsFilePath());
+ EnableEventLogForId(file_with_extensions, id);
+ }
+}
+
void RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread(int id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
@@ -2529,17 +2690,37 @@ void RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread(int id) {
}
}
+void RenderProcessHostImpl::UnregisterEventLogConsumerOnUIThread(int id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
+ it != aec_dump_consumers_.end(); ++it) {
+ if (*it == id) {
+ aec_dump_consumers_.erase(it);
+ break;
+ }
+ }
+}
+
void RenderProcessHostImpl::EnableAecDumpForId(const base::FilePath& file,
int id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&CreateAecDumpFileForProcess,
- file.AddExtension(IntToStringType(id)),
+ base::Bind(&CreateFileForProcess, file.AddExtension(IntToStringType(id)),
GetHandle()),
base::Bind(&RenderProcessHostImpl::SendAecDumpFileToRenderer,
- weak_factory_.GetWeakPtr(),
- id));
+ weak_factory_.GetWeakPtr(), id));
+}
+
+void RenderProcessHostImpl::EnableEventLogForId(const base::FilePath& file,
+ int id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&CreateFileForProcess, file.AddExtension(IntToStringType(id)),
+ GetHandle()),
+ base::Bind(&RenderProcessHostImpl::SendEventLogFileToRenderer,
+ weak_factory_.GetWeakPtr(), id));
}
void RenderProcessHostImpl::SendAecDumpFileToRenderer(
@@ -2550,31 +2731,34 @@ void RenderProcessHostImpl::SendAecDumpFileToRenderer(
Send(new AecDumpMsg_EnableAecDump(id, file_for_transit));
}
+void RenderProcessHostImpl::SendEventLogFileToRenderer(
+ int id,
+ IPC::PlatformFileForTransit file_for_transit) {
+ if (file_for_transit == IPC::InvalidPlatformFileForTransit())
+ return;
+ Send(new WebRTCEventLogMsg_EnableEventLog(id, file_for_transit));
+}
+
void RenderProcessHostImpl::SendDisableAecDumpToRenderer() {
Send(new AecDumpMsg_DisableAecDump());
}
+void RenderProcessHostImpl::SendDisableEventLogToRenderer() {
+ Send(new WebRTCEventLogMsg_DisableEventLog());
+}
+
base::FilePath RenderProcessHostImpl::GetAecDumpFilePathWithExtensions(
const base::FilePath& file) {
return file.AddExtension(IntToStringType(base::GetProcId(GetHandle())))
- .AddExtension(kAecDumpFileNameAddition);
+ .AddExtension(kAecDumpFileNameAddition);
}
-#endif // defined(ENABLE_WEBRTC)
-void RenderProcessHostImpl::IncrementWorkerRefCount() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ++worker_ref_count_;
- if (worker_ref_count_ > max_worker_count_)
- max_worker_count_ = worker_ref_count_;
-}
-
-void RenderProcessHostImpl::DecrementWorkerRefCount() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_GT(worker_ref_count_, 0);
- --worker_ref_count_;
- if (worker_ref_count_ == 0)
- Cleanup();
+base::FilePath RenderProcessHostImpl::GetEventLogFilePathWithExtensions(
+ const base::FilePath& file) {
+ return file.AddExtension(IntToStringType(base::GetProcId(GetHandle())))
+ .AddExtension(kEventLogFileNameAddition);
}
+#endif // defined(ENABLE_WEBRTC)
void RenderProcessHostImpl::GetAudioOutputControllers(
const GetAudioOutputControllersCallback& callback) const {
diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.h b/chromium/content/browser/renderer_host/render_process_host_impl.h
index a648d2db63c..79154957c35 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.h
@@ -5,13 +5,19 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <queue>
#include <string>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/process/process.h"
+#include "base/synchronization/waitable_event.h"
+#include "build/build_config.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/power_monitor_message_broadcaster.h"
@@ -20,14 +26,10 @@
#include "content/public/browser/render_process_host.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_platform_file.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gpu_switching_observer.h"
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include "content/common/mac/io_surface_manager_token.h"
-#endif
-
namespace base {
class CommandLine;
class MessageLoop;
@@ -105,14 +107,15 @@ class CONTENT_EXPORT RenderProcessHostImpl
void EnableSendQueue() override;
bool Init() override;
int GetNextRoutingID() override;
- void AddRoute(int32 routing_id, IPC::Listener* listener) override;
- void RemoveRoute(int32 routing_id) override;
+ void AddRoute(int32_t routing_id, IPC::Listener* listener) override;
+ void RemoveRoute(int32_t routing_id) override;
void AddObserver(RenderProcessHostObserver* observer) override;
void RemoveObserver(RenderProcessHostObserver* observer) override;
void ShutdownForBadMessage() override;
void WidgetRestored() override;
void WidgetHidden() override;
int VisibleWidgetCount() const override;
+ void AudioStateChanged() override;
bool IsForGuestsOnly() const override;
StoragePartition* GetStoragePartition() const override;
bool Shutdown(int exit_code, bool wait) override;
@@ -140,6 +143,8 @@ class CONTENT_EXPORT RenderProcessHostImpl
#if defined(ENABLE_WEBRTC)
void EnableAudioDebugRecordings(const base::FilePath& file) override;
void DisableAudioDebugRecordings() override;
+ void EnableEventLogRecordings(const base::FilePath& file) override;
+ void DisableEventLogRecordings() override;
void SetWebRtcLogMessageCallback(
base::Callback<void(const std::string&)> callback) override;
WebRtcStopRtpDumpCallback StartRtpDump(
@@ -157,16 +162,19 @@ class CONTENT_EXPORT RenderProcessHostImpl
void SendUpdateValueState(
unsigned int target, const gpu::ValueState& state) override;
#if defined(ENABLE_BROWSER_CDMS)
- media::BrowserCdm* GetBrowserCdm(int render_frame_id,
- int cdm_id) const override;
+ scoped_refptr<media::MediaKeys> GetCdm(int render_frame_id,
+ int cdm_id) const override;
#endif
+ bool IsProcessBackgrounded() const override;
+ void IncrementWorkerRefCount() override;
+ void DecrementWorkerRefCount() override;
// IPC::Sender via RenderProcessHost.
bool Send(IPC::Message* msg) override;
// IPC::Listener via RenderProcessHost.
bool OnMessageReceived(const IPC::Message& msg) override;
- void OnChannelConnected(int32 peer_pid) override;
+ void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void OnBadMessageReceived(const IPC::Message& message) override;
@@ -182,11 +190,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
child_process_activity_time_ = base::TimeTicks::Now();
}
-#if defined(ENABLE_WEBRTC)
- // Fires the webrtc log message callback with |message|, if callback is set.
- void WebRtcLogMessage(const std::string& message);
-#endif
-
// Used to extend the lifetime of the sessions until the render view
// in the renderer is fully closed. This is static because its also called
// with mock hosts as input in test cases.
@@ -255,12 +258,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
is_for_guests_only_ = is_for_guests_only;
}
- // Called when the existence of the other renderer process which is connected
- // to the Worker in this renderer process has changed.
- // It is only called when "enable-embedded-shared-worker" flag is set.
- void IncrementWorkerRefCount();
- void DecrementWorkerRefCount();
-
void GetAudioOutputControllers(
const GetAudioOutputControllersCallback& callback) const override;
@@ -284,7 +281,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
// The count of currently swapped out but pending RenderViews. We have
// started to swap these in, so the renderer process should not exit if
// this count is non-zero.
- int32 pending_views_;
+ int32_t pending_views_;
private:
friend class VisitRelayingRenderProcessHost;
@@ -303,7 +300,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
void OnShutdownRequest();
void SuddenTerminationChanged(bool enabled);
void OnUserMetricsRecordAction(const std::string& action);
- void OnSavedPageAsMHTML(int job_id, int64 mhtml_file_size);
void OnCloseACK(int old_route_id);
// Generates a command line to be used to spawn a renderer and appends the
@@ -317,8 +313,10 @@ class CONTENT_EXPORT RenderProcessHostImpl
const base::CommandLine& browser_cmd,
base::CommandLine* renderer_cmd) const;
- // Callers can reduce the RenderProcess' priority.
- void SetBackgrounded(bool backgrounded);
+ // Inspects the current object state and sets/removes background priority if
+ // appropriate. Should be called after any of the involved data members
+ // change.
+ void UpdateProcessPriority();
// Handle termination of our process.
void ProcessDied(bool already_dead, RendererClosedDetails* known_details);
@@ -328,15 +326,24 @@ class CONTENT_EXPORT RenderProcessHostImpl
#if defined(ENABLE_WEBRTC)
void OnRegisterAecDumpConsumer(int id);
+ void OnRegisterEventLogConsumer(int id);
void OnUnregisterAecDumpConsumer(int id);
+ void OnUnregisterEventLogConsumer(int id);
void RegisterAecDumpConsumerOnUIThread(int id);
+ void RegisterEventLogConsumerOnUIThread(int id);
void UnregisterAecDumpConsumerOnUIThread(int id);
+ void UnregisterEventLogConsumerOnUIThread(int id);
void EnableAecDumpForId(const base::FilePath& file, int id);
+ void EnableEventLogForId(const base::FilePath& file, int id);
// Sends |file_for_transit| to the render process.
void SendAecDumpFileToRenderer(int id,
IPC::PlatformFileForTransit file_for_transit);
+ void SendEventLogFileToRenderer(int id,
+ IPC::PlatformFileForTransit file_for_transit);
void SendDisableAecDumpToRenderer();
+ void SendDisableEventLogToRenderer();
base::FilePath GetAecDumpFilePathWithExtensions(const base::FilePath& file);
+ base::FilePath GetEventLogFilePathWithExtensions(const base::FilePath& file);
#endif
scoped_ptr<MojoApplicationHost> mojo_application_host_;
@@ -348,10 +355,11 @@ class CONTENT_EXPORT RenderProcessHostImpl
// The count of currently visible widgets. Since the host can be a container
// for multiple widgets, it uses this count to determine when it should be
// backgrounded.
- int32 visible_widgets_;
+ int32_t visible_widgets_;
- // Does this process have backgrounded priority.
- bool backgrounded_;
+ // Whether this process currently has backgrounded priority. Tracked so that
+ // UpdateProcessPriority() can avoid redundantly setting the priority.
+ bool is_process_backgrounded_;
// Used to allow a RenderWidgetHost to intercept various messages on the
// IO thread.
@@ -393,7 +401,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
std::queue<IPC::Message*> queued_messages_;
// The globally-unique identifier for this RPH.
- int id_;
+ const int id_;
BrowserContext* browser_context_;
@@ -452,8 +460,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
#endif
#if defined(ENABLE_WEBRTC)
- base::Callback<void(const std::string&)> webrtc_log_message_callback_;
-
scoped_refptr<P2PSocketDispatcherHost> p2p_socket_dispatcher_host_;
// Must be accessed on UI thread.
@@ -488,15 +494,18 @@ class CONTENT_EXPORT RenderProcessHostImpl
// Whether or not the CHROMIUM_subscribe_uniform WebGL extension is enabled
bool subscribe_uniform_enabled_;
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- // Unique unguessable token that the child process is using to acquire
- // IOSurface references.
- IOSurfaceManagerToken io_surface_manager_token_;
-#endif
-
bool channel_connected_;
bool sent_render_process_ready_;
+#if defined(OS_ANDROID)
+ // UI thread is the source of sync IPCs and all shutdown signals.
+ // Therefore a proper shutdown event to unblock the UI thread is not
+ // possible without massive refactoring shutdown code.
+ // Luckily Android never performs a clean shutdown. So explicitly
+ // ignore this problem.
+ base::WaitableEvent never_signaled_;
+#endif
+
base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
diff --git a/chromium/content/browser/renderer_host/render_process_host_unittest.cc b/chromium/content/browser/renderer_host/render_process_host_unittest.cc
index ee2395c00bd..019cae63bbb 100644
--- a/chromium/content/browser/renderer_host/render_process_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <limits>
+#include "build/build_config.h"
#include "content/public/common/content_constants.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_utils.h"
diff --git a/chromium/content/browser/renderer_host/render_sandbox_host_linux.h b/chromium/content/browser/renderer_host/render_sandbox_host_linux.h
index a9f8a021d00..b9fad8821ec 100644
--- a/chromium/content/browser/renderer_host/render_sandbox_host_linux.h
+++ b/chromium/content/browser/renderer_host/render_sandbox_host_linux.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/simple_thread.h"
#include "content/browser/renderer_host/sandbox_ipc_linux.h"
diff --git a/chromium/content/browser/renderer_host/render_view_host_browsertest.cc b/chromium/content/browser/renderer_host/render_view_host_browsertest.cc
index 2fdaf0aa833..5e14d47d460 100644
--- a/chromium/content/browser/renderer_host/render_view_host_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_browsertest.cc
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -62,7 +64,7 @@ class RenderViewHostTestWebContentsObserver : public WebContentsObserver {
};
IN_PROC_BROWSER_TEST_F(RenderViewHostTest, FrameNavigateSocketAddress) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
RenderViewHostTestWebContentsObserver observer(shell()->web_contents());
GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
@@ -75,7 +77,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostTest, FrameNavigateSocketAddress) {
}
IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BaseURLParam) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
RenderViewHostTestWebContentsObserver observer(shell()->web_contents());
// Base URL is not set if it is the same as the URL.
@@ -96,7 +98,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BaseURLParam) {
// This test ensures a RenderFrameHost object is created for the top level frame
// in each RenderViewHost.
IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BasicRenderFrameHost) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
NavigateToURL(shell(), test_url);
@@ -117,7 +119,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BasicRenderFrameHost) {
}
IN_PROC_BROWSER_TEST_F(RenderViewHostTest, IsFocusedElementEditable) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url = embedded_test_server()->GetURL("/touch_selection.html");
NavigateToURL(shell(), test_url);
@@ -128,8 +130,14 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostTest, IsFocusedElementEditable) {
EXPECT_TRUE(rvh->IsFocusedElementEditable());
}
-IN_PROC_BROWSER_TEST_F(RenderViewHostTest, ReleaseSessionOnCloseACK) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+// Flaky on Linux (https://crbug.com/559192).
+#if defined(OS_LINUX)
+#define MAYBE_ReleaseSessionOnCloseACK DISABLED_ReleaseSessionOnCloseACK
+#else
+#define MAYBE_ReleaseSessionOnCloseACK ReleaseSessionOnCloseACK
+#endif
+IN_PROC_BROWSER_TEST_F(RenderViewHostTest, MAYBE_ReleaseSessionOnCloseACK) {
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url = embedded_test_server()->GetURL(
"/access-session-storage.html");
NavigateToURL(shell(), test_url);
diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate.cc b/chromium/content/browser/renderer_host/render_view_host_delegate.cc
index 0b109911ddd..c169a056f28 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate.cc
@@ -22,14 +22,6 @@ WebContents* RenderViewHostDelegate::GetAsWebContents() {
return NULL;
}
-bool RenderViewHostDelegate::IsFullscreenForCurrentTab() const {
- return false;
-}
-
-blink::WebDisplayMode RenderViewHostDelegate::GetDisplayMode() const {
- return blink::WebDisplayModeBrowser;
-}
-
SessionStorageNamespace* RenderViewHostDelegate::GetSessionStorageNamespace(
SiteInstance* instance) {
return NULL;
diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate.h b/chromium/content/browser/renderer_host/render_view_host_delegate.h
index 9a451590f98..8fc436c2525 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate.h
@@ -5,16 +5,16 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_DELEGATE_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_DELEGATE_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/process/kill.h"
#include "base/strings/string16.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/common/content_export.h"
#include "net/base/load_states.h"
-#include "third_party/WebKit/public/platform/WebDisplayMode.h"
#include "third_party/WebKit/public/web/WebPopupType.h"
#include "ui/base/window_open_disposition.h"
@@ -33,7 +33,6 @@ class Message;
}
namespace gfx {
-class Point;
class Rect;
class Size;
}
@@ -83,10 +82,6 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// jam as reviewers before you use this method. http://crbug.com/82582
virtual WebContents* GetAsWebContents();
- // Return the rect where to display the resize corner, if any, otherwise
- // an empty rect.
- virtual gfx::Rect GetRootWindowResizerRect() const = 0;
-
// The RenderView is being constructed (message sent to the renderer process
// to construct a RenderView). Now is a good time to send other setup events
// to the RenderView. This precedes any other commands to the RenderView.
@@ -107,7 +102,7 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// The state for the page changed and should be updated.
virtual void UpdateState(RenderViewHost* render_view_host,
- int32 page_id,
+ int32_t page_id,
const PageState& state) {}
// The destination URL has changed should be updated.
@@ -135,66 +130,30 @@ class CONTENT_EXPORT RenderViewHostDelegate {
virtual RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const = 0;
- // Notification the user has made a gesture while focus was on the
- // page. This is used to avoid uninitiated user downloads (aka carpet
- // bombing), see DownloadRequestLimiter for details.
- virtual void OnUserGesture() {}
-
// Notification from the renderer host that blocked UI event occurred.
// This happens when there are tab-modal dialogs. In this case, the
// notification is needed to let us draw attention to the dialog (i.e.
// refocus on the modal dialog, flash title etc).
virtual void OnIgnoredUIEvent() {}
- // Notification that the renderer has become unresponsive. The
- // delegate can use this notification to show a warning to the user.
- virtual void RendererUnresponsive(RenderViewHost* render_view_host) {}
-
- // Notification that a previously unresponsive renderer has become
- // responsive again. The delegate can use this notification to end the
- // warning shown to the user.
- virtual void RendererResponsive(RenderViewHost* render_view_host) {}
-
// Notification that the RenderViewHost's load state changed.
virtual void LoadStateChanged(const GURL& url,
const net::LoadStateWithParam& load_state,
- uint64 upload_position,
- uint64 upload_size) {}
+ uint64_t upload_position,
+ uint64_t upload_size) {}
- // The page wants the hosting window to activate/deactivate itself (it
- // called the JavaScript window.focus()/blur() method).
+ // The page wants the hosting window to activate itself (it called the
+ // JavaScript window.focus() method).
virtual void Activate() {}
- virtual void Deactivate() {}
-
- // Notification that the view has lost capture.
- virtual void LostCapture() {}
// Called when a file selection is to be done.
virtual void RunFileChooser(
RenderViewHost* render_view_host,
const FileChooserParams& params) {}
- // Returns whether the associated tab is in fullscreen mode.
- virtual bool IsFullscreenForCurrentTab() const;
-
- // Returns the display mode for the view.
- virtual blink::WebDisplayMode GetDisplayMode() const;
-
// The contents' preferred size changed.
virtual void UpdatePreferredSize(const gfx::Size& pref_size) {}
- // The contents auto-resized and the container should match it.
- virtual void ResizeDueToAutoResize(const gfx::Size& new_size) {}
-
- // Requests to lock the mouse. Once the request is approved or rejected,
- // GotResponseToLockMouseRequest() will be called on the requesting render
- // view host.
- virtual void RequestToLockMouse(bool user_gesture,
- bool last_unlocked_by_target) {}
-
- // Notification that the view has lost the mouse lock.
- 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_id| in the process of
// |source_site_instance|, but it should not be shown yet. That
@@ -214,8 +173,9 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// new window.
virtual void CreateNewWindow(
SiteInstance* source_site_instance,
- int route_id,
- int main_frame_route_id,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) {}
@@ -225,13 +185,13 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// 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(int32 render_process_id,
- int32 route_id,
+ virtual void CreateNewWidget(int32_t render_process_id,
+ int32_t route_id,
blink::WebPopupType popup_type) {}
// Creates a full screen RenderWidget. Similar to above.
- virtual void CreateNewFullscreenWidget(int32 render_process_id,
- int32 route_id) {}
+ virtual void CreateNewFullscreenWidget(int32_t render_process_id,
+ int32_t 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/chromium/content/browser/renderer_host/render_view_host_delegate_view.h b/chromium/content/browser/renderer_host/render_view_host_delegate_view.h
index 4c2491221bc..1e05290a501 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate_view.h
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate_view.h
@@ -7,8 +7,8 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/common/drag_event_source_info.h"
#include "third_party/WebKit/public/web/WebDragOperation.h"
diff --git a/chromium/content/browser/renderer_host/render_view_host_factory.cc b/chromium/content/browser/renderer_host/render_view_host_factory.cc
index 2e166c4e07f..13b2c082480 100644
--- a/chromium/content/browser/renderer_host/render_view_host_factory.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_factory.cc
@@ -5,20 +5,22 @@
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
namespace content {
// static
-RenderViewHostFactory* RenderViewHostFactory::factory_ = NULL;
+RenderViewHostFactory* RenderViewHostFactory::factory_ = nullptr;
// static
RenderViewHost* RenderViewHostFactory::Create(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
RenderWidgetHostDelegate* widget_delegate,
- int32 routing_id,
- int32 main_frame_routing_id,
+ int32_t routing_id,
+ int32_t main_frame_routing_id,
bool swapped_out,
bool hidden) {
// RenderViewHost creation can be either browser-driven (by the user opening a
@@ -41,9 +43,12 @@ RenderViewHost* RenderViewHostFactory::Create(
routing_id, main_frame_routing_id,
swapped_out);
}
- return new RenderViewHostImpl(instance, delegate, widget_delegate, routing_id,
- main_frame_routing_id, swapped_out, hidden,
- true /* has_initialized_audio_host */);
+ return new RenderViewHostImpl(
+ instance,
+ make_scoped_ptr(new RenderWidgetHostImpl(
+ widget_delegate, instance->GetProcess(), routing_id, hidden)),
+ delegate, main_frame_routing_id, swapped_out,
+ true /* has_initialized_audio_host */);
}
// static
@@ -55,7 +60,7 @@ void RenderViewHostFactory::RegisterFactory(RenderViewHostFactory* factory) {
// static
void RenderViewHostFactory::UnregisterFactory() {
DCHECK(factory_) << "No factory to unregister.";
- factory_ = NULL;
+ factory_ = nullptr;
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_view_host_factory.h b/chromium/content/browser/renderer_host/render_view_host_factory.h
index be2aae5e099..62b23900d6a 100644
--- a/chromium/content/browser/renderer_host/render_view_host_factory.h
+++ b/chromium/content/browser/renderer_host/render_view_host_factory.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_FACTORY_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_FACTORY_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/common/content_export.h"
namespace content {
@@ -27,8 +29,8 @@ class RenderViewHostFactory {
static RenderViewHost* Create(SiteInstance* instance,
RenderViewHostDelegate* delegate,
RenderWidgetHostDelegate* widget_delegate,
- int32 routing_id,
- int32 main_frame_routing_id,
+ int32_t routing_id,
+ int32_t main_frame_routing_id,
bool swapped_out,
bool hidden);
@@ -47,8 +49,8 @@ class RenderViewHostFactory {
SiteInstance* instance,
RenderViewHostDelegate* delegate,
RenderWidgetHostDelegate* widget_delegate,
- int32 routing_id,
- int32 main_frame_routing_id,
+ int32_t routing_id,
+ int32_t main_frame_routing_id,
bool swapped_out) = 0;
// Registers your factory to be called when new RenderViewHosts are created.
diff --git a/chromium/content/browser/renderer_host/render_view_host_impl.cc b/chromium/content/browser/renderer_host/render_view_host_impl.cc
index 4c2c1fac8b5..5916c11e773 100644
--- a/chromium/content/browser/renderer_host/render_view_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_impl.cc
@@ -23,6 +23,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -74,13 +75,13 @@
#include "content/public/common/url_utils.h"
#include "net/base/filename_util.h"
#include "net/base/net_util.h"
-#include "net/base/network_change_notifier.h"
#include "net/url_request/url_request_context_getter.h"
#include "storage/browser/fileapi/isolated_context.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/touch/touch_device.h"
#include "ui/base/touch/touch_enabled.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/gfx/animation/animation.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/native_theme/native_theme_switches.h"
@@ -164,7 +165,7 @@ void GetWindowsSpecificPrefs(RendererPreferences* prefs) {
} // namespace
// static
-const int64 RenderViewHostImpl::kUnloadTimeoutMS = 1000;
+const int64_t RenderViewHostImpl::kUnloadTimeoutMS = 1000;
///////////////////////////////////////////////////////////////////////////////
// RenderViewHost, public:
@@ -177,8 +178,7 @@ RenderViewHost* RenderViewHost::FromID(int render_process_id,
// static
RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
- DCHECK(rwh->IsRenderView());
- return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(rwh));
+ return RenderViewHostImpl::From(rwh);
}
///////////////////////////////////////////////////////////////////////////////
@@ -189,31 +189,36 @@ RenderViewHostImpl* RenderViewHostImpl::FromID(int render_process_id,
int render_view_id) {
RenderWidgetHost* widget =
RenderWidgetHost::FromID(render_process_id, render_view_id);
- if (!widget || !widget->IsRenderView())
- return NULL;
- return static_cast<RenderViewHostImpl*>(RenderWidgetHostImpl::From(widget));
-}
-
-RenderViewHostImpl::RenderViewHostImpl(
- SiteInstance* instance,
- RenderViewHostDelegate* delegate,
- RenderWidgetHostDelegate* widget_delegate,
- int32 routing_id,
- int32 main_frame_routing_id,
- bool swapped_out,
- bool hidden,
- bool has_initialized_audio_host)
- : RenderWidgetHostImpl(widget_delegate,
- instance->GetProcess(),
- routing_id,
- hidden),
+ if (!widget)
+ return nullptr;
+ return From(widget);
+}
+
+// static
+RenderViewHostImpl* RenderViewHostImpl::From(RenderWidgetHost* rwh) {
+ DCHECK(rwh);
+ RenderWidgetHostOwnerDelegate* owner_delegate =
+ RenderWidgetHostImpl::From(rwh)->owner_delegate();
+ if (!owner_delegate)
+ return nullptr;
+ RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(owner_delegate);
+ DCHECK_EQ(rwh, rvh->GetWidget());
+ return rvh;
+}
+
+RenderViewHostImpl::RenderViewHostImpl(SiteInstance* instance,
+ scoped_ptr<RenderWidgetHostImpl> widget,
+ RenderViewHostDelegate* delegate,
+ int32_t main_frame_routing_id,
+ bool swapped_out,
+ bool has_initialized_audio_host)
+ : render_widget_host_(std::move(widget)),
frames_ref_count_(0),
delegate_(delegate),
instance_(static_cast<SiteInstanceImpl*>(instance)),
waiting_for_drag_context_response_(false),
enabled_bindings_(0),
page_id_(-1),
- nav_entry_id_(0),
is_active_(!swapped_out),
is_pending_deletion_(false),
is_swapped_out_(swapped_out),
@@ -229,6 +234,8 @@ RenderViewHostImpl::RenderViewHostImpl(
DCHECK(instance_.get());
CHECK(delegate_); // http://crbug.com/82827
+ GetWidget()->set_owner_delegate(this);
+
GetProcess()->AddObserver(this);
GetProcess()->EnableSendQueue();
@@ -243,14 +250,11 @@ RenderViewHostImpl::RenderViewHostImpl(
arh->RenderFrameHasActiveAudio(main_frame_routing_id_);
}
BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
+ BrowserThread::IO, FROM_HERE,
base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostCreated,
base::Unretained(ResourceDispatcherHostImpl::Get()),
- GetProcess()->GetID(),
- GetRoutingID(),
- !is_hidden(),
- has_active_audio));
+ GetProcess()->GetID(), GetRoutingID(),
+ !GetWidget()->is_hidden(), has_active_audio));
}
}
@@ -278,7 +282,7 @@ SiteInstanceImpl* RenderViewHostImpl::GetSiteInstance() const {
bool RenderViewHostImpl::CreateRenderView(
int opener_frame_route_id,
int proxy_route_id,
- int32 max_page_id,
+ int32_t max_page_id,
const FrameReplicationState& replicated_frame_state,
bool window_was_created_with_opener) {
TRACE_EVENT0("renderer_host,navigation",
@@ -293,12 +297,14 @@ bool RenderViewHostImpl::CreateRenderView(
return false;
DCHECK(GetProcess()->HasConnection());
DCHECK(GetProcess()->GetBrowserContext());
+ CHECK(main_frame_routing_id_ != MSG_ROUTING_NONE ||
+ proxy_route_id != MSG_ROUTING_NONE);
- set_renderer_initialized(true);
+ GetWidget()->set_renderer_initialized(true);
// Ensure the RenderView starts with a next_page_id larger than any existing
// page ID it might be asked to render.
- int32 next_page_id = 1;
+ int32_t next_page_id = 1;
if (max_page_id > -1)
next_page_id = max_page_id + 1;
@@ -311,6 +317,13 @@ bool RenderViewHostImpl::CreateRenderView(
params.web_preferences = GetWebkitPreferences();
params.view_id = GetRoutingID();
params.main_frame_routing_id = main_frame_routing_id_;
+ if (main_frame_routing_id_ != MSG_ROUTING_NONE) {
+ RenderFrameHostImpl* main_rfh = RenderFrameHostImpl::FromID(
+ GetProcess()->GetID(), main_frame_routing_id_);
+ DCHECK(main_rfh);
+ RenderWidgetHostImpl* main_rwh = main_rfh->GetRenderWidgetHost();
+ params.main_frame_widget_routing_id = main_rwh->GetRoutingID();
+ }
params.session_storage_namespace_id =
delegate_->GetSessionStorageNamespace(instance_.get())->id();
// Ensure the RenderView sets its opener correctly.
@@ -318,24 +331,24 @@ bool RenderViewHostImpl::CreateRenderView(
params.swapped_out = !is_active_;
params.replicated_frame_state = replicated_frame_state;
params.proxy_routing_id = proxy_route_id;
- params.hidden = is_hidden();
+ params.hidden = GetWidget()->is_hidden();
params.never_visible = delegate_->IsNeverVisible();
params.window_was_created_with_opener = window_was_created_with_opener;
params.next_page_id = next_page_id;
- params.enable_auto_resize = auto_resize_enabled();
- params.min_size = min_size_for_auto_resize();
- params.max_size = max_size_for_auto_resize();
- GetResizeParams(&params.initial_size);
+ params.enable_auto_resize = GetWidget()->auto_resize_enabled();
+ params.min_size = GetWidget()->min_size_for_auto_resize();
+ params.max_size = GetWidget()->max_size_for_auto_resize();
+ GetWidget()->GetResizeParams(&params.initial_size);
if (!Send(new ViewMsg_New(params)))
return false;
- SetInitialRenderSizeParams(params.initial_size);
+ GetWidget()->SetInitialRenderSizeParams(params.initial_size);
// If the RWHV has not yet been set, the surface ID namespace will get
// passed down by the call to SetView().
- if (view_) {
- Send(new ViewMsg_SetSurfaceIdNamespace(GetRoutingID(),
- view_->GetSurfaceIdNamespace()));
+ if (GetWidget()->GetView()) {
+ Send(new ViewMsg_SetSurfaceIdNamespace(
+ GetRoutingID(), GetWidget()->GetView()->GetSurfaceIdNamespace()));
}
// If it's enabled, tell the renderer to set up the Javascript bindings for
@@ -352,14 +365,14 @@ bool RenderViewHostImpl::CreateRenderView(
RenderFrameHostImpl::FromID(GetProcess()->GetID(), main_frame_routing_id_)
->SetRenderFrameCreated(true);
}
- SendScreenRects();
+ GetWidget()->SendScreenRects();
PostRenderViewReady();
return true;
}
bool RenderViewHostImpl::IsRenderViewLive() const {
- return GetProcess()->HasConnection() && renderer_initialized();
+ return GetProcess()->HasConnection() && GetWidget()->renderer_initialized();
}
void RenderViewHostImpl::SyncRendererPrefs() {
@@ -428,9 +441,6 @@ WebPreferences RenderViewHostImpl::ComputeWebkitPrefs() {
atoi(command_line.GetSwitchValueASCII(
switches::kAcceleratedCanvas2dMSAASampleCount).c_str());
- prefs.inert_visual_viewport =
- command_line.HasSwitch(switches::kInertVisualViewport);
-
prefs.pinch_overlay_scrollbar_thickness = 10;
prefs.use_solid_color_scrollbars = ui::IsOverlayScrollbarEnabled();
@@ -452,7 +462,8 @@ WebPreferences RenderViewHostImpl::ComputeWebkitPrefs() {
prefs.touch_enabled = ui::AreTouchEventsEnabled();
prefs.device_supports_touch = prefs.touch_enabled &&
- ui::IsTouchDevicePresent();
+ ui::GetTouchScreensAvailability() ==
+ ui::TouchScreensAvailability::ENABLED;
prefs.available_pointer_types = ui::GetAvailablePointerTypes();
prefs.primary_pointer_type = ui::GetPrimaryPointerType();
prefs.available_hover_types = ui::GetAvailableHoverTypes();
@@ -467,19 +478,9 @@ WebPreferences RenderViewHostImpl::ComputeWebkitPrefs() {
prefs.touch_adjustment_enabled =
!command_line.HasSwitch(switches::kDisableTouchAdjustment);
- prefs.slimming_paint_v2_enabled =
- command_line.HasSwitch(switches::kEnableSlimmingPaintV2);
-
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
- bool default_enable_scroll_animator = true;
-#else
- bool default_enable_scroll_animator = false;
-#endif
- prefs.enable_scroll_animator = default_enable_scroll_animator;
- if (command_line.HasSwitch(switches::kEnableSmoothScrolling))
- prefs.enable_scroll_animator = true;
- if (command_line.HasSwitch(switches::kDisableSmoothScrolling))
- prefs.enable_scroll_animator = false;
+ prefs.enable_scroll_animator =
+ !command_line.HasSwitch(switches::kDisableSmoothScrolling) &&
+ gfx::Animation::ShouldRenderRichAnimation();
// Certain GPU features might have been blacklisted.
GpuDataManagerImpl::GetInstance()->UpdateRendererWebPrefs(&prefs);
@@ -490,11 +491,6 @@ WebPreferences RenderViewHostImpl::ComputeWebkitPrefs() {
prefs.javascript_enabled = true;
}
- net::NetworkChangeNotifier::GetMaxBandwidthAndConnectionType(
- &prefs.net_info_max_bandwidth_mbps, &prefs.net_info_connection_type);
- prefs.is_online = prefs.net_info_connection_type !=
- net::NetworkChangeNotifier::CONNECTION_NONE;
-
prefs.number_of_cpu_cores = base::SysInfo::NumberOfProcessors();
prefs.viewport_enabled =
@@ -541,13 +537,14 @@ void RenderViewHostImpl::SuppressDialogsUntilSwapOut() {
void RenderViewHostImpl::ClosePage() {
is_waiting_for_close_ack_ = true;
- StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
+ GetWidget()->StartHangMonitorTimeout(
+ TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
if (IsRenderViewLive()) {
// Since we are sending an IPC message to the renderer, increase the event
// count to prevent the hang monitor timeout from being stopped by input
// event acknowledgements.
- increment_in_flight_event_count();
+ GetWidget()->increment_in_flight_event_count();
// TODO(creis): Should this be moved to Shutdown? It may not be called for
// RenderViewHosts that have been swapped out.
@@ -565,7 +562,7 @@ void RenderViewHostImpl::ClosePage() {
}
void RenderViewHostImpl::ClosePageIgnoringUnloadEvents() {
- StopHangMonitorTimeout();
+ GetWidget()->StopHangMonitorTimeout();
is_waiting_for_close_ack_ = false;
sudden_termination_allowed_ = true;
@@ -595,10 +592,10 @@ void RenderViewHostImpl::RenderProcessReady(RenderProcessHost* host) {
void RenderViewHostImpl::RenderProcessExited(RenderProcessHost* host,
base::TerminationStatus status,
int exit_code) {
- if (!renderer_initialized())
+ if (!GetWidget()->renderer_initialized())
return;
- RenderWidgetHostImpl::RendererExited(status, exit_code);
+ GetWidget()->RendererExited(status, exit_code);
delegate_->RenderViewTerminated(this, status, exit_code);
}
@@ -734,6 +731,22 @@ void RenderViewHostImpl::DragSourceSystemDragEnded() {
Send(new DragMsg_SourceSystemDragEnded(GetRoutingID()));
}
+bool RenderViewHostImpl::Send(IPC::Message* msg) {
+ return GetWidget()->Send(msg);
+}
+
+RenderWidgetHostImpl* RenderViewHostImpl::GetWidget() const {
+ return render_widget_host_.get();
+}
+
+RenderProcessHost* RenderViewHostImpl::GetProcess() const {
+ return GetWidget()->GetProcess();
+}
+
+int RenderViewHostImpl::GetRoutingID() const {
+ return GetWidget()->GetRoutingID();
+}
+
RenderFrameHost* RenderViewHostImpl::GetMainFrame() {
return RenderFrameHost::FromID(GetProcess()->GetID(), main_frame_routing_id_);
}
@@ -766,7 +779,7 @@ void RenderViewHostImpl::AllowBindings(int bindings_flags) {
}
enabled_bindings_ |= bindings_flags;
- if (renderer_initialized())
+ if (GetWidget()->renderer_initialized())
Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
}
@@ -789,24 +802,12 @@ void RenderViewHostImpl::SetWebUIProperty(const std::string& name,
}
}
-void RenderViewHostImpl::GotFocus() {
- RenderWidgetHostImpl::GotFocus(); // Notifies the renderer it got focus.
-
+void RenderViewHostImpl::RenderWidgetGotFocus() {
RenderViewHostDelegateView* view = delegate_->GetDelegateView();
if (view)
view->GotFocus();
}
-void RenderViewHostImpl::LostCapture() {
- RenderWidgetHostImpl::LostCapture();
- delegate_->LostCapture();
-}
-
-void RenderViewHostImpl::LostMouseLock() {
- RenderWidgetHostImpl::LostMouseLock();
- delegate_->LostMouseLock();
-}
-
void RenderViewHostImpl::SetInitialFocus(bool reverse) {
Send(new ViewMsg_SetInitialFocus(GetRoutingID(), reverse));
}
@@ -852,7 +853,7 @@ void RenderViewHostImpl::DirectoryEnumerationFinished(
files));
}
-void RenderViewHostImpl::SetIsLoading(bool is_loading) {
+void RenderViewHostImpl::RenderWidgetWillSetIsLoading(bool is_loading) {
if (ResourceDispatcherHostImpl::Get()) {
BrowserThread::PostTask(
BrowserThread::IO,
@@ -863,14 +864,13 @@ void RenderViewHostImpl::SetIsLoading(bool is_loading) {
GetRoutingID(),
is_loading));
}
- RenderWidgetHostImpl::SetIsLoading(is_loading);
}
void RenderViewHostImpl::LoadStateChanged(
const GURL& url,
const net::LoadStateWithParam& load_state,
- uint64 upload_position,
- uint64 upload_size) {
+ uint64_t upload_position,
+ uint64_t upload_size) {
delegate_->LoadStateChanged(url, load_state, upload_position, upload_size);
}
@@ -883,7 +883,7 @@ bool RenderViewHostImpl::SuddenTerminationAllowed() const {
// RenderViewHostImpl, IPC message handlers:
bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
- if (!BrowserMessageFilter::CheckCanDispatchOnUI(msg, this))
+ if (!BrowserMessageFilter::CheckCanDispatchOnUI(msg, GetWidget()))
return true;
// Filter out most IPC messages if this renderer is swapped out.
@@ -929,24 +929,20 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnFocusedNodeChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidZoomURL, OnDidZoomURL)
- IPC_MESSAGE_HANDLER(ViewHostMsg_PageScaleFactorIsOneChanged,
- OnPageScaleFactorIsOneChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnFocus)
IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched)
- // Have the super handle all other messages.
- IPC_MESSAGE_UNHANDLED(
- handled = RenderWidgetHostImpl::OnMessageReceived(msg))
+ IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
-void RenderViewHostImpl::Init() {
- RenderWidgetHostImpl::Init();
+void RenderViewHostImpl::RenderWidgetDidInit() {
PostRenderViewReady();
}
-void RenderViewHostImpl::Shutdown() {
+void RenderViewHostImpl::ShutdownAndDestroy() {
// We can't release the SessionStorageNamespace until our peer
// in the renderer has wound down.
if (GetProcess()->HasConnection()) {
@@ -956,10 +952,11 @@ void RenderViewHostImpl::Shutdown() {
GetRoutingID());
}
- RenderWidgetHostImpl::Shutdown();
+ GetWidget()->ShutdownAndDestroyWidget(false);
+ delete this;
}
-void RenderViewHostImpl::WasHidden() {
+void RenderViewHostImpl::RenderWidgetWillBeHidden() {
if (ResourceDispatcherHostImpl::Get()) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -967,11 +964,9 @@ void RenderViewHostImpl::WasHidden() {
base::Unretained(ResourceDispatcherHostImpl::Get()),
GetProcess()->GetID(), GetRoutingID()));
}
-
- RenderWidgetHostImpl::WasHidden();
}
-void RenderViewHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
+void RenderViewHostImpl::RenderWidgetWillBeShown() {
if (ResourceDispatcherHostImpl::Get()) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -979,17 +974,12 @@ void RenderViewHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
base::Unretained(ResourceDispatcherHostImpl::Get()),
GetProcess()->GetID(), GetRoutingID()));
}
-
- RenderWidgetHostImpl::WasShown(latency_info);
-}
-
-bool RenderViewHostImpl::IsRenderView() const {
- return true;
}
void RenderViewHostImpl::CreateNewWindow(
- int route_id,
- int main_frame_route_id,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) {
ViewHostMsg_CreateWindow_Params validated_params(params);
@@ -998,15 +988,16 @@ void RenderViewHostImpl::CreateNewWindow(
GetProcess()->FilterURL(true, &validated_params.opener_security_origin);
delegate_->CreateNewWindow(GetSiteInstance(), route_id, main_frame_route_id,
- validated_params, session_storage_namespace);
+ main_frame_widget_route_id, validated_params,
+ session_storage_namespace);
}
-void RenderViewHostImpl::CreateNewWidget(int32 route_id,
+void RenderViewHostImpl::CreateNewWidget(int32_t route_id,
blink::WebPopupType popup_type) {
delegate_->CreateNewWidget(GetProcess()->GetID(), route_id, popup_type);
}
-void RenderViewHostImpl::CreateNewFullscreenWidget(int32 route_id) {
+void RenderViewHostImpl::CreateNewFullscreenWidget(int32_t route_id) {
delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), route_id);
}
@@ -1039,7 +1030,8 @@ void RenderViewHostImpl::OnRenderProcessGone(int status, int exit_code) {
// decoupled.
}
-void RenderViewHostImpl::OnUpdateState(int32 page_id, const PageState& state) {
+void RenderViewHostImpl::OnUpdateState(int32_t page_id,
+ const PageState& state) {
// If the following DCHECK fails, you have encountered a tricky edge-case that
// has evaded reproduction for a very long time. Please report what you were
// doing on http://crbug.com/407376, whether or not you can reproduce the
@@ -1097,10 +1089,6 @@ void RenderViewHostImpl::OnDidContentsPreferredSizeChange(
delegate_->UpdatePreferredSize(new_size);
}
-void RenderViewHostImpl::OnRenderAutoResized(const gfx::Size& new_size) {
- delegate_->ResizeDueToAutoResize(new_size);
-}
-
void RenderViewHostImpl::OnRouteCloseEvent() {
// Have the delegate route this to the active RenderViewHost.
delegate_->RouteCloseEvent(this);
@@ -1154,7 +1142,7 @@ void RenderViewHostImpl::OnStartDragging(
filtered_data.file_system_files.push_back(drop_data.file_system_files[i]);
}
- float scale = GetScaleFactorForView(GetView());
+ float scale = GetScaleFactorForView(GetWidget()->GetView());
gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale));
view->StartDragging(filtered_data, drag_operations_mask, image,
bitmap_offset_in_dip, event_info);
@@ -1176,8 +1164,8 @@ void RenderViewHostImpl::OnFocusedNodeChanged(
bool is_editable_node,
const gfx::Rect& node_bounds_in_viewport) {
is_focused_element_editable_ = is_editable_node;
- if (view_)
- view_->FocusedNodeChanged(is_editable_node);
+ if (GetWidget()->GetView())
+ GetWidget()->GetView()->FocusedNodeChanged(is_editable_node);
#if defined(OS_WIN)
if (!is_editable_node && virtual_keyboard_requested_) {
virtual_keyboard_requested_ = false;
@@ -1189,8 +1177,12 @@ void RenderViewHostImpl::OnFocusedNodeChanged(
}
#endif
+ // None of the rest makes sense without a view.
+ if (!GetWidget()->GetView())
+ return;
+
// Convert node_bounds to screen coordinates.
- gfx::Rect view_bounds_in_screen = view_->GetViewBounds();
+ gfx::Rect view_bounds_in_screen = GetWidget()->GetView()->GetViewBounds();
gfx::Point origin = node_bounds_in_viewport.origin();
origin.Offset(view_bounds_in_screen.x(), view_bounds_in_screen.y());
gfx::Rect node_bounds_in_screen(origin.x(), origin.y(),
@@ -1202,74 +1194,43 @@ void RenderViewHostImpl::OnFocusedNodeChanged(
Details<FocusedNodeDetails>(&details));
}
-void RenderViewHostImpl::OnUserGesture() {
- delegate_->OnUserGesture();
-}
-
void RenderViewHostImpl::OnClosePageACK() {
- decrement_in_flight_event_count();
+ GetWidget()->decrement_in_flight_event_count();
ClosePageIgnoringUnloadEvents();
}
-void RenderViewHostImpl::NotifyRendererUnresponsive() {
- delegate_->RendererUnresponsive(this);
-}
-
-void RenderViewHostImpl::NotifyRendererResponsive() {
- delegate_->RendererResponsive(this);
-}
-
-void RenderViewHostImpl::RequestToLockMouse(bool user_gesture,
- bool last_unlocked_by_target) {
- delegate_->RequestToLockMouse(user_gesture, last_unlocked_by_target);
-}
-
-bool RenderViewHostImpl::IsFullscreenGranted() const {
- return delegate_->IsFullscreenForCurrentTab();
-}
-
-blink::WebDisplayMode RenderViewHostImpl::GetDisplayMode() const {
- return delegate_->GetDisplayMode();
-}
-
void RenderViewHostImpl::OnFocus() {
// Note: We allow focus and blur from swapped out RenderViewHosts, even when
// the active RenderViewHost is in a different BrowsingInstance (e.g., WebUI).
delegate_->Activate();
}
-void RenderViewHostImpl::OnBlur() {
- delegate_->Deactivate();
-}
-
-gfx::Rect RenderViewHostImpl::GetRootWindowResizerRect() const {
- return delegate_->GetRootWindowResizerRect();
-}
-
-void RenderViewHostImpl::ForwardMouseEvent(
+void RenderViewHostImpl::RenderWidgetDidForwardMouseEvent(
const blink::WebMouseEvent& mouse_event) {
- RenderWidgetHostImpl::ForwardMouseEvent(mouse_event);
- if (mouse_event.type == WebInputEvent::MouseWheel && ignore_input_events())
+ if (mouse_event.type == WebInputEvent::MouseWheel &&
+ GetWidget()->ignore_input_events()) {
delegate_->OnIgnoredUIEvent();
+ }
}
-void RenderViewHostImpl::ForwardKeyboardEvent(
+bool RenderViewHostImpl::MayRenderWidgetForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event) {
- if (ignore_input_events()) {
+ if (GetWidget()->ignore_input_events()) {
if (key_event.type == WebInputEvent::RawKeyDown)
delegate_->OnIgnoredUIEvent();
- return;
+ return false;
}
- RenderWidgetHostImpl::ForwardKeyboardEvent(key_event);
+ return true;
}
void RenderViewHostImpl::OnTextSurroundingSelectionResponse(
const base::string16& content,
size_t start_offset,
size_t end_offset) {
- if (!view_)
+ if (!GetWidget()->GetView())
return;
- view_->OnTextSurroundingSelectionResponse(content, start_offset, end_offset);
+ GetWidget()->GetView()->OnTextSurroundingSelectionResponse(
+ content, start_offset, end_offset);
}
WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
@@ -1318,15 +1279,15 @@ void RenderViewHostImpl::EnablePreferredSizeMode() {
void RenderViewHostImpl::EnableAutoResize(const gfx::Size& min_size,
const gfx::Size& max_size) {
- SetAutoResize(true, min_size, max_size);
+ GetWidget()->SetAutoResize(true, min_size, max_size);
Send(new ViewMsg_EnableAutoResize(GetRoutingID(), min_size, max_size));
}
void RenderViewHostImpl::DisableAutoResize(const gfx::Size& new_size) {
- SetAutoResize(false, gfx::Size(), gfx::Size());
+ GetWidget()->SetAutoResize(false, gfx::Size(), gfx::Size());
Send(new ViewMsg_DisableAutoResize(GetRoutingID(), new_size));
if (!new_size.IsEmpty())
- GetView()->SetSize(new_size);
+ GetWidget()->GetView()->SetSize(new_size);
}
void RenderViewHostImpl::CopyImageAt(int x, int y) {
@@ -1362,19 +1323,6 @@ void RenderViewHostImpl::OnDidZoomURL(double zoom_level,
net::GetHostOrSpecFromURL(url));
}
-void RenderViewHostImpl::OnPageScaleFactorIsOneChanged(bool is_one) {
- if (!GetSiteInstance())
- return;
- HostZoomMapImpl* host_zoom_map =
- static_cast<HostZoomMapImpl*>(HostZoomMap::Get(GetSiteInstance()));
- if (!host_zoom_map)
- return;
- if (!GetProcess())
- return;
- host_zoom_map->SetPageScaleFactorIsOneForView(GetProcess()->GetID(),
- GetRoutingID(), is_one);
-}
-
void RenderViewHostImpl::OnRunFileChooser(const FileChooserParams& params) {
// Do not allow messages with absolute paths in them as this can permit a
// renderer to coerce the browser to perform I/O on a renderer controlled
diff --git a/chromium/content/browser/renderer_host/render_view_host_impl.h b/chromium/content/browser/renderer_host/render_view_host_impl.h
index 59a104ab792..9d9455dfab7 100644
--- a/chromium/content/browser/renderer_host/render_view_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_view_host_impl.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
@@ -13,9 +16,12 @@
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/kill.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/drag_event_source_info.h"
#include "content/public/browser/notification_observer.h"
@@ -30,48 +36,17 @@
#include "ui/base/window_open_disposition.h"
class SkBitmap;
-class FrameMsg_Navigate;
-struct MediaPlayerAction;
struct ViewHostMsg_CreateWindow_Params;
-struct ViewMsg_PostMessage_Params;
-
-namespace base {
-class ListValue;
-}
-
-namespace gfx {
-class Range;
-}
-
-namespace ui {
-class AXTree;
-}
namespace content {
-class MediaWebContentsObserver;
-class ChildProcessSecurityPolicyImpl;
class PageState;
class RenderWidgetHostDelegate;
class SessionStorageNamespace;
-class SessionStorageNamespaceImpl;
-class TestRenderViewHost;
struct FileChooserFileInfo;
struct FileChooserParams;
struct FrameReplicationState;
-#if defined(COMPILER_MSVC)
-// RenderViewHostImpl is the bottom of a diamond-shaped hierarchy,
-// with RenderWidgetHost at the root. VS warns when methods from the
-// root are overridden in only one of the base classes and not both
-// (in this case, RenderWidgetHostImpl provides implementations of
-// many of the methods). This is a silly warning when dealing with
-// pure virtual methods that only have a single implementation in the
-// hierarchy above this class, and is safe to ignore in this case.
-#pragma warning(push)
-#pragma warning(disable: 4250)
-#endif
-
// This implements the RenderViewHost interface that is exposed to
// embedders of content, and adds things only visible to content.
//
@@ -93,36 +68,32 @@ struct FrameReplicationState;
//
// For context, please see https://crbug.com/467770 and
// http://www.chromium.org/developers/design-documents/site-isolation.
-class CONTENT_EXPORT RenderViewHostImpl
- : public RenderViewHost,
- public RenderWidgetHostImpl,
- public RenderProcessHostObserver {
+class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
+ public RenderWidgetHostOwnerDelegate,
+ public RenderProcessHostObserver {
public:
// Convenience function, just like RenderViewHost::FromID.
static RenderViewHostImpl* FromID(int render_process_id, int render_view_id);
- // |routing_id| could be a valid route id, or it could be MSG_ROUTING_NONE, in
- // which case RenderWidgetHost will create a new one. |swapped_out| indicates
- // whether the view should initially be swapped out (e.g., for an opener
- // frame being rendered by another process). |hidden| indicates whether the
- // view is initially hidden or visible.
- //
- // The |session_storage_namespace| parameter allows multiple render views and
- // WebContentses to share the same session storage (part of the WebStorage
- // spec) space. This is useful when restoring contentses, but most callers
- // should pass in NULL which will cause a new SessionStorageNamespace to be
- // created.
+ // Convenience function, just like RenderViewHost::From.
+ static RenderViewHostImpl* From(RenderWidgetHost* rwh);
+
RenderViewHostImpl(SiteInstance* instance,
+ scoped_ptr<RenderWidgetHostImpl> widget,
RenderViewHostDelegate* delegate,
- RenderWidgetHostDelegate* widget_delegate,
- int32 routing_id,
- int32 main_frame_routing_id,
+ int32_t main_frame_routing_id,
bool swapped_out,
- bool hidden,
bool has_initialized_audio_host);
~RenderViewHostImpl() override;
+ // Shuts down this RenderViewHost and deletes it.
+ void ShutdownAndDestroy();
+
// RenderViewHost implementation.
+ bool Send(IPC::Message* msg) override;
+ RenderWidgetHostImpl* GetWidget() const override;
+ RenderProcessHost* GetProcess() const override;
+ int GetRoutingID() const override;
RenderFrameHost* GetMainFrame() override;
void AllowBindings(int binding_flags) override;
void ClearFocusedElement() override;
@@ -163,7 +134,7 @@ class CONTENT_EXPORT RenderViewHostImpl
const gfx::Point& location,
const blink::WebPluginAction& action) override;
void FilesSelectedInChooser(
- const std::vector<content::FileChooserFileInfo>& files,
+ const std::vector<FileChooserFileInfo>& files,
FileChooserParams::Mode permissions) override;
RenderViewHostDelegate* GetDelegate() const override;
int GetEnabledBindings() const override;
@@ -208,7 +179,7 @@ class CONTENT_EXPORT RenderViewHostImpl
virtual bool CreateRenderView(
int opener_frame_route_id,
int proxy_route_id,
- int32 max_page_id,
+ int32_t max_page_id,
const FrameReplicationState& replicated_frame_state,
bool window_was_created_with_opener);
@@ -262,43 +233,27 @@ class CONTENT_EXPORT RenderViewHostImpl
// Notifies the RenderViewHost that its load state changed.
void LoadStateChanged(const GURL& url,
const net::LoadStateWithParam& load_state,
- uint64 upload_position,
- uint64 upload_size);
+ uint64_t upload_position,
+ uint64_t upload_size);
bool SuddenTerminationAllowed() const;
void set_sudden_termination_allowed(bool enabled) {
sudden_termination_allowed_ = enabled;
}
- // RenderWidgetHost public overrides.
- void Init() override;
- void Shutdown() override;
- void WasHidden() override;
- void WasShown(const ui::LatencyInfo& latency_info) override;
- bool IsRenderView() const override;
- bool OnMessageReceived(const IPC::Message& msg) override;
- void GotFocus() override;
- void LostCapture() override;
- void LostMouseLock() override;
- void SetIsLoading(bool is_loading) override;
- void ForwardMouseEvent(const blink::WebMouseEvent& mouse_event) override;
- void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event) override;
- gfx::Rect GetRootWindowResizerRect() const override;
-
// Creates a new RenderView with the given route id.
- void CreateNewWindow(
- int route_id,
- int main_frame_route_id,
- const ViewHostMsg_CreateWindow_Params& params,
- SessionStorageNamespace* session_storage_namespace);
+ void CreateNewWindow(int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
+ const ViewHostMsg_CreateWindow_Params& params,
+ SessionStorageNamespace* session_storage_namespace);
// Creates a new RenderWidget with the given route id. |popup_type| indicates
// if this widget is a popup and what kind of popup it is (select, autofill).
- void CreateNewWidget(int32 route_id,
- blink::WebPopupType popup_type);
+ void CreateNewWidget(int32_t route_id, blink::WebPopupType popup_type);
// Creates a full screen RenderWidget.
- void CreateNewFullscreenWidget(int32 route_id);
+ void CreateNewFullscreenWidget(int32_t route_id);
void set_main_frame_routing_id(int routing_id) {
main_frame_routing_id_ = routing_id;
@@ -320,28 +275,23 @@ class CONTENT_EXPORT RenderViewHostImpl
// currently using it.
int ref_count() { return frames_ref_count_; }
- // TODO(avi): Move to RenderFrameHost once PageState is broken up into
- // FrameStates.
- int nav_entry_id() const { return nav_entry_id_; }
- void set_nav_entry_id(int nav_entry_id) { nav_entry_id_ = nav_entry_id; }
-
// NOTE: Do not add functions that just send an IPC message that are called in
// one or two places. Have the caller send the IPC message directly (unless
// the caller places are in different platforms, in which case it's better
// to keep them consistent).
protected:
- // RenderWidgetHost protected overrides.
- void OnUserGesture() override;
- void NotifyRendererUnresponsive() override;
- void NotifyRendererResponsive() override;
- void OnRenderAutoResized(const gfx::Size& size) override;
- void RequestToLockMouse(bool user_gesture,
- bool last_unlocked_by_target) override;
- bool IsFullscreenGranted() const override;
- blink::WebDisplayMode GetDisplayMode() const override;
- void OnFocus() override;
- void OnBlur() override;
+ // RenderWidgetHostOwnerDelegate overrides.
+ bool OnMessageReceived(const IPC::Message& msg) override;
+ void RenderWidgetDidInit() override;
+ void RenderWidgetWillSetIsLoading(bool is_loading) override;
+ void RenderWidgetGotFocus() override;
+ void RenderWidgetWillBeHidden() override;
+ void RenderWidgetWillBeShown() override;
+ void RenderWidgetDidForwardMouseEvent(
+ const blink::WebMouseEvent& mouse_event) override;
+ bool MayRenderWidgetForwardKeyboardEvent(
+ const NativeWebKeyboardEvent& key_event) override;
// IPC message handlers.
void OnShowView(int route_id,
@@ -351,7 +301,7 @@ class CONTENT_EXPORT RenderViewHostImpl
void OnShowWidget(int route_id, const gfx::Rect& initial_rect);
void OnShowFullscreenWidget(int route_id);
void OnRenderProcessGone(int status, int error_code);
- void OnUpdateState(int32 page_id, const PageState& state);
+ void OnUpdateState(int32_t page_id, const PageState& state);
void OnUpdateTargetURL(const GURL& url);
void OnClose();
void OnRequestMove(const gfx::Rect& pos);
@@ -370,9 +320,9 @@ class CONTENT_EXPORT RenderViewHostImpl
const gfx::Rect& node_bounds_in_viewport);
void OnClosePageACK();
void OnDidZoomURL(double zoom_level, const GURL& url);
- void OnPageScaleFactorIsOneChanged(bool is_one);
void OnRunFileChooser(const FileChooserParams& params);
void OnFocusedNodeTouched(bool editable);
+ void OnFocus();
private:
// TODO(nasko): Temporarily friend RenderFrameHostImpl, so we don't duplicate
@@ -392,7 +342,7 @@ class CONTENT_EXPORT RenderViewHostImpl
// TODO(creis): Move to a private namespace on RenderFrameHostImpl.
// Delay to wait on closing the WebContents for a beforeunload/unload handler
// to fire.
- static const int64 kUnloadTimeoutMS;
+ static const int64_t kUnloadTimeoutMS;
// Returns the content specific prefs for this RenderViewHost.
// TODO(creis): Move most of this method to RenderProcessHost, since it's
@@ -410,6 +360,9 @@ class CONTENT_EXPORT RenderViewHostImpl
// files without the user's consent.
void GrantFileAccessFromPageState(const PageState& validated_state);
+ // The RenderWidgetHost.
+ scoped_ptr<RenderWidgetHostImpl> render_widget_host_;
+
// The number of RenderFrameHosts which have a reference to this RVH.
int frames_ref_count_;
@@ -432,12 +385,7 @@ class CONTENT_EXPORT RenderViewHostImpl
// The most recent page ID we've heard from the renderer process. This is
// used as context when other session history related IPCs arrive.
// TODO(creis): Allocate this in WebContents/NavigationController instead.
- int32 page_id_;
-
- // The unique ID of the latest NavigationEntry that this RenderViewHost is
- // showing. TODO(avi): Move to RenderFrameHost once PageState is broken up
- // into FrameStates.
- int nav_entry_id_;
+ int32_t page_id_;
// Tracks whether this RenderViewHost is in an active state. False if the
// main frame is pending swap out, pending deletion, or swapped out, because
@@ -487,10 +435,6 @@ class CONTENT_EXPORT RenderViewHostImpl
DISALLOW_COPY_AND_ASSIGN(RenderViewHostImpl);
};
-#if defined(COMPILER_MSVC)
-#pragma warning(pop)
-#endif
-
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_
diff --git a/chromium/content/browser/renderer_host/render_view_host_unittest.cc b/chromium/content/browser/renderer_host/render_view_host_unittest.cc
index 00b7b3da6f0..fc7d722b9ee 100644
--- a/chromium/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -74,7 +77,7 @@ TEST_F(RenderViewHostTest, FilterAbout) {
// Create a full screen popup RenderWidgetHost and View.
TEST_F(RenderViewHostTest, CreateFullscreenWidget) {
- int32 routing_id = process()->GetNextRoutingID();
+ int32_t routing_id = process()->GetNextRoutingID();
test_rvh()->CreateNewFullscreenWidget(routing_id);
}
diff --git a/chromium/content/browser/renderer_host/render_widget_helper.cc b/chromium/content/browser/renderer_host/render_widget_helper.cc
index 0aad52a6dcb..93283733b31 100644
--- a/chromium/content/browser/renderer_host/render_widget_helper.cc
+++ b/chromium/content/browser/renderer_host/render_widget_helper.cc
@@ -102,8 +102,9 @@ void RenderWidgetHelper::CreateNewWindow(
const ViewHostMsg_CreateWindow_Params& params,
bool no_javascript_access,
base::ProcessHandle render_process,
- int* route_id,
- int* main_frame_route_id,
+ int32_t* route_id,
+ int32_t* main_frame_route_id,
+ int32_t* main_frame_widget_route_id,
SessionStorageNamespace* session_storage_namespace) {
if (params.opener_suppressed || no_javascript_access) {
// If the opener is supppressed or script access is disallowed, we should
@@ -113,34 +114,39 @@ void RenderWidgetHelper::CreateNewWindow(
// in OnCreateWindowOnUI, using the params provided here.
*route_id = MSG_ROUTING_NONE;
*main_frame_route_id = MSG_ROUTING_NONE;
+ *main_frame_widget_route_id = MSG_ROUTING_NONE;
} else {
*route_id = GetNextRoutingID();
*main_frame_route_id = GetNextRoutingID();
+ // TODO(avi): When RenderViewHostImpl has-a RenderWidgetHostImpl, this
+ // should be updated to give the widget a distinct routing ID.
+ // https://crbug.com/545684
+ *main_frame_widget_route_id = *route_id;
// Block resource requests until the view is created, since the HWND might
// be needed if a response ends up creating a plugin.
resource_dispatcher_host_->BlockRequestsForRoute(
render_process_id_, *route_id);
- resource_dispatcher_host_->BlockRequestsForRoute(
- render_process_id_, *main_frame_route_id);
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&RenderWidgetHelper::OnCreateWindowOnUI,
- this, params, *route_id, *main_frame_route_id,
+ base::Bind(&RenderWidgetHelper::OnCreateWindowOnUI, this, params,
+ *route_id, *main_frame_route_id, *main_frame_widget_route_id,
make_scoped_refptr(session_storage_namespace)));
}
void RenderWidgetHelper::OnCreateWindowOnUI(
const ViewHostMsg_CreateWindow_Params& params,
- int route_id,
- int main_frame_route_id,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
SessionStorageNamespace* session_storage_namespace) {
RenderViewHostImpl* host =
RenderViewHostImpl::FromID(render_process_id_, params.opener_id);
if (host)
- host->CreateNewWindow(route_id, main_frame_route_id, params,
- session_storage_namespace);
+ host->CreateNewWindow(route_id, main_frame_route_id,
+ main_frame_widget_route_id, params,
+ session_storage_namespace);
}
void RenderWidgetHelper::OnResumeRequestsForView(int route_id) {
@@ -166,8 +172,8 @@ void RenderWidgetHelper::CreateNewFullscreenWidget(int opener_id,
opener_id, *route_id));
}
-void RenderWidgetHelper::OnCreateWidgetOnUI(int32 opener_id,
- int32 route_id,
+void RenderWidgetHelper::OnCreateWidgetOnUI(int32_t opener_id,
+ int32_t route_id,
blink::WebPopupType popup_type) {
RenderViewHostImpl* host = RenderViewHostImpl::FromID(
render_process_id_, opener_id);
@@ -175,8 +181,8 @@ void RenderWidgetHelper::OnCreateWidgetOnUI(int32 opener_id,
host->CreateNewWidget(route_id, popup_type);
}
-void RenderWidgetHelper::OnCreateFullscreenWidgetOnUI(int32 opener_id,
- int32 route_id) {
+void RenderWidgetHelper::OnCreateFullscreenWidgetOnUI(int32_t opener_id,
+ int32_t route_id) {
RenderViewHostImpl* host = RenderViewHostImpl::FromID(
render_process_id_, opener_id);
if (host)
diff --git a/chromium/content/browser/renderer_host/render_widget_helper.h b/chromium/content/browser/renderer_host/render_widget_helper.h
index 18576a41a66..c4b8baf7bf4 100644
--- a/chromium/content/browser/renderer_host/render_widget_helper.h
+++ b/chromium/content/browser/renderer_host/render_widget_helper.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_
+#include <stdint.h>
+
#include <map>
#include "base/atomic_sequence_num.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
#include "content/public/browser/browser_thread.h"
@@ -99,13 +102,13 @@ class RenderWidgetHelper
// IO THREAD ONLY -----------------------------------------------------------
- void CreateNewWindow(
- const ViewHostMsg_CreateWindow_Params& params,
- bool no_javascript_access,
- base::ProcessHandle render_process,
- int* route_id,
- int* main_frame_route_id,
- SessionStorageNamespace* session_storage_namespace);
+ void CreateNewWindow(const ViewHostMsg_CreateWindow_Params& params,
+ bool no_javascript_access,
+ base::ProcessHandle render_process,
+ int32_t* route_id,
+ int32_t* main_frame_route_id,
+ int32_t* main_frame_widget_route_id,
+ SessionStorageNamespace* session_storage_namespace);
void CreateNewWidget(int opener_id,
blink::WebPopupType popup_type,
int* route_id);
@@ -119,22 +122,22 @@ class RenderWidgetHelper
~RenderWidgetHelper();
// Called on the UI thread to finish creating a window.
- void OnCreateWindowOnUI(
- const ViewHostMsg_CreateWindow_Params& params,
- int route_id,
- int main_frame_route_id,
- SessionStorageNamespace* session_storage_namespace);
+ void OnCreateWindowOnUI(const ViewHostMsg_CreateWindow_Params& params,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
+ SessionStorageNamespace* session_storage_namespace);
// Called on the IO thread after a window was created on the UI thread.
void OnResumeRequestsForView(int route_id);
// Called on the UI thread to finish creating a widget.
- void OnCreateWidgetOnUI(int32 opener_id,
- int32 route_id,
+ void OnCreateWidgetOnUI(int32_t opener_id,
+ int32_t route_id,
blink::WebPopupType popup_type);
// Called on the UI thread to create a fullscreen widget.
- void OnCreateFullscreenWidgetOnUI(int32 opener_id, int32 route_id);
+ void OnCreateFullscreenWidgetOnUI(int32_t opener_id, int32_t route_id);
// Called on the IO thread to resume a paused navigation in the network
// stack without transferring it to a new renderer process.
diff --git a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
index 7b8def6c715..c158a41c529 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -2,8 +2,9 @@
// 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 "build/build_config.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "ui/gfx/geometry/rect.h"
namespace content {
@@ -47,4 +48,26 @@ RenderWidgetHostDelegate::GetInputEventRouter() {
return nullptr;
}
+// If a delegate does not override this, the RenderWidgetHostView will
+// assume its own RenderWidgetHost should consume keyboard events.
+RenderWidgetHostImpl* RenderWidgetHostDelegate::GetFocusedRenderWidgetHost(
+ RenderWidgetHostImpl* receiving_widget) {
+ return receiving_widget;
+}
+
+gfx::Rect RenderWidgetHostDelegate::GetRootWindowResizerRect(
+ RenderWidgetHostImpl* render_widget_host) const {
+ return gfx::Rect();
+};
+
+bool RenderWidgetHostDelegate::IsFullscreenForCurrentTab(
+ RenderWidgetHostImpl* render_widget_host) const {
+ return false;
+}
+
+blink::WebDisplayMode RenderWidgetHostDelegate::GetDisplayMode(
+ RenderWidgetHostImpl* render_widget_host) const {
+ return blink::WebDisplayModeBrowser;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_delegate.h b/chromium/content/browser/renderer_host/render_widget_host_delegate.h
index 5a20a8d8b78..f7fbb0e3622 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.h
@@ -5,9 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_DELEGATE_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_DELEGATE_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <vector>
+
#include "build/build_config.h"
#include "content/common/content_export.h"
+#include "third_party/WebKit/public/platform/WebDisplayMode.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/gfx/native_widget_types.h"
namespace blink {
@@ -17,6 +22,8 @@ class WebGestureEvent;
namespace gfx {
class Point;
+class Rect;
+class Size;
}
namespace content {
@@ -33,6 +40,9 @@ struct NativeWebKeyboardEvent;
// of the RenderWidgetHost.
class CONTENT_EXPORT RenderWidgetHostDelegate {
public:
+ // The RenderWidgetHost has just been created.
+ virtual void RenderWidgetCreated(RenderWidgetHostImpl* render_widget_host) {}
+
// The RenderWidgetHost is going to be deleted.
virtual void RenderWidgetDeleted(RenderWidgetHostImpl* render_widget_host) {}
@@ -43,6 +53,10 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
virtual void RenderWidgetWasResized(RenderWidgetHostImpl* render_widget_host,
bool width_changed) {}
+ // The contents auto-resized and the container should match it.
+ virtual void ResizeDueToAutoResize(RenderWidgetHostImpl* render_widget_host,
+ const gfx::Size& new_size) {}
+
// The screen info has changed.
virtual void ScreenInfoChanged() {}
@@ -64,11 +78,22 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
// the event itself.
virtual bool HandleWheelEvent(const blink::WebMouseWheelEvent& event);
+ // Notification the user has performed a direct interaction (mouse down, mouse
+ // wheel, raw key down, or gesture tap) while focus was on the page. Informs
+ // the delegate that a user is interacting with a site. Only the first mouse
+ // wheel event during a scroll will trigger this method.
+ virtual void OnUserInteraction(const blink::WebInputEvent::Type type) {}
+
// Callback to give the browser a chance to handle the specified gesture
// event before sending it to the renderer.
// Returns true if the |event| was handled.
virtual bool PreHandleGestureEvent(const blink::WebGestureEvent& event);
+ // Notification the user has made a gesture while focus was on the
+ // page. This is used to avoid uninitiated user downloads (aka carpet
+ // bombing), see DownloadRequestLimiter for details.
+ virtual void OnUserGesture(RenderWidgetHostImpl* render_widget_host) {}
+
// Notifies that screen rects were sent to renderer process.
virtual void DidSendScreenRects(RenderWidgetHostImpl* rwh) {}
@@ -95,10 +120,66 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
virtual RenderWidgetHostInputEventRouter* GetInputEventRouter();
+ // Send page-level focus state to all SiteInstances involved in rendering the
+ // current FrameTree, not including the main frame's SiteInstance.
+ virtual void ReplicatePageFocus(bool is_focused) {}
+
+ // Get the focused RenderWidgetHost associated with |receiving_widget|. A
+ // RenderWidgetHostView, upon receiving a keyboard event, will pass its
+ // RenderWidgetHost to this function to determine who should ultimately
+ // consume the event. This facilitates keyboard event routing with
+ // out-of-process iframes, where multiple RenderWidgetHosts may be involved
+ // in rendering a page, yet keyboard events all arrive at the main frame's
+ // RenderWidgetHostView. When a main frame's RenderWidgetHost is passed in,
+ // the function returns the focused frame that should consume keyboard
+ // events. In all other cases, the function returns back |receiving_widget|.
+ virtual RenderWidgetHostImpl* GetFocusedRenderWidgetHost(
+ RenderWidgetHostImpl* receiving_widget);
+
+ // Notification that the renderer has become unresponsive. The
+ // delegate can use this notification to show a warning to the user.
+ virtual void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) {}
+
+ // Notification that a previously unresponsive renderer has become
+ // responsive again. The delegate can use this notification to end the
+ // warning shown to the user.
+ virtual void RendererResponsive(RenderWidgetHostImpl* render_widget_host) {}
+
+ // Requests to lock the mouse. Once the request is approved or rejected,
+ // GotResponseToLockMouseRequest() will be called on the requesting render
+ // widget host.
+ virtual void RequestToLockMouse(RenderWidgetHostImpl* render_widget_host,
+ bool user_gesture,
+ bool last_unlocked_by_target) {}
+
+ // Return the rect where to display the resize corner, if any, otherwise
+ // an empty rect.
+ virtual gfx::Rect GetRootWindowResizerRect(
+ RenderWidgetHostImpl* render_widget_host) const;
+
+ // Returns whether the associated tab is in fullscreen mode.
+ virtual bool IsFullscreenForCurrentTab(
+ RenderWidgetHostImpl* render_widget_host) const;
+
+ // Returns the display mode for the view.
+ virtual blink::WebDisplayMode GetDisplayMode(
+ RenderWidgetHostImpl* render_widget_host) const;
+
+ // Notification that the widget has lost capture.
+ virtual void LostCapture(RenderWidgetHostImpl* render_widget_host) {}
+
+ // Notification that the widget has lost the mouse lock.
+ virtual void LostMouseLock(RenderWidgetHostImpl* render_widget_host) {}
+
#if defined(OS_WIN)
virtual gfx::NativeViewAccessible GetParentNativeViewAccessible();
#endif
+ // Called when the widget has sent a compositor proto. This is used in Blimp
+ // mode with the RemoteChannel compositor.
+ virtual void ForwardCompositorProto(RenderWidgetHostImpl* render_widget_host,
+ const std::vector<uint8_t>& proto) {}
+
protected:
virtual ~RenderWidgetHostDelegate() {}
};
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
index 512dfee75fc..6516e5ec903 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
@@ -15,6 +15,7 @@
#include "base/i18n/rtl.h"
#include "base/lazy_instance.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/single_thread_task_runner.h"
@@ -22,6 +23,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "cc/base/switches.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
@@ -43,8 +45,10 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/content_constants_internal.h"
+#include "content/common/content_switches_internal.h"
#include "content/common/cursors/webcursor.h"
#include "content/common/frame_messages.h"
#include "content/common/gpu/gpu_messages.h"
@@ -92,6 +96,13 @@ using blink::WebTextDirection;
namespace content {
namespace {
+// The amount of time after a mouse wheel event is sent to the delegate
+// OnUserInteraction method before another mouse wheel event will be sent. This
+// interval is used by the Blink EventHandler in its orthogonal heuristic for
+// detecting the end of a scroll event (if no event has been seen in 0.1
+// seconds, send an end scroll).
+const double kMouseWheelCoalesceIntervalInSeconds = 0.1;
+
bool g_check_for_pending_resize_ack = true;
// <process id, routing id>
@@ -141,6 +152,7 @@ inline blink::WebGestureEvent CreateScrollBeginForWrapping(
blink::WebGestureEvent wrap_gesture_scroll_begin;
wrap_gesture_scroll_begin.type = blink::WebInputEvent::GestureScrollBegin;
+ wrap_gesture_scroll_begin.sourceDevice = gesture_event.sourceDevice;
wrap_gesture_scroll_begin.data.scrollBegin.deltaXHint = 0;
wrap_gesture_scroll_begin.data.scrollBegin.deltaYHint = 0;
wrap_gesture_scroll_begin.resendingPluginId = gesture_event.resendingPluginId;
@@ -154,6 +166,7 @@ inline blink::WebGestureEvent CreateScrollEndForWrapping(
blink::WebGestureEvent wrap_gesture_scroll_end;
wrap_gesture_scroll_end.type = blink::WebInputEvent::GestureScrollEnd;
+ wrap_gesture_scroll_end.sourceDevice = gesture_event.sourceDevice;
wrap_gesture_scroll_end.resendingPluginId = gesture_event.resendingPluginId;
return wrap_gesture_scroll_end;
@@ -168,13 +181,10 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
int32_t routing_id,
bool hidden)
- : view_(NULL),
- hung_renderer_delay_(
- base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
- new_content_rendering_delay_(
- base::TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)),
- renderer_initialized_(false),
+ : renderer_initialized_(false),
+ destroyed_(false),
delegate_(delegate),
+ owner_delegate_(nullptr),
process_(process),
routing_id_(routing_id),
is_loading_(false),
@@ -201,6 +211,11 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
next_browser_snapshot_id_(1),
owned_by_render_frame_host_(false),
is_focused_(false),
+ hung_renderer_delay_(
+ base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
+ new_content_rendering_delay_(
+ base::TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)),
+ mouse_wheel_coalesce_timer_(new base::ElapsedTimer()),
weak_factory_(this) {
CHECK(delegate_);
CHECK_NE(MSG_ROUTING_NONE, routing_id_);
@@ -223,10 +238,7 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
touch_emulator_.reset();
- RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
- IsRenderView() ? RenderViewHost::From(this) : NULL);
- if (BrowserPluginGuest::IsGuest(rvh) ||
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableHangMonitor)) {
hang_monitor_timeout_.reset(new TimeoutMonitor(
base::Bind(&RenderWidgetHostImpl::RendererIsUnresponsive,
@@ -236,19 +248,13 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
new_content_rendering_timeout_.reset(new TimeoutMonitor(
base::Bind(&RenderWidgetHostImpl::ClearDisplayedGraphics,
weak_factory_.GetWeakPtr())));
+
+ delegate_->RenderWidgetCreated(this);
}
RenderWidgetHostImpl::~RenderWidgetHostImpl() {
- if (view_weak_)
- view_weak_->RenderWidgetHostGone();
- SetView(NULL);
-
- process_->RemoveRoute(routing_id_);
- g_routing_id_widget_map.Get().erase(
- RenderWidgetHostID(process_->GetID(), routing_id_));
-
- if (delegate_)
- delegate_->RenderWidgetDeleted(this);
+ if (!destroyed_)
+ Destroy(false);
}
// static
@@ -271,52 +277,46 @@ RenderWidgetHostImpl* RenderWidgetHostImpl::FromID(
// static
scoped_ptr<RenderWidgetHostIterator> RenderWidgetHost::GetRenderWidgetHosts() {
- RenderWidgetHostIteratorImpl* hosts = new RenderWidgetHostIteratorImpl();
- RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
- for (RoutingIDWidgetMap::const_iterator it = widgets->begin();
- it != widgets->end();
- ++it) {
- RenderWidgetHost* widget = it->second;
+ scoped_ptr<RenderWidgetHostIteratorImpl> hosts(
+ new RenderWidgetHostIteratorImpl());
+ for (auto& it : g_routing_id_widget_map.Get()) {
+ RenderWidgetHost* widget = it.second;
- if (!widget->IsRenderView()) {
+ RenderViewHost* rvh = RenderViewHost::From(widget);
+ if (!rvh) {
hosts->Add(widget);
continue;
}
- // Add only active RenderViewHosts.
- RenderViewHost* rvh = RenderViewHost::From(widget);
+ // For RenderViewHosts, add only active ones.
if (static_cast<RenderViewHostImpl*>(rvh)->is_active())
hosts->Add(widget);
}
- return scoped_ptr<RenderWidgetHostIterator>(hosts);
+ return std::move(hosts);
}
// static
scoped_ptr<RenderWidgetHostIterator>
RenderWidgetHostImpl::GetAllRenderWidgetHosts() {
- RenderWidgetHostIteratorImpl* hosts = new RenderWidgetHostIteratorImpl();
- RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
- for (RoutingIDWidgetMap::const_iterator it = widgets->begin();
- it != widgets->end();
- ++it) {
- hosts->Add(it->second);
- }
+ scoped_ptr<RenderWidgetHostIteratorImpl> hosts(
+ new RenderWidgetHostIteratorImpl());
+ for (auto& it : g_routing_id_widget_map.Get())
+ hosts->Add(it.second);
- return scoped_ptr<RenderWidgetHostIterator>(hosts);
+ return std::move(hosts);
}
// static
RenderWidgetHostImpl* RenderWidgetHostImpl::From(RenderWidgetHost* rwh) {
- return rwh->AsRenderWidgetHostImpl();
+ return static_cast<RenderWidgetHostImpl*>(rwh);
}
void RenderWidgetHostImpl::SetView(RenderWidgetHostViewBase* view) {
if (view)
- view_weak_ = view->GetWeakPtr();
+ view_ = view->GetWeakPtr();
else
- view_weak_.reset();
- view_ = view;
+ view_.reset();
// If the renderer has not yet been initialized, then the surface ID
// namespace will be sent during initialization.
@@ -336,12 +336,8 @@ int RenderWidgetHostImpl::GetRoutingID() const {
return routing_id_;
}
-RenderWidgetHostView* RenderWidgetHostImpl::GetView() const {
- return view_;
-}
-
-RenderWidgetHostImpl* RenderWidgetHostImpl::AsRenderWidgetHostImpl() {
- return this;
+RenderWidgetHostViewBase* RenderWidgetHostImpl::GetView() const {
+ return view_.get();
}
gfx::NativeViewId RenderWidgetHostImpl::GetNativeViewId() const {
@@ -414,6 +410,9 @@ void RenderWidgetHostImpl::Init() {
SendScreenRects();
WasResized();
+
+ if (owner_delegate_)
+ owner_delegate_->RenderWidgetDidInit();
}
void RenderWidgetHostImpl::InitForFrame() {
@@ -421,7 +420,7 @@ void RenderWidgetHostImpl::InitForFrame() {
renderer_initialized_ = true;
}
-void RenderWidgetHostImpl::Shutdown() {
+void RenderWidgetHostImpl::ShutdownAndDestroyWidget(bool also_delete) {
RejectMouseLockOrUnlockIfNecessary();
if (process_->HasConnection()) {
@@ -430,18 +429,17 @@ void RenderWidgetHostImpl::Shutdown() {
DCHECK(rv);
}
- Destroy();
+ Destroy(also_delete);
}
bool RenderWidgetHostImpl::IsLoading() const {
return is_loading_;
}
-bool RenderWidgetHostImpl::IsRenderView() const {
- return false;
-}
-
bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
+ if (owner_delegate_ && owner_delegate_->OnMessageReceived(msg))
+ return true;
+
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostImpl, msg)
IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone)
@@ -457,8 +455,6 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame,
OnSwapCompositorFrame(msg))
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
- IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnFocus)
- IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnBlur)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
OnTextInputStateChanged)
@@ -479,6 +475,8 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
OnImeCompositionRangeChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidFirstPaintAfterLoad,
OnFirstPaintAfterLoad)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardCompositorProto,
+ OnForwardCompositorProto)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -499,16 +497,21 @@ bool RenderWidgetHostImpl::Send(IPC::Message* msg) {
}
void RenderWidgetHostImpl::SetIsLoading(bool is_loading) {
+ if (owner_delegate_)
+ owner_delegate_->RenderWidgetWillSetIsLoading(is_loading);
+
is_loading_ = is_loading;
- if (!view_)
- return;
- view_->SetIsLoading(is_loading);
+ if (view_)
+ view_->SetIsLoading(is_loading);
}
void RenderWidgetHostImpl::WasHidden() {
if (is_hidden_)
return;
+ if (owner_delegate_)
+ owner_delegate_->RenderWidgetWillBeHidden();
+
TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::WasHidden");
is_hidden_ = true;
@@ -533,6 +536,9 @@ void RenderWidgetHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
if (!is_hidden_)
return;
+ if (owner_delegate_)
+ owner_delegate_->RenderWidgetWillBeShown();
+
TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::WasShown");
is_hidden_ = false;
@@ -579,7 +585,15 @@ bool RenderWidgetHostImpl::GetResizeParams(
*resize_params = ViewMsg_Resize_Params();
GetWebScreenInfo(&resize_params->screen_info);
- resize_params->resizer_rect = GetRootWindowResizerRect();
+ if (delegate_) {
+ resize_params->resizer_rect = delegate_->GetRootWindowResizerRect(this);
+ resize_params->is_fullscreen_granted =
+ delegate_->IsFullscreenForCurrentTab(this);
+ resize_params->display_mode = delegate_->GetDisplayMode(this);
+ } else {
+ resize_params->is_fullscreen_granted = false;
+ resize_params->display_mode = blink::WebDisplayModeBrowser;
+ }
if (view_) {
resize_params->new_size = view_->GetRequestedRendererSize();
@@ -588,8 +602,6 @@ bool RenderWidgetHostImpl::GetResizeParams(
resize_params->top_controls_shrink_blink_size =
view_->DoTopControlsShrinkBlinkSize();
resize_params->visible_viewport_size = view_->GetVisibleViewportSize();
- resize_params->is_fullscreen_granted = IsFullscreenGranted();
- resize_params->display_mode = GetDisplayMode();
}
const bool size_changed =
@@ -700,6 +712,8 @@ void RenderWidgetHostImpl::ResizeRectChanged(const gfx::Rect& new_rect) {
void RenderWidgetHostImpl::GotFocus() {
Focus();
+ if (owner_delegate_)
+ owner_delegate_->RenderWidgetGotFocus();
if (delegate_)
delegate_->RenderWidgetGotFocus(this);
}
@@ -708,6 +722,11 @@ void RenderWidgetHostImpl::Focus() {
is_focused_ = true;
Send(new InputMsg_SetFocus(routing_id_, true));
+
+ // Also send page-level focus state to other SiteInstances involved in
+ // rendering the current FrameTree.
+ if (RenderViewHost::From(this) && delegate_)
+ delegate_->ReplicatePageFocus(true);
}
void RenderWidgetHostImpl::Blur() {
@@ -723,6 +742,11 @@ void RenderWidgetHostImpl::Blur() {
touch_emulator_->CancelTouch();
Send(new InputMsg_SetFocus(routing_id_, false));
+
+ // Also send page-level focus state to other SiteInstances involved in
+ // rendering the current FrameTree.
+ if (RenderViewHost::From(this) && delegate_)
+ delegate_->ReplicatePageFocus(false);
}
void RenderWidgetHostImpl::LostCapture() {
@@ -730,6 +754,9 @@ void RenderWidgetHostImpl::LostCapture() {
touch_emulator_->CancelTouch();
Send(new InputMsg_MouseCaptureLost(routing_id_));
+
+ if (delegate_)
+ delegate_->LostCapture(this);
}
void RenderWidgetHostImpl::SetActive(bool active) {
@@ -738,6 +765,9 @@ void RenderWidgetHostImpl::SetActive(bool active) {
void RenderWidgetHostImpl::LostMouseLock() {
Send(new ViewMsg_MouseLockLost(routing_id_));
+
+ if (delegate_)
+ delegate_->LostMouseLock(this);
}
void RenderWidgetHostImpl::ViewDestroyed() {
@@ -773,7 +803,6 @@ bool RenderWidgetHostImpl::CanCopyFromBackingStore() {
return false;
}
-#if defined(OS_ANDROID)
void RenderWidgetHostImpl::LockBackingStore() {
if (view_)
view_->LockCompositingSurface();
@@ -783,7 +812,6 @@ void RenderWidgetHostImpl::UnlockBackingStore() {
if (view_)
view_->UnlockCompositingSurface();
}
-#endif
#if defined(OS_MACOSX)
void RenderWidgetHostImpl::PauseForPendingResizeOrRepaints() {
@@ -881,11 +909,6 @@ void RenderWidgetHostImpl::WaitForSurface() {
break;
}
}
-
- UMA_HISTOGRAM_CUSTOM_TIMES("OSX.RendererHost.SurfaceWaitTime",
- TimeTicks::Now() - start_time,
- TimeDelta::FromMilliseconds(1),
- TimeDelta::FromMilliseconds(200), 50);
}
#endif
@@ -942,6 +965,8 @@ void RenderWidgetHostImpl::OnFirstPaintAfterLoad() {
void RenderWidgetHostImpl::ForwardMouseEvent(const WebMouseEvent& mouse_event) {
ForwardMouseEventWithLatencyInfo(mouse_event, ui::LatencyInfo());
+ if (owner_delegate_)
+ owner_delegate_->RenderWidgetDidForwardMouseEvent(mouse_event);
}
void RenderWidgetHostImpl::ForwardMouseEventWithLatencyInfo(
@@ -955,7 +980,7 @@ void RenderWidgetHostImpl::ForwardMouseEventWithLatencyInfo(
return;
}
- if (IgnoreInputEvents())
+ if (ShouldDropInputEvents())
return;
if (touch_emulator_ && touch_emulator_->HandleMouseEvent(mouse_event))
@@ -988,7 +1013,7 @@ void RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo(
TRACE_EVENT2("input", "RenderWidgetHostImpl::ForwardWheelEvent",
"dx", wheel_event.deltaX, "dy", wheel_event.deltaY);
- if (IgnoreInputEvents())
+ if (ShouldDropInputEvents())
return;
if (touch_emulator_ && touch_emulator_->HandleMouseWheelEvent(wheel_event))
@@ -999,6 +1024,11 @@ void RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo(
input_router_->SendWheelEvent(wheel_with_latency);
}
+void RenderWidgetHostImpl::ForwardEmulatedGestureEvent(
+ const blink::WebGestureEvent& gesture_event) {
+ ForwardGestureEvent(gesture_event);
+}
+
void RenderWidgetHostImpl::ForwardGestureEvent(
const blink::WebGestureEvent& gesture_event) {
ForwardGestureEventWithLatencyInfo(gesture_event, ui::LatencyInfo());
@@ -1009,7 +1039,7 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
const ui::LatencyInfo& ui_latency) {
TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardGestureEvent");
// Early out if necessary, prior to performing latency logic.
- if (IgnoreInputEvents())
+ if (ShouldDropInputEvents())
return;
// TODO(wjmaclean) Remove the code for supporting resending gesture events
@@ -1036,6 +1066,7 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
CreateScrollBeginForWrapping(gesture_event), ui::LatencyInfo());
}
+ // Delegate must be non-null, due to |ShouldDropInputEvents()| test.
if (delegate_->PreHandleGestureEvent(gesture_event))
return;
@@ -1083,7 +1114,12 @@ void RenderWidgetHostImpl::ForwardTouchEventWithLatencyInfo(
void RenderWidgetHostImpl::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event) {
TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardKeyboardEvent");
- if (IgnoreInputEvents())
+ if (owner_delegate_ &&
+ !owner_delegate_->MayRenderWidgetForwardKeyboardEvent(key_event)) {
+ return;
+ }
+
+ if (ShouldDropInputEvents())
return;
if (!process_->HasConnection())
@@ -1102,7 +1138,8 @@ void RenderWidgetHostImpl::ForwardKeyboardEvent(
if (key_event.type == WebKeyboardEvent::Char &&
(key_event.windowsKeyCode == ui::VKEY_RETURN ||
key_event.windowsKeyCode == ui::VKEY_SPACE)) {
- OnUserGesture();
+ if (delegate_)
+ delegate_->OnUserGesture(this);
}
// Double check the type to make sure caller hasn't sent us nonsense that
@@ -1145,8 +1182,9 @@ void RenderWidgetHostImpl::ForwardKeyboardEvent(
return;
NativeWebKeyboardEventWithLatencyInfo key_event_with_latency(key_event);
+ key_event_with_latency.event.isBrowserShortcut = is_shortcut;
latency_tracker_.OnInputEvent(key_event, &key_event_with_latency.latency);
- input_router_->SendKeyboardEvent(key_event_with_latency, is_shortcut);
+ input_router_->SendKeyboardEvent(key_event_with_latency);
}
void RenderWidgetHostImpl::QueueSyntheticGesture(
@@ -1154,12 +1192,11 @@ void RenderWidgetHostImpl::QueueSyntheticGesture(
const base::Callback<void(SyntheticGesture::Result)>& on_complete) {
if (!synthetic_gesture_controller_ && view_) {
synthetic_gesture_controller_.reset(
- new SyntheticGestureController(
- view_->CreateSyntheticGestureTarget().Pass()));
+ new SyntheticGestureController(view_->CreateSyntheticGestureTarget()));
}
if (synthetic_gesture_controller_) {
synthetic_gesture_controller_->QueueSyntheticGesture(
- synthetic_gesture.Pass(), on_complete);
+ std::move(synthetic_gesture), on_complete);
}
}
@@ -1227,6 +1264,8 @@ void RenderWidgetHostImpl::GetWebScreenInfo(blink::WebScreenInfo* result) {
// TODO(sievers): find a way to make this done another way so the method
// can be const.
latency_tracker_.set_device_scale_factor(result->deviceScaleFactor);
+ if (IsUseZoomForDSFEnabled())
+ input_router_->SetDeviceScaleFactor(result->deviceScaleFactor);
}
bool RenderWidgetHostImpl::GetScreenColorProfile(
@@ -1237,6 +1276,12 @@ bool RenderWidgetHostImpl::GetScreenColorProfile(
return false;
}
+void RenderWidgetHostImpl::HandleCompositorProto(
+ const std::vector<uint8_t>& proto) {
+ DCHECK(!proto.empty());
+ Send(new ViewMsg_HandleCompositorProto(GetRoutingID(), proto));
+}
+
void RenderWidgetHostImpl::NotifyScreenInfoChanged() {
color_profile_out_of_date_ = true;
@@ -1275,6 +1320,12 @@ void RenderWidgetHostImpl::OnSelectionBoundsChanged(
}
}
+void RenderWidgetHostImpl::OnForwardCompositorProto(
+ const std::vector<uint8_t>& proto) {
+ if (delegate_)
+ delegate_->ForwardCompositorProto(this, proto);
+}
+
void RenderWidgetHostImpl::UpdateVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) {
Send(new ViewMsg_UpdateVSyncParameters(GetRoutingID(), timebase, interval));
@@ -1317,8 +1368,7 @@ void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
if (view_) {
view_->RenderProcessGone(status, exit_code);
- view_ = nullptr; // The View should be deleted by RenderProcessGone.
- view_weak_.reset();
+ view_.reset(); // The View should be deleted by RenderProcessGone.
}
// Reconstruct the input router to ensure that it has fresh state for a new
@@ -1372,17 +1422,6 @@ void RenderWidgetHostImpl::ImeCancelComposition() {
std::vector<blink::WebCompositionUnderline>(), 0, 0));
}
-gfx::Rect RenderWidgetHostImpl::GetRootWindowResizerRect() const {
- return gfx::Rect();
-}
-
-void RenderWidgetHostImpl::RequestToLockMouse(bool user_gesture,
- bool last_unlocked_by_target) {
- // Directly reject to lock the mouse. Subclass can override this method to
- // decide whether to allow mouse lock or not.
- GotResponseToLockMouseRequest(false);
-}
-
void RenderWidgetHostImpl::RejectMouseLockOrUnlockIfNecessary() {
DCHECK(!pending_mouse_lock_request_ || !IsMouseLocked());
if (pending_mouse_lock_request_) {
@@ -1397,14 +1436,6 @@ bool RenderWidgetHostImpl::IsMouseLocked() const {
return view_ ? view_->IsMouseLocked() : false;
}
-bool RenderWidgetHostImpl::IsFullscreenGranted() const {
- return false;
-}
-
-blink::WebDisplayMode RenderWidgetHostImpl::GetDisplayMode() const {
- return blink::WebDisplayModeBrowser;
-}
-
void RenderWidgetHostImpl::SetAutoResize(bool enable,
const gfx::Size& min_size,
const gfx::Size& max_size) {
@@ -1413,10 +1444,12 @@ void RenderWidgetHostImpl::SetAutoResize(bool enable,
max_size_for_auto_resize_ = max_size;
}
-void RenderWidgetHostImpl::Destroy() {
+void RenderWidgetHostImpl::Destroy(bool also_delete) {
+ DCHECK(!destroyed_);
+ destroyed_ = true;
+
NotificationService::current()->Notify(
- NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
- Source<RenderWidgetHost>(this),
+ NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, Source<RenderWidgetHost>(this),
NotificationService::NoDetails());
// Tell the view to die.
@@ -1425,10 +1458,18 @@ void RenderWidgetHostImpl::Destroy() {
// do it after this call to view_->Destroy().
if (view_) {
view_->Destroy();
- view_ = nullptr;
+ view_.reset();
}
- delete this;
+ process_->RemoveRoute(routing_id_);
+ g_routing_id_widget_map.Get().erase(
+ RenderWidgetHostID(process_->GetID(), routing_id_));
+
+ if (delegate_)
+ delegate_->RenderWidgetDeleted(this);
+
+ if (also_delete)
+ delete this;
}
void RenderWidgetHostImpl::RendererIsUnresponsive() {
@@ -1437,13 +1478,15 @@ void RenderWidgetHostImpl::RendererIsUnresponsive() {
Source<RenderWidgetHost>(this),
NotificationService::NoDetails());
is_unresponsive_ = true;
- NotifyRendererUnresponsive();
+ if (delegate_)
+ delegate_->RendererUnresponsive(this);
}
void RenderWidgetHostImpl::RendererIsResponsive() {
if (is_unresponsive_) {
is_unresponsive_ = false;
- NotifyRendererResponsive();
+ if (delegate_)
+ delegate_->RendererResponsive(this);
}
}
@@ -1460,14 +1503,14 @@ void RenderWidgetHostImpl::OnRenderProcessGone(int status, int exit_code) {
// TODO(evanm): This synchronously ends up calling "delete this".
// Is that really what we want in response to this message? I'm matching
// previous behavior of the code here.
- Destroy();
+ Destroy(true);
} else {
RendererExited(static_cast<base::TerminationStatus>(status), exit_code);
}
}
void RenderWidgetHostImpl::OnClose() {
- Shutdown();
+ ShutdownAndDestroyWidget(true);
}
void RenderWidgetHostImpl::OnSetTooltipText(
@@ -1550,13 +1593,13 @@ bool RenderWidgetHostImpl::OnSwapCompositorFrame(
touch_emulator_->SetDoubleTapSupportForPageEnabled(!is_mobile_optimized);
if (view_) {
- view_->OnSwapCompositorFrame(output_surface_id, frame.Pass());
+ view_->OnSwapCompositorFrame(output_surface_id, std::move(frame));
view_->DidReceiveRendererFrame();
} else {
cc::CompositorFrameAck ack;
if (frame->gl_frame_data) {
- ack.gl_frame_data = frame->gl_frame_data.Pass();
- ack.gl_frame_data->sync_point = 0;
+ ack.gl_frame_data = std::move(frame->gl_frame_data);
+ ack.gl_frame_data->sync_token.Clear();
} else if (frame->delegated_frame_data) {
cc::TransferableResource::ReturnResources(
frame->delegated_frame_data->resource_list,
@@ -1683,16 +1726,6 @@ void RenderWidgetHostImpl::OnQueueSyntheticGesture(
weak_factory_.GetWeakPtr()));
}
-void RenderWidgetHostImpl::OnFocus() {
- // Only RenderViewHost can deal with that message.
- bad_message::ReceivedBadMessage(GetProcess(), bad_message::RWH_FOCUS);
-}
-
-void RenderWidgetHostImpl::OnBlur() {
- // Only RenderViewHost can deal with that message.
- bad_message::ReceivedBadMessage(GetProcess(), bad_message::RWH_BLUR);
-}
-
void RenderWidgetHostImpl::OnSetCursor(const WebCursor& cursor) {
SetCursor(cursor);
}
@@ -1702,7 +1735,8 @@ void RenderWidgetHostImpl::SetTouchEventEmulationEnabled(
if (enabled) {
if (!touch_emulator_) {
touch_emulator_.reset(new TouchEmulator(
- this, view_ ? content::GetScaleFactorForView(view_) : 1.0f));
+ this,
+ view_.get() ? content::GetScaleFactorForView(view_.get()) : 1.0f));
}
touch_emulator_->Enable(config_type);
} else {
@@ -1746,7 +1780,13 @@ void RenderWidgetHostImpl::OnLockMouse(bool user_gesture,
// Directly approve to lock the mouse.
GotResponseToLockMouseRequest(true);
} else {
- RequestToLockMouse(user_gesture, last_unlocked_by_target);
+ if (delegate_) {
+ delegate_->RequestToLockMouse(this, user_gesture,
+ last_unlocked_by_target);
+ return;
+ }
+ // If there's no delegate, just reject it.
+ GotResponseToLockMouseRequest(false);
}
}
@@ -1854,7 +1894,7 @@ InputEventAckState RenderWidgetHostImpl::FilterInputEvent(
// Don't ignore touch cancel events, since they may be sent while input
// events are being ignored in order to keep the renderer from getting
// confused about how many touches are active.
- if (IgnoreInputEvents() && event.type != WebInputEvent::TouchCancel)
+ if (ShouldDropInputEvents() && event.type != WebInputEvent::TouchCancel)
return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
if (!process_->HasConnection())
@@ -1862,7 +1902,23 @@ InputEventAckState RenderWidgetHostImpl::FilterInputEvent(
if (event.type == WebInputEvent::MouseDown ||
event.type == WebInputEvent::GestureTapDown) {
- OnUserGesture();
+ if (delegate_)
+ delegate_->OnUserGesture(this);
+ }
+
+ if (delegate_) {
+ if (event.type == WebInputEvent::MouseDown ||
+ event.type == WebInputEvent::GestureTapDown ||
+ event.type == WebInputEvent::RawKeyDown) {
+ delegate_->OnUserInteraction(event.type);
+ } else if (event.type == WebInputEvent::MouseWheel) {
+ if (mouse_wheel_coalesce_timer_->Elapsed().InSecondsF() >
+ kMouseWheelCoalesceIntervalInSeconds) {
+ delegate_->OnUserInteraction(event.type);
+ }
+
+ mouse_wheel_coalesce_timer_.reset(new base::ElapsedTimer());
+ }
}
return view_ ? view_->FilterInputEvent(event)
@@ -1941,7 +1997,7 @@ void RenderWidgetHostImpl::OnWheelEventAck(
if (!is_hidden() && view_) {
if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
- delegate_->HandleWheelEvent(wheel_event.event)) {
+ delegate_ && delegate_->HandleWheelEvent(wheel_event.event)) {
ack_result = INPUT_EVENT_ACK_STATE_CONSUMED;
}
view_->WheelEventAck(wheel_event.event, ack_result);
@@ -1984,12 +2040,8 @@ void RenderWidgetHostImpl::OnSyntheticGestureCompleted(
Send(new InputMsg_SyntheticGestureCompleted(GetRoutingID()));
}
-bool RenderWidgetHostImpl::IgnoreInputEvents() const {
- return ignore_input_events_ || process_->IgnoreInputEvents();
-}
-
-void RenderWidgetHostImpl::StartUserGesture() {
- OnUserGesture();
+bool RenderWidgetHostImpl::ShouldDropInputEvents() const {
+ return ignore_input_events_ || process_->IgnoreInputEvents() || !delegate_;
}
void RenderWidgetHostImpl::SetBackgroundOpaque(bool opaque) {
@@ -2072,7 +2124,8 @@ void RenderWidgetHostImpl::DelayedAutoResized() {
if (!auto_resize_enabled_)
return;
- OnRenderAutoResized(new_size);
+ if (delegate_)
+ delegate_->ResizeDueToAutoResize(this, new_size);
}
void RenderWidgetHostImpl::DetachDelegate() {
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.h b/chromium/content/browser/renderer_host/render_widget_host_impl.h
index 3489495b7ac..d5d9d5ad654 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
#include <map>
#include <string>
@@ -12,13 +15,14 @@
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/process/kill.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
-#include "base/timer/timer.h"
+#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "cc/resources/shared_bitmap.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
@@ -27,6 +31,7 @@
#include "content/browser/renderer_host/input/render_widget_host_latency_tracker.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/touch_emulator_client.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/synthetic_gesture_packet.h"
#include "content/common/view_message_enums.h"
@@ -54,7 +59,6 @@ class WebLayer;
class WebMouseEvent;
struct WebCompositionUnderline;
struct WebScreenInfo;
-
}
namespace cc {
@@ -71,7 +75,7 @@ class BrowserAccessibilityManager;
class InputRouter;
class MockRenderWidgetHost;
class RenderWidgetHostDelegate;
-class RenderWidgetHostViewBase;
+class RenderWidgetHostOwnerDelegate;
class SyntheticGestureController;
class TimeoutMonitor;
class TouchEmulator;
@@ -80,15 +84,13 @@ struct EditCommand;
// This implements the RenderWidgetHost interface that is exposed to
// embedders of content, and adds things only visible to content.
-class CONTENT_EXPORT RenderWidgetHostImpl
- : virtual public RenderWidgetHost,
- public InputRouterClient,
- public InputAckHandler,
- public TouchEmulatorClient,
- public IPC::Listener {
+class CONTENT_EXPORT RenderWidgetHostImpl : public RenderWidgetHost,
+ public InputRouterClient,
+ public InputAckHandler,
+ public TouchEmulatorClient,
+ public IPC::Listener {
public:
- // routing_id can be MSG_ROUTING_NONE, in which case the next available
- // routing id is taken from the RenderProcessHost.
+ // |routing_id| must not be MSG_ROUTING_NONE.
// If this object outlives |delegate|, DetachDelegate() must be called when
// |delegate| goes away.
RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
@@ -102,23 +104,34 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Returns all RenderWidgetHosts including swapped out ones for
// internal use. The public interface
- // RendgerWidgetHost::GetRenderWidgetHosts only returns active ones.
+ // RenderWidgetHost::GetRenderWidgetHosts only returns active ones.
static scoped_ptr<RenderWidgetHostIterator> GetAllRenderWidgetHosts();
- // Use RenderWidgetHostImpl::From(rwh) to downcast a
- // RenderWidgetHost to a RenderWidgetHostImpl. Internally, this
- // uses RenderWidgetHost::AsRenderWidgetHostImpl().
+ // Use RenderWidgetHostImpl::From(rwh) to downcast a RenderWidgetHost to a
+ // RenderWidgetHostImpl.
static RenderWidgetHostImpl* From(RenderWidgetHost* rwh);
void set_hung_renderer_delay(const base::TimeDelta& delay) {
hung_renderer_delay_ = delay;
}
+ base::TimeDelta hung_renderer_delay() { return hung_renderer_delay_; }
+
void set_new_content_rendering_delay_for_testing(
const base::TimeDelta& delay) {
new_content_rendering_delay_ = delay;
}
+ base::TimeDelta new_content_rendering_delay() {
+ return new_content_rendering_delay_;
+ }
+
+ void set_owner_delegate(RenderWidgetHostOwnerDelegate* owner_delegate) {
+ owner_delegate_ = owner_delegate;
+ }
+
+ RenderWidgetHostOwnerDelegate* owner_delegate() { return owner_delegate_; }
+
// RenderWidgetHost implementation.
void UpdateTextDirection(blink::WebTextDirection direction) override;
void NotifyTextDirection() override;
@@ -130,18 +143,17 @@ class CONTENT_EXPORT RenderWidgetHostImpl
const ReadbackRequestCallback& callback,
const SkColorType preferred_color_type) override;
bool CanCopyFromBackingStore() override;
-#if defined(OS_ANDROID)
void LockBackingStore() override;
void UnlockBackingStore() override;
-#endif
void ForwardMouseEvent(const blink::WebMouseEvent& mouse_event) override;
void ForwardWheelEvent(const blink::WebMouseWheelEvent& wheel_event) override;
void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event) override;
+ void ForwardGestureEvent(
+ const blink::WebGestureEvent& gesture_event) override;
RenderProcessHost* GetProcess() const override;
int GetRoutingID() const override;
- RenderWidgetHostView* GetView() const override;
+ RenderWidgetHostViewBase* GetView() const override;
bool IsLoading() const override;
- bool IsRenderView() const override;
void ResizeRectChanged(const gfx::Rect& new_rect) override;
void RestartHangMonitorTimeout() override;
void SetIgnoreInputEvents(bool ignore_input_events) override;
@@ -153,6 +165,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void RemoveMouseEventCallback(const MouseEventCallback& callback) override;
void GetWebScreenInfo(blink::WebScreenInfo* result) override;
bool GetScreenColorProfile(std::vector<char>* color_profile) override;
+ void HandleCompositorProto(const std::vector<uint8_t>& proto) override;
// Notification that the screen info has changed.
void NotifyScreenInfoChanged();
@@ -175,7 +188,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Called when a renderer object already been created for this host, and we
// just need to be attached to it. Used for window.open, <select> dropdown
// menus, and other times when the renderer initiates creating an object.
- virtual void Init();
+ void Init();
// Initializes a RenderWidgetHost that is attached to a RenderFrameHost.
void InitForFrame();
@@ -185,9 +198,12 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void set_owned_by_render_frame_host(bool owned_by_rfh) {
owned_by_render_frame_host_ = owned_by_rfh;
}
+ bool owned_by_render_frame_host() const {
+ return owned_by_render_frame_host_;
+ }
- // Tells the renderer to die and then calls Destroy().
- virtual void Shutdown();
+ // Tells the renderer to die and optionally delete |this|.
+ void ShutdownAndDestroyWidget(bool also_delete);
// IPC::Listener
bool OnMessageReceived(const IPC::Message& msg) override;
@@ -196,20 +212,20 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool Send(IPC::Message* msg) override;
// Indicates if the page has finished loading.
- virtual void SetIsLoading(bool is_loading);
+ void SetIsLoading(bool is_loading);
// Called to notify the RenderWidget that it has been hidden or restored from
// having been hidden.
- virtual void WasHidden();
- virtual void WasShown(const ui::LatencyInfo& latency_info);
+ void WasHidden();
+ void WasShown(const ui::LatencyInfo& latency_info);
// Returns true if the RenderWidget is hidden.
bool is_hidden() const { return is_hidden_; }
// Called to notify the RenderWidget that its associated native window
// got/lost focused.
- virtual void GotFocus();
- virtual void LostCapture();
+ void GotFocus();
+ void LostCapture();
// Indicates whether the RenderWidgetHost thinks it is focused.
// This is different from RenderWidgetHostView::HasFocus() in the sense that
@@ -221,7 +237,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool is_focused() const { return is_focused_; }
// Called to notify the RenderWidget that it has lost the mouse lock.
- virtual void LostMouseLock();
+ void LostMouseLock();
// Noifies the RenderWidget of the current mouse cursor visibility state.
void SendCursorVisibilityState(bool is_visible);
@@ -289,7 +305,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool enabled, ui::GestureProviderConfigType config_type);
// TouchEmulatorClient implementation.
- void ForwardGestureEvent(
+ void ForwardEmulatedGestureEvent(
const blink::WebGestureEvent& gesture_event) override;
void ForwardEmulatedTouchEvent(
const blink::WebTouchEvent& touch_event) override;
@@ -338,24 +354,15 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Cancels an ongoing composition.
void ImeCancelComposition();
- // This is for derived classes to give us access to the resizer rect.
- // And to also expose it to the RenderWidgetHostView.
- virtual gfx::Rect GetRootWindowResizerRect() const;
-
bool ignore_input_events() const {
return ignore_input_events_;
}
- // Whether forwarded WebInputEvents should be ignored. True if either
- // |ignore_input_events_| or |process_->IgnoreInputEvents()| is true.
- bool IgnoreInputEvents() const;
+ // Whether forwarded WebInputEvents should be dropped.
+ bool ShouldDropInputEvents() const;
bool has_touch_handler() const { return has_touch_handler_; }
- // Notification that the user has made some kind of input that could
- // perform an action. See OnUserGesture for more details.
- void StartUserGesture();
-
// Set the RenderView background transparency.
void SetBackgroundOpaque(bool opaque);
@@ -364,7 +371,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void SetEditCommandsForNextKeyEvent(
const std::vector<EditCommand>& commands);
- // Executes the edit command on the RenderView.
+ // Executes the edit command.
void ExecuteEditCommand(const std::string& command,
const std::string& value);
@@ -382,8 +389,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool GotResponseToLockMouseRequest(bool allowed);
// Tells the RenderWidget about the latest vsync parameters.
- virtual void UpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval);
+ void UpdateVSyncParameters(base::TimeTicks timebase,
+ base::TimeDelta interval);
// Called by the view in response to OnSwapCompositorFrame.
static void SendSwapCompositorFrameAck(
@@ -470,59 +477,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
renderer_initialized_ = renderer_initialized;
}
- protected:
- RenderWidgetHostImpl* AsRenderWidgetHostImpl() override;
-
- // Called when we receive a notification indicating that the renderer
- // process has gone. This will reset our state so that our state will be
- // consistent if a new renderer is created.
- void RendererExited(base::TerminationStatus status, int exit_code);
-
- // Retrieves an id the renderer can use to refer to its view.
- // This is used for various IPC messages, including plugins.
- gfx::NativeViewId GetNativeViewId() const;
-
- // ---------------------------------------------------------------------------
- // The following methods are overridden by RenderViewHost to send upwards to
- // its delegate.
-
- // Called when a mousewheel event was not processed by the renderer.
- virtual void UnhandledWheelEvent(const blink::WebMouseWheelEvent& event) {}
-
- // Notification that the user has made some kind of input that could
- // perform an action. The gestures that count are 1) any mouse down
- // event and 2) enter or space key presses.
- virtual void OnUserGesture() {}
-
- // Callbacks for notification when the renderer becomes unresponsive to user
- // input events, and subsequently responsive again.
- virtual void NotifyRendererUnresponsive() {}
- virtual void NotifyRendererResponsive() {}
-
- // Callback for notification that we failed to receive any rendered graphics
- // from a newly loaded page. Used for testing.
- virtual void NotifyNewContentRenderingTimeoutForTesting() {}
-
- // Called when auto-resize resulted in the renderer size changing.
- virtual void OnRenderAutoResized(const gfx::Size& new_size) {}
-
- // ---------------------------------------------------------------------------
-
- // RenderViewHost overrides this method to impose further restrictions on when
- // to allow mouse lock.
- // Once the request is approved or rejected, GotResponseToLockMouseRequest()
- // will be called.
- virtual void RequestToLockMouse(bool user_gesture,
- bool last_unlocked_by_target);
-
- bool IsMouseLocked() const;
-
- // RenderViewHost overrides this method to report whether tab-initiated
- // fullscreen was granted.
- virtual bool IsFullscreenGranted() const;
-
- virtual blink::WebDisplayMode GetDisplayMode() const;
-
// Indicates if the render widget host should track the render widget's size
// as opposed to visa versa.
void SetAutoResize(bool enable,
@@ -537,6 +491,11 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// request to create a new RenderWidget.
void SetInitialRenderSizeParams(const ViewMsg_Resize_Params& resize_params);
+ // Called when we receive a notification indicating that the renderer process
+ // is gone. This will reset our state so that our state will be consistent if
+ // a new renderer is created.
+ void RendererExited(base::TerminationStatus status, int exit_code);
+
// Expose increment/decrement of the in-flight event count, so
// RenderViewHostImpl can account for in-flight beforeunload/unload events.
int increment_in_flight_event_count() { return ++in_flight_event_count_; }
@@ -547,31 +506,36 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool renderer_initialized() const { return renderer_initialized_; }
- // The View associated with the RenderViewHost. The lifetime of this object
+ protected:
+ // Retrieves an id the renderer can use to refer to its view.
+ // This is used for various IPC messages, including plugins.
+ gfx::NativeViewId GetNativeViewId() const;
+
+ // ---------------------------------------------------------------------------
+ // The following method is overridden by RenderViewHost to send upwards to
+ // its delegate.
+
+ // Callback for notification that we failed to receive any rendered graphics
+ // from a newly loaded page. Used for testing.
+ virtual void NotifyNewContentRenderingTimeoutForTesting() {}
+
+ // ---------------------------------------------------------------------------
+
+ bool IsMouseLocked() const;
+
+ // The View associated with the RenderWidgetHost. The lifetime of this object
// is associated with the lifetime of the Render process. If the Renderer
// crashes, its View is destroyed and this pointer becomes NULL, even though
// render_view_host_ lives on to load another URL (creating a new View while
// doing so).
- RenderWidgetHostViewBase* view_;
-
- // A weak pointer to the view. The above pointer should be weak, but changing
- // that to be weak causes crashes on Android.
- // TODO(ccameron): Fix this.
- // http://crbug.com/404828
- base::WeakPtr<RenderWidgetHostViewBase> view_weak_;
-
- // This value indicates how long to wait before we consider a renderer hung.
- base::TimeDelta hung_renderer_delay_;
-
- // This value indicates how long to wait for a new compositor frame from a
- // renderer process before clearing any previously displayed content.
- base::TimeDelta new_content_rendering_delay_;
+ base::WeakPtr<RenderWidgetHostViewBase> view_;
private:
friend class MockRenderWidgetHost;
- // Tell this object to destroy itself.
- void Destroy();
+ // Tell this object to destroy itself. If |also_delete| is specified, the
+ // destructor is called as well.
+ void Destroy(bool also_delete);
// Called by |hang_monitor_timeout_| on delayed response from the renderer.
void RendererIsUnresponsive();
@@ -599,8 +563,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool OnSwapCompositorFrame(const IPC::Message& message);
void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params);
void OnQueueSyntheticGesture(const SyntheticGesturePacket& gesture_packet);
- virtual void OnFocus();
- virtual void OnBlur();
void OnSetCursor(const WebCursor& cursor);
void OnTextInputStateChanged(
const ViewHostMsg_TextInputState_Params& params);
@@ -627,7 +589,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
const gfx::Range& range);
void OnSelectionBoundsChanged(
const ViewHostMsg_SelectionBounds_Params& params);
- void OnSnapshot(bool success, const SkBitmap& bitmap);
+ void OnForwardCompositorProto(const std::vector<uint8_t>& proto);
// Called (either immediately or asynchronously) after we're done with our
// BackingStore and can send an ACK to the renderer so it can paint onto it
@@ -684,10 +646,16 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// initialization.
bool renderer_initialized_;
+ // True if |Destroy()| has been called.
+ bool destroyed_;
+
// Our delegate, which wants to know mainly about keyboard events.
// It will remain non-NULL until DetachDelegate() is called.
RenderWidgetHostDelegate* delegate_;
+ // The delegate of the owner of this object.
+ RenderWidgetHostOwnerDelegate* owner_delegate_;
+
// Created during construction and guaranteed never to be NULL, but its
// channel may be NULL if the renderer crashed, so one must always check that.
RenderProcessHost* const process_;
@@ -844,6 +812,18 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// causing HasFocus to return false when is_focused_ is true.
bool is_focused_;
+ // This value indicates how long to wait before we consider a renderer hung.
+ base::TimeDelta hung_renderer_delay_;
+
+ // This value indicates how long to wait for a new compositor frame from a
+ // renderer process before clearing any previously displayed content.
+ base::TimeDelta new_content_rendering_delay_;
+
+ // Timer used to batch together mouse wheel events for the delegate
+ // OnUserInteraction method. A wheel event is only dispatched when a wheel
+ // event has not been seen for kMouseWheelCoalesceInterval seconds prior.
+ scoped_ptr<base::ElapsedTimer> mouse_wheel_coalesce_timer_;
+
base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl);
diff --git a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc
index 49053b9718b..eef72ac2c73 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -10,7 +10,8 @@
namespace content {
-RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter() {}
+RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter()
+ : active_touches_(0) {}
RenderWidgetHostInputEventRouter::~RenderWidgetHostInputEventRouter() {
owner_map_.clear();
@@ -40,7 +41,12 @@ RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget(
// parent frame has not sent a new compositor frame since that happened.
if (iter == owner_map_.end())
return root_view;
- return iter->second;
+ RenderWidgetHostViewBase* target = iter->second.get();
+ // If we find the weak pointer is now null, it means the map entry is stale
+ // and should be removed to free space.
+ if (!target)
+ owner_map_.erase(iter);
+ return target;
}
void RenderWidgetHostInputEventRouter::RouteMouseEvent(
@@ -49,6 +55,9 @@ void RenderWidgetHostInputEventRouter::RouteMouseEvent(
gfx::Point transformed_point;
RenderWidgetHostViewBase* target = FindEventTarget(
root_view, gfx::Point(event->x, event->y), &transformed_point);
+ if (!target)
+ return;
+
event->x = transformed_point.x();
event->y = transformed_point.y();
@@ -61,17 +70,65 @@ void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent(
gfx::Point transformed_point;
RenderWidgetHostViewBase* target = FindEventTarget(
root_view, gfx::Point(event->x, event->y), &transformed_point);
+ if (!target)
+ return;
+
event->x = transformed_point.x();
event->y = transformed_point.y();
target->ProcessMouseWheelEvent(*event);
}
+void RenderWidgetHostInputEventRouter::RouteTouchEvent(
+ RenderWidgetHostViewBase* root_view,
+ blink::WebTouchEvent* event,
+ const ui::LatencyInfo& latency) {
+ switch (event->type) {
+ case blink::WebInputEvent::TouchStart: {
+ if (!active_touches_) {
+ // Since this is the first touch, it defines the target for the rest
+ // of this sequence.
+ DCHECK(!current_touch_target_);
+ gfx::Point transformed_point;
+ gfx::Point original_point(event->touches[0].position.x,
+ event->touches[0].position.y);
+ RenderWidgetHostViewBase* target =
+ FindEventTarget(root_view, original_point, &transformed_point);
+ if (!target)
+ return;
+
+ // Store the weak-ptr to the target, since it could disappear in the
+ // middle of a touch sequence.
+ current_touch_target_ = target->GetWeakPtr();
+ }
+ ++active_touches_;
+ if (current_touch_target_)
+ current_touch_target_->ProcessTouchEvent(*event, latency);
+ break;
+ }
+ case blink::WebInputEvent::TouchMove:
+ if (current_touch_target_)
+ current_touch_target_->ProcessTouchEvent(*event, latency);
+ break;
+ case blink::WebInputEvent::TouchEnd:
+ case blink::WebInputEvent::TouchCancel:
+ DCHECK(active_touches_);
+ if (current_touch_target_)
+ current_touch_target_->ProcessTouchEvent(*event, latency);
+ --active_touches_;
+ if (!active_touches_)
+ current_touch_target_ = WeakTarget();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
void RenderWidgetHostInputEventRouter::AddSurfaceIdNamespaceOwner(
uint32_t id,
RenderWidgetHostViewBase* owner) {
DCHECK(owner_map_.find(id) == owner_map_.end());
- owner_map_.insert(std::make_pair(id, owner));
+ owner_map_.insert(std::make_pair(id, owner->GetWeakPtr()));
}
void RenderWidgetHostInputEventRouter::RemoveSurfaceIdNamespaceOwner(
diff --git a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h
index 3a2a967330a..03902f5b3d1 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -8,17 +8,24 @@
#include <stdint.h>
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
namespace blink {
class WebMouseEvent;
class WebMouseWheelEvent;
+class WebTouchEvent;
}
namespace gfx {
class Point;
}
+namespace ui {
+class LatencyInfo;
+}
+
namespace content {
class RenderWidgetHostViewBase;
@@ -38,18 +45,29 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter {
blink::WebMouseEvent* event);
void RouteMouseWheelEvent(RenderWidgetHostViewBase* root_view,
blink::WebMouseWheelEvent* event);
+ void RouteTouchEvent(RenderWidgetHostViewBase* root_view,
+ blink::WebTouchEvent *event,
+ const ui::LatencyInfo& latency);
void AddSurfaceIdNamespaceOwner(uint32_t id, RenderWidgetHostViewBase* owner);
void RemoveSurfaceIdNamespaceOwner(uint32_t id);
+ bool is_registered(uint32_t id) {
+ return owner_map_.find(id) != owner_map_.end();
+ }
+
private:
+ using WeakTarget = base::WeakPtr<RenderWidgetHostViewBase>;
+ using SurfaceIdNamespaceOwnerMap =
+ base::hash_map<uint32_t, base::WeakPtr<RenderWidgetHostViewBase>>;
+
RenderWidgetHostViewBase* FindEventTarget(RenderWidgetHostViewBase* root_view,
const gfx::Point& point,
gfx::Point* transformed_point);
- typedef base::hash_map<uint32_t, RenderWidgetHostViewBase*>
- SurfaceIdNamespaceOwnerMap;
SurfaceIdNamespaceOwnerMap owner_map_;
+ WeakTarget current_touch_target_;
+ int active_touches_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostInputEventRouter);
};
diff --git a/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h b/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
new file mode 100644
index 00000000000..c2b0c45ec09
--- /dev/null
+++ b/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
@@ -0,0 +1,63 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_OWNER_DELEGATE_H_
+#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_OWNER_DELEGATE_H_
+
+#include "content/common/content_export.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace blink {
+class WebMouseEvent;
+}
+
+namespace content {
+
+struct NativeWebKeyboardEvent;
+
+//
+// RenderWidgetHostOwnerDelegate
+//
+// An interface implemented by an object owning a RenderWidgetHost. This is
+// intended to be temporary until the RenderViewHostImpl and
+// RenderWidgetHostImpl classes are disentangled; see http://crbug.com/542477
+// and http://crbug.com/478281.
+class CONTENT_EXPORT RenderWidgetHostOwnerDelegate {
+ public:
+ // The RenderWidgetHost received an IPC message. Return true if this delegate
+ // handles it.
+ virtual bool OnMessageReceived(const IPC::Message& msg) = 0;
+
+ // The RenderWidgetHost has been initialized.
+ virtual void RenderWidgetDidInit() = 0;
+
+ // The RenderWidgetHost will be setting its loading state.
+ virtual void RenderWidgetWillSetIsLoading(bool is_loading) = 0;
+
+ // The RenderWidgetHost got the focus.
+ virtual void RenderWidgetGotFocus() = 0;
+
+ // The RenderWidgetHost will be hidden or shown.
+ virtual void RenderWidgetWillBeHidden() = 0;
+ virtual void RenderWidgetWillBeShown() = 0;
+
+ // The RenderWidgetHost forwarded a mouse event.
+ virtual void RenderWidgetDidForwardMouseEvent(
+ const blink::WebMouseEvent& mouse_event) = 0;
+
+ // The RenderWidgetHost wants to forward a keyboard event; returns whether
+ // it's allowed to do so.
+ virtual bool MayRenderWidgetForwardKeyboardEvent(
+ const NativeWebKeyboardEvent& key_event) = 0;
+
+ protected:
+ virtual ~RenderWidgetHostOwnerDelegate() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_OWNER_DELEGATE_H_
diff --git a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
index 785288d5c6e..c76fc12376b 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -2,14 +2,18 @@
// 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 <stddef.h>
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
@@ -55,6 +59,22 @@ using blink::WebTouchPoint;
namespace content {
+std::string GetInputMessageTypes(MockRenderProcessHost* process) {
+ std::string result;
+ for (size_t i = 0; i < process->sink().message_count(); ++i) {
+ const IPC::Message* message = process->sink().GetMessageAt(i);
+ EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
+ InputMsg_HandleInputEvent::Param params;
+ EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
+ const WebInputEvent* event = base::get<0>(params);
+ if (i != 0)
+ result += " ";
+ result += WebInputEventTraits::GetName(event->type);
+ }
+ process->sink().ClearMessages();
+ return result;
+}
+
// MockInputRouter -------------------------------------------------------------
class MockInputRouter : public InputRouter {
@@ -83,8 +103,8 @@ class MockInputRouter : public InputRouter {
const MouseWheelEventWithLatencyInfo& wheel_event) override {
sent_wheel_event_ = true;
}
- void SendKeyboardEvent(const NativeWebKeyboardEventWithLatencyInfo& key_event,
- bool is_shortcut) override {
+ void SendKeyboardEvent(
+ const NativeWebKeyboardEventWithLatencyInfo& key_event) override {
sent_keyboard_event_ = true;
}
void SendGestureEvent(
@@ -103,6 +123,7 @@ class MockInputRouter : public InputRouter {
void NotifySiteIsMobileOptimized(bool is_mobile_optimized) override {}
void RequestNotificationWhenFlushed() override {}
bool HasPendingEvents() const override { return false; }
+ void SetDeviceScaleFactor(float device_scale_factor) override {}
// IPC::Listener
bool OnMessageReceived(const IPC::Message& message) override {
@@ -136,7 +157,6 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
process,
routing_id,
false),
- unresponsive_timer_fired_(false),
new_content_rendering_timeout_fired_(false) {
acked_touch_event_type_ = blink::WebInputEvent::Undefined;
}
@@ -158,10 +178,6 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
}
- bool unresponsive_timer_fired() const {
- return unresponsive_timer_fired_;
- }
-
bool new_content_rendering_timeout_fired() const {
return new_content_rendering_timeout_fired_;
}
@@ -184,15 +200,10 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
protected:
- void NotifyRendererUnresponsive() override {
- unresponsive_timer_fired_ = true;
- }
-
void NotifyNewContentRenderingTimeoutForTesting() override {
new_content_rendering_timeout_fired_ = true;
}
- bool unresponsive_timer_fired_;
bool new_content_rendering_timeout_fired_;
WebInputEvent::Type acked_touch_event_type_;
@@ -327,13 +338,14 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
public:
MockRenderWidgetHostDelegate()
: prehandle_keyboard_event_(false),
+ prehandle_keyboard_event_is_shortcut_(false),
prehandle_keyboard_event_called_(false),
prehandle_keyboard_event_type_(WebInputEvent::Undefined),
unhandled_keyboard_event_called_(false),
unhandled_keyboard_event_type_(WebInputEvent::Undefined),
handle_wheel_event_(false),
- handle_wheel_event_called_(false) {
- }
+ handle_wheel_event_called_(false),
+ unresponsive_timer_fired_(false) {}
~MockRenderWidgetHostDelegate() override {}
// Tests that make sure we ignore keyboard event acknowledgments to events we
@@ -362,15 +374,20 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
handle_wheel_event_ = handle;
}
- bool handle_wheel_event_called() {
- return handle_wheel_event_called_;
+ void set_prehandle_keyboard_event_is_shortcut(bool is_shortcut) {
+ prehandle_keyboard_event_is_shortcut_ = is_shortcut;
}
+ bool handle_wheel_event_called() const { return handle_wheel_event_called_; }
+
+ bool unresponsive_timer_fired() const { return unresponsive_timer_fired_; }
+
protected:
bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) override {
prehandle_keyboard_event_type_ = event.type;
prehandle_keyboard_event_called_ = true;
+ *is_keyboard_shortcut = prehandle_keyboard_event_is_shortcut_;
return prehandle_keyboard_event_;
}
@@ -384,6 +401,10 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
return handle_wheel_event_;
}
+ void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) override {
+ unresponsive_timer_fired_ = true;
+ }
+
void Cut() override {}
void Copy() override {}
void Paste() override {}
@@ -391,6 +412,7 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
private:
bool prehandle_keyboard_event_;
+ bool prehandle_keyboard_event_is_shortcut_;
bool prehandle_keyboard_event_called_;
WebInputEvent::Type prehandle_keyboard_event_type_;
@@ -399,6 +421,8 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
bool handle_wheel_event_;
bool handle_wheel_event_called_;
+
+ bool unresponsive_timer_fired_;
};
// RenderWidgetHostTest --------------------------------------------------------
@@ -478,9 +502,7 @@ class RenderWidgetHostTest : public testing::Test {
virtual void ConfigureView(TestView* view) {
}
- int64 GetLatencyComponentId() {
- return host_->GetLatencyComponentId();
- }
+ int64_t GetLatencyComponentId() { return host_->GetLatencyComponentId(); }
void SendInputEventACK(WebInputEvent::Type type,
InputEventAckState ack_result) {
@@ -518,8 +540,8 @@ class RenderWidgetHostTest : public testing::Test {
}
void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
- host_->ForwardWheelEvent(
- SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
+ host_->ForwardWheelEvent(SyntheticWebMouseWheelEventBuilder::Build(
+ 0, 0, dX, dY, modifiers, precise));
}
void SimulateWheelEventWithLatencyInfo(float dX,
@@ -528,7 +550,8 @@ class RenderWidgetHostTest : public testing::Test {
bool precise,
const ui::LatencyInfo& ui_latency) {
host_->ForwardWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, dX, dY, modifiers,
+ precise),
ui_latency);
}
@@ -568,8 +591,8 @@ class RenderWidgetHostTest : public testing::Test {
// Sends a touch event (irrespective of whether the page has a touch-event
// handler or not).
- uint32 SendTouchEvent() {
- uint32 touch_event_id = touch_event_.uniqueTouchEventId;
+ uint32_t SendTouchEvent() {
+ uint32_t touch_event_id = touch_event_.uniqueTouchEventId;
host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
touch_event_.ResetPoints();
@@ -891,7 +914,7 @@ TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
}
TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
- // Simluate the situation that the browser handled the key down event during
+ // Simulate the situation that the browser handled the key down event during
// pre-handle phrase.
delegate_->set_prehandle_keyboard_event(true);
process_->sink().ClearMessages();
@@ -932,6 +955,59 @@ TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
}
+TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) {
+ // Simulate the situation that the browser marks the key down as a keyboard
+ // shortcut, but doesn't consume it in the pre-handle phase.
+ delegate_->set_prehandle_keyboard_event_is_shortcut(true);
+ process_->sink().ClearMessages();
+
+ // Simulate a keyboard event.
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
+
+ EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
+ EXPECT_EQ(WebInputEvent::RawKeyDown,
+ delegate_->prehandle_keyboard_event_type());
+
+ // Make sure the RawKeyDown event is sent to the renderer.
+ EXPECT_EQ(1U, process_->sink().message_count());
+ EXPECT_EQ("RawKeyDown", GetInputMessageTypes(process_));
+ process_->sink().ClearMessages();
+
+ // Send the simulated response from the renderer back.
+ SendInputEventACK(WebInputEvent::RawKeyDown,
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(WebInputEvent::RawKeyDown,
+ delegate_->unhandled_keyboard_event_type());
+
+ // The browser won't pre-handle a Char event.
+ delegate_->set_prehandle_keyboard_event_is_shortcut(false);
+
+ // Forward the Char event.
+ SimulateKeyboardEvent(WebInputEvent::Char);
+
+ // The Char event is not suppressed; the renderer will ignore it
+ // if the preceding RawKeyDown shortcut goes unhandled.
+ EXPECT_EQ(1U, process_->sink().message_count());
+ EXPECT_EQ("Char", GetInputMessageTypes(process_));
+ process_->sink().ClearMessages();
+
+ // Send the simulated response from the renderer back.
+ SendInputEventACK(WebInputEvent::Char, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(WebInputEvent::Char, delegate_->unhandled_keyboard_event_type());
+
+ // Forward the KeyUp event.
+ SimulateKeyboardEvent(WebInputEvent::KeyUp);
+
+ // Make sure only KeyUp was sent to the renderer.
+ EXPECT_EQ(1U, process_->sink().message_count());
+ EXPECT_EQ("KeyUp", GetInputMessageTypes(process_));
+ process_->sink().ClearMessages();
+
+ // Send the simulated response from the renderer back.
+ SendInputEventACK(WebInputEvent::KeyUp, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
+}
+
TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
SimulateWheelEvent(-5, 0, 0, true);
@@ -993,15 +1069,15 @@ TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
// Immediately try to add a long 30 second timeout.
- EXPECT_FALSE(host_->unresponsive_timer_fired());
+ EXPECT_FALSE(delegate_->unresponsive_timer_fired());
host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
// Wait long enough for first timeout and see if it fired.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMilliseconds(10));
base::MessageLoop::current()->Run();
- EXPECT_TRUE(host_->unresponsive_timer_fired());
+ EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the hang monitor timer expires properly if it is started, stopped,
@@ -1012,15 +1088,15 @@ TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
host_->StopHangMonitorTimeout();
// Start it again to ensure it still works.
- EXPECT_FALSE(host_->unresponsive_timer_fired());
+ EXPECT_FALSE(delegate_->unresponsive_timer_fired());
host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
// Wait long enough for first timeout and see if it fired.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMilliseconds(40));
base::MessageLoop::current()->Run();
- EXPECT_TRUE(host_->unresponsive_timer_fired());
+ EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the hang monitor timer expires properly if it is started, then
@@ -1030,15 +1106,15 @@ TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
// Start it again with shorter delay.
- EXPECT_FALSE(host_->unresponsive_timer_fired());
+ EXPECT_FALSE(delegate_->unresponsive_timer_fired());
host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
// Wait long enough for the second timeout and see if it fired.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMilliseconds(25));
base::MessageLoop::current()->Run();
- EXPECT_TRUE(host_->unresponsive_timer_fired());
+ EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the hang monitor timer is effectively disabled when the widget is
@@ -1051,29 +1127,29 @@ TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) {
host_->WasHidden();
// The timeout should not fire.
- EXPECT_FALSE(host_->unresponsive_timer_fired());
+ EXPECT_FALSE(delegate_->unresponsive_timer_fired());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMicroseconds(2));
base::MessageLoop::current()->Run();
- EXPECT_FALSE(host_->unresponsive_timer_fired());
+ EXPECT_FALSE(delegate_->unresponsive_timer_fired());
// The timeout should never reactivate while hidden.
SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMicroseconds(2));
base::MessageLoop::current()->Run();
- EXPECT_FALSE(host_->unresponsive_timer_fired());
+ EXPECT_FALSE(delegate_->unresponsive_timer_fired());
// Showing the widget should restore the timeout, as the events have
// not yet been ack'ed.
host_->WasShown(ui::LatencyInfo());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMicroseconds(2));
base::MessageLoop::current()->Run();
- EXPECT_TRUE(host_->unresponsive_timer_fired());
+ EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the hang monitor catches two input events but only one ack.
@@ -1092,10 +1168,10 @@ TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
// Wait long enough for first timeout and see if it fired.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMicroseconds(20));
base::MessageLoop::current()->Run();
- EXPECT_TRUE(host_->unresponsive_timer_fired());
+ EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the rendering timeout for newly loaded content fires
@@ -1108,7 +1184,7 @@ TEST_F(RenderWidgetHostTest, NewContentRenderingTimeout) {
host_->StartNewContentRenderingTimeout();
host_->OnFirstPaintAfterLoad();
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMicroseconds(20));
base::MessageLoop::current()->Run();
@@ -1119,7 +1195,7 @@ TEST_F(RenderWidgetHostTest, NewContentRenderingTimeout) {
host_->OnFirstPaintAfterLoad();
host_->StartNewContentRenderingTimeout();
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMicroseconds(20));
base::MessageLoop::current()->Run();
@@ -1128,28 +1204,12 @@ TEST_F(RenderWidgetHostTest, NewContentRenderingTimeout) {
// Test with a long delay to ensure that it does fire this time.
host_->StartNewContentRenderingTimeout();
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
TimeDelta::FromMicroseconds(20));
base::MessageLoop::current()->Run();
EXPECT_TRUE(host_->new_content_rendering_timeout_fired());
}
-std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
- std::string result;
- for (size_t i = 0; i < process->sink().message_count(); ++i) {
- const IPC::Message *message = process->sink().GetMessageAt(i);
- EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
- InputMsg_HandleInputEvent::Param params;
- EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
- const WebInputEvent* event = base::get<0>(params);
- if (i != 0)
- result += " ";
- result += WebInputEventTraits::GetName(event->type);
- }
- process->sink().ClearMessages();
- return result;
-}
-
TEST_F(RenderWidgetHostTest, TouchEmulator) {
simulated_event_time_delta_seconds_ = 0.1;
// Immediately ack all touches instead of sending them to the renderer.
@@ -1471,7 +1531,7 @@ ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
}
void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
- int64 component_id,
+ int64_t component_id,
WebInputEvent::Type input_type) {
ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
EXPECT_TRUE(latency_info.FindLatency(
@@ -1530,7 +1590,7 @@ TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
// Tests RWHI::ForwardTouchEventWithLatencyInfo().
PressTouchPoint(0, 1);
- uint32 touch_event_id = SendTouchEvent();
+ uint32_t touch_event_id = SendTouchEvent();
InputEventAck ack(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
touch_event_id);
host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
@@ -1596,4 +1656,24 @@ TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
EXPECT_TRUE(host_->resize_ack_pending_);
}
+// Tests that event dispatch after the delegate has been detached doesn't cause
+// a crash. See crbug.com/563237.
+TEST_F(RenderWidgetHostTest, EventDispatchPostDetach) {
+ host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
+ process_->sink().ClearMessages();
+
+ host_->DetachDelegate();
+
+ // Tests RWHI::ForwardGestureEventWithLatencyInfo().
+ SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
+ blink::WebGestureDeviceTouchscreen,
+ ui::LatencyInfo());
+
+
+ // Tests RWHI::ForwardWheelEventWithLatencyInfo().
+ SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
+
+ ASSERT_FALSE(host_->input_router()->HasPendingEvents());
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc
index f321f559440..841754602d9 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -5,13 +5,14 @@
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#include <android/bitmap.h>
+#include <utility>
#include "base/android/build_info.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
@@ -36,17 +37,15 @@
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/browser/android/composited_touch_handle_drawable.h"
#include "content/browser/android/content_view_core_impl.h"
-#include "content/browser/android/edge_effect.h"
-#include "content/browser/android/edge_effect_l.h"
-#include "content/browser/android/in_process/synchronous_compositor_impl.h"
#include "content/browser/android/overscroll_controller_android.h"
#include "content/browser/android/popup_touch_handle_drawable.h"
+#include "content/browser/android/synchronous_compositor_base.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
-#include "content/browser/media/media_web_contents_observer.h"
+#include "content/browser/media/android/media_web_contents_observer_android.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/frame_metadata_util.h"
@@ -73,6 +72,8 @@
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_start.h"
#include "skia/ext/image_operations.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
@@ -216,7 +217,7 @@ GLHelperHolder::CreateContext3D() {
context.reset();
}
- return context.Pass();
+ return context;
}
// This can only be used for readback postprocessing. It may return null if the
@@ -245,14 +246,14 @@ void CopyFromCompositingSurfaceFinished(
TRACE_EVENT0(
"cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished");
bitmap_pixels_lock.reset();
- uint32 sync_point = 0;
+ gpu::SyncToken sync_token;
if (result) {
GLHelper* gl_helper = GetPostReadbackGLHelper();
if (gl_helper)
- sync_point = gl_helper->InsertSyncPoint();
+ gl_helper->GenerateSyncToken(&sync_token);
}
- bool lost_resource = sync_point == 0;
- release_callback->Run(sync_point, lost_resource);
+ const bool lost_resource = !sync_token.HasData();
+ release_callback->Run(sync_token, lost_resource);
UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
base::TimeTicks::Now() - start_time);
ReadbackResponse response = result ? READBACK_SUCCESS : READBACK_FAILED;
@@ -269,6 +270,9 @@ scoped_ptr<ui::TouchSelectionController> CreateSelectionController(
gfx::ViewConfiguration::GetLongPressTimeoutInMs());
config.tap_slop = gfx::ViewConfiguration::GetTouchSlopInDips();
config.show_on_tap_for_empty_editable = false;
+ config.enable_adaptive_handle_orientation =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableAdaptiveSelectionHandleOrientation);
config.enable_longpress_drag_selection =
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLongpressDragSelection);
@@ -293,9 +297,9 @@ gfx::RectF GetSelectionRect(const ui::TouchSelectionController& controller) {
} // anonymous namespace
RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
- uint32 output_id,
+ uint32_t output_id,
scoped_ptr<cc::CompositorFrame> output_frame)
- : output_surface_id(output_id), frame(output_frame.Pass()) {}
+ : output_surface_id(output_id), frame(std::move(output_frame)) {}
RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
@@ -316,6 +320,8 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
: host_(widget_host),
outstanding_vsync_requests_(0),
is_showing_(!widget_host->is_hidden()),
+ is_window_visible_(true),
+ is_window_activity_started_(true),
content_view_core_(nullptr),
content_view_core_window_android_(nullptr),
ime_adapter_android_(this),
@@ -353,6 +359,9 @@ void RenderWidgetHostViewAndroid::Blur() {
bool RenderWidgetHostViewAndroid::OnMessageReceived(
const IPC::Message& message) {
+ if (IPC_MESSAGE_ID_CLASS(message.type()) == SyncCompositorMsgStart) {
+ return SyncCompositorOnMessageReceived(message);
+ }
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
@@ -367,6 +376,12 @@ bool RenderWidgetHostViewAndroid::OnMessageReceived(
return handled;
}
+bool RenderWidgetHostViewAndroid::SyncCompositorOnMessageReceived(
+ const IPC::Message& message) {
+ DCHECK(!content_view_core_ || sync_compositor_) << !!content_view_core_;
+ return sync_compositor_ && sync_compositor_->OnMessageReceived(message);
+}
+
void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
NOTIMPLEMENTED();
}
@@ -471,7 +486,7 @@ gfx::Vector2dF RenderWidgetHostViewAndroid::GetLastScrollOffset() const {
}
gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
- return content_view_core_->GetViewAndroid();
+ return content_view_core_;
}
gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
@@ -512,7 +527,7 @@ bool RenderWidgetHostViewAndroid::HasFocus() const {
}
bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
- return HasValidFrame();
+ return !using_browser_compositor_ || HasValidFrame();
}
void RenderWidgetHostViewAndroid::Show() {
@@ -528,10 +543,7 @@ void RenderWidgetHostViewAndroid::Hide() {
return;
is_showing_ = false;
-
- bool hide_frontbuffer = true;
- bool stop_observing_root_window = true;
- HideInternal(hide_frontbuffer, stop_observing_root_window);
+ HideInternal();
}
bool RenderWidgetHostViewAndroid::IsShowing() {
@@ -560,7 +572,7 @@ void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
if (locks_on_frame_count_ == 0) {
if (last_frame_info_) {
InternalSwapCompositorFrame(last_frame_info_->output_surface_id,
- last_frame_info_->frame.Pass());
+ std::move(last_frame_info_->frame));
last_frame_info_.reset();
}
@@ -690,9 +702,9 @@ void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrames(bool enabled) {
}
void RenderWidgetHostViewAndroid::OnStartContentIntent(
- const GURL& content_url) {
+ const GURL& content_url, bool is_main_frame) {
if (content_view_core_)
- content_view_core_->StartContentIntent(content_url);
+ content_view_core_->StartContentIntent(content_url, is_main_frame);
}
void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
@@ -869,7 +881,7 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
return;
}
base::TimeTicks start_time = base::TimeTicks::Now();
- if (using_browser_compositor_ && !IsSurfaceAvailableForCopy()) {
+ if (!IsSurfaceAvailableForCopy()) {
callback.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE);
return;
}
@@ -909,15 +921,15 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
readback_layer, callback));
if (!src_subrect_in_pixel.IsEmpty())
request->set_area(src_subrect_in_pixel);
- readback_layer->RequestCopyOfOutput(request.Pass());
+ readback_layer->RequestCopyOfOutput(std::move(request));
}
void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
- const gfx::Rect& src_subrect,
- const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) {
+ const gfx::Rect& src_subrect,
+ const scoped_refptr<media::VideoFrame>& target,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) {
NOTIMPLEMENTED();
- callback.Run(false);
+ callback.Run(gfx::Rect(), false);
}
bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
@@ -939,7 +951,7 @@ RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
}
void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
- uint32 output_surface_id) {
+ uint32_t output_surface_id) {
DCHECK(host_);
cc::CompositorFrameAck ack;
if (!surface_returned_resources_.empty())
@@ -951,7 +963,7 @@ void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
}
void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
- uint32 output_surface_id) {
+ uint32_t output_surface_id) {
DCHECK(host_);
cc::CompositorFrameAck ack;
if (!surface_returned_resources_.empty()) {
@@ -982,6 +994,12 @@ void RenderWidgetHostViewAndroid::ReturnResources(
SendReturnedDelegatedResources(last_output_surface_id_);
}
+void RenderWidgetHostViewAndroid::SetBeginFrameSource(
+ cc::SurfaceId surface_id,
+ cc::BeginFrameSource* begin_frame_source) {
+ // TODO(tansell): Hook this up.
+}
+
void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
RemoveLayers();
frame_provider_ = NULL;
@@ -994,7 +1012,7 @@ void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
}
void RenderWidgetHostViewAndroid::CheckOutputSurfaceChanged(
- uint32 output_surface_id) {
+ uint32_t output_surface_id) {
if (output_surface_id == last_output_surface_id_)
return;
// Drop the cc::DelegatedFrameResourceCollection so that we will not return
@@ -1044,7 +1062,7 @@ void RenderWidgetHostViewAndroid::SubmitCompositorFrame(
cc::SurfaceFactory::DrawCallback ack_callback =
base::Bind(&RenderWidgetHostViewAndroid::RunAckCallbacks,
weak_ptr_factory_.GetWeakPtr());
- surface_factory_->SubmitCompositorFrame(surface_id_, frame.Pass(),
+ surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame),
ack_callback);
} else {
if (!resource_collection_.get()) {
@@ -1055,18 +1073,18 @@ void RenderWidgetHostViewAndroid::SubmitCompositorFrame(
texture_size_in_layer_ != frame_provider_->frame_size()) {
RemoveLayers();
frame_provider_ = new cc::DelegatedFrameProvider(
- resource_collection_.get(), frame->delegated_frame_data.Pass());
+ resource_collection_.get(), std::move(frame->delegated_frame_data));
layer_ = cc::DelegatedRendererLayer::Create(Compositor::LayerSettings(),
frame_provider_);
AttachLayers();
} else {
- frame_provider_->SetFrameData(frame->delegated_frame_data.Pass());
+ frame_provider_->SetFrameData(std::move(frame->delegated_frame_data));
}
}
}
void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) {
CheckOutputSurfaceChanged(output_surface_id);
bool has_content = !texture_size_in_layer_.IsEmpty();
@@ -1089,7 +1107,7 @@ void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
if (!has_content) {
DestroyDelegatedContent();
} else {
- SubmitCompositorFrame(frame.Pass());
+ SubmitCompositorFrame(std::move(frame));
}
if (layer_.get()) {
@@ -1103,7 +1121,7 @@ void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
}
void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) {
last_scroll_offset_ = frame->metadata.root_scroll_offset;
if (!frame->delegated_frame_data) {
@@ -1113,7 +1131,7 @@ void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
if (locks_on_frame_count_ > 0) {
DCHECK(HasValidFrame());
- RetainFrame(output_surface_id, frame.Pass());
+ RetainFrame(output_surface_id, std::move(frame));
return;
}
@@ -1122,19 +1140,19 @@ void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
scoped_ptr<cc::SwapPromise> swap_promise(
new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
- layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
+ layer_->layer_tree_host()->QueueSwapPromise(std::move(swap_promise));
}
}
DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
cc::RenderPass* root_pass =
- frame->delegated_frame_data->render_pass_list.back();
+ frame->delegated_frame_data->render_pass_list.back().get();
texture_size_in_layer_ = root_pass->output_rect.size();
cc::CompositorFrameMetadata metadata = frame->metadata;
- SwapDelegatedFrame(output_surface_id, frame.Pass());
+ SwapDelegatedFrame(output_surface_id, std::move(frame));
frame_evictor_->SwappedFrame(!host_->is_hidden());
// As the metadata update may trigger view invalidation, always call it after
@@ -1143,9 +1161,9 @@ void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
}
void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) {
- InternalSwapCompositorFrame(output_surface_id, frame.Pass());
+ InternalSwapCompositorFrame(output_surface_id, std::move(frame));
}
void RenderWidgetHostViewAndroid::ClearCompositorFrame() {
@@ -1153,7 +1171,7 @@ void RenderWidgetHostViewAndroid::ClearCompositorFrame() {
}
void RenderWidgetHostViewAndroid::RetainFrame(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) {
DCHECK(locks_on_frame_count_);
@@ -1170,7 +1188,13 @@ void RenderWidgetHostViewAndroid::RetainFrame(
ack_callbacks_.push(ack_callback);
}
- last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass()));
+ last_frame_info_.reset(
+ new LastFrameInfo(output_surface_id, std::move(frame)));
+}
+
+SynchronousCompositorBase*
+RenderWidgetHostViewAndroid::GetSynchronousCompositor() {
+ return sync_compositor_.get();
}
void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
@@ -1238,8 +1262,10 @@ void RenderWidgetHostViewAndroid::OnSelectionEvent(
// If a selection drag has started, it has taken over the active touch
// sequence. Immediately cancel gesture detection and any downstream touch
// listeners (e.g., web content) to communicate this transfer.
- if (event == ui::SELECTION_HANDLES_SHOWN)
+ if (event == ui::SELECTION_HANDLES_SHOWN &&
+ gesture_provider_.GetCurrentDownEvent()) {
ResetGestureDetection();
+ }
content_view_core_->OnSelectionEvent(
event, selection_controller_->GetStartPosition(),
GetSelectionRect(*selection_controller_));
@@ -1278,10 +1304,7 @@ void RenderWidgetHostViewAndroid::SynchronousCopyContents(
int output_width = output_size_in_pixel.width();
int output_height = output_size_in_pixel.height();
- SynchronousCompositor* compositor =
- SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
- host_->GetRoutingID());
- if (!compositor) {
+ if (!sync_compositor_) {
callback.Run(SkBitmap(), READBACK_FAILED);
return;
}
@@ -1295,7 +1318,7 @@ void RenderWidgetHostViewAndroid::SynchronousCopyContents(
canvas.scale(
(float)output_width / (float)input_size_in_pixel.width(),
(float)output_height / (float)input_size_in_pixel.height());
- compositor->DemandDrawSw(&canvas);
+ sync_compositor_->DemandDrawSw(&canvas);
callback.Run(bitmap, READBACK_SUCCESS);
}
@@ -1318,6 +1341,15 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
selection_controller_->OnSelectionBoundsChanged(
ConvertSelectionBound(frame_metadata.selection.start),
ConvertSelectionBound(frame_metadata.selection.end));
+
+ // Set parameters for adaptive handle orientation.
+ gfx::SizeF viewport_size(frame_metadata.scrollable_viewport_size);
+ viewport_size.Scale(frame_metadata.page_scale_factor);
+ gfx::RectF viewport_rect(
+ frame_metadata.location_bar_content_translation.x(),
+ frame_metadata.location_bar_content_translation.y(),
+ viewport_size.width(), viewport_size.height());
+ selection_controller_->OnViewportChanged(viewport_rect);
}
UpdateBackgroundColor(frame_metadata.root_background_color);
@@ -1334,19 +1366,22 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
frame_metadata.location_bar_content_translation,
is_mobile_optimized);
#if defined(VIDEO_HOLE)
- if (host_ && host_->IsRenderView()) {
- RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(
- RenderViewHost::From(host_));
- WebContentsImpl* web_contents_impl =
- static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvhi));
- if (web_contents_impl)
- web_contents_impl->media_web_contents_observer()->OnFrameInfoUpdated();
+ if (host_) {
+ WebContents* web_contents =
+ WebContents::FromRenderViewHost(RenderViewHostImpl::From(host_));
+ if (web_contents) {
+ MediaWebContentsObserverAndroid::FromWebContents(web_contents)
+ ->OnFrameInfoUpdated();
+ }
}
#endif // defined(VIDEO_HOLE)
}
void RenderWidgetHostViewAndroid::ShowInternal() {
- DCHECK(is_showing_);
+ bool show = is_showing_ && is_window_activity_started_ && is_window_visible_;
+ if (!show)
+ return;
+
if (!host_ || !host_->is_hidden())
return;
@@ -1366,9 +1401,20 @@ void RenderWidgetHostViewAndroid::ShowInternal() {
}
}
-void RenderWidgetHostViewAndroid::HideInternal(
- bool hide_frontbuffer,
- bool stop_observing_root_window) {
+void RenderWidgetHostViewAndroid::HideInternal() {
+ DCHECK(!is_showing_ || !is_window_activity_started_ || !is_window_visible_)
+ << "Hide called when the widget should be shown.";
+
+ // Only preserve the frontbuffer if the activity was stopped while the
+ // window is still visible. This avoids visual artificts when transitioning
+ // between activities.
+ bool hide_frontbuffer = is_window_activity_started_ || !is_window_visible_;
+
+ // Only stop observing the root window if the widget has been explicitly
+ // hidden and the frontbuffer is being cleared. This allows window visibility
+ // notifications to eventually clear the frontbuffer.
+ bool stop_observing_root_window = !is_showing_ && hide_frontbuffer;
+
if (hide_frontbuffer) {
if (layer_.get() && locks_on_frame_count_ == 0)
layer_->SetHideLayerAndSubtree(true);
@@ -1376,8 +1422,10 @@ void RenderWidgetHostViewAndroid::HideInternal(
frame_evictor_->SetVisible(false);
}
- if (stop_observing_root_window)
+ if (stop_observing_root_window) {
+ DCHECK(!is_showing_);
StopObservingRootWindow();
+ }
if (!host_ || host_->is_hidden())
return;
@@ -1412,7 +1460,7 @@ void RenderWidgetHostViewAndroid::RemoveLayers() {
content_view_core_->RemoveLayer(layer_);
}
-void RenderWidgetHostViewAndroid::RequestVSyncUpdate(uint32 requests) {
+void RenderWidgetHostViewAndroid::RequestVSyncUpdate(uint32_t requests) {
bool should_request_vsync = !outstanding_vsync_requests_ && requests;
outstanding_vsync_requests_ |= requests;
@@ -1438,7 +1486,7 @@ void RenderWidgetHostViewAndroid::StartObservingRootWindow() {
content_view_core_window_android_->AddObserver(this);
// Clear existing vsync requests to allow a request to the new window.
- uint32 outstanding_vsync_requests = outstanding_vsync_requests_;
+ uint32_t outstanding_vsync_requests = outstanding_vsync_requests_;
outstanding_vsync_requests_ = 0;
RequestVSyncUpdate(outstanding_vsync_requests);
}
@@ -1452,6 +1500,9 @@ void RenderWidgetHostViewAndroid::StopObservingRootWindow() {
if (!observing_root_window_)
return;
+ // Reset window state variables to their defaults.
+ is_window_activity_started_ = true;
+ is_window_visible_ = true;
observing_root_window_ = false;
content_view_core_window_android_->RemoveObserver(this);
}
@@ -1470,16 +1521,12 @@ void RenderWidgetHostViewAndroid::SendBeginFrame(base::TimeTicks frame_time,
host_->GetRoutingID(),
cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
vsync_period, cc::BeginFrameArgs::NORMAL)));
- } else {
- SynchronousCompositorImpl* compositor = SynchronousCompositorImpl::FromID(
- host_->GetProcess()->GetID(), host_->GetRoutingID());
- if (compositor) {
- // The synchronous compositor synchronously does it's work in this call.
- // It does not use a deadline.
- compositor->BeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, frame_time, base::TimeTicks(), vsync_period,
- cc::BeginFrameArgs::NORMAL));
- }
+ } else if (sync_compositor_) {
+ // The synchronous compositor synchronously does it's work in this call.
+ // It does not use a deadline.
+ sync_compositor_->BeginFrame(cc::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, frame_time, base::TimeTicks(), vsync_period,
+ cc::BeginFrameArgs::NORMAL));
}
}
@@ -1570,6 +1617,10 @@ InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
}
break;
+ case blink::WebInputEvent::GestureScrollBegin:
+ selection_controller_->OnScrollBeginEvent();
+ break;
+
default:
break;
}
@@ -1597,11 +1648,8 @@ InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
shim->Send(new GpuMsg_WakeUpGpu);
}
- SynchronousCompositorImpl* compositor =
- SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
- host_->GetRoutingID());
- if (compositor)
- return compositor->HandleInputEvent(input_event);
+ if (sync_compositor_)
+ return sync_compositor_->HandleInputEvent(input_event);
return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
}
@@ -1645,8 +1693,19 @@ void RenderWidgetHostViewAndroid::UnlockMouse() {
void RenderWidgetHostViewAndroid::SendKeyEvent(
const NativeWebKeyboardEvent& event) {
- if (host_)
- host_->ForwardKeyboardEvent(event);
+ if (!host_)
+ return;
+
+ RenderWidgetHostImpl* target_host = host_;
+
+ // If there are multiple widgets on the page (such as when there are
+ // out-of-process iframes), pick the one that should process this event.
+ if (host_->delegate())
+ target_host = host_->delegate()->GetFocusedRenderWidgetHost(host_);
+ if (!target_host)
+ return;
+
+ target_host->ForwardKeyboardEvent(event);
}
void RenderWidgetHostViewAndroid::SendMouseEvent(
@@ -1733,6 +1792,8 @@ uint32_t RenderWidgetHostViewAndroid::GetSurfaceIdNamespace() {
void RenderWidgetHostViewAndroid::SetContentViewCore(
ContentViewCoreImpl* content_view_core) {
+ DCHECK(!content_view_core || !content_view_core_ ||
+ (content_view_core_ == content_view_core));
RemoveLayers();
StopObservingRootWindow();
@@ -1760,9 +1821,10 @@ void RenderWidgetHostViewAndroid::SetContentViewCore(
}
AttachLayers();
-
- if (!content_view_core_)
+ if (!content_view_core_) {
+ sync_compositor_.reset();
return;
+ }
if (is_showing_)
StartObservingRootWindow();
@@ -1777,6 +1839,13 @@ void RenderWidgetHostViewAndroid::SetContentViewCore(
content_view_core_window_android_->GetCompositor()) {
overscroll_controller_ = CreateOverscrollController(content_view_core_);
}
+
+ if (!sync_compositor_) {
+ sync_compositor_ = SynchronousCompositorBase::Create(
+ this, content_view_core_->GetWebContents());
+ }
+ if (sync_compositor_)
+ sync_compositor_->DidBecomeCurrent();
}
void RenderWidgetHostViewAndroid::RunAckCallbacks(
@@ -1807,14 +1876,19 @@ void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
}
void RenderWidgetHostViewAndroid::OnRootWindowVisibilityChanged(bool visible) {
- DCHECK(is_showing_);
- if (visible) {
+ TRACE_EVENT1("browser",
+ "RenderWidgetHostViewAndroid::OnRootWindowVisibilityChanged",
+ "visible", visible);
+ DCHECK(observing_root_window_);
+ if (is_window_visible_ == visible)
+ return;
+
+ is_window_visible_ = visible;
+
+ if (visible)
ShowInternal();
- } else {
- bool hide_frontbuffer = true;
- bool stop_observing_root_window = false;
- HideInternal(hide_frontbuffer, stop_observing_root_window);
- }
+ else
+ HideInternal();
}
void RenderWidgetHostViewAndroid::OnAttachCompositor() {
@@ -1849,7 +1923,7 @@ void RenderWidgetHostViewAndroid::OnVSync(base::TimeTicks frame_time,
// This allows for SendBeginFrame and FlushInput to modify
// outstanding_vsync_requests.
- uint32 outstanding_vsync_requests = outstanding_vsync_requests_;
+ uint32_t outstanding_vsync_requests = outstanding_vsync_requests_;
outstanding_vsync_requests_ = 0;
RequestVSyncUpdate(outstanding_vsync_requests);
}
@@ -1861,15 +1935,15 @@ void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) {
void RenderWidgetHostViewAndroid::OnActivityStopped() {
TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityStopped");
- DCHECK(is_showing_);
- bool hide_frontbuffer = false;
- bool stop_observing_root_window = false;
- HideInternal(hide_frontbuffer, stop_observing_root_window);
+ DCHECK(observing_root_window_);
+ is_window_activity_started_ = false;
+ HideInternal();
}
void RenderWidgetHostViewAndroid::OnActivityStarted() {
TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityStarted");
- DCHECK(is_showing_);
+ DCHECK(observing_root_window_);
+ is_window_activity_started_ = true;
ShowInternal();
}
@@ -1890,8 +1964,8 @@ void RenderWidgetHostViewAndroid::
const ReadbackRequestCallback& callback,
scoped_ptr<cc::CopyOutputResult> result) {
readback_layer->RemoveFromParent();
- PrepareTextureCopyOutputResult(
- dst_size_in_pixel, color_type, start_time, callback, result.Pass());
+ PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, start_time,
+ callback, std::move(result));
}
// static
@@ -1933,7 +2007,7 @@ void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
new SkAutoLockPixels(*bitmap));
- uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
+ uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels());
cc::TextureMailbox texture_mailbox;
scoped_ptr<cc::SingleReleaseCallback> release_callback;
@@ -1945,19 +2019,11 @@ void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
ignore_result(scoped_callback_runner.Release());
gl_helper->CropScaleReadbackAndCleanMailbox(
- texture_mailbox.mailbox(),
- texture_mailbox.sync_point(),
- result->size(),
- gfx::Rect(result->size()),
- output_size_in_pixel,
- pixels,
- color_type,
- base::Bind(&CopyFromCompositingSurfaceFinished,
- callback,
- base::Passed(&release_callback),
- base::Passed(&bitmap),
- start_time,
- base::Passed(&bitmap_pixels_lock)),
+ texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
+ gfx::Rect(result->size()), output_size_in_pixel, pixels, color_type,
+ base::Bind(&CopyFromCompositingSurfaceFinished, callback,
+ base::Passed(&release_callback), base::Passed(&bitmap),
+ start_time, base::Passed(&bitmap_pixels_lock)),
GLHelper::SCALER_QUALITY_GOOD);
}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.h b/chromium/content/browser/renderer_host/render_widget_host_view_android.h
index 8d2b8a2027a..0d51b7037fe 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.h
@@ -5,12 +5,16 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_ANDROID_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_ANDROID_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <queue>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/i18n/rtl.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
@@ -26,8 +30,8 @@
#include "content/common/content_export.h"
#include "content/public/browser/readback_types.h"
#include "gpu/command_buffer/common/mailbox.h"
-#include "third_party/skia/include/core/SkColor.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/android/window_android_observer.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
#include "ui/gfx/geometry/size.h"
@@ -57,6 +61,7 @@ class ContentViewCoreImpl;
class OverscrollControllerAndroid;
class RenderWidgetHost;
class RenderWidgetHostImpl;
+class SynchronousCompositorBase;
struct DidOverscrollParams;
struct NativeWebKeyboardEvent;
@@ -131,7 +136,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) override;
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
bool CanCopyToVideoFrame() const override;
void GetScreenInfo(blink::WebScreenInfo* results) override;
bool GetScreenColorProfile(std::vector<char>* color_profile) override;
@@ -147,7 +152,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
BrowserAccessibilityDelegate* delegate) override;
bool LockMouse() override;
void UnlockMouse() override;
- void OnSwapCompositorFrame(uint32 output_surface_id,
+ void OnSwapCompositorFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) override;
void ClearCompositorFrame() override;
void DidOverscroll(const DidOverscrollParams& params) override;
@@ -168,6 +173,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
// cc::SurfaceFactoryClient implementation.
void ReturnResources(const cc::ReturnedResourceArray& resources) override;
+ void SetBeginFrameSource(cc::SurfaceId surface_id,
+ cc::BeginFrameSource* begin_frame_source) override;
// ui::GestureProviderClient implementation.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
@@ -210,7 +217,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event);
void SendGestureEvent(const blink::WebGestureEvent& event);
- void OnStartContentIntent(const GURL& content_url);
+ void OnStartContentIntent(const GURL& content_url, bool is_main_frame);
void OnSetNeedsBeginFrames(bool enabled);
void OnSmartClipDataExtracted(const base::string16& text,
const base::string16& html,
@@ -241,6 +248,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void OnShowingPastePopup(const gfx::PointF& point);
void OnShowUnhandledTapUIIfNeeded(int x_dip, int y_dip);
+ SynchronousCompositorBase* GetSynchronousCompositor();
void SynchronousFrameMetadata(
const cc::CompositorFrameMetadata& frame_metadata);
@@ -258,18 +266,18 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void RunAckCallbacks(cc::SurfaceDrawStatus status);
void DestroyDelegatedContent();
- void CheckOutputSurfaceChanged(uint32 output_surface_id);
+ void CheckOutputSurfaceChanged(uint32_t output_surface_id);
void SubmitCompositorFrame(scoped_ptr<cc::CompositorFrame> frame_data);
- void SwapDelegatedFrame(uint32 output_surface_id,
+ void SwapDelegatedFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame_data);
- void SendDelegatedFrameAck(uint32 output_surface_id);
- void SendReturnedDelegatedResources(uint32 output_surface_id);
+ void SendDelegatedFrameAck(uint32_t output_surface_id);
+ void SendReturnedDelegatedResources(uint32_t output_surface_id);
void OnFrameMetadataUpdated(
const cc::CompositorFrameMetadata& frame_metadata);
void ShowInternal();
- void HideInternal(bool hide_frontbuffer, bool stop_observing_root_window);
+ void HideInternal();
void AttachLayers();
void RemoveLayers();
@@ -304,10 +312,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
// Drop any incoming frames from the renderer when there are locks on the
// current frame.
- void RetainFrame(uint32 output_surface_id,
+ void RetainFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame);
- void InternalSwapCompositorFrame(uint32 output_surface_id,
+ void InternalSwapCompositorFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame);
void OnLostResources();
@@ -316,23 +324,29 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
BEGIN_FRAME = 1 << 1,
PERSISTENT_BEGIN_FRAME = 1 << 2
};
- void RequestVSyncUpdate(uint32 requests);
+ void RequestVSyncUpdate(uint32_t requests);
void StartObservingRootWindow();
void StopObservingRootWindow();
void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period);
bool Animate(base::TimeTicks frame_time);
void RequestDisallowInterceptTouchEvent();
+ bool SyncCompositorOnMessageReceived(const IPC::Message& message);
+
// The model object.
RenderWidgetHostImpl* host_;
bool use_surfaces_;
// Used to control action dispatch at the next |OnVSync()| call.
- uint32 outstanding_vsync_requests_;
+ uint32_t outstanding_vsync_requests_;
bool is_showing_;
+ // Window-specific bits that affect widget visibility.
+ bool is_window_visible_;
+ bool is_window_activity_started_;
+
// ContentViewCoreImpl is our interface to the view system.
ContentViewCoreImpl* content_view_core_;
@@ -387,6 +401,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
gfx::Size default_size_;
const bool using_browser_compositor_;
+ scoped_ptr<SynchronousCompositorBase> sync_compositor_;
scoped_ptr<DelegatedFrameEvictor> frame_evictor_;
@@ -394,10 +409,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
bool observing_root_window_;
struct LastFrameInfo {
- LastFrameInfo(uint32 output_id,
+ LastFrameInfo(uint32_t output_id,
scoped_ptr<cc::CompositorFrame> output_frame);
~LastFrameInfo();
- uint32 output_surface_id;
+ uint32_t output_surface_id;
scoped_ptr<cc::CompositorFrame> frame;
};
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
index c7aac43bf87..c5494d9976f 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -5,16 +5,18 @@
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include <set>
+#include <utility>
#include "base/auto_reset.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "cc/layers/layer.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
@@ -44,6 +46,7 @@
#include "content/browser/renderer_host/web_input_event_aura.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/overscroll_configuration.h"
@@ -80,6 +83,7 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_profile.h"
#include "ui/gfx/display.h"
+#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/screen.h"
@@ -98,6 +102,7 @@
#include "content/common/plugin_constants_win.h"
#include "ui/base/win/hidden_window.h"
#include "ui/gfx/gdi_util.h"
+#include "ui/gfx/screen_win.h"
#include "ui/gfx/win/dpi.h"
#endif
@@ -350,7 +355,7 @@ void RenderWidgetHostViewAura::ApplyEventFilterForPopupExit(
// notification. We also set a flag in the view indicating that we need
// to force a Focus notification on the next mouse down.
if (popup_parent_host_view_ && popup_parent_host_view_->host_) {
- popup_parent_host_view_->set_focus_on_mouse_down_ = true;
+ popup_parent_host_view_->set_focus_on_mouse_down_or_key_event_ = true;
popup_parent_host_view_->host_->Blur();
}
// Note: popup_parent_host_view_ may be NULL when there are multiple
@@ -448,7 +453,7 @@ class RenderWidgetHostViewAura::WindowAncestorObserver
RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host,
bool is_guest_view_hack)
: host_(RenderWidgetHostImpl::From(host)),
- window_(new aura::Window(this)),
+ window_(nullptr),
delegated_frame_host_(new DelegatedFrameHost(this)),
in_shutdown_(false),
in_bounds_changed_(false),
@@ -474,19 +479,12 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host,
has_snapped_to_boundary_(false),
is_guest_view_hack_(is_guest_view_hack),
begin_frame_observer_proxy_(this),
- set_focus_on_mouse_down_(false),
+ set_focus_on_mouse_down_or_key_event_(false),
+ device_scale_factor_(0.0f),
weak_ptr_factory_(this) {
if (!is_guest_view_hack_)
host_->SetView(this);
- window_observer_.reset(new WindowObserver(this));
-
- aura::client::SetTooltipText(window_, &tooltip_);
- aura::client::SetActivationDelegate(window_, this);
- aura::client::SetFocusChangeObserver(window_, this);
- window_->set_layer_owner_delegate(delegated_frame_host_.get());
- gfx::Screen::GetScreenFor(window_)->AddObserver(this);
-
// Let the page-level input event router know about our surface ID
// namespace for surface-based hit testing.
if (UseSurfacesEnabled() && host_->delegate() &&
@@ -520,15 +518,24 @@ bool RenderWidgetHostViewAura::OnMessageReceived(
void RenderWidgetHostViewAura::InitAsChild(
gfx::NativeView parent_view) {
+ CreateAuraWindow();
window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
window_->Init(ui::LAYER_SOLID_COLOR);
window_->SetName("RenderWidgetHostViewAura");
window_->layer()->SetColor(background_color_);
+
+ if (parent_view)
+ parent_view->AddChild(GetNativeView());
+
+ const gfx::Display display =
+ gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(window_);
+ device_scale_factor_ = display.device_scale_factor();
}
void RenderWidgetHostViewAura::InitAsPopup(
RenderWidgetHostView* parent_host_view,
const gfx::Rect& bounds_in_screen) {
+ CreateAuraWindow();
popup_parent_host_view_ =
static_cast<RenderWidgetHostViewAura*>(parent_host_view);
@@ -572,10 +579,15 @@ void RenderWidgetHostViewAura::InitAsPopup(
window_->SetCapture();
event_filter_for_popup_exit_.reset(new EventFilterForPopupExit(this));
+
+ const gfx::Display display =
+ gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(window_);
+ device_scale_factor_ = display.device_scale_factor();
}
void RenderWidgetHostViewAura::InitAsFullscreen(
RenderWidgetHostView* reference_host_view) {
+ CreateAuraWindow();
is_fullscreen_ = true;
window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
window_->Init(ui::LAYER_SOLID_COLOR);
@@ -600,6 +612,10 @@ void RenderWidgetHostViewAura::InitAsFullscreen(
aura::client::ParentWindowWithContext(window_, parent, bounds);
Show();
Focus();
+
+ const gfx::Display display =
+ gfx::Screen::GetScreenFor(window_)->GetDisplayNearestWindow(window_);
+ device_scale_factor_ = display.device_scale_factor();
}
RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
@@ -758,20 +774,20 @@ void RenderWidgetHostViewAura::SetKeyboardFocus() {
::SetFocus(host->GetAcceleratedWidget());
}
#endif
- if (host_ && set_focus_on_mouse_down_) {
- set_focus_on_mouse_down_ = false;
+ if (host_ && set_focus_on_mouse_down_or_key_event_) {
+ set_focus_on_mouse_down_or_key_event_ = false;
host_->Focus();
}
}
RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() {
- if (!host_->IsRenderView())
- return NULL;
RenderViewHost* rvh = RenderViewHost::From(host_);
+ if (!rvh)
+ return nullptr;
FrameTreeNode* focused_frame =
rvh->GetDelegate()->GetFrameTree()->GetFocusedFrame();
if (!focused_frame)
- return NULL;
+ return nullptr;
return focused_frame->current_frame_host();
}
@@ -843,6 +859,23 @@ bool RenderWidgetHostViewAura::CanRendererHandleEvent(
return true;
}
+bool RenderWidgetHostViewAura::ShouldRouteEvent(const ui::Event* event) const {
+ // We should route an event in two cases:
+ // 1) Mouse events are routed only if cross-process frames are possible.
+ // 2) Touch events are always routed. In the absence of a BrowserPlugin
+ // we expect the routing to always send the event to this view. If
+ // one or more BrowserPlugins are present, then the event may be targeted
+ // to one of them, or this view. This allows GuestViews to have access to
+ // them while still forcing pinch-zoom to be handled by the top-level
+ // frame. TODO(wjmaclean): At present, this doesn't work for OOPIF, but
+ // it should be a simple extension to modify RenderWidgetHostViewChildFrame
+ // in a similar manner to RenderWidgetHostViewGuest.
+ bool result = host_->delegate() && host_->delegate()->GetInputEventRouter();
+ if (event->IsMouseEvent())
+ result = result && SiteIsolationPolicy::AreCrossProcessFramesPossible();
+ return result;
+}
+
void RenderWidgetHostViewAura::HandleParentBoundsChanged() {
SnapToPhysicalPixelBoundary();
#if defined(OS_WIN)
@@ -1010,11 +1043,16 @@ void RenderWidgetHostViewAura::RenderProcessGone(base::TerminationStatus status,
}
void RenderWidgetHostViewAura::Destroy() {
- // Beware, this function is not called on all destruction paths. It will
- // implicitly end up calling ~RenderWidgetHostViewAura though, so all
- // destruction/cleanup code should happen there, not here.
+ // Beware, this function is not called on all destruction paths. If |window_|
+ // has been created, then it will implicitly end up calling
+ // ~RenderWidgetHostViewAura when |window_| is destroyed. Otherwise, The
+ // destructor is invoked directly from here. So all destruction/cleanup code
+ // should happen there, not here.
in_shutdown_ = true;
- delete window_;
+ if (window_)
+ delete window_;
+ else
+ delete this;
}
void RenderWidgetHostViewAura::SetTooltipText(
@@ -1060,10 +1098,10 @@ gfx::Size RenderWidgetHostViewAura::GetRequestedRendererSize() const {
void RenderWidgetHostViewAura::SelectionBoundsChanged(
const ViewHostMsg_SelectionBounds_Params& params) {
ui::SelectionBound anchor_bound, focus_bound;
- anchor_bound.SetEdge(params.anchor_rect.origin(),
- params.anchor_rect.bottom_left());
- focus_bound.SetEdge(params.focus_rect.origin(),
- params.focus_rect.bottom_left());
+ anchor_bound.SetEdge(gfx::PointF(params.anchor_rect.origin()),
+ gfx::PointF(params.anchor_rect.bottom_left()));
+ focus_bound.SetEdge(gfx::PointF(params.focus_rect.origin()),
+ gfx::PointF(params.focus_rect.bottom_left()));
if (params.anchor_rect == params.focus_rect) {
anchor_bound.set_type(ui::SelectionBound::CENTER);
@@ -1107,9 +1145,9 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface(
}
void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
- const gfx::Rect& src_subrect,
- const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) {
+ const gfx::Rect& src_subrect,
+ const scoped_refptr<media::VideoFrame>& target,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) {
delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame(
src_subrect, target, callback);
}
@@ -1120,7 +1158,7 @@ bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
void RenderWidgetHostViewAura::BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
- delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
+ delegated_frame_host_->BeginFrameSubscription(std::move(subscriber));
}
void RenderWidgetHostViewAura::EndFrameSubscription() {
@@ -1169,21 +1207,21 @@ void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() {
#endif
void RenderWidgetHostViewAura::OnSwapCompositorFrame(
- uint32 output_surface_id,
+ uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) {
TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame");
last_scroll_offset_ = frame->metadata.root_scroll_offset;
if (!frame->delegated_frame_data)
return;
- delegated_frame_host_->SwapDelegatedFrame(
- output_surface_id, frame->delegated_frame_data.Pass(),
- frame->metadata.device_scale_factor, frame->metadata.latency_info,
- &frame->metadata.satisfies_sequences);
- SelectionUpdated(frame->metadata.selection.is_editable,
- frame->metadata.selection.is_empty_text_form_control,
- ConvertSelectionBound(frame->metadata.selection.start),
- ConvertSelectionBound(frame->metadata.selection.end));
+
+ cc::ViewportSelection selection = frame->metadata.selection;
+
+ delegated_frame_host_->SwapDelegatedFrame(output_surface_id,
+ std::move(frame));
+ SelectionUpdated(selection.is_editable, selection.is_empty_text_form_control,
+ ConvertSelectionBound(selection.start),
+ ConvertSelectionBound(selection.end));
}
void RenderWidgetHostViewAura::ClearCompositorFrame() {
@@ -1375,7 +1413,7 @@ RenderWidgetHostViewAura::CreateBrowserAccessibilityManager(
#if defined(OS_WIN)
manager = new BrowserAccessibilityManagerWin(
BrowserAccessibilityManagerWin::GetEmptyDocument(), delegate);
-#else
+#elif !defined(OS_ANDROID)
manager = BrowserAccessibilityManager::Create(
BrowserAccessibilityManager::GetEmptyDocument(), delegate);
#endif
@@ -1403,13 +1441,14 @@ RenderWidgetHostViewAura::AccessibilityGetNativeViewAccessible() {
void RenderWidgetHostViewAura::ShowDisambiguationPopup(
const gfx::Rect& rect_pixels,
const SkBitmap& zoomed_bitmap) {
- RenderViewHostDelegate* delegate = NULL;
- if (host_->IsRenderView())
- delegate = RenderViewHost::From(host_)->GetDelegate();
- // Suppress the link disambiguation popup if the virtual keyboard is currently
- // requested, as it doesn't interact well with the keyboard.
- if (delegate && delegate->IsVirtualKeyboardRequested())
- return;
+ RenderViewHost* rvh = RenderViewHost::From(host_);
+ if (rvh) {
+ RenderViewHostDelegate* delegate = rvh->GetDelegate();
+ // Suppress the link disambiguation popup if the virtual keyboard is
+ // currently requested, as it doesn't interact well with the keyboard.
+ if (delegate && delegate->IsVirtualKeyboardRequested())
+ return;
+ }
// |target_rect| is provided in pixels, not DIPs. So we convert it to DIPs
// by scaling it by the inverse of the device scale factor.
@@ -1443,15 +1482,18 @@ void RenderWidgetHostViewAura::DisambiguationPopupRendered(
// Use RenderViewHostDelegate to get to the WebContentsViewAura, which will
// actually show the disambiguation popup.
- RenderViewHostDelegate* delegate = NULL;
- if (host_->IsRenderView())
- delegate = RenderViewHost::From(host_)->GetDelegate();
- RenderViewHostDelegateView* delegate_view = NULL;
- if (delegate) {
- delegate_view = delegate->GetDelegateView();
- if (delegate->IsVirtualKeyboardRequested())
- return;
- }
+ RenderViewHost* rvh = RenderViewHost::From(host_);
+ if (!rvh)
+ return;
+
+ RenderViewHostDelegate* delegate = rvh->GetDelegate();
+ if (!delegate)
+ return;
+
+ if (delegate->IsVirtualKeyboardRequested())
+ return;
+
+ RenderViewHostDelegateView* delegate_view = delegate->GetDelegateView();
if (delegate_view) {
delegate_view->ShowDisambiguationPopup(
disambiguation_target_rect_,
@@ -1464,12 +1506,15 @@ void RenderWidgetHostViewAura::DisambiguationPopupRendered(
}
void RenderWidgetHostViewAura::HideDisambiguationPopup() {
- RenderViewHostDelegate* delegate = NULL;
- if (host_->IsRenderView())
- delegate = RenderViewHost::From(host_)->GetDelegate();
- RenderViewHostDelegateView* delegate_view = NULL;
- if (delegate)
- delegate_view = delegate->GetDelegateView();
+ RenderViewHost* rvh = RenderViewHost::From(host_);
+ if (!rvh)
+ return;
+
+ RenderViewHostDelegate* delegate = rvh->GetDelegate();
+ if (!delegate)
+ return;
+
+ RenderViewHostDelegateView* delegate_view = delegate->GetDelegateView();
if (delegate_view)
delegate_view->HideDisambiguationPopup();
}
@@ -1607,22 +1652,17 @@ void RenderWidgetHostViewAura::InsertText(const base::string16& text) {
has_composition_text_ = false;
}
-void RenderWidgetHostViewAura::InsertChar(base::char16 ch, int flags) {
+void RenderWidgetHostViewAura::InsertChar(const ui::KeyEvent& event) {
if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
- popup_child_host_view_->InsertChar(ch, flags);
+ popup_child_host_view_->InsertChar(event);
return;
}
// Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547
- if (host_ && (accept_return_character_ || ch != ui::VKEY_RETURN)) {
- double now = ui::EventTimeForNow().InSecondsF();
+ if (host_ &&
+ (accept_return_character_ || event.GetCharacter() != ui::VKEY_RETURN)) {
// Send a blink::WebInputEvent::Char event to |host_|.
- NativeWebKeyboardEvent webkit_event(ui::ET_KEY_PRESSED,
- true /* is_char */,
- ch,
- flags,
- now);
- ForwardKeyboardEvent(webkit_event);
+ ForwardKeyboardEvent(NativeWebKeyboardEvent(event, event.GetCharacter()));
}
}
@@ -1688,7 +1728,7 @@ gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
}
bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(
- uint32 index,
+ uint32_t index,
gfx::Rect* rect) const {
DCHECK(rect);
if (index >= composition_character_bounds_.size())
@@ -1881,6 +1921,7 @@ void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
UpdateScreenInfo(window_);
+ device_scale_factor_ = device_scale_factor;
const gfx::Display display = gfx::Screen::GetScreenFor(window_)->
GetDisplayNearestWindow(window_);
DCHECK_EQ(device_scale_factor, display.device_scale_factor());
@@ -1919,19 +1960,16 @@ void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) {
// Make sure that the input method no longer references to this object before
// this object is removed from the root window (i.e. this object loses access
// to the input method).
- ui::InputMethod* input_method = GetInputMethod();
- if (input_method)
- input_method->DetachTextInputClient(this);
+ DetachFromInputMethod();
if (overscroll_controller_)
overscroll_controller_->Reset();
}
void RenderWidgetHostViewAura::OnWindowDestroyed(aura::Window* window) {
- // Ask the RWH to drop reference to us.
- if (!is_guest_view_hack_)
- host_->ViewDestroyed();
-
+ // This is not called on all destruction paths (e.g. if this view was never
+ // inialized properly to create the window). So the destruction/cleanup code
+ // that do not depend on |window_| should happen in the destructor, not here.
delete this;
}
@@ -1986,6 +2024,10 @@ void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
accept_return_character_ = event->type() == ui::ET_KEY_PRESSED;
}
+ // Call SetKeyboardFocus() for not only ET_KEY_PRESSED but also
+ // ET_KEY_RELEASED. If a user closed the hotdog menu with ESC key press,
+ // we need to notify focus to Blink on ET_KEY_RELEASED for ESC key.
+ SetKeyboardFocus();
// We don't have to communicate with an input method here.
NativeWebKeyboardEvent webkit_event(*event);
ForwardKeyboardEvent(webkit_event);
@@ -2108,7 +2150,7 @@ void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
blink::WebMouseWheelEvent mouse_wheel_event =
MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event));
if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0) {
- if (host_->delegate() && host_->delegate()->GetInputEventRouter()) {
+ if (ShouldRouteEvent(event)) {
host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
this, &mouse_wheel_event);
} else {
@@ -2127,7 +2169,7 @@ void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
blink::WebMouseEvent mouse_event = MakeWebMouseEvent(*event);
ModifyEventMovementAndCoords(&mouse_event);
- if (host_->delegate() && host_->delegate()->GetInputEventRouter()) {
+ if (ShouldRouteEvent(event)) {
host_->delegate()->GetInputEventRouter()->RouteMouseEvent(this,
&mouse_event);
} else {
@@ -2172,8 +2214,17 @@ void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
uint32_t RenderWidgetHostViewAura::SurfaceIdNamespaceAtPoint(
const gfx::Point& point,
gfx::Point* transformed_point) {
- cc::SurfaceId id =
- delegated_frame_host_->SurfaceIdAtPoint(point, transformed_point);
+ DCHECK(device_scale_factor_ != 0.0f);
+
+ // The surface hittest happens in device pixels, so we need to convert the
+ // |point| from DIPs to pixels before hittesting.
+ gfx::Point point_in_pixels =
+ gfx::ConvertPointToPixel(device_scale_factor_, point);
+ cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint(point_in_pixels,
+ transformed_point);
+ *transformed_point =
+ gfx::ConvertPointToDIP(device_scale_factor_, *transformed_point);
+
// It is possible that the renderer has not yet produced a surface, in which
// case we return our current namespace.
if (id.is_null())
@@ -2191,6 +2242,20 @@ void RenderWidgetHostViewAura::ProcessMouseWheelEvent(
host_->ForwardWheelEvent(event);
}
+void RenderWidgetHostViewAura::ProcessTouchEvent(
+ const blink::WebTouchEvent& event,
+ const ui::LatencyInfo& latency) {
+ host_->ForwardTouchEventWithLatencyInfo(event, latency);
+}
+
+void RenderWidgetHostViewAura::TransformPointToLocalCoordSpace(
+ const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point) {
+ delegated_frame_host_->TransformPointToLocalCoordSpace(
+ point, original_surface, transformed_point);
+}
+
void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent");
@@ -2257,7 +2322,12 @@ void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
// Set unchanged touch point to StateStationary for touchmove and
// touchcancel to make sure only send one ack per WebTouchEvent.
MarkUnchangedTouchPointsAsStationary(&touch_event, event->touch_id());
- host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency());
+ if (ShouldRouteEvent(event)) {
+ host_->delegate()->GetInputEventRouter()->RouteTouchEvent(
+ this, &touch_event, *event->latency());
+ } else {
+ ProcessTouchEvent(touch_event, *event->latency());
+ }
}
void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
@@ -2421,6 +2491,10 @@ void RenderWidgetHostViewAura::OnHostMoved(const aura::WindowTreeHost* host,
// RenderWidgetHostViewAura, private:
RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
+ // Ask the RWH to drop reference to us.
+ if (!is_guest_view_hack_)
+ host_->ViewDestroyed();
+
selection_controller_.reset();
selection_controller_client_.reset();
@@ -2431,9 +2505,18 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
}
delegated_frame_host_.reset();
window_observer_.reset();
- if (window_->GetHost())
- window_->GetHost()->RemoveObserver(this);
- UnlockMouse();
+ if (window_) {
+ if (window_->GetHost())
+ window_->GetHost()->RemoveObserver(this);
+ UnlockMouse();
+ aura::client::SetTooltipText(window_, NULL);
+ gfx::Screen::GetScreenFor(window_)->RemoveObserver(this);
+
+ // This call is usually no-op since |this| object is already removed from
+ // the Aura root window and we don't have a way to get an input method
+ // object associated with the window, but just in case.
+ DetachFromInputMethod();
+ }
if (popup_parent_host_view_) {
DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL ||
popup_parent_host_view_->popup_child_host_view_ == this);
@@ -2445,13 +2528,6 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
popup_child_host_view_->popup_parent_host_view_ = NULL;
}
event_filter_for_popup_exit_.reset();
- aura::client::SetTooltipText(window_, NULL);
- gfx::Screen::GetScreenFor(window_)->RemoveObserver(this);
-
- // This call is usually no-op since |this| object is already removed from the
- // Aura root window and we don't have a way to get an input method object
- // associated with the window, but just in case.
- DetachFromInputMethod();
#if defined(OS_WIN)
// The LegacyRenderWidgetHostHWND window should have been destroyed in
@@ -2461,6 +2537,18 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
#endif
}
+void RenderWidgetHostViewAura::CreateAuraWindow() {
+ DCHECK(!window_);
+ window_ = new aura::Window(this);
+ window_observer_.reset(new WindowObserver(this));
+
+ aura::client::SetTooltipText(window_, &tooltip_);
+ aura::client::SetActivationDelegate(window_, this);
+ aura::client::SetFocusChangeObserver(window_, this);
+ window_->set_layer_owner_delegate(delegated_frame_host_.get());
+ gfx::Screen::GetScreenFor(window_)->AddObserver(this);
+}
+
void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
if (host_->GetProcess()->FastShutdownStarted())
return;
@@ -2469,8 +2557,39 @@ void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
if (!root_window)
return;
- gfx::Point root_window_point =
- gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
+ gfx::Screen* screen = gfx::Screen::GetScreenFor(GetNativeView());
+ DCHECK(screen);
+
+ gfx::Point cursor_screen_point = screen->GetCursorScreenPoint();
+
+#if !defined(OS_CHROMEOS)
+ // Ignore cursor update messages if the window under the cursor is not us.
+ aura::Window* window_at_screen_point = screen->GetWindowAtScreenPoint(
+ cursor_screen_point);
+#if defined(OS_WIN)
+ // On Windows we may fail to retrieve the aura Window at the current cursor
+ // position. This is because the WindowFromPoint API may return the legacy
+ // window which is not associated with an aura Window. In this case we need
+ // to get the aura window for the parent of the legacy window.
+ if (!window_at_screen_point && legacy_render_widget_host_HWND_) {
+ HWND hwnd_at_point = ::WindowFromPoint(cursor_screen_point.ToPOINT());
+
+ if (hwnd_at_point == legacy_render_widget_host_HWND_->hwnd())
+ hwnd_at_point = legacy_render_widget_host_HWND_->GetParent();
+
+ gfx::ScreenWin* screen_win = static_cast<gfx::ScreenWin*>(screen);
+ DCHECK(screen_win);
+ window_at_screen_point = screen_win->GetNativeWindowFromHWND(
+ hwnd_at_point);
+ }
+#endif
+ if (!window_at_screen_point ||
+ (window_at_screen_point->GetRootWindow() != root_window)) {
+ return;
+ }
+#endif
+
+ gfx::Point root_window_point = cursor_screen_point;
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root_window);
if (screen_position_client) {
@@ -2503,7 +2622,7 @@ ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
void RenderWidgetHostViewAura::Shutdown() {
if (!in_shutdown_) {
in_shutdown_ = true;
- host_->Shutdown();
+ host_->ShutdownAndDestroyWidget(true);
}
}
@@ -2736,6 +2855,15 @@ void RenderWidgetHostViewAura::DetachFromInputMethod() {
void RenderWidgetHostViewAura::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& event) {
+ RenderWidgetHostImpl* target_host = host_;
+
+ // If there are multiple widgets on the page (such as when there are
+ // out-of-process iframes), pick the one that should process this event.
+ if (host_->delegate())
+ target_host = host_->delegate()->GetFocusedRenderWidgetHost(host_);
+ if (!target_host)
+ return;
+
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
ui::TextEditKeyBindingsDelegateAuraLinux* keybinding_delegate =
ui::GetTextEditKeyBindingsDelegate();
@@ -2751,16 +2879,19 @@ void RenderWidgetHostViewAura::ForwardKeyboardEvent(
edit_commands.push_back(EditCommand(it->GetCommandString(),
it->argument()));
}
- host_->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
- host_->GetRoutingID(), edit_commands));
+ // TODO(alexmos): This needs to be refactored to work with subframe
+ // RenderWidgetHosts for OOPIF. See https://crbug.com/549334.
+ target_host->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
+ target_host->GetRoutingID(), edit_commands));
+
NativeWebKeyboardEvent copy_event(event);
copy_event.match_edit_command = true;
- host_->ForwardKeyboardEvent(copy_event);
+ target_host->ForwardKeyboardEvent(event);
return;
}
#endif
- host_->ForwardKeyboardEvent(event);
+ target_host->ForwardKeyboardEvent(event);
}
void RenderWidgetHostViewAura::SelectionUpdated(bool is_editable,
@@ -2778,7 +2909,7 @@ void RenderWidgetHostViewAura::CreateSelectionController() {
ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
tsc_config.tap_slop = ui::GestureConfiguration::GetInstance()
->max_touch_move_in_pixels_for_click();
- tsc_config.show_on_tap_for_empty_editable = true;
+ tsc_config.show_on_tap_for_empty_editable = false;
tsc_config.enable_longpress_drag_selection = false;
selection_controller_.reset(new ui::TouchSelectionController(
selection_controller_client_.get(), tsc_config));
@@ -2800,6 +2931,7 @@ void RenderWidgetHostViewAura::HandleGestureForTouchSelection(
}
break;
case ui::ET_GESTURE_SCROLL_BEGIN:
+ selection_controller_->OnScrollBeginEvent();
selection_controller_client_->OnScrollStarted();
break;
case ui::ET_GESTURE_SCROLL_END:
@@ -2883,6 +3015,14 @@ void RenderWidgetHostViewAura::OnDidNavigateMainFrameToNewPage() {
ui::GestureRecognizer::Get()->CancelActiveTouches(window_);
}
+void RenderWidgetHostViewAura::LockCompositingSurface() {
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewAura::UnlockCompositingSurface() {
+ NOTIMPLEMENTED();
+}
+
uint32_t RenderWidgetHostViewAura::GetSurfaceIdNamespace() {
return delegated_frame_host_->GetSurfaceIdNamespace();
}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.h b/chromium/content/browser/renderer_host/render_widget_host_view_aura.h
index 99bb3ce5eae..9aecd40beb6 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_AURA_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_AURA_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
@@ -12,10 +15,12 @@
#include "base/callback.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/compositor/delegated_frame_host.h"
#include "content/browser/compositor/image_transport_factory.h"
@@ -55,6 +60,7 @@ class DelegatedFrameData;
namespace gfx {
class Canvas;
class Display;
+class Rect;
}
namespace gpu {
@@ -153,7 +159,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) override;
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
bool CanCopyToVideoFrame() const override;
void BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override;
@@ -179,16 +185,23 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const SkBitmap& zoomed_bitmap) override;
bool LockMouse() override;
void UnlockMouse() override;
- void OnSwapCompositorFrame(uint32 output_surface_id,
+ void OnSwapCompositorFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) override;
void ClearCompositorFrame() override;
void DidStopFlinging() override;
void OnDidNavigateMainFrameToNewPage() override;
+ void LockCompositingSurface() override;
+ void UnlockCompositingSurface() override;
uint32_t GetSurfaceIdNamespace() override;
uint32_t SurfaceIdNamespaceAtPoint(const gfx::Point& point,
gfx::Point* transformed_point) override;
void ProcessMouseEvent(const blink::WebMouseEvent& event) override;
void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
+ void ProcessTouchEvent(const blink::WebTouchEvent& event,
+ const ui::LatencyInfo& latency) override;
+ void TransformPointToLocalCoordSpace(const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point) override;
#if defined(OS_WIN)
void SetParentNativeViewAccessible(
@@ -201,13 +214,13 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void ConfirmCompositionText() override;
void ClearCompositionText() override;
void InsertText(const base::string16& text) override;
- void InsertChar(base::char16 ch, int flags) override;
+ void InsertChar(const ui::KeyEvent& event) override;
ui::TextInputType GetTextInputType() const override;
ui::TextInputMode GetTextInputMode() const override;
int GetTextInputFlags() const override;
bool CanComposeInline() const override;
gfx::Rect GetCaretBounds() const override;
- bool GetCompositionCharacterBounds(uint32 index,
+ bool GetCompositionCharacterBounds(uint32_t index,
gfx::Rect* rect) const override;
bool HasCompositionText() const override;
bool GetTextRange(gfx::Range* range) const override;
@@ -372,6 +385,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
class WindowAncestorObserver;
friend class WindowAncestorObserver;
+ void CreateAuraWindow();
+
void UpdateCursorIfOverSelf();
// Tracks whether SnapToPhysicalPixelBoundary() has been called.
@@ -477,6 +492,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
bool mouse_locked,
bool selection_popup);
+ // Returns true when we can do SurfaceHitTesting for the event type.
+ bool ShouldRouteEvent(const ui::Event* event) const;
+
// Called when the parent window bounds change.
void HandleParentBoundsChanged();
@@ -663,7 +681,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// This flag when set ensures that we send over a notification to blink that
// the current view has focus. Defaults to false.
- bool set_focus_on_mouse_down_;
+ bool set_focus_on_mouse_down_or_key_event_;
+
+ float device_scale_factor_;
base::WeakPtrFactory<RenderWidgetHostViewAura> weak_ptr_factory_;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index d360dc90743..4eef57c2d54 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -4,13 +4,18 @@
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/simple_test_tick_clock.h"
+#include "build/build_config.h"
#include "cc/output/begin_frame_args.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_metadata.h"
@@ -21,6 +26,7 @@
#include "content/browser/compositor/resize_lock.h"
#include "content/browser/compositor/test/no_transport_image_transport_factory.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
+#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/input/input_router.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
#include "content/browser/renderer_host/overscroll_controller.h"
@@ -192,12 +198,14 @@ class TestWindowObserver : public aura::WindowObserver {
class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
public:
FakeFrameSubscriber(gfx::Size size, base::Callback<void(bool)> callback)
- : size_(size), callback_(callback) {}
+ : size_(size), callback_(callback), should_capture_(true) {}
bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) override {
+ if (!should_capture_)
+ return false;
last_present_time_ = present_time;
*storage = media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_YV12, size_,
gfx::Rect(size_), size_,
@@ -208,8 +216,13 @@ class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
base::TimeTicks last_present_time() const { return last_present_time_; }
+ void set_should_capture(bool should_capture) {
+ should_capture_ = should_capture;
+ }
+
static void CallbackMethod(base::Callback<void(bool)> callback,
base::TimeTicks present_time,
+ const gfx::Rect& region_in_frame,
bool success) {
callback.Run(success);
}
@@ -218,6 +231,7 @@ class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
gfx::Size size_;
base::Callback<void(bool)> callback_;
base::TimeTicks last_present_time_;
+ bool should_capture_;
};
class FakeWindowEventDispatcher : public aura::WindowEventDispatcher {
@@ -226,7 +240,7 @@ class FakeWindowEventDispatcher : public aura::WindowEventDispatcher {
: WindowEventDispatcher(host),
processed_touch_event_count_(0) {}
- void ProcessedTouchEvent(uint32 unique_event_id,
+ void ProcessedTouchEvent(uint32_t unique_event_id,
aura::Window* window,
ui::EventResult result) override {
WindowEventDispatcher::ProcessedTouchEvent(unique_event_id, window, result);
@@ -253,7 +267,7 @@ class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
void UseFakeDispatcher() {
dispatcher_ = new FakeWindowEventDispatcher(window()->GetHost());
scoped_ptr<aura::WindowEventDispatcher> dispatcher(dispatcher_);
- aura::test::SetHostDispatcher(window()->GetHost(), dispatcher.Pass());
+ aura::test::SetHostDispatcher(window()->GetHost(), std::move(dispatcher));
}
~FakeRenderWidgetHostViewAura() override {}
@@ -273,13 +287,13 @@ class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
}
void InterceptCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
- last_copy_request_ = request.Pass();
+ last_copy_request_ = std::move(request);
if (last_copy_request_->has_texture_mailbox()) {
// Give the resulting texture a size.
GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
GLuint texture = gl_helper->ConsumeMailboxToTexture(
last_copy_request_->texture_mailbox().mailbox(),
- last_copy_request_->texture_mailbox().sync_point());
+ last_copy_request_->texture_mailbox().sync_token());
gl_helper->ResizeTexture(texture, window()->bounds().size());
gl_helper->DeleteTexture(texture);
}
@@ -387,7 +401,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
sink_ = &process_host_->sink();
- int32 routing_id = process_host_->GetNextRoutingID();
+ int32_t routing_id = process_host_->GetNextRoutingID();
parent_host_ =
new RenderWidgetHostImpl(&delegate_, process_host_, routing_id, false);
parent_view_ = new RenderWidgetHostViewAura(parent_host_,
@@ -407,11 +421,19 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
void TearDownEnvironment() {
sink_ = NULL;
process_host_ = NULL;
- if (view_)
+ if (view_) {
+ // For guest-views, |view_| is not the view used by |widget_host_|.
+ if (!is_guest_view_hack_) {
+ EXPECT_EQ(view_, widget_host_->GetView());
+ }
view_->Destroy();
+ if (!is_guest_view_hack_) {
+ EXPECT_EQ(nullptr, widget_host_->GetView());
+ }
+ }
if (widget_host_uses_shutdown_to_destroy_)
- widget_host_->Shutdown();
+ widget_host_->ShutdownAndDestroyWidget(true);
else
delete widget_host_;
@@ -457,7 +479,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
void SendTouchEventACK(WebInputEvent::Type type,
InputEventAckState ack_result,
- uint32 event_id) {
+ uint32_t event_id) {
DCHECK(WebInputEvent::isTouchEventType(type));
InputEventAck ack(type, ack_result, event_id);
InputHostMsg_HandleInputEvent_ACK response(0, ack);
@@ -600,8 +622,8 @@ class RenderWidgetHostViewAuraOverscrollTest
}
void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
- widget_host_->ForwardWheelEvent(
- SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
+ widget_host_->ForwardWheelEvent(SyntheticWebMouseWheelEventBuilder::Build(
+ 0, 0, dX, dY, modifiers, precise));
}
void SimulateWheelEventWithLatencyInfo(float dX,
@@ -610,7 +632,8 @@ class RenderWidgetHostViewAuraOverscrollTest
bool precise,
const ui::LatencyInfo& ui_latency) {
widget_host_->ForwardWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, dX, dY, modifiers,
+ precise),
ui_latency);
}
@@ -717,8 +740,8 @@ class RenderWidgetHostViewAuraOverscrollTest
return overscroll_delegate_.get();
}
- uint32 SendTouchEvent() {
- uint32 touch_event_id = touch_event_.uniqueTouchEventId;
+ uint32_t SendTouchEvent() {
+ uint32_t touch_event_id = touch_event_.uniqueTouchEventId;
widget_host_->ForwardTouchEventWithLatencyInfo(touch_event_,
ui::LatencyInfo());
touch_event_.ResetPoints();
@@ -758,6 +781,12 @@ class RenderWidgetHostViewAuraShutdownTest
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraShutdownTest);
};
+// Checks that RenderWidgetHostViewAura can be destroyed before it is properly
+// initialized.
+TEST_F(RenderWidgetHostViewAuraTest, DestructionBeforeProperInitialization) {
+ // Terminate the test without initializing |view_|.
+}
+
// Checks that a fullscreen view has the correct show-state and receives the
// focus.
TEST_F(RenderWidgetHostViewAuraTest, FocusFullscreen) {
@@ -1110,17 +1139,11 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
// Start with no touch-event handler in the renderer.
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
- ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
- gfx::Point(30, 30),
- 0,
+ ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0,
ui::EventTimeForNow());
- ui::TouchEvent move(ui::ET_TOUCH_MOVED,
- gfx::Point(20, 20),
- 0,
+ ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0,
ui::EventTimeForNow());
- ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
- gfx::Point(20, 20),
- 0,
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0,
ui::EventTimeForNow());
// The touch events should get forwarded from the view, but they should not
@@ -1176,14 +1199,14 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0,
- base::Time::NowFromSystemTime() - base::Time());
+ base::Time::NowFromSystemTime() - base::Time());
view_->OnTouchEvent(&move2);
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0,
- base::Time::NowFromSystemTime() - base::Time());
+ base::Time::NowFromSystemTime() - base::Time());
view_->OnTouchEvent(&release2);
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(0U, pointer_state().GetPointerCount());
@@ -1284,17 +1307,11 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventSyncAsync) {
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
- ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
- gfx::Point(30, 30),
- 0,
+ ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0,
ui::EventTimeForNow());
- ui::TouchEvent move(ui::ET_TOUCH_MOVED,
- gfx::Point(20, 20),
- 0,
+ ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0,
ui::EventTimeForNow());
- ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
- gfx::Point(20, 20),
- 0,
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0,
ui::EventTimeForNow());
view_->OnTouchEvent(&press);
@@ -1515,8 +1532,8 @@ scoped_ptr<cc::CompositorFrame> MakeDelegatedFrame(float scale_factor,
scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
pass->SetNew(
cc::RenderPassId(1, 1), gfx::Rect(size), damage, gfx::Transform());
- frame->delegated_frame_data->render_pass_list.push_back(pass.Pass());
- return frame.Pass();
+ frame->delegated_frame_data->render_pass_list.push_back(std::move(pass));
+ return frame;
}
// Resizing in fullscreen mode should send the up-to-date screen info.
@@ -1715,7 +1732,7 @@ TEST_F(RenderWidgetHostViewAuraTest, Resize) {
root_window->GetHost()->compositor());
bool has_resize = false;
- for (uint32 i = 0; i < sink_->message_count(); ++i) {
+ for (uint32_t i = 0; i < sink_->message_count(); ++i) {
const IPC::Message* msg = sink_->GetMessageAt(i);
switch (msg->type()) {
case InputMsg_HandleInputEvent::ID: {
@@ -1902,7 +1919,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
// Create a bunch of renderers.
for (size_t i = 0; i < renderer_count; ++i) {
- int32 routing_id = process_host_->GetNextRoutingID();
+ int32_t routing_id = process_host_->GetNextRoutingID();
hosts[i] =
new RenderWidgetHostImpl(&delegate_, process_host_, routing_id, false);
hosts[i]->Init();
@@ -2066,7 +2083,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
// Create a bunch of renderers.
for (size_t i = 0; i < renderer_count; ++i) {
- int32 routing_id = process_host_->GetNextRoutingID();
+ int32_t routing_id = process_host_->GetNextRoutingID();
hosts[i] =
new RenderWidgetHostImpl(&delegate_, process_host_, routing_id, false);
hosts[i]->Init();
@@ -2135,7 +2152,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithMemoryPressure) {
// Create a bunch of renderers.
for (size_t i = 0; i < renderer_count; ++i) {
- int32 routing_id = process_host_->GetNextRoutingID();
+ int32_t routing_id = process_host_->GetNextRoutingID();
hosts[i] =
new RenderWidgetHostImpl(&delegate_, process_host_, routing_id, false);
hosts[i]->Init();
@@ -2236,7 +2253,10 @@ class RenderWidgetHostViewAuraCopyRequestTest
void RunLoopUntilCallback() {
base::RunLoop run_loop;
quit_closure_ = run_loop.QuitClosure();
+ // Temporarily ignore real draw requests.
+ frame_subscriber_->set_should_capture(false);
run_loop.Run();
+ frame_subscriber_->set_should_capture(true);
}
void InitializeView() {
@@ -2268,12 +2288,16 @@ class RenderWidgetHostViewAuraCopyRequestTest
void OnSwapCompositorFrame() {
view_->OnSwapCompositorFrame(
1, MakeDelegatedFrame(1.f, view_rect_.size(), view_rect_));
+ cc::SurfaceId surface_id =
+ view_->GetDelegatedFrameHost()->SurfaceIdForTesting();
+ if (!surface_id.is_null())
+ view_->GetDelegatedFrameHost()->WillDrawSurface(surface_id, view_rect_);
ASSERT_TRUE(view_->last_copy_request_);
}
void ReleaseSwappedFrame() {
scoped_ptr<cc::CopyOutputRequest> request =
- view_->last_copy_request_.Pass();
+ std::move(view_->last_copy_request_);
request->SendTextureResult(view_rect_.size(), request->texture_mailbox(),
scoped_ptr<cc::SingleReleaseCallback>());
RunLoopUntilCallback();
@@ -2385,7 +2409,8 @@ TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DestroyedAfterCopyRequest) {
OnSwapCompositorFrame();
EXPECT_EQ(1, callback_count_);
- scoped_ptr<cc::CopyOutputRequest> request = view_->last_copy_request_.Pass();
+ scoped_ptr<cc::CopyOutputRequest> request =
+ std::move(view_->last_copy_request_);
// Destroy the RenderWidgetHostViewAura and ImageTransportFactory.
TearDownEnvironment();
@@ -2497,10 +2522,10 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventPositionsArentRounded) {
view_->InitAsChild(NULL);
view_->Show();
- ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
- gfx::PointF(kX, kY),
- 0,
+ ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(), 0,
ui::EventTimeForNow());
+ press.set_location_f(gfx::PointF(kX, kY));
+ press.set_root_location_f(gfx::PointF(kX, kY));
view_->OnTouchEvent(&press);
EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
@@ -2979,8 +3004,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
// will reset the state. The scroll-end should therefore be dispatched to the
// renderer, and the gesture-event-filter should await an ACK for it.
base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(15));
base::MessageLoop::current()->Run();
@@ -2998,13 +3022,13 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
// The test sends an intermingled sequence of touch and gesture events.
PressTouchPoint(0, 1);
- uint32 touch_press_event_id1 = SendTouchEvent();
+ uint32_t touch_press_event_id1 = SendTouchEvent();
SendTouchEventACK(WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED, touch_press_event_id1);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
MoveTouchPoint(0, 20, 5);
- uint32 touch_move_event_id1 = SendTouchEvent();
+ uint32_t touch_move_event_id1 = SendTouchEvent();
SendTouchEventACK(WebInputEvent::TouchMove,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED, touch_move_event_id1);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
@@ -3087,8 +3111,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
SimulateGestureEvent(blink::WebInputEvent::GestureScrollEnd,
blink::WebGestureDeviceTouchscreen);
base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(10));
base::MessageLoop::current()->Run();
EXPECT_EQ(1U, sink_->message_count());
@@ -3134,8 +3157,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
blink::WebGestureDeviceTouchscreen);
EXPECT_EQ(0U, sink_->message_count());
base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(10));
base::MessageLoop::current()->Run();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -3170,8 +3192,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
blink::WebGestureDeviceTouchscreen);
EXPECT_EQ(0U, sink_->message_count());
base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(10));
base::MessageLoop::current()->Run();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -3471,7 +3492,7 @@ TEST_F(RenderWidgetHostViewAuraTest, KeyEvent) {
view_->InitAsChild(NULL);
view_->Show();
- ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::KEY_A,
+ ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A,
ui::EF_NONE);
view_->OnKeyEvent(&key_event);
@@ -3526,7 +3547,7 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
// Simulates the scroll event with ctrl modifier applied.
ui::ScrollEvent scroll(ui::ET_SCROLL, gfx::Point(2, 2), ui::EventTimeForNow(),
- ui::EF_CONTROL_DOWN, 0, 5, 0, 5, 2);
+ ui::EF_CONTROL_DOWN, 0, 5, 0, 5, 2);
view_->OnScrollEvent(&scroll);
input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
@@ -3543,15 +3564,15 @@ TEST_F(RenderWidgetHostViewAuraTest, CorrectNumberOfAcksAreDispatched) {
view_->Show();
view_->UseFakeDispatcher();
- ui::TouchEvent press1(
- ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0, ui::EventTimeForNow());
+ ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0,
+ ui::EventTimeForNow());
view_->OnTouchEvent(&press1);
SendTouchEventACK(blink::WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_CONSUMED, press1.unique_event_id());
- ui::TouchEvent press2(
- ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1, ui::EventTimeForNow());
+ ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), 1,
+ ui::EventTimeForNow());
view_->OnTouchEvent(&press2);
SendTouchEventACK(blink::WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_CONSUMED, press2.unique_event_id());
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
index 1b407058f52..a2a0884d005 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "base/logging.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
@@ -568,7 +569,7 @@ void RenderWidgetHostViewBase::EndFrameSubscription() {
NOTREACHED();
}
-uint32 RenderWidgetHostViewBase::RendererFrameNumber() {
+uint32_t RenderWidgetHostViewBase::RendererFrameNumber() {
return renderer_frame_number_;
}
@@ -681,4 +682,17 @@ uint32_t RenderWidgetHostViewBase::SurfaceIdNamespaceAtPoint(
return 0;
}
+void RenderWidgetHostViewBase::TransformPointToRootCoordSpace(
+ const gfx::Point& point,
+ gfx::Point* transformed_point) {
+ *transformed_point = point;
+}
+
+void RenderWidgetHostViewBase::TransformPointToLocalCoordSpace(
+ const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point) {
+ *transformed_point = point;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.h b/chromium/content/browser/renderer_host/render_widget_host_view_base.h
index 2fbfb1ef244..d714137a2d6 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.h
@@ -5,13 +5,18 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_BASE_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_BASE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/kill.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "cc/output/compositor_frame.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
@@ -46,6 +51,10 @@ class WebMouseEvent;
class WebMouseWheelEvent;
}
+namespace ui {
+class LatencyInfo;
+}
+
namespace content {
class BrowserAccessibilityDelegate;
class BrowserAccessibilityManager;
@@ -88,7 +97,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// Return a value that is incremented each time the renderer swaps a new frame
// to the view.
- uint32 RendererFrameNumber();
+ uint32_t RendererFrameNumber();
// Called each time the RenderWidgetHost receives a new frame for display from
// the renderer.
@@ -158,7 +167,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// Informs that the focused DOM node has changed.
virtual void FocusedNodeChanged(bool is_editable_node) {}
- virtual void OnSwapCompositorFrame(uint32 output_surface_id,
+ virtual void OnSwapCompositorFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) {}
// This method exists to allow removing of displayed graphics, after a new
@@ -192,6 +201,28 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
virtual void ProcessKeyboardEvent(const NativeWebKeyboardEvent& event) {}
virtual void ProcessMouseEvent(const blink::WebMouseEvent& event) {}
virtual void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event) {}
+ virtual void ProcessTouchEvent(const blink::WebTouchEvent& event,
+ const ui::LatencyInfo& latency) {}
+
+ // If a RenderWidgetHost is dealing with points that are transformed from the
+ // root frame for a page (i.e. because its content is contained within
+ // that of another RenderWidgetHost), this provides a facility to convert
+ // a point from its own coordinate space to that of the root frame.
+ // This only needs to be overriden by RenderWidgetHostView subclasses
+ // that handle content embedded within other RenderWidgetHostViews.
+ virtual void TransformPointToRootCoordSpace(const gfx::Point& point,
+ gfx::Point* transformed_point);
+
+ // Transform a point that is in the coordinate space of a Surface that is
+ // embedded within the RenderWidgetHostViewBase's Surface to the
+ // coordinate space of the embedding Surface. Typically this means that a
+ // point was received from an out-of-process iframe's RenderWidget and needs
+ // to be translated to viewport coordinates for the root RWHV, in which case
+ // this method is called on the root RWHV with the out-of-process iframe's
+ // SurfaceId.
+ virtual void TransformPointToLocalCoordSpace(const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point);
//----------------------------------------------------------------------------
// The following static methods are implemented by each platform.
@@ -234,13 +265,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
virtual void RenderProcessGone(base::TerminationStatus status,
int error_code) = 0;
- // Notifies the View that the renderer's host has ceased to exist.
- // The default implementation of this is a no-op. This hack exists to fix
- // a crash on the branch.
- // TODO(ccameron): Clean this up.
- // http://crbug.com/404828
- virtual void RenderWidgetHostGone() {}
-
// Tells the View to destroy itself.
virtual void Destroy() = 0;
@@ -282,7 +306,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
virtual void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) = 0;
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) = 0;
// Returns true if CopyFromCompositingSurfaceToVideoFrame() is likely to
// succeed.
@@ -326,11 +350,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// main frame.
virtual void OnDidNavigateMainFrameToNewPage();
-#if defined(OS_ANDROID)
// Instructs the view to not drop the surface even when the view is hidden.
virtual void LockCompositingSurface() = 0;
virtual void UnlockCompositingSurface() = 0;
-#endif
#if defined(OS_MACOSX)
// Does any event handling necessary for plugin IME; should be called after
@@ -421,7 +443,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
gfx::Rect current_display_area_;
- uint32 renderer_frame_number_;
+ uint32_t renderer_frame_number_;
base::OneShotTimer flush_input_timer_;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 3e16918b4cb..d7f79a0b573 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -2,13 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <utility>
+
#include "base/barrier_closure.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/dip_util.h"
@@ -26,7 +31,7 @@
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "media/base/video_frame.h"
-#include "media/blink/skcanvas_video_renderer.h"
+#include "media/renderers/skcanvas_video_renderer.h"
#include "net/base/filename_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
@@ -104,7 +109,7 @@ class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
return static_cast<RenderWidgetHostViewBase*>(
- GetRenderViewHost()->GetView());
+ GetRenderViewHost()->GetWidget()->GetView());
}
// Callback when using CopyFromBackingStore() API.
@@ -122,6 +127,7 @@ class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
// Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
void FinishCopyFromCompositingSurface(const base::Closure& quit_closure,
+ const gfx::Rect& region_in_frame,
bool frame_captured) {
++callback_invoke_count_;
if (frame_captured)
@@ -135,6 +141,7 @@ class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
base::Closure quit_closure,
base::TimeTicks timestamp,
+ const gfx::Rect& region_in_frame,
bool frame_captured) {
++callback_invoke_count_;
if (frame_captured)
@@ -154,13 +161,11 @@ class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
while (true) {
++count_attempts;
base::RunLoop run_loop;
- GetRenderViewHost()->CopyFromBackingStore(
- gfx::Rect(),
- frame_size(),
+ GetRenderViewHost()->GetWidget()->CopyFromBackingStore(
+ gfx::Rect(), frame_size(),
base::Bind(
&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
- base::Unretained(this),
- run_loop.QuitClosure()),
+ base::Unretained(this), run_loop.QuitClosure()),
kN32_SkColorType);
run_loop.Run();
@@ -289,12 +294,10 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
SET_UP_SURFACE_OR_PASS_TEST(NULL);
base::RunLoop run_loop;
- GetRenderViewHost()->CopyFromBackingStore(
- gfx::Rect(),
- frame_size(),
+ GetRenderViewHost()->GetWidget()->CopyFromBackingStore(
+ gfx::Rect(), frame_size(),
base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
- base::Unretained(this),
- run_loop.QuitClosure()),
+ base::Unretained(this), run_loop.QuitClosure()),
kN32_SkColorType);
run_loop.Run();
@@ -329,8 +332,14 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
// Test basic frame subscription functionality. We subscribe, and then run
// until at least one DeliverFrameCallback has been invoked.
+// https://crbug.com/542896
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_FrameSubscriberTest DISABLED_FrameSubscriberTest
+#else
+#define MAYBE_FrameSubscriberTest FrameSubscriberTest
+#endif
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
- FrameSubscriberTest) {
+ MAYBE_FrameSubscriberTest) {
SET_UP_SURFACE_OR_PASS_TEST(NULL);
RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
@@ -340,7 +349,7 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
&RenderWidgetHostViewBrowserTest::FrameDelivered,
base::Unretained(this), base::ThreadTaskRunnerHandle::Get(),
run_loop.QuitClosure())));
- view->BeginFrameSubscription(subscriber.Pass());
+ view->BeginFrameSubscription(std::move(subscriber));
run_loop.Run();
view->EndFrameSubscription();
@@ -491,6 +500,7 @@ class CompositingRenderWidgetHostViewBrowserTestTabCapture
void ReadbackRequestCallbackForVideo(
scoped_refptr<media::VideoFrame> video_frame,
base::Closure quit_callback,
+ const gfx::Rect& region_in_frame,
bool result) {
if (!result) {
readback_response_ = READBACK_TO_VIDEO_FRAME_FAILED;
@@ -579,7 +589,7 @@ class CompositingRenderWidgetHostViewBrowserTestTabCapture
// is allowed to transiently fail. The purpose of these tests is to
// confirm correct cropping/scaling behavior; and not that every
// readback must succeed. http://crbug.com/444237
- uint32 last_frame_number = 0;
+ uint32_t last_frame_number = 0;
do {
// Wait for renderer to provide the next frame.
while (!GetRenderWidgetHost()->ScheduleComposite())
@@ -605,11 +615,10 @@ class CompositingRenderWidgetHostViewBrowserTestTabCapture
output_size, gfx::Rect(output_size),
output_size, base::TimeDelta());
- base::Callback<void(bool success)> callback =
+ base::Callback<void(const gfx::Rect& rect, bool success)> callback =
base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
ReadbackRequestCallbackForVideo,
- base::Unretained(this),
- video_frame,
+ base::Unretained(this), video_frame,
run_loop.QuitClosure());
rwhv->CopyFromCompositingSurfaceToVideoFrame(
copy_rect, video_frame, callback);
@@ -698,8 +707,16 @@ class CompositingRenderWidgetHostViewBrowserTestTabCapture
std::string test_url_;
};
+// https://crbug.com/542896
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_CopyFromCompositingSurface_Origin_Unscaled \
+ DISABLED_CopyFromCompositingSurface_Origin_Unscaled
+#else
+#define MAYBE_CopyFromCompositingSurface_Origin_Unscaled \
+ CopyFromCompositingSurface_Origin_Unscaled
+#endif
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
- CopyFromCompositingSurface_Origin_Unscaled) {
+ MAYBE_CopyFromCompositingSurface_Origin_Unscaled) {
gfx::Rect copy_rect(400, 300);
gfx::Size output_size = copy_rect.size();
gfx::Size html_rect_size(400, 300);
@@ -710,8 +727,16 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
video_frame);
}
+// https://crbug.com/542896
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_CopyFromCompositingSurface_Origin_Scaled \
+ DISABLED_FrameSubscriberTestCopyFromCompositingSurface_Origin_Scaled
+#else
+#define MAYBE_CopyFromCompositingSurface_Origin_Scaled \
+ CopyFromCompositingSurface_Origin_Scaled
+#endif
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
- CopyFromCompositingSurface_Origin_Scaled) {
+ MAYBE_CopyFromCompositingSurface_Origin_Scaled) {
gfx::Rect copy_rect(400, 300);
gfx::Size output_size(200, 100);
gfx::Size html_rect_size(400, 300);
@@ -722,8 +747,16 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
video_frame);
}
+// https://crbug.com/542896
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_CopyFromCompositingSurface_Cropped_Unscaled \
+ DISABLED_CopyFromCompositingSurface_Cropped_Unscaled
+#else
+#define MAYBE_CopyFromCompositingSurface_Cropped_Unscaled \
+ CopyFromCompositingSurface_Cropped_Unscaled
+#endif
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
- CopyFromCompositingSurface_Cropped_Unscaled) {
+ MAYBE_CopyFromCompositingSurface_Cropped_Unscaled) {
// Grab 60x60 pixels from the center of the tab contents.
gfx::Rect copy_rect(400, 300);
copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
@@ -737,8 +770,16 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
video_frame);
}
+// https://crbug.com/542896
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_CopyFromCompositingSurface_Cropped_Scaled \
+ DISABLED_CopyFromCompositingSurface_Cropped_Scaled
+#else
+#define MAYBE_CopyFromCompositingSurface_Cropped_Scaled \
+ CopyFromCompositingSurface_Cropped_Scaled
+#endif
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
- CopyFromCompositingSurface_Cropped_Scaled) {
+ MAYBE_CopyFromCompositingSurface_Cropped_Scaled) {
// Grab 60x60 pixels from the center of the tab contents.
gfx::Rect copy_rect(400, 300);
copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
@@ -752,8 +793,16 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
video_frame);
}
+// https://crbug.com/542896
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_CopyFromCompositingSurface_ForVideoFrame \
+ DISABLED_CopyFromCompositingSurface_ForVideoFrame
+#else
+#define MAYBE_CopyFromCompositingSurface_ForVideoFrame \
+ CopyFromCompositingSurface_ForVideoFrame
+#endif
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
- CopyFromCompositingSurface_ForVideoFrame) {
+ MAYBE_CopyFromCompositingSurface_ForVideoFrame) {
// Grab 90x60 pixels from the center of the tab contents.
gfx::Rect copy_rect(400, 300);
copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
@@ -767,8 +816,16 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
video_frame);
}
+// https://crbug.com/542896
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_CopyFromCompositingSurface_ForVideoFrame_Scaled \
+ DISABLED_CopyFromCompositingSurface_ForVideoFrame_Scaled
+#else
+#define MAYBE_CopyFromCompositingSurface_ForVideoFrame_Scaled \
+ CopyFromCompositingSurface_ForVideoFrame_Scaled
+#endif
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
- CopyFromCompositingSurface_ForVideoFrame_Scaled) {
+ MAYBE_CopyFromCompositingSurface_ForVideoFrame_Scaled) {
// Grab 90x60 pixels from the center of the tab contents.
gfx::Rect copy_rect(400, 300);
copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
@@ -819,7 +876,8 @@ class CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI
// NineImagePainter implementation crashes the process on Windows when this
// content_browsertest forces a device scale factor. http://crbug.com/399349
-#if defined(OS_WIN)
+// Disabled under MSAN. http://crbug.com/542896
+#if defined(OS_WIN) || defined(MEMORY_SANITIZER)
#define MAYBE_CopyToBitmap_EntireRegion DISABLED_CopyToBitmap_EntireRegion
#define MAYBE_CopyToBitmap_CenterRegion DISABLED_CopyToBitmap_CenterRegion
#define MAYBE_CopyToBitmap_ScaledResult DISABLED_CopyToBitmap_ScaledResult
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac.h b/chromium/content/browser/renderer_host/render_widget_host_view_mac.h
index 13b1939052f..459f16a15bc 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -7,6 +7,8 @@
#import <Cocoa/Cocoa.h>
#include <IOSurface/IOSurface.h>
+#include <stddef.h>
+#include <stdint.h>
#include <list>
#include <map>
#include <set>
@@ -15,6 +17,7 @@
#include <vector>
#include "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
@@ -29,7 +32,6 @@
#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/accelerated_widget_mac/display_link_mac.h"
-#include "ui/accelerated_widget_mac/io_surface_layer.h"
#import "ui/base/cocoa/command_dispatcher.h"
#include "ui/base/cocoa/remote_layer_api.h"
#import "ui/base/cocoa/tool_tip_base_view.h"
@@ -208,8 +210,10 @@ class Layer;
- (void)updateCursor:(NSCursor*)cursor;
- (NSRect)firstViewRectForCharacterRange:(NSRange)theRange
actualRange:(NSRangePointer)actualRange;
+- (void)quickLookWithEvent:(NSEvent*)event;
- (void)showLookUpDictionaryOverlayAtPoint:(NSPoint)point;
-- (void)showLookUpDictionaryOverlayFromRange:(NSRange)range;
+- (void)showLookUpDictionaryOverlayFromRange:(NSRange)range
+ targetView:(NSView*)targetView;
@end
namespace content {
@@ -302,7 +306,6 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
const std::vector<gfx::Rect>& character_bounds) override;
void RenderProcessGone(base::TerminationStatus status,
int error_code) override;
- void RenderWidgetHostGone() override;
void Destroy() override;
void SetTooltipText(const base::string16& tooltip_text) override;
void SelectionChanged(const base::string16& text,
@@ -317,12 +320,12 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) override;
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
bool CanCopyToVideoFrame() const override;
void BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override;
void EndFrameSubscription() override;
- void OnSwapCompositorFrame(uint32 output_surface_id,
+ void OnSwapCompositorFrame(uint32_t output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) override;
void ClearCompositorFrame() override;
BrowserAccessibilityManager* CreateBrowserAccessibilityManager(
@@ -335,6 +338,8 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void GetScreenInfo(blink::WebScreenInfo* results) override;
bool GetScreenColorProfile(std::vector<char>* color_profile) override;
gfx::Rect GetBoundsInRootWindow() override;
+ void LockCompositingSurface() override;
+ void UnlockCompositingSurface() override;
bool LockMouse() override;
void UnlockMouse() override;
@@ -346,8 +351,13 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
uint32_t GetSurfaceIdNamespace() override;
uint32_t SurfaceIdNamespaceAtPoint(const gfx::Point& point,
gfx::Point* transformed_point) override;
+ // Returns true when we can do SurfaceHitTesting for the event type.
+ bool ShouldRouteEvent(const blink::WebInputEvent& event) const;
void ProcessMouseEvent(const blink::WebMouseEvent& event) override;
void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
+ void TransformPointToLocalCoordSpace(const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point) override;
// IPC::Sender implementation.
bool Send(IPC::Message* message) override;
@@ -507,12 +517,9 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// AcceleratedWidgetMacNSView implementation.
NSView* AcceleratedWidgetGetNSView() const override;
- bool AcceleratedWidgetShouldIgnoreBackpressure() const override;
void AcceleratedWidgetGetVSyncParameters(
base::TimeTicks* timebase, base::TimeDelta* interval) const override;
- void AcceleratedWidgetSwapCompleted(
- const std::vector<ui::LatencyInfo>& latency_info) override;
- void AcceleratedWidgetHitError() override;
+ void AcceleratedWidgetSwapCompleted() override;
// Transition from being in the Suspended state to being in the Destroyed
// state, if appropriate (see BrowserCompositorViewState for details).
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm
index 8db1f59b57e..ef38d30fe02 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -7,8 +7,11 @@
#import <objc/runtime.h>
#include <OpenGL/gl.h>
#include <QuartzCore/QuartzCore.h>
+#include <stdint.h>
+
+#include <limits>
+#include <utility>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
@@ -51,14 +54,13 @@
#include "content/common/edit_command.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/input_messages.h"
+#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
#include "content/common/webplugin_geometry.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/native_web_keyboard_event.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#import "content/public/browser/render_widget_host_view_mac_delegate.h"
#include "content/public/browser/web_contents.h"
@@ -67,8 +69,6 @@
#include "third_party/WebKit/public/platform/WebScreenInfo.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#import "third_party/mozilla/ComplexTextInputPanel.h"
-#include "ui/accelerated_widget_mac/io_surface_layer.h"
-#include "ui/accelerated_widget_mac/surface_handle_types.h"
#include "ui/base/cocoa/animation_utils.h"
#import "ui/base/cocoa/fullscreen_window_manager.h"
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
@@ -183,7 +183,8 @@ static BOOL SupportsBackingPropertiesChangedNotification() {
- (void)setResponderDelegate:
(NSObject<RenderWidgetHostViewMacDelegate>*)delegate;
- (void)showLookUpDictionaryOverlayInternal:(NSAttributedString*) string
- baselinePoint:(NSPoint) baselinePoint;
+ baselinePoint:(NSPoint) baselinePoint
+ targetView:(NSView*) view;
@end
// A window subclass that allows the fullscreen window to become main and gain
@@ -354,7 +355,7 @@ float FlipYFromRectToScreen(float y, float rect_height) {
if (!g_screen_info_up_to_date) {
if ([[NSScreen screens] count] > 0) {
screen_zero_height =
- [[[NSScreen screens] objectAtIndex:0] frame].size.height;
+ [[[NSScreen screens] firstObject] frame].size.height;
g_screen_info_up_to_date = true;
} else {
return y;
@@ -481,48 +482,6 @@ NSView* RenderWidgetHostViewMac::AcceleratedWidgetGetNSView() const {
return cocoa_view_;
}
-bool RenderWidgetHostViewMac::AcceleratedWidgetShouldIgnoreBackpressure()
- const {
- // If vsync is disabled, then always draw and ack frames immediately.
- static bool is_vsync_disabled =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuVsync);
- if (is_vsync_disabled)
- return true;
-
- // If the window is occluded, then this frame's display call may be severely
- // throttled. This is a good thing, unless tab capture may be active, because
- // the broadcast will be inappropriately throttled.
- // http://crbug.com/350410
-
- // If tab capture isn't active then only ack frames when we draw them.
- if (delegated_frame_host_ && !delegated_frame_host_->HasFrameSubscriber())
- return false;
-
- NSWindow* window = [cocoa_view_ window];
- // If the view isn't even in the heirarchy then frames will never be drawn,
- // so ack them immediately.
- if (!window)
- return true;
-
- // Check the window occlusion API.
- if ([window respondsToSelector:@selector(occlusionState)]) {
- if ([window occlusionState] & NSWindowOcclusionStateVisible) {
- // If the window is visible then it is safe to wait until frames are
- // drawn to ack them.
- return false;
- } else {
- // If the window is occluded then frames may never be drawn, so ack them
- // immediately.
- return true;
- }
- }
-
- // If the window occlusion API is not present then ack frames when we draw
- // them.
- return false;
-}
-
void RenderWidgetHostViewMac::AcceleratedWidgetGetVSyncParameters(
base::TimeTicks* timebase, base::TimeDelta* interval) const {
if (display_link_ &&
@@ -532,28 +491,9 @@ void RenderWidgetHostViewMac::AcceleratedWidgetGetVSyncParameters(
*interval = base::TimeDelta();
}
-void RenderWidgetHostViewMac::AcceleratedWidgetSwapCompleted(
- const std::vector<ui::LatencyInfo>& all_latency_info) {
- if (!render_widget_host_)
- return;
- base::TimeTicks swap_time = base::TimeTicks::Now();
-
- for (auto latency_info : all_latency_info) {
- latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1);
- latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0,
- swap_time, 1);
- render_widget_host_->FrameSwapped(latency_info);
- }
-
+void RenderWidgetHostViewMac::AcceleratedWidgetSwapCompleted() {
if (display_link_)
- display_link_->NotifyCurrentTime(swap_time);
-}
-
-void RenderWidgetHostViewMac::AcceleratedWidgetHitError() {
- // Request a new frame be drawn.
- browser_compositor_->compositor()->ScheduleFullRedraw();
+ display_link_->NotifyCurrentTime(base::TimeTicks::Now());
}
///////////////////////////////////////////////////////////////////////////////
@@ -717,7 +657,7 @@ void RenderWidgetHostViewMac::DestroyBrowserCompositorView() {
browser_compositor_->accelerated_widget_mac()->ResetNSView();
browser_compositor_->compositor()->SetScaleAndSize(1.0, gfx::Size(0, 0));
browser_compositor_->compositor()->SetRootLayer(nullptr);
- BrowserCompositorMac::Recycle(browser_compositor_.Pass());
+ BrowserCompositorMac::Recycle(std::move(browser_compositor_));
browser_compositor_state_ = BrowserCompositorDestroyed;
}
}
@@ -1116,23 +1056,6 @@ void RenderWidgetHostViewMac::RenderProcessGone(base::TerminationStatus status,
Destroy();
}
-void RenderWidgetHostViewMac::RenderWidgetHostGone() {
- // Clear SurfaceID namespace ownership before we shutdown the
- // compositor.
- if (UseSurfacesEnabled() && render_widget_host_ &&
- render_widget_host_->delegate() &&
- render_widget_host_->delegate()->GetInputEventRouter()) {
- render_widget_host_->delegate()
- ->GetInputEventRouter()
- ->RemoveSurfaceIdNamespaceOwner(GetSurfaceIdNamespace());
- }
-
- // Destroy the DelegatedFrameHost, to prevent crashes when Destroy is never
- // called on the view.
- // http://crbug.com/404828
- ShutdownBrowserCompositor();
-}
-
void RenderWidgetHostViewMac::Destroy() {
[[NSNotificationCenter defaultCenter]
removeObserver:cocoa_view_
@@ -1311,9 +1234,9 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurface(
}
void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame(
- const gfx::Rect& src_subrect,
- const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) {
+ const gfx::Rect& src_subrect,
+ const scoped_refptr<media::VideoFrame>& target,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) {
DCHECK(delegated_frame_host_);
delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame(
src_subrect, target, callback);
@@ -1327,7 +1250,7 @@ bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const {
void RenderWidgetHostViewMac::BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
DCHECK(delegated_frame_host_);
- delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
+ delegated_frame_host_->BeginFrameSubscription(std::move(subscriber));
}
void RenderWidgetHostViewMac::EndFrameSubscription() {
@@ -1391,7 +1314,7 @@ bool RenderWidgetHostViewMac::GetLineBreakIndex(
// TODO(nona): Bidi support.
const size_t loop_end_idx = std::min(bounds.size(), range.end());
int max_height = 0;
- int min_y_offset = kint32max;
+ int min_y_offset = std::numeric_limits<int32_t>::max();
for (size_t idx = range.start(); idx < loop_end_idx; ++idx) {
max_height = std::max(max_height, bounds[idx].height());
min_y_offset = std::min(min_y_offset, bounds[idx].y());
@@ -1461,9 +1384,6 @@ gfx::Range RenderWidgetHostViewMac::ConvertCharacterRangeToCompositionRange(
}
WebContents* RenderWidgetHostViewMac::GetWebContents() {
- if (!render_widget_host_->IsRenderView())
- return NULL;
-
return WebContents::FromRenderViewHost(
RenderViewHost::From(render_widget_host_));
}
@@ -1528,7 +1448,8 @@ bool RenderWidgetHostViewMac::HasAcceleratedSurface(
}
void RenderWidgetHostViewMac::OnSwapCompositorFrame(
- uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) {
+ uint32_t output_surface_id,
+ scoped_ptr<cc::CompositorFrame> frame) {
TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame");
last_scroll_offset_ = frame->metadata.root_scroll_offset;
@@ -1541,7 +1462,7 @@ void RenderWidgetHostViewMac::OnSwapCompositorFrame(
// Compute the frame size based on the root render pass rect size.
cc::RenderPass* root_pass =
- frame->delegated_frame_data->render_pass_list.back();
+ frame->delegated_frame_data->render_pass_list.back().get();
gfx::Size pixel_size = root_pass->output_rect.size();
gfx::Size dip_size = gfx::ConvertSizeToDIP(scale_factor, pixel_size);
@@ -1554,12 +1475,8 @@ void RenderWidgetHostViewMac::OnSwapCompositorFrame(
SendVSyncParametersToRenderer();
- delegated_frame_host_->SwapDelegatedFrame(
- output_surface_id,
- frame->delegated_frame_data.Pass(),
- frame->metadata.device_scale_factor,
- frame->metadata.latency_info,
- &frame->metadata.satisfies_sequences);
+ delegated_frame_host_->SwapDelegatedFrame(output_surface_id,
+ std::move(frame));
} else {
DLOG(ERROR) << "Received unexpected frame type.";
bad_message::ReceivedBadMessage(render_widget_host_->GetProcess(),
@@ -1594,6 +1511,14 @@ gfx::Rect RenderWidgetHostViewMac::GetBoundsInRootWindow() {
return FlipNSRectToRectScreen(bounds);
}
+void RenderWidgetHostViewMac::LockCompositingSurface() {
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewMac::UnlockCompositingSurface() {
+ NOTIMPLEMENTED();
+}
+
bool RenderWidgetHostViewMac::LockMouse() {
if (mouse_locked_)
return true;
@@ -1649,8 +1574,16 @@ uint32_t RenderWidgetHostViewMac::GetSurfaceIdNamespace() {
uint32_t RenderWidgetHostViewMac::SurfaceIdNamespaceAtPoint(
const gfx::Point& point,
gfx::Point* transformed_point) {
- cc::SurfaceId id =
- delegated_frame_host_->SurfaceIdAtPoint(point, transformed_point);
+ // The surface hittest happens in device pixels, so we need to convert the
+ // |point| from DIPs to pixels before hittesting.
+ float scale_factor = gfx::Screen::GetScreenFor(cocoa_view_)
+ ->GetDisplayNearestWindow(cocoa_view_)
+ .device_scale_factor();
+ gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
+ cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint(point_in_pixels,
+ transformed_point);
+ *transformed_point = gfx::ConvertPointToDIP(scale_factor, *transformed_point);
+
// It is possible that the renderer has not yet produced a surface, in which
// case we return our current namespace.
if (id.is_null())
@@ -1658,6 +1591,18 @@ uint32_t RenderWidgetHostViewMac::SurfaceIdNamespaceAtPoint(
return cc::SurfaceIdAllocator::NamespaceForId(id);
}
+bool RenderWidgetHostViewMac::ShouldRouteEvent(
+ const WebInputEvent& event) const {
+ // See also RenderWidgetHostViewAura::ShouldRouteEvent.
+ // TODO(wjmaclean): Update this function if RenderWidgetHostViewMac implements
+ // OnTouchEvent(), to match what we are doing in RenderWidgetHostViewAura.
+ DCHECK(WebInputEvent::isMouseEventType(event.type) ||
+ event.type == WebInputEvent::MouseWheel);
+ return render_widget_host_->delegate() &&
+ render_widget_host_->delegate()->GetInputEventRouter() &&
+ SiteIsolationPolicy::AreCrossProcessFramesPossible();
+}
+
void RenderWidgetHostViewMac::ProcessMouseEvent(
const blink::WebMouseEvent& event) {
render_widget_host_->ForwardMouseEvent(event);
@@ -1667,6 +1612,14 @@ void RenderWidgetHostViewMac::ProcessMouseWheelEvent(
render_widget_host_->ForwardWheelEvent(event);
}
+void RenderWidgetHostViewMac::TransformPointToLocalCoordSpace(
+ const gfx::Point& point,
+ cc::SurfaceId original_surface,
+ gfx::Point* transformed_point) {
+ delegated_frame_host_->TransformPointToLocalCoordSpace(
+ point, original_surface, transformed_point);
+}
+
bool RenderWidgetHostViewMac::Send(IPC::Message* message) {
if (render_widget_host_)
return render_widget_host_->Send(message);
@@ -1676,7 +1629,7 @@ bool RenderWidgetHostViewMac::Send(IPC::Message* message) {
void RenderWidgetHostViewMac::ShutdownHost() {
weak_factory_.InvalidateWeakPtrs();
- render_widget_host_->Shutdown();
+ render_widget_host_->ShutdownAndDestroyWidget(true);
// Do not touch any members at this point, |this| has been deleted.
}
@@ -1794,11 +1747,7 @@ void RenderWidgetHostViewMac::PauseForPendingResizeOrRepaintsAndDraw() {
return;
// Wait for a frame of the right size to come in.
- if (browser_compositor_)
- browser_compositor_->accelerated_widget_mac()->BeginPumpingFrames();
render_widget_host_->PauseForPendingResizeOrRepaints();
- if (browser_compositor_)
- browser_compositor_->accelerated_widget_mac()->EndPumpingFrames();
}
////////////////////////////////////////////////////////////////////////////////
@@ -2000,14 +1949,12 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
WebMouseEvent enterEvent = WebMouseEventBuilder::Build(theEvent, self);
enterEvent.type = WebInputEvent::MouseMove;
enterEvent.button = WebMouseEvent::ButtonNone;
- if (renderWidgetHostView_->render_widget_host_->delegate() &&
- renderWidgetHostView_->render_widget_host_->delegate()
- ->GetInputEventRouter()) {
+ if (renderWidgetHostView_->ShouldRouteEvent(enterEvent)) {
renderWidgetHostView_->render_widget_host_->delegate()
->GetInputEventRouter()
->RouteMouseEvent(renderWidgetHostView_.get(), &enterEvent);
} else {
- renderWidgetHostView_->ForwardMouseEvent(enterEvent);
+ renderWidgetHostView_->ProcessMouseEvent(enterEvent);
}
}
}
@@ -2037,14 +1984,12 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
}
WebMouseEvent event = WebMouseEventBuilder::Build(theEvent, self);
- if (renderWidgetHostView_->render_widget_host_->delegate() &&
- renderWidgetHostView_->render_widget_host_->delegate()
- ->GetInputEventRouter()) {
+ if (renderWidgetHostView_->ShouldRouteEvent(event)) {
renderWidgetHostView_->render_widget_host_->delegate()
->GetInputEventRouter()
->RouteMouseEvent(renderWidgetHostView_.get(), &event);
} else {
- renderWidgetHostView_->ForwardMouseEvent(event);
+ renderWidgetHostView_->ProcessMouseEvent(event);
}
}
@@ -2148,10 +2093,17 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
renderWidgetHostView_->fullscreen_parent_host_view();
if (parent)
parent->cocoa_view()->suppressNextEscapeKeyUp_ = YES;
- widgetHost->Shutdown();
+ widgetHost->ShutdownAndDestroyWidget(true);
return;
}
+ // If there are multiple widgets on the page (such as when there are
+ // out-of-process iframes), pick the one that should process this event.
+ if (widgetHost->delegate())
+ widgetHost = widgetHost->delegate()->GetFocusedRenderWidgetHost(widgetHost);
+ if (!widgetHost)
+ return;
+
// Suppress the escape key up event if necessary.
if (event.windowsKeyCode == ui::VKEY_ESCAPE && suppressNextEscapeKeyUp_) {
if (event.type == NativeWebKeyboardEvent::KeyUp)
@@ -2339,7 +2291,7 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
event.skip_in_browser = true;
widgetHost->ForwardKeyboardEvent(event);
} else if ((!textInserted || delayEventUntilAfterImeCompostion) &&
- [[theEvent characters] length] > 0 &&
+ event.text[0] != '\0' &&
(([theEvent modifierFlags] & kCtrlCmdKeyMask) ||
(hasEditCommands_ && editCommands_.empty()))) {
// We don't get insertText: calls if ctrl or cmd is down, or the key event
@@ -2356,6 +2308,10 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
[NSCursor setHiddenUntilMouseMoves:YES];
}
+- (void)forceTouchEvent:(NSEvent*)theEvent {
+ [self quickLookWithEvent:theEvent];
+}
+
- (void)shortCircuitScrollWheelEvent:(NSEvent*)event {
DCHECK(base::mac::IsOSLionOrLater());
@@ -2435,7 +2391,8 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
}
- (void)showLookUpDictionaryOverlayInternal:(NSAttributedString*) string
- baselinePoint:(NSPoint) baselinePoint {
+ baselinePoint:(NSPoint) baselinePoint
+ targetView:(NSView*) view {
if ([string length] == 0) {
// The PDF plugin does not support getting the attributed string at point.
// Until it does, use NSPerformService(), which opens Dictionary.app.
@@ -2453,17 +2410,19 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
- [self showDefinitionForAttributedString:string
- atPoint:baselinePoint];
+ [view showDefinitionForAttributedString:string
+ atPoint:baselinePoint];
});
}
-- (void)showLookUpDictionaryOverlayFromRange:(NSRange)range {
+- (void)showLookUpDictionaryOverlayFromRange:(NSRange)range
+ targetView:(NSView*)targetView {
TextInputClientMac::GetInstance()->GetStringFromRange(
renderWidgetHostView_->render_widget_host_, range,
^(NSAttributedString* string, NSPoint baselinePoint) {
[self showLookUpDictionaryOverlayInternal:string
- baselinePoint:baselinePoint];
+ baselinePoint:baselinePoint
+ targetView:targetView];
}
);
}
@@ -2474,7 +2433,8 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
gfx::Point(point.x, NSHeight([self frame]) - point.y),
^(NSAttributedString* string, NSPoint baselinePoint) {
[self showLookUpDictionaryOverlayInternal:string
- baselinePoint:baselinePoint];
+ baselinePoint:baselinePoint
+ targetView:self];
}
);
}
@@ -2537,14 +2497,12 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build(
event, self, canRubberbandLeft, canRubberbandRight);
webEvent.railsMode = mouseWheelFilter_.UpdateRailsMode(webEvent);
- if (renderWidgetHostView_->render_widget_host_->delegate() &&
- renderWidgetHostView_->render_widget_host_->delegate()
- ->GetInputEventRouter()) {
+ if (renderWidgetHostView_->ShouldRouteEvent(webEvent)) {
renderWidgetHostView_->render_widget_host_->delegate()
->GetInputEventRouter()
->RouteMouseWheelEvent(renderWidgetHostView_.get(), &webEvent);
} else {
- renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(webEvent);
+ renderWidgetHostView_->ProcessMouseWheelEvent(webEvent);
}
}
}
@@ -2745,15 +2703,15 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
}
SEL action = [item action];
+ BOOL is_render_view =
+ RenderViewHost::From(renderWidgetHostView_->render_widget_host_) !=
+ nullptr;
- if (action == @selector(stopSpeaking:)) {
- return renderWidgetHostView_->render_widget_host_->IsRenderView() &&
- renderWidgetHostView_->IsSpeaking();
- }
- if (action == @selector(startSpeaking:)) {
- return renderWidgetHostView_->render_widget_host_->IsRenderView() &&
- renderWidgetHostView_->SupportsSpeech();
- }
+ if (action == @selector(stopSpeaking:))
+ return is_render_view && renderWidgetHostView_->IsSpeaking();
+
+ if (action == @selector(startSpeaking:))
+ return is_render_view && renderWidgetHostView_->SupportsSpeech();
// For now, these actions are always enabled for render view,
// this is sub-optimal.
@@ -2765,7 +2723,7 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
action == @selector(copyToFindPboard:) ||
action == @selector(paste:) ||
action == @selector(pasteAndMatchStyle:)) {
- return renderWidgetHostView_->render_widget_host_->IsRenderView();
+ return is_render_view;
}
return editCommand_helper_->IsMenuItemEnabled(action, self);
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h b/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h
index 4a94d9feb22..71deadbfcb5 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_DICTIONARY_HELPER_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_DICTIONARY_HELPER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "ui/gfx/geometry/vector2d.h"
namespace content {
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm
index e0041777fef..4e5849d3661 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm
@@ -22,7 +22,9 @@ void RenderWidgetHostViewMacDictionaryHelper::SetTargetView(
void RenderWidgetHostViewMacDictionaryHelper::ShowDefinitionForSelection() {
NSRange selection_range = [view_->cocoa_view() selectedRange];
- [view_->cocoa_view() showLookUpDictionaryOverlayFromRange:selection_range];
+ NSView* view = target_view_->cocoa_view();
+ [view_->cocoa_view() showLookUpDictionaryOverlayFromRange:selection_range
+ targetView:view];
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h
index 9ba16b32162..9cdb0aa8e3d 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h
@@ -7,9 +7,9 @@
#import <Cocoa/Cocoa.h>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
namespace content {
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
index 14ee158199f..25dbcfeedce 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
@@ -5,7 +5,9 @@
#import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h"
#import <objc/runtime.h>
+#include <stddef.h>
+#include "base/macros.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#import "content/browser/renderer_host/render_widget_host_view_mac.h"
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
index a6af135f76b..dfa92c11250 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -5,6 +5,8 @@
#import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h"
#import <Cocoa/Cocoa.h>
+#include <stddef.h>
+#include <stdint.h>
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/message_loop/message_loop.h"
@@ -86,7 +88,7 @@ class RenderWidgetHostEditCommandCounter : public RenderWidgetHostImpl {
public:
RenderWidgetHostEditCommandCounter(RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
- int32 routing_id)
+ int32_t routing_id)
: RenderWidgetHostImpl(delegate, process, routing_id, false),
edit_command_message_count_(0) {}
@@ -124,7 +126,7 @@ TEST_F(RenderWidgetHostViewMacEditCommandHelperTest,
supported_factors.push_back(ui::SCALE_FACTOR_100P);
ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
- int32 routing_id = process_host.GetNextRoutingID();
+ int32_t routing_id = process_host.GetNextRoutingID();
RenderWidgetHostEditCommandCounter* render_widget =
new RenderWidgetHostEditCommandCounter(&delegate, &process_host,
routing_id);
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index 4a7dad6fcd2..ac3cb9467f2 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -5,10 +5,13 @@
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
#include <Cocoa/Cocoa.h>
+#include <stddef.h>
+#include <stdint.h>
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/mac/sdk_forward_declarations.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/compositor/test/no_transport_image_transport_factory.h"
@@ -93,6 +96,22 @@ namespace content {
namespace {
+std::string GetInputMessageTypes(MockRenderProcessHost* process) {
+ std::string result;
+ for (size_t i = 0; i < process->sink().message_count(); ++i) {
+ const IPC::Message* message = process->sink().GetMessageAt(i);
+ EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
+ InputMsg_HandleInputEvent::Param params;
+ EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
+ const blink::WebInputEvent* event = base::get<0>(params);
+ if (i != 0)
+ result += " ";
+ result += WebInputEventTraits::GetName(event->type);
+ }
+ process->sink().ClearMessages();
+ return result;
+}
+
id MockGestureEvent(NSEventType type, double magnification) {
id event = [OCMockObject mockForClass:[NSEvent class]];
NSPoint locationInWindow = NSMakePoint(0, 0);
@@ -130,7 +149,7 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
public:
MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
- int32 routing_id)
+ int32_t routing_id)
: RenderWidgetHostImpl(delegate, process, routing_id, false) {}
MOCK_METHOD0(Focus, void());
@@ -206,10 +225,10 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
// TestRenderViewHost's destruction assumes that its view is a
// TestRenderWidgetHostView, so store its view and reset it back to the
// stored view in |TearDown()|.
- old_rwhv_ = rvh()->GetView();
+ old_rwhv_ = rvh()->GetWidget()->GetView();
// Owned by its |cocoa_view()|, i.e. |rwhv_cocoa_|.
- rwhv_mac_ = new RenderWidgetHostViewMac(rvh(), false);
+ rwhv_mac_ = new RenderWidgetHostViewMac(rvh()->GetWidget(), false);
rwhv_cocoa_.reset([rwhv_mac_->cocoa_view() retain]);
}
void TearDown() override {
@@ -218,7 +237,8 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
RecycleAndWait();
// See comment in SetUp().
- test_rvh()->SetView(static_cast<RenderWidgetHostViewBase*>(old_rwhv_));
+ test_rvh()->GetWidget()->SetView(
+ static_cast<RenderWidgetHostViewBase*>(old_rwhv_));
ImageTransportFactory::Terminate();
RenderViewHostImplTestHarness::TearDown();
@@ -231,7 +251,7 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
}
void DestroyHostViewRetainCocoaView() {
- test_rvh()->SetView(nullptr);
+ test_rvh()->GetWidget()->SetView(nullptr);
rwhv_mac_->Destroy();
}
@@ -275,7 +295,7 @@ TEST_F(RenderWidgetHostViewMacTest, FullscreenCloseOnEscape) {
TestBrowserContext browser_context;
MockRenderProcessHost* process_host =
new MockRenderProcessHost(&browser_context);
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
// Owned by its |cocoa_view()|.
RenderWidgetHostImpl* rwh =
new RenderWidgetHostImpl(&delegate, process_host, routing_id, false);
@@ -309,7 +329,7 @@ TEST_F(RenderWidgetHostViewMacTest, AcceleratorDestroy) {
TestBrowserContext browser_context;
MockRenderProcessHost* process_host =
new MockRenderProcessHost(&browser_context);
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
// Owned by its |cocoa_view()|.
RenderWidgetHostImpl* rwh =
new RenderWidgetHostImpl(&delegate, process_host, routing_id, false);
@@ -330,6 +350,52 @@ TEST_F(RenderWidgetHostViewMacTest, AcceleratorDestroy) {
observer.Wait();
}
+// Test that NSEvent of private use character won't generate keypress event
+// http://crbug.com/459089
+TEST_F(RenderWidgetHostViewMacTest, FilterNonPrintableCharacter) {
+ TestBrowserContext browser_context;
+ MockRenderProcessHost* process_host =
+ new MockRenderProcessHost(&browser_context);
+ process_host->Init();
+ MockRenderWidgetHostDelegate delegate;
+ int32_t routing_id = process_host->GetNextRoutingID();
+ MockRenderWidgetHostImpl* host =
+ new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+ RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
+
+ // Simulate ctrl+F12, will produce a private use character but shouldn't
+ // fire keypress event
+ process_host->sink().ClearMessages();
+ EXPECT_EQ(0U, process_host->sink().message_count());
+ [view->cocoa_view() keyEvent:
+ cocoa_test_event_utils::KeyEventWithKeyCode(
+ 0x7B, 0xF70F, NSKeyDown, NSControlKeyMask)];
+ EXPECT_EQ(1U, process_host->sink().message_count());
+ EXPECT_EQ("RawKeyDown", GetInputMessageTypes(process_host));
+
+ // Simulate ctrl+delete, will produce a private use character but shouldn't
+ // fire keypress event
+ process_host->sink().ClearMessages();
+ EXPECT_EQ(0U, process_host->sink().message_count());
+ [view->cocoa_view() keyEvent:
+ cocoa_test_event_utils::KeyEventWithKeyCode(
+ 0x2E, 0xF728, NSKeyDown, NSControlKeyMask)];
+ EXPECT_EQ(1U, process_host->sink().message_count());
+ EXPECT_EQ("RawKeyDown", GetInputMessageTypes(process_host));
+
+ // Simulate a printable char, should generate keypress event
+ process_host->sink().ClearMessages();
+ EXPECT_EQ(0U, process_host->sink().message_count());
+ [view->cocoa_view() keyEvent:
+ cocoa_test_event_utils::KeyEventWithKeyCode(
+ 0x58, 'x', NSKeyDown, NSControlKeyMask)];
+ EXPECT_EQ(2U, process_host->sink().message_count());
+ EXPECT_EQ("RawKeyDown Char", GetInputMessageTypes(process_host));
+
+ // Clean up.
+ host->ShutdownAndDestroyWidget(true);
+}
+
TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharacterRangeCaretCase) {
const base::string16 kDummyString = base::UTF8ToUTF16("hogehoge");
const size_t kDummyOffset = 0;
@@ -690,7 +756,7 @@ TEST_F(RenderWidgetHostViewMacTest, BlurAndFocusOnSetActive) {
new MockRenderProcessHost(&browser_context);
// Owned by its |cocoa_view()|.
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
MockRenderWidgetHostImpl* rwh =
new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false);
@@ -722,7 +788,7 @@ TEST_F(RenderWidgetHostViewMacTest, BlurAndFocusOnSetActive) {
testing::Mock::VerifyAndClearExpectations(rwh);
// Clean up.
- rwh->Shutdown();
+ rwh->ShutdownAndDestroyWidget(true);
}
TEST_F(RenderWidgetHostViewMacTest, ScrollWheelEndEventDelivery) {
@@ -738,7 +804,7 @@ TEST_F(RenderWidgetHostViewMacTest, ScrollWheelEndEventDelivery) {
new MockRenderProcessHost(&browser_context);
process_host->Init();
MockRenderWidgetHostDelegate delegate;
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
MockRenderWidgetHostImpl* host =
new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
@@ -763,7 +829,7 @@ TEST_F(RenderWidgetHostViewMacTest, ScrollWheelEndEventDelivery) {
ASSERT_EQ(2U, process_host->sink().message_count());
// Clean up.
- host->Shutdown();
+ host->ShutdownAndDestroyWidget(true);
}
TEST_F(RenderWidgetHostViewMacTest, IgnoreEmptyUnhandledWheelEvent) {
@@ -779,7 +845,7 @@ TEST_F(RenderWidgetHostViewMacTest, IgnoreEmptyUnhandledWheelEvent) {
new MockRenderProcessHost(&browser_context);
process_host->Init();
MockRenderWidgetHostDelegate delegate;
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
MockRenderWidgetHostImpl* host =
new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
@@ -820,7 +886,7 @@ TEST_F(RenderWidgetHostViewMacTest, IgnoreEmptyUnhandledWheelEvent) {
ASSERT_EQ(NO, view_delegate.get().unhandledWheelEventReceived);
// Clean up.
- host->Shutdown();
+ host->ShutdownAndDestroyWidget(true);
}
// Tests that when view initiated shutdown happens (i.e. RWHView is deleted
@@ -830,7 +896,7 @@ TEST_F(RenderWidgetHostViewMacTest, GuestViewDoesNotLeak) {
TestBrowserContext browser_context;
MockRenderProcessHost* process_host =
new MockRenderProcessHost(&browser_context);
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
// Owned by its |cocoa_view()|.
MockRenderWidgetHostImpl* rwh =
@@ -854,7 +920,7 @@ TEST_F(RenderWidgetHostViewMacTest, GuestViewDoesNotLeak) {
RecycleAndWait();
// Clean up.
- rwh->Shutdown();
+ rwh->ShutdownAndDestroyWidget(true);
// Let |guest_rwhv_weak| have a chance to delete itself.
base::RunLoop run_loop;
@@ -873,7 +939,7 @@ TEST_F(RenderWidgetHostViewMacTest, Background) {
MockRenderProcessHost* process_host =
new MockRenderProcessHost(&browser_context);
MockRenderWidgetHostDelegate delegate;
- int32 routing_id = process_host->GetNextRoutingID();
+ int32_t routing_id = process_host->GetNextRoutingID();
MockRenderWidgetHostImpl* host =
new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
@@ -904,7 +970,7 @@ TEST_F(RenderWidgetHostViewMacTest, Background) {
ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
EXPECT_TRUE(base::get<0>(sent_background));
- host->Shutdown();
+ host->ShutdownAndDestroyWidget(true);
}
class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest {
@@ -927,7 +993,7 @@ class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest {
break;
}
DCHECK(message);
- base::Tuple<IPC::WebInputEventPointer, ui::LatencyInfo, bool> data;
+ base::Tuple<IPC::WebInputEventPointer, ui::LatencyInfo> data;
InputMsg_HandleInputEvent::Read(message, &data);
IPC::WebInputEventPointer ipc_event = base::get<0>(data);
const blink::WebGestureEvent* gesture_event =
@@ -950,7 +1016,7 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
process_host_ = new MockRenderProcessHost(&browser_context);
process_host_->Init();
MockRenderWidgetHostDelegate delegate;
- int32 routing_id = process_host_->GetNextRoutingID();
+ int32_t routing_id = process_host_->GetNextRoutingID();
MockRenderWidgetHostImpl* host =
new MockRenderWidgetHostImpl(&delegate, process_host_, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
@@ -1056,7 +1122,7 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
}
// Clean up.
- host->Shutdown();
+ host->ShutdownAndDestroyWidget(true);
}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mus.cc b/chromium/content/browser/renderer_host/render_widget_host_view_mus.cc
new file mode 100644
index 00000000000..3cfdacf4c85
--- /dev/null
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mus.cc
@@ -0,0 +1,334 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/render_widget_host_view_mus.h"
+
+#include <utility>
+
+#include "build/build_config.h"
+#include "components/mus/public/cpp/window.h"
+#include "components/mus/public/cpp/window_tree_connection.h"
+#include "content/browser/mojo/mojo_shell_client_host.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/common/render_widget_window_tree_client_factory.mojom.h"
+#include "content/public/common/mojo_shell_connection.h"
+#include "mojo/shell/public/cpp/application_impl.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/aura/window.h"
+#include "ui/base/hit_test.h"
+
+namespace blink {
+struct WebScreenInfo;
+}
+
+namespace content {
+
+RenderWidgetHostViewMus::RenderWidgetHostViewMus(mus::Window* parent_window,
+ RenderWidgetHostImpl* host)
+ : host_(host), aura_window_(nullptr) {
+ DCHECK(parent_window);
+ mus::Window* window = parent_window->connection()->NewWindow();
+ window->SetVisible(true);
+ window->SetBounds(gfx::Rect(300, 300));
+ parent_window->AddChild(window);
+ mus_window_.reset(new mus::ScopedWindowPtr(window));
+ host_->SetView(this);
+
+ // Connect to the renderer, pass it a WindowTreeClient interface request
+ // and embed that client inside our mus window.
+ std::string url = GetMojoApplicationInstanceURL(host_->GetProcess());
+ mojom::RenderWidgetWindowTreeClientFactoryPtr factory;
+ MojoShellConnection::Get()->GetApplication()->ConnectToService(url, &factory);
+
+ mus::mojom::WindowTreeClientPtr window_tree_client;
+ factory->CreateWindowTreeClientForRenderWidget(
+ host_->GetRoutingID(), mojo::GetProxy(&window_tree_client));
+ mus_window_->window()->Embed(std::move(window_tree_client));
+}
+
+RenderWidgetHostViewMus::~RenderWidgetHostViewMus() {}
+
+void RenderWidgetHostViewMus::InternalSetBounds(const gfx::Rect& rect) {
+ aura_window_->SetBounds(rect);
+ gfx::Rect bounds = aura_window_->GetBoundsInRootWindow();
+ mus_window_->window()->SetBounds(bounds);
+ host_->WasResized();
+}
+
+void RenderWidgetHostViewMus::Show() {
+ // TODO(fsamuel): Update visibility in Mus.
+ // There is some interstitial complexity that we'll need to figure out here.
+ host_->WasShown(ui::LatencyInfo());
+}
+
+void RenderWidgetHostViewMus::Hide() {
+ host_->WasHidden();
+}
+
+bool RenderWidgetHostViewMus::IsShowing() {
+ return !host_->is_hidden();
+}
+
+void RenderWidgetHostViewMus::SetSize(const gfx::Size& size) {
+ // For a SetSize operation, we don't care what coordinate system the origin
+ // of the window is in, it's only important to make sure that the origin
+ // remains constant after the operation.
+ InternalSetBounds(gfx::Rect(aura_window_->bounds().origin(), size));
+}
+
+void RenderWidgetHostViewMus::SetBounds(const gfx::Rect& rect) {
+ gfx::Point relative_origin(rect.origin());
+
+ // RenderWidgetHostViewMus::SetBounds() takes screen coordinates, but
+ // Window::SetBounds() takes parent coordinates, so do the conversion here.
+ aura::Window* root = aura_window_->GetRootWindow();
+ if (root) {
+ aura::client::ScreenPositionClient* screen_position_client =
+ aura::client::GetScreenPositionClient(root);
+ if (screen_position_client) {
+ screen_position_client->ConvertPointFromScreen(aura_window_->parent(),
+ &relative_origin);
+ }
+ }
+
+ InternalSetBounds(gfx::Rect(relative_origin, rect.size()));
+}
+
+void RenderWidgetHostViewMus::Focus() {
+ // TODO(fsamuel): Request focus for the associated Mus::Window
+ // We need to be careful how we propagate focus as we navigate to and
+ // from interstitials.
+}
+
+bool RenderWidgetHostViewMus::HasFocus() const {
+ return true;
+}
+
+bool RenderWidgetHostViewMus::IsSurfaceAvailableForCopy() const {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+gfx::Rect RenderWidgetHostViewMus::GetViewBounds() const {
+ return aura_window_->GetBoundsInScreen();
+}
+
+gfx::Vector2dF RenderWidgetHostViewMus::GetLastScrollOffset() const {
+ return gfx::Vector2dF();
+}
+
+void RenderWidgetHostViewMus::RenderProcessGone(base::TerminationStatus status,
+ int error_code) {
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewMus::Destroy() {
+ delete aura_window_;
+}
+
+gfx::Size RenderWidgetHostViewMus::GetPhysicalBackingSize() const {
+ return RenderWidgetHostViewBase::GetPhysicalBackingSize();
+}
+
+base::string16 RenderWidgetHostViewMus::GetSelectedText() const {
+ NOTIMPLEMENTED();
+ return base::string16();
+}
+
+void RenderWidgetHostViewMus::SetTooltipText(
+ const base::string16& tooltip_text) {
+ // TOOD(fsamuel): Ask window manager for tooltip?
+}
+
+void RenderWidgetHostViewMus::InitAsChild(gfx::NativeView parent_view) {
+ aura_window_ = new aura::Window(nullptr);
+ aura_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
+ aura_window_->Init(ui::LAYER_SOLID_COLOR);
+ aura_window_->SetName("RenderWidgetHostViewMus");
+ aura_window_->layer()->SetColor(background_color_);
+
+ if (parent_view)
+ parent_view->AddChild(GetNativeView());
+}
+
+RenderWidgetHost* RenderWidgetHostViewMus::GetRenderWidgetHost() const {
+ return host_;
+}
+
+void RenderWidgetHostViewMus::InitAsPopup(
+ RenderWidgetHostView* parent_host_view,
+ const gfx::Rect& bounds) {
+ // TODO(fsamuel): Implement popups in Mus.
+}
+
+void RenderWidgetHostViewMus::InitAsFullscreen(
+ RenderWidgetHostView* reference_host_view) {
+ // TODO(fsamuel): Implement full screen windows in Mus.
+}
+
+gfx::NativeView RenderWidgetHostViewMus::GetNativeView() const {
+ return aura_window_;
+}
+
+gfx::NativeViewId RenderWidgetHostViewMus::GetNativeViewId() const {
+ return gfx::NativeViewId();
+}
+
+gfx::NativeViewAccessible RenderWidgetHostViewMus::GetNativeViewAccessible() {
+ return gfx::NativeViewAccessible();
+}
+
+void RenderWidgetHostViewMus::MovePluginWindows(
+ const std::vector<WebPluginGeometry>& moves) {
+}
+
+void RenderWidgetHostViewMus::UpdateCursor(const WebCursor& cursor) {
+ // TODO(fsamuel): Implement cursors in Mus.
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewMus::SetIsLoading(bool is_loading) {
+}
+
+void RenderWidgetHostViewMus::TextInputStateChanged(
+ const ViewHostMsg_TextInputState_Params& params) {
+ // TODO(fsamuel): Implement an IME mojo app.
+}
+
+void RenderWidgetHostViewMus::ImeCancelComposition() {
+ // TODO(fsamuel): Implement an IME mojo app.
+}
+
+void RenderWidgetHostViewMus::ImeCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) {
+ // TODO(fsamuel): Implement IME.
+}
+
+void RenderWidgetHostViewMus::SelectionChanged(const base::string16& text,
+ size_t offset,
+ const gfx::Range& range) {
+}
+
+void RenderWidgetHostViewMus::SelectionBoundsChanged(
+ const ViewHostMsg_SelectionBounds_Params& params) {
+ // TODO(fsamuel): Implement selection.
+}
+
+void RenderWidgetHostViewMus::SetBackgroundColor(SkColor color) {
+ // TODO(fsamuel): Implement background color and opacity.
+}
+
+void RenderWidgetHostViewMus::CopyFromCompositingSurface(
+ const gfx::Rect& /* src_subrect */,
+ const gfx::Size& /* dst_size */,
+ const ReadbackRequestCallback& callback,
+ const SkColorType /* preferred_color_type */) {
+ // TODO(fsamuel): Implement read back.
+ NOTIMPLEMENTED();
+ callback.Run(SkBitmap(), READBACK_FAILED);
+}
+
+void RenderWidgetHostViewMus::CopyFromCompositingSurfaceToVideoFrame(
+ const gfx::Rect& src_subrect,
+ const scoped_refptr<media::VideoFrame>& target,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) {
+ NOTIMPLEMENTED();
+ callback.Run(gfx::Rect(), false);
+}
+
+bool RenderWidgetHostViewMus::CanCopyToVideoFrame() const {
+ return false;
+}
+
+bool RenderWidgetHostViewMus::HasAcceleratedSurface(
+ const gfx::Size& desired_size) {
+ return false;
+}
+
+bool RenderWidgetHostViewMus::LockMouse() {
+ // TODO(fsamuel): Implement mouse lock in Mus.
+ return false;
+}
+
+void RenderWidgetHostViewMus::UnlockMouse() {
+ // TODO(fsamuel): Implement mouse lock in Mus.
+}
+
+void RenderWidgetHostViewMus::GetScreenInfo(blink::WebScreenInfo* results) {
+ // TODO(fsamuel): Populate screen info from Mus.
+}
+
+bool RenderWidgetHostViewMus::GetScreenColorProfile(
+ std::vector<char>* color_profile) {
+ // TODO(fsamuel): Implement color profile in Mus.
+ return false;
+}
+
+gfx::Rect RenderWidgetHostViewMus::GetBoundsInRootWindow() {
+ aura::Window* top_level = aura_window_->GetToplevelWindow();
+ gfx::Rect bounds(top_level->GetBoundsInScreen());
+ return bounds;
+}
+
+#if defined(OS_MACOSX)
+void RenderWidgetHostViewMus::SetActive(bool active) {
+}
+
+void RenderWidgetHostViewMus::SetWindowVisibility(bool visible) {
+ // TODO(fsamuel): Propagate visibility to Mus?
+}
+
+void RenderWidgetHostViewMus::WindowFrameChanged() {
+}
+
+void RenderWidgetHostViewMus::ShowDefinitionForSelection() {
+ // TODO(fsamuel): Implement this on Mac.
+}
+
+bool RenderWidgetHostViewMus::SupportsSpeech() const {
+ // TODO(fsamuel): Implement this on mac.
+ return false;
+}
+
+void RenderWidgetHostViewMus::SpeakSelection() {
+ // TODO(fsamuel): Implement this on Mac.
+}
+
+bool RenderWidgetHostViewMus::IsSpeaking() const {
+ // TODO(fsamuel): Implement this on Mac.
+ return false;
+}
+
+void RenderWidgetHostViewMus::StopSpeaking() {
+ // TODO(fsamuel): Implement this on Mac.
+}
+
+bool RenderWidgetHostViewMus::PostProcessEventForPluginIme(
+ const NativeWebKeyboardEvent& event) {
+ return false;
+}
+
+#endif // defined(OS_MACOSX)
+
+void RenderWidgetHostViewMus::LockCompositingSurface() {
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewMus::UnlockCompositingSurface() {
+ NOTIMPLEMENTED();
+}
+
+#if defined(OS_WIN)
+void RenderWidgetHostViewMus::SetParentNativeViewAccessible(
+ gfx::NativeViewAccessible accessible_parent) {}
+
+gfx::NativeViewId RenderWidgetHostViewMus::GetParentForWindowlessPlugin()
+ const {
+ return gfx::NativeViewId();
+}
+#endif
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mus.h b/chromium/content/browser/renderer_host/render_widget_host_view_mus.h
new file mode 100644
index 00000000000..0db6d732fba
--- /dev/null
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mus.h
@@ -0,0 +1,142 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MUS_H_
+#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MUS_H_
+
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "components/mus/public/cpp/scoped_window_ptr.h"
+#include "components/mus/public/cpp/window.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "content/public/browser/render_process_host_observer.h"
+
+namespace content {
+
+class RenderWidgetHost;
+class RenderWidgetHostImpl;
+struct NativeWebKeyboardEvent;
+
+// See comments in render_widget_host_view.h about this class and its members.
+// This version of RenderWidgetHostView is for builds of Chrome that run through
+// the mojo shell and use the Mandoline UI Service (Mus). Mus is responsible for
+// windowing, compositing, and input event dispatch. The purpose of
+// RenderWidgetHostViewMus is to manage the mus::Window owned by the content
+// embedder. The browser is the owner of the mus::Window, controlling properties
+// such as visibility, and bounds. Some aspects such as input, focus, and cursor
+// are managed by Mus directly. Input event routing will be plumbed directly to
+// the renderer from Mus.
+class CONTENT_EXPORT RenderWidgetHostViewMus : public RenderWidgetHostViewBase {
+ public:
+ RenderWidgetHostViewMus(mus::Window* parent_window,
+ RenderWidgetHostImpl* widget);
+ ~RenderWidgetHostViewMus() override;
+
+ private:
+ // Set the bounds of the window and handle size changes. Assumes the caller
+ // has already adjusted the origin of |rect| to conform to whatever coordinate
+ // space is required by the aura::Window.
+ void InternalSetBounds(const gfx::Rect& rect);
+
+ // RenderWidgetHostView implementation.
+ void InitAsChild(gfx::NativeView parent_view) override;
+ RenderWidgetHost* GetRenderWidgetHost() const override;
+ void SetSize(const gfx::Size& size) override;
+ void SetBounds(const gfx::Rect& rect) override;
+ void Focus() override;
+ bool HasFocus() const override;
+ bool IsSurfaceAvailableForCopy() const override;
+ void Show() override;
+ void Hide() override;
+ bool IsShowing() override;
+ gfx::NativeView GetNativeView() const override;
+ gfx::NativeViewId GetNativeViewId() const override;
+ gfx::NativeViewAccessible GetNativeViewAccessible() override;
+ gfx::Rect GetViewBounds() const override;
+ gfx::Vector2dF GetLastScrollOffset() const override;
+ void SetBackgroundColor(SkColor color) override;
+ gfx::Size GetPhysicalBackingSize() const override;
+ base::string16 GetSelectedText() const override;
+
+ // RenderWidgetHostViewBase implementation.
+ void InitAsPopup(RenderWidgetHostView* parent_host_view,
+ const gfx::Rect& bounds) override;
+ void InitAsFullscreen(RenderWidgetHostView* reference_host_view) override;
+ void MovePluginWindows(const std::vector<WebPluginGeometry>& moves) override;
+ void UpdateCursor(const WebCursor& cursor) override;
+ void SetIsLoading(bool is_loading) override;
+ void TextInputStateChanged(
+ const ViewHostMsg_TextInputState_Params& params) override;
+ void ImeCancelComposition() override;
+#if defined(OS_MACOSX) || defined(USE_AURA)
+ void ImeCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) override;
+#endif
+ void RenderProcessGone(base::TerminationStatus status,
+ int error_code) override;
+ void Destroy() override;
+ void SetTooltipText(const base::string16& tooltip_text) override;
+ void SelectionChanged(const base::string16& text,
+ size_t offset,
+ const gfx::Range& range) override;
+ void SelectionBoundsChanged(
+ const ViewHostMsg_SelectionBounds_Params& params) override;
+ void CopyFromCompositingSurface(
+ const gfx::Rect& src_subrect,
+ const gfx::Size& dst_size,
+ const ReadbackRequestCallback& callback,
+ const SkColorType preferred_color_type) override;
+ void CopyFromCompositingSurfaceToVideoFrame(
+ const gfx::Rect& src_subrect,
+ const scoped_refptr<media::VideoFrame>& target,
+ const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
+ bool CanCopyToVideoFrame() const override;
+ bool HasAcceleratedSurface(const gfx::Size& desired_size) override;
+ void ClearCompositorFrame() override {}
+ bool LockMouse() override;
+ void UnlockMouse() override;
+ void GetScreenInfo(blink::WebScreenInfo* results) override;
+ bool GetScreenColorProfile(std::vector<char>* color_profile) override;
+ gfx::Rect GetBoundsInRootWindow() override;
+
+#if defined(OS_MACOSX)
+ // RenderWidgetHostView implementation.
+ void SetActive(bool active) override;
+ void SetWindowVisibility(bool visible) override;
+ void WindowFrameChanged() override;
+ void ShowDefinitionForSelection() override;
+ bool SupportsSpeech() const override;
+ void SpeakSelection() override;
+ bool IsSpeaking() const override;
+ void StopSpeaking() override;
+
+ // RenderWidgetHostViewBase implementation.
+ bool PostProcessEventForPluginIme(
+ const NativeWebKeyboardEvent& event) override;
+#endif // defined(OS_MACOSX)
+
+ void LockCompositingSurface() override;
+ void UnlockCompositingSurface() override;
+
+#if defined(OS_WIN)
+ void SetParentNativeViewAccessible(
+ gfx::NativeViewAccessible accessible_parent) override;
+ gfx::NativeViewId GetParentForWindowlessPlugin() const override;
+#endif
+
+ RenderWidgetHostImpl* host_;
+
+ aura::Window* aura_window_;
+
+ scoped_ptr<mus::ScopedWindowPtr> mus_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMus);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MUS_H_
diff --git a/chromium/content/browser/renderer_host/renderer_frame_manager.cc b/chromium/content/browser/renderer_host/renderer_frame_manager.cc
index 34677813de2..3f2281f6960 100644
--- a/chromium/content/browser/renderer_host/renderer_frame_manager.cc
+++ b/chromium/content/browser/renderer_host/renderer_frame_manager.cc
@@ -12,6 +12,7 @@
#include "base/memory/memory_pressure_monitor.h"
#include "base/memory/shared_memory.h"
#include "base/sys_info.h"
+#include "build/build_config.h"
#include "content/common/host_shared_bitmap_manager.h"
namespace content {
diff --git a/chromium/content/browser/renderer_host/renderer_frame_manager.h b/chromium/content/browser/renderer_host/renderer_frame_manager.h
index f8d4a9cbc91..87385481f2e 100644
--- a/chromium/content/browser/renderer_host/renderer_frame_manager.h
+++ b/chromium/content/browser/renderer_host/renderer_frame_manager.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDERER_FRAME_MANAGER_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDERER_FRAME_MANAGER_H_
+#include <stddef.h>
+
#include <list>
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/singleton.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/renderer_host/sandbox_ipc_linux.cc b/chromium/content/browser/renderer_host/sandbox_ipc_linux.cc
index 966f350c774..465ddbdc285 100644
--- a/chromium/content/browser/renderer_host/sandbox_ipc_linux.cc
+++ b/chromium/content/browser/renderer_host/sandbox_ipc_linux.cc
@@ -5,16 +5,17 @@
#include "content/browser/renderer_host/sandbox_ipc_linux.h"
#include <fcntl.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
-#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/files/scoped_file.h"
#include "base/linux_util.h"
#include "base/macros.h"
-#include "base/memory/scoped_vector.h"
#include "base/memory/shared_memory.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/unix_domain_socket_linux.h"
@@ -123,7 +124,7 @@ void SandboxIPCHandler::Run() {
}
void SandboxIPCHandler::HandleRequestFromRenderer(int fd) {
- ScopedVector<base::ScopedFD> fds;
+ std::vector<base::ScopedFD> fds;
// A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength
// bytes long (this is the largest message type).
@@ -149,19 +150,19 @@ void SandboxIPCHandler::HandleRequestFromRenderer(int fd) {
return;
if (kind == FontConfigIPC::METHOD_MATCH) {
- HandleFontMatchRequest(fd, iter, fds.get());
+ HandleFontMatchRequest(fd, iter, fds);
} else if (kind == FontConfigIPC::METHOD_OPEN) {
- HandleFontOpenRequest(fd, iter, fds.get());
+ HandleFontOpenRequest(fd, iter, fds);
} else if (kind == LinuxSandbox::METHOD_GET_FALLBACK_FONT_FOR_CHAR) {
- HandleGetFallbackFontForChar(fd, iter, fds.get());
+ HandleGetFallbackFontForChar(fd, iter, fds);
} else if (kind == LinuxSandbox::METHOD_LOCALTIME) {
- HandleLocaltime(fd, iter, fds.get());
+ HandleLocaltime(fd, iter, fds);
} else if (kind == LinuxSandbox::METHOD_GET_STYLE_FOR_STRIKE) {
- HandleGetStyleForStrike(fd, iter, fds.get());
+ HandleGetStyleForStrike(fd, iter, fds);
} else if (kind == LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
- HandleMakeSharedMemorySegment(fd, iter, fds.get());
+ HandleMakeSharedMemorySegment(fd, iter, fds);
} else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) {
- HandleMatchWithFallback(fd, iter, fds.get());
+ HandleMatchWithFallback(fd, iter, fds);
}
}
@@ -178,7 +179,7 @@ int SandboxIPCHandler::FindOrAddPath(const SkString& path) {
void SandboxIPCHandler::HandleFontMatchRequest(
int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds) {
+ const std::vector<base::ScopedFD>& fds) {
uint32_t requested_style;
std::string family;
if (!iter.ReadString(&family) || !iter.ReadUInt32(&requested_style))
@@ -216,7 +217,7 @@ void SandboxIPCHandler::HandleFontMatchRequest(
void SandboxIPCHandler::HandleFontOpenRequest(
int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds) {
+ const std::vector<base::ScopedFD>& fds) {
uint32_t index;
if (!iter.ReadUInt32(&index))
return;
@@ -244,7 +245,7 @@ void SandboxIPCHandler::HandleFontOpenRequest(
void SandboxIPCHandler::HandleGetFallbackFontForChar(
int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds) {
+ const std::vector<base::ScopedFD>& fds) {
// The other side of this call is
// content/common/child_process_sandbox_support_impl_linux.cc
@@ -284,10 +285,10 @@ void SandboxIPCHandler::HandleGetFallbackFontForChar(
void SandboxIPCHandler::HandleGetStyleForStrike(
int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds) {
+ const std::vector<base::ScopedFD>& fds) {
std::string family;
bool bold, italic;
- uint16 pixel_size;
+ uint16_t pixel_size;
if (!iter.ReadString(&family) ||
!iter.ReadBool(&bold) ||
@@ -322,7 +323,7 @@ void SandboxIPCHandler::HandleGetStyleForStrike(
void SandboxIPCHandler::HandleLocaltime(
int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds) {
+ const std::vector<base::ScopedFD>& fds) {
// The other side of this call is in zygote_main_linux.cc
std::string time_string;
@@ -352,7 +353,7 @@ void SandboxIPCHandler::HandleLocaltime(
void SandboxIPCHandler::HandleMakeSharedMemorySegment(
int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds) {
+ const std::vector<base::ScopedFD>& fds) {
base::SharedMemoryCreateOptions options;
uint32_t size;
if (!iter.ReadUInt32(&size))
@@ -371,10 +372,10 @@ void SandboxIPCHandler::HandleMakeSharedMemorySegment(
void SandboxIPCHandler::HandleMatchWithFallback(
int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds) {
+ const std::vector<base::ScopedFD>& fds) {
std::string face;
bool is_bold, is_italic;
- uint32 charset, fallback_family;
+ uint32_t charset, fallback_family;
if (!iter.ReadString(&face) || face.empty() ||
!iter.ReadBool(&is_bold) ||
@@ -397,7 +398,7 @@ void SandboxIPCHandler::HandleMatchWithFallback(
}
void SandboxIPCHandler::SendRendererReply(
- const std::vector<base::ScopedFD*>& fds,
+ const std::vector<base::ScopedFD>& fds,
const base::Pickle& reply,
int reply_fd) {
struct msghdr msg;
@@ -428,7 +429,7 @@ void SandboxIPCHandler::SendRendererReply(
msg.msg_controllen = cmsg->cmsg_len;
}
- if (HANDLE_EINTR(sendmsg(fds[0]->get(), &msg, MSG_DONTWAIT)) < 0)
+ if (HANDLE_EINTR(sendmsg(fds[0].get(), &msg, MSG_DONTWAIT)) < 0)
PLOG(ERROR) << "sendmsg";
}
diff --git a/chromium/content/browser/renderer_host/sandbox_ipc_linux.h b/chromium/content/browser/renderer_host/sandbox_ipc_linux.h
index 23a65e0d215..a11a8787237 100644
--- a/chromium/content/browser/renderer_host/sandbox_ipc_linux.h
+++ b/chromium/content/browser/renderer_host/sandbox_ipc_linux.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/files/scoped_file.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
#include "base/threading/simple_thread.h"
@@ -37,33 +38,33 @@ class SandboxIPCHandler : public base::DelegateSimpleThread::Delegate {
void HandleFontMatchRequest(int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds);
+ const std::vector<base::ScopedFD>& fds);
void HandleFontOpenRequest(int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds);
+ const std::vector<base::ScopedFD>& fds);
void HandleGetFallbackFontForChar(int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds);
+ base::PickleIterator iter,
+ const std::vector<base::ScopedFD>& fds);
void HandleGetStyleForStrike(int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds);
+ const std::vector<base::ScopedFD>& fds);
void HandleLocaltime(int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds);
+ const std::vector<base::ScopedFD>& fds);
void HandleMakeSharedMemorySegment(int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds);
+ const std::vector<base::ScopedFD>& fds);
void HandleMatchWithFallback(int fd,
base::PickleIterator iter,
- const std::vector<base::ScopedFD*>& fds);
+ const std::vector<base::ScopedFD>& fds);
- void SendRendererReply(const std::vector<base::ScopedFD*>& fds,
+ void SendRendererReply(const std::vector<base::ScopedFD>& fds,
const base::Pickle& reply,
int reply_fd);
diff --git a/chromium/content/browser/renderer_host/text_input_client_mac.h b/chromium/content/browser/renderer_host/text_input_client_mac.h
index 84539e53e30..eeb48a81595 100644
--- a/chromium/content/browser/renderer_host/text_input_client_mac.h
+++ b/chromium/content/browser/renderer_host/text_input_client_mac.h
@@ -9,6 +9,7 @@
#include "base/mac/scoped_block.h"
#include "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
@@ -57,9 +58,6 @@ class CONTENT_EXPORT TextInputClientMac {
//
// Returns NSNotFound if the request times out or is not completed.
NSUInteger GetCharacterIndexAtPoint(RenderWidgetHost* rwh, gfx::Point point);
- // Returns nil if the request times out or is completed.
- NSAttributedString* GetAttributedSubstringFromRange(
- RenderWidgetHost* rwh, NSRange range);
// Returns NSZeroRect if the request times out or is not completed. The result
// is in WebKit coordinates.
NSRect GetFirstRectForRange(RenderWidgetHost* rwh, NSRange range);
diff --git a/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm b/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm
index 6d8652cfabd..aa265fca27c 100644
--- a/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm
+++ b/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm
@@ -4,6 +4,9 @@
#import "content/browser/renderer_host/text_input_client_mac.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
@@ -21,7 +24,7 @@
namespace content {
namespace {
-const int64 kTaskDelayMs = 200;
+const int64_t kTaskDelayMs = 200;
class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
public:
@@ -47,7 +50,7 @@ class TextInputClientMacTest : public testing::Test {
thread_("TextInputClientMacTestThread") {
RenderProcessHost* rph =
process_factory_.CreateRenderProcessHost(&browser_context_, nullptr);
- int32 routing_id = rph->GetNextRoutingID();
+ int32_t routing_id = rph->GetNextRoutingID();
widget_.reset(new RenderWidgetHostImpl(&delegate_, rph, routing_id, false));
}
@@ -139,7 +142,7 @@ TEST_F(TextInputClientMacTest, TimeoutCharacterIndex) {
EXPECT_EQ(1U, ipc_sink().message_count());
EXPECT_TRUE(ipc_sink().GetUniqueMessageMatching(
TextInputClientMsg_CharacterIndexForPoint::ID));
- EXPECT_EQ(NSNotFound, index);
+ EXPECT_EQ(static_cast<NSUInteger>(NSNotFound), index);
}
TEST_F(TextInputClientMacTest, NotFoundCharacterIndex) {
@@ -167,7 +170,7 @@ TEST_F(TextInputClientMacTest, NotFoundCharacterIndex) {
widget(), gfx::Point(2, 2));
EXPECT_EQ(kPreviousValue, index);
index = service()->GetCharacterIndexAtPoint(widget(), gfx::Point(2, 2));
- EXPECT_EQ(NSNotFound, index);
+ EXPECT_EQ(static_cast<NSUInteger>(NSNotFound), index);
EXPECT_EQ(2U, ipc_sink().message_count());
for (size_t i = 0; i < ipc_sink().message_count(); ++i) {
diff --git a/chromium/content/browser/renderer_host/text_input_client_message_filter.h b/chromium/content/browser/renderer_host/text_input_client_message_filter.h
index 992a9a20747..94000653867 100644
--- a/chromium/content/browser/renderer_host/text_input_client_message_filter.h
+++ b/chromium/content/browser/renderer_host/text_input_client_message_filter.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_CLIENT_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_CLIENT_MESSAGE_FILTER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "content/common/mac/attributed_string_coder.h"
#include "content/public/browser/browser_message_filter.h"
diff --git a/chromium/content/browser/renderer_host/ui_events_helper.cc b/chromium/content/browser/renderer_host/ui_events_helper.cc
index 7aa038e1dcc..a062303cc07 100644
--- a/chromium/content/browser/renderer_host/ui_events_helper.cc
+++ b/chromium/content/browser/renderer_host/ui_events_helper.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/ui_events_helper.h"
+#include <stdint.h>
+
#include "content/browser/renderer_host/input/web_input_event_util.h"
#include "content/common/input/web_touch_event_traits.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -63,7 +65,7 @@ bool MakeUITouchEventsFromWebTouchEvents(
int flags = WebEventModifiersToEventFlags(touch.modifiers);
base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
- static_cast<int64>(touch.timeStampSeconds * 1000000));
+ static_cast<int64_t>(touch.timeStampSeconds * 1000000));
for (unsigned i = 0; i < touch.touchesLength; ++i) {
const blink::WebTouchPoint& point = touch.touches[i];
if (WebTouchPointStateToEventType(point.state) != type)
@@ -74,15 +76,11 @@ bool MakeUITouchEventsFromWebTouchEvents(
location = point.position;
else
location = point.screenPosition;
- ui::TouchEvent* uievent = new ui::TouchEvent(type,
- location,
- flags,
- point.id,
- timestamp,
- point.radiusX,
- point.radiusY,
- point.rotationAngle,
- point.force);
+ ui::TouchEvent* uievent = new ui::TouchEvent(
+ type, gfx::Point(), flags, point.id, timestamp, point.radiusX,
+ point.radiusY, point.rotationAngle, point.force);
+ uievent->set_location_f(location);
+ uievent->set_root_location_f(location);
uievent->set_latency(touch_with_latency.latency);
list->push_back(uievent);
}
diff --git a/chromium/content/browser/renderer_host/web_input_event_aura.cc b/chromium/content/browser/renderer_host/web_input_event_aura.cc
index 543ec6d48b1..c4ed46155bd 100644
--- a/chromium/content/browser/renderer_host/web_input_event_aura.cc
+++ b/chromium/content/browser/renderer_host/web_input_event_aura.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/web_input_event_aura.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
#include "content/browser/renderer_host/ui_events_helper.h"
#include "ui/aura/client/screen_position_client.h"
@@ -12,6 +13,7 @@
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
namespace content {
@@ -37,29 +39,33 @@ blink::WebPointerProperties::PointerType EventPointerTypeToWebPointerType(
ui::EventPointerType pointer_type) {
switch (pointer_type) {
case ui::EventPointerType::POINTER_TYPE_UNKNOWN:
- return blink::WebPointerProperties::PointerType::PointerTypeUnknown;
+ return blink::WebPointerProperties::PointerType::Unknown;
case ui::EventPointerType::POINTER_TYPE_MOUSE:
- return blink::WebPointerProperties::PointerType::PointerTypeMouse;
+ return blink::WebPointerProperties::PointerType::Mouse;
case ui::EventPointerType::POINTER_TYPE_PEN:
- return blink::WebPointerProperties::PointerType::PointerTypePen;
+ return blink::WebPointerProperties::PointerType::Pen;
case ui::EventPointerType::POINTER_TYPE_TOUCH:
- return blink::WebPointerProperties::PointerType::PointerTypeTouch;
+ return blink::WebPointerProperties::PointerType::Touch;
}
NOTREACHED() << "Unexpected EventPointerType";
- return blink::WebPointerProperties::PointerType::PointerTypeUnknown;
+ return blink::WebPointerProperties::PointerType::Unknown;
}
} // namespace
#if defined(OS_WIN)
blink::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent(
- const base::NativeEvent& native_event);
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp);
blink::WebMouseWheelEvent MakeUntranslatedWebMouseWheelEventFromNativeEvent(
- const base::NativeEvent& native_event);
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp);
blink::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent(
- const base::NativeEvent& native_event);
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp);
blink::WebGestureEvent MakeWebGestureEventFromNativeEvent(
- const base::NativeEvent& native_event);
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp);
#endif
blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
@@ -85,7 +91,11 @@ blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
if (webkit_event.modifiers & blink::WebInputEvent::AltKey)
webkit_event.isSystemKey = true;
- webkit_event.windowsKeyCode = event.key_code();
+ // TODO(dtapuska): crbug.com/570388. Ozone appears to deliver
+ // key_code events that aren't "located" for the keypad like
+ // Windows and X11 do and blink expects.
+ webkit_event.windowsKeyCode =
+ ui::NonLocatedToLocatedKeypadKeyboardCode(event.key_code(), event.code());
webkit_event.nativeKeyCode =
ui::KeycodeConverter::DomCodeToNativeKeycode(event.code());
webkit_event.domCode = static_cast<int>(event.code());
@@ -189,13 +199,14 @@ blink::WebMouseEvent MakeWebMouseEvent(const ui::MouseEvent& event) {
// Construct an untranslated event from the platform event data.
blink::WebMouseEvent webkit_event =
#if defined(OS_WIN)
- // On Windows we have WM_ events comming from desktop and pure aura
- // events comming from metro mode.
- event.native_event().message && (event.type() != ui::ET_MOUSE_EXITED) ?
- MakeUntranslatedWebMouseEventFromNativeEvent(event.native_event()) :
- MakeWebMouseEventFromAuraEvent(event);
+ // On Windows we have WM_ events comming from desktop and pure aura
+ // events comming from metro mode.
+ event.native_event().message && (event.type() != ui::ET_MOUSE_EXITED)
+ ? MakeUntranslatedWebMouseEventFromNativeEvent(event.native_event(),
+ event.time_stamp())
+ : MakeWebMouseEventFromAuraEvent(event);
#else
- MakeWebMouseEventFromAuraEvent(event);
+ MakeWebMouseEventFromAuraEvent(event);
#endif
// Replace the event's coordinate fields with translated position data from
// |event|.
@@ -217,9 +228,11 @@ blink::WebMouseWheelEvent MakeWebMouseWheelEvent(
const ui::MouseWheelEvent& event) {
#if defined(OS_WIN)
// Construct an untranslated event from the platform event data.
- blink::WebMouseWheelEvent webkit_event = event.native_event().message ?
- MakeUntranslatedWebMouseWheelEventFromNativeEvent(event.native_event()) :
- MakeWebMouseWheelEventFromAuraEvent(event);
+ blink::WebMouseWheelEvent webkit_event =
+ event.native_event().message
+ ? MakeUntranslatedWebMouseWheelEventFromNativeEvent(
+ event.native_event(), event.time_stamp())
+ : MakeWebMouseWheelEventFromAuraEvent(event);
#else
blink::WebMouseWheelEvent webkit_event =
MakeWebMouseWheelEventFromAuraEvent(event);
@@ -248,9 +261,11 @@ blink::WebMouseWheelEvent MakeWebMouseWheelEvent(
blink::WebMouseWheelEvent MakeWebMouseWheelEvent(const ui::ScrollEvent& event) {
#if defined(OS_WIN)
// Construct an untranslated event from the platform event data.
- blink::WebMouseWheelEvent webkit_event = event.native_event().message ?
- MakeUntranslatedWebMouseWheelEventFromNativeEvent(event.native_event()) :
- MakeWebMouseWheelEventFromAuraEvent(event);
+ blink::WebMouseWheelEvent webkit_event =
+ event.native_event().message
+ ? MakeUntranslatedWebMouseWheelEventFromNativeEvent(
+ event.native_event(), event.time_stamp())
+ : MakeWebMouseWheelEventFromAuraEvent(event);
#else
blink::WebMouseWheelEvent webkit_event =
MakeWebMouseWheelEventFromAuraEvent(event);
@@ -278,8 +293,8 @@ blink::WebKeyboardEvent MakeWebKeyboardEvent(const ui::KeyEvent& event) {
#if defined(OS_WIN)
if (event.HasNativeEvent()) {
// Key events require no translation by the aura system.
- blink::WebKeyboardEvent webkit_event(
- MakeWebKeyboardEventFromNativeEvent(event.native_event()));
+ blink::WebKeyboardEvent webkit_event(MakeWebKeyboardEventFromNativeEvent(
+ event.native_event(), event.time_stamp()));
webkit_event.modifiers |= DomCodeToWebInputEventModifiers(event.code());
webkit_event.domCode = static_cast<int>(event.code());
webkit_event.domKey = static_cast<int>(event.GetDomKey());
@@ -293,7 +308,8 @@ blink::WebGestureEvent MakeWebGestureEvent(const ui::GestureEvent& event) {
blink::WebGestureEvent gesture_event;
#if defined(OS_WIN)
if (event.HasNativeEvent())
- gesture_event = MakeWebGestureEventFromNativeEvent(event.native_event());
+ gesture_event = MakeWebGestureEventFromNativeEvent(event.native_event(),
+ event.time_stamp());
else
gesture_event = MakeWebGestureEventFromUIEvent(event);
#else
@@ -314,7 +330,8 @@ blink::WebGestureEvent MakeWebGestureEvent(const ui::ScrollEvent& event) {
blink::WebGestureEvent gesture_event;
#if defined(OS_WIN)
- gesture_event = MakeWebGestureEventFromNativeEvent(event.native_event());
+ gesture_event = MakeWebGestureEventFromNativeEvent(event.native_event(),
+ event.time_stamp());
#else
gesture_event = MakeWebGestureEventFromAuraEvent(event);
#endif
diff --git a/chromium/content/browser/renderer_host/web_input_event_aura_unittest.cc b/chromium/content/browser/renderer_host/web_input_event_aura_unittest.cc
index 42c6a978f6b..2d46dfb2e40 100644
--- a/chromium/content/browser/renderer_host/web_input_event_aura_unittest.cc
+++ b/chromium/content/browser/renderer_host/web_input_event_aura_unittest.cc
@@ -4,7 +4,11 @@
#include "content/browser/renderer_host/web_input_event_aura.h"
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/event.h"
@@ -161,7 +165,7 @@ TEST(WebInputEventAuraTest, TestMakeWebKeyboardEventKeyPadKeyCode) {
struct TestCase {
ui::DomCode dom_code; // The physical key (location).
ui::KeyboardCode ui_keycode; // The virtual key code.
- uint32 x_keysym; // The X11 keysym.
+ uint32_t x_keysym; // The X11 keysym.
bool expected_result; // true if the event has "isKeyPad" modifier.
} kTesCases[] = {
{ui::DomCode::DIGIT0, ui::VKEY_0, XK(0), false},
@@ -250,10 +254,9 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Left pressed.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_PRESSED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp,
- ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
+ ui::MouseEvent aura_event(
+ ui::ET_MOUSE_PRESSED, gfx::Point(123, 321), gfx::Point(123, 321),
+ timestamp, ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
webkit_event.modifiers);
@@ -269,8 +272,8 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Left released.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_RELEASED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp, 0,
+ ui::MouseEvent aura_event(ui::ET_MOUSE_RELEASED, gfx::Point(123, 321),
+ gfx::Point(123, 321), timestamp, 0,
ui::EF_LEFT_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
@@ -287,10 +290,9 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Middle pressed.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_PRESSED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp,
- ui::EF_MIDDLE_MOUSE_BUTTON,
- ui::EF_MIDDLE_MOUSE_BUTTON);
+ ui::MouseEvent aura_event(
+ ui::ET_MOUSE_PRESSED, gfx::Point(123, 321), gfx::Point(123, 321),
+ timestamp, ui::EF_MIDDLE_MOUSE_BUTTON, ui::EF_MIDDLE_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
webkit_event.modifiers);
@@ -306,8 +308,8 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Middle released.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_RELEASED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp, 0,
+ ui::MouseEvent aura_event(ui::ET_MOUSE_RELEASED, gfx::Point(123, 321),
+ gfx::Point(123, 321), timestamp, 0,
ui::EF_MIDDLE_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
@@ -324,10 +326,9 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Right pressed.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_PRESSED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp,
- ui::EF_RIGHT_MOUSE_BUTTON,
- ui::EF_RIGHT_MOUSE_BUTTON);
+ ui::MouseEvent aura_event(
+ ui::ET_MOUSE_PRESSED, gfx::Point(123, 321), gfx::Point(123, 321),
+ timestamp, ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
webkit_event.modifiers);
@@ -343,8 +344,8 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Right released.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_RELEASED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp, 0,
+ ui::MouseEvent aura_event(ui::ET_MOUSE_RELEASED, gfx::Point(123, 321),
+ gfx::Point(123, 321), timestamp, 0,
ui::EF_RIGHT_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
@@ -361,8 +362,8 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Moved
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_MOVED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp, 0, 0);
+ ui::MouseEvent aura_event(ui::ET_MOUSE_MOVED, gfx::Point(123, 321),
+ gfx::Point(123, 321), timestamp, 0, 0);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
webkit_event.modifiers);
@@ -378,8 +379,8 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Moved with left down
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_MOVED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp,
+ ui::MouseEvent aura_event(ui::ET_MOUSE_MOVED, gfx::Point(123, 321),
+ gfx::Point(123, 321), timestamp,
ui::EF_LEFT_MOUSE_BUTTON, 0);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
@@ -396,8 +397,8 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Left with shift pressed.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_PRESSED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp,
+ ui::MouseEvent aura_event(ui::ET_MOUSE_PRESSED, gfx::Point(123, 321),
+ gfx::Point(123, 321), timestamp,
ui::EF_LEFT_MOUSE_BUTTON | ui::EF_SHIFT_DOWN,
ui::EF_LEFT_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
@@ -415,13 +416,12 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Default values for PointerDetails.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_PRESSED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp,
- ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
+ ui::MouseEvent aura_event(
+ ui::ET_MOUSE_PRESSED, gfx::Point(123, 321), gfx::Point(123, 321),
+ timestamp, ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
- EXPECT_EQ(blink::WebPointerProperties::PointerType::PointerTypeMouse,
+ EXPECT_EQ(blink::WebPointerProperties::PointerType::Mouse,
webkit_event.pointerType);
EXPECT_EQ(0, webkit_event.tiltX);
EXPECT_EQ(0, webkit_event.tiltY);
@@ -434,10 +434,9 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
{
// Stylus values for PointerDetails.
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::MouseEvent aura_event(ui::ET_MOUSE_PRESSED, gfx::PointF(123.0, 321.0),
- gfx::PointF(123.0, 321.0), timestamp,
- ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
+ ui::MouseEvent aura_event(
+ ui::ET_MOUSE_PRESSED, gfx::Point(123, 321), gfx::Point(123, 321),
+ timestamp, ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
aura_event.set_pointer_details(
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_PEN,
/* radius_x */ 0.0f,
@@ -447,7 +446,7 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseEvent) {
/* tilt_y */ -89.5f));
blink::WebMouseEvent webkit_event = MakeWebMouseEvent(aura_event);
- EXPECT_EQ(blink::WebPointerProperties::PointerType::PointerTypePen,
+ EXPECT_EQ(blink::WebPointerProperties::PointerType::Pen,
webkit_event.pointerType);
EXPECT_EQ(90, webkit_event.tiltX);
EXPECT_EQ(-90, webkit_event.tiltY);
@@ -466,7 +465,7 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseWheelEvent) {
ui::MouseWheelEvent aura_event(
gfx::Vector2d(ui::MouseWheelEvent::kWheelDelta * 2,
-ui::MouseWheelEvent::kWheelDelta * 2),
- gfx::PointF(123.0, 321.0), gfx::PointF(123.0, 321.0), timestamp, 0, 0);
+ gfx::Point(123, 321), gfx::Point(123, 321), timestamp, 0, 0);
blink::WebMouseWheelEvent webkit_event = MakeWebMouseWheelEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
webkit_event.modifiers);
@@ -475,7 +474,7 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseWheelEvent) {
EXPECT_EQ(blink::WebInputEvent::MouseWheel, webkit_event.type);
EXPECT_FLOAT_EQ(aura_event.x_offset() / 53.0f, webkit_event.wheelTicksX);
EXPECT_FLOAT_EQ(aura_event.y_offset() / 53.0f, webkit_event.wheelTicksY);
- EXPECT_EQ(blink::WebPointerProperties::PointerType::PointerTypeMouse,
+ EXPECT_EQ(blink::WebPointerProperties::PointerType::Mouse,
webkit_event.pointerType);
EXPECT_EQ(0, webkit_event.tiltX);
EXPECT_EQ(0, webkit_event.tiltY);
@@ -490,7 +489,7 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseWheelEvent) {
base::TimeDelta timestamp = ui::EventTimeForNow();
ui::MouseWheelEvent aura_event(
gfx::Vector2d(0, -ui::MouseWheelEvent::kWheelDelta * 2),
- gfx::PointF(123.0, 321.0), gfx::PointF(123.0, 321.0), timestamp,
+ gfx::Point(123, 321), gfx::Point(123, 321), timestamp,
ui::EF_SHIFT_DOWN, 0);
blink::WebMouseWheelEvent webkit_event = MakeWebMouseWheelEvent(aura_event);
EXPECT_EQ(ui::EventFlagsToWebEventModifiers(aura_event.flags()),
@@ -500,7 +499,7 @@ TEST(WebInputEventAuraTest, TestMakeWebMouseWheelEvent) {
EXPECT_EQ(blink::WebInputEvent::MouseWheel, webkit_event.type);
EXPECT_FLOAT_EQ(aura_event.y_offset() / 53.0f, webkit_event.wheelTicksX);
EXPECT_FLOAT_EQ(0, webkit_event.wheelTicksY);
- EXPECT_EQ(blink::WebPointerProperties::PointerType::PointerTypeMouse,
+ EXPECT_EQ(blink::WebPointerProperties::PointerType::Mouse,
webkit_event.pointerType);
EXPECT_EQ(0, webkit_event.tiltX);
EXPECT_EQ(0, webkit_event.tiltY);
diff --git a/chromium/content/browser/renderer_host/web_input_event_aurawin.cc b/chromium/content/browser/renderer_host/web_input_event_aurawin.cc
index 549e2f2bb1d..96e58257654 100644
--- a/chromium/content/browser/renderer_host/web_input_event_aurawin.cc
+++ b/chromium/content/browser/renderer_host/web_input_event_aurawin.cc
@@ -6,6 +6,7 @@
#include "base/event_types.h"
#include "base/logging.h"
+#include "base/time/time.h"
#include "content/browser/renderer_host/input/web_input_event_builders_win.h"
namespace content {
@@ -14,34 +15,32 @@ namespace content {
// construct our pre-translated events.
blink::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent(
- const base::NativeEvent& native_event) {
- return WebMouseEventBuilder::Build(native_event.hwnd,
- native_event.message,
- native_event.wParam,
- native_event.lParam,
- native_event.time);
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp) {
+ return WebMouseEventBuilder::Build(native_event.hwnd, native_event.message,
+ native_event.wParam, native_event.lParam,
+ time_stamp.InSecondsF());
}
blink::WebMouseWheelEvent MakeUntranslatedWebMouseWheelEventFromNativeEvent(
- const base::NativeEvent& native_event) {
- return WebMouseWheelEventBuilder::Build(native_event.hwnd,
- native_event.message,
- native_event.wParam,
- native_event.lParam,
- native_event.time);
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp) {
+ return WebMouseWheelEventBuilder::Build(
+ native_event.hwnd, native_event.message, native_event.wParam,
+ native_event.lParam, time_stamp.InSecondsF());
}
blink::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent(
- const base::NativeEvent& native_event) {
- return WebKeyboardEventBuilder::Build(native_event.hwnd,
- native_event.message,
- native_event.wParam,
- native_event.lParam,
- native_event.time);
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp) {
+ return WebKeyboardEventBuilder::Build(
+ native_event.hwnd, native_event.message, native_event.wParam,
+ native_event.lParam, time_stamp.InSecondsF());
}
blink::WebGestureEvent MakeWebGestureEventFromNativeEvent(
- const base::NativeEvent& native_event) {
+ const base::NativeEvent& native_event,
+ const base::TimeDelta& time_stamp) {
// TODO: Create gestures from native event.
NOTIMPLEMENTED();
return blink::WebGestureEvent();
diff --git a/chromium/content/browser/renderer_host/webmenurunner_mac.mm b/chromium/content/browser/renderer_host/webmenurunner_mac.mm
index 94e77453e91..0e189bedd69 100644
--- a/chromium/content/browser/renderer_host/webmenurunner_mac.mm
+++ b/chromium/content/browser/renderer_host/webmenurunner_mac.mm
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/webmenurunner_mac.h"
+#include <stddef.h>
+
#include "base/strings/sys_string_conversions.h"
@interface WebMenuRunner (PrivateAPI)
diff --git a/chromium/content/browser/renderer_host/websocket_dispatcher_host.cc b/chromium/content/browser/renderer_host/websocket_dispatcher_host.cc
index ab4e68b76c1..0cdf66383a5 100644
--- a/chromium/content/browser/renderer_host/websocket_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/websocket_dispatcher_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/websocket_dispatcher_host.h"
+#include <stddef.h>
+
#include <string>
#include <vector>
@@ -131,8 +133,8 @@ WebSocketHost* WebSocketDispatcherHost::GetHost(int routing_id) const {
}
WebSocketHostState WebSocketDispatcherHost::SendOrDrop(IPC::Message* message) {
- const uint32 message_type = message->type();
- const int32 message_routing_id = message->routing_id();
+ const uint32_t message_type = message->type();
+ const int32_t message_routing_id = message->routing_id();
if (!Send(message)) {
message = NULL;
DVLOG(1) << "Sending of message type " << message_type
@@ -168,7 +170,7 @@ WebSocketHostState WebSocketDispatcherHost::SendFrame(
}
WebSocketHostState WebSocketDispatcherHost::SendFlowControl(int routing_id,
- int64 quota) {
+ int64_t quota) {
return SendOrDrop(new WebSocketMsg_FlowControl(routing_id, quota));
}
@@ -203,7 +205,7 @@ WebSocketHostState WebSocketDispatcherHost::NotifyFailure(
WebSocketHostState WebSocketDispatcherHost::DoDropChannel(
int routing_id,
bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) {
if (SendOrDrop(
new WebSocketMsg_DropChannel(routing_id, was_clean, code, reason)) ==
diff --git a/chromium/content/browser/renderer_host/websocket_dispatcher_host.h b/chromium/content/browser/renderer_host/websocket_dispatcher_host.h
index 50390782eff..56c5f3aaa5d 100644
--- a/chromium/content/browser/renderer_host/websocket_dispatcher_host.h
+++ b/chromium/content/browser/renderer_host/websocket_dispatcher_host.h
@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
@@ -74,7 +75,7 @@ class CONTENT_EXPORT WebSocketDispatcherHost : public BrowserMessageFilter {
// Sends a WebSocketMsg_FlowControl IPC.
WebSocketHostState SendFlowControl(int routing_id,
- int64 quota) WARN_UNUSED_RESULT;
+ int64_t quota) WARN_UNUSED_RESULT;
// Sends a WebSocketMsg_NotifyClosing IPC
WebSocketHostState NotifyClosingHandshake(int routing_id) WARN_UNUSED_RESULT;
@@ -97,11 +98,11 @@ class CONTENT_EXPORT WebSocketDispatcherHost : public BrowserMessageFilter {
// Sends a WebSocketMsg_DropChannel IPC and deletes and unregisters the
// channel.
- WebSocketHostState DoDropChannel(
- int routing_id,
- bool was_clean,
- uint16 code,
- const std::string& reason) WARN_UNUSED_RESULT;
+ WebSocketHostState DoDropChannel(int routing_id,
+ bool was_clean,
+ uint16_t code,
+ const std::string& reason)
+ WARN_UNUSED_RESULT;
// Returns whether the associated renderer process can read raw cookies.
bool CanReadRawCookies() const;
diff --git a/chromium/content/browser/renderer_host/websocket_host.cc b/chromium/content/browser/renderer_host/websocket_host.cc
index 70c846e3981..5551e9643bf 100644
--- a/chromium/content/browser/renderer_host/websocket_host.cc
+++ b/chromium/content/browser/renderer_host/websocket_host.cc
@@ -4,8 +4,10 @@
#include "content/browser/renderer_host/websocket_host.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
@@ -14,6 +16,7 @@
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/browser/ssl/ssl_manager.h"
#include "content/common/websocket_messages.h"
+#include "content/public/browser/render_frame_host.h"
#include "ipc/ipc_message_macros.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
@@ -101,9 +104,9 @@ class WebSocketEventHandler : public net::WebSocketEventInterface {
WebSocketMessageType type,
const std::vector<char>& data) override;
ChannelState OnClosingHandshake() override;
- ChannelState OnFlowControl(int64 quota) override;
+ ChannelState OnFlowControl(int64_t quota) override;
ChannelState OnDropChannel(bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) override;
ChannelState OnFailChannel(const std::string& message) override;
ChannelState OnStartOpeningHandshake(
@@ -188,7 +191,7 @@ ChannelState WebSocketEventHandler::OnClosingHandshake() {
return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_));
}
-ChannelState WebSocketEventHandler::OnFlowControl(int64 quota) {
+ChannelState WebSocketEventHandler::OnFlowControl(int64_t quota) {
DVLOG(3) << "WebSocketEventHandler::OnFlowControl"
<< " routing_id=" << routing_id_ << " quota=" << quota;
@@ -196,7 +199,7 @@ ChannelState WebSocketEventHandler::OnFlowControl(int64 quota) {
}
ChannelState WebSocketEventHandler::OnDropChannel(bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) {
DVLOG(3) << "WebSocketEventHandler::OnDropChannel"
<< " routing_id=" << routing_id_ << " was_clean=" << was_clean
@@ -273,21 +276,17 @@ ChannelState WebSocketEventHandler::OnSSLCertificateError(
<< " routing_id=" << routing_id_ << " url=" << url.spec()
<< " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
ssl_error_handler_delegate_.reset(
- new SSLErrorHandlerDelegate(callbacks.Pass()));
- SSLManager::OnSSLCertificateError(ssl_error_handler_delegate_->GetWeakPtr(),
- RESOURCE_TYPE_SUB_RESOURCE,
- url,
- dispatcher_->render_process_id(),
- render_frame_id_,
- ssl_info,
- fatal);
+ new SSLErrorHandlerDelegate(std::move(callbacks)));
+ SSLManager::OnSSLCertificateSubresourceError(
+ ssl_error_handler_delegate_->GetWeakPtr(), url,
+ dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal);
// The above method is always asynchronous.
return WebSocketEventInterface::CHANNEL_ALIVE;
}
WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate(
scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks)
- : callbacks_(callbacks.Pass()), weak_ptr_factory_(this) {}
+ : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {}
WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {}
@@ -330,7 +329,8 @@ WebSocketHost::WebSocketHost(int routing_id,
WebSocketHost::~WebSocketHost() {}
void WebSocketHost::GoAway() {
- OnDropChannel(false, static_cast<uint16>(net::kWebSocketErrorGoingAway), "");
+ OnDropChannel(false, static_cast<uint16_t>(net::kWebSocketErrorGoingAway),
+ "");
}
bool WebSocketHost::OnMessageReceived(const IPC::Message& message) {
@@ -384,8 +384,8 @@ void WebSocketHost::AddChannel(
scoped_ptr<net::WebSocketEventInterface> event_interface(
new WebSocketEventHandler(dispatcher_, routing_id_, render_frame_id));
- channel_.reset(
- new net::WebSocketChannel(event_interface.Pass(), url_request_context_));
+ channel_.reset(new net::WebSocketChannel(std::move(event_interface),
+ url_request_context_));
if (pending_flow_control_quota_ > 0) {
// channel_->SendFlowControl(pending_flow_control_quota_) must be called
@@ -415,7 +415,7 @@ void WebSocketHost::OnSendFrame(bool fin,
channel_->SendFrame(fin, MessageTypeToOpCode(type), data);
}
-void WebSocketHost::OnFlowControl(int64 quota) {
+void WebSocketHost::OnFlowControl(int64_t quota) {
DVLOG(3) << "WebSocketHost::OnFlowControl"
<< " routing_id=" << routing_id_ << " quota=" << quota;
@@ -431,7 +431,7 @@ void WebSocketHost::OnFlowControl(int64 quota) {
}
void WebSocketHost::OnDropChannel(bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) {
DVLOG(3) << "WebSocketHost::OnDropChannel"
<< " routing_id=" << routing_id_ << " was_clean=" << was_clean
diff --git a/chromium/content/browser/renderer_host/websocket_host.h b/chromium/content/browser/renderer_host/websocket_host.h
index 89b368685d6..efdc9d1bd00 100644
--- a/chromium/content/browser/renderer_host/websocket_host.h
+++ b/chromium/content/browser/renderer_host/websocket_host.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_HOST_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
@@ -74,9 +77,9 @@ class CONTENT_EXPORT WebSocketHost {
WebSocketMessageType type,
const std::vector<char>& data);
- void OnFlowControl(int64 quota);
+ void OnFlowControl(int64_t quota);
- void OnDropChannel(bool was_clean, uint16 code, const std::string& reason);
+ void OnDropChannel(bool was_clean, uint16_t code, const std::string& reason);
// The channel we use to send events to the network.
scoped_ptr<net::WebSocketChannel> channel_;
diff --git a/chromium/content/browser/resource_context_impl.cc b/chromium/content/browser/resource_context_impl.cc
index b99c80d54ab..a4f0303e0da 100644
--- a/chromium/content/browser/resource_context_impl.cc
+++ b/chromium/content/browser/resource_context_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/resource_context_impl.h"
+#include <stdint.h>
+
#include "base/logging.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
@@ -59,7 +61,7 @@ scoped_ptr<net::ClientCertStore> ResourceContext::CreateClientCertStore() {
}
void ResourceContext::CreateKeygenHandler(
- uint32 key_size_in_bits,
+ uint32_t key_size_in_bits,
const std::string& challenge_string,
const GURL& url,
const base::Callback<void(scoped_ptr<net::KeygenHandler>)>& callback) {
diff --git a/chromium/content/browser/resource_loading_browsertest.cc b/chromium/content/browser/resource_loading_browsertest.cc
index 5765fe33132..c68d577c958 100644
--- a/chromium/content/browser/resource_loading_browsertest.cc
+++ b/chromium/content/browser/resource_loading_browsertest.cc
@@ -16,12 +16,12 @@ class ResourceLoadingBrowserTest : public ContentBrowserTest {
};
const char kResourceLoadingNonMobilePage[] =
- "files/resource_loading/resource_loading_non_mobile.html";
+ "/resource_loading/resource_loading_non_mobile.html";
IN_PROC_BROWSER_TEST_F(ResourceLoadingBrowserTest,
ResourceLoadingAvoidDoubleDownloads) {
- ASSERT_TRUE(test_server()->Start());
- GURL url = test_server()->GetURL(kResourceLoadingNonMobilePage);
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL(kResourceLoadingNonMobilePage);
NavigateToURL(shell(), url);
int data = -1;
EXPECT_TRUE(ExecuteScriptAndExtractInt(shell()->web_contents(),
@@ -30,4 +30,3 @@ IN_PROC_BROWSER_TEST_F(ResourceLoadingBrowserTest,
}
} // namespace content
-
diff --git a/chromium/content/browser/resources/accessibility/accessibility.html b/chromium/content/browser/resources/accessibility/accessibility.html
index 888a16c795c..1d8efd302a7 100644
--- a/chromium/content/browser/resources/accessibility/accessibility.html
+++ b/chromium/content/browser/resources/accessibility/accessibility.html
@@ -22,6 +22,9 @@ found in the LICENSE file.
<div id="global" class="row">Global accessibility mode:
<a is="action-link" role="button" id="toggle_global" aria-labelledby="global"></a>
</div>
+ <div id="internal" class="row">Show internal accessibility tree instead of native:
+ <a is="action-link" role="button" id="toggle_internal" aria-labelledby="internal"></a>
+ </div>
<div id="pages" class="list"></div>
<script src="chrome://resources/js/i18n_template.js"></script>
</body>
diff --git a/chromium/content/browser/resources/accessibility/accessibility.js b/chromium/content/browser/resources/accessibility/accessibility.js
index 7277dd2713c..64a68736c60 100644
--- a/chromium/content/browser/resources/accessibility/accessibility.js
+++ b/chromium/content/browser/resources/accessibility/accessibility.js
@@ -63,12 +63,19 @@ cr.define('accessibility', function() {
document.location.reload(); // FIXME see TODO above
}
+ function toggleInternalTree() {
+ chrome.send('toggleInternalTree');
+ document.location.reload(); // FIXME see TODO above
+ }
+
function initialize() {
console.log('initialize');
var data = requestData();
addGlobalAccessibilityModeToggle(data['global_a11y_mode']);
+ addInternalTreeToggle(data['global_internal_tree_mode']);
+
$('pages').textContent = '';
var list = data['list'];
@@ -86,6 +93,15 @@ cr.define('accessibility', function() {
toggleGlobalAccessibility);
}
+ function addInternalTreeToggle(global_internal_tree_mode) {
+ var on = global_internal_tree_mode;
+ $('toggle_internal').textContent = (on ? 'on' : 'off');
+ $('toggle_internal').setAttribute('aria-pressed',
+ (on ? 'true' : 'false'));
+ $('toggle_internal').addEventListener('click',
+ toggleInternalTree);
+ }
+
function addToPagesList(data) {
// TODO: iterate through data and pages rows instead
var id = data['processId'] + '.' + data['routeId'];
diff --git a/chromium/content/browser/resources/gpu/browser_bridge.js b/chromium/content/browser/resources/gpu/browser_bridge.js
index cb4133a3398..b835f44207c 100644
--- a/chromium/content/browser/resources/gpu/browser_bridge.js
+++ b/chromium/content/browser/resources/gpu/browser_bridge.js
@@ -36,9 +36,11 @@ cr.define('gpu', function() {
applySimulatedData_: function applySimulatedData(data) {
// set up things according to the simulated data
this.gpuInfo_ = data.gpuInfo;
+ this.gpuMemoryBufferInfo_ = data.gpuMemoryBufferInfo;
this.clientInfo_ = data.clientInfo;
this.logMessages_ = data.logMessages;
cr.dispatchSimpleEvent(this, 'gpuInfoUpdate');
+ cr.dispatchSimpleEvent(this, 'gpuMemoryBufferInfoUpdate');
cr.dispatchSimpleEvent(this, 'clientInfoChange');
cr.dispatchSimpleEvent(this, 'logMessagesChange');
},
@@ -95,6 +97,21 @@ cr.define('gpu', function() {
},
/**
+ * Get gpuMemoryBufferInfo data.
+ */
+ get gpuMemoryBufferInfo() {
+ return this.gpuMemoryBufferInfo_;
+ },
+
+ /**
+ * Called from gpu c++ code when GpuMemoryBuffer Info is updated.
+ */
+ onGpuMemoryBufferInfoUpdate: function(gpuMemoryBufferInfo) {
+ this.gpuMemoryBufferInfo_ = gpuMemoryBufferInfo;
+ cr.dispatchSimpleEvent(this, 'gpuMemoryBufferInfoUpdate');
+ },
+
+ /**
* This function begins a request for the ClientInfo. If it comes back
* as undefined, then we will issue the request again in 250ms.
*/
@@ -139,6 +156,17 @@ cr.define('gpu', function() {
return this.logMessages_;
},
+ /**
+ * Returns the value of the "Sandboxed" row.
+ */
+ isSandboxedForTesting : function() {
+ for (i = 0; i < this.gpuInfo_.basic_info.length; ++i) {
+ var info = this.gpuInfo_.basic_info[i];
+ if (info.description == "Sandboxed")
+ return info.value;
+ }
+ return false;
+ }
};
return {
diff --git a/chromium/content/browser/resources/gpu/browser_bridge_tests.js b/chromium/content/browser/resources/gpu/browser_bridge_tests.js
index ebff6a775ce..6a3a375bc64 100644
--- a/chromium/content/browser/resources/gpu/browser_bridge_tests.js
+++ b/chromium/content/browser/resources/gpu/browser_bridge_tests.js
@@ -3,7 +3,6 @@
// found in the LICENSE file.
var commandLineFlags = ['--flag-switches-begin',
'--show-composited-layer-borders',
- '--show-fps-counter',
'--flag-switches-end'];
var commandLineStr = './out/Debug/chrome ' + commandLineFlags.join(' ');
diff --git a/chromium/content/browser/resources/gpu/info_view.html b/chromium/content/browser/resources/gpu/info_view.html
index 7a4fade55b4..da813fc8dba 100644
--- a/chromium/content/browser/resources/gpu/info_view.html
+++ b/chromium/content/browser/resources/gpu/info_view.html
@@ -23,6 +23,11 @@ found in the LICENSE file.
</div>
<div>
+ <h3>GpuMemoryBuffer Status</h3>
+ <div id="gpu-memory-buffer-info"></div>
+ </div>
+
+ <div>
<h3>Version Information</h3>
<div id="client-info"></div>
</div>
diff --git a/chromium/content/browser/resources/gpu/info_view.js b/chromium/content/browser/resources/gpu/info_view.js
index 20c6b8e9cc8..3566369cd70 100644
--- a/chromium/content/browser/resources/gpu/info_view.js
+++ b/chromium/content/browser/resources/gpu/info_view.js
@@ -23,6 +23,8 @@ cr.define('gpu', function() {
cr.ui.TabPanel.prototype.decorate.apply(this);
browserBridge.addEventListener('gpuInfoUpdate', this.refresh.bind(this));
+ browserBridge.addEventListener('gpuMemoryBufferInfoUpdate',
+ this.refresh.bind(this));
browserBridge.addEventListener('logMessagesChange',
this.refresh.bind(this));
browserBridge.addEventListener('clientInfoChange',
@@ -152,6 +154,7 @@ cr.define('gpu', function() {
var workaroundsDiv = this.querySelector('.workarounds-div');
var workaroundsList = this.querySelector('.workarounds-list');
var gpuInfo = browserBridge.gpuInfo;
+ var gpuMemoryBufferInfo = browserBridge.gpuMemoryBufferInfo;
var i;
if (gpuInfo) {
// Not using jstemplate here for blacklist status because we construct
@@ -216,6 +219,12 @@ cr.define('gpu', function() {
problemsList.hidden = true;
workaroundsList.hidden = true;
}
+ if (gpuMemoryBufferInfo.gpu_memory_buffer_info)
+ this.setTable_('gpu-memory-buffer-info',
+ gpuMemoryBufferInfo.gpu_memory_buffer_info);
+ else
+ this.setTable_('gpu-memory-buffer-info', []);
+
if (gpuInfo.basic_info)
this.setTable_('basic-info', gpuInfo.basic_info);
else
diff --git a/chromium/content/browser/resources/media/dump_creator.js b/chromium/content/browser/resources/media/dump_creator.js
index 6aca1b698b6..75076493e16 100644
--- a/chromium/content/browser/resources/media/dump_creator.js
+++ b/chromium/content/browser/resources/media/dump_creator.js
@@ -52,12 +52,30 @@ var DumpCreator = (function() {
' enabled using the same base filename, the files will be appended' +
' to and may become invalid. It is recommended to choose a new base' +
' filename each time or move the produced files before enabling' +
- ' again.</p>';
-
+ ' again.</p>' +
+ '<p><label><input type=checkbox>' +
+ 'Enable diagnostic packet and event recording</label></p>' +
+ '<p class=audio-recordings-info>A diagnostic packet and event' +
+ ' recording can be used for analyzing various issues related to' +
+ ' thread starvation, jitter buffers or bandwidth estimation. Two' +
+ ' types of data are logged. First, incoming and outgoing RTP headers' +
+ ' and RTCP packets are logged. These do not include any audio or' +
+ ' video information, nor any other types of personally identifiable' +
+ ' information (so no IP addresses or URLs). Checking this box will' +
+ ' enable the recording for ongoing WebRTC calls and for future' +
+ ' WebRTC calls. When the box is unchecked or this page is closed,' +
+ ' all ongoing recordings will be stopped and this recording' +
+ ' functionality will be disabled for future WebRTC calls. Recording' +
+ ' in multiple tabs or multiple recordings in the same tab is' +
+ ' currently not supported. When enabling, a filename for the' +
+ ' recording can be selected. If an existing file is selected, it' +
+ ' will be overwritten. </p>';
content.getElementsByTagName('a')[0].addEventListener(
'click', this.onDownloadData_.bind(this));
content.getElementsByTagName('input')[0].addEventListener(
'click', this.onAudioDebugRecordingsChanged_.bind(this));
+ content.getElementsByTagName('input')[1].addEventListener(
+ 'click', this.onEventLogRecordingsChanged_.bind(this));
}
DumpCreator.prototype = {
@@ -71,6 +89,16 @@ var DumpCreator = (function() {
this.root_.getElementsByTagName('input')[0].checked = false;
},
+ // Mark the event log recording checkbox checked.
+ enableEventLogRecordings: function() {
+ this.root_.getElementsByTagName('input')[1].checked = true;
+ },
+
+ // Mark the event log recording checkbox unchecked.
+ disableEventLogRecordings: function() {
+ this.root_.getElementsByTagName('input')[1].checked = false;
+ },
+
/**
* Downloads the PeerConnection updates and stats data as a file.
*
@@ -105,6 +133,20 @@ var DumpCreator = (function() {
chrome.send('disableAudioDebugRecordings');
}
},
+
+ /**
+ * Handles the event of toggling the event log recordings state.
+ *
+ * @private
+ */
+ onEventLogRecordingsChanged_: function() {
+ var enabled = this.root_.getElementsByTagName('input')[1].checked;
+ if (enabled) {
+ chrome.send('enableEventLogRecordings');
+ } else {
+ chrome.send('disableEventLogRecordings');
+ }
+ },
};
return DumpCreator;
})();
diff --git a/chromium/content/browser/resources/media/manager.js b/chromium/content/browser/resources/media/manager.js
index b335349fc34..27f6b990edd 100644
--- a/chromium/content/browser/resources/media/manager.js
+++ b/chromium/content/browser/resources/media/manager.js
@@ -117,24 +117,33 @@ var Manager = (function() {
* Example:
*
* format:
- * "resolution: 1280x720, fps: 30.000000, pixel format: I420"
+ * "(160x120)@30.000fps, pixel format: PIXEL_FORMAT_I420, storage: CPU"
*
* formatDict:
- * {'resolution':'1280x720', 'fps': '30.00'}
+ * {'resolution':'1280x720', 'fps': '30.00', "storage: "CPU" }
*/
var parts = format.split(', ');
var formatDict = {};
for (var i in parts) {
var kv = parts[i].split(': ');
- formatDict[kv[0]] = kv[1];
+ if (kv.length == 2) {
+ if (kv[0] == 'pixel format') {
+ // The camera does not actually output I420,
+ // so this info is misleading.
+ continue;
+ }
+ formatDict[kv[0]] = kv[1];
+ } else {
+ kv = parts[i].split("@");
+ if (kv.length == 2) {
+ formatDict['resolution'] = kv[0].replace(/[)(]/g, '');
+ // Round down the FPS to 2 decimals.
+ formatDict['fps'] =
+ parseFloat(kv[1].replace(/fps$/, '')).toFixed(2);
+ }
+ }
}
- // Round down the FPS to 2 decimals.
- formatDict['fps'] = parseFloat(formatDict['fps']).toFixed(2);
-
- // The camera does not actually output I420 so this info is misleading.
- delete formatDict['pixel format'];
-
return formatDict;
},
diff --git a/chromium/content/browser/resources/media/webrtc_internals.js b/chromium/content/browser/resources/media/webrtc_internals.js
index 5b3bb0d4d6f..5ccdf399e97 100644
--- a/chromium/content/browser/resources/media/webrtc_internals.js
+++ b/chromium/content/browser/resources/media/webrtc_internals.js
@@ -332,6 +332,14 @@ function audioDebugRecordingsFileSelectionCancelled() {
/**
+ * Notification that the event log recordings file selection dialog was
+ * cancelled, i.e. recordings have not been enabled.
+ */
+function eventLogRecordingsFileSelectionCancelled() {
+ dumpCreator.disableEventLogRecordings();
+}
+
+/**
* Set
*/
function enableAudioDebugRecordings() {
diff --git a/chromium/content/browser/resources/net/network_errors_listing.css b/chromium/content/browser/resources/net/network_errors_listing.css
new file mode 100644
index 00000000000..1c05bda46a6
--- /dev/null
+++ b/chromium/content/browser/resources/net/network_errors_listing.css
@@ -0,0 +1,16 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+body {
+ margin: 10px 10px 30px;
+}
+
+ul {
+ line-height: 1.7em;
+ padding-left: 15px;
+}
+
+a {
+ word-break: break-word;
+} \ No newline at end of file
diff --git a/chromium/content/browser/resources/net/network_errors_listing.html b/chromium/content/browser/resources/net/network_errors_listing.html
new file mode 100644
index 00000000000..ebc4bbb6f38
--- /dev/null
+++ b/chromium/content/browser/resources/net/network_errors_listing.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+<!--
+Copyright 2015 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Network errors</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" href="chrome://resources/css/roboto.css">
+ <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
+ <link rel="stylesheet" href="network_errors_listing.css">
+ <script src="chrome://resources/js/cr.js"></script>
+ <script src="chrome://resources/js/load_time_data.js"></script>
+ <script src="chrome://resources/js/util.js"></script>
+ <script src="strings.js"></script>
+ <script src="network_errors_listing.js"></script>
+</head>
+<body>
+ <h1>Network errors</h1>
+ <div id="pages" class="list"></div>
+
+ <script src="chrome://resources/js/i18n_template.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/chromium/content/browser/resources/net/network_errors_listing.js b/chromium/content/browser/resources/net/network_errors_listing.js
new file mode 100644
index 00000000000..04bb8c22ca0
--- /dev/null
+++ b/chromium/content/browser/resources/net/network_errors_listing.js
@@ -0,0 +1,50 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('errorCodes', function() {
+ 'use strict';
+
+ /**
+ * Generate the page content.
+ * @param {Array.<Object>} errorCodes Error codes array consisting of a
+ * numerical error ID and error code string.
+ */
+ function listErrorCodes(errorCodes) {
+ var errorPageUrl = 'chrome://network-error/';
+ var errorCodesList = document.createElement('ul');
+ for (var i = 0; i < errorCodes.length; i++) {
+ var listEl = document.createElement('li');
+ var errorCodeLinkEl = document.createElement('a');
+ errorCodeLinkEl.href = errorPageUrl + errorCodes[i].errorId;
+ errorCodeLinkEl.textContent = errorCodes[i].errorCode + ' (' +
+ errorCodes[i].errorId + ')';
+ listEl.appendChild(errorCodeLinkEl);
+ errorCodesList.appendChild(listEl);
+ }
+ $('pages').appendChild(errorCodesList);
+ }
+
+ function initialize() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'network-error-data.json');
+ xhr.addEventListener('load', function(e) {
+ if (xhr.status === 200) {
+ try {
+ var data = JSON.parse(xhr.responseText);
+ listErrorCodes(data['errorCodes']);
+ } catch (e) {
+ $('pages').innerText = 'Could not parse the error codes data. ' +
+ 'Try reloading the page.';
+ }
+ }
+ });
+ xhr.send();
+ }
+
+ return {
+ initialize: initialize
+ };
+});
+
+document.addEventListener('DOMContentLoaded', errorCodes.initialize); \ No newline at end of file
diff --git a/chromium/content/browser/safe_util_win.cc b/chromium/content/browser/safe_util_win.cc
index 2a1f18c7679..820aab5b468 100644
--- a/chromium/content/browser/safe_util_win.cc
+++ b/chromium/content/browser/safe_util_win.cc
@@ -9,6 +9,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_comptr.h"
diff --git a/chromium/content/browser/safe_util_win.h b/chromium/content/browser/safe_util_win.h
index a668e95bc0c..ce044c79a94 100644
--- a/chromium/content/browser/safe_util_win.h
+++ b/chromium/content/browser/safe_util_win.h
@@ -23,7 +23,7 @@ namespace content {
//
// If Attachment Execution Services is unavailable, then this function will
// attempt to manually annotate the file with security zone information. A
-// failure code will be returned in this case even if the file is sucessfully
+// failure code will be returned in this case even if the file is successfully
// annotated.
//
// IAE::Save() will delete the file if it was found to be blocked by local
diff --git a/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc b/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
index 2d7445c3af8..77675b994cb 100644
--- a/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
+++ b/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
@@ -5,6 +5,8 @@
#include <stdlib.h>
#include "base/command_line.h"
+#include "base/macros.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_widget_host.h"
@@ -21,10 +23,6 @@
#include "third_party/WebKit/public/platform/WebScreenInfo.h"
#include "ui/compositor/compositor_switches.h"
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif // OS_WIN
-
namespace content {
class ScreenOrientationBrowserTest : public ContentBrowserTest {
@@ -127,15 +125,6 @@ IN_PROC_BROWSER_TEST_F(ScreenOrientationBrowserTest,
navigation_observer.Wait();
WaitForResizeComplete(shell()->web_contents());
-#if defined(OS_WIN)
- // Screen Orientation is currently disabled on Windows 8.
- // This test will break, requiring an update when the API will be enabled.
- if (base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_WIN8) {
- EXPECT_EQ(false, ScreenOrientationSupported());
- return;
- }
-#endif // defined(OS_WIN)
-
int angle = GetOrientationAngle();
for (int i = 0; i < 4; ++i) {
@@ -193,15 +182,6 @@ IN_PROC_BROWSER_TEST_F(ScreenOrientationBrowserTest, DISABLED_LockSmoke) {
TestNavigationObserver navigation_observer(shell()->web_contents(), 2);
shell()->LoadURL(test_url);
-#if defined(OS_WIN)
- // Screen Orientation is currently disabled on Windows 8.
- // This test will break, requiring an update when the API will be enabled.
- if (base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_WIN8) {
- EXPECT_EQ(false, ScreenOrientationSupported());
- return;
- }
-#endif // defined(OS_WIN)
-
navigation_observer.Wait();
#if USE_AURA || defined(OS_ANDROID)
WaitForResizeComplete(shell()->web_contents());
@@ -228,15 +208,6 @@ IN_PROC_BROWSER_TEST_F(ScreenOrientationBrowserTest, CrashTest_UseAfterDetach) {
TestNavigationObserver navigation_observer(shell()->web_contents(), 2);
shell()->LoadURL(test_url);
-#if defined(OS_WIN)
- // Screen Orientation is currently disabled on Windows 8.
- // When implemented, this test will break, requiring an update.
- if (base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_WIN8) {
- EXPECT_EQ(false, ScreenOrientationSupported());
- return;
- }
-#endif // defined(OS_WIN)
-
navigation_observer.Wait();
// This is a success if the renderer process did not crash, thus, we end up
diff --git a/chromium/content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h b/chromium/content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h
index 1b90f77f3a2..972a42d49de 100644
--- a/chromium/content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h
+++ b/chromium/content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_SCREEN_ORIENTATION_SCREEN_ORIENTATION_DISPATCHER_HOST_IMPL_H_
#define CONTENT_BROWSER_SCREEN_ORIENTATION_SCREEN_ORIENTATION_DISPATCHER_HOST_IMPL_H_
+#include "base/macros.h"
#include "content/public/browser/screen_orientation_dispatcher_host.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/WebKit/public/platform/modules/screen_orientation/WebLockOrientationError.h"
diff --git a/chromium/content/browser/screen_orientation/screen_orientation_message_filter_android.h b/chromium/content/browser/screen_orientation/screen_orientation_message_filter_android.h
index 9d85fe62010..be506f3cb0c 100644
--- a/chromium/content/browser/screen_orientation/screen_orientation_message_filter_android.h
+++ b/chromium/content/browser/screen_orientation/screen_orientation_message_filter_android.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_SCREEN_ORIENTATION_SCREEN_ORIENTATION_MESSAGE_FILTER_ANDROID_H_
#define CONTENT_BROWSER_SCREEN_ORIENTATION_SCREEN_ORIENTATION_MESSAGE_FILTER_ANDROID_H_
+#include "base/macros.h"
#include "content/public/browser/browser_message_filter.h"
namespace content {
diff --git a/chromium/content/browser/security_exploit_browsertest.cc b/chromium/content/browser/security_exploit_browsertest.cc
index 2c5acc4c48d..c515609c576 100644
--- a/chromium/content/browser/security_exploit_browsertest.cc
+++ b/chromium/content/browser/security_exploit_browsertest.cc
@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/command_line.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.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/navigator.h"
@@ -21,6 +25,7 @@
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/appcache_info.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/test/browser_test_utils.h"
@@ -81,13 +86,10 @@ RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell,
// speculative/pending RenderFrameHost. Ensure it exists and is in a different
// process than the initial page.
RenderFrameHostImpl* next_rfh;
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
- next_rfh =
- wc->GetRenderManagerForTesting()->speculative_frame_host();
- } else {
+ if (IsBrowserSideNavigationEnabled())
+ next_rfh = wc->GetRenderManagerForTesting()->speculative_frame_host();
+ else
next_rfh = wc->GetRenderManagerForTesting()->pending_frame_host();
- }
EXPECT_TRUE(next_rfh);
EXPECT_NE(shell->web_contents()->GetRenderProcessHost()->GetID(),
@@ -130,7 +132,7 @@ class SecurityExploitBrowserTest : public ContentBrowserTest {
SecurityExploitBrowserTest() {}
void SetUpCommandLine(base::CommandLine* command_line) override {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
// Add a host resolver rule to map all outgoing requests to the test server.
// This allows us to use "real" hostnames in URLs, which we can use to
@@ -196,7 +198,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, SetWebUIProperty) {
// process.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
AttemptDuplicateRenderViewHost) {
- int duplicate_routing_id = MSG_ROUTING_NONE;
+ int32_t duplicate_routing_id = MSG_ROUTING_NONE;
RenderViewHostImpl* pending_rvh =
PrepareToDuplicateHosts(shell(), &duplicate_routing_id);
EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id);
@@ -213,10 +215,12 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
scoped_refptr<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,
+ int32_t main_frame_routing_id = duplicate_routing_id + 1;
+ // TODO(avi): This should be made unique from the view routing ID once
+ // RenderViewHostImpl has-a RenderWidgetHostImpl. https://crbug.com/545684
+ int32_t main_frame_widget_routing_id = duplicate_routing_id;
+ pending_rvh->CreateNewWindow(duplicate_routing_id, main_frame_routing_id,
+ main_frame_widget_routing_id, params,
session_storage.get());
// If the above operation doesn't cause a crash, the test has succeeded!
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.cc b/chromium/content/browser/service_worker/embedded_worker_instance.cc
index 18aed6440c8..9d3290b6d63 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.cc
@@ -4,7 +4,10 @@
#include "content/browser/service_worker/embedded_worker_instance.h"
+#include <utility>
+
#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/non_thread_safe.h"
#include "base/trace_event/trace_event.h"
@@ -18,6 +21,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/common/child_process_host.h"
#include "ipc/ipc_message.h"
#include "url/gurl.h"
@@ -48,7 +52,7 @@ void RegisterToWorkerDevToolsManagerOnUI(
int process_id,
const ServiceWorkerContextCore* service_worker_context,
const base::WeakPtr<ServiceWorkerContextCore>& service_worker_context_weak,
- int64 service_worker_version_id,
+ int64_t service_worker_version_id,
const GURL& url,
const base::Callback<void(int worker_devtools_agent_route_id,
bool wait_for_debugger)>& callback) {
@@ -74,18 +78,19 @@ void RegisterToWorkerDevToolsManagerOnUI(
base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger));
}
-void SetupMojoOnUIThread(int process_id,
- int thread_id,
- mojo::InterfaceRequest<mojo::ServiceProvider> services,
- mojo::ServiceProviderPtr exposed_services) {
+void SetupMojoOnUIThread(
+ int process_id,
+ int thread_id,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::InterfacePtrInfo<mojo::ServiceProvider> exposed_services) {
RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
- // |rph| may be NULL in unit tests.
- if (!rph)
+ // |rph| or its ServiceRegistry may be NULL in unit tests.
+ if (!rph || !rph->GetServiceRegistry())
return;
EmbeddedWorkerSetupPtr setup;
rph->GetServiceRegistry()->ConnectToRemoteService(mojo::GetProxy(&setup));
- setup->ExchangeServiceProviders(thread_id, services.Pass(),
- exposed_services.Pass());
+ setup->ExchangeServiceProviders(thread_id, std::move(services),
+ mojo::MakeProxy(std::move(exposed_services)));
}
} // namespace
@@ -129,16 +134,198 @@ class EmbeddedWorkerInstance::DevToolsProxy : public base::NonThreadSafe {
DISALLOW_COPY_AND_ASSIGN(DevToolsProxy);
};
+// A handle for a worker process managed by ServiceWorkerProcessManager on the
+// UI thread.
+class EmbeddedWorkerInstance::WorkerProcessHandle {
+ public:
+ WorkerProcessHandle(const base::WeakPtr<ServiceWorkerContextCore>& context,
+ int embedded_worker_id,
+ int process_id)
+ : context_(context),
+ embedded_worker_id_(embedded_worker_id),
+ process_id_(process_id) {
+ DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id_);
+ }
+
+ ~WorkerProcessHandle() {
+ if (context_)
+ context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
+ }
+
+ int process_id() const { return process_id_; }
+
+ private:
+ base::WeakPtr<ServiceWorkerContextCore> context_;
+
+ const int embedded_worker_id_;
+ const int process_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerProcessHandle);
+};
+
+// A task to allocate a worker process and to send a start worker message. This
+// is created on EmbeddedWorkerInstance::Start(), owned by the instance and
+// destroyed on EmbeddedWorkerInstance::OnScriptEvaluated().
+// We can abort starting worker by destroying this task anytime during the
+// sequence.
+class EmbeddedWorkerInstance::StartTask {
+ public:
+ enum class ProcessAllocationState { NOT_ALLOCATED, ALLOCATING, ALLOCATED };
+
+ explicit StartTask(EmbeddedWorkerInstance* instance)
+ : instance_(instance),
+ state_(ProcessAllocationState::NOT_ALLOCATED),
+ weak_factory_(this) {}
+
+ ~StartTask() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!instance_->context_)
+ return;
+
+ switch (state_) {
+ case ProcessAllocationState::NOT_ALLOCATED:
+ // Not necessary to release a process.
+ break;
+ case ProcessAllocationState::ALLOCATING:
+ // Abort half-baked process allocation on the UI thread.
+ instance_->context_->process_manager()->ReleaseWorkerProcess(
+ instance_->embedded_worker_id());
+ break;
+ case ProcessAllocationState::ALLOCATED:
+ // Otherwise, the process will be released by EmbeddedWorkerInstance.
+ break;
+ }
+
+ // Don't have to abort |start_callback_| here. The caller of
+ // EmbeddedWorkerInstance::Start(), that is, ServiceWorkerVersion does not
+ // expect it when the start worker sequence is canceled by Stop() because
+ // the callback, ServiceWorkerVersion::OnStartSentAndScriptEvaluated(),
+ // could drain valid start requests queued in the version. After the worker
+ // is stopped, the version attempts to restart the worker if there are
+ // requests in the queue. See ServiceWorkerVersion::OnStoppedInternal() for
+ // details.
+ // TODO(nhiroki): Reconsider this bizarre layering.
+ }
+
+ void Start(scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
+ const StatusCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
+ "EmbeddedWorkerInstance::ProcessAllocate",
+ params.get(), "Scope", params->scope.spec(),
+ "Script URL", params->script_url.spec());
+ state_ = ProcessAllocationState::ALLOCATING;
+ start_callback_ = callback;
+
+ GURL scope(params->scope);
+ GURL script_url(params->script_url);
+ instance_->context_->process_manager()->AllocateWorkerProcess(
+ instance_->embedded_worker_id(), scope, script_url,
+ base::Bind(&StartTask::OnProcessAllocated, weak_factory_.GetWeakPtr(),
+ base::Passed(&params)));
+ }
+
+ static void RunStartCallback(StartTask* task,
+ ServiceWorkerStatusCode status) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ StatusCallback callback = task->start_callback_;
+ task->start_callback_.Reset();
+ callback.Run(status);
+ // |task| may be destroyed.
+ }
+
+ private:
+ void OnProcessAllocated(
+ scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
+ ServiceWorkerStatusCode status,
+ int process_id,
+ bool is_new_process) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT_ASYNC_END1("ServiceWorker",
+ "EmbeddedWorkerInstance::ProcessAllocate",
+ params.get(), "Status", status);
+
+ if (status != SERVICE_WORKER_OK) {
+ DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, process_id);
+ StatusCallback callback = start_callback_;
+ start_callback_.Reset();
+ instance_->OnStartFailed(callback, status);
+ // |this| may be destroyed.
+ return;
+ }
+
+ // Notify the instance that a process is allocated.
+ state_ = ProcessAllocationState::ALLOCATED;
+ instance_->OnProcessAllocated(make_scoped_ptr(new WorkerProcessHandle(
+ instance_->context_, instance_->embedded_worker_id(), process_id)));
+
+ // Register the instance to DevToolsManager on UI thread.
+ const int64_t service_worker_version_id = params->service_worker_version_id;
+ GURL script_url(params->script_url);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(RegisterToWorkerDevToolsManagerOnUI, process_id,
+ instance_->context_.get(), instance_->context_,
+ service_worker_version_id, script_url,
+ base::Bind(&StartTask::OnRegisteredToDevToolsManager,
+ weak_factory_.GetWeakPtr(), base::Passed(&params),
+ is_new_process)));
+ }
+
+ void OnRegisteredToDevToolsManager(
+ scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
+ bool is_new_process,
+ int worker_devtools_agent_route_id,
+ bool wait_for_debugger) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Notify the instance that it is registered to the devtools manager.
+ instance_->OnRegisteredToDevToolsManager(
+ is_new_process, worker_devtools_agent_route_id, wait_for_debugger);
+
+ params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
+ params->wait_for_debugger = wait_for_debugger;
+ SendStartWorker(std::move(params));
+ }
+
+ void SendStartWorker(
+ scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ServiceWorkerStatusCode status = instance_->registry_->SendStartWorker(
+ std::move(params), instance_->process_id());
+ if (status != SERVICE_WORKER_OK) {
+ StatusCallback callback = start_callback_;
+ start_callback_.Reset();
+ instance_->OnStartFailed(callback, status);
+ // |this| may be destroyed.
+ return;
+ }
+ instance_->OnStartWorkerMessageSent();
+
+ // |start_callback_| will be called via RunStartCallback() when the script
+ // is evaluated.
+ }
+
+ // |instance_| must outlive |this|.
+ EmbeddedWorkerInstance* instance_;
+
+ StatusCallback start_callback_;
+ ProcessAllocationState state_;
+
+ base::WeakPtrFactory<StartTask> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(StartTask);
+};
+
EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
DCHECK(status_ == STOPPING || status_ == STOPPED) << status_;
devtools_proxy_.reset();
- if (context_ && process_id_ != -1)
- context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
if (registry_->GetWorker(embedded_worker_id_))
- registry_->RemoveWorker(process_id_, embedded_worker_id_);
+ registry_->RemoveWorker(process_id(), embedded_worker_id_);
+ process_handle_.reset();
}
-void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
+void EmbeddedWorkerInstance::Start(int64_t service_worker_version_id,
const GURL& scope,
const GURL& script_url,
const StatusCallback& callback) {
@@ -148,19 +335,19 @@ void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
return;
}
DCHECK(status_ == STOPPED);
+
+ // TODO(horo): If we will see crashes here, we have to find the root cause of
+ // the invalid version ID. Otherwise change CHECK to DCHECK.
+ CHECK_NE(service_worker_version_id, kInvalidServiceWorkerVersionId);
start_timing_ = base::TimeTicks::Now();
status_ = STARTING;
starting_phase_ = ALLOCATING_PROCESS;
network_accessed_for_script_ = false;
service_registry_.reset(new ServiceRegistryImpl());
FOR_EACH_OBSERVER(Listener, listener_list_, OnStarting());
+
scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params(
new EmbeddedWorkerMsg_StartWorker_Params());
- TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
- "EmbeddedWorkerInstance::ProcessAllocate",
- params.get(),
- "Scope", scope.spec(),
- "Script URL", script_url.spec());
params->embedded_worker_id = embedded_worker_id_;
params->service_worker_version_id = service_worker_version_id;
params->scope = scope;
@@ -168,21 +355,19 @@ void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
params->worker_devtools_agent_route_id = MSG_ROUTING_NONE;
params->wait_for_debugger = false;
params->v8_cache_options = GetV8CacheOptions();
- context_->process_manager()->AllocateWorkerProcess(
- embedded_worker_id_,
- scope,
- script_url,
- base::Bind(&EmbeddedWorkerInstance::RunProcessAllocated,
- weak_factory_.GetWeakPtr(),
- context_,
- base::Passed(&params),
- callback));
+
+ inflight_start_task_.reset(new StartTask(this));
+ inflight_start_task_->Start(std::move(params), callback);
}
ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() {
DCHECK(status_ == STARTING || status_ == RUNNING) << status_;
+
+ // Abort an inflight start task.
+ inflight_start_task_.reset();
+
ServiceWorkerStatusCode status =
- registry_->StopWorker(process_id_, embedded_worker_id_);
+ registry_->StopWorker(process_id(), embedded_worker_id_);
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.SendStopWorker.Status", status,
SERVICE_WORKER_ERROR_MAX_VALUE);
// StopWorker could fail if we were starting up and don't have a process yet,
@@ -211,7 +396,7 @@ ServiceWorkerStatusCode EmbeddedWorkerInstance::SendMessage(
DCHECK_NE(kInvalidEmbeddedWorkerThreadId, thread_id_);
if (status_ != RUNNING && status_ != STARTING)
return SERVICE_WORKER_ERROR_IPC_FAILED;
- return registry_->Send(process_id_,
+ return registry_->Send(process_id(),
new EmbeddedWorkerContextMsg_MessageToWorker(
thread_id_, embedded_worker_id_, message));
}
@@ -229,93 +414,31 @@ EmbeddedWorkerInstance::EmbeddedWorkerInstance(
embedded_worker_id_(embedded_worker_id),
status_(STOPPED),
starting_phase_(NOT_STARTING),
- process_id_(-1),
thread_id_(kInvalidEmbeddedWorkerThreadId),
devtools_attached_(false),
network_accessed_for_script_(false),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
-// static
-void EmbeddedWorkerInstance::RunProcessAllocated(
- base::WeakPtr<EmbeddedWorkerInstance> instance,
- base::WeakPtr<ServiceWorkerContextCore> context,
- scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
- const EmbeddedWorkerInstance::StatusCallback& callback,
- ServiceWorkerStatusCode status,
- int process_id,
- bool is_new_process) {
- if (!context) {
- callback.Run(SERVICE_WORKER_ERROR_ABORT);
- return;
- }
- if (!instance) {
- if (status == SERVICE_WORKER_OK) {
- // We only have a process allocated if the status is OK.
- context->process_manager()->ReleaseWorkerProcess(
- params->embedded_worker_id);
- }
- callback.Run(SERVICE_WORKER_ERROR_ABORT);
- return;
- }
- instance->ProcessAllocated(params.Pass(), callback, process_id,
- is_new_process, status);
-}
+void EmbeddedWorkerInstance::OnProcessAllocated(
+ scoped_ptr<WorkerProcessHandle> handle) {
+ DCHECK_EQ(STARTING, status_);
+ DCHECK(!process_handle_);
-void EmbeddedWorkerInstance::ProcessAllocated(
- scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
- const StatusCallback& callback,
- int process_id,
- bool is_new_process,
- ServiceWorkerStatusCode status) {
- DCHECK_EQ(process_id_, -1);
- TRACE_EVENT_ASYNC_END1("ServiceWorker",
- "EmbeddedWorkerInstance::ProcessAllocate",
- params.get(),
- "Status", status);
- if (status != SERVICE_WORKER_OK) {
- OnStartFailed(callback, status);
- return;
- }
- const int64 service_worker_version_id = params->service_worker_version_id;
- process_id_ = process_id;
- GURL script_url(params->script_url);
-
- // Register this worker to DevToolsManager on UI thread, then continue to
- // call SendStartWorker on IO thread.
+ process_handle_ = std::move(handle);
starting_phase_ = REGISTERING_TO_DEVTOOLS;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(RegisterToWorkerDevToolsManagerOnUI, process_id_,
- context_.get(), context_, service_worker_version_id,
- script_url,
- base::Bind(&EmbeddedWorkerInstance::SendStartWorker,
- weak_factory_.GetWeakPtr(), base::Passed(&params),
- callback, is_new_process)));
+ FOR_EACH_OBSERVER(Listener, listener_list_, OnProcessAllocated());
}
-void EmbeddedWorkerInstance::SendStartWorker(
- scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
- const StatusCallback& callback,
+void EmbeddedWorkerInstance::OnRegisteredToDevToolsManager(
bool is_new_process,
int worker_devtools_agent_route_id,
bool wait_for_debugger) {
- // We may have been detached or stopped at some point during the start up
- // process, making process_id_ and other state invalid. If that happened,
- // abort instead of trying to send the IPC.
- if (status_ != STARTING) {
- OnStartFailed(callback, SERVICE_WORKER_ERROR_ABORT);
- return;
- }
-
if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) {
DCHECK(!devtools_proxy_);
- devtools_proxy_.reset(new DevToolsProxy(process_id_,
- worker_devtools_agent_route_id));
+ devtools_proxy_.reset(
+ new DevToolsProxy(process_id(), worker_devtools_agent_route_id));
}
- params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
- params->wait_for_debugger = wait_for_debugger;
- if (params->wait_for_debugger) {
+ if (wait_for_debugger) {
// We don't measure the start time when wait_for_debugger flag is set. So we
// set the NULL time here.
start_timing_ = base::TimeTicks();
@@ -334,16 +457,11 @@ void EmbeddedWorkerInstance::SendStartWorker(
// allocation time.
start_timing_ = base::TimeTicks::Now();
}
+}
+void EmbeddedWorkerInstance::OnStartWorkerMessageSent() {
starting_phase_ = SENT_START_WORKER;
- ServiceWorkerStatusCode status =
- registry_->SendStartWorker(params.Pass(), process_id_);
- if (status != SERVICE_WORKER_OK) {
- OnStartFailed(callback, status);
- return;
- }
- DCHECK(start_callback_.is_null());
- start_callback_ = callback;
+ FOR_EACH_OBSERVER(Listener, listener_list_, OnStartWorkerMessageSent());
}
void EmbeddedWorkerInstance::OnReadyForInspection() {
@@ -389,10 +507,10 @@ void EmbeddedWorkerInstance::OnThreadStarted(int thread_id) {
GetProxy(&services);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(SetupMojoOnUIThread, process_id_, thread_id_,
+ base::Bind(SetupMojoOnUIThread, process_id(), thread_id_,
base::Passed(&services_request),
- base::Passed(&exposed_services)));
- service_registry_->BindRemoteServiceProvider(services.Pass());
+ base::Passed(exposed_services.PassInterface())));
+ service_registry_->BindRemoteServiceProvider(std::move(services));
}
void EmbeddedWorkerInstance::OnScriptLoadFailed() {
@@ -400,19 +518,21 @@ void EmbeddedWorkerInstance::OnScriptLoadFailed() {
}
void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) {
- starting_phase_ = SCRIPT_EVALUATED;
- if (start_callback_.is_null()) {
- DVLOG(1) << "Received unexpected OnScriptEvaluated message.";
+ if (!inflight_start_task_)
return;
- }
+ DCHECK_EQ(STARTING, status_);
+
+ starting_phase_ = SCRIPT_EVALUATED;
if (success && !start_timing_.is_null()) {
UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ScriptEvaluate",
base::TimeTicks::Now() - start_timing_);
}
- StatusCallback callback = start_callback_;
- start_callback_.Reset();
- callback.Run(success ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED);
+
+ base::WeakPtr<EmbeddedWorkerInstance> weak_this = weak_factory_.GetWeakPtr();
+ StartTask::RunStartCallback(
+ inflight_start_task_.get(),
+ success ? SERVICE_WORKER_OK
+ : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED);
// |this| may be destroyed by the callback.
}
@@ -422,6 +542,7 @@ void EmbeddedWorkerInstance::OnStarted() {
return;
DCHECK(status_ == STARTING);
status_ = RUNNING;
+ inflight_start_task_.reset();
FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted());
}
@@ -438,7 +559,7 @@ void EmbeddedWorkerInstance::OnDetached() {
}
void EmbeddedWorkerInstance::Detach() {
- registry_->RemoveWorker(process_id_, embedded_worker_id_);
+ registry_->RemoveWorker(process_id(), embedded_worker_id_);
OnDetached();
}
@@ -475,6 +596,12 @@ void EmbeddedWorkerInstance::OnReportConsoleMessage(
source_identifier, message_level, message, line_number, source_url));
}
+int EmbeddedWorkerInstance::process_id() const {
+ if (process_handle_)
+ return process_handle_->process_id();
+ return ChildProcessHost::kInvalidUniqueID;
+}
+
int EmbeddedWorkerInstance::worker_devtools_agent_route_id() const {
if (devtools_proxy_)
return devtools_proxy_->agent_route_id();
@@ -483,7 +610,7 @@ int EmbeddedWorkerInstance::worker_devtools_agent_route_id() const {
MessagePortMessageFilter* EmbeddedWorkerInstance::message_port_message_filter()
const {
- return registry_->MessagePortMessageFilterForProcess(process_id_);
+ return registry_->MessagePortMessageFilterForProcess(process_id());
}
void EmbeddedWorkerInstance::AddListener(Listener* listener) {
@@ -500,14 +627,14 @@ void EmbeddedWorkerInstance::OnNetworkAccessedForScriptLoad() {
}
void EmbeddedWorkerInstance::ReleaseProcess() {
+ // Abort an inflight start task.
+ inflight_start_task_.reset();
+
devtools_proxy_.reset();
- if (context_ && process_id_ != -1)
- context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
+ process_handle_.reset();
status_ = STOPPED;
- process_id_ = -1;
- thread_id_ = -1;
+ thread_id_ = kInvalidEmbeddedWorkerThreadId;
service_registry_.reset();
- start_callback_.Reset();
}
void EmbeddedWorkerInstance::OnStartFailed(const StatusCallback& callback,
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.h b/chromium/content/browser/service_worker/embedded_worker_instance.h
index 60b3363fae0..a4ed91ca8a4 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.h
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.h
@@ -5,13 +5,15 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
@@ -74,9 +76,13 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
class Listener {
public:
virtual ~Listener() {}
- virtual void OnThreadStarted() {}
+
virtual void OnStarting() {}
+ virtual void OnProcessAllocated() {}
+ virtual void OnStartWorkerMessageSent() {}
+ virtual void OnThreadStarted() {}
virtual void OnStarted() {}
+
virtual void OnStopping() {}
// Received ACK from renderer that the worker context terminated.
virtual void OnStopped(Status old_status) {}
@@ -102,7 +108,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
// Starts the worker. It is invalid to call this when the worker is not in
// STOPPED status. |callback| is invoked after the worker script has been
// started and evaluated, or when an error occurs.
- void Start(int64 service_worker_version_id,
+ void Start(int64_t service_worker_version_id,
const GURL& scope,
const GURL& script_url,
const StatusCallback& callback);
@@ -133,7 +139,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
DCHECK_EQ(STARTING, status());
return starting_phase_;
}
- int process_id() const { return process_id_; }
+ int process_id() const;
int thread_id() const { return thread_id_; }
int worker_devtools_agent_route_id() const;
MessagePortMessageFilter* message_port_message_filter() const;
@@ -160,6 +166,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
private:
typedef base::ObserverList<Listener> ListenerList;
class DevToolsProxy;
+ class StartTask;
+ class WorkerProcessHandle;
friend class EmbeddedWorkerRegistry;
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, StartAndStop);
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, DetachDuringStart);
@@ -170,28 +178,17 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
EmbeddedWorkerInstance(base::WeakPtr<ServiceWorkerContextCore> context,
int embedded_worker_id);
- // Called back from ServiceWorkerProcessManager after Start() passes control
- // to the UI thread to acquire a reference to the process.
- static void RunProcessAllocated(
- base::WeakPtr<EmbeddedWorkerInstance> instance,
- base::WeakPtr<ServiceWorkerContextCore> context,
- scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
- const EmbeddedWorkerInstance::StatusCallback& callback,
- ServiceWorkerStatusCode status,
- int process_id,
- bool is_new_process);
- void ProcessAllocated(scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
- const StatusCallback& callback,
- int process_id,
- bool is_new_process,
- ServiceWorkerStatusCode status);
- // Called back after ProcessAllocated() passes control to the UI thread to
- // register to WorkerDevToolsManager.
- void SendStartWorker(scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
- const StatusCallback& callback,
- bool is_new_process,
- int worker_devtools_agent_route_id,
- bool wait_for_debugger);
+ // Called back from StartTask after a process is allocated on the UI thread.
+ void OnProcessAllocated(scoped_ptr<WorkerProcessHandle> handle);
+
+ // Called back from StartTask after the worker is registered to
+ // WorkerDevToolsManager.
+ void OnRegisteredToDevToolsManager(bool is_new_process,
+ int worker_devtools_agent_route_id,
+ bool wait_for_debugger);
+
+ // Called back from StartTask after a start worker message is sent.
+ void OnStartWorkerMessageSent();
// Called back from Registry when the worker instance has ack'ed that
// it is ready for inspection.
@@ -224,6 +221,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
// This will change the internal status from STARTING or RUNNING to
// STOPPED.
void OnStopped();
+
// Called when ServiceWorkerDispatcherHost for the worker died while it was
// running.
void OnDetached();
@@ -249,8 +247,9 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
// Resets all running state. After this function is called, |status_| is
// STOPPED.
void ReleaseProcess();
- // Called when the startup sequence failed. Calls ReleaseProcess() and invokes
- // |callback| with |status|. May destroy |this|.
+
+ // Called back from StartTask when the startup sequence failed. Calls
+ // ReleaseProcess() and invokes |callback| with |status|. May destroy |this|.
void OnStartFailed(const StatusCallback& callback,
ServiceWorkerStatusCode status);
@@ -260,8 +259,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
Status status_;
StartingPhase starting_phase_;
- // Current running information. -1 indicates the worker is not running.
- int process_id_;
+ // Current running information.
+ scoped_ptr<EmbeddedWorkerInstance::WorkerProcessHandle> process_handle_;
int thread_id_;
scoped_ptr<ServiceRegistryImpl> service_registry_;
@@ -272,10 +271,10 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
// served from HTTPCache or ServiceWorkerDatabase this value is false.
bool network_accessed_for_script_;
- StatusCallback start_callback_;
ListenerList listener_list_;
scoped_ptr<DevToolsProxy> devtools_proxy_;
+ scoped_ptr<StartTask> inflight_start_task_;
base::TimeTicks start_timing_;
base::WeakPtrFactory<EmbeddedWorkerInstance> weak_factory_;
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
index 5d3e2b68a56..dcbb856d9d7 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -2,15 +2,21 @@
// 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 "content/browser/service_worker/embedded_worker_instance.h"
+
+#include <stdint.h>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
#include "base/run_loop.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/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/service_worker/embedded_worker_messages.h"
+#include "content/public/common/child_process_host.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -19,15 +25,6 @@ namespace content {
namespace {
-const int kRenderProcessId = 11;
-
-void DestroyWorker(scoped_ptr<EmbeddedWorkerInstance> worker,
- ServiceWorkerStatusCode* out_status,
- ServiceWorkerStatusCode status) {
- *out_status = status;
- worker.reset();
-}
-
void SaveStatusAndCall(ServiceWorkerStatusCode* out,
const base::Closure& callback,
ServiceWorkerStatusCode status) {
@@ -43,21 +40,42 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
EmbeddedWorkerInstanceTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
- void OnStopped(EmbeddedWorkerInstance::Status old_status) override {
- stopped_ = true;
- stopped_old_status_ = old_status;
+ enum EventType {
+ PROCESS_ALLOCATED,
+ START_WORKER_MESSAGE_SENT,
+ STARTED,
+ STOPPED,
+ DETACHED,
+ };
+
+ struct EventLog {
+ EventType type;
+ EmbeddedWorkerInstance::Status status;
+ };
+
+ void RecordEvent(
+ EventType type,
+ EmbeddedWorkerInstance::Status status = EmbeddedWorkerInstance::STOPPED) {
+ EventLog log = {type, status};
+ events_.push_back(log);
}
+ void OnProcessAllocated() override { RecordEvent(PROCESS_ALLOCATED); }
+ void OnStartWorkerMessageSent() override {
+ RecordEvent(START_WORKER_MESSAGE_SENT);
+ }
+ void OnStarted() override { RecordEvent(STARTED); }
+ void OnStopped(EmbeddedWorkerInstance::Status old_status) override {
+ RecordEvent(STOPPED, old_status);
+ }
void OnDetached(EmbeddedWorkerInstance::Status old_status) override {
- detached_ = true;
- detached_old_status_ = old_status;
+ RecordEvent(DETACHED, old_status);
}
bool OnMessageReceived(const IPC::Message& message) override { return false; }
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
}
void TearDown() override { helper_.reset(); }
@@ -84,21 +102,42 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
TestBrowserThreadBundle thread_bundle_;
scoped_ptr<EmbeddedWorkerTestHelper> helper_;
- bool detached_ = false;
- EmbeddedWorkerInstance::Status detached_old_status_ =
- EmbeddedWorkerInstance::STOPPED;
- bool stopped_ = false;
- EmbeddedWorkerInstance::Status stopped_old_status_ =
- EmbeddedWorkerInstance::STOPPED;
+ std::vector<EventLog> events_;
private:
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest);
};
+// A helper to simulate the start worker sequence is stalled in a worker
+// process.
+class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper {
+ public:
+ StalledInStartWorkerHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
+ ~StalledInStartWorkerHelper() override{};
+
+ void OnStartWorker(int embedded_worker_id,
+ int64_t service_worker_version_id,
+ const GURL& scope,
+ const GURL& script_url) override {
+ if (force_stall_in_start_) {
+ // Do nothing to simulate a stall in the worker process.
+ return;
+ }
+ EmbeddedWorkerTestHelper::OnStartWorker(
+ embedded_worker_id, service_worker_version_id, scope, script_url);
+ }
+
+ void set_force_stall_in_start(bool force_stall_in_start) {
+ force_stall_in_start_ = force_stall_in_start;
+ }
+
+ private:
+ bool force_stall_in_start_ = true;
+};
+
class FailToSendIPCHelper : public EmbeddedWorkerTestHelper {
public:
- FailToSendIPCHelper()
- : EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId) {}
+ FailToSendIPCHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
~FailToSendIPCHelper() override {}
bool Send(IPC::Message* message) override {
@@ -112,12 +151,13 @@ TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
embedded_worker_registry()->CreateWorker();
EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
- const int64 service_worker_version_id = 55L;
+ const int64_t service_worker_version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
// Simulate adding one process to the pattern.
- helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern,
+ helper_->mock_render_process_id());
// Start should succeed.
ServiceWorkerStatusCode status;
@@ -134,7 +174,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
// The 'WorkerStarted' message should have been sent by
// EmbeddedWorkerTestHelper.
EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker->status());
- EXPECT_EQ(kRenderProcessId, worker->process_id());
+ EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
// Stop the worker.
EXPECT_EQ(SERVICE_WORKER_OK, worker->Stop());
@@ -157,18 +197,19 @@ TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
embedded_worker_registry()->CreateWorker();
EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
- const int64 service_worker_version_id = 55L;
+ const int64_t service_worker_version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
// Simulate adding one process to the pattern.
- helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern,
+ helper_->mock_render_process_id());
// Start the worker and then call StopIfIdle().
EXPECT_EQ(SERVICE_WORKER_OK,
StartWorker(worker.get(), service_worker_version_id, pattern, url));
EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker->status());
- EXPECT_EQ(kRenderProcessId, worker->process_id());
+ EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
worker->StopIfIdle();
EXPECT_EQ(EmbeddedWorkerInstance::STOPPING, worker->status());
base::RunLoop().RunUntilIdle();
@@ -182,7 +223,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
EXPECT_EQ(SERVICE_WORKER_OK,
StartWorker(worker.get(), service_worker_version_id, pattern, url));
EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker->status());
- EXPECT_EQ(kRenderProcessId, worker->process_id());
+ EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
worker->StopIfIdle();
base::RunLoop().RunUntilIdle();
@@ -204,12 +245,13 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
scoped_ptr<EmbeddedWorkerInstance> worker2 =
embedded_worker_registry()->CreateWorker();
- const int64 version_id1 = 55L;
- const int64 version_id2 = 56L;
+ const int64_t version_id1 = 55L;
+ const int64_t version_id2 = 56L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
+ int process_id = helper_->mock_render_process_id();
- helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern, process_id);
{
// Start worker1.
ServiceWorkerStatusCode status;
@@ -243,71 +285,194 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
// Only worker1 should be removed from the registry's process_map.
EmbeddedWorkerRegistry* registry =
helper_->context()->embedded_worker_registry();
- EXPECT_EQ(0UL,
- registry->worker_process_map_[kRenderProcessId].count(worker1_id));
- EXPECT_EQ(1UL, registry->worker_process_map_[kRenderProcessId].count(
+ EXPECT_EQ(0UL, registry->worker_process_map_[process_id].count(worker1_id));
+ EXPECT_EQ(1UL, registry->worker_process_map_[process_id].count(
worker2->embedded_worker_id()));
worker2->Stop();
}
-// Test detaching in the middle of the start worker sequence.
-TEST_F(EmbeddedWorkerInstanceTest, DetachDuringStart) {
+TEST_F(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) {
+ const int64_t version_id = 55L;
+ const GURL scope("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+
scoped_ptr<EmbeddedWorkerInstance> worker =
embedded_worker_registry()->CreateWorker();
worker->AddListener(this);
- scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params(
- new EmbeddedWorkerMsg_StartWorker_Params());
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ // Run the start worker sequence and detach during process allocation.
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ worker->Start(
+ version_id, scope, url,
+ base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
+ worker->Detach();
+ base::RunLoop().RunUntilIdle();
- // Pretend the worker got stopped before the start sequence reached
- // SendStartWorker.
- worker->status_ = EmbeddedWorkerInstance::STOPPED;
- base::RunLoop run_loop;
- worker->SendStartWorker(params.Pass(), base::Bind(&SaveStatusAndCall, &status,
- run_loop.QuitClosure()),
- true, -1, false);
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
- // Don't expect SendStartWorker() to dispatch an OnStopped/Detached() message
- // since the worker was already stopped.
- EXPECT_FALSE(stopped_);
- EXPECT_FALSE(detached_);
-
- // Repeat, this time have the start callback destroy the worker, as is
- // usual when starting a worker fails, and ensure a crash doesn't occur.
- worker->status_ = EmbeddedWorkerInstance::STOPPED;
- EmbeddedWorkerInstance* worker_ptr = worker.get();
- worker_ptr->SendStartWorker(
- params.Pass(), base::Bind(&DestroyWorker, base::Passed(&worker), &status),
- true, -1, false);
- // No crash.
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
+ EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, worker->process_id());
+
+ // The start callback should not be aborted by detach (see a comment on the
+ // dtor of EmbeddedWorkerInstance::StartTask).
+ EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
+
+ // "PROCESS_ALLOCATED" event should not be recorded.
+ ASSERT_EQ(1u, events_.size());
+ EXPECT_EQ(DETACHED, events_[0].type);
+ EXPECT_EQ(EmbeddedWorkerInstance::STARTING, events_[0].status);
+}
+
+TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
+ const int64_t version_id = 55L;
+ const GURL scope("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+
+ helper_.reset(new StalledInStartWorkerHelper());
+ scoped_ptr<EmbeddedWorkerInstance> worker =
+ embedded_worker_registry()->CreateWorker();
+ worker->AddListener(this);
+
+ // Run the start worker sequence until a start worker message is sent.
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ worker->Start(
+ version_id, scope, url,
+ base::Bind(&SaveStatusAndCall, &status, base::Bind(base::DoNothing)));
+ base::RunLoop().RunUntilIdle();
+
+ ASSERT_EQ(2u, events_.size());
+ EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
+ EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
+ events_.clear();
+
+ worker->Detach();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
+ EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, worker->process_id());
+
+ // The start callback should not be aborted by detach (see a comment on the
+ // dtor of EmbeddedWorkerInstance::StartTask).
+ EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
+
+ // "STARTED" event should not be recorded.
+ ASSERT_EQ(1u, events_.size());
+ EXPECT_EQ(DETACHED, events_[0].type);
+ EXPECT_EQ(EmbeddedWorkerInstance::STARTING, events_[0].status);
+}
+
+TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
+ const int64_t version_id = 55L;
+ const GURL scope("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+
+ scoped_ptr<EmbeddedWorkerInstance> worker =
+ embedded_worker_registry()->CreateWorker();
+ worker->AddListener(this);
+
+ // Stop the start worker sequence before a process is allocated.
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ worker->Start(
+ version_id, scope, url,
+ base::Bind(&SaveStatusAndCall, &status, base::Bind(base::DoNothing)));
+ worker->Stop();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
+ EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, worker->process_id());
+
+ // The start callback should not be aborted by stop (see a comment on the dtor
+ // of EmbeddedWorkerInstance::StartTask).
+ EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
+
+ // "PROCESS_ALLOCATED" event should not be recorded.
+ ASSERT_EQ(1u, events_.size());
+ EXPECT_EQ(DETACHED, events_[0].type);
+ EXPECT_EQ(EmbeddedWorkerInstance::STARTING, events_[0].status);
+ events_.clear();
+
+ // Restart the worker.
+ status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ scoped_ptr<base::RunLoop> run_loop(new base::RunLoop);
+ worker->Start(version_id, scope, url, base::Bind(&SaveStatusAndCall, &status,
+ run_loop->QuitClosure()));
+ run_loop->Run();
+
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(3u, events_.size());
+ EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
+ EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
+ EXPECT_EQ(STARTED, events_[2].type);
+
+ // Tear down the worker.
+ worker->Stop();
}
-// Test stopping in the middle of the start worker sequence, before
-// a process is allocated.
-TEST_F(EmbeddedWorkerInstanceTest, StopDuringStart) {
+TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
+ const int64_t version_id = 55L;
+ const GURL scope("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+
+ helper_.reset(new StalledInStartWorkerHelper);
scoped_ptr<EmbeddedWorkerInstance> worker =
embedded_worker_registry()->CreateWorker();
worker->AddListener(this);
- // Pretend we stop during starting before we got a process allocated.
- worker->status_ = EmbeddedWorkerInstance::STARTING;
- worker->process_id_ = -1;
+
+ // Run the start worker sequence until a start worker message is sent.
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ worker->Start(
+ version_id, scope, url,
+ base::Bind(&SaveStatusAndCall, &status, base::Bind(base::DoNothing)));
+ base::RunLoop().RunUntilIdle();
+
+ ASSERT_EQ(2u, events_.size());
+ EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
+ EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
+ events_.clear();
+
worker->Stop();
+ base::RunLoop().RunUntilIdle();
+
EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
- EXPECT_TRUE(detached_);
- EXPECT_EQ(EmbeddedWorkerInstance::STARTING, detached_old_status_);
+ EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, worker->process_id());
+
+ // The start callback should not be aborted by stop (see a comment on the dtor
+ // of EmbeddedWorkerInstance::StartTask).
+ EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
+
+ // "STARTED" event should not be recorded.
+ ASSERT_EQ(1u, events_.size());
+ EXPECT_EQ(STOPPED, events_[0].type);
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPING, events_[0].status);
+ events_.clear();
+
+ // Restart the worker.
+ static_cast<StalledInStartWorkerHelper*>(helper_.get())
+ ->set_force_stall_in_start(false);
+ status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ scoped_ptr<base::RunLoop> run_loop(new base::RunLoop);
+ worker->Start(version_id, scope, url, base::Bind(&SaveStatusAndCall, &status,
+ run_loop->QuitClosure()));
+ run_loop->Run();
+
+ // The worker should be started.
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(3u, events_.size());
+ EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
+ EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
+ EXPECT_EQ(STARTED, events_[2].type);
+
+ // Tear down the worker.
+ worker->Stop();
}
TEST_F(EmbeddedWorkerInstanceTest, Detach) {
- const int64 version_id = 55L;
+ const int64_t version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
scoped_ptr<EmbeddedWorkerInstance> worker =
embedded_worker_registry()->CreateWorker();
- helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern,
+ helper_->mock_render_process_id());
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
worker->AddListener(this);
@@ -334,13 +499,14 @@ TEST_F(EmbeddedWorkerInstanceTest, Detach) {
TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
helper_.reset(new FailToSendIPCHelper());
- const int64 version_id = 55L;
+ const int64_t version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
scoped_ptr<EmbeddedWorkerInstance> worker =
embedded_worker_registry()->CreateWorker();
- helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern,
+ helper_->mock_render_process_id());
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
worker->AddListener(this);
@@ -353,8 +519,10 @@ TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
// The callback should have run, and we should have got an OnStopped message.
EXPECT_EQ(SERVICE_WORKER_ERROR_IPC_FAILED, status);
- EXPECT_TRUE(stopped_);
- EXPECT_EQ(EmbeddedWorkerInstance::STARTING, stopped_old_status_);
+ ASSERT_EQ(2u, events_.size());
+ EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
+ EXPECT_EQ(STOPPED, events_[1].type);
+ EXPECT_EQ(EmbeddedWorkerInstance::STARTING, events_[1].status);
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/embedded_worker_registry.cc b/chromium/content/browser/service_worker/embedded_worker_registry.cc
index 2a83ba965e5..73eb49f6277 100644
--- a/chromium/content/browser/service_worker/embedded_worker_registry.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_registry.cc
@@ -40,7 +40,7 @@ scoped_ptr<EmbeddedWorkerInstance> EmbeddedWorkerRegistry::CreateWorker() {
scoped_ptr<EmbeddedWorkerInstance> worker(
new EmbeddedWorkerInstance(context_, next_embedded_worker_id_));
worker_map_[next_embedded_worker_id_++] = worker.get();
- return worker.Pass();
+ return worker;
}
ServiceWorkerStatusCode EmbeddedWorkerRegistry::StopWorker(
diff --git a/chromium/content/browser/service_worker/embedded_worker_registry.h b/chromium/content/browser/service_worker/embedded_worker_registry.h
index 22313ddea93..c9cea03f20b 100644
--- a/chromium/content/browser/service_worker/embedded_worker_registry.h
+++ b/chromium/content/browser/service_worker/embedded_worker_registry.h
@@ -9,8 +9,8 @@
#include <set>
#include <vector>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -127,7 +127,8 @@ class CONTENT_EXPORT EmbeddedWorkerRegistry
ServiceWorkerStatusCode Send(int process_id, IPC::Message* message);
// RemoveWorker is called when EmbeddedWorkerInstance is destructed.
- // |process_id| could be invalid (i.e. -1) if it's not running.
+ // |process_id| could be invalid (i.e. ChildProcessHost::kInvalidUniqueID)
+ // if it's not running.
void RemoveWorker(int process_id, int embedded_worker_id);
EmbeddedWorkerInstance* GetWorkerForMessage(int process_id,
diff --git a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
index 887a95f0506..3f572923391 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -6,6 +6,7 @@
#include <map>
#include <string>
+#include <utility>
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
@@ -17,11 +18,17 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/service_worker/embedded_worker_messages.h"
+#include "content/common/service_worker/embedded_worker_setup.mojom.h"
#include "content/common/service_worker/service_worker_messages.h"
+#include "content/public/test/mock_render_process_host.h"
+#include "content/public/test/test_browser_context.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
+namespace {
+
class MockMessagePortMessageFilter : public MessagePortMessageFilter {
public:
MockMessagePortMessageFilter()
@@ -40,24 +47,61 @@ class MockMessagePortMessageFilter : public MessagePortMessageFilter {
ScopedVector<IPC::Message> message_queue_;
};
+} // namespace
+
+class EmbeddedWorkerTestHelper::MockEmbeddedWorkerSetup
+ : public EmbeddedWorkerSetup {
+ public:
+ static void Create(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
+ mojo::InterfaceRequest<EmbeddedWorkerSetup> request) {
+ new MockEmbeddedWorkerSetup(helper, std::move(request));
+ }
+
+ void ExchangeServiceProviders(
+ int32_t thread_id,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) override {
+ if (!helper_)
+ return;
+ helper_->OnSetupMojoStub(thread_id, std::move(services),
+ std::move(exposed_services));
+ }
+
+ private:
+ MockEmbeddedWorkerSetup(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
+ mojo::InterfaceRequest<EmbeddedWorkerSetup> request)
+ : helper_(helper), binding_(this, std::move(request)) {}
+
+ base::WeakPtr<EmbeddedWorkerTestHelper> helper_;
+ mojo::StrongBinding<EmbeddedWorkerSetup> binding_;
+};
+
EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
- const base::FilePath& user_data_directory,
- int mock_render_process_id)
- : wrapper_(new ServiceWorkerContextWrapper(NULL)),
+ const base::FilePath& user_data_directory)
+ : browser_context_(new TestBrowserContext),
+ render_process_host_(new MockRenderProcessHost(browser_context_.get())),
+ wrapper_(new ServiceWorkerContextWrapper(browser_context_.get())),
next_thread_id_(0),
- mock_render_process_id_(mock_render_process_id),
+ mock_render_process_id_(render_process_host_->GetID()),
weak_factory_(this) {
scoped_ptr<MockServiceWorkerDatabaseTaskManager> database_task_manager(
new MockServiceWorkerDatabaseTaskManager(
base::ThreadTaskRunnerHandle::Get()));
- wrapper_->InitInternal(user_data_directory,
- database_task_manager.Pass(),
- base::ThreadTaskRunnerHandle::Get(),
- NULL,
- NULL);
- wrapper_->process_manager()->SetProcessIdForTest(mock_render_process_id);
- registry()->AddChildProcessSender(mock_render_process_id, this,
+ wrapper_->InitInternal(user_data_directory, std::move(database_task_manager),
+ base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr);
+ wrapper_->process_manager()->SetProcessIdForTest(mock_render_process_id_);
+ registry()->AddChildProcessSender(mock_render_process_id_, this,
NewMessagePortMessageFilter());
+
+ // Setup process level mojo service registry pair.
+ scoped_ptr<ServiceRegistryImpl> host_service_registry(
+ new ServiceRegistryImpl);
+ render_process_service_registry_.ServiceRegistry::AddService(
+ base::Bind(&MockEmbeddedWorkerSetup::Create, weak_factory_.GetWeakPtr()));
+ mojo::ServiceProviderPtr services;
+ render_process_service_registry_.Bind(mojo::GetProxy(&services));
+ host_service_registry->BindRemoteServiceProvider(std::move(services));
+ render_process_host_->SetServiceRegistry(std::move(host_service_registry));
}
EmbeddedWorkerTestHelper::~EmbeddedWorkerTestHelper() {
@@ -107,7 +151,7 @@ void EmbeddedWorkerTestHelper::ShutdownContext() {
}
void EmbeddedWorkerTestHelper::OnStartWorker(int embedded_worker_id,
- int64 service_worker_version_id,
+ int64_t service_worker_version_id,
const GURL& scope,
const GURL& script_url) {
embedded_worker_id_service_worker_version_id_map_[embedded_worker_id] =
@@ -143,6 +187,8 @@ bool EmbeddedWorkerTestHelper::OnMessageToWorker(
return handled;
}
+void EmbeddedWorkerTestHelper::OnSetupMojo(ServiceRegistry* service_registry) {}
+
void EmbeddedWorkerTestHelper::OnActivateEvent(int embedded_worker_id,
int request_id) {
SimulateSend(
@@ -193,7 +239,7 @@ void EmbeddedWorkerTestHelper::SimulateWorkerReadyForInspection(
void EmbeddedWorkerTestHelper::SimulateWorkerScriptCached(
int embedded_worker_id) {
- int64 version_id =
+ int64_t version_id =
embedded_worker_id_service_worker_version_id_map_[embedded_worker_id];
ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
if (!version || version->script_cache_map()->size())
@@ -332,6 +378,17 @@ void EmbeddedWorkerTestHelper::OnPushEventStub(int request_id,
current_embedded_worker_id_, request_id, data));
}
+void EmbeddedWorkerTestHelper::OnSetupMojoStub(
+ int thread_id,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) {
+ scoped_ptr<ServiceRegistryImpl> new_registry(new ServiceRegistryImpl);
+ new_registry->Bind(std::move(services));
+ new_registry->BindRemoteServiceProvider(std::move(exposed_services));
+ OnSetupMojo(new_registry.get());
+ thread_id_service_registry_map_.add(thread_id, std::move(new_registry));
+}
+
EmbeddedWorkerRegistry* EmbeddedWorkerTestHelper::registry() {
DCHECK(context());
return context()->embedded_worker_registry();
diff --git a/chromium/content/browser/service_worker/embedded_worker_test_helper.h b/chromium/content/browser/service_worker/embedded_worker_test_helper.h
index e36c18b1778..a95454a9490 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.h
@@ -5,12 +5,17 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_TEST_HELPER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_TEST_HELPER_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
#include "base/callback.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "content/common/mojo/service_registry_impl.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_test_sink.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -24,9 +29,11 @@ namespace content {
class EmbeddedWorkerRegistry;
class EmbeddedWorkerTestHelper;
class MessagePortMessageFilter;
+class MockRenderProcessHost;
class ServiceWorkerContextCore;
class ServiceWorkerContextWrapper;
struct ServiceWorkerFetchRequest;
+class TestBrowserContext;
// In-Process EmbeddedWorker test helper.
//
@@ -46,11 +53,9 @@ struct ServiceWorkerFetchRequest;
class EmbeddedWorkerTestHelper : public IPC::Sender,
public IPC::Listener {
public:
- // Initialize this helper for |context|, and enable this as an IPC
- // sender for |mock_render_process_id|. If |user_data_directory| is empty,
- // the context makes storage stuff in memory.
- EmbeddedWorkerTestHelper(const base::FilePath& user_data_directory,
- int mock_render_process_id);
+ // If |user_data_directory| is empty, the context makes storage stuff in
+ // memory.
+ explicit EmbeddedWorkerTestHelper(const base::FilePath& user_data_directory);
~EmbeddedWorkerTestHelper() override;
// Call this to simulate add/associate a process to a pattern.
@@ -73,6 +78,12 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
void ShutdownContext();
int mock_render_process_id() const { return mock_render_process_id_;}
+ // Mock render process. Only set if the one-parameter constructor was used.
+ MockRenderProcessHost* mock_render_process_host() {
+ return render_process_host_.get();
+ }
+
+ TestBrowserContext* browser_context() { return browser_context_.get(); }
protected:
// Called when StartWorker, StopWorker and SendMessageToWorker message
@@ -82,7 +93,7 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
// - OnStopWorker calls SimulateWorkerStoped
// - OnSendMessageToWorker calls the message's respective On*Event handler
virtual void OnStartWorker(int embedded_worker_id,
- int64 service_worker_version_id,
+ int64_t service_worker_version_id,
const GURL& scope,
const GURL& script_url);
virtual void OnStopWorker(int embedded_worker_id);
@@ -90,6 +101,10 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
int embedded_worker_id,
const IPC::Message& message);
+ // Called to setup mojo for a new embedded worker. Override to register
+ // services the worker should expose to the browser.
+ virtual void OnSetupMojo(ServiceRegistry* service_registry);
+
// On*Event handlers. Called by the default implementation of
// OnMessageToWorker when events are sent to the embedded
// worker. By default they just return success via
@@ -117,6 +132,8 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
EmbeddedWorkerRegistry* registry();
private:
+ class MockEmbeddedWorkerSetup;
+
void OnStartWorkerStub(const EmbeddedWorkerMsg_StartWorker_Params& params);
void OnStopWorkerStub(int embedded_worker_id);
void OnMessageToWorkerStub(int thread_id,
@@ -127,9 +144,15 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
void OnFetchEventStub(int request_id,
const ServiceWorkerFetchRequest& request);
void OnPushEventStub(int request_id, const std::string& data);
+ void OnSetupMojoStub(int thread_id,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services);
MessagePortMessageFilter* NewMessagePortMessageFilter();
+ scoped_ptr<TestBrowserContext> browser_context_;
+ scoped_ptr<MockRenderProcessHost> render_process_host_;
+
scoped_refptr<ServiceWorkerContextWrapper> wrapper_;
IPC::TestSink sink_;
@@ -138,7 +161,14 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
int next_thread_id_;
int mock_render_process_id_;
- std::map<int, int64> embedded_worker_id_service_worker_version_id_map_;
+ ServiceRegistryImpl render_process_service_registry_;
+
+ std::map<int, int64_t> embedded_worker_id_service_worker_version_id_map_;
+
+ // Stores the ServiceRegistries that are associated with each individual
+ // service worker.
+ base::ScopedPtrHashMap<int, scoped_ptr<ServiceRegistryImpl>>
+ thread_id_service_registry_map_;
// Updated each time MessageToWorker message is received.
int current_embedded_worker_id_;
diff --git a/chromium/content/browser/service_worker/foreign_fetch_request_handler.cc b/chromium/content/browser/service_worker/foreign_fetch_request_handler.cc
new file mode 100644
index 00000000000..5edda64902a
--- /dev/null
+++ b/chromium/content/browser/service_worker/foreign_fetch_request_handler.cc
@@ -0,0 +1,227 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/foreign_fetch_request_handler.h"
+
+#include "base/macros.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_url_request_job.h"
+#include "content/common/resource_request_body.h"
+#include "content/common/service_worker/service_worker_utils.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_interceptor.h"
+#include "storage/browser/blob/blob_storage_context.h"
+
+namespace content {
+
+namespace {
+
+int kUserDataKey; // Only address is used.
+
+class ForeignFetchRequestInterceptor : public net::URLRequestInterceptor {
+ public:
+ explicit ForeignFetchRequestInterceptor(ResourceContext* resource_context)
+ : resource_context_(resource_context) {}
+ ~ForeignFetchRequestInterceptor() override {}
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ ForeignFetchRequestHandler* handler =
+ ForeignFetchRequestHandler::GetHandler(request);
+ if (!handler)
+ return nullptr;
+ return handler->MaybeCreateJob(request, network_delegate,
+ resource_context_);
+ }
+
+ private:
+ ResourceContext* resource_context_;
+ DISALLOW_COPY_AND_ASSIGN(ForeignFetchRequestInterceptor);
+};
+
+} // namespace
+
+void ForeignFetchRequestHandler::InitializeHandler(
+ net::URLRequest* request,
+ ServiceWorkerContextWrapper* context_wrapper,
+ storage::BlobStorageContext* blob_storage_context,
+ int process_id,
+ int provider_id,
+ bool skip_service_worker,
+ FetchRequestMode request_mode,
+ FetchCredentialsMode credentials_mode,
+ FetchRedirectMode redirect_mode,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body) {
+ if (!context_wrapper) {
+ return;
+ }
+
+ if (!context_wrapper->OriginHasForeignFetchRegistrations(
+ request->url().GetOrigin())) {
+ return;
+ }
+
+ // Any more precise checks to see if the request should be intercepted are
+ // asynchronous, so just create our handler in all cases.
+ scoped_ptr<ForeignFetchRequestHandler> handler(new ForeignFetchRequestHandler(
+ context_wrapper, blob_storage_context->AsWeakPtr(), request_mode,
+ credentials_mode, redirect_mode, resource_type, request_context_type,
+ frame_type, body));
+ request->SetUserData(&kUserDataKey, handler.release());
+}
+
+ForeignFetchRequestHandler* ForeignFetchRequestHandler::GetHandler(
+ net::URLRequest* request) {
+ return static_cast<ForeignFetchRequestHandler*>(
+ request->GetUserData(&kUserDataKey));
+}
+
+scoped_ptr<net::URLRequestInterceptor>
+ForeignFetchRequestHandler::CreateInterceptor(
+ ResourceContext* resource_context) {
+ return scoped_ptr<net::URLRequestInterceptor>(
+ new ForeignFetchRequestInterceptor(resource_context));
+}
+
+ForeignFetchRequestHandler::~ForeignFetchRequestHandler() {}
+
+net::URLRequestJob* ForeignFetchRequestHandler::MaybeCreateJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ ResourceContext* resource_context) {
+ ClearJob();
+
+ if (!context_) {
+ // We can't do anything other than to fall back to network.
+ job_.reset();
+ return nullptr;
+ }
+
+ // This may get called multiple times for original and redirect requests:
+ // A. original request case: use_network_ is false, no previous location info.
+ // B. redirect or restarted request case:
+ // a) use_network_ is false if the previous location was forwarded to SW.
+ // b) use_network_ is false if the previous location was fallback.
+ // c) use_network_ is true if additional restart was required to fall back.
+
+ // Fall back to network. (Case B-c)
+ if (use_network_) {
+ // TODO(mek): Determine if redirects should be able to be intercepted by
+ // other foreign fetch service workers.
+ return nullptr;
+ }
+
+ // It's for original request (A) or redirect case (B-a or B-b).
+ DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker());
+
+ ServiceWorkerURLRequestJob* job = new ServiceWorkerURLRequestJob(
+ request, network_delegate, blob_storage_context_, resource_context,
+ request_mode_, credentials_mode_, redirect_mode_, false,
+ request_context_type_, frame_type_, body_, this);
+ job_ = job->GetWeakPtr();
+
+ context_->FindReadyRegistrationForDocument(
+ request->url(),
+ base::Bind(&ForeignFetchRequestHandler::DidFindRegistration,
+ weak_factory_.GetWeakPtr(), job_));
+
+ return job_.get();
+}
+
+ForeignFetchRequestHandler::ForeignFetchRequestHandler(
+ ServiceWorkerContextWrapper* context,
+ base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
+ FetchRequestMode request_mode,
+ FetchCredentialsMode credentials_mode,
+ FetchRedirectMode redirect_mode,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body)
+ : context_(context),
+ blob_storage_context_(blob_storage_context),
+ resource_type_(resource_type),
+ request_mode_(request_mode),
+ credentials_mode_(credentials_mode),
+ redirect_mode_(redirect_mode),
+ request_context_type_(request_context_type),
+ frame_type_(frame_type),
+ body_(body),
+ weak_factory_(this) {}
+
+void ForeignFetchRequestHandler::DidFindRegistration(
+ const base::WeakPtr<ServiceWorkerURLRequestJob>& job,
+ ServiceWorkerStatusCode status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ if (!job || job.get() != job_.get()) {
+ // No more job to handle, or job changed somehow, so just return.
+ return;
+ }
+
+ if (status != SERVICE_WORKER_OK || !job->request()) {
+ job->FallbackToNetwork();
+ return;
+ }
+
+ ServiceWorkerVersion* active_version = registration->active_version();
+ DCHECK(active_version);
+
+ const GURL& request_url = job->request()->url();
+ bool scope_matches = false;
+ for (const GURL& scope : active_version->foreign_fetch_scopes()) {
+ if (ServiceWorkerUtils::ScopeMatches(scope, request_url)) {
+ scope_matches = true;
+ break;
+ }
+ }
+
+ if (!scope_matches) {
+ job->FallbackToNetwork();
+ return;
+ }
+
+ target_worker_ = active_version;
+ job->ForwardToServiceWorker();
+}
+
+void ForeignFetchRequestHandler::OnPrepareToRestart(
+ base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) {
+ use_network_ = true;
+ ClearJob();
+}
+
+void ForeignFetchRequestHandler::OnStartCompleted(
+ bool was_fetched_via_service_worker,
+ bool was_fallback_required,
+ const GURL& original_url_via_service_worker,
+ blink::WebServiceWorkerResponseType response_type_via_service_worker,
+ base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) {}
+
+ServiceWorkerVersion* ForeignFetchRequestHandler::GetServiceWorkerVersion(
+ ServiceWorkerMetrics::URLRequestJobResult* result) {
+ // TODO(mek): Figure out what should happen if the active worker changes or
+ // gets uninstalled before this point is reached.
+ if (!target_worker_) {
+ *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION;
+ return nullptr;
+ }
+ return target_worker_.get();
+}
+
+GURL ForeignFetchRequestHandler::GetRequestingOrigin() {
+ // TODO(mek): Implement this.
+ return GURL();
+}
+
+void ForeignFetchRequestHandler::ClearJob() {
+ job_.reset();
+ target_worker_ = nullptr;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/foreign_fetch_request_handler.h b/chromium/content/browser/service_worker/foreign_fetch_request_handler.h
new file mode 100644
index 00000000000..196f7e0f013
--- /dev/null
+++ b/chromium/content/browser/service_worker/foreign_fetch_request_handler.h
@@ -0,0 +1,142 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_FOREIGN_FETCH_REQUEST_HANDLER_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_FOREIGN_FETCH_REQUEST_HANDLER_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/supports_user_data.h"
+#include "base/time/time.h"
+#include "content/browser/service_worker/service_worker_url_request_job.h"
+#include "content/common/content_export.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/request_context_frame_type.h"
+#include "content/public/common/request_context_type.h"
+#include "content/public/common/resource_type.h"
+#include "net/url_request/url_request_job_factory.h"
+
+namespace net {
+class NetworkDelegate;
+class URLRequest;
+class URLRequestInterceptor;
+}
+
+namespace storage {
+class BlobStorageContext;
+}
+
+namespace content {
+
+class ResourceContext;
+class ResourceRequestBody;
+class ServiceWorkerContextCore;
+class ServiceWorkerContextWrapper;
+class ServiceWorkerProviderHost;
+class ServiceWorkerRegistration;
+struct ResourceResponseInfo;
+
+// Class for routing network requests to ServiceWorkers for foreign fetch
+// events. Created one per URLRequest and attached to each request.
+// TODO(mek): Does this need something similar to ServiceWorkerRequestHandler's
+// GetExtraResponseInfo method?
+class CONTENT_EXPORT ForeignFetchRequestHandler
+ : public base::SupportsUserData::Data,
+ public ServiceWorkerURLRequestJob::Delegate {
+ public:
+ // Attaches a newly created handler if the given |request| needs to
+ // be handled by a foreign fetch handling ServiceWorker.
+ static void InitializeHandler(
+ net::URLRequest* request,
+ ServiceWorkerContextWrapper* context_wrapper,
+ storage::BlobStorageContext* blob_storage_context,
+ int process_id,
+ int provider_id,
+ bool skip_service_worker,
+ FetchRequestMode request_mode,
+ FetchCredentialsMode credentials_mode,
+ FetchRedirectMode redirect_mode,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body);
+
+ // Returns the handler attached to |request|. This may return null
+ // if no handler is attached.
+ static ForeignFetchRequestHandler* GetHandler(net::URLRequest* request);
+
+ // Creates a protocol interceptor for foreign fetch.
+ static scoped_ptr<net::URLRequestInterceptor> CreateInterceptor(
+ ResourceContext* resource_context);
+
+ ~ForeignFetchRequestHandler() override;
+
+ // Called via custom URLRequestJobFactory.
+ net::URLRequestJob* MaybeCreateJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ ResourceContext* resource_context);
+
+ private:
+ ForeignFetchRequestHandler(
+ ServiceWorkerContextWrapper* context,
+ base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
+ FetchRequestMode request_mode,
+ FetchCredentialsMode credentials_mode,
+ FetchRedirectMode redirect_mode,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body);
+
+ // Called when a ServiceWorkerRegistration has (or hasn't) been found for the
+ // request being handled.
+ void DidFindRegistration(
+ const base::WeakPtr<ServiceWorkerURLRequestJob>& job,
+ ServiceWorkerStatusCode status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration);
+
+ // ServiceWorkerURLRequestJob::Delegate implementation:
+ void OnPrepareToRestart(base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) override;
+ void OnStartCompleted(
+ bool was_fetched_via_service_worker,
+ bool was_fallback_required,
+ const GURL& original_url_via_service_worker,
+ blink::WebServiceWorkerResponseType response_type_via_service_worker,
+ base::TimeTicks worker_start_time,
+ base::TimeTicks service_worker_ready_time) override;
+ ServiceWorkerVersion* GetServiceWorkerVersion(
+ ServiceWorkerMetrics::URLRequestJobResult* result) override;
+ GURL GetRequestingOrigin() override;
+
+ // Sets |job_| to nullptr, and clears all extra response info associated with
+ // that job.
+ void ClearJob();
+
+ scoped_refptr<ServiceWorkerContextWrapper> context_;
+ base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
+ ResourceType resource_type_;
+ FetchRequestMode request_mode_;
+ FetchCredentialsMode credentials_mode_;
+ FetchRedirectMode redirect_mode_;
+ RequestContextType request_context_type_;
+ RequestContextFrameType frame_type_;
+ scoped_refptr<ResourceRequestBody> body_;
+
+ base::WeakPtr<ServiceWorkerURLRequestJob> job_;
+ scoped_refptr<ServiceWorkerVersion> target_worker_;
+
+ // True if the next time this request is started, the response should be
+ // delivered from the network, bypassing the ServiceWorker.
+ bool use_network_ = false;
+
+ base::WeakPtrFactory<ForeignFetchRequestHandler> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ForeignFetchRequestHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_FOREIGN_FETCH_REQUEST_HANDLER_H_
diff --git a/chromium/content/browser/service_worker/service_worker_browsertest.cc b/chromium/content/browser/service_worker/service_worker_browsertest.cc
index b841b186289..205f067a1eb 100644
--- a/chromium/content/browser/service_worker/service_worker_browsertest.cc
+++ b/chromium/content/browser/service_worker/service_worker_browsertest.cc
@@ -2,13 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
@@ -181,7 +187,7 @@ class WorkerActivatedObserver
RunOnIOThread(base::Bind(&WorkerActivatedObserver::InitOnIOThread, this));
}
// ServiceWorkerContextObserver overrides.
- void OnVersionStateChanged(int64 version_id,
+ void OnVersionStateChanged(int64_t version_id,
ServiceWorkerVersion::Status) override {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
const ServiceWorkerVersion* version = context_->GetLiveVersion(version_id);
@@ -208,15 +214,14 @@ class WorkerActivatedObserver
scoped_ptr<net::test_server::HttpResponse> VerifyServiceWorkerHeaderInRequest(
const net::test_server::HttpRequest& request) {
EXPECT_EQ(request.relative_url, "/service_worker/generated_sw.js");
- std::map<std::string, std::string>::const_iterator it =
- request.headers.find("Service-Worker");
+ auto it = request.headers.find("Service-Worker");
EXPECT_TRUE(it != request.headers.end());
EXPECT_EQ("script", it->second);
scoped_ptr<net::test_server::BasicHttpResponse> http_response(
new net::test_server::BasicHttpResponse());
http_response->set_content_type("text/javascript");
- return http_response.Pass();
+ return std::move(http_response);
}
// The ImportsBustMemcache test requires that the imported script
@@ -235,10 +240,10 @@ class LongLivedResourceInterceptor : public net::URLRequestInterceptor {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
const char kHeaders[] =
- "HTTP/1.1 200 OK\0"
- "Content-Type: text/javascript\0"
- "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-Type: text/javascript\n"
+ "Expires: Thu, 1 Jan 2100 20:00:00 GMT\n"
+ "\n";
std::string headers(kHeaders, arraysize(kHeaders));
return new net::URLRequestTestJob(
request, network_delegate, headers, body_, true);
@@ -257,12 +262,12 @@ void CreateLongLivedResourceInterceptors(
interceptor.reset(new LongLivedResourceInterceptor(
"importScripts('long_lived_import.js');"));
net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
- worker_url, interceptor.Pass());
+ worker_url, std::move(interceptor));
interceptor.reset(new LongLivedResourceInterceptor(
"// the imported script does nothing"));
net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
- import_url, interceptor.Pass());
+ import_url, std::move(interceptor));
}
void CountScriptResources(
@@ -300,13 +305,8 @@ class ServiceWorkerBrowserTest : public ContentBrowserTest {
protected:
using self = ServiceWorkerBrowserTest;
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitch(
- switches::kEnableExperimentalWebPlatformFeatures);
- }
-
void SetUpOnMainThread() override {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
StoragePartition* partition = BrowserContext::GetDefaultStoragePartition(
shell()->web_contents()->GetBrowserContext());
wrapper_ = static_cast<ServiceWorkerContextWrapper*>(
@@ -450,7 +450,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
ASSERT_TRUE(prepare_result);
*result = fetch_result.result;
*response = fetch_result.response;
- *blob_data_handle = fetch_result.blob_data_handle.Pass();
+ *blob_data_handle = std::move(fetch_result.blob_data_handle);
ASSERT_EQ(SERVICE_WORKER_OK, fetch_result.status);
}
@@ -470,6 +470,10 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
pattern,
wrapper()->context()->storage()->NewRegistrationId(),
wrapper()->context()->AsWeakPtr());
+ // Set the update check time to avoid triggering updates in the middle of
+ // tests.
+ registration_->set_last_update_check(base::Time::Now());
+
version_ = new ServiceWorkerVersion(
registration_.get(),
embedded_test_server()->GetURL(worker_url),
@@ -499,7 +503,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
embedded_test_server()->GetURL("/service_worker/host"));
host->AssociateRegistration(registration_.get(),
false /* notify_controllerchange */);
- wrapper()->context()->AddProviderHost(host.Pass());
+ wrapper()->context()->AddProviderHost(std::move(host));
}
void AddWaitingWorkerOnIOThread(const std::string& worker_url) {
@@ -538,7 +542,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
ASSERT_EQ(expected_status, status);
}
- void StoreRegistration(int64 version_id,
+ void StoreRegistration(int64_t version_id,
ServiceWorkerStatusCode expected_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
@@ -554,7 +558,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
this, status));
}
- void FindRegistrationForId(int64 id,
+ void FindRegistrationForId(int64_t id,
const GURL& origin,
ServiceWorkerStatusCode expected_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -570,7 +574,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
void FindRegistrationForIdOnIOThread(const base::Closure& done,
ServiceWorkerStatusCode* result,
- int64 id,
+ int64_t id,
const GURL& origin) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
wrapper()->context()->storage()->FindRegistrationForId(
@@ -585,7 +589,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
registration_.get(), version_.get(), status);
}
- void RemoveLiveRegistrationOnIOThread(int64 id) {
+ void RemoveLiveRegistrationOnIOThread(int64_t id) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
wrapper()->context()->RemoveLiveRegistration(id);
}
@@ -606,7 +610,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
void StoreOnIOThread(const base::Closure& done,
ServiceWorkerStatusCode* result,
- int64 version_id) {
+ int64_t version_id) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ServiceWorkerVersion* version =
wrapper()->context()->GetLiveVersion(version_id);
@@ -985,13 +989,10 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, Reload) {
#endif
IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest,
MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure) {
- const char kPageUrl[] = "files/service_worker/fetch_event_blob.html";
- const char kWorkerUrl[] = "files/service_worker/fetch_event_blob.js";
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS,
- net::BaseTestServer::SSLOptions(
- net::BaseTestServer::SSLOptions::CERT_OK),
- base::FilePath(FILE_PATH_LITERAL("content/test/data/")));
+ const char kPageUrl[] = "/service_worker/fetch_event_blob.html";
+ const char kWorkerUrl[] = "/service_worker/fetch_event_blob.js";
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server.Start());
scoped_refptr<WorkerActivatedObserver> observer =
@@ -1089,7 +1090,7 @@ class ServiceWorkerBlackBoxBrowserTest : public ServiceWorkerBrowserTest {
void FindRegistrationOnIO(const GURL& document_url,
ServiceWorkerStatusCode* status,
const base::Closure& continuation) {
- wrapper()->FindRegistrationForDocument(
+ wrapper()->FindReadyRegistrationForDocument(
document_url,
base::Bind(&ServiceWorkerBlackBoxBrowserTest::FindRegistrationOnIO2,
this, status, continuation));
@@ -1243,7 +1244,6 @@ class ServiceWorkerVersionBrowserV8CacheTest
version_->RemoveListener(this);
}
void SetUpCommandLine(base::CommandLine* command_line) override {
- ServiceWorkerBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(switches::kV8CacheOptions, "code");
}
void SetUpRegistrationAndListenerOnIOThread(const std::string& worker_url) {
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer.cc b/chromium/content/browser/service_worker/service_worker_cache_writer.cc
new file mode 100644
index 00000000000..20c6987934c
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer.cc
@@ -0,0 +1,506 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_cache_writer.h"
+
+#include <algorithm>
+#include <string>
+
+#include "content/browser/appcache/appcache_response.h"
+#include "content/browser/service_worker/service_worker_disk_cache.h"
+#include "content/browser/service_worker/service_worker_storage.h"
+
+namespace {
+
+const size_t kCopyBufferSize = 16 * 1024;
+
+// Shim class used to turn always-async functions into async-or-result
+// functions. See the comments below near ReadInfoHelper.
+class AsyncOnlyCompletionCallbackAdaptor
+ : public base::RefCounted<AsyncOnlyCompletionCallbackAdaptor> {
+ public:
+ explicit AsyncOnlyCompletionCallbackAdaptor(
+ const net::CompletionCallback& callback)
+ : async_(false), result_(net::ERR_IO_PENDING), callback_(callback) {}
+
+ void set_async(bool async) { async_ = async; }
+ bool async() { return async_; }
+ int result() { return result_; }
+
+ void WrappedCallback(int result) {
+ result_ = result;
+ if (async_)
+ callback_.Run(result);
+ }
+
+ private:
+ friend class base::RefCounted<AsyncOnlyCompletionCallbackAdaptor>;
+ virtual ~AsyncOnlyCompletionCallbackAdaptor() {}
+
+ bool async_;
+ int result_;
+ net::CompletionCallback callback_;
+};
+
+} // namespace
+
+namespace content {
+
+int ServiceWorkerCacheWriter::DoLoop(int status) {
+ do {
+ switch (state_) {
+ case STATE_START:
+ status = DoStart(status);
+ break;
+ case STATE_READ_HEADERS_FOR_COMPARE:
+ status = DoReadHeadersForCompare(status);
+ break;
+ case STATE_READ_HEADERS_FOR_COMPARE_DONE:
+ status = DoReadHeadersForCompareDone(status);
+ break;
+ case STATE_READ_DATA_FOR_COMPARE:
+ status = DoReadDataForCompare(status);
+ break;
+ case STATE_READ_DATA_FOR_COMPARE_DONE:
+ status = DoReadDataForCompareDone(status);
+ break;
+ case STATE_READ_HEADERS_FOR_COPY:
+ status = DoReadHeadersForCopy(status);
+ break;
+ case STATE_READ_HEADERS_FOR_COPY_DONE:
+ status = DoReadHeadersForCopyDone(status);
+ break;
+ case STATE_READ_DATA_FOR_COPY:
+ status = DoReadDataForCopy(status);
+ break;
+ case STATE_READ_DATA_FOR_COPY_DONE:
+ status = DoReadDataForCopyDone(status);
+ break;
+ case STATE_WRITE_HEADERS_FOR_PASSTHROUGH:
+ status = DoWriteHeadersForPassthrough(status);
+ break;
+ case STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE:
+ status = DoWriteHeadersForPassthroughDone(status);
+ break;
+ case STATE_WRITE_DATA_FOR_PASSTHROUGH:
+ status = DoWriteDataForPassthrough(status);
+ break;
+ case STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE:
+ status = DoWriteDataForPassthroughDone(status);
+ break;
+ case STATE_WRITE_HEADERS_FOR_COPY:
+ status = DoWriteHeadersForCopy(status);
+ break;
+ case STATE_WRITE_HEADERS_FOR_COPY_DONE:
+ status = DoWriteHeadersForCopyDone(status);
+ break;
+ case STATE_WRITE_DATA_FOR_COPY:
+ status = DoWriteDataForCopy(status);
+ break;
+ case STATE_WRITE_DATA_FOR_COPY_DONE:
+ status = DoWriteDataForCopyDone(status);
+ break;
+ case STATE_DONE:
+ status = DoDone(status);
+ break;
+ default:
+ NOTREACHED() << "Unknown state in DoLoop";
+ state_ = STATE_DONE;
+ break;
+ }
+ } while (status != net::ERR_IO_PENDING && state_ != STATE_DONE);
+ io_pending_ = (status == net::ERR_IO_PENDING);
+ return status;
+}
+
+ServiceWorkerCacheWriter::ServiceWorkerCacheWriter(
+ const ResponseReaderCreator& reader_creator,
+ const ResponseWriterCreator& writer_creator)
+ : state_(STATE_START),
+ io_pending_(false),
+ comparing_(false),
+ did_replace_(false),
+ reader_creator_(reader_creator),
+ writer_creator_(writer_creator),
+ weak_factory_(this) {}
+
+ServiceWorkerCacheWriter::~ServiceWorkerCacheWriter() {}
+
+net::Error ServiceWorkerCacheWriter::MaybeWriteHeaders(
+ HttpResponseInfoIOBuffer* headers,
+ const OnWriteCompleteCallback& callback) {
+ DCHECK(!io_pending_);
+
+ headers_to_write_ = headers;
+ pending_callback_ = callback;
+ DCHECK_EQ(state_, STATE_START);
+ int result = DoLoop(net::OK);
+
+ // Synchronous errors and successes always go to STATE_DONE.
+ if (result != net::ERR_IO_PENDING)
+ DCHECK_EQ(state_, STATE_DONE);
+
+ // ERR_IO_PENDING has to have one of the STATE_*_DONE states as the next state
+ // (not STATE_DONE itself).
+ if (result == net::ERR_IO_PENDING) {
+ DCHECK(state_ == STATE_READ_HEADERS_FOR_COMPARE_DONE ||
+ state_ == STATE_WRITE_HEADERS_FOR_COPY_DONE ||
+ state_ == STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE)
+ << "Unexpected state: " << state_;
+ io_pending_ = true;
+ }
+
+ return result >= 0 ? net::OK : static_cast<net::Error>(result);
+}
+
+net::Error ServiceWorkerCacheWriter::MaybeWriteData(
+ net::IOBuffer* buf,
+ size_t buf_size,
+ const OnWriteCompleteCallback& callback) {
+ DCHECK(!io_pending_);
+
+ data_to_write_ = buf;
+ len_to_write_ = buf_size;
+ pending_callback_ = callback;
+
+ if (comparing_)
+ state_ = STATE_READ_DATA_FOR_COMPARE;
+ else
+ state_ = STATE_WRITE_DATA_FOR_PASSTHROUGH;
+
+ int result = DoLoop(net::OK);
+
+ // Synchronous completions are always STATE_DONE.
+ if (result != net::ERR_IO_PENDING)
+ DCHECK_EQ(state_, STATE_DONE);
+
+ // Asynchronous completion means the state machine must be waiting in one of
+ // the Done states for an IO operation to complete:
+ if (result == net::ERR_IO_PENDING) {
+ // Note that STATE_READ_HEADERS_FOR_COMPARE_DONE is excluded because the
+ // headers are compared in MaybeWriteHeaders, not here, and
+ // STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE is excluded because that write
+ // is done by MaybeWriteHeaders.
+ DCHECK(state_ == STATE_READ_DATA_FOR_COMPARE_DONE ||
+ state_ == STATE_READ_HEADERS_FOR_COPY_DONE ||
+ state_ == STATE_READ_DATA_FOR_COPY_DONE ||
+ state_ == STATE_WRITE_HEADERS_FOR_COPY_DONE ||
+ state_ == STATE_WRITE_DATA_FOR_COPY_DONE ||
+ state_ == STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE)
+ << "Unexpected state: " << state_;
+ }
+
+ return result >= 0 ? net::OK : static_cast<net::Error>(result);
+}
+
+int ServiceWorkerCacheWriter::DoStart(int result) {
+ bytes_written_ = 0;
+ compare_reader_ = reader_creator_.Run();
+ if (compare_reader_.get()) {
+ state_ = STATE_READ_HEADERS_FOR_COMPARE;
+ comparing_ = true;
+ } else {
+ // No existing reader, just write the headers back directly.
+ state_ = STATE_WRITE_HEADERS_FOR_PASSTHROUGH;
+ comparing_ = false;
+ }
+ return net::OK;
+}
+
+int ServiceWorkerCacheWriter::DoReadHeadersForCompare(int result) {
+ DCHECK_GE(result, 0);
+ DCHECK(headers_to_write_);
+
+ headers_to_read_ = new HttpResponseInfoIOBuffer;
+ state_ = STATE_READ_HEADERS_FOR_COMPARE_DONE;
+ return ReadInfoHelper(compare_reader_, headers_to_read_.get());
+}
+
+int ServiceWorkerCacheWriter::DoReadHeadersForCompareDone(int result) {
+ if (result < 0) {
+ state_ = STATE_DONE;
+ return result;
+ }
+ cached_length_ = headers_to_read_->response_data_size;
+ bytes_compared_ = 0;
+ state_ = STATE_DONE;
+ return net::OK;
+}
+
+int ServiceWorkerCacheWriter::DoReadDataForCompare(int result) {
+ DCHECK_GE(result, 0);
+ DCHECK(data_to_write_);
+
+ data_to_read_ = new net::IOBuffer(len_to_write_);
+ len_to_read_ = len_to_write_;
+ state_ = STATE_READ_DATA_FOR_COMPARE_DONE;
+ compare_offset_ = 0;
+ // If this was an EOF, don't issue a read.
+ if (len_to_write_ > 0)
+ result = ReadDataHelper(compare_reader_, data_to_read_.get(), len_to_read_);
+ return result;
+}
+
+int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
+ DCHECK(data_to_read_);
+ DCHECK(data_to_write_);
+ DCHECK_EQ(len_to_read_, len_to_write_);
+
+ if (result < 0) {
+ state_ = STATE_DONE;
+ return result;
+ }
+
+ DCHECK_LE(result + compare_offset_, static_cast<size_t>(len_to_write_));
+
+ // Premature EOF while reading the service worker script cache data to
+ // compare. Fail the comparison.
+ if (result == 0 && len_to_write_ != 0) {
+ comparing_ = false;
+ state_ = STATE_READ_HEADERS_FOR_COPY;
+ return net::OK;
+ }
+
+ // Compare the data from the ServiceWorker script cache to the data from the
+ // network.
+ if (memcmp(data_to_read_->data(), data_to_write_->data() + compare_offset_,
+ result)) {
+ // Data mismatched. This method already validated that all the bytes through
+ // |bytes_compared_| were identical, so copy the first |bytes_compared_|
+ // over, then start writing network data back after the changed point.
+ comparing_ = false;
+ state_ = STATE_READ_HEADERS_FOR_COPY;
+ return net::OK;
+ }
+
+ compare_offset_ += result;
+
+ // This is a little bit tricky. It is possible that not enough data was read
+ // to finish comparing the entire block of data from the network (which is
+ // kept in len_to_write_), so this method may need to issue another read and
+ // return to this state.
+ //
+ // Compare isn't complete yet. Issue another read for the remaining data. Note
+ // that this reuses the same IOBuffer.
+ if (compare_offset_ < static_cast<size_t>(len_to_read_)) {
+ state_ = STATE_READ_DATA_FOR_COMPARE_DONE;
+ return ReadDataHelper(compare_reader_, data_to_read_.get(),
+ len_to_read_ - compare_offset_);
+ }
+
+ // Cached entry is longer than the network entry but the prefix matches. Copy
+ // just the prefix.
+ if (len_to_read_ == 0 && bytes_compared_ + compare_offset_ < cached_length_) {
+ comparing_ = false;
+ state_ = STATE_READ_HEADERS_FOR_COPY;
+ return net::OK;
+ }
+
+ // bytes_compared_ only gets incremented when a full block is compared, to
+ // avoid having to use only parts of the buffered network data.
+ bytes_compared_ += result;
+ state_ = STATE_DONE;
+ return net::OK;
+}
+
+int ServiceWorkerCacheWriter::DoReadHeadersForCopy(int result) {
+ DCHECK_GE(result, 0);
+ bytes_copied_ = 0;
+ copy_reader_ = reader_creator_.Run();
+ headers_to_read_ = new HttpResponseInfoIOBuffer;
+ data_to_copy_ = new net::IOBuffer(kCopyBufferSize);
+ state_ = STATE_READ_HEADERS_FOR_COPY_DONE;
+ return ReadInfoHelper(copy_reader_, headers_to_read_.get());
+}
+
+int ServiceWorkerCacheWriter::DoReadHeadersForCopyDone(int result) {
+ if (result < 0) {
+ state_ = STATE_DONE;
+ return result;
+ }
+ state_ = STATE_WRITE_HEADERS_FOR_COPY;
+ return net::OK;
+}
+
+// Write the just-read headers back to the cache.
+// Note that this method must create |writer_|, since the only paths to this
+// state never create a writer.
+// Also note that this *discards* the read headers and replaces them with the
+// net headers.
+int ServiceWorkerCacheWriter::DoWriteHeadersForCopy(int result) {
+ DCHECK_GE(result, 0);
+ DCHECK(!writer_);
+ writer_ = writer_creator_.Run();
+ state_ = STATE_WRITE_HEADERS_FOR_COPY_DONE;
+ return WriteInfoHelper(writer_, headers_to_write_.get());
+}
+
+int ServiceWorkerCacheWriter::DoWriteHeadersForCopyDone(int result) {
+ if (result < 0) {
+ state_ = STATE_DONE;
+ return result;
+ }
+ state_ = STATE_READ_DATA_FOR_COPY;
+ return net::OK;
+}
+
+int ServiceWorkerCacheWriter::DoReadDataForCopy(int result) {
+ DCHECK_GE(result, 0);
+ size_t to_read = std::min(kCopyBufferSize, bytes_compared_ - bytes_copied_);
+ // At this point, all compared bytes have been read. Currently
+ // |data_to_write_| and |len_to_write_| hold the chunk of network input that
+ // caused the comparison failure, so those need to be written back and this
+ // object needs to go into passthrough mode.
+ if (to_read == 0) {
+ state_ = STATE_WRITE_DATA_FOR_PASSTHROUGH;
+ return net::OK;
+ }
+ state_ = STATE_READ_DATA_FOR_COPY_DONE;
+ return ReadDataHelper(copy_reader_, data_to_copy_.get(), to_read);
+}
+
+int ServiceWorkerCacheWriter::DoReadDataForCopyDone(int result) {
+ if (result < 0) {
+ state_ = STATE_DONE;
+ return result;
+ }
+ state_ = STATE_WRITE_DATA_FOR_COPY;
+ return result;
+}
+
+int ServiceWorkerCacheWriter::DoWriteDataForCopy(int result) {
+ state_ = STATE_WRITE_DATA_FOR_COPY_DONE;
+ DCHECK_GT(result, 0);
+ return WriteDataHelper(writer_, data_to_copy_.get(), result);
+}
+
+int ServiceWorkerCacheWriter::DoWriteDataForCopyDone(int result) {
+ if (result < 0) {
+ state_ = STATE_DONE;
+ return result;
+ }
+ bytes_written_ += result;
+ bytes_copied_ += result;
+ state_ = STATE_READ_DATA_FOR_COPY;
+ return result;
+}
+
+int ServiceWorkerCacheWriter::DoWriteHeadersForPassthrough(int result) {
+ DCHECK_GE(result, 0);
+ writer_ = writer_creator_.Run();
+ state_ = STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE;
+ return WriteInfoHelper(writer_, headers_to_write_.get());
+}
+
+int ServiceWorkerCacheWriter::DoWriteHeadersForPassthroughDone(int result) {
+ state_ = STATE_DONE;
+ return result;
+}
+
+int ServiceWorkerCacheWriter::DoWriteDataForPassthrough(int result) {
+ DCHECK_GE(result, 0);
+ state_ = STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE;
+ if (len_to_write_ > 0)
+ result = WriteDataHelper(writer_, data_to_write_.get(), len_to_write_);
+ return result;
+}
+
+int ServiceWorkerCacheWriter::DoWriteDataForPassthroughDone(int result) {
+ if (result < 0) {
+ state_ = STATE_DONE;
+ return result;
+ }
+ bytes_written_ += result;
+ state_ = STATE_DONE;
+ return net::OK;
+}
+
+int ServiceWorkerCacheWriter::DoDone(int result) {
+ state_ = STATE_DONE;
+ return result;
+}
+
+// These helpers adapt the AppCache "always use the callback" pattern to the
+// //net "only use the callback for async" pattern using
+// AsyncCompletionCallbackAdaptor.
+//
+// Specifically, these methods return result codes directly for synchronous
+// completions, and only run their callback (which is AsyncDoLoop) for
+// asynchronous completions.
+
+int ServiceWorkerCacheWriter::ReadInfoHelper(
+ const scoped_ptr<ServiceWorkerResponseReader>& reader,
+ HttpResponseInfoIOBuffer* buf) {
+ net::CompletionCallback run_callback = base::Bind(
+ &ServiceWorkerCacheWriter::AsyncDoLoop, weak_factory_.GetWeakPtr());
+ scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
+ new AsyncOnlyCompletionCallbackAdaptor(run_callback));
+ reader->ReadInfo(
+ buf, base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
+ adaptor));
+ adaptor->set_async(true);
+ return adaptor->result();
+}
+
+int ServiceWorkerCacheWriter::ReadDataHelper(
+ const scoped_ptr<ServiceWorkerResponseReader>& reader,
+ net::IOBuffer* buf,
+ int buf_len) {
+ net::CompletionCallback run_callback = base::Bind(
+ &ServiceWorkerCacheWriter::AsyncDoLoop, weak_factory_.GetWeakPtr());
+ scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
+ new AsyncOnlyCompletionCallbackAdaptor(run_callback));
+ reader->ReadData(
+ buf, buf_len,
+ base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
+ adaptor));
+ adaptor->set_async(true);
+ return adaptor->result();
+}
+
+int ServiceWorkerCacheWriter::WriteInfoHelper(
+ const scoped_ptr<ServiceWorkerResponseWriter>& writer,
+ HttpResponseInfoIOBuffer* buf) {
+ did_replace_ = true;
+ net::CompletionCallback run_callback = base::Bind(
+ &ServiceWorkerCacheWriter::AsyncDoLoop, weak_factory_.GetWeakPtr());
+ scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
+ new AsyncOnlyCompletionCallbackAdaptor(run_callback));
+ writer->WriteInfo(
+ buf, base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
+ adaptor));
+ adaptor->set_async(true);
+ return adaptor->result();
+}
+
+int ServiceWorkerCacheWriter::WriteDataHelper(
+ const scoped_ptr<ServiceWorkerResponseWriter>& writer,
+ net::IOBuffer* buf,
+ int buf_len) {
+ net::CompletionCallback run_callback = base::Bind(
+ &ServiceWorkerCacheWriter::AsyncDoLoop, weak_factory_.GetWeakPtr());
+ scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
+ new AsyncOnlyCompletionCallbackAdaptor(run_callback));
+ writer->WriteData(
+ buf, buf_len,
+ base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
+ adaptor));
+ adaptor->set_async(true);
+ return adaptor->result();
+}
+
+void ServiceWorkerCacheWriter::AsyncDoLoop(int result) {
+ result = DoLoop(result);
+ // If the result is ERR_IO_PENDING, the pending callback will be run by a
+ // later invocation of AsyncDoLoop.
+ if (result != net::ERR_IO_PENDING) {
+ OnWriteCompleteCallback callback = pending_callback_;
+ pending_callback_.Reset();
+ net::Error error = result >= 0 ? net::OK : static_cast<net::Error>(result);
+ io_pending_ = false;
+ callback.Run(error);
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer.h b/chromium/content/browser/service_worker/service_worker_cache_writer.h
new file mode 100644
index 00000000000..e4c38ccddfa
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer.h
@@ -0,0 +1,232 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
+
+#include <stddef.h>
+
+#include <map>
+#include <set>
+
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+
+namespace content {
+
+struct HttpResponseInfoIOBuffer;
+class ServiceWorkerCacheWriterCore;
+class ServiceWorkerResponseReader;
+class ServiceWorkerResponseWriter;
+class ServiceWorkerStorage;
+
+// This class is responsible for possibly updating the ServiceWorker script
+// cache for an installed ServiceWorker main script. If there is no existing
+// cache entry, this class always writes supplied data back to the cache; if
+// there is an existing cache entry, this class only writes supplied data back
+// if there is a cache mismatch.
+//
+// Note that writes done by this class cannot be "short" - ie, if they succeed,
+// they always write all the supplied data back. Therefore completions are
+// signalled with net::Error without a count of bytes written.
+//
+// This class's behavior is modelled as a state machine; see the DoLoop function
+// for comments about this.
+class CONTENT_EXPORT ServiceWorkerCacheWriter {
+ public:
+ using OnWriteCompleteCallback = base::Callback<void(net::Error)>;
+
+ // The types for the factory functions passed into the constructor. These are
+ // responsible for creating readers from the existing cache entry and writers
+ // to the new cache entry when called. These are passed in as factories
+ // instead of passing readers and writers in directly to avoid creating
+ // writers to entries that won't be updated, and because this class may need
+ // multiple readers internally.
+ using ResponseReaderCreator =
+ base::Callback<scoped_ptr<ServiceWorkerResponseReader>(void)>;
+ using ResponseWriterCreator =
+ base::Callback<scoped_ptr<ServiceWorkerResponseWriter>(void)>;
+
+ // The existing reader may be null, in which case this instance will
+ // unconditionally write back data supplied to |MaybeWriteHeaders| and
+ // |MaybeWriteData|.
+ ServiceWorkerCacheWriter(const ResponseReaderCreator& reader_creator,
+ const ResponseWriterCreator& writer_creator);
+
+ ~ServiceWorkerCacheWriter();
+
+ // Writes the supplied |headers| back to the cache. Returns ERR_IO_PENDING if
+ // the write will complete asynchronously, in which case |callback| will be
+ // called when it completes. Otherwise, returns a code other than
+ // ERR_IO_PENDING and does not invoke |callback|. Note that this method will
+ // not necessarily write data back to the cache if the incoming data is
+ // equivalent to the existing cached data. See the source of this function for
+ // details about how this function drives the state machine.
+ net::Error MaybeWriteHeaders(HttpResponseInfoIOBuffer* headers,
+ const OnWriteCompleteCallback& callback);
+
+ // Writes the supplied body data |data| back to the cache. Returns
+ // ERR_IO_PENDING if the write will complete asynchronously, in which case
+ // |callback| will be called when it completes. Otherwise, returns a code
+ // other than ERR_IO_PENDING and does not invoke |callback|. Note that this
+ // method will not necessarily write data back to the cache if the incoming
+ // data is equivalent to the existing cached data. See the source of this
+ // function for details about how this function drives the state machine.
+ net::Error MaybeWriteData(net::IOBuffer* buf,
+ size_t buf_size,
+ const OnWriteCompleteCallback& callback);
+
+ // Returns a count of bytes written back to the cache.
+ size_t bytes_written() const { return bytes_written_; }
+ bool did_replace() const { return did_replace_; }
+
+ private:
+ // States for the state machine.
+ //
+ // The state machine flows roughly like this: if there is no existing cache
+ // entry, incoming headers and data are written directly back to the cache
+ // ("passthrough mode", the PASSTHROUGH states). If there is an existing cache
+ // entry, incoming headers and data are compared to the existing cache entry
+ // ("compare mode", the COMPARE states); if at any point the incoming
+ // headers/data are not equal to the cached headers/data, this class copies
+ // the cached data up to the point where the incoming data and the cached data
+ // diverged ("copy mode", the COPY states), then switches to "passthrough
+ // mode" to write the remainder of the incoming data. The overall effect is to
+ // avoid rewriting the cache entry if the incoming data is identical to the
+ // cached data.
+ //
+ // Note that after a call to MaybeWriteHeaders or MaybeWriteData completes,
+ // the machine is always in STATE_DONE, indicating that the call is finished;
+ // those methods are responsible for setting a new initial state.
+ enum State {
+ STATE_START,
+ // Control flows linearly through these four states, then loops from
+ // READ_DATA_FOR_COMPARE_DONE to READ_DATA_FOR_COMPARE, or exits to
+ // READ_HEADERS_FOR_COPY.
+ STATE_READ_HEADERS_FOR_COMPARE,
+ STATE_READ_HEADERS_FOR_COMPARE_DONE,
+ STATE_READ_DATA_FOR_COMPARE,
+ STATE_READ_DATA_FOR_COMPARE_DONE,
+
+ // Control flows linearly through these states, with each pass from
+ // READ_DATA_FOR_COPY to WRITE_DATA_FOR_COPY_DONE copying one block of data
+ // at a time. Control loops from WRITE_DATA_FOR_COPY_DONE back to
+ // READ_DATA_FOR_COPY if there is more data to copy, or exits to
+ // WRITE_DATA_FOR_PASSTHROUGH.
+ STATE_READ_HEADERS_FOR_COPY,
+ STATE_READ_HEADERS_FOR_COPY_DONE,
+ STATE_WRITE_HEADERS_FOR_COPY,
+ STATE_WRITE_HEADERS_FOR_COPY_DONE,
+ STATE_READ_DATA_FOR_COPY,
+ STATE_READ_DATA_FOR_COPY_DONE,
+ STATE_WRITE_DATA_FOR_COPY,
+ STATE_WRITE_DATA_FOR_COPY_DONE,
+
+ // Control flows linearly through these states, with a loop between
+ // WRITE_DATA_FOR_PASSTHROUGH and WRITE_DATA_FOR_PASSTHROUGH_DONE.
+ STATE_WRITE_HEADERS_FOR_PASSTHROUGH,
+ STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE,
+ STATE_WRITE_DATA_FOR_PASSTHROUGH,
+ STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE,
+
+ // This state means "done with the current call; ready for another one."
+ STATE_DONE,
+ };
+
+ // Drives this class's state machine. This function steps the state machine
+ // until one of:
+ // a) One of the state functions returns an error
+ // b) The state machine reaches STATE_DONE
+ // A successful value (net::OK or greater) indicates that the requested
+ // operation completed synchronously. A return value of ERR_IO_PENDING
+ // indicates that some step had to submit asynchronous IO for later
+ // completion, and the state machine will resume running (via AsyncDoLoop)
+ // when that asynchronous IO completes. Any other return value indicates that
+ // the requested operation failed synchronously.
+ int DoLoop(int result);
+
+ // State handlers. See function comments in the corresponding source file for
+ // details on these.
+ int DoStart(int result);
+ int DoReadHeadersForCompare(int result);
+ int DoReadHeadersForCompareDone(int result);
+ int DoReadDataForCompare(int result);
+ int DoReadDataForCompareDone(int result);
+ int DoReadHeadersForCopy(int result);
+ int DoReadHeadersForCopyDone(int result);
+ int DoWriteHeadersForCopy(int result);
+ int DoWriteHeadersForCopyDone(int result);
+ int DoReadDataForCopy(int result);
+ int DoReadDataForCopyDone(int result);
+ int DoWriteDataForCopy(int result);
+ int DoWriteDataForCopyDone(int result);
+ int DoWriteHeadersForPassthrough(int result);
+ int DoWriteHeadersForPassthroughDone(int result);
+ int DoWriteDataForPassthrough(int result);
+ int DoWriteDataForPassthroughDone(int result);
+ int DoDone(int result);
+
+ // Wrappers for asynchronous calls. These are responsible for scheduling a
+ // callback to drive the state machine if needed. These either:
+ // a) Return ERR_IO_PENDING, and schedule a callback to run the state
+ // machine's Run() later, or
+ // b) Return some other value and do not schedule a callback.
+ int ReadInfoHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
+ HttpResponseInfoIOBuffer* buf);
+ int ReadDataHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader,
+ net::IOBuffer* buf,
+ int buf_len);
+ int WriteInfoHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
+ HttpResponseInfoIOBuffer* buf);
+ int WriteDataHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer,
+ net::IOBuffer* buf,
+ int buf_len);
+
+ // Callback used by the above helpers for their IO operations. This is only
+ // run when those IO operations complete asynchronously, in which case it
+ // invokes the synchronous DoLoop function and runs the client callback (the
+ // one passed into MaybeWriteData/MaybeWriteHeaders) if that invocation
+ // of DoLoop completes synchronously.
+ void AsyncDoLoop(int result);
+
+ State state_;
+ // Note that this variable is only used for assertions; it reflects "state !=
+ // DONE && not in synchronous DoLoop".
+ bool io_pending_;
+ bool comparing_;
+
+ scoped_refptr<HttpResponseInfoIOBuffer> headers_to_read_;
+ scoped_refptr<HttpResponseInfoIOBuffer> headers_to_write_;
+ scoped_refptr<net::IOBuffer> data_to_read_;
+ int len_to_read_;
+ scoped_refptr<net::IOBuffer> data_to_copy_;
+ scoped_refptr<net::IOBuffer> data_to_write_;
+ int len_to_write_;
+ OnWriteCompleteCallback pending_callback_;
+
+ size_t cached_length_;
+
+ size_t bytes_compared_;
+ size_t bytes_copied_;
+ size_t bytes_written_;
+
+ bool did_replace_;
+
+ size_t compare_offset_;
+
+ ResponseReaderCreator reader_creator_;
+ ResponseWriterCreator writer_creator_;
+ scoped_ptr<ServiceWorkerResponseReader> compare_reader_;
+ scoped_ptr<ServiceWorkerResponseReader> copy_reader_;
+ scoped_ptr<ServiceWorkerResponseWriter> writer_;
+ base::WeakPtrFactory<ServiceWorkerCacheWriter> weak_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc b/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
new file mode 100644
index 00000000000..030411b3dcf
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
@@ -0,0 +1,809 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_cache_writer.h"
+
+#include <stddef.h>
+
+#include <list>
+#include <queue>
+#include <string>
+
+#include "base/macros.h"
+#include "base/stl_util.h"
+#include "content/browser/service_worker/service_worker_disk_cache.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+// A test implementation of ServiceWorkerResponseReader.
+//
+// This class exposes the ability to expect reads (see ExpectRead*() below).
+// Each call to ReadInfo() or ReadData() consumes another expected read, in the
+// order those reads were expected, so:
+// reader->ExpectReadInfoOk(5, false);
+// reader->ExpectReadDataOk("abcdef", false);
+// reader->ExpectReadDataOk("ghijkl", false);
+// Expects these calls, in this order:
+// reader->ReadInfo(...); // reader writes 5 into
+// // |info_buf->response_data_size|
+// reader->ReadData(...); // reader writes "abcdef" into |buf|
+// reader->ReadData(...); // reader writes "ghijkl" into |buf|
+// If an unexpected call happens, this class DCHECKs.
+// If an expected read is marked "async", it will not complete immediately, but
+// must be completed by the test using CompletePendingRead().
+// These is a convenience method AllExpectedReadsDone() which returns whether
+// there are any expected reads that have not yet happened.
+class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader {
+ public:
+ MockServiceWorkerResponseReader() : ServiceWorkerResponseReader(0, nullptr) {}
+ ~MockServiceWorkerResponseReader() override {}
+
+ // ServiceWorkerResponseReader overrides
+ void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
+ const net::CompletionCallback& callback) override;
+ void ReadData(net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback) override;
+
+ // Test helpers. ExpectReadInfo() and ExpectReadData() give precise control
+ // over both the data to be written and the result to return.
+ // ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for
+ // expecting successful reads, which always have their length as their result.
+
+ // Expect a call to ReadInfo() on this reader. For these functions, |len| will
+ // be used as |response_data_size|, not as the length of this particular read.
+ void ExpectReadInfo(size_t len, bool async, int result);
+ void ExpectReadInfoOk(size_t len, bool async);
+
+ // Expect a call to ReadData() on this reader. For these functions, |len| is
+ // the length of the data to be written back; in ExpectReadDataOk(), |len| is
+ // implicitly the length of |data|.
+ void ExpectReadData(const char* data, size_t len, bool async, int result);
+ void ExpectReadDataOk(const std::string& data, bool async);
+
+ // Complete a pending async read. It is an error to call this function without
+ // a pending async read (ie, a previous call to ReadInfo() or ReadData()
+ // having not run its callback yet).
+ void CompletePendingRead();
+
+ // Returns whether all expected reads have occurred.
+ bool AllExpectedReadsDone() { return expected_reads_.size() == 0; }
+
+ private:
+ struct ExpectedRead {
+ ExpectedRead(size_t len, bool async, int result)
+ : data(nullptr), len(len), info(true), async(async), result(result) {}
+ ExpectedRead(const char* data, size_t len, bool async, int result)
+ : data(data), len(len), info(false), async(async), result(result) {}
+ const char* data;
+ size_t len;
+ bool info;
+ bool async;
+ int result;
+ };
+
+ std::queue<ExpectedRead> expected_reads_;
+ scoped_refptr<net::IOBuffer> pending_buffer_;
+ size_t pending_buffer_len_;
+ scoped_refptr<HttpResponseInfoIOBuffer> pending_info_;
+ net::CompletionCallback pending_callback_;
+};
+
+void MockServiceWorkerResponseReader::ReadInfo(
+ HttpResponseInfoIOBuffer* info_buf,
+ const net::CompletionCallback& callback) {
+ DCHECK(!expected_reads_.empty());
+ ExpectedRead expected = expected_reads_.front();
+ EXPECT_TRUE(expected.info);
+ if (expected.async) {
+ pending_info_ = info_buf;
+ pending_callback_ = callback;
+ } else {
+ expected_reads_.pop();
+ info_buf->response_data_size = expected.len;
+ callback.Run(expected.result);
+ }
+}
+
+void MockServiceWorkerResponseReader::ReadData(
+ net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback) {
+ DCHECK(!expected_reads_.empty());
+ ExpectedRead expected = expected_reads_.front();
+ EXPECT_FALSE(expected.info);
+ if (expected.async) {
+ pending_callback_ = callback;
+ pending_buffer_ = buf;
+ pending_buffer_len_ = static_cast<size_t>(buf_len);
+ } else {
+ expected_reads_.pop();
+ if (expected.len > 0) {
+ size_t to_read = std::min(static_cast<size_t>(buf_len), expected.len);
+ memcpy(buf->data(), expected.data, to_read);
+ }
+ callback.Run(expected.result);
+ }
+}
+
+void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len,
+ bool async,
+ int result) {
+ expected_reads_.push(ExpectedRead(len, async, result));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len, bool async) {
+ expected_reads_.push(ExpectedRead(len, async, len));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadData(const char* data,
+ size_t len,
+ bool async,
+ int result) {
+ expected_reads_.push(ExpectedRead(data, len, async, result));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadDataOk(const std::string& data,
+ bool async) {
+ expected_reads_.push(
+ ExpectedRead(data.data(), data.size(), async, data.size()));
+}
+
+void MockServiceWorkerResponseReader::CompletePendingRead() {
+ DCHECK(!expected_reads_.empty());
+ ExpectedRead expected = expected_reads_.front();
+ expected_reads_.pop();
+ EXPECT_TRUE(expected.async);
+ if (expected.info) {
+ pending_info_->response_data_size = expected.len;
+ } else {
+ size_t to_read = std::min(pending_buffer_len_, expected.len);
+ if (to_read > 0)
+ memcpy(pending_buffer_->data(), expected.data, to_read);
+ }
+ pending_info_ = nullptr;
+ pending_buffer_ = nullptr;
+ net::CompletionCallback callback = pending_callback_;
+ pending_callback_.Reset();
+ callback.Run(expected.result);
+}
+
+// A test implementation of ServiceWorkerResponseWriter.
+//
+// This class exposes the ability to expect writes (see ExpectWrite*Ok() below).
+// Each write to this class via WriteInfo() or WriteData() consumes another
+// expected write, in the order they were added, so:
+// writer->ExpectWriteInfoOk(5, false);
+// writer->ExpectWriteDataOk(6, false);
+// writer->ExpectWriteDataOk(6, false);
+// Expects these calls, in this order:
+// writer->WriteInfo(...); // checks that |buf->response_data_size| == 5
+// writer->WriteData(...); // checks that 6 bytes are being written
+// writer->WriteData(...); // checks that another 6 bytes are being written
+// If this class receives an unexpected call to WriteInfo() or WriteData(), it
+// DCHECKs.
+// Expected writes marked async do not complete synchronously, but rather return
+// without running their callback and need to be completed with
+// CompletePendingWrite().
+// A convenience method AllExpectedWritesDone() is exposed so tests can ensure
+// that all expected writes have been consumed by matching calls to WriteInfo()
+// or WriteData().
+class MockServiceWorkerResponseWriter : public ServiceWorkerResponseWriter {
+ public:
+ MockServiceWorkerResponseWriter()
+ : ServiceWorkerResponseWriter(0, nullptr),
+ info_written_(0),
+ data_written_(0) {}
+ ~MockServiceWorkerResponseWriter() override {}
+
+ // ServiceWorkerResponseWriter overrides
+ void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
+ const net::CompletionCallback& callback) override;
+ void WriteData(net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback) override;
+
+ // Enqueue expected writes.
+ void ExpectWriteInfoOk(size_t len, bool async);
+ void ExpectWriteInfo(size_t len, bool async, int result);
+ void ExpectWriteDataOk(size_t len, bool async);
+ void ExpectWriteData(size_t len, bool async, int result);
+
+ // Complete a pending asynchronous write. This method DCHECKs unless there is
+ // a pending write (a write for which WriteInfo() or WriteData() has been
+ // called but the callback has not yet been run).
+ void CompletePendingWrite();
+
+ // Returns whether all expected reads have been consumed.
+ bool AllExpectedWritesDone() { return expected_writes_.size() == 0; }
+
+ private:
+ struct ExpectedWrite {
+ ExpectedWrite(bool is_info, size_t length, bool async, int result)
+ : is_info(is_info), length(length), async(async), result(result) {}
+ bool is_info;
+ size_t length;
+ bool async;
+ int result;
+ };
+
+ std::queue<ExpectedWrite> expected_writes_;
+
+ size_t info_written_;
+ size_t data_written_;
+
+ net::CompletionCallback pending_callback_;
+};
+
+void MockServiceWorkerResponseWriter::WriteInfo(
+ HttpResponseInfoIOBuffer* info_buf,
+ const net::CompletionCallback& callback) {
+ DCHECK(!expected_writes_.empty());
+ ExpectedWrite write = expected_writes_.front();
+ EXPECT_TRUE(write.is_info);
+ if (write.result > 0) {
+ EXPECT_EQ(write.length, static_cast<size_t>(info_buf->response_data_size));
+ info_written_ += info_buf->response_data_size;
+ }
+ if (!write.async) {
+ expected_writes_.pop();
+ callback.Run(write.result);
+ } else {
+ pending_callback_ = callback;
+ }
+}
+
+void MockServiceWorkerResponseWriter::WriteData(
+ net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback) {
+ DCHECK(!expected_writes_.empty());
+ ExpectedWrite write = expected_writes_.front();
+ EXPECT_FALSE(write.is_info);
+ if (write.result > 0) {
+ EXPECT_EQ(write.length, static_cast<size_t>(buf_len));
+ data_written_ += buf_len;
+ }
+ if (!write.async) {
+ expected_writes_.pop();
+ callback.Run(write.result);
+ } else {
+ pending_callback_ = callback;
+ }
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteInfoOk(size_t length,
+ bool async) {
+ ExpectWriteInfo(length, async, length);
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteDataOk(size_t length,
+ bool async) {
+ ExpectWriteData(length, async, length);
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteInfo(size_t length,
+ bool async,
+ int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
+ ExpectedWrite expected(true, length, async, result);
+ expected_writes_.push(expected);
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteData(size_t length,
+ bool async,
+ int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
+ ExpectedWrite expected(false, length, async, result);
+ expected_writes_.push(expected);
+}
+
+void MockServiceWorkerResponseWriter::CompletePendingWrite() {
+ DCHECK(!expected_writes_.empty());
+ ExpectedWrite write = expected_writes_.front();
+ DCHECK(write.async);
+ expected_writes_.pop();
+ pending_callback_.Run(write.result);
+}
+
+class ServiceWorkerCacheWriterTest : public ::testing::Test {
+ public:
+ ServiceWorkerCacheWriterTest()
+ : readers_deleter_(&readers_), writers_deleter_(&writers_) {}
+
+ void SetUp() override {
+ ::testing::Test::SetUp();
+ cache_writer_.reset(new ServiceWorkerCacheWriter(
+ base::Bind(&ServiceWorkerCacheWriterTest::CreateReader,
+ base::Unretained(this)),
+ base::Bind(&ServiceWorkerCacheWriterTest::CreateWriter,
+ base::Unretained(this))));
+ write_complete_ = false;
+ }
+
+ MockServiceWorkerResponseReader* ExpectReader() {
+ scoped_ptr<MockServiceWorkerResponseReader> reader(
+ new MockServiceWorkerResponseReader);
+ MockServiceWorkerResponseReader* borrowed_reader = reader.get();
+ readers_.push_back(reader.release()); // give ownership to |readers_|
+ return borrowed_reader;
+ }
+
+ MockServiceWorkerResponseWriter* ExpectWriter() {
+ scoped_ptr<MockServiceWorkerResponseWriter> writer(
+ new MockServiceWorkerResponseWriter);
+ MockServiceWorkerResponseWriter* borrowed_writer = writer.get();
+ writers_.push_back(writer.release()); // give ownership to |writers_|
+ return borrowed_writer;
+ }
+
+ protected:
+ // TODO(ellyjones): when unique_ptr<> is allowed, make these instead:
+ // std::list<unique_ptr<...>>
+ // Right now, these cannot use scoped_ptr.
+ // Their elements are deleted by the STLElementDeleters below when this object
+ // goes out of scope.
+ std::list<MockServiceWorkerResponseReader*> readers_;
+ std::list<MockServiceWorkerResponseWriter*> writers_;
+ STLElementDeleter<std::list<MockServiceWorkerResponseReader*>>
+ readers_deleter_;
+ STLElementDeleter<std::list<MockServiceWorkerResponseWriter*>>
+ writers_deleter_;
+ scoped_ptr<ServiceWorkerCacheWriter> cache_writer_;
+ bool write_complete_;
+ net::Error last_error_;
+
+ scoped_ptr<ServiceWorkerResponseReader> CreateReader() {
+ if (readers_.empty())
+ return make_scoped_ptr<ServiceWorkerResponseReader>(nullptr);
+ scoped_ptr<ServiceWorkerResponseReader> reader(readers_.front());
+ readers_.pop_front();
+ return reader;
+ }
+ scoped_ptr<ServiceWorkerResponseWriter> CreateWriter() {
+ if (writers_.empty())
+ return make_scoped_ptr<ServiceWorkerResponseWriter>(nullptr);
+ scoped_ptr<ServiceWorkerResponseWriter> writer(writers_.front());
+ writers_.pop_front();
+ return writer;
+ }
+
+ ServiceWorkerCacheWriter::OnWriteCompleteCallback CreateWriteCallback() {
+ return base::Bind(&ServiceWorkerCacheWriterTest::OnWriteComplete,
+ base::Unretained(this));
+ }
+
+ void OnWriteComplete(net::Error error) {
+ write_complete_ = true;
+ last_error_ = error;
+ }
+
+ net::Error WriteHeaders(size_t len) {
+ scoped_refptr<HttpResponseInfoIOBuffer> buf(new HttpResponseInfoIOBuffer);
+ buf->response_data_size = len;
+ return cache_writer_->MaybeWriteHeaders(buf.get(), CreateWriteCallback());
+ }
+
+ net::Error WriteData(const std::string& data) {
+ scoped_refptr<net::IOBuffer> buf = new net::StringIOBuffer(data);
+ return cache_writer_->MaybeWriteData(buf.get(), data.size(),
+ CreateWriteCallback());
+ }
+};
+
+// Passthrough tests:
+// In these tests, the ServiceWorkerCacheWriter under test has no existing
+// reader, since no calls to ExpectReader() have been made; this means that
+// there is no existing cached response and the incoming data is written back to
+// the cache directly.
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersSync) {
+ const size_t kHeaderSize = 16;
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfoOk(kHeaderSize, false);
+
+ net::Error error = WriteHeaders(kHeaderSize);
+ EXPECT_EQ(net::OK, error);
+ EXPECT_FALSE(write_complete_);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersAsync) {
+ size_t kHeaderSize = 16;
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfoOk(kHeaderSize, true);
+
+ net::Error error = WriteHeaders(kHeaderSize);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ EXPECT_FALSE(write_complete_);
+ writer->CompletePendingWrite();
+ EXPECT_TRUE(write_complete_);
+ EXPECT_EQ(net::OK, last_error_);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataSync) {
+ const std::string data1 = "abcdef";
+ const std::string data2 = "ghijklmno";
+ size_t response_size = data1.size() + data2.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfoOk(response_size, false);
+ writer->ExpectWriteDataOk(data1.size(), false);
+ writer->ExpectWriteDataOk(data2.size(), false);
+
+ net::Error error = WriteHeaders(response_size);
+ EXPECT_EQ(net::OK, error);
+
+ error = WriteData(data1);
+ EXPECT_EQ(net::OK, error);
+
+ error = WriteData(data2);
+ EXPECT_EQ(net::OK, error);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataAsync) {
+ const std::string data1 = "abcdef";
+ const std::string data2 = "ghijklmno";
+ size_t response_size = data1.size() + data2.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfoOk(response_size, false);
+ writer->ExpectWriteDataOk(data1.size(), true);
+ writer->ExpectWriteDataOk(data2.size(), true);
+
+ net::Error error = WriteHeaders(response_size);
+ EXPECT_EQ(net::OK, error);
+
+ error = WriteData(data1);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ writer->CompletePendingWrite();
+ EXPECT_TRUE(write_complete_);
+
+ write_complete_ = false;
+ error = WriteData(data2);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ writer->CompletePendingWrite();
+ EXPECT_TRUE(write_complete_);
+ EXPECT_EQ(net::OK, last_error_);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersFailSync) {
+ const size_t kHeaderSize = 16;
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfo(kHeaderSize, false, net::ERR_FAILED);
+
+ net::Error error = WriteHeaders(kHeaderSize);
+ EXPECT_EQ(net::ERR_FAILED, error);
+ EXPECT_FALSE(write_complete_);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersFailAsync) {
+ size_t kHeaderSize = 16;
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfo(kHeaderSize, true, net::ERR_FAILED);
+
+ net::Error error = WriteHeaders(kHeaderSize);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ EXPECT_FALSE(write_complete_);
+ writer->CompletePendingWrite();
+ EXPECT_TRUE(write_complete_);
+ EXPECT_EQ(net::ERR_FAILED, last_error_);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataFailSync) {
+ const std::string data = "abcdef";
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfoOk(data.size(), false);
+ writer->ExpectWriteData(data.size(), false, net::ERR_FAILED);
+
+ EXPECT_EQ(net::OK, WriteHeaders(data.size()));
+ EXPECT_EQ(net::ERR_FAILED, WriteData(data));
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataFailAsync) {
+ const std::string data = "abcdef";
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ writer->ExpectWriteInfoOk(data.size(), false);
+ writer->ExpectWriteData(data.size(), true, net::ERR_FAILED);
+
+ EXPECT_EQ(net::OK, WriteHeaders(data.size()));
+
+ EXPECT_EQ(net::ERR_IO_PENDING, WriteData(data));
+ writer->CompletePendingWrite();
+ EXPECT_EQ(net::ERR_FAILED, last_error_);
+ EXPECT_TRUE(write_complete_);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+}
+
+// Comparison tests:
+// For the Compare* tests below, the ServiceWorkerCacheWriter under test has a
+// reader for an existing cached response, so it will compare the response being
+// written to it against the existing cached response.
+
+TEST_F(ServiceWorkerCacheWriterTest, CompareHeadersSync) {
+ size_t response_size = 3;
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* reader = ExpectReader();
+
+ reader->ExpectReadInfoOk(response_size, false);
+
+ net::Error error = WriteHeaders(response_size);
+ EXPECT_EQ(net::OK, error);
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(reader->AllExpectedReadsDone());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkSync) {
+ const std::string data1 = "abcdef";
+ size_t response_size = data1.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* reader = ExpectReader();
+
+ reader->ExpectReadInfoOk(response_size, false);
+ reader->ExpectReadDataOk(data1, false);
+
+ net::Error error = WriteHeaders(response_size);
+ EXPECT_EQ(net::OK, error);
+
+ error = WriteData(data1);
+ EXPECT_EQ(net::OK, error);
+
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(reader->AllExpectedReadsDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, CompareHeadersFailSync) {
+ size_t response_size = 3;
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* reader = ExpectReader();
+
+ reader->ExpectReadInfo(response_size, false, net::ERR_FAILED);
+
+ EXPECT_EQ(net::ERR_FAILED, WriteHeaders(response_size));
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(reader->AllExpectedReadsDone());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, CompareDataFailSync) {
+ const std::string data1 = "abcdef";
+ size_t response_size = data1.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* reader = ExpectReader();
+
+ reader->ExpectReadInfoOk(response_size, false);
+ reader->ExpectReadData(data1.c_str(), data1.length(), false, net::ERR_FAILED);
+
+ net::Error error = WriteHeaders(response_size);
+ EXPECT_EQ(net::OK, error);
+
+ EXPECT_EQ(net::ERR_FAILED, WriteData(data1));
+
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(reader->AllExpectedReadsDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, CompareShortCacheReads) {
+ const size_t kHeaderSize = 16;
+ const std::string& data1 = "abcdef";
+ const std::string& cache_data2 = "ghi";
+ const std::string& cache_data3 = "j";
+ const std::string& cache_data4 = "kl";
+ const std::string& net_data2 = "ghijkl";
+ const std::string& data5 = "mnopqrst";
+
+ MockServiceWorkerResponseReader* reader = ExpectReader();
+ reader->ExpectReadInfo(kHeaderSize, false, kHeaderSize);
+ reader->ExpectReadDataOk(data1, false);
+ reader->ExpectReadDataOk(cache_data2, false);
+ reader->ExpectReadDataOk(cache_data3, false);
+ reader->ExpectReadDataOk(cache_data4, false);
+ reader->ExpectReadDataOk(data5, false);
+
+ net::Error error = WriteHeaders(kHeaderSize);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(data1);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(net_data2);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(data5);
+ EXPECT_EQ(net::OK, error);
+ EXPECT_TRUE(reader->AllExpectedReadsDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkAsync) {
+ const std::string data1 = "abcdef";
+ size_t response_size = data1.size();
+
+ MockServiceWorkerResponseReader* reader = ExpectReader();
+
+ reader->ExpectReadInfoOk(response_size, true);
+ reader->ExpectReadDataOk(data1, true);
+
+ net::Error error = WriteHeaders(response_size);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ reader->CompletePendingRead();
+
+ error = WriteData(data1);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ reader->CompletePendingRead();
+
+ EXPECT_TRUE(reader->AllExpectedReadsDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+TEST_F(ServiceWorkerCacheWriterTest, CompareDataManyOkAsync) {
+ const std::string expected_data[] = {
+ "abcdef", "ghijkl", "mnopqr", "stuvwxyz",
+ };
+ size_t response_size = 0;
+ for (size_t i = 0; i < arraysize(expected_data); ++i)
+ response_size += expected_data[i].size();
+
+ MockServiceWorkerResponseReader* reader = ExpectReader();
+
+ reader->ExpectReadInfoOk(response_size, true);
+ for (size_t i = 0; i < arraysize(expected_data); ++i) {
+ reader->ExpectReadDataOk(expected_data[i], true);
+ }
+
+ net::Error error = WriteHeaders(response_size);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ reader->CompletePendingRead();
+
+ for (size_t i = 0; i < arraysize(expected_data); ++i) {
+ error = WriteData(expected_data[i]);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+ }
+
+ EXPECT_TRUE(reader->AllExpectedReadsDone());
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+}
+
+// This test writes headers and three data blocks data1, data2, data3; data2
+// differs in the cached version. The writer should be asked to rewrite the
+// headers and body with the new value, and the copy reader should be asked to
+// read the header and data1.
+TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopySync) {
+ std::string data1 = "abcdef";
+ std::string cache_data2 = "ghijkl";
+ std::string net_data2 = "mnopqr";
+ std::string data3 = "stuvwxyz";
+ size_t cache_response_size = data1.size() + cache_data2.size() + data3.size();
+ size_t net_response_size = data1.size() + net_data2.size() + data3.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* compare_reader = ExpectReader();
+ MockServiceWorkerResponseReader* copy_reader = ExpectReader();
+
+ compare_reader->ExpectReadInfoOk(cache_response_size, false);
+ compare_reader->ExpectReadDataOk(data1, false);
+ compare_reader->ExpectReadDataOk(cache_data2, false);
+
+ copy_reader->ExpectReadInfoOk(cache_response_size, false);
+ copy_reader->ExpectReadDataOk(data1, false);
+
+ writer->ExpectWriteInfoOk(net_response_size, false);
+ writer->ExpectWriteDataOk(data1.size(), false);
+ writer->ExpectWriteDataOk(net_data2.size(), false);
+ writer->ExpectWriteDataOk(data3.size(), false);
+
+ net::Error error = WriteHeaders(net_response_size);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(data1);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(net_data2);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(data3);
+ EXPECT_EQ(net::OK, error);
+
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
+ EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
+}
+
+// Tests behavior when the cached data is shorter than the network data.
+TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyShort) {
+ std::string data1 = "abcdef";
+ std::string cache_data2 = "mnop";
+ std::string net_data2 = "mnopqr";
+ std::string data3 = "stuvwxyz";
+ size_t cache_response_size = data1.size() + cache_data2.size() + data3.size();
+ size_t net_response_size = data1.size() + net_data2.size() + data3.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* compare_reader = ExpectReader();
+ MockServiceWorkerResponseReader* copy_reader = ExpectReader();
+
+ compare_reader->ExpectReadInfoOk(cache_response_size, false);
+ compare_reader->ExpectReadDataOk(data1, false);
+ compare_reader->ExpectReadDataOk(cache_data2, false);
+ compare_reader->ExpectReadDataOk("", false); // EOF read
+
+ copy_reader->ExpectReadInfoOk(cache_response_size, false);
+ copy_reader->ExpectReadDataOk(data1, false);
+
+ writer->ExpectWriteInfoOk(net_response_size, false);
+ writer->ExpectWriteDataOk(data1.size(), false);
+ writer->ExpectWriteDataOk(net_data2.size(), false);
+ writer->ExpectWriteDataOk(data3.size(), false);
+
+ net::Error error = WriteHeaders(net_response_size);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(data1);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(net_data2);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(data3);
+ EXPECT_EQ(net::OK, error);
+
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
+ EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
+}
+
+// Tests behavior when the cached data is longer than the network data.
+TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyLong) {
+ std::string data1 = "abcdef";
+ std::string cache_data2 = "mnop";
+ std::string net_data2 = "mnop";
+ std::string cache_data3 = "qr";
+ size_t cached_size = data1.size() + cache_data2.size() + cache_data3.size();
+ size_t net_size = data1.size() + net_data2.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* compare_reader = ExpectReader();
+ MockServiceWorkerResponseReader* copy_reader = ExpectReader();
+
+ compare_reader->ExpectReadInfoOk(cached_size, false);
+ compare_reader->ExpectReadDataOk(data1, false);
+ compare_reader->ExpectReadDataOk(cache_data2, false);
+
+ // The comparison should fail at the end of |cache_data2|, when the cache
+ // writer realizes the two responses are different sizes, and then the network
+ // data should be written back starting with |net_data2|.
+ copy_reader->ExpectReadInfoOk(cached_size, false);
+ copy_reader->ExpectReadDataOk(data1, false);
+ copy_reader->ExpectReadDataOk(net_data2, false);
+
+ writer->ExpectWriteInfoOk(net_size, false);
+ writer->ExpectWriteDataOk(data1.size(), false);
+ writer->ExpectWriteDataOk(net_data2.size(), false);
+
+ net::Error error = WriteHeaders(net_size);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(data1);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData(net_data2);
+ EXPECT_EQ(net::OK, error);
+ error = WriteData("");
+ EXPECT_EQ(net::OK, error);
+
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
+ EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_client_utils.cc b/chromium/content/browser/service_worker/service_worker_client_utils.cc
new file mode 100644
index 00000000000..26ef4d35f18
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_client_utils.cc
@@ -0,0 +1,397 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_client_utils.h"
+
+#include <algorithm>
+
+#include "base/macros.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_version.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/common/service_worker/service_worker_client_info.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/page_navigator.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/child_process_host.h"
+#include "url/gurl.h"
+
+namespace content {
+namespace service_worker_client_utils {
+
+namespace {
+
+using OpenURLCallback = base::Callback<void(int, int)>;
+using GetWindowClientsCallback =
+ base::Callback<void(scoped_ptr<ServiceWorkerClients>)>;
+
+// The OpenURLObserver class is a WebContentsObserver that will wait for a
+// WebContents to be initialized, run the |callback| passed to its constructor
+// then self destroy.
+// The callback will receive the process and frame ids. If something went wrong
+// those will be (kInvalidUniqueID, MSG_ROUTING_NONE).
+// The callback will be called in the IO thread.
+class OpenURLObserver : public WebContentsObserver {
+ public:
+ OpenURLObserver(WebContents* web_contents,
+ int frame_tree_node_id,
+ const OpenURLCallback& callback)
+ : WebContentsObserver(web_contents),
+ frame_tree_node_id_(frame_tree_node_id),
+ callback_(callback) {}
+
+ void DidCommitProvisionalLoadForFrame(
+ RenderFrameHost* render_frame_host,
+ const GURL& validated_url,
+ ui::PageTransition transition_type) override {
+ DCHECK(web_contents());
+
+ RenderFrameHostImpl* rfhi =
+ static_cast<RenderFrameHostImpl*>(render_frame_host);
+ if (rfhi->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_)
+ return;
+
+ RunCallback(render_frame_host->GetProcess()->GetID(),
+ render_frame_host->GetRoutingID());
+ }
+
+ void RenderProcessGone(base::TerminationStatus status) override {
+ RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
+ }
+
+ void WebContentsDestroyed() override {
+ RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
+ }
+
+ private:
+ void RunCallback(int render_process_id, int render_frame_id) {
+ // After running the callback, |this| will stop observing, thus
+ // web_contents() should return nullptr and |RunCallback| should no longer
+ // be called. Then, |this| will self destroy.
+ DCHECK(web_contents());
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(callback_, render_process_id, render_frame_id));
+ Observe(nullptr);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ }
+
+ int frame_tree_node_id_;
+ const OpenURLCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(OpenURLObserver);
+};
+
+// This is only called for main frame navigations in OpenWindowOnUI().
+void DidOpenURL(const OpenURLCallback& callback, WebContents* web_contents) {
+ DCHECK(web_contents);
+
+ RenderFrameHostImpl* rfhi =
+ static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame());
+ new OpenURLObserver(web_contents,
+ rfhi->frame_tree_node()->frame_tree_node_id(), callback);
+}
+
+void OpenWindowOnUI(
+ const GURL& url,
+ const GURL& script_url,
+ int worker_process_id,
+ const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper,
+ const OpenURLCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BrowserContext* browser_context =
+ context_wrapper->storage_partition()
+ ? context_wrapper->storage_partition()->browser_context()
+ : nullptr;
+ // We are shutting down.
+ if (!browser_context)
+ return;
+
+ RenderProcessHost* render_process_host =
+ RenderProcessHost::FromID(worker_process_id);
+ if (render_process_host->IsForGuestsOnly()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, ChildProcessHost::kInvalidUniqueID,
+ MSG_ROUTING_NONE));
+ return;
+ }
+
+ OpenURLParams params(
+ url, Referrer::SanitizeForRequest(
+ url, Referrer(script_url, blink::WebReferrerPolicyDefault)),
+ NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
+ true /* is_renderer_initiated */);
+
+ GetContentClient()->browser()->OpenURL(browser_context, params,
+ base::Bind(&DidOpenURL, callback));
+}
+
+void NavigateClientOnUI(const GURL& url,
+ const GURL& script_url,
+ int process_id,
+ int frame_id,
+ const OpenURLCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ RenderFrameHostImpl* rfhi = RenderFrameHostImpl::FromID(process_id, frame_id);
+ WebContents* web_contents = WebContents::FromRenderFrameHost(rfhi);
+
+ if (!rfhi || !web_contents) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, ChildProcessHost::kInvalidUniqueID,
+ MSG_ROUTING_NONE));
+ return;
+ }
+
+ ui::PageTransition transition = rfhi->GetParent()
+ ? ui::PAGE_TRANSITION_AUTO_SUBFRAME
+ : ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
+ int frame_tree_node_id = rfhi->frame_tree_node()->frame_tree_node_id();
+
+ OpenURLParams params(
+ url, Referrer::SanitizeForRequest(
+ url, Referrer(script_url, blink::WebReferrerPolicyDefault)),
+ frame_tree_node_id, CURRENT_TAB, transition,
+ true /* is_renderer_initiated */);
+ web_contents->OpenURL(params);
+ new OpenURLObserver(web_contents, frame_tree_node_id, callback);
+}
+
+void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context,
+ const GURL& origin,
+ const NavigationCallback& callback,
+ int render_process_id,
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (!context) {
+ callback.Run(SERVICE_WORKER_ERROR_ABORT, std::string(),
+ ServiceWorkerClientInfo());
+ return;
+ }
+
+ if (render_process_id == ChildProcessHost::kInvalidUniqueID &&
+ render_frame_id == MSG_ROUTING_NONE) {
+ callback.Run(SERVICE_WORKER_ERROR_FAILED, std::string(),
+ ServiceWorkerClientInfo());
+ return;
+ }
+
+ for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
+ context->GetClientProviderHostIterator(origin);
+ !it->IsAtEnd(); it->Advance()) {
+ ServiceWorkerProviderHost* provider_host = it->GetProviderHost();
+ if (provider_host->process_id() != render_process_id ||
+ provider_host->frame_id() != render_frame_id) {
+ continue;
+ }
+ provider_host->GetWindowClientInfo(
+ base::Bind(callback, SERVICE_WORKER_OK, provider_host->client_uuid()));
+ return;
+ }
+
+ // If here, it means that no provider_host was found, in which case, the
+ // renderer should still be informed that the window was opened.
+ callback.Run(SERVICE_WORKER_OK, std::string(), ServiceWorkerClientInfo());
+}
+
+void AddWindowClient(
+ ServiceWorkerProviderHost* host,
+ std::vector<base::Tuple<int, int, std::string>>* client_info) {
+ if (host->client_type() != blink::WebServiceWorkerClientTypeWindow)
+ return;
+ client_info->push_back(base::MakeTuple(host->process_id(), host->frame_id(),
+ host->client_uuid()));
+}
+
+void AddNonWindowClient(ServiceWorkerProviderHost* host,
+ const ServiceWorkerClientQueryOptions& options,
+ ServiceWorkerClients* clients) {
+ blink::WebServiceWorkerClientType host_client_type = host->client_type();
+ if (host_client_type == blink::WebServiceWorkerClientTypeWindow)
+ return;
+ if (options.client_type != blink::WebServiceWorkerClientTypeAll &&
+ options.client_type != host_client_type)
+ return;
+
+ ServiceWorkerClientInfo client_info(blink::WebPageVisibilityStateHidden,
+ false, // is_focused
+ host->document_url(),
+ REQUEST_CONTEXT_FRAME_TYPE_NONE,
+ base::TimeTicks(), host_client_type);
+ client_info.client_uuid = host->client_uuid();
+ clients->push_back(client_info);
+}
+
+void OnGetWindowClientsOnUI(
+ // The tuple contains process_id, frame_id, client_uuid.
+ const std::vector<base::Tuple<int, int, std::string>>& clients_info,
+ const GURL& script_url,
+ const GetWindowClientsCallback& callback) {
+ scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients);
+
+ for (const auto& it : clients_info) {
+ ServiceWorkerClientInfo info =
+ ServiceWorkerProviderHost::GetWindowClientInfoOnUI(base::get<0>(it),
+ base::get<1>(it));
+
+ // If the request to the provider_host returned an empty
+ // ServiceWorkerClientInfo, that means that it wasn't possible to associate
+ // it with a valid RenderFrameHost. It might be because the frame was killed
+ // or navigated in between.
+ if (info.IsEmpty())
+ continue;
+
+ // We can get info for a frame that was navigating end ended up with a
+ // different URL than expected. In such case, we should make sure to not
+ // expose cross-origin WindowClient.
+ if (info.url.GetOrigin() != script_url.GetOrigin())
+ continue;
+
+ info.client_uuid = base::get<2>(it);
+ clients->push_back(info);
+ }
+
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, base::Passed(&clients)));
+}
+
+struct ServiceWorkerClientInfoSortMRU {
+ bool operator()(const ServiceWorkerClientInfo& a,
+ const ServiceWorkerClientInfo& b) const {
+ return a.last_focus_time > b.last_focus_time;
+ }
+};
+
+void DidGetClients(const ClientsCallback& callback,
+ ServiceWorkerClients* clients) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Sort clients so that the most recently active tab is in the front.
+ std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSortMRU());
+
+ callback.Run(clients);
+}
+
+void GetNonWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ ServiceWorkerClients* clients) {
+ if (!options.include_uncontrolled) {
+ for (auto& controllee : controller->controllee_map())
+ AddNonWindowClient(controllee.second, options, clients);
+ } else if (controller->context()) {
+ GURL origin = controller->script_url().GetOrigin();
+ for (auto it = controller->context()->GetClientProviderHostIterator(origin);
+ !it->IsAtEnd(); it->Advance()) {
+ AddNonWindowClient(it->GetProviderHost(), options, clients);
+ }
+ }
+}
+
+void DidGetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ const ClientsCallback& callback,
+ scoped_ptr<ServiceWorkerClients> clients) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (options.client_type == blink::WebServiceWorkerClientTypeAll)
+ GetNonWindowClients(controller, options, clients.get());
+ DidGetClients(callback, clients.get());
+}
+
+void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ const ClientsCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(options.client_type == blink::WebServiceWorkerClientTypeWindow ||
+ options.client_type == blink::WebServiceWorkerClientTypeAll);
+
+ std::vector<base::Tuple<int, int, std::string>> clients_info;
+ if (!options.include_uncontrolled) {
+ for (auto& controllee : controller->controllee_map())
+ AddWindowClient(controllee.second, &clients_info);
+ } else if (controller->context()) {
+ GURL origin = controller->script_url().GetOrigin();
+ for (auto it = controller->context()->GetClientProviderHostIterator(origin);
+ !it->IsAtEnd(); it->Advance()) {
+ AddWindowClient(it->GetProviderHost(), &clients_info);
+ }
+ }
+
+ if (clients_info.empty()) {
+ DidGetWindowClients(controller, options, callback,
+ make_scoped_ptr(new ServiceWorkerClients));
+ return;
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &OnGetWindowClientsOnUI, clients_info, controller->script_url(),
+ base::Bind(&DidGetWindowClients, controller, options, callback)));
+}
+
+} // namespace
+
+void OpenWindow(const GURL& url,
+ const GURL& script_url,
+ int worker_process_id,
+ const base::WeakPtr<ServiceWorkerContextCore>& context,
+ const NavigationCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &OpenWindowOnUI, url, script_url, worker_process_id,
+ make_scoped_refptr(context->wrapper()),
+ base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback)));
+}
+
+void NavigateClient(const GURL& url,
+ const GURL& script_url,
+ int process_id,
+ int frame_id,
+ const base::WeakPtr<ServiceWorkerContextCore>& context,
+ const NavigationCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &NavigateClientOnUI, url, script_url, process_id, frame_id,
+ base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback)));
+}
+
+void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ const ClientsCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ ServiceWorkerClients clients;
+ if (!controller->HasControllee() && !options.include_uncontrolled) {
+ DidGetClients(callback, &clients);
+ return;
+ }
+
+ // For Window clients we want to query the info on the UI thread first.
+ if (options.client_type == blink::WebServiceWorkerClientTypeWindow ||
+ options.client_type == blink::WebServiceWorkerClientTypeAll) {
+ GetWindowClients(controller, options, callback);
+ return;
+ }
+
+ GetNonWindowClients(controller, options, &clients);
+ DidGetClients(callback, &clients);
+}
+
+} // namespace service_worker_client_utils
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_client_utils.h b/chromium/content/browser/service_worker/service_worker_client_utils.h
new file mode 100644
index 00000000000..258268e1e0d
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_client_utils.h
@@ -0,0 +1,60 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CLIENT_UTILS_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CLIENT_UTILS_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+
+class GURL;
+
+namespace content {
+
+class ServiceWorkerContextCore;
+class ServiceWorkerVersion;
+struct ServiceWorkerClientInfo;
+struct ServiceWorkerClientQueryOptions;
+
+namespace service_worker_client_utils {
+
+using NavigationCallback =
+ base::Callback<void(ServiceWorkerStatusCode status,
+ const std::string& client_uuid,
+ const ServiceWorkerClientInfo& client_info)>;
+using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>;
+using ClientsCallback = base::Callback<void(ServiceWorkerClients* clients)>;
+
+// Opens a new window and navigates it to |url|. |callback| is called with the
+// window's client information on completion.
+void OpenWindow(const GURL& url,
+ const GURL& script_url,
+ int worker_process_id,
+ const base::WeakPtr<ServiceWorkerContextCore>& context,
+ const NavigationCallback& callback);
+
+// Navigates the client specified by |process_id| and |frame_id| to |url|.
+// |callback| is called with the client information on completion.
+void NavigateClient(const GURL& url,
+ const GURL& script_url,
+ int process_id,
+ int frame_id,
+ const base::WeakPtr<ServiceWorkerContextCore>& context,
+ const NavigationCallback& callback);
+
+// Collects clients matched with |options|. |callback| is called with the client
+// information sorted in MRU order (most recently focused order) on completion.
+void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ const ClientsCallback& callback);
+
+} // namespace service_worker_client_utils
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CLIENT_UTILS_H_
diff --git a/chromium/content/browser/service_worker/service_worker_context_core.cc b/chromium/content/browser/service_worker/service_worker_context_core.cc
index 8e3752ef4be..f6aa2123468 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_core.cc
@@ -4,14 +4,18 @@
#include "content/browser/service_worker/service_worker_context_core.h"
+#include <utility>
+
#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/service_worker_context_observer.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -23,6 +27,7 @@
#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/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_message.h"
#include "net/http/http_response_headers.h"
@@ -57,6 +62,30 @@ bool IsSameOriginClientProviderHost(const GURL& origin,
host->document_url().GetOrigin() == origin;
}
+bool IsSameOriginWindowProviderHost(const GURL& origin,
+ ServiceWorkerProviderHost* host) {
+ return host->provider_type() ==
+ ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_WINDOW &&
+ host->document_url().GetOrigin() == origin;
+}
+
+// Returns true if any of the frames specified by |frames| is a top-level frame.
+// |frames| is a vector of (render process id, frame id) pairs.
+bool FrameListContainsMainFrameOnUI(
+ scoped_ptr<std::vector<std::pair<int, int>>> frames) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ for (const auto& frame : *frames) {
+ RenderFrameHostImpl* render_frame_host =
+ RenderFrameHostImpl::FromID(frame.first, frame.second);
+ if (!render_frame_host)
+ continue;
+ if (!render_frame_host->GetParent())
+ return true;
+ }
+ return false;
+}
+
class ClearAllServiceWorkersHelper
: public base::RefCounted<ClearAllServiceWorkersHelper> {
public:
@@ -76,7 +105,11 @@ class ClearAllServiceWorkersHelper
const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
if (!context)
return;
- for (const auto& version_itr : context->GetLiveVersions()) {
+ // Make a copy of live versions map because StopWorker() removes the version
+ // from it when we were starting up and don't have a process yet.
+ const std::map<int64_t, ServiceWorkerVersion*> live_versions_copy =
+ context->GetLiveVersions();
+ for (const auto& version_itr : live_versions_copy) {
ServiceWorkerVersion* version(version_itr.second);
if (version->running_status() == ServiceWorkerVersion::STARTING ||
version->running_status() == ServiceWorkerVersion::RUNNING) {
@@ -191,12 +224,9 @@ ServiceWorkerContextCore::ServiceWorkerContextCore(
weak_factory_(this) {
// These get a WeakPtr from weak_factory_, so must be set after weak_factory_
// is initialized.
- storage_ = ServiceWorkerStorage::Create(path,
- AsWeakPtr(),
- database_task_manager.Pass(),
- disk_cache_thread,
- quota_manager_proxy,
- special_storage_policy);
+ storage_ = ServiceWorkerStorage::Create(
+ path, AsWeakPtr(), std::move(database_task_manager), disk_cache_thread,
+ quota_manager_proxy, special_storage_policy);
embedded_worker_registry_ = EmbeddedWorkerRegistry::Create(AsWeakPtr());
job_coordinator_.reset(new ServiceWorkerJobCoordinator(AsWeakPtr()));
}
@@ -276,6 +306,37 @@ ServiceWorkerContextCore::GetClientProviderHostIterator(const GURL& origin) {
providers_.get(), base::Bind(IsSameOriginClientProviderHost, origin)));
}
+void ServiceWorkerContextCore::HasMainFrameProviderHost(
+ const GURL& origin,
+ const BoolCallback& callback) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ProviderHostIterator provider_host_iterator(
+ providers_.get(), base::Bind(IsSameOriginWindowProviderHost, origin));
+
+ if (provider_host_iterator.IsAtEnd()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, false));
+ return;
+ }
+
+ scoped_ptr<std::vector<std::pair<int, int>>> render_frames(
+ new std::vector<std::pair<int, int>>());
+
+ while (!provider_host_iterator.IsAtEnd()) {
+ ServiceWorkerProviderHost* provider_host =
+ provider_host_iterator.GetProviderHost();
+ render_frames->push_back(
+ std::make_pair(provider_host->process_id(), provider_host->frame_id()));
+ provider_host_iterator.Advance();
+ }
+
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&FrameListContainsMainFrameOnUI,
+ base::Passed(std::move(render_frames))),
+ callback);
+}
+
void ServiceWorkerContextCore::RegisterProviderHostByClientID(
const std::string& client_uuid,
ServiceWorkerProviderHost* provider_host) {
@@ -462,7 +523,7 @@ void ServiceWorkerContextCore::UpdateComplete(
void ServiceWorkerContextCore::UnregistrationComplete(
const GURL& pattern,
const ServiceWorkerContextCore::UnregistrationCallback& callback,
- int64 registration_id,
+ int64_t registration_id,
ServiceWorkerStatusCode status) {
callback.Run(status);
if (status == SERVICE_WORKER_OK && observer_list_.get()) {
@@ -473,7 +534,7 @@ void ServiceWorkerContextCore::UnregistrationComplete(
}
ServiceWorkerRegistration* ServiceWorkerContextCore::GetLiveRegistration(
- int64 id) {
+ int64_t id) {
RegistrationsMap::iterator it = live_registrations_.find(id);
return (it != live_registrations_.end()) ? it->second : NULL;
}
@@ -489,16 +550,42 @@ void ServiceWorkerContextCore::AddLiveRegistration(
}
}
-void ServiceWorkerContextCore::RemoveLiveRegistration(int64 id) {
+void ServiceWorkerContextCore::RemoveLiveRegistration(int64_t id) {
live_registrations_.erase(id);
}
-ServiceWorkerVersion* ServiceWorkerContextCore::GetLiveVersion(
- int64 id) {
+ServiceWorkerVersion* ServiceWorkerContextCore::GetLiveVersion(int64_t id) {
VersionMap::iterator it = live_versions_.find(id);
return (it != live_versions_.end()) ? it->second : NULL;
}
+// PlzNavigate
+void ServiceWorkerContextCore::AddNavigationHandleCore(
+ int service_worker_provider_id,
+ ServiceWorkerNavigationHandleCore* handle) {
+ auto result = navigation_handle_cores_map_.insert(
+ std::pair<int, ServiceWorkerNavigationHandleCore*>(
+ service_worker_provider_id, handle));
+ DCHECK(result.second)
+ << "Inserting a duplicate ServiceWorkerNavigationHandleCore";
+}
+
+// PlzNavigate
+void ServiceWorkerContextCore::RemoveNavigationHandleCore(
+ int service_worker_provider_id) {
+ navigation_handle_cores_map_.erase(service_worker_provider_id);
+}
+
+// PlzNavigate
+ServiceWorkerNavigationHandleCore*
+ServiceWorkerContextCore::GetNavigationHandleCore(
+ int service_worker_provider_id) {
+ auto result = navigation_handle_cores_map_.find(service_worker_provider_id);
+ if (result == navigation_handle_cores_map_.end())
+ return nullptr;
+ return result->second;
+}
+
void ServiceWorkerContextCore::AddLiveVersion(ServiceWorkerVersion* version) {
// TODO(horo): If we will see crashes here, we have to find the root cause of
// the version ID conflict. Otherwise change CHECK to DCHECK.
@@ -513,17 +600,16 @@ void ServiceWorkerContextCore::AddLiveVersion(ServiceWorkerVersion* version) {
}
}
-void ServiceWorkerContextCore::RemoveLiveVersion(int64 id) {
+void ServiceWorkerContextCore::RemoveLiveVersion(int64_t id) {
live_versions_.erase(id);
}
std::vector<ServiceWorkerRegistrationInfo>
ServiceWorkerContextCore::GetAllLiveRegistrationInfo() {
std::vector<ServiceWorkerRegistrationInfo> infos;
- for (std::map<int64, ServiceWorkerRegistration*>::const_iterator iter =
+ for (std::map<int64_t, ServiceWorkerRegistration*>::const_iterator iter =
live_registrations_.begin();
- iter != live_registrations_.end();
- ++iter) {
+ iter != live_registrations_.end(); ++iter) {
infos.push_back(iter->second->GetInfo());
}
return infos;
@@ -532,10 +618,9 @@ ServiceWorkerContextCore::GetAllLiveRegistrationInfo() {
std::vector<ServiceWorkerVersionInfo>
ServiceWorkerContextCore::GetAllLiveVersionInfo() {
std::vector<ServiceWorkerVersionInfo> infos;
- for (std::map<int64, ServiceWorkerVersion*>::const_iterator iter =
+ for (std::map<int64_t, ServiceWorkerVersion*>::const_iterator iter =
live_versions_.begin();
- iter != live_versions_.end();
- ++iter) {
+ iter != live_versions_.end(); ++iter) {
infos.push_back(iter->second->GetInfo());
}
return infos;
@@ -548,7 +633,7 @@ void ServiceWorkerContextCore::ProtectVersion(
protected_versions_[version->version_id()] = version;
}
-void ServiceWorkerContextCore::UnprotectVersion(int64 version_id) {
+void ServiceWorkerContextCore::UnprotectVersion(int64_t version_id) {
DCHECK(protected_versions_.find(version_id) != protected_versions_.end());
protected_versions_.erase(version_id);
}
@@ -623,6 +708,16 @@ void ServiceWorkerContextCore::ClearAllServiceWorkersForTest(
AsWeakPtr()));
}
+void ServiceWorkerContextCore::CheckHasServiceWorker(
+ const GURL& url,
+ const GURL& other_url,
+ const ServiceWorkerContext::CheckHasServiceWorkerCallback callback) {
+ storage()->FindRegistrationForDocument(
+ url, base::Bind(&ServiceWorkerContextCore::
+ DidFindRegistrationForCheckHasServiceWorker,
+ AsWeakPtr(), other_url, callback));
+}
+
void ServiceWorkerContextCore::OnRunningStateChanged(
ServiceWorkerVersion* version) {
if (!observer_list_)
@@ -714,4 +809,42 @@ ServiceWorkerProcessManager* ServiceWorkerContextCore::process_manager() {
return wrapper_->process_manager();
}
+void ServiceWorkerContextCore::DidFindRegistrationForCheckHasServiceWorker(
+ const GURL& other_url,
+ const ServiceWorkerContext::CheckHasServiceWorkerCallback callback,
+ ServiceWorkerStatusCode status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ if (status != SERVICE_WORKER_OK) {
+ callback.Run(false);
+ return;
+ }
+
+ if (!ServiceWorkerUtils::ScopeMatches(registration->pattern(), other_url)) {
+ callback.Run(false);
+ return;
+ }
+
+ if (registration->is_uninstalling() || registration->is_uninstalled()) {
+ callback.Run(false);
+ return;
+ }
+
+ if (!registration->active_version() && !registration->waiting_version()) {
+ registration->RegisterRegistrationFinishedCallback(
+ base::Bind(&ServiceWorkerContextCore::
+ OnRegistrationFinishedForCheckHasServiceWorker,
+ AsWeakPtr(), callback, registration));
+ return;
+ }
+
+ callback.Run(true);
+}
+
+void ServiceWorkerContextCore::OnRegistrationFinishedForCheckHasServiceWorker(
+ const ServiceWorkerContext::CheckHasServiceWorkerCallback callback,
+ const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ callback.Run(registration->active_version() ||
+ registration->waiting_version());
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_context_core.h b/chromium/content/browser/service_worker/service_worker_context_core.h
index 2467ba6a72b..f9448864207 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.h
+++ b/chromium/content/browser/service_worker/service_worker_context_core.h
@@ -5,12 +5,15 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_H_
+#include <stdint.h>
+
#include <map>
#include <vector>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/id_map.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list_threadsafe.h"
@@ -20,6 +23,7 @@
#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"
+#include "content/public/browser/service_worker_context.h"
class GURL;
@@ -42,6 +46,7 @@ class ServiceWorkerContextWrapper;
class ServiceWorkerDatabaseTaskManager;
class ServiceWorkerHandle;
class ServiceWorkerJobCoordinator;
+class ServiceWorkerNavigationHandleCore;
class ServiceWorkerProviderHost;
class ServiceWorkerRegistration;
class ServiceWorkerStorage;
@@ -54,13 +59,14 @@ class ServiceWorkerStorage;
class CONTENT_EXPORT ServiceWorkerContextCore
: NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) {
public:
+ using BoolCallback = base::Callback<void(bool)>;
typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
typedef base::Callback<void(ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id)> RegistrationCallback;
+ int64_t registration_id)> RegistrationCallback;
typedef base::Callback<void(ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id)> UpdateCallback;
+ int64_t registration_id)> UpdateCallback;
typedef base::Callback<
void(ServiceWorkerStatusCode status)> UnregistrationCallback;
typedef IDMap<ServiceWorkerProviderHost, IDMapOwnPointer> ProviderMap;
@@ -159,6 +165,11 @@ class CONTENT_EXPORT ServiceWorkerContextCore
scoped_ptr<ProviderHostIterator> GetClientProviderHostIterator(
const GURL& origin);
+ // Runs the callback with true if there is a ProviderHost for |origin| of type
+ // SERVICE_WORKER_PROVIDER_FOR_WINDOW which is a main (top-level) frame.
+ void HasMainFrameProviderHost(const GURL& origin,
+ const BoolCallback& callback) const;
+
// Maintains a map from Client UUID to ProviderHost.
// (Note: instead of maintaining 2 maps we might be able to uniformly use
// UUID instead of process_id+provider_id elsewhere. For now I'm leaving
@@ -178,11 +189,15 @@ class CONTENT_EXPORT ServiceWorkerContextCore
const RegistrationCallback& callback);
void UnregisterServiceWorker(const GURL& pattern,
const UnregistrationCallback& callback);
+
// Callback is called issued after all unregistrations occur. The Status
// is populated as SERVICE_WORKER_OK if all succeed, or SERVICE_WORKER_FAILED
// if any did not succeed.
void UnregisterServiceWorkers(const GURL& origin,
const UnregistrationCallback& callback);
+
+ // Updates the service worker. If |force_bypass_cache| is true or 24 hours
+ // have passed since the last update, bypasses the browser cache.
void UpdateServiceWorker(ServiceWorkerRegistration* registration,
bool force_bypass_cache);
void UpdateServiceWorker(ServiceWorkerRegistration* registration,
@@ -201,27 +216,36 @@ class CONTENT_EXPORT ServiceWorkerContextCore
// This class maintains collections of live instances, this class
// does not own these object or influence their lifetime.
- ServiceWorkerRegistration* GetLiveRegistration(int64 registration_id);
+ ServiceWorkerRegistration* GetLiveRegistration(int64_t registration_id);
void AddLiveRegistration(ServiceWorkerRegistration* registration);
- void RemoveLiveRegistration(int64 registration_id);
- const std::map<int64, ServiceWorkerRegistration*>& GetLiveRegistrations()
+ void RemoveLiveRegistration(int64_t registration_id);
+ const std::map<int64_t, ServiceWorkerRegistration*>& GetLiveRegistrations()
const {
return live_registrations_;
}
- ServiceWorkerVersion* GetLiveVersion(int64 version_id);
+ ServiceWorkerVersion* GetLiveVersion(int64_t version_id);
void AddLiveVersion(ServiceWorkerVersion* version);
- void RemoveLiveVersion(int64 registration_id);
- const std::map<int64, ServiceWorkerVersion*>& GetLiveVersions() const {
+ void RemoveLiveVersion(int64_t registration_id);
+ const std::map<int64_t, ServiceWorkerVersion*>& GetLiveVersions() const {
return live_versions_;
}
+ // PlzNavigate
+ // Methods to manage the map keeping track of all
+ // ServiceWorkerNavigationHandleCores registered for ongoing navigations.
+ void AddNavigationHandleCore(int service_worker_provider_id,
+ ServiceWorkerNavigationHandleCore* handle);
+ void RemoveNavigationHandleCore(int service_worker_provider_id);
+ ServiceWorkerNavigationHandleCore* GetNavigationHandleCore(
+ int service_worker_provider_id);
+
std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo();
std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo();
// ProtectVersion holds a reference to |version| until UnprotectVersion is
// called.
void ProtectVersion(const scoped_refptr<ServiceWorkerVersion>& version);
- void UnprotectVersion(int64 version_id);
+ void UnprotectVersion(int64_t version_id);
// Returns new context-local unique ID.
int GetNewServiceWorkerHandleId();
@@ -244,14 +268,21 @@ class CONTENT_EXPORT ServiceWorkerContextCore
void ClearAllServiceWorkersForTest(const base::Closure& callback);
+ // Determines if there is a ServiceWorker registration that matches |url|, and
+ // if |other_url| falls inside the scope of the same registration. See
+ // ServiceWorkerContext::CheckHasServiceWorker for more details.
+ void CheckHasServiceWorker(
+ const GURL& url,
+ const GURL& other_url,
+ const ServiceWorkerContext::CheckHasServiceWorkerCallback callback);
+
base::WeakPtr<ServiceWorkerContextCore> AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
private:
- friend class ServiceWorkerContext;
- typedef std::map<int64, ServiceWorkerRegistration*> RegistrationsMap;
- typedef std::map<int64, ServiceWorkerVersion*> VersionMap;
+ typedef std::map<int64_t, ServiceWorkerRegistration*> RegistrationsMap;
+ typedef std::map<int64_t, ServiceWorkerVersion*> VersionMap;
ProviderMap* GetProviderMapForProcess(int process_id) {
return providers_->Lookup(process_id);
@@ -270,7 +301,7 @@ class CONTENT_EXPORT ServiceWorkerContextCore
void UnregistrationComplete(const GURL& pattern,
const UnregistrationCallback& callback,
- int64 registration_id,
+ int64_t registration_id,
ServiceWorkerStatusCode status);
void DidGetAllRegistrationsForUnregisterForOrigin(
@@ -278,6 +309,15 @@ class CONTENT_EXPORT ServiceWorkerContextCore
const GURL& origin,
const std::vector<ServiceWorkerRegistrationInfo>& registrations);
+ void DidFindRegistrationForCheckHasServiceWorker(
+ const GURL& other_url,
+ const ServiceWorkerContext::CheckHasServiceWorkerCallback callback,
+ ServiceWorkerStatusCode status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration);
+ void OnRegistrationFinishedForCheckHasServiceWorker(
+ const ServiceWorkerContext::CheckHasServiceWorkerCallback callback,
+ const scoped_refptr<ServiceWorkerRegistration>& registration);
+
// It's safe to store a raw pointer instead of a scoped_refptr to |wrapper_|
// because the Wrapper::Shutdown call that hops threads to destroy |this| uses
// Bind() to hold a reference to |wrapper_| until |this| is fully destroyed.
@@ -287,9 +327,15 @@ class CONTENT_EXPORT ServiceWorkerContextCore
scoped_ptr<ServiceWorkerStorage> storage_;
scoped_refptr<EmbeddedWorkerRegistry> embedded_worker_registry_;
scoped_ptr<ServiceWorkerJobCoordinator> job_coordinator_;
- std::map<int64, ServiceWorkerRegistration*> live_registrations_;
- std::map<int64, ServiceWorkerVersion*> live_versions_;
- std::map<int64, scoped_refptr<ServiceWorkerVersion>> protected_versions_;
+ std::map<int64_t, ServiceWorkerRegistration*> live_registrations_;
+ std::map<int64_t, ServiceWorkerVersion*> live_versions_;
+ std::map<int64_t, scoped_refptr<ServiceWorkerVersion>> protected_versions_;
+
+ // PlzNavigate
+ // Map of ServiceWorkerNavigationHandleCores used for navigation requests.
+ std::map<int, ServiceWorkerNavigationHandleCore*>
+ navigation_handle_cores_map_;
+
int next_handle_id_;
int next_registration_handle_id_;
// Set in RegisterServiceWorker(), cleared in ClearAllServiceWorkersForTest().
diff --git a/chromium/content/browser/service_worker/service_worker_context_observer.h b/chromium/content/browser/service_worker/service_worker_context_observer.h
index 1dcd73ec33d..86c238546b8 100644
--- a/chromium/content/browser/service_worker/service_worker_context_observer.h
+++ b/chromium/content/browser/service_worker/service_worker_context_observer.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_OBSERVER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_OBSERVER_H_
+#include <stdint.h>
+
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -45,39 +47,40 @@ class ServiceWorkerContextObserver {
const int line_number;
const GURL source_url;
};
- virtual void OnNewLiveRegistration(int64 registration_id,
+ virtual void OnNewLiveRegistration(int64_t registration_id,
const GURL& pattern) {}
- virtual void OnNewLiveVersion(int64 version_id,
- int64 registration_id,
+ virtual void OnNewLiveVersion(int64_t version_id,
+ int64_t registration_id,
const GURL& script_url) {}
virtual void OnRunningStateChanged(
- int64 version_id,
+ int64_t version_id,
ServiceWorkerVersion::RunningStatus running_status) {}
- virtual void OnVersionStateChanged(int64 version_id,
+ virtual void OnVersionStateChanged(int64_t version_id,
ServiceWorkerVersion::Status status) {}
virtual void OnMainScriptHttpResponseInfoSet(
- int64 version_id,
+ int64_t version_id,
base::Time script_response_time,
base::Time script_last_modified) {}
- virtual void OnErrorReported(int64 version_id,
+ virtual void OnErrorReported(int64_t version_id,
int process_id,
int thread_id,
const ErrorInfo& info) {}
- virtual void OnReportConsoleMessage(int64 version_id,
+ virtual void OnReportConsoleMessage(int64_t version_id,
int process_id,
int thread_id,
const ConsoleMessage& message) {}
- virtual void OnControlleeAdded(int64 version_id,
+ virtual void OnControlleeAdded(int64_t version_id,
const std::string& uuid,
int process_id,
int route_id,
ServiceWorkerProviderType type) {}
- virtual void OnControlleeRemoved(int64 version_id, const std::string& uuid) {}
- virtual void OnRegistrationStored(int64 registration_id,
+ virtual void OnControlleeRemoved(int64_t version_id,
+ const std::string& uuid) {}
+ virtual void OnRegistrationStored(int64_t registration_id,
const GURL& pattern) {}
- virtual void OnRegistrationDeleted(int64 registration_id,
+ virtual void OnRegistrationDeleted(int64_t registration_id,
const GURL& pattern) {}
- virtual void OnForceUpdateOnPageLoadChanged(int64 registration_id,
+ virtual void OnForceUpdateOnPageLoadChanged(int64_t registration_id,
bool force_update_on_page_load) {}
// Notified when the storage corruption recovery is completed and all stored
diff --git a/chromium/content/browser/service_worker/service_worker_context_request_handler.cc b/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
index 847b5c82033..8b76146de80 100644
--- a/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
@@ -60,8 +60,8 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
context_->GetLiveRegistration(version_->registration_id());
DCHECK(registration); // We're registering or updating so must be there.
- int64 response_id = context_->storage()->NewResourceId();
- if (response_id == kInvalidServiceWorkerResponseId)
+ int64_t resource_id = context_->storage()->NewResourceId();
+ if (resource_id == kInvalidServiceWorkerResourceId)
return NULL;
// Bypass the browser cache for initial installs and update
@@ -78,21 +78,21 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
ServiceWorkerVersion* stored_version = registration->waiting_version()
? registration->waiting_version()
: registration->active_version();
- int64 incumbent_response_id = kInvalidServiceWorkerResourceId;
+ int64_t incumbent_resource_id = kInvalidServiceWorkerResourceId;
if (stored_version && stored_version->script_url() == request->url()) {
- incumbent_response_id =
+ incumbent_resource_id =
stored_version->script_cache_map()->LookupResourceId(request->url());
}
return new ServiceWorkerWriteToCacheJob(
request, network_delegate, resource_type_, context_, version_.get(),
- extra_load_flags, response_id, incumbent_response_id);
+ extra_load_flags, resource_id, incumbent_resource_id);
}
- int64 response_id = kInvalidServiceWorkerResponseId;
- if (ShouldReadFromScriptCache(request->url(), &response_id)) {
+ int64_t resource_id = kInvalidServiceWorkerResourceId;
+ if (ShouldReadFromScriptCache(request->url(), &resource_id)) {
return new ServiceWorkerReadFromCacheJob(request, network_delegate,
resource_type_, context_, version_,
- response_id);
+ resource_id);
}
// NULL means use the network.
@@ -116,17 +116,18 @@ bool ServiceWorkerContextRequestHandler::ShouldAddToScriptCache(
return false;
}
return version_->script_cache_map()->LookupResourceId(url) ==
- kInvalidServiceWorkerResponseId;
+ kInvalidServiceWorkerResourceId;
}
bool ServiceWorkerContextRequestHandler::ShouldReadFromScriptCache(
- const GURL& url, int64* response_id_out) {
+ const GURL& url,
+ int64_t* resource_id_out) {
// We don't read from the script cache until the version is INSTALLED.
if (version_->status() == ServiceWorkerVersion::NEW ||
version_->status() == ServiceWorkerVersion::INSTALLING)
return false;
- *response_id_out = version_->script_cache_map()->LookupResourceId(url);
- return *response_id_out != kInvalidServiceWorkerResponseId;
+ *resource_id_out = version_->script_cache_map()->LookupResourceId(url);
+ return *resource_id_out != kInvalidServiceWorkerResourceId;
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_context_request_handler.h b/chromium/content/browser/service_worker/service_worker_context_request_handler.h
index 85db8ebf529..e86fb8332ae 100644
--- a/chromium/content/browser/service_worker/service_worker_context_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_context_request_handler.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_REQUEST_HANDLER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_REQUEST_HANDLER_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
namespace content {
@@ -33,7 +36,7 @@ class CONTENT_EXPORT ServiceWorkerContextRequestHandler
private:
bool ShouldAddToScriptCache(const GURL& url);
- bool ShouldReadFromScriptCache(const GURL& url, int64* response_id_out);
+ bool ShouldReadFromScriptCache(const GURL& url, int64_t* resource_id_out);
scoped_refptr<ServiceWorkerVersion> version_;
diff --git a/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
index e790ad98fc4..94bc88e612b 100644
--- a/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
@@ -2,6 +2,10 @@
// 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_request_handler.h"
+
+#include <utility>
+
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/run_loop.h"
@@ -9,7 +13,6 @@
#include "content/browser/fileapi/mock_url_request_delegate.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
-#include "content/browser/service_worker/service_worker_context_request_handler.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
@@ -23,8 +26,6 @@ namespace content {
namespace {
-int kMockRenderProcessId = 1224;
-
void EmptyCallback() {}
}
@@ -35,8 +36,7 @@ class ServiceWorkerContextRequestHandlerTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kMockRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
// A new unstored registration/version.
scope_ = GURL("http://host/scope/");
@@ -48,11 +48,11 @@ class ServiceWorkerContextRequestHandlerTest : public testing::Test {
// An empty host.
scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
- kMockRenderProcessId, MSG_ROUTING_NONE /* render_frame_id */,
- 1 /* provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- context()->AsWeakPtr(), nullptr));
+ helper_->mock_render_process_id(),
+ MSG_ROUTING_NONE /* render_frame_id */, 1 /* provider_id */,
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), nullptr));
provider_host_ = host->AsWeakPtr();
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
base::RunLoop().RunUntilIdle();
@@ -95,8 +95,8 @@ TEST_F(ServiceWorkerContextRequestHandlerTest, UpdateBefore24Hours) {
provider_host_,
base::WeakPtr<storage::BlobStorageContext>(),
RESOURCE_TYPE_SERVICE_WORKER));
- scoped_refptr<net::URLRequestJob> job =
- handler->MaybeCreateJob(request.get(), nullptr, nullptr);
+ scoped_ptr<net::URLRequestJob> job(
+ handler->MaybeCreateJob(request.get(), nullptr, nullptr));
ASSERT_TRUE(job.get());
ServiceWorkerWriteToCacheJob* sw_job =
static_cast<ServiceWorkerWriteToCacheJob*>(job.get());
@@ -123,8 +123,8 @@ TEST_F(ServiceWorkerContextRequestHandlerTest, UpdateAfter24Hours) {
provider_host_,
base::WeakPtr<storage::BlobStorageContext>(),
RESOURCE_TYPE_SERVICE_WORKER));
- scoped_refptr<net::URLRequestJob> job =
- handler->MaybeCreateJob(request.get(), nullptr, nullptr);
+ scoped_ptr<net::URLRequestJob> job(
+ handler->MaybeCreateJob(request.get(), nullptr, nullptr));
ASSERT_TRUE(job.get());
ServiceWorkerWriteToCacheJob* sw_job =
static_cast<ServiceWorkerWriteToCacheJob*>(job.get());
@@ -150,8 +150,8 @@ TEST_F(ServiceWorkerContextRequestHandlerTest, UpdateForceBypassCache) {
context()->AsWeakPtr(), provider_host_,
base::WeakPtr<storage::BlobStorageContext>(),
RESOURCE_TYPE_SERVICE_WORKER));
- scoped_refptr<net::URLRequestJob> job =
- handler->MaybeCreateJob(request.get(), nullptr, nullptr);
+ scoped_ptr<net::URLRequestJob> job(
+ handler->MaybeCreateJob(request.get(), nullptr, nullptr));
ASSERT_TRUE(job.get());
ServiceWorkerWriteToCacheJob* sw_job =
static_cast<ServiceWorkerWriteToCacheJob*>(job.get());
diff --git a/chromium/content/browser/service_worker/service_worker_context_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
index d299a2e3ba8..a9c898475dd 100644
--- a/chromium/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
@@ -4,6 +4,8 @@
#include "content/public/browser/service_worker_context.h"
+#include <stdint.h>
+
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
@@ -27,10 +29,10 @@ namespace content {
namespace {
void SaveResponseCallback(bool* called,
- int64* store_registration_id,
+ int64_t* store_registration_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
@@ -38,7 +40,7 @@ void SaveResponseCallback(bool* called,
ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback(
bool* called,
- int64* store_registration_id) {
+ int64_t* store_registration_id) {
return base::Bind(&SaveResponseCallback, called, store_registration_id);
}
@@ -78,8 +80,7 @@ void ExpectRegisteredWorkers(
class RejectInstallTestHelper : public EmbeddedWorkerTestHelper {
public:
- explicit RejectInstallTestHelper(int mock_render_process_id)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
+ RejectInstallTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
void OnInstallEvent(int embedded_worker_id,
int request_id) override {
@@ -92,8 +93,7 @@ class RejectInstallTestHelper : public EmbeddedWorkerTestHelper {
class RejectActivateTestHelper : public EmbeddedWorkerTestHelper {
public:
- explicit RejectActivateTestHelper(int mock_render_process_id)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
+ RejectActivateTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
void OnActivateEvent(int embedded_worker_id, int request_id) override {
SimulateSend(
@@ -112,7 +112,7 @@ enum NotificationType {
struct NotificationLog {
NotificationType type;
GURL pattern;
- int64 registration_id;
+ int64_t registration_id;
};
} // namespace
@@ -121,19 +121,17 @@ class ServiceWorkerContextTest : public ServiceWorkerContextObserver,
public testing::Test {
public:
ServiceWorkerContextTest()
- : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- render_process_id_(99) {}
+ : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), render_process_id_));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
helper_->context_wrapper()->AddObserver(this);
}
void TearDown() override { helper_.reset(); }
// ServiceWorkerContextObserver overrides.
- void OnRegistrationStored(int64 registration_id,
+ void OnRegistrationStored(int64_t registration_id,
const GURL& pattern) override {
NotificationLog log;
log.type = REGISTRATION_STORED;
@@ -141,7 +139,7 @@ class ServiceWorkerContextTest : public ServiceWorkerContextObserver,
log.registration_id = registration_id;
notifications_.push_back(log);
}
- void OnRegistrationDeleted(int64 registration_id,
+ void OnRegistrationDeleted(int64_t registration_id,
const GURL& pattern) override {
NotificationLog log;
log.type = REGISTRATION_DELETED;
@@ -160,7 +158,6 @@ class ServiceWorkerContextTest : public ServiceWorkerContextObserver,
protected:
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<EmbeddedWorkerTestHelper> helper_;
- const int render_process_id_;
std::vector<NotificationLog> notifications_;
};
@@ -169,7 +166,7 @@ TEST_F(ServiceWorkerContextTest, Register) {
GURL pattern("http://www.example.com/");
GURL script_url("http://www.example.com/service_worker.js");
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
bool called = false;
context()->RegisterServiceWorker(
pattern,
@@ -215,9 +212,9 @@ TEST_F(ServiceWorkerContextTest, Register_RejectInstall) {
GURL script_url("http://www.example.com/service_worker.js");
helper_.reset(); // Make sure the process lookups stay overridden.
- helper_.reset(new RejectInstallTestHelper(render_process_id_));
+ helper_.reset(new RejectInstallTestHelper);
helper_->context_wrapper()->AddObserver(this);
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
bool called = false;
context()->RegisterServiceWorker(
pattern,
@@ -262,9 +259,9 @@ TEST_F(ServiceWorkerContextTest, Register_RejectActivate) {
GURL script_url("http://www.example.com/service_worker.js");
helper_.reset();
- helper_.reset(new RejectActivateTestHelper(render_process_id_));
+ helper_.reset(new RejectActivateTestHelper);
helper_->context_wrapper()->AddObserver(this);
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
bool called = false;
context()->RegisterServiceWorker(
pattern, script_url, NULL,
@@ -302,7 +299,7 @@ TEST_F(ServiceWorkerContextTest, Unregister) {
GURL pattern("http://www.example.com/");
bool called = false;
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
context()->RegisterServiceWorker(
pattern,
GURL("http://www.example.com/service_worker.js"),
@@ -348,10 +345,10 @@ TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
GURL origin3_p1("http://www.other.com/");
bool called = false;
- int64 registration_id1 = kInvalidServiceWorkerRegistrationId;
- int64 registration_id2 = kInvalidServiceWorkerRegistrationId;
- int64 registration_id3 = kInvalidServiceWorkerRegistrationId;
- int64 registration_id4 = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id1 = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id2 = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id3 = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id4 = kInvalidServiceWorkerRegistrationId;
context()->RegisterServiceWorker(
origin1_p1,
GURL("http://www.example.com/service_worker.js"),
@@ -448,7 +445,7 @@ TEST_F(ServiceWorkerContextTest, RegisterNewScript) {
GURL pattern("http://www.example.com/");
bool called = false;
- int64 old_registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t old_registration_id = kInvalidServiceWorkerRegistrationId;
context()->RegisterServiceWorker(
pattern,
GURL("http://www.example.com/service_worker.js"),
@@ -461,7 +458,7 @@ TEST_F(ServiceWorkerContextTest, RegisterNewScript) {
EXPECT_NE(kInvalidServiceWorkerRegistrationId, old_registration_id);
called = false;
- int64 new_registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t new_registration_id = kInvalidServiceWorkerRegistrationId;
context()->RegisterServiceWorker(
pattern,
GURL("http://www.example.com/service_worker_new.js"),
@@ -491,7 +488,7 @@ TEST_F(ServiceWorkerContextTest, RegisterDuplicateScript) {
GURL script_url("http://www.example.com/service_worker.js");
bool called = false;
- int64 old_registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t old_registration_id = kInvalidServiceWorkerRegistrationId;
context()->RegisterServiceWorker(
pattern,
script_url,
@@ -504,7 +501,7 @@ TEST_F(ServiceWorkerContextTest, RegisterDuplicateScript) {
EXPECT_NE(kInvalidServiceWorkerRegistrationId, old_registration_id);
called = false;
- int64 new_registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t new_registration_id = kInvalidServiceWorkerRegistrationId;
context()->RegisterServiceWorker(
pattern,
script_url,
@@ -620,12 +617,11 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
// Reinitialize the helper to test on-disk storage.
base::ScopedTempDir user_data_directory;
ASSERT_TRUE(user_data_directory.CreateUniqueTempDir());
- helper_.reset(new EmbeddedWorkerTestHelper(user_data_directory.path(),
- render_process_id_));
+ helper_.reset(new EmbeddedWorkerTestHelper(user_data_directory.path()));
helper_->context_wrapper()->AddObserver(this);
}
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
bool called = false;
context()->RegisterServiceWorker(
pattern,
@@ -653,14 +649,11 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
context()->ScheduleDeleteAndStartOver();
// The storage is disabled while the recovery process is running, so the
- // operation should be failed.
+ // operation should be aborted.
context()->storage()->FindRegistrationForId(
- registration_id,
- pattern.GetOrigin(),
- base::Bind(&ExpectRegisteredWorkers,
- SERVICE_WORKER_ERROR_FAILED,
- false /* expect_waiting */,
- true /* expect_active */));
+ registration_id, pattern.GetOrigin(),
+ base::Bind(&ExpectRegisteredWorkers, SERVICE_WORKER_ERROR_ABORT,
+ false /* expect_waiting */, true /* expect_active */));
base::RunLoop().RunUntilIdle();
// The context started over and the storage was re-initialized, so the
diff --git a/chromium/content/browser/service_worker/service_worker_context_watcher.cc b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
index 9c0a24cd08f..d28f8bf6f96 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
@@ -4,6 +4,8 @@
#include "content/browser/service_worker/service_worker_context_watcher.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "content/browser/service_worker/service_worker_context_observer.h"
@@ -63,7 +65,7 @@ void ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
context_->AddObserver(this);
- base::ScopedPtrHashMap<int64, scoped_ptr<ServiceWorkerRegistrationInfo>>
+ base::ScopedPtrHashMap<int64_t, scoped_ptr<ServiceWorkerRegistrationInfo>>
registration_info_map;
for (const auto& registration : stored_registrations)
StoreRegistrationInfo(registration, &registration_info_map);
@@ -105,7 +107,7 @@ ServiceWorkerContextWatcher::~ServiceWorkerContextWatcher() {
void ServiceWorkerContextWatcher::StoreRegistrationInfo(
const ServiceWorkerRegistrationInfo& registration_info,
- base::ScopedPtrHashMap<int64, scoped_ptr<ServiceWorkerRegistrationInfo>>*
+ base::ScopedPtrHashMap<int64_t, scoped_ptr<ServiceWorkerRegistrationInfo>>*
info_map) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (registration_info.registration_id == kInvalidServiceWorkerRegistrationId)
@@ -129,7 +131,7 @@ void ServiceWorkerContextWatcher::StoreVersionInfo(
}
void ServiceWorkerContextWatcher::SendRegistrationInfo(
- int64 registration_id,
+ int64_t registration_id,
const GURL& pattern,
ServiceWorkerRegistrationInfo::DeleteFlag delete_flag) {
std::vector<ServiceWorkerRegistrationInfo> registrations;
@@ -154,14 +156,14 @@ void ServiceWorkerContextWatcher::SendVersionInfo(
base::Bind(version_callback_, versions));
}
-void ServiceWorkerContextWatcher::OnNewLiveRegistration(int64 registration_id,
+void ServiceWorkerContextWatcher::OnNewLiveRegistration(int64_t registration_id,
const GURL& pattern) {
SendRegistrationInfo(registration_id, pattern,
ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
}
-void ServiceWorkerContextWatcher::OnNewLiveVersion(int64 version_id,
- int64 registration_id,
+void ServiceWorkerContextWatcher::OnNewLiveVersion(int64_t version_id,
+ int64_t registration_id,
const GURL& script_url) {
if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id)) {
DCHECK_EQ(version->registration_id, registration_id);
@@ -175,11 +177,11 @@ void ServiceWorkerContextWatcher::OnNewLiveVersion(int64 version_id,
version->script_url = script_url;
SendVersionInfo(*version);
if (!IsStoppedAndRedundant(*version))
- version_info_map_.set(version_id, version.Pass());
+ version_info_map_.set(version_id, std::move(version));
}
void ServiceWorkerContextWatcher::OnRunningStateChanged(
- int64 version_id,
+ int64_t version_id,
content::ServiceWorkerVersion::RunningStatus running_status) {
ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
DCHECK(version);
@@ -192,7 +194,7 @@ void ServiceWorkerContextWatcher::OnRunningStateChanged(
}
void ServiceWorkerContextWatcher::OnVersionStateChanged(
- int64 version_id,
+ int64_t version_id,
content::ServiceWorkerVersion::Status status) {
ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
DCHECK(version);
@@ -205,7 +207,7 @@ void ServiceWorkerContextWatcher::OnVersionStateChanged(
}
void ServiceWorkerContextWatcher::OnMainScriptHttpResponseInfoSet(
- int64 version_id,
+ int64_t version_id,
base::Time script_response_time,
base::Time script_last_modified) {
ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
@@ -215,11 +217,11 @@ void ServiceWorkerContextWatcher::OnMainScriptHttpResponseInfoSet(
SendVersionInfo(*version);
}
-void ServiceWorkerContextWatcher::OnErrorReported(int64 version_id,
+void ServiceWorkerContextWatcher::OnErrorReported(int64_t version_id,
int process_id,
int thread_id,
const ErrorInfo& info) {
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id))
registration_id = version->registration_id;
BrowserThread::PostTask(
@@ -228,13 +230,13 @@ void ServiceWorkerContextWatcher::OnErrorReported(int64 version_id,
}
void ServiceWorkerContextWatcher::OnReportConsoleMessage(
- int64 version_id,
+ int64_t version_id,
int process_id,
int thread_id,
const ConsoleMessage& message) {
if (message.message_level != CONSOLE_MESSAGE_LEVEL_ERROR)
return;
- int64 registration_id = kInvalidServiceWorkerRegistrationId;
+ int64_t registration_id = kInvalidServiceWorkerRegistrationId;
if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id))
registration_id = version->registration_id;
BrowserThread::PostTask(
@@ -245,7 +247,7 @@ void ServiceWorkerContextWatcher::OnReportConsoleMessage(
}
void ServiceWorkerContextWatcher::OnControlleeAdded(
- int64 version_id,
+ int64_t version_id,
const std::string& uuid,
int process_id,
int route_id,
@@ -257,7 +259,7 @@ void ServiceWorkerContextWatcher::OnControlleeAdded(
SendVersionInfo(*version);
}
-void ServiceWorkerContextWatcher::OnControlleeRemoved(int64 version_id,
+void ServiceWorkerContextWatcher::OnControlleeRemoved(int64_t version_id,
const std::string& uuid) {
ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
if (!version)
@@ -266,20 +268,20 @@ void ServiceWorkerContextWatcher::OnControlleeRemoved(int64 version_id,
SendVersionInfo(*version);
}
-void ServiceWorkerContextWatcher::OnRegistrationStored(int64 registration_id,
+void ServiceWorkerContextWatcher::OnRegistrationStored(int64_t registration_id,
const GURL& pattern) {
SendRegistrationInfo(registration_id, pattern,
ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
}
-void ServiceWorkerContextWatcher::OnRegistrationDeleted(int64 registration_id,
+void ServiceWorkerContextWatcher::OnRegistrationDeleted(int64_t registration_id,
const GURL& pattern) {
SendRegistrationInfo(registration_id, pattern,
ServiceWorkerRegistrationInfo::IS_DELETED);
}
void ServiceWorkerContextWatcher::OnForceUpdateOnPageLoadChanged(
- int64 registration_id,
+ int64_t registration_id,
bool force_update_on_page_load) {
ServiceWorkerRegistration* registration =
context_->GetLiveRegistration(registration_id);
diff --git a/chromium/content/browser/service_worker/service_worker_context_watcher.h b/chromium/content/browser/service_worker/service_worker_context_watcher.h
index a7b430ebb93..506418bacc1 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.h
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_WATCHER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_WATCHER_H_
+#include <stdint.h>
+
#include <vector>
#include "base/callback.h"
@@ -27,8 +29,8 @@ class ServiceWorkerContextWatcher
WorkerRegistrationUpdatedCallback;
typedef base::Callback<void(const std::vector<ServiceWorkerVersionInfo>&)>
WorkerVersionUpdatedCallback;
- typedef base::Callback<void(int64 /* registration_id */,
- int64 /* version_id */,
+ typedef base::Callback<void(int64_t /* registration_id */,
+ int64_t /* version_id */,
const ErrorInfo&)> WorkerErrorReportedCallback;
ServiceWorkerContextWatcher(
@@ -50,54 +52,56 @@ class ServiceWorkerContextWatcher
void StoreRegistrationInfo(
const ServiceWorkerRegistrationInfo& registration,
- base::ScopedPtrHashMap<int64, scoped_ptr<ServiceWorkerRegistrationInfo>>*
+ base::ScopedPtrHashMap<int64_t,
+ scoped_ptr<ServiceWorkerRegistrationInfo>>*
info_map);
void StoreVersionInfo(const ServiceWorkerVersionInfo& version);
void SendRegistrationInfo(
- int64 registration_id,
+ int64_t registration_id,
const GURL& pattern,
ServiceWorkerRegistrationInfo::DeleteFlag delete_flag);
void SendVersionInfo(const ServiceWorkerVersionInfo& version);
// ServiceWorkerContextObserver implements
- void OnNewLiveRegistration(int64 registration_id,
+ void OnNewLiveRegistration(int64_t registration_id,
const GURL& pattern) override;
- void OnNewLiveVersion(int64 version_id,
- int64 registration_id,
+ void OnNewLiveVersion(int64_t version_id,
+ int64_t registration_id,
const GURL& script_url) override;
void OnRunningStateChanged(
- int64 version_id,
+ int64_t version_id,
content::ServiceWorkerVersion::RunningStatus running_status) override;
void OnVersionStateChanged(
- int64 version_id,
+ int64_t version_id,
content::ServiceWorkerVersion::Status status) override;
void OnMainScriptHttpResponseInfoSet(
- int64 version_id,
+ int64_t version_id,
base::Time script_response_time,
base::Time script_last_modified) override;
- void OnErrorReported(int64 version_id,
+ void OnErrorReported(int64_t version_id,
int process_id,
int thread_id,
const ErrorInfo& info) override;
- void OnReportConsoleMessage(int64 version_id,
+ void OnReportConsoleMessage(int64_t version_id,
int process_id,
int thread_id,
const ConsoleMessage& message) override;
- void OnControlleeAdded(int64 version_id,
+ void OnControlleeAdded(int64_t version_id,
const std::string& uuid,
int process_id,
int route_id,
ServiceWorkerProviderType type) override;
- void OnControlleeRemoved(int64 version_id, const std::string& uuid) override;
- void OnRegistrationStored(int64 registration_id,
+ void OnControlleeRemoved(int64_t version_id,
+ const std::string& uuid) override;
+ void OnRegistrationStored(int64_t registration_id,
const GURL& pattern) override;
- void OnRegistrationDeleted(int64 registration_id,
+ void OnRegistrationDeleted(int64_t registration_id,
const GURL& pattern) override;
- void OnForceUpdateOnPageLoadChanged(int64 registration_id,
+ void OnForceUpdateOnPageLoadChanged(int64_t registration_id,
bool force_update_on_page_load) override;
- base::ScopedPtrHashMap<int64, scoped_ptr<ServiceWorkerVersionInfo>>
+ base::ScopedPtrHashMap<int64_t, scoped_ptr<ServiceWorkerVersionInfo>>
version_info_map_;
scoped_refptr<ServiceWorkerContextWrapper> context_;
WorkerRegistrationUpdatedCallback registration_callback_;
diff --git a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
index f0deafdd78e..cfe5d87e8f0 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -7,6 +7,7 @@
#include <map>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "base/barrier_closure.h"
@@ -23,14 +24,11 @@
#include "content/browser/service_worker/service_worker_context_observer.h"
#include "content/browser/service_worker/service_worker_process_manager.h"
#include "content/browser/service_worker/service_worker_quota_client.h"
-#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/service_worker_context.h"
-#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/special_storage_policy.h"
@@ -91,16 +89,6 @@ bool ServiceWorkerContext::IsExcludedHeaderNameForFetchEvent(
g_excluded_header_name_set.Get().end();
}
-ServiceWorkerContext* ServiceWorkerContext::GetServiceWorkerContext(
- net::URLRequest* request) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- ServiceWorkerRequestHandler* handler =
- ServiceWorkerRequestHandler::GetHandler(request);
- if (!handler || !handler->context())
- return nullptr;
- return handler->context()->wrapper_;
-}
-
ServiceWorkerContextWrapper::ServiceWorkerContextWrapper(
BrowserContext* browser_context)
: observer_list_(
@@ -127,11 +115,8 @@ void ServiceWorkerContextWrapper::Init(
new ServiceWorkerDatabaseTaskManagerImpl(pool));
scoped_refptr<base::SingleThreadTaskRunner> disk_cache_thread =
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE);
- InitInternal(user_data_directory,
- database_task_manager.Pass(),
- disk_cache_thread,
- quota_manager_proxy,
- special_storage_policy);
+ InitInternal(user_data_directory, std::move(database_task_manager),
+ disk_cache_thread, quota_manager_proxy, special_storage_policy);
}
void ServiceWorkerContextWrapper::Shutdown() {
@@ -183,7 +168,7 @@ static void FinishRegistrationOnIO(
const ServiceWorkerContext::ResultCallback& continuation,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(
BrowserThread::UI,
@@ -307,26 +292,6 @@ void ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad(
force_update_on_page_load);
}
-static void DidFindRegistrationForDocument(
- const net::CompletionCallback& callback,
- ServiceWorkerStatusCode status,
- const scoped_refptr<ServiceWorkerRegistration>& registration) {
- int rv = registration ? net::OK : net::ERR_CACHE_MISS;
- // Use RunSoon here because FindRegistrationForDocument can complete
- // immediately but CanHandleMainResourceOffline must be async.
- RunSoon(base::Bind(callback, rv));
-}
-
-void ServiceWorkerContextWrapper::CanHandleMainResourceOffline(
- const GURL& url,
- const GURL& first_party,
- const net::CompletionCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- context()->storage()->FindRegistrationForDocument(
- net::SimplifyUrlForRequest(url),
- base::Bind(&DidFindRegistrationForDocument, callback));
-}
-
void ServiceWorkerContextWrapper::GetAllOriginsInfo(
const GetUsageInfoCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -365,25 +330,13 @@ void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
callback.Run(usage_infos);
}
-void ServiceWorkerContextWrapper::DidFindRegistrationForCheckHasServiceWorker(
- const GURL& other_url,
+void ServiceWorkerContextWrapper::DidCheckHasServiceWorker(
const CheckHasServiceWorkerCallback& callback,
- ServiceWorkerStatusCode status,
- const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ bool has_service_worker) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(callback, false));
- return;
- }
-
- DCHECK(registration);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(callback, registration->active_version() &&
- ServiceWorkerUtils::ScopeMatches(
- registration->pattern(), other_url)));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, has_service_worker));
}
void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin(
@@ -416,6 +369,11 @@ void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate(
if (!context_core_)
return;
DCHECK(registration);
+ // TODO(jungkees): |force_bypass_cache| is set to true because the call stack
+ // is initiated by an update button on DevTools that expects the cache is
+ // bypassed. However, in order to provide options for callers to choose the
+ // cache bypass mode, plumb |force_bypass_cache| through to
+ // UpdateRegistration().
context_core_->UpdateServiceWorker(registration.get(),
true /* force_bypass_cache */);
}
@@ -467,11 +425,10 @@ void ServiceWorkerContextWrapper::CheckHasServiceWorker(
base::Bind(callback, false));
return;
}
- context()->storage()->FindRegistrationForDocument(
- net::SimplifyUrlForRequest(url),
- base::Bind(&ServiceWorkerContextWrapper::
- DidFindRegistrationForCheckHasServiceWorker,
- this, net::SimplifyUrlForRequest(other_url), callback));
+ context()->CheckHasServiceWorker(
+ net::SimplifyUrlForRequest(url), net::SimplifyUrlForRequest(other_url),
+ base::Bind(&ServiceWorkerContextWrapper::DidCheckHasServiceWorker, this,
+ callback));
}
void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest(
@@ -522,31 +479,31 @@ ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
return context_core_->GetAllLiveVersionInfo();
}
-void ServiceWorkerContextWrapper::FindRegistrationForDocument(
- const GURL& document_url,
- const FindRegistrationCallback& callback) {
+void ServiceWorkerContextWrapper::HasMainFrameProviderHost(
+ const GURL& origin,
+ const BoolCallback& callback) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- // FindRegistrationForDocument() can run the callback synchronously.
- callback.Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, false));
return;
}
- context_core_->storage()->FindRegistrationForDocument(
- net::SimplifyUrlForRequest(document_url), callback);
+ context_core_->HasMainFrameProviderHost(origin, callback);
}
-void ServiceWorkerContextWrapper::FindRegistrationForId(
- int64_t registration_id,
- const GURL& origin,
+void ServiceWorkerContextWrapper::FindReadyRegistrationForDocument(
+ const GURL& document_url,
const FindRegistrationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- // FindRegistrationForId() can run the callback synchronously.
+ // FindRegistrationForDocument() can run the callback synchronously.
callback.Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
return;
}
- context_core_->storage()->FindRegistrationForId(registration_id,
- origin.GetOrigin(), callback);
+ context_core_->storage()->FindRegistrationForDocument(
+ net::SimplifyUrlForRequest(document_url),
+ base::Bind(&ServiceWorkerContextWrapper::DidFindRegistrationForFindReady,
+ this, callback));
}
void ServiceWorkerContextWrapper::FindReadyRegistrationForId(
@@ -684,6 +641,14 @@ void ServiceWorkerContextWrapper::RemoveObserver(
observer_list_->RemoveObserver(observer);
}
+bool ServiceWorkerContextWrapper::OriginHasForeignFetchRegistrations(
+ const GURL& origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!context_core_)
+ return false;
+ return context_core_->storage()->OriginHasForeignFetchRegistrations(origin);
+}
+
void ServiceWorkerContextWrapper::InitInternal(
const base::FilePath& user_data_directory,
scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager,
@@ -711,13 +676,9 @@ void ServiceWorkerContextWrapper::InitInternal(
if (quota_manager_proxy) {
quota_manager_proxy->RegisterClient(new ServiceWorkerQuotaClient(this));
}
- context_core_.reset(new ServiceWorkerContextCore(user_data_directory,
- database_task_manager.Pass(),
- disk_cache_thread,
- quota_manager_proxy,
- special_storage_policy,
- observer_list_.get(),
- this));
+ context_core_.reset(new ServiceWorkerContextCore(
+ user_data_directory, std::move(database_task_manager), disk_cache_thread,
+ quota_manager_proxy, special_storage_policy, observer_list_.get(), this));
}
void ServiceWorkerContextWrapper::ShutdownOnIO() {
diff --git a/chromium/content/browser/service_worker/service_worker_context_wrapper.h b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
index 73f6506acca..a81e8889265 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_WRAPPER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_WRAPPER_H_
+#include <stdint.h>
+
#include <vector>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -42,6 +45,7 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
public base::RefCountedThreadSafe<ServiceWorkerContextWrapper> {
public:
using StatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
+ using BoolCallback = base::Callback<void(bool)>;
using FindRegistrationCallback =
ServiceWorkerStorage::FindRegistrationCallback;
using GetRegistrationsInfosCallback =
@@ -88,10 +92,6 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
const ResultCallback& continuation) override;
void UnregisterServiceWorker(const GURL& pattern,
const ResultCallback& continuation) override;
- void CanHandleMainResourceOffline(
- const GURL& url,
- const GURL& first_party,
- const net::CompletionCallback& callback) override;
void GetAllOriginsInfo(const GetUsageInfoCallback& callback) override;
void DeleteForOrigin(const GURL& origin,
const ResultCallback& callback) override;
@@ -107,16 +107,21 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo();
std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo();
- // Returns the registration whose scope longest matches |document_url|.
- // Returns ERROR_NOT_FOUND if it is not found.
- void FindRegistrationForDocument(const GURL& document_url,
- const FindRegistrationCallback& callback);
+ void HasMainFrameProviderHost(const GURL& origin,
+ const BoolCallback& callback) const;
- // Returns the registration for |registration_id| and |origin|. Returns
- // ERROR_NOT_FOUND if it is not found.
- void FindRegistrationForId(int64_t registration_id,
- const GURL& origin,
- const FindRegistrationCallback& callback);
+ // Returns the registration whose scope longest matches |document_url|. It is
+ // guaranteed that the returned registration has the activated worker.
+ //
+ // - If the registration is not found, returns ERROR_NOT_FOUND.
+ // - If the registration has neither the waiting version nor the active
+ // version, returns ERROR_NOT_FOUND.
+ // - If the registration does not have the active version but has the waiting
+ // version, activates the waiting version and runs |callback| when it is
+ // activated.
+ void FindReadyRegistrationForDocument(
+ const GURL& document_url,
+ const FindRegistrationCallback& callback);
// Returns the registration for |registration_id|. It is guaranteed that the
// returned registration has the activated worker.
@@ -127,9 +132,6 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
// - If the registration does not have the active version but has the waiting
// version, activates the waiting version and runs |callback| when it is
// activated.
- //
- // TODO(nhiroki): Consider merging this into FindRegistrationForId because
- // external modules might not be interested in non-ready registration.
void FindReadyRegistrationForId(int64_t registration_id,
const GURL& origin,
const FindRegistrationCallback& callback);
@@ -159,6 +161,8 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
bool is_incognito() const { return is_incognito_; }
+ bool OriginHasForeignFetchRegistrations(const GURL& origin);
+
private:
friend class BackgroundSyncManagerTest;
friend class base::RefCountedThreadSafe<ServiceWorkerContextWrapper>;
@@ -166,6 +170,7 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
friend class EmbeddedWorkerBrowserTest;
friend class ServiceWorkerDispatcherHost;
friend class ServiceWorkerInternalsUI;
+ friend class ServiceWorkerNavigationHandleCore;
friend class ServiceWorkerProcessManager;
friend class ServiceWorkerRequestHandler;
friend class ServiceWorkerVersionBrowserTest;
@@ -195,11 +200,8 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
const GetUsageInfoCallback& callback,
const std::vector<ServiceWorkerRegistrationInfo>& registrations);
- void DidFindRegistrationForCheckHasServiceWorker(
- const GURL& other_url,
- const CheckHasServiceWorkerCallback& callback,
- ServiceWorkerStatusCode status,
- const scoped_refptr<ServiceWorkerRegistration>& registration);
+ void DidCheckHasServiceWorker(const CheckHasServiceWorkerCallback& callback,
+ bool has_service_worker);
void DidFindRegistrationForUpdate(
ServiceWorkerStatusCode status,
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
index 70629d9edbb..a656fd86997 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -4,6 +4,9 @@
#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_metrics.h"
@@ -45,8 +48,12 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
request_context_type_(request_context_type),
frame_type_(frame_type),
body_(body),
- skip_service_worker_(false),
force_update_started_(false),
+ use_network_(false),
+ was_fetched_via_service_worker_(false),
+ was_fallback_required_(false),
+ response_type_via_service_worker_(
+ blink::WebServiceWorkerResponseTypeDefault),
weak_factory_(this) {}
ServiceWorkerControlleeRequestHandler::
@@ -68,39 +75,37 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
ResourceContext* resource_context) {
- if (job_.get() && worker_start_time_.is_null()) {
- // Save worker timings of the first job.
- worker_start_time_ = job_->worker_start_time();
- worker_ready_time_ = job_->worker_ready_time();
- }
+ ClearJob();
if (!context_ || !provider_host_) {
// We can't do anything other than to fall back to network.
- job_ = NULL;
return NULL;
}
// This may get called multiple times for original and redirect requests:
- // A. original request case: job_ is null, no previous location info.
+ // A. original request case: use_network_ is false, no previous location info.
// B. redirect or restarted request case:
- // a) job_ is non-null if the previous location was forwarded to SW.
- // b) job_ is null if the previous location was fallback.
- // c) job_ is non-null if additional restart was required to fall back.
-
- // We've come here by restart, we already have original request and it
- // tells we should fallback to network. (Case B-c)
- if ((job_.get() && job_->ShouldFallbackToNetwork()) || skip_service_worker_) {
- FallbackToNetwork();
+ // a) use_network_ is false if the previous location was forwarded to SW.
+ // b) use_network_ is false if the previous location was fallback.
+ // c) use_network_ is true if additional restart was required to fall back.
+
+ // Fall back to network. (Case B-c)
+ if (use_network_) {
+ // Once a subresource request has fallen back to the network once, it will
+ // never be handled by a service worker. This is not true of main frame
+ // requests.
+ if (is_main_resource_load_)
+ use_network_ = false;
return NULL;
}
// It's for original request (A) or redirect case (B-a or B-b).
- DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker());
+ scoped_ptr<ServiceWorkerURLRequestJob> job(new ServiceWorkerURLRequestJob(
+ request, network_delegate, blob_storage_context_, resource_context,
+ request_mode_, credentials_mode_, redirect_mode_, is_main_resource_load_,
+ request_context_type_, frame_type_, body_, this));
+ job_ = job->GetWeakPtr();
- job_ = new ServiceWorkerURLRequestJob(
- request, network_delegate, provider_host_, blob_storage_context_,
- resource_context, request_mode_, credentials_mode_, redirect_mode_,
- is_main_resource_load_, request_context_type_, frame_type_, body_);
resource_context_ = resource_context;
if (is_main_resource_load_)
@@ -110,31 +115,33 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
if (job_->ShouldFallbackToNetwork()) {
// If we know we can fallback to network at this point (in case
- // the storage lookup returned immediately), just return NULL here to
- // fallback to network.
- FallbackToNetwork();
- return NULL;
+ // the storage lookup returned immediately), just destroy the job and return
+ // NULL here to fallback to network.
+
+ // If this is a subresource request, all subsequent requests should also use
+ // the network.
+ if (!is_main_resource_load_)
+ use_network_ = true;
+
+ job.reset();
+ ClearJob();
}
- return job_.get();
+ return job.release();
}
void ServiceWorkerControlleeRequestHandler::GetExtraResponseInfo(
ResourceResponseInfo* response_info) const {
- if (!job_.get()) {
- response_info->was_fetched_via_service_worker = false;
- response_info->was_fallback_required_by_service_worker = false;
- response_info->original_url_via_service_worker = GURL();
- response_info->service_worker_start_time = worker_start_time_;
- response_info->service_worker_ready_time = worker_ready_time_;
- return;
- }
- job_->GetExtraResponseInfo(response_info);
- if (!worker_start_time_.is_null()) {
- // If we have worker timings from previous job, use it.
- response_info->service_worker_start_time = worker_start_time_;
- response_info->service_worker_ready_time = worker_ready_time_;
- }
+ response_info->was_fetched_via_service_worker =
+ was_fetched_via_service_worker_;
+ response_info->was_fallback_required_by_service_worker =
+ was_fallback_required_;
+ response_info->original_url_via_service_worker =
+ original_url_via_service_worker_;
+ response_info->response_type_via_service_worker =
+ response_type_via_service_worker_;
+ response_info->service_worker_start_time = service_worker_start_time_;
+ response_info->service_worker_ready_time = service_worker_ready_time_;
}
void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
@@ -167,7 +174,10 @@ void
ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
ServiceWorkerStatusCode status,
const scoped_refptr<ServiceWorkerRegistration>& registration) {
- DCHECK(job_.get());
+ // The job may have been canceled and then destroyed before this was invoked.
+ if (!job_)
+ return;
+
const bool need_to_update = !force_update_started_ && registration &&
registration->force_update_on_page_load();
@@ -236,6 +246,12 @@ ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
return;
}
+ // A registration exists, so associate it. Note that the controller is only
+ // set if there's an active version. If there's no active version, we should
+ // still associate so the provider host can use .ready.
+ provider_host_->AssociateRegistration(registration.get(),
+ false /* notify_controllerchange */);
+
if (!active_version.get() ||
active_version->status() != ServiceWorkerVersion::ACTIVATED) {
job_->FallbackToNetwork();
@@ -251,8 +267,6 @@ ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
ServiceWorkerMetrics::CountControlledPageLoad(stripped_url_);
- provider_host_->AssociateRegistration(registration.get(),
- false /* notify_controllerchange */);
job_->ForwardToServiceWorker();
TRACE_EVENT_ASYNC_END2(
"ServiceWorker",
@@ -266,6 +280,10 @@ ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged(
ServiceWorkerRegistration* registration,
ServiceWorkerVersion* version) {
+ // The job may have been canceled and then destroyed before this was invoked.
+ if (!job_)
+ return;
+
if (provider_host_)
provider_host_->SetAllowAssociation(true);
if (version != registration->active_version() ||
@@ -286,8 +304,13 @@ void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
const scoped_refptr<ServiceWorkerRegistration>& original_registration,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
DCHECK(force_update_started_);
+
+ // The job may have been canceled and then destroyed before this was invoked.
+ if (!job_)
+ return;
+
if (!context_) {
job_->FallbackToNetwork();
return;
@@ -304,6 +327,10 @@ void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
DCHECK_EQ(original_registration->id(), registration_id);
scoped_refptr<ServiceWorkerVersion> new_version =
original_registration->installing_version();
+ new_version->ReportError(
+ SERVICE_WORKER_OK,
+ "ServiceWorker was updated because \"Force update on page load\" was "
+ "checked in DevTools Source tab.");
new_version->set_skip_waiting(true);
new_version->RegisterStatusChangeCallback(base::Bind(
&self::OnUpdatedVersionStatusChanged, weak_factory_.GetWeakPtr(),
@@ -313,6 +340,10 @@ void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
void ServiceWorkerControlleeRequestHandler::OnUpdatedVersionStatusChanged(
const scoped_refptr<ServiceWorkerRegistration>& registration,
const scoped_refptr<ServiceWorkerVersion>& version) {
+ // The job may have been canceled and then destroyed before this was invoked.
+ if (!job_)
+ return;
+
if (!context_) {
job_->FallbackToNetwork();
return;
@@ -339,13 +370,80 @@ void ServiceWorkerControlleeRequestHandler::PrepareForSubResource() {
job_->ForwardToServiceWorker();
}
-void ServiceWorkerControlleeRequestHandler::FallbackToNetwork() {
- // Once a subresource request was fallbacked to the network, we set
- // |skip_service_worker_| because the request should not go to the service
- // worker.
- if (!is_main_resource_load_)
- skip_service_worker_ = true;
- job_ = NULL;
+void ServiceWorkerControlleeRequestHandler::OnPrepareToRestart(
+ base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) {
+ use_network_ = true;
+ ClearJob();
+ // Update times, if not already set by a previous Job.
+ if (service_worker_start_time_.is_null()) {
+ service_worker_start_time_ = service_worker_start_time;
+ service_worker_ready_time_ = service_worker_ready_time;
+ }
+}
+
+void ServiceWorkerControlleeRequestHandler::OnStartCompleted(
+ bool was_fetched_via_service_worker,
+ bool was_fallback_required,
+ const GURL& original_url_via_service_worker,
+ blink::WebServiceWorkerResponseType response_type_via_service_worker,
+ base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) {
+ was_fetched_via_service_worker_ = was_fetched_via_service_worker;
+ was_fallback_required_ = was_fallback_required;
+ original_url_via_service_worker_ = original_url_via_service_worker;
+ response_type_via_service_worker_ = response_type_via_service_worker;
+
+ // Update times, if not already set by a previous Job.
+ if (service_worker_start_time_.is_null()) {
+ service_worker_start_time_ = service_worker_start_time;
+ service_worker_ready_time_ = service_worker_ready_time;
+ }
+}
+
+ServiceWorkerVersion*
+ServiceWorkerControlleeRequestHandler::GetServiceWorkerVersion(
+ ServiceWorkerMetrics::URLRequestJobResult* result) {
+ if (!provider_host_) {
+ *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST;
+ return nullptr;
+ }
+ if (!provider_host_->active_version()) {
+ *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION;
+ return nullptr;
+ }
+ return provider_host_->active_version();
+}
+
+bool ServiceWorkerControlleeRequestHandler::RequestStillValid(
+ ServiceWorkerMetrics::URLRequestJobResult* result) {
+ // A null |provider_host_| probably means the tab was closed. The null value
+ // would cause problems down the line, so bail out.
+ if (!provider_host_) {
+ *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST;
+ return false;
+ }
+ return true;
+}
+
+void ServiceWorkerControlleeRequestHandler::MainResourceLoadFailed() {
+ DCHECK(provider_host_);
+ // Detach the controller so subresource requests also skip the worker.
+ provider_host_->NotifyControllerLost();
+}
+
+GURL ServiceWorkerControlleeRequestHandler::GetRequestingOrigin() {
+ DCHECK(provider_host_);
+ return provider_host_->document_url().GetOrigin();
+}
+
+void ServiceWorkerControlleeRequestHandler::ClearJob() {
+ job_.reset();
+ was_fetched_via_service_worker_ = false;
+ was_fallback_required_ = false;
+ original_url_via_service_worker_ = GURL();
+ response_type_via_service_worker_ =
+ blink::WebServiceWorkerResponseTypeDefault;
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
index 84b39c26c79..1526385a460 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -5,8 +5,15 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTROLLEE_REQUEST_HANDLER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTROLLEE_REQUEST_HANDLER_H_
+#include <stdint.h>
+
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
+#include "content/browser/service_worker/service_worker_url_request_job.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/request_context_frame_type.h"
#include "content/public/common/request_context_type.h"
@@ -23,13 +30,13 @@ namespace content {
class ResourceRequestBody;
class ServiceWorkerRegistration;
-class ServiceWorkerURLRequestJob;
class ServiceWorkerVersion;
// A request handler derivative used to handle requests from
// controlled documents.
class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
- : public ServiceWorkerRequestHandler {
+ : public ServiceWorkerRequestHandler,
+ public ServiceWorkerURLRequestJob::Delegate {
public:
ServiceWorkerControlleeRequestHandler(
base::WeakPtr<ServiceWorkerContextCore> context,
@@ -70,7 +77,7 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
const scoped_refptr<ServiceWorkerRegistration>& original_registration,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id);
+ int64_t registration_id);
void OnUpdatedVersionStatusChanged(
const scoped_refptr<ServiceWorkerRegistration>& registration,
const scoped_refptr<ServiceWorkerVersion>& version);
@@ -78,10 +85,36 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
// For sub resource case.
void PrepareForSubResource();
- void FallbackToNetwork();
+ // ServiceWorkerURLRequestJob::Delegate implementation:
+
+ // Called just before the request is restarted. Makes sure the next request
+ // goes over the network.
+ void OnPrepareToRestart(base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) override;
+
+ // Called when the request's start phase completes. Caches response info for
+ // GetExtraResponseInfo.
+ void OnStartCompleted(
+ bool was_fetched_via_service_worker,
+ bool was_fallback_required,
+ const GURL& original_url_via_service_worker,
+ blink::WebServiceWorkerResponseType response_type_via_service_worker,
+ base::TimeTicks worker_start_time,
+ base::TimeTicks service_worker_ready_time) override;
+
+ ServiceWorkerVersion* GetServiceWorkerVersion(
+ ServiceWorkerMetrics::URLRequestJobResult* result) override;
+ bool RequestStillValid(
+ ServiceWorkerMetrics::URLRequestJobResult* result) override;
+ void MainResourceLoadFailed() override;
+ GURL GetRequestingOrigin() override;
+
+ // Sets |job_| to nullptr, and clears all extra response info associated with
+ // that job, except for timing information.
+ void ClearJob();
bool is_main_resource_load_;
- scoped_refptr<ServiceWorkerURLRequestJob> job_;
+ base::WeakPtr<ServiceWorkerURLRequestJob> job_;
FetchRequestMode request_mode_;
FetchCredentialsMode credentials_mode_;
FetchRedirectMode redirect_mode_;
@@ -90,10 +123,21 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
scoped_refptr<ResourceRequestBody> body_;
ResourceContext* resource_context_;
GURL stripped_url_;
- base::TimeTicks worker_start_time_;
- base::TimeTicks worker_ready_time_;
- bool skip_service_worker_;
bool force_update_started_;
+
+ // True if the next time this request is started, the response should be
+ // delivered from the network, bypassing the ServiceWorker. Cleared after the
+ // next intercept opportunity, for main frame requests.
+ bool use_network_;
+
+ // Cached metadata for GetExtraResponseInfo.
+ bool was_fetched_via_service_worker_;
+ bool was_fallback_required_;
+ GURL original_url_via_service_worker_;
+ blink::WebServiceWorkerResponseType response_type_via_service_worker_;
+ base::TimeTicks service_worker_start_time_;
+ base::TimeTicks service_worker_ready_time_;
+
base::WeakPtrFactory<ServiceWorkerControlleeRequestHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerControlleeRequestHandler);
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
index b338ac849d1..bf79f74dea1 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -2,6 +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/service_worker/service_worker_controllee_request_handler.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/callback_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/run_loop.h"
@@ -9,10 +15,8 @@
#include "content/browser/fileapi/mock_url_request_delegate.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
-#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_url_request_job.h"
#include "content/common/resource_request_body.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -30,11 +34,8 @@ namespace content {
namespace {
-int kMockRenderProcessId = 1224;
int kMockProviderId = 1;
-void EmptyCallback() {}
-
}
class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
@@ -43,8 +44,7 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kMockRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
// A new unstored registration/version.
scope_ = GURL("http://host/scope/");
@@ -61,12 +61,12 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
// An empty host.
scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
- kMockRenderProcessId, MSG_ROUTING_NONE, kMockProviderId,
+ helper_->mock_render_process_id(), MSG_ROUTING_NONE, kMockProviderId,
SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), NULL));
provider_host_ = host->AsWeakPtr();
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
- context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
+ context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
base::RunLoop().RunUntilIdle();
}
@@ -129,8 +129,8 @@ TEST_F(ServiceWorkerControlleeRequestHandlerTest, DisallowServiceWorker) {
FetchRedirectMode::FOLLOW_MODE, RESOURCE_TYPE_MAIN_FRAME,
REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
scoped_refptr<ResourceRequestBody>()));
- scoped_refptr<net::URLRequestJob> job =
- handler->MaybeCreateJob(request.get(), NULL, &mock_resource_context_);
+ scoped_ptr<net::URLRequestJob> job(
+ handler->MaybeCreateJob(request.get(), nullptr, &mock_resource_context_));
ServiceWorkerURLRequestJob* sw_job =
static_cast<ServiceWorkerURLRequestJob*>(job.get());
@@ -169,8 +169,8 @@ TEST_F(ServiceWorkerControlleeRequestHandlerTest, ActivateWaitingVersion) {
FetchRedirectMode::FOLLOW_MODE, RESOURCE_TYPE_MAIN_FRAME,
REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
scoped_refptr<ResourceRequestBody>()));
- scoped_refptr<net::URLRequestJob> job =
- handler->MaybeCreateJob(request.get(), NULL, &mock_resource_context_);
+ scoped_ptr<net::URLRequestJob> job(
+ handler->MaybeCreateJob(request.get(), nullptr, &mock_resource_context_));
ServiceWorkerURLRequestJob* sw_job =
static_cast<ServiceWorkerURLRequestJob*>(job.get());
@@ -191,6 +191,39 @@ TEST_F(ServiceWorkerControlleeRequestHandlerTest, ActivateWaitingVersion) {
EXPECT_TRUE(version_->update_timer_.IsRunning());
}
+// Test that an installing registration is associated with a provider host.
+TEST_F(ServiceWorkerControlleeRequestHandlerTest, InstallingRegistration) {
+ // Create an installing registration.
+ version_->SetStatus(ServiceWorkerVersion::INSTALLING);
+ registration_->SetInstallingVersion(version_);
+ context()->storage()->NotifyInstallingRegistration(registration_.get());
+
+ // Conduct a main resource load.
+ const GURL kDocUrl("http://host/scope/doc");
+ scoped_ptr<net::URLRequest> request = url_request_context_.CreateRequest(
+ kDocUrl, net::DEFAULT_PRIORITY, &url_request_delegate_);
+ scoped_ptr<ServiceWorkerControlleeRequestHandler> handler(
+ new ServiceWorkerControlleeRequestHandler(
+ context()->AsWeakPtr(), provider_host_,
+ base::WeakPtr<storage::BlobStorageContext>(),
+ FETCH_REQUEST_MODE_NO_CORS, FETCH_CREDENTIALS_MODE_OMIT,
+ FetchRedirectMode::FOLLOW_MODE, RESOURCE_TYPE_MAIN_FRAME,
+ REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
+ scoped_refptr<ResourceRequestBody>()));
+ scoped_ptr<net::URLRequestJob> job(
+ handler->MaybeCreateJob(request.get(), nullptr, &mock_resource_context_));
+ base::RunLoop().RunUntilIdle();
+
+ // The handler should have fallen back to network and destroyed the job. The
+ // registration should be associated with the provider host, although it is
+ // not controlled since there is no active version.
+ EXPECT_FALSE(job);
+ EXPECT_EQ(registration_.get(), provider_host_->associated_registration());
+ EXPECT_EQ(version_.get(), provider_host_->installing_version());
+ EXPECT_FALSE(version_->HasControllee());
+ EXPECT_FALSE(provider_host_->controlling_version());
+}
+
// Test to not regress crbug/414118.
TEST_F(ServiceWorkerControlleeRequestHandlerTest, DeletedProviderHost) {
// Store a registration so the call to FindRegistrationForDocument will read
@@ -217,8 +250,8 @@ TEST_F(ServiceWorkerControlleeRequestHandlerTest, DeletedProviderHost) {
FetchRedirectMode::FOLLOW_MODE, RESOURCE_TYPE_MAIN_FRAME,
REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
scoped_refptr<ResourceRequestBody>()));
- scoped_refptr<net::URLRequestJob> job =
- handler->MaybeCreateJob(request.get(), NULL, &mock_resource_context_);
+ scoped_ptr<net::URLRequestJob> job(
+ handler->MaybeCreateJob(request.get(), nullptr, &mock_resource_context_));
ServiceWorkerURLRequestJob* sw_job =
static_cast<ServiceWorkerURLRequestJob*>(job.get());
@@ -227,7 +260,8 @@ TEST_F(ServiceWorkerControlleeRequestHandlerTest, DeletedProviderHost) {
// Shouldn't crash if the ProviderHost is deleted prior to completion of
// the database lookup.
- context()->RemoveProviderHost(kMockRenderProcessId, kMockProviderId);
+ context()->RemoveProviderHost(helper_->mock_render_process_id(),
+ kMockProviderId);
EXPECT_FALSE(provider_host_.get());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(sw_job->ShouldFallbackToNetwork());
diff --git a/chromium/content/browser/service_worker/service_worker_database.cc b/chromium/content/browser/service_worker/service_worker_database.cc
index b79894ea803..83f4325df54 100644
--- a/chromium/content/browser/service_worker/service_worker_database.cc
+++ b/chromium/content/browser/service_worker/service_worker_database.cc
@@ -17,6 +17,7 @@
#include "content/browser/service_worker/service_worker_database.pb.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
@@ -27,7 +28,7 @@
// =======================
//
// NOTE
-// - int64 value is serialized as a string by base::Int64ToString().
+// - int64_t value is serialized as a string by base::Int64ToString().
// - GURL value is serialized as a string by GURL::spec().
//
// Version 1 (in sorted order)
@@ -35,54 +36,59 @@
// value: "1"
//
// key: "INITDATA_NEXT_REGISTRATION_ID"
-// value: <int64 'next_available_registration_id'>
+// value: <int64_t 'next_available_registration_id'>
//
// key: "INITDATA_NEXT_RESOURCE_ID"
-// value: <int64 'next_available_resource_id'>
+// value: <int64_t 'next_available_resource_id'>
//
// key: "INITDATA_NEXT_VERSION_ID"
-// value: <int64 'next_available_version_id'>
+// value: <int64_t 'next_available_version_id'>
//
// key: "INITDATA_UNIQUE_ORIGIN:" + <GURL 'origin'>
// value: <empty>
//
-// key: "PRES:" + <int64 'purgeable_resource_id'>
+// key: "PRES:" + <int64_t 'purgeable_resource_id'>
// value: <empty>
//
-// key: "REG:" + <GURL 'origin'> + '\x00' + <int64 'registration_id'>
+// key: "REG:" + <GURL 'origin'> + '\x00' + <int64_t 'registration_id'>
// (ex. "REG:http://example.com\x00123456")
// value: <ServiceWorkerRegistrationData serialized as a string>
//
// key: "REG_HAS_USER_DATA:" + <std::string 'user_data_name'> + '\x00'
-// + <int64 'registration_id'>
+// + <int64_t 'registration_id'>
// value: <empty>
//
-// key: "REG_USER_DATA:" + <int64 'registration_id'> + '\x00'
+// key: "REG_USER_DATA:" + <int64_t 'registration_id'> + '\x00'
// + <std::string user_data_name>
// (ex. "REG_USER_DATA:123456\x00foo_bar")
// value: <std::string user_data>
//
-// key: "RES:" + <int64 'version_id'> + '\x00' + <int64 'resource_id'>
+// key: "RES:" + <int64_t 'version_id'> + '\x00' + <int64_t 'resource_id'>
// (ex. "RES:123456\x00654321")
// value: <ServiceWorkerResourceRecord serialized as a string>
//
-// key: "URES:" + <int64 'uncommitted_resource_id'>
+// key: "URES:" + <int64_t 'uncommitted_resource_id'>
// value: <empty>
//
// Version 2
//
-// key: "REGID_TO_ORIGIN:" + <int64 'registration_id'>
+// key: "REGID_TO_ORIGIN:" + <int64_t 'registration_id'>
// value: <GURL 'origin'>
//
+// OBSOLETE: http://crbug.com/539713
// key: "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"
// value: <empty>
// - This entry represents that the diskcache uses the Simple backend and
// does not have to do diskcache migration (http://crbug.com/487482).
//
+// OBSOLETE: http://crbug.com/539713
// key: "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"
// value: <empty>
// - This entry represents that the old BlockFile diskcache was deleted
// after diskcache migration (http://crbug.com/487482).
+//
+// key: "INITDATA_FOREIGN_FETCH_ORIGIN:" + <GURL 'origin'>
+// value: <empty>
namespace content {
namespace {
@@ -92,10 +98,7 @@ const char kNextRegIdKey[] = "INITDATA_NEXT_REGISTRATION_ID";
const char kNextResIdKey[] = "INITDATA_NEXT_RESOURCE_ID";
const char kNextVerIdKey[] = "INITDATA_NEXT_VERSION_ID";
const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:";
-const char kDiskCacheMigrationNotNeededKey[] =
- "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED";
-const char kOldDiskCacheDeletionNotNeededKey[] =
- "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED";
+const char kForeignFetchOriginKey[] = "INITDATA_FOREIGN_FETCH_ORIGIN:";
const char kRegKeyPrefix[] = "REG:";
const char kRegUserDataKeyPrefix[] = "REG_USER_DATA:";
@@ -103,12 +106,11 @@ const char kRegHasUserDataKeyPrefix[] = "REG_HAS_USER_DATA:";
const char kRegIdToOriginKeyPrefix[] = "REGID_TO_ORIGIN:";
const char kResKeyPrefix[] = "RES:";
const char kKeySeparator = '\x00';
-const char kEmptyValue[] = "";
const char kUncommittedResIdKeyPrefix[] = "URES:";
const char kPurgeableResIdKeyPrefix[] = "PRES:";
-const int64 kCurrentSchemaVersion = 2;
+const int64_t kCurrentSchemaVersion = 2;
class ServiceWorkerEnv : public leveldb_env::ChromiumEnv {
public:
@@ -134,21 +136,19 @@ std::string CreateRegistrationKeyPrefix(const GURL& origin) {
origin.GetOrigin().spec().c_str(), kKeySeparator);
}
-std::string CreateRegistrationKey(int64 registration_id,
- const GURL& origin) {
+std::string CreateRegistrationKey(int64_t registration_id, const GURL& origin) {
return CreateRegistrationKeyPrefix(origin)
.append(base::Int64ToString(registration_id));
}
-std::string CreateResourceRecordKeyPrefix(int64 version_id) {
+std::string CreateResourceRecordKeyPrefix(int64_t version_id) {
return base::StringPrintf("%s%s%c",
kResKeyPrefix,
base::Int64ToString(version_id).c_str(),
kKeySeparator);
}
-std::string CreateResourceRecordKey(int64 version_id,
- int64 resource_id) {
+std::string CreateResourceRecordKey(int64_t version_id, int64_t resource_id) {
return CreateResourceRecordKeyPrefix(version_id).append(
base::Int64ToString(resource_id));
}
@@ -158,19 +158,24 @@ std::string CreateUniqueOriginKey(const GURL& origin) {
origin.GetOrigin().spec().c_str());
}
-std::string CreateResourceIdKey(const char* key_prefix, int64 resource_id) {
+std::string CreateForeignFetchOriginKey(const GURL& origin) {
+ return base::StringPrintf("%s%s", kForeignFetchOriginKey,
+ origin.GetOrigin().spec().c_str());
+}
+
+std::string CreateResourceIdKey(const char* key_prefix, int64_t resource_id) {
return base::StringPrintf(
"%s%s", key_prefix, base::Int64ToString(resource_id).c_str());
}
-std::string CreateUserDataKeyPrefix(int64 registration_id) {
+std::string CreateUserDataKeyPrefix(int64_t registration_id) {
return base::StringPrintf("%s%s%c",
kRegUserDataKeyPrefix,
base::Int64ToString(registration_id).c_str(),
kKeySeparator);
}
-std::string CreateUserDataKey(int64 registration_id,
+std::string CreateUserDataKey(int64_t registration_id,
const std::string& user_data_name) {
return CreateUserDataKeyPrefix(registration_id).append(user_data_name);
}
@@ -180,151 +185,42 @@ std::string CreateHasUserDataKeyPrefix(const std::string& user_data_name) {
user_data_name.c_str(), kKeySeparator);
}
-std::string CreateHasUserDataKey(int64 registration_id,
+std::string CreateHasUserDataKey(int64_t registration_id,
const std::string& user_data_name) {
return CreateHasUserDataKeyPrefix(user_data_name)
.append(base::Int64ToString(registration_id));
}
-std::string CreateRegistrationIdToOriginKey(int64 registration_id) {
+std::string CreateRegistrationIdToOriginKey(int64_t registration_id) {
return base::StringPrintf("%s%s", kRegIdToOriginKeyPrefix,
base::Int64ToString(registration_id).c_str());
}
-void PutRegistrationDataToBatch(
- const ServiceWorkerDatabase::RegistrationData& input,
- leveldb::WriteBatch* batch) {
- DCHECK(batch);
-
- // Convert RegistrationData to ServiceWorkerRegistrationData.
- ServiceWorkerRegistrationData data;
- data.set_registration_id(input.registration_id);
- data.set_scope_url(input.scope.spec());
- data.set_script_url(input.script.spec());
- data.set_version_id(input.version_id);
- data.set_is_active(input.is_active);
- data.set_has_fetch_handler(input.has_fetch_handler);
- data.set_last_update_check_time(input.last_update_check.ToInternalValue());
- data.set_resources_total_size_bytes(input.resources_total_size_bytes);
-
- std::string value;
- bool success = data.SerializeToString(&value);
- DCHECK(success);
- GURL origin = input.scope.GetOrigin();
- batch->Put(CreateRegistrationKey(data.registration_id(), origin), value);
-}
-
-void PutResourceRecordToBatch(
- const ServiceWorkerDatabase::ResourceRecord& input,
- int64 version_id,
- leveldb::WriteBatch* batch) {
- DCHECK(batch);
- DCHECK_GE(input.size_bytes, 0);
-
- // Convert ResourceRecord to ServiceWorkerResourceRecord.
- ServiceWorkerResourceRecord record;
- record.set_resource_id(input.resource_id);
- record.set_url(input.url.spec());
- record.set_size_bytes(input.size_bytes);
-
- std::string value;
- bool success = record.SerializeToString(&value);
- DCHECK(success);
- batch->Put(CreateResourceRecordKey(version_id, input.resource_id), value);
-}
-
void PutUniqueOriginToBatch(const GURL& origin,
leveldb::WriteBatch* batch) {
// Value should be empty.
batch->Put(CreateUniqueOriginKey(origin), "");
}
-void PutPurgeableResourceIdToBatch(int64 resource_id,
+void PutPurgeableResourceIdToBatch(int64_t resource_id,
leveldb::WriteBatch* batch) {
// Value should be empty.
batch->Put(CreateResourceIdKey(kPurgeableResIdKeyPrefix, resource_id), "");
}
-ServiceWorkerDatabase::Status ParseId(
- const std::string& serialized,
- int64* out) {
- DCHECK(out);
- int64 id;
- if (!base::StringToInt64(serialized, &id) || id < 0)
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
- *out = id;
- return ServiceWorkerDatabase::STATUS_OK;
-}
-
-ServiceWorkerDatabase::Status ParseDatabaseVersion(
- const std::string& serialized,
- int64* out) {
- DCHECK(out);
- const int kFirstValidVersion = 1;
- int64 version;
- if (!base::StringToInt64(serialized, &version) ||
- version < kFirstValidVersion) {
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
- }
- if (kCurrentSchemaVersion < version) {
- DLOG(ERROR) << "ServiceWorkerDatabase has newer schema version"
- << " than the current latest version: "
- << version << " vs " << kCurrentSchemaVersion;
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
- }
- *out = version;
- return ServiceWorkerDatabase::STATUS_OK;
-}
-
-ServiceWorkerDatabase::Status ParseRegistrationData(
- const std::string& serialized,
- ServiceWorkerDatabase::RegistrationData* out) {
- DCHECK(out);
- ServiceWorkerRegistrationData data;
- if (!data.ParseFromString(serialized))
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
-
- GURL scope_url(data.scope_url());
- GURL script_url(data.script_url());
- if (!scope_url.is_valid() ||
- !script_url.is_valid() ||
- scope_url.GetOrigin() != script_url.GetOrigin()) {
- DLOG(ERROR) << "Scope URL '" << data.scope_url() << "' and/or script url '"
- << data.script_url()
- << "' are invalid or have mismatching origins.";
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
- }
-
- // Convert ServiceWorkerRegistrationData to RegistrationData.
- out->registration_id = data.registration_id();
- out->scope = scope_url;
- out->script = script_url;
- out->version_id = data.version_id();
- out->is_active = data.is_active();
- out->has_fetch_handler = data.has_fetch_handler();
- out->last_update_check =
- base::Time::FromInternalValue(data.last_update_check_time());
- out->resources_total_size_bytes = data.resources_total_size_bytes();
-
- return ServiceWorkerDatabase::STATUS_OK;
+void PutForeignFetchOriginToBatch(const GURL& origin,
+ leveldb::WriteBatch* batch) {
+ // Value should be empty.
+ batch->Put(CreateForeignFetchOriginKey(origin), "");
}
-ServiceWorkerDatabase::Status ParseResourceRecord(
- const std::string& serialized,
- ServiceWorkerDatabase::ResourceRecord* out) {
+ServiceWorkerDatabase::Status ParseId(const std::string& serialized,
+ int64_t* out) {
DCHECK(out);
- ServiceWorkerResourceRecord record;
- if (!record.ParseFromString(serialized))
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
-
- GURL url(record.url());
- if (!url.is_valid())
+ int64_t id;
+ if (!base::StringToInt64(serialized, &id) || id < 0)
return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
-
- // Convert ServiceWorkerResourceRecord to ResourceRecord.
- out->resource_id = record.resource_id();
- out->url = url;
- out->size_bytes = record.size_bytes();
+ *out = id;
return ServiceWorkerDatabase::STATUS_OK;
}
@@ -338,6 +234,8 @@ ServiceWorkerDatabase::Status LevelDBStatusToStatus(
return ServiceWorkerDatabase::STATUS_ERROR_IO_ERROR;
else if (status.IsCorruption())
return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+ else if (status.IsNotSupportedError())
+ return ServiceWorkerDatabase::STATUS_ERROR_NOT_SUPPORTED;
else
return ServiceWorkerDatabase::STATUS_ERROR_FAILED;
}
@@ -365,6 +263,8 @@ const char* ServiceWorkerDatabase::StatusToString(
return "Database corrupted";
case ServiceWorkerDatabase::STATUS_ERROR_FAILED:
return "Database operation failed";
+ case ServiceWorkerDatabase::STATUS_ERROR_NOT_SUPPORTED:
+ return "Database operation not supported";
case ServiceWorkerDatabase::STATUS_ERROR_MAX:
NOTREACHED();
return "Database unknown error";
@@ -389,8 +289,7 @@ ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path)
next_avail_registration_id_(0),
next_avail_resource_id_(0),
next_avail_version_id_(0),
- state_(UNINITIALIZED),
- skip_writing_diskcache_migration_state_on_init_for_testing_(false) {
+ state_(UNINITIALIZED) {
sequence_checker_.DetachFromSequence();
}
@@ -400,9 +299,9 @@ ServiceWorkerDatabase::~ServiceWorkerDatabase() {
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds(
- int64* next_avail_registration_id,
- int64* next_avail_version_id,
- int64* next_avail_resource_id) {
+ int64_t* next_avail_registration_id,
+ int64_t* next_avail_version_id,
+ int64_t* next_avail_resource_id) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(next_avail_registration_id);
DCHECK(next_avail_version_id);
@@ -434,94 +333,48 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds(
return STATUS_OK;
}
-ServiceWorkerDatabase::Status ServiceWorkerDatabase::IsDiskCacheMigrationNeeded(
- bool* migration_needed) {
+ServiceWorkerDatabase::Status
+ServiceWorkerDatabase::GetOriginsWithRegistrations(std::set<GURL>* origins) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+ DCHECK(origins->empty());
Status status = LazyOpen(false);
- if (IsNewOrNonexistentDatabase(status)) {
- *migration_needed = false;
- return STATUS_OK;
- }
- if (status != STATUS_OK)
- return status;
-
- std::string value;
- status = LevelDBStatusToStatus(db_->Get(
- leveldb::ReadOptions(), kDiskCacheMigrationNotNeededKey, &value));
- if (status == STATUS_ERROR_NOT_FOUND) {
- *migration_needed = true;
- HandleReadResult(FROM_HERE, STATUS_OK);
+ if (IsNewOrNonexistentDatabase(status))
return STATUS_OK;
- }
- if (status != STATUS_OK) {
- HandleReadResult(FROM_HERE, status);
- return status;
- }
-
- *migration_needed = false;
- HandleReadResult(FROM_HERE, status);
- return status;
-}
-
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::SetDiskCacheMigrationNotNeeded() {
- DCHECK(sequence_checker_.CalledOnValidSequencedThread());
-
- Status status = LazyOpen(true);
if (status != STATUS_OK)
return status;
- leveldb::WriteBatch batch;
- batch.Put(kDiskCacheMigrationNotNeededKey, kEmptyValue);
- return WriteBatch(&batch);
-}
+ scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
+ for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) {
+ status = LevelDBStatusToStatus(itr->status());
+ if (status != STATUS_OK) {
+ HandleReadResult(FROM_HERE, status);
+ origins->clear();
+ return status;
+ }
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::IsOldDiskCacheDeletionNeeded(bool* deletion_needed) {
- DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+ std::string origin_str;
+ if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin_str))
+ break;
- Status status = LazyOpen(false);
- if (IsNewOrNonexistentDatabase(status)) {
- *deletion_needed = false;
- return STATUS_OK;
- }
- if (status != STATUS_OK)
- return status;
+ GURL origin(origin_str);
+ if (!origin.is_valid()) {
+ status = STATUS_ERROR_CORRUPTED;
+ HandleReadResult(FROM_HERE, status);
+ origins->clear();
+ return status;
+ }
- std::string value;
- status = LevelDBStatusToStatus(db_->Get(
- leveldb::ReadOptions(), kOldDiskCacheDeletionNotNeededKey, &value));
- if (status == STATUS_ERROR_NOT_FOUND) {
- *deletion_needed = true;
- HandleReadResult(FROM_HERE, STATUS_OK);
- return STATUS_OK;
- }
- if (status != STATUS_OK) {
- HandleReadResult(FROM_HERE, status);
- return status;
+ origins->insert(origin);
}
- *deletion_needed = false;
HandleReadResult(FROM_HERE, status);
return status;
}
ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::SetOldDiskCacheDeletionNotNeeded() {
- DCHECK(sequence_checker_.CalledOnValidSequencedThread());
-
- Status status = LazyOpen(true);
- if (status != STATUS_OK)
- return status;
-
- leveldb::WriteBatch batch;
- batch.Put(kOldDiskCacheDeletionNotNeededKey, kEmptyValue);
- return WriteBatch(&batch);
-}
-
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::GetOriginsWithRegistrations(std::set<GURL>* origins) {
+ServiceWorkerDatabase::GetOriginsWithForeignFetchRegistrations(
+ std::set<GURL>* origins) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(origins->empty());
@@ -532,7 +385,7 @@ ServiceWorkerDatabase::GetOriginsWithRegistrations(std::set<GURL>* origins) {
return status;
scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
- for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) {
+ for (itr->Seek(kForeignFetchOriginKey); itr->Valid(); itr->Next()) {
status = LevelDBStatusToStatus(itr->status());
if (status != STATUS_OK) {
HandleReadResult(FROM_HERE, status);
@@ -541,7 +394,8 @@ ServiceWorkerDatabase::GetOriginsWithRegistrations(std::set<GURL>* origins) {
}
std::string origin_str;
- if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin_str))
+ if (!RemovePrefix(itr->key().ToString(), kForeignFetchOriginKey,
+ &origin_str))
break;
GURL origin(origin_str);
@@ -653,7 +507,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetAllRegistrations(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistration(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
RegistrationData* registration,
std::vector<ResourceRecord>* resources) {
@@ -685,7 +539,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistration(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistrationOrigin(
- int64 registration_id,
+ int64_t registration_id,
GURL* origin) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(origin);
@@ -722,7 +576,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
const RegistrationData& registration,
const std::vector<ResourceRecord>& resources,
RegistrationData* old_registration,
- std::vector<int64>* newly_purgeable_resources) {
+ std::vector<int64_t>* newly_purgeable_resources) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(old_registration);
DCHECK(!resources.empty());
@@ -737,17 +591,20 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch);
+ if (!registration.foreign_fetch_scopes.empty())
+ PutForeignFetchOriginToBatch(registration.scope.GetOrigin(), &batch);
+
DCHECK_EQ(AccumulateResourceSizeInBytes(resources),
registration.resources_total_size_bytes)
<< "The total size in the registration must match the cumulative "
<< "sizes of the resources.";
- PutRegistrationDataToBatch(registration, &batch);
+ WriteRegistrationDataInBatch(registration, &batch);
batch.Put(CreateRegistrationIdToOriginKey(registration.registration_id),
registration.scope.GetOrigin().spec());
// Used for avoiding multiple writes for the same resource id or url.
- std::set<int64> pushed_resources;
+ std::set<int64_t> pushed_resources;
std::set<GURL> pushed_urls;
for (std::vector<ResourceRecord>::const_iterator itr = resources.begin();
itr != resources.end(); ++itr) {
@@ -758,7 +615,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
DCHECK(pushed_resources.insert(itr->resource_id).second);
DCHECK(pushed_urls.insert(itr->url).second);
- PutResourceRecordToBatch(*itr, registration.version_id, &batch);
+ WriteResourceRecordInBatch(*itr, registration.version_id, &batch);
// Delete a resource from the uncommitted list.
batch.Delete(CreateResourceIdKey(
@@ -784,17 +641,43 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
// Currently resource sharing across versions and registrations is not
// supported, so resource ids should not be overlapped between
// |registration| and |old_registration|.
- std::set<int64> deleted_resources(newly_purgeable_resources->begin(),
- newly_purgeable_resources->end());
- DCHECK(base::STLSetIntersection<std::set<int64> >(
- pushed_resources, deleted_resources).empty());
+ std::set<int64_t> deleted_resources(newly_purgeable_resources->begin(),
+ newly_purgeable_resources->end());
+ DCHECK(base::STLSetIntersection<std::set<int64_t>>(pushed_resources,
+ deleted_resources)
+ .empty());
+
+ // If old registration had foreign fetch scopes, but new registration
+ // doesn't, the origin might have to be removed from the list of origins
+ // with foreign fetch scopes.
+ // TODO(mek): Like the similar check in DeleteRegistration, ideally this
+ // could be done more efficiently.
+ if (!old_registration->foreign_fetch_scopes.empty() &&
+ registration.foreign_fetch_scopes.empty()) {
+ std::vector<RegistrationData> registrations;
+ status = GetRegistrationsForOrigin(registration.scope.GetOrigin(),
+ &registrations, nullptr);
+ if (status != STATUS_OK)
+ return status;
+ bool remaining_ff_scopes = false;
+ for (const auto& existing_reg : registrations) {
+ if (existing_reg.registration_id != registration.registration_id &&
+ !existing_reg.foreign_fetch_scopes.empty()) {
+ remaining_ff_scopes = true;
+ break;
+ }
+ }
+ if (!remaining_ff_scopes)
+ batch.Delete(
+ CreateForeignFetchOriginKey(registration.scope.GetOrigin()));
+ }
}
return WriteBatch(&batch);
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateVersionToActive(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
Status status = LazyOpen(false);
@@ -813,12 +696,12 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateVersionToActive(
registration.is_active = true;
leveldb::WriteBatch batch;
- PutRegistrationDataToBatch(registration, &batch);
+ WriteRegistrationDataInBatch(registration, &batch);
return WriteBatch(&batch);
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateLastCheckTime(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
const base::Time& time) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
@@ -838,15 +721,15 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::UpdateLastCheckTime(
registration.last_update_check = time;
leveldb::WriteBatch batch;
- PutRegistrationDataToBatch(registration, &batch);
+ WriteRegistrationDataInBatch(registration, &batch);
return WriteBatch(&batch);
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
RegistrationData* deleted_version,
- std::vector<int64>* newly_purgeable_resources) {
+ std::vector<int64_t>* newly_purgeable_resources) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(deleted_version);
deleted_version->version_id = kInvalidServiceWorkerVersionId;
@@ -873,6 +756,19 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration(
batch.Delete(CreateUniqueOriginKey(origin));
}
+ // Remove |origin| from foreign fetch origins if a registration specified by
+ // |registration_id| is the only one with foreign fetch scopes for |origin|.
+ bool remaining_ff_scopes = false;
+ for (const auto& registration : registrations) {
+ if (registration.registration_id != registration_id &&
+ !registration.foreign_fetch_scopes.empty()) {
+ remaining_ff_scopes = true;
+ break;
+ }
+ }
+ if (!remaining_ff_scopes)
+ batch.Delete(CreateForeignFetchOriginKey(origin));
+
// Delete a registration specified by |registration_id|.
batch.Delete(CreateRegistrationKey(registration_id, origin));
batch.Delete(CreateRegistrationIdToOriginKey(registration_id));
@@ -897,7 +793,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserData(
- int64 registration_id,
+ int64_t registration_id,
const std::string& user_data_name,
std::string* user_data) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
@@ -920,7 +816,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserData(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteUserData(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
const std::string& user_data_name,
const std::string& user_data) {
@@ -947,7 +843,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteUserData(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteUserData(
- int64 registration_id,
+ int64_t registration_id,
const std::string& user_data_name) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK_NE(kInvalidServiceWorkerRegistrationId, registration_id);
@@ -968,7 +864,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteUserData(
ServiceWorkerDatabase::Status
ServiceWorkerDatabase::ReadUserDataForAllRegistrations(
const std::string& user_data_name,
- std::vector<std::pair<int64, std::string>>* user_data) {
+ std::vector<std::pair<int64_t, std::string>>* user_data) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(user_data->empty());
@@ -994,7 +890,7 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrations(
break;
}
- int64 registration_id;
+ int64_t registration_id;
status = ParseId(registration_id_string, &registration_id);
if (status != STATUS_OK) {
HandleReadResult(FROM_HERE, status);
@@ -1018,39 +914,40 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrations(
return status;
}
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::GetUncommittedResourceIds(std::set<int64>* ids) {
+ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUncommittedResourceIds(
+ std::set<int64_t>* ids) {
return ReadResourceIds(kUncommittedResIdKeyPrefix, ids);
}
ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::WriteUncommittedResourceIds(const std::set<int64>& ids) {
- return WriteResourceIds(kUncommittedResIdKeyPrefix, ids);
-}
-
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::ClearUncommittedResourceIds(const std::set<int64>& ids) {
- return DeleteResourceIds(kUncommittedResIdKeyPrefix, ids);
+ServiceWorkerDatabase::WriteUncommittedResourceIds(
+ const std::set<int64_t>& ids) {
+ leveldb::WriteBatch batch;
+ Status status =
+ WriteResourceIdsInBatch(kUncommittedResIdKeyPrefix, ids, &batch);
+ if (status != STATUS_OK)
+ return status;
+ return WriteBatch(&batch);
}
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::GetPurgeableResourceIds(std::set<int64>* ids) {
+ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetPurgeableResourceIds(
+ std::set<int64_t>* ids) {
return ReadResourceIds(kPurgeableResIdKeyPrefix, ids);
}
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::WritePurgeableResourceIds(const std::set<int64>& ids) {
- return WriteResourceIds(kPurgeableResIdKeyPrefix, ids);
-}
-
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::ClearPurgeableResourceIds(const std::set<int64>& ids) {
- return DeleteResourceIds(kPurgeableResIdKeyPrefix, ids);
+ServiceWorkerDatabase::Status ServiceWorkerDatabase::ClearPurgeableResourceIds(
+ const std::set<int64_t>& ids) {
+ leveldb::WriteBatch batch;
+ Status status =
+ DeleteResourceIdsInBatch(kPurgeableResIdKeyPrefix, ids, &batch);
+ if (status != STATUS_OK)
+ return status;
+ return WriteBatch(&batch);
}
ServiceWorkerDatabase::Status
ServiceWorkerDatabase::PurgeUncommittedResourceIds(
- const std::set<int64>& ids) {
+ const std::set<int64_t>& ids) {
leveldb::WriteBatch batch;
Status status = DeleteResourceIdsInBatch(
kUncommittedResIdKeyPrefix, ids, &batch);
@@ -1064,7 +961,7 @@ ServiceWorkerDatabase::PurgeUncommittedResourceIds(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteAllDataForOrigins(
const std::set<GURL>& origins,
- std::vector<int64>* newly_purgeable_resources) {
+ std::vector<int64_t>* newly_purgeable_resources) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
Status status = LazyOpen(false);
if (IsNewOrNonexistentDatabase(status))
@@ -1080,6 +977,9 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteAllDataForOrigins(
// Delete from the unique origin list.
batch.Delete(CreateUniqueOriginKey(origin));
+ // Delete from the foreign fetch origin list.
+ batch.Delete(CreateForeignFetchOriginKey(origin));
+
std::vector<RegistrationData> registrations;
status = GetRegistrationsForOrigin(origin, &registrations, nullptr);
if (status != STATUS_OK)
@@ -1162,29 +1062,31 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen(
}
db_.reset(db);
- int64 db_version;
+ int64_t db_version;
status = ReadDatabaseVersion(&db_version);
if (status != STATUS_OK)
return status;
- DCHECK_LE(0, db_version);
-
- if (db_version > 0 && db_version < kCurrentSchemaVersion) {
- switch (db_version) {
- case 1:
- status = UpgradeDatabaseSchemaFromV1ToV2();
- if (status != STATUS_OK)
- return status;
- db_version = 2;
- // Intentionally fall-through to other version upgrade cases.
- }
- // Either the database got upgraded to the current schema version, or some
- // upgrade step failed which would have caused this method to abort.
- DCHECK_EQ(db_version, kCurrentSchemaVersion);
- }
- if (db_version > 0)
- state_ = INITIALIZED;
- return STATUS_OK;
+ switch (db_version) {
+ case 0:
+ // This database is new. It will be initialized when something is written.
+ DCHECK_EQ(UNINITIALIZED, state_);
+ return STATUS_OK;
+ case 1:
+ // This database has an obsolete schema version. ServiceWorkerStorage
+ // should recreate it.
+ status = STATUS_ERROR_FAILED;
+ Disable(FROM_HERE, status);
+ return status;
+ case 2:
+ DCHECK_EQ(db_version, kCurrentSchemaVersion);
+ state_ = INITIALIZED;
+ return STATUS_OK;
+ default:
+ // Other cases should be handled in ReadDatabaseVersion.
+ NOTREACHED();
+ return STATUS_ERROR_CORRUPTED;
+ }
}
bool ServiceWorkerDatabase::IsNewOrNonexistentDatabase(
@@ -1196,55 +1098,9 @@ bool ServiceWorkerDatabase::IsNewOrNonexistentDatabase(
return false;
}
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::UpgradeDatabaseSchemaFromV1ToV2() {
- Status status = STATUS_OK;
- leveldb::WriteBatch batch;
-
- // Version 2 introduced REGID_TO_ORIGIN, add for all existing registrations.
- scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
- for (itr->Seek(kRegKeyPrefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
- if (status != STATUS_OK) {
- HandleReadResult(FROM_HERE, status);
- return status;
- }
-
- std::string key;
- if (!RemovePrefix(itr->key().ToString(), kRegKeyPrefix, &key))
- break;
-
- std::vector<std::string> parts =
- base::SplitString(key, std::string(1, kKeySeparator),
- base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
- if (parts.size() != 2) {
- status = STATUS_ERROR_CORRUPTED;
- HandleReadResult(FROM_HERE, status);
- return status;
- }
-
- int64 registration_id;
- status = ParseId(parts[1], &registration_id);
- if (status != STATUS_OK) {
- HandleReadResult(FROM_HERE, status);
- return status;
- }
-
- batch.Put(CreateRegistrationIdToOriginKey(registration_id), parts[0]);
- }
-
- // Update schema version manually instead of relying on WriteBatch to make
- // sure each upgrade step only updates it to the actually correct version.
- batch.Put(kDatabaseVersionKey, base::Int64ToString(2));
- status = LevelDBStatusToStatus(
- db_->Write(leveldb::WriteOptions(), &batch));
- HandleWriteResult(FROM_HERE, status);
- return status;
-}
-
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadNextAvailableId(
const char* id_key,
- int64* next_avail_id) {
+ int64_t* next_avail_id) {
DCHECK(id_key);
DCHECK(next_avail_id);
@@ -1267,7 +1123,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadNextAvailableId(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistrationData(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
RegistrationData* registration) {
DCHECK(registration);
@@ -1288,8 +1144,96 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistrationData(
return status;
}
+ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData(
+ const std::string& serialized,
+ RegistrationData* out) {
+ DCHECK(out);
+ ServiceWorkerRegistrationData data;
+ if (!data.ParseFromString(serialized))
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+
+ GURL scope_url(data.scope_url());
+ GURL script_url(data.script_url());
+ if (!scope_url.is_valid() || !script_url.is_valid() ||
+ scope_url.GetOrigin() != script_url.GetOrigin()) {
+ DLOG(ERROR) << "Scope URL '" << data.scope_url() << "' and/or script url '"
+ << data.script_url()
+ << "' are invalid or have mismatching origins.";
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+ }
+
+ if (data.registration_id() >= next_avail_registration_id_ ||
+ data.version_id() >= next_avail_version_id_) {
+ // The stored registration should not have the higher registration id or
+ // version id than the next available id.
+ DLOG(ERROR) << "Registration id " << data.registration_id()
+ << " and/or version id " << data.version_id()
+ << " is higher than the next available id.";
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+ }
+
+ // Convert ServiceWorkerRegistrationData to RegistrationData.
+ out->registration_id = data.registration_id();
+ out->scope = scope_url;
+ out->script = script_url;
+ out->version_id = data.version_id();
+ out->is_active = data.is_active();
+ out->has_fetch_handler = data.has_fetch_handler();
+ out->last_update_check =
+ base::Time::FromInternalValue(data.last_update_check_time());
+ out->resources_total_size_bytes = data.resources_total_size_bytes();
+ for (int i = 0; i < data.foreign_fetch_scope_size(); ++i) {
+ GURL sub_scope_url(data.foreign_fetch_scope(i));
+ if (!sub_scope_url.is_valid() ||
+ !ServiceWorkerUtils::ScopeMatches(scope_url, sub_scope_url)) {
+ DLOG(ERROR) << "Foreign fetch scope '" << data.foreign_fetch_scope(i)
+ << "' is not valid or does not match Scope URL '" << scope_url
+ << "'.";
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+ }
+ out->foreign_fetch_scopes.push_back(sub_scope_url);
+ }
+
+ return ServiceWorkerDatabase::STATUS_OK;
+}
+
+void ServiceWorkerDatabase::WriteRegistrationDataInBatch(
+ const RegistrationData& registration,
+ leveldb::WriteBatch* batch) {
+ DCHECK(batch);
+
+ // The registration id and version id should be bumped before this.
+ DCHECK_GT(next_avail_registration_id_, registration.registration_id);
+ DCHECK_GT(next_avail_version_id_, registration.version_id);
+
+ // Convert RegistrationData to ServiceWorkerRegistrationData.
+ ServiceWorkerRegistrationData data;
+ data.set_registration_id(registration.registration_id);
+ data.set_scope_url(registration.scope.spec());
+ data.set_script_url(registration.script.spec());
+ data.set_version_id(registration.version_id);
+ data.set_is_active(registration.is_active);
+ data.set_has_fetch_handler(registration.has_fetch_handler);
+ data.set_last_update_check_time(
+ registration.last_update_check.ToInternalValue());
+ data.set_resources_total_size_bytes(registration.resources_total_size_bytes);
+ for (const GURL& url : registration.foreign_fetch_scopes) {
+ DCHECK(ServiceWorkerUtils::ScopeMatches(registration.scope, url))
+ << "Foreign fetch scope '" << url
+ << "' does not match service worker scope '" << registration.scope
+ << "'.";
+ data.add_foreign_fetch_scope(url.spec());
+ }
+
+ std::string value;
+ bool success = data.SerializeToString(&value);
+ DCHECK(success);
+ GURL origin = registration.scope.GetOrigin();
+ batch->Put(CreateRegistrationKey(data.registration_id(), origin), value);
+}
+
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceRecords(
- int64 version_id,
+ int64_t version_id,
std::vector<ResourceRecord>* resources) {
DCHECK(resources->empty());
@@ -1322,9 +1266,62 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceRecords(
return status;
}
+ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseResourceRecord(
+ const std::string& serialized,
+ ServiceWorkerDatabase::ResourceRecord* out) {
+ DCHECK(out);
+ ServiceWorkerResourceRecord record;
+ if (!record.ParseFromString(serialized))
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+
+ GURL url(record.url());
+ if (!url.is_valid())
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+
+ if (record.resource_id() >= next_avail_resource_id_) {
+ // The stored resource should not have a higher resource id than the next
+ // available resource id.
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+ }
+
+ // Convert ServiceWorkerResourceRecord to ResourceRecord.
+ out->resource_id = record.resource_id();
+ out->url = url;
+ out->size_bytes = record.size_bytes();
+ return ServiceWorkerDatabase::STATUS_OK;
+}
+
+void ServiceWorkerDatabase::WriteResourceRecordInBatch(
+ const ResourceRecord& resource,
+ int64_t version_id,
+ leveldb::WriteBatch* batch) {
+ DCHECK(batch);
+ DCHECK_GE(resource.size_bytes, 0);
+
+ // The next available resource id should be bumped when a resource is recorded
+ // in the uncommitted list and this should be nop. However, we attempt it here
+ // for some unit tests that bypass WriteUncommittedResourceIds() when setting
+ // up a dummy registration. Otherwise, tests fail due to a corruption error in
+ // ParseResourceRecord().
+ // TODO(nhiroki): Remove this hack by making tests appropriately set up
+ // uncommitted resource ids before writing a registration.
+ BumpNextResourceIdIfNeeded(resource.resource_id, batch);
+
+ // Convert ResourceRecord to ServiceWorkerResourceRecord.
+ ServiceWorkerResourceRecord data;
+ data.set_resource_id(resource.resource_id);
+ data.set_url(resource.url.spec());
+ data.set_size_bytes(resource.size_bytes);
+
+ std::string value;
+ bool success = data.SerializeToString(&value);
+ DCHECK(success);
+ batch->Put(CreateResourceRecordKey(version_id, data.resource_id()), value);
+}
+
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords(
- int64 version_id,
- std::vector<int64>* newly_purgeable_resources,
+ int64_t version_id,
+ std::vector<int64_t>* newly_purgeable_resources,
leveldb::WriteBatch* batch) {
DCHECK(batch);
@@ -1344,7 +1341,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords(
if (!RemovePrefix(key, prefix, &unprefixed))
break;
- int64 resource_id;
+ int64_t resource_id;
status = ParseId(unprefixed, &resource_id);
if (status != STATUS_OK) {
HandleReadResult(FROM_HERE, status);
@@ -1366,7 +1363,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
const char* id_key_prefix,
- std::set<int64>* ids) {
+ std::set<int64_t>* ids) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(id_key_prefix);
DCHECK(ids->empty());
@@ -1390,7 +1387,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
if (!RemovePrefix(itr->key().ToString(), id_key_prefix, &unprefixed))
break;
- int64 resource_id;
+ int64_t resource_id;
status = ParseId(unprefixed, &resource_id);
if (status != STATUS_OK) {
HandleReadResult(FROM_HERE, status);
@@ -1404,19 +1401,9 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
return status;
}
-ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIds(
- const char* id_key_prefix,
- const std::set<int64>& ids) {
- leveldb::WriteBatch batch;
- Status status = WriteResourceIdsInBatch(id_key_prefix, ids, &batch);
- if (status != STATUS_OK)
- return status;
- return WriteBatch(&batch);
-}
-
ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIdsInBatch(
const char* id_key_prefix,
- const std::set<int64>& ids,
+ const std::set<int64_t>& ids,
leveldb::WriteBatch* batch) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(id_key_prefix);
@@ -1427,8 +1414,8 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIdsInBatch(
if (ids.empty())
return STATUS_OK;
- for (std::set<int64>::const_iterator itr = ids.begin();
- itr != ids.end(); ++itr) {
+ for (std::set<int64_t>::const_iterator itr = ids.begin(); itr != ids.end();
+ ++itr) {
// Value should be empty.
batch->Put(CreateResourceIdKey(id_key_prefix, *itr), "");
}
@@ -1437,19 +1424,9 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIdsInBatch(
return STATUS_OK;
}
-ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceIds(
- const char* id_key_prefix,
- const std::set<int64>& ids) {
- leveldb::WriteBatch batch;
- Status status = DeleteResourceIdsInBatch(id_key_prefix, ids, &batch);
- if (status != STATUS_OK)
- return status;
- return WriteBatch(&batch);
-}
-
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceIdsInBatch(
const char* id_key_prefix,
- const std::set<int64>& ids,
+ const std::set<int64_t>& ids,
leveldb::WriteBatch* batch) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(id_key_prefix);
@@ -1460,8 +1437,8 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceIdsInBatch(
if (status != STATUS_OK)
return status;
- for (std::set<int64>::const_iterator itr = ids.begin();
- itr != ids.end(); ++itr) {
+ for (std::set<int64_t>::const_iterator itr = ids.begin(); itr != ids.end();
+ ++itr) {
batch->Delete(CreateResourceIdKey(id_key_prefix, *itr));
}
return STATUS_OK;
@@ -1469,7 +1446,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceIdsInBatch(
ServiceWorkerDatabase::Status
ServiceWorkerDatabase::DeleteUserDataForRegistration(
- int64 registration_id,
+ int64_t registration_id,
leveldb::WriteBatch* batch) {
DCHECK(batch);
Status status = STATUS_OK;
@@ -1494,7 +1471,7 @@ ServiceWorkerDatabase::DeleteUserDataForRegistration(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadDatabaseVersion(
- int64* db_version) {
+ int64_t* db_version) {
std::string value;
Status status = LevelDBStatusToStatus(
db_->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value));
@@ -1510,7 +1487,15 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadDatabaseVersion(
return status;
}
- status = ParseDatabaseVersion(value, db_version);
+ const int kFirstValidVersion = 1;
+ if (!base::StringToInt64(value, db_version) ||
+ *db_version < kFirstValidVersion || kCurrentSchemaVersion < *db_version) {
+ status = STATUS_ERROR_CORRUPTED;
+ HandleReadResult(FROM_HERE, status);
+ return status;
+ }
+
+ status = STATUS_OK;
HandleReadResult(FROM_HERE, status);
return status;
}
@@ -1523,8 +1508,6 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteBatch(
if (state_ == UNINITIALIZED) {
// Write database default values.
batch->Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion));
- if (!skip_writing_diskcache_migration_state_on_init_for_testing_)
- batch->Put(kDiskCacheMigrationNotNeededKey, kEmptyValue);
state_ = INITIALIZED;
}
@@ -1535,7 +1518,8 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteBatch(
}
void ServiceWorkerDatabase::BumpNextRegistrationIdIfNeeded(
- int64 used_id, leveldb::WriteBatch* batch) {
+ int64_t used_id,
+ leveldb::WriteBatch* batch) {
DCHECK(batch);
if (next_avail_registration_id_ <= used_id) {
next_avail_registration_id_ = used_id + 1;
@@ -1544,7 +1528,8 @@ void ServiceWorkerDatabase::BumpNextRegistrationIdIfNeeded(
}
void ServiceWorkerDatabase::BumpNextResourceIdIfNeeded(
- int64 used_id, leveldb::WriteBatch* batch) {
+ int64_t used_id,
+ leveldb::WriteBatch* batch) {
DCHECK(batch);
if (next_avail_resource_id_ <= used_id) {
next_avail_resource_id_ = used_id + 1;
@@ -1553,7 +1538,8 @@ void ServiceWorkerDatabase::BumpNextResourceIdIfNeeded(
}
void ServiceWorkerDatabase::BumpNextVersionIdIfNeeded(
- int64 used_id, leveldb::WriteBatch* batch) {
+ int64_t used_id,
+ leveldb::WriteBatch* batch) {
DCHECK(batch);
if (next_avail_version_id_ <= used_id) {
next_avail_version_id_ = used_id + 1;
diff --git a/chromium/content/browser/service_worker/service_worker_database.h b/chromium/content/browser/service_worker/service_worker_database.h
index 8dd0b623eac..191ef4d7d56 100644
--- a/chromium/content/browser/service_worker/service_worker_database.h
+++ b/chromium/content/browser/service_worker/service_worker_database.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
@@ -47,23 +49,25 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
STATUS_ERROR_IO_ERROR,
STATUS_ERROR_CORRUPTED,
STATUS_ERROR_FAILED,
+ STATUS_ERROR_NOT_SUPPORTED,
STATUS_ERROR_MAX,
};
static const char* StatusToString(Status status);
struct CONTENT_EXPORT RegistrationData {
// These values are immutable for the life of a registration.
- int64 registration_id;
+ int64_t registration_id;
GURL scope;
// Versions are first stored once they successfully install and become
// the waiting version. Then transition to the active version. The stored
// version may be in the ACTIVATED state or in the INSTALLED state.
GURL script;
- int64 version_id;
+ int64_t version_id;
bool is_active;
bool has_fetch_handler;
base::Time last_update_check;
+ std::vector<GURL> foreign_fetch_scopes;
// Not populated until ServiceWorkerStorage::StoreRegistration is called.
int64_t resources_total_size_bytes;
@@ -73,40 +77,34 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
};
struct ResourceRecord {
- int64 resource_id;
+ int64_t resource_id;
GURL url;
// Signed so we can store -1 to specify an unknown or error state. When
// stored to the database, this value should always be >= 0.
- int64 size_bytes;
+ int64_t size_bytes;
ResourceRecord() : resource_id(-1), size_bytes(0) {}
- ResourceRecord(int64 id, GURL url, int64 size_bytes)
+ ResourceRecord(int64_t id, GURL url, int64_t size_bytes)
: resource_id(id), url(url), size_bytes(size_bytes) {}
};
// Reads next available ids from the database. Returns OK if they are
// successfully read. Fills the arguments with an initial value and returns
// OK if they are not found in the database. Otherwise, returns an error.
- Status GetNextAvailableIds(
- int64* next_avail_registration_id,
- int64* next_avail_version_id,
- int64* next_avail_resource_id);
-
- // Used for diskcache migration (http://crbug.com/487482). Returns true if the
- // storage needs to migrate a disk cache.
- Status IsDiskCacheMigrationNeeded(bool* migration_needed);
- Status SetDiskCacheMigrationNotNeeded();
-
- // Used for diskcache migration (http://crbug.com/487482). Returns true if the
- // storage needs to delete an old disk cache.
- Status IsOldDiskCacheDeletionNeeded(bool* deletion_needed);
- Status SetOldDiskCacheDeletionNotNeeded();
+ Status GetNextAvailableIds(int64_t* next_avail_registration_id,
+ int64_t* next_avail_version_id,
+ int64_t* next_avail_resource_id);
// Reads origins that have one or more than one registration from the
// database. Returns OK if they are successfully read or not found.
// Otherwise, returns an error.
Status GetOriginsWithRegistrations(std::set<GURL>* origins);
+ // Reads origins that have one or more than one registration with at least one
+ // foreign fetch scope registered. Returns OK if they are successfully read or
+ // not found. Otherwise returns an error.
+ Status GetOriginsWithForeignFetchRegistrations(std::set<GURL>* origins);
+
// Reads registrations for |origin| from the database. Returns OK if they are
// successfully read or not found. Otherwise, returns an error.
Status GetRegistrationsForOrigin(
@@ -126,16 +124,15 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// Reads a registration for |registration_id| and resource records associated
// with it from the database. Returns OK if they are successfully read.
// Otherwise, returns an error.
- Status ReadRegistration(
- int64 registration_id,
- const GURL& origin,
- RegistrationData* registration,
- std::vector<ResourceRecord>* resources);
+ Status ReadRegistration(int64_t registration_id,
+ const GURL& origin,
+ RegistrationData* registration,
+ std::vector<ResourceRecord>* resources);
// Looks up the origin for the registration with |registration_id|. Returns OK
// if a registration was found and read successfully. Otherwise, returns an
// error.
- Status ReadRegistrationOrigin(int64 registration_id, GURL* origin);
+ Status ReadRegistrationOrigin(int64_t registration_id, GURL* origin);
// Writes |registration| and |resources| into the database and does following
// things:
@@ -149,20 +146,17 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
Status WriteRegistration(const RegistrationData& registration,
const std::vector<ResourceRecord>& resources,
RegistrationData* deleted_version,
- std::vector<int64>* newly_purgeable_resources);
+ std::vector<int64_t>* newly_purgeable_resources);
// Updates a registration for |registration_id| to an active state. Returns OK
// if it's successfully updated. Otherwise, returns an error.
- Status UpdateVersionToActive(
- int64 registration_id,
- const GURL& origin);
+ Status UpdateVersionToActive(int64_t registration_id, const GURL& origin);
// Updates last check time of a registration for |registration_id| by |time|.
// Returns OK if it's successfully updated. Otherwise, returns an error.
- Status UpdateLastCheckTime(
- int64 registration_id,
- const GURL& origin,
- const base::Time& time);
+ Status UpdateLastCheckTime(int64_t registration_id,
+ const GURL& origin,
+ const base::Time& time);
// Deletes a registration for |registration_id| and moves resource records
// associated with it into the purgeable list. If deletion occurred, sets
@@ -170,20 +164,20 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// |newly_purgeable_resources| to its resources; otherwise, sets |version_id|
// to -1. Returns OK if it's successfully deleted or not found in the
// database. Otherwise, returns an error.
- Status DeleteRegistration(int64 registration_id,
+ Status DeleteRegistration(int64_t registration_id,
const GURL& origin,
RegistrationData* deleted_version,
- std::vector<int64>* newly_purgeable_resources);
+ std::vector<int64_t>* newly_purgeable_resources);
// Reads user data for |registration_id| and |user_data_name| from the
// database.
- Status ReadUserData(int64 registration_id,
+ Status ReadUserData(int64_t registration_id,
const std::string& user_data_name,
std::string* user_data);
// Writes |user_data| into the database. Returns NOT_FOUND if the registration
// specified by |registration_id| does not exist in the database.
- Status WriteUserData(int64 registration_id,
+ Status WriteUserData(int64_t registration_id,
const GURL& origin,
const std::string& user_data_name,
const std::string& user_data);
@@ -191,56 +185,52 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// Deletes user data for |registration_id| and |user_data_name| from the
// database. Returns OK if it's successfully deleted or not found in the
// database.
- Status DeleteUserData(int64 registration_id,
+ Status DeleteUserData(int64_t registration_id,
const std::string& user_data_name);
// Reads user data for all registrations that have data with |user_data_name|
// from the database. Returns OK if they are successfully read or not found.
Status ReadUserDataForAllRegistrations(
const std::string& user_data_name,
- std::vector<std::pair<int64, std::string>>* user_data);
+ std::vector<std::pair<int64_t, std::string>>* user_data);
- // As new resources are put into the diskcache, they go into an uncommitted
- // list. When a registration is saved that refers to those ids, they're
- // removed from that list. When a resource no longer has any registrations or
+ // Resources should belong to one of following resource lists: uncommitted,
+ // committed and purgeable.
+ // As new resources are put into the diskcache, they go into the uncommitted
+ // list. When a registration is saved that refers to those ids, they're moved
+ // to the committed list. When a resource no longer has any registrations or
// caches referring to it, it's added to the purgeable list. Periodically,
// the purgeable list can be purged from the diskcache. At system startup, all
// uncommitted ids are moved to the purgeable list.
- // Reads uncommitted resource ids from the database. Returns OK on success.
+ // Reads resource ids from the uncommitted list. Returns OK on success.
// Otherwise clears |ids| and returns an error.
- Status GetUncommittedResourceIds(std::set<int64>* ids);
-
- // Writes |ids| into the database as uncommitted resources. Returns OK on
- // success. Otherwise writes nothing and returns an error.
- Status WriteUncommittedResourceIds(const std::set<int64>& ids);
+ Status GetUncommittedResourceIds(std::set<int64_t>* ids);
- // Deletes uncommitted resource ids specified by |ids| from the database.
- // Returns OK on success. Otherwise deletes nothing and returns an error.
- Status ClearUncommittedResourceIds(const std::set<int64>& ids);
+ // Writes resource ids into the uncommitted list. Returns OK on success.
+ // Otherwise writes nothing and returns an error.
+ Status WriteUncommittedResourceIds(const std::set<int64_t>& ids);
- // Reads purgeable resource ids from the database. Returns OK on success.
+ // Reads resource ids from the purgeable list. Returns OK on success.
// Otherwise clears |ids| and returns an error.
- Status GetPurgeableResourceIds(std::set<int64>* ids);
-
- // Writes |ids| into the database as purgeable resources. Returns OK on
- // success. Otherwise writes nothing and returns an error.
- Status WritePurgeableResourceIds(const std::set<int64>& ids);
+ Status GetPurgeableResourceIds(std::set<int64_t>* ids);
- // Deletes purgeable resource ids specified by |ids| from the database.
- // Returns OK on success. Otherwise deletes nothing and returns an error.
- Status ClearPurgeableResourceIds(const std::set<int64>& ids);
+ // Deletes resource ids from the purgeable list. Returns OK on success.
+ // Otherwise deletes nothing and returns an error.
+ Status ClearPurgeableResourceIds(const std::set<int64_t>& ids);
- // Moves |ids| from the uncommitted list to the purgeable list.
- // Returns OK on success. Otherwise deletes nothing and returns an error.
- Status PurgeUncommittedResourceIds(const std::set<int64>& ids);
+ // Writes resource ids into the purgeable list and removes them from the
+ // uncommitted list. Returns OK on success. Otherwise writes nothing and
+ // returns an error.
+ Status PurgeUncommittedResourceIds(const std::set<int64_t>& ids);
// Deletes all data for |origins|, namely, unique origin, registrations and
// resource records. Resources are moved to the purgeable list. Returns OK if
// they are successfully deleted or not found in the database. Otherwise,
// returns an error.
- Status DeleteAllDataForOrigins(const std::set<GURL>& origins,
- std::vector<int64>* newly_purgeable_resources);
+ Status DeleteAllDataForOrigins(
+ const std::set<GURL>& origins,
+ std::vector<int64_t>* newly_purgeable_resources);
// Completely deletes the contents of the database.
// Be careful using this function.
@@ -258,76 +248,73 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// the database is new or nonexistent, that is, it has never been used.
bool IsNewOrNonexistentDatabase(Status status);
- // Upgrades the database schema from version 1 to version 2. Called by
- // LazyOpen() when the stored schema is older than version 2.
- Status UpgradeDatabaseSchemaFromV1ToV2();
-
// Reads the next available id for |id_key|. Returns OK if it's successfully
// read. Fills |next_avail_id| with an initial value and returns OK if it's
// not found in the database. Otherwise, returns an error.
- Status ReadNextAvailableId(
- const char* id_key,
- int64* next_avail_id);
+ Status ReadNextAvailableId(const char* id_key, int64_t* next_avail_id);
// Reads registration data for |registration_id| from the database. Returns OK
// if successfully reads. Otherwise, returns an error.
- Status ReadRegistrationData(
- int64 registration_id,
- const GURL& origin,
- RegistrationData* registration);
+ Status ReadRegistrationData(int64_t registration_id,
+ const GURL& origin,
+ RegistrationData* registration);
+
+ // Parses |serialized| as a RegistrationData object and pushes it into |out|.
+ ServiceWorkerDatabase::Status ParseRegistrationData(
+ const std::string& serialized,
+ RegistrationData* out);
+
+ void WriteRegistrationDataInBatch(const RegistrationData& registration,
+ leveldb::WriteBatch* batch);
// Reads resource records for |version_id| from the database. Returns OK if
// it's successfully read or not found in the database. Otherwise, returns an
// error.
- Status ReadResourceRecords(
- int64 version_id,
- std::vector<ResourceRecord>* resources);
+ Status ReadResourceRecords(int64_t version_id,
+ std::vector<ResourceRecord>* resources);
+
+ // Parses |serialized| as a ResourceRecord object and pushes it into |out|.
+ ServiceWorkerDatabase::Status ParseResourceRecord(
+ const std::string& serialized,
+ ResourceRecord* out);
+
+ void WriteResourceRecordInBatch(const ResourceRecord& resource,
+ int64_t version_id,
+ leveldb::WriteBatch* batch);
// Deletes resource records for |version_id| from the database. Returns OK if
// they are successfully deleted or not found in the database. Otherwise,
// returns an error.
- Status DeleteResourceRecords(
- int64 version_id,
- std::vector<int64>* newly_purgeable_resources,
- leveldb::WriteBatch* batch);
+ Status DeleteResourceRecords(int64_t version_id,
+ std::vector<int64_t>* newly_purgeable_resources,
+ leveldb::WriteBatch* batch);
// Reads resource ids for |id_key_prefix| from the database. Returns OK if
// it's successfully read or not found in the database. Otherwise, returns an
// error.
- Status ReadResourceIds(
- const char* id_key_prefix,
- std::set<int64>* ids);
+ Status ReadResourceIds(const char* id_key_prefix, std::set<int64_t>* ids);
// Write resource ids for |id_key_prefix| into the database. Returns OK on
// success. Otherwise, returns writes nothing and returns an error.
- Status WriteResourceIds(
- const char* id_key_prefix,
- const std::set<int64>& ids);
- Status WriteResourceIdsInBatch(
- const char* id_key_prefix,
- const std::set<int64>& ids,
- leveldb::WriteBatch* batch);
+ Status WriteResourceIdsInBatch(const char* id_key_prefix,
+ const std::set<int64_t>& ids,
+ leveldb::WriteBatch* batch);
// Deletes resource ids for |id_key_prefix| from the database. Returns OK if
// it's successfully deleted or not found in the database. Otherwise, returns
// an error.
- Status DeleteResourceIds(
- const char* id_key_prefix,
- const std::set<int64>& ids);
- Status DeleteResourceIdsInBatch(
- const char* id_key_prefix,
- const std::set<int64>& ids,
- leveldb::WriteBatch* batch);
+ Status DeleteResourceIdsInBatch(const char* id_key_prefix,
+ const std::set<int64_t>& ids,
+ leveldb::WriteBatch* batch);
// Deletes all user data for |registration_id| from the database. Returns OK
// if they are successfully deleted or not found in the database.
- Status DeleteUserDataForRegistration(
- int64 registration_id,
- leveldb::WriteBatch* batch);
+ Status DeleteUserDataForRegistration(int64_t registration_id,
+ leveldb::WriteBatch* batch);
// Reads the current schema version from the database. If the database hasn't
// been written anything yet, sets |db_version| to 0 and returns OK.
- Status ReadDatabaseVersion(int64* db_version);
+ Status ReadDatabaseVersion(int64_t* db_version);
// Writes a batch into the database.
// NOTE: You must call this when you want to put something into the database
@@ -336,15 +323,10 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// Bumps the next available id if |used_id| is greater than or equal to the
// cached one.
- void BumpNextRegistrationIdIfNeeded(
- int64 used_id,
- leveldb::WriteBatch* batch);
- void BumpNextResourceIdIfNeeded(
- int64 used_id,
- leveldb::WriteBatch* batch);
- void BumpNextVersionIdIfNeeded(
- int64 used_id,
- leveldb::WriteBatch* batch);
+ void BumpNextRegistrationIdIfNeeded(int64_t used_id,
+ leveldb::WriteBatch* batch);
+ void BumpNextResourceIdIfNeeded(int64_t used_id, leveldb::WriteBatch* batch);
+ void BumpNextVersionIdIfNeeded(int64_t used_id, leveldb::WriteBatch* batch);
bool IsOpen();
@@ -365,9 +347,9 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
scoped_ptr<leveldb::Env> env_;
scoped_ptr<leveldb::DB> db_;
- int64 next_avail_registration_id_;
- int64 next_avail_resource_id_;
- int64 next_avail_version_id_;
+ int64_t next_avail_registration_id_;
+ int64_t next_avail_resource_id_;
+ int64_t next_avail_version_id_;
enum State {
UNINITIALIZED,
@@ -378,28 +360,22 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
bool IsDatabaseInMemory() const;
- void set_skip_writing_diskcache_migration_state_on_init_for_testing() {
- skip_writing_diskcache_migration_state_on_init_for_testing_ = true;
- }
- bool skip_writing_diskcache_migration_state_on_init_for_testing_;
-
base::SequenceChecker sequence_checker_;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, OpenDatabase);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, OpenDatabase_InMemory);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, DatabaseVersion);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest,
+ DatabaseVersion_ValidSchemaVersion);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest,
+ DatabaseVersion_ObsoleteSchemaVersion);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest,
+ DatabaseVersion_CorruptedSchemaVersion);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, GetNextAvailableIds);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest,
Registration_UninitializedDatabase);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest,
UserData_UninitializedDatabase);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, DestroyDatabase);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, DiskCacheMigrationState);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, UpgradeSchemaToVersion2);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest,
- MigrateOnDiskCacheAccess);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest,
- NotMigrateOnDatabaseAccess);
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDatabase);
};
diff --git a/chromium/content/browser/service_worker/service_worker_database.proto b/chromium/content/browser/service_worker/service_worker_database.proto
index bb4acef1fbf..5cce5a78bdc 100644
--- a/chromium/content/browser/service_worker/service_worker_database.proto
+++ b/chromium/content/browser/service_worker/service_worker_database.proto
@@ -25,6 +25,8 @@ message ServiceWorkerRegistrationData {
required int64 last_update_check_time = 7;
optional uint64 resources_total_size_bytes = 8;
+
+ repeated string foreign_fetch_scope = 9;
}
message ServiceWorkerResourceRecord {
diff --git a/chromium/content/browser/service_worker/service_worker_database_task_manager.h b/chromium/content/browser/service_worker/service_worker_database_task_manager.h
index a54b252accf..dbe9aa25190 100644
--- a/chromium/content/browser/service_worker/service_worker_database_task_manager.h
+++ b/chromium/content/browser/service_worker/service_worker_database_task_manager.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_TASK_MANAGER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_TASK_MANAGER_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/service_worker/service_worker_database_unittest.cc b/chromium/content/browser/service_worker/service_worker_database_unittest.cc
index 1d19f2237b8..2b99bb4206f 100644
--- a/chromium/content/browser/service_worker/service_worker_database_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_database_unittest.cc
@@ -4,10 +4,14 @@
#include "content/browser/service_worker/service_worker_database.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/service_worker/service_worker_database.pb.h"
@@ -23,9 +27,9 @@ typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
typedef ServiceWorkerDatabase::ResourceRecord Resource;
struct AvailableIds {
- int64 reg_id;
- int64 res_id;
- int64 ver_id;
+ int64_t reg_id;
+ int64_t res_id;
+ int64_t ver_id;
AvailableIds() : reg_id(-1), res_id(-1), ver_id(-1) {}
~AvailableIds() {}
@@ -39,7 +43,9 @@ GURL URL(const GURL& origin, const std::string& path) {
return out;
}
-Resource CreateResource(int64 resource_id, const GURL& url, uint64 size_bytes) {
+Resource CreateResource(int64_t resource_id,
+ const GURL& url,
+ uint64_t size_bytes) {
EXPECT_TRUE(url.is_valid());
return Resource(resource_id, url, size_bytes);
}
@@ -63,6 +69,7 @@ void VerifyRegistrationData(const RegistrationData& expected,
EXPECT_EQ(expected.last_update_check, actual.last_update_check);
EXPECT_EQ(expected.resources_total_size_bytes,
actual.resources_total_size_bytes);
+ EXPECT_EQ(expected.foreign_fetch_scopes, actual.foreign_fetch_scopes);
}
void VerifyResourceRecords(const std::vector<Resource>& expected,
@@ -108,14 +115,14 @@ TEST(ServiceWorkerDatabaseTest, OpenDatabase_InMemory) {
database->LazyOpen(false));
}
-TEST(ServiceWorkerDatabaseTest, DatabaseVersion) {
+TEST(ServiceWorkerDatabaseTest, DatabaseVersion_ValidSchemaVersion) {
GURL origin("http://example.com");
scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
// Opening a new database does not write anything, so its schema version
// should be 0.
- int64 db_version = -1;
+ int64_t db_version = -1;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->ReadDatabaseVersion(&db_version));
EXPECT_EQ(0u, db_version);
@@ -125,7 +132,7 @@ TEST(ServiceWorkerDatabaseTest, DatabaseVersion) {
std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ServiceWorkerDatabase::RegistrationData data;
data.resources_total_size_bytes = 10;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -137,131 +144,83 @@ TEST(ServiceWorkerDatabaseTest, DatabaseVersion) {
EXPECT_LT(0, db_version);
}
-TEST(ServiceWorkerDatabaseTest, DiskCacheMigrationState) {
- GURL origin("http://example.com");
+TEST(ServiceWorkerDatabaseTest, DatabaseVersion_ObsoleteSchemaVersion) {
base::ScopedTempDir database_dir;
ASSERT_TRUE(database_dir.CreateUniqueTempDir());
scoped_ptr<ServiceWorkerDatabase> database(
CreateDatabase(database_dir.path()));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
- // An empty database should return false.
- bool migration_needed = false;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsDiskCacheMigrationNeeded(&migration_needed));
- EXPECT_FALSE(migration_needed);
- bool deletion_needed = false;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsOldDiskCacheDeletionNeeded(&deletion_needed));
- EXPECT_FALSE(deletion_needed);
-
- // Simulate an existing database created before diskcache migration.
- database->set_skip_writing_diskcache_migration_state_on_init_for_testing();
+ // First writing triggers database initialization and bumps the schema
+ // version.
+ GURL origin("http://example.com");
std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+ resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ServiceWorkerDatabase::RegistrationData data;
- data.registration_id = 100;
- data.scope = URL(origin, "/foo");
- data.script = URL(origin, "/script.js");
- data.version_id = 200;
- data.resources_total_size_bytes = 300;
- resources.push_back(CreateResource(1, data.script, 300));
+ data.resources_total_size_bytes = 10;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(data, resources, &deleted_version,
&newly_purgeable_resources));
- migration_needed = false;
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsDiskCacheMigrationNeeded(&migration_needed));
- ASSERT_TRUE(migration_needed);
- deletion_needed = false;
+ int64_t db_version = -1;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsOldDiskCacheDeletionNeeded(&deletion_needed));
- ASSERT_TRUE(deletion_needed);
-
- // Opening the existing database should not update the migration states.
- database.reset(CreateDatabase(database_dir.path()));
- migration_needed = false;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsDiskCacheMigrationNeeded(&migration_needed));
- EXPECT_TRUE(migration_needed);
- deletion_needed = false;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsOldDiskCacheDeletionNeeded(&deletion_needed));
- EXPECT_TRUE(deletion_needed);
+ database->ReadDatabaseVersion(&db_version));
+ ASSERT_LT(0, db_version);
- // Test SetDiskCacheMigrationNotNeeded().
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->SetDiskCacheMigrationNotNeeded());
- migration_needed = false;
+ // Emulate an obsolete schema version.
+ int64_t old_db_version = 1;
+ leveldb::WriteBatch batch;
+ batch.Put("INITDATA_DB_VERSION", base::Int64ToString(old_db_version));
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->WriteBatch(&batch));
+ db_version = -1;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsDiskCacheMigrationNeeded(&migration_needed));
- EXPECT_FALSE(migration_needed);
+ database->ReadDatabaseVersion(&db_version));
+ ASSERT_EQ(old_db_version, db_version);
- // Test SetOldDiskCacheDeletionNotNeeded().
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->SetOldDiskCacheDeletionNotNeeded());
- deletion_needed = false;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->IsOldDiskCacheDeletionNeeded(&deletion_needed));
- EXPECT_FALSE(deletion_needed);
+ // Opening the database whose schema version is obsolete should fail.
+ database.reset(CreateDatabase(database_dir.path()));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_FAILED,
+ database->LazyOpen(true));
}
-TEST(ServiceWorkerDatabaseTest, UpgradeSchemaToVersion2) {
+TEST(ServiceWorkerDatabaseTest, DatabaseVersion_CorruptedSchemaVersion) {
base::ScopedTempDir database_dir;
ASSERT_TRUE(database_dir.CreateUniqueTempDir());
scoped_ptr<ServiceWorkerDatabase> database(
CreateDatabase(database_dir.path()));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
+ // First writing triggers database initialization and bumps the schema
+ // version.
GURL origin("http://example.com");
-
- // Add a registration to the database.
std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+ resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ServiceWorkerDatabase::RegistrationData data;
- data.registration_id = 100;
- data.scope = URL(origin, "/foo");
- data.script = URL(origin, "/script1.js");
- data.version_id = 200;
- data.resources_total_size_bytes = 300;
- resources.push_back(CreateResource(1, data.script, 300));
+ data.resources_total_size_bytes = 10;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(data, resources, &deleted_version,
&newly_purgeable_resources));
-
- // Sanity check on current version.
- int64 db_version = -1;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ int64_t db_version = -1;
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->ReadDatabaseVersion(&db_version));
- EXPECT_LE(2, db_version);
+ ASSERT_LT(0, db_version);
- // Now delete the data that will be created in an upgrade to schema version 2,
- // and reset the schema version to 1.
+ // Emulate a corrupted schema version.
+ int64_t corrupted_db_version = -10;
leveldb::WriteBatch batch;
- batch.Delete("REGID_TO_ORIGIN:" + base::Int64ToString(data.registration_id));
- batch.Put("INITDATA_DB_VERSION", base::Int64ToString(1));
+ batch.Put("INITDATA_DB_VERSION", base::Int64ToString(corrupted_db_version));
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->WriteBatch(&batch));
-
- // Make sure correct data got deleted.
- GURL origin_out;
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
- database->ReadRegistrationOrigin(data.registration_id, &origin_out));
-
- // Close and reopen the database to verify the schema got updated.
- database.reset(CreateDatabase(database_dir.path()));
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
-
- // Verify version number.
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ db_version = -1;
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED,
database->ReadDatabaseVersion(&db_version));
- EXPECT_LE(2, db_version);
- // And check that looking up origin for registration works.
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_OK,
- database->ReadRegistrationOrigin(data.registration_id, &origin_out));
- EXPECT_EQ(origin, origin_out);
+ // Opening the database whose schema version is corrupted should fail.
+ database.reset(CreateDatabase(database_dir.path()));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED,
+ database->LazyOpen(true));
}
TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
@@ -287,11 +246,37 @@ TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
EXPECT_EQ(0, ids.ver_id);
EXPECT_EQ(0, ids.res_id);
- // Writing a registration bumps the next available ids.
+ // Writing uncommitted resources bumps the next available resource id.
+ const int64_t kUncommittedIds[] = {0, 1, 3, 5, 6, 10};
+ EXPECT_EQ(
+ ServiceWorkerDatabase::STATUS_OK,
+ database->WriteUncommittedResourceIds(std::set<int64_t>(
+ kUncommittedIds, kUncommittedIds + arraysize(kUncommittedIds))));
+ EXPECT_EQ(
+ ServiceWorkerDatabase::STATUS_OK,
+ database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
+ EXPECT_EQ(0, ids.reg_id);
+ EXPECT_EQ(0, ids.ver_id);
+ EXPECT_EQ(11, ids.res_id);
+
+ // Writing purgeable resources bumps the next available id.
+ const int64_t kPurgeableIds[] = {4, 12, 16, 17, 20};
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteUncommittedResourceIds(std::set<int64_t>(
+ kPurgeableIds, kPurgeableIds + arraysize(kPurgeableIds))));
+ EXPECT_EQ(
+ ServiceWorkerDatabase::STATUS_OK,
+ database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
+ EXPECT_EQ(0, ids.reg_id);
+ EXPECT_EQ(0, ids.ver_id);
+ EXPECT_EQ(21, ids.res_id);
+
+ // Writing a registration bumps the next available registration and version
+ // ids.
std::vector<Resource> resources1;
RegistrationData data1;
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
data1.registration_id = 100;
data1.scope = URL(origin, "/foo");
data1.script = URL(origin, "/script1.js");
@@ -302,30 +287,6 @@ TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
database->WriteRegistration(data1, resources1, &deleted_version,
&newly_purgeable_resources));
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
- &ids.reg_id, &ids.ver_id, &ids.res_id));
- EXPECT_EQ(101, ids.reg_id);
- EXPECT_EQ(201, ids.ver_id);
- EXPECT_EQ(0, ids.res_id);
-
- // Writing uncommitted resources bumps the next available id.
- const int64 kUncommittedIds[] = {0, 1, 3, 5, 6, 10};
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_OK,
- database->WriteUncommittedResourceIds(std::set<int64>(
- kUncommittedIds, kUncommittedIds + arraysize(kUncommittedIds))));
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_OK,
- database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
- EXPECT_EQ(101, ids.reg_id);
- EXPECT_EQ(201, ids.ver_id);
- EXPECT_EQ(11, ids.res_id);
-
- // Writing purgeable resources bumps the next available id.
- const int64 kPurgeableIds[] = {4, 12, 16, 17, 20};
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteUncommittedResourceIds(std::set<int64>(
- kPurgeableIds, kPurgeableIds + arraysize(kPurgeableIds))));
EXPECT_EQ(
ServiceWorkerDatabase::STATUS_OK,
database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
@@ -348,10 +309,10 @@ TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
&newly_purgeable_resources));
// Same with resources.
- int64 kLowResourceId = 15;
+ int64_t kLowResourceId = 15;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteUncommittedResourceIds(
- std::set<int64>(&kLowResourceId, &kLowResourceId + 1)));
+ std::set<int64_t>(&kLowResourceId, &kLowResourceId + 1)));
// Close and reopen the database to verify the stored values.
database.reset(CreateDatabase(database_dir.path()));
@@ -372,7 +333,7 @@ TEST(ServiceWorkerDatabaseTest, GetOriginsWithRegistrations) {
EXPECT_TRUE(origins.empty());
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
GURL origin1("http://example.com");
RegistrationData data1;
@@ -483,7 +444,7 @@ TEST(ServiceWorkerDatabaseTest, GetRegistrationsForOrigin) {
EXPECT_TRUE(resources_list.empty());
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
RegistrationData data1;
data1.registration_id = 100;
@@ -585,7 +546,7 @@ TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
EXPECT_TRUE(registrations.empty());
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
GURL origin1("http://www1.example.com");
RegistrationData data1;
@@ -659,6 +620,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
data.script = URL(origin, "/script.js");
data.version_id = 200;
data.resources_total_size_bytes = 10939 + 200;
+ data.foreign_fetch_scopes.push_back(URL(origin, "/foo/bar"));
std::vector<Resource> resources;
resources.push_back(CreateResource(1, URL(origin, "/resource1"), 10939));
@@ -667,18 +629,18 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
// Write a resource to the uncommitted list to make sure that writing
// registration removes resource ids associated with the registration from
// the uncommitted list.
- std::set<int64> uncommitted_ids;
+ std::set<int64_t> uncommitted_ids;
uncommitted_ids.insert(resources[0].resource_id);
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteUncommittedResourceIds(uncommitted_ids));
- std::set<int64> uncommitted_ids_out;
+ std::set<int64_t> uncommitted_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetUncommittedResourceIds(&uncommitted_ids_out));
EXPECT_EQ(uncommitted_ids, uncommitted_ids_out);
ServiceWorkerDatabase::RegistrationData deleted_version;
deleted_version.version_id = 222; // Dummy initial value
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(
@@ -727,7 +689,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
database->ReadRegistrationOrigin(data.registration_id, &origin_out));
// Resources should be purgeable because these are no longer referred.
- std::set<int64> purgeable_ids_out;
+ std::set<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_EQ(2u, purgeable_ids_out.size());
@@ -750,12 +712,12 @@ TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
resources.push_back(CreateResource(1, URL(origin, "/resource1"), 19));
resources.push_back(CreateResource(2, URL(origin, "/resource2"), 29129));
- const int64 kNonExistentRegistrationId = 999;
- const int64 kArbitraryVersionId = 222; // Used as a dummy initial value
+ const int64_t kNonExistentRegistrationId = 999;
+ const int64_t kArbitraryVersionId = 222; // Used as a dummy initial value
ServiceWorkerDatabase::RegistrationData deleted_version;
deleted_version.version_id = kArbitraryVersionId;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(
data, resources, &deleted_version, &newly_purgeable_resources));
@@ -795,6 +757,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
data.script = URL(origin, "/script.js");
data.version_id = 200;
data.resources_total_size_bytes = 10 + 11;
+ data.foreign_fetch_scopes.push_back(URL(origin, "/foo"));
std::vector<Resource> resources1;
resources1.push_back(CreateResource(1, URL(origin, "/resource1"), 10));
@@ -802,7 +765,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
ServiceWorkerDatabase::RegistrationData deleted_version;
deleted_version.version_id = 222; // Dummy inital value
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
EXPECT_EQ(
ServiceWorkerDatabase::STATUS_OK,
@@ -823,6 +786,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
RegistrationData updated_data = data;
updated_data.version_id = data.version_id + 1;
updated_data.resources_total_size_bytes = 12 + 13;
+ updated_data.foreign_fetch_scopes.clear();
std::vector<Resource> resources2;
resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 12));
resources2.push_back(CreateResource(4, URL(origin, "/resource4"), 13));
@@ -845,7 +809,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
VerifyRegistrationData(updated_data, data_out);
VerifyResourceRecords(resources2, resources_out);
- std::set<int64> purgeable_ids_out;
+ std::set<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_EQ(2u, purgeable_ids_out.size());
@@ -858,7 +822,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
GURL origin("http://example.com");
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
// Add registration1.
RegistrationData data1;
@@ -916,7 +880,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
database->ReadRegistrationOrigin(data2.registration_id, &origin_out));
EXPECT_EQ(origin, origin_out);
- std::set<int64> purgeable_ids_out;
+ std::set<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_TRUE(purgeable_ids_out.empty());
@@ -976,7 +940,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_UninitializedDatabase) {
// Deleting non-existent registration should succeed.
RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->DeleteRegistration(
100, origin, &deleted_version, &newly_purgeable_resources));
@@ -1018,7 +982,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_Basic) {
std::vector<Resource> resources;
resources.push_back(CreateResource(1, data.script, 100));
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(
data, resources, &deleted_version, &newly_purgeable_resources));
@@ -1097,7 +1061,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
resources2.push_back(CreateResource(2, data2.script, 200));
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(data1, resources1, &deleted_version,
&newly_purgeable_resources));
@@ -1133,7 +1097,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
EXPECT_EQ("data2", user_data_out);
// Get all registrations with user data.
- std::vector<std::pair<int64, std::string>> user_data_list;
+ std::vector<std::pair<int64_t, std::string>> user_data_list;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->ReadUserDataForAllRegistrations("key", &user_data_list));
EXPECT_EQ(2u, user_data_list.size());
@@ -1188,7 +1152,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_DeleteRegistration) {
resources2.push_back(CreateResource(2, data2.script, 200));
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(data1, resources1, &deleted_version,
&newly_purgeable_resources));
@@ -1277,7 +1241,7 @@ TEST(ServiceWorkerDatabaseTest, UpdateVersionToActive) {
GURL origin("http://example.com");
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
// Should be false because a registration does not exist.
EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
@@ -1337,7 +1301,7 @@ TEST(ServiceWorkerDatabaseTest, UpdateLastCheckTime) {
scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
GURL origin("http://example.com");
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
// Should be false because a registration does not exist.
EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
@@ -1396,24 +1360,24 @@ TEST(ServiceWorkerDatabaseTest, UpdateLastCheckTime) {
data.registration_id, origin, base::Time::Now()));
}
-TEST(ServiceWorkerDatabaseTest, UncommittedResourceIds) {
+TEST(ServiceWorkerDatabaseTest, UncommittedAndPurgeableResourceIds) {
scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- // Write {1, 2, 3}.
- std::set<int64> ids1;
+ // Write {1, 2, 3} into the uncommitted list.
+ std::set<int64_t> ids1;
ids1.insert(1);
ids1.insert(2);
ids1.insert(3);
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteUncommittedResourceIds(ids1));
- std::set<int64> ids_out;
+ std::set<int64_t> ids_out;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetUncommittedResourceIds(&ids_out));
EXPECT_EQ(ids1, ids_out);
- // Write {2, 4}.
- std::set<int64> ids2;
+ // Write {2, 4} into the uncommitted list.
+ std::set<int64_t> ids2;
ids2.insert(2);
ids2.insert(4);
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1422,70 +1386,37 @@ TEST(ServiceWorkerDatabaseTest, UncommittedResourceIds) {
ids_out.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetUncommittedResourceIds(&ids_out));
- std::set<int64> expected = base::STLSetUnion<std::set<int64> >(ids1, ids2);
+ std::set<int64_t> expected = base::STLSetUnion<std::set<int64_t>>(ids1, ids2);
EXPECT_EQ(expected, ids_out);
- // Delete {2, 3}.
- std::set<int64> ids3;
- ids3.insert(2);
- ids3.insert(3);
+ // Move {2, 4} from the uncommitted list to the purgeable list.
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->ClearUncommittedResourceIds(ids3));
-
+ database->PurgeUncommittedResourceIds(ids2));
ids_out.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetUncommittedResourceIds(&ids_out));
- expected = base::STLSetDifference<std::set<int64> >(expected, ids3);
- EXPECT_EQ(expected, ids_out);
-}
-
-TEST(ServiceWorkerDatabaseTest, PurgeableResourceIds) {
- scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
-
- // Write {1, 2, 3}.
- std::set<int64> ids1;
- ids1.insert(1);
- ids1.insert(2);
- ids1.insert(3);
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WritePurgeableResourceIds(ids1));
-
- std::set<int64> ids_out;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetPurgeableResourceIds(&ids_out));
- EXPECT_EQ(ids1, ids_out);
+ EXPECT_EQ(ids2, ids_out);
- // Write {2, 4}.
- std::set<int64> ids2;
- ids2.insert(2);
- ids2.insert(4);
+ // Delete {2, 4} from the purgeable list.
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WritePurgeableResourceIds(ids2));
-
+ database->ClearPurgeableResourceIds(ids2));
ids_out.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetPurgeableResourceIds(&ids_out));
- std::set<int64> expected = base::STLSetUnion<std::set<int64> >(ids1, ids2);
- EXPECT_EQ(expected, ids_out);
-
- // Delete {2, 3}.
- std::set<int64> ids3;
- ids3.insert(2);
- ids3.insert(3);
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->ClearPurgeableResourceIds(ids3));
+ EXPECT_TRUE(ids_out.empty());
+ // {1, 3} should be still in the uncommitted list.
ids_out.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetPurgeableResourceIds(&ids_out));
- expected = base::STLSetDifference<std::set<int64> >(expected, ids3);
+ database->GetUncommittedResourceIds(&ids_out));
+ expected = base::STLSetDifference<std::set<int64_t>>(ids1, ids2);
EXPECT_EQ(expected, ids_out);
}
TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
// Data associated with |origin1| will be removed.
GURL origin1("http://example.com");
@@ -1498,6 +1429,7 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
data1.script = URL(origin1, "/script1.js");
data1.version_id = 100;
data1.resources_total_size_bytes = 2013 + 512;
+ data1.foreign_fetch_scopes.push_back(URL(origin1, "/foo/ff"));
std::vector<Resource> resources1;
resources1.push_back(CreateResource(1, URL(origin1, "/resource1"), 2013));
@@ -1545,6 +1477,7 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
data3.script = URL(origin2, "/script3.js");
data3.version_id = 102;
data3.resources_total_size_bytes = 6 + 7;
+ data3.foreign_fetch_scopes.push_back(URL(origin2, "/hoge/ff"));
std::vector<Resource> resources3;
resources3.push_back(CreateResource(5, URL(origin2, "/resource5"), 6));
@@ -1575,6 +1508,13 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
EXPECT_EQ(1u, unique_origins.size());
EXPECT_TRUE(ContainsKey(unique_origins, origin2));
+ // |origin1| should be removed from the foreign fetch origin list.
+ unique_origins.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->GetOriginsWithForeignFetchRegistrations(&unique_origins));
+ EXPECT_EQ(1u, unique_origins.size());
+ EXPECT_TRUE(ContainsKey(unique_origins, origin2));
+
// The registrations for |origin1| should be removed.
std::vector<RegistrationData> registrations;
EXPECT_EQ(
@@ -1599,7 +1539,7 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
EXPECT_EQ(origin2, origin_out);
// The resources associated with |origin1| should be purgeable.
- std::set<int64> purgeable_ids_out;
+ std::set<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_EQ(4u, purgeable_ids_out.size());
@@ -1647,4 +1587,140 @@ TEST(ServiceWorkerDatabaseTest, DestroyDatabase) {
ASSERT_FALSE(base::DirectoryExists(database_dir.path()));
}
+TEST(ServiceWorkerDatabaseTest, GetOriginsWithForeignFetchRegistrations) {
+ scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+
+ std::set<GURL> origins;
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->GetOriginsWithForeignFetchRegistrations(&origins));
+ EXPECT_TRUE(origins.empty());
+
+ ServiceWorkerDatabase::RegistrationData deleted_version;
+ std::vector<int64_t> newly_purgeable_resources;
+
+ GURL origin1("http://example.com");
+ RegistrationData data1;
+ data1.registration_id = 123;
+ data1.scope = URL(origin1, "/foo");
+ data1.script = URL(origin1, "/script1.js");
+ data1.version_id = 456;
+ data1.resources_total_size_bytes = 100;
+ data1.foreign_fetch_scopes.push_back(URL(origin1, "/foo/bar"));
+ std::vector<Resource> resources1;
+ resources1.push_back(CreateResource(1, data1.script, 100));
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data1, resources1, &deleted_version,
+ &newly_purgeable_resources));
+
+ GURL origin2("https://www.example.com");
+ RegistrationData data2;
+ data2.registration_id = 234;
+ data2.scope = URL(origin2, "/bar");
+ data2.script = URL(origin2, "/script2.js");
+ data2.version_id = 567;
+ data2.resources_total_size_bytes = 200;
+ std::vector<Resource> resources2;
+ resources2.push_back(CreateResource(2, data2.script, 200));
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data2, resources2, &deleted_version,
+ &newly_purgeable_resources));
+
+ GURL origin3("https://example.org");
+ RegistrationData data3;
+ data3.registration_id = 345;
+ data3.scope = URL(origin3, "/hoge");
+ data3.script = URL(origin3, "/script3.js");
+ data3.version_id = 678;
+ data3.resources_total_size_bytes = 300;
+ data3.foreign_fetch_scopes.push_back(URL(origin3, "/hoge/foo"));
+ std::vector<Resource> resources3;
+ resources3.push_back(CreateResource(3, data3.script, 300));
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data3, resources3, &deleted_version,
+ &newly_purgeable_resources));
+
+ // |origin3| has three registrations.
+ RegistrationData data4;
+ data4.registration_id = 456;
+ data4.scope = URL(origin3, "/fuga");
+ data4.script = URL(origin3, "/script4.js");
+ data4.version_id = 789;
+ data4.resources_total_size_bytes = 400;
+ data4.foreign_fetch_scopes.push_back(URL(origin3, "/fuga/bar"));
+ std::vector<Resource> resources4;
+ resources4.push_back(CreateResource(4, data4.script, 400));
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data4, resources4, &deleted_version,
+ &newly_purgeable_resources));
+
+ RegistrationData data5;
+ data5.registration_id = 567;
+ data5.scope = URL(origin3, "/bla");
+ data5.script = URL(origin3, "/script5.js");
+ data5.version_id = 890;
+ data5.resources_total_size_bytes = 500;
+ std::vector<Resource> resources5;
+ resources5.push_back(CreateResource(5, data5.script, 500));
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data5, resources5, &deleted_version,
+ &newly_purgeable_resources));
+
+ origins.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->GetOriginsWithForeignFetchRegistrations(&origins));
+ EXPECT_EQ(2U, origins.size());
+ EXPECT_TRUE(ContainsKey(origins, origin1));
+ EXPECT_TRUE(ContainsKey(origins, origin3));
+
+ // |origin3| has another registration, so should not remove it from the
+ // foreign fetch origin list.
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->DeleteRegistration(data4.registration_id, origin3,
+ &deleted_version,
+ &newly_purgeable_resources));
+ EXPECT_EQ(data4.registration_id, deleted_version.registration_id);
+
+ origins.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->GetOriginsWithForeignFetchRegistrations(&origins));
+ EXPECT_EQ(2U, origins.size());
+ EXPECT_TRUE(ContainsKey(origins, origin1));
+ EXPECT_TRUE(ContainsKey(origins, origin3));
+
+ // |origin3| should be removed from the foreign fetch origin list, since its
+ // only remaining registration doesn't have foreign fetch scopes.
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->DeleteRegistration(data3.registration_id, origin3,
+ &deleted_version,
+ &newly_purgeable_resources));
+ EXPECT_EQ(data3.registration_id, deleted_version.registration_id);
+
+ origins.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->GetOriginsWithForeignFetchRegistrations(&origins));
+ EXPECT_EQ(1U, origins.size());
+ EXPECT_TRUE(ContainsKey(origins, origin1));
+
+ // |origin1| should be removed from the foreign fetch origin list, since we
+ // replace its registration with one without scopes.
+ RegistrationData updated_data1 = data1;
+ updated_data1.version_id++;
+ updated_data1.resources_total_size_bytes = 12 + 13;
+ updated_data1.foreign_fetch_scopes.clear();
+ std::vector<Resource> updated_resources1;
+ updated_resources1.push_back(
+ CreateResource(13, URL(origin1, "/resource3"), 12));
+ updated_resources1.push_back(
+ CreateResource(14, URL(origin1, "/resource4"), 13));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(updated_data1, updated_resources1,
+ &deleted_version,
+ &newly_purgeable_resources));
+
+ origins.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->GetOriginsWithForeignFetchRegistrations(&origins));
+ EXPECT_EQ(0U, origins.size());
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_disk_cache.cc b/chromium/content/browser/service_worker/service_worker_disk_cache.cc
index 0fa1927c073..ef8f168f852 100644
--- a/chromium/content/browser/service_worker/service_worker_disk_cache.cc
+++ b/chromium/content/browser/service_worker/service_worker_disk_cache.cc
@@ -6,36 +6,22 @@
namespace content {
-scoped_ptr<ServiceWorkerDiskCache>
-ServiceWorkerDiskCache::CreateWithBlockFileBackend() {
- return make_scoped_ptr(
- new ServiceWorkerDiskCache(false /* use_simple_cache*/));
-}
-
-scoped_ptr<ServiceWorkerDiskCache>
-ServiceWorkerDiskCache::CreateWithSimpleBackend() {
- return make_scoped_ptr(
- new ServiceWorkerDiskCache(true /* use_simple_cache */));
-}
-
-ServiceWorkerDiskCache::ServiceWorkerDiskCache(bool use_simple_cache)
- : AppCacheDiskCache(use_simple_cache) {
-}
+ServiceWorkerDiskCache::ServiceWorkerDiskCache()
+ : AppCacheDiskCache(true /* use_simple_cache */) {}
ServiceWorkerResponseReader::ServiceWorkerResponseReader(
- int64 response_id, ServiceWorkerDiskCache* disk_cache)
- : AppCacheResponseReader(response_id, 0, disk_cache) {
-}
+ int64_t resource_id,
+ ServiceWorkerDiskCache* disk_cache)
+ : AppCacheResponseReader(resource_id, 0, disk_cache) {}
ServiceWorkerResponseWriter::ServiceWorkerResponseWriter(
- int64 response_id, ServiceWorkerDiskCache* disk_cache)
- : AppCacheResponseWriter(response_id, 0, disk_cache) {
-}
+ int64_t resource_id,
+ ServiceWorkerDiskCache* disk_cache)
+ : AppCacheResponseWriter(resource_id, 0, disk_cache) {}
ServiceWorkerResponseMetadataWriter::ServiceWorkerResponseMetadataWriter(
- int64 response_id,
+ int64_t resource_id,
ServiceWorkerDiskCache* disk_cache)
- : AppCacheResponseMetadataWriter(response_id, 0, disk_cache) {
-}
+ : AppCacheResponseMetadataWriter(resource_id, 0, disk_cache) {}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_disk_cache.h b/chromium/content/browser/service_worker/service_worker_disk_cache.h
index 19cb531fd2b..90f29bcb3f3 100644
--- a/chromium/content/browser/service_worker/service_worker_disk_cache.h
+++ b/chromium/content/browser/service_worker/service_worker_disk_cache.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_H_
+#include <stdint.h>
+
#include "content/browser/appcache/appcache_disk_cache.h"
#include "content/common/content_export.h"
@@ -19,47 +21,33 @@ namespace content {
class CONTENT_EXPORT ServiceWorkerDiskCache
: public AppCacheDiskCache {
public:
- static scoped_ptr<ServiceWorkerDiskCache> CreateWithBlockFileBackend();
- static scoped_ptr<ServiceWorkerDiskCache> CreateWithSimpleBackend();
-
- private:
- friend class ServiceWorkerDiskCacheMigrator;
- friend class ServiceWorkerDiskCacheMigratorTest;
- explicit ServiceWorkerDiskCache(bool use_simple_cache);
+ ServiceWorkerDiskCache();
};
class CONTENT_EXPORT ServiceWorkerResponseReader
: public AppCacheResponseReader {
protected:
// Should only be constructed by the storage class.
- friend class ServiceWorkerDiskCacheMigrator;
- friend class ServiceWorkerDiskCacheMigratorTest;
friend class ServiceWorkerStorage;
- ServiceWorkerResponseReader(
- int64 response_id,
- ServiceWorkerDiskCache* disk_cache);
+ ServiceWorkerResponseReader(int64_t resource_id,
+ ServiceWorkerDiskCache* disk_cache);
};
class CONTENT_EXPORT ServiceWorkerResponseWriter
: public AppCacheResponseWriter {
protected:
// Should only be constructed by the storage class.
- friend class ServiceWorkerDiskCacheMigrator;
- friend class ServiceWorkerDiskCacheMigratorTest;
friend class ServiceWorkerStorage;
- ServiceWorkerResponseWriter(
- int64 response_id,
- ServiceWorkerDiskCache* disk_cache);
+ ServiceWorkerResponseWriter(int64_t resource_id,
+ ServiceWorkerDiskCache* disk_cache);
};
class CONTENT_EXPORT ServiceWorkerResponseMetadataWriter
: public AppCacheResponseMetadataWriter {
protected:
// Should only be constructed by the storage class.
- friend class ServiceWorkerDiskCacheMigrator;
- friend class ServiceWorkerDiskCacheMigratorTest;
friend class ServiceWorkerStorage;
- ServiceWorkerResponseMetadataWriter(int64 response_id,
+ ServiceWorkerResponseMetadataWriter(int64_t resource_id,
ServiceWorkerDiskCache* disk_cache);
};
diff --git a/chromium/content/browser/service_worker/service_worker_disk_cache_migrator.cc b/chromium/content/browser/service_worker/service_worker_disk_cache_migrator.cc
deleted file mode 100644
index dfdfd539dc1..00000000000
--- a/chromium/content/browser/service_worker/service_worker_disk_cache_migrator.cc
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
-
-#include "base/barrier_closure.h"
-#include "base/files/file_util.h"
-#include "base/location.h"
-#include "base/memory/ref_counted.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/task_runner_util.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/disk_cache/disk_cache.h"
-
-namespace content {
-
-namespace {
-
-// Disk cache entry data indices (Copied from appcache_diskcache.cc).
-enum { kResponseInfoIndex, kResponseContentIndex, kResponseMetadataIndex };
-
-} // namespace
-
-// A task to move a cached resource from the src DiskCache to the dest
-// DiskCache. This is owned by ServiceWorkerDiskCacheMigrator.
-class ServiceWorkerDiskCacheMigrator::Task {
- public:
- using MigrationStatusCallback = base::Callback<void(MigrationStatus)>;
-
- Task(InflightTaskMap::KeyType task_id,
- int64 resource_id,
- int32 data_size,
- ServiceWorkerDiskCache* src,
- ServiceWorkerDiskCache* dest,
- const MigrationStatusCallback& callback);
- ~Task();
-
- void Run();
-
- InflightTaskMap::KeyType task_id() const { return task_id_; }
-
- private:
- void ReadResponseInfo();
- void OnReadResponseInfo(
- const scoped_refptr<HttpResponseInfoIOBuffer>& info_buffer,
- int result);
- void OnWriteResponseInfo(
- const scoped_refptr<HttpResponseInfoIOBuffer>& info_buffer,
- int result);
- void WriteResponseMetadata(
- const scoped_refptr<HttpResponseInfoIOBuffer>& info_buffer);
- void OnWriteResponseMetadata(
- const scoped_refptr<HttpResponseInfoIOBuffer>& info_buffer,
- int result);
- void ReadResponseData();
- void OnReadResponseData(const scoped_refptr<net::IOBuffer>& buffer,
- int result);
- void OnWriteResponseData(int result);
-
- InflightTaskMap::KeyType task_id_;
- int64 resource_id_;
- int32 data_size_;
- MigrationStatusCallback callback_;
-
- scoped_ptr<ServiceWorkerResponseReader> reader_;
- scoped_ptr<ServiceWorkerResponseWriter> writer_;
- scoped_ptr<ServiceWorkerResponseMetadataWriter> metadata_writer_;
-
- base::WeakPtrFactory<Task> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(Task);
-};
-
-// A wrapper class for disk_cache::Entry. This is used for holding an open entry
-// and ensuring that the entry gets closed on the dtor.
-class ServiceWorkerDiskCacheMigrator::WrappedEntry {
- public:
- WrappedEntry() {}
-
- ~WrappedEntry() {
- if (entry_)
- entry_->Close();
- }
-
- disk_cache::Entry* Unwrap() {
- disk_cache::Entry* entry = entry_;
- entry_ = nullptr;
- return entry;
- }
-
- disk_cache::Entry** GetPtr() { return &entry_; }
-
- private:
- disk_cache::Entry* entry_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(WrappedEntry);
-};
-
-ServiceWorkerDiskCacheMigrator::Task::Task(
- InflightTaskMap::KeyType task_id,
- int64 resource_id,
- int32 data_size,
- ServiceWorkerDiskCache* src,
- ServiceWorkerDiskCache* dest,
- const MigrationStatusCallback& callback)
- : task_id_(task_id),
- resource_id_(resource_id),
- data_size_(data_size),
- callback_(callback),
- weak_factory_(this) {
- DCHECK_LE(0, data_size_);
- reader_.reset(new ServiceWorkerResponseReader(resource_id, src));
- writer_.reset(new ServiceWorkerResponseWriter(resource_id, dest));
- metadata_writer_.reset(
- new ServiceWorkerResponseMetadataWriter(resource_id, dest));
-}
-
-ServiceWorkerDiskCacheMigrator::Task::~Task() {
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::Run() {
- ReadResponseInfo();
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::ReadResponseInfo() {
- scoped_refptr<HttpResponseInfoIOBuffer> info_buffer(
- new HttpResponseInfoIOBuffer);
- reader_->ReadInfo(info_buffer.get(),
- base::Bind(&Task::OnReadResponseInfo,
- weak_factory_.GetWeakPtr(), info_buffer));
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::OnReadResponseInfo(
- const scoped_refptr<HttpResponseInfoIOBuffer>& info_buffer,
- int result) {
- if (result < 0) {
- LOG(ERROR) << "Failed to read the response info";
- callback_.Run(MigrationStatus::ERROR_READ_RESPONSE_INFO);
- return;
- }
- writer_->WriteInfo(info_buffer.get(),
- base::Bind(&Task::OnWriteResponseInfo,
- weak_factory_.GetWeakPtr(), info_buffer));
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::OnWriteResponseInfo(
- const scoped_refptr<HttpResponseInfoIOBuffer>& buffer,
- int result) {
- if (result < 0) {
- LOG(ERROR) << "Failed to write the response info";
- callback_.Run(MigrationStatus::ERROR_WRITE_RESPONSE_INFO);
- return;
- }
-
- const net::HttpResponseInfo* http_info = buffer->http_info.get();
- if (http_info->metadata && http_info->metadata->size()) {
- WriteResponseMetadata(buffer);
- return;
- }
- ReadResponseData();
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::WriteResponseMetadata(
- const scoped_refptr<HttpResponseInfoIOBuffer>& info_buffer) {
- const net::HttpResponseInfo* http_info = info_buffer->http_info.get();
- DCHECK(http_info->metadata);
- DCHECK(http_info->metadata->size());
-
- // |wrapped_buffer| does not own the given metadata buffer, so a callback
- // for WriteMetadata keeps |info_buffer| which is the real owner of the
- // metadata buffer.
- scoped_refptr<net::WrappedIOBuffer> wrapped_buffer =
- new net::WrappedIOBuffer(http_info->metadata->data());
- metadata_writer_->WriteMetadata(
- wrapped_buffer.get(), http_info->metadata->size(),
- base::Bind(&Task::OnWriteResponseMetadata, weak_factory_.GetWeakPtr(),
- info_buffer));
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::OnWriteResponseMetadata(
- const scoped_refptr<HttpResponseInfoIOBuffer>& info_buffer,
- int result) {
- if (result < 0) {
- LOG(ERROR) << "Failed to write the response metadata";
- callback_.Run(MigrationStatus::ERROR_WRITE_RESPONSE_METADATA);
- return;
- }
- DCHECK_EQ(info_buffer->http_info->metadata->size(), result);
- ReadResponseData();
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::ReadResponseData() {
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_size_);
- reader_->ReadData(buffer.get(), data_size_,
- base::Bind(&Task::OnReadResponseData,
- weak_factory_.GetWeakPtr(), buffer));
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::OnReadResponseData(
- const scoped_refptr<net::IOBuffer>& buffer,
- int result) {
- if (result < 0) {
- LOG(ERROR) << "Failed to read the response data";
- callback_.Run(MigrationStatus::ERROR_READ_RESPONSE_DATA);
- return;
- }
- DCHECK_EQ(data_size_, result);
- writer_->WriteData(
- buffer.get(), result,
- base::Bind(&Task::OnWriteResponseData, weak_factory_.GetWeakPtr()));
-}
-
-void ServiceWorkerDiskCacheMigrator::Task::OnWriteResponseData(int result) {
- if (result < 0) {
- LOG(ERROR) << "Failed to write the response data";
- callback_.Run(MigrationStatus::ERROR_WRITE_RESPONSE_DATA);
- return;
- }
- DCHECK_EQ(data_size_, result);
- callback_.Run(MigrationStatus::OK);
-}
-
-ServiceWorkerDiskCacheMigrator::ServiceWorkerDiskCacheMigrator(
- const base::FilePath& src_path,
- const base::FilePath& dest_path,
- int max_disk_cache_size,
- const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread)
- : src_path_(src_path),
- dest_path_(dest_path),
- max_disk_cache_size_(max_disk_cache_size),
- disk_cache_thread_(disk_cache_thread),
- weak_factory_(this) {
-}
-
-ServiceWorkerDiskCacheMigrator::~ServiceWorkerDiskCacheMigrator() {
-}
-
-void ServiceWorkerDiskCacheMigrator::Start(const StatusCallback& callback) {
- callback_ = callback;
- start_time_ = base::TimeTicks::Now();
-
-#if defined(OS_ANDROID)
- PostTaskAndReplyWithResult(
- disk_cache_thread_.get(), FROM_HERE,
- base::Bind(&MigrateForAndroid, src_path_, dest_path_),
- base::Bind(&ServiceWorkerDiskCacheMigrator::Complete,
- weak_factory_.GetWeakPtr()));
-#else
- PostTaskAndReplyWithResult(
- disk_cache_thread_.get(), FROM_HERE,
- base::Bind(&base::DeleteFile, dest_path_, true),
- base::Bind(&ServiceWorkerDiskCacheMigrator::DidDeleteDestDirectory,
- weak_factory_.GetWeakPtr()));
-#endif // defined(OS_ANDROID)
-}
-
-#if defined(OS_ANDROID)
-// static
-ServiceWorkerDiskCacheMigrator::MigrationStatus
-ServiceWorkerDiskCacheMigrator::MigrateForAndroid(
- const base::FilePath& src_path,
- const base::FilePath& dest_path) {
- // Continue the migration regardless of the deletion result. If the migrator
- // cannot proceed or the diskcache gets corrupted due to the failure, the
- // storage detects it and recovers by DeleteAndStartOver.
- base::DeleteFile(dest_path, true);
-
- if (!base::DirectoryExists(src_path))
- return MigrationStatus::OK;
-
- // Android has alredy used the Simple backend. Just move the existing
- // diskcache files to a new location.
- if (base::Move(src_path, dest_path))
- return MigrationStatus::OK;
- return MigrationStatus::ERROR_MOVE_DISKCACHE;
-}
-#endif // defined(OS_ANDROID)
-
-void ServiceWorkerDiskCacheMigrator::DidDeleteDestDirectory(bool deleted) {
- // Continue the migration regardless of the deletion result. If the migrator
- // cannot proceed or the diskcache gets corrupted due to the failure, the
- // storage detects it and recovers by DeleteAndStartOver.
-
- src_ = ServiceWorkerDiskCache::CreateWithBlockFileBackend();
- dest_ = ServiceWorkerDiskCache::CreateWithSimpleBackend();
-
- scoped_ptr<MigrationStatus> status(new MigrationStatus(MigrationStatus::OK));
- MigrationStatus* status_ptr = status.get();
-
- // This closure is called when both diskcaches are initialized.
- base::Closure barrier_closure = base::BarrierClosure(
- 2, base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeAllDiskCaches,
- weak_factory_.GetWeakPtr(), base::Passed(status.Pass())));
-
- // Initialize the src DiskCache. |status_ptr| is guaranteed to be valid until
- // calling |barrier_closure| which is the owner of the object.
- net::CompletionCallback src_callback =
- base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeSrcDiskCache,
- weak_factory_.GetWeakPtr(), barrier_closure, status_ptr);
- int result = src_->InitWithDiskBackend(src_path_, max_disk_cache_size_,
- false /* force */, disk_cache_thread_,
- src_callback);
- if (result != net::ERR_IO_PENDING)
- src_callback.Run(result);
-
- // Initialize the dest DiskCache. |status_ptr| is guaranteed to be valid until
- // calling |barrier_closure| which is the owner of the object.
- net::CompletionCallback dest_callback =
- base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeDestDiskCache,
- weak_factory_.GetWeakPtr(), barrier_closure, status_ptr);
- result = dest_->InitWithDiskBackend(dest_path_, max_disk_cache_size_,
- false /* force */, disk_cache_thread_,
- dest_callback);
- if (result != net::ERR_IO_PENDING)
- dest_callback.Run(result);
-}
-
-void ServiceWorkerDiskCacheMigrator::DidInitializeSrcDiskCache(
- const base::Closure& barrier_closure,
- MigrationStatus* status_ptr,
- int result) {
- if (result != net::OK)
- *status_ptr = MigrationStatus::ERROR_INIT_SRC_DISKCACHE;
- barrier_closure.Run();
-}
-
-void ServiceWorkerDiskCacheMigrator::DidInitializeDestDiskCache(
- const base::Closure& barrier_closure,
- MigrationStatus* status_ptr,
- int result) {
- if (result != net::OK)
- *status_ptr = MigrationStatus::ERROR_INIT_DEST_DISKCACHE;
- barrier_closure.Run();
-}
-
-void ServiceWorkerDiskCacheMigrator::DidInitializeAllDiskCaches(
- scoped_ptr<MigrationStatus> status) {
- if (*status != MigrationStatus::OK) {
- LOG(ERROR) << "Failed to initialize the diskcache";
- Complete(*status);
- return;
- }
-
- // Iterate through existing entries in the src DiskCache.
- iterator_ = src_->disk_cache()->CreateIterator();
- OpenNextEntry();
-}
-
-void ServiceWorkerDiskCacheMigrator::OpenNextEntry() {
- DCHECK(!pending_task_);
- DCHECK(!is_iterating_);
- is_iterating_ = true;
-
- scoped_ptr<WrappedEntry> wrapped_entry(new WrappedEntry);
- disk_cache::Entry** entry_ptr = wrapped_entry->GetPtr();
-
- net::CompletionCallback callback = base::Bind(
- &ServiceWorkerDiskCacheMigrator::OnNextEntryOpened,
- weak_factory_.GetWeakPtr(), base::Passed(wrapped_entry.Pass()));
- int result = iterator_->OpenNextEntry(entry_ptr, callback);
- if (result == net::ERR_IO_PENDING)
- return;
- callback.Run(result);
-}
-
-void ServiceWorkerDiskCacheMigrator::OnNextEntryOpened(
- scoped_ptr<WrappedEntry> wrapped_entry,
- int result) {
- DCHECK(!pending_task_);
- is_iterating_ = false;
-
- if (result == net::ERR_FAILED) {
- // ERR_FAILED means the iterator reached the end of the enumeration.
- if (inflight_tasks_.IsEmpty())
- Complete(MigrationStatus::OK);
- return;
- }
-
- if (result != net::OK) {
- LOG(ERROR) << "Failed to open the next entry";
- inflight_tasks_.Clear();
- Complete(MigrationStatus::ERROR_OPEN_NEXT_ENTRY);
- return;
- }
-
- disk_cache::ScopedEntryPtr scoped_entry(wrapped_entry->Unwrap());
- DCHECK(scoped_entry);
-
- int64 resource_id = kInvalidServiceWorkerResourceId;
- if (!base::StringToInt64(scoped_entry->GetKey(), &resource_id)) {
- LOG(ERROR) << "Failed to read the resource id";
- inflight_tasks_.Clear();
- Complete(MigrationStatus::ERROR_READ_ENTRY_KEY);
- return;
- }
-
- InflightTaskMap::KeyType task_id = next_task_id_++;
- pending_task_.reset(new Task(
- task_id, resource_id, scoped_entry->GetDataSize(kResponseContentIndex),
- src_.get(), dest_.get(),
- base::Bind(&ServiceWorkerDiskCacheMigrator::OnEntryMigrated,
- weak_factory_.GetWeakPtr(), task_id)));
- if (inflight_tasks_.size() < max_number_of_inflight_tasks_) {
- RunPendingTask();
- OpenNextEntry();
- return;
- }
- // |pending_task_| will run when an inflight task is completed.
-}
-
-void ServiceWorkerDiskCacheMigrator::RunPendingTask() {
- DCHECK(pending_task_);
- DCHECK_GT(max_number_of_inflight_tasks_, inflight_tasks_.size());
- InflightTaskMap::KeyType task_id = pending_task_->task_id();
- pending_task_->Run();
- inflight_tasks_.AddWithID(pending_task_.release(), task_id);
-}
-
-void ServiceWorkerDiskCacheMigrator::OnEntryMigrated(
- InflightTaskMap::KeyType task_id,
- MigrationStatus status) {
- DCHECK(inflight_tasks_.Lookup(task_id));
- inflight_tasks_.Remove(task_id);
-
- if (status != MigrationStatus::OK) {
- inflight_tasks_.Clear();
- pending_task_.reset();
- Complete(status);
- return;
- }
-
- ++number_of_migrated_resources_;
-
- if (pending_task_) {
- RunPendingTask();
- OpenNextEntry();
- return;
- }
-
- if (is_iterating_)
- return;
-
- if (inflight_tasks_.IsEmpty())
- Complete(MigrationStatus::OK);
-}
-
-void ServiceWorkerDiskCacheMigrator::Complete(MigrationStatus status) {
- DCHECK(inflight_tasks_.IsEmpty());
- DCHECK(!pending_task_);
-
- if (status == MigrationStatus::OK) {
- RecordMigrationTime(base::TimeTicks().Now() - start_time_);
- RecordNumberOfMigratedResources(number_of_migrated_resources_);
- }
- RecordMigrationResult(status);
-
- // Invalidate weakptrs to ensure that other running operations do not call
- // OnEntryMigrated().
- weak_factory_.InvalidateWeakPtrs();
-
- // Use PostTask to avoid deleting AppCacheDiskCache in the middle of the
- // execution (see http://crbug.com/502420).
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&ServiceWorkerDiskCacheMigrator::RunUserCallback,
- weak_factory_.GetWeakPtr(),
- status == MigrationStatus::OK ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_FAILED));
-}
-
-void ServiceWorkerDiskCacheMigrator::RunUserCallback(
- ServiceWorkerStatusCode status) {
- src_.reset();
- dest_.reset();
- callback_.Run(status);
-}
-
-void ServiceWorkerDiskCacheMigrator::RecordMigrationResult(
- MigrationStatus status) {
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.DiskCacheMigrator.MigrationResult",
- static_cast<int>(status),
- static_cast<int>(MigrationStatus::NUM_TYPES));
-}
-
-void ServiceWorkerDiskCacheMigrator::RecordNumberOfMigratedResources(
- size_t migrated_resources) {
- UMA_HISTOGRAM_COUNTS_1000(
- "ServiceWorker.DiskCacheMigrator.NumberOfMigratedResources",
- migrated_resources);
-}
-
-void ServiceWorkerDiskCacheMigrator::RecordMigrationTime(
- const base::TimeDelta& time) {
- UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.DiskCacheMigrator.MigrationTime",
- time);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_disk_cache_migrator.h b/chromium/content/browser/service_worker/service_worker_disk_cache_migrator.h
deleted file mode 100644
index 46fce297734..00000000000
--- a/chromium/content/browser/service_worker/service_worker_disk_cache_migrator.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_MIGRATOR_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_MIGRATOR_H_
-
-#include "content/browser/service_worker/service_worker_disk_cache.h"
-
-#include "base/gtest_prod_util.h"
-#include "base/id_map.h"
-#include "base/memory/scoped_ptr.h"
-#include "content/browser/service_worker/service_worker_database.h"
-#include "content/common/service_worker/service_worker_status_code.h"
-
-namespace content {
-
-// This is used for migrating the ServiceWorkerDiskCache from the BlockFile
-// backend to the Simple backend. The migrator iterates over resources in the
-// src DiskCache and copies them into the dest DiskCache one by one. This does
-// not delete the resources in the src DiskCache.
-//
-// TODO(nhiroki): Remove this migrator after several milestones pass
-// (http://crbug.com/487482)
-class CONTENT_EXPORT ServiceWorkerDiskCacheMigrator {
- public:
- using StatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
-
- ServiceWorkerDiskCacheMigrator(
- const base::FilePath& src_path,
- const base::FilePath& dest_path,
- int max_disk_cache_size,
- const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread);
- ~ServiceWorkerDiskCacheMigrator();
-
- // Returns SERVICE_WORKER_OK if all resources are successfully migrated. The
- // caller should delete the src DiskCache after migration.
- void Start(const StatusCallback& callback);
-
- private:
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest,
- ThrottleInflightTasks);
-
- class Task;
- class WrappedEntry;
-
- using InflightTaskMap = IDMap<Task, IDMapOwnPointer>;
-
- // Used for UMA. Append only.
- enum class MigrationStatus {
- OK = 0,
- ERROR_FAILED = 1, // unused, for backwards compatibility.
- ERROR_MOVE_DISKCACHE = 2,
- ERROR_INIT_SRC_DISKCACHE = 3,
- ERROR_INIT_DEST_DISKCACHE = 4,
- ERROR_OPEN_NEXT_ENTRY = 5,
- ERROR_READ_ENTRY_KEY = 6,
- ERROR_READ_RESPONSE_INFO = 7,
- ERROR_WRITE_RESPONSE_INFO = 8,
- ERROR_WRITE_RESPONSE_METADATA = 9,
- ERROR_READ_RESPONSE_DATA = 10,
- ERROR_WRITE_RESPONSE_DATA = 11,
- NUM_TYPES,
- };
-
-#if defined(OS_ANDROID)
- static MigrationStatus MigrateForAndroid(const base::FilePath& src_path,
- const base::FilePath& dest_path);
-#endif // defined(OS_ANDROID)
-
- void DidDeleteDestDirectory(bool deleted);
- void DidInitializeSrcDiskCache(const base::Closure& barrier_closure,
- MigrationStatus* status_ptr,
- int result);
- void DidInitializeDestDiskCache(const base::Closure& barrier_closure,
- MigrationStatus* status_ptr,
- int result);
- void DidInitializeAllDiskCaches(scoped_ptr<MigrationStatus> status);
-
- void OpenNextEntry();
- void OnNextEntryOpened(scoped_ptr<WrappedEntry> entry, int result);
- void RunPendingTask();
- void OnEntryMigrated(InflightTaskMap::KeyType task_id,
- MigrationStatus status);
- void Complete(MigrationStatus status);
- void RunUserCallback(ServiceWorkerStatusCode status);
-
- void RecordMigrationResult(MigrationStatus status);
- void RecordNumberOfMigratedResources(size_t migrated_resources);
- void RecordMigrationTime(const base::TimeDelta& time);
-
- void set_max_number_of_inflight_tasks(size_t max_number) {
- max_number_of_inflight_tasks_ = max_number;
- }
-
- scoped_ptr<disk_cache::Backend::Iterator> iterator_;
- bool is_iterating_ = false;
-
- base::FilePath src_path_;
- base::FilePath dest_path_;
- scoped_ptr<ServiceWorkerDiskCache> src_;
- scoped_ptr<ServiceWorkerDiskCache> dest_;
- const int max_disk_cache_size_;
- scoped_refptr<base::SingleThreadTaskRunner> disk_cache_thread_;
-
- InflightTaskMap::KeyType next_task_id_ = 0;
- InflightTaskMap inflight_tasks_;
- scoped_ptr<Task> pending_task_;
- size_t max_number_of_inflight_tasks_ = 10;
-
- base::TimeTicks start_time_;
- size_t number_of_migrated_resources_ = 0;
-
- StatusCallback callback_;
-
- base::WeakPtrFactory<ServiceWorkerDiskCacheMigrator> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDiskCacheMigrator);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_MIGRATOR_H_
diff --git a/chromium/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc b/chromium/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc
deleted file mode 100644
index 12e0995c453..00000000000
--- a/chromium/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
-
-#include <string>
-#include <vector>
-
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/thread_task_runner_handle.h"
-#include "content/browser/service_worker/service_worker_context_core.h"
-#include "content/browser/service_worker/service_worker_storage.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/base/test_completion_callback.h"
-#include "net/http/http_response_headers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-const int kMaxDiskCacheSize = 250 * 1024 * 1024;
-
-struct ResponseData {
- int64 resource_id;
- std::string headers;
- std::string body;
- std::string metadata;
-
- ResponseData(int64 resource_id,
- const std::string& headers,
- const std::string& body,
- const std::string& metadata)
- : resource_id(resource_id),
- headers(headers),
- body(body),
- metadata(metadata) {}
-};
-
-void OnDiskCacheMigrated(const base::Closure& callback,
- ServiceWorkerStatusCode status) {
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- callback.Run();
-}
-
-void OnRegistrationFound(
- const base::Closure& callback,
- ServiceWorkerStatusCode status,
- const scoped_refptr<ServiceWorkerRegistration>& registration) {
- callback.Run();
-}
-
-} // namespace
-
-class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
- public:
- ServiceWorkerDiskCacheMigratorTest()
- : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
-
- void SetUp() override {
- ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir());
- scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
- new MockServiceWorkerDatabaseTaskManager(
- base::ThreadTaskRunnerHandle::Get()));
-
- context_.reset(new ServiceWorkerContextCore(
- user_data_directory_.path(), database_task_manager.Pass(),
- base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr, nullptr,
- nullptr));
- }
-
- void TearDown() override {
- context_.reset();
- base::RunLoop().RunUntilIdle();
- }
-
- scoped_ptr<ServiceWorkerDiskCache> CreateSrcDiskCache() {
-#if defined(OS_ANDROID)
- // Android has already used the Simple backend.
- scoped_ptr<ServiceWorkerDiskCache> src(
- ServiceWorkerDiskCache::CreateWithSimpleBackend());
-#else
- scoped_ptr<ServiceWorkerDiskCache> src(
- ServiceWorkerDiskCache::CreateWithBlockFileBackend());
-#endif // defined(OS_ANDROID)
-
- net::TestCompletionCallback cb;
- src->InitWithDiskBackend(
- storage()->GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */,
- base::ThreadTaskRunnerHandle::Get(), cb.callback());
- EXPECT_EQ(net::OK, cb.WaitForResult());
- return src.Pass();
- }
-
- scoped_ptr<ServiceWorkerDiskCache> CreateDestDiskCache() {
- scoped_ptr<ServiceWorkerDiskCache> dest(
- ServiceWorkerDiskCache::CreateWithSimpleBackend());
- net::TestCompletionCallback cb;
- dest->InitWithDiskBackend(
- storage()->GetDiskCachePath(), kMaxDiskCacheSize, false /* force */,
- base::ThreadTaskRunnerHandle::Get(), cb.callback());
- EXPECT_EQ(net::OK, cb.WaitForResult());
- return dest.Pass();
- }
-
- scoped_ptr<ServiceWorkerDiskCacheMigrator> CreateMigrator() {
- return make_scoped_ptr(new ServiceWorkerDiskCacheMigrator(
- storage()->GetOldDiskCachePath(), storage()->GetDiskCachePath(),
- kMaxDiskCacheSize, base::ThreadTaskRunnerHandle::Get()));
- }
-
- bool WriteResponse(ServiceWorkerDiskCache* disk_cache,
- const ResponseData& response) {
- scoped_ptr<ServiceWorkerResponseWriter> writer(
- new ServiceWorkerResponseWriter(response.resource_id, disk_cache));
-
- // Write the response info.
- scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
- info->request_time = base::Time() + base::TimeDelta::FromSeconds(10);
- info->response_time = info->request_time + base::TimeDelta::FromSeconds(10);
- info->was_cached = false;
- info->headers = new net::HttpResponseHeaders(response.headers);
- scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
- new HttpResponseInfoIOBuffer(info.release());
- net::TestCompletionCallback cb1;
- writer->WriteInfo(info_buffer.get(), cb1.callback());
- int rv = cb1.WaitForResult();
- EXPECT_LT(0, rv);
- if (rv < 0)
- return false;
-
- // Write the response metadata.
- scoped_ptr<ServiceWorkerResponseMetadataWriter> metadata_writer(
- new ServiceWorkerResponseMetadataWriter(response.resource_id,
- disk_cache));
- scoped_refptr<net::IOBuffer> metadata_buffer(
- new net::WrappedIOBuffer(response.metadata.data()));
- const int metadata_length = response.metadata.length();
- net::TestCompletionCallback cb2;
- metadata_writer->WriteMetadata(metadata_buffer.get(), metadata_length,
- cb2.callback());
- rv = cb2.WaitForResult();
- EXPECT_EQ(metadata_length, rv);
- if (metadata_length != rv)
- return false;
-
- // Write the response body.
- scoped_refptr<net::IOBuffer> body_buffer(
- new net::WrappedIOBuffer(response.body.data()));
- const int body_length = response.body.length();
- net::TestCompletionCallback cb3;
- writer->WriteData(body_buffer.get(), body_length, cb3.callback());
- rv = cb3.WaitForResult();
- EXPECT_EQ(body_length, rv);
- if (body_length != rv)
- return false;
-
- return true;
- }
-
- void VerifyResponse(ServiceWorkerDiskCache* disk_cache,
- const ResponseData& expected) {
- scoped_ptr<ServiceWorkerResponseReader> reader(
- new ServiceWorkerResponseReader(expected.resource_id, disk_cache));
-
- // Verify the response info.
- scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
- new HttpResponseInfoIOBuffer;
- net::TestCompletionCallback cb1;
- reader->ReadInfo(info_buffer.get(), cb1.callback());
- int rv = cb1.WaitForResult();
- EXPECT_LT(0, rv);
- ASSERT_TRUE(info_buffer->http_info);
- ASSERT_TRUE(info_buffer->http_info->headers);
- EXPECT_EQ("OK", info_buffer->http_info->headers->GetStatusText());
-
- // Verify the response metadata.
- if (!expected.metadata.empty()) {
- ASSERT_TRUE(info_buffer->http_info->metadata);
- const int data_size = info_buffer->http_info->metadata->size();
- ASSERT_EQ(static_cast<int>(expected.metadata.length()), data_size);
- EXPECT_EQ(0, memcmp(expected.metadata.data(),
- info_buffer->http_info->metadata->data(),
- expected.metadata.length()));
- }
-
- // Verify the response body.
- const int kBigEnough = 512;
- scoped_refptr<net::IOBuffer> body_buffer = new net::IOBuffer(kBigEnough);
- net::TestCompletionCallback cb2;
- reader->ReadData(body_buffer.get(), kBigEnough, cb2.callback());
- rv = cb2.WaitForResult();
- ASSERT_EQ(static_cast<int>(expected.body.length()), rv);
- EXPECT_EQ(0, memcmp(expected.body.data(), body_buffer->data(), rv));
- }
-
- int32 GetEntryCount(ServiceWorkerDiskCache* disk_cache) {
- return disk_cache->disk_cache()->GetEntryCount();
- }
-
- ServiceWorkerStorage* storage() { return context_->storage(); }
-
- private:
- TestBrowserThreadBundle browser_thread_bundle_;
- base::ScopedTempDir user_data_directory_;
-
- scoped_ptr<ServiceWorkerContextCore> context_;
-};
-
-TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateDiskCache) {
- std::vector<ResponseData> responses;
- responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
- responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
- responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
- responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
- responses.push_back(ResponseData(10, "HTTP/1.1 200 OK\0\0", "", "meta"));
- responses.push_back(ResponseData(11, "HTTP/1.1 200 OK\0\0", "body", ""));
- responses.push_back(ResponseData(12, "HTTP/1.1 200 OK\0\0", "", ""));
- responses.push_back(ResponseData(
- 20, "HTTP/1.1 200 OK\0\0", std::string(256, 'a'), std::string(128, 'b')));
-
- // Populate initial data in the src diskcache.
- scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
- for (const ResponseData& response : responses) {
- ASSERT_TRUE(WriteResponse(src.get(), response));
- VerifyResponse(src.get(), response);
- }
- ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
- src.reset();
-
- // Start the migrator.
- base::RunLoop run_loop;
- scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
- migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
- run_loop.Run();
-
- // Verify the migrated contents in the dest diskcache.
- scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
- for (const ResponseData& response : responses)
- VerifyResponse(dest.get(), response);
- EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest.get()));
-}
-
-TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateEmptyDiskCache) {
- scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
- ASSERT_EQ(0, GetEntryCount(src.get()));
- src.reset();
-
- // Start the migrator.
- base::RunLoop run_loop;
- scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
- migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
- run_loop.Run();
-
- scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
- ASSERT_EQ(0, GetEntryCount(dest.get()));
-}
-
-// Tests that the migrator properly removes existing resources in the dest
-// diskcache before starting the migration.
-TEST_F(ServiceWorkerDiskCacheMigratorTest, RemoveExistingResourcesFromDest) {
- std::vector<ResponseData> responses1;
- responses1.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
- responses1.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", ""));
-
- std::vector<ResponseData> responses2;
- responses2.push_back(ResponseData(10, "HTTP/1.1 200 OK\0\0", "Hello", ""));
- responses2.push_back(ResponseData(11, "HTTP/1.1 200 OK\0\0", "Service", ""));
- responses2.push_back(ResponseData(12, "HTTP/1.1 200 OK\0\0", "", "Worker"));
-
- // Populate initial resources in the src diskcache.
- scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
- for (const ResponseData& response : responses1) {
- ASSERT_TRUE(WriteResponse(src.get(), response));
- VerifyResponse(src.get(), response);
- }
- ASSERT_EQ(static_cast<int>(responses1.size()), GetEntryCount(src.get()));
- src.reset();
-
- // Populate different resources in the dest diskcache in order to simulate
- // a previous partial migration.
- scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
- for (const ResponseData& response : responses2) {
- ASSERT_TRUE(WriteResponse(dest.get(), response));
- VerifyResponse(dest.get(), response);
- }
- ASSERT_EQ(static_cast<int>(responses2.size()), GetEntryCount(dest.get()));
- dest.reset();
-
- // Start the migrator.
- base::RunLoop run_loop;
- scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
- migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
- run_loop.Run();
-
- // Verify that only newly migrated resources exist in the dest diskcache.
- dest = CreateDestDiskCache();
- for (const ResponseData& response : responses1)
- VerifyResponse(dest.get(), response);
- EXPECT_EQ(static_cast<int>(responses1.size()), GetEntryCount(dest.get()));
-}
-
-TEST_F(ServiceWorkerDiskCacheMigratorTest, ThrottleInflightTasks) {
- std::vector<ResponseData> responses;
- for (int i = 0; i < 10; ++i)
- responses.push_back(ResponseData(i, "HTTP/1.1 200 OK\0\0", "foo", "bar"));
-
- // Populate initial data in the src diskcache.
- scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
- for (const ResponseData& response : responses) {
- ASSERT_TRUE(WriteResponse(src.get(), response));
- VerifyResponse(src.get(), response);
- }
- ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
- src.reset();
-
- scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
-
- // Tighten the max number of inflight tasks.
- migrator->set_max_number_of_inflight_tasks(2);
-
- // Migration should hit the limit, but should successfully complete.
- base::RunLoop run_loop;
- migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
- run_loop.Run();
-
- // Verify the migrated contents in the dest diskcache.
- scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
- for (const ResponseData& response : responses)
- VerifyResponse(dest.get(), response);
- EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest.get()));
-}
-
-TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateOnDiskCacheAccess) {
- std::vector<ResponseData> responses;
- responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
- responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
- responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
- responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
-
- // Populate initial resources in the src diskcache.
- scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
- for (const ResponseData& response : responses) {
- ASSERT_TRUE(WriteResponse(src.get(), response));
- VerifyResponse(src.get(), response);
- }
- ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
- ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
- src.reset();
-
- scoped_ptr<ServiceWorkerDatabase> database(
- new ServiceWorkerDatabase(storage()->GetDatabasePath()));
-
- // This is necessary to make the storage schedule diskcache migration.
- database->set_skip_writing_diskcache_migration_state_on_init_for_testing();
-
- // Simulate an existing database.
- std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
- resources.push_back(ServiceWorkerDatabase::ResourceRecord(
- 1, GURL("https://example.com/foo"), 10));
- ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
- ServiceWorkerDatabase::RegistrationData data;
- data.registration_id = 100;
- data.scope = GURL("https://example.com/");
- data.script = GURL("https://example.com/script.js");
- data.version_id = 200;
- data.resources_total_size_bytes = 10;
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(data, resources, &deleted_version,
- &newly_purgeable_resources));
- database.reset();
-
- // LazyInitialize() reads initial data and should schedule to migrate.
- ASSERT_FALSE(storage()->disk_cache_migration_needed_);
- base::RunLoop run_loop;
- storage()->LazyInitialize(run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_TRUE(storage()->disk_cache_migration_needed_);
-
- // DiskCache access should start the migration.
- ServiceWorkerDiskCache* dest = storage()->disk_cache();
-
- // Verify the migrated contents in the dest diskcache.
- for (const ResponseData& response : responses)
- VerifyResponse(dest, response);
- EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest));
-
- // After the migration, the src diskcache should be deleted.
- EXPECT_FALSE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
-
- // After the migration, the migration state should be updated.
- bool migration_needed = false;
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_OK,
- storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
- EXPECT_FALSE(migration_needed);
- bool deletion_needed = false;
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_OK,
- storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
- EXPECT_FALSE(deletion_needed);
-}
-
-TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateOnDatabaseAccess) {
- std::vector<ResponseData> responses;
- responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
- responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
- responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
- responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
-
- // Populate initial resources in the src diskcache.
- scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
- for (const ResponseData& response : responses) {
- ASSERT_TRUE(WriteResponse(src.get(), response));
- VerifyResponse(src.get(), response);
- }
- ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
- ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
-
- scoped_ptr<ServiceWorkerDatabase> database(
- new ServiceWorkerDatabase(storage()->GetDatabasePath()));
-
- // This is necessary to make the storage schedule diskcache migration.
- database->set_skip_writing_diskcache_migration_state_on_init_for_testing();
-
- // Simulate an existing database.
- std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
- resources.push_back(ServiceWorkerDatabase::ResourceRecord(
- 1, GURL("https://example.com/foo"), 10));
- ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
- ServiceWorkerDatabase::RegistrationData data;
- data.registration_id = 100;
- data.scope = GURL("https://example.com/");
- data.script = GURL("https://example.com/script.js");
- data.version_id = 200;
- data.resources_total_size_bytes = 10;
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(data, resources, &deleted_version,
- &newly_purgeable_resources));
- database.reset();
-
- // LazyInitialize() reads initial data and should schedule to migrate.
- ASSERT_FALSE(storage()->disk_cache_migration_needed_);
- base::RunLoop run_loop1;
- storage()->LazyInitialize(run_loop1.QuitClosure());
- run_loop1.Run();
- EXPECT_TRUE(storage()->disk_cache_migration_needed_);
-
- // Database access should not start the migration.
- base::RunLoop run_loop2;
- storage()->FindRegistrationForDocument(
- GURL("http://example.com/"),
- base::Bind(&OnRegistrationFound, run_loop2.QuitClosure()));
- run_loop2.Run();
-
- // Verify that the migration didn't happen.
- scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
- EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
- EXPECT_EQ(0, GetEntryCount(dest.get()));
- EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
-}
-
-TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateForEmptyDatabase) {
- std::vector<ResponseData> responses;
- responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
- responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
- responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
- responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
-
- // Populate initial resources in the src diskcache.
- scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
- for (const ResponseData& response : responses) {
- ASSERT_TRUE(WriteResponse(src.get(), response));
- VerifyResponse(src.get(), response);
- }
- ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
- ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
- src.reset();
-
- // LazyInitialize() reads initial data and should not schedule to migrate
- // because the database is empty.
- ASSERT_FALSE(storage()->disk_cache_migration_needed_);
- base::RunLoop run_loop;
- storage()->LazyInitialize(run_loop.QuitClosure());
- run_loop.Run();
- EXPECT_FALSE(storage()->disk_cache_migration_needed_);
-
- // DiskCache access should not start the migration.
- ServiceWorkerDiskCache* dest = storage()->disk_cache();
-
- // Verify that the migration didn't happen.
- src = CreateSrcDiskCache();
- for (const ResponseData& response : responses)
- VerifyResponse(src.get(), response);
- EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
- EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
- EXPECT_EQ(0, GetEntryCount(dest));
-
- // Write a registration into the database to start database initialization.
- std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
- resources.push_back(ServiceWorkerDatabase::ResourceRecord(
- 1, GURL("https://example.com/foo"), 10));
- ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
- ServiceWorkerDatabase::RegistrationData data;
- data.registration_id = 100;
- data.scope = GURL("https://example.com/");
- data.script = GURL("https://example.com/script.js");
- data.version_id = 200;
- data.resources_total_size_bytes = 10;
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- storage()->database_->WriteRegistration(
- data, resources, &deleted_version, &newly_purgeable_resources));
-
- // After the database initialization, the migration state should be
- // initialized.
- bool migration_needed = false;
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_OK,
- storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
- EXPECT_FALSE(migration_needed);
- bool deletion_needed = false;
- EXPECT_EQ(
- ServiceWorkerDatabase::STATUS_OK,
- storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
-
- // The deletion flag should be set for the case that the database is empty but
- // the old diskcache exists.
- EXPECT_TRUE(deletion_needed);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc b/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
index c192d96e371..f8d80e08730 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -4,7 +4,10 @@
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
+#include <utility>
+
#include "base/logging.h"
+#include "base/macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
@@ -15,6 +18,7 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_handle.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_registration_handle.h"
#include "content/common/service_worker/embedded_worker_messages.h"
@@ -22,6 +26,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/origin_util.h"
#include "ipc/ipc_message_macros.h"
@@ -43,9 +48,8 @@ const char kUserDeniedPermissionMessage[] =
"The user denied permission to use Service Worker.";
const char kInvalidStateErrorMessage[] = "The object is in an invalid state.";
-const uint32 kFilteredMessageClasses[] = {
- ServiceWorkerMsgStart,
- EmbeddedWorkerMsgStart,
+const uint32_t kFilteredMessageClasses[] = {
+ ServiceWorkerMsgStart, EmbeddedWorkerMsgStart,
};
bool AllOriginsMatch(const GURL& url_a, const GURL& url_b, const GURL& url_c) {
@@ -134,10 +138,10 @@ void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender* sender) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerDispatcherHost::OnFilterAdded");
channel_ready_ = true;
- std::vector<IPC::Message*> messages;
- pending_messages_.release(&messages);
- for (size_t i = 0; i < messages.size(); ++i) {
- BrowserMessageFilter::Send(messages[i]);
+ std::vector<scoped_ptr<IPC::Message>> messages;
+ messages.swap(pending_messages_);
+ for (auto& message : messages) {
+ BrowserMessageFilter::Send(message.release());
}
}
@@ -228,7 +232,7 @@ bool ServiceWorkerDispatcherHost::Send(IPC::Message* message) {
return true;
}
- pending_messages_.push_back(message);
+ pending_messages_.push_back(make_scoped_ptr(message));
return true;
}
@@ -246,7 +250,7 @@ void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
ServiceWorkerHandle* ServiceWorkerDispatcherHost::FindServiceWorkerHandle(
int provider_id,
- int64 version_id) {
+ int64_t version_id) {
for (IDMap<ServiceWorkerHandle, IDMapOwnPointer>::iterator iter(&handles_);
!iter.IsAtEnd(); iter.Advance()) {
ServiceWorkerHandle* handle = iter.GetCurrentValue();
@@ -276,7 +280,7 @@ ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
new ServiceWorkerRegistrationHandle(GetContext()->AsWeakPtr(),
provider_host, registration));
ServiceWorkerRegistrationHandle* new_handle_ptr = new_handle.get();
- RegisterServiceWorkerRegistrationHandle(new_handle.Pass());
+ RegisterServiceWorkerRegistrationHandle(std::move(new_handle));
return new_handle_ptr;
}
@@ -364,10 +368,11 @@ void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
request_id));
}
-void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int thread_id,
- int request_id,
- int provider_id,
- int64 registration_id) {
+void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(
+ int thread_id,
+ int request_id,
+ int provider_id,
+ int64_t registration_id) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerDispatcherHost::OnUpdateServiceWorker");
if (!GetContext()) {
@@ -437,10 +442,8 @@ void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int thread_id,
return;
}
- // The spec says, "update() pings the server for an updated version of this
- // script without consulting caches", so set |force_bypass_cache| to true.
GetContext()->UpdateServiceWorker(
- registration, true /* force_bypass_cache */,
+ registration, false /* force_bypass_cache */,
false /* skip_script_comparison */, provider_host,
base::Bind(&ServiceWorkerDispatcherHost::UpdateComplete, this, thread_id,
provider_id, request_id));
@@ -450,7 +453,7 @@ void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
int thread_id,
int request_id,
int provider_id,
- int64 registration_id) {
+ int64_t registration_id) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
if (!GetContext()) {
@@ -735,11 +738,36 @@ void ServiceWorkerDispatcherHost::OnProviderCreated(
bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
return;
}
- scoped_ptr<ServiceWorkerProviderHost> provider_host(
- new ServiceWorkerProviderHost(render_process_id_, route_id, provider_id,
- provider_type, GetContext()->AsWeakPtr(),
- this));
- GetContext()->AddProviderHost(provider_host.Pass());
+
+ scoped_ptr<ServiceWorkerProviderHost> provider_host;
+ if (IsBrowserSideNavigationEnabled() &&
+ ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)) {
+ // PlzNavigate
+ // Retrieve the provider host previously created for navigation requests.
+ ServiceWorkerNavigationHandleCore* navigation_handle_core =
+ GetContext()->GetNavigationHandleCore(provider_id);
+ if (navigation_handle_core != nullptr)
+ provider_host = navigation_handle_core->RetrievePreCreatedHost();
+ if (provider_host == nullptr) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
+ return;
+ }
+ DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type);
+ provider_host->CompleteNavigationInitialized(render_process_id_, route_id,
+ this);
+ } else {
+ if (ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
+ return;
+ }
+ provider_host =
+ scoped_ptr<ServiceWorkerProviderHost>(new ServiceWorkerProviderHost(
+ render_process_id_, route_id, provider_id, provider_type,
+ GetContext()->AsWeakPtr(), this));
+ }
+ GetContext()->AddProviderHost(std::move(provider_host));
}
void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
@@ -755,8 +783,8 @@ void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
GetContext()->RemoveProviderHost(render_process_id_, provider_id);
}
-void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
- int provider_id, int64 version_id) {
+void ServiceWorkerDispatcherHost::OnSetHostedVersionId(int provider_id,
+ int64_t version_id) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerDispatcherHost::OnSetHostedVersionId");
if (!GetContext())
@@ -793,13 +821,13 @@ void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
GetRegistrationObjectInfoAndVersionAttributes(
provider_host->AsWeakPtr(), registration, &info, &attrs);
- Send(new ServiceWorkerMsg_AssociateRegistrationWithServiceWorker(
- kDocumentMainThreadId, provider_id, info, attrs));
+ Send(new ServiceWorkerMsg_AssociateRegistration(kDocumentMainThreadId,
+ provider_id, info, attrs));
}
ServiceWorkerRegistrationHandle*
ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id,
- int64 registration_id) {
+ int64_t registration_id) {
for (RegistrationHandleMap::iterator iter(&registration_handles_);
!iter.IsAtEnd(); iter.Advance()) {
ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue();
@@ -834,7 +862,7 @@ void ServiceWorkerDispatcherHost::RegistrationComplete(
int request_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
if (!GetContext())
return;
@@ -872,7 +900,7 @@ void ServiceWorkerDispatcherHost::UpdateComplete(
int request_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id) {
+ int64_t registration_id) {
if (!GetContext())
return;
diff --git a/chromium/content/browser/service_worker/service_worker_dispatcher_host.h b/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
index f2535409ac1..89ff78997c2 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_HOST_H_
+#include <stdint.h>
+
#include <vector>
#include "base/id_map.h"
-#include "base/memory/scoped_vector.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "content/browser/service_worker/service_worker_registration_status.h"
@@ -63,7 +66,7 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
scoped_ptr<ServiceWorkerRegistrationHandle> handle);
ServiceWorkerHandle* FindServiceWorkerHandle(int provider_id,
- int64 version_id);
+ int64_t version_id);
// Returns the existing registration handle whose reference count is
// incremented or a newly created one if it doesn't exist.
@@ -92,11 +95,11 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
void OnUpdateServiceWorker(int thread_id,
int request_id,
int provider_id,
- int64 registration_id);
+ int64_t registration_id);
void OnUnregisterServiceWorker(int thread_id,
int request_id,
int provider_id,
- int64 registration_id);
+ int64_t registration_id);
void OnGetRegistration(int thread_id,
int request_id,
int provider_id,
@@ -109,7 +112,7 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
int route_id,
ServiceWorkerProviderType provider_type);
void OnProviderDestroyed(int provider_id);
- void OnSetHostedVersionId(int provider_id, int64 version_id);
+ void OnSetHostedVersionId(int provider_id, int64_t version_id);
void OnWorkerReadyForInspection(int embedded_worker_id);
void OnWorkerScriptLoaded(int embedded_worker_id);
void OnWorkerThreadStarted(int embedded_worker_id,
@@ -135,12 +138,11 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
int handle_id,
const base::string16& message,
const std::vector<TransferredMessagePort>& sent_message_ports);
- void OnServiceWorkerObjectDestroyed(int handle_id);
void OnTerminateWorker(int handle_id);
ServiceWorkerRegistrationHandle* FindRegistrationHandle(
int provider_id,
- int64 registration_handle_id);
+ int64_t registration_handle_id);
void GetRegistrationObjectInfoAndVersionAttributes(
base::WeakPtr<ServiceWorkerProviderHost> provider_host,
@@ -154,14 +156,14 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
int request_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id);
+ int64_t registration_id);
void UpdateComplete(int thread_id,
int provider_id,
int request_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
- int64 registration_id);
+ int64_t registration_id);
void UnregistrationComplete(int thread_id,
int request_id,
@@ -223,7 +225,7 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
RegistrationHandleMap registration_handles_;
bool channel_ready_; // True after BrowserMessageFilter::sender_ != NULL.
- ScopedVector<IPC::Message> pending_messages_;
+ std::vector<scoped_ptr<IPC::Message>> pending_messages_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcherHost);
};
diff --git a/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
index 5e4aa27430c..84e1b6e0a35 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/run_loop.h"
@@ -34,7 +37,6 @@ static void SaveStatusCallback(bool* called,
}
-static const int kRenderProcessId = 1;
static const int kRenderFrameId = 1;
class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {
@@ -69,10 +71,10 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
dispatcher_host_ = new TestingServiceWorkerDispatcherHost(
- kRenderProcessId, context_wrapper(), &resource_context_, helper_.get());
+ helper_->mock_render_process_id(), context_wrapper(),
+ &resource_context_, helper_.get());
}
void TearDown() override { helper_.reset(); }
@@ -82,62 +84,62 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
return helper_->context_wrapper();
}
- void SendRegister(int64 provider_id, GURL pattern, GURL worker_url) {
+ void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) {
dispatcher_host_->OnMessageReceived(
ServiceWorkerHostMsg_RegisterServiceWorker(
-1, -1, provider_id, pattern, worker_url));
base::RunLoop().RunUntilIdle();
}
- void Register(int64 provider_id,
+ void Register(int64_t provider_id,
GURL pattern,
GURL worker_url,
- uint32 expected_message) {
+ uint32_t expected_message) {
SendRegister(provider_id, pattern, worker_url);
EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
expected_message));
dispatcher_host_->ipc_sink()->ClearMessages();
}
- void SendUnregister(int64 provider_id, int64 registration_id) {
+ void SendUnregister(int64_t provider_id, int64_t registration_id) {
dispatcher_host_->OnMessageReceived(
ServiceWorkerHostMsg_UnregisterServiceWorker(-1, -1, provider_id,
registration_id));
base::RunLoop().RunUntilIdle();
}
- void Unregister(int64 provider_id,
- int64 registration_id,
- uint32 expected_message) {
+ void Unregister(int64_t provider_id,
+ int64_t registration_id,
+ uint32_t expected_message) {
SendUnregister(provider_id, registration_id);
EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
expected_message));
dispatcher_host_->ipc_sink()->ClearMessages();
}
- void SendGetRegistration(int64 provider_id, GURL document_url) {
+ void SendGetRegistration(int64_t provider_id, GURL document_url) {
dispatcher_host_->OnMessageReceived(
ServiceWorkerHostMsg_GetRegistration(
-1, -1, provider_id, document_url));
base::RunLoop().RunUntilIdle();
}
- void GetRegistration(int64 provider_id,
+ void GetRegistration(int64_t provider_id,
GURL document_url,
- uint32 expected_message) {
+ uint32_t expected_message) {
SendGetRegistration(provider_id, document_url);
EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
expected_message));
dispatcher_host_->ipc_sink()->ClearMessages();
}
- void SendGetRegistrations(int64 provider_id) {
+ void SendGetRegistrations(int64_t provider_id) {
dispatcher_host_->OnMessageReceived(
ServiceWorkerHostMsg_GetRegistrations(-1, -1, provider_id));
base::RunLoop().RunUntilIdle();
}
- void GetRegistrations(int64 provider_id, uint32 expected_message) {
+ void GetRegistrations(int64_t provider_id, uint32_t expected_message) {
SendGetRegistrations(provider_id);
EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
expected_message));
@@ -146,7 +148,7 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
ServiceWorkerProviderHost* CreateServiceWorkerProviderHost(int provider_id) {
return new ServiceWorkerProviderHost(
- kRenderProcessId, kRenderFrameId, provider_id,
+ helper_->mock_render_process_id(), kRenderFrameId, provider_id,
SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(),
dispatcher_host_.get());
}
@@ -176,11 +178,11 @@ TEST_F(ServiceWorkerDispatcherHostTest,
ContentBrowserClient* old_browser_client =
SetBrowserClientForTesting(&test_browser_client);
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
Register(kProviderId,
GURL("https://www.example.com/"),
@@ -194,7 +196,7 @@ TEST_F(ServiceWorkerDispatcherHostTest,
// Add a registration into a live registration map so that Unregister() can
// find it.
- const int64 kRegistrationId = 999; // Dummy value
+ const int64_t kRegistrationId = 999; // Dummy value
scoped_refptr<ServiceWorkerRegistration> registration(
new ServiceWorkerRegistration(GURL("https://www.example.com/"),
kRegistrationId, context()->AsWeakPtr()));
@@ -205,11 +207,11 @@ TEST_F(ServiceWorkerDispatcherHostTest,
}
TEST_F(ServiceWorkerDispatcherHostTest, Register_HTTPS) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
Register(kProviderId,
GURL("https://www.example.com/"),
@@ -218,11 +220,11 @@ TEST_F(ServiceWorkerDispatcherHostTest, Register_HTTPS) {
}
TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureTransportLocalhost) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
Register(kProviderId,
GURL("http://127.0.0.3:81/bar"),
@@ -231,11 +233,11 @@ TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureTransportLocalhost) {
}
TEST_F(ServiceWorkerDispatcherHostTest, Register_InvalidScopeShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendRegister(kProviderId, GURL(""),
GURL("https://www.example.com/bar/hoge.js"));
@@ -243,22 +245,22 @@ TEST_F(ServiceWorkerDispatcherHostTest, Register_InvalidScopeShouldFail) {
}
TEST_F(ServiceWorkerDispatcherHostTest, Register_InvalidScriptShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendRegister(kProviderId, GURL("https://www.example.com/bar/"), GURL(""));
EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
}
TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureOriginShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("http://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendRegister(kProviderId,
GURL("http://www.example.com/"),
@@ -267,11 +269,11 @@ TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureOriginShouldFail) {
}
TEST_F(ServiceWorkerDispatcherHostTest, Register_CrossOriginShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
// Script has a different host
SendRegister(kProviderId,
@@ -311,11 +313,11 @@ TEST_F(ServiceWorkerDispatcherHostTest, Register_CrossOriginShouldFail) {
}
TEST_F(ServiceWorkerDispatcherHostTest, Register_BadCharactersShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendRegister(kProviderId, GURL("https://www.example.com/%2f"),
GURL("https://www.example.com/"));
@@ -344,11 +346,11 @@ TEST_F(ServiceWorkerDispatcherHostTest, Register_BadCharactersShouldFail) {
TEST_F(ServiceWorkerDispatcherHostTest,
Register_FileSystemDocumentShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendRegister(kProviderId,
GURL("filesystem:https://www.example.com/temporary/"),
@@ -368,11 +370,11 @@ TEST_F(ServiceWorkerDispatcherHostTest,
TEST_F(ServiceWorkerDispatcherHostTest,
Register_FileSystemScriptOrScopeShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendRegister(kProviderId,
GURL("filesystem:https://www.example.com/temporary/"),
@@ -403,11 +405,12 @@ TEST_F(ServiceWorkerDispatcherHostTest, EarlyContextDeletion) {
}
TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
- const int kProviderId = 1001; // Test with a value != kRenderProcessId.
+ const int kProviderId = 1001;
+ int process_id = helper_->mock_render_process_id();
dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW));
- EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId));
+ EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
// Two with the same ID should be seen as a bad message.
dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
@@ -416,7 +419,7 @@ TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
dispatcher_host_->OnMessageReceived(
ServiceWorkerHostMsg_ProviderDestroyed(kProviderId));
- EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId));
+ EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
// Destroying an ID that does not exist warrants a bad message.
dispatcher_host_->OnMessageReceived(
@@ -427,18 +430,18 @@ TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
// process to get deleted as well.
dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW));
- EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId));
+ EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
EXPECT_TRUE(dispatcher_host_->HasOneRef());
dispatcher_host_ = NULL;
- EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId));
+ EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
}
TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
GetRegistration(kProviderId,
GURL("https://www.example.com/"),
@@ -446,11 +449,11 @@ TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) {
}
TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_CrossOriginShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendGetRegistration(kProviderId, GURL("https://foo.example.com/"));
EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
@@ -458,11 +461,11 @@ TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_CrossOriginShouldFail) {
TEST_F(ServiceWorkerDispatcherHostTest,
GetRegistration_InvalidScopeShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendGetRegistration(kProviderId, GURL(""));
EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
@@ -470,11 +473,11 @@ TEST_F(ServiceWorkerDispatcherHostTest,
TEST_F(ServiceWorkerDispatcherHostTest,
GetRegistration_NonSecureOriginShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("http://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendGetRegistration(kProviderId, GURL("http://www.example.com/"));
EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
@@ -492,22 +495,22 @@ TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_EarlyContextDeletion) {
}
TEST_F(ServiceWorkerDispatcherHostTest, GetRegistrations_SecureOrigin) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("https://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
GetRegistrations(kProviderId, ServiceWorkerMsg_DidGetRegistrations::ID);
}
TEST_F(ServiceWorkerDispatcherHostTest,
GetRegistrations_NonSecureOriginShouldFail) {
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
scoped_ptr<ServiceWorkerProviderHost> host(
CreateServiceWorkerProviderHost(kProviderId));
host->SetDocumentUrl(GURL("http://www.example.com/foo"));
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
SendGetRegistrations(kProviderId);
EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
@@ -523,8 +526,10 @@ TEST_F(ServiceWorkerDispatcherHostTest, GetRegistrations_EarlyContextDeletion) {
}
TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
+ int process_id = helper_->mock_render_process_id();
+
// Add a provider and worker.
- const int64 kProviderId = 99; // Dummy value
+ const int64_t kProviderId = 99; // Dummy value
dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW));
@@ -556,7 +561,7 @@ TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
EXPECT_TRUE(called);
ASSERT_EQ(SERVICE_WORKER_OK, status);
- helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern, process_id);
// Start up the worker.
status = SERVICE_WORKER_ERROR_ABORT;
@@ -566,24 +571,22 @@ TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
EXPECT_TRUE(called);
EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId));
+ EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
EXPECT_EQ(ServiceWorkerVersion::RUNNING, version->running_status());
// Simulate the render process crashing.
dispatcher_host_->OnFilterRemoved();
// The dispatcher host should clean up the state from the process.
- EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId));
+ EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->running_status());
// We should be able to hook up a new dispatcher host although the old object
// is not yet destroyed. This is what the browser does when reusing a crashed
// render process.
scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host(
- new TestingServiceWorkerDispatcherHost(kRenderProcessId,
- context_wrapper(),
- &resource_context_,
- helper_.get()));
+ new TestingServiceWorkerDispatcherHost(
+ process_id, context_wrapper(), &resource_context_, helper_.get()));
// To show the new dispatcher can operate, simulate provider creation. Since
// the old dispatcher cleaned up the old provider host, the new one won't
diff --git a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 771cbb18707..60c4eb66ef6 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -4,6 +4,8 @@
#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -18,9 +20,8 @@ ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
: version_(version),
prepare_callback_(prepare_callback),
fetch_callback_(fetch_callback),
- request_(request.Pass()),
- weak_factory_(this) {
-}
+ request_(std::move(request)),
+ weak_factory_(this) {}
ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {}
diff --git a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
index f0165b6cccb..518be84906b 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_FETCH_DISPATCHER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_FETCH_DISPATCHER_H_
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
diff --git a/chromium/content/browser/service_worker/service_worker_handle.h b/chromium/content/browser/service_worker/service_worker_handle.h
index 8fe2bd9d65b..a9c0e443a51 100644
--- a/chromium/content/browser/service_worker/service_worker_handle.h
+++ b/chromium/content/browser/service_worker/service_worker_handle.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/content/browser/service_worker/service_worker_handle_unittest.cc b/chromium/content/browser/service_worker/service_worker_handle_unittest.cc
index f99c6f58ad5..25514ffbd58 100644
--- a/chromium/content/browser/service_worker/service_worker_handle_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_handle_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 "base/basictypes.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
@@ -25,7 +25,6 @@ namespace content {
namespace {
-const int kRenderProcessId = 88; // A dummy ID for testing.
const int kRenderFrameId = 44; // A dummy ID for testing.
void VerifyStateChangedMessage(int expected_handle_id,
@@ -71,11 +70,10 @@ class ServiceWorkerHandleTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
dispatcher_host_ = new TestingServiceWorkerDispatcherHost(
- kRenderProcessId, helper_->context_wrapper(),
+ helper_->mock_render_process_id(), helper_->context_wrapper(),
&resource_context_, helper_.get());
const GURL pattern("http://www.example.com/");
@@ -105,10 +103,12 @@ class ServiceWorkerHandleTest : public testing::Test {
ASSERT_EQ(SERVICE_WORKER_OK, status);
provider_host_.reset(new ServiceWorkerProviderHost(
- kRenderProcessId, kRenderFrameId, 1, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- helper_->context()->AsWeakPtr(), dispatcher_host_.get()));
+ helper_->mock_render_process_id(), kRenderFrameId, 1,
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW, helper_->context()->AsWeakPtr(),
+ dispatcher_host_.get()));
- helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern,
+ helper_->mock_render_process_id());
}
void TearDown() override {
diff --git a/chromium/content/browser/service_worker/service_worker_info.cc b/chromium/content/browser/service_worker/service_worker_info.cc
index 9057101607f..836e979763d 100644
--- a/chromium/content/browser/service_worker/service_worker_info.cc
+++ b/chromium/content/browser/service_worker/service_worker_info.cc
@@ -5,13 +5,15 @@
#include "content/browser/service_worker/service_worker_info.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/child_process_host.h"
#include "ipc/ipc_message.h"
namespace content {
ServiceWorkerVersionInfo::ClientInfo::ClientInfo()
- : ClientInfo(-1, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_UNKNOWN) {
-}
+ : ClientInfo(ChildProcessHost::kInvalidUniqueID,
+ MSG_ROUTING_NONE,
+ SERVICE_WORKER_PROVIDER_UNKNOWN) {}
ServiceWorkerVersionInfo::ClientInfo::ClientInfo(int process_id,
int route_id,
@@ -27,17 +29,16 @@ ServiceWorkerVersionInfo::ServiceWorkerVersionInfo()
status(ServiceWorkerVersion::NEW),
registration_id(kInvalidServiceWorkerRegistrationId),
version_id(kInvalidServiceWorkerVersionId),
- process_id(-1),
- thread_id(-1),
- devtools_agent_route_id(MSG_ROUTING_NONE) {
-}
+ process_id(ChildProcessHost::kInvalidUniqueID),
+ thread_id(kInvalidEmbeddedWorkerThreadId),
+ devtools_agent_route_id(MSG_ROUTING_NONE) {}
ServiceWorkerVersionInfo::ServiceWorkerVersionInfo(
ServiceWorkerVersion::RunningStatus running_status,
ServiceWorkerVersion::Status status,
const GURL& script_url,
- int64 registration_id,
- int64 version_id,
+ int64_t registration_id,
+ int64_t version_id,
int process_id,
int thread_id,
int devtools_agent_route_id)
@@ -48,8 +49,7 @@ ServiceWorkerVersionInfo::ServiceWorkerVersionInfo(
version_id(version_id),
process_id(process_id),
thread_id(thread_id),
- devtools_agent_route_id(devtools_agent_route_id) {
-}
+ devtools_agent_route_id(devtools_agent_route_id) {}
ServiceWorkerVersionInfo::~ServiceWorkerVersionInfo() {}
@@ -61,7 +61,7 @@ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo()
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
const GURL& pattern,
- int64 registration_id,
+ int64_t registration_id,
DeleteFlag delete_flag)
: pattern(pattern),
registration_id(registration_id),
@@ -71,7 +71,7 @@ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
const GURL& pattern,
- int64 registration_id,
+ int64_t registration_id,
DeleteFlag delete_flag,
ForceUpdateOnPageLoad force_update_on_page_load,
const ServiceWorkerVersionInfo& active_version,
diff --git a/chromium/content/browser/service_worker/service_worker_info.h b/chromium/content/browser/service_worker/service_worker_info.h
index f7bd894f68b..b1c0a73f082 100644
--- a/chromium/content/browser/service_worker/service_worker_info.h
+++ b/chromium/content/browser/service_worker/service_worker_info.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_INFO_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_INFO_H_
+#include <stdint.h>
+
#include <vector>
#include "base/time/time.h"
@@ -30,8 +32,8 @@ struct CONTENT_EXPORT ServiceWorkerVersionInfo {
ServiceWorkerVersionInfo(ServiceWorkerVersion::RunningStatus running_status,
ServiceWorkerVersion::Status status,
const GURL& script_url,
- int64 registration_id,
- int64 version_id,
+ int64_t registration_id,
+ int64_t version_id,
int process_id,
int thread_id,
int devtools_agent_route_id);
@@ -40,8 +42,8 @@ struct CONTENT_EXPORT ServiceWorkerVersionInfo {
ServiceWorkerVersion::RunningStatus running_status;
ServiceWorkerVersion::Status status;
GURL script_url;
- int64 registration_id;
- int64 version_id;
+ int64_t registration_id;
+ int64_t version_id;
int process_id;
int thread_id;
int devtools_agent_route_id;
@@ -56,11 +58,11 @@ struct CONTENT_EXPORT ServiceWorkerRegistrationInfo {
enum ForceUpdateOnPageLoad { IS_NOT_FORCED, IS_FORCED };
ServiceWorkerRegistrationInfo();
ServiceWorkerRegistrationInfo(const GURL& pattern,
- int64 registration_id,
+ int64_t registration_id,
DeleteFlag delete_flag);
ServiceWorkerRegistrationInfo(
const GURL& pattern,
- int64 registration_id,
+ int64_t registration_id,
DeleteFlag delete_flag,
ForceUpdateOnPageLoad force_update_on_page_load,
const ServiceWorkerVersionInfo& active_version,
@@ -70,7 +72,7 @@ struct CONTENT_EXPORT ServiceWorkerRegistrationInfo {
~ServiceWorkerRegistrationInfo();
GURL pattern;
- int64 registration_id;
+ int64_t registration_id;
DeleteFlag delete_flag;
ForceUpdateOnPageLoad force_update_on_page_load;
ServiceWorkerVersionInfo active_version;
diff --git a/chromium/content/browser/service_worker/service_worker_internals_ui.cc b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
index 0e50fa4b894..ae899dca58d 100644
--- a/chromium/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
@@ -4,7 +4,9 @@
#include "content/browser/service_worker/service_worker_internals_ui.h"
+#include <stdint.h>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -64,7 +66,7 @@ void OperationCompleteCallback(WeakPtr<ServiceWorkerInternalsUI> internals,
void CallServiceWorkerVersionMethodWithVersionID(
ServiceWorkerInternalsUI::ServiceWorkerVersionMethod method,
scoped_refptr<ServiceWorkerContextWrapper> context,
- int64 version_id,
+ int64_t version_id,
const ServiceWorkerInternalsUI::StatusCallback& callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
@@ -89,7 +91,7 @@ void CallServiceWorkerVersionMethodWithVersionID(
void DispatchPushEventWithVersionID(
scoped_refptr<ServiceWorkerContextWrapper> context,
- int64 version_id,
+ int64_t version_id,
const ServiceWorkerInternalsUI::StatusCallback& callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
@@ -251,14 +253,14 @@ class ServiceWorkerInternalsUI::PartitionObserver
: partition_id_(partition_id), web_ui_(web_ui) {}
~PartitionObserver() override {}
// ServiceWorkerContextObserver overrides:
- void OnRunningStateChanged(int64 version_id,
+ void OnRunningStateChanged(int64_t version_id,
ServiceWorkerVersion::RunningStatus) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
web_ui_->CallJavascriptFunction(
"serviceworker.onRunningStateChanged", FundamentalValue(partition_id_),
StringValue(base::Int64ToString(version_id)));
}
- void OnVersionStateChanged(int64 version_id,
+ void OnVersionStateChanged(int64_t version_id,
ServiceWorkerVersion::Status) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
web_ui_->CallJavascriptFunction(
@@ -266,7 +268,7 @@ class ServiceWorkerInternalsUI::PartitionObserver
FundamentalValue(partition_id_),
StringValue(base::Int64ToString(version_id)));
}
- void OnErrorReported(int64 version_id,
+ void OnErrorReported(int64_t version_id,
int process_id,
int thread_id,
const ErrorInfo& info) override {
@@ -285,7 +287,7 @@ class ServiceWorkerInternalsUI::PartitionObserver
web_ui_->CallJavascriptFunction("serviceworker.onErrorReported",
args.get());
}
- void OnReportConsoleMessage(int64 version_id,
+ void OnReportConsoleMessage(int64_t version_id,
int process_id,
int thread_id,
const ConsoleMessage& message) override {
@@ -305,13 +307,13 @@ class ServiceWorkerInternalsUI::PartitionObserver
web_ui_->CallJavascriptFunction("serviceworker.onConsoleMessageReported",
args.get());
}
- void OnRegistrationStored(int64 registration_id,
+ void OnRegistrationStored(int64_t registration_id,
const GURL& pattern) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
web_ui_->CallJavascriptFunction("serviceworker.onRegistrationStored",
StringValue(pattern.spec()));
}
- void OnRegistrationDeleted(int64 registration_id,
+ void OnRegistrationDeleted(int64_t registration_id,
const GURL& pattern) override {
web_ui_->CallJavascriptFunction("serviceworker.onRegistrationDeleted",
StringValue(pattern.spec()));
@@ -429,7 +431,8 @@ void ServiceWorkerInternalsUI::AddContextFromStoragePartition(
scoped_ptr<PartitionObserver> new_observer(
new PartitionObserver(partition_id, web_ui()));
context->AddObserver(new_observer.get());
- observers_.set(reinterpret_cast<uintptr_t>(partition), new_observer.Pass());
+ observers_.set(reinterpret_cast<uintptr_t>(partition),
+ std::move(new_observer));
}
BrowserThread::PostTask(
@@ -491,7 +494,7 @@ void ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod(
int partition_id;
scoped_refptr<ServiceWorkerContextWrapper> context;
std::string version_id_string;
- int64 version_id = 0;
+ int64_t version_id = 0;
if (!args->GetInteger(0, &callback_id) ||
!args->GetDictionary(1, &cmd_args) ||
!cmd_args->GetInteger("partition_id", &partition_id) ||
@@ -512,7 +515,7 @@ void ServiceWorkerInternalsUI::DispatchPushEvent(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
int callback_id;
int partition_id;
- int64 version_id = 0;
+ int64_t version_id = 0;
std::string version_id_string;
const DictionaryValue* cmd_args = NULL;
scoped_refptr<ServiceWorkerContextWrapper> context;
diff --git a/chromium/content/browser/service_worker/service_worker_job_coordinator.cc b/chromium/content/browser/service_worker/service_worker_job_coordinator.cc
index 62ace7dc5bd..b8f71cf5796 100644
--- a/chromium/content/browser/service_worker/service_worker_job_coordinator.cc
+++ b/chromium/content/browser/service_worker/service_worker_job_coordinator.cc
@@ -4,6 +4,9 @@
#include "content/browser/service_worker/service_worker_job_coordinator.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "content/browser/service_worker/service_worker_register_job_base.h"
@@ -105,9 +108,8 @@ void ServiceWorkerJobCoordinator::Register(
const ServiceWorkerRegisterJob::RegistrationCallback& callback) {
scoped_ptr<ServiceWorkerRegisterJobBase> job(
new ServiceWorkerRegisterJob(context_, pattern, script_url));
- ServiceWorkerRegisterJob* queued_job =
- static_cast<ServiceWorkerRegisterJob*>(
- job_queues_[pattern].Push(job.Pass()));
+ ServiceWorkerRegisterJob* queued_job = static_cast<ServiceWorkerRegisterJob*>(
+ job_queues_[pattern].Push(std::move(job)));
queued_job->AddCallback(callback, provider_host);
}
@@ -118,7 +120,7 @@ void ServiceWorkerJobCoordinator::Unregister(
new ServiceWorkerUnregisterJob(context_, pattern));
ServiceWorkerUnregisterJob* queued_job =
static_cast<ServiceWorkerUnregisterJob*>(
- job_queues_[pattern].Push(job.Pass()));
+ job_queues_[pattern].Push(std::move(job)));
queued_job->AddCallback(callback);
}
diff --git a/chromium/content/browser/service_worker/service_worker_job_coordinator.h b/chromium/content/browser/service_worker/service_worker_job_coordinator.h
index b4fa8a28137..728b8206b8f 100644
--- a/chromium/content/browser/service_worker/service_worker_job_coordinator.h
+++ b/chromium/content/browser/service_worker/service_worker_job_coordinator.h
@@ -8,6 +8,7 @@
#include <deque>
#include <map>
+#include "base/macros.h"
#include "content/browser/service_worker/service_worker_register_job.h"
#include "content/browser/service_worker/service_worker_unregister_job.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/service_worker/service_worker_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
index e49c8294d64..a5572a4f60b 100644
--- a/chromium/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
@@ -32,8 +35,6 @@ namespace content {
namespace {
-int kMockRenderProcessId = 88;
-
void SaveRegistrationCallback(
ServiceWorkerStatusCode expected_status,
bool* called,
@@ -84,7 +85,7 @@ ServiceWorkerStorage::FindRegistrationCallback SaveFoundRegistration(
void SaveUnregistrationCallback(ServiceWorkerStatusCode expected_status,
bool* called,
- int64 registration_id,
+ int64_t registration_id,
ServiceWorkerStatusCode status) {
EXPECT_EQ(expected_status, status);
*called = true;
@@ -102,12 +103,10 @@ ServiceWorkerUnregisterJob::UnregistrationCallback SaveUnregistration(
class ServiceWorkerJobTest : public testing::Test {
public:
ServiceWorkerJobTest()
- : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- render_process_id_(kMockRenderProcessId) {}
+ : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), render_process_id_));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
}
void TearDown() override { helper_.reset(); }
@@ -134,7 +133,6 @@ class ServiceWorkerJobTest : public testing::Test {
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<EmbeddedWorkerTestHelper> helper_;
- int render_process_id_;
};
scoped_refptr<ServiceWorkerRegistration> ServiceWorkerJobTest::RunRegisterJob(
@@ -356,11 +354,10 @@ TEST_F(ServiceWorkerJobTest, RegisterDuplicateScript) {
class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper {
public:
- explicit FailToStartWorkerTestHelper(int mock_render_process_id)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
+ FailToStartWorkerTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
void OnStartWorker(int embedded_worker_id,
- int64 service_worker_version_id,
+ int64_t service_worker_version_id,
const GURL& scope,
const GURL& script_url) override {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
@@ -369,7 +366,7 @@ class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper {
};
TEST_F(ServiceWorkerJobTest, Register_FailToStartWorker) {
- helper_.reset(new FailToStartWorkerTestHelper(render_process_id_));
+ helper_.reset(new FailToStartWorkerTestHelper);
scoped_refptr<ServiceWorkerRegistration> registration =
RunRegisterJob(GURL("http://www.example.com/"),
@@ -727,10 +724,11 @@ void OnIOComplete(int* rv_out, int rv) {
*rv_out = rv;
}
-void WriteResponse(
- ServiceWorkerStorage* storage, int64 id,
- const std::string& headers,
- IOBuffer* body, int length) {
+void WriteResponse(ServiceWorkerStorage* storage,
+ int64_t id,
+ const std::string& headers,
+ IOBuffer* body,
+ int length) {
scoped_ptr<ServiceWorkerResponseWriter> writer =
storage->CreateResponseWriter(id);
@@ -754,9 +752,9 @@ void WriteResponse(
EXPECT_EQ(length, rv);
}
-void WriteStringResponse(
- ServiceWorkerStorage* storage, int64 id,
- const std::string& body) {
+void WriteStringResponse(ServiceWorkerStorage* storage,
+ int64_t id,
+ const std::string& body) {
scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(body.data()));
const char kHttpHeaders[] = "HTTP/1.0 200 HONKYDORY\0\0";
std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
@@ -769,19 +767,17 @@ class UpdateJobTestHelper
public ServiceWorkerVersion::Listener {
public:
struct AttributeChangeLogEntry {
- int64 registration_id;
+ int64_t registration_id;
ChangedVersionAttributesMask mask;
ServiceWorkerRegistrationInfo info;
};
struct StateChangeLogEntry {
- int64 version_id;
+ int64_t version_id;
ServiceWorkerVersion::Status status;
};
- UpdateJobTestHelper(int mock_render_process_id)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id),
- update_found_(false) {}
+ UpdateJobTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
~UpdateJobTestHelper() override {
if (registration_.get())
registration_->RemoveListener(this);
@@ -813,11 +809,11 @@ class UpdateJobTestHelper
// EmbeddedWorkerTestHelper overrides
void OnStartWorker(int embedded_worker_id,
- int64 version_id,
+ int64_t version_id,
const GURL& scope,
const GURL& script) override {
const std::string kMockScriptBody = "mock_script";
- const uint64 kMockScriptSize = 19284;
+ const uint64_t kMockScriptSize = 19284;
ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
ServiceWorkerRegistration* registration =
context()->GetLiveRegistration(version->registration_id());
@@ -829,7 +825,7 @@ class UpdateJobTestHelper
if (!is_update) {
// Spoof caching the script for the initial version.
- int64 resource_id = storage()->NewResourceId();
+ int64_t resource_id = storage()->NewResourceId();
version->script_cache_map()->NotifyStartedCaching(script, resource_id);
WriteStringResponse(storage(), resource_id, kMockScriptBody);
version->script_cache_map()->NotifyFinishedCaching(
@@ -842,7 +838,7 @@ class UpdateJobTestHelper
}
// Spoof caching the script for the new version.
- int64 resource_id = storage()->NewResourceId();
+ int64_t resource_id = storage()->NewResourceId();
version->script_cache_map()->NotifyStartedCaching(script, resource_id);
WriteStringResponse(storage(), resource_id, "mock_different_script");
version->script_cache_map()->NotifyFinishedCaching(
@@ -885,19 +881,18 @@ class UpdateJobTestHelper
std::vector<AttributeChangeLogEntry> attribute_change_log_;
std::vector<StateChangeLogEntry> state_change_log_;
- bool update_found_;
+ bool update_found_ = false;
};
// Helper class for update tests that evicts the active version when the update
// worker is about to be started.
class EvictIncumbentVersionHelper : public UpdateJobTestHelper {
public:
- EvictIncumbentVersionHelper(int mock_render_process_id)
- : UpdateJobTestHelper(mock_render_process_id) {}
+ EvictIncumbentVersionHelper() {}
~EvictIncumbentVersionHelper() override {}
void OnStartWorker(int embedded_worker_id,
- int64 version_id,
+ int64_t version_id,
const GURL& scope,
const GURL& script) override {
ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
@@ -925,8 +920,7 @@ class EvictIncumbentVersionHelper : public UpdateJobTestHelper {
} // namespace
TEST_F(ServiceWorkerJobTest, Update_NoChange) {
- UpdateJobTestHelper* update_helper =
- new UpdateJobTestHelper(render_process_id_);
+ UpdateJobTestHelper* update_helper = new UpdateJobTestHelper;
helper_.reset(update_helper);
scoped_refptr<ServiceWorkerRegistration> registration =
update_helper->SetupInitialRegistration(kNoChangeOrigin);
@@ -967,8 +961,7 @@ TEST_F(ServiceWorkerJobTest, Update_BumpLastUpdateCheckTime) {
const base::Time kToday = base::Time::Now();
const base::Time kYesterday =
kToday - base::TimeDelta::FromDays(1) - base::TimeDelta::FromHours(1);
- UpdateJobTestHelper* update_helper =
- new UpdateJobTestHelper(render_process_id_);
+ UpdateJobTestHelper* update_helper = new UpdateJobTestHelper;
helper_.reset(update_helper);
scoped_refptr<ServiceWorkerRegistration> registration =
update_helper->SetupInitialRegistration(kNoChangeOrigin);
@@ -989,8 +982,7 @@ TEST_F(ServiceWorkerJobTest, Update_BumpLastUpdateCheckTime) {
}
TEST_F(ServiceWorkerJobTest, Update_NewVersion) {
- UpdateJobTestHelper* update_helper =
- new UpdateJobTestHelper(render_process_id_);
+ UpdateJobTestHelper* update_helper = new UpdateJobTestHelper;
helper_.reset(update_helper);
scoped_refptr<ServiceWorkerRegistration> registration =
update_helper->SetupInitialRegistration(kNewVersionOrigin);
@@ -1108,8 +1100,7 @@ TEST_F(ServiceWorkerJobTest, Update_NewestVersionChanged) {
// Test that update succeeds if the incumbent worker was evicted
// during the update job (this can happen on disk cache failure).
TEST_F(ServiceWorkerJobTest, Update_EvictedIncumbent) {
- EvictIncumbentVersionHelper* update_helper =
- new EvictIncumbentVersionHelper(render_process_id_);
+ EvictIncumbentVersionHelper* update_helper = new EvictIncumbentVersionHelper;
helper_.reset(update_helper);
scoped_refptr<ServiceWorkerRegistration> registration =
update_helper->SetupInitialRegistration(kNewVersionOrigin);
@@ -1351,8 +1342,8 @@ TEST_F(ServiceWorkerJobTest, RegisterMultipleTimesWhileUninstalling) {
class EventCallbackHelper : public EmbeddedWorkerTestHelper {
public:
- explicit EventCallbackHelper(int mock_render_process_id)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id),
+ EventCallbackHelper()
+ : EmbeddedWorkerTestHelper(base::FilePath()),
install_event_result_(blink::WebServiceWorkerEventResultCompleted),
activate_event_result_(blink::WebServiceWorkerEventResultCompleted) {}
@@ -1386,7 +1377,7 @@ private:
};
TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringInstall) {
- EventCallbackHelper* helper = new EventCallbackHelper(render_process_id_);
+ EventCallbackHelper* helper = new EventCallbackHelper;
helper_.reset(helper);
GURL pattern("http://www.example.com/one/");
@@ -1426,7 +1417,7 @@ TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringInstall) {
}
TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringRejectedInstall) {
- EventCallbackHelper* helper = new EventCallbackHelper(render_process_id_);
+ EventCallbackHelper* helper = new EventCallbackHelper;
helper_.reset(helper);
GURL pattern("http://www.example.com/one/");
@@ -1462,7 +1453,7 @@ TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringRejectedInstall) {
}
TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringInstall_RejectActivate) {
- EventCallbackHelper* helper = new EventCallbackHelper(render_process_id_);
+ EventCallbackHelper* helper = new EventCallbackHelper;
helper_.reset(helper);
GURL pattern("http://www.example.com/one/");
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.cc b/chromium/content/browser/service_worker/service_worker_metrics.cc
index 8b70902278d..c2fc43b905f 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.cc
+++ b/chromium/content/browser/service_worker/service_worker_metrics.cc
@@ -99,12 +99,6 @@ void ServiceWorkerMetrics::RecordPurgeResourceResult(int net_error) {
std::abs(net_error));
}
-void ServiceWorkerMetrics::RecordDiskCacheMigrationResult(
- DiskCacheMigrationResult result) {
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.Storage.DiskCacheMigrationResult",
- result, NUM_MIGRATION_RESULT_TYPES);
-}
-
void ServiceWorkerMetrics::RecordDeleteAndStartOverResult(
DeleteAndStartOverResult result) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.Storage.DeleteAndStartOverResult",
@@ -174,12 +168,54 @@ void ServiceWorkerMetrics::RecordEventHandledRatio(EventType event,
type = EVENT_HANDLED_ALL;
else if (handled_events == 0)
type = EVENT_HANDLED_NONE;
+
// For now Fetch is the only type that is recorded.
- DCHECK_EQ(EVENT_TYPE_FETCH, event);
+ if (event != EventType::FETCH)
+ return;
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.EventHandledRatioType.Fetch", type,
NUM_EVENT_HANDLED_RATIO_TYPE);
}
+void ServiceWorkerMetrics::RecordEventTimeout(EventType event) {
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.RequestTimeouts.Count",
+ static_cast<int>(event),
+ static_cast<int>(EventType::NUM_TYPES));
+}
+
+void ServiceWorkerMetrics::RecordEventDuration(EventType event,
+ const base::TimeDelta& time) {
+ switch (event) {
+ case EventType::ACTIVATE:
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.ActivateEvent.Time", time);
+ break;
+ case EventType::INSTALL:
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.InstallEvent.Time", time);
+ break;
+ case EventType::SYNC:
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.BackgroundSyncEvent.Time",
+ time);
+ break;
+ case EventType::NOTIFICATION_CLICK:
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.NotificationClickEvent.Time",
+ time);
+ break;
+ case EventType::PUSH:
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.PushEvent.Time", time);
+ break;
+
+ // Event duration for fetch is recorded separately.
+ case EventType::FETCH:
+ // For now event duration for these events is not recorded.
+ case EventType::GEOFENCING:
+ case EventType::SERVICE_PORT_CONNECT:
+ break;
+
+ case EventType::NUM_TYPES:
+ NOTREACHED() << "Invalid event type";
+ break;
+ }
+}
+
void ServiceWorkerMetrics::RecordFetchEventStatus(
bool is_main_resource,
ServiceWorkerStatusCode status) {
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.h b/chromium/content/browser/service_worker/service_worker_metrics.h
index b40458442df..83dfb2ac5f8 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.h
+++ b/chromium/content/browser/service_worker/service_worker_metrics.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_METRICS_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_METRICS_H_
+#include <stddef.h>
+
#include "base/macros.h"
#include "content/browser/service_worker/service_worker_database.h"
#include "content/common/service_worker/service_worker_types.h"
@@ -30,14 +32,6 @@ class ServiceWorkerMetrics {
NUM_WRITE_RESPONSE_RESULT_TYPES,
};
- enum DiskCacheMigrationResult {
- MIGRATION_OK,
- MIGRATION_NOT_NECESSARY,
- MIGRATION_ERROR_MIGRATION_FAILED,
- MIGRATION_ERROR_UPDATE_DATABASE,
- NUM_MIGRATION_RESULT_TYPES,
- };
-
enum DeleteAndStartOverResult {
DELETE_OK,
DELETE_DATABASE_ERROR,
@@ -65,6 +59,7 @@ class ServiceWorkerMetrics {
REQUEST_JOB_ERROR_DESTROYED,
REQUEST_JOB_ERROR_DESTROYED_WITH_BLOB,
REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM,
+ REQUEST_JOB_ERROR_BAD_DELEGATE,
NUM_REQUEST_JOB_RESULT_TYPES,
};
@@ -77,11 +72,19 @@ class ServiceWorkerMetrics {
NUM_TYPES
};
- enum EventType {
- EVENT_TYPE_FETCH,
+ // Used for UMA. Append-only.
+ enum class EventType {
+ ACTIVATE,
+ INSTALL,
+ FETCH,
+ SYNC,
+ NOTIFICATION_CLICK,
+ PUSH,
+ GEOFENCING,
+ SERVICE_PORT_CONNECT,
// Add new events to record here.
- NUM_EVENT_TYPES
+ NUM_TYPES
};
// Used for UMA. Append only.
@@ -107,7 +110,6 @@ class ServiceWorkerMetrics {
// Used for ServiceWorkerStorage.
static void RecordPurgeResourceResult(int net_error);
static void RecordDeleteAndStartOverResult(DeleteAndStartOverResult result);
- static void RecordDiskCacheMigrationResult(DiskCacheMigrationResult result);
// Counts the number of page loads controlled by a Service Worker.
static void CountControlledPageLoad(const GURL& url);
@@ -137,6 +139,12 @@ class ServiceWorkerMetrics {
size_t handled_events,
size_t fired_events);
+ // Records how often a dispatched event times out.
+ static void RecordEventTimeout(EventType event);
+
+ // Records the amount of time spent handling an event.
+ static void RecordEventDuration(EventType event, const base::TimeDelta& time);
+
// Records the result of dispatching a fetch event to a service worker.
static void RecordFetchEventStatus(bool is_main_resource,
ServiceWorkerStatusCode status);
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_handle.cc b/chromium/content/browser/service_worker/service_worker_navigation_handle.cc
new file mode 100644
index 00000000000..2bc87a22fb5
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_navigation_handle.cc
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_navigation_handle.h"
+
+#include "base/bind.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+ServiceWorkerNavigationHandle::ServiceWorkerNavigationHandle(
+ ServiceWorkerContextWrapper* context_wrapper)
+ : service_worker_provider_host_id_(kInvalidServiceWorkerProviderId),
+ weak_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ core_ = new ServiceWorkerNavigationHandleCore(weak_factory_.GetWeakPtr(),
+ context_wrapper);
+}
+
+ServiceWorkerNavigationHandle::~ServiceWorkerNavigationHandle() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Delete the ServiceWorkerNavigationHandleCore on the IO thread.
+ BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, core_);
+}
+
+void ServiceWorkerNavigationHandle::DidCreateServiceWorkerProviderHost(
+ int service_worker_provider_host_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ service_worker_provider_host_id_ = service_worker_provider_host_id;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_handle.h b/chromium/content/browser/service_worker/service_worker_navigation_handle.h
new file mode 100644
index 00000000000..c5c69388cf7
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_navigation_handle.h
@@ -0,0 +1,78 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+
+namespace content {
+
+class ServiceWorkerContextWrapper;
+class ServiceWorkerNavigationHandleCore;
+
+// This class is used to manage the lifetime of ServiceWorkerProviderHosts
+// created during navigation. This is a UI thread class, with a pendant class
+// on the IO thread, the ServiceWorkerNavigationHandleCore.
+//
+// The lifetime of the ServiceWorkerNavigationHandle, the
+// ServiceWorkerNavigationHandleCore and the ServiceWorkerProviderHost are the
+// following :
+// 1) We create a ServiceWorkerNavigationHandle on the UI thread with a
+// service worker provider id of -1. This also leads to the creation of a
+// ServiceWorkerNavigationHandleCore with an id of -1.
+//
+// 2) When the navigation request is sent to the IO thread, we include a
+// pointer to the ServiceWorkerNavigationHandleCore.
+//
+// 3) If we pre-create a ServiceWorkerProviderHost for this navigation, its
+// ownershipped is passed to the ServiceWorkerNavigationHandleCore. The
+// ServiceWorkerNavigationHandleCore id is updated.
+//
+// 4) The ServiceWorkerNavigationHandleCore informs the
+// ServiceWorkerNavigationHandle on the UI that the service worker provider
+// id was updated.
+//
+// 5) When the navigation is ready to commit, the NavigationRequest will
+// update the RequestNavigationParams based on the id from the
+// ServiceWorkerNavigationHandle.
+//
+// 6) If the commit leads to the creation of a ServiceWorkerNetworkProvider
+// in the renderer, a ServiceWorkerHostMsg_ProviderCreated will be received
+// in the browser. The ServiceWorkerDispatcherHost will retrieve the
+// ServiceWorkerProviderHost from the ServiceWorkerNavigationHandleCore and
+// put it in the ServiceWorkerContextCore map of ServiceWorkerProviderHosts.
+//
+// 7) When the navigation finishes, the ServiceWorkerNavigationHandle is
+// destroyed. The destructor of the ServiceWorkerNavigationHandle posts a
+// task to destroy the ServiceWorkerNavigationHandleCore on the IO thread.
+// This in turn leads to the destruction of an unclaimed
+// ServiceWorkerProviderHost.
+class ServiceWorkerNavigationHandle {
+ public:
+ explicit ServiceWorkerNavigationHandle(
+ ServiceWorkerContextWrapper* context_wrapper);
+ ~ServiceWorkerNavigationHandle();
+
+ int service_worker_provider_host_id() const {
+ return service_worker_provider_host_id_;
+ }
+ ServiceWorkerNavigationHandleCore* core() const { return core_; }
+
+ // Called after a ServiceWorkerProviderHost with id
+ // |service_worker_provider_host_id| was pre-created for the navigation on the
+ // IO thread.
+ void DidCreateServiceWorkerProviderHost(int service_worker_provider_host_id);
+
+ private:
+ int service_worker_provider_host_id_;
+ ServiceWorkerNavigationHandleCore* core_;
+ base::WeakPtrFactory<ServiceWorkerNavigationHandle> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationHandle);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_H_
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
new file mode 100644
index 00000000000..8c4791da374
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
@@ -0,0 +1,65 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
+
+#include <utility>
+
+#include "base/bind.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_navigation_handle.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+ServiceWorkerNavigationHandleCore::ServiceWorkerNavigationHandleCore(
+ base::WeakPtr<ServiceWorkerNavigationHandle> ui_handle,
+ ServiceWorkerContextWrapper* context_wrapper)
+ : context_wrapper_(context_wrapper), ui_handle_(ui_handle) {
+ // The ServiceWorkerNavigationHandleCore is created on the UI thread but
+ // should only be accessed from the IO thread afterwards.
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
+
+ServiceWorkerNavigationHandleCore::~ServiceWorkerNavigationHandleCore() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (precreated_host_.get() && context_wrapper_->context()) {
+ context_wrapper_->context()->RemoveNavigationHandleCore(
+ precreated_host_->provider_id());
+ }
+}
+
+void ServiceWorkerNavigationHandleCore::DidPreCreateProviderHost(
+ scoped_ptr<ServiceWorkerProviderHost> precreated_host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(precreated_host.get());
+ DCHECK(context_wrapper_->context());
+
+ precreated_host_ = std::move(precreated_host);
+ context_wrapper_->context()->AddNavigationHandleCore(
+ precreated_host_->provider_id(), this);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &ServiceWorkerNavigationHandle::DidCreateServiceWorkerProviderHost,
+ ui_handle_, precreated_host_->provider_id()));
+}
+
+scoped_ptr<ServiceWorkerProviderHost>
+ServiceWorkerNavigationHandleCore::RetrievePreCreatedHost() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(precreated_host_);
+ // Remove the ServiceWorkerNavigationHandleCore from the list of
+ // ServiceWorkerNavigationHandleCores since it will no longer hold a
+ // ServiceWorkerProviderHost.
+ DCHECK(context_wrapper_->context());
+ context_wrapper_->context()->RemoveNavigationHandleCore(
+ precreated_host_->provider_id());
+ return std::move(precreated_host_);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_handle_core.h b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.h
new file mode 100644
index 00000000000..c1ed9eb9cf5
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.h
@@ -0,0 +1,57 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_CORE_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_CORE_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+
+namespace content {
+
+class ServiceWorkerContextWrapper;
+class ServiceWorkerNavigationHandle;
+class ServiceWorkerProviderHost;
+
+// PlzNavigate
+// This class is used to manage the lifetime of ServiceWorkerProviderHosts
+// created during navigations. This class is created on the UI thread, but
+// should only be accessed from the IO thread afterwards. It is the IO thread
+// pendant of ServiceWorkerNavigationHandle. See the
+// ServiceWorkerNavigationHandle header for more details about the lifetime of
+// both classes.
+class ServiceWorkerNavigationHandleCore {
+ public:
+ ServiceWorkerNavigationHandleCore(
+ base::WeakPtr<ServiceWorkerNavigationHandle> ui_handle,
+ ServiceWorkerContextWrapper* context_wrapper);
+ ~ServiceWorkerNavigationHandleCore();
+
+ // Called when a ServiceWorkerProviderHost was pre-created for the navigation
+ // tracked by this ServiceWorkerNavigationHandleCore. Takes ownership of
+ // |precreated_host|.
+ void DidPreCreateProviderHost(
+ scoped_ptr<ServiceWorkerProviderHost> precreated_host);
+
+ // Called when the renderer created a ServiceWorkerNetworkProvider matching
+ // |precreated_host_|. This releases ownership of |precreated_host_|.
+ scoped_ptr<ServiceWorkerProviderHost> RetrievePreCreatedHost();
+
+ ServiceWorkerContextWrapper* context_wrapper() const {
+ return context_wrapper_.get();
+ }
+
+ private:
+ scoped_ptr<ServiceWorkerProviderHost> precreated_host_;
+ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_;
+ base::WeakPtr<ServiceWorkerNavigationHandle> ui_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationHandleCore);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_HANDLE_CORE_H_
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager.cc b/chromium/content/browser/service_worker/service_worker_process_manager.cc
index a310bcc1770..4b559edce8a 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager.cc
+++ b/chromium/content/browser/service_worker/service_worker_process_manager.cc
@@ -4,10 +4,16 @@
#include "content/browser/service_worker/service_worker_process_manager.h"
+#include <stddef.h>
+
+#include <algorithm>
+#include <utility>
+
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/site_instance.h"
+#include "content/public/common/child_process_host.h"
#include "url/gurl.h"
namespace content {
@@ -24,15 +30,6 @@ struct SecondGreater {
} // namespace
-static bool IncrementWorkerRefCountByPid(int process_id) {
- RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
- if (!rph || rph->FastShutdownStarted())
- return false;
-
- static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount();
- return true;
-}
-
ServiceWorkerProcessManager::ProcessInfo::ProcessInfo(
const scoped_refptr<SiteInstance>& site_instance)
: site_instance(site_instance),
@@ -49,16 +46,18 @@ ServiceWorkerProcessManager::ProcessInfo::~ProcessInfo() {
ServiceWorkerProcessManager::ServiceWorkerProcessManager(
BrowserContext* browser_context)
: browser_context_(browser_context),
- process_id_for_test_(-1),
+ process_id_for_test_(ChildProcessHost::kInvalidUniqueID),
weak_this_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
weak_this_ = weak_this_factory_.GetWeakPtr();
}
ServiceWorkerProcessManager::~ServiceWorkerProcessManager() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(browser_context_ == NULL)
+ DCHECK(IsShutdown())
<< "Call Shutdown() before destroying |this|, so that racing method "
<< "invocations don't use a destroyed BrowserContext.";
+ DCHECK(instance_info_.empty());
}
void ServiceWorkerProcessManager::Shutdown() {
@@ -67,9 +66,7 @@ void ServiceWorkerProcessManager::Shutdown() {
for (std::map<int, ProcessInfo>::const_iterator it = instance_info_.begin();
it != instance_info_.end();
++it) {
- RenderProcessHost* rph = RenderProcessHost::FromID(it->second.process_id);
- DCHECK(rph);
- static_cast<RenderProcessHostImpl*>(rph)->DecrementWorkerRefCount();
+ RenderProcessHost::FromID(it->second.process_id)->DecrementWorkerRefCount();
}
instance_info_.clear();
}
@@ -107,7 +104,7 @@ void ServiceWorkerProcessManager::RemoveProcessReferenceFromPattern(
PatternProcessRefMap::iterator it = pattern_processes_.find(pattern);
if (it == pattern_processes_.end()) {
- NOTREACHED() << "process refrences not found for pattern: " << pattern;
+ NOTREACHED() << "process references not found for pattern: " << pattern;
return;
}
ProcessRefMap& process_refs = it->second;
@@ -151,7 +148,7 @@ void ServiceWorkerProcessManager::AllocateWorkerProcess(
return;
}
- if (process_id_for_test_ != -1) {
+ if (process_id_for_test_ != ChildProcessHost::kInvalidUniqueID) {
// Let tests specify the returned process ID. Note: We may need to be able
// to specify the error code too.
BrowserThread::PostTask(
@@ -161,34 +158,35 @@ void ServiceWorkerProcessManager::AllocateWorkerProcess(
return;
}
- DCHECK(!ContainsKey(instance_info_, embedded_worker_id))
- << embedded_worker_id << " already has a process allocated";
-
- std::vector<int> sorted_candidates = SortProcessesForPattern(pattern);
- for (std::vector<int>::const_iterator it = sorted_candidates.begin();
- it != sorted_candidates.end();
- ++it) {
- if (!IncrementWorkerRefCountByPid(*it))
- continue;
- instance_info_.insert(
- std::make_pair(embedded_worker_id, ProcessInfo(*it)));
+ if (IsShutdown()) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback, SERVICE_WORKER_OK, *it,
+ base::Bind(callback, SERVICE_WORKER_ERROR_ABORT,
+ ChildProcessHost::kInvalidUniqueID,
false /* is_new_process */));
return;
}
- if (!browser_context_) {
- // Shutdown has started.
+ // TODO(nhiroki): Make sure the instance info is not mixed up.
+ // (http://crbug.com/568915)
+ CHECK(!ContainsKey(instance_info_, embedded_worker_id))
+ << embedded_worker_id << " already has a process allocated";
+
+ int process_id = FindAvailableProcess(pattern);
+ if (process_id != ChildProcessHost::kInvalidUniqueID) {
+ RenderProcessHost::FromID(process_id)->IncrementWorkerRefCount();
+ instance_info_.insert(
+ std::make_pair(embedded_worker_id, ProcessInfo(process_id)));
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback, SERVICE_WORKER_ERROR_ABORT, -1,
+ base::Bind(callback, SERVICE_WORKER_OK, process_id,
false /* is_new_process */));
return;
}
+
// No existing processes available; start a new one.
scoped_refptr<SiteInstance> site_instance =
SiteInstance::CreateForURL(browser_context_, script_url);
RenderProcessHost* rph = site_instance->GetProcess();
+
// This Init() call posts a task to the IO thread that adds the RPH's
// ServiceWorkerDispatcherHost to the
// EmbeddedWorkerRegistry::process_sender_map_.
@@ -196,7 +194,8 @@ void ServiceWorkerProcessManager::AllocateWorkerProcess(
LOG(ERROR) << "Couldn't start a new process!";
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(callback, SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND, -1,
+ base::Bind(callback, SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND,
+ ChildProcessHost::kInvalidUniqueID,
false /* is_new_process */));
return;
}
@@ -204,7 +203,7 @@ void ServiceWorkerProcessManager::AllocateWorkerProcess(
instance_info_.insert(
std::make_pair(embedded_worker_id, ProcessInfo(site_instance)));
- static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount();
+ rph->IncrementWorkerRefCount();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(callback, SERVICE_WORKER_OK, rph->GetID(),
true /* is_new_process */));
@@ -220,19 +219,27 @@ void ServiceWorkerProcessManager::ReleaseWorkerProcess(int embedded_worker_id) {
embedded_worker_id));
return;
}
- if (process_id_for_test_ != -1) {
+
+ if (process_id_for_test_ != ChildProcessHost::kInvalidUniqueID) {
// Unittests don't increment or decrement the worker refcount of a
// RenderProcessHost.
return;
}
- if (browser_context_ == NULL) {
+
+ if (IsShutdown()) {
// Shutdown already released all instances.
DCHECK(instance_info_.empty());
return;
}
+
std::map<int, ProcessInfo>::iterator info =
instance_info_.find(embedded_worker_id);
- DCHECK(info != instance_info_.end());
+ // ReleaseWorkerProcess could be called for a nonexistent worker id, for
+ // example, when request to start a worker is aborted on the IO thread during
+ // process allocation that is failed on the UI thread.
+ if (info == instance_info_.end())
+ return;
+
RenderProcessHost* rph = NULL;
if (info->second.site_instance.get()) {
rph = info->second.site_instance->GetProcess();
@@ -245,7 +252,7 @@ void ServiceWorkerProcessManager::ReleaseWorkerProcess(int embedded_worker_id) {
<< "Process " << info->second.process_id
<< " was destroyed unexpectedly. Did we actually hold a reference?";
}
- static_cast<RenderProcessHostImpl*>(rph)->DecrementWorkerRefCount();
+ rph->DecrementWorkerRefCount();
instance_info_.erase(info);
}
@@ -255,6 +262,8 @@ std::vector<int> ServiceWorkerProcessManager::SortProcessesForPattern(
if (it == pattern_processes_.end())
return std::vector<int>();
+ // Prioritize higher refcount processes to choose the process which has more
+ // tabs and is less likely to be backgrounded by user action like tab close.
std::vector<std::pair<int, int> > counted(
it->second.begin(), it->second.end());
std::sort(counted.begin(), counted.end(), SecondGreater());
@@ -265,15 +274,42 @@ std::vector<int> ServiceWorkerProcessManager::SortProcessesForPattern(
return result;
}
+int ServiceWorkerProcessManager::FindAvailableProcess(const GURL& pattern) {
+ RenderProcessHost* backgrounded_candidate = nullptr;
+
+ // Try to find an available foreground process.
+ std::vector<int> sorted_candidates = SortProcessesForPattern(pattern);
+ for (int process_id : sorted_candidates) {
+ RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
+ if (!rph || rph->FastShutdownStarted())
+ continue;
+
+ // Keep a backgrounded process for a suboptimal choice.
+ if (rph->IsProcessBackgrounded()) {
+ if (!backgrounded_candidate)
+ backgrounded_candidate = rph;
+ continue;
+ }
+
+ return process_id;
+ }
+
+ // No foreground processes available; choose a backgrounded one.
+ if (backgrounded_candidate)
+ return backgrounded_candidate->GetID();
+
+ return ChildProcessHost::kInvalidUniqueID;
+}
+
} // namespace content
-namespace base {
+namespace std {
// Destroying ServiceWorkerProcessManagers only on the UI thread allows the
// member WeakPtr to safely guard the object's lifetime when used on that
// thread.
-void DefaultDeleter<content::ServiceWorkerProcessManager>::operator()(
+void default_delete<content::ServiceWorkerProcessManager>::operator()(
content::ServiceWorkerProcessManager* ptr) const {
content::BrowserThread::DeleteSoon(
content::BrowserThread::UI, FROM_HERE, ptr);
}
-} // namespace base
+} // namespace std
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager.h b/chromium/content/browser/service_worker/service_worker_process_manager.h
index 10a43e8fa7a..443aafbd017 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager.h
+++ b/chromium/content/browser/service_worker/service_worker_process_manager.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROCESS_MANAGER_H_
#include <map>
+#include <memory>
#include <vector>
#include "base/callback.h"
@@ -75,6 +76,12 @@ class CONTENT_EXPORT ServiceWorkerProcessManager {
private:
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProcessManagerTest, SortProcess);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProcessManagerTest,
+ FindAvailableProcess);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProcessManagerTest,
+ AllocateWorkerProcess_FindAvailableProcess);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProcessManagerTest,
+ AllocateWorkerProcess_InShutdown);
// Information about the process for an EmbeddedWorkerInstance.
struct ProcessInfo {
@@ -94,6 +101,9 @@ class CONTENT_EXPORT ServiceWorkerProcessManager {
int process_id;
};
+ // Returns true if Shutdown() has been called.
+ bool IsShutdown() const { return !browser_context_; }
+
// Maps the process ID to its reference count.
typedef std::map<int, int> ProcessRefMap;
@@ -103,6 +113,10 @@ class CONTENT_EXPORT ServiceWorkerProcessManager {
// Returns a process vector sorted by the reference count for the |pattern|.
std::vector<int> SortProcessesForPattern(const GURL& pattern) const;
+ // Returns the id of an available process for this pattern, or
+ // ChildProcessHost::kInvalidUniqueID if there is none.
+ int FindAvailableProcess(const GURL& pattern);
+
// These fields are only accessed on the UI thread.
BrowserContext* browser_context_;
@@ -130,12 +144,12 @@ class CONTENT_EXPORT ServiceWorkerProcessManager {
} // namespace content
-namespace base {
+namespace std {
// Specialized to post the deletion to the UI thread.
template <>
-struct CONTENT_EXPORT DefaultDeleter<content::ServiceWorkerProcessManager> {
+struct CONTENT_EXPORT default_delete<content::ServiceWorkerProcessManager> {
void operator()(content::ServiceWorkerProcessManager* ptr) const;
};
-} // namespace base
+} // namespace std
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROCESS_MANAGER_H_
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc b/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
index 3b53740aad4..384f996b862 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
@@ -2,8 +2,13 @@
// 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/bind.h"
+#include "base/macros.h"
+#include "base/run_loop.h"
#include "content/browser/service_worker/service_worker_process_manager.h"
+#include "content/public/common/child_process_host.h"
+#include "content/public/test/mock_render_process_host.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -11,20 +16,49 @@
namespace content {
+namespace {
+
+void DidAllocateWorkerProcess(const base::Closure& quit_closure,
+ ServiceWorkerStatusCode* status_out,
+ int* process_id_out,
+ bool* is_new_process_out,
+ ServiceWorkerStatusCode status,
+ int process_id,
+ bool is_new_process) {
+ *status_out = status;
+ *process_id_out = process_id;
+ *is_new_process_out = is_new_process;
+ quit_closure.Run();
+}
+
+} // namespace
+
class ServiceWorkerProcessManagerTest : public testing::Test {
public:
ServiceWorkerProcessManagerTest() {}
void SetUp() override {
- process_manager_.reset(new ServiceWorkerProcessManager(NULL));
+ browser_context_.reset(new TestBrowserContext);
+ process_manager_.reset(
+ new ServiceWorkerProcessManager(browser_context_.get()));
pattern_ = GURL("http://www.example.com/");
+ script_url_ = GURL("http://www.example.com/sw.js");
}
- void TearDown() override { process_manager_.reset(); }
+ void TearDown() override {
+ process_manager_->Shutdown();
+ process_manager_.reset();
+ }
+
+ scoped_ptr<MockRenderProcessHost> CreateRenderProcessHost() {
+ return make_scoped_ptr(new MockRenderProcessHost(browser_context_.get()));
+ }
protected:
+ scoped_ptr<TestBrowserContext> browser_context_;
scoped_ptr<ServiceWorkerProcessManager> process_manager_;
GURL pattern_;
+ GURL script_url_;
private:
content::TestBrowserThreadBundle thread_bundle_;
@@ -32,7 +66,7 @@ class ServiceWorkerProcessManagerTest : public testing::Test {
};
TEST_F(ServiceWorkerProcessManagerTest, SortProcess) {
- // Process 1 has 2 ref, 2 has 3 refs and 3 has 1 refs.
+ // Process 1 has 2 refs, 2 has 3 refs and 3 has 1 ref.
process_manager_->AddProcessReferenceToPattern(pattern_, 1);
process_manager_->AddProcessReferenceToPattern(pattern_, 1);
process_manager_->AddProcessReferenceToPattern(pattern_, 2);
@@ -51,4 +85,165 @@ TEST_F(ServiceWorkerProcessManagerTest, SortProcess) {
testing::ElementsAre(2, 3));
}
+TEST_F(ServiceWorkerProcessManagerTest, FindAvailableProcess) {
+ scoped_ptr<MockRenderProcessHost> host1(CreateRenderProcessHost());
+ scoped_ptr<MockRenderProcessHost> host2(CreateRenderProcessHost());
+ scoped_ptr<MockRenderProcessHost> host3(CreateRenderProcessHost());
+
+ // Process 1 has 2 refs, 2 has 3 refs and 3 has 1 ref.
+ process_manager_->AddProcessReferenceToPattern(pattern_, host1->GetID());
+ process_manager_->AddProcessReferenceToPattern(pattern_, host1->GetID());
+ process_manager_->AddProcessReferenceToPattern(pattern_, host2->GetID());
+ process_manager_->AddProcessReferenceToPattern(pattern_, host2->GetID());
+ process_manager_->AddProcessReferenceToPattern(pattern_, host2->GetID());
+ process_manager_->AddProcessReferenceToPattern(pattern_, host3->GetID());
+
+ // When all processes are in foreground, process 2 that has the highest
+ // refcount should be chosen.
+ EXPECT_EQ(host2->GetID(), process_manager_->FindAvailableProcess(pattern_));
+
+ // Backgrounded process 2 should be deprioritized.
+ host2->set_is_process_backgrounded(true);
+ EXPECT_EQ(host1->GetID(), process_manager_->FindAvailableProcess(pattern_));
+
+ // When all processes are in background, process 2 that has the highest
+ // refcount should be chosen.
+ host1->set_is_process_backgrounded(true);
+ host3->set_is_process_backgrounded(true);
+ EXPECT_EQ(host2->GetID(), process_manager_->FindAvailableProcess(pattern_));
+
+ // Process 3 should be chosen because it is the only foreground process.
+ host3->set_is_process_backgrounded(false);
+ EXPECT_EQ(host3->GetID(), process_manager_->FindAvailableProcess(pattern_));
+}
+
+TEST_F(ServiceWorkerProcessManagerTest,
+ AllocateWorkerProcess_FindAvailableProcess) {
+ const int kEmbeddedWorkerId1 = 100;
+ const int kEmbeddedWorkerId2 = 200;
+ const int kEmbeddedWorkerId3 = 300;
+ GURL scope1("http://example.com/scope1");
+ GURL scope2("http://example.com/scope2");
+
+ // Set up mock renderer process hosts.
+ scoped_ptr<MockRenderProcessHost> host1(CreateRenderProcessHost());
+ scoped_ptr<MockRenderProcessHost> host2(CreateRenderProcessHost());
+ process_manager_->AddProcessReferenceToPattern(scope1, host1->GetID());
+ process_manager_->AddProcessReferenceToPattern(scope2, host2->GetID());
+ ASSERT_EQ(0, host1->worker_ref_count());
+ ASSERT_EQ(0, host2->worker_ref_count());
+
+ std::map<int, ServiceWorkerProcessManager::ProcessInfo>& instance_info =
+ process_manager_->instance_info_;
+
+ // (1) Allocate a process to a worker.
+ base::RunLoop run_loop1;
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ int process_id = -10;
+ bool is_new_process = true;
+ process_manager_->AllocateWorkerProcess(
+ kEmbeddedWorkerId1, scope1, script_url_,
+ base::Bind(&DidAllocateWorkerProcess, run_loop1.QuitClosure(), &status,
+ &process_id, &is_new_process));
+ run_loop1.Run();
+
+ // An existing process should be allocated to the worker.
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(host1->GetID(), process_id);
+ EXPECT_FALSE(is_new_process);
+ EXPECT_EQ(1, host1->worker_ref_count());
+ EXPECT_EQ(0, host2->worker_ref_count());
+ EXPECT_EQ(1u, instance_info.size());
+ std::map<int, ServiceWorkerProcessManager::ProcessInfo>::iterator found =
+ instance_info.find(kEmbeddedWorkerId1);
+ ASSERT_TRUE(found != instance_info.end());
+ EXPECT_EQ(host1->GetID(), found->second.process_id);
+
+ // (2) Allocate a process to another worker whose scope is the same with the
+ // first worker.
+ base::RunLoop run_loop2;
+ status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ process_id = -10;
+ is_new_process = true;
+ process_manager_->AllocateWorkerProcess(
+ kEmbeddedWorkerId2, scope1, script_url_,
+ base::Bind(&DidAllocateWorkerProcess, run_loop2.QuitClosure(), &status,
+ &process_id, &is_new_process));
+ run_loop2.Run();
+
+ // The same process should be allocated to the second worker.
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(host1->GetID(), process_id);
+ EXPECT_FALSE(is_new_process);
+ EXPECT_EQ(2, host1->worker_ref_count());
+ EXPECT_EQ(0, host2->worker_ref_count());
+ EXPECT_EQ(2u, instance_info.size());
+ found = instance_info.find(kEmbeddedWorkerId2);
+ ASSERT_TRUE(found != instance_info.end());
+ EXPECT_EQ(host1->GetID(), found->second.process_id);
+
+ // (3) Allocate a process to the other worker whose scope is different from
+ // other workers.
+ base::RunLoop run_loop3;
+ status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ process_id = -10;
+ is_new_process = true;
+ process_manager_->AllocateWorkerProcess(
+ kEmbeddedWorkerId3, scope2, script_url_,
+ base::Bind(&DidAllocateWorkerProcess, run_loop3.QuitClosure(), &status,
+ &process_id, &is_new_process));
+ run_loop3.Run();
+
+ // A different existing process should be allocated to the third worker.
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(host2->GetID(), process_id);
+ EXPECT_FALSE(is_new_process);
+ EXPECT_EQ(2, host1->worker_ref_count());
+ EXPECT_EQ(1, host2->worker_ref_count());
+ EXPECT_EQ(3u, instance_info.size());
+ found = instance_info.find(kEmbeddedWorkerId3);
+ ASSERT_TRUE(found != instance_info.end());
+ EXPECT_EQ(host2->GetID(), found->second.process_id);
+
+ // The instance map should be updated by process release.
+ process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId3);
+ EXPECT_EQ(2, host1->worker_ref_count());
+ EXPECT_EQ(0, host2->worker_ref_count());
+ EXPECT_EQ(2u, instance_info.size());
+ EXPECT_TRUE(ContainsKey(instance_info, kEmbeddedWorkerId1));
+ EXPECT_TRUE(ContainsKey(instance_info, kEmbeddedWorkerId2));
+
+ process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId1);
+ EXPECT_EQ(1, host1->worker_ref_count());
+ EXPECT_EQ(0, host2->worker_ref_count());
+ EXPECT_EQ(1u, instance_info.size());
+ EXPECT_TRUE(ContainsKey(instance_info, kEmbeddedWorkerId2));
+
+ process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId2);
+ EXPECT_EQ(0, host1->worker_ref_count());
+ EXPECT_EQ(0, host2->worker_ref_count());
+ EXPECT_TRUE(instance_info.empty());
+}
+
+TEST_F(ServiceWorkerProcessManagerTest, AllocateWorkerProcess_InShutdown) {
+ process_manager_->Shutdown();
+ ASSERT_TRUE(process_manager_->IsShutdown());
+
+ base::RunLoop run_loop;
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ int process_id = -10;
+ bool is_new_process = true;
+ process_manager_->AllocateWorkerProcess(
+ 1, pattern_, script_url_,
+ base::Bind(&DidAllocateWorkerProcess, run_loop.QuitClosure(), &status,
+ &process_id, &is_new_process));
+ run_loop.Run();
+
+ // Allocating a process in shutdown should abort.
+ EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
+ EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, process_id);
+ EXPECT_FALSE(is_new_process);
+ EXPECT_TRUE(process_manager_->instance_info_.empty());
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host.cc b/chromium/content/browser/service_worker/service_worker_provider_host.cc
index 50d4f4eb835..1d79f5290b0 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.cc
@@ -4,6 +4,8 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
+#include <utility>
+
#include "base/guid.h"
#include "base/stl_util.h"
#include "base/time/time.h"
@@ -26,6 +28,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/child_process_host.h"
namespace content {
@@ -45,7 +48,8 @@ ServiceWorkerClientInfo FocusOnUIThread(int render_process_id,
FrameTreeNode* frame_tree_node = render_frame_host->frame_tree_node();
// Focus the frame in the frame tree node, in case it has changed.
- frame_tree_node->frame_tree()->SetFocusedFrame(frame_tree_node);
+ frame_tree_node->frame_tree()->SetFocusedFrame(
+ frame_tree_node, render_frame_host->GetSiteInstance());
// Focus the frame's view to make sure the frame is now considered as focused.
render_frame_host->GetView()->Focus();
@@ -57,6 +61,11 @@ ServiceWorkerClientInfo FocusOnUIThread(int render_process_id,
render_frame_id);
}
+// PlzNavigate
+// Next ServiceWorkerProviderHost ID for navigations, starts at -2 and keeps
+// going down.
+int g_next_navigation_provider_id = -2;
+
} // anonymous namespace
ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
@@ -68,6 +77,18 @@ ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() {
}
+// static
+scoped_ptr<ServiceWorkerProviderHost>
+ServiceWorkerProviderHost::PreCreateNavigationHost(
+ base::WeakPtr<ServiceWorkerContextCore> context) {
+ CHECK(IsBrowserSideNavigationEnabled());
+ // Generate a new browser-assigned id for the host.
+ int provider_id = g_next_navigation_provider_id--;
+ return scoped_ptr<ServiceWorkerProviderHost>(new ServiceWorkerProviderHost(
+ ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE, provider_id,
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW, context, nullptr));
+}
+
ServiceWorkerProviderHost::ServiceWorkerProviderHost(
int render_process_id,
int route_id,
@@ -84,9 +105,13 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost(
context_(context),
dispatcher_host_(dispatcher_host),
allow_association_(true) {
- DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_);
DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_type_);
DCHECK_NE(SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME, provider_type_);
+
+ // PlzNavigate
+ CHECK(render_process_id != ChildProcessHost::kInvalidUniqueID ||
+ IsBrowserSideNavigationEnabled());
+
if (provider_type_ == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) {
// Actual thread id is set when the service worker context gets started.
render_thread_id_ = kInvalidEmbeddedWorkerThreadId;
@@ -193,7 +218,7 @@ void ServiceWorkerProviderHost::SetControllerVersionAttribute(
notify_controllerchange));
}
-bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
+bool ServiceWorkerProviderHost::SetHostedVersionId(int64_t version_id) {
if (!context_)
return true; // System is shutting down.
if (active_version())
@@ -300,7 +325,7 @@ void ServiceWorkerProviderHost::RemoveMatchingRegistration(
void ServiceWorkerProviderHost::AddAllMatchingRegistrations() {
DCHECK(context_);
- const std::map<int64, ServiceWorkerRegistration*>& registrations =
+ const std::map<int64_t, ServiceWorkerRegistration*>& registrations =
context_->GetLiveRegistrations();
for (const auto& key_registration : registrations) {
ServiceWorkerRegistration* registration = key_registration.second;
@@ -371,7 +396,7 @@ ServiceWorkerProviderHost::GetOrCreateServiceWorkerHandle(
scoped_ptr<ServiceWorkerHandle> new_handle(
ServiceWorkerHandle::Create(context_, AsWeakPtr(), version));
handle = new_handle.get();
- dispatcher_host_->RegisterServiceWorkerHandle(new_handle.Pass());
+ dispatcher_host_->RegisterServiceWorkerHandle(std::move(new_handle));
return handle->GetObjectInfo();
}
@@ -386,7 +411,7 @@ bool ServiceWorkerProviderHost::CanAssociateRegistration(
return true;
}
-void ServiceWorkerProviderHost::PostMessage(
+void ServiceWorkerProviderHost::PostMessageToClient(
ServiceWorkerVersion* version,
const base::string16& message,
const std::vector<TransferredMessagePort>& sent_message_ports) {
@@ -516,29 +541,27 @@ void ServiceWorkerProviderHost::CompleteCrossSiteTransfer(
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, new_process_id);
DCHECK_NE(MSG_ROUTING_NONE, new_frame_id);
- render_process_id_ = new_process_id;
- route_id_ = new_frame_id;
render_thread_id_ = kDocumentMainThreadId;
provider_id_ = new_provider_id;
provider_type_ = new_provider_type;
- dispatcher_host_ = new_dispatcher_host;
- for (const GURL& pattern : associated_patterns_)
- IncreaseProcessReference(pattern);
+ FinalizeInitialization(new_process_id, new_frame_id, new_dispatcher_host);
+}
- for (auto& key_registration : matching_registrations_)
- IncreaseProcessReference(key_registration.second->pattern());
+// PlzNavigate
+void ServiceWorkerProviderHost::CompleteNavigationInitialized(
+ int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host) {
+ CHECK(IsBrowserSideNavigationEnabled());
+ DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
+ DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type_);
+ DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
- if (associated_registration_.get()) {
- SendAssociateRegistrationMessage();
- if (dispatcher_host_ && associated_registration_->active_version()) {
- Send(new ServiceWorkerMsg_SetControllerServiceWorker(
- render_thread_id_, provider_id(),
- GetOrCreateServiceWorkerHandle(
- associated_registration_->active_version()),
- false /* shouldNotifyControllerChange */));
- }
- }
+ DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
+ DCHECK_NE(MSG_ROUTING_NONE, frame_routing_id);
+
+ FinalizeInitialization(process_id, frame_routing_id, dispatcher_host);
}
void ServiceWorkerProviderHost::SendUpdateFoundMessage(
@@ -587,8 +610,8 @@ void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
attrs.active = GetOrCreateServiceWorkerHandle(active_version);
Send(new ServiceWorkerMsg_SetVersionAttributes(
- render_thread_id_, provider_id_, registration_handle_id,
- changed_mask.changed(), attrs));
+ render_thread_id_, registration_handle_id, changed_mask.changed(),
+ attrs));
}
void ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage(
@@ -684,4 +707,30 @@ void ServiceWorkerProviderHost::Send(IPC::Message* message) const {
dispatcher_host_->Send(message);
}
+void ServiceWorkerProviderHost::FinalizeInitialization(
+ int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host) {
+ render_process_id_ = process_id;
+ route_id_ = frame_routing_id;
+ dispatcher_host_ = dispatcher_host;
+
+ for (const GURL& pattern : associated_patterns_)
+ IncreaseProcessReference(pattern);
+
+ for (auto& key_registration : matching_registrations_)
+ IncreaseProcessReference(key_registration.second->pattern());
+
+ if (associated_registration_.get()) {
+ SendAssociateRegistrationMessage();
+ if (dispatcher_host_ && associated_registration_->active_version()) {
+ Send(new ServiceWorkerMsg_SetControllerServiceWorker(
+ render_thread_id_, provider_id(),
+ GetOrCreateServiceWorkerHandle(
+ associated_registration_->active_version()),
+ false /* shouldNotifyControllerChange */));
+ }
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host.h b/chromium/content/browser/service_worker/service_worker_provider_host.h
index 70ed3495208..2748e293810 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.h
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.h
@@ -5,10 +5,14 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <set>
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_registration.h"
@@ -52,6 +56,13 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
using GetRegistrationForReadyCallback =
base::Callback<void(ServiceWorkerRegistration* reigstration)>;
+ // PlzNavigate
+ // Used to pre-create a ServiceWorkerProviderHost for a navigation. The
+ // ServiceWorkerNetworkProvider will later be created in the renderer, should
+ // the navigation succeed.
+ static scoped_ptr<ServiceWorkerProviderHost> PreCreateNavigationHost(
+ base::WeakPtr<ServiceWorkerContextCore> context);
+
// When this provider host is for a Service Worker context, |route_id| is
// MSG_ROUTING_NONE. When this provider host is for a Document,
// |route_id| is the frame ID of the Document. When this provider host is for
@@ -124,7 +135,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// Returns false if the version is not in the expected STARTING in our
// process state. That would be indicative of a bad IPC message.
- bool SetHostedVersionId(int64 versions_id);
+ bool SetHostedVersionId(int64_t versions_id);
// Returns a handler for a request, the handler may return NULL if
// the request doesn't require special handling.
@@ -159,7 +170,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
bool IsContextAlive();
// Dispatches message event to the document.
- void PostMessage(
+ void PostMessageToClient(
ServiceWorkerVersion* version,
const base::string16& message,
const std::vector<TransferredMessagePort>& sent_message_ports);
@@ -202,6 +213,13 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
return dispatcher_host_;
}
+ // PlzNavigate
+ // Completes initialization of provider hosts used for navigation requests.
+ void CompleteNavigationInitialized(
+ int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host);
+
// Sends event messages to the renderer. Events for the worker are queued up
// until the worker thread id is known via SetReadyToSendMessagesToWorker().
void SendUpdateFoundMessage(
@@ -289,6 +307,11 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
bool IsReadyToSendMessages() const;
void Send(IPC::Message* message) const;
+ // Finalizes cross-site transfers and navigation-initalized hosts.
+ void FinalizeInitialization(int process_id,
+ int frame_routing_id,
+ ServiceWorkerDispatcherHost* dispatcher_host);
+
std::string client_uuid_;
int render_process_id_;
int route_id_;
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc b/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc
index 79a8ac164eb..642260b019f 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -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 "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/thread_task_runner_handle.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
@@ -16,8 +16,6 @@
namespace content {
-static const int kRenderProcessId = 33; // Dummy process ID for testing.
-
class ServiceWorkerProviderHostTest : public testing::Test {
protected:
ServiceWorkerProviderHostTest()
@@ -25,8 +23,7 @@ class ServiceWorkerProviderHostTest : public testing::Test {
~ServiceWorkerProviderHostTest() override {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
context_ = helper_->context();
script_url_ = GURL("http://www.example.com/service_worker.js");
registration1_ = new ServiceWorkerRegistration(
@@ -36,12 +33,14 @@ class ServiceWorkerProviderHostTest : public testing::Test {
// Prepare provider hosts (for the same process).
scoped_ptr<ServiceWorkerProviderHost> host1(new ServiceWorkerProviderHost(
- kRenderProcessId, MSG_ROUTING_NONE, 1 /* provider_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW, context_->AsWeakPtr(), NULL));
+ helper_->mock_render_process_id(), MSG_ROUTING_NONE,
+ 1 /* provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
+ context_->AsWeakPtr(), NULL));
host1->SetDocumentUrl(GURL("http://www.example.com/example1.html"));
scoped_ptr<ServiceWorkerProviderHost> host2(new ServiceWorkerProviderHost(
- kRenderProcessId, MSG_ROUTING_NONE, 2 /* provider_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW, context_->AsWeakPtr(), NULL));
+ helper_->mock_render_process_id(), MSG_ROUTING_NONE,
+ 2 /* provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
+ context_->AsWeakPtr(), NULL));
host2->SetDocumentUrl(GURL("http://www.example.com/example2.html"));
provider_host1_ = host1->AsWeakPtr();
provider_host2_ = host2->AsWeakPtr();
diff --git a/chromium/content/browser/service_worker/service_worker_quota_client.h b/chromium/content/browser/service_worker/service_worker_quota_client.h
index a1cf91ddb80..3c6f84fb969 100644
--- a/chromium/content/browser/service_worker/service_worker_quota_client.h
+++ b/chromium/content/browser/service_worker/service_worker_quota_client.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_QUOTA_CLIENT_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_QUOTA_CLIENT_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "storage/browser/quota/quota_client.h"
diff --git a/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc b/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc
index aecf3900392..bd9844b327e 100644
--- a/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc
@@ -28,40 +28,21 @@ ServiceWorkerReadFromCacheJob::ServiceWorkerReadFromCacheJob(
ResourceType resource_type,
base::WeakPtr<ServiceWorkerContextCore> context,
const scoped_refptr<ServiceWorkerVersion>& version,
- int64 response_id)
+ int64_t resource_id)
: net::URLRequestJob(request, network_delegate),
resource_type_(resource_type),
+ resource_id_(resource_id),
context_(context),
version_(version),
- response_id_(response_id),
- has_been_killed_(false),
weak_factory_(this) {}
ServiceWorkerReadFromCacheJob::~ServiceWorkerReadFromCacheJob() {
}
void ServiceWorkerReadFromCacheJob::Start() {
- TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
- "ServiceWorkerReadFromCacheJob::ReadInfo",
- this,
- "URL", request_->url().spec());
- if (!context_) {
- NotifyStartError(net::URLRequestStatus(
- net::URLRequestStatus::FAILED, net::ERR_FAILED));
- return;
- }
-
- // Create a response reader and start reading the headers,
- // we'll continue when thats done.
- if (is_main_script())
- version_->embedded_worker()->OnScriptReadStarted();
- reader_ = context_->storage()->CreateResponseReader(response_id_);
- http_info_io_buffer_ = new HttpResponseInfoIOBuffer;
- reader_->ReadInfo(
- http_info_io_buffer_.get(),
- base::Bind(&ServiceWorkerReadFromCacheJob::OnReadInfoComplete,
- weak_factory_.GetWeakPtr()));
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&ServiceWorkerReadFromCacheJob::StartAsync,
+ weak_factory_.GetWeakPtr()));
}
void ServiceWorkerReadFromCacheJob::Kill() {
@@ -71,7 +52,7 @@ void ServiceWorkerReadFromCacheJob::Kill() {
has_been_killed_ = true;
reader_.reset();
context_.reset();
- http_info_io_buffer_ = NULL;
+ http_info_io_buffer_ = nullptr;
http_info_.reset();
range_response_info_.reset();
net::URLRequestJob::Kill();
@@ -123,39 +104,60 @@ void ServiceWorkerReadFromCacheJob::SetExtraRequestHeaders(
range_requested_ = ranges[0];
}
-bool ServiceWorkerReadFromCacheJob::ReadRawData(
- net::IOBuffer* buf,
- int buf_size,
- int *bytes_read) {
+int ServiceWorkerReadFromCacheJob::ReadRawData(net::IOBuffer* buf,
+ int buf_size) {
DCHECK_NE(buf_size, 0);
- DCHECK(bytes_read);
DCHECK(!reader_->IsReadPending());
TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
"ServiceWorkerReadFromCacheJob::ReadRawData",
this,
"URL", request_->url().spec());
- reader_->ReadData(
- buf, buf_size, base::Bind(&ServiceWorkerReadFromCacheJob::OnReadComplete,
- weak_factory_.GetWeakPtr()));
+ reader_->ReadData(buf, buf_size,
+ base::Bind(&ServiceWorkerReadFromCacheJob::OnReadComplete,
+ weak_factory_.GetWeakPtr()));
+ return net::ERR_IO_PENDING;
+}
+
+void ServiceWorkerReadFromCacheJob::StartAsync() {
+ TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
+ "ServiceWorkerReadFromCacheJob::ReadInfo", this,
+ "URL", request_->url().spec());
+ if (!context_) {
+ // NotifyStartError is not safe to call synchronously in Start.
+ NotifyStartError(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
+ return;
+ }
+
+ // Create a response reader and start reading the headers,
+ // we'll continue when thats done.
+ if (is_main_script())
+ version_->embedded_worker()->OnScriptReadStarted();
+ reader_ = context_->storage()->CreateResponseReader(resource_id_);
+ http_info_io_buffer_ = new HttpResponseInfoIOBuffer;
+ reader_->ReadInfo(
+ http_info_io_buffer_.get(),
+ base::Bind(&ServiceWorkerReadFromCacheJob::OnReadInfoComplete,
+ weak_factory_.GetWeakPtr()));
SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
- return false;
}
const net::HttpResponseInfo* ServiceWorkerReadFromCacheJob::http_info() const {
if (!http_info_)
- return NULL;
+ return nullptr;
if (range_response_info_)
return range_response_info_.get();
return http_info_.get();
}
void ServiceWorkerReadFromCacheJob::OnReadInfoComplete(int result) {
- scoped_refptr<ServiceWorkerReadFromCacheJob> protect(this);
if (!http_info_io_buffer_->http_info) {
DCHECK_LT(result, 0);
ServiceWorkerMetrics::CountReadResponseResult(
ServiceWorkerMetrics::READ_HEADERS_ERROR);
Done(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
+ NotifyStartError(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
return;
}
DCHECK_GE(result, 0);
@@ -163,7 +165,7 @@ void ServiceWorkerReadFromCacheJob::OnReadInfoComplete(int result) {
http_info_.reset(http_info_io_buffer_->http_info.release());
if (is_range_request())
SetupRangeResponse(http_info_io_buffer_->response_data_size);
- http_info_io_buffer_ = NULL;
+ http_info_io_buffer_ = nullptr;
if (request_->url() == version_->script_url())
version_->SetMainScriptHttpResponseInfo(*http_info_);
TRACE_EVENT_ASYNC_END1("ServiceWorker",
@@ -209,23 +211,22 @@ void ServiceWorkerReadFromCacheJob::Done(const net::URLRequestStatus& status) {
}
if (is_main_script())
version_->embedded_worker()->OnScriptReadFinished();
- NotifyDone(status);
}
void ServiceWorkerReadFromCacheJob::OnReadComplete(int result) {
ServiceWorkerMetrics::ReadResponseResult check_result;
- if (result == 0) {
+
+ if (result >= 0) {
check_result = ServiceWorkerMetrics::READ_OK;
- Done(net::URLRequestStatus());
- } else if (result < 0) {
+ if (result == 0)
+ Done(net::URLRequestStatus());
+ } else {
check_result = ServiceWorkerMetrics::READ_DATA_ERROR;
Done(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
- } else {
- check_result = ServiceWorkerMetrics::READ_OK;
- SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status
}
+
ServiceWorkerMetrics::CountReadResponseResult(check_result);
- NotifyReadComplete(result);
+ ReadRawDataComplete(result);
TRACE_EVENT_ASYNC_END1("ServiceWorker",
"ServiceWorkerReadFromCacheJob::ReadRawData",
this,
diff --git a/chromium/content/browser/service_worker/service_worker_read_from_cache_job.h b/chromium/content/browser/service_worker/service_worker_read_from_cache_job.h
index 9c3fa855a21..41b40caa663 100644
--- a/chromium/content/browser/service_worker/service_worker_read_from_cache_job.h
+++ b/chromium/content/browser/service_worker/service_worker_read_from_cache_job.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_READ_FROM_CACHE_JOB_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_READ_FROM_CACHE_JOB_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
@@ -33,10 +36,11 @@ class CONTENT_EXPORT ServiceWorkerReadFromCacheJob
ResourceType resource_type,
base::WeakPtr<ServiceWorkerContextCore> context,
const scoped_refptr<ServiceWorkerVersion>& version,
- int64 response_id);
+ int64_t resource_id);
+ ~ServiceWorkerReadFromCacheJob() override;
private:
- ~ServiceWorkerReadFromCacheJob() override;
+ friend class ServiceWorkerReadFromCacheJobTest;
bool is_main_script() const {
return resource_type_ == RESOURCE_TYPE_SERVICE_WORKER;
@@ -51,28 +55,31 @@ class CONTENT_EXPORT ServiceWorkerReadFromCacheJob
void GetResponseInfo(net::HttpResponseInfo* info) override;
int GetResponseCode() const override;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;
// Reader completion callbacks.
void OnReadInfoComplete(int result);
void OnReadComplete(int result);
// Helpers
+ void StartAsync();
const net::HttpResponseInfo* http_info() const;
bool is_range_request() const { return range_requested_.IsValid(); }
void SetupRangeResponse(int response_data_size);
void Done(const net::URLRequestStatus& status);
- ResourceType resource_type_;
+ const ResourceType resource_type_;
+ const int64_t resource_id_;
+
base::WeakPtr<ServiceWorkerContextCore> context_;
scoped_refptr<ServiceWorkerVersion> version_;
- int64 response_id_;
scoped_ptr<ServiceWorkerResponseReader> reader_;
scoped_refptr<HttpResponseInfoIOBuffer> http_info_io_buffer_;
scoped_ptr<net::HttpResponseInfo> http_info_;
net::HttpByteRange range_requested_;
scoped_ptr<net::HttpResponseInfo> range_response_info_;
- bool has_been_killed_;
+ bool has_been_killed_ = false;
+
base::WeakPtrFactory<ServiceWorkerReadFromCacheJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerReadFromCacheJob);
diff --git a/chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
new file mode 100644
index 00000000000..aa7508b7520
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
@@ -0,0 +1,234 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_read_from_cache_job.h"
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "content/browser/fileapi/mock_url_request_delegate.h"
+#include "content/browser/service_worker/embedded_worker_test_helper.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/browser/service_worker/service_worker_version.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/base/io_buffer.h"
+#include "net/base/test_completion_callback.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_job_factory_impl.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+const int64_t kRegistrationId = 1;
+const int64_t kVersionId = 2;
+const int64_t kMainScriptResourceId = 10;
+const int64_t kImportedScriptResourceId = 11;
+const int64_t kResourceSize = 100;
+
+void DidStoreRegistration(ServiceWorkerStatusCode* status_out,
+ const base::Closure& quit_closure,
+ ServiceWorkerStatusCode status) {
+ *status_out = status;
+ quit_closure.Run();
+}
+
+void DidFindRegistration(
+ ServiceWorkerStatusCode* status_out,
+ const base::Closure& quit_closure,
+ ServiceWorkerStatusCode status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ *status_out = status;
+ quit_closure.Run();
+}
+
+} // namespace
+
+class ServiceWorkerReadFromCacheJobTest : public testing::Test {
+ public:
+ ServiceWorkerReadFromCacheJobTest()
+ : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
+ main_script_(kMainScriptResourceId,
+ GURL("http://example.com/main.js"),
+ kResourceSize),
+ imported_script_(kImportedScriptResourceId,
+ GURL("http://example.com/imported.js"),
+ kResourceSize) {}
+ ~ServiceWorkerReadFromCacheJobTest() override {}
+
+ void SetUp() override {
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
+ InitializeStorage();
+
+ url_request_context_.reset(new net::URLRequestContext);
+ url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl);
+ url_request_context_->set_job_factory(url_request_job_factory_.get());
+ }
+
+ void InitializeStorage() {
+ base::RunLoop run_loop;
+ context()->storage()->LazyInitialize(run_loop.QuitClosure());
+ run_loop.Run();
+
+ // Populate a registration in the storage.
+ registration_ =
+ new ServiceWorkerRegistration(GURL("http://example.com/scope"),
+ kRegistrationId, context()->AsWeakPtr());
+ version_ = new ServiceWorkerVersion(registration_.get(), main_script_.url,
+ kVersionId, context()->AsWeakPtr());
+ std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+ resources.push_back(main_script_);
+ resources.push_back(imported_script_);
+ version_->script_cache_map()->SetResources(resources);
+ ASSERT_EQ(SERVICE_WORKER_OK, StoreRegistration());
+ ASSERT_TRUE(WriteResource(main_script_.resource_id));
+ ASSERT_TRUE(WriteResource(imported_script_.resource_id));
+ }
+
+ bool WriteResource(int64_t resource_id) {
+ const char kHttpHeaders[] = "HTTP/1.0 200 OK\0Content-Length: 5\0\0";
+ const char kHttpBody[] = "Hello";
+ const int length = arraysize(kHttpBody);
+ std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
+ scoped_refptr<net::IOBuffer> body(new net::WrappedIOBuffer(kHttpBody));
+
+ scoped_ptr<ServiceWorkerResponseWriter> writer =
+ context()->storage()->CreateResponseWriter(resource_id);
+
+ scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
+ info->request_time = base::Time::Now();
+ info->response_time = base::Time::Now();
+ info->was_cached = false;
+ info->headers = new net::HttpResponseHeaders(headers);
+ scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
+ new HttpResponseInfoIOBuffer(info.release());
+ {
+ net::TestCompletionCallback cb;
+ writer->WriteInfo(info_buffer.get(), cb.callback());
+ int rv = cb.WaitForResult();
+ if (rv < 0)
+ return false;
+ }
+ {
+ net::TestCompletionCallback cb;
+ writer->WriteData(body.get(), length, cb.callback());
+ int rv = cb.WaitForResult();
+ if (rv < 0)
+ return false;
+ }
+ return true;
+ }
+
+ ServiceWorkerStatusCode StoreRegistration() {
+ base::RunLoop run_loop;
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ context()->storage()->StoreRegistration(
+ registration_.get(), version_.get(),
+ base::Bind(&DidStoreRegistration, &status, run_loop.QuitClosure()));
+ run_loop.Run();
+ return status;
+ }
+
+ ServiceWorkerStatusCode FindRegistration() {
+ base::RunLoop run_loop;
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ context()->storage()->FindRegistrationForId(
+ registration_->id(), registration_->pattern().GetOrigin(),
+ base::Bind(&DidFindRegistration, &status, run_loop.QuitClosure()));
+ run_loop.Run();
+ return status;
+ }
+
+ void StartAndWaitForJob(
+ const scoped_ptr<ServiceWorkerReadFromCacheJob>& job) {
+ job->Start();
+ // MockURLRequestDelegate quits the loop when the request is completed.
+ base::RunLoop().RunUntilIdle();
+ }
+
+ ServiceWorkerStatusCode DeduceStartWorkerFailureReason(
+ ServiceWorkerStatusCode default_code) {
+ return version_->DeduceStartWorkerFailureReason(default_code);
+ }
+
+ ServiceWorkerContextCore* context() const { return helper_->context(); }
+
+ protected:
+ TestBrowserThreadBundle thread_bundle_;
+ scoped_ptr<EmbeddedWorkerTestHelper> helper_;
+
+ scoped_refptr<ServiceWorkerRegistration> registration_;
+ scoped_refptr<ServiceWorkerVersion> version_;
+ ServiceWorkerDatabase::ResourceRecord main_script_;
+ ServiceWorkerDatabase::ResourceRecord imported_script_;
+
+ scoped_ptr<net::URLRequestContext> url_request_context_;
+ scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
+ MockURLRequestDelegate delegate_;
+};
+
+TEST_F(ServiceWorkerReadFromCacheJobTest, ReadMainScript) {
+ // Read the main script from the diskcache.
+ scoped_ptr<net::URLRequest> request = url_request_context_->CreateRequest(
+ main_script_.url, net::DEFAULT_PRIORITY, &delegate_);
+ scoped_ptr<ServiceWorkerReadFromCacheJob> job(
+ new ServiceWorkerReadFromCacheJob(
+ request.get(), nullptr /* NetworkDelegate */,
+ RESOURCE_TYPE_SERVICE_WORKER, context()->AsWeakPtr(), version_,
+ main_script_.resource_id));
+ StartAndWaitForJob(job);
+
+ EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
+ EXPECT_EQ(0, request->status().error());
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ DeduceStartWorkerFailureReason(SERVICE_WORKER_OK));
+}
+
+TEST_F(ServiceWorkerReadFromCacheJobTest, ReadImportedScript) {
+ // Read the imported script from the diskcache.
+ scoped_ptr<net::URLRequest> request = url_request_context_->CreateRequest(
+ imported_script_.url, net::DEFAULT_PRIORITY, &delegate_);
+ scoped_ptr<ServiceWorkerReadFromCacheJob> job(
+ new ServiceWorkerReadFromCacheJob(
+ request.get(), nullptr /* NetworkDelegate */, RESOURCE_TYPE_SCRIPT,
+ context()->AsWeakPtr(), version_, imported_script_.resource_id));
+ StartAndWaitForJob(job);
+
+ EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
+ EXPECT_EQ(0, request->status().error());
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ DeduceStartWorkerFailureReason(SERVICE_WORKER_OK));
+}
+
+TEST_F(ServiceWorkerReadFromCacheJobTest, ResourceNotFound) {
+ ASSERT_EQ(SERVICE_WORKER_OK, FindRegistration());
+
+ // Try to read a nonexistent resource from the diskcache.
+ scoped_ptr<net::URLRequest> request = url_request_context_->CreateRequest(
+ GURL("http://example.com/nonexistent"), net::DEFAULT_PRIORITY,
+ &delegate_);
+ const int64_t kNonexistentResourceId = 100;
+ scoped_ptr<ServiceWorkerReadFromCacheJob> job(
+ new ServiceWorkerReadFromCacheJob(
+ request.get(), nullptr /* NetworkDelegate */,
+ RESOURCE_TYPE_SERVICE_WORKER, context()->AsWeakPtr(), version_,
+ kNonexistentResourceId));
+ StartAndWaitForJob(job);
+
+ EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
+ EXPECT_EQ(net::ERR_CACHE_MISS, request->status().error());
+ EXPECT_EQ(SERVICE_WORKER_ERROR_DISK_CACHE,
+ DeduceStartWorkerFailureReason(SERVICE_WORKER_OK));
+
+ // The version should be doomed by the job.
+ EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
+ EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND, FindRegistration());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_register_job.cc b/chromium/content/browser/service_worker/service_worker_register_job.cc
index 60dc34b42a1..69f5acdcb9c 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_register_job.cc
@@ -4,6 +4,8 @@
#include "content/browser/service_worker/service_worker_register_job.h"
+#include <stdint.h>
+
#include <vector>
#include "base/location.h"
@@ -274,8 +276,14 @@ void ServiceWorkerRegisterJob::ContinueWithUpdate(
void ServiceWorkerRegisterJob::RegisterAndContinue() {
SetPhase(REGISTER);
- set_registration(new ServiceWorkerRegistration(
- pattern_, context_->storage()->NewRegistrationId(), context_));
+ int64_t registration_id = context_->storage()->NewRegistrationId();
+ if (registration_id == kInvalidServiceWorkerRegistrationId) {
+ Complete(SERVICE_WORKER_ERROR_ABORT);
+ return;
+ }
+
+ set_registration(
+ new ServiceWorkerRegistration(pattern_, registration_id, context_));
AddRegistrationToMatchingProviderHosts(registration());
UpdateAndContinue();
}
@@ -325,12 +333,16 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() {
SetPhase(UPDATE);
context_->storage()->NotifyInstallingRegistration(registration());
+ int64_t version_id = context_->storage()->NewVersionId();
+ if (version_id == kInvalidServiceWorkerVersionId) {
+ Complete(SERVICE_WORKER_ERROR_ABORT);
+ return;
+ }
+
// "Let worker be a new ServiceWorker object..." and start
// the worker.
- set_new_version(new ServiceWorkerVersion(registration(),
- script_url_,
- context_->storage()->NewVersionId(),
- context_));
+ set_new_version(new ServiceWorkerVersion(registration(), script_url_,
+ version_id, context_));
new_version()->set_force_bypass_cache_for_scripts(force_bypass_cache_);
new_version()->set_skip_script_comparison(skip_script_comparison_);
new_version()->StartWorker(
diff --git a/chromium/content/browser/service_worker/service_worker_register_job.h b/chromium/content/browser/service_worker/service_worker_register_job.h
index 848a2718504..15033bcc455 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.h
+++ b/chromium/content/browser/service_worker/service_worker_register_job.h
@@ -7,6 +7,7 @@
#include <vector>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/service_worker_register_job_base.h"
@@ -120,8 +121,6 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
void OnStoreRegistrationComplete(ServiceWorkerStatusCode status);
void InstallAndContinue();
void OnInstallFinished(ServiceWorkerStatusCode status);
- void ActivateAndContinue();
- void OnActivateFinished(ServiceWorkerStatusCode status);
void Complete(ServiceWorkerStatusCode status);
void Complete(ServiceWorkerStatusCode status,
const std::string& status_message);
diff --git a/chromium/content/browser/service_worker/service_worker_registration.cc b/chromium/content/browser/service_worker/service_worker_registration.cc
index 6909f354f1e..6689ca4eb8f 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration.cc
@@ -4,6 +4,8 @@
#include "content/browser/service_worker/service_worker_registration.h"
+#include <vector>
+
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/browser/service_worker/service_worker_metrics.h"
@@ -25,7 +27,7 @@ ServiceWorkerVersionInfo GetVersionInfo(ServiceWorkerVersion* version) {
ServiceWorkerRegistration::ServiceWorkerRegistration(
const GURL& pattern,
- int64 registration_id,
+ int64_t registration_id,
base::WeakPtr<ServiceWorkerContextCore> context)
: pattern_(pattern),
registration_id_(registration_id),
@@ -37,6 +39,7 @@ ServiceWorkerRegistration::ServiceWorkerRegistration(
resources_total_size_bytes_(0),
context_(context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_NE(kInvalidServiceWorkerRegistrationId, registration_id);
DCHECK(context_);
context_->AddLiveRegistration(this);
}
@@ -68,12 +71,21 @@ void ServiceWorkerRegistration::RemoveListener(Listener* listener) {
void ServiceWorkerRegistration::NotifyRegistrationFailed() {
FOR_EACH_OBSERVER(Listener, listeners_, OnRegistrationFailed(this));
+ NotifyRegistrationFinished();
}
void ServiceWorkerRegistration::NotifyUpdateFound() {
FOR_EACH_OBSERVER(Listener, listeners_, OnUpdateFound(this));
}
+void ServiceWorkerRegistration::NotifyVersionAttributesChanged(
+ ChangedVersionAttributesMask mask) {
+ FOR_EACH_OBSERVER(Listener, listeners_,
+ OnVersionAttributesChanged(this, mask, GetInfo()));
+ if (mask.active_changed() || mask.waiting_changed())
+ NotifyRegistrationFinished();
+}
+
ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return ServiceWorkerRegistrationInfo(
@@ -103,8 +115,7 @@ void ServiceWorkerRegistration::SetActiveVersion(
active_version_->AddListener(this);
mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION);
- FOR_EACH_OBSERVER(Listener, listeners_,
- OnVersionAttributesChanged(this, mask, GetInfo()));
+ NotifyVersionAttributesChanged(mask);
}
void ServiceWorkerRegistration::SetWaitingVersion(
@@ -119,8 +130,7 @@ void ServiceWorkerRegistration::SetWaitingVersion(
waiting_version_ = version;
mask.add(ChangedVersionAttributesMask::WAITING_VERSION);
- FOR_EACH_OBSERVER(Listener, listeners_,
- OnVersionAttributesChanged(this, mask, GetInfo()));
+ NotifyVersionAttributesChanged(mask);
}
void ServiceWorkerRegistration::SetInstallingVersion(
@@ -134,8 +144,7 @@ void ServiceWorkerRegistration::SetInstallingVersion(
installing_version_ = version;
mask.add(ChangedVersionAttributesMask::INSTALLING_VERSION);
- FOR_EACH_OBSERVER(Listener, listeners_,
- OnVersionAttributesChanged(this, mask, GetInfo()));
+ NotifyVersionAttributesChanged(mask);
}
void ServiceWorkerRegistration::UnsetVersion(ServiceWorkerVersion* version) {
@@ -143,11 +152,8 @@ void ServiceWorkerRegistration::UnsetVersion(ServiceWorkerVersion* version) {
return;
ChangedVersionAttributesMask mask;
UnsetVersionInternal(version, &mask);
- if (mask.changed()) {
- ServiceWorkerRegistrationInfo info = GetInfo();
- FOR_EACH_OBSERVER(Listener, listeners_,
- OnVersionAttributesChanged(this, mask, info));
- }
+ if (mask.changed())
+ NotifyVersionAttributesChanged(mask);
}
void ServiceWorkerRegistration::UnsetVersionInternal(
@@ -232,29 +238,6 @@ void ServiceWorkerRegistration::AbortPendingClear(
most_recent_version));
}
-void ServiceWorkerRegistration::GetUserData(
- const std::string& key,
- const GetUserDataCallback& callback) {
- DCHECK(context_);
- context_->storage()->GetUserData(registration_id_, key, callback);
-}
-
-void ServiceWorkerRegistration::StoreUserData(
- const std::string& key,
- const std::string& data,
- const StatusCallback& callback) {
- DCHECK(context_);
- context_->storage()->StoreUserData(
- registration_id_, pattern().GetOrigin(), key, data, callback);
-}
-
-void ServiceWorkerRegistration::ClearUserData(
- const std::string& key,
- const StatusCallback& callback) {
- DCHECK(context_);
- context_->storage()->ClearUserData(registration_id_, key, callback);
-}
-
void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) {
if (!context_)
return;
@@ -335,11 +318,26 @@ void ServiceWorkerRegistration::DeleteVersion(
is_deleted_ = false;
} else {
is_uninstalled_ = true;
- FOR_EACH_OBSERVER(Listener, listeners_, OnRegistrationFailed(this));
+ NotifyRegistrationFailed();
}
}
}
+void ServiceWorkerRegistration::NotifyRegistrationFinished() {
+ std::vector<base::Closure> callbacks;
+ callbacks.swap(registration_finished_callbacks_);
+ for (const auto& callback : callbacks)
+ callback.Run();
+}
+
+void ServiceWorkerRegistration::RegisterRegistrationFinishedCallback(
+ const base::Closure& callback) {
+ // This should only be called if the registration is in progress.
+ DCHECK(!active_version() && !waiting_version() && !is_uninstalled() &&
+ !is_uninstalling());
+ registration_finished_callbacks_.push_back(callback);
+}
+
void ServiceWorkerRegistration::OnActivateEventFinished(
ServiceWorkerVersion* activating_version,
ServiceWorkerStatusCode status) {
@@ -370,27 +368,33 @@ void ServiceWorkerRegistration::Clear() {
if (context_)
context_->storage()->NotifyDoneUninstallingRegistration(this);
+ std::vector<scoped_refptr<ServiceWorkerVersion>> versions_to_doom;
ChangedVersionAttributesMask mask;
if (installing_version_.get()) {
- installing_version_->Doom();
- installing_version_ = NULL;
+ versions_to_doom.push_back(installing_version_);
+ installing_version_ = nullptr;
mask.add(ChangedVersionAttributesMask::INSTALLING_VERSION);
}
if (waiting_version_.get()) {
- waiting_version_->Doom();
- waiting_version_ = NULL;
+ versions_to_doom.push_back(waiting_version_);
+ waiting_version_ = nullptr;
mask.add(ChangedVersionAttributesMask::WAITING_VERSION);
}
if (active_version_.get()) {
- active_version_->Doom();
+ versions_to_doom.push_back(active_version_);
active_version_->RemoveListener(this);
- active_version_ = NULL;
+ active_version_ = nullptr;
mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION);
}
+
if (mask.changed()) {
- ServiceWorkerRegistrationInfo info = GetInfo();
- FOR_EACH_OBSERVER(Listener, listeners_,
- OnVersionAttributesChanged(this, mask, info));
+ NotifyVersionAttributesChanged(mask);
+
+ // Doom only after notifying attributes changed, because the spec requires
+ // the attributes to be cleared by the time the statechange event is
+ // dispatched.
+ for (const auto& version : versions_to_doom)
+ version->Doom();
}
FOR_EACH_OBSERVER(
diff --git a/chromium/content/browser/service_worker/service_worker_registration.h b/chromium/content/browser/service_worker/service_worker_registration.h
index 4a37e55f736..dab20434ce5 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.h
+++ b/chromium/content/browser/service_worker/service_worker_registration.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -50,10 +52,10 @@ class CONTENT_EXPORT ServiceWorkerRegistration
};
ServiceWorkerRegistration(const GURL& pattern,
- int64 registration_id,
+ int64_t registration_id,
base::WeakPtr<ServiceWorkerContextCore> context);
- int64 id() const { return registration_id_; }
+ int64_t id() const { return registration_id_; }
const GURL& pattern() const { return pattern_; }
bool is_deleted() const { return is_deleted_; }
@@ -90,6 +92,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
void RemoveListener(Listener* listener);
void NotifyRegistrationFailed();
void NotifyUpdateFound();
+ void NotifyVersionAttributesChanged(ChangedVersionAttributesMask mask);
ServiceWorkerRegistrationInfo GetInfo();
@@ -128,21 +131,13 @@ class CONTENT_EXPORT ServiceWorkerRegistration
base::Time last_update_check() const { return last_update_check_; }
void set_last_update_check(base::Time last) { last_update_check_ = last; }
- // Provide a storage mechanism to read/write arbitrary data associated with
- // this registration in the storage. Stored data is deleted when this
- // registration is deleted from the storage.
- void GetUserData(const std::string& key,
- const GetUserDataCallback& callback);
- void StoreUserData(const std::string& key,
- const std::string& data,
- const StatusCallback& callback);
- void ClearUserData(const std::string& key,
- const StatusCallback& callback);
-
// Unsets the version and deletes its resources. Also deletes this
// registration from storage if there is no longer a stored version.
void DeleteVersion(const scoped_refptr<ServiceWorkerVersion>& version);
+ void RegisterRegistrationFinishedCallback(const base::Closure& callback);
+ void NotifyRegistrationFinished();
+
bool force_update_on_page_load() const { return force_update_on_page_load_; }
void set_force_update_on_page_load(bool force_update_on_page_load) {
force_update_on_page_load_ = force_update_on_page_load;
@@ -175,7 +170,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
ServiceWorkerStatusCode status);
const GURL pattern_;
- const int64 registration_id_;
+ const int64_t registration_id_;
bool is_deleted_;
bool is_uninstalling_;
bool is_uninstalled_;
@@ -190,6 +185,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
scoped_refptr<ServiceWorkerVersion> installing_version_;
base::ObserverList<Listener> listeners_;
+ std::vector<base::Closure> registration_finished_callbacks_;
base::WeakPtr<ServiceWorkerContextCore> context_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistration);
diff --git a/chromium/content/browser/service_worker/service_worker_registration_handle.h b/chromium/content/browser/service_worker/service_worker_registration_handle.h
index bbe0cf8678d..6fb4e07dd25 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_handle.h
+++ b/chromium/content/browser/service_worker/service_worker_registration_handle.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
index f7a644c85f4..78bbf933e45 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -4,10 +4,14 @@
#include "content/browser/service_worker/service_worker_registration.h"
+#include <stdint.h>
+#include <utility>
+
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
+#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_registration_handle.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -22,25 +26,16 @@ class ServiceWorkerRegistrationTest : public testing::Test {
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
- new MockServiceWorkerDatabaseTaskManager(
- base::ThreadTaskRunnerHandle::Get()));
- context_.reset(
- new ServiceWorkerContextCore(base::FilePath(),
- database_task_manager.Pass(),
- base::ThreadTaskRunnerHandle::Get(),
- NULL,
- NULL,
- NULL,
- NULL));
- context_ptr_ = context_->AsWeakPtr();
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
}
void TearDown() override {
- context_.reset();
+ helper_.reset();
base::RunLoop().RunUntilIdle();
}
+ ServiceWorkerContextCore* context() { return helper_->context(); }
+
class RegistrationListener : public ServiceWorkerRegistration::Listener {
public:
RegistrationListener() {}
@@ -78,28 +73,25 @@ class ServiceWorkerRegistrationTest : public testing::Test {
ServiceWorkerRegistrationInfo observed_info_;
};
- protected:
- scoped_ptr<ServiceWorkerContextCore> context_;
- base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
+ private:
+ scoped_ptr<EmbeddedWorkerTestHelper> helper_;
TestBrowserThreadBundle thread_bundle_;
};
TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
const GURL kScope("http://www.example.not/");
const GURL kScript("http://www.example.not/service_worker.js");
- int64 kRegistrationId = 1L;
+ int64_t kRegistrationId = 1L;
scoped_refptr<ServiceWorkerRegistration> registration =
- new ServiceWorkerRegistration(
- kScope,
- kRegistrationId,
- context_ptr_);
+ new ServiceWorkerRegistration(kScope, kRegistrationId,
+ context()->AsWeakPtr());
- const int64 version_1_id = 1L;
- const int64 version_2_id = 2L;
+ const int64_t version_1_id = 1L;
+ const int64_t version_2_id = 2L;
scoped_refptr<ServiceWorkerVersion> version_1 = new ServiceWorkerVersion(
- registration.get(), kScript, version_1_id, context_ptr_);
+ registration.get(), kScript, version_1_id, context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> version_2 = new ServiceWorkerVersion(
- registration.get(), kScript, version_2_id, context_ptr_);
+ registration.get(), kScript, version_2_id, context()->AsWeakPtr());
RegistrationListener listener;
registration->AddListener(&listener);
@@ -156,16 +148,13 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
TEST_F(ServiceWorkerRegistrationTest, FailedRegistrationNoCrash) {
const GURL kScope("http://www.example.not/");
- int64 kRegistrationId = 1L;
+ int64_t kRegistrationId = 1L;
scoped_refptr<ServiceWorkerRegistration> registration =
- new ServiceWorkerRegistration(
- kScope,
- kRegistrationId,
- context_ptr_);
+ new ServiceWorkerRegistration(kScope, kRegistrationId,
+ context()->AsWeakPtr());
scoped_ptr<ServiceWorkerRegistrationHandle> handle(
new ServiceWorkerRegistrationHandle(
- context_ptr_,
- base::WeakPtr<ServiceWorkerProviderHost>(),
+ context()->AsWeakPtr(), base::WeakPtr<ServiceWorkerProviderHost>(),
registration.get()));
registration->NotifyRegistrationFailed();
// Don't crash when handle gets destructed.
diff --git a/chromium/content/browser/service_worker/service_worker_request_handler.cc b/chromium/content/browser/service_worker/service_worker_request_handler.cc
index 6d7d04b2e0a..05984a1a34b 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.cc
@@ -5,9 +5,12 @@
#include "content/browser/service_worker/service_worker_request_handler.h"
#include <string>
+#include <utility>
+#include "base/macros.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_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_url_request_job.h"
@@ -15,7 +18,10 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/resource_context.h"
+#include "content/public/common/browser_side_navigation_policy.h"
+#include "content/public/common/child_process_host.h"
#include "content/public/common/origin_util.h"
+#include "ipc/ipc_message.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_interceptor.h"
@@ -49,8 +55,91 @@ class ServiceWorkerRequestInterceptor
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestInterceptor);
};
+void FinalizeHandlerInitialization(
+ net::URLRequest* request,
+ ServiceWorkerProviderHost* provider_host,
+ storage::BlobStorageContext* blob_storage_context,
+ bool skip_service_worker,
+ FetchRequestMode request_mode,
+ FetchCredentialsMode credentials_mode,
+ FetchRedirectMode redirect_mode,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body) {
+ if (skip_service_worker) {
+ // TODO(horo): Does this work properly for PlzNavigate?
+ if (ServiceWorkerUtils::IsMainResourceType(resource_type)) {
+ provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url()));
+ provider_host->SetTopmostFrameUrl(request->first_party_for_cookies());
+ // A page load with skip_service_worker should be triggered by
+ // shift-reload, so retain all live matching registrations.
+ provider_host->AddAllMatchingRegistrations();
+ }
+ return;
+ }
+
+ scoped_ptr<ServiceWorkerRequestHandler> handler(
+ provider_host->CreateRequestHandler(
+ request_mode, credentials_mode, redirect_mode, resource_type,
+ request_context_type, frame_type, blob_storage_context->AsWeakPtr(),
+ body));
+ if (!handler)
+ return;
+
+ request->SetUserData(&kUserDataKey, handler.release());
+}
+
} // namespace
+// PlzNavigate
+void ServiceWorkerRequestHandler::InitializeForNavigation(
+ net::URLRequest* request,
+ ServiceWorkerNavigationHandleCore* navigation_handle_core,
+ storage::BlobStorageContext* blob_storage_context,
+ bool skip_service_worker,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body) {
+ CHECK(IsBrowserSideNavigationEnabled());
+
+ // Only create a handler when there is a ServiceWorkerNavigationHandlerCore
+ // to take ownership of a pre-created SeviceWorkerProviderHost.
+ if (!navigation_handle_core)
+ return;
+
+ // Create the handler even for insecure HTTP since it's used in the
+ // case of redirect to HTTPS.
+ if (!request->url().SchemeIsHTTPOrHTTPS() &&
+ !OriginCanAccessServiceWorkers(request->url())) {
+ return;
+ }
+
+ if (!navigation_handle_core->context_wrapper() ||
+ !navigation_handle_core->context_wrapper()->context()) {
+ return;
+ }
+
+ // Initialize the SWProviderHost.
+ scoped_ptr<ServiceWorkerProviderHost> provider_host =
+ ServiceWorkerProviderHost::PreCreateNavigationHost(
+ navigation_handle_core->context_wrapper()->context()->AsWeakPtr());
+
+ FinalizeHandlerInitialization(
+ request, provider_host.get(), blob_storage_context, skip_service_worker,
+ FETCH_REQUEST_MODE_SAME_ORIGIN, FETCH_CREDENTIALS_MODE_INCLUDE,
+ FetchRedirectMode::MANUAL_MODE, resource_type, request_context_type,
+ frame_type, body);
+
+ // Transfer ownership to the ServiceWorkerNavigationHandleCore.
+ // In the case of a successful navigation, the SWProviderHost will be
+ // transferred to its "final" destination in the OnProviderCreated handler. If
+ // the navigation fails, it will be destroyed along with the
+ // ServiceWorkerNavigationHandleCore.
+ navigation_handle_core->DidPreCreateProviderHost(std::move(provider_host));
+}
+
void ServiceWorkerRequestHandler::InitializeHandler(
net::URLRequest* request,
ServiceWorkerContextWrapper* context_wrapper,
@@ -82,26 +171,10 @@ void ServiceWorkerRequestHandler::InitializeHandler(
if (!provider_host || !provider_host->IsContextAlive())
return;
- if (skip_service_worker) {
- if (ServiceWorkerUtils::IsMainResourceType(resource_type)) {
- provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url()));
- provider_host->SetTopmostFrameUrl(request->first_party_for_cookies());
- // A page load with skip_service_worker should be triggered by
- // shift-reload, so retain all live matching registrations.
- provider_host->AddAllMatchingRegistrations();
- }
- return;
- }
-
- scoped_ptr<ServiceWorkerRequestHandler> handler(
- provider_host->CreateRequestHandler(
- request_mode, credentials_mode, redirect_mode, resource_type,
- request_context_type, frame_type, blob_storage_context->AsWeakPtr(),
- body));
- if (!handler)
- return;
-
- request->SetUserData(&kUserDataKey, handler.release());
+ FinalizeHandlerInitialization(request, provider_host, blob_storage_context,
+ skip_service_worker, request_mode,
+ credentials_mode, redirect_mode, resource_type,
+ request_context_type, frame_type, body);
}
ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler(
@@ -128,30 +201,30 @@ bool ServiceWorkerRequestHandler::IsControlledByServiceWorker(
void ServiceWorkerRequestHandler::PrepareForCrossSiteTransfer(
int old_process_id) {
+ CHECK(!IsBrowserSideNavigationEnabled());
if (!provider_host_ || !context_)
return;
old_process_id_ = old_process_id;
old_provider_id_ = provider_host_->provider_id();
- host_for_cross_site_transfer_ =
- context_->TransferProviderHostOut(old_process_id,
- provider_host_->provider_id());
+ host_for_cross_site_transfer_ = context_->TransferProviderHostOut(
+ old_process_id, provider_host_->provider_id());
DCHECK_EQ(provider_host_.get(), host_for_cross_site_transfer_.get());
}
void ServiceWorkerRequestHandler::CompleteCrossSiteTransfer(
int new_process_id, int new_provider_id) {
+ CHECK(!IsBrowserSideNavigationEnabled());
if (!host_for_cross_site_transfer_.get() || !context_)
return;
DCHECK_EQ(provider_host_.get(), host_for_cross_site_transfer_.get());
- context_->TransferProviderHostIn(
- new_process_id,
- new_provider_id,
- host_for_cross_site_transfer_.Pass());
+ context_->TransferProviderHostIn(new_process_id, new_provider_id,
+ std::move(host_for_cross_site_transfer_));
DCHECK_EQ(provider_host_->provider_id(), new_provider_id);
}
void ServiceWorkerRequestHandler::MaybeCompleteCrossSiteTransferInOldProcess(
int old_process_id) {
+ CHECK(!IsBrowserSideNavigationEnabled());
if (!host_for_cross_site_transfer_.get() || !context_ ||
old_process_id_ != old_process_id) {
return;
diff --git a/chromium/content/browser/service_worker/service_worker_request_handler.h b/chromium/content/browser/service_worker/service_worker_request_handler.h
index 2c14eb1b862..9f9c7eb40cf 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REQUEST_HANDLER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REQUEST_HANDLER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "base/time/time.h"
@@ -33,6 +33,7 @@ class ResourceContext;
class ResourceRequestBody;
class ServiceWorkerContextCore;
class ServiceWorkerContextWrapper;
+class ServiceWorkerNavigationHandleCore;
class ServiceWorkerProviderHost;
struct ResourceResponseInfo;
@@ -41,6 +42,19 @@ struct ResourceResponseInfo;
class CONTENT_EXPORT ServiceWorkerRequestHandler
: public base::SupportsUserData::Data {
public:
+ // PlzNavigate
+ // Attaches a newly created handler if the given |request| needs to be handled
+ // by ServiceWorker.
+ static void InitializeForNavigation(
+ net::URLRequest* request,
+ ServiceWorkerNavigationHandleCore* navigation_handle_core,
+ storage::BlobStorageContext* blob_storage_context,
+ bool skip_service_worker,
+ ResourceType resource_type,
+ RequestContextType request_context_type,
+ RequestContextFrameType frame_type,
+ scoped_refptr<ResourceRequestBody> body);
+
// Attaches a newly created handler if the given |request| needs to
// be handled by ServiceWorker.
// TODO(kinuko): While utilizing UserData to attach data to URLRequest
@@ -95,8 +109,6 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
void MaybeCompleteCrossSiteTransferInOldProcess(
int old_process_id);
- ServiceWorkerContextCore* context() const { return context_.get(); }
-
protected:
ServiceWorkerRequestHandler(
base::WeakPtr<ServiceWorkerContextCore> context,
diff --git a/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc b/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc
index eea2edf6f32..f2be209d1b6 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/service_worker/service_worker_request_handler.h"
+#include <utility>
+
#include "base/run_loop.h"
#include "content/browser/fileapi/mock_url_request_delegate.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
@@ -24,7 +26,6 @@ namespace content {
namespace {
-int kMockRenderProcessId = 1224;
int kMockProviderId = 1;
void EmptyCallback() {
@@ -38,8 +39,7 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), kMockRenderProcessId));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
// A new unstored registration/version.
registration_ = new ServiceWorkerRegistration(
@@ -51,11 +51,11 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
// An empty host.
scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
- kMockRenderProcessId, MSG_ROUTING_NONE, kMockProviderId,
+ helper_->mock_render_process_id(), MSG_ROUTING_NONE, kMockProviderId,
SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), nullptr));
host->SetDocumentUrl(GURL("http://host/scope/"));
provider_host_ = host->AsWeakPtr();
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
base::RunLoop().RunUntilIdle();
@@ -92,7 +92,7 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
request->set_method(method);
ServiceWorkerRequestHandler::InitializeHandler(
request.get(), context_wrapper(), &blob_storage_context_,
- kMockRenderProcessId, kMockProviderId, skip_service_worker,
+ helper_->mock_render_process_id(), kMockProviderId, skip_service_worker,
FETCH_REQUEST_MODE_NO_CORS, FETCH_CREDENTIALS_MODE_OMIT,
FetchRedirectMode::FOLLOW_MODE, resource_type,
REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
diff --git a/chromium/content/browser/service_worker/service_worker_script_cache_map.cc b/chromium/content/browser/service_worker/service_worker_script_cache_map.cc
index 16931391663..5a9f2b3de25 100644
--- a/chromium/content/browser/service_worker/service_worker_script_cache_map.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_cache_map.cc
@@ -24,23 +24,16 @@ ServiceWorkerScriptCacheMap::ServiceWorkerScriptCacheMap(
ServiceWorkerScriptCacheMap::~ServiceWorkerScriptCacheMap() {
}
-int64 ServiceWorkerScriptCacheMap::LookupResourceId(const GURL& url) {
+int64_t ServiceWorkerScriptCacheMap::LookupResourceId(const GURL& url) {
ResourceMap::const_iterator found = resource_map_.find(url);
if (found == resource_map_.end())
- return kInvalidServiceWorkerResponseId;
+ return kInvalidServiceWorkerResourceId;
return found->second.resource_id;
}
-int64 ServiceWorkerScriptCacheMap::LookupResourceSize(const GURL& url) {
- ResourceMap::const_iterator found = resource_map_.find(url);
- if (found == resource_map_.end())
- return kInvalidServiceWorkerResponseId;
- return found->second.size_bytes;
-}
-
-void ServiceWorkerScriptCacheMap::NotifyStartedCaching(
- const GURL& url, int64 resource_id) {
- DCHECK_EQ(kInvalidServiceWorkerResponseId, LookupResourceId(url));
+void ServiceWorkerScriptCacheMap::NotifyStartedCaching(const GURL& url,
+ int64_t resource_id) {
+ DCHECK_EQ(kInvalidServiceWorkerResourceId, LookupResourceId(url));
DCHECK(owner_->status() == ServiceWorkerVersion::NEW ||
owner_->status() == ServiceWorkerVersion::INSTALLING)
<< owner_->status();
@@ -48,22 +41,22 @@ void ServiceWorkerScriptCacheMap::NotifyStartedCaching(
return; // Our storage has been wiped via DeleteAndStartOver.
resource_map_[url] =
ServiceWorkerDatabase::ResourceRecord(resource_id, url, -1);
- context_->storage()->StoreUncommittedResponseId(resource_id);
+ context_->storage()->StoreUncommittedResourceId(resource_id);
}
void ServiceWorkerScriptCacheMap::NotifyFinishedCaching(
const GURL& url,
- int64 size_bytes,
+ int64_t size_bytes,
const net::URLRequestStatus& status,
const std::string& status_message) {
- DCHECK_NE(kInvalidServiceWorkerResponseId, LookupResourceId(url));
+ DCHECK_NE(kInvalidServiceWorkerResourceId, LookupResourceId(url));
DCHECK(owner_->status() == ServiceWorkerVersion::NEW ||
owner_->status() == ServiceWorkerVersion::INSTALLING ||
owner_->status() == ServiceWorkerVersion::REDUNDANT);
if (!context_)
return; // Our storage has been wiped via DeleteAndStartOver.
if (!status.is_success()) {
- context_->storage()->DoomUncommittedResponse(LookupResourceId(url));
+ context_->storage()->DoomUncommittedResource(LookupResourceId(url));
resource_map_.erase(url);
if (owner_->script_url() == url) {
main_script_status_ = status;
@@ -100,7 +93,7 @@ void ServiceWorkerScriptCacheMap::WriteMetadata(
const net::CompletionCallback& callback) {
ResourceMap::iterator found = resource_map_.find(url);
if (found == resource_map_.end() ||
- found->second.resource_id == kInvalidServiceWorkerResponseId) {
+ found->second.resource_id == kInvalidServiceWorkerResourceId) {
callback.Run(net::ERR_FILE_NOT_FOUND);
return;
}
@@ -114,7 +107,7 @@ void ServiceWorkerScriptCacheMap::WriteMetadata(
raw_writer->WriteMetadata(
buffer.get(), data.size(),
base::Bind(&ServiceWorkerScriptCacheMap::OnMetadataWritten,
- weak_factory_.GetWeakPtr(), Passed(&writer), callback));
+ weak_factory_.GetWeakPtr(), base::Passed(&writer), callback));
}
void ServiceWorkerScriptCacheMap::ClearMetadata(
diff --git a/chromium/content/browser/service_worker/service_worker_script_cache_map.h b/chromium/content/browser/service_worker/service_worker_script_cache_map.h
index 7d3366aa943..f2c27c6d0b4 100644
--- a/chromium/content/browser/service_worker/service_worker_script_cache_map.h
+++ b/chromium/content/browser/service_worker/service_worker_script_cache_map.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_CACHE_MAP_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_CACHE_MAP_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_database.h"
#include "content/common/content_export.h"
@@ -27,16 +30,13 @@ class ServiceWorkerResponseMetadataWriter;
// for a particular version's implicit script resources.
class CONTENT_EXPORT ServiceWorkerScriptCacheMap {
public:
- int64 LookupResourceId(const GURL& url);
- // A size of -1 means that we don't know the size yet
- // (it has not finished caching).
- int64 LookupResourceSize(const GURL& url);
+ int64_t LookupResourceId(const GURL& url);
// Used during the initial run of a new version to build the map
// of resources ids.
- void NotifyStartedCaching(const GURL& url, int64 resource_id);
+ void NotifyStartedCaching(const GURL& url, int64_t resource_id);
void NotifyFinishedCaching(const GURL& url,
- int64 size_bytes,
+ int64_t size_bytes,
const net::URLRequestStatus& status,
const std::string& status_message);
diff --git a/chromium/content/browser/service_worker/service_worker_storage.cc b/chromium/content/browser/service_worker/service_worker_storage.cc
index 8f0bba109da..fff872684d5 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage.cc
@@ -4,6 +4,9 @@
#include "content/browser/service_worker/service_worker_storage.h"
+#include <stddef.h>
+#include <utility>
+
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/message_loop/message_loop.h"
@@ -14,7 +17,6 @@
#include "base/trace_event/trace_event.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
-#include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -61,7 +63,6 @@ const base::FilePath::CharType kDatabaseName[] =
FILE_PATH_LITERAL("Database");
const base::FilePath::CharType kDiskCacheName[] =
FILE_PATH_LITERAL("ScriptCache");
-const base::FilePath::CharType kOldDiskCacheName[] = FILE_PATH_LITERAL("Cache");
const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
const int kMaxDiskCacheSize = 250 * 1024 * 1024;
@@ -85,10 +86,7 @@ ServiceWorkerStatusCode DatabaseStatusToStatusCode(
ServiceWorkerStorage::InitialData::InitialData()
: next_registration_id(kInvalidServiceWorkerRegistrationId),
next_version_id(kInvalidServiceWorkerVersionId),
- next_resource_id(kInvalidServiceWorkerResourceId),
- disk_cache_migration_needed(false),
- old_disk_cache_deletion_needed(false) {
-}
+ next_resource_id(kInvalidServiceWorkerResourceId) {}
ServiceWorkerStorage::InitialData::~InitialData() {
}
@@ -117,12 +115,9 @@ scoped_ptr<ServiceWorkerStorage> ServiceWorkerStorage::Create(
const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread,
storage::QuotaManagerProxy* quota_manager_proxy,
storage::SpecialStoragePolicy* special_storage_policy) {
- return make_scoped_ptr(new ServiceWorkerStorage(path,
- context,
- database_task_manager.Pass(),
- disk_cache_thread,
- quota_manager_proxy,
- special_storage_policy));
+ return make_scoped_ptr(new ServiceWorkerStorage(
+ path, context, std::move(database_task_manager), disk_cache_thread,
+ quota_manager_proxy, special_storage_policy));
}
// static
@@ -147,7 +142,7 @@ void ServiceWorkerStorage::FindRegistrationForDocument(
weak_factory_.GetWeakPtr(), document_url, callback))) {
if (state_ != INITIALIZING) {
CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
- SERVICE_WORKER_ERROR_FAILED, callback);
+ SERVICE_WORKER_ERROR_ABORT, callback);
}
TRACE_EVENT_INSTANT1(
"ServiceWorker",
@@ -180,7 +175,7 @@ void ServiceWorkerStorage::FindRegistrationForDocument(
// To connect this TRACE_EVENT with the callback, TimeTicks is used for
// callback id.
- int64 callback_id = base::TimeTicks::Now().ToInternalValue();
+ int64_t callback_id = base::TimeTicks::Now().ToInternalValue();
TRACE_EVENT_ASYNC_BEGIN1(
"ServiceWorker",
"ServiceWorkerStorage::FindRegistrationForDocument",
@@ -208,7 +203,7 @@ void ServiceWorkerStorage::FindRegistrationForPattern(
weak_factory_.GetWeakPtr(), scope, callback))) {
if (state_ != INITIALIZING) {
CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(),
- SERVICE_WORKER_ERROR_FAILED, callback);
+ SERVICE_WORKER_ERROR_ABORT, callback);
}
return;
}
@@ -253,7 +248,7 @@ ServiceWorkerRegistration* ServiceWorkerStorage::GetUninstallingRegistration(
}
void ServiceWorkerStorage::FindRegistrationForId(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
const FindRegistrationCallback& callback) {
if (!LazyInitialize(base::Bind(
@@ -261,7 +256,7 @@ void ServiceWorkerStorage::FindRegistrationForId(
weak_factory_.GetWeakPtr(), registration_id, origin, callback))) {
if (state_ != INITIALIZING) {
CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
- SERVICE_WORKER_ERROR_FAILED, callback);
+ SERVICE_WORKER_ERROR_ABORT, callback);
}
return;
}
@@ -299,13 +294,13 @@ void ServiceWorkerStorage::FindRegistrationForId(
}
void ServiceWorkerStorage::FindRegistrationForIdOnly(
- int64 registration_id,
+ int64_t registration_id,
const FindRegistrationCallback& callback) {
if (!LazyInitialize(
base::Bind(&ServiceWorkerStorage::FindRegistrationForIdOnly,
weak_factory_.GetWeakPtr(), registration_id, callback))) {
if (state_ != INITIALIZING) {
- CompleteFindNow(nullptr, SERVICE_WORKER_ERROR_FAILED, callback);
+ CompleteFindNow(nullptr, SERVICE_WORKER_ERROR_ABORT, callback);
}
return;
}
@@ -395,7 +390,7 @@ void ServiceWorkerStorage::StoreRegistration(
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
- RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
+ RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -407,6 +402,7 @@ void ServiceWorkerStorage::StoreRegistration(
data.version_id = version->version_id();
data.last_update_check = registration->last_update_check();
data.is_active = (version == registration->active_version());
+ data.foreign_fetch_scopes = version->foreign_fetch_scopes();
ResourceList resources;
version->script_cache_map()->GetResources(&resources);
@@ -416,7 +412,7 @@ void ServiceWorkerStorage::StoreRegistration(
return;
}
- uint64 resources_total_size_bytes = 0;
+ uint64_t resources_total_size_bytes = 0;
for (const auto& resource : resources) {
resources_total_size_bytes += resource.size_bytes;
}
@@ -447,7 +443,7 @@ void ServiceWorkerStorage::UpdateToActiveState(
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
- RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
+ RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -481,13 +477,12 @@ void ServiceWorkerStorage::UpdateLastUpdateCheckTime(
registration->last_update_check()));
}
-void ServiceWorkerStorage::DeleteRegistration(
- int64 registration_id,
- const GURL& origin,
- const StatusCallback& callback) {
+void ServiceWorkerStorage::DeleteRegistration(int64_t registration_id,
+ const GURL& origin,
+ const StatusCallback& callback) {
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
- RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
+ RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -519,58 +514,62 @@ void ServiceWorkerStorage::DeleteRegistration(
}
scoped_ptr<ServiceWorkerResponseReader>
-ServiceWorkerStorage::CreateResponseReader(int64 response_id) {
+ServiceWorkerStorage::CreateResponseReader(int64_t resource_id) {
return make_scoped_ptr(
- new ServiceWorkerResponseReader(response_id, disk_cache()));
+ new ServiceWorkerResponseReader(resource_id, disk_cache()));
}
scoped_ptr<ServiceWorkerResponseWriter>
-ServiceWorkerStorage::CreateResponseWriter(int64 response_id) {
+ServiceWorkerStorage::CreateResponseWriter(int64_t resource_id) {
return make_scoped_ptr(
- new ServiceWorkerResponseWriter(response_id, disk_cache()));
+ new ServiceWorkerResponseWriter(resource_id, disk_cache()));
}
scoped_ptr<ServiceWorkerResponseMetadataWriter>
-ServiceWorkerStorage::CreateResponseMetadataWriter(int64 response_id) {
+ServiceWorkerStorage::CreateResponseMetadataWriter(int64_t resource_id) {
return make_scoped_ptr(
- new ServiceWorkerResponseMetadataWriter(response_id, disk_cache()));
+ new ServiceWorkerResponseMetadataWriter(resource_id, disk_cache()));
}
-void ServiceWorkerStorage::StoreUncommittedResponseId(int64 id) {
- DCHECK_NE(kInvalidServiceWorkerResponseId, id);
+void ServiceWorkerStorage::StoreUncommittedResourceId(int64_t resource_id) {
+ DCHECK_NE(kInvalidServiceWorkerResourceId, resource_id);
DCHECK_EQ(INITIALIZED, state_);
if (!has_checked_for_stale_resources_)
DeleteStaleResources();
- database_task_manager_->GetTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(
- &ServiceWorkerDatabase::WriteUncommittedResourceIds),
- base::Unretained(database_.get()),
- std::set<int64>(&id, &id + 1)));
+ PostTaskAndReplyWithResult(
+ database_task_manager_->GetTaskRunner(), FROM_HERE,
+ base::Bind(&ServiceWorkerDatabase::WriteUncommittedResourceIds,
+ base::Unretained(database_.get()),
+ std::set<int64_t>(&resource_id, &resource_id + 1)),
+ base::Bind(&ServiceWorkerStorage::DidWriteUncommittedResourceIds,
+ weak_factory_.GetWeakPtr()));
}
-void ServiceWorkerStorage::DoomUncommittedResponse(int64 id) {
- DCHECK_NE(kInvalidServiceWorkerResponseId, id);
- database_task_manager_->GetTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(
- &ServiceWorkerDatabase::PurgeUncommittedResourceIds),
- base::Unretained(database_.get()),
- std::set<int64>(&id, &id + 1)));
- StartPurgingResources(std::vector<int64>(1, id));
+void ServiceWorkerStorage::DoomUncommittedResource(int64_t resource_id) {
+ DCHECK_NE(kInvalidServiceWorkerResourceId, resource_id);
+ DoomUncommittedResources(std::set<int64_t>(&resource_id, &resource_id + 1));
}
-void ServiceWorkerStorage::StoreUserData(
- int64 registration_id,
- const GURL& origin,
- const std::string& key,
- const std::string& data,
- const StatusCallback& callback) {
+void ServiceWorkerStorage::DoomUncommittedResources(
+ const std::set<int64_t>& resource_ids) {
+ PostTaskAndReplyWithResult(
+ database_task_manager_->GetTaskRunner(), FROM_HERE,
+ base::Bind(&ServiceWorkerDatabase::PurgeUncommittedResourceIds,
+ base::Unretained(database_.get()), resource_ids),
+ base::Bind(&ServiceWorkerStorage::DidPurgeUncommittedResourceIds,
+ weak_factory_.GetWeakPtr(), resource_ids));
+}
+
+void ServiceWorkerStorage::StoreUserData(int64_t registration_id,
+ const GURL& origin,
+ const std::string& key,
+ const std::string& data,
+ const StatusCallback& callback) {
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
- RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
+ RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -590,14 +589,13 @@ void ServiceWorkerStorage::StoreUserData(
callback));
}
-void ServiceWorkerStorage::GetUserData(
- int64 registration_id,
- const std::string& key,
- const GetUserDataCallback& callback) {
+void ServiceWorkerStorage::GetUserData(int64_t registration_id,
+ const std::string& key,
+ const GetUserDataCallback& callback) {
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
RunSoon(FROM_HERE,
- base::Bind(callback, std::string(), SERVICE_WORKER_ERROR_FAILED));
+ base::Bind(callback, std::string(), SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -619,13 +617,12 @@ void ServiceWorkerStorage::GetUserData(
callback)));
}
-void ServiceWorkerStorage::ClearUserData(
- int64 registration_id,
- const std::string& key,
- const StatusCallback& callback) {
+void ServiceWorkerStorage::ClearUserData(int64_t registration_id,
+ const std::string& key,
+ const StatusCallback& callback) {
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
- RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
+ RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -653,9 +650,10 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrations(
base::Bind(&ServiceWorkerStorage::GetUserDataForAllRegistrations,
weak_factory_.GetWeakPtr(), key, callback))) {
if (state_ != INITIALIZING) {
- RunSoon(FROM_HERE,
- base::Bind(callback, std::vector<std::pair<int64, std::string>>(),
- SERVICE_WORKER_ERROR_FAILED));
+ RunSoon(
+ FROM_HERE,
+ base::Bind(callback, std::vector<std::pair<int64_t, std::string>>(),
+ SERVICE_WORKER_ERROR_ABORT));
}
return;
}
@@ -663,7 +661,7 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrations(
if (key.empty()) {
RunSoon(FROM_HERE,
- base::Bind(callback, std::vector<std::pair<int64, std::string>>(),
+ base::Bind(callback, std::vector<std::pair<int64_t, std::string>>(),
SERVICE_WORKER_ERROR_FAILED));
return;
}
@@ -680,6 +678,12 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrations(
callback)));
}
+bool ServiceWorkerStorage::OriginHasForeignFetchRegistrations(
+ const GURL& origin) {
+ return !IsDisabled() &&
+ foreign_fetch_origins_.find(origin) != foreign_fetch_origins_.end();
+}
+
void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) {
Disable();
@@ -692,21 +696,21 @@ void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) {
weak_factory_.GetWeakPtr(), callback));
}
-int64 ServiceWorkerStorage::NewRegistrationId() {
+int64_t ServiceWorkerStorage::NewRegistrationId() {
if (state_ == DISABLED)
return kInvalidServiceWorkerRegistrationId;
DCHECK_EQ(INITIALIZED, state_);
return next_registration_id_++;
}
-int64 ServiceWorkerStorage::NewVersionId() {
+int64_t ServiceWorkerStorage::NewVersionId() {
if (state_ == DISABLED)
return kInvalidServiceWorkerVersionId;
DCHECK_EQ(INITIALIZED, state_);
return next_version_id_++;
}
-int64 ServiceWorkerStorage::NewResourceId() {
+int64_t ServiceWorkerStorage::NewResourceId() {
if (state_ == DISABLED)
return kInvalidServiceWorkerResourceId;
DCHECK_EQ(INITIALIZED, state_);
@@ -729,16 +733,10 @@ void ServiceWorkerStorage::NotifyDoneInstallingRegistration(
ResourceList resources;
version->script_cache_map()->GetResources(&resources);
- std::set<int64> ids;
+ std::set<int64_t> resource_ids;
for (const auto& resource : resources)
- ids.insert(resource.resource_id);
-
- database_task_manager_->GetTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(
- &ServiceWorkerDatabase::PurgeUncommittedResourceIds),
- base::Unretained(database_.get()),
- ids));
+ resource_ids.insert(resource.resource_id);
+ DoomUncommittedResources(resource_ids);
}
}
@@ -783,12 +781,10 @@ ServiceWorkerStorage::ServiceWorkerStorage(
state_(UNINITIALIZED),
path_(path),
context_(context),
- database_task_manager_(database_task_manager.Pass()),
+ database_task_manager_(std::move(database_task_manager)),
disk_cache_thread_(disk_cache_thread),
quota_manager_proxy_(quota_manager_proxy),
special_storage_policy_(special_storage_policy),
- disk_cache_migration_needed_(false),
- old_disk_cache_deletion_needed_(false),
is_purge_pending_(false),
has_checked_for_stale_resources_(false),
weak_factory_(this) {
@@ -810,13 +806,6 @@ base::FilePath ServiceWorkerStorage::GetDiskCachePath() {
.Append(kDiskCacheName);
}
-base::FilePath ServiceWorkerStorage::GetOldDiskCachePath() {
- if (path_.empty())
- return base::FilePath();
- return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
- .Append(kOldDiskCacheName);
-}
-
bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
switch (state_) {
case INITIALIZED:
@@ -853,8 +842,7 @@ void ServiceWorkerStorage::DidReadInitialData(
next_version_id_ = data->next_version_id;
next_resource_id_ = data->next_resource_id;
registered_origins_.swap(data->origins);
- disk_cache_migration_needed_ = data->disk_cache_migration_needed;
- old_disk_cache_deletion_needed_ = data->old_disk_cache_deletion_needed;
+ foreign_fetch_origins_.swap(data->foreign_fetch_origins);
state_ = INITIALIZED;
} else {
DVLOG(2) << "Failed to initialize: "
@@ -870,7 +858,7 @@ void ServiceWorkerStorage::DidReadInitialData(
void ServiceWorkerStorage::DidFindRegistrationForDocument(
const GURL& document_url,
const FindRegistrationCallback& callback,
- int64 callback_id,
+ int64_t callback_id,
const ServiceWorkerDatabase::RegistrationData& data,
const ResourceList& resources,
ServiceWorkerDatabase::Status status) {
@@ -988,7 +976,7 @@ void ServiceWorkerStorage::DidGetRegistrations(
}
// Add all stored registrations.
- std::set<int64> registration_ids;
+ std::set<int64_t> registration_ids;
std::vector<scoped_refptr<ServiceWorkerRegistration>> registrations;
size_t index = 0;
for (const auto& registration_data : *registration_data_list) {
@@ -1023,7 +1011,7 @@ void ServiceWorkerStorage::DidGetRegistrationsInfos(
}
// Add all stored registrations.
- std::set<int64> pushed_registrations;
+ std::set<int64_t> pushed_registrations;
std::vector<ServiceWorkerRegistrationInfo> infos;
for (const auto& registration_data : *registration_data_list) {
const bool inserted =
@@ -1083,7 +1071,7 @@ void ServiceWorkerStorage::DidStoreRegistration(
const ServiceWorkerDatabase::RegistrationData& new_version,
const GURL& origin,
const ServiceWorkerDatabase::RegistrationData& deleted_version,
- const std::vector<int64>& newly_purgeable_resources,
+ const std::vector<int64_t>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status) {
if (status != ServiceWorkerDatabase::STATUS_OK) {
ScheduleDeleteAndStartOver();
@@ -1091,6 +1079,8 @@ void ServiceWorkerStorage::DidStoreRegistration(
return;
}
registered_origins_.insert(origin);
+ if (!new_version.foreign_fetch_scopes.empty())
+ foreign_fetch_origins_.insert(origin);
scoped_refptr<ServiceWorkerRegistration> registration =
context_->GetLiveRegistration(new_version.registration_id);
@@ -1126,9 +1116,9 @@ void ServiceWorkerStorage::DidUpdateToActiveState(
void ServiceWorkerStorage::DidDeleteRegistration(
const DidDeleteRegistrationParams& params,
- bool origin_is_deletable,
+ OriginState origin_state,
const ServiceWorkerDatabase::RegistrationData& deleted_version,
- const std::vector<int64>& newly_purgeable_resources,
+ const std::vector<int64_t>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status) {
pending_deletions_.erase(params.registration_id);
if (status != ServiceWorkerDatabase::STATUS_OK) {
@@ -1144,14 +1134,33 @@ void ServiceWorkerStorage::DidDeleteRegistration(
storage::StorageType::kStorageTypeTemporary,
-deleted_version.resources_total_size_bytes);
}
- if (origin_is_deletable)
+ if (origin_state == OriginState::DELETE_FROM_ALL)
registered_origins_.erase(params.origin);
+ if (origin_state == OriginState::DELETE_FROM_ALL ||
+ origin_state == OriginState::DELETE_FROM_FOREIGN_FETCH)
+ foreign_fetch_origins_.erase(params.origin);
params.callback.Run(SERVICE_WORKER_OK);
if (!context_->GetLiveVersion(deleted_version.version_id))
StartPurgingResources(newly_purgeable_resources);
}
+void ServiceWorkerStorage::DidWriteUncommittedResourceIds(
+ ServiceWorkerDatabase::Status status) {
+ if (status != ServiceWorkerDatabase::STATUS_OK)
+ ScheduleDeleteAndStartOver();
+}
+
+void ServiceWorkerStorage::DidPurgeUncommittedResourceIds(
+ const std::set<int64_t>& resource_ids,
+ ServiceWorkerDatabase::Status status) {
+ if (status != ServiceWorkerDatabase::STATUS_OK) {
+ ScheduleDeleteAndStartOver();
+ return;
+ }
+ StartPurgingResources(resource_ids);
+}
+
void ServiceWorkerStorage::DidStoreUserData(
const StatusCallback& callback,
ServiceWorkerDatabase::Status status) {
@@ -1186,7 +1195,7 @@ void ServiceWorkerStorage::DidDeleteUserData(
void ServiceWorkerStorage::DidGetUserDataForAllRegistrations(
const GetUserDataForAllRegistrationsCallback& callback,
- const std::vector<std::pair<int64, std::string>>& user_data,
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerDatabase::Status status) {
if (status != ServiceWorkerDatabase::STATUS_OK)
ScheduleDeleteAndStartOver();
@@ -1218,6 +1227,7 @@ ServiceWorkerStorage::GetOrCreateRegistration(
version->SetStatus(data.is_active ?
ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED);
version->script_cache_map()->SetResources(resources);
+ version->set_foreign_fetch_scopes(data.foreign_fetch_scopes);
}
if (version->status() == ServiceWorkerVersion::ACTIVATED)
@@ -1255,7 +1265,7 @@ ServiceWorkerStorage::FindInstallingRegistrationForPattern(const GURL& scope) {
}
ServiceWorkerRegistration*
-ServiceWorkerStorage::FindInstallingRegistrationForId(int64 registration_id) {
+ServiceWorkerStorage::FindInstallingRegistrationForId(int64_t registration_id) {
RegistrationRefsById::const_iterator found =
installing_registrations_.find(registration_id);
if (found == installing_registrations_.end())
@@ -1268,7 +1278,7 @@ ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
if (disk_cache_)
return disk_cache_.get();
- disk_cache_ = ServiceWorkerDiskCache::CreateWithSimpleBackend();
+ disk_cache_.reset(new ServiceWorkerDiskCache);
base::FilePath path = GetDiskCachePath();
if (path.empty()) {
@@ -1278,87 +1288,10 @@ ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
return disk_cache_.get();
}
- if (disk_cache_migration_needed_) {
- // Defer the start of initialization until a migration is complete.
- disk_cache_->set_is_waiting_to_initialize(true);
- DCHECK(!disk_cache_migrator_);
- disk_cache_migrator_.reset(new ServiceWorkerDiskCacheMigrator(
- GetOldDiskCachePath(), GetDiskCachePath(), kMaxDiskCacheSize,
- disk_cache_thread_));
- disk_cache_migrator_->Start(
- base::Bind(&ServiceWorkerStorage::DidMigrateDiskCache,
- weak_factory_.GetWeakPtr()));
- return disk_cache_.get();
- }
-
- if (old_disk_cache_deletion_needed_) {
- // Lazily delete the old diskcache.
- BrowserThread::PostAfterStartupTask(
- FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&ServiceWorkerStorage::DeleteOldDiskCache,
- weak_factory_.GetWeakPtr()));
- }
-
- ServiceWorkerMetrics::RecordDiskCacheMigrationResult(
- ServiceWorkerMetrics::MIGRATION_NOT_NECESSARY);
-
InitializeDiskCache();
return disk_cache_.get();
}
-void ServiceWorkerStorage::DidMigrateDiskCache(ServiceWorkerStatusCode status) {
- disk_cache_migrator_.reset();
- if (status != SERVICE_WORKER_OK) {
- OnDiskCacheMigrationFailed(
- ServiceWorkerMetrics::MIGRATION_ERROR_MIGRATION_FAILED);
- return;
- }
-
- PostTaskAndReplyWithResult(
- database_task_manager_->GetTaskRunner(), FROM_HERE,
- base::Bind(&ServiceWorkerDatabase::SetDiskCacheMigrationNotNeeded,
- base::Unretained(database_.get())),
- base::Bind(&ServiceWorkerStorage::DidSetDiskCacheMigrationNotNeeded,
- weak_factory_.GetWeakPtr()));
-}
-
-void ServiceWorkerStorage::DidSetDiskCacheMigrationNotNeeded(
- ServiceWorkerDatabase::Status status) {
- if (status != ServiceWorkerDatabase::STATUS_OK) {
- OnDiskCacheMigrationFailed(
- ServiceWorkerMetrics::MIGRATION_ERROR_UPDATE_DATABASE);
- return;
- }
-
- // Lazily delete the old diskcache and update the database.
- BrowserThread::PostAfterStartupTask(
- FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&ServiceWorkerStorage::DeleteOldDiskCache,
- weak_factory_.GetWeakPtr()));
-
- ServiceWorkerMetrics::RecordDiskCacheMigrationResult(
- ServiceWorkerMetrics::MIGRATION_OK);
- InitializeDiskCache();
-}
-
-void ServiceWorkerStorage::OnDiskCacheMigrationFailed(
- ServiceWorkerMetrics::DiskCacheMigrationResult result) {
- DCHECK(ServiceWorkerMetrics::MIGRATION_ERROR_MIGRATION_FAILED == result ||
- ServiceWorkerMetrics::MIGRATION_ERROR_UPDATE_DATABASE == result)
- << result;
- ServiceWorkerMetrics::RecordDiskCacheMigrationResult(result);
-
- // Give up migration and recreate the whole storage.
- ScheduleDeleteAndStartOver();
-
- // Lazily delete the old diskcache. Don't have to update the database
- // because it will be deleted by DeleteAndStartOver.
- BrowserThread::PostAfterStartupTask(
- FROM_HERE, disk_cache_thread_.get(),
- base::Bind(base::IgnoreResult(&base::DeleteFile), GetOldDiskCachePath(),
- true));
-}
-
void ServiceWorkerStorage::InitializeDiskCache() {
disk_cache_->set_is_waiting_to_initialize(false);
int rv = disk_cache_->InitWithDiskBackend(
@@ -1378,20 +1311,19 @@ void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) {
ServiceWorkerMetrics::CountInitDiskCacheResult(rv == net::OK);
}
-void ServiceWorkerStorage::DeleteOldDiskCache() {
- DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
- if (IsDisabled())
- return;
- database_task_manager_->GetTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ServiceWorkerStorage::DeleteOldDiskCacheInDB,
- database_.get(), GetOldDiskCachePath()));
+void ServiceWorkerStorage::StartPurgingResources(
+ const std::set<int64_t>& resource_ids) {
+ DCHECK(has_checked_for_stale_resources_);
+ for (int64_t resource_id : resource_ids)
+ purgeable_resource_ids_.push_back(resource_id);
+ ContinuePurgingResources();
}
void ServiceWorkerStorage::StartPurgingResources(
- const std::vector<int64>& ids) {
+ const std::vector<int64_t>& resource_ids) {
DCHECK(has_checked_for_stale_resources_);
- for (const auto& id : ids)
- purgeable_resource_ids_.push_back(id);
+ for (int64_t resource_id : resource_ids)
+ purgeable_resource_ids_.push_back(resource_id);
ContinuePurgingResources();
}
@@ -1410,14 +1342,14 @@ void ServiceWorkerStorage::ContinuePurgingResources() {
// Do one at a time until we're done, use RunSoon to avoid recursion when
// DoomEntry returns immediately.
is_purge_pending_ = true;
- int64 id = purgeable_resource_ids_.front();
+ int64_t id = purgeable_resource_ids_.front();
purgeable_resource_ids_.pop_front();
RunSoon(FROM_HERE,
base::Bind(&ServiceWorkerStorage::PurgeResource,
weak_factory_.GetWeakPtr(), id));
}
-void ServiceWorkerStorage::PurgeResource(int64 id) {
+void ServiceWorkerStorage::PurgeResource(int64_t id) {
DCHECK(is_purge_pending_);
int rv = disk_cache()->DoomEntry(
id, base::Bind(&ServiceWorkerStorage::OnResourcePurged,
@@ -1426,7 +1358,7 @@ void ServiceWorkerStorage::PurgeResource(int64 id) {
OnResourcePurged(id, rv);
}
-void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) {
+void ServiceWorkerStorage::OnResourcePurged(int64_t id, int rv) {
DCHECK(is_purge_pending_);
is_purge_pending_ = false;
@@ -1434,10 +1366,9 @@ void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) {
database_task_manager_->GetTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(base::IgnoreResult(
- &ServiceWorkerDatabase::ClearPurgeableResourceIds),
- base::Unretained(database_.get()),
- std::set<int64>(&id, &id + 1)));
+ base::Bind(
+ base::IgnoreResult(&ServiceWorkerDatabase::ClearPurgeableResourceIds),
+ base::Unretained(database_.get()), std::set<int64_t>(&id, &id + 1)));
// Continue purging resources regardless of the previous result.
ContinuePurgingResources();
@@ -1456,7 +1387,7 @@ void ServiceWorkerStorage::DeleteStaleResources() {
}
void ServiceWorkerStorage::DidCollectStaleResources(
- const std::vector<int64>& stale_resource_ids,
+ const std::vector<int64_t>& stale_resource_ids,
ServiceWorkerDatabase::Status status) {
if (status != ServiceWorkerDatabase::STATUS_OK) {
DCHECK_NE(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND, status);
@@ -1491,14 +1422,14 @@ void ServiceWorkerStorage::CollectStaleResourcesFromDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
const GetResourcesCallback& callback) {
- std::set<int64> ids;
+ std::set<int64_t> ids;
ServiceWorkerDatabase::Status status =
database->GetUncommittedResourceIds(&ids);
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
FROM_HERE,
- base::Bind(
- callback, std::vector<int64>(ids.begin(), ids.end()), status));
+ base::Bind(callback, std::vector<int64_t>(ids.begin(), ids.end()),
+ status));
return;
}
@@ -1506,8 +1437,8 @@ void ServiceWorkerStorage::CollectStaleResourcesFromDB(
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
FROM_HERE,
- base::Bind(
- callback, std::vector<int64>(ids.begin(), ids.end()), status));
+ base::Bind(callback, std::vector<int64_t>(ids.begin(), ids.end()),
+ status));
return;
}
@@ -1515,7 +1446,8 @@ void ServiceWorkerStorage::CollectStaleResourcesFromDB(
status = database->GetPurgeableResourceIds(&ids);
original_task_runner->PostTask(
FROM_HERE,
- base::Bind(callback, std::vector<int64>(ids.begin(), ids.end()), status));
+ base::Bind(callback, std::vector<int64_t>(ids.begin(), ids.end()),
+ status));
}
void ServiceWorkerStorage::ReadInitialDataFromDB(
@@ -1532,57 +1464,39 @@ void ServiceWorkerStorage::ReadInitialDataFromDB(
&data->next_resource_id);
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status));
+ FROM_HERE, base::Bind(callback, base::Passed(std::move(data)), status));
return;
}
- status =
- database->IsDiskCacheMigrationNeeded(&data->disk_cache_migration_needed);
- if (status != ServiceWorkerDatabase::STATUS_OK) {
- original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status));
- return;
- }
-
- status = database->IsOldDiskCacheDeletionNeeded(
- &data->old_disk_cache_deletion_needed);
+ status = database->GetOriginsWithRegistrations(&data->origins);
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status));
+ FROM_HERE, base::Bind(callback, base::Passed(std::move(data)), status));
return;
}
- status = database->GetOriginsWithRegistrations(&data->origins);
+ status = database->GetOriginsWithForeignFetchRegistrations(
+ &data->foreign_fetch_origins);
original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, base::Passed(data.Pass()), status));
-}
-
-void ServiceWorkerStorage::DeleteOldDiskCacheInDB(
- ServiceWorkerDatabase* database,
- const base::FilePath& disk_cache_path) {
- // Ignore a failure. A retry will happen on the next initialization.
- if (!base::DeleteFile(disk_cache_path, true))
- return;
- database->SetOldDiskCacheDeletionNotNeeded();
+ FROM_HERE, base::Bind(callback, base::Passed(std::move(data)), status));
}
void ServiceWorkerStorage::DeleteRegistrationFromDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
const DeleteRegistrationCallback& callback) {
DCHECK(database);
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ServiceWorkerDatabase::Status status = database->DeleteRegistration(
registration_id, origin, &deleted_version, &newly_purgeable_resources);
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
- FROM_HERE,
- base::Bind(
- callback, false, deleted_version, std::vector<int64>(), status));
+ FROM_HERE, base::Bind(callback, OriginState::KEEP_ALL, deleted_version,
+ std::vector<int64_t>(), status));
return;
}
@@ -1592,19 +1506,26 @@ void ServiceWorkerStorage::DeleteRegistrationFromDB(
status = database->GetRegistrationsForOrigin(origin, &registrations, nullptr);
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
- FROM_HERE,
- base::Bind(
- callback, false, deleted_version, std::vector<int64>(), status));
+ FROM_HERE, base::Bind(callback, OriginState::KEEP_ALL, deleted_version,
+ std::vector<int64_t>(), status));
return;
}
- bool deletable = registrations.empty();
- original_task_runner->PostTask(FROM_HERE,
- base::Bind(callback,
- deletable,
- deleted_version,
- newly_purgeable_resources,
- status));
+ OriginState origin_state = registrations.empty()
+ ? OriginState::DELETE_FROM_ALL
+ : OriginState::DELETE_FROM_FOREIGN_FETCH;
+
+ // TODO(mek): Add convenient method to ServiceWorkerDatabase to check the
+ // foreign fetch scope origin list.
+ for (const auto& registration : registrations) {
+ if (!registration.foreign_fetch_scopes.empty()) {
+ origin_state = OriginState::KEEP_ALL;
+ break;
+ }
+ }
+ original_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, origin_state, deleted_version,
+ newly_purgeable_resources, status));
}
void ServiceWorkerStorage::WriteRegistrationInDB(
@@ -1615,7 +1536,7 @@ void ServiceWorkerStorage::WriteRegistrationInDB(
const WriteRegistrationCallback& callback) {
DCHECK(database);
ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
ServiceWorkerDatabase::Status status = database->WriteRegistration(
data, resources, &deleted_version, &newly_purgeable_resources);
original_task_runner->PostTask(FROM_HERE,
@@ -1651,7 +1572,7 @@ void ServiceWorkerStorage::FindForDocumentInDB(
// Find one with a pattern match.
LongestScopeMatcher matcher(document_url);
- int64 match = kInvalidServiceWorkerRegistrationId;
+ int64_t match = kInvalidServiceWorkerRegistrationId;
for (const auto& registration_data : registration_data_list)
if (matcher.MatchLongest(registration_data.scope))
match = registration_data.registration_id;
@@ -1702,7 +1623,7 @@ void ServiceWorkerStorage::FindForPatternInDB(
void ServiceWorkerStorage::FindForIdInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
const FindInDBCallback& callback) {
ServiceWorkerDatabase::RegistrationData data;
@@ -1716,7 +1637,7 @@ void ServiceWorkerStorage::FindForIdInDB(
void ServiceWorkerStorage::FindForIdOnlyInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const FindInDBCallback& callback) {
GURL origin;
ServiceWorkerDatabase::Status status =
@@ -1735,7 +1656,7 @@ void ServiceWorkerStorage::FindForIdOnlyInDB(
void ServiceWorkerStorage::GetUserDataInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const std::string& key,
const GetUserDataInDBCallback& callback) {
std::string data;
@@ -1750,7 +1671,7 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrationsInDB(
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
const std::string& key,
const GetUserDataForAllRegistrationsInDBCallback& callback) {
- std::vector<std::pair<int64, std::string>> user_data;
+ std::vector<std::pair<int64_t, std::string>> user_data;
ServiceWorkerDatabase::Status status =
database->ReadUserDataForAllRegistrations(key, &user_data);
original_task_runner->PostTask(FROM_HERE,
@@ -1762,7 +1683,7 @@ void ServiceWorkerStorage::DeleteAllDataForOriginsFromDB(
const std::set<GURL>& origins) {
DCHECK(database);
- std::vector<int64> newly_purgeable_resources;
+ std::vector<int64_t> newly_purgeable_resources;
database->DeleteAllDataForOrigins(origins, &newly_purgeable_resources);
}
diff --git a/chromium/content/browser/service_worker/service_worker_storage.h b/chromium/content/browser/service_worker/service_worker_storage.h
index 29cf02c36f3..92042def120 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.h
+++ b/chromium/content/browser/service_worker/service_worker_storage.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
+#include <stdint.h>
+
#include <deque>
#include <map>
#include <set>
@@ -14,6 +16,7 @@
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_database.h"
#include "content/browser/service_worker/service_worker_database_task_manager.h"
@@ -37,7 +40,6 @@ namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerDiskCache;
-class ServiceWorkerDiskCacheMigrator;
class ServiceWorkerRegistration;
class ServiceWorkerResponseMetadataWriter;
class ServiceWorkerResponseReader;
@@ -64,9 +66,8 @@ class CONTENT_EXPORT ServiceWorkerStorage
void(const std::string& data, ServiceWorkerStatusCode status)>
GetUserDataCallback;
typedef base::Callback<void(
- const std::vector<std::pair<int64, std::string>>& user_data,
- ServiceWorkerStatusCode status)>
- GetUserDataForAllRegistrationsCallback;
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
+ ServiceWorkerStatusCode status)> GetUserDataForAllRegistrationsCallback;
~ServiceWorkerStorage() override;
@@ -96,7 +97,7 @@ class CONTENT_EXPORT ServiceWorkerStorage
const FindRegistrationCallback& callback);
void FindRegistrationForPattern(const GURL& scope,
const FindRegistrationCallback& callback);
- void FindRegistrationForId(int64 registration_id,
+ void FindRegistrationForId(int64_t registration_id,
const GURL& origin,
const FindRegistrationCallback& callback);
@@ -105,7 +106,7 @@ class CONTENT_EXPORT ServiceWorkerStorage
// is all that is available this method can be used instead.
// Like |FindRegistrationForId| this method may complete immediately (the
// callback may be called prior to the method returning) or asynchronously.
- void FindRegistrationForIdOnly(int64 registration_id,
+ void FindRegistrationForIdOnly(int64_t registration_id,
const FindRegistrationCallback& callback);
ServiceWorkerRegistration* GetUninstallingRegistration(const GURL& scope);
@@ -137,37 +138,38 @@ class CONTENT_EXPORT ServiceWorkerStorage
// Deletes the registration data for |registration_id|. If the registration's
// version is live, its script resources will remain available.
// PurgeResources should be called when it's OK to delete them.
- void DeleteRegistration(int64 registration_id,
+ void DeleteRegistration(int64_t registration_id,
const GURL& origin,
const StatusCallback& callback);
scoped_ptr<ServiceWorkerResponseReader> CreateResponseReader(
- int64 response_id);
+ int64_t resource_id);
scoped_ptr<ServiceWorkerResponseWriter> CreateResponseWriter(
- int64 response_id);
+ int64_t resource_id);
scoped_ptr<ServiceWorkerResponseMetadataWriter> CreateResponseMetadataWriter(
- int64 response_id);
+ int64_t resource_id);
- // Adds |id| to the set of resources ids that are in the disk
- // cache but not yet stored with a registration.
- void StoreUncommittedResponseId(int64 id);
+ // Adds |resource_id| to the set of resources that are in the disk cache
+ // but not yet stored with a registration.
+ void StoreUncommittedResourceId(int64_t resource_id);
- // Removes |id| from uncommitted list, adds it to the
- // purgeable list and purges it.
- void DoomUncommittedResponse(int64 id);
+ // Removes resource ids from uncommitted list, adds them to the purgeable list
+ // and purges them.
+ void DoomUncommittedResource(int64_t resource_id);
+ void DoomUncommittedResources(const std::set<int64_t>& resource_ids);
// Provide a storage mechanism to read/write arbitrary data associated with
// a registration. Each registration has its own key namespace. Stored data
// is deleted when the associated registraton is deleted.
- void GetUserData(int64 registration_id,
+ void GetUserData(int64_t registration_id,
const std::string& key,
const GetUserDataCallback& callback);
- void StoreUserData(int64 registration_id,
+ void StoreUserData(int64_t registration_id,
const GURL& origin,
const std::string& key,
const std::string& data,
const StatusCallback& callback);
- void ClearUserData(int64 registration_id,
+ void ClearUserData(int64_t registration_id,
const std::string& key,
const StatusCallback& callback);
// Returns all registrations that have user data with a particular key, as
@@ -176,13 +178,25 @@ class CONTENT_EXPORT ServiceWorkerStorage
const std::string& key,
const GetUserDataForAllRegistrationsCallback& callback);
+ // Returns true if any service workers at |origin| have registered for foreign
+ // fetch.
+ bool OriginHasForeignFetchRegistrations(const GURL& origin);
+
// Deletes the storage and starts over.
void DeleteAndStartOver(const StatusCallback& callback);
- // Returns new IDs which are guaranteed to be unique in the storage.
- int64 NewRegistrationId();
- int64 NewVersionId();
- int64 NewResourceId();
+ // Returns a new registration id which is guaranteed to be unique in the
+ // storage. Returns kInvalidServiceWorkerRegistrationId if the storage is
+ // disabled.
+ int64_t NewRegistrationId();
+
+ // Returns a new version id which is guaranteed to be unique in the storage.
+ // Returns kInvalidServiceWorkerVersionId if the storage is disabled.
+ int64_t NewVersionId();
+
+ // Returns a new resource id which is guaranteed to be unique in the storage.
+ // Returns kInvalidServiceWorkerResourceId if the storage is disabled.
+ int64_t NewResourceId();
// Intended for use only by ServiceWorkerRegisterJob and
// ServiceWorkerRegistration.
@@ -208,18 +222,12 @@ class CONTENT_EXPORT ServiceWorkerStorage
friend class ServiceWorkerResourceStorageTest;
friend class ServiceWorkerControlleeRequestHandlerTest;
friend class ServiceWorkerContextRequestHandlerTest;
- friend class ServiceWorkerDiskCacheMigratorTest;
+ friend class ServiceWorkerReadFromCacheJobTest;
friend class ServiceWorkerRequestHandlerTest;
friend class ServiceWorkerURLRequestJobTest;
friend class ServiceWorkerVersionBrowserTest;
friend class ServiceWorkerVersionTest;
friend class ServiceWorkerWriteToCacheJobTest;
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest,
- MigrateOnDiskCacheAccess);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest,
- NotMigrateOnDatabaseAccess);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDiskCacheMigratorTest,
- NotMigrateForEmptyDatabase);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDispatcherHostTest,
CleanupOnRendererCrash);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
@@ -242,12 +250,11 @@ class CONTENT_EXPORT ServiceWorkerStorage
DeleteAndStartOver_OpenedFileExists);
struct InitialData {
- int64 next_registration_id;
- int64 next_version_id;
- int64 next_resource_id;
+ int64_t next_registration_id;
+ int64_t next_version_id;
+ int64_t next_resource_id;
std::set<GURL> origins;
- bool disk_cache_migration_needed;
- bool old_disk_cache_deletion_needed;
+ std::set<GURL> foreign_fetch_origins;
InitialData();
~InitialData();
@@ -255,7 +262,7 @@ class CONTENT_EXPORT ServiceWorkerStorage
// Because there are too many params for base::Bind to wrap a closure around.
struct DidDeleteRegistrationParams {
- int64 registration_id;
+ int64_t registration_id;
GURL origin;
StatusCallback callback;
@@ -263,8 +270,18 @@ class CONTENT_EXPORT ServiceWorkerStorage
~DidDeleteRegistrationParams();
};
+ enum class OriginState {
+ // Other registrations with foreign fetch scopes exist for the origin.
+ KEEP_ALL,
+ // Other registrations exist at this origin, but none of them have foreign
+ // fetch scopes.
+ DELETE_FROM_FOREIGN_FETCH,
+ // No other registrations exist at this origin.
+ DELETE_FROM_ALL
+ };
+
typedef std::vector<ServiceWorkerDatabase::RegistrationData> RegistrationList;
- typedef std::map<int64, scoped_refptr<ServiceWorkerRegistration> >
+ typedef std::map<int64_t, scoped_refptr<ServiceWorkerRegistration>>
RegistrationRefsById;
typedef base::Callback<void(scoped_ptr<InitialData> data,
ServiceWorkerDatabase::Status status)>
@@ -274,12 +291,12 @@ class CONTENT_EXPORT ServiceWorkerStorage
typedef base::Callback<void(
const GURL& origin,
const ServiceWorkerDatabase::RegistrationData& deleted_version_data,
- const std::vector<int64>& newly_purgeable_resources,
+ const std::vector<int64_t>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status)> WriteRegistrationCallback;
typedef base::Callback<void(
- bool origin_is_deletable,
+ OriginState origin_state,
const ServiceWorkerDatabase::RegistrationData& deleted_version_data,
- const std::vector<int64>& newly_purgeable_resources,
+ const std::vector<int64_t>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status)> DeleteRegistrationCallback;
typedef base::Callback<void(
const ServiceWorkerDatabase::RegistrationData& data,
@@ -289,10 +306,10 @@ class CONTENT_EXPORT ServiceWorkerStorage
const std::string& data,
ServiceWorkerDatabase::Status)> GetUserDataInDBCallback;
typedef base::Callback<void(
- const std::vector<std::pair<int64, std::string>>& user_data,
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerDatabase::Status)>
GetUserDataForAllRegistrationsInDBCallback;
- typedef base::Callback<void(const std::vector<int64>& resource_ids,
+ typedef base::Callback<void(const std::vector<int64_t>& resource_ids,
ServiceWorkerDatabase::Status status)>
GetResourcesCallback;
@@ -307,12 +324,6 @@ class CONTENT_EXPORT ServiceWorkerStorage
base::FilePath GetDatabasePath();
base::FilePath GetDiskCachePath();
- // Returns a path to an old diskcache backed with BlockFile. This is used for
- // the diskcache migration (see service_worker_disk_cache_migrator.h).
- // TODO(nhiroki): Remove this after several milestones pass
- // (http://crbug.com/487482)
- base::FilePath GetOldDiskCachePath();
-
bool LazyInitialize(
const base::Closure& callback);
void DidReadInitialData(scoped_ptr<InitialData> data,
@@ -320,7 +331,7 @@ class CONTENT_EXPORT ServiceWorkerStorage
void DidFindRegistrationForDocument(
const GURL& document_url,
const FindRegistrationCallback& callback,
- int64 callback_id,
+ int64_t callback_id,
const ServiceWorkerDatabase::RegistrationData& data,
const ResourceList& resources,
ServiceWorkerDatabase::Status status);
@@ -349,17 +360,20 @@ class CONTENT_EXPORT ServiceWorkerStorage
const ServiceWorkerDatabase::RegistrationData& new_version,
const GURL& origin,
const ServiceWorkerDatabase::RegistrationData& deleted_version,
- const std::vector<int64>& newly_purgeable_resources,
+ const std::vector<int64_t>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status);
void DidUpdateToActiveState(
const StatusCallback& callback,
ServiceWorkerDatabase::Status status);
void DidDeleteRegistration(
const DidDeleteRegistrationParams& params,
- bool origin_is_deletable,
+ OriginState origin_state,
const ServiceWorkerDatabase::RegistrationData& deleted_version,
- const std::vector<int64>& newly_purgeable_resources,
+ const std::vector<int64_t>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status);
+ void DidWriteUncommittedResourceIds(ServiceWorkerDatabase::Status status);
+ void DidPurgeUncommittedResourceIds(const std::set<int64_t>& resource_ids,
+ ServiceWorkerDatabase::Status status);
void DidStoreUserData(
const StatusCallback& callback,
ServiceWorkerDatabase::Status status);
@@ -372,7 +386,7 @@ class CONTENT_EXPORT ServiceWorkerStorage
ServiceWorkerDatabase::Status status);
void DidGetUserDataForAllRegistrations(
const GetUserDataForAllRegistrationsCallback& callback,
- const std::vector<std::pair<int64, std::string>>& user_data,
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerDatabase::Status status);
void ReturnFoundRegistration(
const FindRegistrationCallback& callback,
@@ -387,31 +401,25 @@ class CONTENT_EXPORT ServiceWorkerStorage
ServiceWorkerRegistration* FindInstallingRegistrationForPattern(
const GURL& scope);
ServiceWorkerRegistration* FindInstallingRegistrationForId(
- int64 registration_id);
+ int64_t registration_id);
// Lazy disk_cache getter.
ServiceWorkerDiskCache* disk_cache();
- void MigrateDiskCache();
- void DidMigrateDiskCache(ServiceWorkerStatusCode status);
- void DidSetDiskCacheMigrationNotNeeded(ServiceWorkerDatabase::Status status);
- void OnDiskCacheMigrationFailed(
- ServiceWorkerMetrics::DiskCacheMigrationResult result);
void InitializeDiskCache();
void OnDiskCacheInitialized(int rv);
- void DeleteOldDiskCache();
-
- void StartPurgingResources(const std::vector<int64>& ids);
+ void StartPurgingResources(const std::set<int64_t>& resource_ids);
+ void StartPurgingResources(const std::vector<int64_t>& resource_ids);
void StartPurgingResources(const ResourceList& resources);
void ContinuePurgingResources();
- void PurgeResource(int64 id);
- void OnResourcePurged(int64 id, int rv);
+ void PurgeResource(int64_t id);
+ void OnResourcePurged(int64_t id, int rv);
// Deletes purgeable and uncommitted resources left over from the previous
// browser session. This must be called once per session before any database
// operation that may mutate the purgeable or uncommitted resource lists.
void DeleteStaleResources();
- void DidCollectStaleResources(const std::vector<int64>& stale_resource_ids,
+ void DidCollectStaleResources(const std::vector<int64_t>& stale_resource_ids,
ServiceWorkerDatabase::Status status);
void ClearSessionOnlyOrigins();
@@ -425,12 +433,10 @@ class CONTENT_EXPORT ServiceWorkerStorage
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
const InitializeCallback& callback);
- static void DeleteOldDiskCacheInDB(ServiceWorkerDatabase* database,
- const base::FilePath& disk_cache_path);
static void DeleteRegistrationFromDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
const DeleteRegistrationCallback& callback);
static void WriteRegistrationInDB(
@@ -452,18 +458,18 @@ class CONTENT_EXPORT ServiceWorkerStorage
static void FindForIdInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
const FindInDBCallback& callback);
static void FindForIdOnlyInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const FindInDBCallback& callback);
static void GetUserDataInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
+ int64_t registration_id,
const std::string& key,
const GetUserDataInDBCallback& callback);
static void GetUserDataForAllRegistrationsInDB(
@@ -489,13 +495,14 @@ class CONTENT_EXPORT ServiceWorkerStorage
// Origins having registations.
std::set<GURL> registered_origins_;
+ std::set<GURL> foreign_fetch_origins_;
// Pending database tasks waiting for initialization.
std::vector<base::Closure> pending_tasks_;
- int64 next_registration_id_;
- int64 next_version_id_;
- int64 next_resource_id_;
+ int64_t next_registration_id_;
+ int64_t next_version_id_;
+ int64_t next_resource_id_;
enum State {
UNINITIALIZED,
@@ -519,14 +526,11 @@ class CONTENT_EXPORT ServiceWorkerStorage
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
scoped_ptr<ServiceWorkerDiskCache> disk_cache_;
- scoped_ptr<ServiceWorkerDiskCacheMigrator> disk_cache_migrator_;
- bool disk_cache_migration_needed_;
- bool old_disk_cache_deletion_needed_;
- std::deque<int64> purgeable_resource_ids_;
+ std::deque<int64_t> purgeable_resource_ids_;
bool is_purge_pending_;
bool has_checked_for_stale_resources_;
- std::set<int64> pending_deletions_;
+ std::set<int64_t> pending_deletions_;
base::WeakPtrFactory<ServiceWorkerStorage> weak_factory_;
diff --git a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
index 9eb8af1cdd6..6b757161d2f 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -2,18 +2,24 @@
// 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 <stdint.h>
#include <string>
+#include <utility>
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
+#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_storage.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -116,19 +122,20 @@ void GetUserDataCallback(
void GetUserDataForAllRegistrationsCallback(
bool* was_called,
- std::vector<std::pair<int64, std::string>>* data_out,
+ std::vector<std::pair<int64_t, std::string>>* data_out,
ServiceWorkerStatusCode* status_out,
- const std::vector<std::pair<int64, std::string>>& data,
+ const std::vector<std::pair<int64_t, std::string>>& data,
ServiceWorkerStatusCode status) {
*was_called = true;
*data_out = data;
*status_out = status;
}
-void WriteResponse(
- ServiceWorkerStorage* storage, int64 id,
- const std::string& headers,
- IOBuffer* body, int length) {
+void WriteResponse(ServiceWorkerStorage* storage,
+ int64_t id,
+ const std::string& headers,
+ IOBuffer* body,
+ int length) {
scoped_ptr<ServiceWorkerResponseWriter> writer =
storage->CreateResponseWriter(id);
@@ -153,15 +160,15 @@ void WriteResponse(
}
}
-void WriteStringResponse(
- ServiceWorkerStorage* storage, int64 id,
- const std::string& headers,
- const std::string& body) {
+void WriteStringResponse(ServiceWorkerStorage* storage,
+ int64_t id,
+ const std::string& headers,
+ const std::string& body) {
scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(body.data()));
WriteResponse(storage, id, headers, body_buffer.get(), body.length());
}
-void WriteBasicResponse(ServiceWorkerStorage* storage, int64 id) {
+void WriteBasicResponse(ServiceWorkerStorage* storage, int64_t id) {
scoped_ptr<ServiceWorkerResponseWriter> writer =
storage->CreateResponseWriter(id);
@@ -171,7 +178,8 @@ void WriteBasicResponse(ServiceWorkerStorage* storage, int64 id) {
WriteStringResponse(storage, id, headers, std::string(kHttpBody));
}
-bool VerifyBasicResponse(ServiceWorkerStorage* storage, int64 id,
+bool VerifyBasicResponse(ServiceWorkerStorage* storage,
+ int64_t id,
bool expected_positive_result) {
const std::string kExpectedHttpBody("Hello");
scoped_ptr<ServiceWorkerResponseReader> reader =
@@ -212,7 +220,7 @@ bool VerifyBasicResponse(ServiceWorkerStorage* storage, int64 id,
}
int WriteResponseMetadata(ServiceWorkerStorage* storage,
- int64 id,
+ int64_t id,
const std::string& metadata) {
scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(metadata.data()));
scoped_ptr<ServiceWorkerResponseMetadataWriter> metadata_writer =
@@ -241,7 +249,7 @@ int ClearMetadata(ServiceWorkerVersion* version, const GURL& url) {
}
bool VerifyResponseMetadata(ServiceWorkerStorage* storage,
- int64 id,
+ int64_t id,
const std::string& expected_metadata) {
scoped_ptr<ServiceWorkerResponseReader> reader =
storage->CreateResponseReader(id);
@@ -269,31 +277,31 @@ class ServiceWorkerStorageTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {
}
- void SetUp() override {
- scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
- new MockServiceWorkerDatabaseTaskManager(
- base::ThreadTaskRunnerHandle::Get()));
- context_.reset(
- new ServiceWorkerContextCore(GetUserDataDirectory(),
- database_task_manager.Pass(),
- base::ThreadTaskRunnerHandle::Get(),
- NULL,
- NULL,
- NULL,
- NULL));
- context_ptr_ = context_->AsWeakPtr();
+ void SetUp() override { InitializeTestHelper(); }
+
+ void TearDown() override {
+ helper_.reset();
+ base::RunLoop().RunUntilIdle();
}
- void TearDown() override { context_.reset(); }
+ base::FilePath GetUserDataDirectory() { return user_data_directory_.path(); }
+
+ bool InitUserDataDirectory() {
+ return user_data_directory_.CreateUniqueTempDir();
+ }
- virtual base::FilePath GetUserDataDirectory() { return base::FilePath(); }
+ void InitializeTestHelper() {
+ helper_.reset(new EmbeddedWorkerTestHelper(GetUserDataDirectory()));
+ base::RunLoop().RunUntilIdle();
+ }
- ServiceWorkerStorage* storage() { return context_->storage(); }
+ ServiceWorkerContextCore* context() { return helper_->context(); }
+ ServiceWorkerStorage* storage() { return helper_->context()->storage(); }
// A static class method for friendliness.
static void VerifyPurgeableListStatusCallback(
ServiceWorkerDatabase* database,
- std::set<int64> *purgeable_ids,
+ std::set<int64_t>* purgeable_ids,
bool* was_called,
ServiceWorkerStatusCode* result,
ServiceWorkerStatusCode status) {
@@ -323,9 +331,8 @@ class ServiceWorkerStorageTest : public testing::Test {
return result;
}
- ServiceWorkerStatusCode DeleteRegistration(
- int64 registration_id,
- const GURL& origin) {
+ ServiceWorkerStatusCode DeleteRegistration(int64_t registration_id,
+ const GURL& origin) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
storage()->DeleteRegistration(
@@ -357,10 +364,9 @@ class ServiceWorkerStorageTest : public testing::Test {
EXPECT_TRUE(was_called);
}
- ServiceWorkerStatusCode GetUserData(
- int64 registration_id,
- const std::string& key,
- std::string* data) {
+ ServiceWorkerStatusCode GetUserData(int64_t registration_id,
+ const std::string& key,
+ std::string* data) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
storage()->GetUserData(
@@ -372,11 +378,10 @@ class ServiceWorkerStorageTest : public testing::Test {
return result;
}
- ServiceWorkerStatusCode StoreUserData(
- int64 registration_id,
- const GURL& origin,
- const std::string& key,
- const std::string& data) {
+ ServiceWorkerStatusCode StoreUserData(int64_t registration_id,
+ const GURL& origin,
+ const std::string& key,
+ const std::string& data) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
storage()->StoreUserData(
@@ -388,9 +393,8 @@ class ServiceWorkerStorageTest : public testing::Test {
return result;
}
- ServiceWorkerStatusCode ClearUserData(
- int64 registration_id,
- const std::string& key) {
+ ServiceWorkerStatusCode ClearUserData(int64_t registration_id,
+ const std::string& key) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
storage()->ClearUserData(
@@ -403,7 +407,7 @@ class ServiceWorkerStorageTest : public testing::Test {
ServiceWorkerStatusCode GetUserDataForAllRegistrations(
const std::string& key,
- std::vector<std::pair<int64, std::string>>* data) {
+ std::vector<std::pair<int64_t, std::string>>* data) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
storage()->GetUserDataForAllRegistrations(
@@ -458,7 +462,7 @@ class ServiceWorkerStorageTest : public testing::Test {
}
ServiceWorkerStatusCode FindRegistrationForId(
- int64 registration_id,
+ int64_t registration_id,
const GURL& origin,
scoped_refptr<ServiceWorkerRegistration>* registration) {
bool was_called = false;
@@ -472,7 +476,7 @@ class ServiceWorkerStorageTest : public testing::Test {
}
ServiceWorkerStatusCode FindRegistrationForIdOnly(
- int64 registration_id,
+ int64_t registration_id,
scoped_refptr<ServiceWorkerRegistration>* registration) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
@@ -483,8 +487,9 @@ class ServiceWorkerStorageTest : public testing::Test {
return result;
}
- scoped_ptr<ServiceWorkerContextCore> context_;
- base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
+ // user_data_directory_ must be declared first to preserve destructor order.
+ base::ScopedTempDir user_data_directory_;
+ scoped_ptr<EmbeddedWorkerTestHelper> helper_;
TestBrowserThreadBundle browser_thread_bundle_;
};
@@ -493,11 +498,12 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
const GURL kScript("http://www.test.not/script.js");
const GURL kDocumentUrl("http://www.test.not/scope/document.html");
const GURL kResource1("http://www.test.not/scope/resource1.js");
- const int64 kResource1Size = 1591234;
+ const int64_t kResource1Size = 1591234;
const GURL kResource2("http://www.test.not/scope/resource2.js");
- const int64 kResource2Size = 51;
- const int64 kRegistrationId = 0;
- const int64 kVersionId = 0;
+ const int64_t kResource2Size = 51;
+ const int64_t kRegistrationId = 0;
+ const int64_t kVersionId = 0;
+ const GURL kForeignFetchScope("http://www.test.not/scope/ff/");
const base::Time kToday = base::Time::Now();
const base::Time kYesterday = kToday - base::TimeDelta::FromDays(1);
@@ -525,13 +531,14 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
// Store something.
scoped_refptr<ServiceWorkerRegistration> live_registration =
- new ServiceWorkerRegistration(
- kScope, kRegistrationId, context_ptr_);
- scoped_refptr<ServiceWorkerVersion> live_version =
- new ServiceWorkerVersion(
- live_registration.get(), kScript, kVersionId, context_ptr_);
+ new ServiceWorkerRegistration(kScope, kRegistrationId,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
+ live_registration.get(), kScript, kVersionId, context()->AsWeakPtr());
live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
live_version->script_cache_map()->SetResources(resources);
+ live_version->set_foreign_fetch_scopes(
+ std::vector<GURL>(1, kForeignFetchScope));
live_registration->SetWaitingVersion(live_version);
live_registration->set_last_update_check(kYesterday);
EXPECT_EQ(SERVICE_WORKER_OK,
@@ -618,6 +625,10 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
EXPECT_EQ(kYesterday, found_registration->last_update_check());
EXPECT_EQ(ServiceWorkerVersion::INSTALLED,
found_registration->waiting_version()->status());
+ EXPECT_EQ(
+ 1u, found_registration->waiting_version()->foreign_fetch_scopes().size());
+ EXPECT_EQ(kForeignFetchScope,
+ found_registration->waiting_version()->foreign_fetch_scopes()[0]);
// Update to active and update the last check time.
scoped_refptr<ServiceWorkerVersion> temp_version =
@@ -633,8 +644,8 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
// Trying to update a unstored registration to active should fail.
scoped_refptr<ServiceWorkerRegistration> unstored_registration =
- new ServiceWorkerRegistration(
- kScope, kRegistrationId + 1, context_ptr_);
+ new ServiceWorkerRegistration(kScope, kRegistrationId + 1,
+ context()->AsWeakPtr());
EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
UpdateToActiveState(unstored_registration));
unstored_registration = NULL;
@@ -653,10 +664,10 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
EXPECT_EQ(kToday, found_registration->last_update_check());
// Delete from storage but with a instance still live.
- EXPECT_TRUE(context_->GetLiveVersion(kRegistrationId));
+ EXPECT_TRUE(context()->GetLiveVersion(kRegistrationId));
EXPECT_EQ(SERVICE_WORKER_OK,
DeleteRegistration(kRegistrationId, kScope.GetOrigin()));
- EXPECT_TRUE(context_->GetLiveVersion(kRegistrationId));
+ EXPECT_TRUE(context()->GetLiveVersion(kRegistrationId));
// Should no longer be found.
EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
@@ -676,18 +687,17 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
const GURL kScope("http://www.test.not/scope/");
const GURL kScript("http://www.test.not/script.js");
const GURL kDocumentUrl("http://www.test.not/scope/document.html");
- const int64 kRegistrationId = 0;
- const int64 kVersionId = 0;
+ const int64_t kRegistrationId = 0;
+ const int64_t kVersionId = 0;
scoped_refptr<ServiceWorkerRegistration> found_registration;
// Create an unstored registration.
scoped_refptr<ServiceWorkerRegistration> live_registration =
- new ServiceWorkerRegistration(
- kScope, kRegistrationId, context_ptr_);
- scoped_refptr<ServiceWorkerVersion> live_version =
- new ServiceWorkerVersion(
- live_registration.get(), kScript, kVersionId, context_ptr_);
+ new ServiceWorkerRegistration(kScope, kRegistrationId,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
+ live_registration.get(), kScript, kVersionId, context()->AsWeakPtr());
live_version->SetStatus(ServiceWorkerVersion::INSTALLING);
live_registration->SetWaitingVersion(live_version);
@@ -796,18 +806,17 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
TEST_F(ServiceWorkerStorageTest, StoreUserData) {
const GURL kScope("http://www.test.not/scope/");
const GURL kScript("http://www.test.not/script.js");
- const int64 kRegistrationId = 0;
- const int64 kVersionId = 0;
+ const int64_t kRegistrationId = 0;
+ const int64_t kVersionId = 0;
LazyInitialize();
// Store a registration.
scoped_refptr<ServiceWorkerRegistration> live_registration =
- new ServiceWorkerRegistration(
- kScope, kRegistrationId, context_ptr_);
- scoped_refptr<ServiceWorkerVersion> live_version =
- new ServiceWorkerVersion(
- live_registration.get(), kScript, kVersionId, context_ptr_);
+ new ServiceWorkerRegistration(kScope, kRegistrationId,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
+ live_registration.get(), kScript, kVersionId, context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(ServiceWorkerDatabase::ResourceRecord(
1, live_version->script_url(), 100));
@@ -825,7 +834,7 @@ TEST_F(ServiceWorkerStorageTest, StoreUserData) {
EXPECT_EQ("data", data_out);
EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
GetUserData(kRegistrationId, "unknown_key", &data_out));
- std::vector<std::pair<int64, std::string>> data_list_out;
+ std::vector<std::pair<int64_t, std::string>> data_list_out;
EXPECT_EQ(SERVICE_WORKER_OK,
GetUserDataForAllRegistrations("key", &data_list_out));
ASSERT_EQ(1u, data_list_out.size());
@@ -881,9 +890,8 @@ class ServiceWorkerResourceStorageTest : public ServiceWorkerStorageTest {
public:
void SetUp() override {
ServiceWorkerStorageTest::SetUp();
+ LazyInitialize();
- storage()->LazyInitialize(base::Bind(&base::DoNothing));
- base::RunLoop().RunUntilIdle();
scope_ = GURL("http://www.test.not/scope/");
script_ = GURL("http://www.test.not/script.js");
import_ = GURL("http://www.test.not/import.js");
@@ -911,10 +919,10 @@ class ServiceWorkerResourceStorageTest : public ServiceWorkerStorageTest {
registration_->waiting_version()->SetStatus(ServiceWorkerVersion::NEW);
// Add the resources ids to the uncommitted list.
- storage()->StoreUncommittedResponseId(resource_id1_);
- storage()->StoreUncommittedResponseId(resource_id2_);
+ storage()->StoreUncommittedResourceId(resource_id1_);
+ storage()->StoreUncommittedResourceId(resource_id2_);
base::RunLoop().RunUntilIdle();
- std::set<int64> verify_ids;
+ std::set<int64_t> verify_ids;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
storage()->database_->GetUncommittedResourceIds(&verify_ids));
EXPECT_EQ(2u, verify_ids.size());
@@ -941,12 +949,12 @@ class ServiceWorkerResourceStorageTest : public ServiceWorkerStorageTest {
GURL script_;
GURL import_;
GURL document_url_;
- int64 registration_id_;
- int64 version_id_;
- int64 resource_id1_;
- uint64 resource_id1_size_;
- int64 resource_id2_;
- uint64 resource_id2_size_;
+ int64_t registration_id_;
+ int64_t version_id_;
+ int64_t resource_id1_;
+ uint64_t resource_id1_size_;
+ int64_t resource_id2_;
+ uint64_t resource_id2_size_;
scoped_refptr<ServiceWorkerRegistration> registration_;
};
@@ -954,23 +962,17 @@ class ServiceWorkerResourceStorageDiskTest
: public ServiceWorkerResourceStorageTest {
public:
void SetUp() override {
- ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir());
+ ASSERT_TRUE(InitUserDataDirectory());
ServiceWorkerResourceStorageTest::SetUp();
}
- base::FilePath GetUserDataDirectory() override {
- return user_data_directory_.path();
- }
-
- protected:
- base::ScopedTempDir user_data_directory_;
};
TEST_F(ServiceWorkerResourceStorageTest,
WriteMetadataWithServiceWorkerResponseMetadataWriter) {
const char kMetadata1[] = "Test metadata";
const char kMetadata2[] = "small";
- int64 new_resource_id_ = storage()->NewResourceId();
+ int64_t new_resource_id_ = storage()->NewResourceId();
// Writing metadata to nonexistent resoirce ID must fail.
EXPECT_GE(0, WriteResponseMetadata(storage(), new_resource_id_, kMetadata1));
@@ -1028,7 +1030,7 @@ TEST_F(ServiceWorkerResourceStorageTest,
TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
- std::set<int64> verify_ids;
+ std::set<int64_t> verify_ids;
registration_->SetWaitingVersion(NULL);
registration_ = NULL;
@@ -1060,7 +1062,7 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_WaitingVersion) {
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
- std::set<int64> verify_ids;
+ std::set<int64_t> verify_ids;
// Deleting the registration should result in the resources being added to the
// purgeable list and then doomed in the disk cache and removed from that
@@ -1107,12 +1109,12 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_ActiveVersion) {
scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
33 /* dummy render process id */, MSG_ROUTING_NONE,
1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- context_->AsWeakPtr(), NULL));
+ context()->AsWeakPtr(), NULL));
registration_->active_version()->AddControllee(host.get());
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
- std::set<int64> verify_ids;
+ std::set<int64_t> verify_ids;
// Deleting the registration should move the resources to the purgeable list
// but keep them available.
@@ -1158,12 +1160,12 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
33 /* dummy render process id */, MSG_ROUTING_NONE,
1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- context_->AsWeakPtr(), NULL));
+ context()->AsWeakPtr(), NULL));
registration_->active_version()->AddControllee(host.get());
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
- std::set<int64> verify_ids;
+ std::set<int64_t> verify_ids;
// Deleting the registration should move the resources to the purgeable list
// but keep them available.
@@ -1188,8 +1190,8 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_, true));
// Also add an uncommitted resource.
- int64 kStaleUncommittedResourceId = storage()->NewResourceId();
- storage()->StoreUncommittedResponseId(kStaleUncommittedResourceId);
+ int64_t kStaleUncommittedResourceId = storage()->NewResourceId();
+ storage()->StoreUncommittedResourceId(kStaleUncommittedResourceId);
base::RunLoop().RunUntilIdle();
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1201,25 +1203,13 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
// Simulate browser shutdown. The purgeable and uncommitted resources are now
// stale.
- context_.reset();
- scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
- new MockServiceWorkerDatabaseTaskManager(
- base::ThreadTaskRunnerHandle::Get()));
- context_.reset(
- new ServiceWorkerContextCore(GetUserDataDirectory(),
- database_task_manager.Pass(),
- base::ThreadTaskRunnerHandle::Get(),
- NULL,
- NULL,
- NULL,
- NULL));
- storage()->LazyInitialize(base::Bind(&base::DoNothing));
- base::RunLoop().RunUntilIdle();
+ InitializeTestHelper();
+ LazyInitialize();
// Store a new uncommitted resource. This triggers stale resource cleanup.
- int64 kNewResourceId = storage()->NewResourceId();
+ int64_t kNewResourceId = storage()->NewResourceId();
WriteBasicResponse(storage(), kNewResourceId);
- storage()->StoreUncommittedResponseId(kNewResourceId);
+ storage()->StoreUncommittedResourceId(kNewResourceId);
base::RunLoop().RunUntilIdle();
// The stale resources should be purged, but the new resource should persist.
@@ -1329,16 +1319,17 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration) {
scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
33 /* dummy render process id */, MSG_ROUTING_NONE,
1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- context_->AsWeakPtr(), NULL));
+ context()->AsWeakPtr(), NULL));
registration_->active_version()->AddControllee(host.get());
bool was_called = false;
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
- std::set<int64> verify_ids;
+ std::set<int64_t> verify_ids;
// Make an updated registration.
scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
- registration_.get(), script_, storage()->NewVersionId(), context_ptr_);
+ registration_.get(), script_, storage()->NewVersionId(),
+ context()->AsWeakPtr());
live_version->SetStatus(ServiceWorkerVersion::NEW);
registration_->SetWaitingVersion(live_version);
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
@@ -1389,14 +1380,13 @@ TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
// Registration for "/scope/".
const GURL kScope1("http://www.example.com/scope/");
const GURL kScript1("http://www.example.com/script1.js");
- const int64 kRegistrationId1 = 1;
- const int64 kVersionId1 = 1;
+ const int64_t kRegistrationId1 = 1;
+ const int64_t kVersionId1 = 1;
scoped_refptr<ServiceWorkerRegistration> live_registration1 =
- new ServiceWorkerRegistration(
- kScope1, kRegistrationId1, context_ptr_);
- scoped_refptr<ServiceWorkerVersion> live_version1 =
- new ServiceWorkerVersion(
- live_registration1.get(), kScript1, kVersionId1, context_ptr_);
+ new ServiceWorkerRegistration(kScope1, kRegistrationId1,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version1 = new ServiceWorkerVersion(
+ live_registration1.get(), kScript1, kVersionId1, context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records1;
records1.push_back(ServiceWorkerDatabase::ResourceRecord(
1, live_version1->script_url(), 100));
@@ -1407,14 +1397,13 @@ TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
// Registration for "/scope/foo".
const GURL kScope2("http://www.example.com/scope/foo");
const GURL kScript2("http://www.example.com/script2.js");
- const int64 kRegistrationId2 = 2;
- const int64 kVersionId2 = 2;
+ const int64_t kRegistrationId2 = 2;
+ const int64_t kVersionId2 = 2;
scoped_refptr<ServiceWorkerRegistration> live_registration2 =
- new ServiceWorkerRegistration(
- kScope2, kRegistrationId2, context_ptr_);
- scoped_refptr<ServiceWorkerVersion> live_version2 =
- new ServiceWorkerVersion(
- live_registration2.get(), kScript2, kVersionId2, context_ptr_);
+ new ServiceWorkerRegistration(kScope2, kRegistrationId2,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version2 = new ServiceWorkerVersion(
+ live_registration2.get(), kScript2, kVersionId2, context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records2;
records2.push_back(ServiceWorkerDatabase::ResourceRecord(
2, live_version2->script_url(), 100));
@@ -1425,14 +1414,13 @@ TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
// Registration for "/scope/foobar".
const GURL kScope3("http://www.example.com/scope/foobar");
const GURL kScript3("http://www.example.com/script3.js");
- const int64 kRegistrationId3 = 3;
- const int64 kVersionId3 = 3;
+ const int64_t kRegistrationId3 = 3;
+ const int64_t kVersionId3 = 3;
scoped_refptr<ServiceWorkerRegistration> live_registration3 =
- new ServiceWorkerRegistration(
- kScope3, kRegistrationId3, context_ptr_);
- scoped_refptr<ServiceWorkerVersion> live_version3 =
- new ServiceWorkerVersion(
- live_registration3.get(), kScript3, kVersionId3, context_ptr_);
+ new ServiceWorkerRegistration(kScope3, kRegistrationId3,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version3 = new ServiceWorkerVersion(
+ live_registration3.get(), kScript3, kVersionId3, context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records3;
records3.push_back(ServiceWorkerDatabase::ResourceRecord(
3, live_version3->script_url(), 100));
@@ -1473,4 +1461,117 @@ TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
EXPECT_EQ(live_registration2, found_registration);
}
+class ServiceWorkerStorageDiskTest : public ServiceWorkerStorageTest {
+ public:
+ void SetUp() override {
+ ASSERT_TRUE(InitUserDataDirectory());
+ ServiceWorkerStorageTest::SetUp();
+ }
+};
+
+TEST_F(ServiceWorkerStorageDiskTest, OriginHasForeignFetchRegistrations) {
+ LazyInitialize();
+
+ // Registration 1 for http://www.example.com
+ const GURL kScope1("http://www.example.com/scope/");
+ const GURL kScript1("http://www.example.com/script1.js");
+ const int64_t kRegistrationId1 = 1;
+ const int64_t kVersionId1 = 1;
+ scoped_refptr<ServiceWorkerRegistration> live_registration1 =
+ new ServiceWorkerRegistration(kScope1, kRegistrationId1,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version1 = new ServiceWorkerVersion(
+ live_registration1.get(), kScript1, kVersionId1, context()->AsWeakPtr());
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records1;
+ records1.push_back(ServiceWorkerDatabase::ResourceRecord(
+ 1, live_version1->script_url(), 100));
+ live_version1->script_cache_map()->SetResources(records1);
+ live_version1->SetStatus(ServiceWorkerVersion::INSTALLED);
+ live_version1->set_foreign_fetch_scopes(std::vector<GURL>(1, kScope1));
+ live_registration1->SetWaitingVersion(live_version1);
+
+ // Registration 2 for http://www.example.com
+ const GURL kScope2("http://www.example.com/scope/foo");
+ const GURL kScript2("http://www.example.com/script2.js");
+ const int64_t kRegistrationId2 = 2;
+ const int64_t kVersionId2 = 2;
+ scoped_refptr<ServiceWorkerRegistration> live_registration2 =
+ new ServiceWorkerRegistration(kScope2, kRegistrationId2,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version2 = new ServiceWorkerVersion(
+ live_registration2.get(), kScript2, kVersionId2, context()->AsWeakPtr());
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records2;
+ records2.push_back(ServiceWorkerDatabase::ResourceRecord(
+ 2, live_version2->script_url(), 100));
+ live_version2->script_cache_map()->SetResources(records2);
+ live_version2->SetStatus(ServiceWorkerVersion::INSTALLED);
+ live_version2->set_foreign_fetch_scopes(std::vector<GURL>(1, kScope2));
+ live_registration2->SetWaitingVersion(live_version2);
+
+ // Registration for http://www.test.com
+ const GURL kScope3("http://www.test.com/scope/foobar");
+ const GURL kScript3("http://www.test.com/script3.js");
+ const int64_t kRegistrationId3 = 3;
+ const int64_t kVersionId3 = 3;
+ scoped_refptr<ServiceWorkerRegistration> live_registration3 =
+ new ServiceWorkerRegistration(kScope3, kRegistrationId3,
+ context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> live_version3 = new ServiceWorkerVersion(
+ live_registration3.get(), kScript3, kVersionId3, context()->AsWeakPtr());
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records3;
+ records3.push_back(ServiceWorkerDatabase::ResourceRecord(
+ 3, live_version3->script_url(), 100));
+ live_version3->script_cache_map()->SetResources(records3);
+ live_version3->SetStatus(ServiceWorkerVersion::INSTALLED);
+ live_registration3->SetWaitingVersion(live_version3);
+
+ // Neither origin should have registrations before they are stored.
+ const GURL kOrigin1 = kScope1.GetOrigin();
+ const GURL kOrigin2 = kScope3.GetOrigin();
+ EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
+ EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
+
+ // Store all registrations.
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ StoreRegistration(live_registration1, live_version1));
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ StoreRegistration(live_registration2, live_version2));
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ StoreRegistration(live_registration3, live_version3));
+
+ // Now first origin should have foreign fetch registrations, second doesn't.
+ EXPECT_TRUE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
+ EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
+
+ // Remove one registration at first origin.
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ DeleteRegistration(kRegistrationId1, kScope1.GetOrigin()));
+
+ // First origin should still have a registration left.
+ EXPECT_TRUE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
+ EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
+
+ // Simulate browser shutdown and restart.
+ live_registration1 = nullptr;
+ live_version1 = nullptr;
+ live_registration2 = nullptr;
+ live_version2 = nullptr;
+ live_registration3 = nullptr;
+ live_version3 = nullptr;
+ InitializeTestHelper();
+ LazyInitialize();
+
+ // First origin should still have a registration left.
+ EXPECT_TRUE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
+ EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
+
+ // Remove other registration at first origin.
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ DeleteRegistration(kRegistrationId2, kScope2.GetOrigin()));
+
+ // No foreign fetch registrations remain.
+ EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
+ EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_test_utils.h b/chromium/content/browser/service_worker/service_worker_test_utils.h
index 5bb72c9e105..9e3983baa59 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.h
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.h
@@ -26,12 +26,14 @@ CreateReceiver(BrowserThread::ID run_quit_thread,
return base::Bind(&ReceiveResult<Arg>, run_quit_thread, quit, out);
}
-template <typename Arg> base::Callback<void(Arg)>
-CreateReceiverOnCurrentThread(Arg* out) {
+template <typename Arg>
+base::Callback<void(Arg)> CreateReceiverOnCurrentThread(
+ Arg* out,
+ const base::Closure& quit = base::Closure()) {
BrowserThread::ID id;
bool ret = BrowserThread::GetCurrentThreadIdentifier(&id);
DCHECK(ret);
- return base::Bind(&ReceiveResult<Arg>, id, base::Closure(), out);
+ return base::Bind(&ReceiveResult<Arg>, id, quit, out);
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_unregister_job.cc b/chromium/content/browser/service_worker/service_worker_unregister_job.cc
index 155d9fcfed8..c0fc9dc4cb6 100644
--- a/chromium/content/browser/service_worker/service_worker_unregister_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_unregister_job.cc
@@ -80,21 +80,21 @@ void ServiceWorkerUnregisterJob::OnRegistrationFound(
Complete(registration->id(), SERVICE_WORKER_OK);
}
-void ServiceWorkerUnregisterJob::Complete(int64 registration_id,
+void ServiceWorkerUnregisterJob::Complete(int64_t registration_id,
ServiceWorkerStatusCode status) {
CompleteInternal(registration_id, status);
context_->job_coordinator()->FinishJob(pattern_, this);
}
void ServiceWorkerUnregisterJob::CompleteInternal(
- int64 registration_id,
+ int64_t registration_id,
ServiceWorkerStatusCode status) {
if (!is_promise_resolved_)
ResolvePromise(registration_id, status);
}
void ServiceWorkerUnregisterJob::ResolvePromise(
- int64 registration_id,
+ int64_t registration_id,
ServiceWorkerStatusCode status) {
DCHECK(!is_promise_resolved_);
is_promise_resolved_ = true;
diff --git a/chromium/content/browser/service_worker/service_worker_unregister_job.h b/chromium/content/browser/service_worker/service_worker_unregister_job.h
index 282167e9a95..a614253f076 100644
--- a/chromium/content/browser/service_worker/service_worker_unregister_job.h
+++ b/chromium/content/browser/service_worker/service_worker_unregister_job.h
@@ -5,8 +5,11 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UNREGISTER_JOB_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UNREGISTER_JOB_H_
+#include <stdint.h>
+
#include <vector>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_register_job_base.h"
#include "content/common/service_worker/service_worker_status_code.h"
@@ -27,7 +30,7 @@ class ServiceWorkerStorage;
// ServiceWorkerRegistration itself.
class ServiceWorkerUnregisterJob : public ServiceWorkerRegisterJobBase {
public:
- typedef base::Callback<void(int64 registration_id,
+ typedef base::Callback<void(int64_t registration_id,
ServiceWorkerStatusCode status)>
UnregistrationCallback;
@@ -49,9 +52,10 @@ class ServiceWorkerUnregisterJob : public ServiceWorkerRegisterJobBase {
void OnRegistrationFound(
ServiceWorkerStatusCode status,
const scoped_refptr<ServiceWorkerRegistration>& registration);
- void Complete(int64 registration_id, ServiceWorkerStatusCode status);
- void CompleteInternal(int64 registration_id, ServiceWorkerStatusCode status);
- void ResolvePromise(int64 registration_id, ServiceWorkerStatusCode status);
+ void Complete(int64_t registration_id, ServiceWorkerStatusCode status);
+ void CompleteInternal(int64_t registration_id,
+ ServiceWorkerStatusCode status);
+ void ResolvePromise(int64_t registration_id, ServiceWorkerStatusCode status);
base::WeakPtr<ServiceWorkerContextCore> context_;
const GURL pattern_;
diff --git a/chromium/content/browser/service_worker/service_worker_url_request_job.cc b/chromium/content/browser/service_worker/service_worker_url_request_job.cc
index 2572c93a59b..10e85020954 100644
--- a/chromium/content/browser/service_worker/service_worker_url_request_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_request_job.cc
@@ -4,14 +4,18 @@
#include "content/browser/service_worker/service_worker_url_request_job.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <limits>
#include <map>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/guid.h"
#include "base/location.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
@@ -28,7 +32,6 @@
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/common/referrer.h"
-#include "content/public/common/resource_response_info.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
@@ -80,6 +83,8 @@ net::NetLog::EventType RequestJobResultToNetEventType(
return n::TYPE_SERVICE_WORKER_ERROR_KILLED_WITH_BLOB;
case m::REQUEST_JOB_ERROR_KILLED_WITH_STREAM:
return n::TYPE_SERVICE_WORKER_ERROR_KILLED_WITH_STREAM;
+ case m::REQUEST_JOB_ERROR_BAD_DELEGATE:
+ return n::TYPE_SERVICE_WORKER_ERROR_BAD_DELEGATE;
// We can't log if there's no request; fallthrough.
case m::REQUEST_JOB_ERROR_NO_REQUEST:
// Obsolete types; fallthrough.
@@ -96,10 +101,14 @@ net::NetLog::EventType RequestJobResultToNetEventType(
} // namespace
+bool ServiceWorkerURLRequestJob::Delegate::RequestStillValid(
+ ServiceWorkerMetrics::URLRequestJobResult* result) {
+ return true;
+}
+
ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
const ResourceContext* resource_context,
FetchRequestMode request_mode,
@@ -108,9 +117,10 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
bool is_main_resource_load,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
- scoped_refptr<ResourceRequestBody> body)
+ scoped_refptr<ResourceRequestBody> body,
+ Delegate* delegate)
: net::URLRequestJob(request, network_delegate),
- provider_host_(provider_host),
+ delegate_(delegate),
response_type_(NOT_DETERMINED),
is_started_(false),
service_worker_response_type_(blink::WebServiceWorkerResponseTypeDefault),
@@ -125,7 +135,23 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
frame_type_(frame_type),
fall_back_required_(false),
body_(body),
- weak_factory_(this) {}
+ weak_factory_(this) {
+ DCHECK(delegate_) << "ServiceWorkerURLRequestJob requires a delegate";
+}
+
+ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
+ ClearStream();
+
+ if (!ShouldRecordResult())
+ return;
+ ServiceWorkerMetrics::URLRequestJobResult result =
+ ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED;
+ if (response_body_type_ == STREAM)
+ result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_STREAM;
+ else if (response_body_type_ == BLOB)
+ result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_BLOB;
+ RecordResult(result);
+}
void ServiceWorkerURLRequestJob::FallbackToNetwork() {
DCHECK_EQ(NOT_DETERMINED, response_type_);
@@ -203,49 +229,44 @@ void ServiceWorkerURLRequestJob::SetExtraRequestHeaders(
byte_range_ = ranges[0];
}
-bool ServiceWorkerURLRequestJob::ReadRawData(
- net::IOBuffer* buf, int buf_size, int *bytes_read) {
+int ServiceWorkerURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
DCHECK(buf);
DCHECK_GE(buf_size, 0);
- DCHECK(bytes_read);
DCHECK(waiting_stream_url_.is_empty());
+
+ int bytes_read = 0;
+
if (stream_.get()) {
- switch (stream_->ReadRawData(buf, buf_size, bytes_read)) {
+ switch (stream_->ReadRawData(buf, buf_size, &bytes_read)) {
case Stream::STREAM_HAS_DATA:
- DCHECK_GT(*bytes_read, 0);
- return true;
+ DCHECK_GT(bytes_read, 0);
+ return bytes_read;
case Stream::STREAM_COMPLETE:
- DCHECK(!*bytes_read);
+ DCHECK_EQ(0, bytes_read);
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
- return true;
+ return 0;
case Stream::STREAM_EMPTY:
stream_pending_buffer_ = buf;
stream_pending_buffer_size_ = buf_size;
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
- return false;
+ return net::ERR_IO_PENDING;
case Stream::STREAM_ABORTED:
// Handle this as connection reset.
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_CONNECTION_RESET));
- return false;
+ return net::ERR_CONNECTION_RESET;
}
NOTREACHED();
- return false;
+ return net::ERR_FAILED;
}
- if (!blob_request_) {
- *bytes_read = 0;
- return true;
- }
- blob_request_->Read(buf, buf_size, bytes_read);
+ if (!blob_request_)
+ return 0;
+ blob_request_->Read(buf, buf_size, &bytes_read);
net::URLRequestStatus status = blob_request_->status();
- SetStatus(status);
- if (status.is_io_pending())
- return false;
- if (status.is_success() && *bytes_read == 0)
+ if (status.status() != net::URLRequestStatus::SUCCESS)
+ return status.error();
+ if (bytes_read == 0)
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE);
- return status.is_success();
+ return bytes_read;
}
// TODO(falken): Refactor Blob and Stream specific handling to separate classes.
@@ -291,29 +312,18 @@ void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) {
void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request,
int bytes_read) {
- SetStatus(request->status());
if (!request->status().is_success()) {
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_BLOB_READ);
- NotifyDone(request->status());
- return;
- }
-
- if (bytes_read == 0) {
- // Protect because NotifyReadComplete() can destroy |this|.
- scoped_refptr<ServiceWorkerURLRequestJob> protect(this);
+ } else if (bytes_read == 0) {
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE);
- NotifyReadComplete(bytes_read);
- NotifyDone(request->status());
- return;
}
- NotifyReadComplete(bytes_read);
+ net::URLRequestStatus status = request->status();
+ ReadRawDataComplete(status.is_success() ? bytes_read : status.error());
}
// Overrides for Stream reading -----------------------------------------------
void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
- // Clear the IO_PENDING status.
- SetStatus(net::URLRequestStatus());
// Do nothing if stream_pending_buffer_ is empty, i.e. there's no ReadRawData
// operation waiting for IO completion.
if (!stream_pending_buffer_.get())
@@ -322,15 +332,15 @@ void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
// stream_pending_buffer_ is set to the IOBuffer instance provided to
// ReadRawData() by URLRequestJob.
- int bytes_read = 0;
- switch (stream_->ReadRawData(
- stream_pending_buffer_.get(), stream_pending_buffer_size_, &bytes_read)) {
+ int result = 0;
+ switch (stream_->ReadRawData(stream_pending_buffer_.get(),
+ stream_pending_buffer_size_, &result)) {
case Stream::STREAM_HAS_DATA:
- DCHECK_GT(bytes_read, 0);
+ DCHECK_GT(result, 0);
break;
case Stream::STREAM_COMPLETE:
// Calling NotifyReadComplete with 0 signals completion.
- DCHECK(!bytes_read);
+ DCHECK(!result);
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
break;
case Stream::STREAM_EMPTY:
@@ -338,9 +348,8 @@ void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
break;
case Stream::STREAM_ABORTED:
// Handle this as connection reset.
+ result = net::ERR_CONNECTION_RESET;
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_CONNECTION_RESET));
break;
}
@@ -348,7 +357,7 @@ void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
// safe for the observer to read.
stream_pending_buffer_ = nullptr;
stream_pending_buffer_size_ = 0;
- NotifyReadComplete(bytes_read);
+ ReadRawDataComplete(result);
}
void ServiceWorkerURLRequestJob::OnStreamRegistered(Stream* stream) {
@@ -361,6 +370,11 @@ void ServiceWorkerURLRequestJob::OnStreamRegistered(Stream* stream) {
CommitResponseHeader();
}
+base::WeakPtr<ServiceWorkerURLRequestJob>
+ServiceWorkerURLRequestJob::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
// Misc -----------------------------------------------------------------------
const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
@@ -371,40 +385,6 @@ const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
return http_response_info_.get();
}
-void ServiceWorkerURLRequestJob::GetExtraResponseInfo(
- ResourceResponseInfo* response_info) const {
- if (response_type_ != FORWARD_TO_SERVICE_WORKER) {
- response_info->was_fetched_via_service_worker = false;
- response_info->was_fallback_required_by_service_worker = false;
- response_info->original_url_via_service_worker = GURL();
- response_info->response_type_via_service_worker =
- blink::WebServiceWorkerResponseTypeDefault;
- return;
- }
- response_info->was_fetched_via_service_worker = true;
- response_info->was_fallback_required_by_service_worker = fall_back_required_;
- response_info->original_url_via_service_worker = response_url_;
- response_info->response_type_via_service_worker =
- service_worker_response_type_;
- response_info->service_worker_start_time = worker_start_time_;
- response_info->service_worker_ready_time = worker_ready_time_;
-}
-
-
-ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
- ClearStream();
-
- if (!ShouldRecordResult())
- return;
- ServiceWorkerMetrics::URLRequestJobResult result =
- ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED;
- if (response_body_type_ == STREAM)
- result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_STREAM;
- else if (response_body_type_ == BLOB)
- result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_BLOB;
- RecordResult(result);
-}
-
void ServiceWorkerURLRequestJob::MaybeStartRequest() {
if (is_started_ && response_type_ != NOT_DETERMINED) {
// Start asynchronously.
@@ -433,13 +413,12 @@ void ServiceWorkerURLRequestJob::StartRequest() {
return;
case FORWARD_TO_SERVICE_WORKER:
- if (!provider_host_) {
- RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST);
- DeliverErrorResponse();
- return;
- }
- if (!provider_host_->active_version()) {
- RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION);
+ ServiceWorkerMetrics::URLRequestJobResult result =
+ ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
+ ServiceWorkerVersion* active_worker =
+ delegate_->GetServiceWorkerVersion(&result);
+ if (!active_worker) {
+ RecordResult(result);
DeliverErrorResponse();
return;
}
@@ -448,8 +427,7 @@ void ServiceWorkerURLRequestJob::StartRequest() {
// Send a fetch event to the ServiceWorker associated to the
// provider_host.
fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
- CreateFetchRequest(),
- provider_host_->active_version(),
+ CreateFetchRequest(), active_worker,
base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
weak_factory_.GetWeakPtr()),
base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
@@ -465,7 +443,7 @@ void ServiceWorkerURLRequestJob::StartRequest() {
scoped_ptr<ServiceWorkerFetchRequest>
ServiceWorkerURLRequestJob::CreateFetchRequest() {
std::string blob_uuid;
- uint64 blob_size = 0;
+ uint64_t blob_size = 0;
CreateRequestBodyBlob(&blob_uuid, &blob_size);
scoped_ptr<ServiceWorkerFetchRequest> request(
new ServiceWorkerFetchRequest());
@@ -497,17 +475,17 @@ ServiceWorkerURLRequestJob::CreateFetchRequest() {
request->referrer =
Referrer(GURL(request_->referrer()), blink::WebReferrerPolicyDefault);
}
- return request.Pass();
+ return request;
}
bool ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid,
- uint64* blob_size) {
+ uint64_t* blob_size) {
if (!body_.get() || !blob_storage_context_)
return false;
// To ensure the blobs stick around until the end of the reading.
- ScopedVector<storage::BlobDataHandle> handles;
- ScopedVector<storage::BlobDataSnapshot> snapshots;
+ std::vector<scoped_ptr<storage::BlobDataHandle>> handles;
+ std::vector<scoped_ptr<storage::BlobDataSnapshot>> snapshots;
// TODO(dmurph): Allow blobs to be added below, so that the context can
// efficiently re-use blob items for the new blob.
std::vector<const ResourceRequestBody::Element*> resolved_elements;
@@ -526,20 +504,21 @@ bool ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid,
DCHECK_NE(storage::DataElement::TYPE_BLOB, item->type());
resolved_elements.push_back(item->data_element_ptr());
}
- handles.push_back(handle.release());
- snapshots.push_back(snapshot.release());
+ handles.push_back(std::move(handle));
+ snapshots.push_back(std::move(snapshot));
}
const std::string uuid(base::GenerateGUID());
- uint64 total_size = 0;
+ uint64_t total_size = 0;
storage::BlobDataBuilder blob_builder(uuid);
for (size_t i = 0; i < resolved_elements.size(); ++i) {
const ResourceRequestBody::Element& element = *resolved_elements[i];
- if (total_size != kuint64max && element.length() != kuint64max)
+ if (total_size != std::numeric_limits<uint64_t>::max() &&
+ element.length() != std::numeric_limits<uint64_t>::max())
total_size += element.length();
else
- total_size = kuint64max;
+ total_size = std::numeric_limits<uint64_t>::max();
switch (element.type()) {
case ResourceRequestBody::Element::TYPE_BYTES:
blob_builder.AppendData(element.bytes(), element.length());
@@ -589,10 +568,10 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
return;
}
- // A null |provider_host_| probably means the tab was closed. The null value
- // would cause problems down the line, so bail out.
- if (!provider_host_) {
- RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST);
+ ServiceWorkerMetrics::URLRequestJobResult result =
+ ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
+ if (!delegate_->RequestStillValid(&result)) {
+ RecordResult(result);
DeliverErrorResponse();
return;
}
@@ -600,9 +579,8 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
if (status != SERVICE_WORKER_OK) {
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH);
if (is_main_resource_load_) {
- // Using the service worker failed, so fallback to network. Detach the
- // controller so subresource requests also skip the worker.
- provider_host_->NotifyControllerLost();
+ // Using the service worker failed, so fallback to network.
+ delegate_->MainResourceLoadFailed();
response_type_ = FALLBACK_TO_NETWORK;
NotifyRestartRequired();
} else {
@@ -620,8 +598,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
// we returns a fall_back_required response to the renderer.
if ((request_mode_ == FETCH_REQUEST_MODE_CORS ||
request_mode_ == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) &&
- provider_host_->document_url().GetOrigin() !=
- request()->url().GetOrigin()) {
+ delegate_->GetRequestingOrigin() != request()->url().GetOrigin()) {
fall_back_required_ = true;
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS);
CreateResponseHeader(
@@ -644,7 +621,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
// error.
if (response.status_code == 0) {
RecordStatusZeroResponseError(response.error);
- NotifyDone(
+ NotifyStartError(
net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
return;
}
@@ -707,7 +684,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
return;
}
blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
- blob_data_handle.Pass(), request()->context(), this);
+ std::move(blob_data_handle), request()->context(), this);
blob_request_->Start();
}
@@ -818,4 +795,37 @@ void ServiceWorkerURLRequestJob::ClearStream() {
}
}
+void ServiceWorkerURLRequestJob::NotifyHeadersComplete() {
+ OnStartCompleted();
+ URLRequestJob::NotifyHeadersComplete();
+}
+
+void ServiceWorkerURLRequestJob::NotifyStartError(
+ net::URLRequestStatus status) {
+ OnStartCompleted();
+ URLRequestJob::NotifyStartError(status);
+}
+
+void ServiceWorkerURLRequestJob::NotifyRestartRequired() {
+ delegate_->OnPrepareToRestart(worker_start_time_, worker_ready_time_);
+ URLRequestJob::NotifyRestartRequired();
+}
+
+void ServiceWorkerURLRequestJob::OnStartCompleted() const {
+ if (response_type_ != FORWARD_TO_SERVICE_WORKER) {
+ delegate_->OnStartCompleted(
+ false /* was_fetched_via_service_worker */,
+ false /* was_fallback_required */,
+ GURL() /* original_url_via_service_worker */,
+ blink::WebServiceWorkerResponseTypeDefault,
+ base::TimeTicks() /* service_worker_start_time */,
+ base::TimeTicks() /* service_worker_ready_time */);
+ return;
+ }
+ delegate_->OnStartCompleted(true /* was_fetched_via_service_worker */,
+ fall_back_required_, response_url_,
+ service_worker_response_type_, worker_start_time_,
+ worker_ready_time_);
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_url_request_job.h b/chromium/content/browser/service_worker/service_worker_url_request_job.h
index 4815c0be1e9..ea2860dfa1c 100644
--- a/chromium/content/browser/service_worker/service_worker_url_request_job.h
+++ b/chromium/content/browser/service_worker/service_worker_url_request_job.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_REQUEST_JOB_H_
+#include <stdint.h>
+
#include <map>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
@@ -23,6 +26,7 @@
#include "net/http/http_byte_range.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
+#include "net/url_request/url_request_status.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponseType.h"
#include "url/gurl.h"
@@ -44,7 +48,6 @@ class ServiceWorkerFetchDispatcher;
class ServiceWorkerProviderHost;
class ServiceWorkerVersion;
class Stream;
-struct ResourceResponseInfo;
class CONTENT_EXPORT ServiceWorkerURLRequestJob
: public net::URLRequestJob,
@@ -52,10 +55,51 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
public StreamReadObserver,
public StreamRegisterObserver {
public:
+ class CONTENT_EXPORT Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ // Will be invoked before the request is restarted. The caller
+ // can use this opportunity to grab state from the
+ // ServiceWorkerURLRequestJob to determine how it should behave when the
+ // request is restarted.
+ virtual void OnPrepareToRestart(
+ base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) = 0;
+
+ // Called when the request has finished starting.
+ // Unlike URLRequestJob::NotifyComplete, called both on success and failure.
+ virtual void OnStartCompleted(
+ bool was_fetched_via_service_worker,
+ bool was_fallback_required,
+ const GURL& original_url_via_service_worker,
+ blink::WebServiceWorkerResponseType response_type_via_service_worker,
+ base::TimeTicks worker_start_time,
+ base::TimeTicks service_worker_ready_time) = 0;
+
+ // Returns the ServiceWorkerVersion fetch events for this request job should
+ // be dispatched to. If no appropriate worker can be determined, returns
+ // nullptr and sets |*result| to an appropriate error.
+ virtual ServiceWorkerVersion* GetServiceWorkerVersion(
+ ServiceWorkerMetrics::URLRequestJobResult* result) = 0;
+
+ // Called after dispatching the fetch event to determine if processing of
+ // the request should still continue, or if processing should be aborted.
+ // When false is returned, this sets |*result| to an appropriate error.
+ virtual bool RequestStillValid(
+ ServiceWorkerMetrics::URLRequestJobResult* result);
+
+ // Called to signal that loading failed, and that the resource being loaded
+ // was a main resource.
+ virtual void MainResourceLoadFailed() {}
+
+ // Returns the origin of the page/context which initiated this request.
+ virtual GURL GetRequestingOrigin() = 0;
+ };
+
ServiceWorkerURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
const ResourceContext* resource_context,
FetchRequestMode request_mode,
@@ -64,7 +108,10 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
bool is_main_resource_load,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
- scoped_refptr<ResourceRequestBody> body);
+ scoped_refptr<ResourceRequestBody> body,
+ Delegate* delegate);
+
+ ~ServiceWorkerURLRequestJob() override;
// Sets the response type.
void FallbackToNetwork();
@@ -87,7 +134,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override;
int GetResponseCode() const override;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;
// net::URLRequest::Delegate overrides that read the blob from the
// ServiceWorkerFetchResponse.
@@ -112,17 +159,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
// StreamRegisterObserver override:
void OnStreamRegistered(Stream* stream) override;
- void GetExtraResponseInfo(ResourceResponseInfo* response_info) const;
-
- const base::TimeTicks& worker_start_time() const {
- return worker_start_time_;
- }
- const base::TimeTicks& worker_ready_time() const {
- return worker_ready_time_;
- }
-
- protected:
- ~ServiceWorkerURLRequestJob() override;
+ base::WeakPtr<ServiceWorkerURLRequestJob> GetWeakPtr();
private:
enum ResponseType {
@@ -148,7 +185,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
// Creates BlobDataHandle of the request body from |body_|. This handle
// |request_body_blob_data_handle_| will be deleted when
// ServiceWorkerURLRequestJob is deleted.
- bool CreateRequestBodyBlob(std::string* blob_uuid, uint64* blob_size);
+ bool CreateRequestBodyBlob(std::string* blob_uuid, uint64_t* blob_size);
// For FORWARD_TO_SERVICE_WORKER case.
void DidPrepareFetchEvent();
@@ -181,7 +218,17 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
const net::HttpResponseInfo* http_info() const;
- base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
+ // Invoke callbacks before invoking corresponding URLRequestJob methods.
+ void NotifyHeadersComplete();
+ void NotifyStartError(net::URLRequestStatus status);
+ void NotifyRestartRequired();
+
+ // Wrapper that gathers parameters to |on_start_completed_callback_| and then
+ // calls it.
+ void OnStartCompleted() const;
+
+ // Not owned.
+ Delegate* delegate_;
// Timing info to show on the popup in Devtools' Network tab.
net::LoadTimingInfo load_timing_info_;
diff --git a/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index 938b580719d..48a1fdd05e3 100644
--- a/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -2,10 +2,14 @@
// 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_url_request_job.h"
+
+#include <stdint.h>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
@@ -19,7 +23,6 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_context.h"
@@ -55,21 +58,106 @@ class ServiceWorkerURLRequestJobTest;
namespace {
-const int kProcessID = 1;
const int kProviderID = 100;
const char kTestData[] = "Here is sample text for the blob.";
+class TestCallbackTracker {
+ public:
+ TestCallbackTracker() {}
+ ~TestCallbackTracker() {}
+
+ void OnStartCompleted(
+ bool was_fetched_via_service_worker,
+ bool was_fallback_required,
+ const GURL& original_url_via_service_worker,
+ blink::WebServiceWorkerResponseType response_type_via_service_worker,
+ base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) {
+ ++times_on_start_completed_invoked_;
+
+ was_fetched_via_service_worker_ = was_fetched_via_service_worker;
+ was_fallback_required_ = was_fallback_required;
+ original_url_via_service_worker_ = original_url_via_service_worker;
+ response_type_via_service_worker_ =
+ blink::WebServiceWorkerResponseTypeDefault;
+ service_worker_start_time_ = service_worker_start_time;
+ service_worker_ready_time_ = service_worker_ready_time;
+ }
+
+ void OnPrepareToRestart(base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) {
+ ++times_prepare_to_restart_invoked_;
+
+ was_fetched_via_service_worker_ = false;
+ was_fallback_required_ = false;
+ original_url_via_service_worker_ = GURL();
+ response_type_via_service_worker_ =
+ blink::WebServiceWorkerResponseTypeDefault;
+ service_worker_start_time_ = service_worker_start_time;
+ service_worker_ready_time_ = service_worker_ready_time;
+ }
+
+ int times_on_start_completed_invoked() const {
+ return times_on_start_completed_invoked_;
+ }
+
+ int times_prepare_to_restart_invoked() const {
+ return times_prepare_to_restart_invoked_;
+ }
+
+ bool was_fetched_via_service_worker() const {
+ return was_fetched_via_service_worker_;
+ }
+
+ bool was_fallback_required() const { return was_fallback_required_; }
+
+ const GURL& original_url_via_service_worker() const {
+ return original_url_via_service_worker_;
+ }
+
+ blink::WebServiceWorkerResponseType response_type_via_service_worker() const {
+ return response_type_via_service_worker_;
+ }
+
+ base::TimeTicks service_worker_start_time() const {
+ return service_worker_start_time_;
+ }
+
+ base::TimeTicks service_worker_ready_time() const {
+ return service_worker_ready_time_;
+ }
+
+ private:
+ int times_on_start_completed_invoked_ = 0;
+ int times_prepare_to_restart_invoked_ = 0;
+
+ // These are all updated every time OnStartCompleted / OnPrepareToRestart are
+ // invoked.
+ bool was_fetched_via_service_worker_ = false;
+ bool was_fallback_required_ = false;
+ GURL original_url_via_service_worker_;
+ blink::WebServiceWorkerResponseType response_type_via_service_worker_ =
+ blink::WebServiceWorkerResponseTypeDefault;
+ base::TimeTicks service_worker_start_time_;
+ base::TimeTicks service_worker_ready_time_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestCallbackTracker);
+};
+
class MockHttpProtocolHandler
: public net::URLRequestJobFactory::ProtocolHandler {
public:
MockHttpProtocolHandler(
base::WeakPtr<ServiceWorkerProviderHost> provider_host,
const ResourceContext* resource_context,
- base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
+ base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
+ ServiceWorkerURLRequestJob::Delegate* delegate)
: provider_host_(provider_host),
resource_context_(resource_context),
blob_storage_context_(blob_storage_context),
- job_(nullptr) {}
+ job_(nullptr),
+ delegate_(delegate) {}
+
~MockHttpProtocolHandler() override {}
net::URLRequestJob* MaybeCreateJob(
@@ -83,12 +171,11 @@ class MockHttpProtocolHandler
}
job_ = new ServiceWorkerURLRequestJob(
- request, network_delegate, provider_host_, blob_storage_context_,
- resource_context_, FETCH_REQUEST_MODE_NO_CORS,
- FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
- true /* is_main_resource_load */, REQUEST_CONTEXT_TYPE_HYPERLINK,
- REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
- scoped_refptr<ResourceRequestBody>());
+ request, network_delegate, blob_storage_context_, resource_context_,
+ FETCH_REQUEST_MODE_NO_CORS, FETCH_CREDENTIALS_MODE_OMIT,
+ FetchRedirectMode::FOLLOW_MODE, true /* is_main_resource_load */,
+ REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
+ scoped_refptr<ResourceRequestBody>(), delegate_);
job_->ForwardToServiceWorker();
return job_;
}
@@ -98,6 +185,7 @@ class MockHttpProtocolHandler
const ResourceContext* resource_context_;
base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
mutable ServiceWorkerURLRequestJob* job_;
+ ServiceWorkerURLRequestJob::Delegate* delegate_;
};
// Returns a BlobProtocolHandler that uses |blob_storage_context|. Caller owns
@@ -113,7 +201,9 @@ scoped_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler(
} // namespace
-class ServiceWorkerURLRequestJobTest : public testing::Test {
+class ServiceWorkerURLRequestJobTest
+ : public testing::Test,
+ public ServiceWorkerURLRequestJob::Delegate {
protected:
ServiceWorkerURLRequestJobTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
@@ -123,7 +213,7 @@ class ServiceWorkerURLRequestJobTest : public testing::Test {
void SetUp() override {
browser_context_.reset(new TestBrowserContext);
InitializeResourceContext(browser_context_.get());
- SetUpWithHelper(new EmbeddedWorkerTestHelper(base::FilePath(), kProcessID));
+ SetUpWithHelper(new EmbeddedWorkerTestHelper(base::FilePath()));
}
void SetUpWithHelper(EmbeddedWorkerTestHelper* helper,
@@ -167,10 +257,11 @@ class ServiceWorkerURLRequestJobTest : public testing::Test {
}
scoped_ptr<ServiceWorkerProviderHost> provider_host(
- new ServiceWorkerProviderHost(kProcessID, MSG_ROUTING_NONE, kProviderID,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- helper_->context()->AsWeakPtr(),
- nullptr));
+ new ServiceWorkerProviderHost(
+ helper_->mock_render_process_id(), MSG_ROUTING_NONE, kProviderID,
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW, helper_->context()->AsWeakPtr(),
+ nullptr));
+ provider_host_ = provider_host->AsWeakPtr();
provider_host->SetDocumentUrl(GURL("http://example.com/"));
registration_->SetActiveVersion(version_);
provider_host->AssociateRegistration(registration_.get(),
@@ -188,12 +279,12 @@ class ServiceWorkerURLRequestJobTest : public testing::Test {
"http",
make_scoped_ptr(new MockHttpProtocolHandler(
provider_host->AsWeakPtr(), browser_context_->GetResourceContext(),
- blob_storage_context->AsWeakPtr())));
+ blob_storage_context->AsWeakPtr(), this)));
url_request_job_factory_->SetProtocolHandler(
"blob", CreateMockBlobProtocolHandler(blob_storage_context));
url_request_context_.set_job_factory(url_request_job_factory_.get());
- helper_->context()->AddProviderHost(provider_host.Pass());
+ helper_->context()->AddProviderHost(std::move(provider_host));
}
void TearDown() override {
@@ -241,6 +332,59 @@ class ServiceWorkerURLRequestJobTest : public testing::Test {
return version_->HasInflightRequests();
}
+ // ServiceWorkerURLRequestJob::Delegate implementation:
+ void OnPrepareToRestart(base::TimeTicks service_worker_start_time,
+ base::TimeTicks service_worker_ready_time) override {
+ callback_tracker_.OnPrepareToRestart(service_worker_start_time,
+ service_worker_ready_time);
+ }
+
+ void OnStartCompleted(
+ bool was_fetched_via_service_worker,
+ bool was_fallback_required,
+ const GURL& original_url_via_service_worker,
+ blink::WebServiceWorkerResponseType response_type_via_service_worker,
+ base::TimeTicks worker_start_time,
+ base::TimeTicks service_worker_ready_time) override {
+ callback_tracker_.OnStartCompleted(
+ was_fetched_via_service_worker, was_fallback_required,
+ original_url_via_service_worker, response_type_via_service_worker,
+ worker_start_time, service_worker_ready_time);
+ }
+
+ ServiceWorkerVersion* GetServiceWorkerVersion(
+ ServiceWorkerMetrics::URLRequestJobResult* result) override {
+ if (!provider_host_) {
+ *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST;
+ return nullptr;
+ }
+ if (!provider_host_->active_version()) {
+ *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION;
+ return nullptr;
+ }
+ return provider_host_->active_version();
+ }
+
+ bool RequestStillValid(
+ ServiceWorkerMetrics::URLRequestJobResult* result) override {
+ if (!provider_host_) {
+ *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_PROVIDER_HOST;
+ return false;
+ }
+ return true;
+ }
+
+ void MainResourceLoadFailed() override {
+ CHECK(provider_host_);
+ // Detach the controller so subresource requests also skip the worker.
+ provider_host_->NotifyControllerLost();
+ }
+
+ GURL GetRequestingOrigin() override {
+ CHECK(provider_host_);
+ return provider_host_->document_url().GetOrigin();
+ }
+
TestBrowserThreadBundle thread_bundle_;
scoped_ptr<TestBrowserContext> browser_context_;
@@ -255,6 +399,9 @@ class ServiceWorkerURLRequestJobTest : public testing::Test {
scoped_ptr<storage::BlobDataBuilder> blob_data_;
+ TestCallbackTracker callback_tracker_;
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
+
private:
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLRequestJobTest);
};
@@ -262,19 +409,28 @@ class ServiceWorkerURLRequestJobTest : public testing::Test {
TEST_F(ServiceWorkerURLRequestJobTest, Simple) {
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
TestRequest(200, "OK", std::string(), true /* expect_valid_ssl */);
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
public:
- explicit ProviderDeleteHelper(int mock_render_process_id)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
+ ProviderDeleteHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
~ProviderDeleteHelper() override {}
protected:
void OnFetchEvent(int embedded_worker_id,
int request_id,
const ServiceWorkerFetchRequest& request) override {
- context()->RemoveProviderHost(kProcessID, kProviderID);
+ context()->RemoveProviderHost(mock_render_process_id(), kProviderID);
SimulateSend(new ServiceWorkerHostMsg_FetchEventFinished(
embedded_worker_id, request_id,
SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
@@ -292,11 +448,21 @@ TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostOnFetchEvent) {
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
// Shouldn't crash if the ProviderHost is deleted prior to completion of
// the fetch event.
- SetUpWithHelper(new ProviderDeleteHelper(kProcessID));
+ SetUpWithHelper(new ProviderDeleteHelper);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
TestRequest(500, "Service Worker Response Error", std::string(),
false /* expect_valid_ssl */);
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostBeforeFetchEvent) {
@@ -307,19 +473,28 @@ TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostBeforeFetchEvent) {
request_->set_method("GET");
request_->Start();
- helper_->context()->RemoveProviderHost(kProcessID, kProviderID);
+ helper_->context()->RemoveProviderHost(helper_->mock_render_process_id(),
+ kProviderID);
base::RunLoop().RunUntilIdle();
TestRequestResult(500, "Service Worker Response Error", std::string(),
false /* expect_valid_ssl */);
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_TRUE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_TRUE(callback_tracker_.service_worker_ready_time().is_null());
}
// Responds to fetch events with a blob.
class BlobResponder : public EmbeddedWorkerTestHelper {
public:
- BlobResponder(int mock_render_process_id,
- const std::string& blob_uuid,
- uint64 blob_size)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id),
+ BlobResponder(const std::string& blob_uuid, uint64_t blob_size)
+ : EmbeddedWorkerTestHelper(base::FilePath()),
blob_uuid_(blob_uuid),
blob_size_(blob_size) {}
~BlobResponder() override {}
@@ -338,7 +513,7 @@ class BlobResponder : public EmbeddedWorkerTestHelper {
}
std::string blob_uuid_;
- uint64 blob_size_;
+ uint64_t blob_size_;
private:
DISALLOW_COPY_AND_ASSIGN(BlobResponder);
@@ -355,26 +530,45 @@ TEST_F(ServiceWorkerURLRequestJobTest, BlobResponse) {
}
scoped_ptr<storage::BlobDataHandle> blob_handle =
blob_storage_context->context()->AddFinishedBlob(blob_data_.get());
- SetUpWithHelper(new BlobResponder(
- kProcessID, blob_handle->uuid(), expected_response.size()));
+ SetUpWithHelper(
+ new BlobResponder(blob_handle->uuid(), expected_response.size()));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
TestRequest(200, "OK", expected_response, true /* expect_valid_ssl */);
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
TEST_F(ServiceWorkerURLRequestJobTest, NonExistentBlobUUIDResponse) {
- SetUpWithHelper(new BlobResponder(kProcessID, "blob-id:nothing-is-here", 0));
+ SetUpWithHelper(new BlobResponder("blob-id:nothing-is-here", 0));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
TestRequest(500, "Service Worker Response Error", std::string(),
true /* expect_valid_ssl */);
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
// Responds to fetch events with a stream.
class StreamResponder : public EmbeddedWorkerTestHelper {
public:
- StreamResponder(int mock_render_process_id, const GURL& stream_url)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id),
- stream_url_(stream_url) {}
+ explicit StreamResponder(const GURL& stream_url)
+ : EmbeddedWorkerTestHelper(base::FilePath()), stream_url_(stream_url) {}
~StreamResponder() override {}
protected:
@@ -403,7 +597,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse) {
browser_context_->GetResourceContext());
scoped_refptr<Stream> stream =
new Stream(stream_context->registry(), nullptr, stream_url);
- SetUpWithHelper(new StreamResponder(kProcessID, stream_url));
+ SetUpWithHelper(new StreamResponder(stream_url));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
GURL("http://example.com/foo.html"), net::DEFAULT_PRIORITY,
@@ -430,6 +624,16 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse) {
EXPECT_EQ(expected_response, url_request_delegate_.response_data());
request_.reset();
EXPECT_FALSE(HasInflightRequests());
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_DelayedRegistration) {
@@ -437,7 +641,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_DelayedRegistration) {
StreamContext* stream_context =
GetStreamContextForResourceContext(
browser_context_->GetResourceContext());
- SetUpWithHelper(new StreamResponder(kProcessID, stream_url));
+ SetUpWithHelper(new StreamResponder(stream_url));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -467,6 +671,16 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_DelayedRegistration) {
EXPECT_EQ(expected_response, url_request_delegate_.response_data());
request_.reset();
EXPECT_FALSE(HasInflightRequests());
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
@@ -484,7 +698,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_QuickFinalize) {
stream->AddData(kTestData, sizeof(kTestData) - 1);
}
stream->Finalize();
- SetUpWithHelper(new StreamResponder(kProcessID, stream_url));
+ SetUpWithHelper(new StreamResponder(stream_url));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -503,6 +717,16 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_QuickFinalize) {
EXPECT_EQ(expected_response, url_request_delegate_.response_data());
request_.reset();
EXPECT_FALSE(HasInflightRequests());
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
@@ -513,7 +737,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_Flush) {
browser_context_->GetResourceContext());
scoped_refptr<Stream> stream =
new Stream(stream_context->registry(), nullptr, stream_url);
- SetUpWithHelper(new StreamResponder(kProcessID, stream_url));
+ SetUpWithHelper(new StreamResponder(stream_url));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -525,7 +749,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_Flush) {
expected_response.reserve((sizeof(kTestData) - 1) * 1024);
for (int i = 0; i < 1024; ++i) {
expected_response += kTestData;
- stream->AddData(kTestData, sizeof(kTestData) - 1);;
+ stream->AddData(kTestData, sizeof(kTestData) - 1);
stream->Flush();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(expected_response, url_request_delegate_.response_data());
@@ -538,6 +762,16 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_Flush) {
EXPECT_EQ("OK",
request_->response_headers()->GetStatusText());
EXPECT_EQ(expected_response, url_request_delegate_.response_data());
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
TEST_F(ServiceWorkerURLRequestJobTest, StreamResponseAndCancel) {
@@ -549,7 +783,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponseAndCancel) {
new Stream(stream_context->registry(), nullptr, stream_url);
ASSERT_EQ(stream.get(),
stream_context->registry()->GetStream(stream_url).get());
- SetUpWithHelper(new StreamResponder(kProcessID, stream_url));
+ SetUpWithHelper(new StreamResponder(stream_url));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -579,6 +813,16 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponseAndCancel) {
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request_->status().is_success());
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
TEST_F(ServiceWorkerURLRequestJobTest,
@@ -587,7 +831,7 @@ TEST_F(ServiceWorkerURLRequestJobTest,
StreamContext* stream_context =
GetStreamContextForResourceContext(
browser_context_->GetResourceContext());
- SetUpWithHelper(new StreamResponder(kProcessID, stream_url));
+ SetUpWithHelper(new StreamResponder(stream_url));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -611,13 +855,15 @@ TEST_F(ServiceWorkerURLRequestJobTest,
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(request_->status().is_success());
+
+ EXPECT_EQ(0, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
}
// Helper to simulate failing to dispatch a fetch event to a worker.
class FailFetchHelper : public EmbeddedWorkerTestHelper {
public:
- explicit FailFetchHelper(int mock_render_process_id)
- : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
+ FailFetchHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
~FailFetchHelper() override {}
protected:
@@ -632,7 +878,7 @@ class FailFetchHelper : public EmbeddedWorkerTestHelper {
};
TEST_F(ServiceWorkerURLRequestJobTest, FailFetchDispatch) {
- SetUpWithHelper(new FailFetchHelper(kProcessID));
+ SetUpWithHelper(new FailFetchHelper);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -647,17 +893,21 @@ TEST_F(ServiceWorkerURLRequestJobTest, FailFetchDispatch) {
EXPECT_EQ(200, request_->GetResponseCode());
EXPECT_EQ("PASS", url_request_delegate_.response_data());
EXPECT_FALSE(HasInflightRequests());
- ServiceWorkerProviderHost* host =
- helper_->context()->GetProviderHost(kProcessID, kProviderID);
+ ServiceWorkerProviderHost* host = helper_->context()->GetProviderHost(
+ helper_->mock_render_process_id(), kProviderID);
ASSERT_TRUE(host);
EXPECT_EQ(host->controlling_version(), nullptr);
+
+ EXPECT_EQ(0, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(1, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
// TODO(horo): Remove this test when crbug.com/485900 is fixed.
TEST_F(ServiceWorkerURLRequestJobTest, MainScriptHTTPResponseInfoNotSet) {
// Shouldn't crash if MainScriptHttpResponseInfo is not set.
- SetUpWithHelper(new EmbeddedWorkerTestHelper(base::FilePath(), kProcessID),
- false);
+ SetUpWithHelper(new EmbeddedWorkerTestHelper(base::FilePath()), false);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
GURL("http://example.com/foo.html"), net::DEFAULT_PRIORITY,
@@ -668,6 +918,16 @@ TEST_F(ServiceWorkerURLRequestJobTest, MainScriptHTTPResponseInfoNotSet) {
EXPECT_TRUE(request_->status().is_success());
EXPECT_EQ(200, request_->GetResponseCode());
EXPECT_EQ("", url_request_delegate_.response_data());
+
+ EXPECT_EQ(1, callback_tracker_.times_on_start_completed_invoked());
+ EXPECT_EQ(0, callback_tracker_.times_prepare_to_restart_invoked());
+ EXPECT_TRUE(callback_tracker_.was_fetched_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.was_fallback_required());
+ EXPECT_EQ(GURL(), callback_tracker_.original_url_via_service_worker());
+ EXPECT_EQ(blink::WebServiceWorkerResponseTypeDefault,
+ callback_tracker_.response_type_via_service_worker());
+ EXPECT_FALSE(callback_tracker_.service_worker_start_time().is_null());
+ EXPECT_FALSE(callback_tracker_.service_worker_ready_time().is_null());
}
// TODO(kinuko): Add more tests with different response data and also for
diff --git a/chromium/content/browser/service_worker/service_worker_version.cc b/chromium/content/browser/service_worker/service_worker_version.cc
index bcf2911888e..b77ba3b06ec 100644
--- a/chromium/content/browser/service_worker/service_worker_version.cc
+++ b/chromium/content/browser/service_worker/service_worker_version.cc
@@ -4,13 +4,15 @@
#include "content/browser/service_worker/service_worker_version.h"
-#include <algorithm>
+#include <stddef.h>
+
#include <map>
#include <string>
#include "base/command_line.h"
#include "base/guid.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
@@ -21,28 +23,21 @@
#include "base/time/time.h"
#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/message_port_message_filter.h"
#include "content/browser/message_port_service.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_client_utils.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_metrics.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_type_converters.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_observer.h"
-#include "content/public/common/background_sync.mojom.h"
-#include "content/public/common/child_process_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
@@ -55,9 +50,6 @@
namespace content {
using StatusCallback = ServiceWorkerVersion::StatusCallback;
-using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>;
-using GetClientsCallback =
- base::Callback<void(scoped_ptr<ServiceWorkerClients>)>;
namespace {
@@ -165,152 +157,6 @@ void RunErrorMessageCallback(
callback.Run(status);
}
-void RunErrorServicePortConnectCallback(
- const ServiceWorkerVersion::ServicePortConnectCallback& callback,
- ServiceWorkerStatusCode status) {
- callback.Run(status, false /* accept_connection */, base::string16(),
- base::string16());
-}
-
-using OpenURLCallback = base::Callback<void(int, int)>;
-
-// The OpenURLObserver class is a WebContentsObserver that will wait for a
-// WebContents to be initialized, run the |callback| passed to its constructor
-// then self destroy.
-// The callback will receive the process and frame ids. If something went wrong
-// those will be (kInvalidUniqueID, MSG_ROUTING_NONE).
-// The callback will be called in the IO thread.
-class OpenURLObserver : public WebContentsObserver {
- public:
- OpenURLObserver(WebContents* web_contents,
- int frame_tree_node_id,
- const OpenURLCallback& callback)
- : WebContentsObserver(web_contents),
- frame_tree_node_id_(frame_tree_node_id),
- callback_(callback) {}
-
- void DidCommitProvisionalLoadForFrame(
- RenderFrameHost* render_frame_host,
- const GURL& validated_url,
- ui::PageTransition transition_type) override {
- DCHECK(web_contents());
-
- RenderFrameHostImpl* rfhi =
- static_cast<RenderFrameHostImpl*>(render_frame_host);
- if (rfhi->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_)
- return;
-
- RunCallback(render_frame_host->GetProcess()->GetID(),
- render_frame_host->GetRoutingID());
- }
-
- void RenderProcessGone(base::TerminationStatus status) override {
- RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
- }
-
- void WebContentsDestroyed() override {
- RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
- }
-
- private:
- void RunCallback(int render_process_id, int render_frame_id) {
- // After running the callback, |this| will stop observing, thus
- // web_contents() should return nullptr and |RunCallback| should no longer
- // be called. Then, |this| will self destroy.
- DCHECK(web_contents());
-
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback_,
- render_process_id,
- render_frame_id));
- Observe(nullptr);
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
- }
-
- int frame_tree_node_id_;
- const OpenURLCallback callback_;
-
- DISALLOW_COPY_AND_ASSIGN(OpenURLObserver);
-};
-
-// This is only called for main frame navigations in OpenWindowOnUI().
-void DidOpenURL(const OpenURLCallback& callback, WebContents* web_contents) {
- DCHECK(web_contents);
-
- RenderFrameHostImpl* rfhi =
- static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame());
- new OpenURLObserver(web_contents,
- rfhi->frame_tree_node()->frame_tree_node_id(), callback);
-}
-
-void NavigateClientOnUI(const GURL& url,
- const GURL& script_url,
- int process_id,
- int frame_id,
- const OpenURLCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- RenderFrameHostImpl* rfhi = RenderFrameHostImpl::FromID(process_id, frame_id);
- WebContents* web_contents = WebContents::FromRenderFrameHost(rfhi);
-
- if (!rfhi || !web_contents) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(callback, ChildProcessHost::kInvalidUniqueID,
- MSG_ROUTING_NONE));
- return;
- }
-
- ui::PageTransition transition = rfhi->GetParent()
- ? ui::PAGE_TRANSITION_AUTO_SUBFRAME
- : ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
- int frame_tree_node_id = rfhi->frame_tree_node()->frame_tree_node_id();
-
- OpenURLParams params(
- url, Referrer::SanitizeForRequest(
- url, Referrer(script_url, blink::WebReferrerPolicyDefault)),
- frame_tree_node_id, CURRENT_TAB, transition,
- true /* is_renderer_initiated */);
- web_contents->OpenURL(params);
- new OpenURLObserver(web_contents, frame_tree_node_id, callback);
-}
-
-void OpenWindowOnUI(
- const GURL& url,
- const GURL& script_url,
- int process_id,
- const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper,
- const OpenURLCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- BrowserContext* browser_context = context_wrapper->storage_partition()
- ? context_wrapper->storage_partition()->browser_context()
- : nullptr;
- // We are shutting down.
- if (!browser_context)
- return;
-
- RenderProcessHost* render_process_host =
- RenderProcessHost::FromID(process_id);
- if (render_process_host->IsForGuestsOnly()) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback,
- ChildProcessHost::kInvalidUniqueID,
- MSG_ROUTING_NONE));
- return;
- }
-
- OpenURLParams params(
- url, Referrer::SanitizeForRequest(
- url, Referrer(script_url, blink::WebReferrerPolicyDefault)),
- NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
- true /* is_renderer_initiated */);
-
- GetContentClient()->browser()->OpenURL(
- browser_context, params,
- base::Bind(&DidOpenURL, callback));
-}
-
void KillEmbeddedWorkerProcess(int process_id, ResultCode code) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* render_process_host =
@@ -329,73 +175,18 @@ void RestartTick(base::TimeTicks* time) {
*time = base::TimeTicks().Now();
}
+bool RequestExpired(const base::TimeTicks& expiration) {
+ if (expiration.is_null())
+ return false;
+ return base::TimeTicks().Now() >= expiration;
+}
+
base::TimeDelta GetTickDuration(const base::TimeTicks& time) {
if (time.is_null())
return base::TimeDelta();
return base::TimeTicks().Now() - time;
}
-void OnGetWindowClientsFromUI(
- // The tuple contains process_id, frame_id, client_uuid.
- const std::vector<base::Tuple<int, int, std::string>>& clients_info,
- const GURL& script_url,
- const GetClientsCallback& callback) {
- scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients);
-
- for (const auto& it : clients_info) {
- ServiceWorkerClientInfo info =
- ServiceWorkerProviderHost::GetWindowClientInfoOnUI(base::get<0>(it),
- base::get<1>(it));
-
- // If the request to the provider_host returned an empty
- // ServiceWorkerClientInfo, that means that it wasn't possible to associate
- // it with a valid RenderFrameHost. It might be because the frame was killed
- // or navigated in between.
- if (info.IsEmpty())
- continue;
-
- // We can get info for a frame that was navigating end ended up with a
- // different URL than expected. In such case, we should make sure to not
- // expose cross-origin WindowClient.
- if (info.url.GetOrigin() != script_url.GetOrigin())
- continue;
-
- info.client_uuid = base::get<2>(it);
- clients->push_back(info);
- }
-
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(callback, base::Passed(&clients)));
-}
-
-void AddWindowClient(
- ServiceWorkerProviderHost* host,
- std::vector<base::Tuple<int, int, std::string>>* client_info) {
- if (host->client_type() != blink::WebServiceWorkerClientTypeWindow)
- return;
- client_info->push_back(base::MakeTuple(host->process_id(), host->frame_id(),
- host->client_uuid()));
-}
-
-void AddNonWindowClient(ServiceWorkerProviderHost* host,
- const ServiceWorkerClientQueryOptions& options,
- ServiceWorkerClients* clients) {
- blink::WebServiceWorkerClientType host_client_type = host->client_type();
- if (host_client_type == blink::WebServiceWorkerClientTypeWindow)
- return;
- if (options.client_type != blink::WebServiceWorkerClientTypeAll &&
- options.client_type != host_client_type)
- return;
-
- ServiceWorkerClientInfo client_info(blink::WebPageVisibilityStateHidden,
- false, // is_focused
- host->document_url(),
- REQUEST_CONTEXT_FRAME_TYPE_NONE,
- base::TimeTicks(), host_client_type);
- client_info.client_uuid = host->client_uuid();
- clients->push_back(client_info);
-}
-
bool IsInstalled(ServiceWorkerVersion::Status status) {
switch (status) {
case ServiceWorkerVersion::NEW:
@@ -411,17 +202,11 @@ bool IsInstalled(ServiceWorkerVersion::Status status) {
return false;
}
-struct ServiceWorkerClientInfoSortMRU {
- bool operator()(const ServiceWorkerClientInfo& a,
- const ServiceWorkerClientInfo& b) const {
- return a.last_focus_time > b.last_focus_time;
- }
-};
-
} // namespace
const int ServiceWorkerVersion::kTimeoutTimerDelaySeconds = 30;
-const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5;
+const int ServiceWorkerVersion::kStartInstalledWorkerTimeoutSeconds = 10;
+const int ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes = 5;
const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5;
const int ServiceWorkerVersion::kStopWorkerTimeoutSeconds = 5;
@@ -516,7 +301,7 @@ class ServiceWorkerVersion::PingController {
ServiceWorkerVersion::ServiceWorkerVersion(
ServiceWorkerRegistration* registration,
const GURL& script_url,
- int64 version_id,
+ int64_t version_id,
base::WeakPtr<ServiceWorkerContextCore> context)
: version_id_(version_id),
registration_id_(registration->id()),
@@ -528,6 +313,7 @@ ServiceWorkerVersion::ServiceWorkerVersion(
should_exclude_from_uma_(
ServiceWorkerMetrics::ShouldExcludeURLFromHistogram(scope_)),
weak_factory_(this) {
+ DCHECK_NE(kInvalidServiceWorkerVersionId, version_id);
DCHECK(context_);
DCHECK(registration);
context_->AddLiveVersion(this);
@@ -686,6 +472,46 @@ void ServiceWorkerVersion::DeferScheduledUpdate() {
update_timer_.Reset();
}
+int ServiceWorkerVersion::StartRequest(
+ ServiceWorkerMetrics::EventType event_type,
+ const StatusCallback& error_callback) {
+ OnBeginEvent();
+ DCHECK_EQ(RUNNING, running_status())
+ << "Can only start a request with a running worker.";
+ return AddRequest(error_callback, &custom_requests_, REQUEST_CUSTOM,
+ event_type);
+}
+
+int ServiceWorkerVersion::StartRequestWithCustomTimeout(
+ ServiceWorkerMetrics::EventType event_type,
+ const StatusCallback& error_callback,
+ const base::TimeDelta& timeout,
+ TimeoutBehavior timeout_behavior) {
+ OnBeginEvent();
+ DCHECK_EQ(RUNNING, running_status())
+ << "Can only start a request with a running worker.";
+ return AddRequestWithExpiration(
+ error_callback, &custom_requests_, REQUEST_CUSTOM, event_type,
+ base::TimeTicks::Now() + timeout, timeout_behavior);
+}
+
+bool ServiceWorkerVersion::FinishRequest(int request_id) {
+ PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id);
+ if (!request)
+ return false;
+ ServiceWorkerMetrics::RecordEventDuration(
+ request->event_type, base::TimeTicks::Now() - request->start_time);
+ RemoveCallbackAndStopIfRedundant(&custom_requests_, request_id);
+ return true;
+}
+
+void ServiceWorkerVersion::RunAfterStartWorker(
+ const StatusCallback& error_callback,
+ const base::Closure& task) {
+ StartWorker(base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
+ error_callback, task));
+}
+
void ServiceWorkerVersion::DispatchMessageEvent(
const base::string16& message,
const std::vector<TransferredMessagePort>& sent_message_ports,
@@ -787,7 +613,8 @@ void ServiceWorkerVersion::DispatchFetchEvent(
prepare_callback.Run();
- int request_id = AddRequest(fetch_callback, &fetch_requests_, REQUEST_FETCH);
+ int request_id = AddRequest(fetch_callback, &fetch_requests_, REQUEST_FETCH,
+ ServiceWorkerMetrics::EventType::FETCH);
ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
ServiceWorkerMsg_FetchEvent(request_id, request));
if (status != SERVICE_WORKER_OK) {
@@ -798,34 +625,6 @@ void ServiceWorkerVersion::DispatchFetchEvent(
}
}
-void ServiceWorkerVersion::DispatchSyncEvent(
- BackgroundSyncRegistrationHandle::HandleId handle_id,
- const StatusCallback& callback) {
- OnBeginEvent();
- DCHECK_EQ(ACTIVATED, status()) << status();
- if (running_status() != RUNNING) {
- // Schedule calling this method after starting the worker.
- StartWorker(base::Bind(
- &RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), callback,
- base::Bind(&self::DispatchSyncEvent, weak_factory_.GetWeakPtr(),
- handle_id, callback)));
- return;
- }
-
- int request_id = AddRequest(callback, &sync_requests_, REQUEST_SYNC);
- if (!background_sync_dispatcher_) {
- embedded_worker_->GetServiceRegistry()->ConnectToRemoteService(
- mojo::GetProxy(&background_sync_dispatcher_));
- background_sync_dispatcher_.set_connection_error_handler(base::Bind(
- &ServiceWorkerVersion::OnBackgroundSyncDispatcherConnectionError,
- weak_factory_.GetWeakPtr()));
- }
-
- background_sync_dispatcher_->Sync(
- handle_id, base::Bind(&self::OnSyncEventFinished,
- weak_factory_.GetWeakPtr(), request_id));
-}
-
void ServiceWorkerVersion::DispatchNotificationClickEvent(
const StatusCallback& callback,
int64_t persistent_notification_id,
@@ -844,8 +643,9 @@ void ServiceWorkerVersion::DispatchNotificationClickEvent(
return;
}
- int request_id = AddRequest(callback, &notification_click_requests_,
- REQUEST_NOTIFICATION_CLICK);
+ int request_id = AddRequest(
+ callback, &notification_click_requests_, REQUEST_NOTIFICATION_CLICK,
+ ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK);
ServiceWorkerStatusCode status =
embedded_worker_->SendMessage(ServiceWorkerMsg_NotificationClickEvent(
request_id, persistent_notification_id, notification_data,
@@ -870,7 +670,8 @@ void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback& callback,
return;
}
- int request_id = AddRequest(callback, &push_requests_, REQUEST_PUSH);
+ int request_id = AddRequest(callback, &push_requests_, REQUEST_PUSH,
+ ServiceWorkerMetrics::EventType::PUSH);
ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
ServiceWorkerMsg_PushEvent(request_id, data));
if (status != SERVICE_WORKER_OK) {
@@ -879,86 +680,6 @@ void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback& callback,
}
}
-void ServiceWorkerVersion::DispatchGeofencingEvent(
- const StatusCallback& callback,
- blink::WebGeofencingEventType event_type,
- const std::string& region_id,
- const blink::WebCircularGeofencingRegion& region) {
- OnBeginEvent();
- DCHECK_EQ(ACTIVATED, status()) << status();
-
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExperimentalWebPlatformFeatures)) {
- callback.Run(SERVICE_WORKER_ERROR_ABORT);
- return;
- }
-
- if (running_status() != RUNNING) {
- // Schedule calling this method after starting the worker.
- StartWorker(base::Bind(&RunTaskAfterStartWorker,
- weak_factory_.GetWeakPtr(),
- callback,
- base::Bind(&self::DispatchGeofencingEvent,
- weak_factory_.GetWeakPtr(),
- callback,
- event_type,
- region_id,
- region)));
- return;
- }
-
- int request_id =
- AddRequest(callback, &geofencing_requests_, REQUEST_GEOFENCING);
- ServiceWorkerStatusCode status =
- embedded_worker_->SendMessage(ServiceWorkerMsg_GeofencingEvent(
- request_id, event_type, region_id, region));
- if (status != SERVICE_WORKER_OK) {
- geofencing_requests_.Remove(request_id);
- RunSoon(base::Bind(callback, status));
- }
-}
-
-void ServiceWorkerVersion::DispatchServicePortConnectEvent(
- const ServicePortConnectCallback& callback,
- const GURL& target_url,
- const GURL& origin,
- int port_id) {
- OnBeginEvent();
- DCHECK_EQ(ACTIVATED, status()) << status();
-
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExperimentalWebPlatformFeatures)) {
- callback.Run(SERVICE_WORKER_ERROR_ABORT, false, base::string16(),
- base::string16());
- return;
- }
-
- if (running_status() != RUNNING) {
- // Schedule calling this method after starting the worker.
- StartWorker(
- base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
- base::Bind(&RunErrorServicePortConnectCallback, callback),
- base::Bind(&self::DispatchServicePortConnectEvent,
- weak_factory_.GetWeakPtr(), callback, target_url,
- origin, port_id)));
- return;
- }
-
- int request_id = AddRequest(callback, &service_port_connect_requests_,
- REQUEST_SERVICE_PORT_CONNECT);
- if (!service_port_dispatcher_) {
- embedded_worker_->GetServiceRegistry()->ConnectToRemoteService(
- mojo::GetProxy(&service_port_dispatcher_));
- service_port_dispatcher_.set_connection_error_handler(base::Bind(
- &ServiceWorkerVersion::OnServicePortDispatcherConnectionError,
- weak_factory_.GetWeakPtr()));
- }
- service_port_dispatcher_->Connect(
- mojo::String::From(target_url), mojo::String::From(origin), port_id,
- base::Bind(&ServiceWorkerVersion::OnServicePortConnectEventFinished,
- weak_factory_.GetWeakPtr(), request_id));
-}
-
void ServiceWorkerVersion::DispatchCrossOriginMessageEvent(
const NavigatorConnectClient& client,
const base::string16& message,
@@ -1014,10 +735,6 @@ void ServiceWorkerVersion::RemoveControllee(
FOR_EACH_OBSERVER(Listener, listeners_, OnNoControllees(this));
}
-bool ServiceWorkerVersion::HasWindowClients() {
- return !GetWindowClientsInternal(false /* include_uncontrolled */).empty();
-}
-
void ServiceWorkerVersion::AddStreamingURLRequestJob(
const ServiceWorkerURLRequestJob* request_job) {
DCHECK(streaming_url_request_jobs_.find(request_job) ==
@@ -1079,7 +796,7 @@ void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
skip_recording_startup_time_ = true;
// Cancel request timeouts.
- SetAllRequestTimes(base::TimeTicks());
+ SetAllRequestExpirations(base::TimeTicks());
return;
}
if (!start_callbacks_.empty()) {
@@ -1090,8 +807,10 @@ void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
RestartTick(&start_time_);
}
- // Reactivate request timeouts.
- SetAllRequestTimes(base::TimeTicks::Now());
+ // Reactivate request timeouts, setting them all to the same expiration time.
+ SetAllRequestExpirations(
+ base::TimeTicks::Now() +
+ base::TimeDelta::FromMinutes(kRequestTimeoutMinutes));
}
void ServiceWorkerVersion::SetMainScriptHttpResponseInfo(
@@ -1110,24 +829,49 @@ ServiceWorkerVersion::GetMainScriptHttpResponseInfo() {
return main_script_http_info_.get();
}
-ServiceWorkerVersion::RequestInfo::RequestInfo(int id,
- RequestType type,
- const base::TimeTicks& now)
- : id(id), type(type), time(now) {
-}
+ServiceWorkerVersion::RequestInfo::RequestInfo(
+ int id,
+ RequestType type,
+ ServiceWorkerMetrics::EventType event_type,
+ const base::TimeTicks& expiration,
+ TimeoutBehavior timeout_behavior)
+ : id(id),
+ type(type),
+ event_type(event_type),
+ expiration(expiration),
+ timeout_behavior(timeout_behavior) {}
ServiceWorkerVersion::RequestInfo::~RequestInfo() {
}
-template <typename CallbackType>
-ServiceWorkerVersion::PendingRequest<CallbackType>::PendingRequest(
- const CallbackType& callback,
- const base::TimeTicks& time)
- : callback(callback), start_time(time) {
+bool ServiceWorkerVersion::RequestInfo::operator>(
+ const RequestInfo& other) const {
+ return expiration > other.expiration;
}
template <typename CallbackType>
-ServiceWorkerVersion::PendingRequest<CallbackType>::~PendingRequest() {
+ServiceWorkerVersion::PendingRequest<CallbackType>::PendingRequest(
+ const CallbackType& callback,
+ const base::TimeTicks& time,
+ ServiceWorkerMetrics::EventType event_type)
+ : callback(callback), start_time(time), event_type(event_type) {}
+
+ServiceWorkerVersion::BaseMojoServiceWrapper::BaseMojoServiceWrapper(
+ ServiceWorkerVersion* worker,
+ const char* service_name)
+ : worker_(worker), service_name_(service_name) {}
+
+ServiceWorkerVersion::BaseMojoServiceWrapper::~BaseMojoServiceWrapper() {
+ IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer>::iterator iter(
+ &worker_->custom_requests_);
+ while (!iter.IsAtEnd()) {
+ PendingRequest<StatusCallback>* request = iter.GetCurrentValue();
+ if (request->mojo_service == service_name_) {
+ request->callback.Run(SERVICE_WORKER_ERROR_FAILED);
+ worker_->custom_requests_.Remove(iter.GetCurrentKey());
+ }
+ iter.Advance();
+ }
}
void ServiceWorkerVersion::OnThreadStarted() {
@@ -1146,6 +890,11 @@ void ServiceWorkerVersion::OnStarted() {
DCHECK_EQ(RUNNING, running_status());
RestartTick(&idle_time_);
+ // Reset the interval to normal. If may have been shortened so starting an
+ // existing worker can timeout quickly.
+ SetTimeoutTimerInterval(
+ base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds));
+
// Fire all start callbacks.
scoped_refptr<ServiceWorkerVersion> protect(this);
RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK);
@@ -1159,15 +908,8 @@ void ServiceWorkerVersion::OnStopping() {
// Shorten the interval so stalling in stopped can be fixed quickly. Once the
// worker stops, the timer is disabled. The interval will be reset to normal
// when the worker starts up again.
- DCHECK(timeout_timer_.IsRunning());
- base::TimeDelta delay =
- base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds);
- if (timeout_timer_.GetCurrentDelay() != delay) {
- timeout_timer_.Stop();
- timeout_timer_.Start(FROM_HERE, delay, this,
- &ServiceWorkerVersion::OnTimeoutTimer);
- }
-
+ SetTimeoutTimerInterval(
+ base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds));
FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this));
}
@@ -1244,8 +986,6 @@ bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
OnNotificationClickEventFinished)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished,
OnPushEventFinished)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished,
- OnGeofencingEventFinished)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow,
OnOpenWindow)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetCachedMetadata,
@@ -1262,6 +1002,8 @@ bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients,
OnClaimClients)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker)
+ IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterForeignFetchScopes,
+ OnRegisterForeignFetchScopes)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -1281,7 +1023,8 @@ void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker(
DCHECK_EQ(RUNNING, running_status())
<< "Worker stopped too soon after it was started.";
- int request_id = AddRequest(callback, &install_requests_, REQUEST_INSTALL);
+ int request_id = AddRequest(callback, &install_requests_, REQUEST_INSTALL,
+ ServiceWorkerMetrics::EventType::INSTALL);
ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
ServiceWorkerMsg_InstallEvent(request_id));
if (status != SERVICE_WORKER_OK) {
@@ -1295,7 +1038,8 @@ void ServiceWorkerVersion::DispatchActivateEventAfterStartWorker(
DCHECK_EQ(RUNNING, running_status())
<< "Worker stopped too soon after it was started.";
- int request_id = AddRequest(callback, &activate_requests_, REQUEST_ACTIVATE);
+ int request_id = AddRequest(callback, &activate_requests_, REQUEST_ACTIVATE,
+ ServiceWorkerMetrics::EventType::ACTIVATE);
ServiceWorkerStatusCode status =
embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id));
if (status != SERVICE_WORKER_OK) {
@@ -1311,22 +1055,10 @@ void ServiceWorkerVersion::OnGetClients(
"ServiceWorker", "ServiceWorkerVersion::OnGetClients", request_id,
"client_type", options.client_type, "include_uncontrolled",
options.include_uncontrolled);
-
- ServiceWorkerClients clients;
- if (controllee_map_.empty() && !options.include_uncontrolled) {
- OnGetClientsFinished(request_id, &clients);
- return;
- }
-
- // For Window clients we want to query the info on the UI thread first.
- if (options.client_type == blink::WebServiceWorkerClientTypeWindow ||
- options.client_type == blink::WebServiceWorkerClientTypeAll) {
- GetWindowClients(request_id, options);
- return;
- }
-
- GetNonWindowClients(request_id, options, &clients);
- OnGetClientsFinished(request_id, &clients);
+ service_worker_client_utils::GetClients(
+ weak_factory_.GetWeakPtr(), options,
+ base::Bind(&ServiceWorkerVersion::OnGetClientsFinished,
+ weak_factory_.GetWeakPtr(), request_id));
}
void ServiceWorkerVersion::OnGetClientsFinished(int request_id,
@@ -1335,10 +1067,11 @@ void ServiceWorkerVersion::OnGetClientsFinished(int request_id,
TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::OnGetClients",
request_id, "The number of clients", clients->size());
- if (running_status() != RUNNING)
+ // When Clients.matchAll() is called on the script evaluation phase, the
+ // running status can be STARTING here.
+ if (running_status() != STARTING && running_status() != RUNNING)
return;
- // Sort clients so that the most recently active tab is in the front.
- std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSortMRU());
+
embedded_worker_->SendMessage(
ServiceWorkerMsg_DidGetClients(request_id, *clients));
}
@@ -1361,8 +1094,8 @@ void ServiceWorkerVersion::OnActivateEventFinished(
if (result == blink::WebServiceWorkerEventResultRejected)
rv = SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED;
- UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.ActivateEvent.Time",
- base::TimeTicks::Now() - request->start_time);
+ ServiceWorkerMetrics::RecordEventDuration(
+ request->event_type, base::TimeTicks::Now() - request->start_time);
scoped_refptr<ServiceWorkerVersion> protect(this);
request->callback.Run(rv);
@@ -1388,8 +1121,8 @@ void ServiceWorkerVersion::OnInstallEventFinished(
if (result == blink::WebServiceWorkerEventResultRejected)
status = SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED;
- UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.InstallEvent.Time",
- base::TimeTicks::Now() - request->start_time);
+ ServiceWorkerMetrics::RecordEventDuration(
+ request->event_type, base::TimeTicks::Now() - request->start_time);
scoped_refptr<ServiceWorkerVersion> protect(this);
request->callback.Run(status);
@@ -1411,7 +1144,7 @@ void ServiceWorkerVersion::OnFetchEventFinished(
// TODO(kinuko): Record other event statuses too.
const bool handled = (result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE);
- metrics_->RecordEventHandledStatus(ServiceWorkerMetrics::EVENT_TYPE_FETCH,
+ metrics_->RecordEventHandledStatus(ServiceWorkerMetrics::EventType::FETCH,
handled);
ServiceWorkerMetrics::RecordFetchEventTime(
@@ -1422,23 +1155,6 @@ void ServiceWorkerVersion::OnFetchEventFinished(
RemoveCallbackAndStopIfRedundant(&fetch_requests_, request_id);
}
-void ServiceWorkerVersion::OnSyncEventFinished(
- int request_id,
- ServiceWorkerEventStatus status) {
- TRACE_EVENT1("ServiceWorker",
- "ServiceWorkerVersion::OnSyncEventFinished",
- "Request id", request_id);
- PendingRequest<StatusCallback>* request = sync_requests_.Lookup(request_id);
- if (!request) {
- NOTREACHED() << "Got unexpected message: " << request_id;
- return;
- }
-
- scoped_refptr<ServiceWorkerVersion> protect(this);
- request->callback.Run(mojo::ConvertTo<ServiceWorkerStatusCode>(status));
- RemoveCallbackAndStopIfRedundant(&sync_requests_, request_id);
-}
-
void ServiceWorkerVersion::OnNotificationClickEventFinished(
int request_id) {
TRACE_EVENT1("ServiceWorker",
@@ -1451,8 +1167,8 @@ void ServiceWorkerVersion::OnNotificationClickEventFinished(
return;
}
- UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.NotificationClickEvent.Time",
- base::TimeTicks::Now() - request->start_time);
+ ServiceWorkerMetrics::RecordEventDuration(
+ request->event_type, base::TimeTicks::Now() - request->start_time);
scoped_refptr<ServiceWorkerVersion> protect(this);
request->callback.Run(SERVICE_WORKER_OK);
@@ -1474,53 +1190,14 @@ void ServiceWorkerVersion::OnPushEventFinished(
if (result == blink::WebServiceWorkerEventResultRejected)
status = SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED;
- UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.PushEvent.Time",
- base::TimeTicks::Now() - request->start_time);
+ ServiceWorkerMetrics::RecordEventDuration(
+ request->event_type, base::TimeTicks::Now() - request->start_time);
scoped_refptr<ServiceWorkerVersion> protect(this);
request->callback.Run(status);
RemoveCallbackAndStopIfRedundant(&push_requests_, request_id);
}
-void ServiceWorkerVersion::OnGeofencingEventFinished(int request_id) {
- TRACE_EVENT1("ServiceWorker",
- "ServiceWorkerVersion::OnGeofencingEventFinished",
- "Request id",
- request_id);
- PendingRequest<StatusCallback>* request =
- geofencing_requests_.Lookup(request_id);
- if (!request) {
- NOTREACHED() << "Got unexpected message: " << request_id;
- return;
- }
-
- scoped_refptr<ServiceWorkerVersion> protect(this);
- request->callback.Run(SERVICE_WORKER_OK);
- RemoveCallbackAndStopIfRedundant(&geofencing_requests_, request_id);
-}
-
-void ServiceWorkerVersion::OnServicePortConnectEventFinished(
- int request_id,
- ServicePortConnectResult result,
- const mojo::String& name,
- const mojo::String& data) {
- TRACE_EVENT1("ServiceWorker",
- "ServiceWorkerVersion::OnServicePortConnectEventFinished",
- "Request id", request_id);
- PendingRequest<ServicePortConnectCallback>* request =
- service_port_connect_requests_.Lookup(request_id);
- if (!request) {
- NOTREACHED() << "Got unexpected message: " << request_id;
- return;
- }
-
- scoped_refptr<ServiceWorkerVersion> protect(this);
- request->callback.Run(SERVICE_WORKER_OK,
- result == SERVICE_PORT_CONNECT_RESULT_ACCEPT,
- name.To<base::string16>(), data.To<base::string16>());
- RemoveCallbackAndStopIfRedundant(&service_port_connect_requests_, request_id);
-}
-
void ServiceWorkerVersion::OnOpenWindow(int request_id, GURL url) {
// Just abort if we are shutting down.
if (!context_)
@@ -1551,61 +1228,28 @@ void ServiceWorkerVersion::OnOpenWindow(int request_id, GURL url) {
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&OpenWindowOnUI,
- url,
- script_url_,
- embedded_worker_->process_id(),
- make_scoped_refptr(context_->wrapper()),
- base::Bind(&ServiceWorkerVersion::DidOpenWindow,
- weak_factory_.GetWeakPtr(),
- request_id)));
+ service_worker_client_utils::OpenWindow(
+ url, script_url_, embedded_worker_->process_id(), context_,
+ base::Bind(&ServiceWorkerVersion::OnOpenWindowFinished,
+ weak_factory_.GetWeakPtr(), request_id));
}
-void ServiceWorkerVersion::DidOpenWindow(int request_id,
- int render_process_id,
- int render_frame_id) {
+void ServiceWorkerVersion::OnOpenWindowFinished(
+ int request_id,
+ ServiceWorkerStatusCode status,
+ const std::string& client_uuid,
+ const ServiceWorkerClientInfo& client_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (running_status() != RUNNING)
return;
- if (render_process_id == ChildProcessHost::kInvalidUniqueID &&
- render_frame_id == MSG_ROUTING_NONE) {
+ if (status != SERVICE_WORKER_OK) {
embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowError(
request_id, "Something went wrong while trying to open the window."));
return;
}
- for (auto it =
- context_->GetClientProviderHostIterator(script_url_.GetOrigin());
- !it->IsAtEnd(); it->Advance()) {
- ServiceWorkerProviderHost* provider_host = it->GetProviderHost();
- if (provider_host->process_id() != render_process_id ||
- provider_host->frame_id() != render_frame_id) {
- continue;
- }
- provider_host->GetWindowClientInfo(base::Bind(
- &ServiceWorkerVersion::OnOpenWindowFinished, weak_factory_.GetWeakPtr(),
- request_id, provider_host->client_uuid()));
- return;
- }
-
- // If here, it means that no provider_host was found, in which case, the
- // renderer should still be informed that the window was opened.
- OnOpenWindowFinished(request_id, std::string(), ServiceWorkerClientInfo());
-}
-
-void ServiceWorkerVersion::OnOpenWindowFinished(
- int request_id,
- const std::string& client_uuid,
- const ServiceWorkerClientInfo& client_info) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (running_status() != RUNNING)
- return;
-
ServiceWorkerClientInfo client(client_info);
// If the |client_info| is empty, it means that the opened window wasn't
@@ -1620,7 +1264,7 @@ void ServiceWorkerVersion::OnOpenWindowFinished(
void ServiceWorkerVersion::OnSetCachedMetadata(const GURL& url,
const std::vector<char>& data) {
- int64 callback_id = base::TimeTicks::Now().ToInternalValue();
+ int64_t callback_id = base::TimeTicks::Now().ToInternalValue();
TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
"ServiceWorkerVersion::OnSetCachedMetadata",
callback_id, "URL", url.spec());
@@ -1629,7 +1273,7 @@ void ServiceWorkerVersion::OnSetCachedMetadata(const GURL& url,
weak_factory_.GetWeakPtr(), callback_id));
}
-void ServiceWorkerVersion::OnSetCachedMetadataFinished(int64 callback_id,
+void ServiceWorkerVersion::OnSetCachedMetadataFinished(int64_t callback_id,
int result) {
TRACE_EVENT_ASYNC_END1("ServiceWorker",
"ServiceWorkerVersion::OnSetCachedMetadata",
@@ -1638,7 +1282,7 @@ void ServiceWorkerVersion::OnSetCachedMetadataFinished(int64 callback_id,
}
void ServiceWorkerVersion::OnClearCachedMetadata(const GURL& url) {
- int64 callback_id = base::TimeTicks::Now().ToInternalValue();
+ int64_t callback_id = base::TimeTicks::Now().ToInternalValue();
TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
"ServiceWorkerVersion::OnClearCachedMetadata",
callback_id, "URL", url.spec());
@@ -1647,7 +1291,7 @@ void ServiceWorkerVersion::OnClearCachedMetadata(const GURL& url) {
weak_factory_.GetWeakPtr(), callback_id));
}
-void ServiceWorkerVersion::OnClearCachedMetadataFinished(int64 callback_id,
+void ServiceWorkerVersion::OnClearCachedMetadataFinished(int64_t callback_id,
int result) {
TRACE_EVENT_ASYNC_END1("ServiceWorker",
"ServiceWorkerVersion::OnClearCachedMetadata",
@@ -1675,7 +1319,7 @@ void ServiceWorkerVersion::OnPostMessageToClient(
// possibly due to timing issue or bad message.
return;
}
- provider_host->PostMessage(this, message, sent_message_ports);
+ provider_host->PostMessageToClient(this, message, sent_message_ports);
}
void ServiceWorkerVersion::OnFocusClient(int request_id,
@@ -1755,56 +1399,28 @@ void ServiceWorkerVersion::OnNavigateClient(int request_id,
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&NavigateClientOnUI, url, script_url_,
- provider_host->process_id(), provider_host->frame_id(),
- base::Bind(&ServiceWorkerVersion::DidNavigateClient,
- weak_factory_.GetWeakPtr(), request_id)));
+ service_worker_client_utils::NavigateClient(
+ url, script_url_, provider_host->process_id(), provider_host->frame_id(),
+ context_, base::Bind(&ServiceWorkerVersion::OnNavigateClientFinished,
+ weak_factory_.GetWeakPtr(), request_id));
}
-void ServiceWorkerVersion::DidNavigateClient(int request_id,
- int render_process_id,
- int render_frame_id) {
+void ServiceWorkerVersion::OnNavigateClientFinished(
+ int request_id,
+ ServiceWorkerStatusCode status,
+ const std::string& client_uuid,
+ const ServiceWorkerClientInfo& client_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (running_status() != RUNNING)
return;
- if (render_process_id == ChildProcessHost::kInvalidUniqueID &&
- render_frame_id == MSG_ROUTING_NONE) {
+ if (status != SERVICE_WORKER_OK) {
embedded_worker_->SendMessage(
ServiceWorkerMsg_NavigateClientError(request_id, GURL()));
return;
}
- for (auto it =
- context_->GetClientProviderHostIterator(script_url_.GetOrigin());
- !it->IsAtEnd(); it->Advance()) {
- ServiceWorkerProviderHost* provider_host = it->GetProviderHost();
- if (provider_host->process_id() != render_process_id ||
- provider_host->frame_id() != render_frame_id) {
- continue;
- }
- provider_host->GetWindowClientInfo(base::Bind(
- &ServiceWorkerVersion::OnNavigateClientFinished,
- weak_factory_.GetWeakPtr(), request_id, provider_host->client_uuid()));
- return;
- }
-
- OnNavigateClientFinished(request_id, std::string(),
- ServiceWorkerClientInfo());
-}
-
-void ServiceWorkerVersion::OnNavigateClientFinished(
- int request_id,
- const std::string& client_uuid,
- const ServiceWorkerClientInfo& client_info) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (running_status() != RUNNING)
- return;
-
ServiceWorkerClientInfo client(client_info);
// If the |client_info| is empty, it means that the navigated client wasn't
@@ -1864,6 +1480,29 @@ void ServiceWorkerVersion::OnPongFromWorker() {
ping_controller_->OnPongReceived();
}
+void ServiceWorkerVersion::OnRegisterForeignFetchScopes(
+ const std::vector<GURL>& sub_scopes) {
+ DCHECK(status() == INSTALLING || status() == REDUNDANT) << status();
+ // Renderer should have already verified all these urls are inside the
+ // worker's scope, but verify again here on the browser process side.
+ GURL origin = scope_.GetOrigin();
+ std::string scope_path = scope_.path();
+ for (const GURL& url : sub_scopes) {
+ if (!url.is_valid() || url.GetOrigin() != origin ||
+ !base::StartsWith(url.path(), scope_path,
+ base::CompareCase::SENSITIVE)) {
+ DVLOG(1) << "Received unexpected invalid URL from renderer process.";
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&KillEmbeddedWorkerProcess, embedded_worker_->process_id(),
+ RESULT_CODE_KILLED_BAD_MESSAGE));
+ return;
+ }
+ }
+ foreign_fetch_scopes_.insert(foreign_fetch_scopes_.end(), sub_scopes.begin(),
+ sub_scopes.end());
+}
+
void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
const StatusCallback& callback,
ServiceWorkerStatusCode status,
@@ -1927,70 +1566,6 @@ void ServiceWorkerVersion::StartWorkerInternal() {
}
}
-void ServiceWorkerVersion::GetWindowClients(
- int request_id,
- const ServiceWorkerClientQueryOptions& options) {
- DCHECK(options.client_type == blink::WebServiceWorkerClientTypeWindow ||
- options.client_type == blink::WebServiceWorkerClientTypeAll);
- const std::vector<base::Tuple<int, int, std::string>>& clients_info =
- GetWindowClientsInternal(options.include_uncontrolled);
-
- if (clients_info.empty()) {
- DidGetWindowClients(request_id, options,
- make_scoped_ptr(new ServiceWorkerClients));
- return;
- }
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&OnGetWindowClientsFromUI, clients_info, script_url_,
- base::Bind(&ServiceWorkerVersion::DidGetWindowClients,
- weak_factory_.GetWeakPtr(), request_id, options)));
-}
-
-const std::vector<base::Tuple<int, int, std::string>>
-ServiceWorkerVersion::GetWindowClientsInternal(bool include_uncontrolled) {
- std::vector<base::Tuple<int, int, std::string>> clients_info;
- if (!include_uncontrolled) {
- for (auto& controllee : controllee_map_)
- AddWindowClient(controllee.second, &clients_info);
- } else {
- for (auto it =
- context_->GetClientProviderHostIterator(script_url_.GetOrigin());
- !it->IsAtEnd(); it->Advance()) {
- AddWindowClient(it->GetProviderHost(), &clients_info);
- }
- }
- return clients_info;
-}
-
-void ServiceWorkerVersion::DidGetWindowClients(
- int request_id,
- const ServiceWorkerClientQueryOptions& options,
- scoped_ptr<ServiceWorkerClients> clients) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (options.client_type == blink::WebServiceWorkerClientTypeAll)
- GetNonWindowClients(request_id, options, clients.get());
- OnGetClientsFinished(request_id, clients.get());
-}
-
-void ServiceWorkerVersion::GetNonWindowClients(
- int request_id,
- const ServiceWorkerClientQueryOptions& options,
- ServiceWorkerClients* clients) {
- if (!options.include_uncontrolled) {
- for (auto& controllee : controllee_map_) {
- AddNonWindowClient(controllee.second, options, clients);
- }
- } else {
- for (auto it =
- context_->GetClientProviderHostIterator(script_url_.GetOrigin());
- !it->IsAtEnd(); it->Advance()) {
- AddNonWindowClient(it->GetProviderHost(), options, clients);
- }
- }
-}
-
void ServiceWorkerVersion::StartTimeoutTimer() {
DCHECK(!timeout_timer_.IsRunning());
@@ -2009,9 +1584,16 @@ void ServiceWorkerVersion::StartTimeoutTimer() {
// Ping will be activated in OnScriptLoaded.
ping_controller_->Deactivate();
+ // Make the timer delay shorter for starting an existing
+ // worker so stalled in starting workers can be timed out quickly.
+ // The timer will be reset to normal in OnStarted or the next start
+ // attempt.
+ const int delay_in_seconds = IsInstalled(status_)
+ ? kStartInstalledWorkerTimeoutSeconds
+ : kTimeoutTimerDelaySeconds;
timeout_timer_.Start(FROM_HERE,
- base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds),
- this, &ServiceWorkerVersion::OnTimeoutTimer);
+ base::TimeDelta::FromSeconds(delay_in_seconds), this,
+ &ServiceWorkerVersion::OnTimeoutTimer);
}
void ServiceWorkerVersion::StopTimeoutTimer() {
@@ -2026,11 +1608,23 @@ void ServiceWorkerVersion::StopTimeoutTimer() {
}
}
+void ServiceWorkerVersion::SetTimeoutTimerInterval(base::TimeDelta interval) {
+ DCHECK(timeout_timer_.IsRunning());
+ if (timeout_timer_.GetCurrentDelay() != interval) {
+ timeout_timer_.Stop();
+ timeout_timer_.Start(FROM_HERE, interval, this,
+ &ServiceWorkerVersion::OnTimeoutTimer);
+ }
+}
+
void ServiceWorkerVersion::OnTimeoutTimer() {
DCHECK(running_status() == STARTING || running_status() == RUNNING ||
running_status() == STOPPING)
<< running_status();
+ if (!context_)
+ return;
+
MarkIfStale();
// Stopping the worker hasn't finished within a certain period.
@@ -2066,8 +1660,11 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
}
// Starting a worker hasn't finished within a certain period.
- if (GetTickDuration(start_time_) >
- base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) {
+ const base::TimeDelta start_limit =
+ IsInstalled(status())
+ ? base::TimeDelta::FromSeconds(kStartInstalledWorkerTimeoutSeconds)
+ : base::TimeDelta::FromMinutes(kStartNewWorkerTimeoutMinutes);
+ if (GetTickDuration(start_time_) > start_limit) {
DCHECK(running_status() == STARTING || running_status() == STOPPING)
<< running_status();
scoped_refptr<ServiceWorkerVersion> protect(this);
@@ -2077,21 +1674,20 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
return;
}
- // Requests have not finished within a certain period.
- bool request_timed_out = false;
+ // Requests have not finished before their expiration.
+ bool stop_for_timeout = false;
while (!requests_.empty()) {
- RequestInfo info = requests_.front();
- if (GetTickDuration(info.time) <
- base::TimeDelta::FromMinutes(kRequestTimeoutMinutes))
+ RequestInfo info = requests_.top();
+ if (!RequestExpired(info.expiration))
break;
if (MaybeTimeOutRequest(info)) {
- request_timed_out = true;
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.RequestTimeouts.Count",
- info.type, NUM_REQUEST_TYPES);
+ stop_for_timeout =
+ stop_for_timeout || info.timeout_behavior == KILL_ON_TIMEOUT;
+ ServiceWorkerMetrics::RecordEventTimeout(info.event_type);
}
requests_.pop();
}
- if (request_timed_out && running_status() != STOPPING)
+ if (stop_for_timeout && running_status() != STOPPING)
embedded_worker_->Stop();
// For the timeouts below, there are no callbacks to timeout so there is
@@ -2136,11 +1732,9 @@ void ServiceWorkerVersion::StopWorkerIfIdle() {
bool ServiceWorkerVersion::HasInflightRequests() const {
return !activate_requests_.IsEmpty() || !install_requests_.IsEmpty() ||
- !fetch_requests_.IsEmpty() || !sync_requests_.IsEmpty() ||
+ !fetch_requests_.IsEmpty() ||
!notification_click_requests_.IsEmpty() || !push_requests_.IsEmpty() ||
- !geofencing_requests_.IsEmpty() ||
- !service_port_connect_requests_.IsEmpty() ||
- !streaming_url_request_jobs_.empty();
+ !custom_requests_.IsEmpty() || !streaming_url_request_jobs_.empty();
}
void ServiceWorkerVersion::RecordStartWorkerResult(
@@ -2197,11 +1791,27 @@ template <typename CallbackType>
int ServiceWorkerVersion::AddRequest(
const CallbackType& callback,
IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map,
- RequestType request_type) {
- base::TimeTicks now = base::TimeTicks::Now();
- int request_id =
- callback_map->Add(new PendingRequest<CallbackType>(callback, now));
- requests_.push(RequestInfo(request_id, request_type, now));
+ RequestType request_type,
+ ServiceWorkerMetrics::EventType event_type) {
+ base::TimeTicks expiration_time =
+ base::TimeTicks::Now() +
+ base::TimeDelta::FromMinutes(kRequestTimeoutMinutes);
+ return AddRequestWithExpiration(callback, callback_map, request_type,
+ event_type, expiration_time, KILL_ON_TIMEOUT);
+}
+
+template <typename CallbackType>
+int ServiceWorkerVersion::AddRequestWithExpiration(
+ const CallbackType& callback,
+ IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map,
+ RequestType request_type,
+ ServiceWorkerMetrics::EventType event_type,
+ base::TimeTicks expiration,
+ TimeoutBehavior timeout_behavior) {
+ int request_id = callback_map->Add(new PendingRequest<CallbackType>(
+ callback, base::TimeTicks::Now(), event_type));
+ requests_.push(RequestInfo(request_id, request_type, event_type, expiration,
+ timeout_behavior));
return request_id;
}
@@ -2218,23 +1828,15 @@ bool ServiceWorkerVersion::MaybeTimeOutRequest(const RequestInfo& info) {
&fetch_requests_, info.id, SERVICE_WORKER_ERROR_TIMEOUT,
/* The other args are ignored for non-OK status. */
SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, ServiceWorkerResponse());
- case REQUEST_SYNC:
- return RunIDMapCallback(&sync_requests_, info.id,
- SERVICE_WORKER_ERROR_TIMEOUT);
case REQUEST_NOTIFICATION_CLICK:
return RunIDMapCallback(&notification_click_requests_, info.id,
SERVICE_WORKER_ERROR_TIMEOUT);
case REQUEST_PUSH:
return RunIDMapCallback(&push_requests_, info.id,
SERVICE_WORKER_ERROR_TIMEOUT);
- case REQUEST_GEOFENCING:
- return RunIDMapCallback(&geofencing_requests_, info.id,
+ case REQUEST_CUSTOM:
+ return RunIDMapCallback(&custom_requests_, info.id,
SERVICE_WORKER_ERROR_TIMEOUT);
- case REQUEST_SERVICE_PORT_CONNECT:
- return RunIDMapCallback(&service_port_connect_requests_, info.id,
- SERVICE_WORKER_ERROR_TIMEOUT,
- false /* accept_connection */, base::string16(),
- base::string16());
case NUM_REQUEST_TYPES:
break;
}
@@ -2242,11 +1844,12 @@ bool ServiceWorkerVersion::MaybeTimeOutRequest(const RequestInfo& info) {
return false;
}
-void ServiceWorkerVersion::SetAllRequestTimes(const base::TimeTicks& ticks) {
- std::queue<RequestInfo> new_requests;
+void ServiceWorkerVersion::SetAllRequestExpirations(
+ const base::TimeTicks& expiration) {
+ RequestInfoPriorityQueue new_requests;
while (!requests_.empty()) {
- RequestInfo info = requests_.front();
- info.time = ticks;
+ RequestInfo info = requests_.top();
+ info.expiration = expiration;
new_requests.push(info);
requests_.pop();
}
@@ -2349,16 +1952,13 @@ void ServiceWorkerVersion::OnStoppedInternal(
RunIDMapCallbacks(&fetch_requests_, SERVICE_WORKER_ERROR_FAILED,
SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
ServiceWorkerResponse());
- RunIDMapCallbacks(&sync_requests_, SERVICE_WORKER_ERROR_FAILED);
RunIDMapCallbacks(&notification_click_requests_, SERVICE_WORKER_ERROR_FAILED);
RunIDMapCallbacks(&push_requests_, SERVICE_WORKER_ERROR_FAILED);
- RunIDMapCallbacks(&geofencing_requests_, SERVICE_WORKER_ERROR_FAILED);
+ RunIDMapCallbacks(&custom_requests_, SERVICE_WORKER_ERROR_FAILED);
// Close all mojo services. This will also fire and clear all callbacks
// for messages that are still outstanding for those services.
- OnServicePortDispatcherConnectionError();
-
- OnBackgroundSyncDispatcherConnectionError();
+ mojo_services_.clear();
// TODO(falken): Call SWURLRequestJob::ClearStream here?
streaming_url_request_jobs_.clear();
@@ -2369,16 +1969,10 @@ void ServiceWorkerVersion::OnStoppedInternal(
StartWorkerInternal();
}
-void ServiceWorkerVersion::OnServicePortDispatcherConnectionError() {
- RunIDMapCallbacks(&service_port_connect_requests_,
- SERVICE_WORKER_ERROR_FAILED, false, base::string16(),
- base::string16());
- service_port_dispatcher_.reset();
-}
-
-void ServiceWorkerVersion::OnBackgroundSyncDispatcherConnectionError() {
- RunIDMapCallbacks(&sync_requests_, SERVICE_WORKER_ERROR_FAILED);
- background_sync_dispatcher_.reset();
+void ServiceWorkerVersion::OnMojoConnectionError(const char* service_name) {
+ // Simply deleting the service will cause error callbacks to be called from
+ // the destructor of the MojoServiceWrapper instance.
+ mojo_services_.erase(service_name);
}
void ServiceWorkerVersion::OnBeginEvent() {
diff --git a/chromium/content/browser/service_worker/service_worker_version.h b/chromium/content/browser/service_worker/service_worker_version.h
index 545b9c659ea..96c54453043 100644
--- a/chromium/content/browser/service_worker/service_worker_version.h
+++ b/chromium/content/browser/service_worker/service_worker_version.h
@@ -5,30 +5,32 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
+#include <stdint.h>
+
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/containers/scoped_ptr_hash_map.h"
#include "base/gtest_prod_util.h"
#include "base/id_map.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
+#include "base/thread_task_runner_handle.h"
#include "base/timer/timer.h"
-#include "content/browser/background_sync/background_sync_registration_handle.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
+#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_script_cache_map.h"
-#include "content/common/background_sync_service.mojom.h"
#include "content/common/content_export.h"
-#include "content/common/service_port_service.mojom.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/service_registry.h"
-#include "third_party/WebKit/public/platform/WebGeofencingEventType.h"
+#include "ipc/ipc_message.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerEventResult.h"
// Windows headers will redefine SendMessage.
@@ -38,10 +40,6 @@
class GURL;
-namespace blink {
-struct WebCircularGeofencingRegion;
-}
-
namespace net {
class HttpResponseInfo;
}
@@ -72,11 +70,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
typedef base::Callback<void(ServiceWorkerStatusCode,
ServiceWorkerFetchEventResult,
const ServiceWorkerResponse&)> FetchCallback;
- typedef base::Callback<void(ServiceWorkerStatusCode,
- bool /* accept_connction */,
- const base::string16& /* name */,
- const base::string16& /* data */)>
- ServicePortConnectCallback;
enum RunningStatus {
STOPPED = EmbeddedWorkerInstance::STOPPED,
@@ -97,6 +90,13 @@ class CONTENT_EXPORT ServiceWorkerVersion
// unregistration or replace.
};
+ // Behavior when a request times out.
+ enum TimeoutBehavior {
+ KILL_ON_TIMEOUT, // Kill the worker if this request times out.
+ CONTINUE_ON_TIMEOUT // Keep the worker alive, only abandon the request that
+ // timed out.
+ };
+
class Listener {
public:
virtual void OnRunningStateChanged(ServiceWorkerVersion* version) {}
@@ -127,14 +127,13 @@ class CONTENT_EXPORT ServiceWorkerVersion
virtual ~Listener() {}
};
- ServiceWorkerVersion(
- ServiceWorkerRegistration* registration,
- const GURL& script_url,
- int64 version_id,
- base::WeakPtr<ServiceWorkerContextCore> context);
+ ServiceWorkerVersion(ServiceWorkerRegistration* registration,
+ const GURL& script_url,
+ int64_t version_id,
+ base::WeakPtr<ServiceWorkerContextCore> context);
- int64 version_id() const { return version_id_; }
- int64 registration_id() const { return registration_id_; }
+ int64_t version_id() const { return version_id_; }
+ int64_t registration_id() const { return registration_id_; }
const GURL& script_url() const { return script_url_; }
const GURL& scope() const { return scope_; }
RunningStatus running_status() const {
@@ -143,6 +142,13 @@ class CONTENT_EXPORT ServiceWorkerVersion
ServiceWorkerVersionInfo GetInfo();
Status status() const { return status_; }
+ const std::vector<GURL>& foreign_fetch_scopes() const {
+ return foreign_fetch_scopes_;
+ }
+ void set_foreign_fetch_scopes(const std::vector<GURL>& scopes) {
+ foreign_fetch_scopes_ = scopes;
+ }
+
// This sets the new status and also run status change callbacks
// if there're any (see RegisterStatusChangeCallback).
void SetStatus(Status status);
@@ -170,6 +176,54 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Starts an update now.
void StartUpdate();
+ // Starts the worker if it isn't already running, and calls |task| when the
+ // worker is running, or |error_callback| if starting the worker failed.
+ void RunAfterStartWorker(const StatusCallback& error_callback,
+ const base::Closure& task);
+
+ // Call this while the worker is running before dispatching an event to the
+ // worker. This informs ServiceWorkerVersion about the event in progress.
+ // Returns a request id, which should later be passed to FinishRequest when
+ // the event finished.
+ // The |error_callback| is called if either ServiceWorkerVersion decides the
+ // event is taking too long, or if for some reason the worker stops or is
+ // killed before the request finishes.
+ int StartRequest(ServiceWorkerMetrics::EventType event_type,
+ const StatusCallback& error_callback);
+
+ // Same as StartRequest, but allows the caller to specify a custom timeout for
+ // the event, as well as the behavior for when the request times out.
+ int StartRequestWithCustomTimeout(ServiceWorkerMetrics::EventType event_type,
+ const StatusCallback& error_callback,
+ const base::TimeDelta& timeout,
+ TimeoutBehavior timeout_behavior);
+
+ // Informs ServiceWorkerVersion that an event has finished being dispatched.
+ // Returns false if no pending requests with the provided id exist, for
+ // example if the request has already timed out.
+ bool FinishRequest(int request_id);
+
+ // Connects to a specific mojo service exposed by the (running) service
+ // worker. If a connection to a service for the same Interface already exists
+ // this will return that existing connection. The |request_id| must be a value
+ // previously returned by StartRequest. If the connection to the service
+ // fails or closes before the request finished, the error callback associated
+ // with |request_id| is called.
+ // Only call GetMojoServiceForRequest once for a specific |request_id|.
+ template <typename Interface>
+ base::WeakPtr<Interface> GetMojoServiceForRequest(int request_id);
+
+ // Dispatches an event. If dispatching the event fails, the error callback
+ // associated with the |request_id| is called. Any messages sent back in
+ // response to this event are passed on to the response |callback|.
+ // ResponseMessage is the type of the IPC message that is used for the
+ // response, and its first argument MUST be the request_id.
+ // This must be called when the worker is running.
+ template <typename ResponseMessage, typename ResponseCallbackType>
+ void DispatchEvent(int request_id,
+ const IPC::Message& message,
+ const ResponseCallbackType& callback);
+
// Sends a message event to the associated embedded worker.
void DispatchMessageEvent(
const base::string16& message,
@@ -205,14 +259,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
const base::Closure& prepare_callback,
const FetchCallback& fetch_callback);
- // Sends sync event to the associated embedded worker and asynchronously calls
- // |callback| when it errors out or it gets a response from the worker to
- // notify completion.
- //
- // This must be called when the status() is ACTIVATED.
- void DispatchSyncEvent(BackgroundSyncRegistrationHandle::HandleId handle_id,
- const StatusCallback& callback);
-
// Sends notificationclick event to the associated embedded worker and
// asynchronously calls |callback| when it errors out or it gets a response
// from the worker to notify completion.
@@ -232,27 +278,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
void DispatchPushEvent(const StatusCallback& callback,
const std::string& data);
- // Sends geofencing event to the associated embedded worker and asynchronously
- // calls |callback| when it errors out or it gets a response from the worker
- // to notify completion.
- //
- // This must be called when the status() is ACTIVATED.
- void DispatchGeofencingEvent(
- const StatusCallback& callback,
- blink::WebGeofencingEventType event_type,
- const std::string& region_id,
- const blink::WebCircularGeofencingRegion& region);
-
- // Sends a ServicePort connect event to the associated embedded worker and
- // asynchronously calls |callback| with the response from the worker.
- //
- // This must be called when the status() is ACTIVATED.
- void DispatchServicePortConnectEvent(
- const ServicePortConnectCallback& callback,
- const GURL& target_url,
- const GURL& origin,
- int port_id);
-
// Sends a cross origin message event to the associated embedded worker and
// asynchronously calls |callback| when the message was sent (or failed to
// sent).
@@ -275,10 +300,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Returns if it has controllee.
bool HasControllee() const { return !controllee_map_.empty(); }
+ std::map<std::string, ServiceWorkerProviderHost*> controllee_map() {
+ return controllee_map_;
+ }
- // Returns whether the service worker has active window clients under its
- // control.
- bool HasWindowClients();
+ base::WeakPtr<ServiceWorkerContextCore> context() const { return context_; }
// Adds and removes |request_job| as a dependent job not to stop the
// ServiceWorker while |request_job| is reading the stream of the fetch event
@@ -336,9 +362,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
private:
friend class base::RefCounted<ServiceWorkerVersion>;
friend class ServiceWorkerMetrics;
- friend class ServiceWorkerURLRequestJobTest;
+ friend class ServiceWorkerReadFromCacheJobTest;
friend class ServiceWorkerStallInStoppingTest;
+ friend class ServiceWorkerURLRequestJobTest;
friend class ServiceWorkerVersionBrowserTest;
+ friend class ServiceWorkerVersionTest;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerControlleeRequestHandlerTest,
ActivateWaitingVersion);
@@ -352,55 +380,141 @@ class CONTENT_EXPORT ServiceWorkerVersion
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest,
StaleUpdate_DoNotDeferTimer);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWaitForeverInFetchTest, RequestTimeout);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestTimeout);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerFailToStartTest, Timeout);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionBrowserTest,
TimeoutStartingWorker);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionBrowserTest,
TimeoutWorkerInEvent);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, StayAliveAfterPush);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStallInStoppingTest, DetachThenStart);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStallInStoppingTest, DetachThenRestart);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest,
+ RegisterForeignFetchScopes);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestCustomizedTimeout);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest,
+ RequestCustomizedTimeoutKill);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWaitForeverInFetchTest,
+ MixedRequestTimeouts);
class Metrics;
class PingController;
- typedef ServiceWorkerVersion self;
- using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>;
-
- // Used for UMA; add new entries to the end, before NUM_REQUEST_TYPES.
enum RequestType {
REQUEST_ACTIVATE,
REQUEST_INSTALL,
REQUEST_FETCH,
- REQUEST_SYNC,
REQUEST_NOTIFICATION_CLICK,
REQUEST_PUSH,
- REQUEST_GEOFENCING,
- REQUEST_SERVICE_PORT_CONNECT,
+ REQUEST_CUSTOM,
NUM_REQUEST_TYPES
};
struct RequestInfo {
- RequestInfo(int id, RequestType type, const base::TimeTicks& time);
+ RequestInfo(int id,
+ RequestType type,
+ ServiceWorkerMetrics::EventType event_type,
+ const base::TimeTicks& expiration,
+ TimeoutBehavior timeout_behavior);
~RequestInfo();
+ bool operator>(const RequestInfo& other) const;
int id;
RequestType type;
- base::TimeTicks time;
+ ServiceWorkerMetrics::EventType event_type;
+ base::TimeTicks expiration;
+ TimeoutBehavior timeout_behavior;
};
template <typename CallbackType>
struct PendingRequest {
- PendingRequest(const CallbackType& callback, const base::TimeTicks& time);
- ~PendingRequest();
+ PendingRequest(const CallbackType& callback,
+ const base::TimeTicks& time,
+ ServiceWorkerMetrics::EventType event_type);
+ ~PendingRequest() {}
CallbackType callback;
base::TimeTicks start_time;
+ ServiceWorkerMetrics::EventType event_type;
+ // Name of the mojo service this request is associated with. Used to call
+ // the callback when a connection closes with outstanding requests.
+ // Compared as pointer, so should only contain static strings. Typically
+ // this would be Interface::Name_ for some mojo interface.
+ const char* mojo_service = nullptr;
+ scoped_ptr<EmbeddedWorkerInstance::Listener> listener;
+ };
+
+ // Base class to enable storing a list of mojo interface pointers for
+ // arbitrary interfaces. The destructor is also responsible for calling the
+ // error callbacks for any outstanding requests using this service.
+ class CONTENT_EXPORT BaseMojoServiceWrapper {
+ public:
+ BaseMojoServiceWrapper(ServiceWorkerVersion* worker,
+ const char* service_name);
+ virtual ~BaseMojoServiceWrapper();
+
+ private:
+ ServiceWorkerVersion* worker_;
+ const char* service_name_;
+
+ DISALLOW_COPY_AND_ASSIGN(BaseMojoServiceWrapper);
+ };
+
+ // Wrapper around a mojo::InterfacePtr, which passes out WeakPtr's to the
+ // interface.
+ template <typename Interface>
+ class MojoServiceWrapper : public BaseMojoServiceWrapper {
+ public:
+ MojoServiceWrapper(ServiceWorkerVersion* worker,
+ mojo::InterfacePtr<Interface> interface)
+ : BaseMojoServiceWrapper(worker, Interface::Name_),
+ interface_(std::move(interface)),
+ weak_ptr_factory_(interface_.get()) {}
+
+ base::WeakPtr<Interface> GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+ }
+
+ private:
+ mojo::InterfacePtr<Interface> interface_;
+ base::WeakPtrFactory<Interface> weak_ptr_factory_;
+ };
+
+ typedef ServiceWorkerVersion self;
+ using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>;
+ using RequestInfoPriorityQueue =
+ std::priority_queue<RequestInfo,
+ std::vector<RequestInfo>,
+ std::greater<RequestInfo>>;
+
+ // EmbeddedWorkerInstance Listener implementation which calls a callback
+ // on receiving a particular IPC message. ResponseMessage is the type of
+ // the IPC message to listen for, while CallbackType should be a callback
+ // with same arguments as the IPC message.
+ // Additionally only calls the callback for messages with a specific request
+ // id, which must be the first argument of the IPC message.
+ template <typename ResponseMessage, typename CallbackType>
+ class EventResponseHandler : public EmbeddedWorkerInstance::Listener {
+ public:
+ EventResponseHandler(EmbeddedWorkerInstance* worker,
+ int request_id,
+ const CallbackType& callback)
+ : worker_(worker), request_id_(request_id), callback_(callback) {
+ worker_->AddListener(this);
+ }
+ ~EventResponseHandler() override { worker_->RemoveListener(this); }
+ bool OnMessageReceived(const IPC::Message& message) override;
+
+ private:
+ EmbeddedWorkerInstance* const worker_;
+ const int request_id_;
+ const CallbackType callback_;
};
// The timeout timer interval.
static const int kTimeoutTimerDelaySeconds;
- // Timeout for the worker to start.
- static const int kStartWorkerTimeoutMinutes;
+ // Timeout for an installed worker to start.
+ static const int kStartInstalledWorkerTimeoutSeconds;
+ // Timeout for a new worker to start.
+ static const int kStartNewWorkerTimeoutMinutes;
// Timeout for a request to be handled.
static const int kRequestTimeoutMinutes;
// Timeout for the worker to stop.
@@ -451,27 +565,19 @@ class CONTENT_EXPORT ServiceWorkerVersion
void OnFetchEventFinished(int request_id,
ServiceWorkerFetchEventResult result,
const ServiceWorkerResponse& response);
- void OnSyncEventFinished(int request_id, ServiceWorkerEventStatus status);
void OnNotificationClickEventFinished(int request_id);
void OnPushEventFinished(int request_id,
blink::WebServiceWorkerEventResult result);
- void OnGeofencingEventFinished(int request_id);
- void OnServicePortConnectEventFinished(int request_id,
- ServicePortConnectResult result,
- const mojo::String& name,
- const mojo::String& data);
void OnOpenWindow(int request_id, GURL url);
- void DidOpenWindow(int request_id,
- int render_process_id,
- int render_frame_id);
void OnOpenWindowFinished(int request_id,
+ ServiceWorkerStatusCode status,
const std::string& client_uuid,
const ServiceWorkerClientInfo& client_info);
void OnSetCachedMetadata(const GURL& url, const std::vector<char>& data);
- void OnSetCachedMetadataFinished(int64 callback_id, int result);
+ void OnSetCachedMetadataFinished(int64_t callback_id, int result);
void OnClearCachedMetadata(const GURL& url);
- void OnClearCachedMetadataFinished(int64 callback_id, int result);
+ void OnClearCachedMetadataFinished(int64_t callback_id, int result);
void OnPostMessageToClient(
const std::string& client_uuid,
@@ -481,10 +587,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
void OnNavigateClient(int request_id,
const std::string& client_uuid,
const GURL& url);
- void DidNavigateClient(int request_id,
- int render_process_id,
- int render_frame_id);
void OnNavigateClientFinished(int request_id,
+ ServiceWorkerStatusCode status,
const std::string& client_uuid,
const ServiceWorkerClientInfo& client);
void OnSkipWaiting(int request_id);
@@ -495,6 +599,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
const std::string& client_uuid,
const ServiceWorkerClientInfo& client);
+ void OnRegisterForeignFetchScopes(const std::vector<GURL>& sub_scopes);
+
void DidEnsureLiveRegistrationForStartWorker(
const StatusCallback& callback,
ServiceWorkerStatusCode status,
@@ -503,16 +609,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
void DidSkipWaiting(int request_id);
- void GetWindowClients(int request_id,
- const ServiceWorkerClientQueryOptions& options);
- const std::vector<base::Tuple<int, int, std::string>>
- GetWindowClientsInternal(bool include_uncontolled);
- void DidGetWindowClients(int request_id,
- const ServiceWorkerClientQueryOptions& options,
- scoped_ptr<ServiceWorkerClients> clients);
- void GetNonWindowClients(int request_id,
- const ServiceWorkerClientQueryOptions& options,
- ServiceWorkerClients* clients);
void OnGetClientsFinished(int request_id, ServiceWorkerClients* clients);
// The timeout timer periodically calls OnTimeoutTimer, which stops the worker
@@ -520,6 +616,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
void StartTimeoutTimer();
void StopTimeoutTimer();
void OnTimeoutTimer();
+ void SetTimeoutTimerInterval(base::TimeDelta interval);
// Called by PingController for ping protocol.
ServiceWorkerStatusCode PingWorker();
@@ -541,10 +638,20 @@ class CONTENT_EXPORT ServiceWorkerVersion
int AddRequest(
const CallbackType& callback,
IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map,
- RequestType request_type);
+ RequestType request_type,
+ ServiceWorkerMetrics::EventType event_type);
+
+ template <typename CallbackType>
+ int AddRequestWithExpiration(
+ const CallbackType& callback,
+ IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map,
+ RequestType request_type,
+ ServiceWorkerMetrics::EventType event_type,
+ base::TimeTicks expiration,
+ TimeoutBehavior timeout_behavior);
bool MaybeTimeOutRequest(const RequestInfo& info);
- void SetAllRequestTimes(const base::TimeTicks& ticks);
+ void SetAllRequestExpirations(const base::TimeTicks& expiration);
// Returns the reason the embedded worker failed to start, using information
// inaccessible to EmbeddedWorkerInstance. Returns |default_code| if it can't
@@ -562,21 +669,19 @@ class CONTENT_EXPORT ServiceWorkerVersion
void OnStoppedInternal(EmbeddedWorkerInstance::Status old_status);
- // Called when a connection to a mojo event Dispatcher drops or fails.
- // Calls callbacks for any outstanding requests to the dispatcher as well
- // as cleans up the dispatcher.
- void OnServicePortDispatcherConnectionError();
- void OnBackgroundSyncDispatcherConnectionError();
+ // Called when the remote side of a connection to a mojo service is lost.
+ void OnMojoConnectionError(const char* service_name);
// Called at the beginning of each Dispatch*Event function: records
// the time elapsed since idle (generally the time since the previous
// event ended).
void OnBeginEvent();
- const int64 version_id_;
- const int64 registration_id_;
+ const int64_t version_id_;
+ const int64_t registration_id_;
const GURL script_url_;
const GURL scope_;
+ std::vector<GURL> foreign_fetch_scopes_;
Status status_ = NEW;
scoped_ptr<EmbeddedWorkerInstance> embedded_worker_;
@@ -589,16 +694,18 @@ class CONTENT_EXPORT ServiceWorkerVersion
IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> activate_requests_;
IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> install_requests_;
IDMap<PendingRequest<FetchCallback>, IDMapOwnPointer> fetch_requests_;
- IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> sync_requests_;
IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer>
notification_click_requests_;
IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> push_requests_;
- IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> geofencing_requests_;
- IDMap<PendingRequest<ServicePortConnectCallback>, IDMapOwnPointer>
- service_port_connect_requests_;
+ IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> custom_requests_;
- ServicePortDispatcherPtr service_port_dispatcher_;
- BackgroundSyncServiceClientPtr background_sync_dispatcher_;
+ // Stores all open connections to mojo services. Maps the service name to
+ // the actual interface pointer. When a connection is closed it is removed
+ // from this map.
+ // mojo_services_[Interface::Name_] is assumed to always contain a
+ // MojoServiceWrapper<Interface> instance.
+ base::ScopedPtrHashMap<const char*, scoped_ptr<BaseMojoServiceWrapper>>
+ mojo_services_;
std::set<const ServiceWorkerURLRequestJob*> streaming_url_request_jobs_;
@@ -623,10 +730,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
base::TimeTicks stale_time_;
// New requests are added to |requests_| along with their entry in a callback
- // map. The timeout timer periodically checks |requests_| for entries that
- // should time out or have already been fulfilled (i.e., removed from the
- // callback map).
- std::queue<RequestInfo> requests_;
+ // map. Requests are sorted by their expiration time (soonest to expire on top
+ // of the priority queue). The timeout timer periodically checks |requests_|
+ // for entries that should time out or have already been fulfilled (i.e.,
+ // removed from the callback map).
+ RequestInfoPriorityQueue requests_;
bool skip_waiting_ = false;
bool skip_recording_startup_time_ = false;
@@ -653,6 +761,72 @@ class CONTENT_EXPORT ServiceWorkerVersion
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersion);
};
+template <typename Interface>
+base::WeakPtr<Interface> ServiceWorkerVersion::GetMojoServiceForRequest(
+ int request_id) {
+ DCHECK_EQ(RUNNING, running_status());
+ PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id);
+ DCHECK(request) << "Invalid request id";
+ DCHECK(!request->mojo_service)
+ << "Request is already associated with a mojo service";
+
+ MojoServiceWrapper<Interface>* service =
+ static_cast<MojoServiceWrapper<Interface>*>(
+ mojo_services_.get(Interface::Name_));
+ if (!service) {
+ mojo::InterfacePtr<Interface> interface;
+ embedded_worker_->GetServiceRegistry()->ConnectToRemoteService(
+ mojo::GetProxy(&interface));
+ interface.set_connection_error_handler(
+ base::Bind(&ServiceWorkerVersion::OnMojoConnectionError,
+ weak_factory_.GetWeakPtr(), Interface::Name_));
+ service = new MojoServiceWrapper<Interface>(this, std::move(interface));
+ mojo_services_.add(Interface::Name_, make_scoped_ptr(service));
+ }
+ request->mojo_service = Interface::Name_;
+ return service->GetWeakPtr();
+}
+
+template <typename ResponseMessage, typename ResponseCallbackType>
+void ServiceWorkerVersion::DispatchEvent(int request_id,
+ const IPC::Message& message,
+ const ResponseCallbackType& callback) {
+ DCHECK_EQ(RUNNING, running_status());
+ PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id);
+ DCHECK(request) << "Invalid request id";
+ DCHECK(!request->listener) << "Request already dispatched an IPC event";
+
+ ServiceWorkerStatusCode status = embedded_worker_->SendMessage(message);
+ if (status != SERVICE_WORKER_OK) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(request->callback, status));
+ custom_requests_.Remove(request_id);
+ } else {
+ request->listener.reset(
+ new EventResponseHandler<ResponseMessage, ResponseCallbackType>(
+ embedded_worker(), request_id, callback));
+ }
+}
+
+template <typename ResponseMessage, typename CallbackType>
+bool ServiceWorkerVersion::EventResponseHandler<ResponseMessage, CallbackType>::
+ OnMessageReceived(const IPC::Message& message) {
+ if (message.type() != ResponseMessage::ID)
+ return false;
+ int received_request_id;
+ bool result = base::PickleIterator(message).ReadInt(&received_request_id);
+ if (!result || received_request_id != request_id_)
+ return false;
+
+ // Essentially same code as what IPC_MESSAGE_FORWARD expands to.
+ void* param = nullptr;
+ if (!ResponseMessage::Dispatch(&message, &callback_, this, param,
+ &CallbackType::Run))
+ message.set_dispatch_error();
+
+ return true;
+}
+
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
diff --git a/chromium/content/browser/service_worker/service_worker_version_unittest.cc b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
index 43ada89b6bb..f3d1aeb8f70 100644
--- a/chromium/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
@@ -2,7 +2,9 @@
// 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 <stdint.h>
+
+#include "base/macros.h"
#include "base/run_loop.h"
#include "content/browser/message_port_service.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
@@ -12,7 +14,11 @@
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_mojo_service.mojom.h"
+#include "content/public/test/test_utils.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "testing/gtest/include/gtest/gtest.h"
// IPC messages for testing ---------------------------------------------------
@@ -22,8 +28,11 @@
#define IPC_MESSAGE_START TestMsgStart
-IPC_MESSAGE_CONTROL0(TestMsg_Message);
-IPC_MESSAGE_ROUTED1(TestMsg_MessageFromWorker, int);
+IPC_MESSAGE_CONTROL0(TestMsg_Message)
+IPC_MESSAGE_ROUTED1(TestMsg_MessageFromWorker, int)
+
+IPC_MESSAGE_CONTROL1(TestMsg_TestEvent, int)
+IPC_MESSAGE_ROUTED2(TestMsg_TestEventResult, int, std::string)
// ---------------------------------------------------------------------------
@@ -31,12 +40,10 @@ namespace content {
namespace {
-static const int kRenderProcessId = 1;
-
class MessageReceiver : public EmbeddedWorkerTestHelper {
public:
MessageReceiver()
- : EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId),
+ : EmbeddedWorkerTestHelper(base::FilePath()),
current_embedded_worker_id_(0) {}
~MessageReceiver() override {}
@@ -60,6 +67,13 @@ class MessageReceiver : public EmbeddedWorkerTestHelper {
SimulateSend(new TestMsg_MessageFromWorker(embedded_worker_id, value));
}
+ void SimulateSendEventResult(int embedded_worker_id,
+ int request_id,
+ const std::string& reply) {
+ SimulateSend(
+ new TestMsg_TestEventResult(embedded_worker_id, request_id, reply));
+ }
+
private:
void OnMessage() {
// Do nothing.
@@ -87,6 +101,16 @@ void ReceiveFetchResult(ServiceWorkerStatusCode* status,
*status = actual_status;
}
+void ReceiveTestEventResult(int* request_id,
+ std::string* data,
+ const base::Closure& callback,
+ int actual_request_id,
+ const std::string& actual_data) {
+ *request_id = actual_request_id;
+ *data = actual_data;
+ callback.Run();
+}
+
// A specialized listener class to receive test messages from a worker.
class MessageReceiverFromWorker : public EmbeddedWorkerInstance::Listener {
public:
@@ -132,6 +156,27 @@ base::Time GetYesterday() {
base::TimeDelta::FromSeconds(1);
}
+class TestMojoServiceImpl : public TestMojoService {
+ public:
+ static void Create(mojo::InterfaceRequest<TestMojoService> request) {
+ new TestMojoServiceImpl(std::move(request));
+ }
+
+ void DoSomething(const DoSomethingCallback& callback) override {
+ callback.Run();
+ }
+
+ void GetRequestorURL(const GetRequestorURLCallback& callback) override {
+ callback.Run(mojo::String(""));
+ }
+
+ private:
+ explicit TestMojoServiceImpl(mojo::InterfaceRequest<TestMojoService> request)
+ : binding_(this, std::move(request)) {}
+
+ mojo::StrongBinding<TestMojoService> binding_;
+};
+
} // namespace
class ServiceWorkerVersionTest : public testing::Test {
@@ -151,15 +196,18 @@ class ServiceWorkerVersionTest : public testing::Test {
void SetUp() override {
helper_ = GetMessageReceiver();
- pattern_ = GURL("http://www.example.com/");
+ helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
+ base::RunLoop().RunUntilIdle();
+
+ pattern_ = GURL("http://www.example.com/test/");
registration_ = new ServiceWorkerRegistration(
pattern_,
1L,
helper_->context()->AsWeakPtr());
version_ = new ServiceWorkerVersion(
registration_.get(),
- GURL("http://www.example.com/service_worker.js"),
- 1L,
+ GURL("http://www.example.com/test/service_worker.js"),
+ helper_->context()->storage()->NewVersionId(),
helper_->context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(
@@ -167,8 +215,6 @@ class ServiceWorkerVersionTest : public testing::Test {
version_->script_cache_map()->SetResources(records);
// Make the registration findable via storage functions.
- helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing));
- base::RunLoop().RunUntilIdle();
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
helper_->context()->storage()->StoreRegistration(
registration_.get(),
@@ -178,7 +224,8 @@ class ServiceWorkerVersionTest : public testing::Test {
ASSERT_EQ(SERVICE_WORKER_OK, status);
// Simulate adding one process to the pattern.
- helper_->SimulateAddProcessToPattern(pattern_, kRenderProcessId);
+ helper_->SimulateAddProcessToPattern(pattern_,
+ helper_->mock_render_process_id());
ASSERT_TRUE(helper_->context()->process_manager()
->PatternHasProcessToRun(pattern_));
}
@@ -210,7 +257,7 @@ class MessageReceiverDisallowStart : public MessageReceiver {
~MessageReceiverDisallowStart() override {}
void OnStartWorker(int embedded_worker_id,
- int64 service_worker_version_id,
+ int64_t service_worker_version_id,
const GURL& scope,
const GURL& script_url) override {
// Do nothing.
@@ -285,6 +332,31 @@ class ServiceWorkerWaitForeverInFetchTest : public ServiceWorkerVersionTest {
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerWaitForeverInFetchTest);
};
+class MessageReceiverMojoTestService : public MessageReceiver {
+ public:
+ MessageReceiverMojoTestService() : MessageReceiver() {}
+ ~MessageReceiverMojoTestService() override {}
+
+ void OnSetupMojo(ServiceRegistry* service_registry) override {
+ service_registry->AddService(base::Bind(&TestMojoServiceImpl::Create));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MessageReceiverMojoTestService);
+};
+
+class ServiceWorkerVersionWithMojoTest : public ServiceWorkerVersionTest {
+ protected:
+ ServiceWorkerVersionWithMojoTest() : ServiceWorkerVersionTest() {}
+
+ scoped_ptr<MessageReceiver> GetMessageReceiver() override {
+ return make_scoped_ptr(new MessageReceiverMojoTestService());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionWithMojoTest);
+};
+
TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
// Call StartWorker() multiple times.
ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
@@ -558,6 +630,17 @@ TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_LT(idle_time, version_->idle_time_);
+ // Starting and finishing a request resets the idle time.
+ version_->idle_time_ -= kOneSecond;
+ idle_time = version_->idle_time_;
+ int request_id =
+ version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status));
+ EXPECT_TRUE(version_->FinishRequest(request_id));
+
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_LT(idle_time, version_->idle_time_);
+
// Dispatching a message event resets the idle time.
std::vector<TransferredMessagePort> ports;
SetUpDummyMessagePort(&ports);
@@ -573,24 +656,6 @@ TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
EXPECT_LT(idle_time, version_->idle_time_);
}
-// Test that the worker stays alive for some time after
-// receiving a push event.
-// TODO(falken): Remove this test once Facebook doesn't rely on the behavior:
-// crbug.com/519993
-TEST_F(ServiceWorkerVersionTest, StayAliveAfterPush) {
- const base::TimeDelta kTenSeconds = base::TimeDelta::FromSeconds(10);
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
- version_->DispatchPushEvent(CreateReceiverOnCurrentThread(&status),
- std::string());
- base::RunLoop().RunUntilIdle();
-
- // Pretend we've been idle for 10 seconds and fire the timeout code.
- version_->idle_time_ = base::TimeTicks::Now() - kTenSeconds;
- version_->OnTimeoutTimer();
- EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
-}
-
TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
version_->StartWorker(CreateReceiverOnCurrentThread(&status));
@@ -714,7 +779,7 @@ TEST_F(ServiceWorkerVersionTest, StaleUpdate_RunningWorker) {
version_->stale_time_ =
base::TimeTicks::Now() -
base::TimeDelta::FromMinutes(
- ServiceWorkerVersion::kStartWorkerTimeoutMinutes + 1);
+ ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes + 1);
version_->OnTimeoutTimer();
EXPECT_TRUE(version_->stale_time_.is_null());
EXPECT_TRUE(version_->update_timer_.IsRunning());
@@ -729,7 +794,7 @@ TEST_F(ServiceWorkerVersionTest, StaleUpdate_DoNotDeferTimer) {
base::TimeTicks stale_time =
base::TimeTicks::Now() -
base::TimeDelta::FromMinutes(
- ServiceWorkerVersion::kStartWorkerTimeoutMinutes + 1);
+ ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes + 1);
version_->stale_time_ = stale_time;
// Stale time is not deferred.
@@ -772,7 +837,126 @@ TEST_F(ServiceWorkerWaitForeverInFetchTest, RequestTimeout) {
// Simulate timeout.
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
- version_->SetAllRequestTimes(
+ version_->SetAllRequestExpirations(base::TimeTicks::Now());
+ version_->timeout_timer_.user_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
+ EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
+}
+
+TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+
+ version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+ base::RunLoop().RunUntilIdle();
+
+ // Create a request that should expire Now().
+ int request_id = version_->StartRequestWithCustomTimeout(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status), base::TimeDelta(),
+ ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(version_->timeout_timer_.IsRunning());
+ version_->timeout_timer_.user_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
+
+ EXPECT_FALSE(version_->FinishRequest(request_id));
+
+ // CONTINUE_ON_TIMEOUT timeouts don't stop the service worker.
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+}
+
+TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeoutKill) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+
+ version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+ base::RunLoop().RunUntilIdle();
+
+ // Create a request that should expire Now().
+ int request_id = version_->StartRequestWithCustomTimeout(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status), base::TimeDelta(),
+ ServiceWorkerVersion::KILL_ON_TIMEOUT);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(version_->timeout_timer_.IsRunning());
+ version_->timeout_timer_.user_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
+
+ EXPECT_FALSE(version_->FinishRequest(request_id));
+
+ // KILL_ON_TIMEOUT timeouts should stop the service worker.
+ EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
+}
+
+TEST_F(ServiceWorkerWaitForeverInFetchTest, MixedRequestTimeouts) {
+ ServiceWorkerStatusCode sync_status =
+ SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ ServiceWorkerStatusCode fetch_status =
+ SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+
+ version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+ base::RunLoop().RunUntilIdle();
+
+ // Create a fetch request that should expire sometime later.
+ version_->DispatchFetchEvent(ServiceWorkerFetchRequest(),
+ base::Bind(&base::DoNothing),
+ base::Bind(&ReceiveFetchResult, &fetch_status));
+ // Create a request that should expire Now().
+ int request_id = version_->StartRequestWithCustomTimeout(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&sync_status), base::TimeDelta(),
+ ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, sync_status);
+
+ // Verify the sync has timed out but not the fetch.
+ EXPECT_TRUE(version_->timeout_timer_.IsRunning());
+ version_->timeout_timer_.user_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, sync_status);
+ EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, fetch_status);
+
+ // Background sync timeouts don't stop the service worker.
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+
+ // Gracefully handle the sync event finishing after the timeout.
+ EXPECT_FALSE(version_->FinishRequest(request_id));
+
+ // Verify that the fetch times out later.
+ version_->SetAllRequestExpirations(base::TimeTicks::Now());
+ version_->timeout_timer_.user_task().Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, fetch_status);
+
+ // Other timeouts do stop the service worker.
+ EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
+}
+
+TEST_F(ServiceWorkerVersionTest, RequestTimeout) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+ base::RunLoop().RunUntilIdle();
+ int request_id =
+ version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+
+ // Callback has not completed yet.
+ EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status);
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+
+ // Simulate timeout.
+ EXPECT_TRUE(version_->timeout_timer_.IsRunning());
+ version_->SetAllRequestExpirations(
base::TimeTicks::Now() -
base::TimeDelta::FromMinutes(
ServiceWorkerVersion::kRequestTimeoutMinutes + 1));
@@ -780,6 +964,8 @@ TEST_F(ServiceWorkerWaitForeverInFetchTest, RequestTimeout) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
+
+ EXPECT_FALSE(version_->FinishRequest(request_id));
}
TEST_F(ServiceWorkerFailToStartTest, RendererCrash) {
@@ -823,7 +1009,7 @@ TEST_F(ServiceWorkerFailToStartTest, Timeout) {
version_->start_time_ =
base::TimeTicks::Now() -
base::TimeDelta::FromMinutes(
- ServiceWorkerVersion::kStartWorkerTimeoutMinutes + 1);
+ ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes + 1);
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
@@ -908,4 +1094,254 @@ TEST_F(ServiceWorkerStallInStoppingTest, DetachThenRestart) {
EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
}
+TEST_F(ServiceWorkerVersionTest, RegisterForeignFetchScopes) {
+ version_->SetStatus(ServiceWorkerVersion::INSTALLING);
+ // Start a worker.
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+ EXPECT_EQ(0, helper_->mock_render_process_host()->bad_msg_count());
+
+ // Invalid URL, should kill worker (but in tests will only increase bad
+ // message count).
+ version_->OnRegisterForeignFetchScopes(std::vector<GURL>(1, GURL()));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, helper_->mock_render_process_host()->bad_msg_count());
+ EXPECT_EQ(0u, version_->foreign_fetch_scopes_.size());
+
+ // URL outside the scope of the worker.
+ version_->OnRegisterForeignFetchScopes(
+ std::vector<GURL>(1, GURL("http://www.example.com/wrong")));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(2, helper_->mock_render_process_host()->bad_msg_count());
+ EXPECT_EQ(0u, version_->foreign_fetch_scopes_.size());
+
+ // URL on wrong origin.
+ version_->OnRegisterForeignFetchScopes(
+ std::vector<GURL>(1, GURL("http://example.com/test/")));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3, helper_->mock_render_process_host()->bad_msg_count());
+ EXPECT_EQ(0u, version_->foreign_fetch_scopes_.size());
+
+ // Valid URL 1.
+ GURL valid_scope_1("http://www.example.com/test/subscope");
+ version_->OnRegisterForeignFetchScopes(std::vector<GURL>(1, valid_scope_1));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3, helper_->mock_render_process_host()->bad_msg_count());
+ EXPECT_EQ(1u, version_->foreign_fetch_scopes_.size());
+ EXPECT_EQ(valid_scope_1, version_->foreign_fetch_scopes_[0]);
+
+ // Valid URL 2.
+ GURL valid_scope_2("http://www.example.com/test/subscope");
+ version_->OnRegisterForeignFetchScopes(std::vector<GURL>(1, valid_scope_2));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3, helper_->mock_render_process_host()->bad_msg_count());
+ EXPECT_EQ(2u, version_->foreign_fetch_scopes_.size());
+ EXPECT_EQ(valid_scope_1, version_->foreign_fetch_scopes_[0]);
+ EXPECT_EQ(valid_scope_2, version_->foreign_fetch_scopes_[1]);
+}
+
+TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+
+ int request_id =
+ version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+
+ // Callback has not completed yet.
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+
+ // Simulate renderer crash: do what
+ // ServiceWorkerDispatcherHost::OnFilterRemoved does.
+ int process_id = helper_->mock_render_process_id();
+ helper_->context()->RemoveAllProviderHostsForProcess(process_id);
+ helper_->context()->embedded_worker_registry()->RemoveChildProcessSender(
+ process_id);
+ base::RunLoop().RunUntilIdle();
+
+ // Callback completed.
+ EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED, status);
+ EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
+
+ // Request already failed, calling finsh should return false.
+ EXPECT_FALSE(version_->FinishRequest(request_id));
+}
+
+TEST_F(ServiceWorkerVersionWithMojoTest, MojoService) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+
+ scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner);
+ int request_id = version_->StartRequest(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status, runner->QuitClosure()));
+ base::WeakPtr<TestMojoService> service =
+ version_->GetMojoServiceForRequest<TestMojoService>(request_id);
+ service->DoSomething(runner->QuitClosure());
+ runner->Run();
+
+ // Mojo service does exist in worker, so error callback should not have been
+ // called and FinishRequest should return true.
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_TRUE(version_->FinishRequest(request_id));
+}
+
+TEST_F(ServiceWorkerVersionTest, NonExistentMojoService) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+
+ scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner);
+ int request_id = version_->StartRequest(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status, runner->QuitClosure()));
+ base::WeakPtr<TestMojoService> service =
+ version_->GetMojoServiceForRequest<TestMojoService>(request_id);
+ service->DoSomething(runner->QuitClosure());
+ runner->Run();
+
+ // Mojo service doesn't exist in worker, so error callback should have been
+ // called and FinishRequest should return false.
+ EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED, status);
+ EXPECT_FALSE(version_->FinishRequest(request_id));
+}
+
+TEST_F(ServiceWorkerVersionTest, DispatchEvent) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+
+ // Activate and start worker.
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+
+ // Start request and dispatch test event.
+ scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner);
+ int request_id = version_->StartRequest(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status, runner->QuitClosure()));
+ int received_request_id = 0;
+ std::string received_data;
+ version_->DispatchEvent<TestMsg_TestEventResult>(
+ request_id, TestMsg_TestEvent(request_id),
+ base::Bind(&ReceiveTestEventResult, &received_request_id, &received_data,
+ runner->QuitClosure()));
+
+ // Verify event got dispatched to worker.
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(1u, helper_->inner_ipc_sink()->message_count());
+ const IPC::Message* msg = helper_->inner_ipc_sink()->GetMessageAt(0);
+ EXPECT_EQ(TestMsg_TestEvent::ID, msg->type());
+
+ // Simulate sending reply to event.
+ std::string reply("foobar");
+ helper_->SimulateSendEventResult(
+ version_->embedded_worker()->embedded_worker_id(), request_id, reply);
+ runner->Run();
+
+ // Verify message callback got called with correct reply.
+ EXPECT_EQ(request_id, received_request_id);
+ EXPECT_EQ(reply, received_data);
+
+ // Should not have timed out, so error callback should not have been
+ // called and FinishRequest should return true.
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_TRUE(version_->FinishRequest(request_id));
+}
+
+TEST_F(ServiceWorkerVersionTest, DispatchConcurrentEvent) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+
+ // Activate and start worker.
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
+
+ // Start first request and dispatch test event.
+ scoped_refptr<MessageLoopRunner> runner1(new MessageLoopRunner);
+ ServiceWorkerStatusCode status1 = SERVICE_WORKER_OK; // dummy value
+ int request_id1 = version_->StartRequest(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status1, runner1->QuitClosure()));
+ int received_request_id1 = 0;
+ std::string received_data1;
+ version_->DispatchEvent<TestMsg_TestEventResult>(
+ request_id1, TestMsg_TestEvent(request_id1),
+ base::Bind(&ReceiveTestEventResult, &received_request_id1,
+ &received_data1, runner1->QuitClosure()));
+
+ // Start second request and dispatch test event.
+ scoped_refptr<MessageLoopRunner> runner2(new MessageLoopRunner);
+ ServiceWorkerStatusCode status2 = SERVICE_WORKER_OK; // dummy value
+ int request_id2 = version_->StartRequest(
+ ServiceWorkerMetrics::EventType::SYNC,
+ CreateReceiverOnCurrentThread(&status2, runner2->QuitClosure()));
+ int received_request_id2 = 0;
+ std::string received_data2;
+ version_->DispatchEvent<TestMsg_TestEventResult>(
+ request_id2, TestMsg_TestEvent(request_id2),
+ base::Bind(&ReceiveTestEventResult, &received_request_id2,
+ &received_data2, runner2->QuitClosure()));
+
+ // Make sure events got dispatched in same order.
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(2u, helper_->inner_ipc_sink()->message_count());
+ const IPC::Message* msg = helper_->inner_ipc_sink()->GetMessageAt(0);
+ ASSERT_EQ(TestMsg_TestEvent::ID, msg->type());
+ TestMsg_TestEvent::Param params;
+ TestMsg_TestEvent::Read(msg, &params);
+ EXPECT_EQ(request_id1, base::get<0>(params));
+ msg = helper_->inner_ipc_sink()->GetMessageAt(1);
+ ASSERT_EQ(TestMsg_TestEvent::ID, msg->type());
+ TestMsg_TestEvent::Read(msg, &params);
+ EXPECT_EQ(request_id2, base::get<0>(params));
+
+ // Reply to second event.
+ std::string reply2("foobar");
+ helper_->SimulateSendEventResult(
+ version_->embedded_worker()->embedded_worker_id(), request_id2, reply2);
+ runner2->Run();
+
+ // Verify correct message callback got called with correct reply.
+ EXPECT_EQ(0, received_request_id1);
+ EXPECT_EQ(request_id2, received_request_id2);
+ EXPECT_EQ(reply2, received_data2);
+ EXPECT_EQ(SERVICE_WORKER_OK, status2);
+ EXPECT_TRUE(version_->FinishRequest(request_id2));
+
+ // Reply to first event.
+ std::string reply1("hello world");
+ helper_->SimulateSendEventResult(
+ version_->embedded_worker()->embedded_worker_id(), request_id1, reply1);
+ runner1->Run();
+
+ // Verify correct response was received.
+ EXPECT_EQ(request_id1, received_request_id1);
+ EXPECT_EQ(request_id2, received_request_id2);
+ EXPECT_EQ(reply1, received_data1);
+ EXPECT_EQ(SERVICE_WORKER_OK, status1);
+ EXPECT_TRUE(version_->FinishRequest(request_id1));
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc
index 9fff62eed6a..1e7b8706ca5 100644
--- a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -4,10 +4,12 @@
#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
-#include <algorithm>
-
+#include "base/bind.h"
+#include "base/callback.h"
#include "base/strings/stringprintf.h"
+#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "content/browser/service_worker/service_worker_cache_writer.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_metrics.h"
@@ -18,7 +20,6 @@
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
-#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
@@ -40,8 +41,6 @@ const char kRedirectError[] =
"The script resource is behind a redirect, which is disallowed.";
const char kServiceWorkerAllowed[] = "Service-Worker-Allowed";
-const int kBufferSize = 16 * 1024;
-
// The net error code used when the job fails the update attempt because the new
// script is byte-by-byte identical to the incumbent script. This error is shown
// in DevTools and in netlog, so we want something obscure enough that it won't
@@ -49,260 +48,10 @@ const int kBufferSize = 16 * 1024;
// developers.
// TODO(falken): Redesign this class so we don't have to fail at the network
// stack layer just to cancel the update.
-const int kIdenticalScriptError = net::ERR_FILE_EXISTS;
+const net::Error kIdenticalScriptError = net::ERR_FILE_EXISTS;
} // namespace
-// Reads an existing resource and copies it via
-// ServiceWorkerWriteToCacheJob::WriteData.
-class ServiceWorkerWriteToCacheJob::Copier : public base::RefCounted<Copier> {
- public:
- Copier(base::WeakPtr<ServiceWorkerWriteToCacheJob> owner,
- scoped_ptr<ServiceWorkerResponseReader> reader,
- int bytes_to_copy,
- const base::Callback<void(ServiceWorkerStatusCode)>& callback)
- : owner_(owner),
- reader_(reader.release()),
- bytes_to_copy_(bytes_to_copy),
- callback_(callback) {
- DCHECK_LT(0, bytes_to_copy_);
- }
-
- void Start() {
- io_buffer_ = new net::IOBuffer(kBufferSize);
- ReadSomeData();
- }
-
- private:
- friend class base::RefCounted<Copier>;
- ~Copier() {}
-
- void ReadSomeData() {
- reader_->ReadData(io_buffer_.get(), kBufferSize,
- base::Bind(&Copier::OnReadDataComplete, this));
- }
-
- void OnReadDataComplete(int result) {
- if (!owner_)
- return;
- if (result <= 0) {
- // We hit EOF or error but weren't done copying.
- Complete(SERVICE_WORKER_ERROR_FAILED);
- return;
- }
-
- int bytes_to_write = std::min(bytes_to_copy_, result);
- owner_->WriteData(io_buffer_.get(), bytes_to_write,
- base::Bind(&Copier::OnWriteDataComplete, this));
- }
-
- void OnWriteDataComplete(int result) {
- if (result < 0) {
- Complete(SERVICE_WORKER_ERROR_FAILED);
- return;
- }
-
- DCHECK_LE(result, bytes_to_copy_);
- bytes_to_copy_ -= result;
- if (bytes_to_copy_ == 0) {
- Complete(SERVICE_WORKER_OK);
- return;
- }
-
- ReadSomeData();
- }
-
- void Complete(ServiceWorkerStatusCode status) {
- if (!owner_)
- return;
- callback_.Run(status);
- }
-
- base::WeakPtr<ServiceWorkerWriteToCacheJob> owner_;
- scoped_ptr<ServiceWorkerResponseReader> reader_;
- int bytes_to_copy_ = 0;
- base::Callback<void(ServiceWorkerStatusCode)> callback_;
- scoped_refptr<net::IOBuffer> io_buffer_;
-};
-
-// Abstract consumer for ServiceWorkerWriteToCacheJob that processes data from
-// the network.
-class ServiceWorkerWriteToCacheJob::NetDataConsumer {
- public:
- virtual ~NetDataConsumer() {}
-
- // Called by |owner_|'s OnResponseStarted.
- virtual void OnResponseStarted() = 0;
-
- // HandleData should call |owner_|->NotifyReadComplete() when done.
- virtual void HandleData(net::IOBuffer* buf, int size) = 0;
-};
-
-// Dumb consumer that just writes everything it sees to disk.
-class ServiceWorkerWriteToCacheJob::PassThroughConsumer
- : public ServiceWorkerWriteToCacheJob::NetDataConsumer {
- public:
- explicit PassThroughConsumer(ServiceWorkerWriteToCacheJob* owner)
- : owner_(owner), weak_factory_(this) {}
- ~PassThroughConsumer() override {}
-
- void OnResponseStarted() override {
- owner_->WriteHeaders(
- base::Bind(&PassThroughConsumer::OnWriteHeadersComplete,
- weak_factory_.GetWeakPtr()));
- owner_->SetPendingIO();
- }
-
- void HandleData(net::IOBuffer* buf, int size) override {
- if (size == 0) {
- owner_->OnPassThroughComplete();
- return;
- }
-
- owner_->WriteData(buf, size,
- base::Bind(&PassThroughConsumer::OnWriteDataComplete,
- weak_factory_.GetWeakPtr()));
- owner_->SetPendingIO();
- }
-
- private:
- void OnWriteHeadersComplete() {
- owner_->ClearPendingIO();
- owner_->CommitHeadersAndNotifyHeadersComplete();
- }
-
- void OnWriteDataComplete(int result) {
- owner_->ClearPendingIO();
- owner_->NotifyReadComplete(result);
- }
-
- ServiceWorkerWriteToCacheJob* owner_;
- base::WeakPtrFactory<PassThroughConsumer> weak_factory_;
-};
-
-// Compares an existing resource with data progressively fed to it.
-// Calls back to |owner|->OnCompareComplete once done.
-class ServiceWorkerWriteToCacheJob::Comparer
- : public ServiceWorkerWriteToCacheJob::NetDataConsumer {
- public:
- Comparer(ServiceWorkerWriteToCacheJob* owner,
- scoped_ptr<ServiceWorkerResponseReader> reader)
- : owner_(owner), reader_(reader.release()), weak_factory_(this) {}
- ~Comparer() override {}
-
- void OnResponseStarted() override {
- owner_->CommitHeadersAndNotifyHeadersComplete();
- }
-
- void HandleData(net::IOBuffer* buf, int size) override {
- net_data_ = buf;
- net_data_offset_ = 0;
- net_data_size_ = size;
-
- if (size == 0 && info_) {
- Complete(bytes_matched_ == info_->response_data_size);
- return;
- }
-
- if (!info_) {
- read_buffer_ = new net::IOBuffer(kBufferSize);
- info_ = new HttpResponseInfoIOBuffer;
- reader_->ReadInfo(info_.get(), base::Bind(&Comparer::OnReadInfoComplete,
- weak_factory_.GetWeakPtr()));
- owner_->SetPendingIO();
- return;
- }
-
- ReadSomeData();
- owner_->SetPendingIO();
- }
-
- private:
- int bytes_remaining() {
- DCHECK(net_data_);
- DCHECK_LE(0, net_data_offset_);
- DCHECK_LE(net_data_offset_, net_data_size_);
- return net_data_size_ - net_data_offset_;
- }
-
- void OnReadInfoComplete(int result) {
- if (result < 0) {
- Complete(false);
- return;
- }
-
- if (bytes_remaining() == 0) {
- Complete(bytes_matched_ == info_->response_data_size);
- return;
- }
-
- ReadSomeData();
- }
-
- void ReadSomeData() {
- DCHECK_LT(0, bytes_remaining());
- int bytes_to_read = std::min(bytes_remaining(), kBufferSize);
- reader_->ReadData(
- read_buffer_.get(), bytes_to_read,
- base::Bind(&Comparer::OnReadDataComplete, weak_factory_.GetWeakPtr()));
- }
-
- void OnReadDataComplete(int result) {
- if (result <= 0) {
- // We hit error or EOF but had more to compare.
- Complete(false);
- return;
- }
-
- DCHECK_LE(result, bytes_remaining());
- if (memcmp(net_data_->data() + net_data_offset_, read_buffer_->data(),
- result) != 0) {
- Complete(false);
- return;
- }
-
- net_data_offset_ += result;
- if (bytes_remaining() == 0) {
- NotifyReadComplete();
- return;
- }
-
- ReadSomeData();
- }
-
- // Completes one HandleData() call.
- void NotifyReadComplete() {
- int size = net_data_size_;
- net_data_ = nullptr;
- net_data_offset_ = 0;
- net_data_size_ = 0;
-
- bytes_matched_ += size;
- owner_->ClearPendingIO();
- owner_->NotifyReadComplete(size);
- }
-
- // Completes the entire Comparer.
- void Complete(bool is_equal) {
- owner_->OnCompareComplete(bytes_matched_, is_equal);
- }
-
- ServiceWorkerWriteToCacheJob* owner_;
- scoped_ptr<ServiceWorkerResponseReader> reader_;
- scoped_refptr<net::IOBuffer> read_buffer_;
- scoped_refptr<HttpResponseInfoIOBuffer> info_;
-
- // Cumulative number of bytes successfully compared.
- int bytes_matched_ = 0;
-
- // State used for one HandleData() call.
- scoped_refptr<net::IOBuffer> net_data_;
- int net_data_offset_ = 0;
- int net_data_size_ = 0;
-
- base::WeakPtrFactory<Comparer> weak_factory_;
-};
-
ServiceWorkerWriteToCacheJob::ServiceWorkerWriteToCacheJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
@@ -310,14 +59,14 @@ ServiceWorkerWriteToCacheJob::ServiceWorkerWriteToCacheJob(
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerVersion* version,
int extra_load_flags,
- int64 response_id,
- int64 incumbent_response_id)
+ int64_t resource_id,
+ int64_t incumbent_resource_id)
: net::URLRequestJob(request, network_delegate),
resource_type_(resource_type),
context_(context),
url_(request->url()),
- response_id_(response_id),
- incumbent_response_id_(incumbent_response_id),
+ resource_id_(resource_id),
+ incumbent_resource_id_(incumbent_resource_id),
version_(version),
has_been_killed_(false),
did_notify_started_(false),
@@ -331,26 +80,31 @@ ServiceWorkerWriteToCacheJob::~ServiceWorkerWriteToCacheJob() {
}
void ServiceWorkerWriteToCacheJob::Start() {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&ServiceWorkerWriteToCacheJob::StartAsync,
+ weak_factory_.GetWeakPtr()));
+}
+
+void ServiceWorkerWriteToCacheJob::StartAsync() {
TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
"ServiceWorkerWriteToCacheJob::ExecutingJob",
this,
"URL", request_->url().spec());
if (!context_) {
- NotifyStartError(net::URLRequestStatus(
- net::URLRequestStatus::FAILED, net::ERR_FAILED));
+ // NotifyStartError is not safe to call synchronously in Start().
+ NotifyStartError(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
return;
}
- if (incumbent_response_id_ != kInvalidServiceWorkerResourceId &&
- !version_->skip_script_comparison()) {
- scoped_ptr<ServiceWorkerResponseReader> incumbent_reader =
- context_->storage()->CreateResponseReader(incumbent_response_id_);
- consumer_.reset(new Comparer(this, incumbent_reader.Pass()));
- } else {
- consumer_.reset(new PassThroughConsumer(this));
- }
- version_->script_cache_map()->NotifyStartedCaching(
- url_, response_id_);
+ // These uses of Unretained are safe because this object is the sole owner of
+ // |cache_writer_|, which in turn is the sole user of these callbacks.
+ cache_writer_.reset(new ServiceWorkerCacheWriter(
+ base::Bind(&ServiceWorkerWriteToCacheJob::CreateCacheResponseReader,
+ base::Unretained(this)),
+ base::Bind(&ServiceWorkerWriteToCacheJob::CreateCacheResponseWriter,
+ base::Unretained(this))));
+ version_->script_cache_map()->NotifyStartedCaching(url_, resource_id_);
did_notify_started_ = true;
StartNetRequest();
}
@@ -361,12 +115,10 @@ void ServiceWorkerWriteToCacheJob::Kill() {
weak_factory_.InvalidateWeakPtrs();
has_been_killed_ = true;
net_request_.reset();
- if (did_notify_started_ && !did_notify_finished_) {
- version_->script_cache_map()->NotifyFinishedCaching(
- url_, -1,
- net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_ABORTED),
- kKilledError);
- did_notify_finished_ = true;
+ if (did_notify_started_) {
+ net::Error error = NotifyFinishedCaching(
+ net::URLRequestStatus::FromError(net::ERR_ABORTED), kKilledError);
+ DCHECK_EQ(net::ERR_ABORTED, error);
}
writer_.reset();
context_.reset();
@@ -413,26 +165,20 @@ void ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders(
net_request_->SetExtraRequestHeaders(headers);
}
-bool ServiceWorkerWriteToCacheJob::ReadRawData(net::IOBuffer* buf,
- int buf_size,
- int* bytes_read) {
- net::URLRequestStatus status = ReadNetData(buf, buf_size, bytes_read);
- SetStatus(status);
+int ServiceWorkerWriteToCacheJob::ReadRawData(net::IOBuffer* buf,
+ int buf_size) {
+ int bytes_read = 0;
+ net::URLRequestStatus status = ReadNetData(buf, buf_size, &bytes_read);
if (status.is_io_pending())
- return false;
+ return net::ERR_IO_PENDING;
if (!status.is_success()) {
- AsyncNotifyDoneHelper(status, kFetchScriptError);
- return false;
+ net::Error error = NotifyFinishedCaching(status, kFetchScriptError);
+ DCHECK_EQ(status.error(), error);
+ return error;
}
- DCHECK_EQ(0, *bytes_read);
- consumer_->HandleData(buf, 0);
- if (did_notify_finished_)
- return GetStatus().is_success();
- if (GetStatus().is_io_pending())
- return false;
- return status.is_success();
+ return HandleNetData(bytes_read);
}
const net::HttpResponseInfo* ServiceWorkerWriteToCacheJob::http_info() const {
@@ -446,6 +192,7 @@ void ServiceWorkerWriteToCacheJob::InitNetRequest(
request()->url(), request()->priority(), this);
net_request_->set_first_party_for_cookies(
request()->first_party_for_cookies());
+ net_request_->set_initiator(request()->initiator());
net_request_->SetReferrer(request()->referrer());
if (extra_load_flags)
net_request_->SetLoadFlags(net_request_->load_flags() | extra_load_flags);
@@ -471,125 +218,35 @@ net::URLRequestStatus ServiceWorkerWriteToCacheJob::ReadNetData(
int* bytes_read) {
DCHECK_GT(buf_size, 0);
DCHECK(bytes_read);
- *bytes_read = 0;
io_buffer_ = buf;
io_buffer_bytes_ = 0;
- int net_bytes_read = 0;
- if (!net_request_->Read(buf, buf_size, &net_bytes_read)) {
- if (net_request_->status().is_io_pending())
- return net_request_->status();
- DCHECK(!net_request_->status().is_success());
- return net_request_->status();
- }
-
- if (net_bytes_read != 0) {
- HandleNetData(net_bytes_read);
- DCHECK(GetStatus().is_io_pending());
- return GetStatus();
- }
+ if (!net_request_->Read(buf, buf_size, bytes_read))
+ DCHECK_NE(net::URLRequestStatus::SUCCESS, net_request_->status().status());
- DCHECK(net_request_->status().is_success());
return net_request_->status();
}
-void ServiceWorkerWriteToCacheJob::WriteHeaders(const base::Closure& callback) {
- if (!context_) {
- AsyncNotifyDoneHelper(
- net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED),
- kFetchScriptError);
- return;
- }
- TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
- "ServiceWorkerWriteToCacheJob::ExecutingJob",
- this, "WriteHeaders");
- writer_ = context_->storage()->CreateResponseWriter(response_id_);
- scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
- new HttpResponseInfoIOBuffer(
- new net::HttpResponseInfo(net_request_->response_info()));
- writer_->WriteInfo(
- info_buffer.get(),
- base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete,
- weak_factory_.GetWeakPtr(), callback));
-}
-
-void ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete(
- const base::Closure& callback,
- int result) {
- if (result < 0) {
- ServiceWorkerMetrics::CountWriteResponseResult(
- ServiceWorkerMetrics::WRITE_HEADERS_ERROR);
- AsyncNotifyDoneHelper(
- net::URLRequestStatus(net::URLRequestStatus::FAILED, result),
- kFetchScriptError);
- return;
- }
- TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
- "ServiceWorkerWriteToCacheJob::ExecutingJob",
- this, "WriteHeadersCompleted");
- callback.Run();
-}
-
-void ServiceWorkerWriteToCacheJob::WriteData(
- net::IOBuffer* buf,
- int bytes_to_write,
- const base::Callback<void(int result)>& callback) {
- DCHECK_LT(0, bytes_to_write);
- TRACE_EVENT_ASYNC_STEP_INTO1(
- "ServiceWorker", "ServiceWorkerWriteToCacheJob::ExecutingJob", this,
- "WriteData", "Amount to write", bytes_to_write);
-
- writer_->WriteData(
- buf, bytes_to_write,
- base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete,
- weak_factory_.GetWeakPtr(), callback));
-}
-
-void ServiceWorkerWriteToCacheJob::OnWriteDataComplete(
- const base::Callback<void(int result)>& callback,
- int result) {
- DCHECK_NE(0, result);
- if (!context_) {
- AsyncNotifyDoneHelper(
- net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED),
- kFetchScriptError);
- return;
- }
- if (result < 0) {
- ServiceWorkerMetrics::CountWriteResponseResult(
- ServiceWorkerMetrics::WRITE_DATA_ERROR);
- AsyncNotifyDoneHelper(
- net::URLRequestStatus(net::URLRequestStatus::FAILED, result),
- kFetchScriptError);
- return;
- }
- ServiceWorkerMetrics::CountWriteResponseResult(
- ServiceWorkerMetrics::WRITE_OK);
- callback.Run(result);
- TRACE_EVENT_ASYNC_END0("ServiceWorker",
- "ServiceWorkerWriteToCacheJob::ExecutingJob", this);
-}
-
void ServiceWorkerWriteToCacheJob::OnReceivedRedirect(
net::URLRequest* request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) {
- DCHECK_EQ(net_request_, request);
+ DCHECK_EQ(net_request_.get(), request);
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerWriteToCacheJob::OnReceivedRedirect");
// Script resources can't redirect.
- AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_UNSAFE_REDIRECT),
- kRedirectError);
+ NotifyStartErrorHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_UNSAFE_REDIRECT),
+ kRedirectError);
}
void ServiceWorkerWriteToCacheJob::OnAuthRequired(
net::URLRequest* request,
net::AuthChallengeInfo* auth_info) {
- DCHECK_EQ(net_request_, request);
+ DCHECK_EQ(net_request_.get(), request);
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerWriteToCacheJob::OnAuthRequired");
// TODO(michaeln): Pass this thru to our jobs client.
- AsyncNotifyDoneHelper(
+ NotifyStartErrorHelper(
net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED),
kClientAuthenticationError);
}
@@ -597,12 +254,12 @@ void ServiceWorkerWriteToCacheJob::OnAuthRequired(
void ServiceWorkerWriteToCacheJob::OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) {
- DCHECK_EQ(net_request_, request);
+ DCHECK_EQ(net_request_.get(), request);
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerWriteToCacheJob::OnCertificateRequested");
// TODO(michaeln): Pass this thru to our jobs client.
// see NotifyCertificateRequested.
- AsyncNotifyDoneHelper(
+ NotifyStartErrorHelper(
net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED),
kClientAuthenticationError);
}
@@ -611,20 +268,20 @@ void ServiceWorkerWriteToCacheJob::OnSSLCertificateError(
net::URLRequest* request,
const net::SSLInfo& ssl_info,
bool fatal) {
- DCHECK_EQ(net_request_, request);
+ DCHECK_EQ(net_request_.get(), request);
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerWriteToCacheJob::OnSSLCertificateError");
// TODO(michaeln): Pass this thru to our jobs client,
// see NotifySSLCertificateError.
- AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_INSECURE_RESPONSE),
- kSSLError);
+ NotifyStartErrorHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_INSECURE_RESPONSE),
+ kSSLError);
}
void ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart(
net::URLRequest* request,
bool* defer) {
- DCHECK_EQ(net_request_, request);
+ DCHECK_EQ(net_request_.get(), request);
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart");
NotifyBeforeNetworkStart(defer);
@@ -632,17 +289,17 @@ void ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart(
void ServiceWorkerWriteToCacheJob::OnResponseStarted(
net::URLRequest* request) {
- DCHECK_EQ(net_request_, request);
+ DCHECK_EQ(net_request_.get(), request);
if (!request->status().is_success()) {
- AsyncNotifyDoneHelper(request->status(), kFetchScriptError);
+ NotifyStartErrorHelper(request->status(), kFetchScriptError);
return;
}
if (request->GetResponseCode() / 100 != 2) {
std::string error_message =
base::StringPrintf(kBadHTTPResponseError, request->GetResponseCode());
- AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_INVALID_RESPONSE),
- error_message);
+ NotifyStartErrorHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_INVALID_RESPONSE),
+ error_message);
// TODO(michaeln): Instead of error'ing immediately, send the net
// response to our consumer, just don't cache it?
return;
@@ -653,9 +310,10 @@ void ServiceWorkerWriteToCacheJob::OnResponseStarted(
const net::HttpNetworkSession::Params* session_params =
request->context()->GetNetworkSessionParams();
if (!session_params || !session_params->ignore_certificate_errors) {
- AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_INSECURE_RESPONSE),
- kSSLError);
+ NotifyStartErrorHelper(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_INSECURE_RESPONSE),
+ kSSLError);
return;
}
}
@@ -670,9 +328,10 @@ void ServiceWorkerWriteToCacheJob::OnResponseStarted(
mime_type.empty()
? kNoMIMEError
: base::StringPrintf(kBadMIMEError, mime_type.c_str());
- AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_INSECURE_RESPONSE),
- error_message);
+ NotifyStartErrorHelper(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_INSECURE_RESPONSE),
+ error_message);
return;
}
@@ -685,37 +344,64 @@ void ServiceWorkerWriteToCacheJob::OnResponseStarted(
if (net_request_->response_info().network_accessed)
version_->embedded_worker()->OnNetworkAccessedForScriptLoad();
- consumer_->OnResponseStarted();
+ http_info_.reset(new net::HttpResponseInfo(net_request_->response_info()));
+ scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
+ new HttpResponseInfoIOBuffer(
+ new net::HttpResponseInfo(net_request_->response_info()));
+ net::Error error = cache_writer_->MaybeWriteHeaders(
+ info_buffer.get(),
+ base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete,
+ weak_factory_.GetWeakPtr()));
+ if (error == net::ERR_IO_PENDING)
+ return;
+ OnWriteHeadersComplete(error);
}
-void ServiceWorkerWriteToCacheJob::CommitHeadersAndNotifyHeadersComplete() {
- http_info_.reset(new net::HttpResponseInfo(net_request_->response_info()));
+void ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete(net::Error error) {
+ DCHECK_NE(net::ERR_IO_PENDING, error);
+ if (error != net::OK) {
+ ServiceWorkerMetrics::CountWriteResponseResult(
+ ServiceWorkerMetrics::WRITE_HEADERS_ERROR);
+ NotifyStartError(net::URLRequestStatus::FromError(error));
+ return;
+ }
+ SetStatus(net::URLRequestStatus());
NotifyHeadersComplete();
}
-void ServiceWorkerWriteToCacheJob::HandleNetData(int bytes_read) {
- io_buffer_bytes_ = bytes_read;
- consumer_->HandleData(io_buffer_.get(), bytes_read);
+void ServiceWorkerWriteToCacheJob::OnWriteDataComplete(net::Error error) {
+ SetStatus(net::URLRequestStatus::FromError(error));
+ DCHECK_NE(net::ERR_IO_PENDING, error);
+ if (io_buffer_bytes_ == 0)
+ error = NotifyFinishedCaching(net::URLRequestStatus::FromError(error), "");
+ if (error != net::OK) {
+ ServiceWorkerMetrics::CountWriteResponseResult(
+ ServiceWorkerMetrics::WRITE_DATA_ERROR);
+ ReadRawDataComplete(error);
+ return;
+ }
+ ServiceWorkerMetrics::CountWriteResponseResult(
+ ServiceWorkerMetrics::WRITE_OK);
+ ReadRawDataComplete(io_buffer_bytes_);
}
-void ServiceWorkerWriteToCacheJob::OnReadCompleted(
- net::URLRequest* request,
- int bytes_read) {
- DCHECK_EQ(net_request_, request);
+void ServiceWorkerWriteToCacheJob::OnReadCompleted(net::URLRequest* request,
+ int bytes_read) {
+ DCHECK_EQ(net_request_.get(), request);
+
+ int result;
if (bytes_read < 0) {
DCHECK(!request->status().is_success());
- AsyncNotifyDoneHelper(request->status(), kFetchScriptError);
- return;
+ result = NotifyFinishedCaching(request->status(), kFetchScriptError);
+ } else {
+ result = HandleNetData(bytes_read);
}
- if (bytes_read > 0) {
- HandleNetData(bytes_read);
- DCHECK(GetStatus().is_io_pending());
+
+ // ReadRawDataComplete will be called in OnWriteDataComplete, so return early.
+ if (result == net::ERR_IO_PENDING)
return;
- }
- // No more data to process, the job is complete.
- DCHECK(request->status().is_success());
- HandleNetData(0);
+ ReadRawDataComplete(result);
}
bool ServiceWorkerWriteToCacheJob::CheckPathRestriction(
@@ -729,107 +415,90 @@ bool ServiceWorkerWriteToCacheJob::CheckPathRestriction(
if (!ServiceWorkerUtils::IsPathRestrictionSatisfied(
version_->scope(), url_,
has_header ? &service_worker_allowed : nullptr, &error_message)) {
- AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_INSECURE_RESPONSE),
- error_message);
+ NotifyStartErrorHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_INSECURE_RESPONSE),
+ error_message);
return false;
}
return true;
}
-void ServiceWorkerWriteToCacheJob::SetPendingIO() {
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
-}
-
-void ServiceWorkerWriteToCacheJob::ClearPendingIO() {
- SetStatus(net::URLRequestStatus());
-}
-
-void ServiceWorkerWriteToCacheJob::OnPassThroughComplete() {
- NotifyFinishedCaching(net::URLRequestStatus(), std::string());
- if (GetStatus().is_io_pending()) {
- ClearPendingIO();
- NotifyReadComplete(0);
- }
-}
-
-void ServiceWorkerWriteToCacheJob::OnCompareComplete(int bytes_matched,
- bool is_equal) {
- if (is_equal) {
- // This version is identical to the incumbent, so discard it and fail this
- // job.
- version_->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_EXISTS);
- AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- kIdenticalScriptError),
- kFetchScriptError);
- return;
- }
-
- // We must switch to the pass through consumer. Write what is known
- // (headers + bytes matched) to disk.
- WriteHeaders(base::Bind(&ServiceWorkerWriteToCacheJob::CopyIncumbent,
- weak_factory_.GetWeakPtr(), bytes_matched));
- SetPendingIO();
-}
-
-void ServiceWorkerWriteToCacheJob::CopyIncumbent(int bytes_to_copy) {
- if (bytes_to_copy == 0) {
- OnCopyComplete(SERVICE_WORKER_OK);
- return;
- }
- scoped_ptr<ServiceWorkerResponseReader> incumbent_reader =
- context_->storage()->CreateResponseReader(incumbent_response_id_);
- scoped_refptr<Copier> copier = new Copier(
- weak_factory_.GetWeakPtr(), incumbent_reader.Pass(), bytes_to_copy,
- base::Bind(&ServiceWorkerWriteToCacheJob::OnCopyComplete,
+int ServiceWorkerWriteToCacheJob::HandleNetData(int bytes_read) {
+ io_buffer_bytes_ = bytes_read;
+ net::Error error = cache_writer_->MaybeWriteData(
+ io_buffer_.get(), bytes_read,
+ base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete,
weak_factory_.GetWeakPtr()));
- copier->Start(); // It deletes itself when done.
- DCHECK(GetStatus().is_io_pending());
-}
-
-void ServiceWorkerWriteToCacheJob::OnCopyComplete(
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
- AsyncNotifyDoneHelper(
- net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED),
- kFetchScriptError);
- return;
- }
- // Continue processing the net data that triggered the comparison fail and
- // copy.
- if (io_buffer_bytes_ > 0) {
- consumer_.reset(new PassThroughConsumer(this));
- consumer_->HandleData(io_buffer_.get(), io_buffer_bytes_);
- return;
+ // In case of ERR_IO_PENDING, this logic is done in OnWriteDataComplete.
+ if (error != net::ERR_IO_PENDING && bytes_read == 0) {
+ error = NotifyFinishedCaching(net::URLRequestStatus::FromError(error),
+ std::string());
}
-
- // The copy was triggered by EOF from the network, which
- // means the job is now done.
- NotifyFinishedCaching(net::URLRequestStatus(), std::string());
- ClearPendingIO();
- NotifyReadComplete(0);
+ return error == net::OK ? bytes_read : error;
}
-void ServiceWorkerWriteToCacheJob::AsyncNotifyDoneHelper(
+void ServiceWorkerWriteToCacheJob::NotifyStartErrorHelper(
const net::URLRequestStatus& status,
const std::string& status_message) {
DCHECK(!status.is_io_pending());
- NotifyFinishedCaching(status, status_message);
- SetStatus(status);
- NotifyDone(status);
+
+ net::Error error = NotifyFinishedCaching(status, status_message);
+ // The special case mentioned in NotifyFinishedCaching about script being
+ // identical does not apply here, since the entire body needs to be read
+ // before this is relevant.
+ DCHECK_EQ(status.error(), error);
+
+ net::URLRequestStatus reported_status = status;
+ std::string reported_status_message = status_message;
+
+ SetStatus(reported_status);
+ NotifyStartError(reported_status);
}
-void ServiceWorkerWriteToCacheJob::NotifyFinishedCaching(
+net::Error ServiceWorkerWriteToCacheJob::NotifyFinishedCaching(
net::URLRequestStatus status,
const std::string& status_message) {
- DCHECK(!did_notify_finished_);
+ net::Error result = static_cast<net::Error>(status.error());
+ if (did_notify_finished_)
+ return result;
+
int size = -1;
if (status.is_success())
- size = writer_ ? writer_->amount_written() : 0;
- version_->script_cache_map()->NotifyFinishedCaching(url_, size, status,
- status_message);
+ size = cache_writer_->bytes_written();
+
+ // If all the calls to MaybeWriteHeaders/MaybeWriteData succeeded, but the
+ // incumbent entry wasn't actually replaced because the new entry was
+ // equivalent, the new version didn't actually install because it already
+ // exists.
+ if (status.status() == net::URLRequestStatus::SUCCESS &&
+ !cache_writer_->did_replace()) {
+ result = kIdenticalScriptError;
+ status = net::URLRequestStatus::FromError(result);
+ version_->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_EXISTS);
+ version_->script_cache_map()->NotifyFinishedCaching(url_, size, status,
+ std::string());
+ } else {
+ version_->script_cache_map()->NotifyFinishedCaching(url_, size, status,
+ status_message);
+ }
+
did_notify_finished_ = true;
+ return result;
+}
+
+scoped_ptr<ServiceWorkerResponseReader>
+ServiceWorkerWriteToCacheJob::CreateCacheResponseReader() {
+ if (incumbent_resource_id_ == kInvalidServiceWorkerResourceId ||
+ version_->skip_script_comparison()) {
+ return nullptr;
+ }
+ return context_->storage()->CreateResponseReader(incumbent_resource_id_);
+}
+
+scoped_ptr<ServiceWorkerResponseWriter>
+ServiceWorkerWriteToCacheJob::CreateCacheResponseWriter() {
+ return context_->storage()->CreateResponseWriter(resource_id_);
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
index 9fcd4b8675b..8cb483cb41c 100644
--- a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
+++ b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_H_
+#include <stdint.h>
+
#include <string>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -15,13 +18,14 @@
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/resource_type.h"
+#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
namespace content {
+class ServiceWorkerCacheWriter;
class ServiceWorkerContextCore;
-class ServiceWorkerResponseWriter;
class ServiceWorkerVersions;
// A URLRequestJob derivative used to cache the main script
@@ -48,8 +52,8 @@ class CONTENT_EXPORT ServiceWorkerWriteToCacheJob
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerVersion* version,
int extra_load_flags,
- int64 response_id,
- int64 incumbent_response_id);
+ int64_t resource_id,
+ int64_t incumbent_resource_id);
private:
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest,
@@ -58,15 +62,12 @@ class CONTENT_EXPORT ServiceWorkerWriteToCacheJob
UpdateAfter24Hours);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest,
UpdateForceBypassCache);
- class NetDataConsumer;
- class PassThroughConsumer;
- class Comparer;
- class Copier;
~ServiceWorkerWriteToCacheJob() override;
// net::URLRequestJob overrides
void Start() override;
+ void StartAsync();
void Kill() override;
net::LoadState GetLoadState() const override;
bool GetCharset(std::string* charset) override;
@@ -74,7 +75,7 @@ class CONTENT_EXPORT ServiceWorkerWriteToCacheJob
void GetResponseInfo(net::HttpResponseInfo* info) override;
int GetResponseCode() const override;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;
const net::HttpResponseInfo* http_info() const;
@@ -86,14 +87,12 @@ class CONTENT_EXPORT ServiceWorkerWriteToCacheJob
int buf_size,
int* bytes_read);
- void CommitHeadersAndNotifyHeadersComplete();
- void WriteHeaders(const base::Closure& callback);
- void OnWriteHeadersComplete(const base::Closure& callback, int result);
- void WriteData(net::IOBuffer* buf,
- int amount_to_write,
- const base::Callback<void(int result)>& callback);
- void OnWriteDataComplete(const base::Callback<void(int result)>& callback,
- int result);
+ // Callbacks for writing headers and data via |cache_writer_|. Note that since
+ // the MaybeWriteHeaders and MaybeWriteData methods on |cache_writer_| are
+ // guaranteed not to do short writes, these functions only receive a
+ // net::Error indicating success or failure, not a count of bytes written.
+ void OnWriteHeadersComplete(net::Error error);
+ void OnWriteDataComplete(net::Error error);
// net::URLRequest::Delegate overrides that observe the net request.
void OnReceivedRedirect(net::URLRequest* request,
@@ -113,35 +112,43 @@ class CONTENT_EXPORT ServiceWorkerWriteToCacheJob
bool CheckPathRestriction(net::URLRequest* request);
- void SetPendingIO();
- void ClearPendingIO();
- void OnPassThroughComplete();
- void OnCompareComplete(int bytes_matched, bool is_equal);
- void CopyIncumbent(int bytes_to_copy);
- void OnCopyComplete(ServiceWorkerStatusCode status);
- void HandleNetData(int bytes_read);
+ // Writes network data back to the script cache if needed, and notifies the
+ // script cache of fetch completion at EOF. This function returns
+ // net::IO_PENDING if the IO is to be completed asynchronously, returns a
+ // negative number that represents a corresponding net error code (other than
+ // net::IO_PENDING) if an error occurred, or returns a non-negative number
+ // that represents the number of network bytes read. If the return value is
+ // non-negative, all of the data in |io_buffer_| has been written back to the
+ // script cache if necessary.
+ int HandleNetData(int bytes_read);
+
+ void NotifyStartErrorHelper(const net::URLRequestStatus& status,
+ const std::string& status_message);
- void AsyncNotifyDoneHelper(const net::URLRequestStatus& status,
- const std::string& status_message);
+ // Returns an error code that is passed in through |status| or a new one if an
+ // additional error is found.
+ net::Error NotifyFinishedCaching(net::URLRequestStatus status,
+ const std::string& status_message);
- void NotifyFinishedCaching(net::URLRequestStatus status,
- const std::string& status_message);
+ scoped_ptr<ServiceWorkerResponseReader> CreateCacheResponseReader();
+ scoped_ptr<ServiceWorkerResponseWriter> CreateCacheResponseWriter();
ResourceType resource_type_; // Differentiate main script and imports
scoped_refptr<net::IOBuffer> io_buffer_;
int io_buffer_bytes_;
base::WeakPtr<ServiceWorkerContextCore> context_;
GURL url_;
- int64 response_id_;
- int64 incumbent_response_id_;
+ int64_t resource_id_;
+ int64_t incumbent_resource_id_;
scoped_ptr<net::URLRequest> net_request_;
scoped_ptr<net::HttpResponseInfo> http_info_;
scoped_ptr<ServiceWorkerResponseWriter> writer_;
scoped_refptr<ServiceWorkerVersion> version_;
- scoped_ptr<NetDataConsumer> consumer_;
+ scoped_ptr<ServiceWorkerCacheWriter> cache_writer_;
bool has_been_killed_;
bool did_notify_started_;
bool did_notify_finished_;
+
base::WeakPtrFactory<ServiceWorkerWriteToCacheJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerWriteToCacheJob);
diff --git a/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
index 18115d9b8aa..43881d790d2 100644
--- a/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
@@ -2,7 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -20,7 +25,9 @@
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
+#include "net/test/url_request/url_request_failed_job.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_job.h"
@@ -33,10 +40,10 @@ namespace content {
namespace {
const char kHeaders[] =
- "HTTP/1.1 200 OK\0"
- "Content-Type: text/javascript\0"
- "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-Type: text/javascript\n"
+ "Expires: Thu, 1 Jan 2100 20:00:00 GMT\n"
+ "\n";
const char kScriptCode[] = "// no script code\n";
void EmptyCallback() {
@@ -50,6 +57,7 @@ const int kMiddleBlock = 5;
std::string GenerateLongResponse() {
return std::string(kNumBlocks * kBlockSize, 'a');
}
+
net::URLRequestJob* CreateNormalURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) {
@@ -68,14 +76,22 @@ net::URLRequestJob* CreateResponseJob(const std::string& response_data,
response_data, true);
}
+net::URLRequestJob* CreateFailedURLRequestJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) {
+ return new net::URLRequestFailedJob(request, network_delegate,
+ net::URLRequestFailedJob::START,
+ net::ERR_FAILED);
+}
+
net::URLRequestJob* CreateInvalidMimeTypeJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) {
const char kPlainTextHeaders[] =
- "HTTP/1.1 200 OK\0"
- "Content-Type: text/plain\0"
- "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-Type: text/plain\n"
+ "Expires: Thu, 1 Jan 2100 20:00:00 GMT\n"
+ "\n";
return new net::URLRequestTestJob(
request,
network_delegate,
@@ -265,7 +281,7 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
process_id, MSG_ROUTING_NONE, provider_id,
SERVICE_WORKER_PROVIDER_FOR_WORKER, context()->AsWeakPtr(), nullptr));
base::WeakPtr<ServiceWorkerProviderHost> provider_host = host->AsWeakPtr();
- context()->AddProviderHost(host.Pass());
+ context()->AddProviderHost(std::move(host));
provider_host->running_hosted_version_ = version;
}
@@ -294,15 +310,12 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
REQUEST_CONTEXT_FRAME_TYPE_NONE, scoped_refptr<ResourceRequestBody>());
}
- int NextRenderProcessId() { return next_render_process_id_++; }
int NextProviderId() { return next_provider_id_++; }
int NextVersionId() { return next_version_id_++; }
void SetUp() override {
- int render_process_id = NextRenderProcessId();
int provider_id = NextProviderId();
- helper_.reset(
- new EmbeddedWorkerTestHelper(base::FilePath(), render_process_id));
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
// A new unstored registration/version.
scope_ = GURL("https://host/scope/");
@@ -312,8 +325,9 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
version_ =
new ServiceWorkerVersion(registration_.get(), script_url_,
NextVersionId(), context()->AsWeakPtr());
- CreateHostForVersion(render_process_id, provider_id, version_);
- SetUpScriptRequest(render_process_id, provider_id);
+ CreateHostForVersion(helper_->mock_render_process_id(), provider_id,
+ version_);
+ SetUpScriptRequest(helper_->mock_render_process_id(), provider_id);
context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
base::RunLoop().RunUntilIdle();
@@ -339,7 +353,7 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status());
int incumbent_resource_id =
version_->script_cache_map()->LookupResourceId(script_url_);
- EXPECT_NE(kInvalidServiceWorkerResponseId, incumbent_resource_id);
+ EXPECT_NE(kInvalidServiceWorkerResourceId, incumbent_resource_id);
registration_->SetActiveVersion(version_);
@@ -361,14 +375,14 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
// to the script |response|. Returns the new version.
scoped_refptr<ServiceWorkerVersion> UpdateScript(
const std::string& response) {
- int render_process_id = NextRenderProcessId();
int provider_id = NextProviderId();
scoped_refptr<ServiceWorkerVersion> new_version =
new ServiceWorkerVersion(registration_.get(), script_url_,
NextVersionId(), context()->AsWeakPtr());
- CreateHostForVersion(render_process_id, provider_id, new_version);
+ CreateHostForVersion(helper_->mock_render_process_id(), provider_id,
+ new_version);
- SetUpScriptRequest(render_process_id, provider_id);
+ SetUpScriptRequest(helper_->mock_render_process_id(), provider_id);
mock_protocol_handler_->SetCreateJobCallback(
base::Bind(&CreateResponseJob, response));
request_->Start();
@@ -382,7 +396,7 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
scoped_ptr<ServiceWorkerResponseReader> reader =
context()->storage()->CreateResponseReader(id);
scoped_refptr<ResponseVerifier> verifier = new ResponseVerifier(
- reader.Pass(), expected, CreateReceiverOnCurrentThread(&is_equal));
+ std::move(reader), expected, CreateReceiverOnCurrentThread(&is_equal));
verifier->Start();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(is_equal);
@@ -393,6 +407,9 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
return helper_->context_wrapper();
}
+ // Disables the cache to simulate cache errors.
+ void DisableCache() { context()->storage()->disk_cache()->Disable(); }
+
protected:
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<EmbeddedWorkerTestHelper> helper_;
@@ -411,9 +428,8 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
GURL scope_;
GURL script_url_;
- int next_render_process_id_ = 1224; // dummy value
int next_provider_id_ = 1;
- int64 next_version_id_ = 1L;
+ int64_t next_version_id_ = 1L;
};
TEST_F(ServiceWorkerWriteToCacheJobTest, Normal) {
@@ -422,7 +438,7 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, Normal) {
request_->Start();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status());
- EXPECT_NE(kInvalidServiceWorkerResponseId,
+ EXPECT_NE(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
@@ -433,7 +449,7 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, InvalidMimeType) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
- EXPECT_EQ(kInvalidServiceWorkerResponseId,
+ EXPECT_EQ(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
@@ -444,7 +460,7 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, SSLCertificateError) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
- EXPECT_EQ(kInvalidServiceWorkerResponseId,
+ EXPECT_EQ(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
@@ -455,7 +471,7 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, CertStatusError) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
- EXPECT_EQ(kInvalidServiceWorkerResponseId,
+ EXPECT_EQ(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
@@ -463,7 +479,7 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, Update_SameScript) {
std::string response = GenerateLongResponse();
CreateIncumbent(response);
scoped_refptr<ServiceWorkerVersion> version = UpdateScript(response);
- EXPECT_EQ(kInvalidServiceWorkerResponseId, GetResourceId(version.get()));
+ EXPECT_EQ(kInvalidServiceWorkerResourceId, GetResourceId(version.get()));
}
TEST_F(ServiceWorkerWriteToCacheJobTest, Update_SameSizeScript) {
@@ -570,7 +586,28 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, Update_EmptyScript) {
// Update from empty to empty.
version = UpdateScript(std::string());
- EXPECT_EQ(kInvalidServiceWorkerResponseId, GetResourceId(version.get()));
+ EXPECT_EQ(kInvalidServiceWorkerResourceId, GetResourceId(version.get()));
+}
+
+TEST_F(ServiceWorkerWriteToCacheJobTest, Error) {
+ mock_protocol_handler_->SetCreateJobCallback(
+ base::Bind(&CreateFailedURLRequestJob));
+ request_->Start();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
+ EXPECT_EQ(net::ERR_FAILED, request_->status().error());
+ EXPECT_EQ(kInvalidServiceWorkerResourceId,
+ version_->script_cache_map()->LookupResourceId(script_url_));
+}
+
+TEST_F(ServiceWorkerWriteToCacheJobTest, FailedWriteHeadersToCache) {
+ mock_protocol_handler_->SetCreateJobCallback(
+ base::Bind(&CreateNormalURLRequestJob));
+ DisableCache();
+ request_->Start();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
+ EXPECT_EQ(net::ERR_FAILED, request_->status().error());
}
} // namespace content
diff --git a/chromium/content/browser/session_history_browsertest.cc b/chromium/content/browser/session_history_browsertest.cc
index f2d2e04d051..dca5546570d 100644
--- a/chromium/content/browser/session_history_browsertest.cc
+++ b/chromium/content/browser/session_history_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -39,7 +41,7 @@ scoped_ptr<net::test_server::HttpResponse> HandleEchoTitleRequest(
base::StringPrintf(
"<html><head><title>%s</title></head></html>",
request.content.c_str()));
- return http_response.Pass();
+ return std::move(http_response);
}
} // namespace
@@ -49,7 +51,7 @@ class SessionHistoryTest : public ContentBrowserTest {
SessionHistoryTest() {}
void SetUpOnMainThread() override {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
embedded_test_server()->RegisterRequestHandler(
base::Bind(&HandleEchoTitleRequest, "/echotitle"));
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.cc b/chromium/content/browser/shared_worker/shared_worker_host.cc
index 99c369de2d6..8aefff131ee 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_host.cc
@@ -58,6 +58,7 @@ SharedWorkerHost::SharedWorkerHost(SharedWorkerInstance* instance,
container_render_filter_(filter),
worker_process_id_(filter->render_process_id()),
worker_route_id_(worker_route_id),
+ termination_message_sent_(false),
closed_(false),
creation_time_(base::TimeTicks::Now()),
weak_factory_(this) {
@@ -68,7 +69,7 @@ SharedWorkerHost::~SharedWorkerHost() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
UMA_HISTOGRAM_LONG_TIMES("SharedWorker.TimeToDeleted",
base::TimeTicks::Now() - creation_time_);
- if (!closed_)
+ if (!closed_ && !termination_message_sent_)
NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
SharedWorkerServiceImpl::GetInstance()->NotifyWorkerDestroyed(
worker_process_id_, worker_route_id_);
@@ -100,15 +101,11 @@ void SharedWorkerHost::Start(bool pause_on_start) {
bool SharedWorkerHost::FilterMessage(const IPC::Message& message,
SharedWorkerMessageFilter* filter) {
- if (!instance_)
+ if (!IsAvailable() || !HasFilter(filter, message.routing_id()))
return false;
- if (!closed_ && HasFilter(filter, message.routing_id())) {
- RelayMessage(message, filter);
- return true;
- }
-
- return false;
+ RelayMessage(message, filter);
+ return true;
}
void SharedWorkerHost::FilterShutdown(SharedWorkerMessageFilter* filter) {
@@ -118,7 +115,7 @@ void SharedWorkerHost::FilterShutdown(SharedWorkerMessageFilter* filter) {
worker_document_set_->RemoveAll(filter);
if (worker_document_set_->IsEmpty()) {
// This worker has no more associated documents - shut it down.
- Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
+ TerminateWorker();
}
}
@@ -130,7 +127,7 @@ void SharedWorkerHost::DocumentDetached(SharedWorkerMessageFilter* filter,
worker_document_set_->Remove(filter, document_id);
if (worker_document_set_->IsEmpty()) {
// This worker has no more associated documents - shut it down.
- Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
+ TerminateWorker();
}
}
@@ -141,7 +138,8 @@ void SharedWorkerHost::WorkerContextClosed() {
// being sent to the worker (messages can still be sent from the worker,
// for exception reporting, etc).
closed_ = true;
- NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
+ if (!termination_message_sent_)
+ NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
}
void SharedWorkerHost::WorkerContextDestroyed() {
@@ -267,6 +265,9 @@ void SharedWorkerHost::RelayMessage(
}
void SharedWorkerHost::TerminateWorker() {
+ termination_message_sent_ = true;
+ if (!closed_)
+ NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
}
@@ -287,6 +288,10 @@ SharedWorkerHost::GetRenderFrameIDsForWorker() {
return result;
}
+bool SharedWorkerHost::IsAvailable() const {
+ return instance_ && !termination_message_sent_ && !closed_;
+}
+
void SharedWorkerHost::AddFilter(SharedWorkerMessageFilter* filter,
int route_id) {
CHECK(filter);
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.h b/chromium/content/browser/shared_worker/shared_worker_host.h
index 1a32d12826f..9fb9ca3550a 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.h
+++ b/chromium/content/browser/shared_worker/shared_worker_host.h
@@ -8,6 +8,7 @@
#include <list>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
@@ -85,7 +86,7 @@ class SharedWorkerHost {
}
int process_id() const { return worker_process_id_; }
int worker_route_id() const { return worker_route_id_; }
- bool closed() const { return closed_; }
+ bool IsAvailable() const;
private:
// Unique identifier for a worker client.
@@ -127,6 +128,7 @@ class SharedWorkerHost {
SharedWorkerMessageFilter* container_render_filter_;
int worker_process_id_;
int worker_route_id_;
+ bool termination_message_sent_;
bool closed_;
const base::TimeTicks creation_time_;
diff --git a/chromium/content/browser/shared_worker/shared_worker_instance.cc b/chromium/content/browser/shared_worker/shared_worker_instance.cc
index ea8e02db705..caa3876e63d 100644
--- a/chromium/content/browser/shared_worker/shared_worker_instance.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_instance.cc
@@ -14,13 +14,15 @@ SharedWorkerInstance::SharedWorkerInstance(
const base::string16& content_security_policy,
blink::WebContentSecurityPolicyType security_policy_type,
ResourceContext* resource_context,
- const WorkerStoragePartitionId& partition_id)
+ const WorkerStoragePartitionId& partition_id,
+ blink::WebSharedWorkerCreationContextType creation_context_type)
: url_(url),
name_(name),
content_security_policy_(content_security_policy),
security_policy_type_(security_policy_type),
resource_context_(resource_context),
- partition_id_(partition_id) {
+ partition_id_(partition_id),
+ creation_context_type_(creation_context_type) {
DCHECK(resource_context_);
}
@@ -30,8 +32,8 @@ SharedWorkerInstance::SharedWorkerInstance(const SharedWorkerInstance& other)
content_security_policy_(other.content_security_policy_),
security_policy_type_(other.security_policy_type_),
resource_context_(other.resource_context_),
- partition_id_(other.partition_id_) {
-}
+ partition_id_(other.partition_id_),
+ creation_context_type_(other.creation_context_type_) {}
SharedWorkerInstance::~SharedWorkerInstance() {}
diff --git a/chromium/content/browser/shared_worker/shared_worker_instance.h b/chromium/content/browser/shared_worker/shared_worker_instance.h
index 5d650e5cad9..025da9b8008 100644
--- a/chromium/content/browser/shared_worker/shared_worker_instance.h
+++ b/chromium/content/browser/shared_worker/shared_worker_instance.h
@@ -7,10 +7,10 @@
#include <string>
-#include "base/basictypes.h"
#include "content/browser/shared_worker/worker_storage_partition.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebContentSecurityPolicy.h"
+#include "third_party/WebKit/public/web/WebSharedWorkerCreationContextType.h"
#include "url/gurl.h"
namespace content {
@@ -20,12 +20,14 @@ class ResourceContext;
// the UI thread and be used for comparison in SharedWorkerDevToolsManager.
class CONTENT_EXPORT SharedWorkerInstance {
public:
- SharedWorkerInstance(const GURL& url,
- const base::string16& name,
- const base::string16& content_security_policy,
- blink::WebContentSecurityPolicyType security_policy_type,
- ResourceContext* resource_context,
- const WorkerStoragePartitionId& partition_id);
+ SharedWorkerInstance(
+ const GURL& url,
+ const base::string16& name,
+ const base::string16& content_security_policy,
+ blink::WebContentSecurityPolicyType security_policy_type,
+ ResourceContext* resource_context,
+ const WorkerStoragePartitionId& partition_id,
+ blink::WebSharedWorkerCreationContextType creation_context_type);
SharedWorkerInstance(const SharedWorkerInstance& other);
~SharedWorkerInstance();
@@ -54,6 +56,9 @@ class CONTENT_EXPORT SharedWorkerInstance {
return resource_context_;
}
const WorkerStoragePartitionId& partition_id() const { return partition_id_; }
+ blink::WebSharedWorkerCreationContextType creation_context_type() const {
+ return creation_context_type_;
+ }
private:
const GURL url_;
@@ -62,6 +67,7 @@ class CONTENT_EXPORT SharedWorkerInstance {
const blink::WebContentSecurityPolicyType security_policy_type_;
ResourceContext* const resource_context_;
const WorkerStoragePartitionId partition_id_;
+ const blink::WebSharedWorkerCreationContextType creation_context_type_;
};
} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc b/chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc
index 7811e77af30..c78cb1fe0a5 100644
--- a/chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_instance_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 "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
@@ -47,12 +47,11 @@ class SharedWorkerInstanceTest : public testing::Test {
};
TEST_F(SharedWorkerInstanceTest, MatchesTest) {
- SharedWorkerInstance instance1(GURL("http://example.com/w.js"),
- base::string16(),
- base::string16(),
- blink::WebContentSecurityPolicyTypeReport,
- browser_context_->GetResourceContext(),
- partition_id_);
+ SharedWorkerInstance instance1(
+ GURL("http://example.com/w.js"), base::string16(), base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(), partition_id_,
+ blink::WebSharedWorkerCreationContextTypeNonsecure);
EXPECT_TRUE(Matches(instance1, "http://example.com/w.js", ""));
EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", ""));
EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", ""));
@@ -62,12 +61,11 @@ TEST_F(SharedWorkerInstanceTest, MatchesTest) {
EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", "name"));
EXPECT_FALSE(Matches(instance1, "http://example.net/w2.js", "name"));
- SharedWorkerInstance instance2(GURL("http://example.com/w.js"),
- base::ASCIIToUTF16("name"),
- base::string16(),
- blink::WebContentSecurityPolicyTypeReport,
- browser_context_->GetResourceContext(),
- partition_id_);
+ SharedWorkerInstance instance2(
+ GURL("http://example.com/w.js"), base::ASCIIToUTF16("name"),
+ base::string16(), blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(), partition_id_,
+ blink::WebSharedWorkerCreationContextTypeNonsecure);
EXPECT_FALSE(Matches(instance2, "http://example.com/w.js", ""));
EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", ""));
EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", ""));
diff --git a/chromium/content/browser/shared_worker/shared_worker_message_filter.cc b/chromium/content/browser/shared_worker/shared_worker_message_filter.cc
index 9f75967517c..53f04ba54f4 100644
--- a/chromium/content/browser/shared_worker/shared_worker_message_filter.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_message_filter.cc
@@ -4,17 +4,20 @@
#include "content/browser/shared_worker/shared_worker_message_filter.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "content/browser/message_port_message_filter.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
#include "content/common/devtools_messages.h"
#include "content/common/view_messages.h"
#include "content/common/worker_messages.h"
+#include "third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h"
namespace content {
namespace {
-const uint32 kFilteredMessageClasses[] = {
- ViewMsgStart,
- WorkerMsgStart,
+const uint32_t kFilteredMessageClasses[] = {
+ ViewMsgStart, WorkerMsgStart,
};
} // namespace
@@ -77,18 +80,13 @@ int SharedWorkerMessageFilter::GetNextRoutingID() {
void SharedWorkerMessageFilter::OnCreateWorker(
const ViewHostMsg_CreateWorker_Params& params,
- int* route_id) {
- bool url_error = false;
- *route_id = GetNextRoutingID();
+ ViewHostMsg_CreateWorker_Reply* reply) {
+ reply->route_id = GetNextRoutingID();
SharedWorkerServiceImpl::GetInstance()->CreateWorker(
- params,
- *route_id,
- this,
- resource_context_,
- WorkerStoragePartitionId(partition_),
- &url_error);
- if (url_error)
- *route_id = MSG_ROUTING_NONE;
+ params, reply->route_id, this, resource_context_,
+ WorkerStoragePartitionId(partition_), &reply->error);
+ if (reply->error != blink::WebWorkerCreationErrorNone)
+ reply->route_id = MSG_ROUTING_NONE;
}
void SharedWorkerMessageFilter::OnForwardToWorker(const IPC::Message& message) {
diff --git a/chromium/content/browser/shared_worker/shared_worker_message_filter.h b/chromium/content/browser/shared_worker/shared_worker_message_filter.h
index e283a22f2d9..da0d32ca8ad 100644
--- a/chromium/content/browser/shared_worker/shared_worker_message_filter.h
+++ b/chromium/content/browser/shared_worker/shared_worker_message_filter.h
@@ -5,19 +5,21 @@
#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_MESSAGE_FILTER_H_
+#include "base/macros.h"
#include "content/browser/shared_worker/worker_storage_partition.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
class GURL;
struct ViewHostMsg_CreateWorker_Params;
+struct ViewHostMsg_CreateWorker_Reply;
namespace content {
class MessagePortMessageFilter;
class ResourceContext;
-// If "enable-embedded-shared-worker" is set this class will be used instead of
-// WorkerMessageFilter.
+// Handles SharedWorker related IPC messages for one renderer process by
+// forwarding them to the SharedWorkerServiceImpl singleton.
class CONTENT_EXPORT SharedWorkerMessageFilter : public BrowserMessageFilter {
public:
SharedWorkerMessageFilter(int render_process_id,
@@ -43,7 +45,7 @@ class CONTENT_EXPORT SharedWorkerMessageFilter : public BrowserMessageFilter {
private:
// Message handlers.
void OnCreateWorker(const ViewHostMsg_CreateWorker_Params& params,
- int* route_id);
+ ViewHostMsg_CreateWorker_Reply* reply);
void OnForwardToWorker(const IPC::Message& message);
void OnDocumentDetached(unsigned long long document_id);
void OnWorkerContextClosed(int worker_route_id);
diff --git a/chromium/content/browser/shared_worker/shared_worker_service_impl.cc b/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
index 221c1ddf6a8..46d15bc6e61 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -4,12 +4,15 @@
#include "content/browser/shared_worker/shared_worker_service_impl.h"
+#include <stddef.h>
#include <algorithm>
#include <iterator>
#include <set>
+#include <utility>
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/devtools/shared_worker_devtools_manager.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -127,7 +130,7 @@ class SharedWorkerServiceImpl::SharedWorkerPendingInstance {
explicit SharedWorkerPendingInstance(
scoped_ptr<SharedWorkerInstance> instance)
- : instance_(instance.Pass()) {}
+ : instance_(std::move(instance)) {}
~SharedWorkerPendingInstance() {}
SharedWorkerInstance* instance() { return instance_.get(); }
SharedWorkerInstance* release_instance() { return instance_.release(); }
@@ -284,16 +287,13 @@ void SharedWorkerServiceImpl::CreateWorker(
SharedWorkerMessageFilter* filter,
ResourceContext* resource_context,
const WorkerStoragePartitionId& partition_id,
- bool* url_mismatch) {
+ blink::WebWorkerCreationError* creation_error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- *url_mismatch = false;
- scoped_ptr<SharedWorkerInstance> instance(
- new SharedWorkerInstance(params.url,
- params.name,
- params.content_security_policy,
- params.security_policy_type,
- resource_context,
- partition_id));
+ *creation_error = blink::WebWorkerCreationErrorNone;
+ scoped_ptr<SharedWorkerInstance> instance(new SharedWorkerInstance(
+ params.url, params.name, params.content_security_policy,
+ params.security_policy_type, resource_context, partition_id,
+ params.creation_context_type));
scoped_ptr<SharedWorkerPendingInstance::SharedWorkerPendingRequest> request(
new SharedWorkerPendingInstance::SharedWorkerPendingRequest(
filter,
@@ -303,16 +303,22 @@ void SharedWorkerServiceImpl::CreateWorker(
params.render_frame_route_id));
if (SharedWorkerPendingInstance* pending = FindPendingInstance(*instance)) {
if (params.url != pending->instance()->url()) {
- *url_mismatch = true;
+ *creation_error = blink::WebWorkerCreationErrorURLMismatch;
return;
}
- pending->AddRequest(request.Pass());
+ if (params.creation_context_type !=
+ pending->instance()->creation_context_type()) {
+ *creation_error = blink::WebWorkerCreationErrorSecureContextMismatch;
+ return;
+ }
+ pending->AddRequest(std::move(request));
return;
}
scoped_ptr<SharedWorkerPendingInstance> pending_instance(
- new SharedWorkerPendingInstance(instance.Pass()));
- pending_instance->AddRequest(request.Pass());
- ReserveRenderProcessToCreateWorker(pending_instance.Pass(), url_mismatch);
+ new SharedWorkerPendingInstance(std::move(instance)));
+ pending_instance->AddRequest(std::move(request));
+ ReserveRenderProcessToCreateWorker(std::move(pending_instance),
+ creation_error);
}
void SharedWorkerServiceImpl::ForwardToWorker(
@@ -447,9 +453,8 @@ void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing(
}
std::vector<int> remove_pending_instance_list;
- for (PendingInstaneMap::iterator iter = pending_instances_.begin();
- iter != pending_instances_.end();
- ++iter) {
+ for (PendingInstanceMap::iterator iter = pending_instances_.begin();
+ iter != pending_instances_.end(); ++iter) {
iter->second->RemoveRequest(filter->render_process_id());
if (!iter->second->requests()->size())
remove_pending_instance_list.push_back(iter->first);
@@ -467,11 +472,11 @@ void SharedWorkerServiceImpl::NotifyWorkerDestroyed(int worker_process_id,
void SharedWorkerServiceImpl::ReserveRenderProcessToCreateWorker(
scoped_ptr<SharedWorkerPendingInstance> pending_instance,
- bool* url_mismatch) {
+ blink::WebWorkerCreationError* creation_error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!FindPendingInstance(*pending_instance->instance()));
- if (url_mismatch)
- *url_mismatch = false;
+ if (creation_error)
+ *creation_error = blink::WebWorkerCreationErrorNone;
if (!pending_instance->requests()->size())
return;
int worker_process_id = -1;
@@ -480,8 +485,14 @@ void SharedWorkerServiceImpl::ReserveRenderProcessToCreateWorker(
SharedWorkerHost* host = FindSharedWorkerHost(*pending_instance->instance());
if (host) {
if (pending_instance->instance()->url() != host->instance()->url()) {
- if (url_mismatch)
- *url_mismatch = true;
+ if (creation_error)
+ *creation_error = blink::WebWorkerCreationErrorURLMismatch;
+ return;
+ }
+ if (pending_instance->instance()->creation_context_type() !=
+ host->instance()->creation_context_type()) {
+ if (creation_error)
+ *creation_error = blink::WebWorkerCreationErrorSecureContextMismatch;
return;
}
worker_process_id = host->process_id();
@@ -520,7 +531,7 @@ void SharedWorkerServiceImpl::ReserveRenderProcessToCreateWorker(
worker_route_id,
is_new_worker),
s_try_increment_worker_ref_count_));
- pending_instances_.set(pending_instance_id, pending_instance.Pass());
+ pending_instances_.set(pending_instance_id, std::move(pending_instance));
}
void SharedWorkerServiceImpl::RenderProcessReservedCallback(
@@ -546,7 +557,7 @@ void SharedWorkerServiceImpl::RenderProcessReservedCallback(
// Retry reserving a renderer process if the existed Shared Worker was
// destroyed on IO thread while reserving the renderer process on UI
// thread.
- ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
+ ReserveRenderProcessToCreateWorker(std::move(pending_instance), NULL);
return;
}
pending_instance->RegisterToSharedWorkerHost(existing_host);
@@ -559,7 +570,7 @@ void SharedWorkerServiceImpl::RenderProcessReservedCallback(
pending_instance->RemoveRequest(worker_process_id);
// Retry reserving a renderer process if the requested renderer process was
// destroyed on IO thread while reserving the renderer process on UI thread.
- ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
+ ReserveRenderProcessToCreateWorker(std::move(pending_instance), NULL);
return;
}
scoped_ptr<SharedWorkerHost> host(new SharedWorkerHost(
@@ -569,7 +580,7 @@ void SharedWorkerServiceImpl::RenderProcessReservedCallback(
const base::string16 name = host->instance()->name();
host->Start(pause_on_start);
worker_hosts_.set(std::make_pair(worker_process_id, worker_route_id),
- host.Pass());
+ std::move(host));
FOR_EACH_OBSERVER(
WorkerServiceObserver,
observers_,
@@ -589,7 +600,7 @@ void SharedWorkerServiceImpl::RenderProcessReserveFailedCallback(
return;
pending_instance->RemoveRequest(worker_process_id);
// Retry reserving a renderer process.
- ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
+ ReserveRenderProcessToCreateWorker(std::move(pending_instance), NULL);
}
SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
@@ -605,10 +616,8 @@ SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
iter != worker_hosts_.end();
++iter) {
SharedWorkerHost* host = iter->second;
- if (host->instance() && !host->closed() &&
- host->instance()->Matches(instance)) {
+ if (host->IsAvailable() && host->instance()->Matches(instance))
return iter->second;
- }
}
return NULL;
}
@@ -616,9 +625,8 @@ SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
SharedWorkerServiceImpl::SharedWorkerPendingInstance*
SharedWorkerServiceImpl::FindPendingInstance(
const SharedWorkerInstance& instance) {
- for (PendingInstaneMap::iterator iter = pending_instances_.begin();
- iter != pending_instances_.end();
- ++iter) {
+ for (PendingInstanceMap::iterator iter = pending_instances_.begin();
+ iter != pending_instances_.end(); ++iter) {
if (iter->second->instance()->Matches(instance))
return iter->second;
}
diff --git a/chromium/content/browser/shared_worker/shared_worker_service_impl.h b/chromium/content/browser/shared_worker/shared_worker_service_impl.h
index bba2fbd58d9..7b6bf85f03c 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.h
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.h
@@ -9,11 +9,13 @@
#include "base/compiler_specific.h"
#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/worker_service.h"
+#include "third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h"
struct ViewHostMsg_CreateWorker_Params;
@@ -30,9 +32,8 @@ class ResourceContext;
class WorkerServiceObserver;
class WorkerStoragePartitionId;
-// If "enable-embedded-shared-worker" is set this class will be used instead of
-// WorkerServiceImpl.
-// TODO(horo): implement this class.
+// The implementation of WorkerService. We try to place workers in an existing
+// renderer process when possible.
class CONTENT_EXPORT SharedWorkerServiceImpl
: public NON_EXPORTED_BASE(WorkerService) {
public:
@@ -51,7 +52,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl
SharedWorkerMessageFilter* filter,
ResourceContext* resource_context,
const WorkerStoragePartitionId& partition_id,
- bool* url_mismatch);
+ blink::WebWorkerCreationError* creation_error);
void ForwardToWorker(const IPC::Message& message,
SharedWorkerMessageFilter* filter);
void DocumentDetached(unsigned long long document_id,
@@ -111,7 +112,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl
typedef base::ScopedPtrHashMap<ProcessRouteIdPair,
scoped_ptr<SharedWorkerHost>> WorkerHostMap;
typedef base::ScopedPtrHashMap<int, scoped_ptr<SharedWorkerPendingInstance>>
- PendingInstaneMap;
+ PendingInstanceMap;
SharedWorkerServiceImpl();
~SharedWorkerServiceImpl() override;
@@ -124,7 +125,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl
// will be called on IO thread.
void ReserveRenderProcessToCreateWorker(
scoped_ptr<SharedWorkerPendingInstance> pending_instance,
- bool* url_mismatch);
+ blink::WebWorkerCreationError* creation_error);
// Called after the render process is reserved to create Shared Worker in it.
void RenderProcessReservedCallback(int pending_instance_id,
@@ -164,7 +165,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl
static bool (*s_try_increment_worker_ref_count_)(int);
WorkerHostMap worker_hosts_;
- PendingInstaneMap pending_instances_;
+ PendingInstanceMap pending_instances_;
int next_pending_instance_id_;
base::ObserverList<WorkerServiceObserver> observers_;
diff --git a/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc b/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
index 5c3906853fb..1c7d40905d1 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <map>
#include <set>
#include <vector>
#include "base/atomic_sequence_num.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/string16.h"
@@ -208,7 +210,7 @@ class MockRendererProcessHost {
CHECK(queued_messages_.size());
scoped_ptr<IPC::Message> msg(*queued_messages_.begin());
queued_messages_.weak_erase(queued_messages_.begin());
- return msg.Pass();
+ return msg;
}
void FastShutdownIfPossible() {
@@ -243,7 +245,7 @@ void PostCreateWorker(MockRendererProcessHost* renderer,
const std::string& name,
unsigned long long document_id,
int render_frame_route_id,
- int* connector_route_id) {
+ ViewHostMsg_CreateWorker_Reply* reply) {
ViewHostMsg_CreateWorker_Params params;
params.url = GURL(url);
params.name = base::ASCIIToUTF16(name);
@@ -251,8 +253,10 @@ void PostCreateWorker(MockRendererProcessHost* renderer,
params.security_policy_type = blink::WebContentSecurityPolicyTypeReport;
params.document_id = document_id;
params.render_frame_route_id = render_frame_route_id;
- EXPECT_TRUE(renderer->OnMessageReceived(
- new ViewHostMsg_CreateWorker(params, connector_route_id)));
+ params.creation_context_type =
+ blink::WebSharedWorkerCreationContextTypeSecure;
+ EXPECT_TRUE(
+ renderer->OnMessageReceived(new ViewHostMsg_CreateWorker(params, reply)));
}
class MockSharedWorkerConnector {
@@ -262,8 +266,7 @@ class MockSharedWorkerConnector {
temporary_remote_port_route_id_(0),
remote_port_id_(0),
local_port_route_id_(0),
- local_port_id_(0),
- route_id_(0) {}
+ local_port_id_(0) {}
void Create(const std::string& url,
const std::string& name,
unsigned long long document_id,
@@ -273,12 +276,8 @@ class MockSharedWorkerConnector {
&remote_port_id_,
&local_port_route_id_,
&local_port_id_);
- PostCreateWorker(renderer_host_,
- url,
- name,
- document_id,
- render_frame_route_id,
- &route_id_);
+ PostCreateWorker(renderer_host_, url, name, document_id,
+ render_frame_route_id, &create_worker_reply_);
}
void SendQueueMessages() {
EXPECT_TRUE(renderer_host_->OnMessageReceived(
@@ -294,7 +293,8 @@ class MockSharedWorkerConnector {
void SendConnect() {
EXPECT_TRUE(
renderer_host_->OnMessageReceived(new ViewHostMsg_ForwardToWorker(
- WorkerMsg_Connect(route_id_, remote_port_id_, MSG_ROUTING_NONE))));
+ WorkerMsg_Connect(create_worker_reply_.route_id, remote_port_id_,
+ MSG_ROUTING_NONE))));
}
void SendSendQueuedMessages(
const std::vector<QueuedMessage>& queued_messages) {
@@ -308,7 +308,10 @@ class MockSharedWorkerConnector {
int remote_port_id() { return remote_port_id_; }
int local_port_route_id() { return local_port_route_id_; }
int local_port_id() { return local_port_id_; }
- int route_id() { return route_id_; }
+ int route_id() { return create_worker_reply_.route_id; }
+ blink::WebWorkerCreationError creation_error() {
+ return create_worker_reply_.error;
+ }
private:
MockRendererProcessHost* renderer_host_;
@@ -316,7 +319,7 @@ class MockSharedWorkerConnector {
int remote_port_id_;
int local_port_route_id_;
int local_port_id_;
- int route_id_;
+ ViewHostMsg_CreateWorker_Reply create_worker_reply_;
};
void CheckWorkerProcessMsgCreateWorker(
@@ -731,6 +734,8 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest) {
kDocumentIDs[1],
kRenderFrameRouteIDs[1]);
EXPECT_EQ(MSG_ROUTING_NONE, connector1->route_id());
+ EXPECT_EQ(blink::WebWorkerCreationErrorURLMismatch,
+ connector1->creation_error());
EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
RunAllPendingInMessageLoop();
EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
diff --git a/chromium/content/browser/shared_worker/worker_browsertest.cc b/chromium/content/browser/shared_worker/worker_browsertest.cc
index 0a9c34cd8d9..553d129916b 100644
--- a/chromium/content/browser/shared_worker/worker_browsertest.cc
+++ b/chromium/content/browser/shared_worker/worker_browsertest.cc
@@ -10,6 +10,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/test/test_timeouts.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/common/content_paths.h"
@@ -22,6 +23,8 @@
#include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
#include "net/base/escape.h"
#include "net/base/test_data_directory.h"
+#include "net/ssl/ssl_server_config.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "url/gurl.h"
@@ -141,8 +144,8 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, IncognitoSharedWorkers) {
// Make sure that auth dialog is displayed from worker context.
// http://crbug.com/33344
IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerHttpAuth) {
- ASSERT_TRUE(test_server()->Start());
- GURL url = test_server()->GetURL("files/workers/worker_auth.html");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL("/workers/worker_auth.html");
NavigateAndWaitForAuth(url);
}
@@ -158,24 +161,24 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, SharedWorkerHttpAuth) {
if (!SupportsSharedWorker())
return;
- ASSERT_TRUE(test_server()->Start());
- GURL url = test_server()->GetURL("files/workers/shared_worker_auth.html");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL("/workers/shared_worker_auth.html");
NavigateAndWaitForAuth(url);
}
// Tests that TLS client auth prompts for normal workers.
IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerTlsClientAuth) {
// Launch HTTPS server.
- net::SpawnedTestServer::SSLOptions ssl_options;
- ssl_options.request_client_certificate = true;
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
+ net::SSLServerConfig ssl_config;
+ ssl_config.require_client_cert = true;
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
ASSERT_TRUE(https_server.Start());
RunTest("worker_tls_client_auth.html",
- "url=" +
- net::EscapeQueryParamValue(https_server.GetURL("").spec(), true));
+ "url=" + net::EscapeQueryParamValue(https_server.GetURL("/").spec(),
+ true));
EXPECT_EQ(1, select_certificate_count());
}
@@ -186,16 +189,16 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, SharedWorkerTlsClientAuth) {
return;
// Launch HTTPS server.
- net::SpawnedTestServer::SSLOptions ssl_options;
- ssl_options.request_client_certificate = true;
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
+ net::SSLServerConfig ssl_config;
+ ssl_config.require_client_cert = true;
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
ASSERT_TRUE(https_server.Start());
RunTest("worker_tls_client_auth.html",
- "shared=true&url=" +
- net::EscapeQueryParamValue(https_server.GetURL("").spec(), true));
+ "shared=true&url=" + net::EscapeQueryParamValue(
+ https_server.GetURL("/").spec(), true));
EXPECT_EQ(0, select_certificate_count());
}
diff --git a/chromium/content/browser/shared_worker/worker_document_set.h b/chromium/content/browser/shared_worker/worker_document_set.h
index 54ae9e93daa..e7ed2779a19 100644
--- a/chromium/content/browser/shared_worker/worker_document_set.h
+++ b/chromium/content/browser/shared_worker/worker_document_set.h
@@ -7,7 +7,6 @@
#include <set>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
namespace content {
diff --git a/chromium/content/browser/signed_certificate_timestamp_store_impl.h b/chromium/content/browser/signed_certificate_timestamp_store_impl.h
index 3b669707a2c..099cf7a5b80 100644
--- a/chromium/content/browser/signed_certificate_timestamp_store_impl.h
+++ b/chromium/content/browser/signed_certificate_timestamp_store_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_SIGNED_CERTIFICATE_TIMESTAMP_STORE_IMPL_H_
#define CONTENT_BROWSER_SIGNED_CERTIFICATE_TIMESTAMP_STORE_IMPL_H_
+#include "base/macros.h"
#include "content/browser/renderer_data_memoizing_store.h"
#include "content/public/browser/signed_certificate_timestamp_store.h"
#include "net/cert/signed_certificate_timestamp.h"
diff --git a/chromium/content/browser/site_instance_impl.cc b/chromium/content/browser/site_instance_impl.cc
index cd5ac038b4b..9f88bafc19e 100644
--- a/chromium/content/browser/site_instance_impl.cc
+++ b/chromium/content/browser/site_instance_impl.cc
@@ -7,6 +7,7 @@
#include "content/browser/browsing_instance.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/debug_urls.h"
+#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/site_isolation_policy.h"
@@ -20,7 +21,7 @@ namespace content {
const RenderProcessHostFactory*
SiteInstanceImpl::g_render_process_host_factory_ = NULL;
-int32 SiteInstanceImpl::next_site_instance_id_ = 1;
+int32_t SiteInstanceImpl::next_site_instance_id_ = 1;
SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance)
: id_(next_site_instance_id_++),
@@ -45,7 +46,7 @@ SiteInstanceImpl::~SiteInstanceImpl() {
static_cast<SiteInstance*>(this));
}
-int32 SiteInstanceImpl::GetId() {
+int32_t SiteInstanceImpl::GetId() {
return id_;
}
@@ -213,7 +214,17 @@ bool SiteInstanceImpl::HasWrongProcessForURL(const GURL& url) {
bool SiteInstanceImpl::RequiresDedicatedProcess() {
if (!has_site_)
return false;
- return SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(site_);
+ return SiteInstanceImpl::DoesSiteRequireDedicatedProcess(GetBrowserContext(),
+ site_);
+}
+
+void SiteInstanceImpl::IncrementActiveFrameCount() {
+ active_frame_count_++;
+}
+
+void SiteInstanceImpl::DecrementActiveFrameCount() {
+ if (--active_frame_count_ == 0)
+ FOR_EACH_OBSERVER(Observer, observers_, ActiveFrameCountIsZero(this));
}
void SiteInstanceImpl::IncrementRelatedActiveContentsCount() {
@@ -224,6 +235,14 @@ void SiteInstanceImpl::DecrementRelatedActiveContentsCount() {
browsing_instance_->decrement_active_contents_count();
}
+void SiteInstanceImpl::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void SiteInstanceImpl::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
void SiteInstanceImpl::set_render_process_host_factory(
const RenderProcessHostFactory* rph_factory) {
g_render_process_host_factory_ = rph_factory;
@@ -233,12 +252,12 @@ BrowserContext* SiteInstanceImpl::GetBrowserContext() const {
return browsing_instance_->browser_context();
}
-/*static*/
+// static
SiteInstance* SiteInstance::Create(BrowserContext* browser_context) {
return new SiteInstanceImpl(new BrowsingInstance(browser_context));
}
-/*static*/
+// static
SiteInstance* SiteInstance::CreateForURL(BrowserContext* browser_context,
const GURL& url) {
// This will create a new SiteInstance and BrowsingInstance.
@@ -247,7 +266,7 @@ SiteInstance* SiteInstance::CreateForURL(BrowserContext* browser_context,
return instance->GetSiteInstanceForURL(url);
}
-/*static*/
+// static
bool SiteInstance::IsSameWebSite(BrowserContext* browser_context,
const GURL& real_src_url,
const GURL& real_dest_url) {
@@ -287,7 +306,7 @@ bool SiteInstance::IsSameWebSite(BrowserContext* browser_context,
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
}
-/*static*/
+// static
GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
const GURL& real_url) {
// TODO(fsamuel, creis): For some reason appID is not recognized as a host.
@@ -332,25 +351,55 @@ GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
return GURL();
}
-/*static*/
+// static
GURL SiteInstanceImpl::GetEffectiveURL(BrowserContext* browser_context,
const GURL& url) {
return GetContentClient()->browser()->
GetEffectiveURL(browser_context, url);
}
+// static
+bool SiteInstanceImpl::DoesSiteRequireDedicatedProcess(
+ BrowserContext* browser_context,
+ const GURL& effective_url) {
+ // If --site-per-process is enabled, site isolation is enabled everywhere.
+ if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites())
+ return true;
+
+ // Let the content embedder enable site isolation for specific URLs.
+ if (GetContentClient()->IsSupplementarySiteIsolationModeEnabled() &&
+ GetContentClient()->browser()->DoesSiteRequireDedicatedProcess(
+ browser_context, effective_url)) {
+ return true;
+ }
+
+ return false;
+}
+
void SiteInstanceImpl::RenderProcessHostDestroyed(RenderProcessHost* host) {
DCHECK_EQ(process_, host);
process_->RemoveObserver(this);
process_ = NULL;
}
+void SiteInstanceImpl::RenderProcessWillExit(RenderProcessHost* host) {
+ // TODO(nick): http://crbug.com/575400 - RenderProcessWillExit might not serve
+ // any purpose here.
+ FOR_EACH_OBSERVER(Observer, observers_, RenderProcessGone(this));
+}
+
+void SiteInstanceImpl::RenderProcessExited(RenderProcessHost* host,
+ base::TerminationStatus status,
+ int exit_code) {
+ FOR_EACH_OBSERVER(Observer, observers_, RenderProcessGone(this));
+}
+
void SiteInstanceImpl::LockToOrigin() {
// TODO(nick): When all sites are isolated, this operation provides strong
// protection. If only some sites are isolated, we need additional logic to
// prevent the non-isolated sites from requesting resources for isolated
// sites. https://crbug.com/509125
- if (SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(site_)) {
+ if (RequiresDedicatedProcess()) {
// Guest processes cannot be locked to its site because guests always have
// a fixed SiteInstance. The site of GURLs a guest loads doesn't match that
// SiteInstance. So we skip locking the guest process to the site.
diff --git a/chromium/content/browser/site_instance_impl.h b/chromium/content/browser/site_instance_impl.h
index 8c4b8ed650b..b54de7f5886 100644
--- a/chromium/content/browser/site_instance_impl.h
+++ b/chromium/content/browser/site_instance_impl.h
@@ -5,6 +5,11 @@
#ifndef CONTENT_BROWSER_SITE_INSTANCE_IMPL_H_
#define CONTENT_BROWSER_SITE_INSTANCE_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/render_process_host_observer.h"
@@ -18,8 +23,18 @@ class RenderProcessHostFactory;
class CONTENT_EXPORT SiteInstanceImpl : public SiteInstance,
public RenderProcessHostObserver {
public:
+ class Observer {
+ public:
+ // Called when this SiteInstance transitions to having no active frames,
+ // as measured by active_frame_count().
+ virtual void ActiveFrameCountIsZero(SiteInstanceImpl* site_instance) = 0;
+
+ // Called when the renderer process of this SiteInstance has exited.
+ virtual void RenderProcessGone(SiteInstanceImpl* site_instance) = 0;
+ };
+
// SiteInstance interface overrides.
- int32 GetId() override;
+ int32_t GetId() override;
bool HasProcess() const override;
RenderProcessHost* GetProcess() override;
BrowserContext* GetBrowserContext() const override;
@@ -49,12 +64,13 @@ class CONTENT_EXPORT SiteInstanceImpl : public SiteInstance,
// Increase the number of active frames in this SiteInstance. This is
// increased when a frame is created, or a currently swapped out frame
// is swapped in.
- void increment_active_frame_count() { active_frame_count_++; }
+ void IncrementActiveFrameCount();
// Decrease the number of active frames in this SiteInstance. This is
// decreased when a frame is destroyed, or a currently active frame is
- // swapped out.
- void decrement_active_frame_count() { active_frame_count_--; }
+ // swapped out. Decrementing this to zero will notify observers, and may
+ // trigger deletion of proxies.
+ void DecrementActiveFrameCount();
// Get the number of active frames which belong to this SiteInstance. If
// there are no active frames left, all frames in this SiteInstance can be
@@ -69,6 +85,9 @@ class CONTENT_EXPORT SiteInstanceImpl : public SiteInstance,
// that, unlike active_frame_count, this does not count pending RFHs.
void DecrementRelatedActiveContentsCount();
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
// Sets the global factory used to create new RenderProcessHosts. It may be
// NULL, in which case the default RenderProcessHost will be created (this is
// the behavior if you don't call this function). The factory must be set
@@ -85,6 +104,15 @@ class CONTENT_EXPORT SiteInstanceImpl : public SiteInstance,
static GURL GetEffectiveURL(BrowserContext* browser_context,
const GURL& url);
+ // Returns true if pages loaded from |effective_url| ought to be handled only
+ // by a renderer process isolated from other sites. If --site-per-process is
+ // on the command line, this is true for all sites. In other site isolation
+ // modes, only a subset of sites will require dedicated processes.
+ //
+ // |effective_url| must be an effective URL.
+ static bool DoesSiteRequireDedicatedProcess(BrowserContext* browser_context,
+ const GURL& effective_url);
+
protected:
friend class BrowsingInstance;
friend class SiteInstance;
@@ -100,6 +128,10 @@ class CONTENT_EXPORT SiteInstanceImpl : public SiteInstance,
private:
// RenderProcessHostObserver implementation.
void RenderProcessHostDestroyed(RenderProcessHost* host) override;
+ void RenderProcessWillExit(RenderProcessHost* host) override;
+ void RenderProcessExited(RenderProcessHost* host,
+ base::TerminationStatus status,
+ int exit_code) override;
// Used to restrict a process' origin access rights.
void LockToOrigin();
@@ -108,10 +140,10 @@ class CONTENT_EXPORT SiteInstanceImpl : public SiteInstance,
static const RenderProcessHostFactory* g_render_process_host_factory_;
// The next available SiteInstance ID.
- static int32 next_site_instance_id_;
+ static int32_t next_site_instance_id_;
// A unique ID for this SiteInstance.
- int32 id_;
+ int32_t id_;
// The number of active frames in this SiteInstance.
size_t active_frame_count_;
@@ -131,6 +163,8 @@ class CONTENT_EXPORT SiteInstanceImpl : public SiteInstance,
// Whether SetSite has been called.
bool has_site_;
+ base::ObserverList<Observer, true> observers_;
+
DISALLOW_COPY_AND_ASSIGN(SiteInstanceImpl);
};
diff --git a/chromium/content/browser/site_instance_impl_unittest.cc b/chromium/content/browser/site_instance_impl_unittest.cc
index e37b410fbf7..b632d74a19b 100644
--- a/chromium/content/browser/site_instance_impl_unittest.cc
+++ b/chromium/content/browser/site_instance_impl_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_vector.h"
diff --git a/chromium/content/browser/site_per_process_browsertest.cc b/chromium/content/browser/site_per_process_browsertest.cc
index 8a907d52d7d..08f4c26bcb8 100644
--- a/chromium/content/browser/site_per_process_browsertest.cc
+++ b/chromium/content/browser/site_per_process_browsertest.cc
@@ -4,16 +4,22 @@
#include "content/browser/site_per_process_browsertest.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <algorithm>
#include <vector>
#include "base/command_line.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/pattern.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/test_timeouts.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/cross_process_frame_connector.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/navigator.h"
@@ -24,9 +30,12 @@
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
+#include "content/common/view_messages.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
+#include "content/public/browser/resource_dispatcher_host.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -40,6 +49,7 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "ui/gfx/switches.h"
namespace content {
@@ -96,6 +106,161 @@ void NavigateNamedFrame(const ToRenderFrameHost& caller_frame,
EXPECT_TRUE(success);
}
+// Helper function to generate a click on the given RenderWidgetHost. The
+// mouse event is forwarded directly to the RenderWidgetHost without any
+// hit-testing.
+void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) {
+ blink::WebMouseEvent mouse_event;
+ mouse_event.type = blink::WebInputEvent::MouseDown;
+ mouse_event.button = blink::WebPointerProperties::ButtonLeft;
+ mouse_event.x = x;
+ mouse_event.y = y;
+ rwh->ForwardMouseEvent(mouse_event);
+}
+
+class RenderWidgetHostMouseEventMonitor {
+ public:
+ explicit RenderWidgetHostMouseEventMonitor(RenderWidgetHost* host)
+ : host_(host), event_received_(false) {
+ host_->AddMouseEventCallback(
+ base::Bind(&RenderWidgetHostMouseEventMonitor::MouseEventCallback,
+ base::Unretained(this)));
+ }
+ ~RenderWidgetHostMouseEventMonitor() {
+ host_->RemoveMouseEventCallback(
+ base::Bind(&RenderWidgetHostMouseEventMonitor::MouseEventCallback,
+ base::Unretained(this)));
+ }
+ bool EventWasReceived() const { return event_received_; }
+ void ResetEventReceived() { event_received_ = false; }
+ const blink::WebMouseEvent& event() const { return event_; }
+
+ private:
+ bool MouseEventCallback(const blink::WebMouseEvent& event) {
+ event_received_ = true;
+ event_ = event;
+ return false;
+ }
+ RenderWidgetHost* host_;
+ bool event_received_;
+ blink::WebMouseEvent event_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostMouseEventMonitor);
+};
+
+// Helper function that performs a surface hittest.
+void SurfaceHitTestTestHelper(
+ Shell* shell,
+ net::test_server::EmbeddedTestServer* embedded_test_server) {
+ if (!UseSurfacesEnabled())
+ return;
+
+ GURL main_url(embedded_test_server->GetURL(
+ "/frame_tree/page_with_positioned_frame.html"));
+ NavigateToURL(shell, main_url);
+
+ // It is safe to obtain the root frame tree node here, as it doesn't change.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1U, root->child_count());
+
+ FrameTreeNode* child_node = root->child_at(0);
+ GURL site_url(embedded_test_server->GetURL("baz.com", "/title1.html"));
+ EXPECT_EQ(site_url, child_node->current_url());
+ EXPECT_NE(shell->web_contents()->GetSiteInstance(),
+ child_node->current_frame_host()->GetSiteInstance());
+
+ // Create listeners for mouse events.
+ RenderWidgetHostMouseEventMonitor main_frame_monitor(
+ root->current_frame_host()->GetRenderWidgetHost());
+ RenderWidgetHostMouseEventMonitor child_frame_monitor(
+ child_node->current_frame_host()->GetRenderWidgetHost());
+
+ RenderWidgetHostInputEventRouter* router =
+ static_cast<WebContentsImpl*>(shell->web_contents())
+ ->GetInputEventRouter();
+
+ RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
+ root->current_frame_host()->GetRenderWidgetHost()->GetView());
+ RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
+ child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+ // We need to wait for a compositor frame from the child frame, at which
+ // point its surface will be created.
+ while (rwhv_child->RendererFrameNumber() <= 0) {
+ // TODO(lazyboy): Find a better way to avoid sleeping like this. See
+ // http://crbug.com/405282 for details.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(10));
+ run_loop.Run();
+ }
+
+ uint32_t cur_render_frame_number = root_view->RendererFrameNumber();
+
+ // Target input event to child frame.
+ blink::WebMouseEvent child_event;
+ child_event.type = blink::WebInputEvent::MouseDown;
+ child_event.button = blink::WebPointerProperties::ButtonLeft;
+ child_event.x = 75;
+ child_event.y = 75;
+ child_event.clickCount = 1;
+ main_frame_monitor.ResetEventReceived();
+ child_frame_monitor.ResetEventReceived();
+ router->RouteMouseEvent(root_view, &child_event);
+
+ while (!child_frame_monitor.EventWasReceived()) {
+ // This is working around a big synchronization problem. It is very
+ // difficult to know if we have received a compositor frame from the
+ // main frame renderer *after* it received the child frame's surface
+ // ID. Hit testing won't work until this happens. So if the hit test
+ // fails then we wait for another frame to arrive and try again.
+ // TODO(kenrb): We need a better way to do all of this, possibly coming
+ // from http://crbug.com/405282.
+ while (root_view->RendererFrameNumber() <= cur_render_frame_number) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(10));
+ run_loop.Run();
+ }
+ cur_render_frame_number = root_view->RendererFrameNumber();
+ child_event.type = blink::WebInputEvent::MouseDown;
+ child_event.button = blink::WebPointerProperties::ButtonLeft;
+ child_event.x = 75;
+ child_event.y = 75;
+ child_event.clickCount = 1;
+ main_frame_monitor.ResetEventReceived();
+ child_frame_monitor.ResetEventReceived();
+ router->RouteMouseEvent(root_view, &child_event);
+ }
+
+ EXPECT_TRUE(child_frame_monitor.EventWasReceived());
+ EXPECT_EQ(23, child_frame_monitor.event().x);
+ EXPECT_EQ(23, child_frame_monitor.event().y);
+ EXPECT_FALSE(main_frame_monitor.EventWasReceived());
+
+ child_frame_monitor.ResetEventReceived();
+ main_frame_monitor.ResetEventReceived();
+
+ // Target input event to main frame.
+ blink::WebMouseEvent main_event;
+ main_event.type = blink::WebInputEvent::MouseDown;
+ main_event.button = blink::WebPointerProperties::ButtonLeft;
+ main_event.x = 1;
+ main_event.y = 1;
+ main_event.clickCount = 1;
+ // Ladies and gentlemen, THIS is the main_event!
+ router->RouteMouseEvent(root_view, &main_event);
+
+ EXPECT_FALSE(child_frame_monitor.EventWasReceived());
+ EXPECT_TRUE(main_frame_monitor.EventWasReceived());
+ EXPECT_EQ(1, main_frame_monitor.event().x);
+ EXPECT_EQ(1, main_frame_monitor.event().y);
+}
+
class RedirectNotificationObserver : public NotificationObserver {
public:
// Register to listen for notifications of the given type from either a
@@ -223,6 +388,62 @@ void RenderFrameHostCreatedObserver::RenderFrameCreated(
}
}
+// This observer is used to wait for its owner FrameTreeNode to become focused.
+class FrameFocusedObserver : public FrameTreeNode::Observer {
+ public:
+ FrameFocusedObserver(FrameTreeNode* owner)
+ : owner_(owner), message_loop_runner_(new MessageLoopRunner) {
+ owner->AddObserver(this);
+ }
+
+ ~FrameFocusedObserver() override { owner_->RemoveObserver(this); }
+
+ void Wait() { message_loop_runner_->Run(); }
+
+ private:
+ // FrameTreeNode::Observer
+ void OnFrameTreeNodeFocused(FrameTreeNode* node) override {
+ if (node == owner_)
+ message_loop_runner_->Quit();
+ }
+
+ FrameTreeNode* owner_;
+ scoped_refptr<MessageLoopRunner> message_loop_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameFocusedObserver);
+};
+
+// This observer is used to wait for its owner FrameTreeNode to become deleted.
+class FrameDeletedObserver : public FrameTreeNode::Observer {
+ public:
+ FrameDeletedObserver(FrameTreeNode* owner)
+ : owner_(owner), message_loop_runner_(new MessageLoopRunner) {
+ owner->AddObserver(this);
+ }
+
+ void Wait() { message_loop_runner_->Run(); }
+
+ private:
+ // FrameTreeNode::Observer
+ void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override {
+ if (node == owner_)
+ message_loop_runner_->Quit();
+ }
+
+ FrameTreeNode* owner_;
+ scoped_refptr<MessageLoopRunner> message_loop_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameDeletedObserver);
+};
+
+// Helper function to focus a frame by sending it a mouse click and then
+// waiting for it to become focused.
+void FocusFrame(FrameTreeNode* frame) {
+ FrameFocusedObserver focus_observer(frame);
+ SimulateMouseClick(frame->current_frame_host()->GetRenderWidgetHost(), 1, 1);
+ focus_observer.Wait();
+}
+
// A WebContentsDelegate that catches messages sent to the console.
class ConsoleObserverDelegate : public WebContentsDelegate {
public:
@@ -235,9 +456,9 @@ class ConsoleObserverDelegate : public WebContentsDelegate {
~ConsoleObserverDelegate() override {}
bool AddMessageToConsole(WebContents* source,
- int32 level,
+ int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id) override;
std::string message() { return message_; }
@@ -261,9 +482,9 @@ void ConsoleObserverDelegate::Wait() {
bool ConsoleObserverDelegate::AddMessageToConsole(
WebContents* source,
- int32 level,
+ int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id) {
DCHECK(source == web_contents_);
@@ -292,6 +513,49 @@ class SwapoutACKMessageFilter : public BrowserMessageFilter {
DISALLOW_COPY_AND_ASSIGN(SwapoutACKMessageFilter);
};
+class RenderWidgetHostVisibilityObserver : public NotificationObserver {
+ public:
+ explicit RenderWidgetHostVisibilityObserver(RenderWidgetHostImpl* rwhi,
+ bool expected_visibility_state)
+ : expected_visibility_state_(expected_visibility_state),
+ was_observed_(false),
+ did_fail_(false),
+ source_(rwhi) {
+ registrar_.Add(this, NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
+ source_);
+ message_loop_runner_ = new MessageLoopRunner;
+ }
+
+ bool WaitUntilSatisfied() {
+ if (!was_observed_)
+ message_loop_runner_->Run();
+ registrar_.Remove(this, NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
+ source_);
+ return !did_fail_;
+ }
+
+ private:
+ void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) override {
+ was_observed_ = true;
+ did_fail_ = expected_visibility_state_ !=
+ (*static_cast<const Details<bool>&>(details).ptr());
+ if (message_loop_runner_->loop_running())
+ message_loop_runner_->Quit();
+ }
+
+ RenderWidgetHostImpl* render_widget_host_;
+ bool expected_visibility_state_;
+ scoped_refptr<MessageLoopRunner> message_loop_runner_;
+ NotificationRegistrar registrar_;
+ bool was_observed_;
+ bool did_fail_;
+ Source<RenderWidgetHost> source_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostVisibilityObserver);
+};
+
} // namespace
//
@@ -312,10 +576,27 @@ void SitePerProcessBrowserTest::SetUpCommandLine(
void SitePerProcessBrowserTest::SetUpOnMainThread() {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
SetupCrossSiteRedirector(embedded_test_server());
}
+//
+// SitePerProcessHighDPIBrowserTest
+//
+
+
+class SitePerProcessHighDPIBrowserTest : public SitePerProcessBrowserTest {
+ public:
+ SitePerProcessHighDPIBrowserTest() {}
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ SitePerProcessBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
+ base::StringPrintf("2"));
+ }
+};
+
// Ensure that navigating subframes in --site-per-process mode works and the
// correct documents are committed.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
@@ -385,7 +666,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
// The out-of-process iframe should have its own RenderWidgetHost,
// independent of any RenderViewHost.
EXPECT_NE(
- rvh->GetView(),
+ rvh->GetWidget()->GetView(),
proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());
EXPECT_TRUE(child->current_frame_host()->GetRenderWidgetHost());
@@ -429,7 +710,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
EXPECT_EQ(proxy_to_parent, child->render_manager()->GetProxyToParent());
EXPECT_TRUE(proxy_to_parent->cross_process_frame_connector());
EXPECT_NE(
- child->current_frame_host()->render_view_host()->GetView(),
+ child->current_frame_host()->render_view_host()->GetWidget()->GetView(),
proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());
EXPECT_TRUE(child->current_frame_host()->GetRenderWidgetHost());
@@ -445,144 +726,31 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
DepictFrameTree(root));
}
-class RenderWidgetHostMouseEventMonitor {
- public:
- RenderWidgetHostMouseEventMonitor(RenderWidgetHost* host)
- : host_(host), event_received(false) {
- host_->AddMouseEventCallback(
- base::Bind(&RenderWidgetHostMouseEventMonitor::MouseEventCallback,
- base::Unretained(this)));
- }
- ~RenderWidgetHostMouseEventMonitor() {
- host_->RemoveMouseEventCallback(
- base::Bind(&RenderWidgetHostMouseEventMonitor::MouseEventCallback,
- base::Unretained(this)));
- }
- bool EventWasReceived() { return event_received; }
- void ResetEventReceived() { event_received = false; }
- const blink::WebMouseEvent& event() const { return event_; }
-
- private:
- bool MouseEventCallback(const blink::WebMouseEvent& event) {
- event_received = true;
- event_ = event;
- return false;
- }
- RenderWidgetHost* host_;
- bool event_received;
- blink::WebMouseEvent event_;
-};
-
// Test that mouse events are being routed to the correct RenderWidgetHostView
// based on coordinates.
-#if defined(OS_ANDROID) || defined(THREAD_SANITIZER) || defined(OS_LINUX)
+#if defined(OS_ANDROID)
// Browser process hit testing is not implemented on Android.
// https://crbug.com/491334
-// Test fails under TSAN, see https://crbug.com/527618
-// Test is flaky under Linux, see https://crbug.com/528189
#define MAYBE_SurfaceHitTestTest DISABLED_SurfaceHitTestTest
#else
#define MAYBE_SurfaceHitTestTest SurfaceHitTestTest
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_SurfaceHitTestTest) {
- if (!UseSurfacesEnabled())
- return;
-
- GURL main_url(embedded_test_server()->GetURL(
- "/frame_tree/page_with_positioned_frame.html"));
- NavigateToURL(shell(), main_url);
-
- // It is safe to obtain the root frame tree node here, as it doesn't change.
- FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()
- ->root();
- ASSERT_EQ(1U, root->child_count());
-
- FrameTreeNode* child_node = root->child_at(0);
- GURL site_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
- EXPECT_EQ(site_url, child_node->current_url());
- EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
- child_node->current_frame_host()->GetSiteInstance());
-
- // Create listeners for mouse events.
- RenderWidgetHostMouseEventMonitor main_frame_monitor(
- root->current_frame_host()->GetRenderWidgetHost());
- RenderWidgetHostMouseEventMonitor child_frame_monitor(
- child_node->current_frame_host()->GetRenderWidgetHost());
-
- RenderWidgetHostInputEventRouter* router =
- static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetInputEventRouter();
-
- RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
- root->current_frame_host()->GetRenderWidgetHost()->GetView());
- RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
- child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
-
- // We need to wait for a compositor frame from the child frame, at which
- // point its surface will be created.
- while (rwhv_child->RendererFrameNumber() <= 0) {
- // TODO(lazyboy): Find a better way to avoid sleeping like this. See
- // http://crbug.com/405282 for details.
- base::RunLoop run_loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMilliseconds(10));
- run_loop.Run();
- }
-
- uint32_t cur_render_frame_number = root_view->RendererFrameNumber();
-
- // Target input event to child frame.
- blink::WebMouseEvent child_event;
- child_event.type = blink::WebInputEvent::MouseDown;
- child_event.button = blink::WebPointerProperties::ButtonLeft;
- child_event.x = 75;
- child_event.y = 75;
- child_event.clickCount = 1;
- router->RouteMouseEvent(root_view, &child_event);
-
- if (!child_frame_monitor.EventWasReceived()) {
- main_frame_monitor.ResetEventReceived();
- // This is working around a big synchronization problem. It is very
- // difficult to know if we have received a compositor frame from the
- // main frame renderer *after* it received the child frame's surface
- // ID. Hit testing won't work until this happens. So if the hit test
- // fails then we wait for another frame to arrive and try again.
- // TODO(kenrb): We need a better way to do all of this, possibly coming
- // from http://crbug.com/405282.
- while (root_view->RendererFrameNumber() <= cur_render_frame_number) {
- base::RunLoop run_loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMilliseconds(10));
- run_loop.Run();
- }
- router->RouteMouseEvent(root_view, &child_event);
- }
-
- EXPECT_TRUE(child_frame_monitor.EventWasReceived());
- EXPECT_EQ(23, child_frame_monitor.event().x);
- EXPECT_EQ(23, child_frame_monitor.event().y);
- EXPECT_FALSE(main_frame_monitor.EventWasReceived());
-
- child_frame_monitor.ResetEventReceived();
- main_frame_monitor.ResetEventReceived();
-
- // Target input event to main frame.
- blink::WebMouseEvent main_event;
- main_event.type = blink::WebInputEvent::MouseDown;
- main_event.button = blink::WebPointerProperties::ButtonLeft;
- main_event.x = 1;
- main_event.y = 1;
- main_event.clickCount = 1;
- // Ladies and gentlemen, THIS is the main_event!
- router->RouteMouseEvent(root_view, &main_event);
+ SurfaceHitTestTestHelper(shell(), embedded_test_server());
+}
- EXPECT_FALSE(child_frame_monitor.EventWasReceived());
- EXPECT_TRUE(main_frame_monitor.EventWasReceived());
- EXPECT_EQ(1, main_frame_monitor.event().x);
- EXPECT_EQ(1, main_frame_monitor.event().y);
+// Same test as above, but runs in high-dpi mode.
+#if defined(OS_ANDROID) || defined(OS_WIN)
+// Browser process hit testing is not implemented on Android.
+// https://crbug.com/491334
+// Windows is disabled because of https://crbug.com/545547.
+#define MAYBE_HighDPISurfaceHitTestTest DISABLED_SurfaceHitTestTest
+#else
+#define MAYBE_HighDPISurfaceHitTestTest SurfaceHitTestTest
+#endif
+IN_PROC_BROWSER_TEST_F(SitePerProcessHighDPIBrowserTest,
+ MAYBE_HighDPISurfaceHitTestTest) {
+ SurfaceHitTestTestHelper(shell(), embedded_test_server());
}
// Tests OOPIF rendering by checking that the RWH of the iframe generates
@@ -1486,20 +1654,15 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CreateProxiesForNewFrames) {
// TODO(nasko): Disable this test until out-of-process iframes is ready and the
// security checks are back in place.
-// TODO(creis): Replace SpawnedTestServer with host_resolver to get test to run
-// on Android (http://crbug.com/187570).
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DISABLED_CrossSiteIframeRedirectOnce) {
- ASSERT_TRUE(test_server()->Start());
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS,
- net::SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server.Start());
- GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
- GURL http_url(test_server()->GetURL("files/title1.html"));
- GURL https_url(https_server.GetURL("files/title1.html"));
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
+ GURL http_url(embedded_test_server()->GetURL("/title1.html"));
+ GURL https_url(https_server.GetURL("/title1.html"));
NavigateToURL(shell(), main_url);
@@ -1507,8 +1670,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load cross-site client-redirect page into Iframe.
// Should be blocked.
- GURL client_redirect_https_url(https_server.GetURL(
- "client-redirect?files/title1.html"));
+ GURL client_redirect_https_url(
+ https_server.GetURL("/client-redirect?/title1.html"));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
client_redirect_https_url));
// DidFailProvisionalLoad when navigating to client_redirect_https_url.
@@ -1519,8 +1682,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load cross-site server-redirect page into Iframe,
// which redirects to same-site page.
- GURL server_redirect_http_url(https_server.GetURL(
- "server-redirect?" + http_url.spec()));
+ GURL server_redirect_http_url(
+ https_server.GetURL("/server-redirect?" + http_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
server_redirect_http_url));
EXPECT_EQ(observer.last_navigation_url(), http_url);
@@ -1530,8 +1693,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load cross-site server-redirect page into Iframe,
// which redirects to cross-site page.
- GURL server_redirect_http_url(https_server.GetURL(
- "server-redirect?files/title1.html"));
+ GURL server_redirect_http_url(
+ https_server.GetURL("/server-redirect?/title1.html"));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
server_redirect_http_url));
// DidFailProvisionalLoad when navigating to https_url.
@@ -1542,8 +1705,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load same-site server-redirect page into Iframe,
// which redirects to cross-site page.
- GURL server_redirect_http_url(test_server()->GetURL(
- "server-redirect?" + https_url.spec()));
+ GURL server_redirect_http_url(
+ embedded_test_server()->GetURL("/server-redirect?" + https_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
server_redirect_http_url));
@@ -1554,8 +1717,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load same-site client-redirect page into Iframe,
// which redirects to cross-site page.
- GURL client_redirect_http_url(test_server()->GetURL(
- "client-redirect?" + https_url.spec()));
+ GURL client_redirect_http_url(
+ embedded_test_server()->GetURL("/client-redirect?" + https_url.spec()));
RedirectNotificationObserver load_observer2(
NOTIFICATION_LOAD_STOP,
@@ -1578,8 +1741,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load same-site server-redirect page into Iframe,
// which redirects to same-site page.
- GURL server_redirect_http_url(test_server()->GetURL(
- "server-redirect?files/title1.html"));
+ GURL server_redirect_http_url(
+ embedded_test_server()->GetURL("/server-redirect?/title1.html"));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
server_redirect_http_url));
EXPECT_EQ(observer.last_navigation_url(), http_url);
@@ -1589,8 +1752,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load same-site client-redirect page into Iframe,
// which redirects to same-site page.
- GURL client_redirect_http_url(test_server()->GetURL(
- "client-redirect?" + http_url.spec()));
+ GURL client_redirect_http_url(
+ embedded_test_server()->GetURL("/client-redirect?" + http_url.spec()));
RedirectNotificationObserver load_observer2(
NOTIFICATION_LOAD_STOP,
Source<NavigationController>(
@@ -1612,20 +1775,15 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// TODO(nasko): Disable this test until out-of-process iframes is ready and the
// security checks are back in place.
-// TODO(creis): Replace SpawnedTestServer with host_resolver to get test to run
-// on Android (http://crbug.com/187570).
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DISABLED_CrossSiteIframeRedirectTwice) {
- ASSERT_TRUE(test_server()->Start());
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS,
- net::SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server.Start());
- GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
- GURL http_url(test_server()->GetURL("files/title1.html"));
- GURL https_url(https_server.GetURL("files/title1.html"));
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
+ GURL http_url(embedded_test_server()->GetURL("/title1.html"));
+ GURL https_url(https_server.GetURL("/title1.html"));
NavigateToURL(shell(), main_url);
@@ -1633,10 +1791,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load client-redirect page pointing to a cross-site client-redirect page,
// which eventually redirects back to same-site page.
- GURL client_redirect_https_url(https_server.GetURL(
- "client-redirect?" + http_url.spec()));
- GURL client_redirect_http_url(test_server()->GetURL(
- "client-redirect?" + client_redirect_https_url.spec()));
+ GURL client_redirect_https_url(
+ https_server.GetURL("/client-redirect?" + http_url.spec()));
+ GURL client_redirect_http_url(embedded_test_server()->GetURL(
+ "/client-redirect?" + client_redirect_https_url.spec()));
// We should wait until second client redirect get cancelled.
RedirectNotificationObserver load_observer2(
@@ -1656,10 +1814,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load server-redirect page pointing to a cross-site server-redirect page,
// which eventually redirect back to same-site page.
- GURL server_redirect_https_url(https_server.GetURL(
- "server-redirect?" + http_url.spec()));
- GURL server_redirect_http_url(test_server()->GetURL(
- "server-redirect?" + server_redirect_https_url.spec()));
+ GURL server_redirect_https_url(
+ https_server.GetURL("/server-redirect?" + http_url.spec()));
+ GURL server_redirect_http_url(embedded_test_server()->GetURL(
+ "/server-redirect?" + server_redirect_https_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
server_redirect_http_url));
EXPECT_EQ(observer.last_navigation_url(), http_url);
@@ -1669,10 +1827,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load server-redirect page pointing to a cross-site server-redirect page,
// which eventually redirects back to cross-site page.
- GURL server_redirect_https_url(https_server.GetURL(
- "server-redirect?" + https_url.spec()));
- GURL server_redirect_http_url(test_server()->GetURL(
- "server-redirect?" + server_redirect_https_url.spec()));
+ GURL server_redirect_https_url(
+ https_server.GetURL("/server-redirect?" + https_url.spec()));
+ GURL server_redirect_http_url(embedded_test_server()->GetURL(
+ "/server-redirect?" + server_redirect_https_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
server_redirect_http_url));
@@ -1684,10 +1842,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
// Load server-redirect page pointing to a cross-site client-redirect page,
// which eventually redirects back to same-site page.
- GURL client_redirect_http_url(https_server.GetURL(
- "client-redirect?" + http_url.spec()));
- GURL server_redirect_http_url(test_server()->GetURL(
- "server-redirect?" + client_redirect_http_url.spec()));
+ GURL client_redirect_http_url(
+ https_server.GetURL("/client-redirect?" + http_url.spec()));
+ GURL server_redirect_http_url(embedded_test_server()->GetURL(
+ "/server-redirect?" + client_redirect_http_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
server_redirect_http_url));
@@ -1742,9 +1900,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// message loop, so no IPCs that alter the frame tree can be processed.
FrameTreeNode* child = root->child_at(1);
SiteInstance* site = NULL;
- bool browser_side_navigation =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation);
+ bool browser_side_navigation = IsBrowserSideNavigationEnabled();
std::string cross_site_rfh_type =
browser_side_navigation ? "speculative" : "pending";
{
@@ -1836,6 +1992,181 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
}
}
+// Verify that "scrolling" property on frame elements propagates to child frames
+// correctly.
+// Does not work on android since android has scrollbars overlayed.
+#if defined(OS_ANDROID)
+#define MAYBE_FrameOwnerPropertiesPropagationScrolling \
+ DISABLED_FrameOwnerPropertiesPropagationScrolling
+#else
+#define MAYBE_FrameOwnerPropertiesPropagationScrolling \
+ FrameOwnerPropertiesPropagationScrolling
+#endif
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ MAYBE_FrameOwnerPropertiesPropagationScrolling) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/frame_owner_properties_scrolling.html"));
+ NavigateToURL(shell(), main_url);
+
+ // It is safe to obtain the root frame tree node here, as it doesn't change.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1u, root->child_count());
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child = root->child_at(0);
+
+ // If the available client width within the iframe is smaller than the
+ // frame element's width, we assume there's a scrollbar.
+ // Also note that just comparing clientHeight and scrollHeight of the frame's
+ // document will not work.
+ auto has_scrollbar = [](RenderFrameHostImpl* rfh) {
+ int client_width;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(rfh,
+ "window.domAutomationController.send(document.body.clientWidth);",
+ &client_width));
+ const int kFrameElementWidth = 200;
+ return client_width < kFrameElementWidth;
+ };
+
+ auto set_scrolling_property = [](RenderFrameHostImpl* parent_rfh,
+ const std::string& value) {
+ EXPECT_TRUE(ExecuteScript(
+ parent_rfh,
+ base::StringPrintf(
+ "document.getElementById('child-1').setAttribute("
+ " 'scrolling', '%s');", value.c_str())));
+ };
+
+ // Run the test over variety of parent/child cases.
+ GURL urls[] = {
+ // Remote to remote.
+ embedded_test_server()->GetURL("c.com", "/tall_page.html"),
+ // Remote to local.
+ embedded_test_server()->GetURL("a.com", "/tall_page.html"),
+ // Local to remote.
+ embedded_test_server()->GetURL("b.com", "/tall_page.html")
+ };
+ const std::string scrolling_values[] = {
+ "yes", "auto", "no"
+ };
+
+ for (size_t i = 0; i < arraysize(scrolling_values); ++i) {
+ bool expect_scrollbar = scrolling_values[i] != "no";
+ set_scrolling_property(root->current_frame_host(), scrolling_values[i]);
+ for (size_t j = 0; j < arraysize(urls); ++j) {
+ NavigateFrameToURL(child, urls[j]);
+
+ // TODO(alexmos): This can be removed once TestFrameNavigationObserver is
+ // fixed to use DidFinishLoad.
+ EXPECT_TRUE(WaitForRenderFrameReady(child->current_frame_host()));
+
+ EXPECT_EQ(expect_scrollbar, has_scrollbar(child->current_frame_host()));
+ }
+ }
+}
+
+// Verify that "marginwidth" and "marginheight" properties on frame elements
+// propagate to child frames correctly.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ FrameOwnerPropertiesPropagationMargin) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/frame_owner_properties_margin.html"));
+ NavigateToURL(shell(), main_url);
+
+ // It is safe to obtain the root frame tree node here, as it doesn't change.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1u, root->child_count());
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child = root->child_at(0);
+
+ std::string margin_width;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ child->current_frame_host(),
+ "window.domAutomationController.send("
+ "document.body.getAttribute('marginwidth'));",
+ &margin_width));
+ EXPECT_EQ("10", margin_width);
+
+ std::string margin_height;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ child->current_frame_host(),
+ "window.domAutomationController.send("
+ "document.body.getAttribute('marginheight'));",
+ &margin_height));
+ EXPECT_EQ("50", margin_height);
+
+ // Run the test over variety of parent/child cases.
+ GURL urls[] = {
+ // Remote to remote.
+ embedded_test_server()->GetURL("c.com", "/title2.html"),
+ // Remote to local.
+ embedded_test_server()->GetURL("a.com", "/title1.html"),
+ // Local to remote.
+ embedded_test_server()->GetURL("b.com", "/title2.html")
+ };
+
+ int current_margin_width = 15;
+ int current_margin_height = 25;
+
+ // Before each navigation, we change the marginwidth and marginheight
+ // properties of the frame. We then check whether those properties are applied
+ // correctly after the navigation has completed.
+ for (size_t i = 0; i < arraysize(urls); ++i) {
+ // Change marginwidth and marginheight before navigating.
+ EXPECT_TRUE(ExecuteScript(
+ root->current_frame_host(),
+ base::StringPrintf(
+ "document.getElementById('child-1').setAttribute("
+ " 'marginwidth', '%d');", current_margin_width)));
+ EXPECT_TRUE(ExecuteScript(
+ root->current_frame_host(),
+ base::StringPrintf(
+ "document.getElementById('child-1').setAttribute("
+ " 'marginheight', '%d');", current_margin_height)));
+
+ NavigateFrameToURL(child, urls[i]);
+ // TODO(alexmos): This can be removed once TestFrameNavigationObserver is
+ // fixed to use DidFinishLoad.
+ EXPECT_TRUE(WaitForRenderFrameReady(child->current_frame_host()));
+
+ std::string actual_margin_width;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ child->current_frame_host(),
+ "window.domAutomationController.send("
+ "document.body.getAttribute('marginwidth'));",
+ &actual_margin_width));
+ EXPECT_EQ(base::IntToString(current_margin_width), actual_margin_width);
+
+ std::string actual_margin_height;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ child->current_frame_host(),
+ "window.domAutomationController.send("
+ "document.body.getAttribute('marginheight'));",
+ &actual_margin_height));
+ EXPECT_EQ(base::IntToString(current_margin_height), actual_margin_height);
+
+ current_margin_width += 5;
+ current_margin_height += 10;
+ }
+}
+
// Verify origin replication with an A-embed-B-embed-C-embed-A hierarchy.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, OriginReplication) {
GURL main_url(embedded_test_server()->GetURL(
@@ -2526,8 +2857,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, OriginUpdatesReachProxies) {
" parent.frames['frame2'].location.href = 'data:text/html,foo');"));
console_delegate->Wait();
- std::string frame_origin =
- root->child_at(1)->current_replication_state().origin.Serialize();
+ std::string frame_origin = root->child_at(1)->current_origin().Serialize();
EXPECT_EQ(frame_origin + "/", frame_url.GetOrigin().spec());
EXPECT_TRUE(
base::MatchPattern(console_delegate->message(), "*" + frame_origin + "*"))
@@ -3390,8 +3720,16 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// delay the SwapOut ACK from the A->B navigation, so that the second B->A
// navigation is initiated before the first page receives the SwapOut ACK.
// Ensure that the RVH(A) that's pending deletion is not reused in that case.
+// crbug.com/554825
+#if defined(THREAD_SANITIZER)
+#define MAYBE_RenderViewHostPendingDeletionIsNotReused \
+ DISABLED_RenderViewHostPendingDeletionIsNotReused
+#else
+#define MAYBE_RenderViewHostPendingDeletionIsNotReused \
+ RenderViewHostPendingDeletionIsNotReused
+#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
- RenderViewHostPendingDeletionIsNotReused) {
+ MAYBE_RenderViewHostPendingDeletionIsNotReused) {
GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
NavigateToURL(shell(), a_url);
@@ -3480,14 +3818,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DOMMessageQueue msg_queue;
// Click on the cross-process subframe.
- blink::WebMouseEvent mouse_event;
- mouse_event.type = blink::WebInputEvent::MouseDown;
- mouse_event.button = blink::WebPointerProperties::ButtonLeft;
- mouse_event.x = 1;
- mouse_event.y = 1;
- RenderWidgetHost* rwh_child =
- root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
- rwh_child->ForwardMouseEvent(mouse_event);
+ SimulateMouseClick(
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
// Check that the main frame lost focus and fired blur event on the input
// text field.
@@ -3501,7 +3833,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
// Click on the root frame.
- shell()->web_contents()->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
+ SimulateMouseClick(
+ shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
// Check that the subframe lost focus and fired blur event on its
// document's body.
@@ -3514,4 +3847,902 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
}
+// Check that when a cross-process subframe is focused, its parent's
+// document.activeElement correctly returns the corresponding <iframe> element.
+// The test sets up an A-embed-B-embed-C page and shifts focus A->B->A->C,
+// checking document.activeElement after each change.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DocumentActiveElement) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B C\n"
+ " +--Site B ------- proxies for A C\n"
+ " +--Site C -- proxies for A B\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/\n"
+ " C = http://c.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child = root->child_at(0);
+ FrameTreeNode* grandchild = root->child_at(0)->child_at(0);
+
+ // The main frame should be focused to start with.
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+ // Focus the b.com frame.
+ FocusFrame(child);
+ EXPECT_EQ(child, root->frame_tree()->GetFocusedFrame());
+
+ // Helper function to check a property of document.activeElement in the
+ // specified frame.
+ auto verify_active_element_property = [](RenderFrameHost* rfh,
+ const std::string& property,
+ const std::string& expected_value) {
+ std::string script = base::StringPrintf(
+ "window.domAutomationController.send(document.activeElement.%s);",
+ property.c_str());
+ std::string result;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(rfh, script, &result));
+ EXPECT_EQ(expected_value, base::ToLowerASCII(result));
+ };
+
+ // Verify that document.activeElement on main frame points to the <iframe>
+ // element for the b.com frame.
+ RenderFrameHost* root_rfh = root->current_frame_host();
+ verify_active_element_property(root_rfh, "tagName", "iframe");
+ verify_active_element_property(root_rfh, "src", child->current_url().spec());
+
+ // Focus the a.com main frame again.
+ FocusFrame(root);
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+ // Main frame document's <body> should now be the active element.
+ verify_active_element_property(root_rfh, "tagName", "body");
+
+ // Now shift focus from main frame to c.com frame.
+ FocusFrame(grandchild);
+
+ // Check document.activeElement in main frame. It should still point to
+ // <iframe> for the b.com frame, since Blink computes the focused iframe
+ // element by walking the parent chain of the focused frame until it hits the
+ // current frame. This logic should still work with remote frames.
+ verify_active_element_property(root_rfh, "tagName", "iframe");
+ verify_active_element_property(root_rfh, "src", child->current_url().spec());
+
+ // Check document.activeElement in b.com subframe. It should point to
+ // <iframe> for the c.com frame. This is a tricky case where B needs to find
+ // out that focus changed from one remote frame to another (A to C).
+ RenderFrameHost* child_rfh = child->current_frame_host();
+ verify_active_element_property(child_rfh, "tagName", "iframe");
+ verify_active_element_property(child_rfh, "src",
+ grandchild->current_url().spec());
+}
+
+// Check that document.hasFocus() works properly with out-of-process iframes.
+// The test builds a page with four cross-site frames and then focuses them one
+// by one, checking the value of document.hasFocus() in all frames. For any
+// given focused frame, document.hasFocus() should return true for that frame
+// and all its ancestor frames.
+// Disabled due to flakes; see https://crbug.com/559273.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DISABLED_DocumentHasFocus) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(c),d)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B C D\n"
+ " |--Site B ------- proxies for A C D\n"
+ " | +--Site C -- proxies for A B D\n"
+ " +--Site D ------- proxies for A B C\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/\n"
+ " C = http://c.com/\n"
+ " D = http://d.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child1 = root->child_at(0);
+ FrameTreeNode* child2 = root->child_at(1);
+ FrameTreeNode* grandchild = root->child_at(0)->child_at(0);
+
+ // Helper function to check document.hasFocus() for a given frame.
+ auto document_has_focus = [](FrameTreeNode* node) {
+ bool hasFocus = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ node->current_frame_host(),
+ "window.domAutomationController.send(document.hasFocus())",
+ &hasFocus));
+ return hasFocus;
+ };
+
+ // The main frame should be focused to start with.
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+ EXPECT_TRUE(document_has_focus(root));
+ EXPECT_FALSE(document_has_focus(child1));
+ EXPECT_FALSE(document_has_focus(grandchild));
+ EXPECT_FALSE(document_has_focus(child2));
+
+ FocusFrame(child1);
+ EXPECT_EQ(child1, root->frame_tree()->GetFocusedFrame());
+
+ EXPECT_TRUE(document_has_focus(root));
+ EXPECT_TRUE(document_has_focus(child1));
+ EXPECT_FALSE(document_has_focus(grandchild));
+ EXPECT_FALSE(document_has_focus(child2));
+
+ FocusFrame(grandchild);
+ EXPECT_EQ(grandchild, root->frame_tree()->GetFocusedFrame());
+
+ EXPECT_TRUE(document_has_focus(root));
+ EXPECT_TRUE(document_has_focus(child1));
+ EXPECT_TRUE(document_has_focus(grandchild));
+ EXPECT_FALSE(document_has_focus(child2));
+
+ FocusFrame(child2);
+ EXPECT_EQ(child2, root->frame_tree()->GetFocusedFrame());
+
+ EXPECT_TRUE(document_has_focus(root));
+ EXPECT_FALSE(document_has_focus(child1));
+ EXPECT_FALSE(document_has_focus(grandchild));
+ EXPECT_TRUE(document_has_focus(child2));
+}
+
+// Check that window.focus works for cross-process subframes.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SubframeWindowFocus) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B C\n"
+ " |--Site B ------- proxies for A C\n"
+ " +--Site C ------- proxies for A B\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/\n"
+ " C = http://c.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child1 = root->child_at(0);
+ FrameTreeNode* child2 = root->child_at(1);
+
+ // The main frame should be focused to start with.
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+ DOMMessageQueue msg_queue;
+
+ // Register focus and blur events that will send messages when each frame's
+ // window gets or loses focus.
+ const char kSetupFocusEvents[] =
+ "window.addEventListener('focus', function() {"
+ " domAutomationController.setAutomationId(0);"
+ " domAutomationController.send('%s-got-focus');"
+ "});"
+ "window.addEventListener('blur', function() {"
+ " domAutomationController.setAutomationId(0);"
+ " domAutomationController.send('%s-lost-focus');"
+ "});";
+ std::string script = base::StringPrintf(kSetupFocusEvents, "main", "main");
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(), script));
+ script = base::StringPrintf(kSetupFocusEvents, "child1", "child1");
+ EXPECT_TRUE(ExecuteScript(child1->current_frame_host(), script));
+ script = base::StringPrintf(kSetupFocusEvents, "child2", "child2");
+ EXPECT_TRUE(ExecuteScript(child2->current_frame_host(), script));
+
+ // Execute window.focus on the B subframe from the A main frame.
+ EXPECT_TRUE(ExecuteScript(root->current_frame_host(), "frames[0].focus()"));
+
+ // Helper to wait for two specified messages to arrive on the specified
+ // DOMMessageQueue, assuming that the two messages can arrive in any order.
+ auto wait_for_two_messages = [](DOMMessageQueue* msg_queue,
+ const std::string& msg1,
+ const std::string& msg2) {
+ bool msg1_received = false;
+ bool msg2_received = false;
+ std::string status;
+ while (msg_queue->WaitForMessage(&status)) {
+ if (status == msg1)
+ msg1_received = true;
+ if (status == msg2)
+ msg2_received = true;
+ if (msg1_received && msg2_received)
+ break;
+ }
+ };
+
+ // Process A should fire a blur event, and process B should fire a focus
+ // event. Wait for both events.
+ wait_for_two_messages(&msg_queue, "\"main-lost-focus\"",
+ "\"child1-got-focus\"");
+
+ // The B subframe should now be focused in the browser process.
+ EXPECT_EQ(child1, root->frame_tree()->GetFocusedFrame());
+
+ // Now, execute window.focus on the C subframe from A main frame. This
+ // checks that we can shift focus from one remote frame to another.
+ EXPECT_TRUE(ExecuteScript(root->current_frame_host(), "frames[1].focus()"));
+
+ // Wait for the two subframes (B and C) to fire blur and focus events.
+ wait_for_two_messages(&msg_queue, "\"child1-lost-focus\"",
+ "\"child2-got-focus\"");
+
+ // The C subframe should now be focused.
+ EXPECT_EQ(child2, root->frame_tree()->GetFocusedFrame());
+
+ // window.focus the main frame from the C subframe.
+ EXPECT_TRUE(ExecuteScript(child2->current_frame_host(), "parent.focus()"));
+
+ // Wait for the C subframe to blur and main frame to focus.
+ wait_for_two_messages(&msg_queue, "\"child2-lost-focus\"",
+ "\"main-got-focus\"");
+
+ // The main frame should now be focused.
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+}
+
+// There are no cursors on Android.
+#if !defined(OS_ANDROID)
+class CursorMessageFilter : public content::BrowserMessageFilter {
+ public:
+ CursorMessageFilter()
+ : content::BrowserMessageFilter(ViewMsgStart),
+ message_loop_runner_(new content::MessageLoopRunner),
+ last_set_cursor_routing_id_(MSG_ROUTING_NONE) {}
+
+ bool OnMessageReceived(const IPC::Message& message) override {
+ if (message.type() == ViewHostMsg_SetCursor::ID) {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&CursorMessageFilter::OnSetCursor, this,
+ message.routing_id()));
+ }
+ return false;
+ }
+
+ void OnSetCursor(int routing_id) {
+ last_set_cursor_routing_id_ = routing_id;
+ message_loop_runner_->Quit();
+ }
+
+ int last_set_cursor_routing_id() const { return last_set_cursor_routing_id_; }
+
+ void Wait() {
+ last_set_cursor_routing_id_ = MSG_ROUTING_NONE;
+ message_loop_runner_->Run();
+ }
+
+ private:
+ ~CursorMessageFilter() override {}
+
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
+ int last_set_cursor_routing_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(CursorMessageFilter);
+};
+
+// Verify that we receive a mouse cursor update message when we mouse over
+// a text field contained in an out-of-process iframe.
+// Fails under TSan. http://crbug.com/545237
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ DISABLED_CursorUpdateFromReceivedFromCrossSiteIframe) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "/frame_tree/page_with_positioned_frame.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ FrameTreeNode* child_node = root->child_at(0);
+ EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
+ child_node->current_frame_host()->GetSiteInstance());
+
+ scoped_refptr<CursorMessageFilter> filter = new CursorMessageFilter();
+ child_node->current_frame_host()->GetProcess()->AddFilter(filter.get());
+
+ // Send a MouseMove to the subframe. The frame contains text, and moving the
+ // mouse over it should cause the renderer to send a mouse cursor update.
+ blink::WebMouseEvent mouse_event;
+ mouse_event.type = blink::WebInputEvent::MouseMove;
+ mouse_event.x = 60;
+ mouse_event.y = 60;
+ RenderWidgetHost* rwh_child =
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
+ RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
+ root->current_frame_host()->GetRenderWidgetHost()->GetView());
+ static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetInputEventRouter()
+ ->RouteMouseEvent(root_view, &mouse_event);
+
+ // CursorMessageFilter::Wait() implicitly tests whether we receive a
+ // ViewHostMsg_SetCursor message from the renderer process, because it does
+ // does not return otherwise.
+ filter->Wait();
+ EXPECT_EQ(filter->last_set_cursor_routing_id(), rwh_child->GetRoutingID());
+}
+#endif
+
+// Tests that we are using the correct RenderFrameProxy when navigating an
+// opener window.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, OpenerSetLocation) {
+ // Navigate the main window.
+ GURL main_url(embedded_test_server()->GetURL("/title1.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), main_url);
+
+ // Load cross-site page into a new window.
+ GURL cross_url = embedded_test_server()->GetURL("foo.com", "/title1.html");
+ Shell* popup = OpenPopup(shell()->web_contents(), cross_url, "");
+ EXPECT_EQ(popup->web_contents()->GetLastCommittedURL(), cross_url);
+
+ // Use new window to navigate main window.
+ std::string script =
+ "window.opener.location.href = '" + cross_url.spec() + "'";
+ EXPECT_TRUE(ExecuteScript(popup->web_contents(), script));
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
+}
+
+// Ensure that a cross-process subframe can receive keyboard events when in
+// focus.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ SubframeKeyboardEventRouting) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/frame_tree/page_with_one_frame.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ FrameTreeNode* root = web_contents->GetFrameTree()->root();
+
+ GURL frame_url(
+ embedded_test_server()->GetURL("b.com", "/page_with_input_field.html"));
+ NavigateFrameToURL(root->child_at(0), frame_url);
+ EXPECT_TRUE(WaitForRenderFrameReady(root->child_at(0)->current_frame_host()));
+
+ // Focus the subframe and then its input field. The return value
+ // "input-focus" will be sent once the input field's focus event fires.
+ FocusFrame(root->child_at(0));
+ std::string result;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ root->child_at(0)->current_frame_host(), "focusInputField()", &result));
+ EXPECT_EQ(result, "input-focus");
+
+ // The subframe should now be focused.
+ EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
+
+ // Generate a few keyboard events and route them to currently focused frame.
+ SimulateKeyPress(web_contents, ui::VKEY_F, false, false, false, false);
+ SimulateKeyPress(web_contents, ui::VKEY_O, false, false, false, false);
+ SimulateKeyPress(web_contents, ui::VKEY_O, false, false, false, false);
+
+ // Verify that the input field in the subframe received the keystrokes.
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ root->child_at(0)->current_frame_host(),
+ "window.domAutomationController.send(getInputFieldText());", &result));
+ EXPECT_EQ("FOO", result);
+}
+
+// Ensure that sequential focus navigation (advancing focused elements with
+// <tab> and <shift-tab>) works across cross-process subframes.
+// The test sets up six inputs fields in a page with two cross-process
+// subframes:
+// child1 child2
+// /------------\ /------------\.
+// | 2. <input> | | 4. <input> |
+// 1. <input> | 3. <input> | | 5. <input> | 6. <input>
+// \------------/ \------------/.
+//
+// The test then presses <tab> six times to cycle through focused elements 1-6.
+// The test then repeats this with <shift-tab> to cycle in reverse order.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SequentialFocusNavigation) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ WebContents* contents = shell()->web_contents();
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();
+
+ // Assign a name to each frame. This will be sent along in test messages
+ // from focus events.
+ EXPECT_TRUE(ExecuteScript(root->current_frame_host(),
+ "window.name = 'root';"));
+ EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(),
+ "window.name = 'child1';"));
+ EXPECT_TRUE(ExecuteScript(root->child_at(1)->current_frame_host(),
+ "window.name = 'child2';"));
+
+ // This script will insert two <input> fields in the document, one at the
+ // beginning and one at the end. For root frame, this means that we will
+ // have an <input>, then two <iframe> elements, then another <input>.
+ std::string script =
+ "function onFocus(e) {"
+ " domAutomationController.setAutomationId(0);"
+ " domAutomationController.send(window.name + '-focused-' + e.target.id);"
+ "}"
+ "var input1 = document.createElement('input');"
+ "input1.id = 'input1';"
+ "var input2 = document.createElement('input');"
+ "input2.id = 'input2';"
+ "document.body.insertBefore(input1, document.body.firstChild);"
+ "document.body.appendChild(input2);"
+ "input1.addEventListener('focus', onFocus, false);"
+ "input2.addEventListener('focus', onFocus, false);";
+
+ // Add two input fields to each of the three frames.
+ EXPECT_TRUE(ExecuteScript(root->current_frame_host(), script));
+ EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script));
+ EXPECT_TRUE(ExecuteScript(root->child_at(1)->current_frame_host(), script));
+
+ // Helper to simulate a tab press and wait for a focus message.
+ auto press_tab_and_wait_for_message = [contents](bool reverse) {
+ DOMMessageQueue msg_queue;
+ std::string reply;
+ SimulateKeyPress(contents, ui::VKEY_TAB, false, reverse /* shift */, false,
+ false);
+ EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
+ return reply;
+ };
+
+ // Press <tab> six times to focus each of the <input> elements in turn.
+ EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(false));
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+ EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(false));
+ EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
+ EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(false));
+ EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(false));
+ EXPECT_EQ(root->child_at(1), root->frame_tree()->GetFocusedFrame());
+ EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(false));
+ EXPECT_EQ("\"root-focused-input2\"", press_tab_and_wait_for_message(false));
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+ // Now, press <shift-tab> to navigate focus in the reverse direction.
+ EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(true));
+ EXPECT_EQ(root->child_at(1), root->frame_tree()->GetFocusedFrame());
+ EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(true));
+ EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true));
+ EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
+ EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(true));
+ EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true));
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+}
+
+// A WebContentsDelegate to capture ContextMenu creation events.
+class ContextMenuObserverDelegate : public WebContentsDelegate {
+ public:
+ ContextMenuObserverDelegate()
+ : context_menu_created_(false),
+ message_loop_runner_(new MessageLoopRunner) {}
+
+ ~ContextMenuObserverDelegate() override {}
+
+ bool HandleContextMenu(const content::ContextMenuParams& params) override {
+ context_menu_created_ = true;
+ menu_params_ = params;
+ message_loop_runner_->Quit();
+ return true;
+ }
+
+ ContextMenuParams getParams() { return menu_params_; }
+
+ void Wait() {
+ if (!context_menu_created_)
+ message_loop_runner_->Run();
+ context_menu_created_ = false;
+ }
+
+ private:
+ bool context_menu_created_;
+ ContextMenuParams menu_params_;
+
+ // The MessageLoopRunner used to spin the message loop.
+ scoped_refptr<MessageLoopRunner> message_loop_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContextMenuObserverDelegate);
+};
+
+// Test that a mouse right-click to an out-of-process iframe causes a context
+// menu to be generated with the correct screen position.
+#if defined(OS_ANDROID)
+// Browser process hit testing is not implemented on Android.
+// https://crbug.com/491334
+#define MAYBE_CreateContextMenuTest DISABLED_CreateContextMenuTest
+#else
+#define MAYBE_CreateContextMenuTest CreateContextMenuTest
+#endif
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_CreateContextMenuTest) {
+ if (!UseSurfacesEnabled())
+ return;
+
+ GURL main_url(embedded_test_server()->GetURL(
+ "/frame_tree/page_with_positioned_frame.html"));
+ NavigateToURL(shell(), main_url);
+
+ // It is safe to obtain the root frame tree node here, as it doesn't change.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1U, root->child_count());
+
+ FrameTreeNode* child_node = root->child_at(0);
+ GURL site_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
+ EXPECT_EQ(site_url, child_node->current_url());
+ EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
+ child_node->current_frame_host()->GetSiteInstance());
+
+ RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
+ root->current_frame_host()->GetRenderWidgetHost()->GetView());
+ RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
+ child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+ // Ensure that the child process renderer is ready to have input events
+ // routed to it. This happens when the browser process has received
+ // updated compositor surfaces from both renderer processes.
+ gfx::Point point(75, 75);
+ gfx::Point transformed_point;
+ while (root_view->SurfaceIdNamespaceAtPoint(point, &transformed_point) !=
+ rwhv_child->GetSurfaceIdNamespace()) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+ run_loop.Run();
+ }
+
+ // A WebContentsDelegate to listen for the ShowContextMenu message.
+ ContextMenuObserverDelegate context_menu_delegate;
+ shell()->web_contents()->SetDelegate(&context_menu_delegate);
+
+ RenderWidgetHostInputEventRouter* router =
+ static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetInputEventRouter();
+
+ // Target right-click event to child frame.
+ blink::WebMouseEvent click_event;
+ click_event.type = blink::WebInputEvent::MouseDown;
+ click_event.button = blink::WebPointerProperties::ButtonRight;
+ click_event.x = 75;
+ click_event.y = 75;
+ click_event.clickCount = 1;
+ router->RouteMouseEvent(root_view, &click_event);
+
+ // We also need a MouseUp event, needed by Windows.
+ click_event.type = blink::WebInputEvent::MouseUp;
+ click_event.x = 75;
+ click_event.y = 75;
+ router->RouteMouseEvent(root_view, &click_event);
+
+ context_menu_delegate.Wait();
+
+ ContextMenuParams params = context_menu_delegate.getParams();
+
+ EXPECT_EQ(point.x(), params.x);
+ EXPECT_EQ(point.y(), params.y);
+}
+
+// Test for https://crbug.com/526304, where a parent frame executes a
+// remote-to-local navigation on a child frame and immediately removes the same
+// child frame. This test exercises the path where the detach happens before
+// the provisional local frame is created.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ NavigateProxyAndDetachBeforeProvisionalFrameCreation) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ WebContents* contents = shell()->web_contents();
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();
+ EXPECT_EQ(2U, root->child_count());
+
+ // Navigate the first child frame to 'about:blank' (which is a
+ // remote-to-local transition), and then detach it.
+ FrameDeletedObserver observer(root->child_at(0));
+ std::string script =
+ "var f = document.querySelector('iframe');"
+ "f.contentWindow.location.href = 'about:blank';"
+ "setTimeout(function() { document.body.removeChild(f); }, 0);";
+ EXPECT_TRUE(ExecuteScript(root->current_frame_host(), script));
+ observer.Wait();
+ EXPECT_EQ(1U, root->child_count());
+
+ // Make sure the main frame renderer does not crash and ignores the
+ // navigation to the frame that's already been deleted.
+ int child_count = 0;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root->current_frame_host(),
+ "domAutomationController.send(frames.length)",
+ &child_count));
+ EXPECT_EQ(1, child_count);
+}
+
+// Test for a variation of https://crbug.com/526304, where a child frame does a
+// remote-to-local navigation, and the parent frame removes that child frame
+// after the provisional local frame is created and starts to navigate, but
+// before it commits.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ NavigateProxyAndDetachBeforeCommit) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ WebContents* contents = shell()->web_contents();
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();
+ EXPECT_EQ(2U, root->child_count());
+ FrameTreeNode* child = root->child_at(0);
+
+ // Start a remote-to-local navigation for the child, but don't wait for
+ // commit.
+ GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ NavigationController::LoadURLParams params(same_site_url);
+ params.transition_type = ui::PAGE_TRANSITION_LINK;
+ params.frame_tree_node_id = child->frame_tree_node_id();
+ child->navigator()->GetController()->LoadURLWithParams(params);
+
+ // Tell parent to remove the first child. This should happen after the
+ // previous navigation starts but before it commits.
+ FrameDeletedObserver observer(child);
+ EXPECT_TRUE(ExecuteScript(
+ root->current_frame_host(),
+ "document.body.removeChild(document.querySelector('iframe'));"));
+ observer.Wait();
+ EXPECT_EQ(1U, root->child_count());
+
+ // Make sure the a.com renderer does not crash.
+ int child_count = 0;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root->current_frame_host(),
+ "domAutomationController.send(frames.length)",
+ &child_count));
+ EXPECT_EQ(1, child_count);
+}
+
+// Test for https://crbug.com/568670. In A-embed-B, simultaneously have B
+// create a new (local) child frame, and have A detach B's proxy. The child
+// frame creation sends an IPC to create a new proxy in A's process, and if
+// that IPC arrives after the detach, the new frame's parent (a proxy) won't be
+// available, and this shouldn't cause RenderFrameProxy::CreateFrameProxy to
+// crash.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ RaceBetweenCreateChildFrameAndDetachParentProxy) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ WebContents* contents = shell()->web_contents();
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();
+
+ // Simulate subframe B creating a new child frame in parallel to main frame A
+ // detaching subframe B. We can't use ExecuteScript in both A and B to do
+ // this simultaneously, as that won't guarantee the timing that we want.
+ // Instead, tell A to detach B and then send a fake proxy creation IPC to A
+ // that would've come from create-child-frame code in B. Prepare parameters
+ // for that IPC ahead of the detach, while B's FrameTreeNode still exists.
+ SiteInstance* site_instance_a = root->current_frame_host()->GetSiteInstance();
+ RenderProcessHost* process_a =
+ root->render_manager()->current_frame_host()->GetProcess();
+ int new_routing_id = process_a->GetNextRoutingID();
+ int view_routing_id =
+ root->frame_tree()->GetRenderViewHost(site_instance_a)->GetRoutingID();
+ int parent_routing_id =
+ root->child_at(0)->render_manager()->GetProxyToParent()->GetRoutingID();
+
+ // Tell main frame A to delete its subframe B.
+ FrameDeletedObserver observer(root->child_at(0));
+ EXPECT_TRUE(ExecuteScript(
+ root->current_frame_host(),
+ "document.body.removeChild(document.querySelector('iframe'));"));
+
+ // Send the message to create a proxy for B's new child frame in A. This
+ // used to crash, as parent_routing_id refers to a proxy that doesn't exist
+ // anymore.
+ process_a->Send(new FrameMsg_NewFrameProxy(
+ new_routing_id, view_routing_id, MSG_ROUTING_NONE, parent_routing_id,
+ FrameReplicationState()));
+
+ // Ensure the subframe is detached in the browser process.
+ observer.Wait();
+ EXPECT_EQ(0U, root->child_count());
+
+ // Make sure process A did not crash.
+ int child_count = 0;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root->current_frame_host(),
+ "domAutomationController.send(frames.length)",
+ &child_count));
+ EXPECT_EQ(0, child_count);
+}
+
+// This test ensures that the RenderFrame isn't leaked in the renderer process
+// if a pending cross-process navigation is cancelled. The test works by trying
+// to create a new RenderFrame with the same routing id. If there is an
+// entry with the same routing ID, a CHECK is hit and the process crashes.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ SubframePendingAndBackToSameSiteInstance) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ NavigateToURL(shell(), main_url);
+
+ // Capture the FrameTreeNode this test will be navigating.
+ FrameTreeNode* node = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root()
+ ->child_at(0);
+ EXPECT_TRUE(node);
+ EXPECT_NE(node->current_frame_host()->GetSiteInstance(),
+ node->parent()->current_frame_host()->GetSiteInstance());
+
+ // Navigate to the site of the parent, but to a page that will not commit.
+ GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ NavigationStallDelegate stall_delegate(same_site_url);
+ ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ {
+ NavigationController::LoadURLParams params(same_site_url);
+ params.transition_type = ui::PAGE_TRANSITION_LINK;
+ params.frame_tree_node_id = node->frame_tree_node_id();
+ node->navigator()->GetController()->LoadURLWithParams(params);
+ }
+
+ // Grab the routing id of the pending RenderFrameHost and set up a process
+ // observer to ensure there is no crash when a new RenderFrame creation is
+ // attempted.
+ RenderProcessHost* process =
+ node->render_manager()->pending_frame_host()->GetProcess();
+ RenderProcessHostWatcher watcher(
+ process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ int frame_routing_id =
+ node->render_manager()->pending_frame_host()->GetRoutingID();
+ int proxy_routing_id =
+ node->render_manager()->GetProxyToParent()->GetRoutingID();
+
+ // Now go to c.com so the navigation to a.com is cancelled and send an IPC
+ // to create a new RenderFrame with the routing id of the previously pending
+ // one.
+ NavigateFrameToURL(node,
+ embedded_test_server()->GetURL("c.com", "/title2.html"));
+ {
+ FrameMsg_NewFrame_Params params;
+ params.routing_id = frame_routing_id;
+ params.proxy_routing_id = proxy_routing_id;
+ params.opener_routing_id = MSG_ROUTING_NONE;
+ params.parent_routing_id =
+ shell()->web_contents()->GetMainFrame()->GetRoutingID();
+ params.previous_sibling_routing_id = MSG_ROUTING_NONE;
+ params.widget_params.routing_id = MSG_ROUTING_NONE;
+ params.widget_params.hidden = true;
+
+ process->Send(new FrameMsg_NewFrame(params));
+ }
+
+ // The test must wait for the process to exit, but if there is no leak, the
+ // RenderFrame will be properly created and there will be no crash.
+ // Therefore, navigate the main frame to completely different site, which
+ // will cause the original process to exit cleanly.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("d.com", "/title3.html")));
+ watcher.Wait();
+ EXPECT_TRUE(watcher.did_exit_normally());
+
+ ResourceDispatcherHost::Get()->SetDelegate(nullptr);
+}
+
+// This test ensures that the RenderFrame isn't leaked in the renderer process
+// when a remote parent detaches a child frame. The test works by trying
+// to create a new RenderFrame with the same routing id. If there is an
+// entry with the same routing ID, a CHECK is hit and the process crashes.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ParentDetachRemoteChild) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
+ NavigateToURL(shell(), main_url);
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ EXPECT_EQ(2U, web_contents->GetFrameTree()->root()->child_count());
+
+ // Capture the FrameTreeNode this test will be navigating.
+ FrameTreeNode* node = web_contents->GetFrameTree()->root()->child_at(0);
+ EXPECT_TRUE(node);
+ EXPECT_NE(node->current_frame_host()->GetSiteInstance(),
+ node->parent()->current_frame_host()->GetSiteInstance());
+
+ // Grab the routing id of the first child RenderFrameHost and set up a process
+ // observer to ensure there is no crash when a new RenderFrame creation is
+ // attempted.
+ RenderProcessHost* process = node->current_frame_host()->GetProcess();
+ RenderProcessHostWatcher watcher(
+ process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ int frame_routing_id = node->current_frame_host()->GetRoutingID();
+ int widget_routing_id =
+ node->current_frame_host()->GetRenderWidgetHost()->GetRoutingID();
+ int parent_routing_id =
+ node->parent()->render_manager()->GetRoutingIdForSiteInstance(
+ node->current_frame_host()->GetSiteInstance());
+
+ // Have the parent frame remove the child frame from its DOM. This should
+ // result in the child RenderFrame being deleted in the remote process.
+ EXPECT_TRUE(ExecuteScript(web_contents,
+ "document.body.removeChild("
+ "document.querySelectorAll('iframe')[0])"));
+ EXPECT_EQ(1U, web_contents->GetFrameTree()->root()->child_count());
+
+ {
+ FrameMsg_NewFrame_Params params;
+ params.routing_id = frame_routing_id;
+ params.proxy_routing_id = MSG_ROUTING_NONE;
+ params.opener_routing_id = MSG_ROUTING_NONE;
+ params.parent_routing_id = parent_routing_id;
+ params.previous_sibling_routing_id = MSG_ROUTING_NONE;
+ params.widget_params.routing_id = widget_routing_id;
+ params.widget_params.hidden = true;
+
+ process->Send(new FrameMsg_NewFrame(params));
+ }
+
+ // The test must wait for the process to exit, but if there is no leak, the
+ // RenderFrame will be properly created and there will be no crash.
+ // Therefore, navigate the remaining subframe to completely different site,
+ // which will cause the original process to exit cleanly.
+ NavigateFrameToURL(
+ web_contents->GetFrameTree()->root()->child_at(0),
+ embedded_test_server()->GetURL("d.com", "/title3.html"));
+ watcher.Wait();
+ EXPECT_TRUE(watcher.did_exit_normally());
+}
+
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, VisibilityChanged) {
+ GURL main_url(
+ embedded_test_server()->GetURL("a.com", "/page_with_iframe.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), main_url);
+
+ GURL cross_site_url =
+ embedded_test_server()->GetURL("oopif.com", "/title1.html");
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ TestNavigationObserver observer(shell()->web_contents());
+
+ NavigateFrameToURL(root->child_at(0), cross_site_url);
+ EXPECT_EQ(cross_site_url, observer.last_navigation_url());
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+
+ RenderWidgetHostImpl* render_widget_host =
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
+ EXPECT_FALSE(render_widget_host->is_hidden());
+
+ std::string show_script =
+ "document.querySelector('iframe').style.visibility = 'visible';";
+ std::string hide_script =
+ "document.querySelector('iframe').style.visibility = 'hidden';";
+
+ // Verify that hiding leads to a notification from RenderWidgetHost.
+ RenderWidgetHostVisibilityObserver hide_observer(
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), false);
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(), hide_script));
+ EXPECT_TRUE(hide_observer.WaitUntilSatisfied());
+
+ // Verify showing leads to a notification as well.
+ RenderWidgetHostVisibilityObserver show_observer(
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), true);
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(), show_script));
+ EXPECT_TRUE(show_observer.WaitUntilSatisfied());
+}
+
} // namespace content
diff --git a/chromium/content/browser/speech/audio_buffer.cc b/chromium/content/browser/speech/audio_buffer.cc
index 823fff5291f..1038ac938f1 100644
--- a/chromium/content/browser/speech/audio_buffer.cc
+++ b/chromium/content/browser/speech/audio_buffer.cc
@@ -17,7 +17,7 @@ AudioChunk::AudioChunk(size_t length, int bytes_per_sample)
DCHECK_EQ(length % bytes_per_sample, 0U);
}
-AudioChunk::AudioChunk(const uint8* data, size_t length, int bytes_per_sample)
+AudioChunk::AudioChunk(const uint8_t* data, size_t length, int bytes_per_sample)
: data_string_(reinterpret_cast<const char*>(data), length),
bytes_per_sample_(bytes_per_sample) {
DCHECK_EQ(length % bytes_per_sample, 0U);
@@ -35,13 +35,13 @@ const std::string& AudioChunk::AsString() const {
return data_string_;
}
-int16 AudioChunk::GetSample16(size_t index) const {
- DCHECK(index < (data_string_.size() / sizeof(int16)));
+int16_t AudioChunk::GetSample16(size_t index) const {
+ DCHECK(index < (data_string_.size() / sizeof(int16_t)));
return SamplesData16()[index];
}
-const int16* AudioChunk::SamplesData16() const {
- return reinterpret_cast<const int16*>(data_string_.data());
+const int16_t* AudioChunk::SamplesData16() const {
+ return reinterpret_cast<const int16_t*>(data_string_.data());
}
AudioBuffer::AudioBuffer(int bytes_per_sample)
@@ -55,7 +55,7 @@ AudioBuffer::~AudioBuffer() {
Clear();
}
-void AudioBuffer::Enqueue(const uint8* data, size_t length) {
+void AudioBuffer::Enqueue(const uint8_t* data, size_t length) {
chunks_.push_back(new AudioChunk(data, length, bytes_per_sample_));
}
@@ -76,7 +76,7 @@ scoped_refptr<AudioChunk> AudioBuffer::DequeueAll() {
}
scoped_refptr<AudioChunk> chunk(
new AudioChunk(resulting_length, bytes_per_sample_));
- uint8* dest = chunk->writable_data();
+ uint8_t* dest = chunk->writable_data();
for (it = chunks_.begin(); it != chunks_.end(); ++it) {
memcpy(dest, (*it)->AsString().data(), (*it)->AsString().length());
dest += (*it)->AsString().length();
diff --git a/chromium/content/browser/speech/audio_buffer.h b/chromium/content/browser/speech/audio_buffer.h
index 7b0fd7e19df..d9415438697 100644
--- a/chromium/content/browser/speech/audio_buffer.h
+++ b/chromium/content/browser/speech/audio_buffer.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_SPEECH_AUDIO_BUFFER_H_
#define CONTENT_BROWSER_SPEECH_AUDIO_BUFFER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
@@ -21,15 +24,17 @@ class CONTENT_EXPORT AudioChunk :
explicit AudioChunk(int bytes_per_sample);
// Creates a chunk of |length| bytes, initialized to zeros.
AudioChunk(size_t length, int bytes_per_sample);
- AudioChunk(const uint8* data, size_t length, int bytes_per_sample);
+ AudioChunk(const uint8_t* data, size_t length, int bytes_per_sample);
bool IsEmpty() const;
int bytes_per_sample() const { return bytes_per_sample_; }
size_t NumSamples() const;
const std::string& AsString() const;
- int16 GetSample16(size_t index) const;
- const int16* SamplesData16() const;
- uint8* writable_data() { return reinterpret_cast<uint8*>(&data_string_[0]); }
+ int16_t GetSample16(size_t index) const;
+ const int16_t* SamplesData16() const;
+ uint8_t* writable_data() {
+ return reinterpret_cast<uint8_t*>(&data_string_[0]);
+ }
private:
friend class base::RefCountedThreadSafe<AudioChunk>;
@@ -49,7 +54,7 @@ class AudioBuffer {
~AudioBuffer();
// Enqueues a copy of |length| bytes of |data| buffer.
- void Enqueue(const uint8* data, size_t length);
+ void Enqueue(const uint8_t* data, size_t length);
// Dequeues, in FIFO order, a single chunk respecting the length of the
// corresponding Enqueue call (in a nutshell: multiple Enqueue calls followed
diff --git a/chromium/content/browser/speech/audio_encoder.cc b/chromium/content/browser/speech/audio_encoder.cc
index eccd671c6e5..e4473a0ac42 100644
--- a/chromium/content/browser/speech/audio_encoder.cc
+++ b/chromium/content/browser/speech/audio_encoder.cc
@@ -4,6 +4,8 @@
#include "content/browser/speech/audio_encoder.h"
+#include <stddef.h>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
diff --git a/chromium/content/browser/speech/chunked_byte_buffer.cc b/chromium/content/browser/speech/chunked_byte_buffer.cc
index 5fcf5d18fe6..7a0558918c8 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer.cc
+++ b/chromium/content/browser/speech/chunked_byte_buffer.cc
@@ -5,23 +5,23 @@
#include "content/browser/speech/chunked_byte_buffer.h"
#include <algorithm>
+#include <utility>
-#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
namespace {
-static const size_t kHeaderLength = sizeof(uint32);
+static const size_t kHeaderLength = sizeof(uint32_t);
static_assert(sizeof(size_t) >= kHeaderLength,
"chunked byte buffer not supported on this architecture");
-uint32 ReadBigEndian32(const uint8* buffer) {
- return (static_cast<uint32>(buffer[3])) |
- (static_cast<uint32>(buffer[2]) << 8) |
- (static_cast<uint32>(buffer[1]) << 16) |
- (static_cast<uint32>(buffer[0]) << 24);
+uint32_t ReadBigEndian32(const uint8_t* buffer) {
+ return (static_cast<uint32_t>(buffer[3])) |
+ (static_cast<uint32_t>(buffer[2]) << 8) |
+ (static_cast<uint32_t>(buffer[1]) << 16) |
+ (static_cast<uint32_t>(buffer[0]) << 24);
}
} // namespace
@@ -37,16 +37,16 @@ ChunkedByteBuffer::~ChunkedByteBuffer() {
Clear();
}
-void ChunkedByteBuffer::Append(const uint8* start, size_t length) {
+void ChunkedByteBuffer::Append(const uint8_t* start, size_t length) {
size_t remaining_bytes = length;
- const uint8* next_data = start;
+ const uint8_t* next_data = start;
while (remaining_bytes > 0) {
DCHECK(partial_chunk_ != NULL);
size_t insert_length = 0;
bool header_completed = false;
bool content_completed = false;
- std::vector<uint8>* insert_target;
+ std::vector<uint8_t>* insert_target;
if (partial_chunk_->header.size() < kHeaderLength) {
const size_t bytes_to_complete_header =
@@ -96,23 +96,23 @@ void ChunkedByteBuffer::Append(const uint8* start, size_t length) {
}
void ChunkedByteBuffer::Append(const std::string& string) {
- Append(reinterpret_cast<const uint8*>(string.data()), string.size());
+ Append(reinterpret_cast<const uint8_t*>(string.data()), string.size());
}
bool ChunkedByteBuffer::HasChunks() const {
return !chunks_.empty();
}
-scoped_ptr< std::vector<uint8> > ChunkedByteBuffer::PopChunk() {
+scoped_ptr<std::vector<uint8_t>> ChunkedByteBuffer::PopChunk() {
if (chunks_.empty())
- return scoped_ptr< std::vector<uint8> >();
+ return scoped_ptr<std::vector<uint8_t>>();
scoped_ptr<Chunk> chunk(*chunks_.begin());
chunks_.weak_erase(chunks_.begin());
DCHECK_EQ(chunk->header.size(), kHeaderLength);
DCHECK_EQ(chunk->content->size(), chunk->ExpectedContentLength());
total_bytes_stored_ -= chunk->content->size();
total_bytes_stored_ -= kHeaderLength;
- return chunk->content.Pass();
+ return std::move(chunk->content);
}
void ChunkedByteBuffer::Clear() {
@@ -121,9 +121,7 @@ void ChunkedByteBuffer::Clear() {
total_bytes_stored_ = 0;
}
-ChunkedByteBuffer::Chunk::Chunk()
- : content(new std::vector<uint8>()) {
-}
+ChunkedByteBuffer::Chunk::Chunk() : content(new std::vector<uint8_t>()) {}
ChunkedByteBuffer::Chunk::~Chunk() {
}
diff --git a/chromium/content/browser/speech/chunked_byte_buffer.h b/chromium/content/browser/speech/chunked_byte_buffer.h
index 8b9d2378111..82e576c48e3 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer.h
+++ b/chromium/content/browser/speech/chunked_byte_buffer.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_SPEECH_CHUNKED_BYTE_BUFFER_H_
#define CONTENT_BROWSER_SPEECH_CHUNKED_BYTE_BUFFER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "content/common/content_export.h"
@@ -31,7 +34,7 @@ class CONTENT_EXPORT ChunkedByteBuffer {
~ChunkedByteBuffer();
// Appends |length| bytes starting from |start| to the buffer.
- void Append(const uint8* start, size_t length);
+ void Append(const uint8_t* start, size_t length);
// Appends bytes contained in the |string| to the buffer.
void Append(const std::string& string);
@@ -41,7 +44,7 @@ class CONTENT_EXPORT ChunkedByteBuffer {
// If enough data is available, reads and removes the first complete chunk
// from the buffer. Returns a NULL pointer if no complete chunk is available.
- scoped_ptr< std::vector<uint8> > PopChunk();
+ scoped_ptr<std::vector<uint8_t>> PopChunk();
// Clears all the content of the buffer.
void Clear();
@@ -54,8 +57,8 @@ class CONTENT_EXPORT ChunkedByteBuffer {
Chunk();
~Chunk();
- std::vector<uint8> header;
- scoped_ptr< std::vector<uint8> > content;
+ std::vector<uint8_t> header;
+ scoped_ptr<std::vector<uint8_t>> content;
size_t ExpectedContentLength() const;
private:
diff --git a/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc b/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc
index 57fdf4ca1bf..56919757a4e 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc
+++ b/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -10,15 +12,15 @@
namespace content {
-typedef std::vector<uint8> ByteVector;
+typedef std::vector<uint8_t> ByteVector;
TEST(ChunkedByteBufferTest, BasicTest) {
ChunkedByteBuffer buffer;
- const uint8 kChunks[] = {
+ const uint8_t kChunks[] = {
0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, // Chunk 1: 4 bytes
- 0x00, 0x00, 0x00, 0x02, 0x05, 0x06, // Chunk 2: 2 bytes
- 0x00, 0x00, 0x00, 0x01, 0x07 // Chunk 3: 1 bytes
+ 0x00, 0x00, 0x00, 0x02, 0x05, 0x06, // Chunk 2: 2 bytes
+ 0x00, 0x00, 0x00, 0x01, 0x07 // Chunk 3: 1 bytes
};
EXPECT_EQ(0U, buffer.GetTotalLength());
@@ -44,9 +46,8 @@ TEST(ChunkedByteBufferTest, BasicTest) {
chunk = buffer.PopChunk();
EXPECT_TRUE(chunk != NULL);
EXPECT_EQ(4U, chunk->size());
- EXPECT_EQ(0, std::char_traits<uint8>::compare(kChunks + 4,
- &(*chunk)[0],
- chunk->size()));
+ EXPECT_EQ(0, std::char_traits<uint8_t>::compare(kChunks + 4, &(*chunk)[0],
+ chunk->size()));
EXPECT_EQ(6U, buffer.GetTotalLength());
EXPECT_TRUE(buffer.HasChunks());
@@ -54,9 +55,8 @@ TEST(ChunkedByteBufferTest, BasicTest) {
chunk = buffer.PopChunk();
EXPECT_TRUE(chunk != NULL);
EXPECT_EQ(2U, chunk->size());
- EXPECT_EQ(0, std::char_traits<uint8>::compare(kChunks + 12,
- &(*chunk)[0],
- chunk->size()));
+ EXPECT_EQ(0, std::char_traits<uint8_t>::compare(kChunks + 12, &(*chunk)[0],
+ chunk->size()));
EXPECT_EQ(0U, buffer.GetTotalLength());
EXPECT_FALSE(buffer.HasChunks());
diff --git a/chromium/content/browser/speech/endpointer/endpointer.cc b/chromium/content/browser/speech/endpointer/endpointer.cc
index 5ed48ca323f..1758970ee11 100644
--- a/chromium/content/browser/speech/endpointer/endpointer.cc
+++ b/chromium/content/browser/speech/endpointer/endpointer.cc
@@ -26,9 +26,9 @@ Endpointer::Endpointer(int sample_rate)
frame_size_ = static_cast<int>(sample_rate / static_cast<float>(kFrameRate));
speech_input_minimum_length_us_ =
- static_cast<int64>(1.7 * Time::kMicrosecondsPerSecond);
+ static_cast<int64_t>(1.7 * Time::kMicrosecondsPerSecond);
speech_input_complete_silence_length_us_ =
- static_cast<int64>(0.5 * Time::kMicrosecondsPerSecond);
+ static_cast<int64_t>(0.5 * Time::kMicrosecondsPerSecond);
long_speech_input_complete_silence_length_us_ = -1;
long_speech_length_us_ = -1;
speech_input_possibly_complete_silence_length_us_ =
@@ -85,12 +85,12 @@ void Endpointer::SetUserInputMode() {
energy_endpointer_.SetUserInputMode();
}
-EpStatus Endpointer::Status(int64 *time) {
+EpStatus Endpointer::Status(int64_t* time) {
return energy_endpointer_.Status(time);
}
EpStatus Endpointer::ProcessAudio(const AudioChunk& raw_audio, float* rms_out) {
- const int16* audio_data = raw_audio.SamplesData16();
+ const int16_t* audio_data = raw_audio.SamplesData16();
const int num_samples = raw_audio.NumSamples();
EpStatus ep_status = EP_PRE_SPEECH;
@@ -109,7 +109,7 @@ EpStatus Endpointer::ProcessAudio(const AudioChunk& raw_audio, float* rms_out) {
sample_rate_;
// Get the status of the endpointer.
- int64 ep_time;
+ int64_t ep_time;
ep_status = energy_endpointer_.Status(&ep_time);
// Handle state changes.
@@ -144,7 +144,7 @@ EpStatus Endpointer::ProcessAudio(const AudioChunk& raw_audio, float* rms_out) {
bool has_stepped_silence =
(long_speech_length_us_ > 0) &&
(long_speech_input_complete_silence_length_us_ > 0);
- int64 requested_silence_length;
+ int64_t requested_silence_length;
if (has_stepped_silence &&
(ep_time - speech_start_time_us_) > long_speech_length_us_) {
requested_silence_length =
diff --git a/chromium/content/browser/speech/endpointer/endpointer.h b/chromium/content/browser/speech/endpointer/endpointer.h
index 6688ee63dc9..5790672bc45 100644
--- a/chromium/content/browser/speech/endpointer/endpointer.h
+++ b/chromium/content/browser/speech/endpointer/endpointer.h
@@ -5,7 +5,8 @@
#ifndef CONTENT_BROWSER_SPEECH_ENDPOINTER_ENDPOINTER_H_
#define CONTENT_BROWSER_SPEECH_ENDPOINTER_ENDPOINTER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "content/browser/speech/endpointer/energy_endpointer.h"
#include "content/common/content_export.h"
@@ -66,7 +67,7 @@ class CONTENT_EXPORT Endpointer {
EpStatus ProcessAudio(const AudioChunk& raw_audio, float* rms_out);
// Get the status of the endpointer.
- EpStatus Status(int64 *time_us);
+ EpStatus Status(int64_t* time_us);
// Returns true if the endpointer detected reasonable audio levels above
// background noise which could be user speech, false if not.
@@ -78,19 +79,19 @@ class CONTENT_EXPORT Endpointer {
return energy_endpointer_.estimating_environment();
}
- void set_speech_input_complete_silence_length(int64 time_us) {
+ void set_speech_input_complete_silence_length(int64_t time_us) {
speech_input_complete_silence_length_us_ = time_us;
}
- void set_long_speech_input_complete_silence_length(int64 time_us) {
+ void set_long_speech_input_complete_silence_length(int64_t time_us) {
long_speech_input_complete_silence_length_us_ = time_us;
}
- void set_speech_input_possibly_complete_silence_length(int64 time_us) {
+ void set_speech_input_possibly_complete_silence_length(int64_t time_us) {
speech_input_possibly_complete_silence_length_us_ = time_us;
}
- void set_long_speech_length(int64 time_us) {
+ void set_long_speech_length(int64_t time_us) {
long_speech_length_us_ = time_us;
}
@@ -107,37 +108,37 @@ class CONTENT_EXPORT Endpointer {
void Reset();
// Minimum allowable length of speech input.
- int64 speech_input_minimum_length_us_;
+ int64_t speech_input_minimum_length_us_;
// The speechInputPossiblyComplete event signals that silence/noise has been
// detected for a *short* amount of time after some speech has been detected.
// This proporty specifies the time period.
- int64 speech_input_possibly_complete_silence_length_us_;
+ int64_t speech_input_possibly_complete_silence_length_us_;
// The speechInputComplete event signals that silence/noise has been
// detected for a *long* amount of time after some speech has been detected.
// This property specifies the time period.
- int64 speech_input_complete_silence_length_us_;
+ int64_t speech_input_complete_silence_length_us_;
// Same as above, this specifies the required silence period after speech
// detection. This period is used instead of
// speech_input_complete_silence_length_ when the utterance is longer than
// long_speech_length_. This parameter is optional.
- int64 long_speech_input_complete_silence_length_us_;
+ int64_t long_speech_input_complete_silence_length_us_;
// The period of time after which the endpointer should consider
// long_speech_input_complete_silence_length_ as a valid silence period
// instead of speech_input_complete_silence_length_. This parameter is
// optional.
- int64 long_speech_length_us_;
+ int64_t long_speech_length_us_;
// First speech onset time, used in determination of speech complete timeout.
- int64 speech_start_time_us_;
+ int64_t speech_start_time_us_;
// Most recent end time, used in determination of speech complete timeout.
- int64 speech_end_time_us_;
+ int64_t speech_end_time_us_;
- int64 audio_frame_time_us_;
+ int64_t audio_frame_time_us_;
EpStatus old_ep_status_;
bool waiting_for_speech_possibly_complete_timeout_;
bool waiting_for_speech_complete_timeout_;
@@ -145,7 +146,7 @@ class CONTENT_EXPORT Endpointer {
bool speech_input_complete_;
EnergyEndpointer energy_endpointer_;
int sample_rate_;
- int32 frame_size_;
+ int32_t frame_size_;
};
} // namespace content
diff --git a/chromium/content/browser/speech/endpointer/endpointer_unittest.cc b/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
index c65a7c9b4e1..53ec4d19afc 100644
--- a/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
+++ b/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "content/browser/speech/audio_buffer.h"
#include "content/browser/speech/endpointer/endpointer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,11 +23,13 @@ namespace content {
class FrameProcessor {
public:
// Process a single frame of test audio samples.
- virtual EpStatus ProcessFrame(int64 time, int16* samples, int frame_size) = 0;
+ virtual EpStatus ProcessFrame(int64_t time,
+ int16_t* samples,
+ int frame_size) = 0;
};
void RunEndpointerEventsTest(FrameProcessor* processor) {
- int16 samples[kFrameSize];
+ int16_t samples[kFrameSize];
// We will create a white noise signal of 150 frames. The frames from 50 to
// 100 will have more power, and the endpointer should fire on those frames.
@@ -34,7 +38,7 @@ void RunEndpointerEventsTest(FrameProcessor* processor) {
// Create a random sequence of samples.
srand(1);
float gain = 0.0;
- int64 time = 0;
+ int64_t time = 0;
for (int frame_count = 0; frame_count < kNumFrames; ++frame_count) {
// The frames from 50 to 100 will have more power, and the endpointer
// should detect those frames as speech.
@@ -47,11 +51,11 @@ void RunEndpointerEventsTest(FrameProcessor* processor) {
for (int i = 0; i < kFrameSize; ++i) {
float randNum = static_cast<float>(rand() - (RAND_MAX / 2)) /
static_cast<float>(RAND_MAX);
- samples[i] = static_cast<int16>(gain * randNum);
+ samples[i] = static_cast<int16_t>(gain * randNum);
}
EpStatus ep_status = processor->ProcessFrame(time, samples, kFrameSize);
- time += static_cast<int64>(kFrameSize * (1e6 / kSampleRate));
+ time += static_cast<int64_t>(kFrameSize * (1e6 / kSampleRate));
// Log the status.
if (20 == frame_count)
@@ -73,9 +77,11 @@ class EnergyEndpointerFrameProcessor : public FrameProcessor {
explicit EnergyEndpointerFrameProcessor(EnergyEndpointer* endpointer)
: endpointer_(endpointer) {}
- EpStatus ProcessFrame(int64 time, int16* samples, int frame_size) override {
+ EpStatus ProcessFrame(int64_t time,
+ int16_t* samples,
+ int frame_size) override {
endpointer_->ProcessAudioFrame(time, samples, kFrameSize, NULL);
- int64 ep_time;
+ int64_t ep_time;
return endpointer_->Status(&ep_time);
}
@@ -116,11 +122,13 @@ class EndpointerFrameProcessor : public FrameProcessor {
explicit EndpointerFrameProcessor(Endpointer* endpointer)
: endpointer_(endpointer) {}
- EpStatus ProcessFrame(int64 time, int16* samples, int frame_size) override {
+ EpStatus ProcessFrame(int64_t time,
+ int16_t* samples,
+ int frame_size) override {
scoped_refptr<AudioChunk> frame(
- new AudioChunk(reinterpret_cast<uint8*>(samples), kFrameSize * 2, 2));
+ new AudioChunk(reinterpret_cast<uint8_t*>(samples), kFrameSize * 2, 2));
endpointer_->ProcessAudio(*frame.get(), NULL);
- int64 ep_time;
+ int64_t ep_time;
return endpointer_->Status(&ep_time);
}
@@ -132,10 +140,10 @@ TEST(EndpointerTest, TestEmbeddedEndpointerEvents) {
const int kSampleRate = 8000; // 8 k samples per second for AMR encoding.
Endpointer endpointer(kSampleRate);
- const int64 kMillisecondsPerMicrosecond = 1000;
- const int64 short_timeout = 300 * kMillisecondsPerMicrosecond;
+ const int64_t kMillisecondsPerMicrosecond = 1000;
+ const int64_t short_timeout = 300 * kMillisecondsPerMicrosecond;
endpointer.set_speech_input_possibly_complete_silence_length(short_timeout);
- const int64 long_timeout = 500 * kMillisecondsPerMicrosecond;
+ const int64_t long_timeout = 500 * kMillisecondsPerMicrosecond;
endpointer.set_speech_input_complete_silence_length(long_timeout);
endpointer.StartSession();
diff --git a/chromium/content/browser/speech/endpointer/energy_endpointer.cc b/chromium/content/browser/speech/endpointer/energy_endpointer.cc
index 30f3770286e..a554465742b 100644
--- a/chromium/content/browser/speech/endpointer/energy_endpointer.cc
+++ b/chromium/content/browser/speech/endpointer/energy_endpointer.cc
@@ -9,15 +9,17 @@
#include "content/browser/speech/endpointer/energy_endpointer.h"
#include <math.h>
+#include <stddef.h>
#include "base/logging.h"
+#include "base/macros.h"
namespace {
// Returns the RMS (quadratic mean) of the input signal.
-float RMS(const int16* samples, int num_samples) {
- int64 ssq_int64 = 0;
- int64 sum_int64 = 0;
+float RMS(const int16_t* samples, int num_samples) {
+ int64_t ssq_int64 = 0;
+ int64_t sum_int64 = 0;
for (int i = 0; i < num_samples; ++i) {
sum_int64 += samples[i];
ssq_int64 += samples[i] * samples[i];
@@ -29,8 +31,8 @@ float RMS(const int16* samples, int num_samples) {
return static_cast<float>(sqrt((ssq / num_samples) - (sum * sum)));
}
-int64 Secs2Usecs(float seconds) {
- return static_cast<int64>(0.5 + (1.0e6 * seconds));
+int64_t Secs2Usecs(float seconds) {
+ return static_cast<int64_t>(0.5 + (1.0e6 * seconds));
}
float GetDecibel(float value) {
@@ -53,10 +55,10 @@ class EnergyEndpointer::HistoryRing {
void SetRing(int size, bool initial_state);
// Inserts a new entry into the ring and drops the oldest entry.
- void Insert(int64 time_us, bool decision);
+ void Insert(int64_t time_us, bool decision);
// Returns the time in microseconds of the most recently added entry.
- int64 EndTime() const;
+ int64_t EndTime() const;
// Returns the sum of all intervals during which 'decision' is true within
// the time in seconds specified by 'duration'. The returned interval is
@@ -65,7 +67,7 @@ class EnergyEndpointer::HistoryRing {
private:
struct DecisionPoint {
- int64 time_us;
+ int64_t time_us;
bool decision;
};
@@ -82,13 +84,13 @@ void EnergyEndpointer::HistoryRing::SetRing(int size, bool initial_state) {
decision_points_.resize(size, init);
}
-void EnergyEndpointer::HistoryRing::Insert(int64 time_us, bool decision) {
+void EnergyEndpointer::HistoryRing::Insert(int64_t time_us, bool decision) {
decision_points_[insertion_index_].time_us = time_us;
decision_points_[insertion_index_].decision = decision;
insertion_index_ = (insertion_index_ + 1) % decision_points_.size();
}
-int64 EnergyEndpointer::HistoryRing::EndTime() const {
+int64_t EnergyEndpointer::HistoryRing::EndTime() const {
int ind = insertion_index_ - 1;
if (ind < 0)
ind = decision_points_.size() - 1;
@@ -99,13 +101,14 @@ float EnergyEndpointer::HistoryRing::RingSum(float duration_sec) {
if (!decision_points_.size())
return 0.0;
- int64 sum_us = 0;
+ int64_t sum_us = 0;
int ind = insertion_index_ - 1;
if (ind < 0)
ind = decision_points_.size() - 1;
- int64 end_us = decision_points_[ind].time_us;
+ int64_t end_us = decision_points_[ind].time_us;
bool is_on = decision_points_[ind].decision;
- int64 start_us = end_us - static_cast<int64>(0.5 + (1.0e6 * duration_sec));
+ int64_t start_us =
+ end_us - static_cast<int64_t>(0.5 + (1.0e6 * duration_sec));
if (start_us < 0)
start_us = 0;
size_t n_summed = 1; // n points ==> (n-1) intervals
@@ -146,7 +149,7 @@ EnergyEndpointer::~EnergyEndpointer() {
}
int EnergyEndpointer::TimeToFrame(float time) const {
- return static_cast<int32>(0.5 + (time / params_.frame_period()));
+ return static_cast<int32_t>(0.5 + (time / params_.frame_period()));
}
void EnergyEndpointer::Restart(bool reset_threshold) {
@@ -200,7 +203,7 @@ void EnergyEndpointer::Init(const EnergyEndpointerParams& params) {
// The level of the first frame will overwrite these values.
noise_level_ = params_.decision_threshold() / 2.0f;
fast_update_frames_ =
- static_cast<int64>(params_.fast_update_dur() / params_.frame_period());
+ static_cast<int64_t>(params_.fast_update_dur() / params_.frame_period());
frame_counter_ = 0; // Used for rapid initial update of levels.
@@ -229,8 +232,8 @@ void EnergyEndpointer::SetUserInputMode() {
user_input_start_time_us_ = endpointer_time_us_;
}
-void EnergyEndpointer::ProcessAudioFrame(int64 time_us,
- const int16* samples,
+void EnergyEndpointer::ProcessAudioFrame(int64_t time_us,
+ const int16_t* samples,
int num_samples,
float* rms_out) {
endpointer_time_us_ = time_us;
@@ -368,7 +371,7 @@ void EnergyEndpointer::UpdateLevels(float rms) {
}
}
-EpStatus EnergyEndpointer::Status(int64* status_time) const {
+EpStatus EnergyEndpointer::Status(int64_t* status_time) const {
*status_time = history_->EndTime();
return status_;
}
diff --git a/chromium/content/browser/speech/endpointer/energy_endpointer.h b/chromium/content/browser/speech/endpointer/energy_endpointer.h
index 0aa421fb363..27837bb625e 100644
--- a/chromium/content/browser/speech/endpointer/energy_endpointer.h
+++ b/chromium/content/browser/speech/endpointer/energy_endpointer.h
@@ -37,9 +37,11 @@
#ifndef CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_H_
#define CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_H_
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/speech/endpointer/energy_endpointer_params.h"
#include "content/common/content_export.h"
@@ -80,13 +82,14 @@ class CONTENT_EXPORT EnergyEndpointer {
// Computes the next input frame and modifies EnergyEndpointer status as
// appropriate based on the computation.
- void ProcessAudioFrame(int64 time_us,
- const int16* samples, int num_samples,
+ void ProcessAudioFrame(int64_t time_us,
+ const int16_t* samples,
+ int num_samples,
float* rms_out);
// Returns the current state of the EnergyEndpointer and the time
// corresponding to the most recently computed frame.
- EpStatus Status(int64* status_time_us) const;
+ EpStatus Status(int64_t* status_time_us) const;
bool estimating_environment() const {
return estimating_environment_;
@@ -112,9 +115,12 @@ class CONTENT_EXPORT EnergyEndpointer {
EpStatus status_; // The current state of this instance.
float offset_confirm_dur_sec_; // max on time allowed to confirm POST_SPEECH
- int64 endpointer_time_us_; // Time of the most recently received audio frame.
- int64 fast_update_frames_; // Number of frames for initial level adaptation.
- int64 frame_counter_; // Number of frames seen. Used for initial adaptation.
+ int64_t
+ endpointer_time_us_; // Time of the most recently received audio frame.
+ int64_t
+ fast_update_frames_; // Number of frames for initial level adaptation.
+ int64_t
+ frame_counter_; // Number of frames seen. Used for initial adaptation.
float max_window_dur_; // Largest search window size (seconds)
float sample_rate_; // Sampling rate.
@@ -145,7 +151,7 @@ class CONTENT_EXPORT EnergyEndpointer {
// Time when mode switched from environment estimation to user input. This
// is used to time forced rejection of audio feedback contamination.
- int64 user_input_start_time_us_;
+ int64_t user_input_start_time_us_;
DISALLOW_COPY_AND_ASSIGN(EnergyEndpointer);
};
diff --git a/chromium/content/browser/speech/endpointer/energy_endpointer_params.h b/chromium/content/browser/speech/endpointer/energy_endpointer_params.h
index 436adce8dc3..1510435d5ab 100644
--- a/chromium/content/browser/speech/endpointer/energy_endpointer_params.h
+++ b/chromium/content/browser/speech/endpointer/energy_endpointer_params.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_PARAMS_H_
#define CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_PARAMS_H_
-#include "base/basictypes.h"
#include "content/common/content_export.h"
namespace content {
diff --git a/chromium/content/browser/speech/google_one_shot_remote_engine.cc b/chromium/content/browser/speech/google_one_shot_remote_engine.cc
index cdd6b104c89..97743c9f94a 100644
--- a/chromium/content/browser/speech/google_one_shot_remote_engine.cc
+++ b/chromium/content/browser/speech/google_one_shot_remote_engine.cc
@@ -4,6 +4,9 @@
#include "content/browser/speech/google_one_shot_remote_engine.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
#include "base/json/json_reader.h"
@@ -247,7 +250,7 @@ void GoogleOneShotRemoteEngine::AudioChunksEnded() {
size_t sample_count =
config_.audio_sample_rate * kAudioPacketIntervalMs / 1000;
scoped_refptr<AudioChunk> dummy_chunk(new AudioChunk(
- sample_count * sizeof(int16), encoder_->GetBitsPerSample() / 8));
+ sample_count * sizeof(int16_t), encoder_->GetBitsPerSample() / 8));
encoder_->Encode(*dummy_chunk.get());
encoder_->Flush();
scoped_refptr<AudioChunk> encoded_dummy_data(
diff --git a/chromium/content/browser/speech/google_one_shot_remote_engine.h b/chromium/content/browser/speech/google_one_shot_remote_engine.h
index 0e5b09f904e..22063d22470 100644
--- a/chromium/content/browser/speech/google_one_shot_remote_engine.h
+++ b/chromium/content/browser/speech/google_one_shot_remote_engine.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/speech/audio_encoder.h"
diff --git a/chromium/content/browser/speech/google_streaming_remote_engine.cc b/chromium/content/browser/speech/google_streaming_remote_engine.cc
index 3e0129fb169..2f7e3656c16 100644
--- a/chromium/content/browser/speech/google_streaming_remote_engine.cc
+++ b/chromium/content/browser/speech/google_streaming_remote_engine.cc
@@ -38,7 +38,7 @@ const char kDownstreamUrl[] = "/down?";
const char kUpstreamUrl[] = "/up?";
// This matches the maximum maxAlternatives value supported by the server.
-const uint32 kMaxMaxAlternatives = 30;
+const uint32_t kMaxMaxAlternatives = 30;
// TODO(hans): Remove this and other logging when we don't need it anymore.
void DumpResponse(const std::string& response) {
@@ -121,7 +121,9 @@ void GoogleStreamingRemoteEngine::OnURLFetchComplete(const URLFetcher* source) {
}
void GoogleStreamingRemoteEngine::OnURLFetchDownloadProgress(
- const URLFetcher* source, int64 current, int64 total) {
+ const URLFetcher* source,
+ int64_t current,
+ int64_t total) {
const bool kPartialResponse = false;
DispatchHTTPResponse(source, kPartialResponse);
}
@@ -341,7 +343,7 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) {
upstream_args.push_back(
config_.filter_profanities ? "pFilter=2" : "pFilter=0");
if (config_.max_hypotheses > 0U) {
- uint32 max_alternatives =
+ uint32_t max_alternatives =
std::min(kMaxMaxAlternatives, config_.max_hypotheses);
upstream_args.push_back("maxAlternatives=" +
base::UintToString(max_alternatives));
@@ -398,9 +400,8 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) {
if (preamble_encoder_) {
// Encode and send preamble right away.
scoped_refptr<AudioChunk> chunk = new AudioChunk(
- reinterpret_cast<const uint8*>(config_.preamble->sample_data.data()),
- config_.preamble->sample_data.size(),
- config_.preamble->sample_depth);
+ reinterpret_cast<const uint8_t*>(config_.preamble->sample_data.data()),
+ config_.preamble->sample_data.size(), config_.preamble->sample_depth);
preamble_encoder_->Encode(*chunk);
preamble_encoder_->Flush();
scoped_refptr<AudioChunk> encoded_data(
@@ -519,7 +520,7 @@ GoogleStreamingRemoteEngine::CloseUpstreamAndWaitForResults(
size_t sample_count =
config_.audio_sample_rate * kAudioPacketIntervalMs / 1000;
scoped_refptr<AudioChunk> dummy_chunk = new AudioChunk(
- sample_count * sizeof(int16), encoder_->GetBitsPerSample() / 8);
+ sample_count * sizeof(int16_t), encoder_->GetBitsPerSample() / 8);
encoder_->Encode(*dummy_chunk.get());
encoder_->Flush();
scoped_refptr<AudioChunk> encoded_dummy_data =
@@ -607,13 +608,13 @@ std::string GoogleStreamingRemoteEngine::GetAcceptedLanguages() const {
// TODO(primiano): Is there any utility in the codebase that already does this?
std::string GoogleStreamingRemoteEngine::GenerateRequestKey() const {
- const int64 kKeepLowBytes = 0x00000000FFFFFFFFLL;
- const int64 kKeepHighBytes = 0xFFFFFFFF00000000LL;
+ const int64_t kKeepLowBytes = 0x00000000FFFFFFFFLL;
+ const int64_t kKeepHighBytes = 0xFFFFFFFF00000000LL;
// Just keep the least significant bits of timestamp, in order to reduce
// probability of collisions.
- int64 key = (base::Time::Now().ToInternalValue() & kKeepLowBytes) |
- (base::RandUint64() & kKeepHighBytes);
+ int64_t key = (base::Time::Now().ToInternalValue() & kKeepLowBytes) |
+ (base::RandUint64() & kKeepHighBytes);
return base::HexEncode(reinterpret_cast<void*>(&key), sizeof(key));
}
diff --git a/chromium/content/browser/speech/google_streaming_remote_engine.h b/chromium/content/browser/speech/google_streaming_remote_engine.h
index 15b866ba63b..27abe2f3124 100644
--- a/chromium/content/browser/speech/google_streaming_remote_engine.h
+++ b/chromium/content/browser/speech/google_streaming_remote_engine.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_SPEECH_GOOGLE_STREAMING_REMOTE_ENGINE_H_
#define CONTENT_BROWSER_SPEECH_GOOGLE_STREAMING_REMOTE_ENGINE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
@@ -71,8 +74,8 @@ class CONTENT_EXPORT GoogleStreamingRemoteEngine
// net::URLFetcherDelegate methods.
void OnURLFetchComplete(const net::URLFetcher* source) override;
void OnURLFetchDownloadProgress(const net::URLFetcher* source,
- int64 current,
- int64 total) override;
+ int64_t current,
+ int64_t total) override;
private:
// Response status codes from the speech recognition webservice.
@@ -116,7 +119,7 @@ class CONTENT_EXPORT GoogleStreamingRemoteEngine
scoped_refptr<const AudioChunk> audio_data;
// In case of EVENT_DOWNSTREAM_RESPONSE, hold the current chunk bytes.
- scoped_ptr<std::vector<uint8> > response;
+ scoped_ptr<std::vector<uint8_t>> response;
private:
DISALLOW_COPY_AND_ASSIGN(FSMEventArgs);
diff --git a/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc b/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc
index adc54aa6e43..62631e1f47e 100644
--- a/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc
+++ b/chromium/content/browser/speech/google_streaming_remote_engine_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <queue>
#include "base/big_endian.h"
@@ -593,7 +596,7 @@ std::string GoogleStreamingRemoteEngineTest::SerializeProtobufResponse(
// Prepend 4 byte prefix length indication to the protobuf message as
// envisaged by the google streaming recognition webservice protocol.
- uint32 prefix = HostToNet32(checked_cast<uint32>(msg_string.size()));
+ uint32_t prefix = HostToNet32(checked_cast<uint32_t>(msg_string.size()));
msg_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix));
return msg_string;
diff --git a/chromium/content/browser/speech/speech_recognition_browsertest.cc b/chromium/content/browser/speech/speech_recognition_browsertest.cc
index 1d0073f341b..64188817587 100644
--- a/chromium/content/browser/speech/speech_recognition_browsertest.cc
+++ b/chromium/content/browser/speech/speech_recognition_browsertest.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
#include <list>
#include "base/bind.h"
@@ -137,11 +141,11 @@ class SpeechRecognitionBrowserTest :
bool fill_with_noise) {
DCHECK(controller.get());
const media::AudioParameters& audio_params = controller->audio_parameters();
- scoped_ptr<uint8[]> audio_buffer(new uint8[buffer_size]);
+ scoped_ptr<uint8_t[]> audio_buffer(new uint8_t[buffer_size]);
if (fill_with_noise) {
for (size_t i = 0; i < buffer_size; ++i)
- audio_buffer[i] = static_cast<uint8>(127 * sin(i * 3.14F /
- (16 * buffer_size)));
+ audio_buffer[i] =
+ static_cast<uint8_t>(127 * sin(i * 3.14F / (16 * buffer_size)));
} else {
memset(audio_buffer.get(), 0, buffer_size);
}
diff --git a/chromium/content/browser/speech/speech_recognition_dispatcher_host.h b/chromium/content/browser/speech/speech_recognition_dispatcher_host.h
index 34b333207e8..a7a433b51a9 100644
--- a/chromium/content/browser/speech/speech_recognition_dispatcher_host.h
+++ b/chromium/content/browser/speech/speech_recognition_dispatcher_host.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_SPEECH_SPEECH_RECOGNITION_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNITION_DISPATCHER_HOST_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/speech/speech_recognition_engine.cc b/chromium/content/browser/speech/speech_recognition_engine.cc
index 53f0e91ce56..e3b236b7976 100644
--- a/chromium/content/browser/speech/speech_recognition_engine.cc
+++ b/chromium/content/browser/speech/speech_recognition_engine.cc
@@ -7,7 +7,7 @@
namespace {
const int kDefaultConfigSampleRate = 8000;
const int kDefaultConfigBitsPerSample = 16;
-const uint32 kDefaultMaxHypotheses = 1;
+const uint32_t kDefaultMaxHypotheses = 1;
} // namespace
namespace content {
diff --git a/chromium/content/browser/speech/speech_recognition_engine.h b/chromium/content/browser/speech/speech_recognition_engine.h
index 239cabf1b0a..c25fd19c359 100644
--- a/chromium/content/browser/speech/speech_recognition_engine.h
+++ b/chromium/content/browser/speech/speech_recognition_engine.h
@@ -5,9 +5,10 @@
#ifndef CONTENT_BROWSER_SPEECH_SPEECH_RECOGNITION_ENGINE_H_
#define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNITION_ENGINE_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "content/common/content_export.h"
#include "content/public/browser/speech_recognition_session_preamble.h"
#include "content/public/common/speech_recognition_grammar.h"
@@ -56,7 +57,7 @@ class SpeechRecognitionEngine {
bool filter_profanities;
bool continuous;
bool interim_results;
- uint32 max_hypotheses;
+ uint32_t max_hypotheses;
std::string hardware_info;
std::string origin_url;
int audio_sample_rate;
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.cc b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
index 852cfeaa325..06311bb04dd 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
@@ -4,10 +4,13 @@
#include "content/browser/speech/speech_recognition_manager_impl.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
@@ -200,11 +203,8 @@ void SpeechRecognitionManagerImpl::RecognitionAllowedCallback(int session_id,
if (ask_user) {
SpeechRecognitionSessionContext& context = session->context;
context.label = media_stream_manager_->MakeMediaAccessRequest(
- context.render_process_id,
- context.render_frame_id,
- context.request_id,
- StreamOptions(true, false),
- GURL(context.context_name),
+ context.render_process_id, context.render_frame_id, context.request_id,
+ StreamControls(true, false), GURL(context.context_name),
base::Bind(
&SpeechRecognitionManagerImpl::MediaRequestPermissionCallback,
weak_factory_.GetWeakPtr(), session_id));
@@ -242,7 +242,7 @@ void SpeechRecognitionManagerImpl::MediaRequestPermissionCallback(
iter->second->context.devices = devices;
// Save the UI object.
- iter->second->ui = stream_ui.Pass();
+ iter->second->ui = std::move(stream_ui);
}
// Clear the label to indicate the request has been done.
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.h b/chromium/content/browser/speech/speech_recognition_manager_impl.h
index 9b8da39fc47..93e9fd850cc 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.h
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.h
@@ -6,9 +6,9 @@
#define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNITION_MANAGER_IMPL_H_
#include <map>
+#include <memory>
#include <string>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
@@ -98,7 +98,7 @@ class CONTENT_EXPORT SpeechRecognitionManagerImpl :
// BrowserMainLoop is the only one allowed to istantiate and free us.
friend class BrowserMainLoop;
// Needed for dtor.
- friend struct base::DefaultDeleter<SpeechRecognitionManagerImpl>;
+ friend std::default_delete<SpeechRecognitionManagerImpl>;
SpeechRecognitionManagerImpl(media::AudioManager* audio_manager,
MediaStreamManager* media_stream_manager);
~SpeechRecognitionManagerImpl() override;
diff --git a/chromium/content/browser/speech/speech_recognizer.h b/chromium/content/browser/speech/speech_recognizer.h
index 92feebb3755..64c896518a2 100644
--- a/chromium/content/browser/speech/speech_recognizer.h
+++ b/chromium/content/browser/speech/speech_recognizer.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_H_
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.cc b/chromium/content/browser/speech/speech_recognizer_impl.cc
index 305dcaac9f0..273187d4b76 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl.cc
@@ -4,9 +4,12 @@
#include "content/browser/speech/speech_recognizer_impl.h"
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/bind.h"
+#include "base/macros.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/speech/audio_buffer.h"
@@ -69,9 +72,10 @@ namespace {
const float kUpSmoothingFactor = 1.0f;
// Multiplier used when new volume is lesser than previous level.
const float kDownSmoothingFactor = 0.7f;
-// RMS dB value of a maximum (unclipped) sine wave for int16 samples.
+// RMS dB value of a maximum (unclipped) sine wave for int16_t samples.
const float kAudioMeterMaxDb = 90.31f;
-// This value corresponds to RMS dB for int16 with 6 most-significant-bits = 0.
+// This value corresponds to RMS dB for int16_t with 6 most-significant-bits =
+// 0.
// Values lower than this will display as empty level-meter.
const float kAudioMeterMinDb = 30.0f;
const float kAudioMeterDbRange = kAudioMeterMaxDb - kAudioMeterMinDb;
@@ -82,7 +86,7 @@ const float kAudioMeterRangeMaxUnclipped = 47.0f / 48.0f;
// Returns true if more than 5% of the samples are at min or max value.
bool DetectClipping(const AudioChunk& chunk) {
const int num_samples = chunk.NumSamples();
- const int16* samples = chunk.SamplesData16();
+ const int16_t* samples = chunk.SamplesData16();
const int kThreshold = num_samples / 20;
int clipping_samples = 0;
@@ -196,7 +200,7 @@ SpeechRecognizerImpl::SpeechRecognizerImpl(
} else {
// In continuous recognition, the session is automatically ended after 15
// seconds of silence.
- const int64 cont_timeout_us = base::Time::kMicrosecondsPerSecond * 15;
+ const int64_t cont_timeout_us = base::Time::kMicrosecondsPerSecond * 15;
endpointer_.set_speech_input_complete_silence_length(cont_timeout_us);
endpointer_.set_long_speech_length(0); // Use only a single timeout.
}
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.h b/chromium/content/browser/speech/speech_recognizer_impl.h
index f60802d4de7..ff2484beed0 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.h
+++ b/chromium/content/browser/speech/speech_recognizer_impl.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_H_
#define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/speech/endpointer/endpointer.h"
#include "content/browser/speech/speech_recognition_engine.h"
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_android.cc b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
index 1b8a07e37d7..5337da1cb2d 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_android.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
@@ -4,6 +4,9 @@
#include "content/browser/speech/speech_recognizer_impl_android.h"
+#include <stddef.h>
+
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
@@ -98,11 +101,14 @@ bool SpeechRecognizerImplAndroid::IsCapturingAudio() const {
return state_ == STATE_CAPTURING_AUDIO;
}
-void SpeechRecognizerImplAndroid::OnAudioStart(JNIEnv* env, jobject obj) {
+void SpeechRecognizerImplAndroid::OnAudioStart(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &SpeechRecognizerImplAndroid::OnAudioStart, this,
- static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognizerImplAndroid::OnAudioStart, this, nullptr,
+ nullptr));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -110,33 +116,38 @@ void SpeechRecognizerImplAndroid::OnAudioStart(JNIEnv* env, jobject obj) {
listener()->OnAudioStart(session_id());
}
-void SpeechRecognizerImplAndroid::OnSoundStart(JNIEnv* env, jobject obj) {
+void SpeechRecognizerImplAndroid::OnSoundStart(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &SpeechRecognizerImplAndroid::OnSoundStart, this,
- static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognizerImplAndroid::OnSoundStart, this, nullptr,
+ nullptr));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::IO);
listener()->OnSoundStart(session_id());
}
-void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env, jobject obj) {
+void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &SpeechRecognizerImplAndroid::OnSoundEnd, this,
- static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognizerImplAndroid::OnSoundEnd,
+ this, nullptr, nullptr));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::IO);
listener()->OnSoundEnd(session_id());
}
-void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) {
+void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &SpeechRecognizerImplAndroid::OnAudioEnd, this,
- static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognizerImplAndroid::OnAudioEnd,
+ this, nullptr, nullptr));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -145,8 +156,12 @@ void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) {
listener()->OnAudioEnd(session_id());
}
-void SpeechRecognizerImplAndroid::OnRecognitionResults(JNIEnv* env, jobject obj,
- jobjectArray strings, jfloatArray floats, jboolean provisional) {
+void SpeechRecognizerImplAndroid::OnRecognitionResults(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobjectArray>& strings,
+ const JavaParamRef<jfloatArray>& floats,
+ jboolean provisional) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<base::string16> options;
AppendJavaStringArrayToStringVector(env, strings, &options);
@@ -173,12 +188,15 @@ void SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread(
listener()->OnRecognitionResults(session_id(), results);
}
-void SpeechRecognizerImplAndroid::OnRecognitionError(JNIEnv* env,
- jobject obj, jint error) {
+void SpeechRecognizerImplAndroid::OnRecognitionError(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint error) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &SpeechRecognizerImplAndroid::OnRecognitionError, this,
- static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL), error));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognizerImplAndroid::OnRecognitionError, this,
+ nullptr, nullptr, error));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -187,12 +205,14 @@ void SpeechRecognizerImplAndroid::OnRecognitionError(JNIEnv* env,
listener()->OnRecognitionError(session_id(), SpeechRecognitionError(code));
}
-void SpeechRecognizerImplAndroid::OnRecognitionEnd(JNIEnv* env,
- jobject obj) {
+void SpeechRecognizerImplAndroid::OnRecognitionEnd(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &SpeechRecognizerImplAndroid::OnRecognitionEnd, this,
- static_cast<JNIEnv*>(NULL), static_cast<jobject>(NULL)));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SpeechRecognizerImplAndroid::OnRecognitionEnd, this,
+ nullptr, nullptr));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_android.h b/chromium/content/browser/speech/speech_recognizer_impl_android.h
index 9472ca6a956..e51a9e4801d 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_android.h
+++ b/chromium/content/browser/speech/speech_recognizer_impl_android.h
@@ -8,6 +8,7 @@
#include <jni.h>
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/speech/speech_recognizer.h"
@@ -31,14 +32,23 @@ class CONTENT_EXPORT SpeechRecognizerImplAndroid : public SpeechRecognizer {
bool IsCapturingAudio() const override;
// Called from Java methods via JNI.
- void OnAudioStart(JNIEnv* env, jobject obj);
- void OnSoundStart(JNIEnv* env, jobject obj);
- void OnSoundEnd(JNIEnv* env, jobject obj);
- void OnAudioEnd(JNIEnv* env, jobject obj);
- void OnRecognitionResults(JNIEnv* env, jobject obj, jobjectArray strings,
- jfloatArray floats, jboolean interim);
- void OnRecognitionError(JNIEnv* env, jobject obj, jint error);
- void OnRecognitionEnd(JNIEnv* env, jobject obj);
+ void OnAudioStart(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void OnSoundStart(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void OnSoundEnd(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void OnAudioEnd(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void OnRecognitionResults(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobjectArray>& strings,
+ const base::android::JavaParamRef<jfloatArray>& floats,
+ jboolean interim);
+ void OnRecognitionError(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint error);
+ void OnRecognitionEnd(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
static bool RegisterSpeechRecognizer(JNIEnv* env);
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
index 320ca8130ac..300e4054853 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
#include "content/browser/browser_thread_impl.h"
@@ -164,7 +167,7 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
void FillPacketWithTestWaveform() {
// Fill the input with a simple pattern, a 125Hz sawtooth waveform.
for (size_t i = 0; i < audio_packet_.size(); ++i)
- audio_packet_[i] = static_cast<uint8>(i);
+ audio_packet_[i] = static_cast<uint8_t>(i);
CopyPacketToAudioBus();
}
@@ -193,7 +196,7 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
SpeechRecognitionErrorCode error_;
net::TestURLFetcherFactory url_fetcher_factory_;
TestAudioInputControllerFactory audio_input_controller_factory_;
- std::vector<uint8> audio_packet_;
+ std::vector<uint8_t> audio_packet_;
scoped_ptr<media::AudioBus> audio_bus_;
int bytes_per_sample_;
float volume_;
diff --git a/chromium/content/browser/ssl/ssl_cert_error_handler.cc b/chromium/content/browser/ssl/ssl_cert_error_handler.cc
index 9ec7885d58d..54b165d9d49 100644
--- a/chromium/content/browser/ssl/ssl_cert_error_handler.cc
+++ b/chromium/content/browser/ssl/ssl_cert_error_handler.cc
@@ -15,19 +15,12 @@ SSLCertErrorHandler::SSLCertErrorHandler(
const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
const GURL& url,
- int render_process_id,
- int render_frame_id,
const net::SSLInfo& ssl_info,
bool fatal)
- : SSLErrorHandler(delegate,
- resource_type,
- url,
- render_process_id,
- render_frame_id),
+ : SSLErrorHandler(delegate, resource_type, url),
ssl_info_(ssl_info),
cert_error_(net::MapCertStatusToNetError(ssl_info.cert_status)),
- fatal_(fatal) {
-}
+ fatal_(fatal) {}
SSLCertErrorHandler* SSLCertErrorHandler::AsSSLCertErrorHandler() {
return this;
diff --git a/chromium/content/browser/ssl/ssl_cert_error_handler.h b/chromium/content/browser/ssl/ssl_cert_error_handler.h
index e3c4378f167..e5d098b333d 100644
--- a/chromium/content/browser/ssl/ssl_cert_error_handler.h
+++ b/chromium/content/browser/ssl/ssl_cert_error_handler.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/ssl/ssl_error_handler.h"
#include "net/ssl/ssl_info.h"
@@ -22,8 +23,6 @@ class SSLCertErrorHandler : public SSLErrorHandler {
SSLCertErrorHandler(const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
const GURL& url,
- int render_process_id,
- int render_frame_id,
const net::SSLInfo& ssl_info,
bool fatal);
diff --git a/chromium/content/browser/ssl/ssl_client_auth_handler.cc b/chromium/content/browser/ssl/ssl_client_auth_handler.cc
index e52864398b9..3c1e42cb1f7 100644
--- a/chromium/content/browser/ssl/ssl_client_auth_handler.cc
+++ b/chromium/content/browser/ssl/ssl_client_auth_handler.cc
@@ -4,8 +4,11 @@
#include "content/browser/ssl/ssl_client_auth_handler.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/content_browser_client.h"
@@ -69,7 +72,7 @@ void SelectCertificateOnUIThread(
return;
GetContentClient()->browser()->SelectClientCertificate(
- web_contents, cert_request_info, delegate.Pass());
+ web_contents, cert_request_info, std::move(delegate));
}
} // namespace
@@ -82,7 +85,7 @@ class SSLClientAuthHandler::Core : public base::RefCountedThreadSafe<Core> {
scoped_ptr<net::ClientCertStore> client_cert_store,
net::SSLCertRequestInfo* cert_request_info)
: handler_(handler),
- client_cert_store_(client_cert_store.Pass()),
+ client_cert_store_(std::move(client_cert_store)),
cert_request_info_(cert_request_info) {}
bool has_client_cert_store() const { return client_cert_store_; }
@@ -128,7 +131,7 @@ SSLClientAuthHandler::SSLClientAuthHandler(
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- core_ = new Core(weak_factory_.GetWeakPtr(), client_cert_store.Pass(),
+ core_ = new Core(weak_factory_.GetWeakPtr(), std::move(client_cert_store),
cert_request_info_.get());
}
diff --git a/chromium/content/browser/ssl/ssl_client_auth_handler.h b/chromium/content/browser/ssl/ssl_client_auth_handler.h
index b9c2447c7f4..72c6cbd4dea 100644
--- a/chromium/content/browser/ssl/ssl_client_auth_handler.h
+++ b/chromium/content/browser/ssl/ssl_client_auth_handler.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_H_
#define CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_H_
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/content/browser/ssl/ssl_error_handler.cc b/chromium/content/browser/ssl/ssl_error_handler.cc
index 45b6dfd830c..40b2b564506 100644
--- a/chromium/content/browser/ssl/ssl_error_handler.cc
+++ b/chromium/content/browser/ssl/ssl_error_handler.cc
@@ -20,13 +20,9 @@ namespace content {
SSLErrorHandler::SSLErrorHandler(const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
- const GURL& url,
- int render_process_id,
- int render_frame_id)
+ const GURL& url)
: manager_(NULL),
delegate_(delegate),
- render_process_id_(render_process_id),
- render_frame_id_(render_frame_id),
request_url_(url),
resource_type_(resource_type),
request_has_been_notified_(false) {
@@ -55,13 +51,11 @@ SSLCertErrorHandler* SSLErrorHandler::AsSSLCertErrorHandler() {
return NULL;
}
-void SSLErrorHandler::Dispatch() {
+void SSLErrorHandler::Dispatch(
+ const base::Callback<WebContents*(void)>& web_contents_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- WebContents* web_contents = NULL;
- RenderFrameHost* render_frame_host =
- RenderFrameHost::FromID(render_process_id_, render_frame_id_);
- web_contents = WebContents::FromRenderFrameHost(render_frame_host);
+ WebContents* web_contents = web_contents_getter.Run();
if (!web_contents) {
// We arrived on the UI thread, but the tab we're looking for is no longer
@@ -116,6 +110,11 @@ void SSLErrorHandler::TakeNoAction() {
base::Bind(&SSLErrorHandler::CompleteTakeNoAction, this));
}
+SSLManager* SSLErrorHandler::GetManager() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return manager_;
+}
+
void SSLErrorHandler::CompleteCancelRequest(int error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/ssl/ssl_error_handler.h b/chromium/content/browser/ssl/ssl_error_handler.h
index 26fc147c3f4..658ec01a40d 100644
--- a/chromium/content/browser/ssl/ssl_error_handler.h
+++ b/chromium/content/browser/ssl/ssl_error_handler.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
@@ -25,6 +25,7 @@ namespace content {
class ResourceDispatcherHostImpl;
class SSLCertErrorHandler;
class SSLManager;
+class WebContents;
// An SSLErrorHandler carries information from the IO thread to the UI thread
// and is dispatched to the appropriate SSLManager when it arrives on the
@@ -65,7 +66,7 @@ class SSLErrorHandler : public base::RefCountedThreadSafe<SSLErrorHandler> {
// this error.
//
// Call on UI thread.
- void Dispatch();
+ void Dispatch(const base::Callback<WebContents*(void)>& web_contents_getter);
// Available on either thread.
const GURL& request_url() const { return request_url_; }
@@ -96,8 +97,9 @@ class SSLErrorHandler : public base::RefCountedThreadSafe<SSLErrorHandler> {
// call this.
void TakeNoAction();
- int render_process_id() const { return render_process_id_; }
- int render_frame_id() const { return render_frame_id_; }
+ // Returns the manager associated with this SSLErrorHandler.
+ // Should only be accessed on the UI thread.
+ SSLManager* GetManager() const;
protected:
friend class base::RefCountedThreadSafe<SSLErrorHandler>;
@@ -105,9 +107,7 @@ class SSLErrorHandler : public base::RefCountedThreadSafe<SSLErrorHandler> {
// Construct on the IO thread.
SSLErrorHandler(const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
- const GURL& url,
- int render_process_id,
- int render_frame_id);
+ const GURL& url);
virtual ~SSLErrorHandler();
@@ -137,11 +137,6 @@ class SSLErrorHandler : public base::RefCountedThreadSafe<SSLErrorHandler> {
// Call on the IO thread.
void CompleteTakeNoAction();
- // We use these members to find the correct SSLManager when we arrive on
- // the UI thread.
- int render_process_id_;
- int render_frame_id_;
-
// The URL that we requested.
// This read-only member can be accessed on any thread.
const GURL request_url_;
diff --git a/chromium/content/browser/ssl/ssl_manager.cc b/chromium/content/browser/ssl/ssl_manager.cc
index e4c71e3dc4e..ee764be6553 100644
--- a/chromium/content/browser/ssl/ssl_manager.cc
+++ b/chromium/content/browser/ssl/ssl_manager.cc
@@ -7,6 +7,7 @@
#include <set>
#include "base/bind.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/supports_user_data.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
@@ -51,8 +52,7 @@ void SSLManager::OnSSLCertificateError(
const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
const ResourceType resource_type,
const GURL& url,
- int render_process_id,
- int render_frame_id,
+ const base::Callback<WebContents*(void)>& web_contents_getter,
const net::SSLInfo& ssl_info,
bool fatal) {
DCHECK(delegate.get());
@@ -60,8 +60,6 @@ void SSLManager::OnSSLCertificateError(
<< net::MapCertStatusToNetError(ssl_info.cert_status)
<< " resource_type: " << resource_type
<< " url: " << url.spec()
- << " render_process_id: " << render_process_id
- << " render_frame_id: " << render_frame_id
<< " cert_status: " << std::hex << ssl_info.cert_status;
// A certificate error occurred. Construct a SSLCertErrorHandler object and
@@ -69,13 +67,23 @@ void SSLManager::OnSSLCertificateError(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&SSLCertErrorHandler::Dispatch,
- new SSLCertErrorHandler(delegate,
- resource_type,
- url,
- render_process_id,
- render_frame_id,
- ssl_info,
- fatal)));
+ new SSLCertErrorHandler(delegate, resource_type, url, ssl_info,
+ fatal),
+ web_contents_getter));
+}
+
+// static
+void SSLManager::OnSSLCertificateSubresourceError(
+ const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
+ const GURL& url,
+ int render_process_id,
+ int render_frame_id,
+ const net::SSLInfo& ssl_info,
+ bool fatal) {
+ OnSSLCertificateError(delegate, RESOURCE_TYPE_SUB_RESOURCE, url,
+ base::Bind(&WebContentsImpl::FromRenderFrameHostID,
+ render_process_id, render_frame_id),
+ ssl_info, fatal);
}
// static
@@ -127,11 +135,7 @@ void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) {
NotifyDidChangeVisibleSSLState();
}
-void SSLManager::DidDisplayInsecureContent() {
- UpdateEntry(controller_->GetLastCommittedEntry());
-}
-
-void SSLManager::DidRunInsecureContent(const std::string& security_origin) {
+void SSLManager::DidRunInsecureContent(const GURL& security_origin) {
NavigationEntryImpl* navigation_entry = controller_->GetLastCommittedEntry();
policy()->DidRunInsecureContent(navigation_entry, security_origin);
UpdateEntry(navigation_entry);
@@ -147,7 +151,6 @@ void SSLManager::DidLoadFromMemoryCache(
scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo(
details.url,
RESOURCE_TYPE_SUB_RESOURCE,
- details.pid,
details.cert_id,
details.cert_status));
@@ -160,7 +163,6 @@ void SSLManager::DidStartResourceResponse(
scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo(
details.url,
details.resource_type,
- details.origin_child_id,
details.ssl_cert_id,
details.ssl_cert_status));
diff --git a/chromium/content/browser/ssl/ssl_manager.h b/chromium/content/browser/ssl/ssl_manager.h
index 8128ee8e049..6a8377500ac 100644
--- a/chromium/content/browser/ssl/ssl_manager.h
+++ b/chromium/content/browser/ssl/ssl_manager.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/ssl/ssl_error_handler.h"
@@ -31,6 +31,7 @@ struct LoadCommittedDetails;
struct LoadFromMemoryCacheDetails;
struct ResourceRedirectDetails;
struct ResourceRequestDetails;
+struct SSLStatus;
// The SSLManager SSLManager controls the SSL UI elements in a WebContents. It
// listens for various events that influence when these elements should or
@@ -52,6 +53,16 @@ class CONTENT_EXPORT SSLManager {
const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
ResourceType resource_type,
const GURL& url,
+ const base::Callback<WebContents*(void)>& web_contents_getter,
+ const net::SSLInfo& ssl_info,
+ bool fatal);
+
+ // Same as the above, and only works for subresources. Prefer using
+ // OnSSLCertificateError whenever possible (ie when you have access to the
+ // WebContents).
+ static void OnSSLCertificateSubresourceError(
+ const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
+ const GURL& url,
int render_process_id,
int render_frame_id,
const net::SSLInfo& ssl_info,
@@ -78,8 +89,7 @@ class CONTENT_EXPORT SSLManager {
void DidReceiveResourceRedirect(const ResourceRedirectDetails& details);
// Insecure content entry point.
- void DidDisplayInsecureContent();
- void DidRunInsecureContent(const std::string& security_origin);
+ void DidRunInsecureContent(const GURL& security_origin);
private:
// Updates the NavigationEntry with our current state. This will
diff --git a/chromium/content/browser/ssl/ssl_policy.cc b/chromium/content/browser/ssl/ssl_policy.cc
index dab2a5aa1ec..06677dc25e9 100644
--- a/chromium/content/browser/ssl/ssl_policy.cc
+++ b/chromium/content/browser/ssl/ssl_policy.cc
@@ -105,7 +105,7 @@ void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) {
}
void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry,
- const std::string& security_origin) {
+ const GURL& security_origin) {
if (!entry)
return;
@@ -113,20 +113,16 @@ void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry,
if (!site_instance)
return;
- backend_->HostRanInsecureContent(GURL(security_origin).host(),
+ backend_->HostRanInsecureContent(security_origin.host(),
site_instance->GetProcess()->GetID());
}
void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) {
- // TODO(abarth): This mechanism is wrong. What we should be doing is sending
- // this information back through WebKit and out some FrameLoaderClient
- // methods.
-
- if (net::IsCertStatusError(info->ssl_cert_status())) {
- backend_->HostRanInsecureContent(info->url().host(), info->child_id());
- } else if (info->ssl_cert_id() && info->url().SchemeIsCryptographic()) {
- // If the scheme is https: or wss: *and* the security info for the cert has
- // been set (i.e. the cert id is not 0), revoke any previous decisions that
+ if (info->ssl_cert_id() && info->url().SchemeIsCryptographic() &&
+ !net::IsCertStatusError(info->ssl_cert_status())) {
+ // If the scheme is https: or wss: *and* the security info for the
+ // cert has been set (i.e. the cert id is not 0) and the cert did
+ // not have any errors, revoke any previous decisions that
// have occurred. If the cert info has not been set, do nothing since it
// isn't known if the connection was actually a valid connection or if it
// had a cert error.
@@ -232,17 +228,11 @@ void SSLPolicy::OnCertErrorInternal(SSLCertErrorHandler* handler,
CertificateRequestResultType result =
CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE;
GetContentClient()->browser()->AllowCertificateError(
- handler->render_process_id(),
- handler->render_frame_id(),
- handler->cert_error(),
- handler->ssl_info(),
- handler->request_url(),
- handler->resource_type(),
- overridable,
- strict_enforcement,
+ handler->GetManager()->controller()->GetWebContents(),
+ handler->cert_error(), handler->ssl_info(), handler->request_url(),
+ handler->resource_type(), overridable, strict_enforcement,
expired_previous_decision,
- base::Bind(&SSLPolicy::OnAllowCertificate,
- base::Unretained(this),
+ base::Bind(&SSLPolicy::OnAllowCertificate, base::Unretained(this),
make_scoped_refptr(handler)),
&result);
switch (result) {
diff --git a/chromium/content/browser/ssl/ssl_policy.h b/chromium/content/browser/ssl/ssl_policy.h
index 2855a1bbb8c..624d8bbb534 100644
--- a/chromium/content/browser/ssl/ssl_policy.h
+++ b/chromium/content/browser/ssl/ssl_policy.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/security_style.h"
@@ -36,7 +37,7 @@ class SSLPolicy {
void OnCertError(SSLCertErrorHandler* handler);
void DidRunInsecureContent(NavigationEntryImpl* entry,
- const std::string& security_origin);
+ const GURL& security_origin);
// We have started a resource request with the given info.
void OnRequestStarted(SSLRequestInfo* info);
diff --git a/chromium/content/browser/ssl/ssl_policy_backend.h b/chromium/content/browser/ssl/ssl_policy_backend.h
index 15c514a9cad..3de34623fe7 100644
--- a/chromium/content/browser/ssl/ssl_policy_backend.h
+++ b/chromium/content/browser/ssl/ssl_policy_backend.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "content/public/browser/ssl_host_state_delegate.h"
#include "net/cert/cert_status_flags.h"
diff --git a/chromium/content/browser/ssl/ssl_request_info.cc b/chromium/content/browser/ssl/ssl_request_info.cc
index f22376acff2..4917a0ae4a0 100644
--- a/chromium/content/browser/ssl/ssl_request_info.cc
+++ b/chromium/content/browser/ssl/ssl_request_info.cc
@@ -8,12 +8,10 @@ namespace content {
SSLRequestInfo::SSLRequestInfo(const GURL& url,
ResourceType resource_type,
- int child_id,
int ssl_cert_id,
net::CertStatus ssl_cert_status)
: url_(url),
resource_type_(resource_type),
- child_id_(child_id),
ssl_cert_id_(ssl_cert_id),
ssl_cert_status_(ssl_cert_status) {
}
diff --git a/chromium/content/browser/ssl/ssl_request_info.h b/chromium/content/browser/ssl/ssl_request_info.h
index 9f50448f4ed..f07f0f86959 100644
--- a/chromium/content/browser/ssl/ssl_request_info.h
+++ b/chromium/content/browser/ssl/ssl_request_info.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/public/common/resource_type.h"
#include "net/cert/cert_status_flags.h"
@@ -15,19 +16,17 @@
namespace content {
// SSLRequestInfo wraps up the information SSLPolicy needs about a request in
-// order to update our security IU. SSLRequestInfo is RefCounted in case we
+// order to update our security UI. SSLRequestInfo is RefCounted in case we
// need to deal with the request asynchronously.
class SSLRequestInfo : public base::RefCounted<SSLRequestInfo> {
public:
SSLRequestInfo(const GURL& url,
ResourceType resource_type,
- int child_id,
int ssl_cert_id,
net::CertStatus ssl_cert_status);
const GURL& url() const { return url_; }
ResourceType resource_type() const { return resource_type_; }
- int child_id() const { return child_id_; }
int ssl_cert_id() const { return ssl_cert_id_; }
net::CertStatus ssl_cert_status() const { return ssl_cert_status_; }
@@ -38,7 +37,6 @@ class SSLRequestInfo : public base::RefCounted<SSLRequestInfo> {
GURL url_;
ResourceType resource_type_;
- int child_id_;
int ssl_cert_id_;
net::CertStatus ssl_cert_status_;
diff --git a/chromium/content/browser/startup_task_runner.h b/chromium/content/browser/startup_task_runner.h
index 80e5627803f..8f70ed2114f 100644
--- a/chromium/content/browser/startup_task_runner.h
+++ b/chromium/content/browser/startup_task_runner.h
@@ -8,6 +8,7 @@
#include <list>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
diff --git a/chromium/content/browser/storage_partition_impl.cc b/chromium/content/browser/storage_partition_impl.cc
index 7bcd5cf8bc7..0afff15d733 100644
--- a/chromium/content/browser/storage_partition_impl.cc
+++ b/chromium/content/browser/storage_partition_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/storage_partition_impl.h"
+#include <stddef.h>
+
#include <set>
#include <vector>
@@ -201,7 +203,7 @@ void ClearSessionStorageOnUIThread(
} // namespace
// Static.
-int StoragePartitionImpl::GenerateQuotaClientMask(uint32 remove_mask) {
+int StoragePartitionImpl::GenerateQuotaClientMask(uint32_t remove_mask) {
int quota_client_mask = 0;
if (remove_mask & StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS)
@@ -224,16 +226,15 @@ int StoragePartitionImpl::GenerateQuotaClientMask(uint32 remove_mask) {
//
// Most of the operations in this class are done on IO thread.
struct StoragePartitionImpl::QuotaManagedDataDeletionHelper {
- QuotaManagedDataDeletionHelper(uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ QuotaManagedDataDeletionHelper(uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
const base::Closure& callback)
: remove_mask(remove_mask),
quota_storage_remove_mask(quota_storage_remove_mask),
storage_origin(storage_origin),
callback(callback),
- task_count(0) {
- }
+ task_count(0) {}
void IncrementTaskCountOnIO();
void DecrementTaskCountOnIO();
@@ -255,8 +256,8 @@ struct StoragePartitionImpl::QuotaManagedDataDeletionHelper {
storage::StorageType quota_storage_type);
// All of these data are accessed on IO thread.
- uint32 remove_mask;
- uint32 quota_storage_remove_mask;
+ uint32_t remove_mask;
+ uint32_t quota_storage_remove_mask;
GURL storage_origin;
const base::Closure callback;
int task_count;
@@ -273,14 +274,13 @@ struct StoragePartitionImpl::QuotaManagedDataDeletionHelper {
// forwarded and updated on each (sub) deletion's callback. The instance is
// finally destroyed when deletion completes (and |callback| is invoked).
struct StoragePartitionImpl::DataDeletionHelper {
- DataDeletionHelper(uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ DataDeletionHelper(uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const base::Closure& callback)
- : remove_mask(remove_mask),
- quota_storage_remove_mask(quota_storage_remove_mask),
- callback(callback),
- task_count(0) {
- }
+ : remove_mask(remove_mask),
+ quota_storage_remove_mask(quota_storage_remove_mask),
+ callback(callback),
+ task_count(0) {}
void IncrementTaskCountOnUI();
void DecrementTaskCountOnUI();
@@ -306,8 +306,8 @@ struct StoragePartitionImpl::DataDeletionHelper {
const StoragePartition::OriginMatcherFunction& origin_matcher,
const base::Closure& callback);
- uint32 remove_mask;
- uint32 quota_storage_remove_mask;
+ uint32_t remove_mask;
+ uint32_t quota_storage_remove_mask;
// Accessed on UI thread.
const base::Closure callback;
@@ -592,8 +592,8 @@ BackgroundSyncContextImpl* StoragePartitionImpl::GetBackgroundSyncContext() {
}
void StoragePartitionImpl::ClearDataImpl(
- uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
const OriginMatcherFunction& origin_matcher,
net::URLRequestContextGetter* rq_context,
@@ -850,8 +850,8 @@ void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread(
}
void StoragePartitionImpl::ClearDataForOrigin(
- uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
net::URLRequestContextGetter* request_context_getter,
const base::Closure& callback) {
@@ -867,8 +867,8 @@ void StoragePartitionImpl::ClearDataForOrigin(
}
void StoragePartitionImpl::ClearData(
- uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
const OriginMatcherFunction& origin_matcher,
const base::Time begin,
diff --git a/chromium/content/browser/storage_partition_impl.h b/chromium/content/browser/storage_partition_impl.h
index 37ee1f8b44f..ece0a8ebff6 100644
--- a/chromium/content/browser/storage_partition_impl.h
+++ b/chromium/content/browser/storage_partition_impl.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_STORAGE_PARTITION_IMPL_H_
#define CONTENT_BROWSER_STORAGE_PARTITION_IMPL_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/background_sync/background_sync_context_impl.h"
@@ -31,7 +34,7 @@ class StoragePartitionImpl : public StoragePartition {
// Quota managed data uses a different bitmask for types than
// StoragePartition uses. This method generates that mask.
- CONTENT_EXPORT static int GenerateQuotaClientMask(uint32 remove_mask);
+ CONTENT_EXPORT static int GenerateQuotaClientMask(uint32_t remove_mask);
CONTENT_EXPORT void OverrideQuotaManagerForTesting(
storage::QuotaManager* quota_manager);
@@ -58,13 +61,13 @@ class StoragePartitionImpl : public StoragePartition {
PlatformNotificationContextImpl* GetPlatformNotificationContext() override;
BackgroundSyncContextImpl* GetBackgroundSyncContext() override;
- void ClearDataForOrigin(uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ void ClearDataForOrigin(uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
net::URLRequestContextGetter* request_context_getter,
const base::Closure& callback) override;
- void ClearData(uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ void ClearData(uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
const OriginMatcherFunction& origin_matcher,
const base::Time begin,
@@ -82,6 +85,8 @@ class StoragePartitionImpl : public StoragePartition {
struct QuotaManagedDataDeletionHelper;
private:
+ friend class BackgroundSyncManagerTest;
+ friend class BackgroundSyncServiceImplTest;
friend class StoragePartitionImplMap;
FRIEND_TEST_ALL_PREFIXES(StoragePartitionShaderClearTest, ClearShaderCache);
FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest,
@@ -144,8 +149,8 @@ class StoragePartitionImpl : public StoragePartition {
PlatformNotificationContextImpl* platform_notification_context,
BackgroundSyncContextImpl* background_sync_context);
- void ClearDataImpl(uint32 remove_mask,
- uint32 quota_storage_remove_mask,
+ void ClearDataImpl(uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
const GURL& remove_origin,
const OriginMatcherFunction& origin_matcher,
net::URLRequestContextGetter* rq_context,
diff --git a/chromium/content/browser/storage_partition_impl_map.cc b/chromium/content/browser/storage_partition_impl_map.cc
index b36ea6c06b6..75c257ac081 100644
--- a/chromium/content/browser/storage_partition_impl_map.cc
+++ b/chromium/content/browser/storage_partition_impl_map.cc
@@ -4,12 +4,16 @@
#include "content/browser/storage_partition_impl_map.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/callback.h"
+#include "base/command_line.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -17,12 +21,14 @@
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "build/build_config.h"
#include "content/browser/appcache/appcache_interceptor.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/resource_context_impl.h"
+#include "content/browser/service_worker/foreign_fetch_request_handler.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/streams/stream.h"
@@ -37,6 +43,7 @@
#include "content/public/browser/navigator_connect_service_factory.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_constants.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "crypto/sha2.h"
#include "net/url_request/url_request_context.h"
@@ -397,6 +404,10 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
partition_path);
partitions_[partition_config] = partition;
+ partition->GetQuotaManager()->SetTemporaryStorageEvictionPolicy(
+ GetContentClient()->browser()->GetTemporaryStorageEvictionPolicy(
+ browser_context_));
+
ChromeBlobStorageContext* blob_storage_context =
ChromeBlobStorageContext::GetFor(browser_context_);
StreamContext* stream_context = StreamContext::GetFor(browser_context_);
@@ -415,7 +426,6 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
URLDataManagerBackend::CreateProtocolHandler(
browser_context_->GetResourceContext(),
browser_context_->IsOffTheRecord(),
- partition->GetAppCacheService(),
blob_storage_context).release());
std::vector<std::string> additional_webui_schemes;
GetContentClient()->browser()->GetAdditionalWebUISchemes(
@@ -429,7 +439,6 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
URLDataManagerBackend::CreateProtocolHandler(
browser_context_->GetResourceContext(),
browser_context_->IsOffTheRecord(),
- partition->GetAppCacheService(),
blob_storage_context).release());
}
protocol_handlers[kChromeDevToolsScheme] =
@@ -441,23 +450,26 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
request_interceptors.push_back(
ServiceWorkerRequestHandler::CreateInterceptor(
browser_context_->GetResourceContext()).release());
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures)) {
+ request_interceptors.push_back(
+ ForeignFetchRequestHandler::CreateInterceptor(
+ browser_context_->GetResourceContext())
+ .release());
+ }
request_interceptors.push_back(new AppCacheInterceptor());
// These calls must happen after StoragePartitionImpl::Create().
if (partition_domain.empty()) {
partition->SetURLRequestContext(
GetContentClient()->browser()->CreateRequestContext(
- browser_context_,
- &protocol_handlers,
- request_interceptors.Pass()));
+ browser_context_, &protocol_handlers,
+ std::move(request_interceptors)));
} else {
partition->SetURLRequestContext(
GetContentClient()->browser()->CreateRequestContextForStoragePartition(
- browser_context_,
- partition->GetPath(),
- in_memory,
- &protocol_handlers,
- request_interceptors.Pass()));
+ browser_context_, partition->GetPath(), in_memory,
+ &protocol_handlers, std::move(request_interceptors)));
}
partition->SetMediaURLRequestContext(
partition_domain.empty() ?
diff --git a/chromium/content/browser/storage_partition_impl_map_unittest.cc b/chromium/content/browser/storage_partition_impl_map_unittest.cc
index c88fb538764..2659b8e3374 100644
--- a/chromium/content/browser/storage_partition_impl_map_unittest.cc
+++ b/chromium/content/browser/storage_partition_impl_map_unittest.cc
@@ -4,8 +4,11 @@
#include "content/browser/storage_partition_impl_map.h"
+#include <utility>
+
#include "base/files/file_util.h"
#include "base/run_loop.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -62,8 +65,8 @@ TEST(StoragePartitionConfigTest, OperatorLess) {
}
TEST(StoragePartitionImplMapTest, GarbageCollect) {
- base::MessageLoop message_loop;
TestBrowserContext browser_context;
+ base::MessageLoop message_loop;
StoragePartitionImplMap storage_partition_impl_map(&browser_context);
scoped_ptr<base::hash_set<base::FilePath> > active_paths(
@@ -81,9 +84,10 @@ TEST(StoragePartitionImplMapTest, GarbageCollect) {
ASSERT_TRUE(base::CreateDirectory(inactive_path));
base::RunLoop run_loop;
- storage_partition_impl_map.GarbageCollect(
- active_paths.Pass(), run_loop.QuitClosure());
+ storage_partition_impl_map.GarbageCollect(std::move(active_paths),
+ run_loop.QuitClosure());
run_loop.Run();
+ BrowserThread::GetBlockingPool()->FlushForTesting();
EXPECT_TRUE(base::PathExists(active_path));
EXPECT_FALSE(base::PathExists(inactive_path));
diff --git a/chromium/content/browser/storage_partition_impl_unittest.cc b/chromium/content/browser/storage_partition_impl_unittest.cc
index 79e33beb250..e4b790967b2 100644
--- a/chromium/content/browser/storage_partition_impl_unittest.cc
+++ b/chromium/content/browser/storage_partition_impl_unittest.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/files/file_util.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -19,7 +23,7 @@
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/test_completion_callback.h"
-#include "net/cookies/cookie_monster.h"
+#include "net/cookies/cookie_store.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "storage/browser/quota/quota_manager.h"
@@ -56,7 +60,7 @@ const storage::StorageType kPersistent = storage::kStorageTypePersistent;
const storage::QuotaClient::ID kClientFile = storage::QuotaClient::kFileSystem;
-const uint32 kAllQuotaRemoveMask =
+const uint32_t kAllQuotaRemoveMask =
StoragePartition::REMOVE_DATA_MASK_APPCACHE |
StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS |
StoragePartition::REMOVE_DATA_MASK_INDEXEDDB |
@@ -81,7 +85,7 @@ class AwaitCompletionHelper {
void Notify() {
if (start_) {
DCHECK(!already_quit_);
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
start_ = false;
} else {
DCHECK(!already_quit_);
@@ -101,15 +105,15 @@ class AwaitCompletionHelper {
class RemoveCookieTester {
public:
explicit RemoveCookieTester(TestBrowserContext* context)
- : get_cookie_success_(false), monster_(NULL) {
- SetMonster(context->GetRequestContext()->GetURLRequestContext()->
- cookie_store()->GetCookieMonster());
- }
+ : get_cookie_success_(false),
+ cookie_store_(context->GetRequestContext()
+ ->GetURLRequestContext()
+ ->cookie_store()) {}
// Returns true, if the given cookie exists in the cookie store.
bool ContainsCookie() {
get_cookie_success_ = false;
- monster_->GetCookiesWithOptionsAsync(
+ cookie_store_->GetCookiesWithOptionsAsync(
kOrigin1, net::CookieOptions(),
base::Bind(&RemoveCookieTester::GetCookieCallback,
base::Unretained(this)));
@@ -118,18 +122,13 @@ class RemoveCookieTester {
}
void AddCookie() {
- monster_->SetCookieWithOptionsAsync(
+ cookie_store_->SetCookieWithOptionsAsync(
kOrigin1, "A=1", net::CookieOptions(),
base::Bind(&RemoveCookieTester::SetCookieCallback,
base::Unretained(this)));
await_completion_.BlockUntilNotified();
}
- protected:
- void SetMonster(net::CookieStore* monster) {
- monster_ = monster;
- }
-
private:
void GetCookieCallback(const std::string& cookies) {
if (cookies == "A=1") {
@@ -148,7 +147,7 @@ class RemoveCookieTester {
bool get_cookie_success_;
AwaitCompletionHelper await_completion_;
- net::CookieStore* monster_;
+ net::CookieStore* cookie_store_;
DISALLOW_COPY_AND_ASSIGN(RemoveCookieTester);
};
@@ -299,7 +298,7 @@ void ClearCookies(content::StoragePartition* partition,
delete_begin, delete_end, run_loop->QuitClosure());
}
-void ClearStuff(uint32 remove_mask,
+void ClearStuff(uint32_t remove_mask,
content::StoragePartition* partition,
const base::Time delete_begin,
const base::Time delete_end,
diff --git a/chromium/content/browser/streams/stream.cc b/chromium/content/browser/streams/stream.cc
index 3f4ae68083e..d3a3ec40255 100644
--- a/chromium/content/browser/streams/stream.cc
+++ b/chromium/content/browser/streams/stream.cc
@@ -168,7 +168,7 @@ Stream::StreamState Stream::ReadRawData(net::IOBuffer* buf,
scoped_ptr<StreamHandle> Stream::CreateHandle() {
CHECK(!stream_handle_);
stream_handle_ = new StreamHandleImpl(weak_ptr_factory_.GetWeakPtr());
- return scoped_ptr<StreamHandle>(stream_handle_).Pass();
+ return scoped_ptr<StreamHandle>(stream_handle_);
}
void Stream::CloseHandle() {
diff --git a/chromium/content/browser/streams/stream.h b/chromium/content/browser/streams/stream.h
index 27788b305a2..3f3d06a6209 100644
--- a/chromium/content/browser/streams/stream.h
+++ b/chromium/content/browser/streams/stream.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_STREAMS_STREAM_H_
#define CONTENT_BROWSER_STREAMS_STREAM_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/byte_stream.h"
diff --git a/chromium/content/browser/streams/stream_handle_impl.cc b/chromium/content/browser/streams/stream_handle_impl.cc
index ba4dee2a490..7e2d771107a 100644
--- a/chromium/content/browser/streams/stream_handle_impl.cc
+++ b/chromium/content/browser/streams/stream_handle_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/streams/stream_handle_impl.h"
+#include <stddef.h>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/thread_task_runner_handle.h"
diff --git a/chromium/content/browser/streams/stream_registry.h b/chromium/content/browser/streams/stream_registry.h
index 05c53100f04..c7b31ab7792 100644
--- a/chromium/content/browser/streams/stream_registry.h
+++ b/chromium/content/browser/streams/stream_registry.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_STREAMS_STREAM_REGISTRY_H_
#define CONTENT_BROWSER_STREAMS_STREAM_REGISTRY_H_
+#include <stddef.h>
+
#include <map>
#include <set>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/non_thread_safe.h"
#include "content/browser/streams/stream_register_observer.h"
diff --git a/chromium/content/browser/streams/stream_unittest.cc b/chromium/content/browser/streams/stream_unittest.cc
index eb83357f9fe..af2b0034727 100644
--- a/chromium/content/browser/streams/stream_unittest.cc
+++ b/chromium/content/browser/streams/stream_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include "base/message_loop/message_loop.h"
#include "base/test/test_simple_task_runner.h"
#include "content/browser/streams/stream.h"
diff --git a/chromium/content/browser/streams/stream_url_request_job.cc b/chromium/content/browser/streams/stream_url_request_job.cc
index d2bce89aca6..e26fe35a41a 100644
--- a/chromium/content/browser/streams/stream_url_request_job.cc
+++ b/chromium/content/browser/streams/stream_url_request_job.cc
@@ -40,8 +40,6 @@ StreamURLRequestJob::~StreamURLRequestJob() {
}
void StreamURLRequestJob::OnDataAvailable(Stream* stream) {
- // Clear the IO_PENDING status.
- SetStatus(net::URLRequestStatus());
// Do nothing if pending_buffer_ is empty, i.e. there's no ReadRawData()
// operation waiting for IO completion.
if (!pending_buffer_.get())
@@ -50,24 +48,22 @@ void StreamURLRequestJob::OnDataAvailable(Stream* stream) {
// pending_buffer_ is set to the IOBuffer instance provided to ReadRawData()
// by URLRequestJob.
- int bytes_read;
- switch (stream_->ReadRawData(
- pending_buffer_.get(), pending_buffer_size_, &bytes_read)) {
+ int result = 0;
+ switch (stream_->ReadRawData(pending_buffer_.get(), pending_buffer_size_,
+ &result)) {
case Stream::STREAM_HAS_DATA:
- DCHECK_GT(bytes_read, 0);
+ DCHECK_GT(result, 0);
break;
case Stream::STREAM_COMPLETE:
- // Ensure this. Calling NotifyReadComplete call with 0 signals
- // completion.
- bytes_read = 0;
+ // Ensure ReadRawData gives net::OK.
+ DCHECK_EQ(net::OK, result);
break;
case Stream::STREAM_EMPTY:
NOTREACHED();
break;
case Stream::STREAM_ABORTED:
// Handle this as connection reset.
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_CONNECTION_RESET));
+ result = net::ERR_CONNECTION_RESET;
break;
}
@@ -76,8 +72,9 @@ void StreamURLRequestJob::OnDataAvailable(Stream* stream) {
pending_buffer_ = NULL;
pending_buffer_size_ = 0;
- total_bytes_read_ += bytes_read;
- NotifyReadComplete(bytes_read);
+ if (result > 0)
+ total_bytes_read_ += result;
+ ReadRawDataComplete(result);
}
// net::URLRequestJob methods.
@@ -94,43 +91,40 @@ void StreamURLRequestJob::Kill() {
ClearStream();
}
-bool StreamURLRequestJob::ReadRawData(net::IOBuffer* buf,
- int buf_size,
- int* bytes_read) {
+int StreamURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
+ // TODO(ellyjones): This is not right. The old code returned true here, but
+ // ReadRawData's old contract was to return true only for synchronous
+ // successes, which had the effect of treating all errors as synchronous EOFs.
+ // See https://crbug.com/508957
if (request_failed_)
- return true;
+ return 0;
DCHECK(buf);
- DCHECK(bytes_read);
int to_read = buf_size;
if (max_range_ && to_read) {
if (to_read + total_bytes_read_ > max_range_)
to_read = max_range_ - total_bytes_read_;
- if (to_read <= 0) {
- *bytes_read = 0;
- return true;
- }
+ if (to_read == 0)
+ return 0;
}
- switch (stream_->ReadRawData(buf, to_read, bytes_read)) {
+ int bytes_read = 0;
+ switch (stream_->ReadRawData(buf, to_read, &bytes_read)) {
case Stream::STREAM_HAS_DATA:
case Stream::STREAM_COMPLETE:
- total_bytes_read_ += *bytes_read;
- return true;
+ total_bytes_read_ += bytes_read;
+ return bytes_read;
case Stream::STREAM_EMPTY:
pending_buffer_ = buf;
pending_buffer_size_ = to_read;
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
- return false;
+ return net::ERR_IO_PENDING;
case Stream::STREAM_ABORTED:
// Handle this as connection reset.
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_CONNECTION_RESET));
- return false;
+ return net::ERR_CONNECTION_RESET;
}
NOTREACHED();
- return false;
+ return net::ERR_FAILED;
}
bool StreamURLRequestJob::GetMimeType(std::string* mime_type) const {
@@ -189,13 +183,8 @@ void StreamURLRequestJob::DidStart() {
void StreamURLRequestJob::NotifyFailure(int error_code) {
request_failed_ = true;
- // If we already return the headers on success, we can't change the headers
- // now. Instead, we just error out.
- if (headers_set_) {
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- error_code));
- return;
- }
+ // This method can only be called before headers are set.
+ DCHECK(!headers_set_);
// TODO(zork): Share these with BlobURLRequestJob.
net::HttpStatusCode status_code = net::HTTP_INTERNAL_SERVER_ERROR;
diff --git a/chromium/content/browser/streams/stream_url_request_job.h b/chromium/content/browser/streams/stream_url_request_job.h
index 05c95515c16..ded5fa729ca 100644
--- a/chromium/content/browser/streams/stream_url_request_job.h
+++ b/chromium/content/browser/streams/stream_url_request_job.h
@@ -5,10 +5,11 @@
#ifndef CONTENT_BROWSER_STREAMS_STREAM_URL_REQUEST_JOB_H_
#define CONTENT_BROWSER_STREAMS_STREAM_URL_REQUEST_JOB_H_
-#include "net/http/http_status_code.h"
-#include "net/url_request/url_request_job.h"
+#include "base/macros.h"
#include "content/browser/streams/stream_read_observer.h"
#include "content/common/content_export.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_job.h"
namespace content {
@@ -29,7 +30,7 @@ class CONTENT_EXPORT StreamURLRequestJob
// net::URLRequestJob methods.
void Start() override;
void Kill() override;
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;
bool GetMimeType(std::string* mime_type) const override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
int GetResponseCode() const override;
diff --git a/chromium/content/browser/system_message_window_win.cc b/chromium/content/browser/system_message_window_win.cc
index 08f44cb6a6d..0316fc7cb02 100644
--- a/chromium/content/browser/system_message_window_win.cc
+++ b/chromium/content/browser/system_message_window_win.cc
@@ -5,8 +5,10 @@
#include "content/browser/system_message_window_win.h"
#include <dbt.h>
+#include <stddef.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/system_monitor/system_monitor.h"
#include "base/win/wrapped_window_proc.h"
#include "media/audio/win/core_audio_util_win.h"
@@ -45,7 +47,7 @@ class SystemMessageWindowWin::DeviceNotifications {
filter.dbcc_size = sizeof(filter);
filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
bool core_audio_support = media::CoreAudioUtil::IsSupported();
- for (int i = 0; i < arraysize(kDeviceCategoryMap); ++i) {
+ for (size_t i = 0; i < arraysize(kDeviceCategoryMap); ++i) {
// If CoreAudio is supported, AudioDeviceListenerWin will
// take care of monitoring audio devices.
if (core_audio_support &&
@@ -63,7 +65,7 @@ class SystemMessageWindowWin::DeviceNotifications {
}
void Unregister() {
- for (int i = 0; i < arraysize(notifications_); ++i) {
+ for (size_t i = 0; i < arraysize(notifications_); ++i) {
if (notifications_[i]) {
UnregisterDeviceNotification(notifications_[i]);
notifications_[i] = NULL;
@@ -122,7 +124,7 @@ LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, LPARAM data) {
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(data);
if (device_interface->dbcc_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
return TRUE;
- for (int i = 0; i < arraysize(kDeviceCategoryMap); ++i) {
+ for (size_t i = 0; i < arraysize(kDeviceCategoryMap); ++i) {
if (kDeviceCategoryMap[i].device_category ==
device_interface->dbcc_classguid) {
device_type = kDeviceCategoryMap[i].device_type;
diff --git a/chromium/content/browser/system_message_window_win.h b/chromium/content/browser/system_message_window_win.h
index b29bad57c89..061db54908f 100644
--- a/chromium/content/browser/system_message_window_win.h
+++ b/chromium/content/browser/system_message_window_win.h
@@ -7,7 +7,7 @@
#include <windows.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/tcmalloc_internals_request_job.cc b/chromium/content/browser/tcmalloc_internals_request_job.cc
deleted file mode 100644
index e55df5e5141..00000000000
--- a/chromium/content/browser/tcmalloc_internals_request_job.cc
+++ /dev/null
@@ -1,121 +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/tcmalloc_internals_request_job.h"
-
-#include "base/allocator/allocator_extension.h"
-#include "content/common/child_process_messages.h"
-#include "content/public/browser/browser_child_process_host_iterator.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/common/process_type.h"
-#include "net/base/net_errors.h"
-
-namespace content {
-
-// static
-AboutTcmallocOutputs* AboutTcmallocOutputs::GetInstance() {
- return base::Singleton<AboutTcmallocOutputs>::get();
-}
-
-AboutTcmallocOutputs::AboutTcmallocOutputs() {}
-
-AboutTcmallocOutputs::~AboutTcmallocOutputs() {}
-
-void AboutTcmallocOutputs::OnStatsForChildProcess(
- base::ProcessId pid, int process_type,
- const std::string& output) {
- std::string header = GetProcessTypeNameInEnglish(process_type);
- base::StringAppendF(&header, " PID %d", static_cast<int>(pid));
- SetOutput(header, output);
-}
-
-void AboutTcmallocOutputs::SetOutput(const std::string& header,
- const std::string& output) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- outputs_[header] = output;
-}
-
-void AboutTcmallocOutputs::DumpToHTMLTable(std::string* data) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- data->append("<table width=\"100%\">\n");
- for (AboutTcmallocOutputsType::const_iterator oit = outputs_.begin();
- oit != outputs_.end();
- oit++) {
- data->append("<tr><td bgcolor=\"yellow\">");
- data->append(oit->first);
- data->append("</td></tr>\n");
- data->append("<tr><td><pre>\n");
- data->append(oit->second);
- data->append("</pre></td></tr>\n");
- }
- data->append("</table>\n");
- outputs_.clear();
-}
-
-TcmallocInternalsRequestJob::TcmallocInternalsRequestJob(
- net::URLRequest* request, net::NetworkDelegate* network_delegate)
- : net::URLRequestSimpleJob(request, network_delegate) {
-}
-
-#if defined(USE_TCMALLOC)
-void RequestTcmallocStatsFromChildRenderProcesses() {
- RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
- while (!it.IsAtEnd()) {
- it.GetCurrentValue()->Send(new ChildProcessMsg_GetTcmallocStats);
- it.Advance();
- }
-}
-
-void AboutTcmalloc(std::string* data) {
- data->append("<!DOCTYPE html>\n<html>\n<head>\n");
- data->append(
- "<meta http-equiv=\"Content-Security-Policy\" "
- "content=\"object-src 'none'; script-src 'none'\">");
- data->append("<title>tcmalloc stats</title>");
- data->append("</head><body>");
-
- // Display any stats for which we sent off requests the last time.
- data->append("<p>Stats as of last page load;");
- data->append("reload to get stats as of this page load.</p>\n");
- data->append("<table width=\"100%\">\n");
-
- AboutTcmallocOutputs::GetInstance()->DumpToHTMLTable(data);
-
- data->append("</body></html>\n");
-
- // Populate the collector with stats from the local browser process
- // and send off requests to all the renderer processes.
- char buffer[1024 * 32];
- base::allocator::GetStats(buffer, sizeof(buffer));
- std::string browser("Browser");
- AboutTcmallocOutputs::GetInstance()->SetOutput(browser, buffer);
-
- for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
- iter.Send(new ChildProcessMsg_GetTcmallocStats);
- }
-
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
- &RequestTcmallocStatsFromChildRenderProcesses));
-}
-#endif
-
-int TcmallocInternalsRequestJob::GetData(
- std::string* mime_type,
- std::string* charset,
- std::string* data,
- const net::CompletionCallback& callback) const {
- mime_type->assign("text/html");
- charset->assign("UTF8");
-
- data->clear();
-#if defined(USE_TCMALLOC)
- AboutTcmalloc(data);
-#endif
- return net::OK;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/tcmalloc_internals_request_job.h b/chromium/content/browser/tcmalloc_internals_request_job.h
deleted file mode 100644
index 2d57a10d636..00000000000
--- a/chromium/content/browser/tcmalloc_internals_request_job.h
+++ /dev/null
@@ -1,67 +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_TCMALLOC_INTERNALS_REQUEST_JOB_H_
-#define CONTENT_BROWSER_TCMALLOC_INTERNALS_REQUEST_JOB_H_
-
-#include <map>
-#include "base/basictypes.h"
-#include "base/memory/singleton.h"
-#include "base/process/process.h"
-#include "build/build_config.h" // USE_TCMALLOC
-#include "net/url_request/url_request_simple_job.h"
-
-namespace content {
-
-class AboutTcmallocOutputs {
- public:
- // Returns the singleton instance.
- static AboutTcmallocOutputs* GetInstance();
-
- // Records the output for a specified header string.
- void SetOutput(const std::string& header, const std::string& output);
-
- void DumpToHTMLTable(std::string* data);
-
- // Callback for output returned from a child process. Adds
- // the output for a canonical process-specific header string that
- // incorporates the pid.
- void OnStatsForChildProcess(base::ProcessId pid,
- int process_type,
- const std::string& output);
-
- private:
- AboutTcmallocOutputs();
- ~AboutTcmallocOutputs();
-
- // A map of header strings (e.g. "Browser", "Renderer PID 123")
- // to the tcmalloc output collected for each process.
- typedef std::map<std::string, std::string> AboutTcmallocOutputsType;
- AboutTcmallocOutputsType outputs_;
-
- friend struct base::DefaultSingletonTraits<AboutTcmallocOutputs>;
-
- DISALLOW_COPY_AND_ASSIGN(AboutTcmallocOutputs);
-};
-
-class TcmallocInternalsRequestJob : public net::URLRequestSimpleJob {
- public:
- TcmallocInternalsRequestJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate);
-
- int GetData(std::string* mime_type,
- std::string* charset,
- std::string* data,
- const net::CompletionCallback& callback) const override;
-
- protected:
- ~TcmallocInternalsRequestJob() override {}
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(TcmallocInternalsRequestJob);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_TCMALLOC_INTERNALS_REQUEST_JOB_H_
diff --git a/chromium/content/browser/theme_helper_mac.h b/chromium/content/browser/theme_helper_mac.h
index 265d0d6a649..be507d95351 100644
--- a/chromium/content/browser/theme_helper_mac.h
+++ b/chromium/content/browser/theme_helper_mac.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_THEME_HELPER_MAC_H_
#define CONTENT_BROWSER_THEME_HELPER_MAC_H_
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
diff --git a/chromium/content/browser/theme_helper_mac.mm b/chromium/content/browser/theme_helper_mac.mm
index 9b2656b7731..aa5ebd05a0d 100644
--- a/chromium/content/browser/theme_helper_mac.mm
+++ b/chromium/content/browser/theme_helper_mac.mm
@@ -37,17 +37,17 @@ bool GetScrollAnimationEnabled() {
return enabled;
}
-blink::ScrollbarButtonsPlacement GetButtonPlacement() {
+blink::WebScrollbarButtonsPlacement GetButtonPlacement() {
NSString* scrollbar_variant = [[NSUserDefaults standardUserDefaults]
objectForKey:@"AppleScrollBarVariant"];
if ([scrollbar_variant isEqualToString:@"Single"])
- return blink::ScrollbarButtonsPlacementSingle;
+ return blink::WebScrollbarButtonsPlacementSingle;
else if ([scrollbar_variant isEqualToString:@"DoubleMin"])
- return blink::ScrollbarButtonsPlacementDoubleStart;
+ return blink::WebScrollbarButtonsPlacementDoubleStart;
else if ([scrollbar_variant isEqualToString:@"DoubleBoth"])
- return blink::ScrollbarButtonsPlacementDoubleBoth;
+ return blink::WebScrollbarButtonsPlacementDoubleBoth;
else
- return blink::ScrollbarButtonsPlacementDoubleEnd;
+ return blink::WebScrollbarButtonsPlacementDoubleEnd;
}
void FillScrollbarThemeParams(ViewMsg_UpdateScrollbarTheme_Params* params) {
diff --git a/chromium/content/browser/time_zone_monitor.cc b/chromium/content/browser/time_zone_monitor.cc
index f414e979ab9..1eb72c6f5c4 100644
--- a/chromium/content/browser/time_zone_monitor.cc
+++ b/chromium/content/browser/time_zone_monitor.cc
@@ -5,6 +5,7 @@
#include "content/browser/time_zone_monitor.h"
#include "base/logging.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "third_party/icu/source/common/unicode/unistr.h"
diff --git a/chromium/content/browser/time_zone_monitor.h b/chromium/content/browser/time_zone_monitor.h
index fed177f9ae6..6fff155e766 100644
--- a/chromium/content/browser/time_zone_monitor.h
+++ b/chromium/content/browser/time_zone_monitor.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_TIME_ZONE_MONITOR_H_
#define CONTENT_BROWSER_TIME_ZONE_MONITOR_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
namespace content {
diff --git a/chromium/content/browser/time_zone_monitor_android.cc b/chromium/content/browser/time_zone_monitor_android.cc
index af57f80a516..4eb777bfa3d 100644
--- a/chromium/content/browser/time_zone_monitor_android.cc
+++ b/chromium/content/browser/time_zone_monitor_android.cc
@@ -4,6 +4,7 @@
#include "content/browser/time_zone_monitor_android.h"
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "jni/TimeZoneMonitor_jni.h"
@@ -25,8 +26,9 @@ bool TimeZoneMonitorAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
}
-void TimeZoneMonitorAndroid::TimeZoneChangedFromJava(JNIEnv* env,
- jobject caller) {
+void TimeZoneMonitorAndroid::TimeZoneChangedFromJava(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& caller) {
NotifyRenderers();
}
diff --git a/chromium/content/browser/time_zone_monitor_android.h b/chromium/content/browser/time_zone_monitor_android.h
index cb3cb9f216e..530445c27ab 100644
--- a/chromium/content/browser/time_zone_monitor_android.h
+++ b/chromium/content/browser/time_zone_monitor_android.h
@@ -10,7 +10,7 @@
#include <jni.h>
#include "base/android/scoped_java_ref.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
namespace content {
@@ -23,7 +23,9 @@ class TimeZoneMonitorAndroid : public TimeZoneMonitor {
static bool Register(JNIEnv* env);
// Called by the Java implementation when the system time zone changes.
- void TimeZoneChangedFromJava(JNIEnv* env, jobject caller);
+ void TimeZoneChangedFromJava(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& caller);
private:
// Java provider of system time zone change notifications.
diff --git a/chromium/content/browser/time_zone_monitor_chromeos.cc b/chromium/content/browser/time_zone_monitor_chromeos.cc
index 7ad81789bca..c3a509a732c 100644
--- a/chromium/content/browser/time_zone_monitor_chromeos.cc
+++ b/chromium/content/browser/time_zone_monitor_chromeos.cc
@@ -4,6 +4,7 @@
#include "content/browser/time_zone_monitor.h"
+#include "base/macros.h"
#include "chromeos/settings/timezone_settings.h"
namespace content {
diff --git a/chromium/content/browser/time_zone_monitor_linux.cc b/chromium/content/browser/time_zone_monitor_linux.cc
index dd0a26f27f6..ded57a42333 100644
--- a/chromium/content/browser/time_zone_monitor_linux.cc
+++ b/chromium/content/browser/time_zone_monitor_linux.cc
@@ -4,16 +4,18 @@
#include "content/browser/time_zone_monitor.h"
+#include <stddef.h>
#include <stdlib.h>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#if !defined(OS_CHROMEOS)
diff --git a/chromium/content/browser/time_zone_monitor_mac.mm b/chromium/content/browser/time_zone_monitor_mac.mm
index 700c17e6c58..5a381d89d4d 100644
--- a/chromium/content/browser/time_zone_monitor_mac.mm
+++ b/chromium/content/browser/time_zone_monitor_mac.mm
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/time_zone_monitor.h"
-
#import <Foundation/Foundation.h>
+#include "base/macros.h"
+#include "content/browser/time_zone_monitor.h"
+
namespace content {
class TimeZoneMonitorMac : public TimeZoneMonitor {
diff --git a/chromium/content/browser/time_zone_monitor_win.cc b/chromium/content/browser/time_zone_monitor_win.cc
index abeaafff81c..e8b84fd3d3f 100644
--- a/chromium/content/browser/time_zone_monitor_win.cc
+++ b/chromium/content/browser/time_zone_monitor_win.cc
@@ -6,9 +6,9 @@
#include <windows.h>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/win/singleton_hwnd_observer.h"
diff --git a/chromium/content/browser/tracing/OWNERS b/chromium/content/browser/tracing/OWNERS
index 73bcad32377..a7ae2029ca8 100644
--- a/chromium/content/browser/tracing/OWNERS
+++ b/chromium/content/browser/tracing/OWNERS
@@ -1,3 +1,4 @@
-nduca@chromium.org
dsinclair@chromium.org
+nduca@chromium.org
+oysteine@chromium.org
simonhatch@chromium.org
diff --git a/chromium/content/browser/tracing/background_tracing_config_impl.cc b/chromium/content/browser/tracing/background_tracing_config_impl.cc
index cc944ce90ef..32eebe5a715 100644
--- a/chromium/content/browser/tracing/background_tracing_config_impl.cc
+++ b/chromium/content/browser/tracing/background_tracing_config_impl.cc
@@ -2,9 +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/tracing/background_tracing_config_impl.h"
+
+#include <utility>
+
#include "base/macros.h"
#include "base/values.h"
-#include "content/browser/tracing/background_tracing_config_impl.h"
#include "content/browser/tracing/background_tracing_rule.h"
namespace content {
@@ -17,12 +20,17 @@ const char kConfigModeKey[] = "mode";
const char kConfigModePreemptive[] = "PREEMPTIVE_TRACING_MODE";
const char kConfigModeReactive[] = "REACTIVE_TRACING_MODE";
+const char kConfigScenarioName[] = "scenario_name";
+const char kConfigEnableBlinkFeatures[] = "enable_blink_features";
+const char kConfigDisableBlinkFeatures[] = "disable_blink_features";
+
const char kConfigCategoryKey[] = "category";
const char kConfigCategoryBenchmark[] = "BENCHMARK";
const char kConfigCategoryBenchmarkDeep[] = "BENCHMARK_DEEP";
const char kConfigCategoryBenchmarkGPU[] = "BENCHMARK_GPU";
const char kConfigCategoryBenchmarkIPC[] = "BENCHMARK_IPC";
const char kConfigCategoryBenchmarkStartup[] = "BENCHMARK_STARTUP";
+const char kConfigCategoryBlinkStyle[] = "BLINK_STYLE";
} // namespace
@@ -46,6 +54,8 @@ std::string BackgroundTracingConfigImpl::CategoryPresetToString(
return kConfigCategoryBenchmarkIPC;
case BackgroundTracingConfigImpl::BENCHMARK_STARTUP:
return kConfigCategoryBenchmarkStartup;
+ case BackgroundTracingConfigImpl::BLINK_STYLE:
+ return kConfigCategoryBlinkStyle;
}
NOTREACHED();
return "";
@@ -79,6 +89,11 @@ bool BackgroundTracingConfigImpl::StringToCategoryPreset(
return true;
}
+ if (category_preset_string == kConfigCategoryBlinkStyle) {
+ *category_preset = BackgroundTracingConfigImpl::BLINK_STYLE;
+ return true;
+ }
+
return false;
}
@@ -99,10 +114,17 @@ void BackgroundTracingConfigImpl::IntoDict(base::DictionaryValue* dict) const {
scoped_ptr<base::DictionaryValue> config_dict(new base::DictionaryValue());
DCHECK(it);
it->IntoDict(config_dict.get());
- configs_list->Append(config_dict.Pass());
+ configs_list->Append(std::move(config_dict));
}
- dict->Set(kConfigsKey, configs_list.Pass());
+ dict->Set(kConfigsKey, std::move(configs_list));
+
+ if (!scenario_name_.empty())
+ dict->SetString(kConfigScenarioName, scenario_name_);
+ if (!enable_blink_features_.empty())
+ dict->SetString(kConfigEnableBlinkFeatures, enable_blink_features_);
+ if (!disable_blink_features_.empty())
+ dict->SetString(kConfigDisableBlinkFeatures, disable_blink_features_);
}
void BackgroundTracingConfigImpl::AddPreemptiveRule(
@@ -110,7 +132,7 @@ void BackgroundTracingConfigImpl::AddPreemptiveRule(
scoped_ptr<BackgroundTracingRule> rule =
BackgroundTracingRule::PreemptiveRuleFromDict(dict);
if (rule)
- rules_.push_back(rule.Pass());
+ rules_.push_back(std::move(rule));
}
void BackgroundTracingConfigImpl::AddReactiveRule(
@@ -119,7 +141,7 @@ void BackgroundTracingConfigImpl::AddReactiveRule(
scoped_ptr<BackgroundTracingRule> rule =
BackgroundTracingRule::ReactiveRuleFromDict(dict, category_preset);
if (rule)
- rules_.push_back(rule.Pass());
+ rules_.push_back(std::move(rule));
}
scoped_ptr<BackgroundTracingConfigImpl> BackgroundTracingConfigImpl::FromDict(
@@ -140,7 +162,15 @@ scoped_ptr<BackgroundTracingConfigImpl> BackgroundTracingConfigImpl::FromDict(
return nullptr;
}
- return config.Pass();
+ if (config) {
+ dict->GetString(kConfigScenarioName, &config->scenario_name_);
+ dict->GetString(kConfigEnableBlinkFeatures,
+ &config->enable_blink_features_);
+ dict->GetString(kConfigDisableBlinkFeatures,
+ &config->disable_blink_features_);
+ }
+
+ return config;
}
scoped_ptr<BackgroundTracingConfigImpl>
@@ -174,7 +204,7 @@ BackgroundTracingConfigImpl::PreemptiveFromDict(
if (config->rules().empty())
return nullptr;
- return config.Pass();
+ return config;
}
scoped_ptr<BackgroundTracingConfigImpl>
@@ -208,7 +238,7 @@ BackgroundTracingConfigImpl::ReactiveFromDict(
if (config->rules().empty())
return nullptr;
- return config.Pass();
+ return config;
}
} // namspace content
diff --git a/chromium/content/browser/tracing/background_tracing_config_impl.h b/chromium/content/browser/tracing/background_tracing_config_impl.h
index c3ff85cab1c..841a04711a5 100644
--- a/chromium/content/browser/tracing/background_tracing_config_impl.h
+++ b/chromium/content/browser/tracing/background_tracing_config_impl.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_CONFIG_IMPL_H_
#define CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_CONFIG_IMPL_H_
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "content/common/content_export.h"
#include "content/public/browser/background_tracing_config.h"
@@ -28,6 +30,7 @@ class CONTENT_EXPORT BackgroundTracingConfigImpl
BENCHMARK_GPU,
BENCHMARK_IPC,
BENCHMARK_STARTUP,
+ BLINK_STYLE
};
CategoryPreset category_preset() const { return category_preset_; }
@@ -36,6 +39,13 @@ class CONTENT_EXPORT BackgroundTracingConfigImpl
}
const ScopedVector<BackgroundTracingRule>& rules() const { return rules_; }
+ const std::string& scenario_name() const { return scenario_name_; }
+ const std::string& enable_blink_features() const {
+ return enable_blink_features_;
+ }
+ const std::string& disable_blink_features() const {
+ return disable_blink_features_;
+ }
void AddPreemptiveRule(const base::DictionaryValue* dict);
void AddReactiveRule(
@@ -57,8 +67,14 @@ class CONTENT_EXPORT BackgroundTracingConfigImpl
BackgroundTracingConfigImpl::CategoryPreset* category_preset);
private:
+ FRIEND_TEST_ALL_PREFIXES(BackgroundTracingConfigTest,
+ ValidPreemptiveConfigToString);
+
CategoryPreset category_preset_;
ScopedVector<BackgroundTracingRule> rules_;
+ std::string scenario_name_;
+ std::string enable_blink_features_;
+ std::string disable_blink_features_;
DISALLOW_COPY_AND_ASSIGN(BackgroundTracingConfigImpl);
};
diff --git a/chromium/content/browser/tracing/background_tracing_config_unittest.cc b/chromium/content/browser/tracing/background_tracing_config_unittest.cc
index 4aa462c222c..2b95069a401 100644
--- a/chromium/content/browser/tracing/background_tracing_config_unittest.cc
+++ b/chromium/content/browser/tracing/background_tracing_config_unittest.cc
@@ -192,8 +192,23 @@ TEST_F(BackgroundTracingConfigTest, PreemptiveConfigFromValidString) {
EXPECT_EQ(config->rules().size(), 1u);
EXPECT_EQ(RuleToString(config->rules()[0]),
"{\"histogram_lower_value\":1,\"histogram_name\":\"foo\","
- "\"histogram_upper_value\":2147483647,\"rule\":\"MONITOR_AND_DUMP_"
- "WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
+ "\"histogram_repeat\":true,\"histogram_upper_value\":2147483647,"
+ "\"rule\":\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
+
+ config = ReadFromJSONString(
+ "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
+ "\"BENCHMARK\",\"configs\": [{\"rule\": "
+ "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+ "\"histogram_name\":\"foo\", \"histogram_value\": 1, "
+ "\"histogram_repeat\":false}]}");
+ EXPECT_TRUE(config);
+ EXPECT_EQ(config->tracing_mode(), BackgroundTracingConfig::PREEMPTIVE);
+ EXPECT_EQ(config->category_preset(), BackgroundTracingConfigImpl::BENCHMARK);
+ EXPECT_EQ(config->rules().size(), 1u);
+ EXPECT_EQ(RuleToString(config->rules()[0]),
+ "{\"histogram_lower_value\":1,\"histogram_name\":\"foo\","
+ "\"histogram_repeat\":false,\"histogram_upper_value\":2147483647,"
+ "\"rule\":\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
config = ReadFromJSONString(
"{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
@@ -207,8 +222,23 @@ TEST_F(BackgroundTracingConfigTest, PreemptiveConfigFromValidString) {
EXPECT_EQ(config->rules().size(), 1u);
EXPECT_EQ(RuleToString(config->rules()[0]),
"{\"histogram_lower_value\":1,\"histogram_name\":\"foo\","
- "\"histogram_upper_value\":2,\"rule\":\"MONITOR_AND_DUMP_WHEN_"
- "SPECIFIC_HISTOGRAM_AND_VALUE\"}");
+ "\"histogram_repeat\":true,\"histogram_upper_value\":2,\"rule\":"
+ "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
+
+ config = ReadFromJSONString(
+ "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
+ "\"BENCHMARK\",\"configs\": [{\"rule\": "
+ "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+ "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1, "
+ "\"histogram_upper_value\": 2, \"histogram_repeat\":false}]}");
+ EXPECT_TRUE(config);
+ EXPECT_EQ(config->tracing_mode(), BackgroundTracingConfig::PREEMPTIVE);
+ EXPECT_EQ(config->category_preset(), BackgroundTracingConfigImpl::BENCHMARK);
+ EXPECT_EQ(config->rules().size(), 1u);
+ EXPECT_EQ(RuleToString(config->rules()[0]),
+ "{\"histogram_lower_value\":1,\"histogram_name\":\"foo\","
+ "\"histogram_repeat\":false,\"histogram_upper_value\":2,\"rule\":"
+ "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
config = ReadFromJSONString(
"{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
@@ -226,6 +256,17 @@ TEST_F(BackgroundTracingConfigTest, PreemptiveConfigFromValidString) {
EXPECT_EQ(RuleToString(config->rules()[1]),
"{\"rule\":\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\","
"\"trigger_name\":\"foo2\"}");
+
+ config = ReadFromJSONString(
+ "{\"category\":\"BENCHMARK_DEEP\",\"configs\":[{\"rule\":"
+ "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_name\":"
+ "\"foo1\"}],\"disable_blink_features\":\"SlowerWeb1,SlowerWeb2\","
+ "\"enable_blink_features\":\"FasterWeb1,FasterWeb2\","
+ "\"mode\":\"PREEMPTIVE_TRACING_MODE\","
+ "\"scenario_name\":\"my_awesome_experiment\"}");
+ EXPECT_EQ(config->enable_blink_features(), "FasterWeb1,FasterWeb2");
+ EXPECT_EQ(config->disable_blink_features(), "SlowerWeb1,SlowerWeb2");
+ EXPECT_EQ(config->scenario_name(), "my_awesome_experiment");
}
TEST_F(BackgroundTracingConfigTest, ReactiveConfigFromValidString) {
@@ -254,6 +295,20 @@ TEST_F(BackgroundTracingConfigTest, ReactiveConfigFromValidString) {
"{\"category\":\"BENCHMARK_DEEP\","
"\"rule\":\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\","
"\"trigger_name\":\"foo\"}");
+
+ config = ReadFromJSONString(
+ "{\"mode\":\"REACTIVE_TRACING_MODE\",\"configs\": [{\"rule\": "
+ "\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", "
+ "\"category\": \"BENCHMARK_DEEP\", \"trigger_name\": \"foo\", "
+ "\"trigger_chance\": 0.5}]}");
+ EXPECT_TRUE(config);
+ EXPECT_EQ(config->tracing_mode(), BackgroundTracingConfig::REACTIVE);
+ EXPECT_EQ(config->rules().size(), 1u);
+ EXPECT_EQ(RuleToString(config->rules()[0]),
+ "{\"category\":\"BENCHMARK_DEEP\","
+ "\"rule\":\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\","
+ "\"trigger_chance\":0.5,\"trigger_name\":\"foo\"}");
+
config = ReadFromJSONString(
"{\"mode\":\"REACTIVE_TRACING_MODE\",\"configs\": [{\"rule\": "
"\"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL\", "
@@ -322,6 +377,24 @@ TEST_F(BackgroundTracingConfigTest, ValidPreemptiveConfigToString) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
+ dict->SetString("trigger_name", "foo");
+ dict->SetDouble("trigger_chance", 0.5);
+ config->AddPreemptiveRule(dict.get());
+
+ EXPECT_EQ(
+ ConfigToString(config.get()),
+ "{\"category\":\"BENCHMARK_DEEP\",\"configs\":[{\"rule\":"
+ "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_chance\":0.5,"
+ "\"trigger_name\":\"foo\"}],\"mode\":\"PREEMPTIVE_TRACING_MODE\"}");
+ }
+
+ {
+ config.reset(
+ new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE));
+ config->set_category_preset(BackgroundTracingConfigImpl::BENCHMARK_DEEP);
+
+ scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
dict->SetString("trigger_name", "foo1");
config->AddPreemptiveRule(dict.get());
@@ -350,9 +423,54 @@ TEST_F(BackgroundTracingConfigTest, ValidPreemptiveConfigToString) {
EXPECT_EQ(ConfigToString(config.get()),
"{\"category\":\"BENCHMARK\",\"configs\":[{\"histogram_lower_"
- "value\":1,\"histogram_name\":\"foo\",\"histogram_upper_value\":"
- "2,\"rule\":\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_"
- "VALUE\"}],\"mode\":\"PREEMPTIVE_TRACING_MODE\"}");
+ "value\":1,\"histogram_name\":\"foo\",\"histogram_repeat\":true,"
+ "\"histogram_upper_value\":2,\"rule\":\"MONITOR_AND_DUMP_WHEN_"
+ "SPECIFIC_HISTOGRAM_AND_VALUE\"}],\"mode\":\"PREEMPTIVE_TRACING_"
+ "MODE\"}");
+ }
+
+ {
+ config.reset(
+ new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE));
+
+ scoped_ptr<base::DictionaryValue> second_dict(new base::DictionaryValue());
+ second_dict->SetString(
+ "rule", "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
+ second_dict->SetString("histogram_name", "foo");
+ second_dict->SetInteger("histogram_lower_value", 1);
+ second_dict->SetInteger("histogram_upper_value", 2);
+ second_dict->SetInteger("trigger_delay", 10);
+ config->AddPreemptiveRule(second_dict.get());
+
+ EXPECT_EQ(ConfigToString(config.get()),
+ "{\"category\":\"BENCHMARK\",\"configs\":[{\"histogram_lower_"
+ "value\":1,\"histogram_name\":\"foo\",\"histogram_repeat\":true,"
+ "\"histogram_upper_value\":2,\"rule\":\"MONITOR_AND_DUMP_WHEN_"
+ "SPECIFIC_HISTOGRAM_AND_VALUE\",\"trigger_delay\":10}],\"mode\":"
+ "\"PREEMPTIVE_TRACING_MODE\"}");
+ }
+
+ {
+ config.reset(
+ new BackgroundTracingConfigImpl(BackgroundTracingConfig::PREEMPTIVE));
+ config->set_category_preset(BackgroundTracingConfigImpl::BENCHMARK_DEEP);
+
+ scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
+ dict->SetString("trigger_name", "foo1");
+ config->AddPreemptiveRule(dict.get());
+
+ config->scenario_name_ = "my_awesome_experiment";
+ config->enable_blink_features_ = "FasterWeb1,FasterWeb2";
+ config->disable_blink_features_ = "SlowerWeb1,SlowerWeb2";
+
+ EXPECT_EQ(ConfigToString(config.get()),
+ "{\"category\":\"BENCHMARK_DEEP\",\"configs\":[{\"rule\":"
+ "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_name\":"
+ "\"foo1\"}],\"disable_blink_features\":\"SlowerWeb1,SlowerWeb2\","
+ "\"enable_blink_features\":\"FasterWeb1,FasterWeb2\","
+ "\"mode\":\"PREEMPTIVE_TRACING_MODE\","
+ "\"scenario_name\":\"my_awesome_experiment\"}");
}
}
diff --git a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
index c8d9b815069..e0001b86dd9 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -2,12 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+#include <utility>
+
#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/pattern.h"
#include "base/trace_event/trace_event.h"
+#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/background_tracing_rule.h"
-#include "content/public/browser/background_tracing_manager.h"
+#include "content/public/common/content_switches.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
@@ -33,7 +39,7 @@ class BackgroundTracingManagerUploadConfigWrapper {
}
void Upload(const scoped_refptr<base::RefCountedString>& file_contents,
- scoped_ptr<base::DictionaryValue> metadata,
+ scoped_ptr<const base::DictionaryValue> metadata,
base::Callback<void()> done_callback) {
receive_count_ += 1;
EXPECT_TRUE(file_contents);
@@ -46,7 +52,7 @@ class BackgroundTracingManagerUploadConfigWrapper {
stream.avail_in = compressed_length;
stream.avail_out = kOutputBufferLength;
stream.next_in = (Bytef*)&file_contents->data()[0];
- stream.next_out = (Bytef*)vector_as_array(&output_str);
+ stream.next_out = (Bytef*)output_str.data();
// 16 + MAX_WBITS means only decoding gzip encoded streams, and using
// the biggest window size, according to zlib.h
@@ -58,7 +64,7 @@ class BackgroundTracingManagerUploadConfigWrapper {
inflateEnd(&stream);
EXPECT_EQ(Z_STREAM_END, result);
- last_file_contents_.assign(vector_as_array(&output_str), bytes_written);
+ last_file_contents_.assign(output_str.data(), bytes_written);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(done_callback));
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
@@ -102,15 +108,15 @@ scoped_ptr<BackgroundTracingConfig> CreatePreemptiveConfig() {
scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
rules_dict->SetString("trigger_name", "preemptive_test");
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
EXPECT_TRUE(config);
- return config.Pass();
+ return config;
}
scoped_ptr<BackgroundTracingConfig> CreateReactiveConfig() {
@@ -124,15 +130,15 @@ scoped_ptr<BackgroundTracingConfig> CreateReactiveConfig() {
rules_dict->SetString("rule", "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
rules_dict->SetString("trigger_name", "reactive_test");
rules_dict->SetString("category", "BENCHMARK");
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
EXPECT_TRUE(config);
- return config.Pass();
+ return config;
}
void SetupBackgroundTracingManager() {
@@ -163,7 +169,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("preemptive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -195,7 +201,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"preemptive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -214,8 +220,10 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
namespace {
-bool IsTraceEventArgsWhitelisted(const char* category_group_name,
- const char* event_name) {
+bool IsTraceEventArgsWhitelisted(
+ const char* category_group_name,
+ const char* event_name,
+ base::trace_event::ArgumentNameFilterPredicate* arg_filter) {
if (base::MatchPattern(category_group_name, "benchmark") &&
base::MatchPattern(event_name, "whitelisted")) {
return true;
@@ -248,7 +256,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
wait_for_activated.QuitClosure());
EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::ANONYMIZE_DATA));
wait_for_activated.Run();
@@ -267,7 +275,48 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("{"));
EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("find_this"));
- EXPECT_TRUE(!upload_config_wrapper.TraceHasMatchingString("this_not_found"));
+ EXPECT_FALSE(upload_config_wrapper.TraceHasMatchingString("this_not_found"));
+}
+
+// This tests that browser metadata gets included in the trace.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ TraceMetadataInTrace) {
+ SetupBackgroundTracingManager();
+
+ base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
+ base::Bind(&IsTraceEventArgsWhitelisted));
+
+ base::RunLoop wait_for_upload;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ wait_for_upload.QuitClosure());
+
+ scoped_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig();
+
+ content::BackgroundTracingManager::TriggerHandle handle =
+ content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
+ "preemptive_test");
+
+ base::RunLoop wait_for_activated;
+ BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
+ wait_for_activated.QuitClosure());
+ EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ std::move(config), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::ANONYMIZE_DATA));
+
+ wait_for_activated.Run();
+
+ BackgroundTracingManager::GetInstance()->WhenIdle(
+ base::Bind(&DisableScenarioWhenIdle));
+
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
+
+ wait_for_upload.Run();
+
+ EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
+ EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("cpu-brand"));
+ EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("network-type"));
+ EXPECT_TRUE(upload_config_wrapper.TraceHasMatchingString("user-agent"));
}
// This tests subprocesses (like a navigating renderer) which gets told to
@@ -295,7 +344,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
BackgroundTracingManager::GetInstance()->SetTracingEnabledCallbackForTesting(
wait_for_activated.QuitClosure());
EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::ANONYMIZE_DATA));
wait_for_activated.Run();
@@ -335,16 +384,16 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
rules_dict->SetString("trigger_name", "test1");
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
{
scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
rules_dict->SetString("trigger_name", "test2");
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
@@ -356,7 +405,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
BackgroundTracingManager::GetInstance()->RegisterTriggerType("test2");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -374,6 +423,159 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
}
}
+// This tests that toggling Blink scenarios in the config alters the
+// command-line.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ ToggleBlinkScenarios) {
+ {
+ SetupBackgroundTracingManager();
+
+ base::RunLoop run_loop;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ run_loop.QuitClosure());
+
+ base::DictionaryValue dict;
+ dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
+ dict.SetString("category", "BENCHMARK");
+
+ scoped_ptr<base::ListValue> rules_list(new base::ListValue());
+ {
+ scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
+ rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
+ rules_dict->SetString("trigger_name", "test2");
+ rules_list->Append(std::move(rules_dict));
+ }
+
+ dict.Set("configs", std::move(rules_list));
+ dict.SetString("enable_blink_features", "FasterWeb1,FasterWeb2");
+ dict.SetString("disable_blink_features", "SlowerWeb1,SlowerWeb2");
+ scoped_ptr<BackgroundTracingConfig> config(
+ BackgroundTracingConfigImpl::FromDict(&dict));
+ EXPECT_TRUE(config);
+
+ bool scenario_activated =
+ BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ std::move(config), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
+
+ EXPECT_TRUE(scenario_activated);
+
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ EXPECT_TRUE(command_line);
+
+ EXPECT_EQ(command_line->GetSwitchValueASCII(switches::kEnableBlinkFeatures),
+ "FasterWeb1,FasterWeb2");
+ EXPECT_EQ(
+ command_line->GetSwitchValueASCII(switches::kDisableBlinkFeatures),
+ "SlowerWeb1,SlowerWeb2");
+ }
+}
+
+// This tests that toggling Blink scenarios in a scenario won't activate
+// if there's already Blink features toggled by something else (about://flags)
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ ToggleBlinkScenariosNotOverridingSwitches) {
+ SetupBackgroundTracingManager();
+
+ base::RunLoop run_loop;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ run_loop.QuitClosure());
+
+ base::DictionaryValue dict;
+ dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
+ dict.SetString("category", "BENCHMARK");
+
+ scoped_ptr<base::ListValue> rules_list(new base::ListValue());
+ {
+ scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
+ rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
+ rules_dict->SetString("trigger_name", "test2");
+ rules_list->Append(std::move(rules_dict));
+ }
+
+ dict.Set("configs", std::move(rules_list));
+ dict.SetString("enable_blink_features", "FasterWeb1,FasterWeb2");
+ dict.SetString("disable_blink_features", "SlowerWeb1,SlowerWeb2");
+ scoped_ptr<BackgroundTracingConfig> config(
+ BackgroundTracingConfigImpl::FromDict(&dict));
+ EXPECT_TRUE(config);
+
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kEnableBlinkFeatures, "FooFeature");
+
+ bool scenario_activated =
+ BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ std::move(config), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
+
+ EXPECT_FALSE(scenario_activated);
+}
+
+// This tests that delayed histogram triggers triggers work as expected
+// with preemptive scenarios.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ CallPreemptiveTriggerWithDelay) {
+ {
+ SetupBackgroundTracingManager();
+
+ base::RunLoop run_loop;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ run_loop.QuitClosure());
+
+ base::DictionaryValue dict;
+ dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
+ dict.SetString("category", "BENCHMARK");
+
+ scoped_ptr<base::ListValue> rules_list(new base::ListValue());
+ {
+ scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
+ rules_dict->SetString(
+ "rule", "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
+ rules_dict->SetString("histogram_name", "fake");
+ rules_dict->SetInteger("histogram_value", 1);
+ rules_dict->SetInteger("trigger_delay", 10);
+ rules_list->Append(std::move(rules_dict));
+ }
+
+ dict.Set("configs", std::move(rules_list));
+
+ scoped_ptr<BackgroundTracingConfig> config(
+ BackgroundTracingConfigImpl::FromDict(&dict));
+ EXPECT_TRUE(config);
+
+ BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ std::move(config), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
+
+ BackgroundTracingManager::GetInstance()->WhenIdle(
+ base::Bind(&DisableScenarioWhenIdle));
+
+ base::RunLoop rule_triggered_runloop;
+ BackgroundTracingManagerImpl::GetInstance()
+ ->SetRuleTriggeredCallbackForTesting(
+ rule_triggered_runloop.QuitClosure());
+
+ // Our reference value is "1", so a value of "2" should trigger a trace.
+ LOCAL_HISTOGRAM_COUNTS("fake", 2);
+
+ rule_triggered_runloop.Run();
+
+ // Since we specified a delay in the scenario, we should still be tracing
+ // at this point.
+ EXPECT_TRUE(
+ BackgroundTracingManagerImpl::GetInstance()->IsTracingForTesting());
+
+ // Fake the timer firing.
+ BackgroundTracingManagerImpl::GetInstance()->FireTimerForTesting();
+ EXPECT_FALSE(
+ BackgroundTracingManagerImpl::GetInstance()->IsTracingForTesting());
+
+ run_loop.Run();
+
+ EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 1);
+ }
+}
+
// This tests that you can't trigger without a scenario set.
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
CannotTriggerWithoutScenarioSet) {
@@ -418,7 +620,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"does_not_exist");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -454,7 +656,111 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
->InvalidateTriggerHandlesForTesting();
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
+
+ BackgroundTracingManager::GetInstance()->WhenIdle(
+ base::Bind(&DisableScenarioWhenIdle));
+
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle,
+ base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
+
+ run_loop.Run();
+
+ EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
+ }
+}
+
+// This tests that no preemptive trace is triggered with 0 chance set.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ PreemptiveNotTriggerWithZeroChance) {
+ {
+ SetupBackgroundTracingManager();
+
+ base::RunLoop run_loop;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ (base::Closure()));
+
+ base::DictionaryValue dict;
+
+ dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
+ dict.SetString("category", "BENCHMARK");
+
+ scoped_ptr<base::ListValue> rules_list(new base::ListValue());
+ {
+ scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
+ rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED");
+ rules_dict->SetString("trigger_name", "preemptive_test");
+ rules_dict->SetDouble("trigger_chance", 0.0);
+ rules_list->Append(std::move(rules_dict));
+ }
+ dict.Set("configs", std::move(rules_list));
+
+ scoped_ptr<BackgroundTracingConfig> config(
+ BackgroundTracingConfigImpl::FromDict(&dict));
+
+ EXPECT_TRUE(config);
+
+ content::BackgroundTracingManager::TriggerHandle handle =
+ content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
+ "preemptive_test");
+
+ BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ std::move(config), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING);
+
+ BackgroundTracingManager::GetInstance()->WhenIdle(
+ base::Bind(&DisableScenarioWhenIdle));
+
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle,
+ base::Bind(&StartedFinalizingCallback, run_loop.QuitClosure(), false));
+
+ run_loop.Run();
+
+ EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 0);
+ }
+}
+
+// This tests that no reactive trace is triggered with 0 chance set.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ ReactiveNotTriggerWithZeroChance) {
+ {
+ SetupBackgroundTracingManager();
+
+ base::RunLoop run_loop;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ (base::Closure()));
+
+ base::DictionaryValue dict;
+
+ dict.SetString("mode", "REACTIVE_TRACING_MODE");
+
+ scoped_ptr<base::ListValue> rules_list(new base::ListValue());
+ {
+ scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
+ rules_dict->SetString("rule",
+ "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
+ rules_dict->SetString("trigger_name", "reactive_test1");
+ rules_dict->SetString("category", "BENCHMARK");
+ rules_dict->SetDouble("trigger_chance", 0.0);
+
+ rules_list->Append(std::move(rules_dict));
+ }
+ dict.Set("configs", std::move(rules_list));
+
+ scoped_ptr<BackgroundTracingConfig> config(
+ BackgroundTracingConfigImpl::FromDict(&dict));
+
+ EXPECT_TRUE(config);
+
+ content::BackgroundTracingManager::TriggerHandle handle =
+ content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
+ "preemptive_test");
+
+ BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -492,17 +798,17 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"rule", "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
rules_dict->SetString("histogram_name", "fake");
rules_dict->SetInteger("histogram_value", 1);
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
EXPECT_TRUE(config);
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
// Our reference value is "1", so a value of "2" should trigger a trace.
@@ -536,17 +842,17 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"rule", "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
rules_dict->SetString("histogram_name", "fake");
rules_dict->SetInteger("histogram_value", 1);
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
EXPECT_TRUE(config);
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
// This should fail to trigger a trace since the sample value < the
@@ -582,17 +888,17 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
rules_dict->SetString("histogram_name", "fake");
rules_dict->SetInteger("histogram_lower_value", 1);
rules_dict->SetInteger("histogram_upper_value", 3);
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
EXPECT_TRUE(config);
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
// This should fail to trigger a trace since the sample value > the
@@ -622,10 +928,10 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
{
scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
rules_dict->SetString("rule", "INVALID_RULE");
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
@@ -651,7 +957,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("reactive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -685,7 +991,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("reactive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -723,7 +1029,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
rules_dict->SetString("trigger_name", "reactive_test1");
rules_dict->SetString("category", "BENCHMARK");
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
{
scoped_ptr<base::DictionaryValue> rules_dict(new base::DictionaryValue());
@@ -731,9 +1037,9 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL");
rules_dict->SetString("trigger_name", "reactive_test2");
rules_dict->SetString("category", "BENCHMARK");
- rules_list->Append(rules_dict.Pass());
+ rules_list->Append(std::move(rules_dict));
}
- dict.Set("configs", rules_list.Pass());
+ dict.Set("configs", std::move(rules_list));
scoped_ptr<BackgroundTracingConfig> config(
BackgroundTracingConfigImpl::FromDict(&dict));
@@ -746,7 +1052,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
"reactive_test2");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
@@ -787,7 +1093,7 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
GetInstance()->RegisterTriggerType("reactive_test");
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- config.Pass(), upload_config_wrapper.get_receive_callback(),
+ std::move(config), upload_config_wrapper.get_receive_callback(),
BackgroundTracingManager::NO_DATA_FILTERING);
BackgroundTracingManager::GetInstance()->WhenIdle(
diff --git a/chromium/content/browser/tracing/background_tracing_manager_impl.cc b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
index 3985a2404b4..250d0fa4c13 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
@@ -4,20 +4,20 @@
#include "content/browser/tracing/background_tracing_manager_impl.h"
-#include "base/cpu.h"
+#include <utility>
+
+#include "base/command_line.h"
#include "base/json/json_writer.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
-#include "base/sys_info.h"
+#include "base/rand_util.h"
#include "base/time/time.h"
#include "content/browser/tracing/background_tracing_rule.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/tracing_delegate.h"
#include "content/public/common/content_client.h"
-#include "gpu/config/gpu_info.h"
-#include "net/base/network_change_notifier.h"
+#include "content/public/common/content_switches.h"
namespace content {
@@ -37,6 +37,7 @@ enum BackgroundTracingMetrics {
FINALIZATION_DISALLOWED = 6,
FINALIZATION_STARTED = 7,
FINALIZATION_COMPLETE = 8,
+ SCENARIO_ACTION_FAILED_LOWRES_CLOCK = 9,
NUMBER_OF_BACKGROUND_TRACING_METRICS,
};
@@ -45,29 +46,6 @@ void RecordBackgroundTracingMetric(BackgroundTracingMetrics metric) {
NUMBER_OF_BACKGROUND_TRACING_METRICS);
}
-std::string GetNetworkTypeString() {
- switch (net::NetworkChangeNotifier::GetConnectionType()) {
- case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
- return "Ethernet";
- case net::NetworkChangeNotifier::CONNECTION_WIFI:
- return "WiFi";
- case net::NetworkChangeNotifier::CONNECTION_2G:
- return "2G";
- case net::NetworkChangeNotifier::CONNECTION_3G:
- return "3G";
- case net::NetworkChangeNotifier::CONNECTION_4G:
- return "4G";
- case net::NetworkChangeNotifier::CONNECTION_NONE:
- return "None";
- case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
- return "Bluetooth";
- case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
- default:
- break;
- }
- return "Unknown";
-}
-
} // namespace
BackgroundTracingManagerImpl::TracingTimer::TracingTimer(
@@ -110,7 +88,7 @@ BackgroundTracingManagerImpl::BackgroundTracingManagerImpl()
is_tracing_(false),
requires_anonymized_data_(true),
trigger_handle_ids_(0),
- reactive_triggered_handle_(-1) {}
+ triggered_named_event_handle_(-1) {}
BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() {
NOTREACHED();
@@ -122,25 +100,6 @@ void BackgroundTracingManagerImpl::WhenIdle(
idle_callback_ = idle_callback;
}
-void BackgroundTracingManagerImpl::TriggerPreemptiveFinalization() {
- CHECK(config_ &&
- config_->tracing_mode() == BackgroundTracingConfigImpl::PREEMPTIVE);
-
- if (!is_tracing_ || is_gathering_)
- return;
-
- RecordBackgroundTracingMetric(PREEMPTIVE_TRIGGERED);
- BeginFinalizing(StartedFinalizingCallback());
-}
-
-void BackgroundTracingManagerImpl::OnHistogramTrigger(
- const std::string& histogram_name) {
- for (auto& rule : config_->rules()) {
- static_cast<BackgroundTracingRule*>(rule)
- ->OnHistogramTrigger(histogram_name);
- }
-}
-
bool BackgroundTracingManagerImpl::SetActiveScenario(
scoped_ptr<BackgroundTracingConfig> config,
const BackgroundTracingManager::ReceiveCallback& receive_callback,
@@ -151,6 +110,13 @@ bool BackgroundTracingManagerImpl::SetActiveScenario(
if (is_tracing_)
return false;
+ // If we don't have a high resolution timer available, traces will be
+ // too inaccurate to be useful.
+ if (!base::TimeTicks::IsHighResolution()) {
+ RecordBackgroundTracingMetric(SCENARIO_ACTION_FAILED_LOWRES_CLOCK);
+ return false;
+ }
+
bool requires_anonymized_data = (data_filtering == ANONYMIZE_DATA);
// If the I/O thread isn't running, this is a startup scenario and
@@ -170,11 +136,32 @@ bool BackgroundTracingManagerImpl::SetActiveScenario(
base::Unretained(this)));
}
- // No point in tracing if there's nowhere to send it.
- if (config && receive_callback.is_null())
- return false;
+ scoped_ptr<const content::BackgroundTracingConfigImpl> config_impl(
+ static_cast<BackgroundTracingConfigImpl*>(config.release()));
+
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+
+ if (config_impl) {
+ // No point in tracing if there's nowhere to send it.
+ if (receive_callback.is_null())
+ return false;
- config_.reset(static_cast<BackgroundTracingConfigImpl*>(config.release()));
+ // If the scenario requires us to toggle Blink features, we want
+ // to neither override anything else nor to do we want to activate
+ // the scenario without doing the toggle, so if something else has
+ // configured these switches we just abort.
+ if (!config_impl->enable_blink_features().empty() &&
+ command_line->HasSwitch(switches::kEnableBlinkFeatures)) {
+ return false;
+ }
+
+ if (!config_impl->disable_blink_features().empty() &&
+ command_line->HasSwitch(switches::kDisableBlinkFeatures)) {
+ return false;
+ }
+ }
+
+ config_ = std::move(config_impl);
receive_callback_ = receive_callback;
requires_anonymized_data_ = requires_anonymized_data;
@@ -182,18 +169,32 @@ bool BackgroundTracingManagerImpl::SetActiveScenario(
DCHECK(!config_.get()->rules().empty());
for (auto& rule : config_.get()->rules())
static_cast<BackgroundTracingRule*>(rule)->Install();
+
+ if (!config_->enable_blink_features().empty()) {
+ command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
+ config_->enable_blink_features());
+ }
+
+ if (!config_->disable_blink_features().empty()) {
+ command_line->AppendSwitchASCII(switches::kDisableBlinkFeatures,
+ config_->disable_blink_features());
+ }
}
- EnableRecordingIfConfigNeedsIt();
+ StartTracingIfConfigNeedsIt();
RecordBackgroundTracingMetric(SCENARIO_ACTIVATED_SUCCESSFULLY);
return true;
}
-bool BackgroundTracingManagerImpl::HasActiveScenarioForTesting() {
+bool BackgroundTracingManagerImpl::HasActiveScenario() {
return config_;
}
+bool BackgroundTracingManagerImpl::IsTracingForTesting() {
+ return is_tracing_;
+}
+
void BackgroundTracingManagerImpl::ValidateStartupScenario() {
if (!config_ || !delegate_)
return;
@@ -204,12 +205,12 @@ void BackgroundTracingManagerImpl::ValidateStartupScenario() {
}
}
-void BackgroundTracingManagerImpl::EnableRecordingIfConfigNeedsIt() {
+void BackgroundTracingManagerImpl::StartTracingIfConfigNeedsIt() {
if (!config_)
return;
if (config_->tracing_mode() == BackgroundTracingConfigImpl::PREEMPTIVE) {
- EnableRecording(
+ StartTracing(
GetCategoryFilterStringForCategoryPreset(config_->category_preset()),
base::trace_event::RECORD_CONTINUOUSLY);
}
@@ -240,6 +241,22 @@ BackgroundTracingManagerImpl::GetRuleAbleToTriggerTracing(
return nullptr;
}
+void BackgroundTracingManagerImpl::OnHistogramTrigger(
+ const std::string& histogram_name) {
+ if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&BackgroundTracingManagerImpl::OnHistogramTrigger,
+ base::Unretained(this), histogram_name));
+ return;
+ }
+
+ for (const auto& rule : config_->rules()) {
+ if (rule->ShouldTriggerNamedEvent(histogram_name))
+ OnRuleTriggered(rule, StartedFinalizingCallback());
+ }
+}
+
void BackgroundTracingManagerImpl::TriggerNamedEvent(
BackgroundTracingManagerImpl::TriggerHandle handle,
StartedFinalizingCallback callback) {
@@ -251,39 +268,81 @@ void BackgroundTracingManagerImpl::TriggerNamedEvent(
return;
}
- BackgroundTracingRule* triggered_rule = GetRuleAbleToTriggerTracing(handle);
- if (!triggered_rule) {
+ bool is_valid_trigger = true;
+
+ const BackgroundTracingRule* triggered_rule =
+ GetRuleAbleToTriggerTracing(handle);
+ if (!triggered_rule)
+ is_valid_trigger = false;
+
+ // A different reactive config than the running one tried to trigger.
+ if (!config_ ||
+ (config_->tracing_mode() == BackgroundTracingConfigImpl::REACTIVE &&
+ is_tracing_ && triggered_named_event_handle_ != handle)) {
+ is_valid_trigger = false;
+ }
+
+ if (!is_valid_trigger) {
if (!callback.is_null())
callback.Run(false);
return;
}
- if (config_->tracing_mode() == BackgroundTracingConfigImpl::PREEMPTIVE) {
- RecordBackgroundTracingMetric(PREEMPTIVE_TRIGGERED);
- BeginFinalizing(callback);
+ triggered_named_event_handle_ = handle;
+ OnRuleTriggered(triggered_rule, callback);
+}
+
+void BackgroundTracingManagerImpl::OnRuleTriggered(
+ const BackgroundTracingRule* triggered_rule,
+ StartedFinalizingCallback callback) {
+ CHECK(config_);
+
+ double trigger_chance = triggered_rule->trigger_chance();
+ if (trigger_chance < 1.0 && base::RandDouble() > trigger_chance) {
+ if (!callback.is_null())
+ callback.Run(false);
+ return;
+ }
+
+ int trace_timeout = triggered_rule->GetTraceTimeout();
+
+ if (config_->tracing_mode() == BackgroundTracingConfigImpl::REACTIVE) {
+ // In reactive mode, a trigger starts tracing, or finalizes tracing
+ // immediately if it's already running.
+ RecordBackgroundTracingMetric(REACTIVE_TRIGGERED);
+
+ if (!is_tracing_) {
+ // It was not already tracing, start a new trace.
+ StartTracing(GetCategoryFilterStringForCategoryPreset(
+ triggered_rule->GetCategoryPreset()),
+ base::trace_event::RECORD_UNTIL_FULL);
+ } else {
+ // Reactive configs that trigger again while tracing should just
+ // end right away (to not capture multiple navigations, for example).
+ trace_timeout = -1;
+ }
} else {
- // A different reactive config tried to trigger.
- if (is_tracing_ && handle != reactive_triggered_handle_) {
+ // In preemptive mode, a trigger starts finalizing a trace if one is
+ // running and we're not got a finalization timer running,
+ // otherwise we do nothing.
+ if (!is_tracing_ || is_gathering_ || tracing_timer_) {
if (!callback.is_null())
callback.Run(false);
return;
}
- RecordBackgroundTracingMetric(REACTIVE_TRIGGERED);
- if (is_tracing_) {
- tracing_timer_->CancelTimer();
- BeginFinalizing(callback);
- return;
- }
+ RecordBackgroundTracingMetric(PREEMPTIVE_TRIGGERED);
+ }
- // It was not already tracing, start a new trace.
- EnableRecording(GetCategoryFilterStringForCategoryPreset(
- triggered_rule->GetCategoryPreset()),
- base::trace_event::RECORD_UNTIL_FULL);
+ if (trace_timeout < 0) {
+ BeginFinalizing(callback);
+ } else {
tracing_timer_.reset(new TracingTimer(callback));
- tracing_timer_->StartTimer(triggered_rule->GetReactiveTimeout());
- reactive_triggered_handle_ = handle;
+ tracing_timer_->StartTimer(trace_timeout);
}
+
+ if (!rule_triggered_callback_for_testing_.is_null())
+ rule_triggered_callback_for_testing_.Run();
}
BackgroundTracingManagerImpl::TriggerHandle
@@ -318,23 +377,30 @@ void BackgroundTracingManagerImpl::SetTracingEnabledCallbackForTesting(
tracing_enabled_callback_for_testing_ = callback;
};
+void BackgroundTracingManagerImpl::SetRuleTriggeredCallbackForTesting(
+ const base::Closure& callback) {
+ rule_triggered_callback_for_testing_ = callback;
+};
+
void BackgroundTracingManagerImpl::FireTimerForTesting() {
+ DCHECK(tracing_timer_);
tracing_timer_->FireTimerForTesting();
}
-void BackgroundTracingManagerImpl::EnableRecording(
+void BackgroundTracingManagerImpl::StartTracing(
std::string category_filter_str,
base::trace_event::TraceRecordMode record_mode) {
base::trace_event::TraceConfig trace_config(category_filter_str, record_mode);
if (requires_anonymized_data_)
trace_config.EnableArgumentFilter();
- is_tracing_ = TracingController::GetInstance()->EnableRecording(
+ is_tracing_ = TracingController::GetInstance()->StartTracing(
trace_config, tracing_enabled_callback_for_testing_);
RecordBackgroundTracingMetric(RECORDING_ENABLED);
}
void BackgroundTracingManagerImpl::OnFinalizeStarted(
+ scoped_ptr<const base::DictionaryValue> metadata,
base::RefCountedString* file_contents) {
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
@@ -344,7 +410,7 @@ void BackgroundTracingManagerImpl::OnFinalizeStarted(
if (!receive_callback_.is_null()) {
receive_callback_.Run(
- file_contents, GenerateMetadataDict(),
+ file_contents, std::move(metadata),
base::Bind(&BackgroundTracingManagerImpl::OnFinalizeComplete,
base::Unretained(this)));
}
@@ -366,12 +432,15 @@ void BackgroundTracingManagerImpl::OnFinalizeComplete() {
if (!idle_callback_.is_null())
idle_callback_.Run();
+ bool is_allowed_begin =
+ !delegate_ || (config_ &&
+ delegate_->IsAllowedToBeginBackgroundScenario(
+ *config_.get(), requires_anonymized_data_));
+
// Now that a trace has completed, we may need to enable recording again.
// TODO(oysteine): Retry later if IsAllowedToBeginBackgroundScenario fails.
- if (!delegate_ ||
- delegate_->IsAllowedToBeginBackgroundScenario(
- *config_.get(), requires_anonymized_data_)) {
- EnableRecordingIfConfigNeedsIt();
+ if (is_allowed_begin) {
+ StartTracingIfConfigNeedsIt();
} else {
AbortScenario();
}
@@ -379,75 +448,23 @@ void BackgroundTracingManagerImpl::OnFinalizeComplete() {
RecordBackgroundTracingMetric(FINALIZATION_COMPLETE);
}
-scoped_ptr<base::DictionaryValue>
-BackgroundTracingManagerImpl::GenerateMetadataDict() const {
- // Grab the network type.
- std::string network_type = GetNetworkTypeString();
-
- // Grab the product version.
- std::string product_version = GetContentClient()->GetProduct();
+void BackgroundTracingManagerImpl::AddCustomMetadata(
+ TracingControllerImpl::TraceDataSink* trace_data_sink) const {
+ base::DictionaryValue metadata_dict;
- // Serialize the config into json.
scoped_ptr<base::DictionaryValue> config_dict(new base::DictionaryValue());
-
config_->IntoDict(config_dict.get());
+ metadata_dict.Set("config", std::move(config_dict));
- scoped_ptr<base::DictionaryValue> metadata_dict(new base::DictionaryValue());
- metadata_dict->Set("config", config_dict.Pass());
- metadata_dict->SetString("network-type", network_type);
- metadata_dict->SetString("product-version", product_version);
-
- // OS
- metadata_dict->SetString("os-name", base::SysInfo::OperatingSystemName());
- metadata_dict->SetString("os-version",
- base::SysInfo::OperatingSystemVersion());
- metadata_dict->SetString("os-arch",
- base::SysInfo::OperatingSystemArchitecture());
-
- // CPU
- base::CPU cpu;
- metadata_dict->SetInteger("cpu-family", cpu.family());
- metadata_dict->SetInteger("cpu-model", cpu.model());
- metadata_dict->SetInteger("cpu-stepping", cpu.stepping());
- metadata_dict->SetInteger("num-cpus", base::SysInfo::NumberOfProcessors());
- metadata_dict->SetInteger("physical-memory",
- base::SysInfo::AmountOfPhysicalMemoryMB());
-
- std::string cpu_brand = cpu.cpu_brand();
- // Workaround for crbug.com/249713.
- // TODO(oysteine): Remove workaround when bug is fixed.
- size_t null_pos = cpu_brand.find('\0');
- if (null_pos != std::string::npos)
- cpu_brand.erase(null_pos);
- metadata_dict->SetString("cpu-brand", cpu_brand);
-
- // GPU
- gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
-
-#if !defined(OS_ANDROID)
- metadata_dict->SetInteger("gpu-venid", gpu_info.gpu.vendor_id);
- metadata_dict->SetInteger("gpu-devid", gpu_info.gpu.device_id);
-#endif
-
- metadata_dict->SetString("gpu-driver", gpu_info.driver_version);
- metadata_dict->SetString("gpu-psver", gpu_info.pixel_shader_version);
- metadata_dict->SetString("gpu-vsver", gpu_info.vertex_shader_version);
-
-#if defined(OS_MACOSX)
- metadata_dict->SetString("gpu-glver", gpu_info.gl_version);
-#elif defined(OS_POSIX)
- metadata_dict->SetString("gpu-gl-vendor", gpu_info.gl_vendor);
- metadata_dict->SetString("gpu-gl-renderer", gpu_info.gl_renderer);
-#endif
-
- return metadata_dict.Pass();
+ trace_data_sink->AddMetadata(metadata_dict);
}
void BackgroundTracingManagerImpl::BeginFinalizing(
StartedFinalizingCallback callback) {
is_gathering_ = true;
is_tracing_ = false;
- reactive_triggered_handle_ = -1;
+ triggered_named_event_handle_ = -1;
+ tracing_timer_.reset();
bool is_allowed_finalization =
!delegate_ || (config_ &&
@@ -461,17 +478,12 @@ void BackgroundTracingManagerImpl::BeginFinalizing(
base::Bind(&BackgroundTracingManagerImpl::OnFinalizeStarted,
base::Unretained(this))));
RecordBackgroundTracingMetric(FINALIZATION_ALLOWED);
-
- if (auto metadata_dict = GenerateMetadataDict()) {
- std::string results;
- if (base::JSONWriter::Write(*metadata_dict.get(), &results))
- trace_data_sink->SetMetadata(results);
- }
+ AddCustomMetadata(trace_data_sink.get());
} else {
RecordBackgroundTracingMetric(FINALIZATION_DISALLOWED);
}
- content::TracingController::GetInstance()->DisableRecording(trace_data_sink);
+ content::TracingController::GetInstance()->StopTracing(trace_data_sink);
if (!callback.is_null())
callback.Run(is_allowed_finalization);
@@ -479,10 +491,11 @@ void BackgroundTracingManagerImpl::BeginFinalizing(
void BackgroundTracingManagerImpl::AbortScenario() {
is_tracing_ = false;
- reactive_triggered_handle_ = -1;
+ triggered_named_event_handle_ = -1;
config_.reset();
+ tracing_timer_.reset();
- content::TracingController::GetInstance()->DisableRecording(nullptr);
+ content::TracingController::GetInstance()->StopTracing(nullptr);
}
std::string
@@ -499,7 +512,11 @@ BackgroundTracingManagerImpl::GetCategoryFilterStringForCategoryPreset(
case BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_IPC:
return "benchmark,toplevel,ipc";
case BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_STARTUP:
- return "benchmark,toplevel,startup,disabled-by-default-file";
+ return "benchmark,toplevel,startup,disabled-by-default-file,"
+ "disabled-by-default-toplevel.flow,"
+ "disabled-by-default-ipc.flow";
+ case BackgroundTracingConfigImpl::CategoryPreset::BLINK_STYLE:
+ return "blink_style";
}
NOTREACHED();
return "";
diff --git a/chromium/content/browser/tracing/background_tracing_manager_impl.h b/chromium/content/browser/tracing/background_tracing_manager_impl.h
index e5570af2f07..f1d88f26b2b 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_impl.h
+++ b/chromium/content/browser/tracing/background_tracing_manager_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -22,7 +23,7 @@ class TracingDelegate;
class BackgroundTracingManagerImpl : public BackgroundTracingManager {
public:
- static BackgroundTracingManagerImpl* GetInstance();
+ static CONTENT_EXPORT BackgroundTracingManagerImpl* GetInstance();
bool SetActiveScenario(scoped_ptr<BackgroundTracingConfig>,
const ReceiveCallback&,
@@ -32,28 +33,36 @@ class BackgroundTracingManagerImpl : public BackgroundTracingManager {
void TriggerNamedEvent(TriggerHandle, StartedFinalizingCallback) override;
TriggerHandle RegisterTriggerType(const char* trigger_name) override;
+ void OnHistogramTrigger(const std::string& histogram_name);
+
+ void OnRuleTriggered(const BackgroundTracingRule* triggered_rule,
+ StartedFinalizingCallback callback);
+ void AbortScenario();
+ bool HasActiveScenario() override;
+
+ // For tests
void InvalidateTriggerHandlesForTesting() override;
void SetTracingEnabledCallbackForTesting(
const base::Closure& callback) override;
+ CONTENT_EXPORT void SetRuleTriggeredCallbackForTesting(
+ const base::Closure& callback);
void FireTimerForTesting() override;
- bool HasActiveScenarioForTesting() override;
- void OnHistogramTrigger(const std::string& histogram_name);
-
- void TriggerPreemptiveFinalization();
+ CONTENT_EXPORT bool IsTracingForTesting();
private:
BackgroundTracingManagerImpl();
~BackgroundTracingManagerImpl() override;
- void EnableRecording(std::string, base::trace_event::TraceRecordMode);
- void EnableRecordingIfConfigNeedsIt();
- void OnFinalizeStarted(base::RefCountedString*);
+ void StartTracing(std::string, base::trace_event::TraceRecordMode);
+ void StartTracingIfConfigNeedsIt();
+ void OnFinalizeStarted(
+ scoped_ptr<const base::DictionaryValue> metadata,
+ base::RefCountedString*);
void OnFinalizeComplete();
void BeginFinalizing(StartedFinalizingCallback);
void ValidateStartupScenario();
- void AbortScenario();
- scoped_ptr<base::DictionaryValue> GenerateMetadataDict() const;
+ void AddCustomMetadata(TracingControllerImpl::TraceDataSink*) const;
std::string GetTriggerNameFromHandle(TriggerHandle handle) const;
bool IsTriggerHandleValid(TriggerHandle handle) const;
@@ -72,7 +81,6 @@ class BackgroundTracingManagerImpl : public BackgroundTracingManager {
void StartTimer(int seconds);
void CancelTimer();
-
void FireTimerForTesting();
private:
@@ -93,10 +101,11 @@ class BackgroundTracingManagerImpl : public BackgroundTracingManager {
bool requires_anonymized_data_;
int trigger_handle_ids_;
- TriggerHandle reactive_triggered_handle_;
+ TriggerHandle triggered_named_event_handle_;
IdleCallback idle_callback_;
base::Closure tracing_enabled_callback_for_testing_;
+ base::Closure rule_triggered_callback_for_testing_;
friend struct base::DefaultLazyInstanceTraits<BackgroundTracingManagerImpl>;
diff --git a/chromium/content/browser/tracing/background_tracing_rule.cc b/chromium/content/browser/tracing/background_tracing_rule.cc
index 1393a513969..f09608ab0b7 100644
--- a/chromium/content/browser/tracing/background_tracing_rule.cc
+++ b/chromium/content/browser/tracing/background_tracing_rule.cc
@@ -21,11 +21,14 @@ namespace {
const char kConfigRuleKey[] = "rule";
const char kConfigCategoryKey[] = "category";
const char kConfigRuleTriggerNameKey[] = "trigger_name";
+const char kConfigRuleTriggerDelay[] = "trigger_delay";
+const char kConfigRuleTriggerChance[] = "trigger_chance";
const char kConfigRuleHistogramNameKey[] = "histogram_name";
const char kConfigRuleHistogramValueOldKey[] = "histogram_value";
const char kConfigRuleHistogramValue1Key[] = "histogram_lower_value";
const char kConfigRuleHistogramValue2Key[] = "histogram_upper_value";
+const char kConfigRuleHistogramRepeatKey[] = "histogram_repeat";
const char kConfigRuleRandomIntervalTimeoutMin[] = "timeout_min";
const char kConfigRuleRandomIntervalTimeoutMax[] = "timeout_max";
@@ -53,7 +56,7 @@ const int kReactiveTraceRandomStartTimeMax = 120;
namespace content {
-BackgroundTracingRule::BackgroundTracingRule() {}
+BackgroundTracingRule::BackgroundTracingRule() : trigger_chance_(1.0) {}
BackgroundTracingRule::~BackgroundTracingRule() {}
@@ -67,15 +70,41 @@ BackgroundTracingRule::GetCategoryPreset() const {
return BackgroundTracingConfigImpl::BENCHMARK;
}
+int BackgroundTracingRule::GetTraceTimeout() const {
+ return -1;
+}
+
+void BackgroundTracingRule::IntoDict(base::DictionaryValue* dict) const {
+ DCHECK(dict);
+ if (trigger_chance_ < 1.0)
+ dict->SetDouble(kConfigRuleTriggerChance, trigger_chance_);
+}
+
+void BackgroundTracingRule::Setup(const base::DictionaryValue* dict) {
+ dict->GetDouble(kConfigRuleTriggerChance, &trigger_chance_);
+}
+
namespace {
class NamedTriggerRule : public BackgroundTracingRule {
- public:
+ private:
NamedTriggerRule(const std::string& named_event)
: named_event_(named_event) {}
+ public:
+ static scoped_ptr<BackgroundTracingRule> Create(
+ const base::DictionaryValue* dict) {
+ std::string trigger_name;
+ if (!dict->GetString(kConfigRuleTriggerNameKey, &trigger_name))
+ return nullptr;
+
+ return scoped_ptr<BackgroundTracingRule>(
+ new NamedTriggerRule(trigger_name));
+ }
+
void IntoDict(base::DictionaryValue* dict) const override {
DCHECK(dict);
+ BackgroundTracingRule::IntoDict(dict);
dict->SetString(kConfigRuleKey, kPreemptiveConfigRuleMonitorNamed);
dict->SetString(kConfigRuleTriggerNameKey, named_event_.c_str());
}
@@ -90,13 +119,52 @@ class NamedTriggerRule : public BackgroundTracingRule {
class HistogramRule : public BackgroundTracingRule,
public TracingControllerImpl::TraceMessageFilterObserver {
- public:
+ private:
HistogramRule(const std::string& histogram_name,
int histogram_lower_value,
- int histogram_upper_value)
+ int histogram_upper_value,
+ bool repeat,
+ int trigger_delay)
: histogram_name_(histogram_name),
histogram_lower_value_(histogram_lower_value),
- histogram_upper_value_(histogram_upper_value) {}
+ histogram_upper_value_(histogram_upper_value),
+ repeat_(repeat),
+ trigger_delay_(trigger_delay) {}
+
+ public:
+ static scoped_ptr<BackgroundTracingRule> Create(
+ const base::DictionaryValue* dict) {
+ std::string histogram_name;
+ if (!dict->GetString(kConfigRuleHistogramNameKey, &histogram_name))
+ return nullptr;
+
+ // Optional parameter, so we don't need to check if the key exists.
+ bool repeat = true;
+ dict->GetBoolean(kConfigRuleHistogramRepeatKey, &repeat);
+
+ int histogram_lower_value;
+ int histogram_upper_value = std::numeric_limits<int>::max();
+
+ if (!dict->GetInteger(kConfigRuleHistogramValue1Key,
+ &histogram_lower_value)) {
+ // Check for the old naming.
+ if (!dict->GetInteger(kConfigRuleHistogramValueOldKey,
+ &histogram_lower_value))
+ return nullptr;
+ }
+
+ dict->GetInteger(kConfigRuleHistogramValue2Key, &histogram_upper_value);
+
+ if (histogram_lower_value >= histogram_upper_value)
+ return nullptr;
+
+ int trigger_delay = -1;
+ dict->GetInteger(kConfigRuleTriggerDelay, &trigger_delay);
+
+ return scoped_ptr<BackgroundTracingRule>(
+ new HistogramRule(histogram_name, histogram_lower_value,
+ histogram_upper_value, repeat, trigger_delay));
+ }
~HistogramRule() override {
base::StatisticsRecorder::ClearCallback(histogram_name_);
@@ -110,17 +178,21 @@ class HistogramRule : public BackgroundTracingRule,
histogram_name_,
base::Bind(&HistogramRule::OnHistogramChangedCallback,
base::Unretained(this), histogram_name_,
- histogram_lower_value_, histogram_upper_value_));
+ histogram_lower_value_, histogram_upper_value_, repeat_));
TracingControllerImpl::GetInstance()->AddTraceMessageFilterObserver(this);
}
void IntoDict(base::DictionaryValue* dict) const override {
DCHECK(dict);
+ BackgroundTracingRule::IntoDict(dict);
dict->SetString(kConfigRuleKey, kPreemptiveConfigRuleMonitorHistogram);
dict->SetString(kConfigRuleHistogramNameKey, histogram_name_.c_str());
dict->SetInteger(kConfigRuleHistogramValue1Key, histogram_lower_value_);
dict->SetInteger(kConfigRuleHistogramValue2Key, histogram_upper_value_);
+ dict->SetBoolean(kConfigRuleHistogramRepeatKey, repeat_);
+ if (trigger_delay_ != -1)
+ dict->SetInteger(kConfigRuleTriggerDelay, trigger_delay_);
}
void OnHistogramTrigger(const std::string& histogram_name) const override {
@@ -130,14 +202,24 @@ class HistogramRule : public BackgroundTracingRule,
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(
- &BackgroundTracingManagerImpl::TriggerPreemptiveFinalization,
+ &BackgroundTracingManagerImpl::OnRuleTriggered,
+ base::Unretained(BackgroundTracingManagerImpl::GetInstance()), this,
+ BackgroundTracingManager::StartedFinalizingCallback()));
+ }
+
+ void AbortTracing() {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &BackgroundTracingManagerImpl::AbortScenario,
base::Unretained(BackgroundTracingManagerImpl::GetInstance())));
}
// TracingControllerImpl::TraceMessageFilterObserver implementation
void OnTraceMessageFilterAdded(TraceMessageFilter* filter) override {
- filter->Send(new TracingMsg_SetUMACallback(
- histogram_name_, histogram_lower_value_, histogram_upper_value_));
+ filter->Send(
+ new TracingMsg_SetUMACallback(histogram_name_, histogram_lower_value_,
+ histogram_upper_value_, repeat_));
}
void OnTraceMessageFilterRemoved(TraceMessageFilter* filter) override {
@@ -147,30 +229,56 @@ class HistogramRule : public BackgroundTracingRule,
void OnHistogramChangedCallback(const std::string& histogram_name,
base::Histogram::Sample reference_lower_value,
base::Histogram::Sample reference_upper_value,
+ bool repeat,
base::Histogram::Sample actual_value) {
if (reference_lower_value > actual_value ||
- reference_upper_value < actual_value)
+ reference_upper_value < actual_value) {
+ if (!repeat)
+ AbortTracing();
return;
+ }
OnHistogramTrigger(histogram_name);
}
+ bool ShouldTriggerNamedEvent(const std::string& named_event) const override {
+ return named_event == histogram_name_;
+ }
+
+ int GetTraceTimeout() const override { return trigger_delay_; }
+
private:
std::string histogram_name_;
int histogram_lower_value_;
int histogram_upper_value_;
+ bool repeat_;
+ int trigger_delay_;
};
class ReactiveTraceForNSOrTriggerOrFullRule : public BackgroundTracingRule {
- public:
+ private:
ReactiveTraceForNSOrTriggerOrFullRule(
const std::string& named_event,
BackgroundTracingConfigImpl::CategoryPreset category_preset)
: named_event_(named_event), category_preset_(category_preset) {}
+ public:
+ static scoped_ptr<BackgroundTracingRule> Create(
+ const base::DictionaryValue* dict,
+ BackgroundTracingConfigImpl::CategoryPreset category_preset) {
+ std::string trigger_name;
+ if (!dict->GetString(kConfigRuleTriggerNameKey, &trigger_name))
+ return nullptr;
+
+ return scoped_ptr<BackgroundTracingRule>(
+ new ReactiveTraceForNSOrTriggerOrFullRule(trigger_name,
+ category_preset));
+ }
+
// BackgroundTracingRule implementation
void IntoDict(base::DictionaryValue* dict) const override {
DCHECK(dict);
+ BackgroundTracingRule::IntoDict(dict);
dict->SetString(
kConfigCategoryKey,
BackgroundTracingConfigImpl::CategoryPresetToString(category_preset_));
@@ -183,7 +291,7 @@ class ReactiveTraceForNSOrTriggerOrFullRule : public BackgroundTracingRule {
return named_event == named_event_;
}
- int GetReactiveTimeout() const override {
+ int GetTraceTimeout() const override {
return kReactiveConfigNavigationTimeout;
}
@@ -198,7 +306,7 @@ class ReactiveTraceForNSOrTriggerOrFullRule : public BackgroundTracingRule {
};
class ReactiveTraceAtRandomIntervalsRule : public BackgroundTracingRule {
- public:
+ private:
ReactiveTraceAtRandomIntervalsRule(
BackgroundTracingConfigImpl::CategoryPreset category_preset,
int timeout_min,
@@ -209,10 +317,30 @@ class ReactiveTraceAtRandomIntervalsRule : public BackgroundTracingRule {
named_event_ = GenerateUniqueName();
}
+ public:
+ static scoped_ptr<BackgroundTracingRule> Create(
+ const base::DictionaryValue* dict,
+ BackgroundTracingConfigImpl::CategoryPreset category_preset) {
+ int timeout_min;
+ if (!dict->GetInteger(kConfigRuleRandomIntervalTimeoutMin, &timeout_min))
+ return nullptr;
+
+ int timeout_max;
+ if (!dict->GetInteger(kConfigRuleRandomIntervalTimeoutMax, &timeout_max))
+ return nullptr;
+
+ if (timeout_min > timeout_max)
+ return nullptr;
+
+ return scoped_ptr<BackgroundTracingRule>(
+ new ReactiveTraceAtRandomIntervalsRule(category_preset, timeout_min,
+ timeout_max));
+ }
~ReactiveTraceAtRandomIntervalsRule() override {}
void IntoDict(base::DictionaryValue* dict) const override {
DCHECK(dict);
+ BackgroundTracingRule::IntoDict(dict);
dict->SetString(
kConfigCategoryKey,
BackgroundTracingConfigImpl::CategoryPresetToString(category_preset_));
@@ -251,7 +379,7 @@ class ReactiveTraceAtRandomIntervalsRule : public BackgroundTracingRule {
base::Unretained(this)));
}
- int GetReactiveTimeout() const override {
+ int GetTraceTimeout() const override {
return base::RandInt(timeout_min_, timeout_max_);
}
@@ -283,10 +411,6 @@ class ReactiveTraceAtRandomIntervalsRule : public BackgroundTracingRule {
} // namespace
-int BackgroundTracingRule::GetReactiveTimeout() const {
- return -1;
-}
-
scoped_ptr<BackgroundTracingRule> BackgroundTracingRule::PreemptiveRuleFromDict(
const base::DictionaryValue* dict) {
DCHECK(dict);
@@ -295,44 +419,16 @@ scoped_ptr<BackgroundTracingRule> BackgroundTracingRule::PreemptiveRuleFromDict(
if (!dict->GetString(kConfigRuleKey, &type))
return nullptr;
- if (type == kPreemptiveConfigRuleMonitorNamed) {
- std::string trigger_name;
- if (!dict->GetString(kConfigRuleTriggerNameKey, &trigger_name))
- return nullptr;
-
- return scoped_ptr<BackgroundTracingRule>(
- new NamedTriggerRule(trigger_name));
- }
-
- if (type == kPreemptiveConfigRuleMonitorHistogram) {
- std::string histogram_name;
- if (!dict->GetString(kConfigRuleHistogramNameKey, &histogram_name))
- return nullptr;
-
- // Check for the old naming.
- int histogram_value;
- if (dict->GetInteger(kConfigRuleHistogramValueOldKey, &histogram_value))
- return scoped_ptr<BackgroundTracingRule>(new HistogramRule(
- histogram_name, histogram_value, std::numeric_limits<int>::max()));
-
- int histogram_lower_value;
- if (!dict->GetInteger(kConfigRuleHistogramValue1Key,
- &histogram_lower_value))
- return nullptr;
-
- int histogram_upper_value;
- if (!dict->GetInteger(kConfigRuleHistogramValue2Key,
- &histogram_upper_value))
- histogram_upper_value = std::numeric_limits<int>::max();
+ scoped_ptr<BackgroundTracingRule> tracing_rule;
+ if (type == kPreemptiveConfigRuleMonitorNamed)
+ tracing_rule = NamedTriggerRule::Create(dict);
+ else if (type == kPreemptiveConfigRuleMonitorHistogram)
+ tracing_rule = HistogramRule::Create(dict);
- if (histogram_lower_value >= histogram_upper_value)
- return nullptr;
-
- return scoped_ptr<BackgroundTracingRule>(new HistogramRule(
- histogram_name, histogram_lower_value, histogram_upper_value));
- }
+ if (tracing_rule)
+ tracing_rule->Setup(dict);
- return nullptr;
+ return tracing_rule;
}
scoped_ptr<BackgroundTracingRule> BackgroundTracingRule::ReactiveRuleFromDict(
@@ -344,34 +440,20 @@ scoped_ptr<BackgroundTracingRule> BackgroundTracingRule::ReactiveRuleFromDict(
if (!dict->GetString(kConfigRuleKey, &type))
return nullptr;
- if (type == kReactiveConfigRuleTraceOnNavigationUntilTriggerOrFull) {
- std::string trigger_name;
- if (!dict->GetString(kConfigRuleTriggerNameKey, &trigger_name))
- return nullptr;
+ scoped_ptr<BackgroundTracingRule> tracing_rule;
- return scoped_ptr<BackgroundTracingRule>(
- new ReactiveTraceForNSOrTriggerOrFullRule(trigger_name,
- category_preset));
+ if (type == kReactiveConfigRuleTraceOnNavigationUntilTriggerOrFull) {
+ tracing_rule =
+ ReactiveTraceForNSOrTriggerOrFullRule::Create(dict, category_preset);
+ } else if (type == kReactiveConfigRuleTraceAtRandomIntervals) {
+ tracing_rule =
+ ReactiveTraceAtRandomIntervalsRule::Create(dict, category_preset);
}
- if (type == kReactiveConfigRuleTraceAtRandomIntervals) {
- int timeout_min;
- if (!dict->GetInteger(kConfigRuleRandomIntervalTimeoutMin, &timeout_min))
- return nullptr;
-
- int timeout_max;
- if (!dict->GetInteger(kConfigRuleRandomIntervalTimeoutMax, &timeout_max))
- return nullptr;
-
- if (timeout_min > timeout_max)
- return nullptr;
-
- return scoped_ptr<BackgroundTracingRule>(
- new ReactiveTraceAtRandomIntervalsRule(category_preset, timeout_min,
- timeout_max));
- }
+ if (tracing_rule)
+ tracing_rule->Setup(dict);
- return nullptr;
+ return tracing_rule;
}
} // namespace content
diff --git a/chromium/content/browser/tracing/background_tracing_rule.h b/chromium/content/browser/tracing/background_tracing_rule.h
index 2f693c9a1a7..3277716bd22 100644
--- a/chromium/content/browser/tracing/background_tracing_rule.h
+++ b/chromium/content/browser/tracing/background_tracing_rule.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_RULE_H_
#define CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_RULE_H_
+#include "base/macros.h"
#include "content/browser/tracing/background_tracing_config_impl.h"
#include "content/common/content_export.h"
@@ -20,12 +21,17 @@ class CONTENT_EXPORT BackgroundTracingRule {
virtual ~BackgroundTracingRule();
virtual void Install() {}
- virtual void IntoDict(base::DictionaryValue* dict) const = 0;
+ virtual void IntoDict(base::DictionaryValue* dict) const;
+ void Setup(const base::DictionaryValue* dict);
virtual bool ShouldTriggerNamedEvent(const std::string& named_event) const;
virtual BackgroundTracingConfigImpl::CategoryPreset GetCategoryPreset() const;
virtual void OnHistogramTrigger(const std::string& histogram_name) const {}
- virtual int GetReactiveTimeout() const;
+ // Seconds from the rule is triggered to finalization should start.
+ virtual int GetTraceTimeout() const;
+
+ // Probability that we should allow a tigger to happen.
+ double trigger_chance() const { return trigger_chance_; }
static scoped_ptr<BackgroundTracingRule> PreemptiveRuleFromDict(
const base::DictionaryValue* dict);
@@ -36,6 +42,8 @@ class CONTENT_EXPORT BackgroundTracingRule {
private:
DISALLOW_COPY_AND_ASSIGN(BackgroundTracingRule);
+
+ double trigger_chance_;
};
} // namespace content
diff --git a/chromium/content/browser/tracing/battor_power_trace_provider.cc b/chromium/content/browser/tracing/battor_power_trace_provider.cc
index c4c90bdda26..41e99110381 100644
--- a/chromium/content/browser/tracing/battor_power_trace_provider.cc
+++ b/chromium/content/browser/tracing/battor_power_trace_provider.cc
@@ -22,6 +22,8 @@ bool BattorPowerTraceProvider::StopTracing() {
return false;
}
+void BattorPowerTraceProvider::RecordClockSyncMarker(int sync_id) {}
+
void BattorPowerTraceProvider::GetLog(std::string* log_str) {
// Get logs from battor.
*log_str = "";
diff --git a/chromium/content/browser/tracing/battor_power_trace_provider.h b/chromium/content/browser/tracing/battor_power_trace_provider.h
index 26ab3e01e30..8a9a5b5e890 100644
--- a/chromium/content/browser/tracing/battor_power_trace_provider.h
+++ b/chromium/content/browser/tracing/battor_power_trace_provider.h
@@ -13,13 +13,14 @@ namespace content {
// This class handles the connection with the battor h/w using
// chrome serial port interfaces.
-// TODO (aschulman) port over battor C code.
+// TODO(charliea): port over battor C code.
class BattorPowerTraceProvider {
public:
BattorPowerTraceProvider();
bool IsConnected();
bool StartTracing();
bool StopTracing();
+ void RecordClockSyncMarker(int sync_id);
void GetLog(std::string* log_str);
~BattorPowerTraceProvider();
diff --git a/chromium/content/browser/tracing/etw_system_event_consumer_win.cc b/chromium/content/browser/tracing/etw_system_event_consumer_win.cc
index 7d8b327dde8..07dfd4db7b8 100644
--- a/chromium/content/browser/tracing/etw_system_event_consumer_win.cc
+++ b/chromium/content/browser/tracing/etw_system_event_consumer_win.cc
@@ -4,6 +4,8 @@
#include "content/browser/tracing/etw_system_event_consumer_win.h"
+#include <stdint.h>
+
#include "base/base64.h"
#include "base/json/json_string_value_serializer.h"
#include "base/lazy_instance.h"
@@ -17,6 +19,9 @@ namespace content {
namespace {
+const char kETWTracingAgentName[] = "etw";
+const char kETWTraceLabel[] = "systemTraceEvents";
+
const int kEtwBufferSizeInKBytes = 16;
const int kEtwBufferFlushTimeoutInSeconds = 1;
@@ -36,8 +41,16 @@ EtwSystemEventConsumer::EtwSystemEventConsumer()
EtwSystemEventConsumer::~EtwSystemEventConsumer() {
}
-bool EtwSystemEventConsumer::StartSystemTracing() {
+std::string EtwSystemEventConsumer::GetTracingAgentName() {
+ return kETWTracingAgentName;
+}
+
+std::string EtwSystemEventConsumer::GetTraceEventLabel() {
+ return kETWTraceLabel;
+}
+bool EtwSystemEventConsumer::StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) {
// Activate kernel tracing.
if (!StartKernelSessionTracing())
return false;
@@ -52,39 +65,36 @@ bool EtwSystemEventConsumer::StartSystemTracing() {
return true;
}
-void EtwSystemEventConsumer::StopSystemTracing(const OutputCallback& callback) {
+void EtwSystemEventConsumer::StopAgentTracing(
+ const StopAgentTracingCallback& callback) {
// Deactivate kernel tracing.
if (!StopKernelSessionTracing()) {
LOG(FATAL) << "Could not stop system tracing.";
}
// Stop consuming and flush events.
- OutputCallback on_stop_system_tracing_done_callback =
- base::Bind(&EtwSystemEventConsumer::OnStopSystemTracingDone,
- base::Unretained(this),
- callback);
thread_.message_loop()->PostTask(FROM_HERE,
base::Bind(&EtwSystemEventConsumer::FlushOnThread,
- base::Unretained(this), on_stop_system_tracing_done_callback));
+ base::Unretained(this),
+ callback));
}
void EtwSystemEventConsumer::OnStopSystemTracingDone(
- const OutputCallback& callback,
+ const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result) {
// Stop the consumer thread.
thread_.Stop();
// Pass the serialized events.
- callback.Run(result);
+ callback.Run(GetTracingAgentName(), GetTraceEventLabel(), result);
}
bool EtwSystemEventConsumer::StartKernelSessionTracing() {
// Enabled flags (tracing facilities).
- uint32 enabled_flags = EVENT_TRACE_FLAG_IMAGE_LOAD |
- EVENT_TRACE_FLAG_PROCESS |
- EVENT_TRACE_FLAG_THREAD |
- EVENT_TRACE_FLAG_CSWITCH;
+ uint32_t enabled_flags = EVENT_TRACE_FLAG_IMAGE_LOAD |
+ EVENT_TRACE_FLAG_PROCESS | EVENT_TRACE_FLAG_THREAD |
+ EVENT_TRACE_FLAG_CSWITCH;
EVENT_TRACE_PROPERTIES& p = *properties_.get();
p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
@@ -140,7 +150,7 @@ void EtwSystemEventConsumer::ProcessEvent(EVENT_TRACE* event) {
void EtwSystemEventConsumer::AddSyncEventToBuffer() {
// Sync the clocks.
base::Time walltime = base::Time::NowFromSystemTime();
- base::TraceTicks now = base::TraceTicks::Now();
+ base::TimeTicks now = base::TimeTicks::Now();
LARGE_INTEGER walltime_in_us;
walltime_in_us.QuadPart = walltime.ToInternalValue();
@@ -209,7 +219,8 @@ void EtwSystemEventConsumer::TraceAndConsumeOnThread() {
Close();
}
-void EtwSystemEventConsumer::FlushOnThread(const OutputCallback& callback) {
+void EtwSystemEventConsumer::FlushOnThread(
+ const StopAgentTracingCallback& callback) {
// Add the header information to the stream.
scoped_ptr<base::DictionaryValue> header(new base::DictionaryValue());
header->Set("name", new base::StringValue("ETW"));
@@ -225,8 +236,12 @@ void EtwSystemEventConsumer::FlushOnThread(const OutputCallback& callback) {
// Pass the result to the UI Thread.
scoped_refptr<base::RefCountedString> result =
base::RefCountedString::TakeString(&output);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(callback, result));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&EtwSystemEventConsumer::OnStopSystemTracingDone,
+ base::Unretained(this),
+ callback,
+ result));
}
} // namespace content
diff --git a/chromium/content/browser/tracing/etw_system_event_consumer_win.h b/chromium/content/browser/tracing/etw_system_event_consumer_win.h
index 25f4656f7ad..4327365386a 100644
--- a/chromium/content/browser/tracing/etw_system_event_consumer_win.h
+++ b/chromium/content/browser/tracing/etw_system_event_consumer_win.h
@@ -6,8 +6,10 @@
#define CONTENT_BROWSER_TRACING_ETW_SYSTEM_EVENT_CONSUMER_WIN_H_
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/threading/thread.h"
+#include "base/trace_event/tracing_agent.h"
#include "base/values.h"
#include "base/win/event_trace_consumer.h"
#include "base/win/event_trace_controller.h"
@@ -19,14 +21,16 @@ struct DefaultSingletonTraits;
namespace content {
-class EtwSystemEventConsumer :
- public base::win::EtwTraceConsumerBase<EtwSystemEventConsumer> {
+class EtwSystemEventConsumer
+ : public base::win::EtwTraceConsumerBase<EtwSystemEventConsumer>,
+ public base::trace_event::TracingAgent {
public:
- typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
- OutputCallback;
-
- bool StartSystemTracing();
- void StopSystemTracing(const OutputCallback& callback);
+ // base::trace_event::TracingAgent implementation.
+ std::string GetTracingAgentName() override;
+ std::string GetTraceEventLabel() override;
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override;
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override;
// Retrieve the ETW consumer instance.
static EtwSystemEventConsumer* GetInstance();
@@ -38,7 +42,7 @@ class EtwSystemEventConsumer :
// Constructor.
EtwSystemEventConsumer();
- virtual ~EtwSystemEventConsumer();
+ ~EtwSystemEventConsumer() override;
void AddSyncEventToBuffer();
void AppendEventToBuffer(EVENT_TRACE* event);
@@ -58,11 +62,11 @@ class EtwSystemEventConsumer :
bool StopKernelSessionTracing();
void OnStopSystemTracingDone(
- const OutputCallback& callback,
+ const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result);
void TraceAndConsumeOnThread();
- void FlushOnThread(const OutputCallback& callback);
+ void FlushOnThread(const StopAgentTracingCallback& callback);
scoped_ptr<base::ListValue> events_;
base::Thread thread_;
diff --git a/chromium/content/browser/tracing/file_tracing_provider_impl.cc b/chromium/content/browser/tracing/file_tracing_provider_impl.cc
index 5406231bbf7..7f63024942c 100644
--- a/chromium/content/browser/tracing/file_tracing_provider_impl.cc
+++ b/chromium/content/browser/tracing/file_tracing_provider_impl.cc
@@ -31,7 +31,7 @@ void FileTracingProviderImpl::FileTracingDisable(void* id) {
}
void FileTracingProviderImpl::FileTracingEventBegin(
- const char* name, void* id, const base::FilePath& path, int64 size) {
+ const char* name, void* id, const base::FilePath& path, int64_t size) {
TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(kFileTracingEventCategoryGroup, name, id,
"path", path.AsUTF8Unsafe(), "size", size);
}
diff --git a/chromium/content/browser/tracing/file_tracing_provider_impl.h b/chromium/content/browser/tracing/file_tracing_provider_impl.h
index 1dc01a4fd7e..8926635adae 100644
--- a/chromium/content/browser/tracing/file_tracing_provider_impl.h
+++ b/chromium/content/browser/tracing/file_tracing_provider_impl.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_TRACING_FILE_TRACING_PROVIDER_IMPL_H_
#define CONTENT_BROWSER_TRACING_FILE_TRACING_PROVIDER_IMPL_H_
+#include <stdint.h>
+
#include "base/files/file_tracing.h"
#include "base/macros.h"
@@ -22,7 +24,7 @@ class FileTracingProviderImpl : public base::FileTracing::Provider {
void FileTracingEnable(void* id) override;
void FileTracingDisable(void* id) override;
void FileTracingEventBegin(const char* name, void* id,
- const base::FilePath& path, int64 size) override;
+ const base::FilePath& path, int64_t size) override;
void FileTracingEventEnd(const char* name, void* id) override;
private:
diff --git a/chromium/content/browser/tracing/memory_tracing_browsertest.cc b/chromium/content/browser/tracing/memory_tracing_browsertest.cc
index 6b6437c9ae2..13b09231230 100644
--- a/chromium/content/browser/tracing/memory_tracing_browsertest.cc
+++ b/chromium/content/browser/tracing/memory_tracing_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/run_loop.h"
@@ -47,7 +49,7 @@ class MemoryTracingTest : public ContentBrowserTest {
void OnGlobalMemoryDumpDone(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::Closure closure,
- uint64 dump_guid,
+ uint64_t dump_guid,
bool success) {
// Make sure we run the RunLoop closure on the same thread that originated
// the run loop (which is the IN_PROC_BROWSER_TEST_F main thread).
@@ -72,7 +74,9 @@ class MemoryTracingTest : public ContentBrowserTest {
mock_dump_provider_.reset(new MockDumpProvider());
MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- mock_dump_provider_.get());
+ mock_dump_provider_.get(), "MockDumpProvider", nullptr);
+ MemoryDumpManager::GetInstance()
+ ->set_dumper_registrations_ignored_for_testing(false);
ContentBrowserTest::SetUp();
}
@@ -90,14 +94,14 @@ class MemoryTracingTest : public ContentBrowserTest {
GetTraceConfig_EmptyTriggers());
base::RunLoop run_loop;
- bool success = TracingController::GetInstance()->EnableRecording(
+ bool success = TracingController::GetInstance()->StartTracing(
trace_config, run_loop.QuitClosure());
EXPECT_TRUE(success);
run_loop.Run();
}
void DisableTracing() {
- bool success = TracingController::GetInstance()->DisableRecording(NULL);
+ bool success = TracingController::GetInstance()->StopTracing(NULL);
EXPECT_TRUE(success);
base::RunLoop().RunUntilIdle();
}
@@ -123,8 +127,8 @@ class MemoryTracingTest : public ContentBrowserTest {
base::Closure on_memory_dump_complete_closure_;
scoped_ptr<MockDumpProvider> mock_dump_provider_;
- uint32 callback_call_count_;
- uint64 last_callback_dump_guid_;
+ uint32_t callback_call_count_;
+ uint64_t last_callback_dump_guid_;
bool last_callback_success_;
};
@@ -204,9 +208,15 @@ IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, ManyInterleavedDumps) {
#endif // !defined(GOOGLE_CHROME_BUILD)
+// Non-deterministic races under TSan. crbug.com/529678
+#if defined(THREAD_SANITIZER)
+#define MAYBE_BrowserInitiatedDump DISABLED_BrowserInitiatedDump
+#else
+#define MAYBE_BrowserInitiatedDump BrowserInitiatedDump
+#endif
// Checks that a memory dump initiated from a the main browser thread ends up in
// a successful dump.
-IN_PROC_BROWSER_TEST_F(MemoryTracingTest, BrowserInitiatedDump) {
+IN_PROC_BROWSER_TEST_F(MemoryTracingTest, MAYBE_BrowserInitiatedDump) {
Navigate(shell());
EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true));
diff --git a/chromium/content/browser/tracing/power_tracing_agent.cc b/chromium/content/browser/tracing/power_tracing_agent.cc
index 409240c4fe7..6bf47e66bd2 100644
--- a/chromium/content/browser/tracing/power_tracing_agent.cc
+++ b/chromium/content/browser/tracing/power_tracing_agent.cc
@@ -11,63 +11,129 @@
namespace content {
-PowerTracingAgent::PowerTracingAgent() : is_tracing_(false) {
+namespace {
+
+const char kPowerTracingAgentName[] = "battor";
+const char kPowerTraceLabel[] = "powerTraceAsString";
+
+} // namespace
+
+// static
+PowerTracingAgent* PowerTracingAgent::GetInstance() {
+ return base::Singleton<PowerTracingAgent>::get();
+}
+
+PowerTracingAgent::PowerTracingAgent() : thread_("PowerTracingAgentThread") {
battor_trace_provider_.reset(new BattorPowerTraceProvider());
}
PowerTracingAgent::~PowerTracingAgent() {}
-bool PowerTracingAgent::StartTracing() {
- // Tracing session already in progress.
- if (is_tracing_)
+std::string PowerTracingAgent::GetTracingAgentName() {
+ return kPowerTracingAgentName;
+}
+
+std::string PowerTracingAgent::GetTraceEventLabel() {
+ return kPowerTraceLabel;
+}
+
+bool PowerTracingAgent::StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // TODO(charliea): When system tracing is enabled in about://tracing, it will
+ // trigger power tracing. We need a way of checking if BattOr is connected.
+ // Currently, IsConnected() always returns false, so that we do not include
+ // BattOr trace until it is hooked up.
+ if (!battor_trace_provider_->IsConnected())
return false;
- // TODO(prabhur) Start tracing probably needs to be done in a
- // separate thread since it involves talking to the h/w.
- // Revisit once battor h/w communication is enabled.
- is_tracing_ = battor_trace_provider_->StartTracing();
- return is_tracing_;
+ thread_.Start();
+
+ thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&PowerTracingAgent::TraceOnThread, base::Unretained(this)));
+ return true;
}
-void PowerTracingAgent::StopTracing(const OutputCallback& callback) {
- // No tracing session in progress.
- if (!is_tracing_)
- return;
+void PowerTracingAgent::StopAgentTracing(
+ const StopAgentTracingCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(thread_.IsRunning());
- // Stop tracing & collect logs.
- OutputCallback on_stop_power_tracing_done_callback = base::Bind(
- &PowerTracingAgent::OnStopTracingDone, base::Unretained(this), callback);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ thread_.task_runner()->PostTask(
+ FROM_HERE,
base::Bind(&PowerTracingAgent::FlushOnThread, base::Unretained(this),
- on_stop_power_tracing_done_callback));
+ callback));
}
void PowerTracingAgent::OnStopTracingDone(
- const OutputCallback& callback,
+ const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result) {
- is_tracing_ = false;
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
// Pass the serialized events.
- callback.Run(result);
+ callback.Run(GetTracingAgentName(), GetTraceEventLabel(), result);
+
+ // Stop the power tracing agent thread on file thread.
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&base::Thread::Stop, base::Unretained(&thread_)));
}
-// static
-PowerTracingAgent* PowerTracingAgent::GetInstance() {
- return base::Singleton<PowerTracingAgent>::get();
+void PowerTracingAgent::TraceOnThread() {
+ DCHECK(thread_.task_runner()->BelongsToCurrentThread());
+ battor_trace_provider_->StartTracing();
}
-void PowerTracingAgent::FlushOnThread(const OutputCallback& callback) {
- // Pass the result to the UI Thread.
+void PowerTracingAgent::FlushOnThread(
+ const StopAgentTracingCallback& callback) {
+ DCHECK(thread_.task_runner()->BelongsToCurrentThread());
- // TODO(prabhur) StopTracing & GetLog need to be called on a
- // separate thread depending on how BattorPowerTraceProvider is implemented.
battor_trace_provider_->StopTracing();
std::string battor_logs;
battor_trace_provider_->GetLog(&battor_logs);
scoped_refptr<base::RefCountedString> result =
base::RefCountedString::TakeString(&battor_logs);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(callback, result));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PowerTracingAgent::OnStopTracingDone,
+ base::Unretained(this),
+ callback,
+ result));
+}
+
+bool PowerTracingAgent::SupportsExplicitClockSync() {
+ return true;
+}
+
+void PowerTracingAgent::RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(SupportsExplicitClockSync());
+
+ thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&PowerTracingAgent::RecordClockSyncMarkerOnThread,
+ base::Unretained(this),
+ sync_id,
+ callback));
+}
+
+void PowerTracingAgent::RecordClockSyncMarkerOnThread(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) {
+ DCHECK(thread_.task_runner()->BelongsToCurrentThread());
+ DCHECK(SupportsExplicitClockSync());
+
+ base::TimeTicks issue_ts = base::TimeTicks::Now();
+ battor_trace_provider_->RecordClockSyncMarker(sync_id);
+ base::TimeTicks issue_end_ts = base::TimeTicks::Now();
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, sync_id, issue_ts, issue_end_ts));
}
} // namespace content
diff --git a/chromium/content/browser/tracing/power_tracing_agent.h b/chromium/content/browser/tracing/power_tracing_agent.h
index 3c897d6753d..58c6a87d02c 100644
--- a/chromium/content/browser/tracing/power_tracing_agent.h
+++ b/chromium/content/browser/tracing/power_tracing_agent.h
@@ -5,8 +5,10 @@
#ifndef CONTENT_BROWSER_TRACING_POWER_TRACING_AGENT_H_
#define CONTENT_BROWSER_TRACING_POWER_TRACING_AGENT_H_
+#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/threading/thread.h"
+#include "base/trace_event/tracing_agent.h"
namespace base {
template <typename Type>
@@ -17,17 +19,24 @@ namespace content {
class BattorPowerTraceProvider;
-class PowerTracingAgent {
+class PowerTracingAgent : public base::trace_event::TracingAgent {
public:
- typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
- OutputCallback;
-
- bool StartTracing();
- void StopTracing(const OutputCallback& callback);
-
// Retrieve the singleton instance.
static PowerTracingAgent* GetInstance();
+ // base::trace_event::TracingAgent implementation.
+ std::string GetTracingAgentName() override;
+ std::string GetTraceEventLabel() override;
+
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override;
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override;
+
+ bool SupportsExplicitClockSync() override;
+ void RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) override;
+
private:
// This allows constructor and destructor to be private and usable only
// by the Singleton class.
@@ -35,15 +44,19 @@ class PowerTracingAgent {
// Constructor.
PowerTracingAgent();
- virtual ~PowerTracingAgent();
+ ~PowerTracingAgent() override;
- void OnStopTracingDone(const OutputCallback& callback,
+ void OnStopTracingDone(const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result);
- void FlushOnThread(const OutputCallback& callback);
+ void TraceOnThread();
+ void FlushOnThread(const StopAgentTracingCallback& callback);
+ void RecordClockSyncMarkerOnThread(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback);
+ base::Thread thread_;
scoped_ptr<BattorPowerTraceProvider> battor_trace_provider_;
- bool is_tracing_;
DISALLOW_COPY_AND_ASSIGN(PowerTracingAgent);
};
diff --git a/chromium/content/browser/tracing/trace_message_filter.cc b/chromium/content/browser/tracing/trace_message_filter.cc
index a26c6542b39..45cb7023379 100644
--- a/chromium/content/browser/tracing/trace_message_filter.cc
+++ b/chromium/content/browser/tracing/trace_message_filter.cc
@@ -62,6 +62,8 @@ bool TraceMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnProcessMemoryDumpResponse)
IPC_MESSAGE_HANDLER(TracingHostMsg_TriggerBackgroundTrace,
OnTriggerBackgroundTrace)
+ IPC_MESSAGE_HANDLER(TracingHostMsg_AbortBackgroundTrace,
+ OnAbortBackgroundTrace)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -71,7 +73,7 @@ void TraceMessageFilter::SendBeginTracing(
const base::trace_event::TraceConfig& trace_config) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
Send(new TracingMsg_BeginTracing(
- trace_config.ToString(), base::TraceTicks::Now(), tracing_process_id_));
+ trace_config.ToString(), base::TimeTicks::Now(), tracing_process_id_));
}
void TraceMessageFilter::SendEndTracing() {
@@ -88,16 +90,16 @@ void TraceMessageFilter::SendCancelTracing() {
Send(new TracingMsg_CancelTracing);
}
-void TraceMessageFilter::SendEnableMonitoring(
+void TraceMessageFilter::SendStartMonitoring(
const base::trace_event::TraceConfig& trace_config) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- Send(new TracingMsg_EnableMonitoring(trace_config.ToString(),
- base::TraceTicks::Now()));
+ Send(new TracingMsg_StartMonitoring(trace_config.ToString(),
+ base::TimeTicks::Now()));
}
-void TraceMessageFilter::SendDisableMonitoring() {
+void TraceMessageFilter::SendStopMonitoring() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- Send(new TracingMsg_DisableMonitoring);
+ Send(new TracingMsg_StopMonitoring);
}
void TraceMessageFilter::SendCaptureMonitoringSnapshot() {
@@ -130,7 +132,7 @@ void TraceMessageFilter::SendProcessMemoryDumpRequest(
}
// Called by TracingControllerImpl, which handles the multiprocess coordination.
-void TraceMessageFilter::SendGlobalMemoryDumpResponse(uint64 dump_guid,
+void TraceMessageFilter::SendGlobalMemoryDumpResponse(uint64_t dump_guid,
bool success) {
Send(new TracingMsg_GlobalMemoryDumpResponse(dump_guid, success));
}
@@ -146,7 +148,7 @@ void TraceMessageFilter::OnEndTracingAck(
// child process is compromised.
if (is_awaiting_end_ack_) {
is_awaiting_end_ack_ = false;
- TracingControllerImpl::GetInstance()->OnDisableRecordingAcked(
+ TracingControllerImpl::GetInstance()->OnStopTracingAcked(
this, known_categories);
} else {
NOTREACHED();
@@ -200,7 +202,7 @@ void TraceMessageFilter::OnGlobalMemoryDumpRequest(
base::Bind(&TraceMessageFilter::SendGlobalMemoryDumpResponse, this));
}
-void TraceMessageFilter::OnProcessMemoryDumpResponse(uint64 dump_guid,
+void TraceMessageFilter::OnProcessMemoryDumpResponse(uint64_t dump_guid,
bool success) {
TracingControllerImpl::GetInstance()->OnProcessMemoryDumpResponse(
this, dump_guid, success);
@@ -210,4 +212,8 @@ void TraceMessageFilter::OnTriggerBackgroundTrace(const std::string& name) {
BackgroundTracingManagerImpl::GetInstance()->OnHistogramTrigger(name);
}
+void TraceMessageFilter::OnAbortBackgroundTrace() {
+ BackgroundTracingManagerImpl::GetInstance()->AbortScenario();
+}
+
} // namespace content
diff --git a/chromium/content/browser/tracing/trace_message_filter.h b/chromium/content/browser/tracing/trace_message_filter.h
index 7da12b0736c..22d91d914ad 100644
--- a/chromium/content/browser/tracing/trace_message_filter.h
+++ b/chromium/content/browser/tracing/trace_message_filter.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_TRACING_TRACE_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_TRACING_TRACE_MESSAGE_FILTER_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/trace_event.h"
#include "content/public/browser/browser_message_filter.h"
@@ -29,9 +32,9 @@ class TraceMessageFilter : public BrowserMessageFilter {
const base::trace_event::TraceConfig& trace_config);
void SendEndTracing();
void SendCancelTracing();
- void SendEnableMonitoring(
+ void SendStartMonitoring(
const base::trace_event::TraceConfig& trace_config);
- void SendDisableMonitoring();
+ void SendStopMonitoring();
void SendCaptureMonitoringSnapshot();
void SendGetTraceLogStatus();
void SendSetWatchEvent(const std::string& category_name,
@@ -54,16 +57,17 @@ class TraceMessageFilter : public BrowserMessageFilter {
void OnMonitoringTraceDataCollected(const std::string& data);
void OnGlobalMemoryDumpRequest(
const base::trace_event::MemoryDumpRequestArgs& args);
- void OnProcessMemoryDumpResponse(uint64 dump_guid, bool success);
+ void OnProcessMemoryDumpResponse(uint64_t dump_guid, bool success);
- void SendGlobalMemoryDumpResponse(uint64 dump_guid, bool success);
+ void SendGlobalMemoryDumpResponse(uint64_t dump_guid, bool success);
void OnTriggerBackgroundTrace(const std::string& histogram_name);
+ void OnAbortBackgroundTrace();
// ChildTraceMessageFilter exists:
bool has_child_;
// Hash of id of the child process.
- uint64 tracing_process_id_;
+ uint64_t tracing_process_id_;
// Awaiting ack for previously sent SendEndTracing
bool is_awaiting_end_ack_;
diff --git a/chromium/content/browser/tracing/tracing_controller_browsertest.cc b/chromium/content/browser/tracing/tracing_controller_browsertest.cc
index ca94e40f0c8..d4b8671d915 100644
--- a/chromium/content/browser/tracing/tracing_controller_browsertest.cc
+++ b/chromium/content/browser/tracing/tracing_controller_browsertest.cc
@@ -2,11 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/public/browser/tracing_controller.h"
+
+#include <stdint.h>
+#include <utility>
+
#include "base/files/file_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
+#include "base/strings/pattern.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/tracing_controller.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -18,11 +24,43 @@ using base::trace_event::TraceConfig;
namespace content {
+namespace {
+
+const char* kMetadataWhitelist[] = {
+ "cpu-brand",
+ "network-type",
+ "os-name",
+ "user-agent"
+};
+
+bool IsMetadataWhitelisted(const std::string& metadata_name) {
+ for (auto key : kMetadataWhitelist) {
+ if (base::MatchPattern(metadata_name, key)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IsTraceEventArgsWhitelisted(
+ const char* category_group_name,
+ const char* event_name,
+ base::trace_event::ArgumentNameFilterPredicate* arg_filter) {
+ if (base::MatchPattern(category_group_name, "benchmark") &&
+ base::MatchPattern(event_name, "whitelisted")) {
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
class TracingControllerTestEndpoint
: public TracingController::TraceDataEndpoint {
public:
TracingControllerTestEndpoint(
- base::Callback<void(base::RefCountedString*)> done_callback)
+ base::Callback<void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)> done_callback)
: done_callback_(done_callback) {}
void ReceiveTraceChunk(const std::string& chunk) override {
@@ -30,7 +68,9 @@ class TracingControllerTestEndpoint
trace_ += chunk;
}
- void ReceiveTraceFinalContents(const std::string& contents) override {
+ void ReceiveTraceFinalContents(
+ scoped_ptr<const base::DictionaryValue> metadata,
+ const std::string& contents) override {
EXPECT_EQ(trace_, contents);
std::string tmp = contents;
@@ -39,14 +79,16 @@ class TracingControllerTestEndpoint
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(done_callback_, chunk_ptr));
+ base::Bind(done_callback_, base::Passed(std::move(metadata)),
+ chunk_ptr));
}
protected:
~TracingControllerTestEndpoint() override {}
std::string trace_;
- base::Callback<void(base::RefCountedString*)> done_callback_;
+ base::Callback<void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)> done_callback_;
};
class TracingControllerTest : public ContentBrowserTest {
@@ -76,35 +118,39 @@ class TracingControllerTest : public ContentBrowserTest {
quit_callback.Run();
}
- void EnableRecordingDoneCallbackTest(base::Closure quit_callback) {
+ void StartTracingDoneCallbackTest(base::Closure quit_callback) {
enable_recording_done_callback_count_++;
quit_callback.Run();
}
- void DisableRecordingStringDoneCallbackTest(base::Closure quit_callback,
- base::RefCountedString* data) {
+ void StopTracingStringDoneCallbackTest(
+ base::Closure quit_callback,
+ scoped_ptr<const base::DictionaryValue> metadata,
+ base::RefCountedString* data) {
disable_recording_done_callback_count_++;
+ last_metadata_.reset(metadata.release());
+ last_data_ = data->data();
EXPECT_TRUE(data->size() > 0);
quit_callback.Run();
}
- void DisableRecordingFileDoneCallbackTest(base::Closure quit_callback,
+ void StopTracingFileDoneCallbackTest(base::Closure quit_callback,
const base::FilePath& file_path) {
disable_recording_done_callback_count_++;
EXPECT_TRUE(PathExists(file_path));
- int64 file_size;
+ int64_t file_size;
base::GetFileSize(file_path, &file_size);
EXPECT_TRUE(file_size > 0);
quit_callback.Run();
last_actual_recording_file_path_ = file_path;
}
- void EnableMonitoringDoneCallbackTest(base::Closure quit_callback) {
+ void StartMonitoringDoneCallbackTest(base::Closure quit_callback) {
enable_monitoring_done_callback_count_++;
quit_callback.Run();
}
- void DisableMonitoringDoneCallbackTest(base::Closure quit_callback) {
+ void StopMonitoringDoneCallbackTest(base::Closure quit_callback) {
disable_monitoring_done_callback_count_++;
quit_callback.Run();
}
@@ -113,7 +159,7 @@ class TracingControllerTest : public ContentBrowserTest {
base::Closure quit_callback, const base::FilePath& file_path) {
capture_monitoring_snapshot_done_callback_count_++;
EXPECT_TRUE(PathExists(file_path));
- int64 file_size;
+ int64_t file_size;
base::GetFileSize(file_path, &file_size);
EXPECT_TRUE(file_size > 0);
quit_callback.Run();
@@ -152,18 +198,26 @@ class TracingControllerTest : public ContentBrowserTest {
return last_actual_monitoring_file_path_;
}
- void TestEnableAndDisableRecordingString() {
+ const base::DictionaryValue* last_metadata() const {
+ return last_metadata_.get();
+ }
+
+ const std::string& last_data() const {
+ return last_data_;
+ }
+
+ void TestStartAndStopTracingString() {
Navigate(shell());
TracingController* controller = TracingController::GetInstance();
{
base::RunLoop run_loop;
- TracingController::EnableRecordingDoneCallback callback =
- base::Bind(&TracingControllerTest::EnableRecordingDoneCallbackTest,
+ TracingController::StartTracingDoneCallback callback =
+ base::Bind(&TracingControllerTest::StartTracingDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure());
- bool result = controller->EnableRecording(
+ bool result = controller->StartTracing(
TraceConfig(), callback);
ASSERT_TRUE(result);
run_loop.Run();
@@ -172,11 +226,12 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
- base::Callback<void(base::RefCountedString*)> callback = base::Bind(
- &TracingControllerTest::DisableRecordingStringDoneCallbackTest,
+ base::Callback<void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)> callback = base::Bind(
+ &TracingControllerTest::StopTracingStringDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure());
- bool result = controller->DisableRecording(
+ bool result = controller->StopTracing(
TracingController::CreateStringSink(callback));
ASSERT_TRUE(result);
run_loop.Run();
@@ -184,17 +239,64 @@ class TracingControllerTest : public ContentBrowserTest {
}
}
- void TestEnableAndDisableRecordingCompressed() {
+ void TestStartAndStopTracingStringWithFilter() {
Navigate(shell());
+ base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
+ base::Bind(&IsTraceEventArgsWhitelisted));
TracingController* controller = TracingController::GetInstance();
{
base::RunLoop run_loop;
- TracingController::EnableRecordingDoneCallback callback =
- base::Bind(&TracingControllerTest::EnableRecordingDoneCallbackTest,
+ TracingController::StartTracingDoneCallback callback =
+ base::Bind(&TracingControllerTest::StartTracingDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+
+ TraceConfig config = TraceConfig();
+ config.EnableArgumentFilter();
+
+ bool result = controller->StartTracing(config, callback);
+ ASSERT_TRUE(result);
+ run_loop.Run();
+ EXPECT_EQ(enable_recording_done_callback_count(), 1);
+ }
+
+ {
+ base::RunLoop run_loop;
+ base::Callback<void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)> callback = base::Bind(
+ &TracingControllerTest::StopTracingStringDoneCallbackTest,
+ base::Unretained(this),
+ run_loop.QuitClosure());
+
+ scoped_refptr<TracingController::TraceDataSink> trace_data_sink =
+ TracingController::CreateStringSink(callback);
+
+ trace_data_sink->SetMetadataFilterPredicate(
+ base::Bind(&IsMetadataWhitelisted));
+ base::DictionaryValue metadata;
+ metadata.SetString("not-whitelisted", "this_not_found");
+ trace_data_sink->AddMetadata(metadata);
+
+ bool result = controller->StopTracing(trace_data_sink);
+ ASSERT_TRUE(result);
+ run_loop.Run();
+ EXPECT_EQ(disable_recording_done_callback_count(), 1);
+ }
+ }
+
+ void TestStartAndStopTracingCompressed() {
+ Navigate(shell());
+
+ TracingController* controller = TracingController::GetInstance();
+
+ {
+ base::RunLoop run_loop;
+ TracingController::StartTracingDoneCallback callback =
+ base::Bind(&TracingControllerTest::StartTracingDoneCallbackTest,
base::Unretained(this), run_loop.QuitClosure());
- bool result = controller->EnableRecording(TraceConfig(), callback);
+ bool result = controller->StartTracing(TraceConfig(), callback);
ASSERT_TRUE(result);
run_loop.Run();
EXPECT_EQ(enable_recording_done_callback_count(), 1);
@@ -202,10 +304,11 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
- base::Callback<void(base::RefCountedString*)> callback = base::Bind(
- &TracingControllerTest::DisableRecordingStringDoneCallbackTest,
+ base::Callback<void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)> callback = base::Bind(
+ &TracingControllerTest::StopTracingStringDoneCallbackTest,
base::Unretained(this), run_loop.QuitClosure());
- bool result = controller->DisableRecording(
+ bool result = controller->StopTracing(
TracingController::CreateCompressedStringSink(
new TracingControllerTestEndpoint(callback)));
ASSERT_TRUE(result);
@@ -214,7 +317,7 @@ class TracingControllerTest : public ContentBrowserTest {
}
}
- void TestEnableAndDisableRecordingCompressedFile(
+ void TestStartAndStopTracingCompressedFile(
const base::FilePath& result_file_path) {
Navigate(shell());
@@ -222,10 +325,10 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
- TracingController::EnableRecordingDoneCallback callback =
- base::Bind(&TracingControllerTest::EnableRecordingDoneCallbackTest,
+ TracingController::StartTracingDoneCallback callback =
+ base::Bind(&TracingControllerTest::StartTracingDoneCallbackTest,
base::Unretained(this), run_loop.QuitClosure());
- bool result = controller->EnableRecording(TraceConfig(), callback);
+ bool result = controller->StartTracing(TraceConfig(), callback);
ASSERT_TRUE(result);
run_loop.Run();
EXPECT_EQ(enable_recording_done_callback_count(), 1);
@@ -234,9 +337,9 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
base::Closure callback = base::Bind(
- &TracingControllerTest::DisableRecordingFileDoneCallbackTest,
+ &TracingControllerTest::StopTracingFileDoneCallbackTest,
base::Unretained(this), run_loop.QuitClosure(), result_file_path);
- bool result = controller->DisableRecording(
+ bool result = controller->StopTracing(
TracingController::CreateCompressedStringSink(
TracingController::CreateFileEndpoint(result_file_path,
callback)));
@@ -246,7 +349,7 @@ class TracingControllerTest : public ContentBrowserTest {
}
}
- void TestEnableAndDisableRecordingFile(
+ void TestStartAndStopTracingFile(
const base::FilePath& result_file_path) {
Navigate(shell());
@@ -254,11 +357,11 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
- TracingController::EnableRecordingDoneCallback callback =
- base::Bind(&TracingControllerTest::EnableRecordingDoneCallbackTest,
+ TracingController::StartTracingDoneCallback callback =
+ base::Bind(&TracingControllerTest::StartTracingDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure());
- bool result = controller->EnableRecording(TraceConfig(), callback);
+ bool result = controller->StartTracing(TraceConfig(), callback);
ASSERT_TRUE(result);
run_loop.Run();
EXPECT_EQ(enable_recording_done_callback_count(), 1);
@@ -267,11 +370,11 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
base::Closure callback = base::Bind(
- &TracingControllerTest::DisableRecordingFileDoneCallbackTest,
+ &TracingControllerTest::StopTracingFileDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure(),
result_file_path);
- bool result = controller->DisableRecording(
+ bool result = controller->StopTracing(
TracingController::CreateFileSink(result_file_path, callback));
ASSERT_TRUE(result);
run_loop.Run();
@@ -279,7 +382,7 @@ class TracingControllerTest : public ContentBrowserTest {
}
}
- void TestEnableCaptureAndDisableMonitoring(
+ void TestEnableCaptureAndStopMonitoring(
const base::FilePath& result_file_path) {
Navigate(shell());
@@ -299,14 +402,14 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
- TracingController::EnableMonitoringDoneCallback callback =
- base::Bind(&TracingControllerTest::EnableMonitoringDoneCallbackTest,
+ TracingController::StartMonitoringDoneCallback callback =
+ base::Bind(&TracingControllerTest::StartMonitoringDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure());
TraceConfig trace_config("*", "");
trace_config.EnableSampling();
- bool result = controller->EnableMonitoring(trace_config, callback);
+ bool result = controller->StartMonitoring(trace_config, callback);
ASSERT_TRUE(result);
run_loop.Run();
EXPECT_EQ(enable_monitoring_done_callback_count(), 1);
@@ -338,11 +441,11 @@ class TracingControllerTest : public ContentBrowserTest {
{
base::RunLoop run_loop;
- TracingController::DisableMonitoringDoneCallback callback =
- base::Bind(&TracingControllerTest::DisableMonitoringDoneCallbackTest,
+ TracingController::StopMonitoringDoneCallback callback =
+ base::Bind(&TracingControllerTest::StopMonitoringDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure());
- bool result = controller->DisableMonitoring(callback);
+ bool result = controller->StopMonitoring(callback);
ASSERT_TRUE(result);
run_loop.Run();
EXPECT_EQ(disable_monitoring_done_callback_count(), 1);
@@ -369,6 +472,8 @@ class TracingControllerTest : public ContentBrowserTest {
int capture_monitoring_snapshot_done_callback_count_;
base::FilePath last_actual_recording_file_path_;
base::FilePath last_actual_monitoring_file_path_;
+ scoped_ptr<const base::DictionaryValue> last_metadata_;
+ std::string last_data_;
};
IN_PROC_BROWSER_TEST_F(TracingControllerTest, GetCategories) {
@@ -386,81 +491,138 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest, GetCategories) {
EXPECT_EQ(get_categories_done_callback_count(), 1);
}
-IN_PROC_BROWSER_TEST_F(TracingControllerTest, EnableAndDisableRecording) {
- TestEnableAndDisableRecordingString();
+IN_PROC_BROWSER_TEST_F(TracingControllerTest, EnableAndStopTracing) {
+ TestStartAndStopTracingString();
+}
+
+IN_PROC_BROWSER_TEST_F(TracingControllerTest, DisableRecordingStoresMetadata) {
+ TestStartAndStopTracingString();
+ // Check that a number of important keys exist in the metadata dictionary. The
+ // values are not checked to ensure the test is robust.
+ EXPECT_TRUE(last_metadata() != NULL);
+ std::string network_type;
+ last_metadata()->GetString("network-type", &network_type);
+ EXPECT_TRUE(network_type.length() > 0);
+ std::string user_agent;
+ last_metadata()->GetString("user-agent", &user_agent);
+ EXPECT_TRUE(user_agent.length() > 0);
+ std::string os_name;
+ last_metadata()->GetString("os-name", &os_name);
+ EXPECT_TRUE(os_name.length() > 0);
+ std::string cpu_brand;
+ last_metadata()->GetString("cpu-brand", &cpu_brand);
+ EXPECT_TRUE(cpu_brand.length() > 0);
+}
+
+IN_PROC_BROWSER_TEST_F(TracingControllerTest, NotWhitelistedMetadataStripped) {
+ TestStartAndStopTracingStringWithFilter();
+ // Check that a number of important keys exist in the metadata dictionary.
+ EXPECT_TRUE(last_metadata() != NULL);
+ std::string cpu_brand;
+ last_metadata()->GetString("cpu-brand", &cpu_brand);
+ EXPECT_TRUE(cpu_brand.length() > 0);
+ EXPECT_TRUE(cpu_brand != "__stripped__");
+ std::string network_type;
+ last_metadata()->GetString("network-type", &network_type);
+ EXPECT_TRUE(network_type.length() > 0);
+ EXPECT_TRUE(network_type != "__stripped__");
+ std::string os_name;
+ last_metadata()->GetString("os-name", &os_name);
+ EXPECT_TRUE(os_name.length() > 0);
+ EXPECT_TRUE(os_name != "__stripped__");
+ std::string user_agent;
+ last_metadata()->GetString("user-agent", &user_agent);
+ EXPECT_TRUE(user_agent.length() > 0);
+ EXPECT_TRUE(user_agent != "__stripped__");
+
+ // Check that the not whitelisted metadata is stripped.
+ std::string not_whitelisted;
+ last_metadata()->GetString("not-whitelisted", &not_whitelisted);
+ EXPECT_TRUE(not_whitelisted.length() > 0);
+ EXPECT_TRUE(not_whitelisted == "__stripped__");
+
+ // Also check the string data.
+ EXPECT_TRUE(last_data().size() > 0);
+ EXPECT_TRUE(last_data().find("cpu-brand") != std::string::npos);
+ EXPECT_TRUE(last_data().find("network-type") != std::string::npos);
+ EXPECT_TRUE(last_data().find("os-name") != std::string::npos);
+ EXPECT_TRUE(last_data().find("user-agent") != std::string::npos);
+
+ EXPECT_TRUE(last_data().find("not-whitelisted") != std::string::npos);
+ EXPECT_TRUE(last_data().find("this_not_found") == std::string::npos);
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
- EnableAndDisableRecordingWithFilePath) {
+ EnableAndStopTracingWithFilePath) {
base::FilePath file_path;
base::CreateTemporaryFile(&file_path);
- TestEnableAndDisableRecordingFile(file_path);
+ TestStartAndStopTracingFile(file_path);
EXPECT_EQ(file_path.value(), last_actual_recording_file_path().value());
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
- EnableAndDisableRecordingWithCompression) {
- TestEnableAndDisableRecordingCompressed();
+ EnableAndStopTracingWithCompression) {
+ TestStartAndStopTracingCompressed();
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
- EnableAndDisableRecordingToFileWithCompression) {
+ EnableAndStopTracingToFileWithCompression) {
base::FilePath file_path;
base::CreateTemporaryFile(&file_path);
- TestEnableAndDisableRecordingCompressedFile(file_path);
+ TestStartAndStopTracingCompressedFile(file_path);
EXPECT_EQ(file_path.value(), last_actual_recording_file_path().value());
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
- EnableAndDisableRecordingWithEmptyFileAndNullCallback) {
+ EnableAndStopTracingWithEmptyFileAndNullCallback) {
Navigate(shell());
TracingController* controller = TracingController::GetInstance();
- EXPECT_TRUE(controller->EnableRecording(
+ EXPECT_TRUE(controller->StartTracing(
TraceConfig(),
- TracingController::EnableRecordingDoneCallback()));
- EXPECT_TRUE(controller->DisableRecording(NULL));
+ TracingController::StartTracingDoneCallback()));
+ EXPECT_TRUE(controller->StopTracing(NULL));
base::RunLoop().RunUntilIdle();
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
- EnableCaptureAndDisableMonitoring) {
+ EnableCaptureAndStopMonitoring) {
base::FilePath file_path;
base::CreateTemporaryFile(&file_path);
- TestEnableCaptureAndDisableMonitoring(file_path);
+ TestEnableCaptureAndStopMonitoring(file_path);
}
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
- EnableCaptureAndDisableMonitoringWithFilePath) {
+ EnableCaptureAndStopMonitoringWithFilePath) {
base::FilePath file_path;
base::CreateTemporaryFile(&file_path);
- TestEnableCaptureAndDisableMonitoring(file_path);
+ TestEnableCaptureAndStopMonitoring(file_path);
EXPECT_EQ(file_path.value(), last_actual_monitoring_file_path().value());
}
// See http://crbug.com/392446
#if defined(OS_ANDROID)
-#define MAYBE_EnableCaptureAndDisableMonitoringWithEmptyFileAndNullCallback \
- DISABLED_EnableCaptureAndDisableMonitoringWithEmptyFileAndNullCallback
+#define MAYBE_EnableCaptureAndStopMonitoringWithEmptyFileAndNullCallback \
+ DISABLED_EnableCaptureAndStopMonitoringWithEmptyFileAndNullCallback
#else
-#define MAYBE_EnableCaptureAndDisableMonitoringWithEmptyFileAndNullCallback \
- EnableCaptureAndDisableMonitoringWithEmptyFileAndNullCallback
+#define MAYBE_EnableCaptureAndStopMonitoringWithEmptyFileAndNullCallback \
+ EnableCaptureAndStopMonitoringWithEmptyFileAndNullCallback
#endif
IN_PROC_BROWSER_TEST_F(
TracingControllerTest,
- MAYBE_EnableCaptureAndDisableMonitoringWithEmptyFileAndNullCallback) {
+ MAYBE_EnableCaptureAndStopMonitoringWithEmptyFileAndNullCallback) {
Navigate(shell());
TracingController* controller = TracingController::GetInstance();
TraceConfig trace_config("*", "");
trace_config.EnableSampling();
- EXPECT_TRUE(controller->EnableMonitoring(
+ EXPECT_TRUE(controller->StartMonitoring(
trace_config,
- TracingController::EnableMonitoringDoneCallback()));
+ TracingController::StartMonitoringDoneCallback()));
controller->CaptureMonitoringSnapshot(NULL);
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(controller->DisableMonitoring(
- TracingController::DisableMonitoringDoneCallback()));
+ EXPECT_TRUE(controller->StopMonitoring(
+ TracingController::StopMonitoringDoneCallback()));
base::RunLoop().RunUntilIdle();
}
diff --git a/chromium/content/browser/tracing/tracing_controller_impl.cc b/chromium/content/browser/tracing/tracing_controller_impl.cc
index 4b9f4556d6f..684bea8ec49 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl.cc
+++ b/chromium/content/browser/tracing/tracing_controller_impl.cc
@@ -4,19 +4,28 @@
#include "content/browser/tracing/tracing_controller_impl.h"
#include "base/bind.h"
+#include "base/cpu.h"
#include "base/files/file_util.h"
#include "base/json/string_escape.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
+#include "base/sys_info.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/tracing/file_tracing_provider_impl.h"
#include "content/browser/tracing/power_tracing_agent.h"
#include "content/browser/tracing/trace_message_filter.h"
#include "content/browser/tracing/tracing_ui.h"
#include "content/common/child_process_messages.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/gpu_data_manager.h"
+#include "content/public/browser/tracing_delegate.h"
#include "content/public/common/child_process_host.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
+#include "gpu/config/gpu_info.h"
+#include "net/base/network_change_notifier.h"
#if defined(OS_CHROMEOS)
#include "chromeos/dbus/dbus_thread_manager.h"
@@ -37,6 +46,97 @@ namespace {
base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
LAZY_INSTANCE_INITIALIZER;
+const char kChromeTracingAgentName[] = "chrome";
+const char kETWTracingAgentName[] = "etw";
+const char kChromeTraceLabel[] = "traceEvents";
+
+const int kIssueClockSyncTimeout = 30;
+
+std::string GetNetworkTypeString() {
+ switch (net::NetworkChangeNotifier::GetConnectionType()) {
+ case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
+ return "Ethernet";
+ case net::NetworkChangeNotifier::CONNECTION_WIFI:
+ return "WiFi";
+ case net::NetworkChangeNotifier::CONNECTION_2G:
+ return "2G";
+ case net::NetworkChangeNotifier::CONNECTION_3G:
+ return "3G";
+ case net::NetworkChangeNotifier::CONNECTION_4G:
+ return "4G";
+ case net::NetworkChangeNotifier::CONNECTION_NONE:
+ return "None";
+ case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
+ return "Bluetooth";
+ case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
+ default:
+ break;
+ }
+ return "Unknown";
+}
+
+scoped_ptr<base::DictionaryValue> GenerateTracingMetadataDict() {
+ scoped_ptr<base::DictionaryValue> metadata_dict(new base::DictionaryValue());
+
+ metadata_dict->SetString("network-type", GetNetworkTypeString());
+ metadata_dict->SetString("product-version", GetContentClient()->GetProduct());
+ metadata_dict->SetString("user-agent", GetContentClient()->GetUserAgent());
+
+ // OS
+ metadata_dict->SetString("os-name", base::SysInfo::OperatingSystemName());
+ metadata_dict->SetString("os-version",
+ base::SysInfo::OperatingSystemVersion());
+ metadata_dict->SetString("os-arch",
+ base::SysInfo::OperatingSystemArchitecture());
+
+ // CPU
+ base::CPU cpu;
+ metadata_dict->SetInteger("cpu-family", cpu.family());
+ metadata_dict->SetInteger("cpu-model", cpu.model());
+ metadata_dict->SetInteger("cpu-stepping", cpu.stepping());
+ metadata_dict->SetInteger("num-cpus", base::SysInfo::NumberOfProcessors());
+ metadata_dict->SetInteger("physical-memory",
+ base::SysInfo::AmountOfPhysicalMemoryMB());
+
+ std::string cpu_brand = cpu.cpu_brand();
+ // Workaround for crbug.com/249713.
+ // TODO(oysteine): Remove workaround when bug is fixed.
+ size_t null_pos = cpu_brand.find('\0');
+ if (null_pos != std::string::npos)
+ cpu_brand.erase(null_pos);
+ metadata_dict->SetString("cpu-brand", cpu_brand);
+
+ // GPU
+ gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
+
+#if !defined(OS_ANDROID)
+ metadata_dict->SetInteger("gpu-venid", gpu_info.gpu.vendor_id);
+ metadata_dict->SetInteger("gpu-devid", gpu_info.gpu.device_id);
+#endif
+
+ metadata_dict->SetString("gpu-driver", gpu_info.driver_version);
+ metadata_dict->SetString("gpu-psver", gpu_info.pixel_shader_version);
+ metadata_dict->SetString("gpu-vsver", gpu_info.vertex_shader_version);
+
+#if defined(OS_MACOSX)
+ metadata_dict->SetString("gpu-glver", gpu_info.gl_version);
+#elif defined(OS_POSIX)
+ metadata_dict->SetString("gpu-gl-vendor", gpu_info.gl_vendor);
+ metadata_dict->SetString("gpu-gl-renderer", gpu_info.gl_renderer);
+#endif
+
+ scoped_ptr<TracingDelegate> delegate(
+ GetContentClient()->browser()->GetTracingDelegate());
+ if (delegate)
+ delegate->GenerateMetadataDict(metadata_dict.get());
+
+ // Highres ticks.
+ metadata_dict->SetBoolean("highres-ticks",
+ base::TimeTicks::IsHighResolution());
+
+ return metadata_dict;
+}
+
} // namespace
TracingController* TracingController::GetInstance() {
@@ -44,21 +144,17 @@ TracingController* TracingController::GetInstance() {
}
TracingControllerImpl::TracingControllerImpl()
- : pending_disable_recording_ack_count_(0),
+ : pending_stop_tracing_ack_count_(0),
pending_capture_monitoring_snapshot_ack_count_(0),
pending_trace_log_status_ack_count_(0),
maximum_trace_buffer_usage_(0),
approximate_event_count_(0),
pending_memory_dump_ack_count_(0),
failed_memory_dump_count_(0),
- // Tracing may have been enabled by ContentMainRunner if kTraceStartup
- // is specified in command line.
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- is_system_tracing_(false),
-#endif
- is_recording_(TraceLog::GetInstance()->IsEnabled()),
- is_monitoring_(false),
- is_power_tracing_(false) {
+ clock_sync_id_(0),
+ pending_clock_sync_ack_count_(0),
+ is_tracing_(false),
+ is_monitoring_(false) {
base::trace_event::MemoryDumpManager::GetInstance()->Initialize(
this /* delegate */, true /* is_coordinator */);
@@ -83,12 +179,12 @@ bool 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;
- if (!EnableRecording(TraceConfig("*", ""), EnableRecordingDoneCallback())) {
+ if (!StartTracing(TraceConfig("*", ""), StartTracingDoneCallback())) {
pending_get_categories_done_callback_.Reset();
return false;
}
- bool ok = DisableRecording(NULL);
+ bool ok = StopTracing(NULL);
DCHECK(ok);
return true;
}
@@ -112,14 +208,16 @@ void TracingControllerImpl::SetDisabledOnFileThread(
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
}
-bool TracingControllerImpl::EnableRecording(
+bool TracingControllerImpl::StartTracing(
const TraceConfig& trace_config,
- const EnableRecordingDoneCallback& callback) {
+ const StartTracingDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(additional_tracing_agents_.empty());
- if (!can_enable_recording())
+ if (!can_start_tracing())
return false;
- is_recording_ = true;
+ is_tracing_ = true;
+ start_tracing_done_callback_ = callback;
#if defined(OS_ANDROID)
if (pending_get_categories_done_callback_.is_null())
@@ -127,46 +225,42 @@ bool TracingControllerImpl::EnableRecording(
#endif
if (trace_config.IsSystraceEnabled()) {
- DCHECK(!is_power_tracing_);
- is_power_tracing_ = PowerTracingAgent::GetInstance()->StartTracing();
+ if (PowerTracingAgent::GetInstance()->StartAgentTracing(trace_config))
+ additional_tracing_agents_.push_back(PowerTracingAgent::GetInstance());
#if defined(OS_CHROMEOS)
- DCHECK(!is_system_tracing_);
- chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
- StartSystemTracing();
- is_system_tracing_ = true;
+ chromeos::DebugDaemonClient* debug_daemon =
+ chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
+ if (debug_daemon && debug_daemon->StartAgentTracing(trace_config)) {
+ debug_daemon->SetStopAgentTracingTaskRunner(
+ BrowserThread::GetBlockingPool());
+ additional_tracing_agents_.push_back(
+ chromeos::DBusThreadManager::Get()->GetDebugDaemonClient());
+ }
#elif defined(OS_WIN)
- DCHECK(!is_system_tracing_);
- is_system_tracing_ =
- EtwSystemEventConsumer::GetInstance()->StartSystemTracing();
+ if (EtwSystemEventConsumer::GetInstance()->StartAgentTracing(
+ trace_config)) {
+ additional_tracing_agents_.push_back(
+ EtwSystemEventConsumer::GetInstance());
+ }
#endif
}
- base::Closure on_enable_recording_done_callback =
- base::Bind(&TracingControllerImpl::OnEnableRecordingDone,
- base::Unretained(this),
- trace_config, callback);
- if (!BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
- base::Unretained(this), trace_config,
- base::trace_event::TraceLog::RECORDING_MODE,
- on_enable_recording_done_callback))) {
- // BrowserThread::PostTask fails if the threads haven't been created yet,
- // so it should be safe to just use TraceLog::SetEnabled directly.
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- trace_config, base::trace_event::TraceLog::RECORDING_MODE);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- on_enable_recording_done_callback);
- }
-
- return true;
+ // TraceLog may have been enabled in startup tracing before threads are ready.
+ if (TraceLog::GetInstance()->IsEnabled())
+ return true;
+ return StartAgentTracing(trace_config);
}
-void TracingControllerImpl::OnEnableRecordingDone(
+void TracingControllerImpl::OnStartAgentTracingDone(
const TraceConfig& trace_config,
- const EnableRecordingDoneCallback& callback) {
+ const StartTracingDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value",
+ base::TimeTicks::IsHighResolution());
+ TRACE_EVENT_API_ADD_METADATA_EVENT("TraceConfig", "value",
+ trace_config.AsConvertableToTraceFormat());
+
// Notify all child processes.
for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
it != trace_message_filters_.end(); ++it) {
@@ -177,26 +271,52 @@ void TracingControllerImpl::OnEnableRecordingDone(
callback.Run();
}
-bool TracingControllerImpl::DisableRecording(
+bool TracingControllerImpl::StopTracing(
const scoped_refptr<TraceDataSink>& trace_data_sink) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!can_disable_recording())
+ if (trace_data_sink) {
+ if (TraceLog::GetInstance()->GetCurrentTraceConfig()
+ .IsArgumentFilterEnabled()) {
+ scoped_ptr<TracingDelegate> delegate(
+ GetContentClient()->browser()->GetTracingDelegate());
+ if (delegate) {
+ trace_data_sink->SetMetadataFilterPredicate(
+ delegate->GetMetadataFilterPredicate());
+ }
+ }
+ trace_data_sink->AddMetadata(*GenerateTracingMetadataDict().get());
+ }
+
+ if (!can_stop_tracing())
return false;
trace_data_sink_ = trace_data_sink;
+
+ // Issue clock sync marker before actually stopping tracing.
+ // StopTracingAfterClockSync() will be called after clock sync is done.
+ IssueClockSyncMarker();
+
+ return true;
+}
+
+void TracingControllerImpl::StopTracingAfterClockSync() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // |pending_clock_sync_ack_count_| could be non-zero if clock sync times out.
+ pending_clock_sync_ack_count_ = 0;
+
// Disable local trace early to avoid traces during end-tracing process from
// interfering with the process.
- base::Closure on_disable_recording_done_callback = base::Bind(
- &TracingControllerImpl::OnDisableRecordingDone, base::Unretained(this));
+ base::Closure on_stop_tracing_done_callback = base::Bind(
+ &TracingControllerImpl::OnStopTracingDone, base::Unretained(this));
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&TracingControllerImpl::SetDisabledOnFileThread,
base::Unretained(this),
- on_disable_recording_done_callback));
- return true;
+ on_stop_tracing_done_callback));
}
-void TracingControllerImpl::OnDisableRecordingDone() {
+void TracingControllerImpl::OnStopTracingDone() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(OS_ANDROID)
@@ -204,76 +324,28 @@ void TracingControllerImpl::OnDisableRecordingDone() {
TraceLog::GetInstance()->AddClockSyncMetadataEvent();
#endif
- // Count myself (local trace) in pending_disable_recording_ack_count_,
+ // Count myself (local trace) in pending_stop_tracing_ack_count_,
// acked below.
- pending_disable_recording_ack_count_ = trace_message_filters_.size() + 1;
- pending_disable_recording_filters_ = trace_message_filters_;
-
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- if (is_system_tracing_) {
- // Disable system tracing.
- is_system_tracing_ = false;
- ++pending_disable_recording_ack_count_;
-
-#if defined(OS_CHROMEOS)
- scoped_refptr<base::TaskRunner> task_runner =
- BrowserThread::GetBlockingPool();
- chromeos::DBusThreadManager::Get()
- ->GetDebugDaemonClient()
- ->RequestStopSystemTracing(
- task_runner,
- base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
- base::Unretained(this)));
-#elif defined(OS_WIN)
- EtwSystemEventConsumer::GetInstance()->StopSystemTracing(
- base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
- base::Unretained(this)));
-#endif
- }
-#endif // defined(OS_CHROMEOS) || defined(OS_WIN)
+ pending_stop_tracing_ack_count_ = trace_message_filters_.size() + 1;
+ pending_stop_tracing_filters_ = trace_message_filters_;
- if (is_power_tracing_) {
- is_power_tracing_ = false;
- ++pending_disable_recording_ack_count_;
- PowerTracingAgent::GetInstance()->StopTracing(
- base::Bind(&TracingControllerImpl::OnEndPowerTracingAcked,
+ pending_stop_tracing_ack_count_ += additional_tracing_agents_.size();
+ for (auto it : additional_tracing_agents_) {
+ it->StopAgentTracing(
+ base::Bind(&TracingControllerImpl::OnEndAgentTracingAcked,
base::Unretained(this)));
}
+ additional_tracing_agents_.clear();
- // Handle special case of zero child processes by immediately flushing the
- // trace log. Once the flush has completed the caller will be notified that
- // tracing has ended.
- if (pending_disable_recording_ack_count_ == 1) {
- // Flush/cancel asynchronously now, because we don't have any children to
- // wait for.
- if (trace_data_sink_) {
- TraceLog::GetInstance()->Flush(
- base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
- base::Unretained(this)),
- true);
- } else {
- TraceLog::GetInstance()->CancelTracing(
- base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
- base::Unretained(this)));
- }
- }
-
- // Notify all child processes.
- for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
- it != trace_message_filters_.end(); ++it) {
- if (trace_data_sink_)
- it->get()->SendEndTracing();
- else
- it->get()->SendCancelTracing();
- }
+ StopAgentTracing(StopAgentTracingCallback());
}
-bool TracingControllerImpl::EnableMonitoring(
+bool TracingControllerImpl::StartMonitoring(
const TraceConfig& trace_config,
- const EnableMonitoringDoneCallback& callback) {
+ const StartMonitoringDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!can_enable_monitoring())
+ if (!can_start_monitoring())
return false;
OnMonitoringStateChanged(true);
@@ -281,8 +353,8 @@ bool TracingControllerImpl::EnableMonitoring(
TraceLog::GetInstance()->AddClockSyncMetadataEvent();
#endif
- base::Closure on_enable_monitoring_done_callback =
- base::Bind(&TracingControllerImpl::OnEnableMonitoringDone,
+ base::Closure on_start_monitoring_done_callback =
+ base::Bind(&TracingControllerImpl::OnStartMonitoringDone,
base::Unretained(this),
trace_config, callback);
if (!BrowserThread::PostTask(
@@ -290,51 +362,51 @@ bool TracingControllerImpl::EnableMonitoring(
base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
base::Unretained(this), trace_config,
base::trace_event::TraceLog::MONITORING_MODE,
- on_enable_monitoring_done_callback))) {
+ on_start_monitoring_done_callback))) {
// BrowserThread::PostTask fails if the threads haven't been created yet,
// so it should be safe to just use TraceLog::SetEnabled directly.
base::trace_event::TraceLog::GetInstance()->SetEnabled(
trace_config, base::trace_event::TraceLog::MONITORING_MODE);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- on_enable_monitoring_done_callback);
+ on_start_monitoring_done_callback);
}
return true;
}
-void TracingControllerImpl::OnEnableMonitoringDone(
+void TracingControllerImpl::OnStartMonitoringDone(
const TraceConfig& trace_config,
- const EnableMonitoringDoneCallback& callback) {
+ const StartMonitoringDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Notify all child processes.
for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
it != trace_message_filters_.end(); ++it) {
- it->get()->SendEnableMonitoring(trace_config);
+ it->get()->SendStartMonitoring(trace_config);
}
if (!callback.is_null())
callback.Run();
}
-bool TracingControllerImpl::DisableMonitoring(
- const DisableMonitoringDoneCallback& callback) {
+bool TracingControllerImpl::StopMonitoring(
+ const StopMonitoringDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!can_disable_monitoring())
+ if (!can_stop_monitoring())
return false;
- base::Closure on_disable_monitoring_done_callback =
- base::Bind(&TracingControllerImpl::OnDisableMonitoringDone,
+ base::Closure on_stop_monitoring_done_callback =
+ base::Bind(&TracingControllerImpl::OnStopMonitoringDone,
base::Unretained(this), callback);
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&TracingControllerImpl::SetDisabledOnFileThread,
base::Unretained(this),
- on_disable_monitoring_done_callback));
+ on_stop_monitoring_done_callback));
return true;
}
-void TracingControllerImpl::OnDisableMonitoringDone(
- const DisableMonitoringDoneCallback& callback) {
+void TracingControllerImpl::OnStopMonitoringDone(
+ const StopMonitoringDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
OnMonitoringStateChanged(false);
@@ -342,7 +414,7 @@ void TracingControllerImpl::OnDisableMonitoringDone(
// Notify all child processes.
for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
it != trace_message_filters_.end(); ++it) {
- it->get()->SendDisableMonitoring();
+ it->get()->SendStopMonitoring();
}
if (!callback.is_null())
callback.Run();
@@ -359,7 +431,7 @@ bool TracingControllerImpl::CaptureMonitoringSnapshot(
const scoped_refptr<TraceDataSink>& monitoring_data_sink) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!can_disable_monitoring())
+ if (!can_stop_monitoring())
return false;
if (!monitoring_data_sink.get())
@@ -470,8 +542,8 @@ bool TracingControllerImpl::CancelWatchEvent() {
return true;
}
-bool TracingControllerImpl::IsRecording() const {
- return is_recording_;
+bool TracingControllerImpl::IsTracing() const {
+ return is_tracing_;
}
void TracingControllerImpl::AddTraceMessageFilter(
@@ -489,12 +561,12 @@ void TracingControllerImpl::AddTraceMessageFilter(
trace_message_filter->SendSetWatchEvent(watch_category_name_,
watch_event_name_);
}
- if (can_disable_recording()) {
+ if (can_stop_tracing()) {
trace_message_filter->SendBeginTracing(
TraceLog::GetInstance()->GetCurrentTraceConfig());
}
- if (can_disable_monitoring()) {
- trace_message_filter->SendEnableMonitoring(
+ if (can_stop_monitoring()) {
+ trace_message_filter->SendStartMonitoring(
TraceLog::GetInstance()->GetCurrentTraceConfig());
}
@@ -515,12 +587,12 @@ void TracingControllerImpl::RemoveTraceMessageFilter(
// If a filter is removed while a response from that filter is pending then
// simulate the response. Otherwise the response count will be wrong and the
// completion callback will never be executed.
- if (pending_disable_recording_ack_count_ > 0) {
+ if (pending_stop_tracing_ack_count_ > 0) {
TraceMessageFilterSet::const_iterator it =
- pending_disable_recording_filters_.find(trace_message_filter);
- if (it != pending_disable_recording_filters_.end()) {
+ pending_stop_tracing_filters_.find(trace_message_filter);
+ if (it != pending_stop_tracing_filters_.end()) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::OnDisableRecordingAcked,
+ base::Bind(&TracingControllerImpl::OnStopTracingAcked,
base::Unretained(this),
make_scoped_refptr(trace_message_filter),
std::vector<std::string>()));
@@ -563,12 +635,12 @@ void TracingControllerImpl::RemoveTraceMessageFilter(
trace_message_filters_.erase(trace_message_filter);
}
-void TracingControllerImpl::OnDisableRecordingAcked(
+void TracingControllerImpl::OnStopTracingAcked(
TraceMessageFilter* trace_message_filter,
const std::vector<std::string>& known_category_groups) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::OnDisableRecordingAcked,
+ base::Bind(&TracingControllerImpl::OnStopTracingAcked,
base::Unretained(this),
make_scoped_refptr(trace_message_filter),
known_category_groups));
@@ -579,16 +651,16 @@ void TracingControllerImpl::OnDisableRecordingAcked(
known_category_groups_.insert(known_category_groups.begin(),
known_category_groups.end());
- if (pending_disable_recording_ack_count_ == 0)
+ if (pending_stop_tracing_ack_count_ == 0)
return;
if (trace_message_filter &&
- !pending_disable_recording_filters_.erase(trace_message_filter)) {
+ !pending_stop_tracing_filters_.erase(trace_message_filter)) {
// The response from the specified message filter has already been received.
return;
}
- if (--pending_disable_recording_ack_count_ == 1) {
+ if (--pending_stop_tracing_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.
@@ -605,12 +677,12 @@ void TracingControllerImpl::OnDisableRecordingAcked(
return;
}
- if (pending_disable_recording_ack_count_ != 0)
+ if (pending_stop_tracing_ack_count_ != 0)
return;
// All acks (including from the subprocesses and the local trace) have been
// received.
- is_recording_ = false;
+ is_tracing_ = false;
// Trigger callback if one is set.
if (!pending_get_categories_done_callback_.is_null()) {
@@ -622,39 +694,26 @@ void TracingControllerImpl::OnDisableRecordingAcked(
}
}
-void TracingControllerImpl::OnEndPowerTracingAcked(
+void TracingControllerImpl::OnEndAgentTracingAcked(
+ const std::string& agent_name,
+ const std::string& events_label,
const scoped_refptr<base::RefCountedString>& events_str_ptr) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (trace_data_sink_.get()) {
- std::string json_string = base::GetQuotedJSONString(events_str_ptr->data());
- trace_data_sink_->SetPowerTrace(json_string);
- }
- std::vector<std::string> category_groups;
- OnDisableRecordingAcked(NULL, category_groups);
-}
-
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
-void TracingControllerImpl::OnEndSystemTracingAcked(
- const scoped_refptr<base::RefCountedString>& events_str_ptr) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- if (trace_data_sink_.get()) {
-#if defined(OS_WIN)
- // The Windows kernel events are kept into a JSon format stored as string
- // and must not be escaped.
- std::string json_string = events_str_ptr->data();
-#else
- std::string json_string =
- base::GetQuotedJSONString(events_str_ptr->data());
-#endif
- trace_data_sink_->SetSystemTrace(json_string);
+ std::string json_string;
+ if (agent_name == kETWTracingAgentName) {
+ // The Windows kernel events are kept into a JSON format stored as string
+ // and must not be escaped.
+ json_string = events_str_ptr->data();
+ } else {
+ json_string = base::GetQuotedJSONString(events_str_ptr->data());
+ }
+ trace_data_sink_->AddAgentTrace(events_label, json_string);
}
- DCHECK(!is_system_tracing_);
std::vector<std::string> category_groups;
- OnDisableRecordingAcked(NULL, category_groups);
+ OnStopTracingAcked(NULL, category_groups);
}
-#endif
void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked(
TraceMessageFilter* trace_message_filter) {
@@ -731,10 +790,10 @@ void TracingControllerImpl::OnLocalTraceDataCollected(
if (has_more_events)
return;
- // Simulate an DisableRecordingAcked for the local trace.
+ // Simulate an StopTracingAcked for the local trace.
std::vector<std::string> category_groups;
TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
- OnDisableRecordingAcked(NULL, category_groups);
+ OnStopTracingAcked(NULL, category_groups);
}
void TracingControllerImpl::OnLocalMonitoringTraceDataCollected(
@@ -808,6 +867,133 @@ void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
tracing_uis_.erase(it);
}
+std::string TracingControllerImpl::GetTracingAgentName() {
+ return kChromeTracingAgentName;
+}
+
+std::string TracingControllerImpl::GetTraceEventLabel() {
+ return kChromeTraceLabel;
+}
+
+bool TracingControllerImpl::StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ base::Closure on_start_tracing_done_callback =
+ base::Bind(&TracingControllerImpl::OnStartAgentTracingDone,
+ base::Unretained(this),
+ trace_config, start_tracing_done_callback_);
+ if (!BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
+ base::Unretained(this), trace_config,
+ base::trace_event::TraceLog::RECORDING_MODE,
+ on_start_tracing_done_callback))) {
+ // BrowserThread::PostTask fails if the threads haven't been created yet,
+ // so it should be safe to just use TraceLog::SetEnabled directly.
+ base::trace_event::TraceLog::GetInstance()->SetEnabled(
+ trace_config, base::trace_event::TraceLog::RECORDING_MODE);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ on_start_tracing_done_callback);
+ }
+
+ return true;
+}
+
+void TracingControllerImpl::StopAgentTracing(
+ const StopAgentTracingCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Handle special case of zero child processes by immediately flushing the
+ // trace log. Once the flush has completed the caller will be notified that
+ // tracing has ended.
+ if (pending_stop_tracing_ack_count_ == 1) {
+ // Flush/cancel asynchronously now, because we don't have any children to
+ // wait for.
+ if (trace_data_sink_) {
+ TraceLog::GetInstance()->Flush(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)),
+ true);
+ } else {
+ TraceLog::GetInstance()->CancelTracing(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)));
+ }
+ }
+
+ // Notify all child processes.
+ for (auto it : trace_message_filters_) {
+ if (trace_data_sink_)
+ it->SendEndTracing();
+ else
+ it->SendCancelTracing();
+ }
+}
+
+bool TracingControllerImpl::SupportsExplicitClockSync() {
+ return true;
+}
+
+void TracingControllerImpl::RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) {
+ DCHECK(SupportsExplicitClockSync());
+
+ TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id);
+}
+
+int TracingControllerImpl::GetUniqueClockSyncID() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // There is no need to lock because this function only runs on UI thread.
+ return ++clock_sync_id_;
+}
+
+void TracingControllerImpl::IssueClockSyncMarker() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(pending_clock_sync_ack_count_ == 0);
+
+ for (const auto& it : additional_tracing_agents_) {
+ if (it->SupportsExplicitClockSync()) {
+ it->RecordClockSyncMarker(
+ GetUniqueClockSyncID(),
+ base::Bind(&TracingControllerImpl::OnClockSyncMarkerRecordedByAgent,
+ base::Unretained(this)));
+ pending_clock_sync_ack_count_++;
+ }
+ }
+
+ // If no clock sync is needed, stop tracing right away. Otherwise, schedule
+ // to stop tracing after timeout.
+ if (pending_clock_sync_ack_count_ == 0) {
+ StopTracingAfterClockSync();
+ } else {
+ clock_sync_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromSeconds(kIssueClockSyncTimeout),
+ this,
+ &TracingControllerImpl::StopTracingAfterClockSync);
+ }
+}
+
+void TracingControllerImpl::OnClockSyncMarkerRecordedByAgent(
+ int sync_id,
+ const base::TimeTicks& issue_ts,
+ const base::TimeTicks& issue_end_ts) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts);
+
+ // Timer is not running means that clock sync already timed out.
+ if (!clock_sync_timer_.IsRunning())
+ return;
+
+ // Stop tracing only if all agents report back.
+ if(--pending_clock_sync_ack_count_ == 0) {
+ clock_sync_timer_.Stop();
+ StopTracingAfterClockSync();
+ }
+}
+
void TracingControllerImpl::RequestGlobalMemoryDump(
const base::trace_event::MemoryDumpRequestArgs& args,
const base::trace_event::MemoryDumpCallback& callback) {
@@ -849,7 +1035,7 @@ void TracingControllerImpl::RequestGlobalMemoryDump(
tmf->SendProcessMemoryDumpRequest(args);
}
-uint64 TracingControllerImpl::GetTracingProcessId() const {
+uint64_t TracingControllerImpl::GetTracingProcessId() const {
return ChildProcessHost::kBrowserTracingProcessId;
}
@@ -873,7 +1059,7 @@ void TracingControllerImpl::RemoveTraceMessageFilterObserver(
void TracingControllerImpl::OnProcessMemoryDumpResponse(
TraceMessageFilter* trace_message_filter,
- uint64 dump_guid,
+ uint64_t dump_guid,
bool success) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(
@@ -905,7 +1091,7 @@ void TracingControllerImpl::OnProcessMemoryDumpResponse(
FinalizeGlobalMemoryDumpIfAllProcessesReplied();
}
-void TracingControllerImpl::OnBrowserProcessMemoryDumpDone(uint64 dump_guid,
+void TracingControllerImpl::OnBrowserProcessMemoryDumpDone(uint64_t dump_guid,
bool success) {
DCHECK_GT(pending_memory_dump_ack_count_, 0);
--pending_memory_dump_ack_count_;
diff --git a/chromium/content/browser/tracing/tracing_controller_impl.h b/chromium/content/browser/tracing/tracing_controller_impl.h
index 9af728ef069..90dcc408076 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl.h
+++ b/chromium/content/browser/tracing/tracing_controller_impl.h
@@ -5,12 +5,18 @@
#ifndef CONTENT_BROWSER_TRACING_TRACING_CONTROLLER_IMPL_H_
#define CONTENT_BROWSER_TRACING_TRACING_CONTROLLER_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <set>
#include <string>
#include <vector>
#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "base/time/time.h"
#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/tracing_agent.h"
#include "content/public/browser/tracing_controller.h"
namespace base {
@@ -25,20 +31,21 @@ class TracingUI;
class TracingControllerImpl
: public TracingController,
- public base::trace_event::MemoryDumpManagerDelegate {
+ public base::trace_event::MemoryDumpManagerDelegate,
+ public base::trace_event::TracingAgent {
public:
static TracingControllerImpl* GetInstance();
// TracingController implementation.
bool GetCategories(const GetCategoriesDoneCallback& callback) override;
- bool EnableRecording(const base::trace_event::TraceConfig& trace_config,
- const EnableRecordingDoneCallback& callback) override;
- bool DisableRecording(const scoped_refptr<TraceDataSink>& sink) override;
- bool EnableMonitoring(
+ bool StartTracing(const base::trace_event::TraceConfig& trace_config,
+ const StartTracingDoneCallback& callback) override;
+ bool StopTracing(const scoped_refptr<TraceDataSink>& sink) override;
+ bool StartMonitoring(
const base::trace_event::TraceConfig& trace_config,
- const EnableMonitoringDoneCallback& callback) override;
- bool DisableMonitoring(
- const DisableMonitoringDoneCallback& callback) override;
+ const StartMonitoringDoneCallback& callback) override;
+ bool StopMonitoring(
+ const StopMonitoringDoneCallback& callback) override;
void GetMonitoringStatus(
bool* out_enabled,
base::trace_event::TraceConfig* out_trace_config) override;
@@ -50,16 +57,27 @@ class TracingControllerImpl
const std::string& event_name,
const WatchEventCallback& callback) override;
bool CancelWatchEvent() override;
- bool IsRecording() const override;
+ bool IsTracing() const override;
void RegisterTracingUI(TracingUI* tracing_ui);
void UnregisterTracingUI(TracingUI* tracing_ui);
+ // base::trace_event::TracingAgent implementation.
+ std::string GetTracingAgentName() override;
+ std::string GetTraceEventLabel() override;
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override;
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override;
+ bool SupportsExplicitClockSync() override;
+ void RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) override;
+
// base::trace_event::MemoryDumpManagerDelegate implementation.
void RequestGlobalMemoryDump(
const base::trace_event::MemoryDumpRequestArgs& args,
const base::trace_event::MemoryDumpCallback& callback) override;
- uint64 GetTracingProcessId() const override;
+ uint64_t GetTracingProcessId() const override;
class TraceMessageFilterObserver {
public:
@@ -76,19 +94,19 @@ class TracingControllerImpl
TracingControllerImpl();
~TracingControllerImpl() override;
- bool can_enable_recording() const {
- return !is_recording_;
+ bool can_start_tracing() const {
+ return !is_tracing_;
}
- bool can_disable_recording() const {
- return is_recording_ && !trace_data_sink_.get();
+ bool can_stop_tracing() const {
+ return is_tracing_ && !trace_data_sink_.get();
}
- bool can_enable_monitoring() const {
+ bool can_start_monitoring() const {
return !is_monitoring_;
}
- bool can_disable_monitoring() const {
+ bool can_stop_monitoring() const {
return is_monitoring_ && !monitoring_data_sink_.get();
}
@@ -118,16 +136,13 @@ class TracingControllerImpl
const scoped_refptr<base::RefCountedString>& events_str_ptr,
bool has_more_events);
- void OnDisableRecordingAcked(
+ void OnStopTracingAcked(
TraceMessageFilter* trace_message_filter,
const std::vector<std::string>& known_category_groups);
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- void OnEndSystemTracingAcked(
- const scoped_refptr<base::RefCountedString>& events_str_ptr);
-#endif
-
- void OnEndPowerTracingAcked(
+ void OnEndAgentTracingAcked(
+ const std::string& agent_name,
+ const std::string& events_label,
const scoped_refptr<base::RefCountedString>& events_str_ptr);
void OnCaptureMonitoringSnapshotAcked(
@@ -136,11 +151,11 @@ class TracingControllerImpl
void OnTraceLogStatusReply(TraceMessageFilter* trace_message_filter,
const base::trace_event::TraceLogStatus& status);
void OnProcessMemoryDumpResponse(TraceMessageFilter* trace_message_filter,
- uint64 dump_guid,
+ uint64_t dump_guid,
bool success);
// Callback of MemoryDumpManager::CreateProcessDump().
- void OnBrowserProcessMemoryDumpDone(uint64 dump_guid, bool success);
+ void OnBrowserProcessMemoryDumpDone(uint64_t dump_guid, bool success);
void FinalizeGlobalMemoryDumpIfAllProcessesReplied();
@@ -151,23 +166,32 @@ class TracingControllerImpl
int mode,
const base::Closure& callback);
void SetDisabledOnFileThread(const base::Closure& callback);
- void OnEnableRecordingDone(
+ void OnStartAgentTracingDone(
const base::trace_event::TraceConfig& trace_config,
- const EnableRecordingDoneCallback& callback);
- void OnDisableRecordingDone();
- void OnEnableMonitoringDone(
+ const StartTracingDoneCallback& callback);
+ void StopTracingAfterClockSync();
+ void OnStopTracingDone();
+ void OnStartMonitoringDone(
const base::trace_event::TraceConfig& trace_config,
- const EnableMonitoringDoneCallback& callback);
- void OnDisableMonitoringDone(const DisableMonitoringDoneCallback& callback);
+ const StartMonitoringDoneCallback& callback);
+ void OnStopMonitoringDone(const StopMonitoringDoneCallback& callback);
void OnMonitoringStateChanged(bool is_monitoring);
+ int GetUniqueClockSyncID();
+ // Issue clock sync markers to the tracing agents.
+ void IssueClockSyncMarker();
+ void OnClockSyncMarkerRecordedByAgent(
+ int sync_id,
+ const base::TimeTicks& issue_ts,
+ const base::TimeTicks& issue_end_ts);
+
typedef std::set<scoped_refptr<TraceMessageFilter>> TraceMessageFilterSet;
TraceMessageFilterSet trace_message_filters_;
- // Pending acks for DisableRecording.
- int pending_disable_recording_ack_count_;
- TraceMessageFilterSet pending_disable_recording_filters_;
+ // Pending acks for StopTracing.
+ int pending_stop_tracing_ack_count_;
+ TraceMessageFilterSet pending_stop_tracing_filters_;
// Pending acks for CaptureMonitoringSnapshot.
int pending_capture_monitoring_snapshot_ack_count_;
@@ -183,15 +207,17 @@ class TracingControllerImpl
int pending_memory_dump_ack_count_;
int failed_memory_dump_count_;
TraceMessageFilterSet pending_memory_dump_filters_;
- uint64 pending_memory_dump_guid_;
+ uint64_t pending_memory_dump_guid_;
base::trace_event::MemoryDumpCallback pending_memory_dump_callback_;
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- bool is_system_tracing_;
-#endif
- bool is_recording_;
+ StartTracingDoneCallback start_tracing_done_callback_;
+ std::vector<base::trace_event::TracingAgent*> additional_tracing_agents_;
+ int clock_sync_id_;
+ int pending_clock_sync_ack_count_;
+ base::OneShotTimer clock_sync_timer_;
+
+ bool is_tracing_;
bool is_monitoring_;
- bool is_power_tracing_;
GetCategoriesDoneCallback pending_get_categories_done_callback_;
GetTraceBufferUsageCallback pending_trace_buffer_usage_callback_;
diff --git a/chromium/content/browser/tracing/tracing_controller_impl_data_sinks.cc b/chromium/content/browser/tracing/tracing_controller_impl_data_sinks.cc
index 38fdfbcd34c..025619f2024 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl_data_sinks.cc
+++ b/chromium/content/browser/tracing/tracing_controller_impl_data_sinks.cc
@@ -1,10 +1,14 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/tracing/tracing_controller_impl.h"
+#include <utility>
#include "base/bind.h"
#include "base/files/file_util.h"
+#include "base/json/json_writer.h"
+#include "base/macros.h"
+#include "base/strings/pattern.h"
+#include "content/browser/tracing/tracing_controller_impl.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/zlib/zlib.h"
@@ -12,20 +16,27 @@ namespace content {
namespace {
+const char kChromeTraceLabel[] = "traceEvents";
+const char kMetadataTraceLabel[] = "metadata";
+
class StringTraceDataEndpoint : public TracingController::TraceDataEndpoint {
public:
- typedef base::Callback<void(base::RefCountedString*)> CompletionCallback;
+ typedef base::Callback<void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)> CompletionCallback;
explicit StringTraceDataEndpoint(CompletionCallback callback)
: completion_callback_(callback) {}
- void ReceiveTraceFinalContents(const std::string& contents) override {
+ void ReceiveTraceFinalContents(
+ scoped_ptr<const base::DictionaryValue> metadata,
+ const std::string& contents) override {
std::string tmp = contents;
scoped_refptr<base::RefCountedString> str =
base::RefCountedString::TakeString(&tmp);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(completion_callback_, str));
+ base::Bind(completion_callback_,
+ base::Passed(std::move(metadata)), str));
}
private:
@@ -54,7 +65,9 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
chunk_ptr));
}
- void ReceiveTraceFinalContents(const std::string& contents) override {
+ void ReceiveTraceFinalContents(
+ scoped_ptr<const base::DictionaryValue> ,
+ const std::string& contents) override {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&FileTraceDataEndpoint::CloseOnFileThread, this));
@@ -110,7 +123,7 @@ class StringTraceDataSink : public TracingController::TraceDataSink {
void AddTraceChunk(const std::string& chunk) override {
std::string trace_string;
if (trace_.empty())
- trace_string = "{\"traceEvents\":[";
+ trace_string = "{\"" + std::string(kChromeTraceLabel) + "\":[";
else
trace_string = ",";
trace_string += chunk;
@@ -124,31 +137,22 @@ class StringTraceDataSink : public TracingController::TraceDataSink {
endpoint_->ReceiveTraceChunk(chunk);
}
- void SetSystemTrace(const std::string& data) override {
- system_trace_ = data;
- }
-
- void SetMetadata(const std::string& data) override {
- metadata_ = data;
- }
-
- void SetPowerTrace(const std::string& data) override { power_trace_ = data; }
-
void Close() override {
AddTraceChunkAndPassToEndpoint("]");
- if (!system_trace_.empty())
- AddTraceChunkAndPassToEndpoint(",\"systemTraceEvents\": " +
- system_trace_);
- if (!metadata_.empty())
- AddTraceChunkAndPassToEndpoint(",\"metadata\": " + metadata_);
- if (!power_trace_.empty()) {
- AddTraceChunkAndPassToEndpoint(",\"powerTraceAsString\": " +
- power_trace_);
+
+ for (auto const &it : GetAgentTrace())
+ AddTraceChunkAndPassToEndpoint(",\"" + it.first + "\": " + it.second);
+
+ std::string metadataJSON;
+ if (base::JSONWriter::Write(*GetMetadataCopy(), &metadataJSON) &&
+ !metadataJSON.empty()) {
+ AddTraceChunkAndPassToEndpoint(
+ ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON);
}
AddTraceChunkAndPassToEndpoint("}");
- endpoint_->ReceiveTraceFinalContents(trace_);
+ endpoint_->ReceiveTraceFinalContents(GetMetadataCopy(), trace_);
}
private:
@@ -156,9 +160,6 @@ class StringTraceDataSink : public TracingController::TraceDataSink {
scoped_refptr<TracingController::TraceDataEndpoint> endpoint_;
std::string trace_;
- std::string system_trace_;
- std::string metadata_;
- std::string power_trace_;
DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink);
};
@@ -179,16 +180,6 @@ class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
this, chunk_ptr));
}
- void SetSystemTrace(const std::string& data) override {
- system_trace_ = data;
- }
-
- void SetMetadata(const std::string& data) override {
- metadata_ = data;
- }
-
- void SetPowerTrace(const std::string& data) override { power_trace_ = data; }
-
void Close() override {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
@@ -226,7 +217,7 @@ class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
std::string trace;
if (compressed_trace_data_.empty())
- trace = "{\"traceEvents\":[";
+ trace = "{\"" + std::string(kChromeTraceLabel) + "\":[";
else
trace = ",";
trace += chunk_ptr->data();
@@ -268,46 +259,90 @@ class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
if (!OpenZStreamOnFileThread())
return;
- if (compressed_trace_data_.empty())
- AddTraceChunkAndCompressOnFileThread("{\"traceEvents\":[", false);
-
- AddTraceChunkAndCompressOnFileThread("]", false);
- if (!system_trace_.empty()) {
+ if (compressed_trace_data_.empty()) {
AddTraceChunkAndCompressOnFileThread(
- ",\"systemTraceEvents\": " + system_trace_, false);
+ "{\"" + std::string(kChromeTraceLabel) + "\":[", false);
}
- if (!metadata_.empty()) {
- AddTraceChunkAndCompressOnFileThread(",\"metadata\": " + metadata_,
- false);
+ AddTraceChunkAndCompressOnFileThread("]", false);
+
+ for (auto const &it : GetAgentTrace()) {
+ AddTraceChunkAndCompressOnFileThread(
+ ",\"" + it.first + "\": " + it.second, false);
}
- if (!power_trace_.empty()) {
+
+ std::string metadataJSON;
+ if (base::JSONWriter::Write(*GetMetadataCopy(), &metadataJSON) &&
+ !metadataJSON.empty()) {
AddTraceChunkAndCompressOnFileThread(
- ",\"powerTraceAsString\": " + power_trace_, false);
+ ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON,
+ false);
}
AddTraceChunkAndCompressOnFileThread("}", true);
deflateEnd(stream_.get());
stream_.reset();
- endpoint_->ReceiveTraceFinalContents(compressed_trace_data_);
+ endpoint_->ReceiveTraceFinalContents(GetMetadataCopy(),
+ compressed_trace_data_);
}
scoped_refptr<TracingController::TraceDataEndpoint> endpoint_;
scoped_ptr<z_stream> stream_;
bool already_tried_open_;
std::string compressed_trace_data_;
- std::string system_trace_;
- std::string metadata_;
- std::string power_trace_;
DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink);
};
} // namespace
+TracingController::TraceDataSink::TraceDataSink() {}
+
+TracingController::TraceDataSink::~TraceDataSink() {}
+
+void TracingController::TraceDataSink::AddAgentTrace(
+ const std::string& trace_label,
+ const std::string& trace_data) {
+ DCHECK(additional_tracing_agent_trace_.find(trace_label) ==
+ additional_tracing_agent_trace_.end());
+ additional_tracing_agent_trace_[trace_label] = trace_data;
+}
+
+const std::map<std::string, std::string>&
+ TracingController::TraceDataSink::GetAgentTrace() const {
+ return additional_tracing_agent_trace_;
+}
+
+void TracingController::TraceDataSink::AddMetadata(
+ const base::DictionaryValue& data) {
+ metadata_.MergeDictionary(&data);
+}
+
+void TracingController::TraceDataSink::SetMetadataFilterPredicate(
+ const MetadataFilterPredicate& metadata_filter_predicate) {
+ metadata_filter_predicate_ = metadata_filter_predicate;
+}
+
+scoped_ptr<const base::DictionaryValue>
+ TracingController::TraceDataSink::GetMetadataCopy() const {
+ if (metadata_filter_predicate_.is_null())
+ return scoped_ptr<const base::DictionaryValue>(metadata_.DeepCopy());
+
+ scoped_ptr<base::DictionaryValue> metadata_copy(new base::DictionaryValue);
+ for (base::DictionaryValue::Iterator it(metadata_); !it.IsAtEnd();
+ it.Advance()) {
+ if (metadata_filter_predicate_.Run(it.key()))
+ metadata_copy->Set(it.key(), it.value().DeepCopy());
+ else
+ metadata_copy->SetString(it.key(), "__stripped__");
+ }
+ return std::move(metadata_copy);
+}
+
scoped_refptr<TracingController::TraceDataSink>
TracingController::CreateStringSink(
- const base::Callback<void(base::RefCountedString*)>& callback) {
+ const base::Callback<void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)>& callback) {
return new StringTraceDataSink(new StringTraceDataEndpoint(callback));
}
@@ -325,8 +360,9 @@ TracingController::CreateFileSink(const base::FilePath& file_path,
}
scoped_refptr<TracingController::TraceDataEndpoint>
-TracingController::CreateCallbackEndpoint(
- const base::Callback<void(base::RefCountedString*)>& callback) {
+TracingController::CreateCallbackEndpoint(const base::Callback<
+ void(scoped_ptr<const base::DictionaryValue>,
+ base::RefCountedString*)>& callback) {
return new StringTraceDataEndpoint(callback);
}
diff --git a/chromium/content/browser/tracing/tracing_resources.gyp b/chromium/content/browser/tracing/tracing_resources.gyp
index d63e8d85af5..df12689a9b1 100644
--- a/chromium/content/browser/tracing/tracing_resources.gyp
+++ b/chromium/content/browser/tracing/tracing_resources.gyp
@@ -12,6 +12,7 @@
# GN version: //content/browser/tracing:generate_tracing_grd
'target_name': 'generate_tracing_grd',
'type': 'none',
+ 'hard_dependency': 1,
'dependencies': [
'<(trace_viewer_src_dir)/trace_viewer.gyp:generate_about_tracing',
],
@@ -41,6 +42,7 @@
# GN version: //content/browser/tracing:resources
'target_name': 'tracing_resources',
'type': 'none',
+ 'hard_dependency': 1,
'dependencies': [
'<(trace_viewer_src_dir)/trace_viewer.gyp:generate_about_tracing',
'generate_tracing_grd',
@@ -76,6 +78,7 @@
},
'inputs': [
'<(grit_grd_file)',
+ '<(DEPTH)/tools/gritsettings/resource_ids',
'<!@pymod_do_main(grit_info --inputs)',
],
'outputs': [
diff --git a/chromium/content/browser/tracing/tracing_ui.cc b/chromium/content/browser/tracing/tracing_ui.cc
index 4829c367ebd..13eaa402036 100644
--- a/chromium/content/browser/tracing/tracing_ui.cc
+++ b/chromium/content/browser/tracing/tracing_ui.cc
@@ -4,6 +4,8 @@
#include "content/browser/tracing/tracing_ui.h"
+#include <stddef.h>
+
#include <set>
#include <string>
#include <vector>
@@ -47,7 +49,7 @@ void OnGotCategories(const WebUIDataSource::GotDataCallback& callback,
category_list.AppendString(*it);
}
- base::RefCountedString* res = new base::RefCountedString();
+ scoped_refptr<base::RefCountedString> res(new base::RefCountedString());
base::JSONWriter::Write(category_list, &res->data());
callback.Run(res);
}
@@ -111,14 +113,14 @@ bool BeginRecording(const std::string& data64,
if (!GetTracingOptions(data64, &trace_config))
return false;
- return TracingController::GetInstance()->EnableRecording(
+ return TracingController::GetInstance()->StartTracing(
trace_config,
base::Bind(&OnRecordingEnabledAck, callback));
}
void OnRecordingEnabledAck(const WebUIDataSource::GotDataCallback& callback) {
- base::RefCountedString* res = new base::RefCountedString();
- callback.Run(res);
+ callback.Run(
+ scoped_refptr<base::RefCountedMemory>(new base::RefCountedString()));
}
void OnTraceBufferUsageResult(const WebUIDataSource::GotDataCallback& callback,
@@ -145,13 +147,13 @@ void OnTraceBufferStatusResult(const WebUIDataSource::GotDataCallback& callback,
void OnMonitoringEnabledAck(const WebUIDataSource::GotDataCallback& callback);
-bool EnableMonitoring(const std::string& data64,
+bool StartMonitoring(const std::string& data64,
const WebUIDataSource::GotDataCallback& callback) {
base::trace_event::TraceConfig trace_config("", "");
if (!GetTracingOptions(data64, &trace_config))
return false;
- return TracingController::GetInstance()->EnableMonitoring(
+ return TracingController::GetInstance()->StartMonitoring(
trace_config,
base::Bind(OnMonitoringEnabledAck, callback));
}
@@ -194,24 +196,19 @@ void GetMonitoringStatus(const WebUIDataSource::GotDataCallback& callback) {
void TracingCallbackWrapperBase64(
const WebUIDataSource::GotDataCallback& callback,
+ scoped_ptr<const base::DictionaryValue> metadata,
base::RefCountedString* data) {
base::RefCountedString* data_base64 = new base::RefCountedString();
base::Base64Encode(data->data(), &data_base64->data());
callback.Run(data_base64);
}
-std::string GenerateMetadataJSON() {
- // Serialize metadata to json.
- scoped_ptr<base::DictionaryValue> metadata_dict(new base::DictionaryValue());
- metadata_dict->SetString("version", GetContentClient()->GetProduct());
- metadata_dict->SetString(
+void AddCustomMetadata(TracingControllerImpl::TraceDataSink* trace_data_sink) {
+ base::DictionaryValue metadata_dict;
+ metadata_dict.SetString(
"command_line",
base::CommandLine::ForCurrentProcess()->GetCommandLineString());
-
- std::string results;
- if (base::JSONWriter::Write(*metadata_dict.get(), &results))
- return results;
- return std::string();
+ trace_data_sink->AddMetadata(metadata_dict);
}
bool OnBeginJSONRequest(const std::string& path,
@@ -240,17 +237,17 @@ bool OnBeginJSONRequest(const std::string& path,
TracingController::CreateCompressedStringSink(
TracingController::CreateCallbackEndpoint(
base::Bind(TracingCallbackWrapperBase64, callback)));
- data_sink->SetMetadata(GenerateMetadataJSON());
- return TracingController::GetInstance()->DisableRecording(data_sink);
+ AddCustomMetadata(data_sink.get());
+ return TracingController::GetInstance()->StopTracing(data_sink);
}
- const char* enableMonitoringPath = "json/begin_monitoring?";
- if (path.find(enableMonitoringPath) == 0) {
- std::string data = path.substr(strlen(enableMonitoringPath));
- return EnableMonitoring(data, callback);
+ const char* StartMonitoringPath = "json/begin_monitoring?";
+ if (path.find(StartMonitoringPath) == 0) {
+ std::string data = path.substr(strlen(StartMonitoringPath));
+ return StartMonitoring(data, callback);
}
if (path == "json/end_monitoring") {
- return TracingController::GetInstance()->DisableMonitoring(
+ return TracingController::GetInstance()->StopMonitoring(
base::Bind(OnMonitoringDisabled, callback));
}
if (path == "json/capture_monitoring_compressed") {
@@ -258,7 +255,7 @@ bool OnBeginJSONRequest(const std::string& path,
TracingController::CreateCompressedStringSink(
TracingController::CreateCallbackEndpoint(
base::Bind(TracingCallbackWrapperBase64, callback)));
- data_sink->SetMetadata(GenerateMetadataJSON());
+ AddCustomMetadata(data_sink.get());
TracingController::GetInstance()->CaptureMonitoringSnapshot(data_sink);
return true;
}
@@ -381,7 +378,7 @@ void TracingUI::DoUploadInternal(const std::string& file_contents,
// TODO(mmandlis): Add support for stopping the upload in progress.
}
-void TracingUI::OnTraceUploadProgress(int64 current, int64 total) {
+void TracingUI::OnTraceUploadProgress(int64_t current, int64_t total) {
DCHECK(current <= total);
int percent = (current / total) * 100;
web_ui()->CallJavascriptFunction(
diff --git a/chromium/content/browser/tracing/tracing_ui.h b/chromium/content/browser/tracing/tracing_ui.h
index db7b594720e..22e8616cab5 100644
--- a/chromium/content/browser/tracing/tracing_ui.h
+++ b/chromium/content/browser/tracing/tracing_ui.h
@@ -5,9 +5,12 @@
#ifndef CONTENT_BROWSER_TRACING_TRACING_UI_H_
#define CONTENT_BROWSER_TRACING_TRACING_UI_H_
+#include <stdint.h>
+
#include <map>
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/trace_uploader.h"
#include "content/public/browser/web_ui_controller.h"
@@ -22,7 +25,7 @@ class CONTENT_EXPORT TracingUI : public WebUIController {
explicit TracingUI(WebUI* web_ui);
~TracingUI() override;
void OnMonitoringStateChanged(bool is_monitoring);
- void OnTraceUploadProgress(int64 current, int64 total);
+ void OnTraceUploadProgress(int64_t current, int64_t total);
void OnTraceUploadComplete(bool success, const std::string& feedback);
private:
diff --git a/chromium/content/browser/udev_linux.cc b/chromium/content/browser/udev_linux.cc
index dfcb52b9f2e..1890523d714 100644
--- a/chromium/content/browser/udev_linux.cc
+++ b/chromium/content/browser/udev_linux.cc
@@ -4,6 +4,8 @@
#include "content/browser/udev_linux.h"
+#include <stddef.h>
+
#include "base/message_loop/message_loop.h"
namespace content {
diff --git a/chromium/content/browser/udev_linux.h b/chromium/content/browser/udev_linux.h
index 0160fd3241b..3e4ac44a778 100644
--- a/chromium/content/browser/udev_linux.h
+++ b/chromium/content/browser/udev_linux.h
@@ -38,9 +38,9 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/message_loop/message_pump_libevent.h"
#include "device/udev_linux/scoped_udev.h"
diff --git a/chromium/content/browser/utility_process_host_impl.cc b/chromium/content/browser/utility_process_host_impl.cc
index a43fa5d7aa0..db67d60dc22 100644
--- a/chromium/content/browser/utility_process_host_impl.cc
+++ b/chromium/content/browser/utility_process_host_impl.cc
@@ -4,11 +4,15 @@
#include "content/browser/utility_process_host_impl.h"
+#include <utility>
+
#include "base/base_switches.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/files/file_path.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/process/process_handle.h"
#include "base/run_loop.h"
@@ -16,6 +20,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
+#include "build/build_config.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/mojo/mojo_application_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -32,6 +37,11 @@
#include "ipc/ipc_switches.h"
#include "ui/base/ui_base_switches.h"
+#if defined(OS_WIN)
+#include "sandbox/win/src/sandbox_policy.h"
+#include "sandbox/win/src/sandbox_types.h"
+#endif
+
namespace content {
// NOTE: changes to this class need to be reviewed by the security team.
@@ -57,17 +67,32 @@ class UtilitySandboxedProcessLauncherDelegate
#if defined(OS_WIN)
bool ShouldLaunchElevated() override { return launch_elevated_; }
- void PreSandbox(bool* disable_default_policy,
- base::FilePath* exposed_dir) override {
- *exposed_dir = exposed_dir_;
+
+ bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
+ if (exposed_dir_.empty())
+ return true;
+
+ sandbox::ResultCode result;
+ result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
+ sandbox::TargetPolicy::FILES_ALLOW_ANY,
+ exposed_dir_.value().c_str());
+ if (result != sandbox::SBOX_ALL_OK)
+ return false;
+
+ base::FilePath exposed_files = exposed_dir_.AppendASCII("*");
+ result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
+ sandbox::TargetPolicy::FILES_ALLOW_ANY,
+ exposed_files.value().c_str());
+ return result == sandbox::SBOX_ALL_OK;
}
+
#elif defined(OS_POSIX)
bool ShouldUseZygote() override {
return !no_sandbox_ && exposed_dir_.empty();
}
base::EnvironmentMap GetEnvironment() override { return env_; }
- base::ScopedFD TakeIpcFd() override { return ipc_fd_.Pass(); }
+ base::ScopedFD TakeIpcFd() override { return std::move(ipc_fd_); }
#endif // OS_WIN
SandboxType GetSandboxType() override {
@@ -105,7 +130,6 @@ UtilityProcessHostImpl::UtilityProcessHostImpl(
: client_(client),
client_task_runner_(client_task_runner),
is_batch_mode_(false),
- is_mdns_enabled_(false),
no_sandbox_(false),
run_elevated_(false),
#if defined(OS_LINUX)
@@ -122,13 +146,6 @@ UtilityProcessHostImpl::~UtilityProcessHostImpl() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (is_batch_mode_)
EndBatchMode();
-
- // We could be destroyed as a result of Chrome shutdown. When that happens,
- // the Mojo channel doesn't get the opportunity to shut down cleanly because
- // it posts to the IO thread (the current thread) which is being destroyed.
- // To guarantee proper shutdown of the Mojo channel, do it explicitly here.
- if (mojo_application_host_)
- mojo_application_host_->ShutdownOnIOThread();
}
base::WeakPtr<UtilityProcessHost> UtilityProcessHostImpl::AsWeakPtr() {
@@ -159,10 +176,6 @@ void UtilityProcessHostImpl::SetExposedDir(const base::FilePath& dir) {
exposed_dir_ = dir;
}
-void UtilityProcessHostImpl::EnableMDns() {
- is_mdns_enabled_ = true;
-}
-
void UtilityProcessHostImpl::DisableSandbox() {
no_sandbox_ = true;
}
@@ -237,26 +250,36 @@ bool UtilityProcessHostImpl::StartProcess() {
} else {
const base::CommandLine& browser_command_line =
*base::CommandLine::ForCurrentProcess();
- int child_flags = child_flags_;
bool has_cmd_prefix = browser_command_line.HasSwitch(
switches::kUtilityCmdPrefix);
- // When running under gdb, forking /proc/self/exe ends up forking the gdb
- // executable instead of Chromium. It is almost safe to assume that no
- // updates will happen while a developer is running with
- // |switches::kUtilityCmdPrefix|. See ChildProcessHost::GetChildPath() for
- // a similar case with Valgrind.
- if (has_cmd_prefix)
- child_flags = ChildProcessHost::CHILD_NORMAL;
-
- base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags);
- if (exe_path.empty()) {
- NOTREACHED() << "Unable to get utility process binary name.";
- return false;
- }
+ #if defined(OS_ANDROID)
+ // readlink("/prof/self/exe") sometimes fails on Android at startup.
+ // As a workaround skip calling it here, since the executable name is
+ // not needed on Android anyway. See crbug.com/500854.
+ base::CommandLine* cmd_line =
+ new base::CommandLine(base::CommandLine::NO_PROGRAM);
+ #else
+ int child_flags = child_flags_;
+
+ // When running under gdb, forking /proc/self/exe ends up forking the gdb
+ // executable instead of Chromium. It is almost safe to assume that no
+ // updates will happen while a developer is running with
+ // |switches::kUtilityCmdPrefix|. See ChildProcessHost::GetChildPath() for
+ // a similar case with Valgrind.
+ if (has_cmd_prefix)
+ child_flags = ChildProcessHost::CHILD_NORMAL;
+
+ base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags);
+ if (exe_path.empty()) {
+ NOTREACHED() << "Unable to get utility process binary name.";
+ return false;
+ }
+
+ base::CommandLine* cmd_line = new base::CommandLine(exe_path);
+ #endif
- base::CommandLine* cmd_line = new base::CommandLine(exe_path);
cmd_line->AppendSwitchASCII(switches::kProcessType,
switches::kUtilityProcess);
cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
@@ -290,9 +313,6 @@ bool UtilityProcessHostImpl::StartProcess() {
exposed_dir_);
}
- if (is_mdns_enabled_)
- cmd_line->AppendSwitch(switches::kUtilityProcessEnableMDns);
-
#if defined(OS_WIN)
// Let the utility process know if it is intended to be elevated.
if (run_elevated_)
diff --git a/chromium/content/browser/utility_process_host_impl.h b/chromium/content/browser/utility_process_host_impl.h
index 2b54d3de51f..94aafa7c517 100644
--- a/chromium/content/browser/utility_process_host_impl.h
+++ b/chromium/content/browser/utility_process_host_impl.h
@@ -8,12 +8,13 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/browser/utility_process_host.h"
@@ -48,7 +49,6 @@ class CONTENT_EXPORT UtilityProcessHostImpl
bool StartBatchMode() override;
void EndBatchMode() override;
void SetExposedDir(const base::FilePath& dir) override;
- void EnableMDns() override;
void DisableSandbox() override;
#if defined(OS_WIN)
void ElevatePrivileges() override;
@@ -83,10 +83,6 @@ class CONTENT_EXPORT UtilityProcessHostImpl
base::FilePath exposed_dir_;
- // Whether the utility process needs to perform presandbox initialization
- // for mDNS.
- bool is_mdns_enabled_;
-
// Whether to pass switches::kNoSandbox to the child.
bool no_sandbox_;
diff --git a/chromium/content/browser/vibration_manager_integration_browsertest.cc b/chromium/content/browser/vibration_manager_integration_browsertest.cc
new file mode 100644
index 00000000000..0a79119c6d9
--- /dev/null
+++ b/chromium/content/browser/vibration_manager_integration_browsertest.cc
@@ -0,0 +1,140 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include <utility>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/service_registry.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_content_browser_client.h"
+#include "device/vibration/vibration_manager.mojom.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+// These tests run against a dummy implementation of the VibrationManager
+// service. That is, they verify that the service implementation is correctly
+// exposed to the renderer, whatever the implementation is.
+
+namespace content {
+
+namespace {
+
+// Global, record milliseconds when Vibrate() got called.
+int64_t g_vibrate_milliseconds;
+// Global, record whether Cancel() got called.
+bool g_cancelled;
+// Global, wait for end of execution for VibrationManager API Vibrate().
+scoped_refptr<content::MessageLoopRunner> g_wait_vibrate_runner;
+// Global, wait for end of execution for VibrationManager API Cancel().
+scoped_refptr<content::MessageLoopRunner> g_wait_cancel_runner;
+
+void ResetGlobalValues() {
+ g_vibrate_milliseconds = -1;
+ g_cancelled = false;
+
+ g_wait_vibrate_runner = new content::MessageLoopRunner();
+ g_wait_cancel_runner = new content::MessageLoopRunner();
+}
+
+class FakeVibrationManager : public device::VibrationManager {
+ public:
+ static void Create(mojo::InterfaceRequest<VibrationManager> request) {
+ new FakeVibrationManager(std::move(request));
+ }
+
+ private:
+ FakeVibrationManager(mojo::InterfaceRequest<VibrationManager> request)
+ : binding_(this, std::move(request)) {}
+ ~FakeVibrationManager() override {}
+
+ void Vibrate(int64_t milliseconds) override {
+ g_vibrate_milliseconds = milliseconds;
+ g_wait_vibrate_runner->Quit();
+ }
+
+ void Cancel() override {
+ g_cancelled = true;
+ g_wait_cancel_runner->Quit();
+ }
+
+ mojo::StrongBinding<VibrationManager> binding_;
+};
+
+// Overrides the default service implementation with the test implementation
+// declared above.
+class TestContentBrowserClient : public ContentBrowserClient {
+ public:
+ void RegisterRenderProcessMojoServices(ServiceRegistry* registry) override {
+ registry->AddService(base::Bind(&FakeVibrationManager::Create));
+ }
+
+#if defined(OS_ANDROID)
+ void GetAdditionalMappedFilesForChildProcess(
+ const base::CommandLine& command_line,
+ int child_process_id,
+ FileDescriptorInfo* mappings,
+ std::map<int, base::MemoryMappedFile::Region>* regions) override {
+ ShellContentBrowserClient::Get()->GetAdditionalMappedFilesForChildProcess(
+ command_line, child_process_id, mappings, regions);
+ }
+#endif // defined(OS_ANDROID)
+};
+
+class VibrationManagerIntegrationTest : public ContentBrowserTest {
+ public:
+ VibrationManagerIntegrationTest() {}
+
+ void SetUpOnMainThread() override {
+ old_client_ = SetBrowserClientForTesting(&test_client_);
+ ResetGlobalValues();
+ }
+
+ void TearDownOnMainThread() override {
+ SetBrowserClientForTesting(old_client_);
+ }
+
+ private:
+ TestContentBrowserClient test_client_;
+ ContentBrowserClient* old_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(VibrationManagerIntegrationTest);
+};
+
+IN_PROC_BROWSER_TEST_F(VibrationManagerIntegrationTest, Vibrate) {
+ // From JavaScript call navigator.vibrate(3000),
+ // then check the global value g_vibrate_milliseconds.
+ ASSERT_EQ(-1, g_vibrate_milliseconds);
+ ASSERT_FALSE(g_wait_vibrate_runner->loop_running());
+
+ GURL test_url =
+ GetTestUrl("vibration", "vibration_manager_vibrate_test.html");
+ shell()->LoadURL(test_url);
+ // Wait until VibrationManager::Vibrate() got called.
+ g_wait_vibrate_runner->Run();
+
+ EXPECT_EQ(3000, g_vibrate_milliseconds);
+}
+
+IN_PROC_BROWSER_TEST_F(VibrationManagerIntegrationTest, Cancel) {
+ // From JavaScript call navigator.vibrate(0),
+ // then check the global value g_cancelled.
+ ASSERT_FALSE(g_cancelled);
+ ASSERT_FALSE(g_wait_cancel_runner->loop_running());
+
+ GURL test_url = GetTestUrl("vibration", "vibration_manager_cancel_test.html");
+ shell()->LoadURL(test_url);
+ // Wait until VibrationManager::Cancel() got called.
+ g_wait_cancel_runner->Run();
+
+ EXPECT_TRUE(g_cancelled);
+}
+
+} // namespace
+
+} // namespace content
diff --git a/chromium/content/browser/vr/OWNERS b/chromium/content/browser/vr/OWNERS
index 1c724a66a0e..8bc3cc2bc1c 100644
--- a/chromium/content/browser/vr/OWNERS
+++ b/chromium/content/browser/vr/OWNERS
@@ -1,2 +1,3 @@
bajones@chromium.org
kbr@chromium.org
+hendrikw@chromium.org
diff --git a/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.cc b/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.cc
index 378a85501f3..9d9aca7c632 100644
--- a/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.cc
+++ b/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.cc
@@ -7,6 +7,7 @@
#include <math.h>
#include <algorithm>
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
@@ -117,7 +118,7 @@ VRDeviceInfoPtr CardboardVRDevice::GetVRDevice() {
right_eye->renderRect->width = screen_size[0] / 2.0;
right_eye->renderRect->height = screen_size[1];
- return device.Pass();
+ return device;
}
VRSensorStatePtr CardboardVRDevice::GetSensorState() {
@@ -155,7 +156,7 @@ VRSensorStatePtr CardboardVRDevice::GetSensorState() {
state->position->y = decomposed_transform.translate[1];
state->position->z = decomposed_transform.translate[2];
- return state.Pass();
+ return state;
}
void CardboardVRDevice::ResetSensor() {
diff --git a/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.h b/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.h
index 769fd9af723..66f82876ab1 100644
--- a/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.h
+++ b/chromium/content/browser/vr/android/cardboard/cardboard_vr_device.h
@@ -8,7 +8,7 @@
#include <jni.h>
#include "base/android/jni_android.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "content/browser/vr/vr_device.h"
namespace content {
diff --git a/chromium/content/browser/vr/android/cardboard/cardboard_vr_device_provider.h b/chromium/content/browser/vr/android/cardboard/cardboard_vr_device_provider.h
index 2b3f87c2b1e..b041316bc8c 100644
--- a/chromium/content/browser/vr/android/cardboard/cardboard_vr_device_provider.h
+++ b/chromium/content/browser/vr/android/cardboard/cardboard_vr_device_provider.h
@@ -7,7 +7,7 @@
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/vr/vr_device.h"
#include "content/browser/vr/vr_device_provider.h"
diff --git a/chromium/content/browser/vr/vr_device_manager.cc b/chromium/content/browser/vr/vr_device_manager.cc
index 07e420da38b..c99ee393009 100644
--- a/chromium/content/browser/vr/vr_device_manager.cc
+++ b/chromium/content/browser/vr/vr_device_manager.cc
@@ -4,8 +4,11 @@
#include "content/browser/vr/vr_device_manager.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/memory/singleton.h"
+#include "build/build_config.h"
#include "third_party/WebKit/public/platform/modules/vr/WebVR.h"
#if defined(OS_ANDROID)
@@ -26,14 +29,14 @@ VRDeviceManager::VRDeviceManager()
#if defined(OS_ANDROID)
scoped_ptr<VRDeviceProvider> cardboard_provider(
new CardboardVRDeviceProvider());
- RegisterProvider(cardboard_provider.Pass());
+ RegisterProvider(std::move(cardboard_provider));
#endif
}
VRDeviceManager::VRDeviceManager(scoped_ptr<VRDeviceProvider> provider)
: vr_initialized_(false), keep_alive_(true) {
thread_checker_.DetachFromThread();
- RegisterProvider(provider.Pass());
+ RegisterProvider(std::move(provider));
SetInstance(this);
}
@@ -44,7 +47,7 @@ VRDeviceManager::~VRDeviceManager() {
void VRDeviceManager::BindRequest(mojo::InterfaceRequest<VRService> request) {
VRDeviceManager* device_manager = GetInstance();
- device_manager->bindings_.AddBinding(device_manager, request.Pass());
+ device_manager->bindings_.AddBinding(device_manager, std::move(request));
}
void VRDeviceManager::OnConnectionError() {
@@ -96,7 +99,7 @@ mojo::Array<VRDeviceInfoPtr> VRDeviceManager::GetVRDevices() {
continue;
vr_device_info->index = device->id();
- out_devices.push_back(vr_device_info.Pass());
+ out_devices.push_back(std::move(vr_device_info));
}
return out_devices;
diff --git a/chromium/content/browser/vr/vr_device_manager.h b/chromium/content/browser/vr/vr_device_manager.h
index 58789f767be..4eb39ea685e 100644
--- a/chromium/content/browser/vr/vr_device_manager.h
+++ b/chromium/content/browser/vr/vr_device_manager.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_VR_VR_DEVICE_MANAGER_H
#define CONTENT_BROWSER_VR_VR_DEVICE_MANAGER_H
+#include <stdint.h>
+
#include <map>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
diff --git a/chromium/content/browser/vr/vr_device_manager_unittest.cc b/chromium/content/browser/vr/vr_device_manager_unittest.cc
index 873a2967069..001d4403e67 100644
--- a/chromium/content/browser/vr/vr_device_manager_unittest.cc
+++ b/chromium/content/browser/vr/vr_device_manager_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/vr/test/fake_vr_device.h"
diff --git a/chromium/content/browser/wake_lock/wake_lock_browsertest.cc b/chromium/content/browser/wake_lock/wake_lock_browsertest.cc
new file mode 100644
index 00000000000..3ac458973ce
--- /dev/null
+++ b/chromium/content/browser/wake_lock/wake_lock_browsertest.cc
@@ -0,0 +1,376 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/test/test_timeouts.h"
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace content {
+
+namespace {
+
+const char kBlinkWakeLockFeature[] = "WakeLock";
+
+} // namespace
+
+class WakeLockTest : public ContentBrowserTest {
+ public:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
+ kBlinkWakeLockFeature);
+ command_line->AppendSwitch(switches::kSitePerProcess);
+ }
+
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ EXPECT_TRUE(embedded_test_server()->Start());
+ // To prevent occlusion events from changing page visibility.
+ GetWebContents()->IncrementCapturerCount(gfx::Size());
+ }
+
+ void TearDownOnMainThread() override {
+ GetWebContents()->DecrementCapturerCount();
+ }
+
+ protected:
+ WebContents* GetWebContents() { return shell()->web_contents(); }
+
+ WebContentsImpl* GetWebContentsImpl() {
+ return static_cast<WebContentsImpl*>(GetWebContents());
+ }
+
+ RenderFrameHost* GetMainFrame() { return GetWebContents()->GetMainFrame(); }
+
+ FrameTreeNode* GetNestedFrameNode() {
+ FrameTreeNode* root = GetWebContentsImpl()->GetFrameTree()->root();
+ CHECK_EQ(1U, root->child_count());
+ return root->child_at(0);
+ }
+
+ RenderFrameHost* GetNestedFrame() {
+ return GetNestedFrameNode()->current_frame_host();
+ }
+
+ WakeLockServiceContext* GetWakeLockServiceContext() {
+ return GetWebContentsImpl()->GetWakeLockServiceContext();
+ }
+
+ bool HasWakeLock() {
+ return GetWakeLockServiceContext()->HasWakeLockForTests();
+ }
+
+ void WaitForPossibleUpdate() {
+ // As Mojo channels have no common FIFO order in respect to each other and
+ // to the Chromium IPC, we cannot assume that when screen.keepAwake state
+ // is changed from within a script, WakeLockService will receive an update
+ // request before ExecuteScript() returns. Therefore, some time slack is
+ // needed to make sure that WakeLockService has received any possible update
+ // requests before checking the resulting wake lock state.
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
+ RunAllPendingInMessageLoop();
+ }
+
+ void ScreenWakeLockInMainFrame() {
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+ EXPECT_TRUE(HasWakeLock());
+ }
+
+ bool EvaluateAsBool(const ToRenderFrameHost& adapter,
+ const std::string& expr) {
+ bool result;
+ CHECK(ExecuteScriptAndExtractBool(
+ adapter, "window.domAutomationController.send(" + expr + ");",
+ &result));
+ return result;
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, WakeLockApiIsPresent) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+ EXPECT_TRUE(
+ EvaluateAsBool(GetMainFrame(), "typeof screen.keepAwake !== undefined"));
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, LockAndUnlockScreenInMainFrame) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+
+ // Should not have screen wake lock initially.
+ EXPECT_FALSE(HasWakeLock());
+
+ // Check attribute 'screen.keepAwake' in main frame.
+ EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+ // Set keep awake flag in main frame.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // Keep awake flag should be set in main frame.
+ EXPECT_TRUE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+ // Should create screen wake lock.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Reset keep awake flag in main frame.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;"));
+ WaitForPossibleUpdate();
+
+ // Keep awake flag should not be set in main frame.
+ EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+ // Should release screen wake lock.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, MultipleLockThenUnlock) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+
+ // Set keep awake flag.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // Set keep awake flag again.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // Screen should still be locked.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Reset keep awake flag.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;"));
+ WaitForPossibleUpdate();
+
+ // Should release screen wake lock.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, LockInMainFrameAndNestedFrame) {
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+ EXPECT_FALSE(HasWakeLock());
+
+ // Lock screen in nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // Should create screen wake lock.
+ EXPECT_TRUE(HasWakeLock());
+
+ // screen.keepAwake should be false in the main frame.
+ EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+ // Lock screen in main frame.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // screen.keepAwake should be true in the main frame.
+ EXPECT_TRUE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+ // Screen wake lock should not change.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Unlock screen in nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = false;"));
+ WaitForPossibleUpdate();
+
+ // Screen wake lock should be present, as the main frame is still requesting
+ // it.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Unlock screen in main frame.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;"));
+ WaitForPossibleUpdate();
+
+ // Screen wake lock should be released, as no frames are requesting it.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, FrameRemoved) {
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+ EXPECT_FALSE(HasWakeLock());
+
+ // Lock screen in nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ EXPECT_TRUE(HasWakeLock());
+
+ // Remove nested frame.
+ EXPECT_TRUE(ExecuteScript(GetMainFrame(),
+ "var iframe = document.getElementById('3-1-id');"
+ "iframe.parentNode.removeChild(iframe);"));
+
+ // Screen wake lock should be released.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterTabCrashed) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+ ScreenWakeLockInMainFrame();
+
+ // Crash the tab.
+ CrashTab(GetWebContents());
+
+ // Screen wake lock should be released.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterNavigation) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+ ScreenWakeLockInMainFrame();
+
+ // Navigate to a different document.
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
+
+ // Screen wake lock should be released after navigation.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterNavigationToSelf) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+ ScreenWakeLockInMainFrame();
+
+ // Navigate to the same document.
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+
+ // Screen wake lock should be released after navigation to the same URL.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, KeepLockAfterInPageNavigation) {
+ GURL test_url(
+ embedded_test_server()->GetURL("/session_history/fragment.html"));
+ GURL test_in_page_url(test_url.spec() + "#a");
+
+ NavigateToURL(shell(), test_url);
+ ScreenWakeLockInMainFrame();
+
+ NavigateToURL(shell(), test_in_page_url);
+ EXPECT_TRUE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterReload) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+ ScreenWakeLockInMainFrame();
+
+ shell()->Reload();
+ WaitForLoadStop(GetWebContents());
+
+ // Screen wake lock should be released after reload.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, BrowserInitiatedFrameNavigation) {
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+
+ EXPECT_FALSE(HasWakeLock());
+
+ // Lock screen in nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // Screen wake lock should be present.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Navigate the nested frame (browser-initiated).
+ NavigateFrameToURL(GetNestedFrameNode(),
+ embedded_test_server()->GetURL("/simple_page.html"));
+ WaitForPossibleUpdate();
+
+ // Screen wake lock should be released.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, RendererInitiatedFrameNavigation) {
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+
+ EXPECT_FALSE(HasWakeLock());
+
+ // Lock screen in nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // Screen wake lock should be present.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Navigate the nested frame (renderer-initiated).
+ NavigateIframeToURL(GetWebContents(), "3-1-id",
+ embedded_test_server()->GetURL("/simple_page.html"));
+ WaitForPossibleUpdate();
+
+ // Screen wake lock should be released.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, OutOfProcessFrame) {
+ NavigateToURL(shell(), embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a)"));
+ EXPECT_FALSE(HasWakeLock());
+
+ // Ensure that the nested frame is same-process.
+ EXPECT_FALSE(GetNestedFrame()->IsCrossProcessSubframe());
+
+ // Lock screen in same-site nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+ EXPECT_TRUE(HasWakeLock());
+
+ // Navigate nested frame to a cross-site document.
+ NavigateFrameToURL(GetNestedFrameNode(), embedded_test_server()->GetURL(
+ "b.com", "/simple_page.html"));
+ WaitForPossibleUpdate();
+
+ // Ensure that a new process has been created for the nested frame.
+ EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe());
+
+ // Screen wake lock should be released.
+ EXPECT_FALSE(HasWakeLock());
+
+ // Lock screen in the cross-site nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+
+ // Screen wake lock should be created.
+ EXPECT_TRUE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterCrashOutOfProcessFrame) {
+ // Load a page with cross-site iframe.
+ NavigateToURL(shell(), embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_FALSE(HasWakeLock());
+
+ // Ensure that a new process has been created for the nested frame.
+ EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe());
+
+ // Lock screen in cross-site nested frame.
+ EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+ WaitForPossibleUpdate();
+ EXPECT_TRUE(HasWakeLock());
+
+ // Crash process that owns the out-of-process frame.
+ RenderProcessHostWatcher watcher(
+ GetNestedFrame()->GetProcess(),
+ RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ GetNestedFrame()->GetProcess()->Shutdown(0, false);
+ watcher.Wait();
+
+ // Screen wake lock should be released.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/wake_lock/wake_lock_service_context.cc b/chromium/content/browser/wake_lock/wake_lock_service_context.cc
new file mode 100644
index 00000000000..a6da2103def
--- /dev/null
+++ b/chromium/content/browser/wake_lock/wake_lock_service_context.cc
@@ -0,0 +1,92 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "build/build_config.h"
+#include "content/browser/power_save_blocker_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/power_save_blocker.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/service_registry.h"
+
+namespace content {
+
+WakeLockServiceContext::WakeLockServiceContext(WebContents* web_contents)
+ : WebContentsObserver(web_contents), weak_factory_(this) {}
+
+WakeLockServiceContext::~WakeLockServiceContext() {}
+
+void WakeLockServiceContext::CreateService(
+ int render_process_id,
+ int render_frame_id,
+ mojo::InterfaceRequest<WakeLockService> request) {
+ new WakeLockServiceImpl(weak_factory_.GetWeakPtr(), render_process_id,
+ render_frame_id, std::move(request));
+}
+
+void WakeLockServiceContext::RenderFrameDeleted(
+ RenderFrameHost* render_frame_host) {
+ CancelWakeLock(render_frame_host->GetProcess()->GetID(),
+ render_frame_host->GetRoutingID());
+}
+
+void WakeLockServiceContext::RequestWakeLock(int render_process_id,
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!RenderFrameHost::FromID(render_process_id, render_frame_id))
+ return;
+
+ frames_requesting_lock_.insert(
+ std::pair<int, int>(render_process_id, render_frame_id));
+ UpdateWakeLock();
+}
+
+void WakeLockServiceContext::CancelWakeLock(int render_process_id,
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ frames_requesting_lock_.erase(
+ std::pair<int, int>(render_process_id, render_frame_id));
+ UpdateWakeLock();
+}
+
+bool WakeLockServiceContext::HasWakeLockForTests() const {
+ return wake_lock_;
+}
+
+void WakeLockServiceContext::CreateWakeLock() {
+ DCHECK(!wake_lock_);
+ wake_lock_ = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
+ PowerSaveBlocker::kReasonOther, "Wake Lock API");
+
+#if defined(OS_ANDROID) && !defined(USE_AURA)
+ // On Android, additionaly associate the blocker with this WebContents.
+ DCHECK(web_contents());
+
+ static_cast<PowerSaveBlockerImpl*>(wake_lock_.get())
+ ->InitDisplaySleepBlocker(web_contents());
+#endif
+}
+
+void WakeLockServiceContext::RemoveWakeLock() {
+ DCHECK(wake_lock_);
+ wake_lock_.reset();
+}
+
+void WakeLockServiceContext::UpdateWakeLock() {
+ if (!frames_requesting_lock_.empty()) {
+ if (!wake_lock_)
+ CreateWakeLock();
+ } else {
+ if (wake_lock_)
+ RemoveWakeLock();
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/wake_lock/wake_lock_service_context.h b/chromium/content/browser/wake_lock/wake_lock_service_context.h
new file mode 100644
index 00000000000..f3114d73e94
--- /dev/null
+++ b/chromium/content/browser/wake_lock/wake_lock_service_context.h
@@ -0,0 +1,68 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_CONTEXT_H_
+#define CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_CONTEXT_H_
+
+#include <set>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/wake_lock/wake_lock_service_impl.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+
+namespace content {
+
+class PowerSaveBlocker;
+class RenderFrameHost;
+class WebContents;
+
+class CONTENT_EXPORT WakeLockServiceContext : public WebContentsObserver {
+ public:
+ explicit WakeLockServiceContext(WebContents* web_contents);
+ ~WakeLockServiceContext() override;
+
+ // Creates a WakeLockServiceImpl that is strongly bound to |request|.
+ void CreateService(int render_process_id,
+ int render_frame_id,
+ mojo::InterfaceRequest<WakeLockService> request);
+
+ // WebContentsObserver implementation.
+ void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
+
+ // Requests wake lock for RenderFrame identified by |render_process_id| and
+ // |render_frame_id|.
+ void RequestWakeLock(int render_process_id, int render_frame_id);
+
+ // Cancels wake lock request for RenderFrame identified by
+ // |render_process_id| and |render_frame_id|.
+ void CancelWakeLock(int render_process_id, int render_frame_id);
+
+ // Used by tests.
+ bool HasWakeLockForTests() const;
+
+ private:
+ void CreateWakeLock();
+ void RemoveWakeLock();
+ void UpdateWakeLock();
+
+ // Set of (render_process_id, render_frame_id) pairs identifying all
+ // RenderFrames requesting wake lock.
+ std::set<std::pair<int, int>> frames_requesting_lock_;
+
+ // The actual power save blocker for screen.
+ scoped_ptr<PowerSaveBlocker> wake_lock_;
+
+ base::WeakPtrFactory<WakeLockServiceContext> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WakeLockServiceContext);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_CONTEXT_H_
diff --git a/chromium/content/browser/wake_lock/wake_lock_service_context_unittest.cc b/chromium/content/browser/wake_lock/wake_lock_service_context_unittest.cc
new file mode 100644
index 00000000000..49211583929
--- /dev/null
+++ b/chromium/content/browser/wake_lock/wake_lock_service_context_unittest.cc
@@ -0,0 +1,96 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/process/kill.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/test_renderer_host.h"
+
+namespace content {
+
+class RenderFrameHost;
+
+class WakeLockServiceContextTest : public RenderViewHostTestHarness {
+ protected:
+ void RequestWakeLock(RenderFrameHost* rfh) {
+ GetWakeLockServiceContext()->RequestWakeLock(rfh->GetProcess()->GetID(),
+ rfh->GetRoutingID());
+ }
+
+ void CancelWakeLock(RenderFrameHost* rfh) {
+ GetWakeLockServiceContext()->CancelWakeLock(rfh->GetProcess()->GetID(),
+ rfh->GetRoutingID());
+ }
+
+ WakeLockServiceContext* GetWakeLockServiceContext() {
+ WebContentsImpl* web_contents_impl =
+ static_cast<WebContentsImpl*>(web_contents());
+ return web_contents_impl->GetWakeLockServiceContext();
+ }
+
+ bool HasWakeLock() {
+ return GetWakeLockServiceContext()->HasWakeLockForTests();
+ }
+};
+
+TEST_F(WakeLockServiceContextTest, NoLockInitially) {
+ EXPECT_FALSE(HasWakeLock());
+}
+
+TEST_F(WakeLockServiceContextTest, LockUnlock) {
+ ASSERT_TRUE(GetWakeLockServiceContext());
+ ASSERT_TRUE(web_contents());
+ ASSERT_TRUE(main_rfh());
+
+ // Request wake lock for main frame.
+ RequestWakeLock(main_rfh());
+
+ // Should set the blocker.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Remove wake lock request for main frame.
+ CancelWakeLock(main_rfh());
+
+ // Should remove the blocker.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+TEST_F(WakeLockServiceContextTest, RenderFrameDeleted) {
+ ASSERT_TRUE(GetWakeLockServiceContext());
+ ASSERT_TRUE(web_contents());
+ ASSERT_TRUE(main_rfh());
+
+ // Request wake lock for main frame.
+ RequestWakeLock(main_rfh());
+
+ // Should set the blocker.
+ EXPECT_TRUE(HasWakeLock());
+
+ // Simulate render frame deletion.
+ GetWakeLockServiceContext()->RenderFrameDeleted(main_rfh());
+
+ // Should remove the blocker.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+TEST_F(WakeLockServiceContextTest, NoLockForBogusFrameId) {
+ ASSERT_TRUE(GetWakeLockServiceContext());
+ ASSERT_TRUE(web_contents());
+
+ // Request wake lock for non-existent render frame id.
+ int non_existent_render_frame_id =
+ main_rfh()->GetProcess()->GetNextRoutingID();
+ GetWakeLockServiceContext()->RequestWakeLock(
+ main_rfh()->GetProcess()->GetID(), non_existent_render_frame_id);
+
+ // Should not set the blocker.
+ EXPECT_FALSE(HasWakeLock());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/wake_lock/wake_lock_service_impl.cc b/chromium/content/browser/wake_lock/wake_lock_service_impl.cc
new file mode 100644
index 00000000000..036cb1dec9a
--- /dev/null
+++ b/chromium/content/browser/wake_lock/wake_lock_service_impl.cc
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/wake_lock/wake_lock_service_impl.h"
+
+#include <utility>
+
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+
+namespace content {
+
+WakeLockServiceImpl::WakeLockServiceImpl(
+ base::WeakPtr<WakeLockServiceContext> context,
+ int render_process_id,
+ int render_frame_id,
+ mojo::InterfaceRequest<WakeLockService> request)
+ : context_(context),
+ render_process_id_(render_process_id),
+ render_frame_id_(render_frame_id),
+ binding_(this, std::move(request)) {}
+
+WakeLockServiceImpl::~WakeLockServiceImpl() {}
+
+void WakeLockServiceImpl::RequestWakeLock() {
+ if (context_)
+ context_->RequestWakeLock(render_process_id_, render_frame_id_);
+}
+
+void WakeLockServiceImpl::CancelWakeLock() {
+ if (context_)
+ context_->CancelWakeLock(render_process_id_, render_frame_id_);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/wake_lock/wake_lock_service_impl.h b/chromium/content/browser/wake_lock/wake_lock_service_impl.h
new file mode 100644
index 00000000000..903f5057fa3
--- /dev/null
+++ b/chromium/content/browser/wake_lock/wake_lock_service_impl.h
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_IMPL_H_
+#define CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_IMPL_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/wake_lock_service.mojom.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace content {
+
+class WakeLockServiceContext;
+
+class WakeLockServiceImpl : public WakeLockService {
+ public:
+ WakeLockServiceImpl(base::WeakPtr<WakeLockServiceContext> context,
+ int render_process_id,
+ int render_frame_id,
+ mojo::InterfaceRequest<WakeLockService> request);
+ ~WakeLockServiceImpl() override;
+
+ // WakeLockSevice implementation.
+ void RequestWakeLock() override;
+ void CancelWakeLock() override;
+
+ private:
+ base::WeakPtr<WakeLockServiceContext> context_;
+ const int render_process_id_;
+ const int render_frame_id_;
+ mojo::StrongBinding<WakeLockService> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(WakeLockServiceImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_IMPL_H_
diff --git a/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc b/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc
index c8569b92dc3..debe71138ea 100644
--- a/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc
+++ b/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc
@@ -4,6 +4,9 @@
#include "content/browser/web_contents/aura/gesture_nav_simple.h"
+#include <utility>
+
+#include "base/macros.h"
#include "cc/layers/layer.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/renderer_host/overscroll_controller.h"
@@ -49,7 +52,7 @@ template <class T>
class DeleteAfterAnimation : public ui::ImplicitAnimationObserver {
public:
explicit DeleteAfterAnimation(scoped_ptr<T> object)
- : object_(object.Pass()) {}
+ : object_(std::move(object)) {}
private:
friend class base::DeleteHelper<DeleteAfterAnimation<T> >;
@@ -128,9 +131,10 @@ void GestureNavSimple::ApplyEffectsAndDestroy(const gfx::Transform& transform,
ui::Layer* layer = arrow_.get();
ui::ScopedLayerAnimationSettings settings(arrow_->GetAnimator());
settings.AddObserver(
- new DeleteAfterAnimation<ArrowLayerDelegate>(arrow_delegate_.Pass()));
- settings.AddObserver(new DeleteAfterAnimation<ui::Layer>(arrow_.Pass()));
- settings.AddObserver(new DeleteAfterAnimation<ui::Layer>(clip_layer_.Pass()));
+ new DeleteAfterAnimation<ArrowLayerDelegate>(std::move(arrow_delegate_)));
+ settings.AddObserver(new DeleteAfterAnimation<ui::Layer>(std::move(arrow_)));
+ settings.AddObserver(
+ new DeleteAfterAnimation<ui::Layer>(std::move(clip_layer_)));
layer->SetTransform(transform);
layer->SetOpacity(opacity);
}
diff --git a/chromium/content/browser/web_contents/aura/gesture_nav_simple.h b/chromium/content/browser/web_contents/aura/gesture_nav_simple.h
index 46da9098470..999ef262600 100644
--- a/chromium/content/browser/web_contents/aura/gesture_nav_simple.h
+++ b/chromium/content/browser/web_contents/aura/gesture_nav_simple.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_WEB_CONTENTS_AURA_GESTURE_NAV_SIMPLE_H_
#define CONTENT_BROWSER_WEB_CONTENTS_AURA_GESTURE_NAV_SIMPLE_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
diff --git a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
index 14b23752fda..b05feedb6d9 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
@@ -4,9 +4,11 @@
#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
+#include <utility>
#include <vector>
#include "base/i18n/rtl.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -52,7 +54,7 @@ class OverlayDismissAnimator
public:
// Takes ownership of the layer.
explicit OverlayDismissAnimator(scoped_ptr<ui::Layer> layer)
- : layer_(layer.Pass()) {
+ : layer_(std::move(layer)) {
CHECK(layer_.get());
}
@@ -133,7 +135,7 @@ void OverscrollNavigationOverlay::StopObservingIfDone() {
// animation completes.
scoped_ptr<ui::Layer> dismiss_layer = window_->AcquireLayer();
window_.reset();
- (new OverlayDismissAnimator(dismiss_layer.Pass()))->Animate();
+ (new OverlayDismissAnimator(std::move(dismiss_layer)))->Animate();
Observe(nullptr);
received_paint_update_ = false;
loading_complete_ = false;
@@ -163,7 +165,7 @@ scoped_ptr<aura::Window> OverscrollNavigationOverlay::CreateOverlayWindow(
// off its bounds.
event_window->SetCapture();
window->Show();
- return window.Pass();
+ return window;
}
const gfx::Image OverscrollNavigationOverlay::GetImageForDirection(
@@ -246,7 +248,7 @@ void OverscrollNavigationOverlay::OnOverscrollCompleted(
}
main_window->SetTransform(gfx::Transform());
- window_ = window.Pass();
+ window_ = std::move(window);
// Make sure the window is in its default position.
window_->SetBounds(gfx::Rect(web_contents_window_->bounds().size()));
window_->SetTransform(gfx::Transform());
diff --git a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
index 841332a6ce4..97dd750160c 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
@@ -4,14 +4,17 @@
#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
+#include <string.h>
+#include <utility>
#include <vector>
-#include "base/command_line.h"
+
+#include "base/macros.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/overscroll_configuration.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/test/test_render_frame_host.h"
#include "content/test/test_render_view_host.h"
@@ -39,7 +42,8 @@ class OverscrollTestWebContents : public TestWebContents {
scoped_ptr<aura::Window> fake_native_view,
scoped_ptr<aura::Window> fake_contents_window) {
OverscrollTestWebContents* web_contents = new OverscrollTestWebContents(
- browser_context, fake_native_view.Pass(), fake_contents_window.Pass());
+ browser_context, std::move(fake_native_view),
+ std::move(fake_contents_window));
web_contents->Init(WebContents::CreateParams(browser_context, instance));
return web_contents;
}
@@ -64,8 +68,8 @@ class OverscrollTestWebContents : public TestWebContents {
scoped_ptr<aura::Window> fake_native_view,
scoped_ptr<aura::Window> fake_contents_window)
: TestWebContents(browser_context),
- fake_native_view_(fake_native_view.Pass()),
- fake_contents_window_(fake_contents_window.Pass()),
+ fake_native_view_(std::move(fake_native_view)),
+ fake_contents_window_(std::move(fake_contents_window)),
is_being_destroyed_(false) {}
private:
@@ -117,13 +121,11 @@ class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness {
else
EXPECT_EQ(GetOverlay()->direction_, OverscrollNavigationOverlay::NONE);
window->SetBounds(gfx::Rect(root_window()->bounds().size()));
- GetOverlay()->OnOverscrollCompleted(window.Pass());
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ GetOverlay()->OnOverscrollCompleted(std::move(window));
+ if (IsBrowserSideNavigationEnabled())
main_test_rfh()->PrepareForCommit();
- } else {
+ else
contents()->GetPendingMainFrame()->PrepareForCommit();
- }
if (window_created)
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
else
@@ -165,10 +167,8 @@ class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness {
// Replace the default test web contents with our custom class.
SetContents(OverscrollTestWebContents::Create(
- browser_context(),
- SiteInstance::Create(browser_context()),
- fake_native_view.Pass(),
- fake_contents_window.Pass()));
+ browser_context(), SiteInstance::Create(browser_context()),
+ std::move(fake_native_view), std::move(fake_contents_window)));
contents()->NavigateAndCommit(first());
EXPECT_TRUE(controller().GetVisibleEntry());
@@ -193,7 +193,7 @@ class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness {
RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect);
// Reset pending flags for size/paint.
- test_rvh()->ResetSizeAndRepaintPendingFlags();
+ test_rvh()->GetWidget()->ResetSizeAndRepaintPendingFlags();
// Create the overlay, and set the contents of the overlay window.
overlay_.reset(new OverscrollNavigationOverlay(contents(), root_window()));
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_animation.cc b/chromium/content/browser/web_contents/aura/overscroll_window_animation.cc
index c89faa08b08..8ed3bf04d48 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_animation.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_animation.cc
@@ -5,6 +5,7 @@
#include "content/browser/web_contents/aura/overscroll_window_animation.h"
#include <algorithm>
+#include <utility>
#include "base/i18n/rtl.h"
#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
@@ -78,7 +79,7 @@ void OverscrollWindowAnimation::OnImplicitAnimationsCompleted() {
delegate_->OnOverscrollCancelled();
overscroll_cancelled_ = false;
} else {
- delegate_->OnOverscrollCompleted(slide_window_.Pass());
+ delegate_->OnOverscrollCompleted(std::move(slide_window_));
}
direction_ = SLIDE_NONE;
}
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_animation.h b/chromium/content/browser/web_contents/aura/overscroll_window_animation.h
index 4e4936575c0..7de03fd2ad1 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_animation.h
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_animation.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_WEB_CONTENTS_AURA_OVERSCROLL_WINDOW_ANIMATION_H_
#define CONTENT_BROWSER_WEB_CONTENTS_AURA_OVERSCROLL_WINDOW_ANIMATION_H_
+#include "base/macros.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
#include "content/common/content_export.h"
#include "ui/compositor/layer_animation_observer.h"
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_animation_unittest.cc b/chromium/content/browser/web_contents/aura/overscroll_window_animation_unittest.cc
index cb077262dbe..a34c41b8155 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_animation_unittest.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_animation_unittest.cc
@@ -4,6 +4,7 @@
#include "content/browser/web_contents/aura/overscroll_window_animation.h"
+#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
@@ -93,7 +94,7 @@ class OverscrollWindowAnimationTest
scoped_ptr<aura::Window> window(
CreateNormalWindow(++last_window_id_, root_window(), nullptr));
window->SetBounds(bounds);
- return window.Pass();
+ return window;
}
return nullptr;
}
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h b/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h
index db590f7ba7d..1abde586930 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_WEB_CONTENTS_AURA_OVERSCROLL_WINDOW_DELEGATE_H_
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
#include "content/browser/web_contents/web_contents_impl.h"
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc b/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc
index 13382a8656f..6b1b54662c3 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc
@@ -4,6 +4,7 @@
#include "content/browser/web_contents/aura/overscroll_window_delegate.h"
+#include "base/macros.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
#include "content/public/browser/overscroll_configuration.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -54,11 +55,9 @@ class OverscrollWindowDelegateTest : public aura::test::AuraTestBase,
OverscrollMode current_mode() { return current_mode_; }
- const float touch_start_threshold() {
- return touch_start_threshold_;
- }
+ float touch_start_threshold() { return touch_start_threshold_; }
- const float touch_complete_threshold() {
+ float touch_complete_threshold() {
return kTestWindowWidth * touch_complete_threshold_;
}
diff --git a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc
index 74be3d04f65..067a1472258 100644
--- a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc
+++ b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc
@@ -5,6 +5,7 @@
#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
#include "base/bind.h"
+#include "base/macros.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
diff --git a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h
index c9a0b7ed7d1..3f477591380 100644
--- a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h
+++ b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_WEB_CONTENTS_AURA_SHADOW_LAYER_DELEGATE_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "ui/compositor/layer_delegate.h"
diff --git a/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc b/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc
index efca34f28fe..44a184c2039 100644
--- a/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc
+++ b/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
@@ -82,12 +83,12 @@ class OpenedByDOMTest : public ContentBrowserTest {
// Tests that window.close() does not work on a normal window that has navigated
// a few times.
IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, NormalWindow) {
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
// window.close is allowed if the window was opened by DOM OR the back/forward
// list has only one element. Navigate a bit so the second condition is false.
- GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
- GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
+ GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
+ GURL url2 = embedded_test_server()->GetURL("/site_isolation/blank.html?2");
NavigateToURL(shell(), url1);
NavigateToURL(shell(), url2);
@@ -99,11 +100,11 @@ IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, NormalWindow) {
// Tests that window.close() works in a popup window that has navigated a few
// times.
IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, Popup) {
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
- GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
- GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
- GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
+ GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
+ GURL url2 = embedded_test_server()->GetURL("/site_isolation/blank.html?2");
+ GURL url3 = embedded_test_server()->GetURL("/site_isolation/blank.html?3");
NavigateToURL(shell(), url1);
Shell* popup = OpenWindowFromJavaScript(shell(), url2);
@@ -115,16 +116,16 @@ IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, Popup) {
// times and swapped processes.
IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, CrossProcessPopup) {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
- GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
+ GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1");
- GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
+ GURL url2 = embedded_test_server()->GetURL("/site_isolation/blank.html?2");
GURL::Replacements replace_host;
replace_host.SetHostStr("foo.com");
url2 = url2.ReplaceComponents(replace_host);
- GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
+ GURL url3 = embedded_test_server()->GetURL("/site_isolation/blank.html?3");
url3 = url3.ReplaceComponents(replace_host);
NavigateToURL(shell(), url1);
diff --git a/chromium/content/browser/web_contents/web_contents_android.cc b/chromium/content/browser/web_contents/web_contents_android.cc
index ff58da2f893..f772161f6ee 100644
--- a/chromium/content/browser/web_contents/web_contents_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/web_contents/web_contents_android.h"
+#include <stdint.h>
+
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
@@ -18,7 +20,7 @@
#include "content/browser/android/interstitial_page_delegate_android.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/media/android/browser_media_player_manager.h"
-#include "content/browser/media/media_web_contents_observer.h"
+#include "content/browser/media/android/media_web_contents_observer_android.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/devtools_messages.h"
@@ -28,18 +30,22 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/message_port_provider.h"
+#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "jni/WebContentsImpl_jni.h"
#include "net/android/network_library.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/gfx/android/device_display_info.h"
+#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/geometry/rect.h"
using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF8ToJavaString;
using base::android::ConvertUTF16ToJavaString;
+using base::android::JavaParamRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ToJavaIntArray;
@@ -62,9 +68,35 @@ void JavaScriptResultCallback(const ScopedJavaGlobalRef<jobject>& callback,
env, j_json.obj(), callback.obj());
}
-ScopedJavaLocalRef<jobject> WalkAXTreeDepthFirst(JNIEnv* env,
- BrowserAccessibilityAndroid* node, float scale_factor,
- float y_offset, float x_scroll) {
+struct AccessibilitySnapshotParams {
+ AccessibilitySnapshotParams(float scale,
+ float horizontal_scroll,
+ float vertical_offset)
+ : scale_factor(scale),
+ x_scroll(horizontal_scroll),
+ y_offset(vertical_offset),
+ has_tree_data(false),
+ should_select_leaf_nodes(false) {}
+
+ float scale_factor;
+ float x_scroll;
+ float y_offset;
+ bool has_tree_data;
+ // The current text selection within this tree, if any, expressed as the
+ // node ID and character offset of the anchor (selection start) and focus
+ // (selection end).
+ int32_t sel_anchor_object_id;
+ int32_t sel_anchor_offset;
+ int32_t sel_focus_object_id;
+ int32_t sel_focus_offset;
+ // if the flag is true, mark the leaf node as selected.
+ bool should_select_leaf_nodes;
+};
+
+ScopedJavaLocalRef<jobject> WalkAXTreeDepthFirst(
+ JNIEnv* env,
+ BrowserAccessibilityAndroid* node,
+ AccessibilitySnapshotParams* params) {
ScopedJavaLocalRef<jstring> j_text =
ConvertUTF16ToJavaString(env, node->GetText());
ScopedJavaLocalRef<jstring> j_class =
@@ -77,38 +109,56 @@ ScopedJavaLocalRef<jobject> WalkAXTreeDepthFirst(JNIEnv* env,
int color = 0;
int bgcolor = 0;
int text_style = 0;
+
if (node->HasFloatAttribute(ui::AX_ATTR_FONT_SIZE)) {
color = node->GetIntAttribute(ui::AX_ATTR_COLOR);
bgcolor = node->GetIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR);
size = node->GetFloatAttribute(ui::AX_ATTR_FONT_SIZE);
text_style = node->GetIntAttribute(ui::AX_ATTR_TEXT_STYLE);
}
+ float scale_factor = params->scale_factor;
ScopedJavaLocalRef<jobject> j_node =
- Java_WebContentsImpl_createAccessibilitySnapshotNode(env,
- scale_factor * location.x() - x_scroll,
- scale_factor * location.y() + y_offset,
+ Java_WebContentsImpl_createAccessibilitySnapshotNode(
+ env, scale_factor * location.x() - params->x_scroll,
+ scale_factor * location.y() + params->y_offset,
scale_factor * node->GetScrollX(), scale_factor * node->GetScrollY(),
scale_factor * location.width(), scale_factor * location.height(),
j_text.obj(), color, bgcolor, scale_factor * size, text_style,
j_class.obj());
- for(uint32 i = 0; i < node->PlatformChildCount(); i++) {
+ if (params->has_tree_data && node->PlatformIsLeaf()) {
+ int start_selection = 0;
+ int end_selection = 0;
+ if (params->sel_anchor_object_id == node->GetId()) {
+ start_selection = params->sel_anchor_offset;
+ params->should_select_leaf_nodes = true;
+ }
+ if (params->should_select_leaf_nodes)
+ end_selection = node->GetText().length();
+
+ if (params->sel_focus_object_id == node->GetId()) {
+ end_selection = params->sel_focus_offset;
+ params->should_select_leaf_nodes = false;
+ }
+ if (end_selection > 0)
+ Java_WebContentsImpl_setAccessibilitySnapshotSelection(
+ env, j_node.obj(), start_selection, end_selection);
+ }
+
+ for (uint32_t i = 0; i < node->PlatformChildCount(); i++) {
BrowserAccessibilityAndroid* child =
static_cast<BrowserAccessibilityAndroid*>(
node->PlatformGetChild(i));
- Java_WebContentsImpl_addAccessibilityNodeAsChild(env,
- j_node.obj(), WalkAXTreeDepthFirst(env, child, scale_factor, y_offset,
- x_scroll).obj());
+ Java_WebContentsImpl_addAccessibilityNodeAsChild(
+ env, j_node.obj(), WalkAXTreeDepthFirst(env, child, params).obj());
}
return j_node;
}
// Walks over the AXTreeUpdate and creates a light weight snapshot.
void AXTreeSnapshotCallback(const ScopedJavaGlobalRef<jobject>& callback,
- float scale_factor,
- float y_offset,
- float x_scroll,
- const ui::AXTreeUpdate<ui::AXNodeData>& result) {
+ AccessibilitySnapshotParams* params,
+ const ui::AXTreeUpdate& result) {
JNIEnv* env = base::android::AttachCurrentThread();
if (result.nodes.empty()) {
Java_WebContentsImpl_onAccessibilitySnapshot(env, nullptr, callback.obj());
@@ -120,8 +170,14 @@ void AXTreeSnapshotCallback(const ScopedJavaGlobalRef<jobject>& callback,
manager->set_prune_tree_for_screen_reader(false);
BrowserAccessibilityAndroid* root =
static_cast<BrowserAccessibilityAndroid*>(manager->GetRoot());
- ScopedJavaLocalRef<jobject> j_root =
- WalkAXTreeDepthFirst(env, root, scale_factor, y_offset, x_scroll);
+ if (result.has_tree_data) {
+ params->has_tree_data = true;
+ params->sel_anchor_object_id = result.tree_data.sel_anchor_object_id;
+ params->sel_anchor_offset = result.tree_data.sel_anchor_offset;
+ params->sel_focus_object_id = result.tree_data.sel_focus_object_id;
+ params->sel_focus_offset = result.tree_data.sel_focus_offset;
+ }
+ ScopedJavaLocalRef<jobject> j_root = WalkAXTreeDepthFirst(env, root, params);
Java_WebContentsImpl_onAccessibilitySnapshot(
env, j_root.obj(), callback.obj());
}
@@ -129,9 +185,8 @@ void AXTreeSnapshotCallback(const ScopedJavaGlobalRef<jobject>& callback,
void ReleaseAllMediaPlayers(WebContents* web_contents,
RenderFrameHost* render_frame_host) {
BrowserMediaPlayerManager* manager =
- static_cast<WebContentsImpl*>(web_contents)->
- media_web_contents_observer()->GetMediaPlayerManager(
- render_frame_host);
+ MediaWebContentsObserverAndroid::FromWebContents(web_contents)
+ ->GetMediaPlayerManager(render_frame_host);
if (manager)
manager->ReleaseAllMediaPlayers();
}
@@ -197,6 +252,7 @@ bool WebContentsAndroid::Register(JNIEnv* env) {
WebContentsAndroid::WebContentsAndroid(WebContents* web_contents)
: web_contents_(web_contents),
navigation_controller_(&(web_contents->GetController())),
+ synchronous_compositor_client_(nullptr),
weak_factory_(this) {
g_allocated_web_contents_androids.Get().insert(this);
JNIEnv* env = AttachCurrentThread();
@@ -226,52 +282,65 @@ WebContentsAndroid::GetJavaObject() {
}
ScopedJavaLocalRef<jstring> WebContentsAndroid::GetTitle(
- JNIEnv* env, jobject obj) const {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) const {
return base::android::ConvertUTF16ToJavaString(env,
web_contents_->GetTitle());
}
ScopedJavaLocalRef<jstring> WebContentsAndroid::GetVisibleURL(
- JNIEnv* env, jobject obj) const {
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) const {
return base::android::ConvertUTF8ToJavaString(
env, web_contents_->GetVisibleURL().spec());
}
-bool WebContentsAndroid::IsLoading(JNIEnv* env, jobject obj) const {
+bool WebContentsAndroid::IsLoading(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) const {
return web_contents_->IsLoading();
}
-bool WebContentsAndroid::IsLoadingToDifferentDocument(JNIEnv* env,
- jobject obj) const {
+bool WebContentsAndroid::IsLoadingToDifferentDocument(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) const {
return web_contents_->IsLoadingToDifferentDocument();
}
-void WebContentsAndroid::Stop(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::Stop(JNIEnv* env, const JavaParamRef<jobject>& obj) {
web_contents_->Stop();
}
-void WebContentsAndroid::Cut(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::Cut(JNIEnv* env, const JavaParamRef<jobject>& obj) {
web_contents_->Cut();
}
-void WebContentsAndroid::Copy(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::Copy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
web_contents_->Copy();
}
-void WebContentsAndroid::Paste(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::Paste(JNIEnv* env, const JavaParamRef<jobject>& obj) {
web_contents_->Paste();
}
-void WebContentsAndroid::SelectAll(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::Replace(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& jstr) {
+ web_contents_->Replace(base::android::ConvertJavaStringToUTF16(env, jstr));
+}
+
+void WebContentsAndroid::SelectAll(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
web_contents_->SelectAll();
}
-void WebContentsAndroid::Unselect(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::Unselect(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
web_contents_->Unselect();
}
-void WebContentsAndroid::InsertCSS(
- JNIEnv* env, jobject jobj, jstring jcss) {
+void WebContentsAndroid::InsertCSS(JNIEnv* env,
+ const JavaParamRef<jobject>& jobj,
+ const JavaParamRef<jstring>& jcss) {
web_contents_->InsertCSS(base::android::ConvertJavaStringToUTF8(env, jcss));
}
@@ -283,60 +352,65 @@ RenderWidgetHostViewAndroid*
rwhv = web_contents_->GetInterstitialPage()
->GetMainFrame()
->GetRenderViewHost()
+ ->GetWidget()
->GetView();
}
return static_cast<RenderWidgetHostViewAndroid*>(rwhv);
}
-jint WebContentsAndroid::GetBackgroundColor(JNIEnv* env, jobject obj) {
+jint WebContentsAndroid::GetBackgroundColor(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
if (!rwhva)
return SK_ColorWHITE;
return rwhva->GetCachedBackgroundColor();
}
-ScopedJavaLocalRef<jstring> WebContentsAndroid::GetURL(JNIEnv* env,
- jobject obj) const {
+ScopedJavaLocalRef<jstring> WebContentsAndroid::GetURL(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) const {
return ConvertUTF8ToJavaString(env, web_contents_->GetURL().spec());
}
ScopedJavaLocalRef<jstring> WebContentsAndroid::GetLastCommittedURL(
JNIEnv* env,
- jobject) const {
+ const JavaParamRef<jobject>&) const {
return ConvertUTF8ToJavaString(env,
web_contents_->GetLastCommittedURL().spec());
}
-
-jboolean WebContentsAndroid::IsIncognito(JNIEnv* env, jobject obj) {
+jboolean WebContentsAndroid::IsIncognito(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return web_contents_->GetBrowserContext()->IsOffTheRecord();
}
-void WebContentsAndroid::ResumeLoadingCreatedWebContents(JNIEnv* env,
- jobject obj) {
+void WebContentsAndroid::ResumeLoadingCreatedWebContents(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
web_contents_->ResumeLoadingCreatedWebContents();
}
-void WebContentsAndroid::OnHide(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::OnHide(JNIEnv* env, const JavaParamRef<jobject>& obj) {
web_contents_->WasHidden();
}
-void WebContentsAndroid::OnShow(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::OnShow(JNIEnv* env, const JavaParamRef<jobject>& obj) {
web_contents_->WasShown();
}
-void WebContentsAndroid::ReleaseMediaPlayers(JNIEnv* env, jobject jobj) {
+void WebContentsAndroid::ReleaseMediaPlayers(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& jobj) {
#if defined(ENABLE_BROWSER_CDMS)
web_contents_->ForEachFrame(
base::Bind(&ReleaseAllMediaPlayers, base::Unretained(web_contents_)));
#endif // defined(ENABLE_BROWSER_CDMS)
}
-void WebContentsAndroid::ShowInterstitialPage(
- JNIEnv* env,
- jobject obj,
- jstring jurl,
- jlong delegate_ptr) {
+void WebContentsAndroid::ShowInterstitialPage(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& jurl,
+ jlong delegate_ptr) {
GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
InterstitialPageDelegateAndroid* delegate =
reinterpret_cast<InterstitialPageDelegateAndroid*>(delegate_ptr);
@@ -346,25 +420,33 @@ void WebContentsAndroid::ShowInterstitialPage(
interstitial->Show();
}
-jboolean WebContentsAndroid::IsShowingInterstitialPage(JNIEnv* env,
- jobject obj) {
+jboolean WebContentsAndroid::IsShowingInterstitialPage(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return web_contents_->ShowingInterstitialPage();
}
+jboolean WebContentsAndroid::FocusLocationBarByDefault(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
+ return web_contents_->FocusLocationBarByDefault();
+}
+
jboolean WebContentsAndroid::IsRenderWidgetHostViewReady(
JNIEnv* env,
- jobject obj) {
+ const JavaParamRef<jobject>& obj) {
RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
return view && view->HasValidFrame();
}
-void WebContentsAndroid::ExitFullscreen(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::ExitFullscreen(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
web_contents_->ExitFullscreen();
}
void WebContentsAndroid::UpdateTopControlsState(
JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
bool enable_hiding,
bool enable_showing,
bool animate) {
@@ -377,7 +459,8 @@ void WebContentsAndroid::UpdateTopControlsState(
animate));
}
-void WebContentsAndroid::ShowImeIfNeeded(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::ShowImeIfNeeded(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
RenderViewHost* host = web_contents_->GetRenderViewHost();
if (!host)
return;
@@ -386,7 +469,7 @@ void WebContentsAndroid::ShowImeIfNeeded(JNIEnv* env, jobject obj) {
void WebContentsAndroid::ScrollFocusedEditableNodeIntoView(
JNIEnv* env,
- jobject obj) {
+ const JavaParamRef<jobject>& obj) {
RenderViewHost* host = web_contents_->GetRenderViewHost();
if (!host)
return;
@@ -394,24 +477,28 @@ void WebContentsAndroid::ScrollFocusedEditableNodeIntoView(
host->GetRoutingID(), gfx::Rect()));
}
-void WebContentsAndroid::SelectWordAroundCaret(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::SelectWordAroundCaret(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
RenderViewHost* host = web_contents_->GetRenderViewHost();
if (!host)
return;
host->SelectWordAroundCaret();
}
-void WebContentsAndroid::AdjustSelectionByCharacterOffset(JNIEnv* env,
- jobject obj,
- jint start_adjust,
- jint end_adjust) {
+void WebContentsAndroid::AdjustSelectionByCharacterOffset(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint start_adjust,
+ jint end_adjust) {
web_contents_->AdjustSelectionByCharacterOffset(start_adjust, end_adjust);
}
-void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
- jobject obj,
- jstring script,
- jobject callback) {
+void WebContentsAndroid::EvaluateJavaScript(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& script,
+ const JavaParamRef<jobject>& callback) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
@@ -441,10 +528,11 @@ void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
ConvertJavaStringToUTF16(env, script), js_callback);
}
-void WebContentsAndroid::EvaluateJavaScriptForTests(JNIEnv* env,
- jobject obj,
- jstring script,
- jobject callback) {
+void WebContentsAndroid::EvaluateJavaScriptForTests(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& script,
+ const JavaParamRef<jobject>& callback) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
@@ -474,10 +562,11 @@ void WebContentsAndroid::EvaluateJavaScriptForTests(JNIEnv* env,
ConvertJavaStringToUTF16(env, script), js_callback);
}
-void WebContentsAndroid::AddMessageToDevToolsConsole(JNIEnv* env,
- jobject jobj,
- jint level,
- jstring message) {
+void WebContentsAndroid::AddMessageToDevToolsConsole(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& jobj,
+ jint level,
+ const JavaParamRef<jstring>& message) {
DCHECK_GE(level, 0);
DCHECK_LE(level, CONSOLE_MESSAGE_LEVEL_LAST);
@@ -486,11 +575,12 @@ void WebContentsAndroid::AddMessageToDevToolsConsole(JNIEnv* env,
ConvertJavaStringToUTF8(env, message));
}
-void WebContentsAndroid::SendMessageToFrame(JNIEnv* env,
- jobject obj,
- jstring frame_name,
- jstring message,
- jstring target_origin) {
+void WebContentsAndroid::SendMessageToFrame(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& frame_name,
+ const JavaParamRef<jstring>& message,
+ const JavaParamRef<jstring>& target_origin) {
base::string16 source_origin;
base::string16 j_target_origin(ConvertJavaStringToUTF16(env, target_origin));
base::string16 j_message(ConvertJavaStringToUTF16(env, message));
@@ -501,20 +591,22 @@ void WebContentsAndroid::SendMessageToFrame(JNIEnv* env,
jboolean WebContentsAndroid::HasAccessedInitialDocument(
JNIEnv* env,
- jobject jobj) {
+ const JavaParamRef<jobject>& jobj) {
return static_cast<WebContentsImpl*>(web_contents_)->
HasAccessedInitialDocument();
}
-jint WebContentsAndroid::GetThemeColor(JNIEnv* env, jobject obj) {
+jint WebContentsAndroid::GetThemeColor(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
return web_contents_->GetThemeColor();
}
-void WebContentsAndroid::RequestAccessibilitySnapshot(JNIEnv* env,
- jobject obj,
- jobject callback,
- jfloat y_offset,
- jfloat x_scroll) {
+void WebContentsAndroid::RequestAccessibilitySnapshot(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& callback,
+ jfloat y_offset,
+ jfloat x_scroll) {
// Secure the Java callback in a scoped object and give ownership of it to the
// base::Callback.
ScopedJavaGlobalRef<jobject> j_callback;
@@ -522,29 +614,88 @@ void WebContentsAndroid::RequestAccessibilitySnapshot(JNIEnv* env,
gfx::DeviceDisplayInfo device_info;
ContentViewCoreImpl* contentViewCore =
ContentViewCoreImpl::FromWebContents(web_contents_);
+
+ AccessibilitySnapshotParams* params = new AccessibilitySnapshotParams(
+ contentViewCore->GetScaleFactor(), y_offset, x_scroll);
WebContentsImpl::AXTreeSnapshotCallback snapshot_callback =
- base::Bind(&AXTreeSnapshotCallback, j_callback,
- contentViewCore->GetScaleFactor(), y_offset, x_scroll);
+ base::Bind(&AXTreeSnapshotCallback, j_callback, base::Owned(params));
static_cast<WebContentsImpl*>(web_contents_)->RequestAXTreeSnapshot(
snapshot_callback);
}
-void WebContentsAndroid::ResumeMediaSession(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::ResumeMediaSession(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
web_contents_->ResumeMediaSession();
}
-void WebContentsAndroid::SuspendMediaSession(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::SuspendMediaSession(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
web_contents_->SuspendMediaSession();
}
-void WebContentsAndroid::StopMediaSession(JNIEnv* env, jobject obj) {
+void WebContentsAndroid::StopMediaSession(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
web_contents_->StopMediaSession();
}
-ScopedJavaLocalRef<jstring> WebContentsAndroid::GetEncoding(
- JNIEnv* env, jobject obj) const {
+ScopedJavaLocalRef<jstring> WebContentsAndroid::GetEncoding(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) const {
return base::android::ConvertUTF8ToJavaString(env,
web_contents_->GetEncoding());
}
+void WebContentsAndroid::GetContentBitmap(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& jcallback,
+ const JavaParamRef<jobject>& color_type,
+ jfloat scale,
+ jfloat x,
+ jfloat y,
+ jfloat width,
+ jfloat height) {
+ RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
+ const ReadbackRequestCallback result_callback =
+ base::Bind(&WebContentsAndroid::OnFinishGetContentBitmap,
+ weak_factory_.GetWeakPtr(),
+ base::Owned(new ScopedJavaGlobalRef<jobject>(env, obj)),
+ base::Owned(new ScopedJavaGlobalRef<jobject>(env, jcallback)));
+ SkColorType pref_color_type = gfx::ConvertToSkiaColorType(color_type.obj());
+ if (!view || pref_color_type == kUnknown_SkColorType) {
+ result_callback.Run(SkBitmap(), READBACK_FAILED);
+ return;
+ }
+ if (!view->IsSurfaceAvailableForCopy()) {
+ result_callback.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE);
+ return;
+ }
+ view->GetScaledContentBitmap(scale,
+ pref_color_type,
+ gfx::Rect(x, y, width, height),
+ result_callback);
+}
+
+void WebContentsAndroid::OnContextMenuClosed(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
+ static_cast<WebContentsImpl*>(web_contents_)
+ ->NotifyContextMenuClosed(CustomContextMenuContext());
+}
+
+void WebContentsAndroid::OnFinishGetContentBitmap(
+ ScopedJavaGlobalRef<jobject>* obj,
+ ScopedJavaGlobalRef<jobject>* callback,
+ const SkBitmap& bitmap,
+ ReadbackResponse response) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> java_bitmap;
+ if (response == READBACK_SUCCESS)
+ java_bitmap = gfx::ConvertToJavaBitmap(&bitmap);
+ Java_WebContentsImpl_onGetContentBitmapFinished(env,
+ obj->obj(),
+ callback->obj(),
+ java_bitmap.obj(),
+ response);
+}
+
} // namespace content
diff --git a/chromium/content/browser/web_contents/web_contents_android.h b/chromium/content/browser/web_contents/web_contents_android.h
index 5088d97b6de..9453d52d020 100644
--- a/chromium/content/browser/web_contents/web_contents_android.h
+++ b/chromium/content/browser/web_contents/web_contents_android.h
@@ -7,9 +7,10 @@
#include <jni.h>
+#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
@@ -19,6 +20,7 @@
namespace content {
+class SynchronousCompositorClient;
class WebContents;
// Android wrapper around WebContents that provides safer passage from java and
@@ -37,94 +39,165 @@ class CONTENT_EXPORT WebContentsAndroid
base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
// Methods called from Java
- base::android::ScopedJavaLocalRef<jstring> GetTitle(JNIEnv* env,
- jobject obj) const;
- base::android::ScopedJavaLocalRef<jstring> GetVisibleURL(JNIEnv* env,
- jobject obj) const;
-
- bool IsLoading(JNIEnv* env, jobject obj) const;
- bool IsLoadingToDifferentDocument(JNIEnv* env, jobject obj) const;
-
- void Stop(JNIEnv* env, jobject obj);
- void Cut(JNIEnv* env, jobject obj);
- void Copy(JNIEnv* env, jobject obj);
- void Paste(JNIEnv* env, jobject obj);
- void SelectAll(JNIEnv* env, jobject obj);
- void Unselect(JNIEnv* env, jobject obj);
- jint GetBackgroundColor(JNIEnv* env, jobject obj);
- base::android::ScopedJavaLocalRef<jstring> GetURL(JNIEnv* env, jobject) const;
- base::android::ScopedJavaLocalRef<jstring> GetLastCommittedURL(JNIEnv* env,
- jobject) const;
- jboolean IsIncognito(JNIEnv* env, jobject obj);
-
- void ResumeLoadingCreatedWebContents(JNIEnv* env, jobject obj);
-
- void OnHide(JNIEnv* env, jobject obj);
- void OnShow(JNIEnv* env, jobject obj);
- void ReleaseMediaPlayers(JNIEnv* env, jobject jobj);
-
- void ShowInterstitialPage(
- JNIEnv* env, jobject obj, jstring jurl, jlong delegate_ptr);
- jboolean IsShowingInterstitialPage(JNIEnv* env, jobject obj);
- jboolean IsRenderWidgetHostViewReady(JNIEnv* env, jobject obj);
- void ExitFullscreen(JNIEnv* env, jobject obj);
- void UpdateTopControlsState(
- JNIEnv* env,
- jobject obj,
- bool enable_hiding,
- bool enable_showing,
- bool animate);
- void ShowImeIfNeeded(JNIEnv* env, jobject obj);
- void ScrollFocusedEditableNodeIntoView(JNIEnv* env, jobject obj);
- void SelectWordAroundCaret(JNIEnv* env, jobject obj);
- void AdjustSelectionByCharacterOffset(JNIEnv* env,
- jobject obj,
- jint start_adjust,
- jint end_adjust);
- void InsertCSS(JNIEnv* env, jobject jobj, jstring jcss);
+ base::android::ScopedJavaLocalRef<jstring> GetTitle(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj) const;
+ base::android::ScopedJavaLocalRef<jstring> GetVisibleURL(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj) const;
+
+ bool IsLoading(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj) const;
+ bool IsLoadingToDifferentDocument(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj) const;
+
+ void Stop(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void Cut(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void Copy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void Paste(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void Replace(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& jstr);
+ void SelectAll(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void Unselect(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ jint GetBackgroundColor(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ base::android::ScopedJavaLocalRef<jstring> GetURL(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>&) const;
+ base::android::ScopedJavaLocalRef<jstring> GetLastCommittedURL(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>&) const;
+ jboolean IsIncognito(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+
+ void ResumeLoadingCreatedWebContents(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+
+ void OnHide(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void OnShow(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+ void ReleaseMediaPlayers(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj);
+
+ void ShowInterstitialPage(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& jurl,
+ jlong delegate_ptr);
+ jboolean IsShowingInterstitialPage(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ jboolean FocusLocationBarByDefault(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ jboolean IsRenderWidgetHostViewReady(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void ExitFullscreen(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void UpdateTopControlsState(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ bool enable_hiding,
+ bool enable_showing,
+ bool animate);
+ void ShowImeIfNeeded(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void ScrollFocusedEditableNodeIntoView(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void SelectWordAroundCaret(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void AdjustSelectionByCharacterOffset(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint start_adjust,
+ jint end_adjust);
+ void InsertCSS(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj,
+ const base::android::JavaParamRef<jstring>& jcss);
void EvaluateJavaScript(JNIEnv* env,
- jobject obj,
- jstring script,
- jobject callback);
- void EvaluateJavaScriptForTests(JNIEnv* env,
- jobject obj,
- jstring script,
- jobject callback);
-
- void AddMessageToDevToolsConsole(JNIEnv* env,
- jobject jobj,
- jint level,
- jstring message);
-
- void SendMessageToFrame(JNIEnv* env,
- jobject obj,
- jstring frame_name,
- jstring message,
- jstring target_origin);
-
- jboolean HasAccessedInitialDocument(JNIEnv* env, jobject jobj);
-
- jint GetThemeColor(JNIEnv* env, jobject obj);
-
- void RequestAccessibilitySnapshot(JNIEnv* env,
- jobject obj,
- jobject callback,
- jfloat y_offset,
- jfloat x_scroll);
-
- void ResumeMediaSession(JNIEnv* env, jobject obj);
- void SuspendMediaSession(JNIEnv* env, jobject obj);
- void StopMediaSession(JNIEnv* env, jobject obj);
-
- base::android::ScopedJavaLocalRef<jstring> GetEncoding(JNIEnv* env,
- jobject obj) const;
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& script,
+ const base::android::JavaParamRef<jobject>& callback);
+ void EvaluateJavaScriptForTests(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& script,
+ const base::android::JavaParamRef<jobject>& callback);
+
+ void AddMessageToDevToolsConsole(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj,
+ jint level,
+ const base::android::JavaParamRef<jstring>& message);
+
+ void SendMessageToFrame(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& frame_name,
+ const base::android::JavaParamRef<jstring>& message,
+ const base::android::JavaParamRef<jstring>& target_origin);
+
+ jboolean HasAccessedInitialDocument(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj);
+
+ jint GetThemeColor(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+
+ void RequestAccessibilitySnapshot(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& callback,
+ jfloat y_offset,
+ jfloat x_scroll);
+
+ void ResumeMediaSession(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void SuspendMediaSession(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ void StopMediaSession(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+
+ base::android::ScopedJavaLocalRef<jstring> GetEncoding(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj) const;
+
+ // Relay the access from Java layer to GetScaledContentBitmap through JNI.
+ void GetContentBitmap(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& jcallback,
+ const base::android::JavaParamRef<jobject>& color_type,
+ jfloat scale,
+ jfloat x,
+ jfloat y,
+ jfloat width,
+ jfloat height);
+
+ void OnContextMenuClosed(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+
+ void set_synchronous_compositor_client(SynchronousCompositorClient* client) {
+ synchronous_compositor_client_ = client;
+ }
+ SynchronousCompositorClient* synchronous_compositor_client() const {
+ return synchronous_compositor_client_;
+ }
private:
RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid();
+ void OnFinishGetContentBitmap(
+ base::android::ScopedJavaGlobalRef<jobject>* obj,
+ base::android::ScopedJavaGlobalRef<jobject>* callback,
+ const SkBitmap& bitmap,
+ ReadbackResponse response);
+
WebContents* web_contents_;
NavigationControllerAndroid navigation_controller_;
base::android::ScopedJavaGlobalRef<jobject> obj_;
+ SynchronousCompositorClient* synchronous_compositor_client_;
base::WeakPtrFactory<WebContentsAndroid> weak_factory_;
diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc
index 93ab4387928..233c1e09382 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl.cc
@@ -4,12 +4,16 @@
#include "content/browser/web_contents/web_contents_impl.h"
+#include <stddef.h>
+
+#include <cmath>
#include <utility>
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/process/process.h"
#include "base/profiler/scoped_tracker.h"
@@ -21,6 +25,7 @@
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "components/mime_util/mime_util.h"
#include "components/url_formatter/url_formatter.h"
#include "content/browser/accessibility/accessibility_mode_helper.h"
@@ -47,9 +52,9 @@
#include "content/browser/manifest/manifest_manager_host.h"
#include "content/browser/media/audio_stream_monitor.h"
#include "content/browser/media/capture/web_contents_audio_muter.h"
+#include "content/browser/media/media_web_contents_observer.h"
#include "content/browser/message_port_message_filter.h"
#include "content/browser/plugin_content_origin_whitelist.h"
-#include "content/browser/power_save_blocker_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -58,6 +63,7 @@
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h"
#include "content/browser/site_instance_impl.h"
+#include "content/browser/wake_lock/wake_lock_service_context.h"
#include "content/browser/web_contents/web_contents_view_guest.h"
#include "content/browser/webui/generic_handler.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
@@ -90,9 +96,9 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_plugin_guest_mode.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
@@ -114,21 +120,27 @@
#include "ui/gfx/screen.h"
#include "ui/gl/gl_switches.h"
-#if defined(ENABLE_BROWSER_CDMS)
-#include "content/browser/media/media_web_contents_observer.h"
-#endif
-
#if defined(OS_ANDROID)
#include "content/browser/android/content_video_view.h"
-#include "content/browser/android/date_time_chooser_android.h"
#include "content/browser/media/android/media_session.h"
+#include "content/browser/media/android/media_web_contents_observer_android.h"
+#endif // OS_ANDROID
+
+#if defined(OS_ANDROID) && !defined(USE_AURA)
+#include "content/browser/android/date_time_chooser_android.h"
#include "content/browser/web_contents/web_contents_android.h"
-#endif
+#endif // OS_ANDROID && !USE_AURA
#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
#endif
+#if defined(MOJO_SHELL_CLIENT)
+#include "content/browser/web_contents/web_contents_view_mus.h"
+#include "content/public/common/mojo_shell_connection.h"
+#include "ui/aura/mus/mus_util.h"
+#endif
+
namespace content {
namespace {
@@ -167,22 +179,6 @@ void NotifyCacheOnIO(
cache->OnExternalCacheHit(url, http_method);
}
-// Helper function for retrieving all the sites in a frame tree.
-bool CollectSites(BrowserContext* context,
- std::set<GURL>* sites,
- FrameTreeNode* node) {
- // Record about:blank as a real (process-having) site only if the SiteInstance
- // is unassigned. Do not otherwise depend on the siteinstance's site URL,
- // since its value reflects the current process model, and this function
- // should behave identically across all process models.
- if (node->current_url() == GURL(url::kAboutBlankURL) &&
- node->current_frame_host()->GetSiteInstance()->HasSite()) {
- return true;
- }
- sites->insert(SiteInstance::GetSiteForURL(context, node->current_url()));
- return true;
-}
-
bool FindMatchingProcess(int render_process_id,
bool* did_match_process,
FrameTreeNode* node) {
@@ -210,7 +206,10 @@ bool ForEachPendingFrameInternal(
return true;
}
-void SendToAllFramesInternal(IPC::Message* message, RenderFrameHost* rfh) {
+void SendToAllFramesInternal(int* number_of_messages,
+ IPC::Message* message,
+ RenderFrameHost* rfh) {
+ *number_of_messages = *number_of_messages + 1;
IPC::Message* message_copy = new IPC::Message(*message);
message_copy->set_routing_id(rfh->GetRoutingID());
rfh->Send(message_copy);
@@ -279,15 +278,16 @@ void WebContentsImpl::FriendZone::RemoveCreatedCallbackForTesting(
}
}
-WebContents* WebContents::FromRenderViewHost(const RenderViewHost* rvh) {
+WebContents* WebContents::FromRenderViewHost(RenderViewHost* rvh) {
+ if (!rvh)
+ return nullptr;
return rvh->GetDelegate()->GetAsWebContents();
}
WebContents* WebContents::FromRenderFrameHost(RenderFrameHost* rfh) {
- RenderFrameHostImpl* rfh_impl = static_cast<RenderFrameHostImpl*>(rfh);
- if (!rfh_impl)
- return NULL;
- return rfh_impl->delegate()->GetAsWebContents();
+ if (!rfh)
+ return nullptr;
+ return static_cast<RenderFrameHostImpl*>(rfh)->delegate()->GetAsWebContents();
}
// WebContentsImpl::DestructionObserver ----------------------------------------
@@ -328,7 +328,7 @@ WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() {
WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode()
: outer_web_contents_(nullptr),
outer_contents_frame_tree_node_id_(
- FrameTreeNode::kFrameTreeNodeInvalidID) {
+ FrameTreeNode::kFrameTreeNodeInvalidId) {
}
WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
@@ -401,6 +401,7 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
closed_by_user_gesture_(false),
minimum_zoom_percent_(static_cast<int>(kMinimumZoomFactor * 100)),
maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)),
+ zoom_scroll_remainder_(0),
render_view_message_source_(NULL),
render_frame_message_source_(NULL),
fullscreen_widget_routing_id_(MSG_ROUTING_NONE),
@@ -413,13 +414,17 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()),
audio_stream_monitor_(this),
virtual_keyboard_requested_(false),
+ page_scale_factor_is_one_(true),
loading_weak_factory_(this) {
frame_tree_.SetFrameRemoveListener(
base::Bind(&WebContentsImpl::OnFrameRemoved,
base::Unretained(this)));
-#if defined(ENABLE_BROWSER_CDMS)
+#if defined(OS_ANDROID)
+ media_web_contents_observer_.reset(new MediaWebContentsObserverAndroid(this));
+#else
media_web_contents_observer_.reset(new MediaWebContentsObserver(this));
#endif
+ wake_lock_service_context_.reset(new WakeLockServiceContext(this));
}
WebContentsImpl::~WebContentsImpl() {
@@ -432,7 +437,8 @@ WebContentsImpl::~WebContentsImpl() {
frame_tree_.ForEach(
base::Bind(&RenderFrameHostManager::ClearRFHsPendingShutdown));
- ClearAllPowerSaveBlockers();
+ // Destroy all WebUI instances.
+ frame_tree_.ForEach(base::Bind(&RenderFrameHostManager::ClearWebUIInstances));
for (std::set<RenderWidgetHostImpl*>::iterator iter =
created_widgets_.begin(); iter != created_widgets_.end(); ++iter) {
@@ -476,8 +482,7 @@ WebContentsImpl::~WebContentsImpl() {
scoped_ptr<NavigationHandleImpl>());
// PlzNavigate: clear up state specific to browser-side navigation.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled()) {
frame_tree_.root()->ResetNavigationRequest(false);
if (root->speculative_frame_host()) {
root->speculative_frame_host()->SetRenderFrameCreated(false);
@@ -546,21 +551,18 @@ std::vector<WebContentsImpl*> WebContentsImpl::GetAllWebContents() {
std::vector<WebContentsImpl*> result;
scoped_ptr<RenderWidgetHostIterator> widgets(
RenderWidgetHostImpl::GetRenderWidgetHosts());
- std::set<WebContentsImpl*> web_contents_set;
while (RenderWidgetHost* rwh = widgets->GetNextHost()) {
- if (!rwh->IsRenderView())
- continue;
RenderViewHost* rvh = RenderViewHost::From(rwh);
if (!rvh)
continue;
WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
if (!web_contents)
continue;
- WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents);
- if (web_contents_set.find(wci) == web_contents_set.end()) {
- web_contents_set.insert(wci);
- result.push_back(wci);
- }
+ if (web_contents->GetRenderViewHost() != rvh)
+ continue;
+ // Because a WebContents can only have one current RVH at a time, there will
+ // be no duplicate WebContents here.
+ result.push_back(static_cast<WebContentsImpl*>(web_contents));
}
return result;
}
@@ -572,6 +574,18 @@ WebContentsImpl* WebContentsImpl::FromFrameTreeNode(
WebContents::FromRenderFrameHost(frame_tree_node->current_frame_host()));
}
+// static
+WebContents* WebContentsImpl::FromRenderFrameHostID(int render_process_host_id,
+ int render_frame_host_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHost* render_frame_host =
+ RenderFrameHost::FromID(render_process_host_id, render_frame_host_id);
+ if (!render_frame_host)
+ return nullptr;
+
+ return WebContents::FromRenderFrameHost(render_frame_host);
+}
+
RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
return GetRenderManager();
}
@@ -623,10 +637,7 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser)
IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser,
OnSetSelectedColorInColorChooser)
- IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification,
- OnMediaPlayingNotification)
- IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification,
- OnMediaPausedNotification)
+
IPC_MESSAGE_HANDLER(ViewHostMsg_DidFirstVisuallyNonEmptyPaint,
OnFirstVisuallyNonEmptyPaint)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidLoadResourceFromMemoryCache,
@@ -635,8 +646,14 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
OnDidDisplayInsecureContent)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunInsecureContent,
OnDidRunInsecureContent)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidDisplayContentWithCertificateErrors,
+ OnDidDisplayContentWithCertificateErrors)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunContentWithCertificateErrors,
+ OnDidRunContentWithCertificateErrors)
IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_PageScaleFactorChanged,
+ OnPageScaleFactorChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_EnumerateDirectory, OnEnumerateDirectory)
IPC_MESSAGE_HANDLER(FrameHostMsg_RegisterProtocolHandler,
OnRegisterProtocolHandler)
@@ -667,7 +684,7 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
OnHideValidationMessage)
IPC_MESSAGE_HANDLER(ViewHostMsg_MoveValidationMessage,
OnMoveValidationMessage)
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
IPC_MESSAGE_HANDLER(ViewHostMsg_FindMatchRects_Reply,
OnFindMatchRectsReply)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenDateTimeDialog,
@@ -764,14 +781,23 @@ RenderFrameHostImpl* WebContentsImpl::GetFocusedFrame() {
return focused_node->current_frame_host();
}
+RenderFrameHostImpl* WebContentsImpl::FindFrameByFrameTreeNodeId(
+ int frame_tree_node_id) {
+ FrameTreeNode* frame = frame_tree_.FindByID(frame_tree_node_id);
+ return frame ? frame->current_frame_host() : nullptr;
+}
+
void WebContentsImpl::ForEachFrame(
const base::Callback<void(RenderFrameHost*)>& on_frame) {
frame_tree_.ForEach(base::Bind(&ForEachFrameInternal, on_frame));
}
-void WebContentsImpl::SendToAllFrames(IPC::Message* message) {
- ForEachFrame(base::Bind(&SendToAllFramesInternal, message));
+int WebContentsImpl::SendToAllFrames(IPC::Message* message) {
+ int number_of_messages = 0;
+ ForEachFrame(
+ base::Bind(&SendToAllFramesInternal, &number_of_messages, message));
delete message;
+ return number_of_messages;
}
RenderViewHostImpl* WebContentsImpl::GetRenderViewHost() const {
@@ -855,12 +881,13 @@ WebUI* WebContentsImpl::CreateSubframeWebUI(const GURL& url,
}
WebUI* WebContentsImpl::GetWebUI() const {
- return GetRenderManager()->web_ui() ? GetRenderManager()->web_ui()
- : GetRenderManager()->pending_web_ui();
+ WebUI* commited_web_ui = GetCommittedWebUI();
+ return commited_web_ui ? commited_web_ui
+ : GetRenderManager()->GetNavigatingWebUI();
}
WebUI* WebContentsImpl::GetCommittedWebUI() const {
- return GetRenderManager()->web_ui();
+ return frame_tree_.root()->current_frame_host()->web_ui();
}
void WebContentsImpl::SetUserAgentOverride(const std::string& override) {
@@ -889,7 +916,7 @@ const std::string& WebContentsImpl::GetUserAgentOverride() const {
}
void WebContentsImpl::EnableTreeOnlyAccessibilityMode() {
- if (GetAccessibilityMode() == AccessibilityModeTreeOnly)
+ if (GetAccessibilityMode() != AccessibilityModeOff)
ForEachFrame(base::Bind(&ResetAccessibility));
else
AddAccessibilityMode(AccessibilityModeTreeOnly);
@@ -927,8 +954,12 @@ const base::string16& WebContentsImpl::GetTitle() const {
if (entry) {
return entry->GetTitleForDisplay(accept_languages);
}
- WebUI* our_web_ui = GetRenderManager()->pending_web_ui() ?
- GetRenderManager()->pending_web_ui() : GetRenderManager()->web_ui();
+
+ WebUI* navigating_web_ui = GetRenderManager()->GetNavigatingWebUI();
+ WebUI* our_web_ui = navigating_web_ui
+ ? navigating_web_ui
+ : GetRenderManager()->current_frame_host()->web_ui();
+
if (our_web_ui) {
// Don't override the title in view source mode.
entry = controller_.GetVisibleEntry();
@@ -970,11 +1001,11 @@ const base::string16& WebContentsImpl::GetTitle() const {
return page_title_when_no_navigation_entry_;
}
-int32 WebContentsImpl::GetMaxPageID() {
+int32_t WebContentsImpl::GetMaxPageID() {
return GetMaxPageIDForSiteInstance(GetSiteInstance());
}
-int32 WebContentsImpl::GetMaxPageIDForSiteInstance(
+int32_t WebContentsImpl::GetMaxPageIDForSiteInstance(
SiteInstance* site_instance) {
if (max_page_ids_.find(site_instance->GetId()) == max_page_ids_.end())
max_page_ids_[site_instance->GetId()] = -1;
@@ -982,12 +1013,13 @@ int32 WebContentsImpl::GetMaxPageIDForSiteInstance(
return max_page_ids_[site_instance->GetId()];
}
-void WebContentsImpl::UpdateMaxPageID(int32 page_id) {
+void WebContentsImpl::UpdateMaxPageID(int32_t page_id) {
UpdateMaxPageIDForSiteInstance(GetSiteInstance(), page_id);
}
void WebContentsImpl::UpdateMaxPageIDForSiteInstance(
- SiteInstance* site_instance, int32 page_id) {
+ SiteInstance* site_instance,
+ int32_t page_id) {
if (GetMaxPageIDForSiteInstance(site_instance) < page_id)
max_page_ids_[site_instance->GetId()] = page_id;
}
@@ -1029,22 +1061,14 @@ const base::string16& WebContentsImpl::GetLoadStateHost() const {
return load_state_host_;
}
-uint64 WebContentsImpl::GetUploadSize() const {
+uint64_t WebContentsImpl::GetUploadSize() const {
return upload_size_;
}
-uint64 WebContentsImpl::GetUploadPosition() const {
+uint64_t WebContentsImpl::GetUploadPosition() const {
return upload_position_;
}
-std::set<GURL> WebContentsImpl::GetSitesInTab() const {
- std::set<GURL> sites;
- frame_tree_.ForEach(base::Bind(&CollectSites,
- base::Unretained(GetBrowserContext()),
- base::Unretained(&sites)));
- return sites;
-}
-
const std::string& WebContentsImpl::GetEncoding() const {
return canonical_encoding_;
}
@@ -1115,6 +1139,9 @@ void WebContentsImpl::SetAudioMuted(bool mute) {
audio_muter_->StopMuting();
}
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_,
+ DidUpdateAudioMutingState(mute));
+
// Notification for UI updates in response to the changed muting state.
NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
}
@@ -1156,16 +1183,9 @@ void WebContentsImpl::NotifyNavigationStateChanged(
tracked_objects::ScopedTracker tracking_profile(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"466285 WebContentsImpl::NotifyNavigationStateChanged"));
- // Create and release the audio power save blocker depending on whether the
- // tab is actively producing audio or not.
- if ((changed_flags & INVALIDATE_TYPE_TAB) &&
- AudioStreamMonitor::monitoring_available()) {
- if (WasRecentlyAudible()) {
- if (!audio_power_save_blocker_)
- CreateAudioPowerSaveBlocker();
- } else {
- audio_power_save_blocker_.reset();
- }
+ // Notify the media observer of potential audibility changes.
+ if (changed_flags & INVALIDATE_TYPE_TAB) {
+ media_web_contents_observer_->MaybeUpdateAudibleState();
}
if (delegate_)
@@ -1197,12 +1217,10 @@ void WebContentsImpl::WasShown() {
// The resize rect might have changed while this was inactive -- send the new
// one to make sure it's up to date.
RenderViewHostImpl* rvh = GetRenderViewHost();
- if (rvh)
- rvh->ResizeRectChanged(GetRootWindowResizerRect());
-
- // Restore power save blocker if there are active video players running.
- if (!active_video_players_.empty() && !video_power_save_blocker_)
- CreateVideoPowerSaveBlocker();
+ if (rvh) {
+ rvh->GetWidget()->ResizeRectChanged(
+ GetRootWindowResizerRect(rvh->GetWidget()));
+ }
FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasShown());
@@ -1223,9 +1241,6 @@ void WebContentsImpl::WasHidden() {
if (view)
view->Hide();
}
-
- // Release any video power save blockers held as video is not visible.
- video_power_save_blocker_.reset();
}
FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasHidden());
@@ -1343,33 +1358,60 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
// it should be hidden.
should_normally_be_visible_ = !params.initially_hidden;
- // Either both routing ids can be given, or neither can be.
+ // The routing ids must either all be set or all be unset.
DCHECK((params.routing_id == MSG_ROUTING_NONE &&
- params.main_frame_routing_id == MSG_ROUTING_NONE) ||
+ params.main_frame_routing_id == MSG_ROUTING_NONE &&
+ params.main_frame_widget_routing_id == MSG_ROUTING_NONE) ||
(params.routing_id != MSG_ROUTING_NONE &&
- params.main_frame_routing_id != MSG_ROUTING_NONE));
- GetRenderManager()->Init(params.browser_context, params.site_instance,
- params.routing_id, params.main_frame_routing_id,
- MSG_ROUTING_NONE);
+ params.main_frame_routing_id != MSG_ROUTING_NONE &&
+ params.main_frame_widget_routing_id != MSG_ROUTING_NONE));
+
+ scoped_refptr<SiteInstance> site_instance = params.site_instance;
+ if (!site_instance)
+ site_instance = SiteInstance::Create(params.browser_context);
+
+ // A main RenderFrameHost always has a RenderWidgetHost, since it is always a
+ // local root by definition.
+ // TODO(avi): Once RenderViewHostImpl has-a RenderWidgetHostImpl, it will no
+ // longer be necessary to eagerly grab a routing ID for the view.
+ // https://crbug.com/545684
+ int32_t view_routing_id = params.routing_id;
+ int32_t main_frame_widget_routing_id = params.main_frame_widget_routing_id;
+ if (main_frame_widget_routing_id == MSG_ROUTING_NONE) {
+ view_routing_id = main_frame_widget_routing_id =
+ site_instance->GetProcess()->GetNextRoutingID();
+ }
+
+ GetRenderManager()->Init(site_instance.get(), view_routing_id,
+ params.main_frame_routing_id,
+ main_frame_widget_routing_id);
frame_tree_.root()->SetFrameName(params.main_frame_name);
WebContentsViewDelegate* delegate =
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
+#if defined(MOJO_SHELL_CLIENT)
+ if (MojoShellConnection::Get() &&
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseMusInRenderer)) {
+ mus::Window* mus_window = aura::GetMusWindow(params.context);
+ if (mus_window) {
+ view_.reset(new WebContentsViewMus(mus_window, this, delegate,
+ &render_view_host_delegate_view_));
+ }
+ }
+#endif
+
+ if (!view_) {
+ view_.reset(CreateWebContentsView(this, delegate,
+ &render_view_host_delegate_view_));
+ }
+
if (browser_plugin_guest_ &&
!BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
- scoped_ptr<WebContentsView> platform_view(CreateWebContentsView(
- this, delegate, &render_view_host_delegate_view_));
-
- WebContentsViewGuest* rv = new WebContentsViewGuest(
- this, browser_plugin_guest_.get(), platform_view.Pass(),
- render_view_host_delegate_view_);
- render_view_host_delegate_view_ = rv;
- view_.reset(rv);
- } else {
- // Regular WebContentsView.
- view_.reset(CreateWebContentsView(
- this, delegate, &render_view_host_delegate_view_));
+ view_.reset(new WebContentsViewGuest(this, browser_plugin_guest_.get(),
+ std::move(view_),
+ &render_view_host_delegate_view_));
}
CHECK(render_view_host_delegate_view_);
CHECK(view_.get());
@@ -1391,7 +1433,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
manifest_manager_host_.reset(new ManifestManagerHost(this));
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
date_time_chooser_.reset(new DateTimeChooserAndroid());
#endif
@@ -1407,7 +1449,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
// corresponding RenderView and main RenderFrame have already been created.
// Ensure observers are notified about this.
if (params.renderer_initiated_creation) {
- GetRenderViewHost()->set_renderer_initialized(true);
+ GetRenderViewHost()->GetWidget()->set_renderer_initialized(true);
RenderViewCreated(GetRenderViewHost());
GetRenderManager()->current_frame_host()->SetRenderFrameCreated(true);
}
@@ -1476,27 +1518,28 @@ void WebContentsImpl::Activate() {
delegate_->ActivateContents(this);
}
-void WebContentsImpl::Deactivate() {
- if (delegate_)
- delegate_->DeactivateContents(this);
-}
+void WebContentsImpl::LostCapture(RenderWidgetHostImpl* render_widget_host) {
+ if (!RenderViewHostImpl::From(render_widget_host))
+ return;
-void WebContentsImpl::LostCapture() {
if (delegate_)
delegate_->LostCapture();
}
+void WebContentsImpl::RenderWidgetCreated(
+ RenderWidgetHostImpl* render_widget_host) {
+ created_widgets_.insert(render_widget_host);
+}
+
void WebContentsImpl::RenderWidgetDeleted(
RenderWidgetHostImpl* render_widget_host) {
- if (is_being_destroyed_) {
- // |created_widgets_| might have been destroyed.
- return;
- }
+ // Note that |is_being_destroyed_| can be true at this point as
+ // ~WebContentsImpl() calls RFHM::ClearRFHsPendingShutdown(), which might lead
+ // us here.
+ created_widgets_.erase(render_widget_host);
- std::set<RenderWidgetHostImpl*>::iterator iter =
- created_widgets_.find(render_widget_host);
- if (iter != created_widgets_.end())
- created_widgets_.erase(iter);
+ if (is_being_destroyed_)
+ return;
if (render_widget_host &&
render_widget_host->GetRoutingID() == fullscreen_widget_routing_id_) {
@@ -1565,7 +1608,14 @@ bool WebContentsImpl::HandleWheelEvent(
if (delegate_ && event.wheelTicksY &&
(event.modifiers & blink::WebInputEvent::ControlKey) &&
!event.canScroll) {
- delegate_->ContentsZoomChange(event.wheelTicksY > 0);
+ // Count only integer cumulative scrolls as zoom events; this handles
+ // smooth scroll and regular scroll device behavior.
+ zoom_scroll_remainder_ += event.wheelTicksY;
+ int whole_zoom_scroll_remainder_ = std::lround(zoom_scroll_remainder_);
+ zoom_scroll_remainder_ -= whole_zoom_scroll_remainder_;
+ if (whole_zoom_scroll_remainder_ != 0) {
+ delegate_->ContentsZoomChange(whole_zoom_scroll_remainder_ > 0);
+ }
return true;
}
#endif
@@ -1578,33 +1628,74 @@ bool WebContentsImpl::PreHandleGestureEvent(
}
RenderWidgetHostInputEventRouter* WebContentsImpl::GetInputEventRouter() {
- // Currently only supported in site per process mode (--site-per-process).
- if (!rwh_input_event_router_.get() && !is_being_destroyed_ &&
- SiteIsolationPolicy::AreCrossProcessFramesPossible())
+ if (!is_being_destroyed_ && GetOuterWebContents())
+ return GetOuterWebContents()->GetInputEventRouter();
+
+ if (!rwh_input_event_router_.get() && !is_being_destroyed_)
rwh_input_event_router_.reset(new RenderWidgetHostInputEventRouter);
return rwh_input_event_router_.get();
}
+void WebContentsImpl::ReplicatePageFocus(bool is_focused) {
+ // Focus loss may occur while this WebContents is being destroyed. Don't
+ // send the message in this case, as the main frame's RenderFrameHost and
+ // other state has already been cleared.
+ if (is_being_destroyed_)
+ return;
+
+ frame_tree_.ReplicatePageFocus(is_focused);
+}
+
+RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost(
+ RenderWidgetHostImpl* receiving_widget) {
+ if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
+ return receiving_widget;
+
+ // Events for widgets other than the main frame (e.g., popup menus) should be
+ // forwarded directly to the widget they arrived on.
+ if (receiving_widget != GetMainFrame()->GetRenderWidgetHost())
+ return receiving_widget;
+
+ FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame();
+ if (!focused_frame)
+ return receiving_widget;
+
+ // The view may be null if a subframe's renderer process has crashed while
+ // the subframe has focus. Drop the event in that case. Do not give
+ // it to the main frame, so that the user doesn't unexpectedly type into the
+ // wrong frame if a focused subframe renderer crashes while they type.
+ RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView();
+ if (!view)
+ return nullptr;
+
+ return RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
+}
+
void WebContentsImpl::EnterFullscreenMode(const GURL& origin) {
// This method is being called to enter renderer-initiated fullscreen mode.
// Make sure any existing fullscreen widget is shut down first.
RenderWidgetHostView* const widget_view = GetFullscreenRenderWidgetHostView();
- if (widget_view)
- RenderWidgetHostImpl::From(widget_view->GetRenderWidgetHost())->Shutdown();
+ if (widget_view) {
+ RenderWidgetHostImpl::From(widget_view->GetRenderWidgetHost())
+ ->ShutdownAndDestroyWidget(true);
+ }
if (delegate_)
delegate_->EnterFullscreenModeForTab(this, origin);
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- DidToggleFullscreenModeForTab(IsFullscreenForCurrentTab()));
+ DidToggleFullscreenModeForTab(IsFullscreenForCurrentTab(
+ GetRenderViewHost()->GetWidget())));
}
void WebContentsImpl::ExitFullscreenMode() {
// This method is being called to leave renderer-initiated fullscreen mode.
// Make sure any existing fullscreen widget is shut down first.
RenderWidgetHostView* const widget_view = GetFullscreenRenderWidgetHostView();
- if (widget_view)
- RenderWidgetHostImpl::From(widget_view->GetRenderWidgetHost())->Shutdown();
+ if (widget_view) {
+ RenderWidgetHostImpl::From(widget_view->GetRenderWidgetHost())
+ ->ShutdownAndDestroyWidget(true);
+ }
#if defined(OS_ANDROID)
ContentVideoView* video_view = ContentVideoView::GetInstance();
@@ -1626,38 +1717,66 @@ void WebContentsImpl::ExitFullscreenMode() {
render_widget_host->WasResized();
}
- FOR_EACH_OBSERVER(WebContentsObserver,
- observers_,
- DidToggleFullscreenModeForTab(IsFullscreenForCurrentTab()));
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_,
+ DidToggleFullscreenModeForTab(IsFullscreenForCurrentTab(
+ GetRenderViewHost()->GetWidget())));
}
-bool WebContentsImpl::IsFullscreenForCurrentTab() const {
+bool WebContentsImpl::IsFullscreenForCurrentTab(
+ RenderWidgetHostImpl* render_widget_host) const {
+ if (!RenderViewHostImpl::From(render_widget_host))
+ return false;
+
return delegate_ ? delegate_->IsFullscreenForTabOrPending(this) : false;
}
-blink::WebDisplayMode WebContentsImpl::GetDisplayMode() const {
+blink::WebDisplayMode WebContentsImpl::GetDisplayMode(
+ RenderWidgetHostImpl* render_widget_host) const {
+ if (!RenderViewHostImpl::From(render_widget_host))
+ return blink::WebDisplayModeBrowser;
+
return delegate_ ? delegate_->GetDisplayMode(this)
: blink::WebDisplayModeBrowser;
}
-void WebContentsImpl::RequestToLockMouse(bool user_gesture,
- bool last_unlocked_by_target) {
- if (delegate_) {
+void WebContentsImpl::RequestToLockMouse(
+ RenderWidgetHostImpl* render_widget_host,
+ bool user_gesture,
+ bool last_unlocked_by_target) {
+ if (render_widget_host != GetRenderViewHost()->GetWidget()) {
+ render_widget_host->GotResponseToLockMouseRequest(false);
+ return;
+ }
+
+ if (delegate_)
delegate_->RequestToLockMouse(this, user_gesture, last_unlocked_by_target);
- } else {
+ else
GotResponseToLockMouseRequest(false);
- }
}
-void WebContentsImpl::LostMouseLock() {
+void WebContentsImpl::LostMouseLock(RenderWidgetHostImpl* render_widget_host) {
+ if (!RenderViewHostImpl::From(render_widget_host))
+ return;
+
if (delegate_)
delegate_->LostMouseLock();
}
+void WebContentsImpl::ForwardCompositorProto(
+ RenderWidgetHostImpl* render_widget_host,
+ const std::vector<uint8_t>& proto) {
+ if (render_widget_host != GetRenderViewHost()->GetWidget())
+ return;
+
+ if (delegate_)
+ delegate_->ForwardCompositorProto(proto);
+}
+
void WebContentsImpl::CreateNewWindow(
SiteInstance* source_site_instance,
- int route_id,
- int main_frame_route_id,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) {
// We usually create the new window in the same BrowsingInstance (group of
@@ -1716,14 +1835,10 @@ void WebContentsImpl::CreateNewWindow(
CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
if (delegate_ &&
- !delegate_->ShouldCreateWebContents(this,
- route_id,
- main_frame_route_id,
- params.window_container_type,
- params.frame_name,
- params.target_url,
- partition_id,
- session_storage_namespace)) {
+ !delegate_->ShouldCreateWebContents(
+ this, route_id, main_frame_route_id, main_frame_widget_route_id,
+ params.window_container_type, params.frame_name, params.target_url,
+ partition_id, session_storage_namespace)) {
if (route_id != MSG_ROUTING_NONE &&
!RenderViewHost::FromID(render_process_id, route_id)) {
// If the embedder didn't create a WebContents for this route, we need to
@@ -1731,8 +1846,6 @@ void WebContentsImpl::CreateNewWindow(
Send(new ViewMsg_Close(route_id));
}
GetRenderViewHost()->GetProcess()->ResumeRequestsForView(route_id);
- GetRenderViewHost()->GetProcess()->ResumeRequestsForView(
- main_frame_route_id);
return;
}
@@ -1741,6 +1854,7 @@ void WebContentsImpl::CreateNewWindow(
CreateParams create_params(GetBrowserContext(), site_instance.get());
create_params.routing_id = route_id;
create_params.main_frame_routing_id = main_frame_route_id;
+ create_params.main_frame_widget_routing_id = main_frame_widget_route_id;
create_params.main_frame_name = params.frame_name;
create_params.opener_render_process_id = render_process_id;
create_params.opener_render_frame_id = params.opener_render_frame_id;
@@ -1778,7 +1892,8 @@ void WebContentsImpl::CreateNewWindow(
// TODO(brettw): It seems bogus that we have to call this function on the
// newly created object and give it one of its own member variables.
- new_view->CreateViewForWidget(new_contents->GetRenderViewHost(), false);
+ new_view->CreateViewForWidget(
+ new_contents->GetRenderViewHost()->GetWidget(), false);
}
// Save the created window associated with the route so we can show it
// later.
@@ -1823,26 +1938,29 @@ void WebContentsImpl::CreateNewWindow(
}
}
-void WebContentsImpl::CreateNewWidget(int32 render_process_id,
- int32 route_id,
+void WebContentsImpl::CreateNewWidget(int32_t render_process_id,
+ int32_t route_id,
blink::WebPopupType popup_type) {
CreateNewWidget(render_process_id, route_id, false, popup_type);
}
-void WebContentsImpl::CreateNewFullscreenWidget(int32 render_process_id,
- int32 route_id) {
+void WebContentsImpl::CreateNewFullscreenWidget(int32_t render_process_id,
+ int32_t route_id) {
CreateNewWidget(render_process_id, route_id, true, blink::WebPopupTypeNone);
}
-void WebContentsImpl::CreateNewWidget(int32 render_process_id,
- int32 route_id,
+void WebContentsImpl::CreateNewWidget(int32_t render_process_id,
+ int32_t 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
+ // A message to create a new widget can only come from an 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) {
+ bool did_match_process = false;
+ frame_tree_.ForEach(
+ base::Bind(&FindMatchingProcess, render_process_id, &did_match_process));
+ if (!did_match_process) {
RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
base::ProcessHandle process_handle = rph->GetHandle();
if (process_handle != base::kNullProcessHandle) {
@@ -1855,7 +1973,6 @@ void WebContentsImpl::CreateNewWidget(int32 render_process_id,
RenderWidgetHostImpl* widget_host =
new RenderWidgetHostImpl(this, process, route_id, IsHidden());
- created_widgets_.insert(widget_host);
RenderWidgetHostViewBase* widget_view =
static_cast<RenderWidgetHostViewBase*>(
@@ -1971,7 +2088,7 @@ WebContentsImpl* WebContentsImpl::GetCreatedWindow(int route_id) {
return new_contents;
if (!new_contents->GetRenderProcessHost()->HasConnection() ||
- !new_contents->GetRenderViewHost()->GetView())
+ !new_contents->GetRenderViewHost()->GetWidget()->GetView())
return NULL;
return new_contents;
@@ -2067,6 +2184,10 @@ GeolocationServiceContext* WebContentsImpl::GetGeolocationServiceContext() {
return geolocation_service_context_.get();
}
+WakeLockServiceContext* WebContentsImpl::GetWakeLockServiceContext() {
+ return wake_lock_service_context_.get();
+}
+
void WebContentsImpl::OnShowValidationMessage(
const gfx::Rect& anchor_in_root_view,
const base::string16& main_text,
@@ -2139,7 +2260,12 @@ void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) {
OnPreferredSizeChanged(old_size);
}
-void WebContentsImpl::ResizeDueToAutoResize(const gfx::Size& new_size) {
+void WebContentsImpl::ResizeDueToAutoResize(
+ RenderWidgetHostImpl* render_widget_host,
+ const gfx::Size& new_size) {
+ if (render_widget_host != GetRenderViewHost()->GetWidget())
+ return;
+
if (delegate_)
delegate_->ResizeDueToAutoResize(this, new_size);
}
@@ -2468,7 +2594,7 @@ void WebContentsImpl::SaveFrameWithHeaders(const GURL& url,
BrowserContext::GetDownloadManager(GetBrowserContext());
if (!dlm)
return;
- int64 post_id = -1;
+ int64_t post_id = -1;
if (is_main_frame) {
const NavigationEntry* entry = controller_.GetLastCommittedEntry();
if (entry)
@@ -2494,12 +2620,12 @@ void WebContentsImpl::SaveFrameWithHeaders(const GURL& url,
params->add_request_header(pair[0], pair[1]);
}
}
- dlm->DownloadUrl(params.Pass());
+ dlm->DownloadUrl(std::move(params));
}
void WebContentsImpl::GenerateMHTML(
const base::FilePath& file,
- const base::Callback<void(int64)>& callback) {
+ const base::Callback<void(int64_t)>& callback) {
MHTMLGenerationManager::GetInstance()->SaveMHTML(this, file, callback);
}
@@ -2584,7 +2710,7 @@ void WebContentsImpl::SystemDragEnded() {
}
void WebContentsImpl::UserGestureDone() {
- OnUserGesture();
+ OnUserGesture(GetRenderViewHost()->GetWidget());
}
void WebContentsImpl::SetClosedByUserGesture(bool value) {
@@ -2622,8 +2748,8 @@ int WebContentsImpl::GetMaximumZoomPercent() const {
return maximum_zoom_percent_;
}
-void WebContentsImpl::ResetPageScale() {
- Send(new ViewMsg_ResetPageScale(GetRoutingID()));
+void WebContentsImpl::SetPageScale(float page_scale_factor) {
+ Send(new ViewMsg_SetPageScale(GetRoutingID(), page_scale_factor));
}
gfx::Size WebContentsImpl::GetPreferredSize() const {
@@ -2635,7 +2761,8 @@ bool WebContentsImpl::GotResponseToLockMouseRequest(bool allowed) {
return GetBrowserPluginGuest()->LockMouse(allowed);
return GetRenderViewHost()
- ? GetRenderViewHost()->GotResponseToLockMouseRequest(allowed)
+ ? GetRenderViewHost()->GetWidget()->GotResponseToLockMouseRequest(
+ allowed)
: false;
}
@@ -2709,7 +2836,7 @@ int WebContentsImpl::DownloadImage(
req->bypass_cache = bypass_cache;
mojo_image_downloader->DownloadImage(
- req.Pass(),
+ std::move(req),
base::Bind(&DidDownloadImage, callback, download_id, url));
return download_id;
}
@@ -2757,9 +2884,13 @@ void WebContentsImpl::GetManifest(const GetManifestCallback& callback) {
manifest_manager_host_->GetManifest(GetMainFrame(), callback);
}
+void WebContentsImpl::HasManifest(const HasManifestCallback& callback) {
+ manifest_manager_host_->HasManifest(GetMainFrame(), callback);
+}
+
void WebContentsImpl::ExitFullscreen() {
// Clean up related state and initiate the fullscreen exit.
- GetRenderViewHost()->RejectMouseLockOrUnlockIfNecessary();
+ GetRenderViewHost()->GetWidget()->RejectMouseLockOrUnlockIfNecessary();
ExitFullscreenMode();
}
@@ -2774,7 +2905,7 @@ void WebContentsImpl::ResumeLoadingCreatedWebContents() {
// TODO(brettw): It seems bogus to reach into here and initialize the host.
if (is_resume_pending_) {
is_resume_pending_ = false;
- GetRenderViewHost()->Init();
+ GetRenderViewHost()->GetWidget()->Init();
GetMainFrame()->Init();
}
}
@@ -2874,16 +3005,6 @@ void WebContentsImpl::NotifyChangedNavigationState(
NotifyNavigationStateChanged(changed_flags);
}
-void WebContentsImpl::AboutToNavigateRenderFrame(
- RenderFrameHostImpl* old_host,
- RenderFrameHostImpl* new_host) {
- // Notify observers that we will navigate in this RenderFrame.
- FOR_EACH_OBSERVER(
- WebContentsObserver,
- observers_,
- AboutToNavigateRenderFrame(old_host, new_host));
-}
-
void WebContentsImpl::DidStartNavigationToPendingEntry(
const GURL& url,
NavigationController::ReloadType reload_type) {
@@ -2915,6 +3036,12 @@ void WebContentsImpl::RequestOpenURL(RenderFrameHostImpl* render_frame_host,
}
}
+bool WebContentsImpl::ShouldTransferNavigation() {
+ if (!delegate_)
+ return true;
+ return delegate_->ShouldTransferNavigation();
+}
+
bool WebContentsImpl::ShouldPreserveAbortedURLs() {
if (!delegate_)
return false;
@@ -2946,9 +3073,9 @@ void WebContentsImpl::DidNavigateMainFramePreCommit(
// No page change? Then, the renderer and browser can remain in fullscreen.
return;
}
- if (IsFullscreenForCurrentTab())
+ if (IsFullscreenForCurrentTab(GetRenderViewHost()->GetWidget()))
ExitFullscreen();
- DCHECK(!IsFullscreenForCurrentTab());
+ DCHECK(!IsFullscreenForCurrentTab(GetRenderViewHost()->GetWidget()));
}
void WebContentsImpl::DidNavigateMainFramePostCommit(
@@ -3054,8 +3181,8 @@ void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
// Send out a notification that we loaded a resource from our memory cache.
// TODO(alcutter,eranm): Pass signed_certificate_timestamp_ids into details.
LoadFromMemoryCacheDetails details(
- url, GetRenderProcessHost()->GetID(), status.cert_id, status.cert_status,
- http_method, mime_type, resource_type);
+ url, status.cert_id, status.cert_status, http_method, mime_type,
+ resource_type);
controller_.ssl_manager()->DidLoadFromMemoryCache(details);
@@ -3083,12 +3210,12 @@ void WebContentsImpl::OnDidDisplayInsecureContent() {
GetController().GetBrowserContext());
}
-void WebContentsImpl::OnDidRunInsecureContent(
- const std::string& security_origin, const GURL& target_url) {
+void WebContentsImpl::OnDidRunInsecureContent(const GURL& security_origin,
+ const GURL& target_url) {
LOG(WARNING) << security_origin << " ran insecure content from "
<< target_url.possibly_invalid_spec();
RecordAction(base::UserMetricsAction("SSL.RanInsecureContent"));
- if (base::EndsWith(security_origin, kDotGoogleDotCom,
+ if (base::EndsWith(security_origin.spec(), kDotGoogleDotCom,
base::CompareCase::INSENSITIVE_ASCII))
RecordAction(base::UserMetricsAction("SSL.RanInsecureContentGoogle"));
controller_.ssl_manager()->DidRunInsecureContent(security_origin);
@@ -3096,6 +3223,39 @@ void WebContentsImpl::OnDidRunInsecureContent(
GetController().GetBrowserContext());
}
+void WebContentsImpl::OnDidDisplayContentWithCertificateErrors(
+ const GURL& url,
+ const std::string& security_info) {
+ SSLStatus ssl;
+ if (!DeserializeSecurityInfo(security_info, &ssl)) {
+ bad_message::ReceivedBadMessage(
+ GetRenderProcessHost(),
+ bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO);
+ return;
+ }
+
+ displayed_insecure_content_ = true;
+ SSLManager::NotifySSLInternalStateChanged(
+ GetController().GetBrowserContext());
+}
+
+void WebContentsImpl::OnDidRunContentWithCertificateErrors(
+ const GURL& security_origin,
+ const GURL& url,
+ const std::string& security_info) {
+ SSLStatus ssl;
+ if (!DeserializeSecurityInfo(security_info, &ssl)) {
+ bad_message::ReceivedBadMessage(
+ GetRenderProcessHost(),
+ bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO);
+ return;
+ }
+
+ controller_.ssl_manager()->DidRunInsecureContent(security_origin);
+ SSLManager::NotifySSLInternalStateChanged(
+ GetController().GetBrowserContext());
+}
+
void WebContentsImpl::OnDocumentLoadedInFrame() {
if (!HasValidFrameSource())
return;
@@ -3132,6 +3292,26 @@ void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent,
maximum_zoom_percent_ = maximum_percent;
}
+void WebContentsImpl::OnPageScaleFactorChanged(float page_scale_factor) {
+ bool is_one = page_scale_factor == 1.f;
+ if (is_one != page_scale_factor_is_one_) {
+ page_scale_factor_is_one_ = is_one;
+
+ HostZoomMapImpl* host_zoom_map =
+ static_cast<HostZoomMapImpl*>(HostZoomMap::GetForWebContents(this));
+
+ if (host_zoom_map && GetRenderProcessHost()) {
+ host_zoom_map->SetPageScaleFactorIsOneForView(
+ GetRenderProcessHost()->GetID(), GetRoutingID(),
+ page_scale_factor_is_one_);
+ }
+ }
+
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ OnPageScaleFactorChanged(page_scale_factor));
+}
+
void WebContentsImpl::OnEnumerateDirectory(int request_id,
const base::FilePath& path) {
if (!delegate_)
@@ -3188,7 +3368,7 @@ void WebContentsImpl::OnFindReply(int request_id,
}
}
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
void WebContentsImpl::OnFindMatchRectsReply(
int version,
const std::vector<gfx::RectF>& rects,
@@ -3338,77 +3518,6 @@ void WebContentsImpl::OnUpdateFaviconURL(
DidUpdateFaviconURL(candidates));
}
-void WebContentsImpl::CreateAudioPowerSaveBlocker() {
- DCHECK(!audio_power_save_blocker_);
- audio_power_save_blocker_ = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
- PowerSaveBlocker::kReasonAudioPlayback, "Playing audio");
-}
-
-void WebContentsImpl::CreateVideoPowerSaveBlocker() {
- DCHECK(!video_power_save_blocker_);
- DCHECK(!active_video_players_.empty());
- video_power_save_blocker_ = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
- PowerSaveBlocker::kReasonVideoPlayback, "Playing video");
-#if defined(OS_ANDROID)
- static_cast<PowerSaveBlockerImpl*>(video_power_save_blocker_.get())
- ->InitDisplaySleepBlocker(this);
-#endif
-}
-
-void WebContentsImpl::MaybeReleasePowerSaveBlockers() {
- // If there are no more audio players and we don't have audio stream
- // monitoring, release the audio power save blocker here instead of during
- // NotifyNavigationStateChanged().
- if (active_audio_players_.empty() &&
- !AudioStreamMonitor::monitoring_available()) {
- audio_power_save_blocker_.reset();
- }
-
- // If there are no more video players, clear the video power save blocker.
- if (active_video_players_.empty())
- video_power_save_blocker_.reset();
-}
-
-void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
- bool has_video,
- bool has_audio,
- bool is_remote) {
- // Ignore the videos playing remotely and don't hold the wake lock for the
- // screen.
- if (is_remote) return;
-
- if (has_audio) {
- AddMediaPlayerEntry(player_cookie, &active_audio_players_);
-
- // If we don't have audio stream monitoring, allocate the audio power save
- // blocker here instead of during NotifyNavigationStateChanged().
- if (!audio_power_save_blocker_ &&
- !AudioStreamMonitor::monitoring_available()) {
- CreateAudioPowerSaveBlocker();
- }
- }
-
- if (has_video) {
- AddMediaPlayerEntry(player_cookie, &active_video_players_);
-
- // If we're not hidden and have just created a player, create a blocker.
- if (!video_power_save_blocker_ && !IsHidden())
- CreateVideoPowerSaveBlocker();
- }
-
- FOR_EACH_OBSERVER(WebContentsObserver, observers_, MediaStartedPlaying());
-}
-
-void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
- RemoveMediaPlayerEntry(player_cookie, &active_audio_players_);
- RemoveMediaPlayerEntry(player_cookie, &active_video_players_);
- MaybeReleasePowerSaveBlockers();
-
- FOR_EACH_OBSERVER(WebContentsObserver, observers_, MediaPaused());
-}
-
#if defined(OS_ANDROID)
void WebContentsImpl::OnMediaSessionStateChanged() {
@@ -3502,8 +3611,9 @@ void WebContentsImpl::SetIsLoading(bool is_loading,
std::string url = (details ? details->url.possibly_invalid_spec() : "NULL");
if (is_loading) {
- TRACE_EVENT_ASYNC_BEGIN1("browser,navigation", "WebContentsImpl Loading",
- this, "URL", url);
+ TRACE_EVENT_ASYNC_BEGIN2("browser,navigation", "WebContentsImpl Loading",
+ this, "URL", url, "Main FrameTreeNode id",
+ GetFrameTree()->root()->frame_tree_node_id());
FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidStartLoading());
} else {
TRACE_EVENT_ASYNC_END1("browser,navigation", "WebContentsImpl Loading",
@@ -3636,8 +3746,6 @@ const GURL& WebContentsImpl::GetMainFrameLastCommittedURL() const {
}
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));
@@ -3645,7 +3753,6 @@ void WebContentsImpl::RenderFrameCreated(RenderFrameHost* render_frame_host) {
}
void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
- ClearPowerSaveBlockers(render_frame_host);
FOR_EACH_OBSERVER(WebContentsObserver,
observers_,
RenderFrameDeleted(render_frame_host));
@@ -3758,7 +3865,11 @@ RendererPreferences WebContentsImpl::GetRendererPrefs(
return renderer_preferences_;
}
-gfx::Rect WebContentsImpl::GetRootWindowResizerRect() const {
+gfx::Rect WebContentsImpl::GetRootWindowResizerRect(
+ RenderWidgetHostImpl* render_widget_host) const {
+ if (!RenderViewHostImpl::From(render_widget_host))
+ return gfx::Rect();
+
if (delegate_)
return delegate_->GetRootWindowResizerRect();
return gfx::Rect();
@@ -3784,18 +3895,6 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
Source<WebContents>(this),
Details<RenderViewHost>(render_view_host));
- // When we're creating views, we're still doing initial setup, so we always
- // use the pending Web UI rather than any possibly existing committed one.
- if (GetRenderManager()->pending_web_ui())
- GetRenderManager()->pending_web_ui()->RenderViewCreated(render_view_host);
-
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation) &&
- GetRenderManager()->speculative_web_ui()) {
- GetRenderManager()->speculative_web_ui()->RenderViewCreated(
- render_view_host);
- }
-
NavigationEntry* entry = controller_.GetPendingEntry();
if (entry && entry->IsViewSourceMode()) {
// Put the renderer in view source mode.
@@ -3846,7 +3945,7 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
// Ensure fullscreen mode is exited in the |delegate_| since a crashed
// renderer may not have made a clean exit.
- if (IsFullscreenForCurrentTab())
+ if (IsFullscreenForCurrentTab(GetRenderViewHost()->GetWidget()))
ExitFullscreenMode();
// Cancel any visible dialogs so they are not left dangling over the sad tab.
@@ -3875,8 +3974,10 @@ void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
}
void WebContentsImpl::UpdateState(RenderViewHost* rvh,
- int32 page_id,
+ int32_t page_id,
const PageState& page_state) {
+ DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
+
// Ensure that this state update comes from a RenderViewHost that belongs to
// this WebContents.
// TODO(nasko): This should go through RenderFrameHost.
@@ -3894,15 +3995,13 @@ void WebContentsImpl::UpdateState(RenderViewHost* rvh,
if (!entry)
return;
- NavigationEntryImpl* new_entry = controller_.GetEntryWithUniqueID(
- rvhi->nav_entry_id());
+ // Sanity check that ensures nav_entry_id and page_id point to the same
+ // navigation entry.
+ if (rvhi->GetMainFrame()) {
+ NavigationEntryImpl* new_entry = controller_.GetEntryWithUniqueID(
+ static_cast<RenderFrameHostImpl*>(rvhi->GetMainFrame())
+ ->nav_entry_id());
- if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
- // TODO(creis): We can't properly update state for cross-process subframes
- // until PageState is decomposed into FrameStates. Until then, use the new
- // method.
- entry = new_entry;
- } else {
DCHECK_EQ(entry, new_entry);
}
@@ -3918,7 +4017,7 @@ void WebContentsImpl::UpdateTargetURL(RenderViewHost* render_view_host,
// If we're fullscreen only update the url if it's from the fullscreen
// renderer.
RenderWidgetHostView* fs = GetFullscreenRenderWidgetHostView();
- if (fs && fs->GetRenderWidgetHost() != render_view_host)
+ if (fs && fs->GetRenderWidgetHost() != render_view_host->GetWidget())
return;
}
if (delegate_)
@@ -4066,8 +4165,42 @@ void WebContentsImpl::DocumentOnLoadCompleted(
NotificationService::NoDetails());
}
+void WebContentsImpl::UpdateStateForFrame(RenderFrameHost* render_frame_host,
+ const PageState& page_state) {
+ DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+
+ // The state update affects the last NavigationEntry associated with the given
+ // |render_frame_host|. This may not be the last committed NavigationEntry (as
+ // in the case of an UpdateState from a frame being swapped out). We track
+ // which entry this is in the RenderFrameHost's nav_entry_id.
+ RenderFrameHostImpl* rfhi =
+ static_cast<RenderFrameHostImpl*>(render_frame_host);
+ NavigationEntryImpl* entry =
+ controller_.GetEntryWithUniqueID(rfhi->nav_entry_id());
+ if (!entry)
+ return;
+
+ FrameNavigationEntry* frame_entry =
+ entry->GetFrameEntry(rfhi->frame_tree_node());
+ if (!frame_entry)
+ return;
+
+ // The SiteInstance might not match if we do a cross-process navigation with
+ // replacement (e.g., auto-subframe), in which case the swap out of the old
+ // RenderFrameHost runs in the background after the old FrameNavigationEntry
+ // has already been replaced and destroyed.
+ if (frame_entry->site_instance() != rfhi->GetSiteInstance())
+ return;
+
+ if (page_state == frame_entry->page_state())
+ return; // Nothing to update.
+
+ frame_entry->set_page_state(page_state);
+ controller_.NotifyEntryChanged(entry);
+}
+
void WebContentsImpl::UpdateTitle(RenderFrameHost* render_frame_host,
- int32 page_id,
+ int32_t page_id,
const base::string16& title,
base::i18n::TextDirection title_direction) {
// If we have a title, that's a pretty good indication that we've started
@@ -4079,10 +4212,8 @@ void WebContentsImpl::UpdateTitle(RenderFrameHost* render_frame_host,
NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
render_frame_host->GetSiteInstance(), page_id);
- RenderViewHostImpl* rvhi =
- static_cast<RenderViewHostImpl*>(render_frame_host->GetRenderViewHost());
NavigationEntryImpl* new_entry = controller_.GetEntryWithUniqueID(
- rvhi->nav_entry_id());
+ static_cast<RenderFrameHostImpl*>(render_frame_host)->nav_entry_id());
DCHECK_EQ(entry, new_entry);
// We can handle title updates when we don't have an entry in
@@ -4166,9 +4297,9 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) {
}
}
-bool WebContentsImpl::AddMessageToConsole(int32 level,
+bool WebContentsImpl::AddMessageToConsole(int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id) {
if (!delegate_)
return false;
@@ -4183,13 +4314,16 @@ int WebContentsImpl::CreateSwappedOutRenderView(
GetRenderManager()->CreateRenderFrameProxy(instance);
} else {
GetRenderManager()->CreateRenderFrame(
- instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
+ instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
&render_view_routing_id);
}
return render_view_routing_id;
}
-void WebContentsImpl::OnUserGesture() {
+void WebContentsImpl::OnUserGesture(RenderWidgetHostImpl* render_widget_host) {
+ if (render_widget_host != GetRenderViewHost()->GetWidget())
+ return;
+
// Notify observers.
FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidGetUserGesture());
@@ -4198,19 +4332,24 @@ void WebContentsImpl::OnUserGesture() {
rdh->OnUserGesture(this);
}
+void WebContentsImpl::OnUserInteraction(const blink::WebInputEvent::Type type) {
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_,
+ DidGetUserInteraction(type));
+}
+
void WebContentsImpl::OnIgnoredUIEvent() {
// Notify observers.
FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidGetIgnoredUIEvent());
}
-void WebContentsImpl::RendererUnresponsive(RenderViewHost* render_view_host) {
+void WebContentsImpl::RendererUnresponsive(
+ RenderWidgetHostImpl* render_widget_host) {
// Don't show hung renderer dialog for a swapped out RVH.
- if (render_view_host != GetRenderViewHost())
+ if (render_widget_host != GetRenderViewHost()->GetWidget())
return;
- RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(render_view_host);
RenderFrameHostImpl* rfhi =
- static_cast<RenderFrameHostImpl*>(rvhi->GetMainFrame());
+ static_cast<RenderFrameHostImpl*>(GetRenderViewHost()->GetMainFrame());
// Ignore renderer unresponsive event if debugger is attached to the tab
// since the event may be a result of the renderer sitting on a breakpoint.
@@ -4222,7 +4361,7 @@ void WebContentsImpl::RendererUnresponsive(RenderViewHost* render_view_host) {
rfhi->IsWaitingForUnloadACK()) {
// Hang occurred while firing the beforeunload/unload handler.
// Pretend the handler fired so tab closing continues as if it had.
- rvhi->set_sudden_termination_allowed(true);
+ GetRenderViewHost()->set_sudden_termination_allowed(true);
if (!GetRenderManager()->ShouldCloseTabOnUnresponsiveRenderer())
return;
@@ -4238,7 +4377,7 @@ void WebContentsImpl::RendererUnresponsive(RenderViewHost* render_view_host) {
delegate_->BeforeUnloadFired(this, true, &close);
}
if (close)
- Close(rvhi);
+ Close();
return;
}
@@ -4249,7 +4388,11 @@ void WebContentsImpl::RendererUnresponsive(RenderViewHost* render_view_host) {
delegate_->RendererUnresponsive(this);
}
-void WebContentsImpl::RendererResponsive(RenderViewHost* render_view_host) {
+void WebContentsImpl::RendererResponsive(
+ RenderWidgetHostImpl* render_widget_host) {
+ if (render_widget_host != GetRenderViewHost()->GetWidget())
+ return;
+
if (delegate_)
delegate_->RendererResponsive(this);
}
@@ -4257,8 +4400,8 @@ void WebContentsImpl::RendererResponsive(RenderViewHost* render_view_host) {
void WebContentsImpl::LoadStateChanged(
const GURL& url,
const net::LoadStateWithParam& load_state,
- uint64 upload_position,
- uint64 upload_size) {
+ uint64_t upload_position,
+ uint64_t upload_size) {
// TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466285
// is fixed.
tracked_objects::ScopedTracker tracking_profile1(
@@ -4345,7 +4488,7 @@ NavigationControllerImpl& WebContentsImpl::GetControllerForRenderManager() {
return GetController();
}
-scoped_ptr<WebUIImpl> WebContentsImpl::CreateWebUIForRenderManager(
+scoped_ptr<WebUIImpl> WebContentsImpl::CreateWebUIForRenderFrameHost(
const GURL& url) {
return scoped_ptr<WebUIImpl>(static_cast<WebUIImpl*>(CreateWebUI(
url, std::string())));
@@ -4364,10 +4507,10 @@ void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager(
BrowserPluginGuestMode::UseCrossProcessFramesForGuests();
if (is_guest_in_site_per_process) {
RenderWidgetHostViewChildFrame* rwh_view_child =
- new RenderWidgetHostViewChildFrame(render_view_host);
+ new RenderWidgetHostViewChildFrame(render_view_host->GetWidget());
rwh_view = rwh_view_child;
} else {
- rwh_view = view_->CreateViewForWidget(render_view_host, false);
+ rwh_view = view_->CreateViewForWidget(render_view_host->GetWidget(), false);
}
// Now that the RenderView has been created, we need to tell it its size.
@@ -4388,7 +4531,7 @@ bool WebContentsImpl::CreateRenderViewForRenderManager(
// Make sure we use the correct starting page_id in the new RenderView.
UpdateMaxPageIDIfNecessary(render_view_host);
- int32 max_page_id =
+ int32_t max_page_id =
GetMaxPageIDForSiteInstance(render_view_host->GetSiteInstance());
if (!static_cast<RenderViewHostImpl*>(render_view_host)
@@ -4405,7 +4548,7 @@ bool WebContentsImpl::CreateRenderViewForRenderManager(
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
// Force a ViewMsg_Resize to be sent, needed to make plugins show up on
// linux. See crbug.com/83941.
- RenderWidgetHostView* rwh_view = render_view_host->GetView();
+ RenderWidgetHostView* rwh_view = render_view_host->GetWidget()->GetView();
if (rwh_view) {
if (RenderWidgetHost* render_widget_host = rwh_view->GetRenderWidgetHost())
render_widget_host->WasResized();
@@ -4437,7 +4580,7 @@ bool WebContentsImpl::CreateRenderFrameForRenderManager(
return true;
}
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
base::android::ScopedJavaLocalRef<jobject>
WebContentsImpl::GetJavaWebContents() {
@@ -4517,11 +4660,11 @@ bool WebContentsImpl::IsHidden() {
return capturer_count_ == 0 && !should_normally_be_visible_;
}
-int WebContentsImpl::GetOuterDelegateFrameTreeNodeID() {
+int WebContentsImpl::GetOuterDelegateFrameTreeNodeId() {
if (node_ && node_->outer_web_contents())
return node_->outer_contents_frame_tree_node_id();
- return FrameTreeNode::kFrameTreeNodeInvalidID;
+ return FrameTreeNode::kFrameTreeNodeInvalidId;
}
RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
@@ -4559,20 +4702,6 @@ void WebContentsImpl::CreateBrowserPluginEmbedderIfNecessary() {
browser_plugin_embedder_.reset(BrowserPluginEmbedder::Create(this));
}
-void WebContentsImpl::ClearPowerSaveBlockers(
- RenderFrameHost* render_frame_host) {
- RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_);
- RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_);
- MaybeReleasePowerSaveBlockers();
-}
-
-void WebContentsImpl::ClearAllPowerSaveBlockers() {
- active_audio_players_.clear();
- active_video_players_.clear();
- audio_power_save_blocker_.reset();
- video_power_save_blocker_.reset();
-}
-
gfx::Size WebContentsImpl::GetSizeForNewRenderView() {
gfx::Size size;
if (delegate_)
@@ -4595,51 +4724,6 @@ void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
delegate_->UpdatePreferredSize(this, new_size);
}
-void WebContentsImpl::AddMediaPlayerEntry(int64 player_cookie,
- ActiveMediaPlayerMap* player_map) {
- if (!HasValidFrameSource())
- return;
-
- const uintptr_t key =
- reinterpret_cast<uintptr_t>(render_frame_message_source_);
- DCHECK(std::find((*player_map)[key].begin(),
- (*player_map)[key].end(),
- player_cookie) == (*player_map)[key].end());
- (*player_map)[key].push_back(player_cookie);
-}
-
-void WebContentsImpl::RemoveMediaPlayerEntry(int64 player_cookie,
- ActiveMediaPlayerMap* player_map) {
- if (!HasValidFrameSource())
- return;
-
- const uintptr_t key =
- reinterpret_cast<uintptr_t>(render_frame_message_source_);
- ActiveMediaPlayerMap::iterator it = player_map->find(key);
- if (it == player_map->end())
- return;
-
- // Remove the player.
- PlayerList::iterator player_it =
- std::find(it->second.begin(), it->second.end(), player_cookie);
- if (player_it != it->second.end())
- it->second.erase(player_it);
-
- // If there are no players left, remove the map entry.
- if (it->second.empty())
- player_map->erase(it);
-}
-
-void WebContentsImpl::RemoveAllMediaPlayerEntries(
- RenderFrameHost* render_frame_host,
- ActiveMediaPlayerMap* player_map) {
- ActiveMediaPlayerMap::iterator it =
- player_map->find(reinterpret_cast<uintptr_t>(render_frame_host));
- if (it == player_map->end())
- return;
- player_map->erase(it);
-}
-
WebUI* WebContentsImpl::CreateWebUI(const GURL& url,
const std::string& frame_name) {
WebUIImpl* web_ui = new WebUIImpl(this, frame_name);
@@ -4661,4 +4745,14 @@ void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
view_->SetOverscrollControllerEnabled(CanOverscrollContent());
}
+void WebContentsImpl::MediaStartedPlaying(
+ const WebContentsObserver::MediaPlayerId& id) {
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_, MediaStartedPlaying(id));
+}
+
+void WebContentsImpl::MediaStoppedPlaying(
+ const WebContentsObserver::MediaPlayerId& id) {
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_, MediaStoppedPlaying(id));
+}
+
} // namespace content
diff --git a/chromium/content/browser/web_contents/web_contents_impl.h b/chromium/content/browser/web_contents/web_contents_impl.h
index 9e779b8be76..f0e8b0b4d08 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.h
+++ b/chromium/content/browser/web_contents/web_contents_impl.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_IMPL_H_
#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_IMPL_H_
+#include <stdint.h>
+
#include <map>
#include <set>
#include <string>
@@ -12,10 +14,12 @@
#include "base/compiler_specific.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/process/process.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/navigation_controller_delegate.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
@@ -32,6 +36,7 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/page_importance_signals.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/resource_type.h"
@@ -43,13 +48,11 @@
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
-struct BrowserPluginHostMsg_ResizeGuest_Params;
struct ViewHostMsg_DateTimeDialogValue_Params;
namespace content {
class BrowserPluginEmbedder;
class BrowserPluginGuest;
-class BrowserPluginGuestManager;
class DateTimeChooserAndroid;
class DownloadItem;
class GeolocationServiceContext;
@@ -67,10 +70,10 @@ class SavePackage;
class ScreenOrientationDispatcherHost;
class SiteInstance;
class TestWebContents;
+class WakeLockServiceContext;
class WebContentsAudioMuter;
class WebContentsDelegate;
class WebContentsImpl;
-class WebContentsObserver;
class WebContentsView;
class WebContentsViewDelegate;
struct AXEventNotificationDetails;
@@ -80,7 +83,7 @@ struct LoadNotificationDetails;
struct ResourceRedirectDetails;
struct ResourceRequestDetails;
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
class WebContentsAndroid;
#endif
@@ -112,6 +115,8 @@ class CONTENT_EXPORT WebContentsImpl
static std::vector<WebContentsImpl*> GetAllWebContents();
static WebContentsImpl* FromFrameTreeNode(FrameTreeNode* frame_tree_node);
+ static WebContents* FromRenderFrameHostID(int render_process_host_id,
+ int render_frame_host_id);
// Creates a swapped out RenderView. This is used by the browser plugin to
// create a swapped out RenderView in the embedder render process for the
@@ -126,7 +131,7 @@ class CONTENT_EXPORT WebContentsImpl
// Returns the SavePackage which manages the page saving job. May be NULL.
SavePackage* save_package() const { return save_package_.get(); }
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
// In Android WebView, the RenderView needs created even there is no
// navigation entry, this allows Android WebViews to use
// javascript: URLs that load into the DOMWindow before the first page
@@ -219,7 +224,8 @@ class CONTENT_EXPORT WebContentsImpl
// Request a one-time snapshot of the accessibility tree without changing
// the accessibility mode.
using AXTreeSnapshotCallback =
- base::Callback<void(const ui::AXTreeUpdate<ui::AXNodeData>&)>;
+ base::Callback<void(
+ const ui::AXTreeUpdate&)>;
void RequestAXTreeSnapshot(AXTreeSnapshotCallback callback);
// WebContents ------------------------------------------------------
@@ -234,9 +240,11 @@ class CONTENT_EXPORT WebContentsImpl
RenderProcessHost* GetRenderProcessHost() const override;
RenderFrameHostImpl* GetMainFrame() override;
RenderFrameHostImpl* GetFocusedFrame() override;
+ RenderFrameHostImpl* FindFrameByFrameTreeNodeId(
+ int frame_tree_node_id) override;
void ForEachFrame(
const base::Callback<void(RenderFrameHost*)>& on_frame) override;
- void SendToAllFrames(IPC::Message* message) override;
+ int SendToAllFrames(IPC::Message* message) override;
RenderViewHostImpl* GetRenderViewHost() const override;
int GetRoutingID() const override;
RenderWidgetHostView* GetRenderWidgetHostView() const override;
@@ -258,8 +266,8 @@ class CONTENT_EXPORT WebContentsImpl
#endif
const PageImportanceSignals& GetPageImportanceSignals() const override;
const base::string16& GetTitle() const override;
- int32 GetMaxPageID() override;
- int32 GetMaxPageIDForSiteInstance(SiteInstance* site_instance) override;
+ int32_t GetMaxPageID() override;
+ int32_t GetMaxPageIDForSiteInstance(SiteInstance* site_instance) override;
SiteInstanceImpl* GetSiteInstance() const override;
SiteInstanceImpl* GetPendingSiteInstance() const override;
bool IsLoading() const override;
@@ -267,9 +275,8 @@ class CONTENT_EXPORT WebContentsImpl
bool IsWaitingForResponse() const override;
const net::LoadStateWithParam& GetLoadState() const override;
const base::string16& GetLoadStateHost() const override;
- uint64 GetUploadSize() const override;
- uint64 GetUploadPosition() const override;
- std::set<GURL> GetSitesInTab() const override;
+ uint64_t GetUploadSize() const override;
+ uint64_t GetUploadPosition() const override;
const std::string& GetEncoding() const override;
bool DisplayedInsecureContent() const override;
void IncrementCapturerCount(const gfx::Size& capture_size) override;
@@ -334,7 +341,7 @@ class CONTENT_EXPORT WebContentsImpl
const Referrer& referrer,
const std::string& headers) override;
void GenerateMHTML(const base::FilePath& file,
- const base::Callback<void(int64)>& callback) override;
+ const base::Callback<void(int64_t)>& callback) override;
const std::string& GetContentsMimeType() const override;
bool WillNotifyDisconnection() const override;
void SetOverrideEncoding(const std::string& encoding) override;
@@ -349,7 +356,7 @@ class CONTENT_EXPORT WebContentsImpl
void ViewFrameSource(const GURL& url, const PageState& page_state) override;
int GetMinimumZoomPercent() const override;
int GetMaximumZoomPercent() const override;
- void ResetPageScale() override;
+ void SetPageScale(float page_scale_factor) override;
gfx::Size GetPreferredSize() const override;
bool GotResponseToLockMouseRequest(bool allowed) override;
bool HasOpener() const override;
@@ -368,7 +375,8 @@ class CONTENT_EXPORT WebContentsImpl
void StopFinding(StopFindAction action) override;
void InsertCSS(const std::string& css) override;
bool WasRecentlyAudible() override;
- void GetManifest(const GetManifestCallback&) override;
+ void GetManifest(const GetManifestCallback& callback) override;
+ void HasManifest(const HasManifestCallback& callback) override;
void ExitFullscreen() override;
void ResumeLoadingCreatedWebContents() override;
#if defined(OS_ANDROID)
@@ -376,9 +384,10 @@ class CONTENT_EXPORT WebContentsImpl
void ResumeMediaSession() override;
void SuspendMediaSession() override;
void StopMediaSession() override;
-
+#if !defined(USE_AURA)
base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents() override;
virtual WebContentsAndroid* GetWebContentsAndroid();
+#endif // !USE_AURA
#elif defined(OS_MACOSX)
void SetAllowOtherViews(bool allow) override;
bool GetAllowOtherViews() override;
@@ -413,8 +422,10 @@ class CONTENT_EXPORT WebContentsImpl
void DidChangeName(RenderFrameHost* render_frame_host,
const std::string& name) override;
void DocumentOnLoadCompleted(RenderFrameHost* render_frame_host) override;
+ void UpdateStateForFrame(RenderFrameHost* render_frame_host,
+ const PageState& page_state) override;
void UpdateTitle(RenderFrameHost* render_frame_host,
- int32 page_id,
+ int32_t page_id,
const base::string16& title,
base::i18n::TextDirection title_direction) override;
void UpdateEncoding(RenderFrameHost* render_frame_host,
@@ -428,12 +439,14 @@ class CONTENT_EXPORT WebContentsImpl
RenderFrameHost* render_frame_host,
int browser_plugin_instance_id) override;
GeolocationServiceContext* GetGeolocationServiceContext() override;
+ WakeLockServiceContext* GetWakeLockServiceContext() override;
void EnterFullscreenMode(const GURL& origin) override;
void ExitFullscreenMode() override;
bool ShouldRouteMessageEvent(
RenderFrameHost* target_rfh,
SiteInstance* source_site_instance) const override;
void EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) override;
+ scoped_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(const GURL& url) override;
#if defined(OS_WIN)
gfx::NativeViewAccessible GetParentNativeViewAccessible() override;
#endif
@@ -445,7 +458,6 @@ class CONTENT_EXPORT WebContentsImpl
// RenderFrameHostDelegate has the same method, so list it there because this
// interface is going away.
// WebContents* GetAsWebContents() override;
- gfx::Rect GetRootWindowResizerRect() const override;
void RenderViewCreated(RenderViewHost* render_view_host) override;
void RenderViewReady(RenderViewHost* render_view_host) override;
void RenderViewTerminated(RenderViewHost* render_view_host,
@@ -453,7 +465,7 @@ class CONTENT_EXPORT WebContentsImpl
int error_code) override;
void RenderViewDeleted(RenderViewHost* render_view_host) override;
void UpdateState(RenderViewHost* render_view_host,
- int32 page_id,
+ int32_t page_id,
const PageState& page_state) override;
void UpdateTargetURL(RenderViewHost* render_view_host,
const GURL& url) override;
@@ -462,43 +474,34 @@ class CONTENT_EXPORT WebContentsImpl
void DidCancelLoading() override;
void DocumentAvailableInMainFrame(RenderViewHost* render_view_host) override;
void RouteCloseEvent(RenderViewHost* rvh) override;
- bool AddMessageToConsole(int32 level,
+ bool AddMessageToConsole(int32_t level,
const base::string16& message,
- int32 line_no,
+ int32_t line_no,
const base::string16& source_id) override;
RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const override;
- void OnUserGesture() override;
+ void OnUserInteraction(const blink::WebInputEvent::Type type) override;
void OnIgnoredUIEvent() override;
- void RendererUnresponsive(RenderViewHost* render_view_host) override;
- void RendererResponsive(RenderViewHost* render_view_host) override;
void LoadStateChanged(const GURL& url,
const net::LoadStateWithParam& load_state,
- uint64 upload_position,
- uint64 upload_size) override;
+ uint64_t upload_position,
+ uint64_t upload_size) override;
void Activate() override;
- void Deactivate() override;
- void LostCapture() override;
void RunFileChooser(RenderViewHost* render_view_host,
const FileChooserParams& params) override;
- bool IsFullscreenForCurrentTab() const override;
- blink::WebDisplayMode GetDisplayMode() const override;
void UpdatePreferredSize(const gfx::Size& pref_size) override;
- void ResizeDueToAutoResize(const gfx::Size& new_size) override;
- void RequestToLockMouse(bool user_gesture,
- bool last_unlocked_by_target) override;
- void LostMouseLock() override;
void CreateNewWindow(
SiteInstance* source_site_instance,
- int route_id,
- int main_frame_route_id,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) override;
- void CreateNewWidget(int32 render_process_id,
- int32 route_id,
+ void CreateNewWidget(int32_t render_process_id,
+ int32_t route_id,
blink::WebPopupType popup_type) override;
- void CreateNewFullscreenWidget(int32 render_process_id,
- int32 route_id) override;
+ void CreateNewFullscreenWidget(int32_t render_process_id,
+ int32_t route_id) override;
void ShowCreatedWindow(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
@@ -551,14 +554,12 @@ class CONTENT_EXPORT WebContentsImpl
void SetMainFrameMimeType(const std::string& mime_type) override;
bool CanOverscrollContent() const override;
void NotifyChangedNavigationState(InvalidateTypes changed_flags) override;
- void AboutToNavigateRenderFrame(
- RenderFrameHostImpl* old_host,
- RenderFrameHostImpl* new_host) override;
void DidStartNavigationToPendingEntry(
const GURL& url,
NavigationController::ReloadType reload_type) override;
void RequestOpenURL(RenderFrameHostImpl* render_frame_host,
const OpenURLParams& params) override;
+ bool ShouldTransferNavigation() override;
bool ShouldPreserveAbortedURLs() override;
void DidStartLoading(FrameTreeNode* frame_tree_node,
bool to_different_document) override;
@@ -567,15 +568,19 @@ class CONTENT_EXPORT WebContentsImpl
// RenderWidgetHostDelegate --------------------------------------------------
+ void RenderWidgetCreated(RenderWidgetHostImpl* render_widget_host) override;
void RenderWidgetDeleted(RenderWidgetHostImpl* render_widget_host) override;
void RenderWidgetGotFocus(RenderWidgetHostImpl* render_widget_host) override;
void RenderWidgetWasResized(RenderWidgetHostImpl* render_widget_host,
bool width_changed) override;
+ void ResizeDueToAutoResize(RenderWidgetHostImpl* render_widget_host,
+ const gfx::Size& new_size) override;
void ScreenInfoChanged() override;
bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) override;
void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override;
bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override;
+ void OnUserGesture(RenderWidgetHostImpl* render_widget_host) override;
bool PreHandleGestureEvent(const blink::WebGestureEvent& event) override;
void DidSendScreenRects(RenderWidgetHostImpl* rwh) override;
BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override;
@@ -591,6 +596,24 @@ class CONTENT_EXPORT WebContentsImpl
void AdjustSelectionByCharacterOffset(int start_adjust, int end_adjust)
override;
RenderWidgetHostInputEventRouter* GetInputEventRouter() override;
+ void ReplicatePageFocus(bool is_focused) override;
+ RenderWidgetHostImpl* GetFocusedRenderWidgetHost(
+ RenderWidgetHostImpl* receiving_widget) override;
+ void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) override;
+ void RendererResponsive(RenderWidgetHostImpl* render_widget_host) override;
+ void RequestToLockMouse(RenderWidgetHostImpl* render_widget_host,
+ bool user_gesture,
+ bool last_unlocked_by_target) override;
+ gfx::Rect GetRootWindowResizerRect(
+ RenderWidgetHostImpl* render_widget_host) const override;
+ bool IsFullscreenForCurrentTab(
+ RenderWidgetHostImpl* render_widget_host) const override;
+ blink::WebDisplayMode GetDisplayMode(
+ RenderWidgetHostImpl* render_widget_host) const override;
+ void LostCapture(RenderWidgetHostImpl* render_widget_host) override;
+ void LostMouseLock(RenderWidgetHostImpl* render_widget_host) override;
+ void ForwardCompositorProto(RenderWidgetHostImpl* render_widget_host,
+ const std::vector<uint8_t>& proto) override;
// RenderFrameHostManager::Delegate ------------------------------------------
@@ -622,12 +645,11 @@ class CONTENT_EXPORT WebContentsImpl
RenderViewHost* old_host,
RenderViewHost* new_host) override;
NavigationControllerImpl& GetControllerForRenderManager() override;
- scoped_ptr<WebUIImpl> CreateWebUIForRenderManager(const GURL& url) override;
NavigationEntry* GetLastCommittedNavigationEntryForRenderManager() override;
bool FocusLocationBarByDefault() override;
void SetFocusToLocationBar(bool select_all) override;
bool IsHidden() override;
- int GetOuterDelegateFrameTreeNodeID() override;
+ int GetOuterDelegateFrameTreeNodeId() override;
// NotificationObserver ------------------------------------------------------
@@ -654,12 +676,12 @@ class CONTENT_EXPORT WebContentsImpl
// Updates the max page ID for the current SiteInstance in this
// WebContentsImpl to be at least |page_id|.
- void UpdateMaxPageID(int32 page_id) override;
+ void UpdateMaxPageID(int32_t page_id) override;
// Updates the max page ID for the given SiteInstance in this WebContentsImpl
// to be at least |page_id|.
void UpdateMaxPageIDForSiteInstance(SiteInstance* site_instance,
- int32 page_id) override;
+ int32_t page_id) override;
// Copy the current map of SiteInstance ID to max page ID from another tab.
// This is necessary when this tab adopts the NavigationEntries from
@@ -698,19 +720,14 @@ class CONTENT_EXPORT WebContentsImpl
return &audio_stream_monitor_;
}
- bool has_audio_power_save_blocker_for_testing() const {
- return audio_power_save_blocker_;
- }
-
- bool has_video_power_save_blocker_for_testing() const {
- return video_power_save_blocker_;
- }
+ // Called by MediaWebContentsObserver when playback starts or stops. See the
+ // WebContentsObserver function stubs for more details.
+ void MediaStartedPlaying(const WebContentsObserver::MediaPlayerId& id);
+ void MediaStoppedPlaying(const WebContentsObserver::MediaPlayerId& id);
-#if defined(ENABLE_BROWSER_CDMS)
MediaWebContentsObserver* media_web_contents_observer() {
return media_web_contents_observer_.get();
}
-#endif
private:
friend class WebContentsObserver;
@@ -826,13 +843,20 @@ class CONTENT_EXPORT WebContentsImpl
const std::string& mime_type,
ResourceType resource_type);
void OnDidDisplayInsecureContent();
- void OnDidRunInsecureContent(const std::string& security_origin,
+ void OnDidRunInsecureContent(const GURL& security_origin,
const GURL& target_url);
+ void OnDidDisplayContentWithCertificateErrors(
+ const GURL& url,
+ const std::string& security_info);
+ void OnDidRunContentWithCertificateErrors(const GURL& security_origin,
+ const GURL& url,
+ const std::string& security_info);
void OnDocumentLoadedInFrame();
void OnDidFinishLoad(const GURL& url);
void OnGoToEntryAtOffset(int offset);
void OnUpdateZoomLimits(int minimum_percent,
int maximum_percent);
+ void OnPageScaleFactorChanged(float page_scale_factor);
void OnEnumerateDirectory(int request_id, const base::FilePath& path);
void OnRegisterProtocolHandler(const std::string& protocol,
@@ -847,7 +871,7 @@ class CONTENT_EXPORT WebContentsImpl
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update);
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
void OnFindMatchRectsReply(int version,
const std::vector<gfx::RectF>& rects,
const gfx::RectF& active_rect);
@@ -887,11 +911,6 @@ class CONTENT_EXPORT WebContentsImpl
#endif // defined(ENABLE_PLUGINS)
void OnUpdateFaviconURL(const std::vector<FaviconURL>& candidates);
void OnFirstVisuallyNonEmptyPaint();
- void OnMediaPlayingNotification(int64 player_cookie,
- bool has_video,
- bool has_audio,
- bool is_remote);
- void OnMediaPausedNotification(int64 player_cookie);
void OnShowValidationMessage(const gfx::Rect& anchor_in_root_view,
const base::string16& main_text,
const base::string16& sub_text);
@@ -930,8 +949,8 @@ class CONTENT_EXPORT WebContentsImpl
const base::string16& title);
// Helper for CreateNewWidget/CreateNewFullscreenWidget.
- void CreateNewWidget(int32 render_process_id,
- int32 route_id,
+ void CreateNewWidget(int32_t render_process_id,
+ int32_t route_id,
bool is_fullscreen,
blink::WebPopupType popup_type);
@@ -979,22 +998,6 @@ class CONTENT_EXPORT WebContentsImpl
// Removes browser plugin embedder if there is one.
void RemoveBrowserPluginEmbedder();
- // Clear |render_frame_host|'s tracking entry for its power save blockers.
- void ClearPowerSaveBlockers(RenderFrameHost* render_frame_host);
-
- // Clear tracking entries for all RenderFrameHosts, clears
- // |audio_power_save_blocker_| and |video_power_save_blocker_|.
- void ClearAllPowerSaveBlockers();
-
- // Creates an audio or video power save blocker respectively.
- void CreateAudioPowerSaveBlocker();
- void CreateVideoPowerSaveBlocker();
-
- // Releases the audio power save blockers if |active_audio_players_| is empty.
- // Likewise, releases the video power save blockers if |active_video_players_|
- // is empty.
- void MaybeReleasePowerSaveBlockers();
-
// Helper function to invoke WebContentsDelegate::GetSizeForNewRenderView().
gfx::Size GetSizeForNewRenderView();
@@ -1005,18 +1008,6 @@ class CONTENT_EXPORT WebContentsImpl
// |delegate_|.
void OnPreferredSizeChanged(const gfx::Size& old_size);
- // Helper methods for adding or removing player entries in |player_map| under
- // the key |render_frame_message_source_|.
- typedef std::vector<int64> PlayerList;
- typedef std::map<uintptr_t, PlayerList> ActiveMediaPlayerMap;
- void AddMediaPlayerEntry(int64 player_cookie,
- ActiveMediaPlayerMap* player_map);
- void RemoveMediaPlayerEntry(int64 player_cookie,
- ActiveMediaPlayerMap* player_map);
- // Removes all entries from |player_map| for |render_frame_host|.
- void RemoveAllMediaPlayerEntries(RenderFrameHost* render_frame_host,
- ActiveMediaPlayerMap* player_map);
-
// Internal helper to create WebUI objects associated with |this|. |url| is
// used to determine which WebUI should be created (if any). |frame_name|
// corresponds to the name of a frame that the WebUI should be created for (or
@@ -1068,12 +1059,6 @@ class CONTENT_EXPORT WebContentsImpl
// Helper classes ------------------------------------------------------------
- // Tracking variables and associated power save blockers for media playback.
- ActiveMediaPlayerMap active_audio_players_;
- ActiveMediaPlayerMap active_video_players_;
- scoped_ptr<PowerSaveBlocker> audio_power_save_blocker_;
- scoped_ptr<PowerSaveBlocker> video_power_save_blocker_;
-
// Manages the frame tree of the page and process swaps in each node.
FrameTree frame_tree_;
@@ -1105,7 +1090,7 @@ class CONTENT_EXPORT WebContentsImpl
// Map of SiteInstance ID to max page ID for this tab. A page ID is specific
// to a given tab and SiteInstance, and must be valid for the lifetime of the
// WebContentsImpl.
- std::map<int32, int32> max_page_ids_;
+ std::map<int32_t, int32_t> max_page_ids_;
// The current load state and the URL associated with it.
net::LoadStateWithParam load_state_;
@@ -1115,8 +1100,8 @@ class CONTENT_EXPORT WebContentsImpl
// Upload progress, for displaying in the status bar.
// Set to zero when there is no significant upload happening.
- uint64 upload_size_;
- uint64 upload_position_;
+ uint64_t upload_size_;
+ uint64_t upload_position_;
// Tracks that this WebContents needs to unblock requests to the renderer.
// See ResumeLoadingCreatedWebContents.
@@ -1197,6 +1182,9 @@ class CONTENT_EXPORT WebContentsImpl
int minimum_zoom_percent_;
int maximum_zoom_percent_;
+ // Used to correctly handle integer zooming through a smooth scroll device.
+ float zoom_scroll_remainder_;
+
// The intrinsic size of the page.
gfx::Size preferred_size_;
@@ -1204,7 +1192,7 @@ class CONTENT_EXPORT WebContentsImpl
// this overrides |preferred_size_|.
gfx::Size preferred_size_for_capture_;
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !defined(USE_AURA)
// Date time chooser opened by this tab.
// Only used in Android since all other platforms use a multi field UI.
scoped_ptr<DateTimeChooserAndroid> date_time_chooser_;
@@ -1287,6 +1275,8 @@ class CONTENT_EXPORT WebContentsImpl
scoped_ptr<GeolocationServiceContext> geolocation_service_context_;
+ scoped_ptr<WakeLockServiceContext> wake_lock_service_context_;
+
scoped_ptr<ScreenOrientationDispatcherHost>
screen_orientation_dispatcher_host_;
@@ -1304,15 +1294,15 @@ class CONTENT_EXPORT WebContentsImpl
bool virtual_keyboard_requested_;
-#if defined(ENABLE_BROWSER_CDMS)
- // Manages all the media player and CDM managers and forwards IPCs to them.
+ // Manages media players, CDMs, and power save blockers for media.
scoped_ptr<MediaWebContentsObserver> media_web_contents_observer_;
-#endif
scoped_ptr<RenderWidgetHostInputEventRouter> rwh_input_event_router_;
PageImportanceSignals page_importance_signals_;
+ bool page_scale_factor_is_one_;
+
base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebContentsImpl);
diff --git a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
index aa00317d4d4..532cf018ff7 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -27,6 +29,7 @@
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "testing/gmock/include/gmock/gmock.h"
namespace content {
@@ -142,7 +145,7 @@ class RenderViewSizeObserver : public WebContentsObserver {
// WebContentsObserver:
void RenderViewCreated(RenderViewHost* rvh) override {
- rwhv_create_size_ = rvh->GetView()->GetViewBounds().size();
+ rwhv_create_size_ = rvh->GetWidget()->GetView()->GetViewBounds().size();
}
void DidStartProvisionalLoadForFrame(
@@ -196,7 +199,7 @@ class LoadingStateChangedDelegate : public WebContentsDelegate {
// Test that DidStopLoading includes the correct URL in the details.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
MAYBE_DidStopLoadingDetails) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
LoadStopNotificationObserver load_observer(
&shell()->web_contents()->GetController());
@@ -221,7 +224,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
// pending entry is present.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
MAYBE_DidStopLoadingDetailsWithPending) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url("data:text/html,<div>test</div>");
// Listen for the first load to stop.
@@ -247,7 +250,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
// See http://crbug.com/280512.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
ClearNonVisiblePendingOnFail) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
@@ -279,12 +282,10 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
// WebContentsDelegate::GetSizeForNewRenderView().
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
MAYBE_GetSizeForNewRenderView) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
// Create a new server with a different site.
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS,
- net::SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server.Start());
scoped_ptr<RenderViewSizeDelegate> delegate(new RenderViewSizeDelegate());
@@ -374,9 +375,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, SetTitleOnUnload) {
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, OpenURLSubframe) {
// Navigate to a page with frames and grab a subframe's FrameTreeNode ID.
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
NavigateToURL(shell(),
- test_server()->GetURL("files/frame_tree/top.html"));
+ embedded_test_server()->GetURL("/frame_tree/top.html"));
WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
FrameTreeNode* root = wc->GetFrameTree()->root();
ASSERT_EQ(3UL, root->child_count());
@@ -384,7 +385,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, OpenURLSubframe) {
EXPECT_NE(-1, frame_tree_node_id);
// Navigate with the subframe's FrameTreeNode ID.
- const GURL url(test_server()->GetURL("files/title1.html"));
+ const GURL url(embedded_test_server()->GetURL("/title1.html"));
OpenURLParams params(url, Referrer(), frame_tree_node_id, CURRENT_TAB,
ui::PAGE_TRANSITION_LINK, true);
shell()->web_contents()->OpenURL(params);
@@ -443,14 +444,14 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
// Setup the server to allow serving separate sites, so we can perform
// cross-process navigation.
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
- foo_host_port = test_server()->host_port_pair();
+ foo_host_port = embedded_test_server()->host_port_pair();
foo_host_port.set_host(kFooCom);
- GURL initial_url(test_server()->GetURL("/title1.html"));
+ GURL initial_url(embedded_test_server()->GetURL("/title1.html"));
- cross_site_url = test_server()->GetURL("/title2.html");
+ cross_site_url = embedded_test_server()->GetURL("/title2.html");
replace_host.SetHostStr(kFooCom);
cross_site_url = cross_site_url.ReplaceComponents(replace_host);
@@ -471,7 +472,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
LoadingStateChangedForSameDocumentNavigation) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
scoped_ptr<LoadingStateChangedDelegate> delegate(
new LoadingStateChangedDelegate());
shell()->web_contents()->SetDelegate(delegate.get());
@@ -496,7 +497,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
RenderViewCreatedForChildWindow) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
NavigateToURL(shell(),
embedded_test_server()->GetURL("/title1.html"));
@@ -550,7 +551,7 @@ struct LoadProgressDelegateAndObserver : public WebContentsDelegate,
};
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgress) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
scoped_ptr<LoadProgressDelegateAndObserver> delegate(
new LoadProgressDelegateAndObserver(shell()));
@@ -572,7 +573,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgress) {
}
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgressWithFrames) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
scoped_ptr<LoadProgressDelegateAndObserver> delegate(
new LoadProgressDelegateAndObserver(shell()));
@@ -599,7 +600,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgressWithFrames) {
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
LoadProgressAfterInterruptedNav) {
host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
// Start at a real page.
NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
@@ -663,7 +664,7 @@ struct FirstVisuallyNonEmptyPaintObserver : public WebContentsObserver {
#endif
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
MAYBE_FirstVisuallyNonEmptyPaint) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
scoped_ptr<FirstVisuallyNonEmptyPaintObserver> observer(
new FirstVisuallyNonEmptyPaintObserver(shell()));
@@ -692,7 +693,7 @@ class WebDisplayModeDelegate : public WebContentsDelegate {
}
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ChangeDisplayMode) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
WebDisplayModeDelegate delegate(blink::WebDisplayModeMinimalUi);
shell()->web_contents()->SetDelegate(&delegate);
@@ -706,7 +707,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ChangeDisplayMode) {
delegate.set_mode(blink::WebDisplayModeFullscreen);
// Simulate widget is entering fullscreen (changing size is enough).
- shell()->web_contents()->GetRenderViewHost()->WasResized();
+ shell()->web_contents()->GetRenderViewHost()->GetWidget()->WasResized();
ASSERT_TRUE(ExecuteScript(shell()->web_contents(),
"document.title = "
@@ -715,8 +716,62 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ChangeDisplayMode) {
EXPECT_EQ(base::ASCIIToUTF16("true"), shell()->web_contents()->GetTitle());
}
+// Observer class used to verify that WebContentsObservers are notified
+// when the page scale factor changes.
+// See WebContentsImplBrowserTest.ChangePageScale.
+class MockPageScaleObserver : public WebContentsObserver {
+ public:
+ MockPageScaleObserver(Shell* shell)
+ : WebContentsObserver(shell->web_contents()),
+ got_page_scale_update_(false) {
+ // Once OnPageScaleFactorChanged is called, quit the run loop.
+ ON_CALL(*this, OnPageScaleFactorChanged(::testing::_)).WillByDefault(
+ ::testing::InvokeWithoutArgs(
+ this, &MockPageScaleObserver::GotPageScaleUpdate));
+ }
+
+ MOCK_METHOD1(OnPageScaleFactorChanged, void(float page_scale_factor));
+
+ void WaitForPageScaleUpdate() {
+ if (!got_page_scale_update_) {
+ base::RunLoop run_loop;
+ on_page_scale_update_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+ got_page_scale_update_ = false;
+ }
+
+ private:
+ void GotPageScaleUpdate() {
+ got_page_scale_update_ = true;
+ on_page_scale_update_.Run();
+ }
+
+ base::Closure on_page_scale_update_;
+ bool got_page_scale_update_;
+};
+
+// When the page scale factor is set in the renderer it should send
+// a notification to the browser so that WebContentsObservers are notified.
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ChangePageScale) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
+
+ MockPageScaleObserver observer(shell());
+ ::testing::InSequence expect_call_sequence;
+
+ shell()->web_contents()->SetPageScale(1.5);
+ EXPECT_CALL(observer, OnPageScaleFactorChanged(::testing::FloatEq(1.5)));
+ observer.WaitForPageScaleUpdate();
+
+ // Navigate to reset the page scale factor.
+ shell()->LoadURL(embedded_test_server()->GetURL("/title2.html"));
+ EXPECT_CALL(observer, OnPageScaleFactorChanged(::testing::_));
+ observer.WaitForPageScaleUpdate();
+}
+
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NewNamedWindow) {
- ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/click-noreferrer-links.html");
EXPECT_TRUE(NavigateToURL(shell(), url));
diff --git a/chromium/content/browser/web_contents/web_contents_impl_unittest.cc b/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
index 7dabef2c441..fef8e5bbc09 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -2,15 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+#include <utility>
+
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/cross_site_transferring_request.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/media/audio_stream_monitor.h"
+#include "content/browser/media/media_web_contents_observer.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
@@ -29,10 +35,9 @@
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_constants.h"
-#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
-#include "content/public/common/url_utils.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_utils.h"
#include "content/test/test_content_browser_client.h"
@@ -150,7 +155,8 @@ class TestInterstitialPage : public InterstitialPageImpl {
bool is_showing() const {
return static_cast<TestRenderWidgetHostView*>(
- GetMainFrame()->GetRenderViewHost()->GetView())->is_showing();
+ GetMainFrame()->GetRenderViewHost()->GetWidget()->GetView())
+ ->is_showing();
}
void ClearStates() {
@@ -244,6 +250,18 @@ class WebContentsImplTest : public RenderViewHostImplTestHarness {
ContentWebUIControllerFactory::GetInstance());
RenderViewHostImplTestHarness::TearDown();
}
+
+ bool has_audio_power_save_blocker() {
+ return contents()
+ ->media_web_contents_observer()
+ ->has_audio_power_save_blocker_for_testing();
+ }
+
+ bool has_video_power_save_blocker() {
+ return contents()
+ ->media_web_contents_observer()
+ ->has_video_power_save_blocker_for_testing();
+ }
};
class TestWebContentsObserver : public WebContentsObserver {
@@ -468,7 +486,7 @@ TEST_F(WebContentsImplTest, SimpleNavigation) {
TEST_F(WebContentsImplTest, NavigateToExcessivelyLongURL) {
// Construct a URL that's kMaxURLChars + 1 long of all 'a's.
const GURL url(std::string("http://example.org/").append(
- GetMaxURLChars() + 1, 'a'));
+ kMaxURLChars + 1, 'a'));
controller().LoadURL(
url, Referrer(), ui::PAGE_TRANSITION_GENERATED, std::string());
@@ -508,7 +526,7 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
// Keep the number of active frames in orig_rfh's SiteInstance non-zero so
// that orig_rfh doesn't get deleted when it gets swapped out.
- orig_rfh->GetSiteInstance()->increment_active_frame_count();
+ orig_rfh->GetSiteInstance()->IncrementActiveFrameCount();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(orig_rfh->GetRenderViewHost(), contents()->GetRenderViewHost());
@@ -520,10 +538,8 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
controller().LoadURL(
url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
entry_id = controller().GetPendingEntry()->GetUniqueID();
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
orig_rfh->PrepareForCommit();
- }
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(url, contents()->GetLastCommittedURL());
EXPECT_EQ(url2, contents()->GetVisibleURL());
@@ -533,8 +549,7 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
&pending_rvh_delete_count);
// Navigations should be suspended in pending_rfh until BeforeUnloadACK.
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (!IsBrowserSideNavigationEnabled()) {
EXPECT_TRUE(pending_rfh->are_navigations_suspended());
orig_rfh->SendBeforeUnloadACK(true);
EXPECT_FALSE(pending_rfh->are_navigations_suspended());
@@ -548,7 +563,7 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
// Keep the number of active frames in pending_rfh's SiteInstance
// non-zero so that orig_rfh doesn't get deleted when it gets
// swapped out.
- pending_rfh->GetSiteInstance()->increment_active_frame_count();
+ pending_rfh->GetSiteInstance()->IncrementActiveFrameCount();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(pending_rfh, contents()->GetMainFrame());
@@ -566,10 +581,8 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
// We should use the same RFH as before, swapping it back in.
controller().GoBack();
entry_id = controller().GetPendingEntry()->GetUniqueID();
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
contents()->GetMainFrame()->PrepareForCommit();
- }
TestRenderFrameHost* goback_rfh = contents()->GetPendingMainFrame();
if (!SiteIsolationPolicy::IsSwappedOutStateForbidden()) {
// Recycling the rfh is a behavior specific to swappedout://
@@ -578,8 +591,7 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
// Navigations should be suspended in goback_rfh until BeforeUnloadACK.
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (!IsBrowserSideNavigationEnabled()) {
EXPECT_TRUE(goback_rfh->are_navigations_suspended());
pending_rfh->SendBeforeUnloadACK(true);
EXPECT_FALSE(goback_rfh->are_navigations_suspended());
@@ -769,7 +781,7 @@ TEST_F(WebContentsImplTest, NavigateFromSitelessUrl) {
// Keep the number of active frames in orig_rfh's SiteInstance
// non-zero so that orig_rfh doesn't get deleted when it gets
// swapped out.
- orig_rfh->GetSiteInstance()->increment_active_frame_count();
+ orig_rfh->GetSiteInstance()->IncrementActiveFrameCount();
EXPECT_EQ(orig_instance, contents()->GetSiteInstance());
EXPECT_TRUE(
@@ -781,10 +793,8 @@ TEST_F(WebContentsImplTest, NavigateFromSitelessUrl) {
controller().LoadURL(
url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
entry_id = controller().GetPendingEntry()->GetUniqueID();
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
orig_rfh->PrepareForCommit();
- }
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(url, contents()->GetLastCommittedURL());
EXPECT_EQ(url2, contents()->GetVisibleURL());
@@ -794,8 +804,7 @@ TEST_F(WebContentsImplTest, NavigateFromSitelessUrl) {
&pending_rvh_delete_count);
// Navigations should be suspended in pending_rvh until BeforeUnloadACK.
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (!IsBrowserSideNavigationEnabled()) {
EXPECT_TRUE(pending_rfh->are_navigations_suspended());
orig_rfh->SendBeforeUnloadACK(true);
EXPECT_FALSE(pending_rfh->are_navigations_suspended());
@@ -837,13 +846,13 @@ TEST_F(WebContentsImplTest, NavigateFromRestoredSitelessUrl) {
// SiteInstance.
browser_client.set_assign_site_for_url(false);
const GURL native_url("non-site-url://stuffandthings");
- ScopedVector<NavigationEntry> entries;
+ std::vector<scoped_ptr<NavigationEntry>> entries;
scoped_ptr<NavigationEntry> new_entry =
NavigationControllerImpl::CreateNavigationEntry(
native_url, Referrer(), ui::PAGE_TRANSITION_LINK, false,
std::string(), browser_context());
new_entry->SetPageID(0);
- entries.push_back(new_entry.Pass());
+ entries.push_back(std::move(new_entry));
controller().Restore(
0,
NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
@@ -887,13 +896,13 @@ TEST_F(WebContentsImplTest, NavigateFromRestoredRegularUrl) {
// ShouldAssignSiteForUrl override is disabled (i.e. returns true).
browser_client.set_assign_site_for_url(true);
const GURL regular_url("http://www.yahoo.com");
- ScopedVector<NavigationEntry> entries;
+ std::vector<scoped_ptr<NavigationEntry>> entries;
scoped_ptr<NavigationEntry> new_entry =
NavigationControllerImpl::CreateNavigationEntry(
regular_url, Referrer(), ui::PAGE_TRANSITION_LINK, false,
std::string(), browser_context());
new_entry->SetPageID(0);
- entries.push_back(new_entry.Pass());
+ entries.push_back(std::move(new_entry));
controller().Restore(
0,
NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
@@ -1486,7 +1495,7 @@ TEST_F(WebContentsImplTest, NavigationEntryContentStateNewWindow) {
NavigationEntryImpl* entry_impl =
NavigationEntryImpl::FromNavigationEntry(entry);
EXPECT_FALSE(entry_impl->site_instance()->HasSite());
- int32 site_instance_id = entry_impl->site_instance()->GetId();
+ int32_t site_instance_id = entry_impl->site_instance()->GetId();
// Navigating to a normal page should not cause a process swap.
const GURL new_url("http://www.google.com");
@@ -1510,7 +1519,6 @@ TEST_F(WebContentsImplTest, NavigationExitsFullscreen) {
FakeFullscreenDelegate fake_delegate;
contents()->SetDelegate(&fake_delegate);
TestRenderFrameHost* orig_rfh = contents()->GetMainFrame();
- TestRenderViewHost* orig_rvh = orig_rfh->GetRenderViewHost();
// Navigate to a site.
const GURL url("http://www.google.com");
@@ -1523,13 +1531,11 @@ TEST_F(WebContentsImplTest, NavigationExitsFullscreen) {
EXPECT_EQ(orig_rfh, contents()->GetMainFrame());
// Toggle fullscreen mode on (as if initiated via IPC from renderer).
- EXPECT_FALSE(orig_rvh->IsFullscreenGranted());
- EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_FALSE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
orig_rfh->OnMessageReceived(
FrameHostMsg_ToggleFullscreen(orig_rfh->GetRoutingID(), true));
- EXPECT_TRUE(orig_rvh->IsFullscreenGranted());
- EXPECT_TRUE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_TRUE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_TRUE(fake_delegate.IsFullscreenForTabOrPending(contents()));
// Navigate to a new site.
@@ -1543,8 +1549,7 @@ TEST_F(WebContentsImplTest, NavigationExitsFullscreen) {
ui::PAGE_TRANSITION_TYPED);
// Confirm fullscreen has exited.
- EXPECT_FALSE(orig_rvh->IsFullscreenGranted());
- EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_FALSE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
contents()->SetDelegate(nullptr);
@@ -1555,8 +1560,7 @@ TEST_F(WebContentsImplTest, NavigationExitsFullscreen) {
TEST_F(WebContentsImplTest, HistoryNavigationExitsFullscreen) {
FakeFullscreenDelegate fake_delegate;
contents()->SetDelegate(&fake_delegate);
- TestRenderFrameHost* const orig_rfh = contents()->GetMainFrame();
- TestRenderViewHost* const orig_rvh = orig_rfh->GetRenderViewHost();
+ TestRenderFrameHost* orig_rfh = contents()->GetMainFrame();
// Navigate to a site.
const GURL url("http://www.google.com");
@@ -1580,16 +1584,14 @@ TEST_F(WebContentsImplTest, HistoryNavigationExitsFullscreen) {
EXPECT_EQ(orig_rfh, contents()->GetMainFrame());
// Sanity-check: Confirm we're not starting out in fullscreen mode.
- EXPECT_FALSE(orig_rvh->IsFullscreenGranted());
- EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_FALSE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
for (int i = 0; i < 2; ++i) {
// Toggle fullscreen mode on (as if initiated via IPC from renderer).
orig_rfh->OnMessageReceived(
FrameHostMsg_ToggleFullscreen(orig_rfh->GetRoutingID(), true));
- EXPECT_TRUE(orig_rvh->IsFullscreenGranted());
- EXPECT_TRUE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_TRUE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_TRUE(fake_delegate.IsFullscreenForTabOrPending(contents()));
// Navigate backward (or forward).
@@ -1606,8 +1608,8 @@ TEST_F(WebContentsImplTest, HistoryNavigationExitsFullscreen) {
orig_rfh->SimulateNavigationStop();
// Confirm fullscreen has exited.
- EXPECT_FALSE(orig_rvh->IsFullscreenGranted());
- EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_FALSE(
+ contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
}
@@ -1646,21 +1648,18 @@ TEST_F(WebContentsImplTest, CrashExitsFullscreen) {
url, ui::PAGE_TRANSITION_TYPED);
// Toggle fullscreen mode on (as if initiated via IPC from renderer).
- EXPECT_FALSE(test_rvh()->IsFullscreenGranted());
- EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_FALSE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
contents()->GetMainFrame()->OnMessageReceived(FrameHostMsg_ToggleFullscreen(
contents()->GetMainFrame()->GetRoutingID(), true));
- EXPECT_TRUE(test_rvh()->IsFullscreenGranted());
- EXPECT_TRUE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_TRUE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_TRUE(fake_delegate.IsFullscreenForTabOrPending(contents()));
// Crash the renderer.
main_test_rfh()->GetProcess()->SimulateCrash();
// Confirm fullscreen has exited.
- EXPECT_FALSE(test_rvh()->IsFullscreenGranted());
- EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
+ EXPECT_FALSE(contents()->IsFullscreenForCurrentTab(test_rvh()->GetWidget()));
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
contents()->SetDelegate(nullptr);
@@ -2692,7 +2691,7 @@ TEST_F(WebContentsImplTest, CapturerPreventsHiding) {
contents()->UpdatePreferredSize(original_preferred_size);
TestRenderWidgetHostView* view = static_cast<TestRenderWidgetHostView*>(
- contents()->GetMainFrame()->GetRenderViewHost()->GetView());
+ contents()->GetMainFrame()->GetRenderViewHost()->GetWidget()->GetView());
// With no capturers, setting and un-setting occlusion should change the
// view's occlusion state.
@@ -2719,7 +2718,7 @@ TEST_F(WebContentsImplTest, CapturerPreventsOcclusion) {
contents()->UpdatePreferredSize(original_preferred_size);
TestRenderWidgetHostView* view = static_cast<TestRenderWidgetHostView*>(
- contents()->GetMainFrame()->GetRenderViewHost()->GetView());
+ contents()->GetMainFrame()->GetRenderViewHost()->GetWidget()->GetView());
// With no capturers, setting and un-setting occlusion should change the
// view's occlusion state.
@@ -2803,13 +2802,14 @@ TEST_F(WebContentsImplTest, HandleWheelEvent) {
int modifiers = 0;
// Verify that normal mouse wheel events do nothing to change the zoom level.
blink::WebMouseWheelEvent event =
- SyntheticWebMouseWheelEventBuilder::Build(0, 1, modifiers, false);
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, 0, 1, modifiers, false);
EXPECT_FALSE(contents()->HandleWheelEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey |
WebInputEvent::ControlKey;
- event = SyntheticWebMouseWheelEventBuilder::Build(0, 1, modifiers, false);
+ event =
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, 0, 1, modifiers, false);
EXPECT_FALSE(contents()->HandleWheelEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
@@ -2817,7 +2817,8 @@ TEST_F(WebContentsImplTest, HandleWheelEvent) {
// increase/decrease zoom. Except on MacOS where we never want to adjust zoom
// with mousewheel.
modifiers = WebInputEvent::ControlKey;
- event = SyntheticWebMouseWheelEventBuilder::Build(0, 1, modifiers, false);
+ event =
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, 0, 1, modifiers, false);
event.canScroll = false;
bool handled = contents()->HandleWheelEvent(event);
#if defined(OS_MACOSX)
@@ -2831,7 +2832,8 @@ TEST_F(WebContentsImplTest, HandleWheelEvent) {
modifiers = WebInputEvent::ControlKey | WebInputEvent::ShiftKey |
WebInputEvent::AltKey;
- event = SyntheticWebMouseWheelEventBuilder::Build(2, -5, modifiers, false);
+ event =
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, 2, -5, modifiers, false);
event.canScroll = false;
handled = contents()->HandleWheelEvent(event);
#if defined(OS_MACOSX)
@@ -2844,7 +2846,8 @@ TEST_F(WebContentsImplTest, HandleWheelEvent) {
#endif
// Unless there is no vertical movement.
- event = SyntheticWebMouseWheelEventBuilder::Build(2, 0, modifiers, false);
+ event =
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, 2, 0, modifiers, false);
EXPECT_FALSE(contents()->HandleWheelEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
@@ -2852,7 +2855,8 @@ TEST_F(WebContentsImplTest, HandleWheelEvent) {
// zoom being adjusted, to avoid accidental adjustments caused by
// two-finger-scrolling on a touchpad.
modifiers = WebInputEvent::ControlKey;
- event = SyntheticWebMouseWheelEventBuilder::Build(0, 5, modifiers, true);
+ event =
+ SyntheticWebMouseWheelEventBuilder::Build(0, 0, 0, 5, modifiers, true);
EXPECT_FALSE(contents()->HandleWheelEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
@@ -2927,10 +2931,8 @@ TEST_F(WebContentsImplTest, ActiveContentsCountNavigate) {
ui::PAGE_TRANSITION_TYPED,
std::string());
int entry_id = contents->GetController().GetPendingEntry()->GetUniqueID();
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (IsBrowserSideNavigationEnabled())
contents->GetMainFrame()->PrepareForCommit();
- }
EXPECT_TRUE(contents->CrossProcessNavigationPending());
EXPECT_EQ(1u, instance->GetRelatedActiveContentsCount());
contents->GetPendingMainFrame()->SendNavigate(1, entry_id, true, kUrl);
@@ -3197,15 +3199,16 @@ TEST_F(WebContentsImplTest, NoEarlyStop) {
}
TEST_F(WebContentsImplTest, MediaPowerSaveBlocking) {
- // PlayerIDs are actually pointers cast to int64, so verify that both negative
+ // PlayerIDs are actually pointers cast to int64_t, so verify that both
+ // negative
// and positive player ids don't blow up.
const int kPlayerAudioVideoId = 15;
const int kPlayerAudioOnlyId = -15;
const int kPlayerVideoOnlyId = 30;
const int kPlayerRemoteId = -30;
- EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing());
- EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing());
+ EXPECT_FALSE(has_audio_power_save_blocker());
+ EXPECT_FALSE(has_video_power_save_blocker());
TestRenderFrameHost* rfh = contents()->GetMainFrame();
AudioStreamMonitor* monitor = contents()->audio_stream_monitor();
@@ -3220,13 +3223,13 @@ TEST_F(WebContentsImplTest, MediaPowerSaveBlocking) {
// blocker should be created.
monitor->set_was_recently_audible_for_testing(true);
contents()->NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
- EXPECT_TRUE(contents()->has_audio_power_save_blocker_for_testing());
+ EXPECT_TRUE(has_audio_power_save_blocker());
// Send another fake notification, this time when WasRecentlyAudible() will
// be false. The power save blocker should be released.
monitor->set_was_recently_audible_for_testing(false);
contents()->NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
- EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing());
+ EXPECT_FALSE(has_audio_power_save_blocker());
}
// Start a player with both audio and video. A video power save blocker
@@ -3234,84 +3237,84 @@ TEST_F(WebContentsImplTest, MediaPowerSaveBlocking) {
// save blocker should be created too.
rfh->OnMessageReceived(FrameHostMsg_MediaPlayingNotification(
0, kPlayerAudioVideoId, true, true, false));
- EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(),
+ EXPECT_TRUE(has_video_power_save_blocker());
+ EXPECT_EQ(has_audio_power_save_blocker(),
!AudioStreamMonitor::monitoring_available());
// Upon hiding the video power save blocker should be released.
contents()->WasHidden();
- EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing());
+ EXPECT_FALSE(has_video_power_save_blocker());
// Start another player that only has video. There should be no change in
// the power save blockers. The notification should take into account the
// visibility state of the WebContents.
rfh->OnMessageReceived(FrameHostMsg_MediaPlayingNotification(
0, kPlayerVideoOnlyId, true, false, false));
- EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(),
+ EXPECT_FALSE(has_video_power_save_blocker());
+ EXPECT_EQ(has_audio_power_save_blocker(),
!AudioStreamMonitor::monitoring_available());
// Showing the WebContents should result in the creation of the blocker.
contents()->WasShown();
- EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing());
+ EXPECT_TRUE(has_video_power_save_blocker());
// Start another player that only has audio. There should be no change in
// the power save blockers.
rfh->OnMessageReceived(FrameHostMsg_MediaPlayingNotification(
0, kPlayerAudioOnlyId, false, true, false));
- EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(),
+ EXPECT_TRUE(has_video_power_save_blocker());
+ EXPECT_EQ(has_audio_power_save_blocker(),
!AudioStreamMonitor::monitoring_available());
// Start a remote player. There should be no change in the power save
// blockers.
rfh->OnMessageReceived(FrameHostMsg_MediaPlayingNotification(
0, kPlayerRemoteId, true, true, true));
- EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(),
+ EXPECT_TRUE(has_video_power_save_blocker());
+ EXPECT_EQ(has_audio_power_save_blocker(),
!AudioStreamMonitor::monitoring_available());
// Destroy the original audio video player. Both power save blockers should
// remain.
rfh->OnMessageReceived(
FrameHostMsg_MediaPausedNotification(0, kPlayerAudioVideoId));
- EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(),
+ EXPECT_TRUE(has_video_power_save_blocker());
+ EXPECT_EQ(has_audio_power_save_blocker(),
!AudioStreamMonitor::monitoring_available());
// Destroy the audio only player. The video power save blocker should remain.
rfh->OnMessageReceived(
FrameHostMsg_MediaPausedNotification(0, kPlayerAudioOnlyId));
- EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing());
+ EXPECT_TRUE(has_video_power_save_blocker());
+ EXPECT_FALSE(has_audio_power_save_blocker());
// Destroy the video only player. No power save blockers should remain.
rfh->OnMessageReceived(
FrameHostMsg_MediaPausedNotification(0, kPlayerVideoOnlyId));
- EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing());
+ EXPECT_FALSE(has_video_power_save_blocker());
+ EXPECT_FALSE(has_audio_power_save_blocker());
// Destroy the remote player. No power save blockers should remain.
rfh->OnMessageReceived(
FrameHostMsg_MediaPausedNotification(0, kPlayerRemoteId));
- EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing());
+ EXPECT_FALSE(has_video_power_save_blocker());
+ EXPECT_FALSE(has_audio_power_save_blocker());
// Start a player with both audio and video. A video power save blocker
// should be created. If audio stream monitoring is available, an audio power
// save blocker should be created too.
rfh->OnMessageReceived(FrameHostMsg_MediaPlayingNotification(
0, kPlayerAudioVideoId, true, true, false));
- EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(),
+ EXPECT_TRUE(has_video_power_save_blocker());
+ EXPECT_EQ(has_audio_power_save_blocker(),
!AudioStreamMonitor::monitoring_available());
// Crash the renderer.
contents()->GetMainFrame()->GetProcess()->SimulateCrash();
// Verify that all the power save blockers have been released.
- EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing());
- EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing());
+ EXPECT_FALSE(has_video_power_save_blocker());
+ EXPECT_FALSE(has_audio_power_save_blocker());
}
TEST_F(WebContentsImplTest, ThemeColorChangeDependingOnFirstVisiblePaint) {
diff --git a/chromium/content/browser/web_contents/web_contents_view.h b/chromium/content/browser/web_contents/web_contents_view.h
index 439dda4fbcf..cbca3845b5d 100644
--- a/chromium/content/browser/web_contents/web_contents_view.h
+++ b/chromium/content/browser/web_contents/web_contents_view.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
diff --git a/chromium/content/browser/web_contents/web_contents_view_android.cc b/chromium/content/browser/web_contents/web_contents_view_android.cc
index 48ccdc5458e..0716d13d2fb 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_android.cc
@@ -11,6 +11,7 @@
#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/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents_delegate.h"
namespace content {
@@ -48,6 +49,7 @@ void WebContentsViewAndroid::SetContentViewCore(
web_contents_->GetInterstitialPage()
->GetMainFrame()
->GetRenderViewHost()
+ ->GetWidget()
->GetView());
if (rwhv)
rwhv->SetContentViewCore(content_view_core_);
@@ -55,11 +57,11 @@ void WebContentsViewAndroid::SetContentViewCore(
}
gfx::NativeView WebContentsViewAndroid::GetNativeView() const {
- return content_view_core_ ? content_view_core_->GetViewAndroid() : NULL;
+ return content_view_core_ ? content_view_core_ : NULL;
}
gfx::NativeView WebContentsViewAndroid::GetContentNativeView() const {
- return content_view_core_ ? content_view_core_->GetViewAndroid() : NULL;
+ return content_view_core_ ? content_view_core_ : NULL;
}
gfx::NativeWindow WebContentsViewAndroid::GetTopLevelNativeWindow() const {
diff --git a/chromium/content/browser/web_contents/web_contents_view_android.h b/chromium/content/browser/web_contents/web_contents_view_android.h
index 9f7216f6577..6b135dc214c 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.h
+++ b/chromium/content/browser/web_contents/web_contents_view_android.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_ANDROID_H_
#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_ANDROID_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/web_contents/web_contents_view.h"
diff --git a/chromium/content/browser/web_contents/web_contents_view_aura.cc b/chromium/content/browser/web_contents/web_contents_view_aura.cc
index e6c144b50a4..a899bf33104 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.cc
@@ -4,10 +4,15 @@
#include "content/browser/web_contents/web_contents_view_aura.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/download/drag_download_util.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
@@ -218,10 +223,10 @@ void PrepareDragForDownload(
}
#endif // defined(OS_WIN)
-// Returns the CustomFormat to store file system files.
-const ui::OSExchangeData::CustomFormat& GetFileSystemFileCustomFormat() {
+// Returns the FormatType to store file system files.
+const ui::Clipboard::FormatType& GetFileSystemFileFormatType() {
static const char kFormatString[] = "chromium/x-file-system-files";
- CR_DEFINE_STATIC_LOCAL(ui::OSExchangeData::CustomFormat,
+ CR_DEFINE_STATIC_LOCAL(ui::Clipboard::FormatType,
format,
(ui::Clipboard::GetFormatType(kFormatString)));
return format;
@@ -251,7 +256,7 @@ bool ReadFileSystemFilesFromPickle(
for (size_t i = 0; i < num_files; ++i) {
std::string url_string;
- int64 size = 0;
+ int64_t size = 0;
if (!iter.ReadString(&url_string) || !iter.ReadInt64(&size))
return false;
@@ -298,7 +303,7 @@ void PrepareDragData(const DropData& drop_data,
if (!drop_data.file_system_files.empty()) {
base::Pickle pickle;
WriteFileSystemFilesToPickle(drop_data.file_system_files, &pickle);
- provider->SetPickledData(GetFileSystemFileCustomFormat(), pickle);
+ provider->SetPickledData(GetFileSystemFileFormatType(), pickle);
}
if (!drop_data.custom_data.empty()) {
base::Pickle pickle;
@@ -338,7 +343,7 @@ void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) {
base::Pickle pickle;
std::vector<DropData::FileSystemFileInfo> file_system_files;
- if (data.GetPickledData(GetFileSystemFileCustomFormat(), &pickle) &&
+ if (data.GetPickledData(GetFileSystemFileFormatType(), &pickle) &&
ReadFileSystemFilesFromPickle(pickle, &file_system_files))
drop_data->file_system_files = file_system_files;
@@ -455,7 +460,7 @@ class WebContentsViewAura::WindowObserver
}
void OnWillRemoveWindow(aura::Window* window) override {
- if (window == view_->window_)
+ if (window == view_->window_.get())
return;
window->RemoveObserver(this);
@@ -463,8 +468,7 @@ class WebContentsViewAura::WindowObserver
}
void OnWindowVisibilityChanged(aura::Window* window, bool visible) override {
- if (window == view_->window_ ||
- window->parent() == host_window_ ||
+ if (window == view_->window_.get() || window->parent() == host_window_ ||
window->parent() == view_->window_->GetRootWindow()) {
UpdateConstrainedWindows(NULL);
}
@@ -473,7 +477,7 @@ class WebContentsViewAura::WindowObserver
void OnWindowParentChanged(aura::Window* window,
aura::Window* parent) override {
- if (window != view_->window_)
+ if (window != view_->window_.get())
return;
aura::Window* host_window =
@@ -529,7 +533,7 @@ class WebContentsViewAura::WindowObserver
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) override {
- if (window == host_window_ || window == view_->window_) {
+ if (window == host_window_ || window == view_->window_.get()) {
SendScreenRects();
if (old_bounds.origin() != new_bounds.origin()) {
TouchSelectionControllerClientAura* selection_controller_client =
@@ -552,7 +556,7 @@ class WebContentsViewAura::WindowObserver
}
void OnWindowAddedToRootWindow(aura::Window* window) override {
- if (window == view_->window_) {
+ if (window == view_->window_.get()) {
window->GetHost()->AddObserver(this);
#if defined(OS_WIN)
if (!window->GetRootWindow()->HasObserver(this))
@@ -563,7 +567,7 @@ class WebContentsViewAura::WindowObserver
void OnWindowRemovingFromRootWindow(aura::Window* window,
aura::Window* new_root) override {
- if (window == view_->window_) {
+ if (window == view_->window_.get()) {
window->GetHost()->RemoveObserver(this);
#if defined(OS_WIN)
window->GetRootWindow()->RemoveObserver(this);
@@ -571,7 +575,7 @@ class WebContentsViewAura::WindowObserver
const aura::Window::Windows& root_children =
window->GetRootWindow()->children();
for (size_t i = 0; i < root_children.size(); ++i) {
- if (root_children[i] != view_->window_ &&
+ if (root_children[i] != view_->window_.get() &&
root_children[i] != host_window_) {
root_children[i]->RemoveObserver(this);
}
@@ -593,8 +597,9 @@ class WebContentsViewAura::WindowObserver
private:
void SendScreenRects() {
- RenderWidgetHostImpl::From(view_->web_contents_->GetRenderViewHost())->
- SendScreenRects();
+ RenderWidgetHostImpl::From(
+ view_->web_contents_->GetRenderViewHost()->GetWidget())
+ ->SendScreenRects();
}
#if defined(OS_WIN)
@@ -687,7 +692,7 @@ void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) {
gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
gfx::Point client_loc = screen_loc;
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
- aura::Window* window = rvh->GetView()->GetNativeView();
+ aura::Window* window = rvh->GetWidget()->GetView()->GetNativeView();
aura::Window::ConvertPointToTarget(root_window, window, &client_loc);
if (!web_contents_)
return;
@@ -847,10 +852,8 @@ void WebContentsViewAura::CreateView(
// It should be OK to not set a default parent since such users will
// explicitly add this WebContentsViewAura to their tree after they create
// us.
- if (root_window) {
- aura::client::ParentWindowWithContext(
- window_.get(), root_window, root_window->GetBoundsInScreen());
- }
+ aura::client::ParentWindowWithContext(window_.get(), root_window,
+ root_window->GetBoundsInScreen());
}
window_->layer()->SetMasksToBounds(true);
window_->SetName("WebContentsViewAura");
@@ -885,8 +888,7 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
RenderWidgetHostViewAura* view =
new RenderWidgetHostViewAura(render_widget_host, is_guest_view_hack);
- view->InitAsChild(NULL);
- GetNativeView()->AddChild(view->GetNativeView());
+ view->InitAsChild(GetNativeView());
RenderWidgetHostImpl* host_impl =
RenderWidgetHostImpl::From(render_widget_host);
@@ -943,9 +945,12 @@ void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
const ContextMenuParams& params) {
- ui::TouchSelectionController* selection_controller = GetSelectionController();
- if (selection_controller)
- selection_controller->HideAndDisallowShowingAutomatically();
+ TouchSelectionControllerClientAura* selection_controller_client =
+ GetSelectionControllerClient();
+ if (selection_controller_client &&
+ selection_controller_client->HandleContextMenu(params)) {
+ return;
+ }
if (delegate_) {
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
web_contents_->GetRenderWidgetHostView());
@@ -1187,20 +1192,14 @@ void WebContentsViewAura::OnMouseEvent(ui::MouseEvent* event) {
if (!web_contents_->GetDelegate())
return;
- switch (event->type()) {
- case ui::ET_MOUSE_PRESSED:
+ ui::EventType type = event->type();
+ if (type == ui::ET_MOUSE_PRESSED)
web_contents_->GetDelegate()->ActivateContents(web_contents_);
- break;
- case ui::ET_MOUSE_MOVED:
- case ui::ET_MOUSE_EXITED:
- web_contents_->GetDelegate()->ContentsMouseEvent(
- web_contents_,
- gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
- event->type() == ui::ET_MOUSE_MOVED);
- break;
- default:
- break;
- }
+
+ web_contents_->GetDelegate()->ContentsMouseEvent(
+ web_contents_,
+ gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
+ type == ui::ET_MOUSE_MOVED, type == ui::ET_MOUSE_EXITED);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chromium/content/browser/web_contents/web_contents_view_aura.h b/chromium/content/browser/web_contents/web_contents_view_aura.h
index 0d84b5acb5c..70c29b0583b 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.h
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
diff --git a/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index fbaa6f4240f..8d08134b629 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -4,17 +4,18 @@
#include "content/browser/web_contents/web_contents_view_aura.h"
+#include <stddef.h>
+
#include "base/command_line.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_timeouts.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
+#include "build/build_config.h"
#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"
@@ -26,6 +27,7 @@
#include "content/common/view_messages.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
@@ -35,6 +37,7 @@
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
@@ -43,6 +46,10 @@
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
namespace {
// TODO(tdresser): Find a way to avoid sleeping like this. See crbug.com/405282
@@ -174,7 +181,7 @@ class NavigationWatcher : public WebContentsObserver {
NavigationController::ReloadType reload_type) override {
navigated_ = true;
if (should_quit_loop_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
bool navigated_;
@@ -249,8 +256,12 @@ class WebContentsViewAuraTest : public ContentBrowserTest {
// size to the root window. Returns after the navigation to the url is
// complete.
void StartTestWithPage(const std::string& url) {
- ASSERT_TRUE(test_server()->Start());
- GURL test_url(test_server()->GetURL(url));
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL test_url;
+ if (url == "about:blank")
+ test_url = GURL(url);
+ else
+ test_url = GURL(embedded_test_server()->GetURL(url));
NavigateToURL(shell(), test_url);
WebContentsImpl* web_contents =
@@ -270,8 +281,7 @@ class WebContentsViewAuraTest : public ContentBrowserTest {
}
void TestOverscrollNavigation(bool touch_handler) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
NavigationController& controller = web_contents->GetController();
@@ -396,7 +406,7 @@ class WebContentsViewAuraTest : public ContentBrowserTest {
RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
return static_cast<RenderWidgetHostViewBase*>(
- GetRenderViewHost()->GetView());
+ GetRenderViewHost()->GetWidget()->GetView());
}
InputEventMessageFilterWaitsForAcks* filter() {
@@ -466,8 +476,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
#endif
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
MAYBE_QuickOverscrollDirectionChange) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderFrameHost* main_frame = web_contents->GetMainFrame();
@@ -490,17 +499,18 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
gfx::Rect bounds = content->GetBoundsInRootWindow();
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
- gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
- 0, timestamp);
+ ui::TouchEvent press(
+ ui::ET_TOUCH_PRESSED,
+ gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), 0,
+ timestamp);
ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(1, GetCurrentIndex());
timestamp += base::TimeDelta::FromMilliseconds(10);
ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
- gfx::Point(bounds.right() - 10, bounds.y() + 5),
- 0, timestamp);
+ gfx::Point(bounds.right() - 10, bounds.y() + 5), 0,
+ timestamp);
details = dispatcher->OnEventFromSource(&move1);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(1, GetCurrentIndex());
@@ -510,9 +520,8 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
for (int x = bounds.right() - 10; x >= bounds.x() + 10; x-= 10) {
timestamp += base::TimeDelta::FromMilliseconds(10);
- ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
- gfx::Point(x, bounds.y() + 5),
- 0, timestamp);
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, gfx::Point(x, bounds.y() + 5), 0,
+ timestamp);
details = dispatcher->OnEventFromSource(&inc);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(1, GetCurrentIndex());
@@ -520,9 +529,8 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
for (int x = bounds.x() + 10; x <= bounds.width() - 10; x+= 10) {
timestamp += base::TimeDelta::FromMilliseconds(10);
- ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
- gfx::Point(x, bounds.y() + 5),
- 0, timestamp);
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, gfx::Point(x, bounds.y() + 5), 0,
+ timestamp);
details = dispatcher->OnEventFromSource(&inc);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(1, GetCurrentIndex());
@@ -530,9 +538,8 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
for (int x = bounds.width() - 10; x >= bounds.x() + 10; x-= 10) {
timestamp += base::TimeDelta::FromMilliseconds(10);
- ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
- gfx::Point(x, bounds.y() + 5),
- 0, timestamp);
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, gfx::Point(x, bounds.y() + 5), 0,
+ timestamp);
details = dispatcher->OnEventFromSource(&inc);
ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(1, GetCurrentIndex());
@@ -564,8 +571,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollScreenshot) {
}
#endif
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderFrameHost* main_frame = web_contents->GetMainFrame();
@@ -654,13 +660,10 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollScreenshot) {
// RenderViewHost to be swapped out.
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
MAYBE_ScreenshotForSwappedOutRenderViews) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
// Create a new server with a different site.
- net::SpawnedTestServer https_server(
- net::SpawnedTestServer::TYPE_HTTPS,
- net::SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server.Start());
WebContentsImpl* web_contents =
@@ -671,14 +674,13 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
GURL url;
int transition;
} navigations[] = {
- { https_server.GetURL("files/title1.html"),
- ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
- { test_server()->GetURL("files/title2.html"),
- ui::PAGE_TRANSITION_AUTO_BOOKMARK },
- { https_server.GetURL("files/title3.html"),
- ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
- { GURL(), 0 }
- };
+ {https_server.GetURL("/title1.html"),
+ ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR},
+ {embedded_test_server()->GetURL("/title2.html"),
+ ui::PAGE_TRANSITION_AUTO_BOOKMARK},
+ {https_server.GetURL("/title3.html"),
+ ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR},
+ {GURL(), 0}};
screenshot_manager()->Reset();
for (int i = 0; !navigations[i].url.is_empty(); ++i) {
@@ -723,8 +725,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
// Tests that navigations resulting from reloads, history.replaceState,
// and history.pushState do not capture screenshots.
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ReplaceStateReloadPushState) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
RenderFrameHost* main_frame = web_contents->GetMainFrame();
@@ -762,8 +763,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ReplaceStateReloadPushState) {
// better.
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
DISABLED_ContentWindowReparent) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
scoped_ptr<aura::Window> window(new aura::Window(NULL));
window->Init(ui::LAYER_NOT_DRAWN);
@@ -786,8 +786,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
}
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ContentWindowClose) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
@@ -819,8 +818,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ContentWindowClose) {
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
MAYBE_RepeatedQuickOverscrollGestures) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
@@ -874,7 +872,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
// Verify that hiding a parent of the renderer will hide the content too.
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, HideContentOnParenHide) {
- ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/title1.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/title1.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
aura::Window* content = web_contents->GetNativeView()->parent();
@@ -888,8 +886,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, HideContentOnParenHide) {
// Ensure that SnapToPhysicalPixelBoundary() is called on WebContentsView parent
// change. This is a regression test for http://crbug.com/388908.
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, WebContentsViewReparent) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
scoped_ptr<aura::Window> window(new aura::Window(NULL));
window->Init(ui::LAYER_NOT_DRAWN);
@@ -919,8 +916,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, WebContentsViewReparent) {
// a non-scrollable area, except during gesture-nav.
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
MAYBE_OverscrollNavigationTouchThrottling) {
- ASSERT_NO_FATAL_FAILURE(
- StartTestWithPage("files/overscroll_navigation.html"));
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
AddInputEventMessageFilter();
@@ -1035,11 +1031,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_VerticalOverscroll) {
int kXStep = bounds.width() / 10;
gfx::Point location(bounds.right() - kXStep, bounds.y() + 5);
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::TouchEvent press(
- ui::ET_TOUCH_PRESSED,
- location,
- 0,
- timestamp);
+ ui::TouchEvent press(ui::ET_TOUCH_PRESSED, location, 0, timestamp);
ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
ASSERT_FALSE(details.dispatcher_destroyed);
WaitAFrame();
@@ -1071,11 +1063,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_VerticalOverscroll) {
int kYStep = bounds.height() / 10;
gfx::Point location(bounds.x() + 10, bounds.y() + kYStep);
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::TouchEvent press(
- ui::ET_TOUCH_PRESSED,
- location,
- 0,
- timestamp);
+ ui::TouchEvent press(ui::ET_TOUCH_PRESSED, location, 0, timestamp);
ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
ASSERT_FALSE(details.dispatcher_destroyed);
WaitAFrame();
@@ -1109,11 +1097,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_VerticalOverscroll) {
int kYStep = bounds.height() / 10;
gfx::Point location = bounds.origin() + gfx::Vector2d(0, kYStep);
base::TimeDelta timestamp = ui::EventTimeForNow();
- ui::TouchEvent press(
- ui::ET_TOUCH_PRESSED,
- location,
- 0,
- timestamp);
+ ui::TouchEvent press(ui::ET_TOUCH_PRESSED, location, 0, timestamp);
ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
ASSERT_FALSE(details.dispatcher_destroyed);
WaitAFrame();
diff --git a/chromium/content/browser/web_contents/web_contents_view_guest.cc b/chromium/content/browser/web_contents/web_contents_view_guest.cc
index 940b4209b1e..5f6b51821fe 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.cc
@@ -4,6 +4,8 @@
#include "content/browser/web_contents/web_contents_view_guest.h"
+#include <utility>
+
#include "build/build_config.h"
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
@@ -35,11 +37,12 @@ WebContentsViewGuest::WebContentsViewGuest(
WebContentsImpl* web_contents,
BrowserPluginGuest* guest,
scoped_ptr<WebContentsView> platform_view,
- RenderViewHostDelegateView* platform_view_delegate_view)
+ RenderViewHostDelegateView** delegate_view)
: web_contents_(web_contents),
guest_(guest),
- platform_view_(platform_view.Pass()),
- platform_view_delegate_view_(platform_view_delegate_view) {
+ platform_view_(std::move(platform_view)),
+ platform_view_delegate_view_(*delegate_view) {
+ *delegate_view = this;
}
WebContentsViewGuest::~WebContentsViewGuest() {
diff --git a/chromium/content/browser/web_contents/web_contents_view_guest.h b/chromium/content/browser/web_contents/web_contents_view_guest.h
index f2a10c86816..7f2df7f9e61 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.h
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.h
@@ -7,7 +7,9 @@
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/content_export.h"
@@ -30,7 +32,7 @@ class WebContentsViewGuest : public WebContentsView,
WebContentsViewGuest(WebContentsImpl* web_contents,
BrowserPluginGuest* guest,
scoped_ptr<WebContentsView> platform_view,
- RenderViewHostDelegateView* platform_view_delegate_view);
+ RenderViewHostDelegateView** delegate_view);
~WebContentsViewGuest() override;
WebContents* web_contents();
diff --git a/chromium/content/browser/web_contents/web_contents_view_mac.h b/chromium/content/browser/web_contents/web_contents_view_mac.h
index d116d7d2a33..62a8b34219f 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.h
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.h
@@ -11,6 +11,7 @@
#include <vector>
#include "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/web_contents/web_contents_view.h"
@@ -38,7 +39,10 @@ class Vector2d;
CONTENT_EXPORT
@interface WebContentsViewCocoa : BaseView {
@private
- content::WebContentsViewMac* webContentsView_; // WEAK; owns us
+ // Instances of this class are owned by both webContentsView_ and AppKit. It
+ // is possible for an instance to outlive its webContentsView_. The
+ // webContentsView_ must call -clearWebContentsView in its destructor.
+ content::WebContentsViewMac* webContentsView_;
base::scoped_nsobject<WebDragSource> dragSource_;
base::scoped_nsobject<WebDragDest> dragDest_;
BOOL mouseDownCanMoveWindow_;
@@ -46,10 +50,6 @@ CONTENT_EXPORT
- (void)setMouseDownCanMoveWindow:(BOOL)canMove;
- (void)setOpaque:(BOOL)opaque;
-
-// Expose this, since sometimes one needs both the NSView and the
-// WebContentsImpl.
-- (content::WebContentsImpl*)webContents;
@end
namespace content {
diff --git a/chromium/content/browser/web_contents/web_contents_view_mac.mm b/chromium/content/browser/web_contents/web_contents_view_mac.mm
index 9e1f7925e21..9556dde593a 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.mm
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.mm
@@ -67,6 +67,7 @@ STATIC_ASSERT_MATCHING_ENUM(DragOperationEvery);
- (void)clearWebContentsView;
- (void)closeTabAfterEvent;
- (void)viewDidBecomeFirstResponder:(NSNotification*)notification;
+- (content::WebContentsImpl*)webContents;
@end
namespace content {
@@ -122,7 +123,7 @@ void WebContentsViewMac::GetContainerBounds(gfx::Rect* out) const {
bounds.origin = [window convertBaseToScreen:bounds.origin];
// Flip y to account for screen flip.
- NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
+ NSScreen* screen = [[NSScreen screens] firstObject];
bounds.origin.y = [screen frame].size.height - bounds.origin.y
- bounds.size.height;
*out = gfx::Rect(NSRectToCGRect(bounds));
@@ -455,8 +456,8 @@ void WebContentsViewMac::CloseTab() {
}
- (WebContentsImpl*)webContents {
- if (webContentsView_ == NULL)
- return NULL;
+ if (!webContentsView_)
+ return nullptr;
return webContentsView_->web_contents();
}
@@ -464,12 +465,9 @@ void WebContentsViewMac::CloseTab() {
WebContentsImpl* webContents = [self webContents];
if (webContents && webContents->GetDelegate()) {
NSPoint location = [NSEvent mouseLocation];
- if ([theEvent type] == NSMouseMoved)
- webContents->GetDelegate()->ContentsMouseEvent(
- webContents, gfx::Point(location.x, location.y), true);
- if ([theEvent type] == NSMouseExited)
- webContents->GetDelegate()->ContentsMouseEvent(
- webContents, gfx::Point(location.x, location.y), false);
+ webContents->GetDelegate()->ContentsMouseEvent(
+ webContents, gfx::Point(location.x, location.y),
+ [theEvent type] == NSMouseMoved, [theEvent type] == NSMouseExited);
}
}
@@ -488,8 +486,11 @@ void WebContentsViewMac::CloseTab() {
}
- (void)setOpaque:(BOOL)opaque {
+ WebContentsImpl* webContents = [self webContents];
+ if (!webContents)
+ return;
RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
- webContentsView_->web_contents()->GetRenderWidgetHostView());
+ webContents->GetRenderWidgetHostView());
DCHECK(view);
[view->cocoa_view() setOpaque:opaque];
}
@@ -503,6 +504,8 @@ void WebContentsViewMac::CloseTab() {
dragOperationMask:(NSDragOperation)operationMask
image:(NSImage*)image
offset:(NSPoint)offset {
+ if (![self webContents])
+ return;
dragSource_.reset([[WebDragSource alloc]
initWithContents:[self webContents]
view:self
@@ -580,15 +583,19 @@ void WebContentsViewMac::CloseTab() {
}
- (void)clearWebContentsView {
- webContentsView_ = NULL;
+ webContentsView_ = nullptr;
[dragSource_ clearWebContentsView];
}
- (void)closeTabAfterEvent {
- webContentsView_->CloseTab();
+ if (webContentsView_)
+ webContentsView_->CloseTab();
}
- (void)viewDidBecomeFirstResponder:(NSNotification*)notification {
+ if (![self webContents])
+ return;
+
NSView* view = [notification object];
if (![[self subviews] containsObject:view])
return;
diff --git a/chromium/content/browser/web_contents/web_contents_view_mus.cc b/chromium/content/browser/web_contents/web_contents_view_mus.cc
new file mode 100644
index 00000000000..b987ab198b8
--- /dev/null
+++ b/chromium/content/browser/web_contents/web_contents_view_mus.cc
@@ -0,0 +1,266 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/web_contents_view_mus.h"
+
+#include "build/build_config.h"
+#include "components/mus/public/cpp/window.h"
+#include "components/mus/public/cpp/window_tree_connection.h"
+#include "content/browser/frame_host/interstitial_page_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_mus.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/web_contents_view_delegate.h"
+#include "third_party/WebKit/public/web/WebDragOperation.h"
+#include "ui/aura/client/window_tree_client.h"
+#include "ui/aura/window.h"
+#include "ui/base/hit_test.h"
+
+using blink::WebDragOperation;
+using blink::WebDragOperationsMask;
+
+namespace content {
+
+WebContentsViewMus::WebContentsViewMus(
+ mus::Window* parent_window,
+ WebContentsImpl* web_contents,
+ WebContentsViewDelegate* delegate,
+ RenderViewHostDelegateView** delegate_view)
+ : web_contents_(web_contents), delegate_(delegate) {
+ DCHECK(parent_window);
+ *delegate_view = this;
+ mus::Window* window = parent_window->connection()->NewWindow();
+ window->SetVisible(true);
+ window->SetBounds(gfx::Rect(300, 300));
+ parent_window->AddChild(window);
+ mus_window_.reset(new mus::ScopedWindowPtr(window));
+}
+
+WebContentsViewMus::~WebContentsViewMus() {}
+
+void WebContentsViewMus::SizeChangedCommon(const gfx::Size& size) {
+ if (web_contents_->GetInterstitialPage())
+ web_contents_->GetInterstitialPage()->SetSize(size);
+ RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
+ if (rwhv)
+ rwhv->SetSize(size);
+ mus_window_->window()->SetBounds(gfx::Rect(size));
+}
+
+gfx::NativeView WebContentsViewMus::GetNativeView() const {
+ return aura_window_.get();
+}
+
+gfx::NativeView WebContentsViewMus::GetContentNativeView() const {
+ RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
+ return rwhv ? rwhv->GetNativeView() : nullptr;
+}
+
+gfx::NativeWindow WebContentsViewMus::GetTopLevelNativeWindow() const {
+ gfx::NativeWindow window = aura_window_->GetToplevelWindow();
+ return window ? window : delegate_->GetNativeWindow();
+}
+
+void WebContentsViewMus::GetContainerBounds(gfx::Rect* out) const {
+ *out = aura_window_->GetBoundsInScreen();
+}
+
+void WebContentsViewMus::SizeContents(const gfx::Size& size) {
+ gfx::Rect bounds = aura_window_->bounds();
+ if (bounds.size() != size) {
+ bounds.set_size(size);
+ aura_window_->SetBounds(bounds);
+ SizeChangedCommon(size);
+ } else {
+ // Our size matches what we want but the renderers size may not match.
+ // Pretend we were resized so that the renderers size is updated too.
+ SizeChangedCommon(size);
+ }
+}
+
+void WebContentsViewMus::SetInitialFocus() {
+ if (web_contents_->FocusLocationBarByDefault())
+ web_contents_->SetFocusToLocationBar(false);
+}
+
+gfx::Rect WebContentsViewMus::GetViewBounds() const {
+ return aura_window_->GetBoundsInScreen();
+}
+
+#if defined(OS_MACOSX)
+void WebContentsViewMus::SetAllowOtherViews(bool allow) {
+}
+
+bool WebContentsViewMus::GetAllowOtherViews() const {
+ return false;
+}
+#endif
+
+void WebContentsViewMus::CreateView(const gfx::Size& initial_size,
+ gfx::NativeView context) {
+ // We install a WindowDelegate so that the mus_window_ can track the size
+ // of the |aura_window_|.
+ aura_window_.reset(new aura::Window(this));
+ aura_window_->set_owned_by_parent(false);
+ aura_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
+ aura_window_->SetTransparent(false);
+ aura_window_->Init(ui::LAYER_NOT_DRAWN);
+ aura::Window* root_window = context ? context->GetRootWindow() : nullptr;
+ if (root_window) {
+ // There are places where there is no context currently because object
+ // hierarchies are built before they're attached to a Widget. (See
+ // views::WebView as an example; GetWidget() returns nullptr at the point
+ // where we are created.)
+ //
+ // It should be OK to not set a default parent since such users will
+ // explicitly add this WebContentsViewMus to their tree after they create
+ // us.
+ aura::client::ParentWindowWithContext(aura_window_.get(), root_window,
+ root_window->GetBoundsInScreen());
+ }
+ aura_window_->layer()->SetMasksToBounds(true);
+ aura_window_->SetName("WebContentsViewMus");
+}
+
+RenderWidgetHostViewBase* WebContentsViewMus::CreateViewForWidget(
+ RenderWidgetHost* render_widget_host,
+ bool is_guest_view_hack) {
+ RenderWidgetHostViewBase* view = new RenderWidgetHostViewMus(
+ mus_window_->window(), RenderWidgetHostImpl::From(render_widget_host));
+ view->InitAsChild(GetNativeView());
+ return view;
+}
+
+RenderWidgetHostViewBase* WebContentsViewMus::CreateViewForPopupWidget(
+ RenderWidgetHost* render_widget_host) {
+ return new RenderWidgetHostViewMus(
+ mus_window_->window(), RenderWidgetHostImpl::From(render_widget_host));
+}
+
+void WebContentsViewMus::SetPageTitle(const base::string16& title) {}
+
+void WebContentsViewMus::RenderViewCreated(RenderViewHost* host) {
+}
+
+void WebContentsViewMus::RenderViewSwappedIn(RenderViewHost* host) {
+}
+
+void WebContentsViewMus::SetOverscrollControllerEnabled(bool enabled) {
+ // This should never override the setting of the embedder view.
+}
+
+#if defined(OS_MACOSX)
+bool WebContentsViewMus::IsEventTracking() const {
+ return false;
+}
+
+void WebContentsViewMus::CloseTabAfterEventTracking() {}
+#endif
+
+WebContents* WebContentsViewMus::web_contents() {
+ return web_contents_;
+}
+
+void WebContentsViewMus::RestoreFocus() {
+ // Focus is managed by mus, not the browser.
+ NOTIMPLEMENTED();
+}
+
+void WebContentsViewMus::Focus() {
+ // Focus is managed by mus, not the browser.
+ NOTIMPLEMENTED();
+}
+
+void WebContentsViewMus::StoreFocus() {
+ // Focus is managed by mus, not the browser.
+ NOTIMPLEMENTED();
+}
+
+DropData* WebContentsViewMus::GetDropData() const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+void WebContentsViewMus::UpdateDragCursor(WebDragOperation operation) {
+ // TODO(fsamuel): Implement cursor in Mus.
+}
+
+void WebContentsViewMus::GotFocus() {
+ // Focus is managed by mus, not the browser.
+ NOTIMPLEMENTED();
+}
+
+void WebContentsViewMus::TakeFocus(bool reverse) {
+ // Focus is managed by mus, not the browser.
+ NOTIMPLEMENTED();
+}
+
+void WebContentsViewMus::ShowContextMenu(RenderFrameHost* render_frame_host,
+ const ContextMenuParams& params) {
+}
+
+void WebContentsViewMus::StartDragging(const DropData& drop_data,
+ WebDragOperationsMask ops,
+ const gfx::ImageSkia& image,
+ const gfx::Vector2d& image_offset,
+ const DragEventSourceInfo& event_info) {
+ // TODO(fsamuel): Implement drag and drop.
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WebContentsViewMus, aura::WindowDelegate implementation:
+
+gfx::Size WebContentsViewMus::GetMinimumSize() const {
+ return gfx::Size();
+}
+
+gfx::Size WebContentsViewMus::GetMaximumSize() const {
+ return gfx::Size();
+}
+
+void WebContentsViewMus::OnBoundsChanged(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ SizeChangedCommon(new_bounds.size());
+ if (delegate_)
+ delegate_->SizeChanged(new_bounds.size());
+}
+
+gfx::NativeCursor WebContentsViewMus::GetCursor(const gfx::Point& point) {
+ return gfx::kNullCursor;
+}
+
+int WebContentsViewMus::GetNonClientComponent(const gfx::Point& point) const {
+ return HTCLIENT;
+}
+
+bool WebContentsViewMus::ShouldDescendIntoChildForEventHandling(
+ aura::Window* child,
+ const gfx::Point& location) {
+ return true;
+}
+
+bool WebContentsViewMus::CanFocus() {
+ return false;
+}
+
+void WebContentsViewMus::OnCaptureLost() {}
+
+void WebContentsViewMus::OnPaint(const ui::PaintContext& context) {}
+
+void WebContentsViewMus::OnDeviceScaleFactorChanged(float device_scale_factor) {
+}
+
+void WebContentsViewMus::OnWindowDestroying(aura::Window* window) {}
+
+void WebContentsViewMus::OnWindowDestroyed(aura::Window* window) {}
+
+void WebContentsViewMus::OnWindowTargetVisibilityChanged(bool visible) {}
+
+bool WebContentsViewMus::HasHitTestMask() const {
+ return false;
+}
+
+void WebContentsViewMus::GetHitTestMask(gfx::Path* mask) const {}
+
+} // namespace content
diff --git a/chromium/content/browser/web_contents/web_contents_view_mus.h b/chromium/content/browser/web_contents/web_contents_view_mus.h
new file mode 100644
index 00000000000..05d51d1a49e
--- /dev/null
+++ b/chromium/content/browser/web_contents/web_contents_view_mus.h
@@ -0,0 +1,119 @@
+// 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_WEB_CONTENTS_WEB_CONTENTS_VIEW_MUS_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_MUS_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
+#include "components/mus/public/cpp/scoped_window_ptr.h"
+#include "components/mus/public/cpp/window.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
+#include "content/browser/web_contents/web_contents_view.h"
+#include "content/common/content_export.h"
+#include "content/common/drag_event_source_info.h"
+#include "ui/aura/window_delegate.h"
+
+namespace content {
+
+class WebContents;
+class WebContentsImpl;
+class WebContentsViewDelegate;
+
+class WebContentsViewMus : public WebContentsView,
+ public RenderViewHostDelegateView,
+ public aura::WindowDelegate {
+ public:
+ // The corresponding WebContentsImpl is passed in the constructor, and manages
+ // our lifetime. This doesn't need to be the case, but is this way currently
+ // because that's what was easiest when they were split.
+ WebContentsViewMus(mus::Window* parent_window,
+ WebContentsImpl* web_contents,
+ WebContentsViewDelegate* delegate,
+ RenderViewHostDelegateView** delegate_view);
+ ~WebContentsViewMus() override;
+
+ WebContents* web_contents();
+
+ private:
+ void SizeChangedCommon(const gfx::Size& size);
+
+ // WebContentsView implementation:
+ gfx::NativeView GetNativeView() const override;
+ gfx::NativeView GetContentNativeView() const override;
+ gfx::NativeWindow GetTopLevelNativeWindow() const override;
+ void GetContainerBounds(gfx::Rect* out) const override;
+ void SizeContents(const gfx::Size& size) override;
+ void Focus() override;
+ void SetInitialFocus() override;
+ void StoreFocus() override;
+ void RestoreFocus() override;
+ DropData* GetDropData() const override;
+ gfx::Rect GetViewBounds() const override;
+ void CreateView(const gfx::Size& initial_size,
+ gfx::NativeView context) override;
+ RenderWidgetHostViewBase* CreateViewForWidget(
+ RenderWidgetHost* render_widget_host,
+ bool is_guest_view_hack) override;
+ RenderWidgetHostViewBase* CreateViewForPopupWidget(
+ RenderWidgetHost* render_widget_host) override;
+ void SetPageTitle(const base::string16& title) override;
+ void RenderViewCreated(RenderViewHost* host) override;
+ void RenderViewSwappedIn(RenderViewHost* host) override;
+ void SetOverscrollControllerEnabled(bool enabled) override;
+#if defined(OS_MACOSX)
+ void SetAllowOtherViews(bool allow) override;
+ bool GetAllowOtherViews() const override;
+ bool IsEventTracking() const override;
+ void CloseTabAfterEventTracking() override;
+#endif
+
+ // Backend implementation of RenderViewHostDelegateView.
+ void ShowContextMenu(RenderFrameHost* render_frame_host,
+ const ContextMenuParams& params) override;
+ void StartDragging(const DropData& drop_data,
+ blink::WebDragOperationsMask allowed_ops,
+ const gfx::ImageSkia& image,
+ const gfx::Vector2d& image_offset,
+ const DragEventSourceInfo& event_info) override;
+ void UpdateDragCursor(blink::WebDragOperation operation) override;
+ void GotFocus() override;
+ void TakeFocus(bool reverse) override;
+
+ // Overridden from aura::WindowDelegate:
+ gfx::Size GetMinimumSize() const override;
+ gfx::Size GetMaximumSize() const override;
+ void OnBoundsChanged(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) override;
+ gfx::NativeCursor GetCursor(const gfx::Point& point) override;
+ int GetNonClientComponent(const gfx::Point& point) const override;
+ bool ShouldDescendIntoChildForEventHandling(
+ aura::Window* child,
+ const gfx::Point& location) override;
+ bool CanFocus() override;
+ void OnCaptureLost() override;
+ void OnPaint(const ui::PaintContext& context) override;
+ void OnDeviceScaleFactorChanged(float device_scale_factor) override;
+ void OnWindowDestroying(aura::Window* window) override;
+ void OnWindowDestroyed(aura::Window* window) override;
+ void OnWindowTargetVisibilityChanged(bool visible) override;
+ bool HasHitTestMask() const override;
+ void GetHitTestMask(gfx::Path* mask) const override;
+
+ // The WebContentsImpl whose contents we display.
+ WebContentsImpl* web_contents_;
+
+ scoped_ptr<WebContentsViewDelegate> delegate_;
+ scoped_ptr<aura::Window> aura_window_;
+ scoped_ptr<mus::ScopedWindowPtr> mus_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebContentsViewMus);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_MUS_H_
diff --git a/chromium/content/browser/web_contents/web_drag_source_mac.h b/chromium/content/browser/web_contents/web_drag_source_mac.h
index f1ccc4df16b..49dad89cc77 100644
--- a/chromium/content/browser/web_contents/web_drag_source_mac.h
+++ b/chromium/content/browser/web_contents/web_drag_source_mac.h
@@ -22,9 +22,13 @@ CONTENT_EXPORT
@interface WebDragSource : NSObject {
@private
// Our contents. Weak reference (owns or co-owns us).
+ // An instance of this class may outlive |contents_|. The destructor of
+ // |contents_| must set this ivar to |nullptr|.
content::WebContentsImpl* contents_;
// The view from which the drag was initiated. Weak reference.
+ // An instance of this class may outlive |contentsView_|. The destructor of
+ // |contentsView_| must set this ivar to |nullptr|.
NSView* contentsView_;
// Our drop data. Should only be initialized once.
diff --git a/chromium/content/browser/web_contents/web_drag_source_mac.mm b/chromium/content/browser/web_contents/web_drag_source_mac.mm
index ff3a881ea7f..a94f9d32daa 100644
--- a/chromium/content/browser/web_contents/web_drag_source_mac.mm
+++ b/chromium/content/browser/web_contents/web_drag_source_mac.mm
@@ -6,6 +6,8 @@
#include <sys/param.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
@@ -225,6 +227,9 @@ void PromiseWriterHelper(const DropData& drop_data,
}
- (void)startDrag {
+ if (!contentsView_)
+ return;
+
NSEvent* currentEvent = [NSApp currentEvent];
// Synthesize an event for dragging, since we can't be sure that
@@ -260,7 +265,7 @@ void PromiseWriterHelper(const DropData& drop_data,
- (void)endDragAt:(NSPoint)screenPoint
operation:(NSDragOperation)operation {
- if (!contents_)
+ if (!contents_ || !contentsView_)
return;
contents_->SystemDragEnded();
@@ -309,15 +314,12 @@ void PromiseWriterHelper(const DropData& drop_data,
if (!file.IsValid())
return nil;
- if (downloadURL_.is_valid()) {
- scoped_refptr<DragDownloadFile> dragFileDownloader(new DragDownloadFile(
- filePath,
- file.Pass(),
- downloadURL_,
- content::Referrer(contents_->GetLastCommittedURL(),
- dropData_->referrer_policy),
- contents_->GetEncoding(),
- contents_));
+ if (downloadURL_.is_valid() && contents_) {
+ scoped_refptr<DragDownloadFile> dragFileDownloader(
+ new DragDownloadFile(filePath, std::move(file), downloadURL_,
+ content::Referrer(contents_->GetLastCommittedURL(),
+ dropData_->referrer_policy),
+ contents_->GetEncoding(), contents_));
// The finalizer will take care of closing and deletion.
dragFileDownloader->Start(new PromiseFileFinalizer(
@@ -342,6 +344,9 @@ void PromiseWriterHelper(const DropData& drop_data,
@implementation WebDragSource (Private)
- (void)fillPasteboard {
+ if (!contentsView_)
+ return;
+
DCHECK(pasteboard_.get());
[pasteboard_ declareTypes:@[ ui::kChromeDragDummyPboardType ]
diff --git a/chromium/content/browser/webkit_browsertest.cc b/chromium/content/browser/webkit_browsertest.cc
index 4202eecb3ef..bd67587a327 100644
--- a/chromium/content/browser/webkit_browsertest.cc
+++ b/chromium/content/browser/webkit_browsertest.cc
@@ -8,13 +8,14 @@
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/net/url_request_abort_on_end_job.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
namespace content {
typedef ContentBrowserTest WebKitBrowserTest;
const char kAsyncScriptThatAbortsOnEndPage[] =
- "files/webkit/async_script_abort_on_end.html";
+ "/webkit/async_script_abort_on_end.html";
// This is a browser test because it is hard to reproduce reliably in a
// layout test without races. http://crbug.com/75604 deals with a request
@@ -23,9 +24,9 @@ const char kAsyncScriptThatAbortsOnEndPage[] =
// if chrome does not crash.
IN_PROC_BROWSER_TEST_F(WebKitBrowserTest, AbortOnEnd) {
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
URLRequestAbortOnEndJob::AddUrlHandler();
- GURL url = test_server()->GetURL(kAsyncScriptThatAbortsOnEndPage);
+ GURL url = embedded_test_server()->GetURL(kAsyncScriptThatAbortsOnEndPage);
NavigateToURL(shell(), url);
@@ -36,26 +37,25 @@ IN_PROC_BROWSER_TEST_F(WebKitBrowserTest, AbortOnEnd) {
EXPECT_FALSE(shell()->web_contents()->IsCrashed());
}
-// This is a browser test because the DumpRenderTree framework holds
+// This is a browser test because the test_runner framework holds
// onto a Document* reference that blocks this reproduction from
// destroying the Document, so it is not a use after free unless
-// you don't have DumpRenderTree loaded.
+// you don't have test_runner loaded.
// TODO(gavinp): remove this browser_test if we can get good LayoutTest
// coverage of the same issue.
-const char kXsltBadImportPage[] =
- "files/webkit/xslt-bad-import.html";
+const char kXsltBadImportPage[] = "/webkit/xslt-bad-import.html";
IN_PROC_BROWSER_TEST_F(WebKitBrowserTest, XsltBadImport) {
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
URLRequestAbortOnEndJob::AddUrlHandler();
- GURL url = test_server()->GetURL(kXsltBadImportPage);
+ GURL url = embedded_test_server()->GetURL(kXsltBadImportPage);
NavigateToURL(shell(), url);
EXPECT_FALSE(shell()->web_contents()->IsCrashed());
}
-// This is a browser test because DumpRenderTree has a PrerendererClient
+// This is a browser test because test_runner has a PrerendererClient
// implementation, and the purpose of this test is to ensure that content_shell
// does not crash when prerender elements are encountered with no Prererering
// implementation supplied to WebKit.
@@ -65,11 +65,10 @@ IN_PROC_BROWSER_TEST_F(WebKitBrowserTest, XsltBadImport) {
// But both will exist when we use content_shell to run layout tests. We must
// then add a mechanism to start content_shell without these, or else this
// test is not very interesting.
-const char kPrerenderNoCrashPage[] =
- "files/prerender/prerender-no-crash.html";
+const char kPrerenderNoCrashPage[] = "/prerender/prerender-no-crash.html";
IN_PROC_BROWSER_TEST_F(WebKitBrowserTest, PrerenderNoCrash) {
- ASSERT_TRUE(test_server()->Start());
- GURL url = test_server()->GetURL(kPrerenderNoCrashPage);
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL(kPrerenderNoCrashPage);
NavigateToURL(shell(), url);
diff --git a/chromium/content/browser/webui/OWNERS b/chromium/content/browser/webui/OWNERS
index 06e8b6d3b98..658a9f5cd0c 100644
--- a/chromium/content/browser/webui/OWNERS
+++ b/chromium/content/browser/webui/OWNERS
@@ -1,2 +1 @@
estade@chromium.org
-jhawkins@chromium.org
diff --git a/chromium/content/browser/webui/content_web_ui_controller_factory.cc b/chromium/content/browser/webui/content_web_ui_controller_factory.cc
index e2c6c547a03..196da55c9f9 100644
--- a/chromium/content/browser/webui/content_web_ui_controller_factory.cc
+++ b/chromium/content/browser/webui/content_web_ui_controller_factory.cc
@@ -4,11 +4,13 @@
#include "content/browser/webui/content_web_ui_controller_factory.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_ui.h"
#include "content/browser/appcache/appcache_internals_ui.h"
#include "content/browser/gpu/gpu_internals_ui.h"
#include "content/browser/indexed_db/indexed_db_internals_ui.h"
#include "content/browser/media/media_internals_ui.h"
+#include "content/browser/net/network_errors_listing_ui.h"
#include "content/browser/service_worker/service_worker_internals_ui.h"
#include "content/browser/tracing/tracing_ui.h"
#include "content/public/browser/storage_partition.h"
@@ -36,7 +38,8 @@ WebUI::TypeID ContentWebUIControllerFactory::GetWebUIType(
url.host() == kChromeUIMediaInternalsHost ||
url.host() == kChromeUIServiceWorkerInternalsHost ||
url.host() == kChromeUIAccessibilityHost ||
- url.host() == kChromeUIAppCacheInternalsHost) {
+ url.host() == kChromeUIAppCacheInternalsHost ||
+ url.host() == kChromeUINetworkErrorsListingHost) {
return const_cast<ContentWebUIControllerFactory*>(this);
}
return WebUI::kNoWebUI;
@@ -69,6 +72,8 @@ WebUIController* ContentWebUIControllerFactory::CreateWebUIControllerForURL(
return new AccessibilityUI(web_ui);
if (url.host() == kChromeUIServiceWorkerInternalsHost)
return new ServiceWorkerInternalsUI(web_ui);
+ if (url.host() == kChromeUINetworkErrorsListingHost)
+ return new NetworkErrorsListingUI(web_ui);
#if !defined(OS_ANDROID)
if (url.host() == kChromeUITracingHost)
return new TracingUI(web_ui);
diff --git a/chromium/content/browser/webui/content_web_ui_controller_factory.h b/chromium/content/browser/webui/content_web_ui_controller_factory.h
index 63023f30329..15f782c3255 100644
--- a/chromium/content/browser/webui/content_web_ui_controller_factory.h
+++ b/chromium/content/browser/webui/content_web_ui_controller_factory.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_WEBUI_CONTENT_WEB_UI_CONTROLLER_FACTORY_H_
#define CONTENT_BROWSER_WEBUI_CONTENT_WEB_UI_CONTROLLER_FACTORY_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_controller_factory.h"
diff --git a/chromium/content/browser/webui/generic_handler.h b/chromium/content/browser/webui/generic_handler.h
index 62f0e42021c..4a6d123b561 100644
--- a/chromium/content/browser/webui/generic_handler.h
+++ b/chromium/content/browser/webui/generic_handler.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_WEBUI_GENERIC_HANDLER_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/public/browser/web_ui_message_handler.h"
namespace base {
diff --git a/chromium/content/browser/webui/shared_resources_data_source.cc b/chromium/content/browser/webui/shared_resources_data_source.cc
index 32dc6c6388f..8383fc2220a 100644
--- a/chromium/content/browser/webui/shared_resources_data_source.cc
+++ b/chromium/content/browser/webui/shared_resources_data_source.cc
@@ -4,6 +4,8 @@
#include "content/browser/webui/shared_resources_data_source.h"
+#include <stddef.h>
+
#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
@@ -90,6 +92,9 @@ void SharedResourcesDataSource::StartDataRequest(
if (idr == IDR_WEBUI_CSS_TEXT_DEFAULTS) {
std::string css = webui::GetWebUiCssTextDefaults();
bytes = base::RefCountedString::TakeString(&css);
+ } else if (idr == IDR_WEBUI_CSS_TEXT_DEFAULTS_MD) {
+ std::string css = webui::GetWebUiCssTextDefaultsMd();
+ bytes = base::RefCountedString::TakeString(&css);
} else {
bytes = GetContentClient()->GetDataResourceBytes(idr);
}
diff --git a/chromium/content/browser/webui/shared_resources_data_source.h b/chromium/content/browser/webui/shared_resources_data_source.h
index 5c300ef68ec..53bf513bf74 100644
--- a/chromium/content/browser/webui/shared_resources_data_source.h
+++ b/chromium/content/browser/webui/shared_resources_data_source.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_WEBUI_SHARED_RESOURCES_DATA_SOURCE_H_
#define CONTENT_BROWSER_WEBUI_SHARED_RESOURCES_DATA_SOURCE_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "content/public/browser/url_data_source.h"
namespace content {
diff --git a/chromium/content/browser/webui/url_data_manager.cc b/chromium/content/browser/webui/url_data_manager.cc
index ffd992e1463..a9ec107df46 100644
--- a/chromium/content/browser/webui/url_data_manager.cc
+++ b/chromium/content/browser/webui/url_data_manager.cc
@@ -4,6 +4,8 @@
#include "content/browser/webui/url_data_manager.h"
+#include <stddef.h>
+
#include <vector>
#include "base/bind.h"
diff --git a/chromium/content/browser/webui/url_data_manager.h b/chromium/content/browser/webui/url_data_manager.h
index 8a318b73dba..8eca18c6561 100644
--- a/chromium/content/browser/webui/url_data_manager.h
+++ b/chromium/content/browser/webui/url_data_manager.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/supports_user_data.h"
#include "content/common/content_export.h"
diff --git a/chromium/content/browser/webui/url_data_manager_backend.cc b/chromium/content/browser/webui/url_data_manager_backend.cc
index ac346dda7ca..b604a461224 100644
--- a/chromium/content/browser/webui/url_data_manager_backend.cc
+++ b/chromium/content/browser/webui/url_data_manager_backend.cc
@@ -6,18 +6,19 @@
#include <set>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/debug/alias.h"
#include "base/lazy_instance.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/profiler/scoped_tracker.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
@@ -26,7 +27,6 @@
#include "content/browser/net/view_blob_internals_job_factory.h"
#include "content/browser/net/view_http_cache_job_factory.h"
#include "content/browser/resource_context_impl.h"
-#include "content/browser/tcmalloc_internals_request_job.h"
#include "content/browser/webui/shared_resources_data_source.h"
#include "content/browser/webui/url_data_source_impl.h"
#include "content/public/browser/browser_context.h"
@@ -39,10 +39,13 @@
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
+#include "net/log/net_log_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
+
#include "url/url_util.h"
namespace content {
@@ -53,7 +56,7 @@ const char kChromeURLContentSecurityPolicyHeaderBase[] =
"Content-Security-Policy: script-src chrome://resources 'self'";
const char kChromeURLXFrameOptionsHeader[] = "X-Frame-Options: DENY";
-
+static const char kNetworkErrorKey[] = "netError";
const int kNoRenderProcessId = -1;
bool SchemeIsInSchemes(const std::string& scheme,
@@ -119,7 +122,7 @@ class URLRequestChromeJob : public net::URLRequestJob {
// net::URLRequestJob implementation.
void Start() override;
void Kill() override;
- bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(net::IOBuffer* buf, int buf_size) override;
bool GetMimeType(std::string* mime_type) const override;
int GetResponseCode() const override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
@@ -190,8 +193,9 @@ class URLRequestChromeJob : public net::URLRequestJob {
bool RequiresUnsafeEval() const;
// Do the actual copy from data_ (the data we're serving) into |buf|.
- // Separate from ReadRawData so we can handle async I/O.
- void CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read);
+ // Separate from ReadRawData so we can handle async I/O. Returns the number of
+ // bytes read.
+ int CompleteRead(net::IOBuffer* buf, int buf_size);
// The actual data we're serving. NULL until it's been fetched.
scoped_refptr<base::RefCountedMemory> data_;
@@ -336,22 +340,16 @@ void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) {
void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) {
TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this);
if (bytes) {
- // The request completed, and we have all the data.
- // Clear any IO pending status.
- SetStatus(net::URLRequestStatus());
-
data_ = bytes;
- int bytes_read;
if (pending_buf_.get()) {
CHECK(pending_buf_->data());
- CompleteRead(pending_buf_.get(), pending_buf_size_, &bytes_read);
+ int result = CompleteRead(pending_buf_.get(), pending_buf_size_);
pending_buf_ = NULL;
- NotifyReadComplete(bytes_read);
+ ReadRawDataComplete(result);
}
} else {
// The request failed.
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_FAILED));
+ ReadRawDataComplete(net::ERR_FAILED);
}
}
@@ -359,25 +357,21 @@ base::WeakPtr<URLRequestChromeJob> URLRequestChromeJob::AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
-bool URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size,
- int* bytes_read) {
+int URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
if (!data_.get()) {
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
DCHECK(!pending_buf_.get());
CHECK(buf->data());
pending_buf_ = buf;
pending_buf_size_ = buf_size;
- return false; // Tell the caller we're still waiting for data.
+ return net::ERR_IO_PENDING;
}
// Otherwise, the data is available.
- CompleteRead(buf, buf_size, bytes_read);
- return true;
+ return CompleteRead(buf, buf_size);
}
-void URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size,
- int* bytes_read) {
- int remaining = static_cast<int>(data_->size()) - data_offset_;
+int URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size) {
+ int remaining = data_->size() - data_offset_;
if (buf_size > remaining)
buf_size = remaining;
if (buf_size > 0) {
@@ -389,7 +383,7 @@ void URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size,
memcpy(buf->data(), data_->front() + data_offset_, buf_size);
data_offset_ += buf_size;
}
- *bytes_read = buf_size;
+ return buf_size;
}
void URLRequestChromeJob::CheckStoragePartitionMatches(
@@ -463,17 +457,39 @@ void GetMimeTypeOnUI(URLDataSourceImpl* source,
namespace {
+bool IsValidNetworkErrorCode(int error_code) {
+ scoped_ptr<base::DictionaryValue> error_codes = net::GetNetConstants();
+ const base::DictionaryValue* net_error_codes_dict = nullptr;
+
+ for (base::DictionaryValue::Iterator itr(*error_codes); !itr.IsAtEnd();
+ itr.Advance()) {
+ if (itr.key() == kNetworkErrorKey) {
+ itr.value().GetAsDictionary(&net_error_codes_dict);
+ break;
+ }
+ }
+
+ if (net_error_codes_dict != nullptr) {
+ for (base::DictionaryValue::Iterator itr(*net_error_codes_dict);
+ !itr.IsAtEnd(); itr.Advance()) {
+ int net_error_code;
+ itr.value().GetAsInteger(&net_error_code);
+ if (error_code == net_error_code)
+ return true;
+ }
+ }
+ return false;
+}
+
class ChromeProtocolHandler
: public net::URLRequestJobFactory::ProtocolHandler {
public:
// |is_incognito| should be set for incognito profiles.
ChromeProtocolHandler(ResourceContext* resource_context,
bool is_incognito,
- AppCacheServiceImpl* appcache_service,
ChromeBlobStorageContext* blob_storage_context)
: resource_context_(resource_context),
is_incognito_(is_incognito),
- appcache_service_(appcache_service),
blob_storage_context_(blob_storage_context) {}
~ChromeProtocolHandler() override {}
@@ -493,20 +509,30 @@ class ChromeProtocolHandler
request, network_delegate, blob_storage_context_->context());
}
-#if defined(USE_TCMALLOC)
- // Next check for chrome://tcmalloc/, which uses its own job type.
- if (request->url().SchemeIs(kChromeUIScheme) &&
- request->url().host() == kChromeUITcmallocHost) {
- return new TcmallocInternalsRequestJob(request, network_delegate);
- }
-#endif
-
// Next check for chrome://histograms/, which uses its own job type.
if (request->url().SchemeIs(kChromeUIScheme) &&
request->url().host() == kChromeUIHistogramHost) {
return new HistogramInternalsRequestJob(request, network_delegate);
}
+ // Check for chrome://network-error/, which uses its own job type.
+ if (request->url().SchemeIs(kChromeUIScheme) &&
+ request->url().host() == kChromeUINetworkErrorHost) {
+ // Get the error code passed in via the request URL path.
+ std::basic_string<char> error_code_string =
+ request->url().path().substr(1);
+
+ int error_code;
+ if (base::StringToInt(error_code_string, &error_code)) {
+ // Check for a valid error code.
+ if (IsValidNetworkErrorCode(error_code) &&
+ error_code != net::Error::ERR_IO_PENDING) {
+ return new net::URLRequestErrorJob(request, network_delegate,
+ error_code);
+ }
+ }
+ }
+
// Fall back to using a custom handler
return new URLRequestChromeJob(
request, network_delegate,
@@ -523,7 +549,6 @@ class ChromeProtocolHandler
// True when generated from an incognito profile.
const bool is_incognito_;
- AppCacheServiceImpl* appcache_service_;
ChromeBlobStorageContext* blob_storage_context_;
DISALLOW_COPY_AND_ASSIGN(ChromeProtocolHandler);
@@ -552,11 +577,10 @@ scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
URLDataManagerBackend::CreateProtocolHandler(
content::ResourceContext* resource_context,
bool is_incognito,
- AppCacheServiceImpl* appcache_service,
ChromeBlobStorageContext* blob_storage_context) {
DCHECK(resource_context);
return make_scoped_ptr(new ChromeProtocolHandler(
- resource_context, is_incognito, appcache_service, blob_storage_context));
+ resource_context, is_incognito, blob_storage_context));
}
void URLDataManagerBackend::AddDataSource(
diff --git a/chromium/content/browser/webui/url_data_manager_backend.h b/chromium/content/browser/webui/url_data_manager_backend.h
index 6a326a08803..0e312aab26c 100644
--- a/chromium/content/browser/webui/url_data_manager_backend.h
+++ b/chromium/content/browser/webui/url_data_manager_backend.h
@@ -9,8 +9,8 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/supports_user_data.h"
#include "content/browser/webui/url_data_manager.h"
@@ -25,7 +25,6 @@ class RefCountedMemory;
namespace content {
-class AppCacheServiceImpl;
class ChromeBlobStorageContext;
class ResourceContext;
class URLDataManagerBackend;
@@ -47,7 +46,6 @@ class URLDataManagerBackend : public base::SupportsUserData::Data {
CONTENT_EXPORT static scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
CreateProtocolHandler(content::ResourceContext* resource_context,
bool is_incognito,
- AppCacheServiceImpl* appcache_service,
ChromeBlobStorageContext* blob_storage_context);
// Adds a DataSource to the collection of data sources.
diff --git a/chromium/content/browser/webui/url_data_manager_backend_unittest.cc b/chromium/content/browser/webui/url_data_manager_backend_unittest.cc
index 9a511f1e25d..f8fefe5fe27 100644
--- a/chromium/content/browser/webui/url_data_manager_backend_unittest.cc
+++ b/chromium/content/browser/webui/url_data_manager_backend_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "content/browser/webui/url_data_manager_backend.h"
@@ -44,7 +45,7 @@ class UrlDataManagerBackendTest : public testing::Test {
// URLRequestJobFactory takes ownership of the passed in ProtocolHandler.
url_request_job_factory_.SetProtocolHandler(
"chrome", URLDataManagerBackend::CreateProtocolHandler(
- &resource_context_, false, nullptr, nullptr));
+ &resource_context_, false, nullptr));
url_request_context_.set_job_factory(&url_request_job_factory_);
}
@@ -54,7 +55,7 @@ class UrlDataManagerBackendTest : public testing::Test {
GURL("chrome://resources/polymer/v1_0/polymer/polymer-extracted.js"),
net::HIGHEST, delegate);
request->SetExtraRequestHeaderByName("Origin", origin, true);
- return request.Pass();
+ return request;
}
protected:
@@ -107,4 +108,26 @@ TEST_F(UrlDataManagerBackendTest, CancelAfterFirstReadStarted) {
EXPECT_EQ("", cancel_delegate.data_received());
}
+// Check for a network error page request via chrome://network-error/.
+TEST_F(UrlDataManagerBackendTest, ChromeNetworkErrorPageRequest) {
+ scoped_ptr<net::URLRequest> error_request =
+ url_request_context_.CreateRequest(
+ GURL("chrome://network-error/-105"), net::HIGHEST, &delegate_);
+ error_request->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(net::URLRequestStatus::FAILED, error_request->status().status());
+ EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, error_request->status().error());
+}
+
+// Check for an invalid network error page request via chrome://network-error/.
+TEST_F(UrlDataManagerBackendTest, ChromeNetworkErrorPageRequestFailed) {
+ scoped_ptr<net::URLRequest> error_request =
+ url_request_context_.CreateRequest(
+ GURL("chrome://network-error/-123456789"), net::HIGHEST, &delegate_);
+ error_request->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(net::URLRequestStatus::FAILED, error_request->status().status());
+ EXPECT_EQ(net::ERR_INVALID_URL, error_request->status().error());
+}
+
} // namespace content
diff --git a/chromium/content/browser/webui/url_data_source_impl.cc b/chromium/content/browser/webui/url_data_source_impl.cc
index 10b88ec7d45..3c06d881a34 100644
--- a/chromium/content/browser/webui/url_data_source_impl.cc
+++ b/chromium/content/browser/webui/url_data_source_impl.cc
@@ -25,9 +25,7 @@ URLDataSourceImpl::~URLDataSourceImpl() {
void URLDataSourceImpl::SendResponse(
int request_id,
- base::RefCountedMemory* bytes) {
- // Take a ref-pointer on entry so byte->Release() will always get called.
- scoped_refptr<base::RefCountedMemory> bytes_ptr(bytes);
+ scoped_refptr<base::RefCountedMemory> bytes) {
if (URLDataManager::IsScheduledForDeletion(this)) {
// We're scheduled for deletion. Servicing the request would result in
// this->AddRef being invoked, even though the ref count is 0 and 'this' is
@@ -42,10 +40,9 @@ void URLDataSourceImpl::SendResponse(
// when the object is deleted.
return;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&URLDataSourceImpl::SendResponseOnIOThread, this, request_id,
- bytes_ptr));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLDataSourceImpl::SendResponseOnIOThread,
+ this, request_id, std::move(bytes)));
}
void URLDataSourceImpl::SendResponseOnIOThread(
diff --git a/chromium/content/browser/webui/url_data_source_impl.h b/chromium/content/browser/webui/url_data_source_impl.h
index 4785b37a194..723c1baf225 100644
--- a/chromium/content/browser/webui/url_data_source_impl.h
+++ b/chromium/content/browser/webui/url_data_source_impl.h
@@ -56,7 +56,8 @@ class URLDataSourceImpl : public base::RefCountedThreadSafe<
// Report that a request has resulted in the data |bytes|.
// If the request can't be satisfied, pass NULL for |bytes| to indicate
// the request is over.
- virtual void SendResponse(int request_id, base::RefCountedMemory* bytes);
+ virtual void SendResponse(int request_id,
+ scoped_refptr<base::RefCountedMemory> bytes);
const std::string& source_name() const { return source_name_; }
URLDataSource* source() const { return source_.get(); }
diff --git a/chromium/content/browser/webui/web_ui_controller_factory_registry.cc b/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
index 8626646698d..240c4dbbde7 100644
--- a/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
+++ b/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
@@ -4,6 +4,8 @@
#include "content/browser/webui/web_ui_controller_factory_registry.h"
+#include <stddef.h>
+
#include "base/lazy_instance.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/public/common/url_constants.h"
diff --git a/chromium/content/browser/webui/web_ui_controller_factory_registry.h b/chromium/content/browser/webui/web_ui_controller_factory_registry.h
index af7fb3d12fb..11020c2da24 100644
--- a/chromium/content/browser/webui/web_ui_controller_factory_registry.h
+++ b/chromium/content/browser/webui/web_ui_controller_factory_registry.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_WEBUI_WEB_UI_CONTROLLER_FACTORY_REGISTRY_H_
#define CONTENT_BROWSER_WEBUI_WEB_UI_CONTROLLER_FACTORY_REGISTRY_H_
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/web_ui_controller_factory.h"
diff --git a/chromium/content/browser/webui/web_ui_data_source_impl.cc b/chromium/content/browser/webui/web_ui_data_source_impl.cc
index 09c58966aa1..9a026008daf 100644
--- a/chromium/content/browser/webui/web_ui_data_source_impl.cc
+++ b/chromium/content/browser/webui/web_ui_data_source_impl.cc
@@ -4,15 +4,18 @@
#include "content/browser/webui/web_ui_data_source_impl.h"
+#include <stddef.h>
+
#include <string>
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_util.h"
#include "content/grit/content_resources.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
-#include "third_party/mojo/src/mojo/public/js/constants.h"
+#include "mojo/public/js/constants.h"
#include "ui/base/webui/jstemplate_builder.h"
#include "ui/base/webui/web_ui_util.h"
@@ -24,31 +27,6 @@ WebUIDataSource* WebUIDataSource::Create(const std::string& source_name) {
}
// static
-WebUIDataSource* WebUIDataSource::AddMojoDataSource(
- BrowserContext* browser_context) {
- WebUIDataSource* mojo_source = Create("mojo");
-
- static const struct {
- const char* path;
- int id;
- } resources[] = {
- { mojo::kBindingsModuleName, IDR_MOJO_BINDINGS_JS },
- { mojo::kBufferModuleName, IDR_MOJO_BUFFER_JS },
- { mojo::kCodecModuleName, IDR_MOJO_CODEC_JS },
- { mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS },
- { mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS },
- { mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS },
- { mojo::kUnicodeModuleName, IDR_MOJO_UNICODE_JS },
- { mojo::kValidatorModuleName, IDR_MOJO_VALIDATOR_JS },
- };
- for (size_t i = 0; i < arraysize(resources); ++i)
- mojo_source->AddResourcePath(resources[i].path, resources[i].id);
-
- URLDataManager::AddWebUIDataSource(browser_context, mojo_source);
- return mojo_source;
-}
-
-// static
void WebUIDataSource::Add(BrowserContext* browser_context,
WebUIDataSource* source) {
URLDataManager::AddWebUIDataSource(browser_context, source);
@@ -161,6 +139,24 @@ void WebUIDataSourceImpl::SetRequestFilter(
filter_callback_ = callback;
}
+void WebUIDataSourceImpl::AddMojoResources() {
+ static const struct {
+ const char* path;
+ int id;
+ } resources[] = {
+ {mojo::kBindingsModuleName, IDR_MOJO_BINDINGS_JS},
+ {mojo::kBufferModuleName, IDR_MOJO_BUFFER_JS},
+ {mojo::kCodecModuleName, IDR_MOJO_CODEC_JS},
+ {mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS},
+ {mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS},
+ {mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS},
+ {mojo::kUnicodeModuleName, IDR_MOJO_UNICODE_JS},
+ {mojo::kValidatorModuleName, IDR_MOJO_VALIDATOR_JS},
+ };
+ for (size_t i = 0; i < arraysize(resources); ++i)
+ AddResourcePath(resources[i].path, resources[i].id);
+}
+
void WebUIDataSourceImpl::DisableReplaceExistingSource() {
replace_existing_source_ = false;
}
@@ -190,19 +186,22 @@ std::string WebUIDataSourceImpl::GetSource() const {
}
std::string WebUIDataSourceImpl::GetMimeType(const std::string& path) const {
- if (base::EndsWith(path, ".css", base::CompareCase::INSENSITIVE_ASCII))
+ // Remove the query string for to determine the mime type.
+ std::string file_path = path.substr(0, path.find_first_of('?'));
+
+ if (base::EndsWith(file_path, ".css", base::CompareCase::INSENSITIVE_ASCII))
return "text/css";
- if (base::EndsWith(path, ".js", base::CompareCase::INSENSITIVE_ASCII))
+ if (base::EndsWith(file_path, ".js", base::CompareCase::INSENSITIVE_ASCII))
return "application/javascript";
- if (base::EndsWith(path, ".json", base::CompareCase::INSENSITIVE_ASCII))
+ if (base::EndsWith(file_path, ".json", base::CompareCase::INSENSITIVE_ASCII))
return "application/json";
- if (base::EndsWith(path, ".pdf", base::CompareCase::INSENSITIVE_ASCII))
+ if (base::EndsWith(file_path, ".pdf", base::CompareCase::INSENSITIVE_ASCII))
return "application/pdf";
- if (base::EndsWith(path, ".svg", base::CompareCase::INSENSITIVE_ASCII))
+ if (base::EndsWith(file_path, ".svg", base::CompareCase::INSENSITIVE_ASCII))
return "image/svg+xml";
return "text/html";
@@ -225,7 +224,9 @@ void WebUIDataSourceImpl::StartDataRequest(
int resource_id = default_resource_;
std::map<std::string, int>::iterator result;
- result = path_to_idr_map_.find(path);
+ // Remove the query string for named resource lookups.
+ std::string file_path = path.substr(0, path.find_first_of('?'));
+ result = path_to_idr_map_.find(file_path);
if (result != path_to_idr_map_.end())
resource_id = result->second;
DCHECK_NE(resource_id, -1);
diff --git a/chromium/content/browser/webui/web_ui_data_source_impl.h b/chromium/content/browser/webui/web_ui_data_source_impl.h
index d9f44887d1c..7d899a9e194 100644
--- a/chromium/content/browser/webui/web_ui_data_source_impl.h
+++ b/chromium/content/browser/webui/web_ui_data_source_impl.h
@@ -8,9 +8,9 @@
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/values.h"
#include "content/browser/webui/url_data_manager.h"
#include "content/browser/webui/url_data_source_impl.h"
@@ -38,6 +38,7 @@ class CONTENT_EXPORT WebUIDataSourceImpl
void SetDefaultResource(int resource_id) override;
void SetRequestFilter(
const WebUIDataSource::HandleRequestCallback& callback) override;
+ void AddMojoResources() override;
void DisableReplaceExistingSource() override;
void DisableContentSecurityPolicy() override;
void OverrideContentSecurityPolicyObjectSrc(const std::string& data) override;
diff --git a/chromium/content/browser/webui/web_ui_data_source_unittest.cc b/chromium/content/browser/webui/web_ui_data_source_unittest.cc
index 2b5d854b58f..492415c48c0 100644
--- a/chromium/content/browser/webui/web_ui_data_source_unittest.cc
+++ b/chromium/content/browser/webui/web_ui_data_source_unittest.cc
@@ -1,8 +1,9 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 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 "base/bind.h"
+#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
@@ -19,7 +20,7 @@ const int kDummyResourceId = 789;
const char kDummyString[] = "foo";
const char kDummyDefaultResource[] = "<html>foo</html>";
-const char kDummytResource[] = "<html>blah</html>";
+const char kDummyResource[] = "<html>blah</html>";
class TestClient : public TestContentClient {
public:
@@ -30,7 +31,6 @@ class TestClient : public TestContentClient {
if (message_id == kDummyStringId)
return base::UTF8ToUTF16(kDummyString);
return base::string16();
-
}
base::RefCountedStaticMemory* GetDataResourceBytes(
@@ -40,34 +40,41 @@ class TestClient : public TestContentClient {
bytes = new base::RefCountedStaticMemory(
kDummyDefaultResource, arraysize(kDummyDefaultResource));
} else if (resource_id == kDummyResourceId) {
- bytes = new base::RefCountedStaticMemory(
- kDummytResource, arraysize(kDummytResource));
+ bytes = new base::RefCountedStaticMemory(kDummyResource,
+ arraysize(kDummyResource));
}
return bytes;
}
};
-}
+} // namespace
class WebUIDataSourceTest : public testing::Test {
public:
- WebUIDataSourceTest() : result_data_(NULL) {}
+ WebUIDataSourceTest() {}
~WebUIDataSourceTest() override {}
WebUIDataSourceImpl* source() { return source_.get(); }
- void StartDataRequest(const std::string& path) {
- source_->StartDataRequest(
- path,
- 0, 0,
- base::Bind(&WebUIDataSourceTest::SendResult,
- base::Unretained(this)));
+ void StartDataRequest(const std::string& path,
+ const URLDataSource::GotDataCallback& callback) {
+ source_->StartDataRequest(path, 0, 0, callback);
}
std::string GetMimeType(const std::string& path) const {
return source_->GetMimeType(path);
}
- scoped_refptr<base::RefCountedMemory> result_data_;
+ bool HandleRequest(const std::string& path,
+ const WebUIDataSourceImpl::GotDataCallback&) {
+ request_path_ = path;
+ return true;
+ }
+
+ void RequestFilterQueryStringCallback(
+ scoped_refptr<base::RefCountedMemory> data);
+
+ protected:
+ std::string request_path_;
private:
void SetUp() override {
@@ -79,53 +86,100 @@ class WebUIDataSourceTest : public testing::Test {
source_ = make_scoped_refptr(source_impl);
}
- // Store response for later comparisons.
- void SendResult(base::RefCountedMemory* data) {
- result_data_ = data;
- }
-
TestBrowserThreadBundle thread_bundle_;
scoped_refptr<WebUIDataSourceImpl> source_;
TestClient client_;
};
-TEST_F(WebUIDataSourceTest, EmptyStrings) {
- source()->SetJsonPath("strings.js");
- StartDataRequest("strings.js");
- std::string result(result_data_->front_as<char>(), result_data_->size());
+void EmptyStringsCallback(scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
EXPECT_NE(result.find("loadTimeData.data = {"), std::string::npos);
EXPECT_NE(result.find("};"), std::string::npos);
}
+TEST_F(WebUIDataSourceTest, EmptyStrings) {
+ source()->SetJsonPath("strings.js");
+ StartDataRequest("strings.js", base::Bind(&EmptyStringsCallback));
+}
+
+void SomeStringsCallback(scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
+ EXPECT_NE(result.find("\"planet\":\"pluto\""), std::string::npos);
+ EXPECT_NE(result.find("\"button\":\"foo\""), std::string::npos);
+}
+
TEST_F(WebUIDataSourceTest, SomeStrings) {
source()->SetJsonPath("strings.js");
source()->AddString("planet", base::ASCIIToUTF16("pluto"));
source()->AddLocalizedString("button", kDummyStringId);
- StartDataRequest("strings.js");
- std::string result(result_data_->front_as<char>(), result_data_->size());
- EXPECT_NE(result.find("\"planet\":\"pluto\""), std::string::npos);
- EXPECT_NE(result.find("\"button\":\"foo\""), std::string::npos);
+ StartDataRequest("strings.js", base::Bind(&SomeStringsCallback));
+}
+
+void DefaultResourceFoobarCallback(scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
+ EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
+}
+
+void DefaultResourceStringsCallback(
+ scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
+ EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
}
TEST_F(WebUIDataSourceTest, DefaultResource) {
source()->SetDefaultResource(kDummyDefaultResourceId);
- StartDataRequest("foobar" );
- std::string result(result_data_->front_as<char>(), result_data_->size());
- EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
- StartDataRequest("strings.js");
- result = std::string(result_data_->front_as<char>(), result_data_->size());
+ StartDataRequest("foobar", base::Bind(&DefaultResourceFoobarCallback));
+ StartDataRequest("strings.js", base::Bind(&DefaultResourceStringsCallback));
+}
+
+void NamedResourceFoobarCallback(scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
+ EXPECT_NE(result.find(kDummyResource), std::string::npos);
+}
+
+void NamedResourceStringsCallback(scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
}
TEST_F(WebUIDataSourceTest, NamedResource) {
source()->SetDefaultResource(kDummyDefaultResourceId);
source()->AddResourcePath("foobar", kDummyResourceId);
- StartDataRequest("foobar");
- std::string result(result_data_->front_as<char>(), result_data_->size());
- EXPECT_NE(result.find(kDummytResource), std::string::npos);
- StartDataRequest("strings.js");
- result = std::string(result_data_->front_as<char>(), result_data_->size());
- EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
+ StartDataRequest("foobar", base::Bind(&NamedResourceFoobarCallback));
+ StartDataRequest("strings.js", base::Bind(&NamedResourceStringsCallback));
+}
+
+void NamedResourceWithQueryStringCallback(
+ scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
+ EXPECT_NE(result.find(kDummyResource), std::string::npos);
+}
+
+TEST_F(WebUIDataSourceTest, NamedResourceWithQueryString) {
+ source()->SetDefaultResource(kDummyDefaultResourceId);
+ source()->AddResourcePath("foobar", kDummyResourceId);
+ StartDataRequest("foobar?query?string",
+ base::Bind(&NamedResourceWithQueryStringCallback));
+}
+
+void WebUIDataSourceTest::RequestFilterQueryStringCallback(
+ scoped_refptr<base::RefCountedMemory> data) {
+ std::string result(data->front_as<char>(), data->size());
+ // Check that the query string is passed to the request filter (and not
+ // trimmed).
+ EXPECT_EQ("foobar?query?string", request_path_);
+}
+
+TEST_F(WebUIDataSourceTest, RequestFilterQueryString) {
+ request_path_ = std::string();
+ source()->SetRequestFilter(
+ base::Bind(&WebUIDataSourceTest::HandleRequest, base::Unretained(this)));
+ source()->SetDefaultResource(kDummyDefaultResourceId);
+ source()->AddResourcePath("foobar", kDummyResourceId);
+ StartDataRequest(
+ "foobar?query?string",
+ base::Bind(&WebUIDataSourceTest::RequestFilterQueryStringCallback,
+ base::Unretained(this)));
}
TEST_F(WebUIDataSourceTest, MimeType) {
@@ -143,6 +197,12 @@ TEST_F(WebUIDataSourceTest, MimeType) {
EXPECT_EQ(GetMimeType("foocss"), html);
EXPECT_EQ(GetMimeType("foo.css"), css);
EXPECT_EQ(GetMimeType(".css.foo"), html);
+
+ // With query strings.
+ EXPECT_EQ(GetMimeType("foo?abc?abc"), html);
+ EXPECT_EQ(GetMimeType("foo.html?abc?abc"), html);
+ EXPECT_EQ(GetMimeType("foo.css?abc?abc"), css);
+ EXPECT_EQ(GetMimeType("foo.js?abc?abc"), js);
}
} // namespace content
diff --git a/chromium/content/browser/webui/web_ui_impl.cc b/chromium/content/browser/webui/web_ui_impl.cc
index 8a24604a403..a7b76147a41 100644
--- a/chromium/content/browser/webui/web_ui_impl.cc
+++ b/chromium/content/browser/webui/web_ui_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/webui/web_ui_impl.h"
+#include <stddef.h>
+
#include "base/debug/dump_without_crashing.h"
#include "base/json/json_writer.h"
#include "base/strings/utf_string_conversions.h"
@@ -237,9 +239,8 @@ void WebUIImpl::ExecuteJavascript(const base::string16& javascript) {
// It's possible to load about:blank in a Web UI renderer.
// See http://crbug.com/42547
target_frame->GetLastCommittedURL().spec() == url::kAboutBlankURL)) {
- // Don't crash when we try to inject JavaScript into a non-WebUI page, but
- // upload a crash report anyways. http://crbug.com/516690
- base::debug::DumpWithoutCrashing();
+ // Silently ignore the request. Would be nice to clean-up WebUI so we
+ // could turn this into a CHECK(). http://crbug.com/516690.
return;
}
target_frame->ExecuteJavaScript(javascript);
diff --git a/chromium/content/browser/webui/web_ui_impl.h b/chromium/content/browser/webui/web_ui_impl.h
index 86c70711282..26c051def9e 100644
--- a/chromium/content/browser/webui/web_ui_impl.h
+++ b/chromium/content/browser/webui/web_ui_impl.h
@@ -9,6 +9,7 @@
#include <set>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_ui.h"
@@ -25,13 +26,13 @@ class CONTENT_EXPORT WebUIImpl : public WebUI,
WebUIImpl(WebContents* contents, const std::string& frame_name);
~WebUIImpl() override;
- // Called by WebContentsImpl when the RenderView is first created. This is
- // *not* called for every page load because in some cases
- // RenderFrameHostManager will reuse RenderView instances.
+ // Called when a RenderView is created for a WebUI (reload after a renderer
+ // crash) or when a WebUI is created for an RenderView (i.e. navigating from
+ // chrome://downloads to chrome://bookmarks) or when both are new (i.e.
+ // opening a new tab).
void RenderViewCreated(RenderViewHost* render_view_host);
- // Called by WebContentsImpl when the RenderView is reused. This happens on
- // refresh or when the main page is navigated within the same SiteInstance.
+ // Called when a RenderView is reused for the same WebUI type (i.e. reload).
void RenderViewReused(RenderViewHost* render_view_host, bool was_main_frame);
// WebUI implementation:
diff --git a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
index 5ceb632a5d6..805f1bb5775 100644
--- a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -3,10 +3,13 @@
// found in the LICENSE file.
#include <limits>
+#include <utility>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
+#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
@@ -26,10 +29,11 @@
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/data/web_ui_test_mojo_bindings.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/js/constants.h"
#include "mojo/test/test_utils.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
-#include "third_party/mojo/src/mojo/public/js/constants.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
namespace content {
namespace {
@@ -51,10 +55,23 @@ bool GetResource(const std::string& id,
id == mojo::kValidatorModuleName)
return false;
+ if (id.find(".mojom") != std::string::npos) {
+ std::string contents;
+ CHECK(base::ReadFileToString(mojo::test::GetFilePathForJSResource(id),
+ &contents, std::string::npos))
+ << id;
+ base::RefCountedString* ref_contents = new base::RefCountedString;
+ ref_contents->data() = contents;
+ callback.Run(ref_contents);
+ return true;
+ }
+
+ base::FilePath path;
+ CHECK(base::PathService::Get(content::DIR_TEST_DATA, &path));
+ path = path.AppendASCII(id.substr(0, id.find("?")));
std::string contents;
- CHECK(base::ReadFileToString(mojo::test::GetFilePathForJSResource(id),
- &contents,
- std::string::npos)) << id;
+ CHECK(base::ReadFileToString(path, &contents, std::string::npos))
+ << path.value();
base::RefCountedString* ref_contents = new base::RefCountedString;
ref_contents->data() = contents;
callback.Run(ref_contents);
@@ -65,7 +82,7 @@ class BrowserTargetImpl : public BrowserTarget {
public:
BrowserTargetImpl(base::RunLoop* run_loop,
mojo::InterfaceRequest<BrowserTarget> request)
- : run_loop_(run_loop), binding_(this, request.Pass()) {}
+ : run_loop_(run_loop), binding_(this, std::move(request)) {}
~BrowserTargetImpl() override {}
@@ -89,13 +106,14 @@ class BrowserTargetImpl : public BrowserTarget {
// WebUIController that sets up mojo bindings.
class TestWebUIController : public WebUIController {
public:
- TestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
- : WebUIController(web_ui),
- run_loop_(run_loop) {
+ TestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
+ : WebUIController(web_ui), run_loop_(run_loop) {
content::WebUIDataSource* data_source =
- WebUIDataSource::AddMojoDataSource(
- web_ui->GetWebContents()->GetBrowserContext());
+ WebUIDataSource::Create("mojo-web-ui");
+ data_source->AddMojoResources();
data_source->SetRequestFilter(base::Bind(&GetResource));
+ content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
+ data_source);
}
protected:
@@ -123,7 +141,7 @@ class PingTestWebUIController : public TestWebUIController {
}
void CreateHandler(mojo::InterfaceRequest<BrowserTarget> request) {
- browser_target_.reset(new BrowserTargetImpl(run_loop_, request.Pass()));
+ browser_target_.reset(new BrowserTargetImpl(run_loop_, std::move(request)));
}
private:
@@ -201,10 +219,10 @@ IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEndPing) {
return;
got_message = false;
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
base::RunLoop run_loop;
factory()->set_run_loop(&run_loop);
- GURL test_url(test_server()->GetURL("files/web_ui_mojo.html?ping"));
+ GURL test_url("chrome://mojo-web-ui/web_ui_mojo.html?ping");
NavigateToURL(shell(), test_url);
// RunLoop is quit when message received from page.
run_loop.Run();
@@ -231,9 +249,9 @@ IN_PROC_BROWSER_TEST_F(WebUIMojoTest, ConnectToApplication) {
"content/public/test/test_mojo_service.mojom"))
return;
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(embedded_test_server()->Start());
NavigateToURL(shell(),
- test_server()->GetURL("files/web_ui_mojo_shell_test.html"));
+ GURL("chrome://mojo-web-ui/web_ui_mojo_shell_test.html"));
DOMMessageQueue message_queue;
std::string message;
diff --git a/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc b/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
index 01b79471890..f439e0690da 100644
--- a/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
+++ b/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -4,6 +4,7 @@
#include "content/browser/zygote_host/zygote_host_impl_linux.h"
+#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -18,9 +19,9 @@
#include "base/files/scoped_file.h"
#include "base/linux_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/path_service.h"
@@ -33,6 +34,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/render_sandbox_host_linux.h"
#include "content/common/child_process_sandbox_support_impl_linux.h"
#include "content/common/zygote_commands_linux.h"
@@ -62,7 +64,7 @@ bool ReceiveFixedMessage(int fd,
size_t expect_len,
base::ProcessId* sender_pid) {
char buf[expect_len + 1];
- ScopedVector<base::ScopedFD> fds_vec;
+ std::vector<base::ScopedFD> fds_vec;
const ssize_t len = base::UnixDomainSocket::RecvMsgWithPid(
fd, buf, sizeof(buf), &fds_vec, sender_pid);
@@ -131,6 +133,7 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
static const char* kForwardSwitches[] = {
switches::kAllowSandboxDebugging,
switches::kDisableSeccompFilterSandbox,
+ switches::kEnableHeapProfiling,
switches::kEnableLogging, // Support, e.g., --enable-logging=stderr.
// Zygote process needs to know what resources to have loaded when it
// becomes a renderer process.
@@ -158,7 +161,7 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
// or namespace sandbox. This is needed beacuse the processes are
// non-dumpable, so /proc/pid/oom_score_adj can only be written by root.
use_suid_sandbox_for_adj_oom_score_ =
- using_namespace_sandbox || using_suid_sandbox;
+ !sandbox_binary_.empty() && using_suid_sandbox;
// Start up the sandbox host process and get the file descriptor for the
// renderers to talk to it.
@@ -360,7 +363,7 @@ pid_t ZygoteHostImpl::ForkRequest(const std::vector<std::string>& argv,
{
char buf[sizeof(kZygoteChildPingMessage) + 1];
- ScopedVector<base::ScopedFD> recv_fds;
+ std::vector<base::ScopedFD> recv_fds;
base::ProcessId real_pid;
ssize_t n = base::UnixDomainSocket::RecvMsgWithPid(
diff --git a/chromium/content/browser/zygote_host/zygote_host_impl_linux.h b/chromium/content/browser/zygote_host/zygote_host_impl_linux.h
index 1c0e0b7dd74..6793f73757c 100644
--- a/chromium/content/browser/zygote_host/zygote_host_impl_linux.h
+++ b/chromium/content/browser/zygote_host/zygote_host_impl_linux.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_ZYGOTE_HOST_ZYGOTE_HOST_IMPL_LINUX_H_
#define CONTENT_BROWSER_ZYGOTE_HOST_ZYGOTE_HOST_IMPL_LINUX_H_
+#include <stddef.h>
+
#include <set>
#include <string>
#include <vector>