summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
m---------src/3rdparty0
-rw-r--r--src/buildtools/gn.pro12
-rw-r--r--src/core/accessibility_activation_observer.cpp89
-rw-r--r--src/core/accessibility_activation_observer.h (renamed from src/core/net/qrc_protocol_handler_qt.cpp)32
-rw-r--r--src/core/accessibility_tree_formatter_qt.cpp4
-rw-r--r--src/core/api/core_api.pro4
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp6
-rw-r--r--src/core/api/qtwebenginecoreglobal.h4
-rw-r--r--src/core/api/qtwebenginecoreglobal_p.h2
-rw-r--r--src/core/api/qwebenginecallback.h20
-rw-r--r--src/core/api/qwebenginecallback_p.h85
-rw-r--r--src/core/api/qwebengineclientcertificatestore.cpp120
-rw-r--r--src/core/api/qwebengineclientcertificatestore.h79
-rw-r--r--src/core/api/qwebenginecookiestore.cpp21
-rw-r--r--src/core/api/qwebenginecookiestore.h6
-rw-r--r--src/core/api/qwebenginecookiestore_p.h6
-rw-r--r--src/core/api/qwebenginehttprequest.cpp42
-rw-r--r--src/core/api/qwebenginehttprequest.h19
-rw-r--r--src/core/api/qwebenginemessagepumpscheduler_p.h3
-rw-r--r--src/core/api/qwebenginenotification.cpp323
-rw-r--r--src/core/api/qwebenginenotification.h99
-rw-r--r--src/core/api/qwebenginequotarequest.cpp3
-rw-r--r--src/core/api/qwebenginequotarequest.h5
-rw-r--r--src/core/api/qwebengineregisterprotocolhandlerrequest.cpp2
-rw-r--r--src/core/api/qwebengineregisterprotocolhandlerrequest.h8
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp41
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h9
-rw-r--r--src/core/api/qwebengineurlrequestinfo_p.h11
-rw-r--r--src/core/api/qwebengineurlrequestinterceptor.h8
-rw-r--r--src/core/api/qwebengineurlrequestjob.cpp14
-rw-r--r--src/core/api/qwebengineurlrequestjob.h7
-rw-r--r--src/core/api/qwebengineurlscheme.cpp10
-rw-r--r--src/core/api/qwebengineurlscheme.h6
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp1
-rw-r--r--src/core/api/qwebengineurlschemehandler.h9
-rw-r--r--src/core/authentication_dialog_controller.cpp9
-rw-r--r--src/core/authentication_dialog_controller.h2
-rw-r--r--src/core/browser_accessibility_qt.cpp7
-rw-r--r--src/core/browser_accessibility_qt.h1
-rw-r--r--src/core/browser_main_parts_qt.cpp137
-rw-r--r--src/core/browser_main_parts_qt.h6
-rw-r--r--src/core/browser_message_filter_qt.cpp1
-rw-r--r--src/core/browser_message_filter_qt.h1
-rw-r--r--src/core/certificate_error_controller.h2
-rw-r--r--src/core/chromium_overrides.cpp81
-rw-r--r--src/core/client_cert_select_controller.cpp40
-rw-r--r--src/core/client_cert_select_controller.h4
-rw-r--r--src/core/clipboard_change_observer.h64
-rw-r--r--src/core/clipboard_qt.cpp202
-rw-r--r--src/core/clipboard_qt.h59
-rw-r--r--src/core/color_chooser_controller.cpp3
-rw-r--r--src/core/color_chooser_controller.h5
-rw-r--r--src/core/command_line_pref_store_qt.cpp90
-rw-r--r--src/core/command_line_pref_store_qt.h56
-rw-r--r--src/core/common/extensions/api/qtwebengine_extensions_features.gni25
-rw-r--r--src/core/common/extensions/extensions_api_provider_qt.cpp100
-rw-r--r--src/core/common/extensions/extensions_api_provider_qt.h73
-rw-r--r--src/core/common/extensions/extensions_client_qt.cpp190
-rw-r--r--src/core/common/extensions/extensions_client_qt.h148
-rw-r--r--src/core/common/qt_messages.cpp4
-rw-r--r--src/core/common/qt_messages.h3
-rw-r--r--src/core/compositor/chromium_gpu_helper.cpp (renamed from src/core/chromium_gpu_helper.cpp)17
-rw-r--r--src/core/compositor/chromium_gpu_helper.h (renamed from src/core/chromium_gpu_helper.h)9
-rw-r--r--src/core/compositor/compositor.cpp (renamed from src/core/compositor.cpp)89
-rw-r--r--src/core/compositor/compositor.h (renamed from src/core/compositor.h)44
-rw-r--r--src/core/compositor/compositor_resource.h123
-rw-r--r--src/core/compositor/compositor_resource_fence.cpp158
-rw-r--r--src/core/compositor/compositor_resource_fence.h71
-rw-r--r--src/core/compositor/compositor_resource_tracker.cpp266
-rw-r--r--src/core/compositor/compositor_resource_tracker.h126
-rw-r--r--src/core/compositor/content_gpu_client_qt.cpp59
-rw-r--r--src/core/compositor/content_gpu_client_qt.h57
-rw-r--r--src/core/compositor/delegated_frame_node.cpp (renamed from src/core/delegated_frame_node.cpp)566
-rw-r--r--src/core/compositor/delegated_frame_node.h (renamed from src/core/delegated_frame_node.h)70
-rw-r--r--src/core/compositor/stream_video_node.cpp (renamed from src/core/stream_video_node.cpp)0
-rw-r--r--src/core/compositor/stream_video_node.h (renamed from src/core/stream_video_node.h)0
-rw-r--r--src/core/compositor/yuv_video_node.cpp (renamed from src/core/yuv_video_node.cpp)0
-rw-r--r--src/core/compositor/yuv_video_node.h (renamed from src/core/yuv_video_node.h)0
-rw-r--r--src/core/config/common.pri32
-rw-r--r--src/core/config/linux.pri34
-rw-r--r--src/core/config/mac_osx.pri2
-rw-r--r--src/core/config/windows.pri18
-rw-r--r--src/core/configure.json52
-rw-r--r--src/core/content_browser_client_qt.cpp271
-rw-r--r--src/core/content_browser_client_qt.h58
-rw-r--r--src/core/content_client_qt.cpp51
-rw-r--r--src/core/content_client_qt.h8
-rw-r--r--src/core/content_main_delegate_qt.cpp23
-rw-r--r--src/core/content_main_delegate_qt.h3
-rw-r--r--src/core/content_utility_client_qt.cpp40
-rw-r--r--src/core/content_utility_client_qt.h4
-rw-r--r--src/core/core_chromium.pri112
-rw-r--r--src/core/core_common.pri7
-rw-r--r--src/core/core_generator.pro2
-rw-r--r--src/core/core_gn_config.pri7
-rw-r--r--src/core/core_module.pro6
-rw-r--r--src/core/core_project.pro1
-rw-r--r--src/core/devtools_frontend_qt.cpp175
-rw-r--r--src/core/devtools_frontend_qt.h15
-rw-r--r--src/core/download_manager_delegate_qt.cpp4
-rw-r--r--src/core/download_manager_delegate_qt.h2
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.cpp99
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.h80
-rw-r--r--src/core/extensions/extension_system_factory_qt.cpp98
-rw-r--r--src/core/extensions/extension_system_factory_qt.h82
-rw-r--r--src/core/extensions/extension_system_qt.cpp447
-rw-r--r--src/core/extensions/extension_system_qt.h158
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.cpp126
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.h76
-rw-r--r--src/core/extensions/extensions_api_client_qt.cpp85
-rw-r--r--src/core/extensions/extensions_api_client_qt.h68
-rw-r--r--src/core/extensions/extensions_browser_api_provider_qt.cpp57
-rw-r--r--src/core/extensions/extensions_browser_api_provider_qt.h61
-rw-r--r--src/core/extensions/extensions_browser_client_qt.cpp499
-rw-r--r--src/core/extensions/extensions_browser_client_qt.h161
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.cpp78
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.h76
-rw-r--r--src/core/extensions/pdf_web_contents_helper_client_qt.h29
-rw-r--r--src/core/favicon_manager.h4
-rw-r--r--src/core/file_picker_controller.cpp80
-rw-r--r--src/core/file_picker_controller.h14
-rw-r--r--src/core/gn_run.pro2
-rw-r--r--src/core/javascript_dialog_controller.h2
-rw-r--r--src/core/locked_ptr.h301
-rw-r--r--src/core/login_delegate_qt.cpp51
-rw-r--r--src/core/login_delegate_qt.h6
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp99
-rw-r--r--src/core/media_capture_devices_dispatcher.h20
-rw-r--r--src/core/net/client_cert_override.cpp176
-rw-r--r--src/core/net/client_cert_override.h75
-rw-r--r--src/core/net/client_cert_store_data.cpp168
-rw-r--r--src/core/net/client_cert_store_data.h78
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp47
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h2
-rw-r--r--src/core/net/custom_protocol_handler.cpp2
-rw-r--r--src/core/net/custom_protocol_handler.h2
-rw-r--r--src/core/net/network_delegate_qt.cpp228
-rw-r--r--src/core/net/network_delegate_qt.h7
-rw-r--r--src/core/net/proxy_config_service_qt.cpp16
-rw-r--r--src/core/net/proxy_config_service_qt.h12
-rw-r--r--src/core/net/qrc_url_scheme_handler.cpp (renamed from src/core/net/url_request_qrc_job_qt.h)55
-rw-r--r--src/core/net/qrc_url_scheme_handler.h55
-rw-r--r--src/core/net/url_request_context_getter_qt.cpp6
-rw-r--r--src/core/net/url_request_custom_job.cpp34
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp42
-rw-r--r--src/core/net/url_request_custom_job_delegate.h8
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp12
-rw-r--r--src/core/net/url_request_custom_job_proxy.h2
-rw-r--r--src/core/net/url_request_notification.cpp194
-rw-r--r--src/core/net/url_request_notification.h85
-rw-r--r--src/core/net/url_request_qrc_job_qt.cpp133
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp3
-rw-r--r--src/core/ozone/BUILD.gn25
-rw-r--r--src/core/ozone/gl_context_qt.cpp13
-rw-r--r--src/core/ozone/gl_surface_egl_qt.cpp18
-rw-r--r--src/core/ozone/gl_surface_qt.cpp4
-rw-r--r--src/core/ozone/gl_surface_wgl_qt.cpp4
-rw-r--r--src/core/ozone/ozone_extra.gni19
-rw-r--r--src/core/ozone/ozone_platform_qt.cpp8
-rw-r--r--src/core/ozone/platform_window_qt.h3
-rw-r--r--src/core/ozone/surface_factory_qt.cpp5
-rw-r--r--src/core/permission_manager_qt.cpp24
-rw-r--r--src/core/permission_manager_qt.h2
-rw-r--r--src/core/platform_notification_service_qt.cpp208
-rw-r--r--src/core/platform_notification_service_qt.h92
-rw-r--r--src/core/printing/pdfium_document_wrapper_qt.cpp32
-rw-r--r--src/core/printing/pdfium_document_wrapper_qt.h7
-rw-r--r--src/core/printing/print_view_manager_base_qt.cpp27
-rw-r--r--src/core/printing/print_view_manager_qt.cpp97
-rw-r--r--src/core/printing/print_view_manager_qt.h5
-rw-r--r--src/core/printing/printing_message_filter_qt.cpp10
-rw-r--r--src/core/printing/printing_message_filter_qt.h2
-rw-r--r--src/core/process_main.cpp12
-rw-r--r--src/core/process_main.h2
-rw-r--r--src/core/profile_adapter.cpp170
-rw-r--r--src/core/profile_adapter.h54
-rw-r--r--src/core/profile_adapter_client.h7
-rw-r--r--src/core/profile_io_data_qt.cpp209
-rw-r--r--src/core/profile_io_data_qt.h46
-rw-r--r--src/core/profile_qt.cpp101
-rw-r--r--src/core/profile_qt.h22
-rw-r--r--src/core/qtwebengine.gni31
-rw-r--r--src/core/qtwebengine_resources.gni40
-rw-r--r--src/core/qtwebengine_sources.gni62
-rw-r--r--src/core/quota_permission_context_qt.cpp18
-rw-r--r--src/core/render_view_context_menu_qt.h2
-rw-r--r--src/core/render_widget_host_view_qt.cpp365
-rw-r--r--src/core/render_widget_host_view_qt.h59
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h12
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp185
-rw-r--r--src/core/renderer/content_renderer_client_qt.h44
-rw-r--r--src/core/renderer/content_settings_observer_qt.cpp11
-rw-r--r--src/core/renderer/content_settings_observer_qt.h7
-rw-r--r--src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp (renamed from src/core/chromium_overrides.h)20
-rw-r--r--src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h60
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.cpp205
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.h135
-rw-r--r--src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp66
-rw-r--r--src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h (renamed from src/core/net/qrc_protocol_handler_qt.h)38
-rw-r--r--src/core/renderer/extensions/resource_request_policy_qt.cpp183
-rw-r--r--src/core/renderer/extensions/resource_request_policy_qt.h89
-rw-r--r--src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp26
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp14
-rw-r--r--src/core/renderer/print_web_view_helper_delegate_qt.cpp17
-rw-r--r--src/core/renderer/render_frame_observer_qt.h5
-rw-r--r--src/core/renderer/render_thread_observer_qt.cpp73
-rw-r--r--src/core/renderer/render_thread_observer_qt.h77
-rw-r--r--src/core/renderer/render_view_observer_qt.cpp2
-rw-r--r--src/core/renderer/user_resource_controller.cpp8
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp14
-rw-r--r--src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp4
-rw-r--r--src/core/renderer_host/render_view_observer_host_qt.cpp (renamed from src/core/render_view_observer_host_qt.cpp)0
-rw-r--r--src/core/renderer_host/render_view_observer_host_qt.h (renamed from src/core/render_view_observer_host_qt.h)0
-rw-r--r--src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp186
-rw-r--r--src/core/renderer_host/resource_dispatcher_host_delegate_qt.h77
-rw-r--r--src/core/renderer_host/user_resource_controller_host.h2
-rw-r--r--src/core/resource_bundle_qt.cpp1
-rw-r--r--src/core/resource_context_qt.cpp18
-rw-r--r--src/core/resource_context_qt.h17
-rw-r--r--src/core/service/service_qt.cpp29
-rw-r--r--src/core/service/service_qt.h6
-rw-r--r--src/core/touch_handle_drawable_client.h60
-rw-r--r--src/core/touch_handle_drawable_qt.cpp211
-rw-r--r--src/core/touch_handle_drawable_qt.h87
-rw-r--r--src/core/touch_selection_controller_client_qt.cpp343
-rw-r--r--src/core/touch_selection_controller_client_qt.h118
-rw-r--r--src/core/touch_selection_menu_controller.cpp91
-rw-r--r--src/core/touch_selection_menu_controller.h76
-rw-r--r--src/core/type_conversion.cpp15
-rw-r--r--src/core/type_conversion.h19
-rw-r--r--src/core/user_notification_controller.cpp216
-rw-r--r--src/core/user_notification_controller.h114
-rw-r--r--src/core/user_script.h2
-rw-r--r--src/core/visited_links_manager_qt.cpp10
-rw-r--r--src/core/visited_links_manager_qt.h6
-rw-r--r--src/core/web_contents_adapter.cpp150
-rw-r--r--src/core/web_contents_adapter.h4
-rw-r--r--src/core/web_contents_adapter_client.h13
-rw-r--r--src/core/web_contents_delegate_qt.cpp50
-rw-r--r--src/core/web_contents_delegate_qt.h11
-rw-r--r--src/core/web_contents_view_qt.cpp44
-rw-r--r--src/core/web_contents_view_qt.h23
-rw-r--r--src/core/web_engine_context.cpp278
-rw-r--r--src/core/web_engine_context.h25
-rw-r--r--src/core/web_engine_context_threads.cpp136
-rw-r--r--src/core/web_engine_error.h2
-rw-r--r--src/core/web_engine_library_info.cpp31
-rw-r--r--src/core/web_engine_settings.cpp9
-rw-r--r--src/core/web_engine_settings.h3
-rw-r--r--src/core/web_event_factory.cpp36
-rw-r--r--src/core/web_event_factory.h12
-rw-r--r--src/plugins/plugins.pro2
-rw-r--r--src/src.pro22
-rw-r--r--src/tools/qwebengine_convert_dict/main.cpp4
-rw-r--r--src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro2
-rw-r--r--src/webengine/api/qquickwebengineclientcertificateselection.cpp226
-rw-r--r--src/webengine/api/qquickwebengineclientcertificateselection_p.h131
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp196
-rw-r--r--src/webengine/api/qquickwebengineprofile.h24
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h4
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp24
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h4
-rw-r--r--src/webengine/api/qquickwebenginetouchhandleprovider.cpp80
-rw-r--r--src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h77
-rw-r--r--src/webengine/api/qquickwebengineview.cpp111
-rw-r--r--src/webengine/api/qquickwebengineview_p.h10
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h25
-rw-r--r--src/webengine/api/qtwebengineglobal.h1
-rw-r--r--src/webengine/api/qtwebengineglobal_p.h4
-rw-r--r--src/webengine/configure.json30
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf13
-rw-r--r--src/webengine/doc/src/external-resources.qdoc5
-rw-r--r--src/webengine/doc/src/qtwebengine-features.qdoc30
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc18
-rw-r--r--src/webengine/doc/src/qtwebengine-qmlmodule.qdoc4
-rw-r--r--src/webengine/doc/src/webengineview_lgpl.qdoc18
-rw-r--r--src/webengine/module.pro94
-rw-r--r--src/webengine/plugin/plugin.cpp61
-rw-r--r--src/webengine/plugin/plugin.pro7
-rw-r--r--src/webengine/plugin/plugins.qmltypes101
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp45
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h5
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp50
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h11
-rw-r--r--src/webengine/testsupport/plugin.cpp (renamed from src/webengine/plugin/testsupport/plugin.cpp)2
-rw-r--r--src/webengine/testsupport/plugins.qmltypes73
-rw-r--r--src/webengine/testsupport/qmldir (renamed from src/webengine/plugin/testsupport/qmldir)0
-rw-r--r--src/webengine/testsupport/testsupport.pro (renamed from src/webengine/plugin/testsupport/testsupport.pro)4
-rw-r--r--src/webengine/ui/TouchHandle.qml42
-rw-r--r--src/webengine/ui/TouchSelectionMenu.qml175
-rw-r--r--src/webengine/ui/ui.pro4
-rw-r--r--src/webengine/ui_delegates_manager.cpp83
-rw-r--r--src/webengine/ui_delegates_manager.h7
-rw-r--r--src/webengine/webengine.pro92
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter.cpp109
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter_p.h87
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp177
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h5
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h11
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp152
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h22
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h6
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp3
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.h1
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp7
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc2
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc4
-rw-r--r--src/webenginewidgets/printer_worker.cpp169
-rw-r--r--src/webenginewidgets/printer_worker.h88
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp65
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h5
-rw-r--r--src/webenginewidgets/webenginewidgets.pro5
312 files changed, 14650 insertions, 3126 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 111349f18a4d352d40c1c106a6f8e98a9f84389
+Subproject 0240cfc1a59deb5b612923d47ccef72f10504fe
diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro
index 559cdf183..b6bf9cfc4 100644
--- a/src/buildtools/gn.pro
+++ b/src/buildtools/gn.pro
@@ -18,7 +18,17 @@ build_pass|!debug_and_release {
src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
gn_bootstrap = $$system_path($$absolute_path(gn/build/gen.py, $$src_3rd_party_dir))
- gn_configure = $$system_quote($$gn_bootstrap) --no-last-commit-position --out-path $$out_path
+ gn_gen_args = --no-last-commit-position --out-path $$out_path \
+ --cc \"$$which($$QMAKE_CC)\" --cxx \"$$which($$QMAKE_CXX)\" \
+ --ld \"$$which($$QMAKE_LINK)\"
+
+ msvc:!clang_cl: gn_gen_args += --use-lto
+
+ gn_configure = $$system_quote($$gn_bootstrap) $$gn_gen_args
+ macos {
+ gn_configure += --isysroot \"$$QMAKE_MAC_SDK_PATH\"
+ }
+ message($$gn_configure)
!system("$$pythonPathForSystem() $$gn_configure") {
error("GN generation error!")
}
diff --git a/src/core/accessibility_activation_observer.cpp b/src/core/accessibility_activation_observer.cpp
new file mode 100644
index 000000000..75ad90c54
--- /dev/null
+++ b/src/core/accessibility_activation_observer.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "accessibility_activation_observer.h"
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#include "content/browser/accessibility/browser_accessibility_state_impl.h"
+
+namespace QtWebEngineCore {
+
+namespace {
+
+bool isAccessibilityEnabled() {
+ // On Linux accessibility is disabled by default due to performance issues,
+ // and can be re-enabled by setting the QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
+ // variable. For details, see QTBUG-59922.
+#ifdef Q_OS_LINUX
+ static bool accessibility_enabled
+ = qEnvironmentVariableIsSet("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY");
+#else
+ const bool accessibility_enabled = true;
+#endif
+ return accessibility_enabled;
+}
+
+} // namespace
+
+AccessibilityActivationObserver::AccessibilityActivationObserver()
+{
+ if (isAccessibilityEnabled()) {
+ QAccessible::installActivationObserver(this);
+ if (QAccessible::isActive())
+ content::BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility();
+ }
+}
+
+AccessibilityActivationObserver::~AccessibilityActivationObserver()
+{
+ QAccessible::removeActivationObserver(this);
+}
+
+void AccessibilityActivationObserver::accessibilityActiveChanged(bool active)
+{
+ if (active)
+ content::BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility();
+ else
+ content::BrowserAccessibilityStateImpl::GetInstance()->DisableAccessibility();
+}
+
+} // namespace QtWebEngineCore
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/core/net/qrc_protocol_handler_qt.cpp b/src/core/accessibility_activation_observer.h
index eb716f182..e42c83eb5 100644
--- a/src/core/net/qrc_protocol_handler_qt.cpp
+++ b/src/core/accessibility_activation_observer.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,27 +37,27 @@
**
****************************************************************************/
-#include "qrc_protocol_handler_qt.h"
-#include "url_request_qrc_job_qt.h"
+#ifndef ACCESSIBILITY_ACTIVATION_OBSERVER_H
+#define ACCESSIBILITY_ACTIVATION_OBSERVER_H
-#include "net/base/net_errors.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_error_job.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qaccessible.h>
namespace QtWebEngineCore {
-const char kQrcSchemeQt[] = "qrc";
+class RenderWidgetHostViewQt;
-QrcProtocolHandlerQt::QrcProtocolHandlerQt()
+class AccessibilityActivationObserver : public QAccessible::ActivationObserver
{
-}
+public:
+ AccessibilityActivationObserver();
+ ~AccessibilityActivationObserver();
-net::URLRequestJob *QrcProtocolHandlerQt::MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const
-{
- if (!networkDelegate)
- return new net::URLRequestErrorJob(request, Q_NULLPTR, net::ERR_ACCESS_DENIED);
-
- return new URLRequestQrcJobQt(request, networkDelegate);
-}
+ void accessibilityActiveChanged(bool active) override;
+};
} // namespace QtWebEngineCore
+
+#endif // QT_NO_ACCESSIBILITY
+
+#endif // ACCESSIBILITY_ACTIVATION_OBSERVER_H
diff --git a/src/core/accessibility_tree_formatter_qt.cpp b/src/core/accessibility_tree_formatter_qt.cpp
index 8b15c5dee..706857207 100644
--- a/src/core/accessibility_tree_formatter_qt.cpp
+++ b/src/core/accessibility_tree_formatter_qt.cpp
@@ -201,10 +201,10 @@ const std::string AccessibilityTreeFormatterQt::GetDenyString()
#endif // QT_NO_ACCESSIBILITY
// static
-AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create()
+std::unique_ptr<AccessibilityTreeFormatter> AccessibilityTreeFormatter::Create()
{
#ifndef QT_NO_ACCESSIBILITY
- return new AccessibilityTreeFormatterQt();
+ return std::unique_ptr<AccessibilityTreeFormatter>(new AccessibilityTreeFormatterQt());
#else
return nullptr;
#endif
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 4b69b348a..326d4481f 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -32,12 +32,14 @@ gcc: QMAKE_CXXFLAGS_WARN_ON = -Wno-unused-parameter
HEADERS = \
qwebenginecallback.h \
qwebenginecallback_p.h \
+ qwebengineclientcertificatestore.h \
qtwebenginecoreglobal.h \
qtwebenginecoreglobal_p.h \
qwebenginecookiestore.h \
qwebenginecookiestore_p.h \
qwebenginehttprequest.h \
qwebenginemessagepumpscheduler_p.h \
+ qwebenginenotification.h \
qwebenginequotarequest.h \
qwebengineregisterprotocolhandlerrequest.h \
qwebengineurlrequestinterceptor.h \
@@ -49,9 +51,11 @@ HEADERS = \
SOURCES = \
qtwebenginecoreglobal.cpp \
+ qwebengineclientcertificatestore.cpp \
qwebenginecookiestore.cpp \
qwebenginehttprequest.cpp \
qwebenginemessagepumpscheduler.cpp \
+ qwebenginenotification.cpp \
qwebenginequotarequest.cpp \
qwebengineregisterprotocolhandlerrequest.cpp \
qwebengineurlrequestinfo.cpp \
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index 5a634641b..25d0bd3be 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -58,7 +58,8 @@ QT_END_NAMESPACE
#ifndef QT_NO_OPENGL
#ifdef Q_OS_MACOS
-static bool needsOfflineRendererWorkaround() {
+static bool needsOfflineRendererWorkaround()
+{
size_t hwmodelsize = 0;
if (sysctlbyname("hw.model", nullptr, &hwmodelsize, nullptr, 0) == -1)
@@ -91,7 +92,7 @@ static void deleteShareContext()
// after the QGuiApplication creation, when AA_ShareOpenGLContexts fills
// the same need but the flag has to be set earlier.
-QWEBENGINECORE_PRIVATE_EXPORT void initialize()
+Q_WEBENGINECORE_PRIVATE_EXPORT void initialize()
{
#ifndef QT_NO_OPENGL
#ifdef Q_OS_WIN32
@@ -133,4 +134,3 @@ QWEBENGINECORE_PRIVATE_EXPORT void initialize()
#endif // QT_NO_OPENGL
}
} // namespace QtWebEngineCore
-
diff --git a/src/core/api/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal.h
index bcff622b7..c425d1478 100644
--- a/src/core/api/qtwebenginecoreglobal.h
+++ b/src/core/api/qtwebenginecoreglobal.h
@@ -46,9 +46,9 @@
QT_BEGIN_NAMESPACE
#if defined(BUILDING_CHROMIUM)
-# define QWEBENGINECORE_EXPORT Q_DECL_EXPORT
+# define Q_WEBENGINECORE_EXPORT Q_DECL_EXPORT
#else
-# define QWEBENGINECORE_EXPORT Q_DECL_IMPORT
+# define Q_WEBENGINECORE_EXPORT Q_DECL_IMPORT
#endif
#define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match");
diff --git a/src/core/api/qtwebenginecoreglobal_p.h b/src/core/api/qtwebenginecoreglobal_p.h
index 27bf2d9f9..655b2a814 100644
--- a/src/core/api/qtwebenginecoreglobal_p.h
+++ b/src/core/api/qtwebenginecoreglobal_p.h
@@ -63,6 +63,6 @@
#define QT_NOT_USED Q_UNREACHABLE(); // This will assert in debug.
#endif
-#define QWEBENGINECORE_PRIVATE_EXPORT QWEBENGINECORE_EXPORT
+#define Q_WEBENGINECORE_PRIVATE_EXPORT Q_WEBENGINECORE_EXPORT
#endif // QTWEBENGINECOREGLOBAL_P_H
diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h
index b981b2afb..49efc50b2 100644
--- a/src/core/api/qwebenginecallback.h
+++ b/src/core/api/qwebenginecallback.h
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
namespace QtWebEnginePrivate {
-template <typename T>
+template<typename T>
class QWebEngineCallbackPrivateBase : public QSharedData {
public:
QWebEngineCallbackPrivateBase() {}
@@ -62,32 +62,32 @@ public:
virtual void operator()(T) = 0;
};
-template <typename T, typename F>
+template<typename T, typename F>
class QWebEngineCallbackPrivate : public QWebEngineCallbackPrivateBase<T> {
public:
- QWebEngineCallbackPrivate(F callable)
- : m_callable(callable)
- {}
+ QWebEngineCallbackPrivate(F callable) : m_callable(callable) {}
void operator()(T value) override { m_callable(value); }
+
private:
F m_callable;
};
} // namespace QtWebEnginePrivate
-template <typename T>
+template<typename T>
class QWebEngineCallback {
public:
- template <typename F>
+ template<typename F>
QWebEngineCallback(F f)
: d(new QtWebEnginePrivate::QWebEngineCallbackPrivate<T, F>(f))
- { }
- QWebEngineCallback() { }
+ {}
+ QWebEngineCallback() {}
void swap(QWebEngineCallback &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
operator bool() const { return d; }
+
private:
friend class QtWebEngineCore::CallbackDirectory;
- QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d;
+ QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T>> d;
};
Q_DECLARE_SHARED(QWebEngineCallback<int>)
diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h
index 24b4495df..133a86f6d 100644
--- a/src/core/api/qwebenginecallback_p.h
+++ b/src/core/api/qwebenginecallback_p.h
@@ -62,11 +62,11 @@
#include <type_traits>
// keep in sync with Q_DECLARE_SHARED... in qwebenginecallback.h
-#define FOR_EACH_TYPE(F) \
- F(bool) \
- F(int) \
- F(const QString &) \
- F(const QByteArray &) \
+#define FOR_EACH_TYPE(F) \
+ F(bool) \
+ F(int) \
+ F(const QString &) \
+ F(const QByteArray &) \
F(const QVariant &)
namespace QtWebEngineCore {
@@ -82,7 +82,7 @@ public:
{
// "Cancel" pending callbacks by calling them with an invalid value.
// This guarantees that each callback is called exactly once.
- for (CallbackSharedDataPointerBase * const sharedPtrBase: m_callbackMap) {
+ for (CallbackSharedDataPointerBase *const sharedPtrBase : m_callbackMap) {
Q_ASSERT(sharedPtrBase);
sharedPtrBase->invokeEmpty();
delete sharedPtrBase;
@@ -106,20 +106,18 @@ public:
template<typename T>
void invokeEmpty(const QWebEngineCallback<T> &callback);
-#define DEFINE_INVOKE_FOR_TYPE(Type) \
- void invoke(quint64 callbackId, Type result) { \
- invokeInternal<Type>(callbackId, std::forward<Type>(result)); \
- }
+#define DEFINE_INVOKE_FOR_TYPE(Type) \
+ void invoke(quint64 callbackId, Type result) { invokeInternal<Type>(callbackId, std::forward<Type>(result)); }
FOR_EACH_TYPE(DEFINE_INVOKE_FOR_TYPE)
#undef DEFINE_INVOKE_FOR_TYPE
- template <typename A>
+ template<typename A>
void invokeDirectly(const QWebEngineCallback<typename std::remove_reference<A>::type &> &callback, A &argument)
{
return callback.d.data()->operator()(argument);
}
- template <typename A>
+ template<typename A>
void invokeDirectly(const QWebEngineCallback<typename std::remove_reference<A>::type> &callback, const A &argument)
{
return callback.d.data()->operator()(std::forward<const A &>(argument));
@@ -127,39 +125,45 @@ public:
private:
struct CallbackSharedDataPointerBase {
- virtual ~CallbackSharedDataPointerBase() { }
+ virtual ~CallbackSharedDataPointerBase() {}
virtual void invokeEmpty() = 0;
virtual void doRef() = 0;
virtual void doDeref() = 0;
- virtual operator bool () const = 0;
+ virtual operator bool() const = 0;
};
- template <typename T>
+ template<typename T>
struct CallbackSharedDataPointer : public CallbackSharedDataPointerBase {
- CallbackDirectory* parent;
+ CallbackDirectory *parent;
QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback;
~CallbackSharedDataPointer() { doDeref(); }
- CallbackSharedDataPointer() : parent(0), callback(0) { }
+ CallbackSharedDataPointer() : parent(0), callback(0) {}
CallbackSharedDataPointer(const CallbackSharedDataPointer<T> &other)
- : parent(other.parent), callback(other.callback) { doRef(); }
+ : parent(other.parent), callback(other.callback)
+ {
+ doRef();
+ }
CallbackSharedDataPointer(CallbackDirectory *p, QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *c)
- : parent(p), callback(c) { Q_ASSERT(callback); doRef(); }
+ : parent(p), callback(c)
+ {
+ Q_ASSERT(callback);
+ doRef();
+ }
void invokeEmpty() override;
- operator bool () const override { return callback; }
+ operator bool() const override { return callback; }
private:
void doRef() override;
void doDeref() override;
};
- QHash<quint64, CallbackSharedDataPointerBase*> m_callbackMap;
+ QHash<quint64, CallbackSharedDataPointerBase *> m_callbackMap;
};
template<typename T>
-inline
-void CallbackDirectory::registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback)
+inline void CallbackDirectory::registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback)
{
if (!callback.d)
return;
@@ -167,10 +171,9 @@ void CallbackDirectory::registerCallback(quint64 callbackId, const QWebEngineCal
}
template<typename T>
-inline
-void CallbackDirectory::invokeInternal(quint64 callbackId, T result)
+inline void CallbackDirectory::invokeInternal(quint64 callbackId, T result)
{
- CallbackSharedDataPointerBase * const sharedPtrBase = m_callbackMap.take(callbackId);
+ CallbackSharedDataPointerBase *const sharedPtrBase = m_callbackMap.take(callbackId);
if (!sharedPtrBase)
return;
@@ -181,8 +184,7 @@ void CallbackDirectory::invokeInternal(quint64 callbackId, T result)
}
template<typename T>
-inline
-void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback)
+inline void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback)
{
Q_ASSERT(callback);
using NoRefT = typename std::remove_reference<T>::type;
@@ -192,24 +194,21 @@ void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallba
}
template<>
-inline
-void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<bool> *callback)
+inline void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<bool> *callback)
{
Q_ASSERT(callback);
(*callback)(false);
}
template<>
-inline
-void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<int> *callback)
+inline void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<int> *callback)
{
Q_ASSERT(callback);
(*callback)(0);
}
template<typename T>
-inline
-void CallbackDirectory::invokeEmpty(const QWebEngineCallback<T> &callback)
+inline void CallbackDirectory::invokeEmpty(const QWebEngineCallback<T> &callback)
{
if (!callback.d)
return;
@@ -217,9 +216,8 @@ void CallbackDirectory::invokeEmpty(const QWebEngineCallback<T> &callback)
invokeEmptyInternal(callback.d.data());
}
-template <typename T>
-inline
-void CallbackDirectory::CallbackSharedDataPointer<T>::doRef()
+template<typename T>
+inline void CallbackDirectory::CallbackSharedDataPointer<T>::doRef()
{
if (!callback)
return;
@@ -227,9 +225,8 @@ void CallbackDirectory::CallbackSharedDataPointer<T>::doRef()
callback->ref.ref();
}
-template <typename T>
-inline
-void CallbackDirectory::CallbackSharedDataPointer<T>::doDeref()
+template<typename T>
+inline void CallbackDirectory::CallbackSharedDataPointer<T>::doDeref()
{
if (!callback)
return;
@@ -237,9 +234,8 @@ void CallbackDirectory::CallbackSharedDataPointer<T>::doDeref()
delete callback;
}
-template <typename T>
-inline
-void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty()
+template<typename T>
+inline void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty()
{
if (!callback)
return;
@@ -248,8 +244,7 @@ void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty()
parent->invokeEmptyInternal(callback);
}
-#define CHECK_RELOCATABLE(x) \
- Q_STATIC_ASSERT((QTypeInfoQuery<QWebEngineCallback< x > >::isRelocatable));
+#define CHECK_RELOCATABLE(x) Q_STATIC_ASSERT((QTypeInfoQuery<QWebEngineCallback<x>>::isRelocatable));
FOR_EACH_TYPE(CHECK_RELOCATABLE)
#undef CHECK_RELOCATABLE
diff --git a/src/core/api/qwebengineclientcertificatestore.cpp b/src/core/api/qwebengineclientcertificatestore.cpp
new file mode 100644
index 000000000..84f273328
--- /dev/null
+++ b/src/core/api/qwebengineclientcertificatestore.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebengineclientcertificatestore.h"
+
+#include "net/client_cert_store_data.h"
+
+#include <QByteArray>
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(ssl)
+
+/*!
+ \class QWebEngineClientCertificateStore
+ \inmodule QtWebEngineCore
+ \since 5.13
+ \brief The QWebEngineClientCertificateStore class provides an in-memory store for client certificates.
+
+ The class allows to store client certificates in an in-memory store.
+ When a web site requests an SSL client certificate, the QWebEnginePage::selectClientCertificate
+ signal is emitted with matching certificates from the native certificate store or the in-memory store.
+ The getInstance() method can be used to access the single instance of the class.
+*/
+
+QWebEngineClientCertificateStore::QWebEngineClientCertificateStore(QtWebEngineCore::ClientCertificateStoreData *storeData)
+ : m_storeData(storeData)
+{}
+
+/*!
+ Destroys this QWebEngineClientCertificateStore object.
+*/
+
+QWebEngineClientCertificateStore::~QWebEngineClientCertificateStore()
+{
+ // Just in case user has not deleted in-memory certificates
+ clear();
+}
+
+/*!
+ Adds a \a certificate with the \a privateKey to the in-memory client certificate store.
+*/
+
+void QWebEngineClientCertificateStore::add(const QSslCertificate &certificate, const QSslKey &privateKey)
+{
+ m_storeData->add(certificate, privateKey);
+}
+
+/*!
+ Returns a list of the client certificates in the in-memory store.
+ Returns an empty list if the store does not contain any certificates.
+*/
+
+QVector<QSslCertificate> QWebEngineClientCertificateStore::certificates() const
+{
+ QVector<QSslCertificate> certificateList;
+ for (auto data : qAsConst(m_storeData->extraCerts))
+ certificateList.append(data->certificate);
+ return certificateList;
+}
+
+/*!
+ Deletes all the instances of the client certificate in the in-memory client certificate store
+ that matches the certificate \a certificate.
+*/
+
+void QWebEngineClientCertificateStore::remove(const QSslCertificate &certificate)
+{
+ m_storeData->remove(certificate);
+}
+
+/*!
+ Clears all the client certificates from the in-memory store.
+*/
+
+void QWebEngineClientCertificateStore::clear()
+{
+ m_storeData->clear();
+}
+
+#endif // QT_CONFIG(ssl)
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineclientcertificatestore.h b/src/core/api/qwebengineclientcertificatestore.h
new file mode 100644
index 000000000..a4c83bb2e
--- /dev/null
+++ b/src/core/api/qwebengineclientcertificatestore.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINECLIENTCERTIFICATESTORE_H
+#define QWEBENGINECLIENTCERTIFICATESTORE_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+#include <QtCore/qvector.h>
+#include <QtNetwork/qsslcertificate.h>
+#include <QtNetwork/qsslkey.h>
+
+namespace QtWebEngineCore {
+struct ClientCertificateStoreData;
+class ProfileAdapter;
+} // namespace QtWebEngineCore
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(ssl)
+
+class Q_WEBENGINECORE_EXPORT QWebEngineClientCertificateStore {
+
+public:
+ void add(const QSslCertificate &certificate, const QSslKey &privateKey);
+ QVector<QSslCertificate> certificates() const;
+ void remove(const QSslCertificate &certificate);
+ void clear();
+
+private:
+ friend class QtWebEngineCore::ProfileAdapter;
+ Q_DISABLE_COPY(QWebEngineClientCertificateStore)
+
+ QWebEngineClientCertificateStore(QtWebEngineCore::ClientCertificateStoreData *storeData);
+ ~QWebEngineClientCertificateStore();
+ QtWebEngineCore::ClientCertificateStoreData *m_storeData;
+};
+
+#endif // QT_CONFIG(ssl)
+
+QT_END_NAMESPACE
+
+#endif // QWebEngineClientCertificateStore_H
diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp
index 3897fb128..40594b9c0 100644
--- a/src/core/api/qwebenginecookiestore.cpp
+++ b/src/core/api/qwebenginecookiestore.cpp
@@ -47,15 +47,14 @@
#include <QByteArray>
#include <QUrl>
-
namespace {
-inline GURL toGurl(const QUrl& url)
+inline GURL toGurl(const QUrl &url)
{
return GURL(url.toString().toStdString());
}
-}
+} // namespace
QT_BEGIN_NAMESPACE
@@ -68,8 +67,7 @@ QWebEngineCookieStorePrivate::QWebEngineCookieStorePrivate(QWebEngineCookieStore
, m_deleteAllCookiesPending(false)
, m_getAllCookiesPending(false)
, delegate(0)
-{
-}
+{}
void QWebEngineCookieStorePrivate::processPendingUserCookies()
{
@@ -112,7 +110,8 @@ void QWebEngineCookieStorePrivate::rejectPendingUserCookies()
m_pendingUserCookies.clear();
}
-void QWebEngineCookieStorePrivate::setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie, const QUrl &origin)
+void QWebEngineCookieStorePrivate::setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie,
+ const QUrl &origin)
{
const quint64 currentCallbackId = callback ? m_nextCallbackId++ : static_cast<quint64>(CallbackDirectory::NoCallbackId);
@@ -201,7 +200,7 @@ bool QWebEngineCookieStorePrivate::canAccessCookies(const QUrl &firstPartyUrl, c
toGurl(firstPartyUrl),
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- QWebEngineCookieStore::FilterRequest request = { firstPartyUrl, url, thirdParty, false, 0};
+ QWebEngineCookieStore::FilterRequest request = { firstPartyUrl, url, thirdParty, false, 0 };
return filterCallback(request);
}
@@ -249,10 +248,7 @@ QWebEngineCookieStore::QWebEngineCookieStore(QObject *parent)
Destroys this QWebEngineCookieStore object.
*/
-QWebEngineCookieStore::~QWebEngineCookieStore()
-{
-
-}
+QWebEngineCookieStore::~QWebEngineCookieStore() {}
/*!
Adds \a cookie to the cookie store.
@@ -298,7 +294,8 @@ void QWebEngineCookieStore::loadAllCookies()
//TODO: use callbacks or delete dummy ones
if (d_ptr->m_getAllCookiesPending)
return;
- d_ptr->callbackDirectory.registerCallback(CallbackDirectory::GetAllCookiesCallbackId, QWebEngineCallback<const QByteArray&>());
+ d_ptr->callbackDirectory.registerCallback(CallbackDirectory::GetAllCookiesCallbackId,
+ QWebEngineCallback<const QByteArray &>());
//this will trigger cookieAdded signal
d_ptr->getAllCookies();
}
diff --git a/src/core/api/qwebenginecookiestore.h b/src/core/api/qwebenginecookiestore.h
index 89e72dfb0..3d313ac23 100644
--- a/src/core/api/qwebenginecookiestore.h
+++ b/src/core/api/qwebenginecookiestore.h
@@ -52,12 +52,12 @@
namespace QtWebEngineCore {
class ProfileAdapter;
class CookieMonsterDelegateQt;
-}
+} // namespace QtWebEngineCore
QT_BEGIN_NAMESPACE
class QWebEngineCookieStorePrivate;
-class QWEBENGINECORE_EXPORT QWebEngineCookieStore : public QObject {
+class Q_WEBENGINECORE_EXPORT QWebEngineCookieStore : public QObject {
Q_OBJECT
public:
@@ -93,6 +93,6 @@ private:
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QWebEngineCookieStore*)
+Q_DECLARE_METATYPE(QWebEngineCookieStore *)
#endif // QWEBENGINECOOKIESTORE_H
diff --git a/src/core/api/qwebenginecookiestore_p.h b/src/core/api/qwebenginecookiestore_p.h
index 93198d8ed..a79e2b095 100644
--- a/src/core/api/qwebenginecookiestore_p.h
+++ b/src/core/api/qwebenginecookiestore_p.h
@@ -66,8 +66,7 @@ class CookieMonsterDelegateQt;
QT_BEGIN_NAMESPACE
-class QWEBENGINECORE_PRIVATE_EXPORT QWebEngineCookieStorePrivate
-{
+class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineCookieStorePrivate {
Q_DECLARE_PUBLIC(QWebEngineCookieStore)
struct CookieData {
quint64 callbackId;
@@ -76,9 +75,10 @@ class QWEBENGINECORE_PRIVATE_EXPORT QWebEngineCookieStorePrivate
};
friend class QTypeInfo<CookieData>;
QWebEngineCookieStore *q_ptr;
+
public:
QtWebEngineCore::CallbackDirectory callbackDirectory;
- std::function<bool(const QWebEngineCookieStore::FilterRequest&)> filterCallback;
+ std::function<bool(const QWebEngineCookieStore::FilterRequest &)> filterCallback;
QVector<CookieData> m_pendingUserCookies;
quint64 m_nextCallbackId;
bool m_deleteSessionCookiesPending;
diff --git a/src/core/api/qwebenginehttprequest.cpp b/src/core/api/qwebenginehttprequest.cpp
index b64af4466..3395cc99f 100644
--- a/src/core/api/qwebenginehttprequest.cpp
+++ b/src/core/api/qwebenginehttprequest.cpp
@@ -67,8 +67,7 @@ QT_BEGIN_NAMESPACE
\value Post The POST method.
*/
-class QWebEngineHttpRequestPrivate : public QSharedData
-{
+class QWebEngineHttpRequestPrivate : public QSharedData {
public:
QUrl url;
QWebEngineHttpRequest::Method method;
@@ -77,23 +76,18 @@ public:
Headers headers;
QByteArray postData;
- inline QWebEngineHttpRequestPrivate()
- {
- }
+ QWebEngineHttpRequestPrivate() {}
- ~QWebEngineHttpRequestPrivate()
- {
- }
+ ~QWebEngineHttpRequestPrivate() {}
- QWebEngineHttpRequestPrivate(const QWebEngineHttpRequestPrivate &other)
- : QSharedData(other)
+ QWebEngineHttpRequestPrivate(const QWebEngineHttpRequestPrivate &other) : QSharedData(other)
{
method = other.method;
url = other.url;
headers = other.headers;
}
- inline bool operator==(const QWebEngineHttpRequestPrivate &other) const
+ bool operator==(const QWebEngineHttpRequestPrivate &other) const
{
return method == other.method
&& url == other.url
@@ -128,10 +122,7 @@ QWebEngineHttpRequest::QWebEngineHttpRequest(const QUrl &url,
/*!
Creates a copy of \a other.
*/
-QWebEngineHttpRequest::QWebEngineHttpRequest(const QWebEngineHttpRequest &other)
- : d(other.d)
-{
-}
+QWebEngineHttpRequest::QWebEngineHttpRequest(const QWebEngineHttpRequest &other) : d(other.d) {}
/*!
Disposes of the QWebEngineHttpRequest object.
@@ -207,7 +198,6 @@ QWebEngineHttpRequest QWebEngineHttpRequest::postRequest(const QUrl &url,
return result;
}
-
/*!
Returns the method this WebEngine request is using.
@@ -291,8 +281,7 @@ bool QWebEngineHttpRequest::hasHeader(const QByteArray &headerName) const
*/
QByteArray QWebEngineHttpRequest::header(const QByteArray &headerName) const
{
- QWebEngineHttpRequestPrivate::Headers::ConstIterator it =
- d->findHeader(headerName);
+ QWebEngineHttpRequestPrivate::Headers::ConstIterator it = d->findHeader(headerName);
if (it != d->headers.constEnd())
return it->second;
return QByteArray();
@@ -334,16 +323,15 @@ void QWebEngineHttpRequest::unsetHeader(const QByteArray &key)
d->setHeader(key, QByteArray());
}
-QWebEngineHttpRequestPrivate::Headers::ConstIterator
-QWebEngineHttpRequestPrivate::findHeader(const QByteArray &key) const
+QWebEngineHttpRequestPrivate::Headers::ConstIterator QWebEngineHttpRequestPrivate::findHeader(const QByteArray &key) const
{
Headers::ConstIterator it = headers.constBegin();
Headers::ConstIterator end = headers.constEnd();
- for ( ; it != end; ++it)
+ for (; it != end; ++it)
if (qstricmp(it->first.constData(), key.constData()) == 0)
return it;
- return end; // not found
+ return end; // not found
}
QWebEngineHttpRequestPrivate::Headers QWebEngineHttpRequestPrivate::allHeaders() const
@@ -355,9 +343,8 @@ QVector<QByteArray> QWebEngineHttpRequestPrivate::headersKeys() const
{
QVector<QByteArray> result;
result.reserve(headers.size());
- Headers::ConstIterator it = headers.constBegin(),
- end = headers.constEnd();
- for ( ; it != end; ++it)
+ Headers::ConstIterator it = headers.constBegin(), end = headers.constEnd();
+ for (; it != end; ++it)
result << it->first;
return result;
@@ -385,8 +372,7 @@ void QWebEngineHttpRequestPrivate::unsetHeader(const QByteArray &key)
auto firstEqualsKey = [&key](const HeaderPair &header) {
return qstricmp(header.first.constData(), key.constData()) == 0;
};
- headers.erase(std::remove_if(headers.begin(), headers.end(), firstEqualsKey),
- headers.end());
+ headers.erase(std::remove_if(headers.begin(), headers.end(), firstEqualsKey), headers.end());
}
/*!
@@ -408,7 +394,7 @@ void QWebEngineHttpRequestPrivate::setHeaderInternal(const QByteArray &key, cons
unsetHeader(key);
if (value.isNull())
- return; // only wanted to erase key
+ return; // only wanted to erase key
HeaderPair pair;
pair.first = key;
diff --git a/src/core/api/qwebenginehttprequest.h b/src/core/api/qwebenginehttprequest.h
index c6b5a6b63..1c4d7837b 100644
--- a/src/core/api/qwebenginehttprequest.h
+++ b/src/core/api/qwebenginehttprequest.h
@@ -49,11 +49,9 @@
QT_BEGIN_NAMESPACE
-
class QWebEngineHttpRequestPrivate;
-class QWEBENGINECORE_EXPORT QWebEngineHttpRequest
-{
+class Q_WEBENGINECORE_EXPORT QWebEngineHttpRequest {
public:
enum Method {
Get,
@@ -61,22 +59,23 @@ public:
};
explicit QWebEngineHttpRequest(const QUrl &url = QUrl(),
- const QWebEngineHttpRequest::Method &method = QWebEngineHttpRequest::Get);
+ const QWebEngineHttpRequest::Method &method = QWebEngineHttpRequest::Get);
QWebEngineHttpRequest(const QWebEngineHttpRequest &other);
~QWebEngineHttpRequest();
#ifdef Q_COMPILER_RVALUE_REFS
- QWebEngineHttpRequest &operator=(QWebEngineHttpRequest &&other) Q_DECL_NOTHROW { swap(other);
- return *this; }
+ QWebEngineHttpRequest &operator=(QWebEngineHttpRequest &&other) Q_DECL_NOTHROW
+ {
+ swap(other);
+ return *this;
+ }
#endif
QWebEngineHttpRequest &operator=(const QWebEngineHttpRequest &other);
- static QWebEngineHttpRequest postRequest(const QUrl &url,
- const QMap<QString, QString> &postData);
+ static QWebEngineHttpRequest postRequest(const QUrl &url, const QMap<QString, QString> &postData);
void swap(QWebEngineHttpRequest &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
bool operator==(const QWebEngineHttpRequest &other) const;
- inline bool operator!=(const QWebEngineHttpRequest &other) const
- { return !operator==(other); }
+ inline bool operator!=(const QWebEngineHttpRequest &other) const { return !operator==(other); }
Method method() const;
void setMethod(QWebEngineHttpRequest::Method method);
diff --git a/src/core/api/qwebenginemessagepumpscheduler_p.h b/src/core/api/qwebenginemessagepumpscheduler_p.h
index 4c9e4d600..07b2ca203 100644
--- a/src/core/api/qwebenginemessagepumpscheduler_p.h
+++ b/src/core/api/qwebenginemessagepumpscheduler_p.h
@@ -59,8 +59,7 @@
QT_BEGIN_NAMESPACE
-class QWEBENGINECORE_PRIVATE_EXPORT QWebEngineMessagePumpScheduler : public QObject
-{
+class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineMessagePumpScheduler : public QObject {
Q_OBJECT
public:
QWebEngineMessagePumpScheduler(std::function<void()> callback);
diff --git a/src/core/api/qwebenginenotification.cpp b/src/core/api/qwebenginenotification.cpp
new file mode 100644
index 000000000..abc63fed2
--- /dev/null
+++ b/src/core/api/qwebenginenotification.cpp
@@ -0,0 +1,323 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginenotification.h"
+
+#include "user_notification_controller.h"
+
+#include <QExplicitlySharedDataPointer>
+
+QT_BEGIN_NAMESPACE
+
+using QtWebEngineCore::UserNotificationController;
+
+/*!
+ \qmltype WebEngineNotification
+ \instantiates QWebEngineNotification
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 1.9
+ \brief Encapsulates the data of an HTML5 web notification.
+
+ This type contains the information and API for HTML5 desktop and push notifications.
+
+ Web engine notifications are passed to the user in the
+ \l WebEngineProfile::presentNotification() signal.
+
+ For more information about how to handle web notification, see the
+ \l{WebEngine Notifications Example}{Notification Example}.
+*/
+
+/*!
+ \class QWebEngineNotification
+ \brief The QWebEngineNotification class encapsulates the data of an HTML5 web notification.
+ \since 5.13
+
+ \inmodule QtWebEngineCore
+
+ This class contains the information and API for HTML5 desktop and push notifications.
+
+ Web engine notifications are passed to the user through the custom handler
+ provided with the \l QWebEngineProfile::setNotificationPresenter() call.
+
+ For more information about how to handle web notification, see the
+ \l{WebEngine Notifications Example}{Notification Example}.
+*/
+
+class QWebEngineNotificationPrivate : public UserNotificationController::Client {
+public:
+ QWebEngineNotificationPrivate(QWebEngineNotification *q, const QSharedPointer<UserNotificationController> &controller)
+ : controller(controller)
+ , q(q)
+ {
+ controller->setClient(this);
+ }
+ ~QWebEngineNotificationPrivate() override
+ {
+ if (controller->client() == this)
+ controller->setClient(0);
+ }
+
+ // UserNotificationController::Client:
+ virtual void notificationClosed(const UserNotificationController *) override
+ {
+ Q_EMIT q->closed();
+ }
+
+ QSharedPointer<UserNotificationController> controller;
+ QWebEngineNotification *q;
+};
+
+/*! \internal
+*/
+QWebEngineNotification::QWebEngineNotification(const QSharedPointer<UserNotificationController> &controller)
+ : d_ptr(new QWebEngineNotificationPrivate(this, controller))
+{}
+
+/*! \internal
+*/
+QWebEngineNotification::~QWebEngineNotification() {}
+
+/*!
+ Returns \c true if the two notifications belong to the same message chain.
+ That is, if their tag() and origin() are the same. This means one is
+ a replacement or an update of the \a other.
+
+ \sa tag(), origin()
+*/
+bool QWebEngineNotification::matches(const QWebEngineNotification *other) const
+{
+ if (!other)
+ return false;
+ if (!d_ptr)
+ return !other->d_ptr;
+ if (!other->d_ptr)
+ return false;
+ return tag() == other->tag() && origin() == other->origin();
+}
+
+/*!
+ \qmlproperty bool WebEngineNotification::title
+ \brief The title of the notification.
+*/
+/*!
+ \property QWebEngineNotification::title
+ \brief The title of the notification.
+ \sa message()
+*/
+QString QWebEngineNotification::title() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->title() : QString();
+}
+
+/*!
+ \qmlproperty string WebEngineNotification::message
+ \brief The body of the notification message.
+*/
+/*!
+ \property QWebEngineNotification::message
+ \brief The body of the notification message.
+ \sa title()
+*/
+
+QString QWebEngineNotification::message() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->body() : QString();
+}
+
+/*!
+ \qmlproperty string WebEngineNotification::tag
+ \brief The tag of the notification message.
+
+ New notifications that have the same tag and origin URL as an existing
+ one should replace or update the old notification with the same tag.
+*/
+/*!
+ \property QWebEngineNotification::tag
+ \brief The tag of the notification message.
+
+ New notifications that have the same tag and origin URL as an existing
+ one should replace or update the old notification with the same tag.
+
+ \sa matches()
+*/
+QString QWebEngineNotification::tag() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->tag() : QString();
+}
+
+/*!
+ \qmlproperty url WebEngineNotification::origin
+ \brief The URL of the page sending the notification.
+*/
+/*!
+ \property QWebEngineNotification::origin
+ \brief The URL of the page sending the notification.
+*/
+
+QUrl QWebEngineNotification::origin() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->origin() : QUrl();
+}
+
+/*!
+ Returns the icon to be shown with the notification.
+
+ If no icon is set by the sender, a null QImage is returned.
+*/
+QImage QWebEngineNotification::icon() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->icon() : QImage();
+}
+
+/*!
+ \qmlproperty string WebEngineNotification::language
+ \brief The primary language for the notification's title and body.
+
+ Its value is a valid BCP 47 language tag, or the empty string.
+*/
+/*!
+ \property QWebEngineNotification::language
+ \brief The primary language for the notification's title and body.
+
+ Its value is a valid BCP 47 language tag, or the empty string.
+
+ \sa title(), message()
+*/
+QString QWebEngineNotification::language() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->language() : QString();
+}
+
+/*!
+ \qmlproperty enumeration WebEngineNotification::direction
+ \brief The text direction for the notification's title and body.
+
+ \value Qt.LeftToRight Items are laid out from left to right.
+ \value Qt.RightToLeft Items are laid out from right to left.
+ \value Qt.LayoutDirectionAuto The direction to lay out items is determined automatically.
+*/
+/*!
+ \property QWebEngineNotification::direction
+ \brief The text direction for the notification's title and body.
+ \sa title(), message()
+*/
+Qt::LayoutDirection QWebEngineNotification::direction() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->direction() : Qt::LayoutDirectionAuto;
+}
+
+/*!
+ \qmlmethod void WebEngineNotification::show()
+ Creates and dispatches a JavaScript \e {show event} on notification.
+
+ Should be called by the notification platform when the notification has been shown to user.
+*/
+/*!
+ Creates and dispatches a JavaScript \e {show event} on notification.
+
+ Should be called by the notification platform when the notification has been shown to user.
+*/
+void QWebEngineNotification::show() const
+{
+ Q_D(const QWebEngineNotification);
+ if (d)
+ d->controller->notificationDisplayed();
+}
+
+/*!
+ \qmlmethod void WebEngineNotification::click()
+ Creates and dispatches a JavaScript \e {click event} on notification.
+
+ Should be called by the notification platform when the notification is activated by the user.
+*/
+/*!
+ Creates and dispatches a JavaScript \e {click event} on notification.
+
+ Should be called by the notification platform when the notification is activated by the user.
+*/
+void QWebEngineNotification::click() const
+{
+ Q_D(const QWebEngineNotification);
+ if (d)
+ d->controller->notificationClicked();
+}
+
+/*!
+ \qmlmethod void WebEngineNotification::close()
+ Creates and dispatches a JavaScript \e {close event} on notification.
+
+ Should be called by the notification platform when the notification is closed,
+ either by the underlying platform or by the user.
+*/
+/*!
+ Creates and dispatches a JavaScript \e {close event} on notification.
+
+ Should be called by the notification platform when the notification is closed,
+ either by the underlying platform or by the user.
+*/
+void QWebEngineNotification::close() const
+{
+ Q_D(const QWebEngineNotification);
+ if (d)
+ d->controller->notificationClosed();
+}
+
+/*!
+ \qmlsignal WebEngineNotification::closed()
+
+ This signal is emitted when the web page calls close steps for the notification,
+ and it no longer needs to be shown.
+*/
+/*!
+ \fn void QWebEngineNotification::closed()
+
+ This signal is emitted when the web page calls close steps for the notification,
+ and it no longer needs to be shown.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginenotification.cpp"
diff --git a/src/core/api/qwebenginenotification.h b/src/core/api/qwebenginenotification.h
new file mode 100644
index 000000000..08fd629be
--- /dev/null
+++ b/src/core/api/qwebenginenotification.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINENOTIFICATION_H
+#define QWEBENGINENOTIFICATION_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QUrl>
+
+namespace QtWebEngineCore {
+class UserNotificationController;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineNotificationPrivate;
+
+class Q_WEBENGINECORE_EXPORT QWebEngineNotification : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
+ Q_PROPERTY(QString title READ title CONSTANT FINAL)
+ Q_PROPERTY(QString message READ message CONSTANT FINAL)
+ Q_PROPERTY(QString tag READ tag CONSTANT FINAL)
+ Q_PROPERTY(QString language READ language CONSTANT FINAL)
+ Q_PROPERTY(Qt::LayoutDirection direction READ direction CONSTANT FINAL)
+
+public:
+ virtual ~QWebEngineNotification() override;
+
+ bool matches(const QWebEngineNotification *other) const;
+
+ QUrl origin() const;
+ QImage icon() const;
+ QString title() const;
+ QString message() const;
+ QString tag() const;
+ QString language() const;
+ Qt::LayoutDirection direction() const;
+
+public Q_SLOTS:
+ void show() const;
+ void click() const;
+ void close() const;
+
+Q_SIGNALS:
+ void closed();
+
+private:
+ Q_DISABLE_COPY(QWebEngineNotification)
+ Q_DECLARE_PRIVATE(QWebEngineNotification)
+ QWebEngineNotification(const QSharedPointer<QtWebEngineCore::UserNotificationController> &controller);
+ QScopedPointer<QWebEngineNotificationPrivate> d_ptr;
+ friend class QQuickWebEngineProfilePrivate;
+ friend class QWebEngineProfilePrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINENOTIFICATION_H
diff --git a/src/core/api/qwebenginequotarequest.cpp b/src/core/api/qwebenginequotarequest.cpp
index 49c9f041f..7686d0806 100644
--- a/src/core/api/qwebenginequotarequest.cpp
+++ b/src/core/api/qwebenginequotarequest.cpp
@@ -64,8 +64,7 @@ QT_BEGIN_NAMESPACE
/*! \internal */
QWebEngineQuotaRequest::QWebEngineQuotaRequest(QSharedPointer<QtWebEngineCore::QuotaRequestController> controller)
: d_ptr(controller)
-{
-}
+{}
/*!
Rejects a request for larger persistent storage.
diff --git a/src/core/api/qwebenginequotarequest.h b/src/core/api/qwebenginequotarequest.h
index a759f5bb6..da72116c8 100644
--- a/src/core/api/qwebenginequotarequest.h
+++ b/src/core/api/qwebenginequotarequest.h
@@ -47,11 +47,11 @@
namespace QtWebEngineCore {
class QuotaPermissionContextQt;
class QuotaRequestController;
-}
+} // namespace QtWebEngineCore
QT_BEGIN_NAMESPACE
-class QWEBENGINECORE_EXPORT QWebEngineQuotaRequest {
+class Q_WEBENGINECORE_EXPORT QWebEngineQuotaRequest {
Q_GADGET
Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
Q_PROPERTY(qint64 requestedSize READ requestedSize CONSTANT FINAL)
@@ -63,6 +63,7 @@ public:
qint64 requestedSize() const;
bool operator==(const QWebEngineQuotaRequest &that) const { return d_ptr == that.d_ptr; }
bool operator!=(const QWebEngineQuotaRequest &that) const { return d_ptr != that.d_ptr; }
+
private:
QWebEngineQuotaRequest(QSharedPointer<QtWebEngineCore::QuotaRequestController>);
friend QtWebEngineCore::QuotaPermissionContextQt;
diff --git a/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp b/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp
index 1921f78f4..a3960327d 100644
--- a/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp
+++ b/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
/*! \internal */
QWebEngineRegisterProtocolHandlerRequest::QWebEngineRegisterProtocolHandlerRequest(
- QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerRequestController> d_ptr)
+ QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerRequestController> d_ptr)
: d_ptr(std::move(d_ptr))
{}
diff --git a/src/core/api/qwebengineregisterprotocolhandlerrequest.h b/src/core/api/qwebengineregisterprotocolhandlerrequest.h
index 12b1d6edf..67caf1590 100644
--- a/src/core/api/qwebengineregisterprotocolhandlerrequest.h
+++ b/src/core/api/qwebengineregisterprotocolhandlerrequest.h
@@ -47,11 +47,11 @@
namespace QtWebEngineCore {
class RegisterProtocolHandlerRequestController;
class WebContentsDelegateQt;
-}
+} // namespace QtWebEngineCore
QT_BEGIN_NAMESPACE
-class QWEBENGINECORE_EXPORT QWebEngineRegisterProtocolHandlerRequest {
+class Q_WEBENGINECORE_EXPORT QWebEngineRegisterProtocolHandlerRequest {
Q_GADGET
Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
Q_PROPERTY(QString scheme READ scheme CONSTANT FINAL)
@@ -63,9 +63,9 @@ public:
QString scheme() const;
bool operator==(const QWebEngineRegisterProtocolHandlerRequest &that) const { return d_ptr == that.d_ptr; }
bool operator!=(const QWebEngineRegisterProtocolHandlerRequest &that) const { return d_ptr != that.d_ptr; }
+
private:
- QWebEngineRegisterProtocolHandlerRequest(
- QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerRequestController>);
+ QWebEngineRegisterProtocolHandlerRequest(QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerRequestController>);
friend QtWebEngineCore::WebContentsDelegateQt;
QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerRequestController> d_ptr;
};
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 2b8a69c9a..3cbb4da17 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -68,8 +68,10 @@ ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeLast, content::RESOURCE
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::LinkNavigation, QWebEngineUrlRequestInfo::NavigationTypeLink)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::TypedNavigation, QWebEngineUrlRequestInfo::NavigationTypeTyped)
-ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::FormSubmittedNavigation, QWebEngineUrlRequestInfo::NavigationTypeFormSubmitted)
-ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::BackForwardNavigation, QWebEngineUrlRequestInfo::NavigationTypeBackForward)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::FormSubmittedNavigation,
+ QWebEngineUrlRequestInfo::NavigationTypeFormSubmitted)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::BackForwardNavigation,
+ QWebEngineUrlRequestInfo::NavigationTypeBackForward)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::ReloadNavigation, QWebEngineUrlRequestInfo::NavigationTypeReload)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, QWebEngineUrlRequestInfo::NavigationTypeOther)
@@ -96,8 +98,8 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
interceptor on the profile enables intercepting, blocking, and modifying URL requests
before they reach the networking stack of Chromium.
- You can install the interceptor on a profile via QWebEngineProfile::setRequestInterceptor()
- or QQuickWebEngineProfile::setRequestInterceptor().
+ You can install the interceptor on a profile via QWebEngineProfile::setUrlRequestInterceptor()
+ or QQuickWebEngineProfile::setUrlRequestInterceptor().
When using the \l{Qt WebEngine Widgets Module}, \l{QWebEnginePage::acceptNavigationRequest()}
offers further options to accept or block requests.
@@ -115,8 +117,7 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
\fn void QWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
Reimplementing this virtual function makes it possible to intercept URL
- requests. This function is executed on the IO thread, and therefore running
- long tasks here will block networking.
+ requests. This method will be stalling the URL request until handled.
\a info contains the information about the URL request and will track internally
whether its members have been altered.
@@ -125,8 +126,9 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
execution of this function is finished.
*/
-
-QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource, QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu, const QByteArray &m)
+QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
+ QWebEngineUrlRequestInfo::NavigationType navigation,
+ const QUrl &u, const QUrl &fpu, const QByteArray &m)
: resourceType(resource)
, navigationType(navigation)
, shouldBlockRequest(false)
@@ -134,24 +136,24 @@ QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRe
, firstPartyUrl(fpu)
, method(m)
, changed(false)
-{
-}
+{}
/*!
\internal
*/
+QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfo &&p) : d_ptr(p.d_ptr.take()) {}
-QWebEngineUrlRequestInfo::~QWebEngineUrlRequestInfo()
-{
+/*!
+ \internal
+*/
-}
+QWebEngineUrlRequestInfo::~QWebEngineUrlRequestInfo() {}
/*!
\internal
*/
-QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPrivate *p)
- : d_ptr(p)
+QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPrivate *p) : d_ptr(p)
{
d_ptr->q_ptr = this;
}
@@ -241,7 +243,6 @@ QUrl QWebEngineUrlRequestInfo::firstPartyUrl() const
return d_ptr->firstPartyUrl;
}
-
/*!
Returns the HTTP method of the request (for example, GET or POST).
*/
@@ -260,6 +261,14 @@ bool QWebEngineUrlRequestInfo::changed() const
}
/*!
+ \internal
+*/
+void QWebEngineUrlRequestInfo::resetChanged()
+{
+ d_ptr->changed = false;
+}
+
+/*!
Redirects this request to \a url.
It is only possible to redirect requests that do not have payload data, such as GET requests.
*/
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
index 68c46dcf4..cf5a4801d 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -47,13 +47,14 @@
namespace QtWebEngineCore {
class NetworkDelegateQt;
-}
+class URLRequestNotification;
+} // namespace QtWebEngineCore
QT_BEGIN_NAMESPACE
class QWebEngineUrlRequestInfoPrivate;
-class QWEBENGINECORE_EXPORT QWebEngineUrlRequestInfo {
+class Q_WEBENGINECORE_EXPORT QWebEngineUrlRequestInfo {
public:
enum ResourceType {
ResourceTypeMainFrame = 0, // top level page
@@ -104,10 +105,14 @@ public:
private:
friend class QtWebEngineCore::NetworkDelegateQt;
+ friend class QtWebEngineCore::URLRequestNotification;
Q_DISABLE_COPY(QWebEngineUrlRequestInfo)
Q_DECLARE_PRIVATE(QWebEngineUrlRequestInfo)
+ void resetChanged();
+
QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPrivate *p);
+ QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfo &&p);
~QWebEngineUrlRequestInfo();
QScopedPointer<QWebEngineUrlRequestInfoPrivate> d_ptr;
};
diff --git a/src/core/api/qwebengineurlrequestinfo_p.h b/src/core/api/qwebengineurlrequestinfo_p.h
index 9afd04398..9d795b2b5 100644
--- a/src/core/api/qwebengineurlrequestinfo_p.h
+++ b/src/core/api/qwebengineurlrequestinfo_p.h
@@ -65,15 +65,12 @@ class URLRequest;
QT_BEGIN_NAMESPACE
-class QWebEngineUrlRequestInfoPrivate
-{
+class QWebEngineUrlRequestInfoPrivate {
Q_DECLARE_PUBLIC(QWebEngineUrlRequestInfo)
public:
- QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource
- , QWebEngineUrlRequestInfo::NavigationType navigation
- , const QUrl &u
- , const QUrl &fpu
- , const QByteArray &m);
+ QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
+ QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu,
+ const QByteArray &m);
QWebEngineUrlRequestInfo::ResourceType resourceType;
QWebEngineUrlRequestInfo::NavigationType navigationType;
diff --git a/src/core/api/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h
index dc2a15ee3..4d3020306 100644
--- a/src/core/api/qwebengineurlrequestinterceptor.h
+++ b/src/core/api/qwebengineurlrequestinterceptor.h
@@ -50,15 +50,11 @@
QT_BEGIN_NAMESPACE
-class QWEBENGINECORE_EXPORT QWebEngineUrlRequestInterceptor : public QObject
-{
+class Q_WEBENGINECORE_EXPORT QWebEngineUrlRequestInterceptor : public QObject {
Q_OBJECT
Q_DISABLE_COPY(QWebEngineUrlRequestInterceptor)
public:
- explicit QWebEngineUrlRequestInterceptor(QObject *p = Q_NULLPTR)
- : QObject (p)
- {
- }
+ explicit QWebEngineUrlRequestInterceptor(QObject *p = nullptr) : QObject(p) {}
virtual void interceptRequest(QWebEngineUrlRequestInfo &info) = 0;
};
diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index c3541598b..3bb9d1732 100644
--- a/src/core/api/qwebengineurlrequestjob.cpp
+++ b/src/core/api/qwebengineurlrequestjob.cpp
@@ -84,11 +84,10 @@ QT_BEGIN_NAMESPACE
/*!
\internal
*/
-QWebEngineUrlRequestJob::QWebEngineUrlRequestJob(URLRequestCustomJobDelegate * p)
+QWebEngineUrlRequestJob::QWebEngineUrlRequestJob(URLRequestCustomJobDelegate *p)
: QObject(p) // owned by the jobdelegate and deleted when the job is done
, d_ptr(p)
-{
-}
+{}
/*!
\internal
@@ -140,6 +139,15 @@ QUrl QWebEngineUrlRequestJob::initiator() const
}
/*!
+ \since 5.13
+ Returns any HTTP headers added to the request.
+*/
+QMap<QByteArray, QByteArray> QWebEngineUrlRequestJob::requestHeaders() const
+{
+ return d_ptr->requestHeaders();
+}
+
+/*!
Replies to the request with \a device and the MIME type \a contentType.
The user has to be aware that \a device will be used on another thread
diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h
index 7ce8be7ec..6d4a9e734 100644
--- a/src/core/api/qwebengineurlrequestjob.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -49,13 +49,13 @@
namespace QtWebEngineCore {
class URLRequestCustomJobDelegate;
class URLRequestCustomJobProxy;
-} // namespace
+} // namespace QtWebEngineCore
QT_BEGIN_NAMESPACE
class QIODevice;
-class QWEBENGINECORE_EXPORT QWebEngineUrlRequestJob : public QObject {
+class Q_WEBENGINECORE_EXPORT QWebEngineUrlRequestJob : public QObject {
Q_OBJECT
public:
~QWebEngineUrlRequestJob();
@@ -73,6 +73,7 @@ public:
QUrl requestUrl() const;
QByteArray requestMethod() const;
QUrl initiator() const;
+ QMap<QByteArray, QByteArray> requestHeaders() const;
void reply(const QByteArray &contentType, QIODevice *device);
void fail(Error error);
@@ -82,7 +83,7 @@ private:
QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *);
friend class QtWebEngineCore::URLRequestCustomJobProxy;
- QtWebEngineCore::URLRequestCustomJobDelegate* d_ptr;
+ QtWebEngineCore::URLRequestCustomJobDelegate *d_ptr;
};
QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index 9cc5b5056..f4efad717 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -48,8 +48,7 @@ QT_BEGIN_NAMESPACE
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::Path, url::SCHEME_WITHOUT_AUTHORITY)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::Host, url::SCHEME_WITH_HOST)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::HostAndPort, url::SCHEME_WITH_HOST_AND_PORT)
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::HostPortAndUserInformation,
- url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::HostPortAndUserInformation, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::PortUnspecified, url::PORT_UNSPECIFIED)
@@ -193,10 +192,7 @@ public:
Content-Security-Policy checks.
*/
-QWebEngineUrlScheme::QWebEngineUrlScheme(QWebEngineUrlSchemePrivate *d)
- : d(d)
-{
-}
+QWebEngineUrlScheme::QWebEngineUrlScheme(QWebEngineUrlSchemePrivate *d) : d(d) {}
/*!
Constructs a web engine URL scheme with default values.
@@ -399,7 +395,7 @@ void QWebEngineUrlScheme::registerScheme(const QWebEngineUrlScheme &scheme)
*/
QWebEngineUrlScheme QWebEngineUrlScheme::schemeByName(const QByteArray &name)
{
- base::StringPiece namePiece{name.data(), static_cast<size_t>(name.size())};
+ base::StringPiece namePiece{ name.data(), static_cast<size_t>(name.size()) };
if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(namePiece))
return QWebEngineUrlScheme(new QWebEngineUrlSchemePrivate(*cs));
return QWebEngineUrlScheme();
diff --git a/src/core/api/qwebengineurlscheme.h b/src/core/api/qwebengineurlscheme.h
index da3010335..095b47320 100644
--- a/src/core/api/qwebengineurlscheme.h
+++ b/src/core/api/qwebengineurlscheme.h
@@ -46,13 +46,15 @@
#include <QtCore/qobjectdefs.h>
#include <QtCore/qshareddata.h>
-namespace QtWebEngineCore { class WebEngineContext; }
+namespace QtWebEngineCore {
+class WebEngineContext;
+}
QT_BEGIN_NAMESPACE
class QWebEngineUrlSchemePrivate;
-class QWEBENGINECORE_EXPORT QWebEngineUrlScheme {
+class Q_WEBENGINECORE_EXPORT QWebEngineUrlScheme {
Q_GADGET
public:
enum class Syntax {
diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
index b5912703d..aecee5044 100644
--- a/src/core/api/qwebengineurlschemehandler.cpp
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -111,7 +111,6 @@ QWebEngineUrlSchemeHandler::QWebEngineUrlSchemeHandler(QObject *parent)
*/
QWebEngineUrlSchemeHandler::~QWebEngineUrlSchemeHandler()
{
- Q_EMIT _q_destroyedUrlSchemeHandler(this);
}
/*!
diff --git a/src/core/api/qwebengineurlschemehandler.h b/src/core/api/qwebengineurlschemehandler.h
index 23fee4b95..09c5b08cb 100644
--- a/src/core/api/qwebengineurlschemehandler.h
+++ b/src/core/api/qwebengineurlschemehandler.h
@@ -52,18 +52,13 @@ QT_BEGIN_NAMESPACE
class QWebEngineUrlRequestJob;
-class QWEBENGINECORE_EXPORT QWebEngineUrlSchemeHandler : public QObject {
+class Q_WEBENGINECORE_EXPORT QWebEngineUrlSchemeHandler : public QObject {
Q_OBJECT
public:
QWebEngineUrlSchemeHandler(QObject *parent = Q_NULLPTR);
~QWebEngineUrlSchemeHandler();
- virtual void requestStarted(QWebEngineUrlRequestJob*) = 0;
-
-#ifndef Q_QDOC
-Q_SIGNALS:
- void _q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*);
-#endif
+ virtual void requestStarted(QWebEngineUrlRequestJob *) = 0;
private:
Q_DISABLE_COPY(QWebEngineUrlSchemeHandler)
diff --git a/src/core/authentication_dialog_controller.cpp b/src/core/authentication_dialog_controller.cpp
index bd23d1768..1133b0bc1 100644
--- a/src/core/authentication_dialog_controller.cpp
+++ b/src/core/authentication_dialog_controller.cpp
@@ -40,7 +40,9 @@
#include "authentication_dialog_controller.h"
#include "authentication_dialog_controller_p.h"
+#include "base/task/post_task.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/browser_task_traits.h"
namespace QtWebEngineCore {
@@ -51,9 +53,10 @@ AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(Log
void AuthenticationDialogControllerPrivate::dialogFinished(bool accepted, const QString &user, const QString &password)
{
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&LoginDelegateQt::sendAuthToRequester, loginDelegate, accepted, user, password));
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&LoginDelegateQt::sendAuthToRequester,
+ loginDelegate, accepted, user, password));
}
AuthenticationDialogController::AuthenticationDialogController(AuthenticationDialogControllerPrivate *dd)
diff --git a/src/core/authentication_dialog_controller.h b/src/core/authentication_dialog_controller.h
index aec91aac5..631a95c34 100644
--- a/src/core/authentication_dialog_controller.h
+++ b/src/core/authentication_dialog_controller.h
@@ -59,7 +59,7 @@ namespace QtWebEngineCore {
class AuthenticationDialogControllerPrivate;
-class QWEBENGINECORE_PRIVATE_EXPORT AuthenticationDialogController : public QObject {
+class Q_WEBENGINECORE_PRIVATE_EXPORT AuthenticationDialogController : public QObject {
Q_OBJECT
public:
~AuthenticationDialogController();
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index 29fbbc542..75527ea95 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -61,6 +61,11 @@ const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibilit
return static_cast<const BrowserAccessibilityQt *>(obj);
}
+QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj)
+{
+ return static_cast<BrowserAccessibilityQt *>(obj);
+}
+
BrowserAccessibilityQt::BrowserAccessibilityQt()
{
QAccessible::registerAccessibleInterface(this);
@@ -357,6 +362,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::EditableText;
case ax::mojom::Role::kInputTime:
return QAccessible::SpinBox;
+ case ax::mojom::Role::kKeyboard:
+ return QAccessible::NoRole; // FIXME
case ax::mojom::Role::kLabelText:
return QAccessible::StaticText;
case ax::mojom::Role::kLayoutTable:
diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h
index 345ee9862..decfc1e9d 100644
--- a/src/core/browser_accessibility_qt.h
+++ b/src/core/browser_accessibility_qt.h
@@ -146,6 +146,7 @@ public:
};
const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibility *obj);
+QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *acc);
} // namespace content
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index 3d85c04c4..dacaf177f 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -42,11 +42,22 @@
#include "api/qwebenginemessagepumpscheduler_p.h"
#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_impl.h"
+#include "base/message_loop/message_loop_current.h"
#include "base/process/process.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/browser_main_parts.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_security_policy.h"
#include "content/public/common/service_manager_connection.h"
+#include "extensions/buildflags/buildflags.h"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/common/constants.h"
+#include "extensions/common/extensions_client.h"
+#include "extensions/extensions_browser_client_qt.h"
+#include "extensions/extension_system_factory_qt.h"
+#include "common/extensions/extensions_client_qt.h"
+#endif //BUILDFLAG(ENABLE_EXTENSIONS)
#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -56,7 +67,12 @@
#include "service/service_qt.h"
#include "web_engine_context.h"
-#include <QEventLoop>
+#include <QtGui/qtgui-config.h>
+
+#if QT_CONFIG(opengl)
+#include "ui/gl/gl_context.h"
+#include <QOpenGLContext>
+#endif
#if defined(OS_MACOSX)
#include "ui/base/idle/idle.h"
@@ -89,6 +105,8 @@ int GetTimeIntervalMilliseconds(const base::TimeTicks &from)
return delay < 0 ? 0 : delay;
}
+} // anonymous namespace
+
class MessagePumpForUIQt : public base::MessagePump
{
public:
@@ -96,43 +114,86 @@ public:
: m_scheduler([this]() { handleScheduledWork(); })
{}
+ void setDelegate(Delegate *delegate)
+ {
+ m_delegate = delegate;
+ }
+
void Run(Delegate *delegate) override
{
- if (!m_delegate)
- m_delegate = delegate;
- else
- Q_ASSERT(delegate == m_delegate);
// This is used only when MessagePumpForUIQt is used outside of the GUI thread.
- QEventLoop loop;
- m_explicitLoop = &loop;
- loop.exec();
- m_explicitLoop = nullptr;
+ NOTIMPLEMENTED();
}
void Quit() override
{
- Q_ASSERT(m_explicitLoop);
- m_explicitLoop->quit();
+ // This is used only when MessagePumpForUIQt is used outside of the GUI thread.
+ NOTIMPLEMENTED();
}
void ScheduleWork() override
{
// NOTE: This method may called from any thread at any time.
- if (!m_delegate)
- m_delegate = base::MessageLoopForUI::current();
m_scheduler.scheduleWork();
}
void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override
{
- if (!m_delegate)
- m_delegate = base::MessageLoopForUI::current();
m_scheduler.scheduleDelayedWork(GetTimeIntervalMilliseconds(delayed_work_time));
}
private:
+ // Both Qt and Chromium keep track of the current GL context by using
+ // thread-local variables, and naturally they are completely unaware of each
+ // other. As a result, when a QOpenGLContext is made current, the previous
+ // gl::GLContext is not released, and vice-versa. This is fine as long as
+ // each thread uses exclusively either Qt or Chromium GL bindings, which is
+ // usually the case.
+ //
+ // The only exception is when the GL driver is considered thread-unsafe
+ // (QOpenGLContext::supportsThreadedOpenGL() is false), in which case we
+ // have to run all GL operations, including Chromium's GPU service, on the
+ // UI thread. Now the bindings are being mixed and both Qt and Chromium get
+ // quite confused regarding the current state of the surface.
+ //
+ // To get this to work we have to release the current QOpenGLContext before
+ // executing any tasks from Chromium's GPU service and the gl::GLContext
+ // afterwards. Since GPU service just posts tasks to the UI thread task
+ // runner, we'll have to instrument the entire UI thread message pump.
+ class ScopedGLContextChecker
+ {
+#if QT_CONFIG(opengl)
+ public:
+ ScopedGLContextChecker()
+ {
+ if (!m_enabled)
+ return;
+
+ if (QOpenGLContext *context = QOpenGLContext::currentContext())
+ context->doneCurrent();
+ }
+
+ ~ScopedGLContextChecker()
+ {
+ if (!m_enabled)
+ return;
+
+ if (gl::GLContext *context = gl::GLContext::GetCurrent())
+ context->ReleaseCurrent(nullptr);
+ }
+
+ private:
+ bool m_enabled = !QOpenGLContext::supportsThreadedOpenGL();
+#endif // QT_CONFIG(opengl)
+ };
+
+
void handleScheduledWork()
{
+ Q_ASSERT(m_delegate);
+
+ ScopedGLContextChecker glContextChecker;
+
bool more_work_is_plausible = m_delegate->DoWork();
base::TimeTicks delayed_work_time;
@@ -149,16 +210,26 @@ private:
}
Delegate *m_delegate = nullptr;
- QEventLoop *m_explicitLoop = nullptr;
QWebEngineMessagePumpScheduler m_scheduler;
};
-} // anonymous namespace
+// Needed to access protected constructor from MessageLoop.
+class MessageLoopForUIQt : public base::MessageLoop {
+public:
+ MessageLoopForUIQt() : MessageLoop(TYPE_UI, base::BindOnce(&messagePumpFactory))
+ {
+ BindToCurrentThread();
-std::unique_ptr<base::MessagePump> messagePumpFactory()
-{
- return base::WrapUnique(new MessagePumpForUIQt);
-}
+ auto pump = static_cast<MessagePumpForUIQt *>(pump_);
+ auto backend = static_cast<base::MessageLoopImpl *>(backend_.get());
+ pump->setDelegate(backend);
+ }
+private:
+ static std::unique_ptr<base::MessagePump> messagePumpFactory()
+ {
+ return base::WrapUnique(new MessagePumpForUIQt);
+ }
+};
BrowserMainPartsQt::BrowserMainPartsQt() : content::BrowserMainParts()
{ }
@@ -168,12 +239,25 @@ BrowserMainPartsQt::~BrowserMainPartsQt() = default;
int BrowserMainPartsQt::PreEarlyInitialization()
{
- base::MessageLoop::InitMessagePumpForUIFactory(messagePumpFactory);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(extensions::kExtensionScheme);
+#endif //ENABLE_EXTENSIONS
return 0;
}
void BrowserMainPartsQt::PreMainMessageLoopStart()
{
+ // Overrides message loop creation in BrowserMainLoop::MainMessageLoopStart().
+ m_mainMessageLoop.reset(new MessageLoopForUIQt);
+}
+
+void BrowserMainPartsQt::PreMainMessageLoopRun()
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::ExtensionsClient::Set(new extensions::ExtensionsClientQt());
+ extensions::ExtensionsBrowserClient::Set(new extensions::ExtensionsBrowserClientQt());
+ extensions::ExtensionSystemFactoryQt::GetInstance();
+#endif //ENABLE_EXTENSIONS
}
void BrowserMainPartsQt::PostMainMessageLoopRun()
@@ -203,12 +287,9 @@ int BrowserMainPartsQt::PreCreateThreads()
void BrowserMainPartsQt::ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection)
{
ServiceQt::GetInstance()->InitConnector();
- connection->GetConnector()->StartService(service_manager::Identity("qtwebengine"));
- if (resource_coordinator::IsResourceCoordinatorEnabled()) {
- m_processResourceCoordinator = std::make_unique<resource_coordinator::ProcessResourceCoordinator>(connection->GetConnector());
- m_processResourceCoordinator->SetLaunchTime(base::Time::Now());
- m_processResourceCoordinator->SetPID(base::Process::Current().Pid());
- }
+ connection->GetConnector()->WarmService(service_manager::ServiceFilter::ByName("qtwebengine"));
+ m_processResourceCoordinator = std::make_unique<resource_coordinator::ProcessResourceCoordinator>(connection->GetConnector());
+ m_processResourceCoordinator->OnProcessLaunched(base::Process::Current());
}
} // namespace QtWebEngineCore
diff --git a/src/core/browser_main_parts_qt.h b/src/core/browser_main_parts_qt.h
index 04ca9483d..4eb10e379 100644
--- a/src/core/browser_main_parts_qt.h
+++ b/src/core/browser_main_parts_qt.h
@@ -43,7 +43,7 @@
#include "content/public/browser/browser_main_parts.h"
namespace base {
-class MessagePump;
+class MessageLoop;
}
namespace content {
@@ -56,8 +56,6 @@ class ProcessResourceCoordinator;
namespace QtWebEngineCore {
-std::unique_ptr<base::MessagePump> messagePumpFactory();
-
class BrowserMainPartsQt : public content::BrowserMainParts
{
public:
@@ -66,6 +64,7 @@ public:
int PreEarlyInitialization() override;
void PreMainMessageLoopStart() override;
+ void PreMainMessageLoopRun() override;
void PostMainMessageLoopRun() override;
int PreCreateThreads() override;
void ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection) override;
@@ -73,6 +72,7 @@ public:
private:
DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt);
std::unique_ptr<resource_coordinator::ProcessResourceCoordinator> m_processResourceCoordinator;
+ std::unique_ptr<base::MessageLoop> m_mainMessageLoop;
};
} // namespace QtWebEngineCore
diff --git a/src/core/browser_message_filter_qt.cpp b/src/core/browser_message_filter_qt.cpp
index d4fdc4122..034447512 100644
--- a/src/core/browser_message_filter_qt.cpp
+++ b/src/core/browser_message_filter_qt.cpp
@@ -100,7 +100,6 @@ void BrowserMessageFilterQt::OnAllowDOMStorage(int /*render_frame_id*/,
void BrowserMessageFilterQt::OnAllowIndexedDB(int /*render_frame_id*/,
const GURL &origin_url,
const GURL &top_origin_url,
- const base::string16 &/*name*/,
bool *allowed)
{
NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(m_profile->GetRequestContext()->GetURLRequestContext()->network_delegate());
diff --git a/src/core/browser_message_filter_qt.h b/src/core/browser_message_filter_qt.h
index 8b22ab6ac..d121aa65d 100644
--- a/src/core/browser_message_filter_qt.h
+++ b/src/core/browser_message_filter_qt.h
@@ -73,7 +73,6 @@ private:
void OnAllowIndexedDB(int render_frame_id,
const GURL &origin_url,
const GURL &top_origin_url,
- const base::string16 &name,
bool *allowed);
void OnRequestFileSystemAccessSync(int render_frame_id,
diff --git a/src/core/certificate_error_controller.h b/src/core/certificate_error_controller.h
index 6e1e87cb0..5bea61c9b 100644
--- a/src/core/certificate_error_controller.h
+++ b/src/core/certificate_error_controller.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class CertificateErrorControllerPrivate;
-class QWEBENGINECORE_PRIVATE_EXPORT CertificateErrorController {
+class Q_WEBENGINECORE_PRIVATE_EXPORT CertificateErrorController {
public:
CertificateErrorController(CertificateErrorControllerPrivate *p);
~CertificateErrorController();
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 841dcf4c9..c44d75a42 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -37,8 +37,6 @@
**
****************************************************************************/
-#include "chromium_overrides.h"
-
#include "ozone/gl_context_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "web_contents_view_qt.h"
@@ -52,6 +50,7 @@
#include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
#include "ui/events/devices/device_data_manager.h"
#include "ui/events/platform/platform_event_source.h"
+#include "ui/snapshot/snapshot.h"
#include "ppapi/buildflags/buildflags.h"
#include <QGuiApplication>
@@ -59,6 +58,7 @@
#include <QWindow>
#include <QFontDatabase>
#include <QStringList>
+#include <QLibraryInfo>
#if defined(USE_AURA) && !defined(USE_OZONE)
#include "ui/base/dragdrop/os_exchange_data.h"
@@ -71,27 +71,6 @@
#include "net/ssl/openssl_client_key_store.h"
#endif
-namespace QtWebEngineCore {
-void GetScreenInfoFromNativeWindow(QWindow* window, content::ScreenInfo* results)
-{
- QScreen* screen = window->screen();
- if (!screen)
- return;
- content::ScreenInfo r;
- r.device_scale_factor = screen->devicePixelRatio();
- r.depth_per_component = 8;
- r.depth = screen->depth();
- r.is_monochrome = (r.depth == 1);
-
- QRect screenGeometry = screen->geometry();
- r.rect = gfx::Rect(screenGeometry.x(), screenGeometry.y(), screenGeometry.width(), screenGeometry.height());
- QRect available = screen->availableGeometry();
- r.available_rect = gfx::Rect(available.x(), available.y(), available.width(), available.height());
- *results = r;
-}
-
-} // namespace QtWebEngineCore
-
void *GetQtXDisplay()
{
return GLContextHelper::getXDisplay();
@@ -112,12 +91,13 @@ WebContentsView* CreateWebContentsView(WebContentsImpl *web_contents,
return rv;
}
-// static
-void WebContentsView::GetDefaultScreenInfo(content::ScreenInfo* results)
+#if defined(Q_OS_MACOS)
+std::string getQtPrefix()
{
- QWindow dummy;
- QtWebEngineCore::GetScreenInfoFromNativeWindow(&dummy, results);
+ const QString prefix = QLibraryInfo::location(QLibraryInfo::PrefixPath);
+ return prefix.toStdString();
}
+#endif
} // namespace content
@@ -173,6 +153,53 @@ ActivationClient *GetActivationClient(aura::Window *)
} // namespace wm
#endif // defined(USE_AURA) || defined(USE_OZONE)
+#if defined(USE_AURA)
+namespace ui {
+
+bool GrabWindowSnapshot(gfx::NativeWindow window,
+ const gfx::Rect& snapshot_bounds,
+ gfx::Image* image)
+{
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool GrabViewSnapshot(gfx::NativeView view,
+ const gfx::Rect& snapshot_bounds,
+ gfx::Image* image)
+{
+ NOTIMPLEMENTED();
+ return false;
+}
+
+void GrabWindowSnapshotAndScaleAsync(gfx::NativeWindow window,
+ const gfx::Rect& source_rect,
+ const gfx::Size& target_size,
+ const GrabWindowSnapshotAsyncCallback& callback)
+{
+ NOTIMPLEMENTED();
+ callback.Run(gfx::Image());
+}
+
+void GrabWindowSnapshotAsync(gfx::NativeWindow window,
+ const gfx::Rect& source_rect,
+ const GrabWindowSnapshotAsyncCallback& callback)
+{
+ NOTIMPLEMENTED();
+ callback.Run(gfx::Image());
+}
+
+void GrabViewSnapshotAsync(gfx::NativeView view,
+ const gfx::Rect& source_rect,
+ const GrabWindowSnapshotAsyncCallback& callback)
+{
+ NOTIMPLEMENTED();
+ callback.Run(gfx::Image());
+}
+
+} // namespace ui
+#endif // defined(USE_AURA)
+
std::unique_ptr<ui::OSExchangeData::Provider>
ui::OSExchangeDataProviderFactory::CreateProvider() {
return nullptr;
diff --git a/src/core/client_cert_select_controller.cpp b/src/core/client_cert_select_controller.cpp
index 7d08d57c1..0baaf2bc5 100644
--- a/src/core/client_cert_select_controller.cpp
+++ b/src/core/client_cert_select_controller.cpp
@@ -48,6 +48,8 @@
#include "type_conversion.h"
+#include <QDebug>
+
QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
@@ -76,17 +78,40 @@ ClientCertSelectController::~ClientCertSelectController()
void ClientCertSelectController::selectNone()
{
if (m_selected) {
- qWarning() << "ClientCertSelectController::selectNone() certicate already selected";
+ LOG(WARNING) << "ClientCertSelectController::selectNone() certificate already selected";
return;
}
m_selected = true;
m_delegate->ContinueWithCertificate(nullptr, nullptr);
}
+void ClientCertSelectController::select(int index)
+{
+ if (m_selected) {
+ LOG(WARNING) << "ClientCertSelectController::select() certificate already selected";
+ return;
+ }
+ for (auto &certInfo : m_clientCerts) {
+ if (index == 0) {
+ m_selected = true;
+ scoped_refptr<net::X509Certificate> cert = certInfo->certificate();
+ net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
+ std::move(certInfo),
+ base::Bind(&content::ClientCertificateDelegate::ContinueWithCertificate,
+ base::Passed(std::move(m_delegate)), std::move(cert)));
+ return;
+ }
+ std::vector<std::string> pem_encoded;
+ if (certInfo->certificate()->GetPEMEncodedChain(&pem_encoded))
+ --index;
+ }
+ LOG(WARNING) << "ClientCertSelectController::select() index out of range:" << index;
+}
+
void ClientCertSelectController::select(const QSslCertificate &certificate)
{
if (m_selected) {
- qWarning() << "ClientCertSelectController::select() certicate already selected";
+ LOG(WARNING) << "ClientCertSelectController::select() certificate already selected";
return;
}
QByteArray derCertificate = certificate.toDer();
@@ -103,19 +128,20 @@ void ClientCertSelectController::select(const QSslCertificate &certificate)
return;
}
}
- qWarning() << "ClientCertSelectController::select() - selected client certificate not recognized."
- << " Selected certificate needs to be one of the offered";
+ LOG(WARNING) << "ClientCertSelectController::select() - selected client certificate not recognized."
+ << " Selected certificate needs to be one of the offered";
}
QVector<QSslCertificate> ClientCertSelectController::certificates() const
{
- QVector<QSslCertificate> out;
+ if (!m_certificates.isEmpty())
+ return m_certificates;
for (auto &cert : m_clientCerts) {
std::vector<std::string> pem_encoded;
if (cert->certificate()->GetPEMEncodedChain(&pem_encoded))
- out.append(QSslCertificate(QByteArray::fromStdString(pem_encoded.front())));
+ m_certificates.append(QSslCertificate(QByteArray::fromStdString(pem_encoded.front())));
}
- return out;
+ return m_certificates;
}
#endif // !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
diff --git a/src/core/client_cert_select_controller.h b/src/core/client_cert_select_controller.h
index 46324ee90..f121c1155 100644
--- a/src/core/client_cert_select_controller.h
+++ b/src/core/client_cert_select_controller.h
@@ -72,7 +72,7 @@ class SSLCertRequestInfo;
QT_BEGIN_NAMESPACE
-class QWEBENGINECORE_PRIVATE_EXPORT ClientCertSelectController {
+class Q_WEBENGINECORE_PRIVATE_EXPORT ClientCertSelectController {
public:
ClientCertSelectController(net::SSLCertRequestInfo *certRequestInfo,
std::vector<std::unique_ptr<net::ClientCertIdentity>> clientCerts,
@@ -83,6 +83,7 @@ public:
#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
void selectNone();
void select(const QSslCertificate &certificate);
+ void select(int index);
QVector<QSslCertificate> certificates() const;
#endif
@@ -91,6 +92,7 @@ private:
QUrl m_hostAndPort;
std::vector<std::unique_ptr<net::ClientCertIdentity>> m_clientCerts;
std::unique_ptr<content::ClientCertificateDelegate> m_delegate;
+ mutable QVector<QSslCertificate> m_certificates;
bool m_selected;
};
diff --git a/src/core/clipboard_change_observer.h b/src/core/clipboard_change_observer.h
new file mode 100644
index 000000000..f9b33fc93
--- /dev/null
+++ b/src/core/clipboard_change_observer.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CLIPBOARD_CHANGE_OBSERVER_H
+#define CLIPBOARD_CHANGE_OBSERVER_H
+
+#include <QClipboard>
+#include <QMap>
+#include <QObject>
+
+namespace QtWebEngineCore {
+
+class ClipboardChangeObserver : public QObject {
+ Q_OBJECT
+public:
+ ClipboardChangeObserver();
+ quint64 getSequenceNumber(QClipboard::Mode mode) { return sequenceNumber.value(mode); }
+
+private Q_SLOTS:
+ void trackChange(QClipboard::Mode mode);
+
+private:
+ QMap<QClipboard::Mode, quint64> sequenceNumber;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // CLIPBOARD_CHANGE_OBSERVER_H
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 44756bdfe..f4a14570a 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -42,13 +42,15 @@
// found in the LICENSE.Chromium file.
#include "clipboard_qt.h"
-#include "ui/base/clipboard/clipboard.h"
-
+#include "clipboard_change_observer.h"
#include "type_conversion.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/custom_data_helper.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_format_type.h"
#include <QGuiApplication>
#include <QImage>
@@ -81,12 +83,6 @@ using namespace QtWebEngineCore;
namespace {
-const char kMimeTypeBitmap[] = "image/bmp";
-const char kMimeTypeMozillaURL[] = "text/x-moz-url";
-const char kMimeTypeWebCustomDataCopy[] = "chromium/x-web-custom-data";
-const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
-const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
-
QScopedPointer<QMimeData> uncommittedData;
QMimeData *getUncommittedData()
{
@@ -95,118 +91,21 @@ QMimeData *getUncommittedData()
return uncommittedData.data();
}
-} // namespace
+} // namespace
namespace ui {
// Factory function
-Clipboard* Clipboard::Create() {
- return new ClipboardQt;
-}
-
-Clipboard::FormatType Clipboard::GetFormatType(const std::string& format_string)
-{
- return FormatType::Deserialize(format_string);
-}
-
-const Clipboard::FormatType& Clipboard::GetPlainTextFormatType()
-{
- CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeText));
- return type;
-}
-
-const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType()
-{
- return GetPlainTextFormatType();
-}
-
-const Clipboard::FormatType& Clipboard::GetUrlFormatType()
-{
- return GetPlainTextFormatType();
-}
-
-const Clipboard::FormatType& Clipboard::GetUrlWFormatType()
-{
- return GetPlainTextWFormatType();
-}
-
-const Clipboard::FormatType& Clipboard::GetHtmlFormatType()
-{
- CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeHTML));
- return type;
-}
-
-const Clipboard::FormatType& Clipboard::GetRtfFormatType()
-{
- CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeRTF));
- return type;
-}
-
-const Clipboard::FormatType& Clipboard::GetBitmapFormatType()
-{
- CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeBitmap));
- return type;
-}
-
-const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType()
+Clipboard *Clipboard::Create()
{
- CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebkitSmartPaste));
- return type;
-}
-
-const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType()
-{
- CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomDataCopy));
- return type;
-}
-
-const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType()
-{
- CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
- return type;
-}
-
-
-Clipboard::FormatType::FormatType()
-{
-}
-
-Clipboard::FormatType::FormatType(const std::string& format_string)
- : data_(format_string)
-{
-}
-
-Clipboard::FormatType::~FormatType()
-{
-}
-
-std::string Clipboard::FormatType::Serialize() const
-{
- return data_;
-}
-
-Clipboard::FormatType Clipboard::FormatType::Deserialize(const std::string& serialization)
-{
- return FormatType(serialization);
-}
-
-bool Clipboard::FormatType::Equals(const FormatType& other) const
-{
- return data_ == other.data_;
-}
-
-#if defined(OS_WIN) || defined(USE_AURA)
-bool Clipboard::FormatType::operator<(const FormatType& other) const
-{
- return data_.compare(other.data_) < 0;
+ return new ClipboardQt;
}
-#endif
} // namespace ui
namespace QtWebEngineCore {
-void ClipboardQt::WriteObjects(ui::ClipboardType type, const ObjectMap& objects)
+void ClipboardQt::WriteObjects(ui::ClipboardType type, const ObjectMap &objects)
{
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardType(type));
@@ -216,7 +115,9 @@ void ClipboardQt::WriteObjects(ui::ClipboardType type, const ObjectMap& objects)
// Commit the accumulated data.
if (uncommittedData)
- QGuiApplication::clipboard()->setMimeData(uncommittedData.take(), type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ QGuiApplication::clipboard()->setMimeData(uncommittedData.take(),
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard
+ : QClipboard::Selection);
if (type == ui::CLIPBOARD_TYPE_COPY_PASTE && IsSupportedClipboardType(ui::CLIPBOARD_TYPE_SELECTION)) {
ObjectMap::const_iterator text_iter = objects.find(CBF_TEXT);
@@ -228,32 +129,32 @@ void ClipboardQt::WriteObjects(ui::ClipboardType type, const ObjectMap& objects)
}
}
-void ClipboardQt::WriteText(const char* text_data, size_t text_len)
+void ClipboardQt::WriteText(const char *text_data, size_t text_len)
{
getUncommittedData()->setText(QString::fromUtf8(text_data, text_len));
}
-void ClipboardQt::WriteHTML(const char* markup_data, size_t markup_len, const char* url_data, size_t url_len)
+void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len)
{
getUncommittedData()->setHtml(QString::fromUtf8(markup_data, markup_len));
}
-void ClipboardQt::WriteRTF(const char* rtf_data, size_t data_len)
+void ClipboardQt::WriteRTF(const char *rtf_data, size_t data_len)
{
- getUncommittedData()->setData(QString::fromLatin1(kMimeTypeRTF), QByteArray(rtf_data, data_len));
+ getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeRTF), QByteArray(rtf_data, data_len));
}
void ClipboardQt::WriteWebSmartPaste()
{
- getUncommittedData()->setData(QString::fromLatin1(kMimeTypeWebkitSmartPaste), QByteArray());
+ getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeWebkitSmartPaste), QByteArray());
}
-void ClipboardQt::WriteBitmap(const SkBitmap& bitmap)
+void ClipboardQt::WriteBitmap(const SkBitmap &bitmap)
{
getUncommittedData()->setImageData(toQImage(bitmap).copy());
}
-void ClipboardQt::WriteBookmark(const char* title_data, size_t title_len, const char* url_data, size_t url_len)
+void ClipboardQt::WriteBookmark(const char *title_data, size_t title_len, const char *url_data, size_t url_len)
{
// FIXME: Untested, seems to be used only for drag-n-drop.
// Write as a mozilla url (UTF16: URL, newline, title).
@@ -261,29 +162,32 @@ void ClipboardQt::WriteBookmark(const char* title_data, size_t title_len, const
QString title = QString::fromUtf8(title_data, title_len);
QByteArray data;
- data.append(reinterpret_cast<const char*>(url.utf16()), url.size() * 2);
+ data.append(reinterpret_cast<const char *>(url.utf16()), url.size() * 2);
data.append('\n');
- data.append(reinterpret_cast<const char*>(title.utf16()), title.size() * 2);
- getUncommittedData()->setData(QString::fromLatin1(kMimeTypeMozillaURL), data);
+ data.append(reinterpret_cast<const char *>(title.utf16()), title.size() * 2);
+ getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeMozillaURL), data);
}
-void ClipboardQt::WriteData(const FormatType& format, const char* data_data, size_t data_len)
+void ClipboardQt::WriteData(const ui::ClipboardFormatType &format, const char *data_data, size_t data_len)
{
getUncommittedData()->setData(QString::fromStdString(format.ToString()), QByteArray(data_data, data_len));
}
-bool ClipboardQt::IsFormatAvailable(const ui::Clipboard::FormatType& format, ui::ClipboardType type) const
+bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format, ui::ClipboardType type) const
{
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
return mimeData && mimeData->hasFormat(QString::fromStdString(format.ToString()));
}
void ClipboardQt::Clear(ui::ClipboardType type)
{
- QGuiApplication::clipboard()->clear(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ QGuiApplication::clipboard()->clear(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard
+ : QClipboard::Selection);
}
-void ClipboardQt::ReadAvailableTypes(ui::ClipboardType type, std::vector<base::string16>* types, bool* contains_filenames) const
+void ClipboardQt::ReadAvailableTypes(ui::ClipboardType type, std::vector<base::string16> *types,
+ bool *contains_filenames) const
{
if (!types || !contains_filenames) {
NOTREACHED();
@@ -291,7 +195,8 @@ void ClipboardQt::ReadAvailableTypes(ui::ClipboardType type, std::vector<base::s
}
types->clear();
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
if (!mimeData)
return;
if (mimeData->hasImage() && !mimeData->formats().contains(QStringLiteral("image/png")))
@@ -301,26 +206,28 @@ void ClipboardQt::ReadAvailableTypes(ui::ClipboardType type, std::vector<base::s
types->push_back(toString16(mimeType));
*contains_filenames = false;
- const QByteArray customData = mimeData->data(QString::fromLatin1(kMimeTypeWebCustomDataCopy));
+ const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
ui::ReadCustomDataTypes(customData.constData(), customData.size(), types);
}
-
-void ClipboardQt::ReadText(ui::ClipboardType type, base::string16* result) const
+void ClipboardQt::ReadText(ui::ClipboardType type, base::string16 *result) const
{
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
if (mimeData)
*result = toString16(mimeData->text());
}
-void ClipboardQt::ReadAsciiText(ui::ClipboardType type, std::string* result) const
+void ClipboardQt::ReadAsciiText(ui::ClipboardType type, std::string *result) const
{
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
if (mimeData)
*result = mimeData->text().toStdString();
}
-void ClipboardQt::ReadHTML(ui::ClipboardType type, base::string16* markup, std::string* src_url, uint32_t* fragment_start, uint32_t* fragment_end) const
+void ClipboardQt::ReadHTML(ui::ClipboardType type, base::string16 *markup, std::string *src_url,
+ uint32_t *fragment_start, uint32_t *fragment_end) const
{
markup->clear();
if (src_url)
@@ -328,25 +235,28 @@ void ClipboardQt::ReadHTML(ui::ClipboardType type, base::string16* markup, std::
*fragment_start = 0;
*fragment_end = 0;
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
if (!mimeData)
return;
*markup = toString16(mimeData->html());
*fragment_end = static_cast<uint32_t>(markup->length());
}
-void ClipboardQt::ReadRTF(ui::ClipboardType type, std::string* result) const
+void ClipboardQt::ReadRTF(ui::ClipboardType type, std::string *result) const
{
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
if (!mimeData)
return;
- const QByteArray byteArray = mimeData->data(QString::fromLatin1(kMimeTypeRTF));
+ const QByteArray byteArray = mimeData->data(QString::fromLatin1(ui::kMimeTypeRTF));
*result = std::string(byteArray.constData(), byteArray.length());
}
SkBitmap ClipboardQt::ReadImage(ui::ClipboardType type) const
{
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
if (!mimeData)
return SkBitmap();
QImage image = qvariant_cast<QImage>(mimeData->imageData());
@@ -369,21 +279,22 @@ SkBitmap ClipboardQt::ReadImage(ui::ClipboardType type) const
return bitmap;
}
-void ClipboardQt::ReadCustomData(ui::ClipboardType clipboard_type, const base::string16& type, base::string16* result) const
+void ClipboardQt::ReadCustomData(ui::ClipboardType clipboard_type, const base::string16 &type, base::string16 *result) const
{
- const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(clipboard_type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ clipboard_type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
if (!mimeData)
return;
- const QByteArray customData = mimeData->data(QString::fromLatin1(kMimeTypeWebCustomDataCopy));
+ const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
ui::ReadCustomDataForType(customData.constData(), customData.size(), type, result);
}
-void ClipboardQt::ReadBookmark(base::string16* title, std::string* url) const
+void ClipboardQt::ReadBookmark(base::string16 *title, std::string *url) const
{
NOTIMPLEMENTED();
}
-void ClipboardQt::ReadData(const FormatType& format, std::string* result) const
+void ClipboardQt::ReadData(const ui::ClipboardFormatType &format, std::string *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData();
if (!mimeData)
@@ -394,7 +305,8 @@ void ClipboardQt::ReadData(const FormatType& format, std::string* result) const
uint64_t ClipboardQt::GetSequenceNumber(ui::ClipboardType type) const
{
- return clipboardChangeObserver()->getSequenceNumber(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection);
+ return clipboardChangeObserver()->getSequenceNumber(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard
+ : QClipboard::Selection);
}
-} // namespace QtWebEngineCore
+} // namespace QtWebEngineCore
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
index 2089208bf..7884da167 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -42,57 +42,36 @@
#include "ui/base/clipboard/clipboard.h"
-#include <QClipboard>
-#include <QMap>
-#include <QObject>
-
namespace QtWebEngineCore {
-class ClipboardChangeObserver : public QObject {
- Q_OBJECT
-public:
- ClipboardChangeObserver();
- quint64 getSequenceNumber(QClipboard::Mode mode) {
- return sequenceNumber.value(mode);
- }
-
-private Q_SLOTS:
- void trackChange(QClipboard::Mode mode);
-
-private:
- QMap<QClipboard::Mode, quint64> sequenceNumber;
-};
-
class ClipboardQt : public ui::Clipboard {
public:
uint64_t GetSequenceNumber(ui::ClipboardType type) const override;
- bool IsFormatAvailable(const FormatType& format, ui::ClipboardType type) const override;
+ bool IsFormatAvailable(const ui::ClipboardFormatType &format, ui::ClipboardType type) const override;
void Clear(ui::ClipboardType type) override;
- void ReadAvailableTypes(ui::ClipboardType type, std::vector<base::string16>* types, bool* contains_filenames) const override;
- void ReadText(ui::ClipboardType type, base::string16* result) const override;
- void ReadAsciiText(ui::ClipboardType type, std::string* result) const override;
- void ReadHTML(ui::ClipboardType type,
- base::string16* markup,
- std::string* src_url,
- uint32_t* fragment_start,
- uint32_t* fragment_end) const override;
- void ReadRTF(ui::ClipboardType type, std::string* result) const override;
+ void ReadAvailableTypes(ui::ClipboardType type, std::vector<base::string16> *types,
+ bool *contains_filenames) const override;
+ void ReadText(ui::ClipboardType type, base::string16 *result) const override;
+ void ReadAsciiText(ui::ClipboardType type, std::string *result) const override;
+ void ReadHTML(ui::ClipboardType type, base::string16 *markup, std::string *src_url, uint32_t *fragment_start,
+ uint32_t *fragment_end) const override;
+ void ReadRTF(ui::ClipboardType type, std::string *result) const override;
SkBitmap ReadImage(ui::ClipboardType type) const override;
- void ReadCustomData(ui::ClipboardType clipboard_type, const base::string16& type, base::string16* result) const override;
- void ReadBookmark(base::string16* title, std::string* url) const override;
- void ReadData(const FormatType& format, std::string* result) const override;
+ void ReadCustomData(ui::ClipboardType clipboard_type, const base::string16 &type, base::string16 *result) const override;
+ void ReadBookmark(base::string16 *title, std::string *url) const override;
+ void ReadData(const ui::ClipboardFormatType &format, std::string *result) const override;
- void OnPreShutdown() override { }
+ void OnPreShutdown() override {}
protected:
- void WriteObjects(ui::ClipboardType type, const ObjectMap& objects) override;
- void WriteText(const char* text_data, size_t text_len) override;
- void WriteHTML(const char* markup_data, size_t markup_len, const char* url_data, size_t url_len) override;
- void WriteRTF(const char* rtf_data, size_t data_len) override;
- void WriteBookmark(const char* title_data, size_t title_len, const char* url_data, size_t url_len) override;
+ void WriteObjects(ui::ClipboardType type, const ObjectMap &objects) override;
+ void WriteText(const char *text_data, size_t text_len) override;
+ void WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len) override;
+ void WriteRTF(const char *rtf_data, size_t data_len) override;
+ void WriteBookmark(const char *title_data, size_t title_len, const char *url_data, size_t url_len) override;
void WriteWebSmartPaste() override;
- void WriteBitmap(const SkBitmap& bitmap) override;
- void WriteData(const FormatType& format, const char* data_data, size_t data_len) override;
+ void WriteBitmap(const SkBitmap &bitmap) override;
+ void WriteData(const ui::ClipboardFormatType &format, const char *data_data, size_t data_len) override;
};
} // namespace QtWebEngineCore
diff --git a/src/core/color_chooser_controller.cpp b/src/core/color_chooser_controller.cpp
index 26d675908..361ff93ba 100644
--- a/src/core/color_chooser_controller.cpp
+++ b/src/core/color_chooser_controller.cpp
@@ -43,6 +43,9 @@
#include "color_chooser_controller_p.h"
#include "type_conversion.h"
+#include <QColor>
+#include <QVariant>
+
namespace QtWebEngineCore {
ColorChooserControllerPrivate::ColorChooserControllerPrivate(content::WebContents *content, const QColor &color)
diff --git a/src/core/color_chooser_controller.h b/src/core/color_chooser_controller.h
index 4c1b81a9a..66222bb77 100644
--- a/src/core/color_chooser_controller.h
+++ b/src/core/color_chooser_controller.h
@@ -55,11 +55,14 @@
#include <QObject>
+QT_FORWARD_DECLARE_CLASS(QColor)
+QT_FORWARD_DECLARE_CLASS(QVariant)
+
namespace QtWebEngineCore {
class ColorChooserControllerPrivate;
-class QWEBENGINECORE_PRIVATE_EXPORT ColorChooserController : public QObject {
+class Q_WEBENGINECORE_PRIVATE_EXPORT ColorChooserController : public QObject {
Q_OBJECT
public:
~ColorChooserController();
diff --git a/src/core/command_line_pref_store_qt.cpp b/src/core/command_line_pref_store_qt.cpp
new file mode 100644
index 000000000..5c5c82e1a
--- /dev/null
+++ b/src/core/command_line_pref_store_qt.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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 "command_line_pref_store_qt.h"
+
+#include "chrome/common/chrome_switches.h"
+#include "components/proxy_config/proxy_config_dictionary.h"
+#include "components/proxy_config/proxy_config_pref_names.h"
+#include "content/public/common/content_switches.h"
+#include <QDebug>
+
+CommandLinePrefStoreQt::CommandLinePrefStoreQt(const base::CommandLine *commandLine)
+ : CommandLinePrefStore(commandLine)
+{
+
+ if (commandLine->HasSwitch(switches::kNoProxyServer)) {
+ SetValue(proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(ProxyConfigDictionary::CreateDirect()),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ } else if (commandLine->HasSwitch(switches::kProxyPacUrl)) {
+ std::string pac_script_url =
+ commandLine->GetSwitchValueASCII(switches::kProxyPacUrl);
+ SetValue(proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(ProxyConfigDictionary::CreatePacScript(
+ pac_script_url, false)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ } else if (commandLine->HasSwitch(switches::kProxyAutoDetect)) {
+ SetValue(proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(
+ ProxyConfigDictionary::CreateAutoDetect()),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ } else if (commandLine->HasSwitch(switches::kProxyServer)) {
+ std::string proxy_server =
+ commandLine->GetSwitchValueASCII(switches::kProxyServer);
+ std::string bypass_list =
+ commandLine->GetSwitchValueASCII(switches::kProxyBypassList);
+ SetValue(
+ proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(ProxyConfigDictionary::CreateFixedServers(
+ proxy_server, bypass_list)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ }
+
+ if (commandLine->HasSwitch(switches::kNoProxyServer) && (commandLine->HasSwitch(switches::kProxyAutoDetect) || commandLine->HasSwitch(switches::kProxyServer) || commandLine->HasSwitch(switches::kProxyPacUrl) || commandLine->HasSwitch(switches::kProxyBypassList))) {
+ qWarning("Additional command-line proxy switches specified when --%s was also specified",
+ qPrintable(switches::kNoProxyServer));
+ }
+}
+
+CommandLinePrefStoreQt::~CommandLinePrefStoreQt() = default;
diff --git a/src/core/command_line_pref_store_qt.h b/src/core/command_line_pref_store_qt.h
new file mode 100644
index 000000000..a509f8ca9
--- /dev/null
+++ b/src/core/command_line_pref_store_qt.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMMAND_LINE_PREF_STORE_QT_H
+#define COMMAND_LINE_PREF_STORE_QT_H
+
+#include "base/command_line.h"
+#include "components/prefs/command_line_pref_store.h"
+
+class CommandLinePrefStoreQt : public CommandLinePrefStore
+{
+public:
+ explicit CommandLinePrefStoreQt(const base::CommandLine *commandLine);
+
+protected:
+ ~CommandLinePrefStoreQt() override;
+ DISALLOW_COPY_AND_ASSIGN(CommandLinePrefStoreQt);
+};
+
+#endif // COMMAND_LINE_PREF_STORE_QT_H
diff --git a/src/core/common/extensions/api/qtwebengine_extensions_features.gni b/src/core/common/extensions/api/qtwebengine_extensions_features.gni
new file mode 100644
index 000000000..ed7e713c6
--- /dev/null
+++ b/src/core/common/extensions/api/qtwebengine_extensions_features.gni
@@ -0,0 +1,25 @@
+import("//tools/json_schema_compiler/json_features.gni")
+
+json_features("qt_api_features") {
+ feature_type = "APIFeature"
+ method_name = "AddQtAPIFeatures"
+ sources = [
+ "//extensions/common/api/_webengine_api_features.json"
+ ]
+}
+
+json_features("qt_permission_features") {
+ feature_type = "PermissionFeature"
+ method_name = "AddQtPermissionFeatures"
+ sources = [
+ "//extensions/common/api/_permission_features.json"
+ ]
+}
+
+group("qtwebengine_extensions_features") {
+ public_deps = [
+ ":qt_api_features",
+ ":qt_permission_features",
+ "//extensions/common/api:extensions_features",
+ ]
+}
diff --git a/src/core/common/extensions/extensions_api_provider_qt.cpp b/src/core/common/extensions/extensions_api_provider_qt.cpp
new file mode 100644
index 000000000..22154a9d1
--- /dev/null
+++ b/src/core/common/extensions/extensions_api_provider_qt.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "extensions_api_provider_qt.h"
+
+#include "chrome/grit/common_resources.h"
+
+#include "extensions/common/api/api_features.h"
+#include "extensions/common/api/behavior_features.h"
+#include "extensions/common/api/generated_schemas.h"
+#include "extensions/common/api/manifest_features.h"
+#include "extensions/common/api/permission_features.h"
+#include "extensions/common/common_manifest_handlers.h"
+#include "extensions/common/features/feature_provider.h"
+#include "extensions/common/features/json_feature_provider_source.h"
+#include "extensions/common/permissions/permissions_info.h"
+#include "extensions/grit/extensions_resources.h"
+
+#include "qt_api_features.h"
+//#include "qt_behavior_features.h"
+#include "qt_permission_features.h"
+//#include "qt_manifest_features.h"
+
+
+namespace extensions {
+
+ExtensionsAPIProviderQt::ExtensionsAPIProviderQt()
+{
+}
+
+void ExtensionsAPIProviderQt::RegisterManifestHandlers()
+{
+}
+
+void ExtensionsAPIProviderQt::AddAPIFeatures(FeatureProvider *provider)
+{
+ AddQtAPIFeatures(provider);
+}
+
+void ExtensionsAPIProviderQt::AddAPIJSONSources(JSONFeatureProviderSource *json_source)
+{
+ json_source->LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES);
+}
+
+void ExtensionsAPIProviderQt::AddPermissionFeatures(FeatureProvider *provider)
+{
+ AddQtPermissionFeatures(provider);
+}
+
+bool ExtensionsAPIProviderQt::IsAPISchemaGenerated(const std::string &name)
+{
+ return api::GeneratedSchemas::IsGenerated(name);
+}
+
+base::StringPiece ExtensionsAPIProviderQt::GetAPISchema(const std::string &name)
+{
+ return api::GeneratedSchemas::Get(name);
+}
+
+void ExtensionsAPIProviderQt::RegisterPermissions(PermissionsInfo* permissions_info)
+{
+}
+
+}
diff --git a/src/core/common/extensions/extensions_api_provider_qt.h b/src/core/common/extensions/extensions_api_provider_qt.h
new file mode 100644
index 000000000..7d8c5f98b
--- /dev/null
+++ b/src/core/common/extensions/extensions_api_provider_qt.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef EXTENSIONS_API_PROVIDER_QT_H
+#define EXTENSIONS_API_PROVIDER_QT_H
+
+#include "extensions/common/extensions_api_provider.h"
+
+#include "base/macros.h"
+
+namespace extensions {
+
+class ExtensionsAPIProviderQt : public ExtensionsAPIProvider
+{
+public:
+ ExtensionsAPIProviderQt();
+
+ void RegisterManifestHandlers() override;
+ void AddAPIFeatures(FeatureProvider *provider) override;
+ void AddAPIJSONSources(JSONFeatureProviderSource* json_source) override;
+ void AddPermissionFeatures(FeatureProvider* provider) override;
+
+ bool IsAPISchemaGenerated(const std::string& name) override;
+ base::StringPiece GetAPISchema(const std::string& name) override;
+
+ // Adds feature definitions to the given |provider| of the specified type.
+ void AddManifestFeatures(FeatureProvider* provider) override { }
+ void AddBehaviorFeatures(FeatureProvider* provider) override { }
+
+ // Registers permissions for any associated API features.
+ void RegisterPermissions(PermissionsInfo* permissions_info) override;
+
+DISALLOW_COPY_AND_ASSIGN(ExtensionsAPIProviderQt);
+};
+
+}
+
+#endif // EXTENSIONS_API_PROVIDER_QT_H
diff --git a/src/core/common/extensions/extensions_client_qt.cpp b/src/core/common/extensions/extensions_client_qt.cpp
new file mode 100644
index 000000000..6c6200eb0
--- /dev/null
+++ b/src/core/common/extensions/extensions_client_qt.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions 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 "extensions_client_qt.h"
+
+#include "extensions/common/alias.h"
+#include "extensions/common/core_extensions_api_provider.h"
+#include "extensions/common/extension_urls.h"
+
+#include "extensions/common/features/simple_feature.h"
+#include "extensions/common/permissions/permissions_info.h"
+
+#include "extensions_api_provider_qt.h"
+
+
+namespace extensions {
+
+template<class FeatureClass> SimpleFeature *CreateFeature()
+{
+ return new FeatureClass;
+}
+
+static base::LazyInstance<ExtensionsClientQt>::Leaky g_client = LAZY_INSTANCE_INITIALIZER;
+
+ExtensionsClientQt *ExtensionsClientQt::GetInstance()
+{
+ return g_client.Pointer();
+}
+
+ExtensionsClientQt::ExtensionsClientQt() : ExtensionsClient()
+{
+ AddAPIProvider(std::make_unique<CoreExtensionsAPIProvider>());
+ AddAPIProvider(std::make_unique<ExtensionsAPIProviderQt>());
+}
+
+// Initializes global state. Not done in the constructor because unit tests
+// can create additional ExtensionsClients because the utility thread runs
+// in-process.
+void ExtensionsClientQt::Initialize()
+{
+}
+
+void ExtensionsClientQt::InitializeWebStoreUrls(base::CommandLine *command_line)
+{
+}
+
+// Returns the global PermissionMessageProvider to use to provide permission
+// warning strings.
+const PermissionMessageProvider &ExtensionsClientQt::GetPermissionMessageProvider() const
+{
+ return permission_message_provider_;
+}
+
+// Returns the application name. For example, "Chromium" or "app_shell".
+const std::string ExtensionsClientQt::GetProductName()
+{
+ return "Qt WebEngine"; // return Qt WebEngine for now, consider returning the application name if possible.
+}
+
+// Takes the list of all hosts and filters out those with special
+// permission strings. Adds the regular hosts to |new_hosts|,
+// and adds any additional permissions to |permissions|.
+// TODO(sashab): Split this function in two: One to filter out ignored host
+// permissions, and one to get permissions for the given hosts.
+void ExtensionsClientQt::FilterHostPermissions(const URLPatternSet &hosts,
+ URLPatternSet *new_hosts,
+ PermissionIDSet *permissions) const
+{
+}
+
+// Replaces the scripting whitelist with |whitelist|. Used in the renderer{}
+// only used for testing in the browser process.
+void ExtensionsClientQt::SetScriptingWhitelist(const ExtensionsClient::ScriptingWhitelist &whitelist)
+{
+ scripting_whitelist_ = whitelist;
+}
+
+// Return the whitelist of extensions that can run content scripts on
+// any origin.
+const ExtensionsClient::ScriptingWhitelist &ExtensionsClientQt::GetScriptingWhitelist() const
+{
+ return scripting_whitelist_;
+}
+
+// Get the set of chrome:// hosts that |extension| can run content scripts on.
+URLPatternSet ExtensionsClientQt::GetPermittedChromeSchemeHosts(const Extension *extension,
+ const APIPermissionSet &api_permissions) const
+{
+ return URLPatternSet();
+}
+
+// Returns false if content scripts are forbidden from running on |url|.
+bool ExtensionsClientQt::IsScriptableURL(const GURL &url, std::string *error) const
+{
+ return true;
+}
+
+// Determines if certain fatal extensions errors should be surpressed
+// (i.e., only logged) or allowed (i.e., logged before crashing).
+bool ExtensionsClientQt::ShouldSuppressFatalErrors() const
+{
+ return true;
+}
+
+// Records that a fatal error was caught and suppressed. It is expected that
+// embedders will only do so if ShouldSuppressFatalErrors at some point
+// returned true.
+void ExtensionsClientQt::RecordDidSuppressFatalError()
+{
+}
+
+// Returns the base webstore URL prefix.
+const GURL &ExtensionsClientQt::GetWebstoreBaseURL() const
+{
+ if (base_url_.is_empty())
+ base_url_ = GURL(extension_urls::kChromeWebstoreBaseURL);
+ return base_url_;
+}
+
+// Returns the URL to use for update manifest queries.
+const GURL &ExtensionsClientQt::GetWebstoreUpdateURL() const
+{
+ if (update_url_.is_empty())
+ update_url_ = GURL(extension_urls::GetWebstoreUpdateUrl());
+ return update_url_;
+}
+
+// Returns a flag indicating whether or not a given URL is a valid
+// extension blacklist URL.
+bool ExtensionsClientQt::IsBlacklistUpdateURL(const GURL &url) const
+{
+ return true;
+}
+
+// Returns the set of file paths corresponding to any images within an
+// extension's contents that may be displayed directly within the browser UI
+// or WebUI, such as icons or theme images. This set of paths is used by the
+// extension unpacker to determine which assets should be transcoded safely
+// within the utility sandbox.
+//
+// The default implementation returns the images used as icons for the
+// extension itself, so implementors of ExtensionsClient overriding this may
+// want to call the base class version and then add additional paths to that
+// result.
+std::set<base::FilePath> ExtensionsClientQt::GetBrowserImagePaths(const Extension *extension)
+{
+ return ExtensionsClient::GetBrowserImagePaths(extension);
+}
+
+} // namespace extensions
diff --git a/src/core/common/extensions/extensions_client_qt.h b/src/core/common/extensions/extensions_client_qt.h
new file mode 100644
index 000000000..657487277
--- /dev/null
+++ b/src/core/common/extensions/extensions_client_qt.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions 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 EXTENSIONS_CLIENT_QT_H
+#define EXTENSIONS_CLIENT_QT_H
+
+#include "extensions/common/extensions_client.h"
+
+#include "base/compiler_specific.h"
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
+#include "extensions/common/features/feature_provider.h"
+#include "extensions/common/features/json_feature_provider_source.h"
+#include "extensions/common/permissions/extensions_api_permissions.h"
+#include "url/gurl.h"
+
+namespace extensions {
+
+// Sets up global state for the extensions system. Should be Set() once in each
+// process. This should be implemented by the client of the extensions system.
+class ExtensionsClientQt : public ExtensionsClient
+{
+public:
+ ExtensionsClientQt();
+ virtual ~ExtensionsClientQt() {}
+
+ // Initializes global state. Not done in the constructor because unit tests
+ // can create additional ExtensionsClients because the utility thread runs
+ // in-process.
+ void Initialize() override;
+ void InitializeWebStoreUrls(base::CommandLine *command_line) override;
+
+ // Returns the global PermissionMessageProvider to use to provide permission
+ // warning strings.
+ const PermissionMessageProvider &GetPermissionMessageProvider() const override;
+
+ // Returns the application name. For example, "Chromium" or "app_shell".
+ const std::string GetProductName() override;
+
+ // Takes the list of all hosts and filters out those with special
+ // permission strings. Adds the regular hosts to |new_hosts|,
+ // and adds any additional permissions to |permissions|.
+ // TODO(sashab): Split this function in two: One to filter out ignored host
+ // permissions, and one to get permissions for the given hosts.
+ void FilterHostPermissions(const URLPatternSet &hosts,
+ URLPatternSet *new_hosts,
+ PermissionIDSet *permissions) const override;
+
+ // Replaces the scripting whitelist with |whitelist|. Used in the renderer;
+ // only used for testing in the browser process.
+ void SetScriptingWhitelist(const ScriptingWhitelist &whitelist) override;
+
+ // Return the whitelist of extensions that can run content scripts on
+ // any origin.
+ const ScriptingWhitelist &GetScriptingWhitelist() const override;
+
+ // Get the set of chrome:// hosts that |extension| can run content scripts on.
+ URLPatternSet GetPermittedChromeSchemeHosts(const Extension *extension,
+ const APIPermissionSet &api_permissions) const override;
+
+ // Returns false if content scripts are forbidden from running on |url|.
+ bool IsScriptableURL(const GURL &url, std::string *error) const override;
+
+ // Determines if certain fatal extensions errors should be surpressed
+ // (i.e., only logged) or allowed (i.e., logged before crashing).
+ bool ShouldSuppressFatalErrors() const override;
+
+ // Records that a fatal error was caught and suppressed. It is expected that
+ // embedders will only do so if ShouldSuppressFatalErrors at some point
+ // returned true.
+ void RecordDidSuppressFatalError() override;
+
+ // Returns the base webstore URL prefix.
+ const GURL &GetWebstoreBaseURL() const override;
+
+ // Returns the URL to use for update manifest queries.
+ const GURL &GetWebstoreUpdateURL() const override;
+
+ // Returns a flag indicating whether or not a given URL is a valid
+ // extension blacklist URL.
+ bool IsBlacklistUpdateURL(const GURL &url) const override;
+
+ // Returns the set of file paths corresponding to any images within an
+ // extension's contents that may be displayed directly within the browser UI
+ // or WebUI, such as icons or theme images. This set of paths is used by the
+ // extension unpacker to determine which assets should be transcoded safely
+ // within the utility sandbox.
+ //
+ // The default implementation returns the images used as icons for the
+ // extension itself, so implementors of ExtensionsClient overriding this may
+ // want to call the base class version and then add additional paths to that
+ // result.
+ std::set<base::FilePath> GetBrowserImagePaths(const Extension *extension) override;
+ // Get the LazyInstance for ChromeExtensionsClient.
+ static ExtensionsClientQt *GetInstance();
+
+private:
+ ScriptingWhitelist scripting_whitelist_;
+ const ChromePermissionMessageProvider permission_message_provider_;
+ mutable GURL update_url_;
+ mutable GURL base_url_;
+ DISALLOW_COPY_AND_ASSIGN(ExtensionsClientQt);
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_CLIENT_QT_H
diff --git a/src/core/common/qt_messages.cpp b/src/core/common/qt_messages.cpp
index d64db69c9..2f087d21f 100644
--- a/src/core/common/qt_messages.cpp
+++ b/src/core/common/qt_messages.cpp
@@ -10,10 +10,6 @@
#include "ipc/struct_constructor_macros.h"
#include "common/qt_messages.h"
-// Generate destructors.
-#include "ipc/struct_destructor_macros.h"
-#include "common/qt_messages.h"
-
// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index 88c29f13b..9add826ae 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -111,9 +111,8 @@ IPC_MESSAGE_CONTROL4(QtWebEngineHostMsg_RequestFileSystemAccessAsync,
// Sent by the renderer process to check whether access to Indexed DB is
// granted by content settings.
-IPC_SYNC_MESSAGE_CONTROL4_1(QtWebEngineHostMsg_AllowIndexedDB,
+IPC_SYNC_MESSAGE_CONTROL3_1(QtWebEngineHostMsg_AllowIndexedDB,
int /* render_frame_id */,
GURL /* origin_url */,
GURL /* top origin url */,
- base::string16 /* database name */,
bool /* allowed */)
diff --git a/src/core/chromium_gpu_helper.cpp b/src/core/compositor/chromium_gpu_helper.cpp
index 92a8b13ed..71d0f3687 100644
--- a/src/core/chromium_gpu_helper.cpp
+++ b/src/core/compositor/chromium_gpu_helper.cpp
@@ -43,10 +43,14 @@
#include "chromium_gpu_helper.h"
+// Some headers include the namespace ws, and can not coexist with
+// Qt headers that include QTextStream, which includes most QSG headers
+// via QMatrix4x4.
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+
// Including gpu/command_buffer headers before content/gpu headers makes sure that
// guards are defined to prevent duplicate definition errors with forward declared
// GL typedefs cascading through content header includes.
-#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_base.h"
@@ -62,12 +66,6 @@ scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner()
return content::GpuChildThread::instance()->main_thread_runner();
}
-gpu::SyncPointManager *sync_point_manager()
-{
- gpu::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->gpu_channel_manager();
- return gpuChannelManager->sync_point_manager();
-}
-
gpu::MailboxManager *mailbox_manager()
{
gpu::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->gpu_channel_manager();
@@ -85,6 +83,11 @@ unsigned int service_id(gpu::TextureBase *tex)
return tex->service_id();
}
+void ProgressFlingIfNeeded(content::RenderWidgetHost *host, const base::TimeTicks &current_time)
+{
+ content::RenderWidgetHostImpl::From(host)->ProgressFlingIfNeeded(current_time);
+}
+
#ifdef Q_OS_QNX
EGLStreamData eglstream_connect_consumer(gpu::Texture *tex)
{
diff --git a/src/core/chromium_gpu_helper.h b/src/core/compositor/chromium_gpu_helper.h
index 21b764997..4086d12ab 100644
--- a/src/core/chromium_gpu_helper.h
+++ b/src/core/compositor/chromium_gpu_helper.h
@@ -46,11 +46,15 @@
namespace base {
class SingleThreadTaskRunner;
+class TimeTicks;
+}
+
+namespace content {
+class RenderWidgetHost;
}
namespace gpu {
struct Mailbox;
-class SyncPointManager;
class MailboxManager;
class TextureBase;
}
@@ -61,12 +65,13 @@ class TextureBase;
// functions should only be forward-declared and considered as opaque types.
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner();
-gpu::SyncPointManager *sync_point_manager();
gpu::MailboxManager *mailbox_manager();
gpu::TextureBase* ConsumeTexture(gpu::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox);
unsigned int service_id(gpu::TextureBase *tex);
+void ProgressFlingIfNeeded(content::RenderWidgetHost *host, const base::TimeTicks &current_time);
+
#ifdef Q_OS_QNX
typedef void* EGLDisplay;
typedef void* EGLStreamKHR;
diff --git a/src/core/compositor.cpp b/src/core/compositor/compositor.cpp
index f7a5e651c..56693961c 100644
--- a/src/core/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -39,26 +39,27 @@
#include "compositor.h"
+#include "compositor_resource_tracker.h"
#include "delegated_frame_node.h"
-#include "render_widget_host_view_qt.h"
+#include "base/task/post_task.h"
#include "components/viz/common/resources/returned_resource.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
namespace QtWebEngineCore {
-Compositor::Compositor(RenderWidgetHostViewQt *hostView)
- : m_chromiumCompositorData(new ChromiumCompositorData)
- , m_view(hostView)
+Compositor::Compositor(content::RenderWidgetHost *host)
+ : m_resourceTracker(new CompositorResourceTracker)
+ , m_host(host)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- base::SingleThreadTaskRunner *taskRunner =
- content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI).get();
+ m_taskRunner = base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI, base::TaskPriority::USER_VISIBLE});
m_beginFrameSource =
std::make_unique<viz::DelayBasedBeginFrameSource>(
- std::make_unique<viz::DelayBasedTimeSource>(taskRunner),
+ std::make_unique<viz::DelayBasedTimeSource>(m_taskRunner.get()),
viz::BeginFrameSource::kNotRestartableId);
}
@@ -67,13 +68,6 @@ Compositor::~Compositor()
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}
-void Compositor::setViewDelegate(RenderWidgetHostViewQtDelegate *viewDelegate)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- m_viewDelegate = viewDelegate;
-}
-
void Compositor::setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -85,7 +79,7 @@ void Compositor::setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frame
// should not be returned.
//
// TODO(juvaldma): Can there be a pending frame from the old client?
- m_resourcesToRelease.clear();
+ m_resourceTracker->returnResources();
m_frameSinkClient = frameSinkClient;
}
@@ -104,21 +98,19 @@ void Compositor::setNeedsBeginFrames(bool needsBeginFrames)
m_needsBeginFrames = needsBeginFrames;
}
-void Compositor::submitFrame(viz::CompositorFrame frame)
+void Compositor::submitFrame(viz::CompositorFrame frame, base::OnceClosure callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- DCHECK(!m_havePendingFrame);
+ DCHECK(!m_submitCallback);
- m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor;
- m_chromiumCompositorData->previousFrameData = std::move(m_chromiumCompositorData->frameData);
- m_chromiumCompositorData->frameData = std::move(frame);
- m_havePendingFrame = true;
-
- // Tell viewDelegate to call updatePaintNode() soon.
- m_viewDelegate->update();
+ m_pendingFrame = std::move(frame);
+ m_submitCallback = std::move(callback);
+ m_resourceTracker->submitResources(
+ m_pendingFrame,
+ base::BindOnce(&Compositor::runSubmitCallback, base::Unretained(this)));
}
-QSGNode *Compositor::updatePaintNode(QSGNode *oldNode)
+QSGNode *Compositor::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *viewDelegate)
{
// DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
//
@@ -129,46 +121,59 @@ QSGNode *Compositor::updatePaintNode(QSGNode *oldNode)
if (!frameNode)
frameNode = new DelegatedFrameNode;
- frameNode->commit(m_chromiumCompositorData.data(), &m_resourcesToRelease, m_viewDelegate);
-
- if (m_havePendingFrame) {
- m_havePendingFrame = false;
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Compositor::notifyFrameCommitted, m_weakPtrFactory.GetWeakPtr()));
+ if (!m_updatePaintNodeShouldCommit) {
+ frameNode->commit(m_committedFrame, viz::CompositorFrame(), m_resourceTracker.get(), viewDelegate);
+ return frameNode;
}
- if (m_chromiumCompositorData->frameData.metadata.request_presentation_feedback)
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Compositor::sendPresentationFeedback, m_weakPtrFactory.GetWeakPtr(), m_chromiumCompositorData->frameData.metadata.frame_token));
+ m_updatePaintNodeShouldCommit = false;
+
+ gfx::PresentationFeedback dummyFeedback(base::TimeTicks::Now(), base::TimeDelta(), gfx::PresentationFeedback::Flags::kVSync);
+ m_presentations.insert({m_committedFrame.metadata.frame_token, dummyFeedback});
+
+ m_resourceTracker->commitResources();
+ frameNode->commit(m_pendingFrame, m_committedFrame, m_resourceTracker.get(), viewDelegate);
+ m_committedFrame = std::move(m_pendingFrame);
+ m_pendingFrame = viz::CompositorFrame();
+
+ m_taskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&Compositor::notifyFrameCommitted, m_weakPtrFactory.GetWeakPtr()));
return frameNode;
}
+void Compositor::runSubmitCallback()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ m_updatePaintNodeShouldCommit = true;
+ std::move(m_submitCallback).Run();
+}
+
void Compositor::notifyFrameCommitted()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
m_beginFrameSource->DidFinishFrame(this);
if (m_frameSinkClient)
- m_frameSinkClient->DidReceiveCompositorFrameAck(m_resourcesToRelease);
- m_resourcesToRelease.clear();
+ m_frameSinkClient->DidReceiveCompositorFrameAck(m_resourceTracker->returnResources());
}
void Compositor::sendPresentationFeedback(uint frame_token)
{
gfx::PresentationFeedback dummyFeedback(base::TimeTicks::Now(), base::TimeDelta(), gfx::PresentationFeedback::Flags::kVSync);
- m_frameSinkClient->DidPresentCompositorFrame(frame_token, dummyFeedback);
+ m_presentations.insert({frame_token, dummyFeedback});
}
bool Compositor::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- m_view->OnBeginFrame(args.frame_time);
+ ProgressFlingIfNeeded(m_host, args.frame_time);
m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval);
- if (m_frameSinkClient)
- m_frameSinkClient->OnBeginFrame(args);
+ if (m_frameSinkClient) {
+ m_frameSinkClient->OnBeginFrame(args, m_presentations);
+ m_presentations.clear();
+ }
return true;
}
diff --git a/src/core/compositor.h b/src/core/compositor/compositor.h
index 7d7db5d04..6d88dc054 100644
--- a/src/core/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -40,8 +40,13 @@
#ifndef COMPOSITOR_H
#define COMPOSITOR_H
-#include <base/memory/weak_ptr.h>
-#include <components/viz/common/frame_sinks/begin_frame_source.h>
+#include "base/memory/weak_ptr.h"
+#include "components/viz/common/frame_sinks/begin_frame_source.h"
+#include "components/viz/common/quads/compositor_frame.h"
+#include "ui/gfx/presentation_feedback.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qshareddata.h>
#include <QtCore/qglobal.h>
#include <QtCore/qshareddata.h>
@@ -50,8 +55,10 @@ QT_BEGIN_NAMESPACE
class QSGNode;
QT_END_NAMESPACE
+namespace content {
+class RenderWidgetHost;
+}
namespace viz {
-class CompositorFrame;
struct ReturnedResource;
namespace mojom {
class CompositorFrameSinkClient;
@@ -60,9 +67,8 @@ class CompositorFrameSinkClient;
namespace QtWebEngineCore {
-class RenderWidgetHostViewQt;
+class CompositorResourceTracker;
class RenderWidgetHostViewQtDelegate;
-class ChromiumCompositorData;
// Receives viz::CompositorFrames from child compositors and provides QSGNodes
// to the Qt Quick renderer.
@@ -72,10 +78,10 @@ class ChromiumCompositorData;
// Step 1. A new CompositorFrame is received from child compositors and handed
// off to submitFrame(). The new frame will start off in a pending state.
//
-// Step 2. Once the new frame is ready to be rendered, Compositor will call
-// update() on the delegate.
+// Step 2. Once the new frame is ready to be rendered, Compositor will notify
+// the client by running the callback given to submitFrame().
//
-// Step 3. Once the delegate is ready to render, updatePaintNode() should be
+// Step 3. Once the client is ready to render, updatePaintNode() should be
// called to receive the scene graph for the new frame. This call will commit
// the pending frame. Until the next frame is ready, all subsequent calls to
// updatePaintNode() will keep using this same committed frame.
@@ -85,18 +91,17 @@ class ChromiumCompositorData;
class Compositor final : private viz::BeginFrameObserverBase
{
public:
- explicit Compositor(RenderWidgetHostViewQt *hostView);
+ explicit Compositor(content::RenderWidgetHost *host);
~Compositor() override;
- void setViewDelegate(RenderWidgetHostViewQtDelegate *viewDelegate);
void setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient);
void setNeedsBeginFrames(bool needsBeginFrames);
- void submitFrame(viz::CompositorFrame frame);
-
- QSGNode *updatePaintNode(QSGNode *oldNode);
+ void submitFrame(viz::CompositorFrame frame, base::OnceClosure callback);
+ QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *viewDelegate);
private:
+ void runSubmitCallback();
void notifyFrameCommitted();
void sendPresentationFeedback(uint frame_token);
@@ -104,15 +109,18 @@ private:
bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args) override;
void OnBeginFrameSourcePausedChanged(bool paused) override;
- std::vector<viz::ReturnedResource> m_resourcesToRelease;
- QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
- RenderWidgetHostViewQt *m_view;
- RenderWidgetHostViewQtDelegate *m_viewDelegate = nullptr;
+ viz::CompositorFrame m_committedFrame;
+ viz::CompositorFrame m_pendingFrame;
+ base::OnceClosure m_submitCallback;
+ std::unique_ptr<CompositorResourceTracker> m_resourceTracker;
+ content::RenderWidgetHost *m_host;
std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource;
+ base::flat_map<uint32_t, gfx::PresentationFeedback> m_presentations;
viz::mojom::CompositorFrameSinkClient *m_frameSinkClient = nullptr;
- bool m_havePendingFrame = false;
+ bool m_updatePaintNodeShouldCommit = false;
bool m_needsBeginFrames = false;
+ scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
base::WeakPtrFactory<Compositor> m_weakPtrFactory{this};
DISALLOW_COPY_AND_ASSIGN(Compositor);
diff --git a/src/core/compositor/compositor_resource.h b/src/core/compositor/compositor_resource.h
new file mode 100644
index 000000000..f7df2ab59
--- /dev/null
+++ b/src/core/compositor/compositor_resource.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPOSITOR_RESOURCE_H
+#define COMPOSITOR_RESOURCE_H
+
+#include <base/memory/ref_counted.h>
+#include <components/viz/common/resources/transferable_resource.h>
+
+#include <QtCore/qglobal.h>
+#include <QtGui/qtgui-config.h>
+
+#if QT_CONFIG(opengl)
+# include "compositor_resource_fence.h"
+#endif
+
+namespace viz {
+class SharedBitmap;
+} // namespace viz
+
+namespace QtWebEngineCore {
+
+using CompositorResourceId = quint32;
+
+// A resource (OpenGL texture or software shared bitmap).
+//
+// - Created by the CompositorResourceTracker from a newly submitted
+// CompositorFrame's resource_list.
+//
+// - Until the frame is committed, its resources are in a 'pending' state and
+// are inaccessible from outside the CompositorResourceTracker.
+//
+// - Once the frame is committed, its resources can be found via
+// CompositorResourceTracker::findResource.
+//
+// - A committed resource's fields may not be updated and are safe to use from
+// other threads without synchronization (unless noted otherwise).
+class CompositorResource : public viz::TransferableResource
+{
+public:
+ CompositorResource(const viz::TransferableResource &tr) : viz::TransferableResource(tr) {}
+
+ // Counts the number of times this resource has been encountered in
+ // CompositorFrames' resource lists.
+ //
+ // Corresponds to viz::ReturnedResource::count.
+ //
+ // Updated by CompositorResourceTracker on UI thread.
+ int import_count = 1;
+
+ // Identifies the last frame that needed this resource. Used by
+ // CompositorResourceTracker to return unused resources back to child
+ // compositors.
+ //
+ // Updated by CompositorResourceTracker on UI thread.
+ quint32 last_used_for_frame = 0;
+
+ // Bitmap (if is_software).
+ std::unique_ptr<viz::SharedBitmap> bitmap;
+
+#if QT_CONFIG(opengl)
+ // OpenGL texture id (if !is_software).
+ quint32 texture_id = 0;
+
+ // Should be waited on before using the texture (non-null if !is_software).
+ scoped_refptr<CompositorResourceFence> texture_fence;
+#endif // QT_CONFIG(opengl)
+};
+
+inline bool operator<(const CompositorResource &r1, const CompositorResource &r2)
+{
+ return r1.id < r2.id;
+}
+
+inline bool operator<(const CompositorResource &r, CompositorResourceId id)
+{
+ return r.id < id;
+}
+
+inline bool operator<(CompositorResourceId id, const CompositorResource &r)
+{
+ return id < r.id;
+}
+
+} // namespace QtWebEngineCore
+
+#endif // !COMPOSITOR_RESOURCE_H
diff --git a/src/core/compositor/compositor_resource_fence.cpp b/src/core/compositor/compositor_resource_fence.cpp
new file mode 100644
index 000000000..7fc5fbfb2
--- /dev/null
+++ b/src/core/compositor/compositor_resource_fence.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "compositor_resource_fence.h"
+
+#include "ui/gl/gl_context.h"
+
+#include <QtGui/qopenglcontext.h>
+
+#ifndef GL_TIMEOUT_IGNORED
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
+namespace QtWebEngineCore {
+
+void CompositorResourceFence::wait()
+{
+ if (!m_sync)
+ return;
+
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ Q_ASSERT(context);
+
+ // Chromium uses its own GL bindings and stores in in thread local storage.
+ // For that reason, let chromium_gpu_helper.cpp contain the producing code that will run in the Chromium
+ // GPU thread, and put the sync consuming code here that will run in the QtQuick SG or GUI thread.
+ switch (m_sync.type) {
+ case gl::TransferableFence::NoSync:
+ break;
+ case gl::TransferableFence::EglSync:
+#ifdef EGL_KHR_reusable_sync
+ {
+ static bool resolved = false;
+ static PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR = 0;
+
+ if (!resolved) {
+ if (gl::GLSurfaceQt::HasEGLExtension("EGL_KHR_fence_sync"))
+ eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)context->getProcAddress("eglClientWaitSyncKHR");
+ resolved = true;
+ }
+
+ if (eglClientWaitSyncKHR)
+ // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
+ eglClientWaitSyncKHR(m_sync.egl.display, m_sync.egl.sync, 0, EGL_FOREVER_KHR);
+ }
+#endif
+ break;
+ case gl::TransferableFence::ArbSync:
+ typedef void (QOPENGLF_APIENTRYP WaitSyncPtr)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ static WaitSyncPtr glWaitSync_ = 0;
+ if (!glWaitSync_) {
+ glWaitSync_ = (WaitSyncPtr)context->getProcAddress("glWaitSync");
+ Q_ASSERT(glWaitSync_);
+ }
+ glWaitSync_(m_sync.arb.sync, 0, GL_TIMEOUT_IGNORED);
+ break;
+ }
+
+ release();
+}
+
+void CompositorResourceFence::release()
+{
+ if (!m_sync)
+ return;
+
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ if (!context)
+ return;
+
+ // Chromium uses its own GL bindings and stores in in thread local storage.
+ // For that reason, let chromium_gpu_helper.cpp contain the producing code that will run in the Chromium
+ // GPU thread, and put the sync consuming code here that will run in the QtQuick SG or GUI thread.
+ switch (m_sync.type) {
+ case gl::TransferableFence::NoSync:
+ break;
+ case gl::TransferableFence::EglSync:
+#ifdef EGL_KHR_reusable_sync
+ {
+ static bool resolved = false;
+ static PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = 0;
+
+ if (!resolved) {
+ if (gl::GLSurfaceQt::HasEGLExtension("EGL_KHR_fence_sync"))
+ eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)context->getProcAddress("eglDestroySyncKHR");
+ resolved = true;
+ }
+
+ if (eglDestroySyncKHR) {
+ // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
+ eglDestroySyncKHR(m_sync.egl.display, m_sync.egl.sync);
+ m_sync.reset();
+ }
+ }
+#endif
+ break;
+ case gl::TransferableFence::ArbSync:
+ typedef void (QOPENGLF_APIENTRYP DeleteSyncPtr)(GLsync sync);
+ static DeleteSyncPtr glDeleteSync_ = 0;
+ if (!glDeleteSync_) {
+ glDeleteSync_ = (DeleteSyncPtr)context->getProcAddress("glDeleteSync");
+ Q_ASSERT(glDeleteSync_);
+ }
+ glDeleteSync_(m_sync.arb.sync);
+ m_sync.reset();
+ break;
+ }
+ // If Chromium was able to create a sync, we should have been able to handle its type here too.
+ Q_ASSERT(!m_sync);
+}
+
+// static
+scoped_refptr<CompositorResourceFence> CompositorResourceFence::create()
+{
+ if (gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) {
+ std::unique_ptr<gl::GLFence> glFence{gl::GLFence::Create()};
+ return base::MakeRefCounted<CompositorResourceFence>(glFence->Transfer());
+ }
+ return nullptr;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/compositor_resource_fence.h b/src/core/compositor/compositor_resource_fence.h
new file mode 100644
index 000000000..1c2ea3695
--- /dev/null
+++ b/src/core/compositor/compositor_resource_fence.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPOSITOR_RESOURCE_FENCE_H
+#define COMPOSITOR_RESOURCE_FENCE_H
+
+#include <base/memory/ref_counted.h>
+#include <ui/gl/gl_fence.h>
+
+namespace QtWebEngineCore {
+
+// Sync object created on GPU thread and consumed on render thread.
+class CompositorResourceFence final : public base::RefCountedThreadSafe<CompositorResourceFence>
+{
+public:
+ REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
+
+ CompositorResourceFence() {}
+ CompositorResourceFence(const gl::TransferableFence &sync) : m_sync(sync) {};
+ ~CompositorResourceFence() { release(); }
+
+ // May be used only by Qt Quick render thread.
+ void wait();
+ void release();
+
+ // May be used only by GPU thread.
+ static scoped_refptr<CompositorResourceFence> create();
+
+private:
+ gl::TransferableFence m_sync;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !COMPOSITOR_RESOURCE_FENCE_H
diff --git a/src/core/compositor/compositor_resource_tracker.cpp b/src/core/compositor/compositor_resource_tracker.cpp
new file mode 100644
index 000000000..741c2717c
--- /dev/null
+++ b/src/core/compositor/compositor_resource_tracker.cpp
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "compositor_resource_tracker.h"
+
+#include "chromium_gpu_helper.h"
+#include "render_widget_host_view_qt_delegate.h"
+#include "web_engine_context.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/task/post_task.h"
+#include "components/viz/common/quads/compositor_frame.h"
+#include "components/viz/common/resources/returned_resource.h"
+#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
+#include "content/browser/browser_main_loop.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/gpu/content_gpu_client.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/sync_point_manager.h"
+
+namespace QtWebEngineCore {
+
+CompositorResourceTracker::CompositorResourceTracker()
+{}
+
+CompositorResourceTracker::~CompositorResourceTracker()
+{}
+
+void CompositorResourceTracker::submitResources(const viz::CompositorFrame &frame, base::OnceClosure callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(!m_submitCallback);
+ DCHECK(m_pendingResources.empty());
+ DCHECK(m_pendingImports.empty());
+ DCHECK(m_pendingResourceUpdates == 0);
+
+ m_submitCallback = std::move(callback);
+
+ m_pendingResources.reserve(frame.resource_list.size());
+ m_pendingImports.reserve(frame.resource_list.size());
+
+ for (const viz::TransferableResource &transferableResource : frame.resource_list) {
+ auto it = m_committedResources.find(transferableResource.id);
+ if (it != m_committedResources.end())
+ m_pendingImports.push_back(&*it);
+ else
+ m_pendingResources.emplace_back(transferableResource);
+ }
+
+ if (m_pendingResources.empty()) {
+ scheduleRunSubmitCallback();
+ return;
+ }
+
+ m_pendingResourceUpdates = m_pendingResources.size();
+
+ std::vector<CompositorResource *> batch;
+ batch.reserve(m_pendingResources.size());
+
+ for (CompositorResource &resource : m_pendingResources) {
+ if (resource.is_software)
+ updateBitmap(&resource);
+ else if (!scheduleUpdateMailbox(&resource))
+ batch.push_back(&resource);
+ }
+
+ if (!batch.empty())
+ scheduleUpdateMailboxes(std::move(batch));
+}
+
+void CompositorResourceTracker::commitResources()
+{
+ // DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ //
+ // This might be called from a Qt Quick render thread, but the UI thread
+ // will still be blocked for the duration of this call.
+
+ DCHECK(m_pendingResourceUpdates == 0);
+
+ for (CompositorResource *resource : m_pendingImports)
+ resource->import_count++;
+ m_pendingImports.clear();
+
+ m_committedResources.insert(std::make_move_iterator(m_pendingResources.begin()),
+ std::make_move_iterator(m_pendingResources.end()));
+ m_pendingResources.clear();
+
+ ++m_committedFrameId;
+}
+
+std::vector<viz::ReturnedResource> CompositorResourceTracker::returnResources()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ std::vector<viz::ReturnedResource> returnedResources;
+ base::EraseIf(m_committedResources, [&](const CompositorResource &resource) {
+ if (resource.last_used_for_frame != m_committedFrameId) {
+ viz::ReturnedResource returnedResource;
+ returnedResource.id = resource.id;
+ returnedResource.count = resource.import_count;
+ returnedResources.push_back(std::move(returnedResource));
+ return true;
+ }
+ return false;
+ });
+ return returnedResources;
+}
+
+const CompositorResource *CompositorResourceTracker::findResource(CompositorResourceId id) const
+{
+ auto it = m_committedResources.find(id);
+ DCHECK(it != m_committedResources.end());
+
+ const_cast<CompositorResource &>(*it).last_used_for_frame = m_committedFrameId;
+
+ return &*it;
+}
+
+void CompositorResourceTracker::updateBitmap(CompositorResource *resource)
+{
+ content::BrowserMainLoop *browserMainLoop = content::BrowserMainLoop::GetInstance();
+ viz::ServerSharedBitmapManager *bitmapManager = browserMainLoop->GetServerSharedBitmapManager();
+
+ resource->bitmap = bitmapManager->GetSharedBitmapFromId(
+ resource->size,
+ viz::BGRA_8888,
+ resource->mailbox_holder.mailbox);
+
+ if (--m_pendingResourceUpdates == 0)
+ scheduleRunSubmitCallback();
+}
+
+quint32 CompositorResourceTracker::consumeMailbox(const gpu::MailboxHolder &mailboxHolder)
+{
+#if QT_CONFIG(opengl)
+ gpu::MailboxManager *mailboxManager = mailbox_manager();
+ DCHECK(mailboxManager);
+ if (mailboxHolder.sync_token.HasData())
+ mailboxManager->PullTextureUpdates(mailboxHolder.sync_token);
+ gpu::TextureBase *tex = mailboxManager->ConsumeTexture(mailboxHolder.mailbox);
+ return tex ? service_id(tex) : 0;
+#else
+ NOTREACHED();
+#endif // QT_CONFIG(OPENGL)
+}
+
+bool CompositorResourceTracker::scheduleUpdateMailbox(CompositorResource *resource)
+{
+#if QT_CONFIG(opengl)
+ gpu::SyncPointManager *syncPointManager = WebEngineContext::syncPointManager();
+ DCHECK(syncPointManager);
+ return syncPointManager->WaitOutOfOrder(
+ resource->mailbox_holder.sync_token,
+ base::BindOnce(&CompositorResourceTracker::updateMailbox,
+ m_weakPtrFactory.GetWeakPtr(),
+ resource));
+#else
+ NOTREACHED();
+#endif // QT_CONFIG(OPENGL)
+}
+
+void CompositorResourceTracker::updateMailbox(CompositorResource *resource)
+{
+#if QT_CONFIG(opengl)
+ resource->texture_id = consumeMailbox(resource->mailbox_holder);
+ resource->texture_fence = CompositorResourceFence::create();
+
+ if (--m_pendingResourceUpdates == 0)
+ scheduleRunSubmitCallback();
+#else
+ NOTREACHED();
+#endif // QT_CONFIG(OPENGL)
+}
+
+void CompositorResourceTracker::scheduleUpdateMailboxes(std::vector<CompositorResource *> resources)
+{
+#if QT_CONFIG(opengl)
+ scoped_refptr<base::SingleThreadTaskRunner> gpuTaskRunner = gpu_task_runner();
+ DCHECK(gpuTaskRunner);
+ thread_local bool currentThreadIsGpu = gpuTaskRunner->BelongsToCurrentThread();
+ if (currentThreadIsGpu)
+ return updateMailboxes(std::move(resources));
+ gpuTaskRunner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CompositorResourceTracker::updateMailboxes,
+ m_weakPtrFactory.GetWeakPtr(),
+ std::move(resources)));
+#else
+ NOTREACHED();
+#endif // QT_CONFIG(OPENGL)
+}
+
+void CompositorResourceTracker::updateMailboxes(std::vector<CompositorResource *> resources)
+{
+#if QT_CONFIG(opengl)
+ for (CompositorResource *resource : resources)
+ resource->texture_id = consumeMailbox(resource->mailbox_holder);
+
+ scoped_refptr<CompositorResourceFence> fence = CompositorResourceFence::create();
+
+ for (CompositorResource *resource : resources)
+ resource->texture_fence = fence;
+
+ if ((m_pendingResourceUpdates -= resources.size()) == 0)
+ scheduleRunSubmitCallback();
+#else
+ NOTREACHED();
+#endif // QT_CONFIG(OPENGL)
+}
+
+void CompositorResourceTracker::scheduleRunSubmitCallback()
+{
+ thread_local bool currentThreadIsUi = content::BrowserThread::CurrentlyOn(content::BrowserThread::UI);
+ if (currentThreadIsUi)
+ return runSubmitCallback();
+ base::PostTaskWithTraits(
+ FROM_HERE, { content::BrowserThread::UI, base::TaskPriority::USER_VISIBLE },
+ base::BindOnce(&CompositorResourceTracker::runSubmitCallback,
+ m_weakPtrFactory.GetWeakPtr()));
+}
+
+void CompositorResourceTracker::runSubmitCallback()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ std::move(m_submitCallback).Run();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/compositor_resource_tracker.h b/src/core/compositor/compositor_resource_tracker.h
new file mode 100644
index 000000000..887309395
--- /dev/null
+++ b/src/core/compositor/compositor_resource_tracker.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPOSITOR_RESOURCE_TRACKER_H
+#define COMPOSITOR_RESOURCE_TRACKER_H
+
+#include "compositor_resource.h"
+#include "locked_ptr.h"
+
+#include <base/callback.h>
+#include <base/containers/flat_set.h>
+
+#include <atomic>
+#include <vector>
+
+namespace viz {
+class CompositorFrame;
+struct ReturnedResource;
+} // namespace viz
+
+namespace gpu {
+struct MailboxHolder;
+} // namespace gpu
+
+namespace QtWebEngineCore {
+
+// Ensures resources are not used before they are ready.
+//
+// The life cycle of a frame's resources:
+//
+// Step 1. A new CompositorFrame is received and given to submitResources().
+// The frame's resources will extracted and initialized to a pending state.
+//
+// Step 2. Once the new resources are ready to be committed,
+// CompositorResourceTracker will notify the client by running the callback
+// given to submitResources().
+//
+// Step 3. Once the client is ready to render, commitResources() should be
+// called. This will commit all the pending resources, making them available
+// via findResource().
+//
+// Step 4. Once all the resources have been used (via findResource()),
+// returnResources() may be called to return a list of all the resources which
+// were *not* used since the last commitResources(). Go to step 1.
+class CompositorResourceTracker final
+{
+public:
+ CompositorResourceTracker();
+ ~CompositorResourceTracker();
+
+ void submitResources(const viz::CompositorFrame &frame, base::OnceClosure callback);
+ void commitResources();
+ std::vector<viz::ReturnedResource> returnResources();
+
+ // The returned pointer is invalidated by the next call to commitFrame() or
+ // returnResources(). It should therefore not be stored in data structures
+ // but used immediately.
+ //
+ // Do not ask for resources which do not exist.
+ const CompositorResource *findResource(CompositorResourceId id) const;
+
+private:
+ void updateBitmap(CompositorResource *resource);
+
+ quint32 consumeMailbox(const gpu::MailboxHolder &mailboxHolder);
+
+ bool scheduleUpdateMailbox(CompositorResource *resource);
+ void updateMailbox(CompositorResource *resource);
+
+ void scheduleUpdateMailboxes(std::vector<CompositorResource *> resources);
+ void updateMailboxes(std::vector<CompositorResource *> resources);
+
+ void scheduleRunSubmitCallback();
+ void runSubmitCallback();
+
+ base::flat_set<CompositorResource> m_committedResources;
+ std::vector<CompositorResource> m_pendingResources;
+ std::vector<CompositorResource *> m_pendingImports;
+ base::OnceClosure m_submitCallback;
+ std::atomic<size_t> m_pendingResourceUpdates{0};
+ quint32 m_committedFrameId = 0;
+
+ base::LockedPtrFactory<CompositorResourceTracker> m_weakPtrFactory{this};
+
+ DISALLOW_COPY_AND_ASSIGN(CompositorResourceTracker);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !COMPOSITOR_RESOURCE_TRACKER_H
diff --git a/src/core/compositor/content_gpu_client_qt.cpp b/src/core/compositor/content_gpu_client_qt.cpp
new file mode 100644
index 000000000..f934979a0
--- /dev/null
+++ b/src/core/compositor/content_gpu_client_qt.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "content_gpu_client_qt.h"
+
+#include "web_engine_context.h"
+
+namespace QtWebEngineCore {
+
+ContentGpuClientQt::ContentGpuClientQt()
+{
+}
+
+ContentGpuClientQt::~ContentGpuClientQt()
+{
+}
+
+gpu::SyncPointManager *ContentGpuClientQt::GetSyncPointManager()
+{
+ return WebEngineContext::syncPointManager();
+}
+
+} // namespace
diff --git a/src/core/compositor/content_gpu_client_qt.h b/src/core/compositor/content_gpu_client_qt.h
new file mode 100644
index 000000000..d7ad43881
--- /dev/null
+++ b/src/core/compositor/content_gpu_client_qt.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CONTENT_GPU_CLIENT_QT_H
+#define CONTENT_GPU_CLIENT_QT_H
+
+#include "content/public/gpu/content_gpu_client.h"
+
+namespace QtWebEngineCore {
+
+class ContentGpuClientQt : public content::ContentGpuClient {
+public:
+ explicit ContentGpuClientQt();
+ ~ContentGpuClientQt() override;
+
+ // content::ContentGpuClient implementation.
+ gpu::SyncPointManager *GetSyncPointManager() override;
+};
+
+}
+
+#endif // CONTENT_GPU_CLIENT_QT_H
diff --git a/src/core/delegated_frame_node.cpp b/src/core/compositor/delegated_frame_node.cpp
index 8ac82dbf1..5f474cbfb 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/compositor/delegated_frame_node.cpp
@@ -49,17 +49,14 @@
#include "delegated_frame_node.h"
#include "chromium_gpu_helper.h"
-#include "ozone/gl_surface_qt.h"
#include "stream_video_node.h"
#include "type_conversion.h"
#include "yuv_video_node.h"
+#include "compositor_resource_tracker.h"
#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
#include "cc/base/math_util.h"
#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "components/viz/common/quads/debug_border_draw_quad.h"
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/common/quads/render_pass_draw_quad.h"
@@ -68,14 +65,8 @@
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
-#include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/service/display/bsp_tree.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
-#include "content/browser/browser_main_loop.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_fence.h"
#ifndef QT_NO_OPENGL
# include <QOpenGLContext>
@@ -93,10 +84,6 @@
#include <EGL/eglext.h>
#endif
-#ifndef GL_TIMEOUT_IGNORED
-#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
-#endif
-
#ifndef GL_TEXTURE_RECTANGLE
#define GL_TEXTURE_RECTANGLE 0x84F5
#endif
@@ -131,7 +118,7 @@ namespace QtWebEngineCore {
#ifndef QT_NO_OPENGL
class MailboxTexture : public QSGTexture, protected QOpenGLFunctions {
public:
- MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QSize textureSize);
+ MailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target = -1);
~MailboxTexture();
// QSGTexture:
int textureId() const override { return m_textureId; }
@@ -140,14 +127,9 @@ public:
bool hasMipmaps() const override { return false; }
void bind() override;
- void setHasAlphaChannel(bool hasAlpha) { m_hasAlpha = hasAlpha; }
- gpu::MailboxHolder &mailboxHolder() { return m_mailboxHolder; }
- void fetchTexture(gpu::MailboxManager *mailboxManager);
- void setTarget(GLenum target);
-
private:
- gpu::MailboxHolder m_mailboxHolder;
int m_textureId;
+ scoped_refptr<CompositorResourceFence> m_fence;
QSize m_textureSize;
bool m_hasAlpha;
GLenum m_target;
@@ -160,20 +142,6 @@ private:
friend class DelegatedFrameNode;
};
#endif // QT_NO_OPENGL
-class ResourceHolder {
-public:
- ResourceHolder(const viz::TransferableResource &resource);
- QSharedPointer<QSGTexture> initTexture(bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
- QSGTexture *texture() const { return m_texture.data(); }
- viz::ReturnedResource returnResource();
- void incImportCount() { ++m_importCount; }
- bool needsToFetch() const { return !m_resource.is_software && m_texture && !m_texture.data()->textureId(); }
-
-private:
- QWeakPointer<QSGTexture> m_texture;
- viz::TransferableResource m_resource;
- int m_importCount;
-};
class RectClipNode : public QSGClipNode
{
@@ -443,7 +411,9 @@ static QSGNode *buildLayerChain(QSGNode *chainParent, const viz::SharedQuadState
}
if (!layerState->quad_to_target_transform.IsIdentity()) {
QSGTransformNode *transformNode = new QSGTransformNode;
- transformNode->setMatrix(toQt(layerState->quad_to_target_transform.matrix()));
+ QMatrix4x4 qMatrix;
+ convertToQt(layerState->quad_to_target_transform.matrix(), qMatrix);
+ transformNode->setMatrix(qMatrix);
layerChain->appendChildNode(transformNode);
layerChain = transformNode;
}
@@ -457,99 +427,12 @@ static QSGNode *buildLayerChain(QSGNode *chainParent, const viz::SharedQuadState
}
#ifndef QT_NO_OPENGL
-static void waitChromiumSync(gl::TransferableFence *sync)
-{
- // Chromium uses its own GL bindings and stores in in thread local storage.
- // For that reason, let chromium_gpu_helper.cpp contain the producing code that will run in the Chromium
- // GPU thread, and put the sync consuming code here that will run in the QtQuick SG or GUI thread.
- switch (sync->type) {
- case gl::TransferableFence::NoSync:
- break;
- case gl::TransferableFence::EglSync:
-#ifdef EGL_KHR_reusable_sync
- {
- static bool resolved = false;
- static PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR = 0;
-
- if (!resolved) {
- if (gl::GLSurfaceQt::HasEGLExtension("EGL_KHR_fence_sync")) {
- QOpenGLContext *context = QOpenGLContext::currentContext();
- eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)context->getProcAddress("eglClientWaitSyncKHR");
- }
- resolved = true;
- }
-
- if (eglClientWaitSyncKHR)
- // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
- eglClientWaitSyncKHR(sync->egl.display, sync->egl.sync, 0, EGL_FOREVER_KHR);
- }
-#endif
- break;
- case gl::TransferableFence::ArbSync:
- typedef void (QOPENGLF_APIENTRYP WaitSyncPtr)(GLsync sync, GLbitfield flags, GLuint64 timeout);
- static WaitSyncPtr glWaitSync_ = 0;
- if (!glWaitSync_) {
- QOpenGLContext *context = QOpenGLContext::currentContext();
- glWaitSync_ = (WaitSyncPtr)context->getProcAddress("glWaitSync");
- Q_ASSERT(glWaitSync_);
- }
- glWaitSync_(sync->arb.sync, 0, GL_TIMEOUT_IGNORED);
- break;
- }
-}
-
-static void deleteChromiumSync(gl::TransferableFence *sync)
-{
- // Chromium uses its own GL bindings and stores in in thread local storage.
- // For that reason, let chromium_gpu_helper.cpp contain the producing code that will run in the Chromium
- // GPU thread, and put the sync consuming code here that will run in the QtQuick SG or GUI thread.
- switch (sync->type) {
- case gl::TransferableFence::NoSync:
- break;
- case gl::TransferableFence::EglSync:
-#ifdef EGL_KHR_reusable_sync
- {
- static bool resolved = false;
- static PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = 0;
-
- if (!resolved) {
- if (gl::GLSurfaceQt::HasEGLExtension("EGL_KHR_fence_sync")) {
- QOpenGLContext *context = QOpenGLContext::currentContext();
- eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)context->getProcAddress("eglDestroySyncKHR");
- }
- resolved = true;
- }
-
- if (eglDestroySyncKHR) {
- // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
- eglDestroySyncKHR(sync->egl.display, sync->egl.sync);
- sync->reset();
- }
- }
-#endif
- break;
- case gl::TransferableFence::ArbSync:
- typedef void (QOPENGLF_APIENTRYP DeleteSyncPtr)(GLsync sync);
- static DeleteSyncPtr glDeleteSync_ = 0;
- if (!glDeleteSync_) {
- QOpenGLContext *context = QOpenGLContext::currentContext();
- glDeleteSync_ = (DeleteSyncPtr)context->getProcAddress("glDeleteSync");
- Q_ASSERT(glDeleteSync_);
- }
- glDeleteSync_(sync->arb.sync);
- sync->reset();
- break;
- }
- // If Chromium was able to create a sync, we should have been able to handle its type here too.
- Q_ASSERT(!*sync);
-}
-
-MailboxTexture::MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QSize textureSize)
- : m_mailboxHolder(mailboxHolder)
- , m_textureId(0)
- , m_textureSize(textureSize)
- , m_hasAlpha(false)
- , m_target(GL_TEXTURE_2D)
+MailboxTexture::MailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target)
+ : m_textureId(resource->texture_id)
+ , m_fence(resource->texture_fence)
+ , m_textureSize(toQt(resource->size))
+ , m_hasAlpha(hasAlphaChannel)
+ , m_target(target >= 0 ? target : GL_TEXTURE_2D)
#if defined(USE_OZONE)
, m_ownsTexture(false)
#endif
@@ -580,6 +463,8 @@ MailboxTexture::~MailboxTexture()
void MailboxTexture::bind()
{
+ if (m_fence)
+ m_fence->wait();
glBindTexture(m_target, m_textureId);
#ifdef Q_OS_QNX
if (m_target == GL_TEXTURE_EXTERNAL_OES) {
@@ -596,96 +481,7 @@ void MailboxTexture::bind()
}
#endif
}
-
-void MailboxTexture::setTarget(GLenum target)
-{
- m_target = target;
-}
-
-void MailboxTexture::fetchTexture(gpu::MailboxManager *mailboxManager)
-{
- gpu::TextureBase *tex = ConsumeTexture(mailboxManager, m_target, m_mailboxHolder.mailbox);
-
- // The texture might already have been deleted (e.g. when navigating away from a page).
- if (tex) {
- m_textureId = service_id(tex);
-#ifdef Q_OS_QNX
- if (m_target == GL_TEXTURE_EXTERNAL_OES) {
- m_eglStreamData = eglstream_connect_consumer(tex);
- }
-#endif
- }
-}
-#endif //QT_NO_OPENGL
-
-ResourceHolder::ResourceHolder(const viz::TransferableResource &resource)
- : m_resource(resource)
- , m_importCount(1)
-{
-}
-
-QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, RenderWidgetHostViewQtDelegate *apiDelegate)
-{
- QSharedPointer<QSGTexture> texture = m_texture.toStrongRef();
- if (!texture) {
- if (m_resource.is_software) {
- Q_ASSERT(apiDelegate);
- std::unique_ptr<viz::SharedBitmap> sharedBitmap =
- content::BrowserMainLoop::GetInstance()->GetServerSharedBitmapManager()->GetSharedBitmapFromId(
- m_resource.size, viz::BGRA_8888, m_resource.mailbox_holder.mailbox);
- // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending
- // to draw it but Chromium keeps this information in the quads.
- // The input format is currently always Format_ARGB32_Premultiplied, so assume that all
- // alpha bytes are 0xff if quads aren't requesting blending and avoid the conversion
- // from Format_ARGB32_Premultiplied to Format_RGB32 just to get hasAlphaChannel to
- // return false.
- QImage::Format format = quadNeedsBlending ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- QImage image = sharedBitmap
- ? QImage(sharedBitmap->pixels(), m_resource.size.width(), m_resource.size.height(), format)
- : QImage(m_resource.size.width(), m_resource.size.height(), format);
- texture.reset(apiDelegate->createTextureFromImage(image.copy()));
- } else {
-#ifndef QT_NO_OPENGL
- texture.reset(new MailboxTexture(m_resource.mailbox_holder, toQt(m_resource.size)));
- static_cast<MailboxTexture *>(texture.data())->setHasAlphaChannel(quadNeedsBlending);
-#else
- Q_UNREACHABLE();
-#endif
- }
- if (m_resource.filter == GL_NEAREST)
- texture->setFiltering(QSGTexture::Nearest);
- else if (m_resource.filter == GL_LINEAR)
- texture->setFiltering(QSGTexture::Linear);
- else {
- // Depends on qtdeclarative fix, see QTBUG-71322
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1)
- texture->setFiltering(QSGTexture::Linear);
-#else
- texture->setFiltering(QSGTexture::Nearest);
-#endif
- }
- m_texture = texture;
- }
- // All quads using a resource should request the same blending state.
- Q_ASSERT(texture->hasAlphaChannel() || !quadNeedsBlending);
- return texture;
-}
-
-viz::ReturnedResource ResourceHolder::returnResource()
-{
- viz::ReturnedResource returned;
- // The ResourceProvider ensures that the resource isn't used by the parent compositor's GL
- // context in the GPU process by inserting a sync point to be waited for by the child
- // compositor's GL context. We don't need this since we are triggering the delegated frame
- // ack directly from our rendering thread. At this point (in updatePaintNode) we know that
- // a frame that was compositing any of those resources has already been swapped and we thus
- // don't need to use this mechanism.
- returned.id = m_resource.id;
- returned.count = m_importCount;
- m_importCount = 0;
- return returned;
-}
-
+#endif // !QT_NO_OPENGL
RectClipNode::RectClipNode(const QRectF &rect)
: m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
@@ -697,9 +493,8 @@ RectClipNode::RectClipNode(const QRectF &rect)
}
DelegatedFrameNode::DelegatedFrameNode()
- : m_numPendingSyncPoints(0)
#if defined(USE_OZONE) && !defined(QT_NO_OPENGL)
- , m_contextShared(true)
+ : m_contextShared(true)
#endif
{
setFlag(UsePreprocess);
@@ -725,22 +520,6 @@ DelegatedFrameNode::~DelegatedFrameNode()
void DelegatedFrameNode::preprocess()
{
-#ifndef QT_NO_OPENGL
- // With the threaded render loop the GUI thread has been unlocked at this point.
- // We can now wait for the Chromium GPU thread to produce textures that will be
- // rendered on our quads and fetch the IDs from the mailboxes we were given.
- QList<MailboxTexture *> mailboxesToFetch;
- typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator ResourceHolderIterator;
- ResourceHolderIterator end = m_chromiumCompositorData->resourceHolders.constEnd();
- for (ResourceHolderIterator it = m_chromiumCompositorData->resourceHolders.constBegin(); it != end ; ++it) {
- if ((*it)->needsToFetch())
- mailboxesToFetch.append(static_cast<MailboxTexture *>((*it)->texture()));
- }
-
- if (!mailboxesToFetch.isEmpty())
- fetchAndSyncMailboxes(mailboxesToFetch);
-#endif
-
// Then render any intermediate RenderPass in order.
typedef QPair<int, QSharedPointer<QSGLayer> > Pair;
for (const Pair &pair : qAsConst(m_sgObjects.renderPassLayers)) {
@@ -767,8 +546,8 @@ static bool areSharedQuadStatesEqual(const viz::SharedQuadState *layerState,
// Compares if the frame data that we got from the Chromium Compositor is
// *structurally* equivalent to the one of the previous frame.
// If it is, we will just reuse and update the old nodes where necessary.
-static bool areRenderPassStructuresEqual(viz::CompositorFrame *frameData,
- viz::CompositorFrame *previousFrameData)
+static bool areRenderPassStructuresEqual(const viz::CompositorFrame *frameData,
+ const viz::CompositorFrame *previousFrameData)
{
if (!previousFrameData)
return false;
@@ -820,12 +599,12 @@ static bool areRenderPassStructuresEqual(viz::CompositorFrame *frameData,
return true;
}
-void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
- std::vector<viz::ReturnedResource> *resourcesToRelease,
+void DelegatedFrameNode::commit(const viz::CompositorFrame &pendingFrame,
+ const viz::CompositorFrame &committedFrame,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate)
{
- m_chromiumCompositorData = chromiumCompositorData;
- viz::CompositorFrame* frameData = &m_chromiumCompositorData->frameData;
+ const viz::CompositorFrame* frameData = &pendingFrame;
if (frameData->render_pass_list.empty())
return;
@@ -833,30 +612,14 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
// countering the scale of devicePixel-scaled tiles when rendering them
// to the final surface.
QMatrix4x4 matrix;
- const float devicePixelRatio = m_chromiumCompositorData->frameDevicePixelRatio;
+ const float devicePixelRatio = frameData->metadata.device_scale_factor;
matrix.scale(1 / devicePixelRatio, 1 / devicePixelRatio);
if (QSGTransformNode::matrix() != matrix)
setMatrix(matrix);
- QHash<unsigned, QSharedPointer<ResourceHolder> > resourceCandidates;
- qSwap(m_chromiumCompositorData->resourceHolders, resourceCandidates);
-
- // A frame's resource_list only contains the new resources to be added to the scene. Quads can
- // still reference resources that were added in previous frames. Add them to the list of
- // candidates to be picked up by quads, it's then our responsibility to return unused resources
- // to the producing child compositor.
- for (unsigned i = 0; i < frameData->resource_list.size(); ++i) {
- const viz::TransferableResource &res = frameData->resource_list.at(i);
- if (QSharedPointer<ResourceHolder> resource = resourceCandidates.value(res.id))
- resource->incImportCount();
- else
- resourceCandidates[res.id] = QSharedPointer<ResourceHolder>(new ResourceHolder(res));
- }
-
- frameData->resource_list.clear();
QScopedPointer<DelegatedNodeTreeHandler> nodeHandler;
- const QSizeF viewportSizeInPt = apiDelegate->screenRect().size();
+ const QSizeF viewportSizeInPt = apiDelegate->viewGeometry().size();
const QSizeF viewportSizeF = viewportSizeInPt * devicePixelRatio;
const QSize viewportSize(std::ceil(viewportSizeF.width()), std::ceil(viewportSizeF.height()));
@@ -867,26 +630,22 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
// Additionally, because we clip (i.e. don't build scene graph nodes for) quads outside
// of the visible area, we also have to rebuild the tree whenever the window is resized.
const bool buildNewTree =
- !areRenderPassStructuresEqual(frameData, &m_chromiumCompositorData->previousFrameData) ||
+ !areRenderPassStructuresEqual(frameData, &committedFrame) ||
m_sceneGraphNodes.empty() ||
viewportSize != m_previousViewportSize;
- m_chromiumCompositorData->previousFrameData = viz::CompositorFrame();
- SGObjects previousSGObjects;
- QVector<QSharedPointer<QSGTexture> > textureStrongRefs;
if (buildNewTree) {
// Keep the old objects in scope to hold a ref on layers, resources and textures
// that we can re-use. Destroy the remaining objects before returning.
- qSwap(m_sgObjects, previousSGObjects);
+ qSwap(m_sgObjects, m_previousSGObjects);
// Discard the scene graph nodes from the previous frame.
while (QSGNode *oldChain = firstChild())
delete oldChain;
m_sceneGraphNodes.clear();
nodeHandler.reset(new DelegatedNodeTreeCreator(&m_sceneGraphNodes, apiDelegate));
} else {
- // Save the texture strong refs so they only go out of scope when the method returns and
- // the new vector of texture strong refs has been filled.
- qSwap(m_sgObjects.textureStrongRefs, textureStrongRefs);
+ qSwap(m_sgObjects.bitmapTextures, m_previousSGObjects.bitmapTextures);
+ qSwap(m_sgObjects.mailboxTextures, m_previousSGObjects.mailboxTextures);
nodeHandler.reset(new DelegatedNodeTreeUpdater(&m_sceneGraphNodes));
}
// The RenderPasses list is actually a tree where a parent RenderPass is connected
@@ -906,7 +665,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
if (pass != rootRenderPass) {
QSharedPointer<QSGLayer> rpLayer;
if (buildNewTree) {
- rpLayer = findRenderPassLayer(pass->id, previousSGObjects.renderPassLayers);
+ rpLayer = findRenderPassLayer(pass->id, m_previousSGObjects.renderPassLayers);
if (!rpLayer) {
rpLayer = QSharedPointer<QSGLayer>(apiDelegate->createLayer());
// Avoid any premature texture update since we need to wait
@@ -935,7 +694,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
}
if (scissorRect.IsEmpty()) {
- holdResources(pass, resourceCandidates);
+ holdResources(pass, resourceTracker);
continue;
}
@@ -961,13 +720,13 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
targetRect.Intersect(quadState->clip_rect);
targetRect.Intersect(scissorRect);
if (targetRect.IsEmpty()) {
- holdResources(quad, resourceCandidates);
+ holdResources(quad, resourceTracker);
continue;
}
if (quadState->sorting_context_id != currentSortingContextId) {
flushPolygons(&polygonQueue, renderPassChain,
- nodeHandler.data(), resourceCandidates, apiDelegate);
+ nodeHandler.data(), resourceTracker, apiDelegate);
currentSortingContextId = quadState->sorting_context_id;
}
@@ -989,28 +748,23 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
}
handleQuad(quad, currentLayerChain,
- nodeHandler.data(), resourceCandidates, apiDelegate);
+ nodeHandler.data(), resourceTracker, apiDelegate);
}
flushPolygons(&polygonQueue, renderPassChain,
- nodeHandler.data(), resourceCandidates, apiDelegate);
+ nodeHandler.data(), resourceTracker, apiDelegate);
}
- // Send resources of remaining candidates back to the child compositors so that
- // they can be freed or reused.
- typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator
- ResourceHolderIterator;
- ResourceHolderIterator end = resourceCandidates.constEnd();
- for (ResourceHolderIterator it = resourceCandidates.constBegin(); it != end ; ++it)
- resourcesToRelease->push_back((*it)->returnResource());
+ copyMailboxTextures();
m_previousViewportSize = viewportSize;
+ m_previousSGObjects = SGObjects();
}
void DelegatedFrameNode::flushPolygons(
base::circular_deque<std::unique_ptr<viz::DrawPolygon>> *polygonQueue,
QSGNode *renderPassChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate)
{
if (polygonQueue->empty())
@@ -1030,7 +784,7 @@ void DelegatedFrameNode::flushPolygons(
polygon->TransformToLayerSpace(inverseTransform);
handlePolygon(polygon, currentLayerChain,
- nodeHandler, resourceCandidates, apiDelegate);
+ nodeHandler, resourceTracker, apiDelegate);
};
viz::BspTree(polygonQueue).TraverseWithActionHandler(&actionHandler);
@@ -1040,20 +794,20 @@ void DelegatedFrameNode::handlePolygon(
const viz::DrawPolygon *polygon,
QSGNode *currentLayerChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate)
{
const viz::DrawQuad *quad = polygon->original_ref();
if (!polygon->is_split()) {
handleQuad(quad, currentLayerChain,
- nodeHandler, resourceCandidates, apiDelegate);
+ nodeHandler, resourceTracker, apiDelegate);
} else {
std::vector<gfx::QuadF> clipRegionList;
polygon->ToQuads2D(&clipRegionList);
for (const auto & clipRegion : clipRegionList)
handleClippedQuad(quad, clipRegion, currentLayerChain,
- nodeHandler, resourceCandidates, apiDelegate);
+ nodeHandler, resourceTracker, apiDelegate);
}
}
@@ -1062,7 +816,7 @@ void DelegatedFrameNode::handleClippedQuad(
const gfx::QuadF &clipRegion,
QSGNode *currentLayerChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate)
{
if (currentLayerChain) {
@@ -1080,21 +834,21 @@ void DelegatedFrameNode::handleClippedQuad(
currentLayerChain = clipNode;
}
handleQuad(quad, currentLayerChain,
- nodeHandler, resourceCandidates, apiDelegate);
+ nodeHandler, resourceTracker, apiDelegate);
}
void DelegatedFrameNode::handleQuad(
const viz::DrawQuad *quad,
QSGNode *currentLayerChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate)
{
switch (quad->material) {
case viz::DrawQuad::RENDER_PASS: {
const viz::RenderPassDrawQuad *renderPassQuad = viz::RenderPassDrawQuad::MaterialCast(quad);
if (!renderPassQuad->mask_texture_size.IsEmpty()) {
- ResourceHolder *resource = findAndHoldResource(renderPassQuad->mask_resource_id(), resourceCandidates);
+ const CompositorResource *resource = findAndHoldResource(renderPassQuad->mask_resource_id(), resourceTracker);
Q_UNUSED(resource); // FIXME: QTBUG-67652
}
QSGLayer *layer =
@@ -1107,7 +861,7 @@ void DelegatedFrameNode::handleQuad(
}
case viz::DrawQuad::TEXTURE_CONTENT: {
const viz::TextureDrawQuad *tquad = viz::TextureDrawQuad::MaterialCast(quad);
- ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), resourceCandidates);
+ const CompositorResource *resource = findAndHoldResource(tquad->resource_id(), resourceTracker);
QSGTexture *texture =
initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate);
QSizeF textureSize;
@@ -1158,7 +912,7 @@ void DelegatedFrameNode::handleQuad(
}
case viz::DrawQuad::TILED_CONTENT: {
const viz::TileDrawQuad *tquad = viz::TileDrawQuad::MaterialCast(quad);
- ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), resourceCandidates);
+ const CompositorResource *resource = findAndHoldResource(tquad->resource_id(), resourceTracker);
nodeHandler->setupTextureContentNode(
initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate),
toQt(quad->rect), toQt(tquad->tex_coord_rect),
@@ -1168,17 +922,17 @@ void DelegatedFrameNode::handleQuad(
}
case viz::DrawQuad::YUV_VIDEO_CONTENT: {
const viz::YUVVideoDrawQuad *vquad = viz::YUVVideoDrawQuad::MaterialCast(quad);
- ResourceHolder *yResource =
- findAndHoldResource(vquad->y_plane_resource_id(), resourceCandidates);
- ResourceHolder *uResource =
- findAndHoldResource(vquad->u_plane_resource_id(), resourceCandidates);
- ResourceHolder *vResource =
- findAndHoldResource(vquad->v_plane_resource_id(), resourceCandidates);
- ResourceHolder *aResource = 0;
+ const CompositorResource *yResource =
+ findAndHoldResource(vquad->y_plane_resource_id(), resourceTracker);
+ const CompositorResource *uResource =
+ findAndHoldResource(vquad->u_plane_resource_id(), resourceTracker);
+ const CompositorResource *vResource =
+ findAndHoldResource(vquad->v_plane_resource_id(), resourceTracker);
+ const CompositorResource *aResource = nullptr;
// This currently requires --enable-vp8-alpha-playback and
// needs a video with alpha data to be triggered.
if (vquad->a_plane_resource_id())
- aResource = findAndHoldResource(vquad->a_plane_resource_id(), resourceCandidates);
+ aResource = findAndHoldResource(vquad->a_plane_resource_id(), resourceTracker);
nodeHandler->setupYUVVideoNode(
initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()),
@@ -1194,14 +948,13 @@ void DelegatedFrameNode::handleQuad(
}
case viz::DrawQuad::STREAM_VIDEO_CONTENT: {
const viz::StreamVideoDrawQuad *squad = viz::StreamVideoDrawQuad::MaterialCast(quad);
- ResourceHolder *resource = findAndHoldResource(squad->resource_id(), resourceCandidates);
+ const CompositorResource *resource = findAndHoldResource(squad->resource_id(), resourceTracker);
MailboxTexture *texture = static_cast<MailboxTexture *>(
- initAndHoldTexture(resource, quad->ShouldDrawWithBlending()));
- // since this is not default TEXTURE_2D type
- texture->setTarget(GL_TEXTURE_EXTERNAL_OES);
+ initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate, GL_TEXTURE_EXTERNAL_OES));
- nodeHandler->setupStreamVideoNode(texture, toQt(squad->rect), toQt(squad->matrix.matrix()),
- currentLayerChain);
+ QMatrix4x4 qMatrix;
+ convertToQt(squad->matrix.matrix(), qMatrix);
+ nodeHandler->setupStreamVideoNode(texture, toQt(squad->rect), qMatrix, currentLayerChain);
break;
#endif // GL_OES_EGL_image_external
#endif // QT_NO_OPENGL
@@ -1213,75 +966,105 @@ void DelegatedFrameNode::handleQuad(
}
}
-ResourceHolder *DelegatedFrameNode::findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates)
+const CompositorResource *DelegatedFrameNode::findAndHoldResource(unsigned resourceId, const CompositorResourceTracker *resourceTracker)
{
- // ResourceHolders must survive when the scene graph destroys our node branch
- QSharedPointer<ResourceHolder> &resource = m_chromiumCompositorData->resourceHolders[resourceId];
- if (!resource)
- resource = candidates.take(resourceId);
- Q_ASSERT(resource);
- return resource.data();
+ return resourceTracker->findResource(resourceId);
}
-void DelegatedFrameNode::holdResources(const viz::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates)
+void DelegatedFrameNode::holdResources(const viz::DrawQuad *quad, const CompositorResourceTracker *resourceTracker)
{
for (auto resource : quad->resources)
- findAndHoldResource(resource, candidates);
+ findAndHoldResource(resource, resourceTracker);
}
-void DelegatedFrameNode::holdResources(const viz::RenderPass *pass, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates)
+void DelegatedFrameNode::holdResources(const viz::RenderPass *pass, const CompositorResourceTracker *resourceTracker)
{
for (const auto &quad : pass->quad_list)
- holdResources(quad, candidates);
+ holdResources(quad, resourceTracker);
}
-QSGTexture *DelegatedFrameNode::initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate)
+template<class Container, class Key>
+inline auto &findTexture(Container &map, Container &previousMap, const Key &key)
{
- // QSGTextures must be destroyed in the scene graph thread as part of the QSGNode tree,
- // so we can't store them with the ResourceHolder in m_chromiumCompositorData.
- // Hold them through a QSharedPointer solely on the root DelegatedFrameNode of the web view
- // and access them through a QWeakPointer from the resource holder to find them later.
- m_sgObjects.textureStrongRefs.append(resource->initTexture(quadIsAllOpaque, apiDelegate));
- return m_sgObjects.textureStrongRefs.last().data();
+ auto &value = map[key];
+ if (value)
+ return value;
+ value = previousMap[key];
+ return value;
}
-void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxesToFetch)
+QSGTexture *DelegatedFrameNode::initAndHoldTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate, int target)
{
-#ifndef QT_NO_OPENGL
- QList<gl::TransferableFence> transferredFences;
- {
- QMutexLocker lock(&m_mutex);
- QVector<MailboxTexture *> mailboxesToPull;
- mailboxesToPull.reserve(mailboxesToFetch.size());
-
- gpu::SyncPointManager *syncPointManager = sync_point_manager();
- scoped_refptr<base::SingleThreadTaskRunner> gpuTaskRunner = gpu_task_runner();
- Q_ASSERT(m_numPendingSyncPoints == 0);
- m_numPendingSyncPoints = mailboxesToFetch.count();
- for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) {
- gpu::SyncToken &syncToken = mailboxTexture->mailboxHolder().sync_token;
- const auto task = base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture);
- if (!syncPointManager->WaitOutOfOrder(syncToken, std::move(task)))
- mailboxesToPull.append(mailboxTexture);
- }
- if (!mailboxesToPull.isEmpty()) {
- auto task = base::BindOnce(&DelegatedFrameNode::pullTextures, this, std::move(mailboxesToPull));
- gpuTaskRunner->PostTask(FROM_HERE, std::move(task));
- }
-
- m_mailboxesFetchedWaitCond.wait(&m_mutex);
- m_textureFences.swap(transferredFences);
+ QSGTexture::Filtering filtering;
+
+ if (resource->filter == GL_NEAREST)
+ filtering = QSGTexture::Nearest;
+ else if (resource->filter == GL_LINEAR)
+ filtering = QSGTexture::Linear;
+ else {
+ // Depends on qtdeclarative fix, see QTBUG-71322
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1)
+ filtering = QSGTexture::Linear;
+#else
+ filtering = QSGTexture::Nearest;
+#endif
}
- for (gl::TransferableFence sync : qAsConst(transferredFences)) {
- // We need to wait on the fences on the Qt current context, and
- // can therefore not use GLFence routines that uses a different
- // concept of current context.
- waitChromiumSync(&sync);
- deleteChromiumSync(&sync);
+ if (resource->is_software) {
+ QSharedPointer<QSGTexture> &texture =
+ findTexture(m_sgObjects.bitmapTextures, m_previousSGObjects.bitmapTextures, resource->id);
+ if (texture)
+ return texture.data();
+ texture = createBitmapTexture(resource, hasAlphaChannel, apiDelegate);
+ texture->setFiltering(filtering);
+ return texture.data();
+ } else {
+#if QT_CONFIG(opengl)
+ QSharedPointer<MailboxTexture> &texture =
+ findTexture(m_sgObjects.mailboxTextures, m_previousSGObjects.mailboxTextures, resource->id);
+ if (texture)
+ return texture.data();
+ texture = createMailboxTexture(resource, hasAlphaChannel, target);
+ texture->setFiltering(filtering);
+ return texture.data();
+#else
+ Q_UNREACHABLE();
+ return nullptr;
+#endif
}
+}
-#if defined(USE_OZONE) && !defined(QT_NO_OPENGL)
+QSharedPointer<QSGTexture> DelegatedFrameNode::createBitmapTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate)
+{
+ Q_ASSERT(apiDelegate);
+ viz::SharedBitmap *sharedBitmap = resource->bitmap.get();
+ gfx::Size size = resource->size;
+
+ // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending
+ // to draw it but Chromium keeps this information in the quads.
+ // The input format is currently always Format_ARGB32_Premultiplied, so assume that all
+ // alpha bytes are 0xff if quads aren't requesting blending and avoid the conversion
+ // from Format_ARGB32_Premultiplied to Format_RGB32 just to get hasAlphaChannel to
+ // return false.
+ QImage::Format format = hasAlphaChannel ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ QImage image = sharedBitmap
+ ? QImage(sharedBitmap->pixels(), size.width(), size.height(), format)
+ : QImage(size.width(), size.height(), format);
+ return QSharedPointer<QSGTexture>(apiDelegate->createTextureFromImage(image.copy()));
+}
+
+QSharedPointer<MailboxTexture> DelegatedFrameNode::createMailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target)
+{
+#ifndef QT_NO_OPENGL
+ return QSharedPointer<MailboxTexture>::create(resource, hasAlphaChannel, target);
+#else
+ Q_UNREACHABLE();
+#endif
+}
+
+void DelegatedFrameNode::copyMailboxTextures()
+{
+#if !defined(QT_NO_OPENGL) && defined(USE_OZONE)
// Workaround when context is not shared QTBUG-48969
// Make slow copy between two contexts.
if (!m_contextShared) {
@@ -1296,13 +1079,17 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe
GLuint fbo = 0;
funcs->glGenFramebuffers(1, &fbo);
- for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) {
+ for (const QSharedPointer<MailboxTexture> &mailboxTexture : qAsConst(m_sgObjects.mailboxTextures)) {
+ if (mailboxTexture->m_ownsTexture)
+ continue;
+
// Read texture into QImage from shared context.
// Switch to shared context.
sharedContext->makeCurrent(m_offsurface.data());
funcs = sharedContext->functions();
QImage img(mailboxTexture->textureSize(), QImage::Format_RGBA8888_Premultiplied);
funcs->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ mailboxTexture->m_fence->wait();
funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mailboxTexture->m_textureId, 0);
GLenum status = funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
@@ -1336,69 +1123,6 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe
currentContext->makeCurrent(surface);
}
#endif
-#else
- Q_UNUSED(mailboxesToFetch)
-#endif //QT_NO_OPENGL
-}
-
-
-void DelegatedFrameNode::pullTextures(DelegatedFrameNode *frameNode, const QVector<MailboxTexture *> textures)
-{
-#ifndef QT_NO_OPENGL
- gpu::MailboxManager *mailboxManager = mailbox_manager();
- for (MailboxTexture *texture : textures) {
- gpu::SyncToken &syncToken = texture->mailboxHolder().sync_token;
- if (syncToken.HasData())
- mailboxManager->PullTextureUpdates(syncToken);
- texture->fetchTexture(mailboxManager);
- --frameNode->m_numPendingSyncPoints;
- }
-
- fenceAndUnlockQt(frameNode);
-#else
- Q_UNUSED(frameNode)
- Q_UNUSED(textures)
-#endif
-}
-
-void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *texture)
-{
-#ifndef QT_NO_OPENGL
- gpu::MailboxManager *mailboxManager = mailbox_manager();
- gpu::SyncToken &syncToken = texture->mailboxHolder().sync_token;
- if (syncToken.HasData())
- mailboxManager->PullTextureUpdates(syncToken);
- texture->fetchTexture(mailboxManager);
- --frameNode->m_numPendingSyncPoints;
-
- fenceAndUnlockQt(frameNode);
-#else
- Q_UNUSED(frameNode)
- Q_UNUSED(texture)
-#endif
-}
-
-void DelegatedFrameNode::fenceAndUnlockQt(DelegatedFrameNode *frameNode)
-{
-#ifndef QT_NO_OPENGL
- if (!!gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) {
- // Create a fence on the Chromium GPU-thread and context
- std::unique_ptr<gl::GLFence> fence = gl::GLFence::Create();
- // But transfer it to something generic since we need to read it using Qt's OpenGL.
- frameNode->m_textureFences.append(fence->Transfer());
- }
- if (frameNode->m_numPendingSyncPoints == 0)
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::unlockQt, frameNode));
-#else
- Q_UNUSED(frameNode)
-#endif
-}
-
-void DelegatedFrameNode::unlockQt(DelegatedFrameNode *frameNode)
-{
- QMutexLocker lock(&frameNode->m_mutex);
- // Signal preprocess() the textures are ready
- frameNode->m_mailboxesFetchedWaitCond.wakeOne();
}
} // namespace QtWebEngineCore
diff --git a/src/core/delegated_frame_node.h b/src/core/compositor/delegated_frame_node.h
index e37ad08a3..34e4ba029 100644
--- a/src/core/delegated_frame_node.h
+++ b/src/core/compositor/delegated_frame_node.h
@@ -43,15 +43,10 @@
#include "base/containers/circular_deque.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/render_pass.h"
-#include "components/viz/common/resources/transferable_resource.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-#include "ui/gl/gl_fence.h"
-#include <QMutex>
-#include <QSGNode>
-#include <QSharedData>
-#include <QSharedPointer>
-#include <QWaitCondition>
+
+#include <QtCore/QSharedPointer>
#include <QtGui/QOffscreenSurface>
+#include <QtQuick/QSGTransformNode>
#include "chromium_gpu_helper.h"
#include "render_widget_host_view_qt_delegate.h"
@@ -72,77 +67,60 @@ class DrawPolygon;
namespace QtWebEngineCore {
+class CompositorResource;
+class CompositorResourceTracker;
class DelegatedNodeTreeHandler;
class MailboxTexture;
-class ResourceHolder;
-
-// Separating this data allows another DelegatedFrameNode to reconstruct the QSGNode tree from the mailbox textures
-// and render pass information.
-class ChromiumCompositorData : public QSharedData {
-public:
- ChromiumCompositorData() : frameDevicePixelRatio(1) { }
- QHash<unsigned, QSharedPointer<ResourceHolder> > resourceHolders;
- viz::CompositorFrame frameData;
- viz::CompositorFrame previousFrameData;
- qreal frameDevicePixelRatio;
-};
class DelegatedFrameNode : public QSGTransformNode {
public:
DelegatedFrameNode();
~DelegatedFrameNode();
- void preprocess();
- void commit(ChromiumCompositorData *chromiumCompositorData, std::vector<viz::ReturnedResource> *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate);
+ void preprocess() override;
+ void commit(const viz::CompositorFrame &pendingFrame, const viz::CompositorFrame &committedFrame, const CompositorResourceTracker *resourceTracker, RenderWidgetHostViewQtDelegate *apiDelegate);
private:
void flushPolygons(base::circular_deque<std::unique_ptr<viz::DrawPolygon> > *polygonQueue,
QSGNode *renderPassChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate);
void handlePolygon(
const viz::DrawPolygon *polygon,
QSGNode *currentLayerChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate);
void handleClippedQuad(
const viz::DrawQuad *quad,
const gfx::QuadF &clipRegion,
QSGNode *currentLayerChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate);
void handleQuad(
const viz::DrawQuad *quad,
QSGNode *currentLayerChain,
DelegatedNodeTreeHandler *nodeHandler,
- QHash<unsigned, QSharedPointer<ResourceHolder> > &resourceCandidates,
+ const CompositorResourceTracker *resourceTracker,
RenderWidgetHostViewQtDelegate *apiDelegate);
- void fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxesToFetch);
- // Making those callbacks static bypasses base::Bind's ref-counting requirement
- // of the this pointer when the callback is a method.
- static void pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *mailbox);
- static void pullTextures(DelegatedFrameNode *frameNode, const QVector<MailboxTexture *> mailboxes);
- static void fenceAndUnlockQt(DelegatedFrameNode *frameNode);
- static void unlockQt(DelegatedFrameNode *frameNode);
-
- ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);
- void holdResources(const viz::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);
- void holdResources(const viz::RenderPass *pass, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);
- QSGTexture *initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
-
- QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
+
+ const CompositorResource *findAndHoldResource(unsigned resourceId, const CompositorResourceTracker *resourceTracker);
+ void holdResources(const viz::DrawQuad *quad, const CompositorResourceTracker *resourceTracker);
+ void holdResources(const viz::RenderPass *pass, const CompositorResourceTracker *resourceTracker);
+ QSGTexture *initAndHoldTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate = 0, int target = -1);
+ QSharedPointer<QSGTexture> createBitmapTexture(const CompositorResource *resource, bool hasAlphaChannel, RenderWidgetHostViewQtDelegate *apiDelegate);
+ QSharedPointer<MailboxTexture> createMailboxTexture(const CompositorResource *resource, bool hasAlphaChannel, int target);
+
+ void copyMailboxTextures();
+
struct SGObjects {
QVector<QPair<int, QSharedPointer<QSGLayer> > > renderPassLayers;
QVector<QSharedPointer<QSGRootNode> > renderPassRootNodes;
- QVector<QSharedPointer<QSGTexture> > textureStrongRefs;
- } m_sgObjects;
+ QHash<unsigned, QSharedPointer<QSGTexture> > bitmapTextures;
+ QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextures;
+ } m_sgObjects, m_previousSGObjects;
QVector<QSGNode*> m_sceneGraphNodes;
- int m_numPendingSyncPoints;
- QWaitCondition m_mailboxesFetchedWaitCond;
- QMutex m_mutex;
- QList<gl::TransferableFence> m_textureFences;
#if defined(USE_OZONE)
bool m_contextShared;
QScopedPointer<QOffscreenSurface> m_offsurface;
diff --git a/src/core/stream_video_node.cpp b/src/core/compositor/stream_video_node.cpp
index 29922f866..29922f866 100644
--- a/src/core/stream_video_node.cpp
+++ b/src/core/compositor/stream_video_node.cpp
diff --git a/src/core/stream_video_node.h b/src/core/compositor/stream_video_node.h
index 9d937791f..9d937791f 100644
--- a/src/core/stream_video_node.h
+++ b/src/core/compositor/stream_video_node.h
diff --git a/src/core/yuv_video_node.cpp b/src/core/compositor/yuv_video_node.cpp
index 4a436d952..4a436d952 100644
--- a/src/core/yuv_video_node.cpp
+++ b/src/core/compositor/yuv_video_node.cpp
diff --git a/src/core/yuv_video_node.h b/src/core/compositor/yuv_video_node.h
index dca8fa5e2..dca8fa5e2 100644
--- a/src/core/yuv_video_node.h
+++ b/src/core/compositor/yuv_video_node.h
diff --git a/src/core/config/common.pri b/src/core/config/common.pri
index 42cf445df..fce89f576 100644
--- a/src/core/config/common.pri
+++ b/src/core/config/common.pri
@@ -4,6 +4,7 @@ QT_FOR_CONFIG += webenginecore
gn_args += \
use_qt=true \
+ closure_compile=false \
is_component_build=false \
is_shared=true \
enable_message_center=false \
@@ -11,15 +12,20 @@ gn_args += \
enable_nacl=false \
enable_remoting=false \
enable_reporting=false \
+ enable_swiftshader=false \
+ enable_web_auth=false \
enable_web_speech=false \
enable_widevine=true \
has_native_accessibility=false \
+ enable_debugallocation=false \
use_allocator_shim=false \
use_allocator=\"none\" \
+ use_custom_libcxx=false \
v8_use_external_startup_data=false \
+ toolkit_views=false \
treat_warnings_as_errors=false \
- enable_swiftshader=false \
- use_custom_libcxx=false
+ safe_browsing_mode=0 \
+ optimize_webui=false
!win32: gn_args += \
use_jumbo_build=true \
@@ -49,11 +55,17 @@ qtConfig(webengine-spellchecker) {
qtConfig(webengine-webrtc) {
gn_args += enable_webrtc=true
} else {
- gn_args += enable_webrtc=false
+ gn_args += enable_webrtc=false audio_processing_in_audio_service_supported=false
}
qtConfig(webengine-proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\"
+qtConfig(webengine-extensions) {
+ gn_args += enable_extensions=true
+} else {
+ gn_args += enable_extensions=false
+}
+
precompile_header {
gn_args += enable_precompiled_headers=true
} else {
@@ -81,6 +93,12 @@ CONFIG(release, debug|release) {
CONFIG(debug, debug|release) {
gn_args += is_debug=true
gn_args += use_debug_fission=false
+ # MSVC requires iterator debug to always match and Qt has leaves it default on.
+ msvc: gn_args += enable_iterator_debugging=true
+
+ # We also can not have optimized V8 binaries for MSVC as iterator debugging
+ # would mismatch.
+ msvc|v8base_debug: gn_args += v8_optimized_debug=false
}
!webcore_debug: gn_args += remove_webcore_debug_symbols=true
@@ -91,14 +109,10 @@ optimize_size: gn_args += optimize_for_size=true
# We don't want to apply sanitizer options to the build tools (GN, dict convert, etc).
!host_build {
- sanitizer: gn_args += sanitizer_keep_symbols=true
sanitize_address: gn_args += is_asan=true
sanitize_thread: gn_args += is_tsan=true
sanitize_memory: gn_args += is_msan=true
- # rtti is required for a specific check of ubsan, -fsanitize=vptr, which uses the runtime
- # type information to check that correct derived objects are assigned to base pointers. Without
- # rtti, linking would fail at build time.
- sanitize_undefined: gn_args += is_ubsan=true use_rtti=true
+ sanitize_undefined: gn_args += is_ubsan=true is_ubsan_vptr=true
}
qtConfig(webengine-v8-snapshot) {
@@ -113,8 +127,6 @@ qtConfig(webengine-kerberos) {
gn_args += use_kerberos=false
}
-!msvc: gn_args += enable_iterator_debugging=false
-
ccache {
gn_args += cc_wrapper=\"ccache\"
}
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index eaecab3c9..22cb5991f 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -22,15 +22,19 @@ gn_args += \
ozone_auto_platforms=false \
ozone_platform_headless=false \
ozone_platform_external=true \
- ozone_platform=\"qt\"
+ ozone_platform=\"qt\" \
+ ozone_extra_path=\"$$QTWEBENGINE_ROOT/src/core/ozone/ozone_extra.gni\"
qtConfig(webengine-embedded-build) {
gn_args += is_desktop_linux=false
- gn_args += use_gold=false
-} else {
- !use_gold_linker: gn_args += use_gold=false
}
+use_gold_linker: gn_args += use_gold=true
+else: gn_args += use_gold=false
+
+use_lld_linker: gn_args += use_lld=true
+else: gn_args += use_lld=false
+
clang {
clang_full_path = $$which($${QMAKE_CXX})
# Remove the "/bin/clang++" part.
@@ -38,8 +42,8 @@ clang {
gn_args += \
is_clang=true \
clang_use_chrome_plugins=false \
- clang_base_path=\"$${clang_prefix}\" \
- use_lld=false
+ clang_use_default_sample_profile=false \
+ clang_base_path=\"$${clang_prefix}\"
linux-clang-libc++: gn_args += use_libcxx=true
} else {
@@ -159,9 +163,21 @@ host_build {
gn_args += use_system_libpng=true
qtConfig(webengine-printing-and-pdf): gn_args += pdfium_use_system_libpng=true
}
- qtConfig(webengine-system-jpeg): gn_args += use_system_libjpeg=true
- qtConfig(webengine-system-freetype): gn_args += use_system_freetype=true
- qtConfig(webengine-system-harfbuzz): gn_args += use_system_harfbuzz=true
+ qtConfig(webengine-system-jpeg) {
+ gn_args += use_system_libjpeg=true
+ } else {
+ gn_args += use_system_libjpeg=false
+ }
+ qtConfig(webengine-system-freetype) {
+ gn_args += use_system_freetype=true
+ } else {
+ gn_args += use_system_freetype=false
+ }
+ qtConfig(webengine-system-harfbuzz) {
+ gn_args += use_system_harfbuzz=true
+ } else {
+ gn_args += use_system_harfbuzz=false
+ }
!qtConfig(webengine-system-glib): gn_args += use_glib=false
qtConfig(webengine-pulseaudio) {
gn_args += use_pulseaudio=true
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index 4426901cf..e49df90e7 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -28,8 +28,6 @@ gn_args += \
clang_use_chrome_plugins=false \
mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \
- mac_views_browser=false \
- toolkit_views=false \
use_external_popup_menu=false
qtConfig(webengine-spellchecker) {
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index 730b38a35..385faeed0 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -1,7 +1,6 @@
include(common.pri)
gn_args += \
- is_clang=false \
use_sysroot=false \
enable_session_service=false \
ninja_use_custom_environment_files=false \
@@ -9,6 +8,20 @@ gn_args += \
win_linker_timing=true \
com_init_check_hook_disabled=true
+clang_cl {
+ clang_full_path = $$system_path($$which($${QMAKE_CXX}))
+ # Remove the "\bin\clang-cl.exe" part:
+ clang_dir = $$dirname(clang_full_path)
+ clang_prefix = $$join(clang_dir,,,"\..")
+ gn_args += \
+ is_clang=true \
+ use_ldd=true \
+ clang_use_chrome_plugins=false \
+ clang_base_path=\"$$system_path($$clean_path($$clang_prefix))\"
+} else {
+ gn_args += is_clang=false use_lld=false
+}
+
isDeveloperBuild() {
gn_args += \
is_win_fastlink=true
@@ -71,7 +84,6 @@ msvc {
GN_TARGET_CPU = $$gnArch($$QT_ARCH)
gn_args += target_cpu=\"$$GN_TARGET_CPU\"
-
} else {
- error("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler")
+ error("Qt WebEngine for Windows can only be built with a Microsoft Visual Studio C++ compatible compiler")
}
diff --git a/src/core/configure.json b/src/core/configure.json
index b9c920444..be686850b 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -22,11 +22,14 @@
"webengine-pulseaudio": "boolean",
"webengine-spellchecker": "boolean",
"webengine-native-spellchecker": "boolean",
+ "webengine-extensions": "boolean",
"webengine-webrtc": "boolean",
"webengine-geolocation": "boolean",
"webengine-v8-snapshot": "boolean",
"webengine-webchannel": "boolean",
"webengine-kerberos": "boolean",
+ "webengine-widgets": "boolean",
+ "webengine-qml": "boolean",
"alsa": { "type": "boolean", "name": "webengine-alsa" },
"pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" },
"ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
@@ -36,6 +39,7 @@
"printing-and-pdf": { "type": "boolean", "name": "webengine-printing-and-pdf" },
"proprietary-codecs": { "type": "boolean", "name": "webengine-proprietary-codecs" },
"spellchecker": { "type": "boolean", "name": "webengine-spellchecker" },
+ "extensions": { "type": "boolean", "name": "webengine-extensions" },
"webrtc": { "type": "boolean", "name": "webengine-webrtc" }
}
},
@@ -84,9 +88,9 @@
]
},
"webengine-harfbuzz": {
- "label": "harfbuzz >= 1.4.2",
+ "label": "harfbuzz >= 2.2.0",
"sources": [
- { "type": "pkgConfig", "args": "harfbuzz >= 1.4.2" }
+ { "type": "pkgConfig", "args": "harfbuzz >= 2.2.0" }
]
},
"webengine-glib": {
@@ -144,9 +148,9 @@
]
},
"webengine-icu": {
- "label": "icu >= 53",
+ "label": "icu >= 63",
"sources": [
- { "type": "pkgConfig", "args": "icu-uc >= 53 icu-i18n >= 53" }
+ { "type": "pkgConfig", "args": "icu-uc >= 63 icu-i18n >= 63" }
]
},
"webengine-ffmpeg": {
@@ -310,7 +314,8 @@
},
"webengine-glibc": {
"label": "glibc > 2.16",
- "type": "detectGlibc"
+ "type": "compile",
+ "test": "glibc"
},
"webengine-libxml2-compatible": {
"label" : "compatible system libxml2",
@@ -329,6 +334,10 @@
"label": "thumb instruction set",
"type": "hasThumbFlag"
},
+ "webengine-extensions-gcc-version" : {
+ "label": "GCC 6 or newer",
+ "type": "hasGcc6OrNewer"
+ },
"webengine-noexecstack" : {
"label": "linker supports -z noexecstack",
"type": "linkerSupportsFlag",
@@ -553,14 +562,13 @@
"condition": "config.macos && features.webengine-spellchecker",
"output": [ "publicFeature" ]
},
- "webengine-ui-delegates": {
- "label": "UI Delegates",
- "output": [ "privateFeature" ]
- },
- "webengine-testsupport": {
- "label": "Test Support",
- "autoDetect": "features.private_tests || call.isTestsInBuildParts",
- "output": [ "privateFeature" ]
+ "webengine-extensions": {
+ "label": "Extensions",
+ "purpose": "Enables Chromium extensions within certain limits. Currently used for enabling the pdf viewer.",
+ "section": "WebEngine",
+ "condition": "features.webengine-printing-and-pdf && (tests.webengine-extensions-gcc-version || config.clang || !config.gcc)",
+ "autoDetect": "features.webengine-printing-and-pdf",
+ "output": [ "publicFeature" ]
},
"webengine-webrtc": {
"label": "WebRTC",
@@ -676,6 +684,19 @@
"condition": "config.linux && features.webengine-embedded-build && arch.arm && tests.webengine-arm-thumb",
"output": [ "privateFeature" ]
},
+ "webengine-widgets": {
+ "label": "Qt WebEngine Widgets",
+ "purpose": "Provides WebEngine Widgets support.",
+ "section": "WebEngine",
+ "condition": "module.widgets",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-qml": {
+ "label": "Qt WebEngine Qml",
+ "purpose": "Provides WebEngine Qml support.",
+ "section": "WebEngine",
+ "output": [ "privateFeature" ]
+ },
"webengine-full-debug-info": {
"label": "Full debug information",
"purpose": "Enables debug information for Blink and V8.",
@@ -738,8 +759,10 @@
"summary": [
{
- "section": "Qt WebEngine",
+ "section": "Qt WebEngineCore",
"entries": [
+ "webengine-widgets",
+ "webengine-qml",
"webengine-embedded-build",
"webengine-full-debug-info",
"webengine-pepper-plugins",
@@ -753,6 +776,7 @@
"webengine-webchannel",
"webengine-v8-snapshot",
"webengine-kerberos",
+ "webengine-extensions",
{
"type": "feature",
"args": "webengine-ozone-x11",
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index acd652b15..16945020b 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -39,15 +39,20 @@
#include "content_browser_client_qt.h"
-#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
+#include "base/optional.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/message_loop/message_loop.h"
+#include "base/task/post_task.h"
+#include "base/threading/thread_restrictions.h"
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
#endif
+#include "components/guest_view/browser/guest_view_base.h"
#include "components/network_hints/browser/network_hints_message_filter.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/common/url_schemes.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/client_certificate_delegate.h"
@@ -65,15 +70,23 @@
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/user_agent.h"
#include "media/media_buildflags.h"
+#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "printing/buildflags/buildflags.h"
+#include "qtwebengine/browser/qtwebengine_content_browser_overlay_manifest.h"
+#include "qtwebengine/browser/qtwebengine_content_renderer_overlay_manifest.h"
+#include "qtwebengine/browser/qtwebengine_packaged_service_manifest.h"
+#include "qtwebengine/browser/qtwebengine_renderer_manifest.h"
#include "net/ssl/client_cert_identity.h"
+#include "net/ssl/client_cert_store.h"
#include "services/proxy_resolver/proxy_resolver_service.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/sandbox/switches.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/platform/modules/insecure_input/insecure_input_service.mojom.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
@@ -83,6 +96,7 @@
#include "ui/gl/gpu_timing.h"
#include "url/url_util_qt.h"
+#include "qtwebengine/common/renderer_configuration.mojom.h"
#include "qtwebengine/grit/qt_webengine_resources.h"
#include "profile_adapter.h"
@@ -95,12 +109,13 @@
#include "login_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
#include "net/network_delegate_qt.h"
-#include "net/qrc_protocol_handler_qt.h"
#include "net/url_request_context_getter_qt.h"
+#include "platform_notification_service_qt.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/printing_message_filter_qt.h"
#endif
#include "profile_qt.h"
+#include "profile_io_data_qt.h"
#include "quota_permission_context_qt.h"
#include "renderer_host/user_resource_controller_host.h"
#include "service/service_qt.h"
@@ -114,18 +129,6 @@
#include "ui/base/resource/resource_bundle.h"
#endif
-#if defined(USE_NSS_CERTS)
-#include "net/ssl/client_cert_store_nss.h"
-#endif
-
-#if defined(OS_WIN)
-#include "net/ssl/client_cert_store_win.h"
-#endif
-
-#if defined(OS_MACOSX)
-#include "net/ssl/client_cert_store_mac.h"
-#endif
-
#if QT_CONFIG(webengine_pepper_plugins)
#include "content/public/browser/browser_ppapi_host.h"
#include "ppapi/host/ppapi_host.h"
@@ -136,6 +139,16 @@
#include "location_provider_qt.h"
#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/extensions_browser_client_qt.h"
+#include "extensions/browser/extension_message_filter.h"
+#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
+#include "extensions/browser/io_thread_extension_message_filter.h"
+#include "extensions/common/constants.h"
+#include "common/extensions/extensions_client_qt.h"
+#include "renderer_host/resource_dispatcher_host_delegate_qt.h"
+#endif
+
#include <QGuiApplication>
#include <QLocale>
#ifndef QT_NO_OPENGL
@@ -157,7 +170,7 @@ public:
{
QString platform = qApp->platformName().toLower();
QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface();
- if (platform == QLatin1String("xcb")) {
+ if (platform == QLatin1String("xcb") || platform == QLatin1String("offscreen")) {
if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2)
m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
else
@@ -248,10 +261,10 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost*
{
const int id = host->GetID();
Profile *profile = Profile::FromBrowserContext(host->GetBrowserContext());
- content::BrowserThread::PostTaskAndReplyWithResult(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&net::URLRequestContextGetter::GetURLRequestContext, base::Unretained(profile->GetRequestContext())),
- base::Bind(&ContentBrowserClientQt::AddNetworkHintsMessageFilter, base::Unretained(this), id));
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&net::URLRequestContextGetter::GetURLRequestContext, base::Unretained(profile->GetRequestContext())),
+ base::BindOnce(&ContentBrowserClientQt::AddNetworkHintsMessageFilter, base::Unretained(this), id));
// FIXME: Add a settings variable to enable/disable the file scheme.
content::ChildProcessSecurityPolicy::GetInstance()->GrantRequestScheme(id, url::kFileScheme);
@@ -260,21 +273,36 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost*
#if QT_CONFIG(webengine_printing_and_pdf)
host->AddFilter(new PrintingMessageFilterQt(host->GetID()));
#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ host->AddFilter(new extensions::ExtensionMessageFilter(host->GetID(), host->GetBrowserContext()));
+ host->AddFilter(new extensions::IOThreadExtensionMessageFilter(host->GetID(), host->GetBrowserContext()));
+ host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(host->GetID(), host->GetBrowserContext()));
+#endif //ENABLE_EXTENSIONS
+
+ bool is_incognito_process = profile->IsOffTheRecord();
+ qtwebengine::mojom::RendererConfigurationAssociatedPtr renderer_configuration;
+ host->GetChannel()->GetRemoteAssociatedInterface(&renderer_configuration);
+ renderer_configuration->SetInitialConfiguration(is_incognito_process);
service_manager::mojom::ServicePtr service;
*service_request = mojo::MakeRequest(&service);
service_manager::mojom::PIDReceiverPtr pid_receiver;
service_manager::Identity renderer_identity = host->GetChildIdentity();
- ServiceQt::GetInstance()->connector()->StartService(
+ ServiceQt::GetInstance()->connector()->RegisterServiceInstance(
service_manager::Identity("qtwebengine_renderer",
- renderer_identity.user_id(),
- renderer_identity.instance()),
+ renderer_identity.instance_group(),
+ renderer_identity.instance_id(),
+ base::Token::CreateRandom()),
std::move(service), mojo::MakeRequest(&pid_receiver));
}
void ContentBrowserClientQt::ResourceDispatcherHostCreated()
{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ m_resourceDispatcherHostDelegate.reset(new ResourceDispatcherHostDelegateQt);
+#else
m_resourceDispatcherHostDelegate.reset(new content::ResourceDispatcherHostDelegate);
+#endif
content::ResourceDispatcherHost::Get()->SetDelegate(m_resourceDispatcherHostDelegate.get());
}
@@ -293,6 +321,10 @@ content::MediaObserver *ContentBrowserClientQt::GetMediaObserver()
void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, content::WebPreferences *web_prefs)
{
if (content::WebContents *webContents = rvh->GetDelegate()->GetAsWebContents()) {
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (guest_view::GuestViewBase::IsGuest(webContents))
+ return;
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
WebContentsDelegateQt* delegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
if (delegate)
delegate->overrideWebPreferences(webContents, web_prefs);
@@ -382,17 +414,8 @@ std::unique_ptr<net::ClientCertStore> ContentBrowserClientQt::CreateClientCertSt
{
if (!resource_context)
return nullptr;
-#if defined(USE_NSS_CERTS)
- // FIXME: Give it a proper callback for a password delegate.
- return std::unique_ptr<net::ClientCertStore>(
- new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory()));
-#elif defined(OS_WIN)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
-#elif defined(OS_MACOSX)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
-#else
- return nullptr;
-#endif
+
+ return ProfileIODataQt::FromResourceContext(resource_context)->CreateClientCertStore();
}
std::string ContentBrowserClientQt::GetApplicationLocale()
@@ -421,6 +444,11 @@ void ContentBrowserClientQt::GetAdditionalWebUISchemes(std::vector<std::string>*
additional_schemes->push_back(content::kChromeDevToolsScheme);
}
+void ContentBrowserClientQt::GetAdditionalViewSourceSchemes(std::vector<std::string>* additional_schemes)
+{
+ additional_schemes->push_back(content::kChromeDevToolsScheme);
+}
+
#if defined(Q_OS_LINUX)
void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings)
{
@@ -441,7 +469,7 @@ void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base:
void ContentBrowserClientQt::DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host)
{
browser_host->GetPpapiHost()->AddHostFactoryFilter(
- base::WrapUnique(new QtWebEngineCore::PepperHostFactoryQt(browser_host)));
+ std::make_unique<QtWebEngineCore::PepperHostFactoryQt>(browser_host));
}
#endif
@@ -450,6 +478,13 @@ content::DevToolsManagerDelegate* ContentBrowserClientQt::GetDevToolsManagerDele
return new DevToolsManagerDelegateQt;
}
+content::PlatformNotificationService *ContentBrowserClientQt::GetPlatformNotificationService()
+{
+ if (!m_platformNotificationService)
+ m_platformNotificationService = std::make_unique<PlatformNotificationServiceQt>();
+ return m_platformNotificationService.get();
+}
+
// This is a really complicated way of doing absolutely nothing, but Mojo demands it:
class ServiceDriver
: public blink::mojom::InsecureInputService
@@ -485,19 +520,18 @@ public:
}
// blink::mojom::InsecureInputService:
- void PasswordFieldVisibleInInsecureContext() override
- { }
- void AllPasswordFieldsInInsecureContextInvisible() override
- { }
void DidEditFieldInInsecureContext() override
{ }
private:
+ WEB_CONTENTS_USER_DATA_KEY_DECL()
explicit ServiceDriver(content::WebContents* /*web_contents*/) { }
friend class content::WebContentsUserData<ServiceDriver>;
mojo::BindingSet<blink::mojom::InsecureInputService> m_insecureInputServiceBindings;
};
+WEB_CONTENTS_USER_DATA_KEY_IMPL(ServiceDriver)
+
void ContentBrowserClientQt::InitFrameInterfaces()
{
m_frameInterfaces = std::make_unique<service_manager::BinderRegistry>();
@@ -516,11 +550,11 @@ void ContentBrowserClientQt::BindInterfaceRequestFromFrame(content::RenderFrameH
m_frameInterfaces->TryBindInterface(interface_name, &interface_pipe);
}
-void ContentBrowserClientQt::RegisterInProcessServices(StaticServiceMap* services, content::ServiceManagerConnection* connection)
+void ContentBrowserClientQt::RegisterIOThreadServiceHandlers(content::ServiceManagerConnection *connection)
{
- service_manager::EmbeddedServiceInfo info;
- info.factory = ServiceQt::GetInstance()->CreateServiceQtFactory();
- services->insert(std::make_pair("qtwebengine", info));
+ connection->AddServiceRequestHandler(
+ "qtwebengine",
+ ServiceQt::GetInstance()->CreateServiceQtRequestHandler());
}
void ContentBrowserClientQt::RegisterOutOfProcessServices(content::ContentBrowserClient::OutOfProcessServiceMap *services)
@@ -529,46 +563,41 @@ void ContentBrowserClientQt::RegisterOutOfProcessServices(content::ContentBrowse
base::BindRepeating(&base::ASCIIToUTF16, "V8 Proxy Resolver");
}
-std::unique_ptr<base::Value> ContentBrowserClientQt::GetServiceManifestOverlay(base::StringPiece name)
+base::Optional<service_manager::Manifest> ContentBrowserClientQt::GetServiceManifestOverlay(base::StringPiece name)
{
- ui::ResourceBundle &rb = ui::ResourceBundle::GetSharedInstance();
- int id = -1;
- if (name == content::mojom::kPackagedServicesServiceName)
- id = IDR_QTWEBENGINE_CONTENT_PACKAGED_SERVICES_MANIFEST_OVERLAY;
- else if (name == content::mojom::kRendererServiceName)
- id = IDR_QTWEBENGINE_CONTENT_RENDERER_MANIFEST_OVERLAY;
- else if (name == content::mojom::kBrowserServiceName)
- id = IDR_QTWEBENGINE_CONTENT_BROWSER_MANIFEST_OVERLAY;
- if (id == -1)
- return nullptr;
+ if (name == content::mojom::kBrowserServiceName) {
+ return GetQtWebEngineContentBrowserOverlayManifest();
+ } else if (name == content::mojom::kPackagedServicesServiceName) {
+ service_manager::Manifest overlay;
+ overlay.packaged_services = GetQtWebEnginePackagedServiceManifests();
+ return overlay;
+ } else if (name == content::mojom::kRendererServiceName) {
+ return GetQtWebEngineContentRendererOverlayManifest();
+ }
- base::StringPiece manifest_contents =
- rb.GetRawDataResourceForScale(id, ui::ScaleFactor::SCALE_FACTOR_NONE);
- return base::JSONReader::Read(manifest_contents);
+ return base::nullopt;
}
-std::vector<content::ContentBrowserClient::ServiceManifestInfo> ContentBrowserClientQt::GetExtraServiceManifests()
+std::vector<service_manager::Manifest> ContentBrowserClientQt::GetExtraServiceManifests()
{
- return std::vector<content::ContentBrowserClient::ServiceManifestInfo>({
- {"qtwebengine_renderer", IDR_QTWEBENGINE_RENDERER_SERVICE_MANIFEST},
- });
+ return std::vector<service_manager::Manifest>{GetQtWebEngineRendererManifest()};
}
bool ContentBrowserClientQt::CanCreateWindow(
- content::RenderFrameHost* opener,
- const GURL& opener_url,
- const GURL& opener_top_level_frame_url,
- const GURL& source_origin,
- content::mojom::WindowContainerType container_type,
- const GURL& target_url,
- const content::Referrer& referrer,
- const std::string& frame_name,
- WindowOpenDisposition disposition,
- const blink::mojom::WindowFeatures& features,
- bool user_gesture,
- bool opener_suppressed,
- bool* no_javascript_access) {
-
+ content::RenderFrameHost* opener,
+ const GURL& opener_url,
+ const GURL& opener_top_level_frame_url,
+ const url::Origin& source_origin,
+ content::mojom::WindowContainerType container_type,
+ const GURL& target_url,
+ const content::Referrer& referrer,
+ const std::string& frame_name,
+ WindowOpenDisposition disposition,
+ const blink::mojom::WindowFeatures& features,
+ bool user_gesture,
+ bool opener_suppressed,
+ bool* no_javascript_access)
+{
Q_UNUSED(opener_url);
Q_UNUSED(opener_top_level_frame_url);
Q_UNUSED(source_origin);
@@ -618,11 +647,18 @@ void ContentBrowserClientQt::AddNetworkHintsMessageFilter(int render_process_id,
if (!host)
return;
- content::BrowserMessageFilter *network_hints_message_filter(
- new network_hints::NetworkHintsMessageFilter(context->host_resolver()));
+ content::BrowserMessageFilter *network_hints_message_filter =
+ new network_hints::NetworkHintsMessageFilter(render_process_id);
host->AddFilter(network_hints_message_filter);
}
+bool ContentBrowserClientQt::ShouldEnableStrictSiteIsolation()
+{
+ // mirroring AwContentBrowserClient, CastContentBrowserClient and
+ // HeadlessContentBrowserClient
+ return false;
+}
+
bool ContentBrowserClientQt::AllowGetCookie(const GURL &url,
const GURL &first_party,
const net::CookieList & /*cookie_list*/,
@@ -631,8 +667,7 @@ bool ContentBrowserClientQt::AllowGetCookie(const GURL &url,
int /*render_frame_id*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(context->GetRequestContext()->network_delegate());
- return networkDelegate->canGetCookies(first_party, url);
+ return ProfileIODataQt::FromResourceContext(context)->canGetCookies(toQt(first_party), toQt(url));
}
bool ContentBrowserClientQt::AllowSetCookie(const GURL &url,
@@ -643,8 +678,7 @@ bool ContentBrowserClientQt::AllowSetCookie(const GURL &url,
int /*render_frame_id*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(context->GetRequestContext()->network_delegate());
- return networkDelegate->canSetCookies(first_party, url, std::string());
+ return ProfileIODataQt::FromResourceContext(context)->canSetCookie(toQt(first_party), QByteArray(), toQt(url));
}
bool ContentBrowserClientQt::AllowAppCache(const GURL &manifest_url,
@@ -652,41 +686,37 @@ bool ContentBrowserClientQt::AllowAppCache(const GURL &manifest_url,
content::ResourceContext *context)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(context->GetRequestContext()->network_delegate());
- return networkDelegate->canGetCookies(first_party, manifest_url);
+ return ProfileIODataQt::FromResourceContext(context)->canGetCookies(toQt(first_party), toQt(manifest_url));
}
bool ContentBrowserClientQt::AllowServiceWorker(const GURL &scope,
const GURL &first_party,
content::ResourceContext *context,
- const base::Callback<content::WebContents*(void)> &/*wc_getter*/)
+ base::RepeatingCallback<content::WebContents*()> wc_getter)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
// FIXME: Chrome also checks if javascript is enabled here to check if has been disabled since the service worker
// was started.
- NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(context->GetRequestContext()->network_delegate());
- return networkDelegate->canGetCookies(first_party, scope);
+ return ProfileIODataQt::FromResourceContext(context)->canGetCookies(toQt(first_party), toQt(scope));
}
// We control worker access to FS and indexed-db using cookie permissions, this is mirroring Chromium's logic.
void ContentBrowserClientQt::AllowWorkerFileSystem(const GURL &url,
content::ResourceContext *context,
- const std::vector<std::pair<int, int> > &/*render_frames*/,
+ const std::vector<content::GlobalFrameRoutingId> &/*render_frames*/,
base::Callback<void(bool)> callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(context->GetRequestContext()->network_delegate());
- callback.Run(networkDelegate->canSetCookies(url, url, std::string()));
+ callback.Run(ProfileIODataQt::FromResourceContext(context)->canSetCookie(toQt(url), QByteArray(), toQt(url)));
}
+
bool ContentBrowserClientQt::AllowWorkerIndexedDB(const GURL &url,
- const base::string16 &/*name*/,
content::ResourceContext *context,
- const std::vector<std::pair<int, int> > &/*render_frames*/)
+ const std::vector<content::GlobalFrameRoutingId> &/*render_frames*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(context->GetRequestContext()->network_delegate());
- return networkDelegate->canSetCookies(url, url, std::string());
+ return ProfileIODataQt::FromResourceContext(context)->canSetCookie(toQt(url), QByteArray(), toQt(url));
}
static void LaunchURL(const GURL& url,
@@ -709,21 +739,23 @@ bool ContentBrowserClientQt::HandleExternalProtocol(
content::NavigationUIData *navigation_data,
bool is_main_frame,
ui::PageTransition page_transition,
- bool has_user_gesture)
+ bool has_user_gesture,
+ const std::string &method,
+ const net::HttpRequestHeaders &headers)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_UNUSED(child_id);
Q_UNUSED(navigation_data);
-
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::BindOnce(&LaunchURL,
- url,
- web_contents_getter,
- page_transition,
- is_main_frame,
- has_user_gesture));
+ Q_UNUSED(method);
+ Q_UNUSED(headers);
+
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&LaunchURL,
+ url,
+ web_contents_getter,
+ page_transition,
+ is_main_frame,
+ has_user_gesture));
return true;
}
@@ -737,9 +769,36 @@ scoped_refptr<content::LoginDelegate> ContentBrowserClientQt::CreateLoginDelegat
bool first_auth_attempt,
LoginAuthRequiredCallback auth_required_callback)
{
- return base::MakeRefCounted<LoginDelegateQt>(authInfo, web_contents_getter, url, first_auth_attempt, std::move(auth_required_callback));
+ auto loginDelegate = base::MakeRefCounted<LoginDelegateQt>(authInfo, web_contents_getter, url, first_auth_attempt, std::move(auth_required_callback));
+ loginDelegate->triggerDialog();
+ return loginDelegate;
}
-} // namespace QtWebEngineCore
+bool ContentBrowserClientQt::ShouldIsolateErrorPage(bool in_main_frame)
+{
+ Q_UNUSED(in_main_frame);
+ return false;
+}
-DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::ServiceDriver);
+bool ContentBrowserClientQt::ShouldUseProcessPerSite(content::BrowserContext* browser_context, const GURL& effective_url)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (effective_url.SchemeIs(extensions::kExtensionScheme))
+ return true;
+#endif
+ return ContentBrowserClient::ShouldUseProcessPerSite(browser_context, effective_url);
+}
+
+std::string ContentBrowserClientQt::getUserAgent()
+{
+ // Mention the Chromium version we're based on to get passed stupid UA-string-based feature detection (several WebRTC demos need this)
+ return content::BuildUserAgentFromProduct("QtWebEngine/" QTWEBENGINECORE_VERSION_STR " Chrome/" CHROMIUM_VERSION);
+}
+
+std::string ContentBrowserClientQt::GetProduct() const
+{
+ QString productName(qApp->applicationName() % '/' % qApp->applicationVersion());
+ return productName.toStdString();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index b2761b311..0b1c134cc 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -108,33 +108,36 @@ public:
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(content::ResourceContext *resource_context) override;
content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() override;
+ content::PlatformNotificationService *GetPlatformNotificationService() override;
std::string GetApplicationLocale() override;
std::string GetAcceptLangs(content::BrowserContext* context) override;
void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override;
+
+ void GetAdditionalViewSourceSchemes(std::vector<std::string>* additional_schemes) override;
void GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes) override;
void BindInterfaceRequestFromFrame(content::RenderFrameHost* render_frame_host,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
- void RegisterInProcessServices(StaticServiceMap* services, content::ServiceManagerConnection* connection) override;
+ void RegisterIOThreadServiceHandlers(content::ServiceManagerConnection *connection) override;
void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
- std::vector<ServiceManifestInfo> GetExtraServiceManifests() override;
- std::unique_ptr<base::Value> GetServiceManifestOverlay(base::StringPiece name) override;
- bool CanCreateWindow(
- content::RenderFrameHost* opener,
- const GURL& opener_url,
- const GURL& opener_top_level_frame_url,
- const GURL& source_origin,
- content::mojom::WindowContainerType container_type,
- const GURL& target_url,
- const content::Referrer& referrer,
- const std::string& frame_name,
- WindowOpenDisposition disposition,
- const blink::mojom::WindowFeatures& features,
- bool user_gesture,
- bool opener_suppressed,
- bool* no_javascript_access) override;
+ std::vector<service_manager::Manifest> GetExtraServiceManifests() override;
+ base::Optional<service_manager::Manifest> GetServiceManifestOverlay(base::StringPiece name) override;
+ bool CanCreateWindow(content::RenderFrameHost *opener,
+ const GURL &opener_url,
+ const GURL &opener_top_level_frame_url,
+ const url::Origin &source_origin,
+ content::mojom::WindowContainerType container_type,
+ const GURL &target_url,
+ const content::Referrer &referrer,
+ const std::string &frame_name,
+ WindowOpenDisposition disposition,
+ const blink::mojom::WindowFeatures &features,
+ bool user_gesture,
+ bool opener_suppressed,
+ bool *no_javascript_access) override;
+ bool ShouldEnableStrictSiteIsolation() override;
bool AllowGetCookie(const GURL& url,
const GURL& first_party,
@@ -157,21 +160,22 @@ public:
bool AllowServiceWorker(const GURL& scope,
const GURL& first_party,
content::ResourceContext* context,
- const base::Callback<content::WebContents*(void)>& wc_getter) override;
+ base::RepeatingCallback<content::WebContents*()> wc_getter) override;
void AllowWorkerFileSystem(const GURL &url,
content::ResourceContext *context,
- const std::vector<std::pair<int, int> > &render_frames,
+ const std::vector<content::GlobalFrameRoutingId> &render_frames,
base::Callback<void(bool)> callback) override;
bool AllowWorkerIndexedDB(const GURL &url,
- const base::string16 &name,
content::ResourceContext *context,
- const std::vector<std::pair<int, int> > &render_frames) override;
+ const std::vector<content::GlobalFrameRoutingId> &render_frames) override;
#if QT_CONFIG(webengine_geolocation)
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider() override;
#endif
+ bool ShouldIsolateErrorPage(bool in_main_frame) override;
+ bool ShouldUseProcessPerSite(content::BrowserContext* browser_context, const GURL& effective_url) override;
#if defined(Q_OS_LINUX)
void GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings) override;
@@ -194,10 +198,17 @@ public:
const GURL &url,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
int child_id,
- content::NavigationUIData *navigation_data,
+ content::NavigationUIData *navigation_data,
bool is_main_frame,
ui::PageTransition page_transition,
- bool has_user_gesture) override;
+ bool has_user_gesture,
+ const std::string &method,
+ const net::HttpRequestHeaders &headers) override;
+
+ static std::string getUserAgent();
+
+ std::string GetUserAgent() const override { return getUserAgent(); }
+ std::string GetProduct() const override;
private:
void InitFrameInterfaces();
@@ -205,6 +216,7 @@ private:
BrowserMainPartsQt* m_browserMainParts;
std::unique_ptr<content::ResourceDispatcherHostDelegate> m_resourceDispatcherHostDelegate;
+ std::unique_ptr<content::PlatformNotificationService> m_platformNotificationService;
scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick;
std::unique_ptr<service_manager::BinderRegistry> m_frameInterfaces;
std::unique_ptr<service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>> m_frameInterfacesParameterized;
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index df1bc303d..8e5fdf06c 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -48,7 +48,6 @@
#include "base/version.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_constants.h"
-#include "content/public/common/user_agent.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
#include "media/media_buildflags.h"
@@ -56,7 +55,6 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
-#include "net/qrc_protocol_handler_qt.h"
#include "type_conversion.h"
#include <QCoreApplication>
@@ -66,10 +64,9 @@
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_paths.h" // nogncheck
+#include "third_party/widevine/cdm/buildflags.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
-#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
-#define WIDEVINE_CDM_AVAILABLE
-#if defined(WIDEVINE_CDM_AVAILABLE) && !defined(WIDEVINE_CDM_IS_COMPONENT)
+#if BUILDFLAG(ENABLE_WIDEVINE) && !BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
#define WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT
namespace switches {
const char kCdmWidevinePath[] = "widevine-path";
@@ -85,6 +82,14 @@ const char kWidevineCdmFileName[] =
#endif
#endif
+#if QT_CONFIG(webengine_printing_and_pdf)
+#include "pdf/pdf.h"
+#include "pdf/pdf_ppapi.h"
+const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
+const char kPdfPluginPath[] = "internal-pdf-viewer/";
+const char kPdfPluginSrc[] = "src";
+#endif // QT_CONFIG(webengine_printing_and_pdf)
+
static QString webenginePluginsPath()
{
// Look for plugins in /plugins/webengine or application dir.
@@ -99,7 +104,6 @@ static QString webenginePluginsPath()
}
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
-
#if defined(Q_OS_WIN)
#include <shlobj.h>
static QString getLocalAppDataDir()
@@ -235,10 +239,30 @@ void AddPepperFlashFromCommandLine(std::vector<content::PepperPluginInfo>* plugi
plugins->push_back(CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
}
+void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins)
+{
+#if QT_CONFIG(webengine_printing_and_pdf)
+ content::PepperPluginInfo pdf_info;
+ pdf_info.is_internal = true;
+ pdf_info.is_out_of_process = true;
+ pdf_info.name = "Chromium PDF Viewer";
+ pdf_info.description = "Portable Document Format";
+ pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
+ content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf", "Portable Document Format");
+ pdf_info.mime_types.push_back(pdf_mime_type);
+ pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface;
+ pdf_info.internal_entry_points.initialize_module = chrome_pdf::PPP_InitializeModule;
+ pdf_info.internal_entry_points.shutdown_module = chrome_pdf::PPP_ShutdownModule;
+ pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV | ppapi::PERMISSION_PDF;
+ plugins->push_back(pdf_info);
+#endif // QT_CONFIG(webengine_printing_and_pdf)
+}
+
namespace QtWebEngineCore {
void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins)
{
+ ComputeBuiltInPlugins(plugins);
AddPepperFlashFromSystem(plugins);
AddPepperFlashFromCommandLine(plugins);
}
@@ -330,7 +354,6 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
}
#endif // defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT)
-
void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo> *cdms,
std::vector<media::CdmHostFilePath> *cdm_host_file_paths)
{
@@ -386,10 +409,9 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo>
}
}
-std::string ContentClientQt::getUserAgent()
+void ContentClientQt::AddAdditionalSchemes(Schemes* schemes)
{
- // Mention the Chromium version we're based on to get passed stupid UA-string-based feature detection (several WebRTC demos need this)
- return content::BuildUserAgentFromProduct("QtWebEngine/" QTWEBENGINECORE_VERSION_STR " Chrome/" CHROMIUM_VERSION);
+ schemes->standard_schemes.push_back("chrome-extension");
}
base::StringPiece ContentClientQt::GetDataResource(int resource_id, ui::ScaleFactor scale_factor) const {
@@ -401,15 +423,14 @@ base::RefCountedMemory *ContentClientQt::GetDataResourceBytes(int resource_id) c
return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes(resource_id);
}
-base::string16 ContentClientQt::GetLocalizedString(int message_id) const
+gfx::Image &ContentClientQt::GetNativeImageNamed(int resource_id) const
{
- return l10n_util::GetStringUTF16(message_id);
+ return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);
}
-std::string ContentClientQt::GetProduct() const
+base::string16 ContentClientQt::GetLocalizedString(int message_id) const
{
- QString productName(qApp->applicationName() % '/' % qApp->applicationVersion());
- return productName.toStdString();
+ return l10n_util::GetStringUTF16(message_id);
}
} // namespace QtWebEngineCore
diff --git a/src/core/content_client_qt.h b/src/core/content_client_qt.h
index fbafa6a4b..1f4ac0b63 100644
--- a/src/core/content_client_qt.h
+++ b/src/core/content_client_qt.h
@@ -49,19 +49,17 @@ namespace QtWebEngineCore {
class ContentClientQt : public content::ContentClient {
public:
- static std::string getUserAgent();
-
#if QT_CONFIG(webengine_pepper_plugins)
void AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) override;
#endif
void AddContentDecryptionModules(std::vector<content::CdmInfo> *cdms,
std::vector<media::CdmHostFilePath> *cdm_host_file_paths) override;
+ void AddAdditionalSchemes(Schemes* schemes) override;
base::StringPiece GetDataResource(int, ui::ScaleFactor) const override;
- base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override;
- std::string GetUserAgent() const override { return getUserAgent(); }
+ base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override;
+ gfx::Image &GetNativeImageNamed(int resource_id) const override;
base::string16 GetLocalizedString(int message_id) const override;
- std::string GetProduct() const override;
};
} // namespace QtWebEngineCore
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 2811d5545..57f8af63c 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -40,17 +40,18 @@
#include "content_main_delegate_qt.h"
#include "base/command_line.h"
-#include <base/i18n/rtl.h>
+#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
-#include <chrome/grit/generated_resources.h>
+#include "chrome/grit/generated_resources.h"
+#include "content/public/browser/browser_main_runner.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/resource/resource_bundle.h"
-#include <ui/base/webui/jstemplate_builder.h>
+#include "ui/base/webui/jstemplate_builder.h"
#include "net/grit/net_resources.h"
#include "net/base/net_module.h"
#include "services/service_manager/sandbox/switches.h"
@@ -59,6 +60,7 @@
#include "content_client_qt.h"
#include "renderer/content_renderer_client_qt.h"
#include "type_conversion.h"
+#include "web_engine_context.h"
#include "web_engine_library_info.h"
#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
@@ -71,6 +73,10 @@
#include <QtCore/qcoreapplication.h>
+namespace content {
+ContentClient *GetContentClient();
+}
+
namespace QtWebEngineCore {
// The logic of this function is based on chrome/common/net/net_resource_provider.cc
@@ -167,6 +173,12 @@ content::ContentBrowserClient *ContentMainDelegateQt::CreateContentBrowserClient
return m_browserClient.get();
}
+content::ContentGpuClient *ContentMainDelegateQt::CreateContentGpuClient()
+{
+ m_gpuClient.reset(new ContentGpuClientQt);
+ return m_gpuClient.get();
+}
+
content::ContentRendererClient *ContentMainDelegateQt::CreateContentRendererClient()
{
#if defined(OS_LINUX)
@@ -214,14 +226,13 @@ static void SafeOverridePathImpl(const char *keyName, int key, const base::FileP
bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
{
SafeOverridePath(base::FILE_EXE, WebEngineLibraryInfo::getPath(base::FILE_EXE));
-#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
SafeOverridePath(base::DIR_QT_LIBRARY_DATA, WebEngineLibraryInfo::getPath(base::DIR_QT_LIBRARY_DATA));
-#endif
SafeOverridePath(ui::DIR_LOCALES, WebEngineLibraryInfo::getPath(ui::DIR_LOCALES));
#if QT_CONFIG(webengine_spellchecker)
SafeOverridePath(base::DIR_APP_DICTIONARIES, WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES));
#endif
- SetContentClient(new ContentClientQt);
+ if (!content::GetContentClient())
+ content::SetContentClient(new ContentClientQt);
url::CustomScheme::LoadSchemes(base::CommandLine::ForCurrentProcess());
diff --git a/src/core/content_main_delegate_qt.h b/src/core/content_main_delegate_qt.h
index c06afb0fb..4d2f33792 100644
--- a/src/core/content_main_delegate_qt.h
+++ b/src/core/content_main_delegate_qt.h
@@ -42,6 +42,7 @@
#include "content/public/app/content_main_delegate.h"
+#include "compositor/content_gpu_client_qt.h"
#include "content_browser_client_qt.h"
#include "content_utility_client_qt.h"
@@ -56,12 +57,14 @@ public:
void PreSandboxStartup() override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
+ content::ContentGpuClient* CreateContentGpuClient() override;
content::ContentRendererClient* CreateContentRendererClient() override;
content::ContentUtilityClient* CreateContentUtilityClient() override;
bool BasicStartupComplete(int* /*exit_code*/) override;
private:
std::unique_ptr<ContentBrowserClientQt> m_browserClient;
+ std::unique_ptr<ContentGpuClientQt> m_gpuClient;
std::unique_ptr<ContentUtilityClientQt> m_utilityClient;
};
diff --git a/src/core/content_utility_client_qt.cpp b/src/core/content_utility_client_qt.cpp
index f49fa6386..0b2dbd08e 100644
--- a/src/core/content_utility_client_qt.cpp
+++ b/src/core/content_utility_client_qt.cpp
@@ -39,6 +39,7 @@
#include "content_utility_client_qt.h"
+#include "base/bind.h"
#include "content/public/utility/utility_thread.h"
#include "services/proxy_resolver/proxy_resolver_service.h"
@@ -50,12 +51,41 @@ ContentUtilityClientQt::ContentUtilityClientQt()
ContentUtilityClientQt::~ContentUtilityClientQt() = default;
-void ContentUtilityClientQt::RegisterServices(ContentUtilityClient::StaticServiceMap *services)
+namespace {
+
+std::unique_ptr<service_manager::Service> CreateProxyResolverService(service_manager::mojom::ServiceRequest request)
{
- service_manager::EmbeddedServiceInfo proxy_resolver_info;
- proxy_resolver_info.task_runner = content::ChildThread::Get()->GetIOTaskRunner();
- proxy_resolver_info.factory = base::BindRepeating(&proxy_resolver::ProxyResolverService::CreateService);
- services->emplace(proxy_resolver::mojom::kProxyResolverServiceName, proxy_resolver_info);
+ return std::make_unique<proxy_resolver::ProxyResolverService>(std::move(request));
+}
+
+using ServiceFactory = base::OnceCallback<std::unique_ptr<service_manager::Service>()>;
+void RunServiceOnIOThread(ServiceFactory factory)
+{
+ base::OnceClosure terminate_process = base::BindOnce(
+ base::IgnoreResult(&base::SequencedTaskRunner::PostTask),
+ base::SequencedTaskRunnerHandle::Get(), FROM_HERE,
+ base::BindOnce([] { content::UtilityThread::Get()->ReleaseProcess(); }));
+ content::ChildThread::Get()->GetIOTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](ServiceFactory factory, base::OnceClosure terminate_process) {
+ service_manager::Service::RunAsyncUntilTermination(
+ std::move(factory).Run(), std::move(terminate_process));
+ },
+ std::move(factory), std::move(terminate_process)));
+}
+
+} // namespace
+
+bool ContentUtilityClientQt::HandleServiceRequest(const std::string &service_name,
+ service_manager::mojom::ServiceRequest request)
+{
+ if (service_name == proxy_resolver::mojom::kProxyResolverServiceName) {
+ RunServiceOnIOThread(base::BindOnce(&CreateProxyResolverService, std::move(request)));
+ return true;
+ }
+
+ return false;
}
} // namespace
diff --git a/src/core/content_utility_client_qt.h b/src/core/content_utility_client_qt.h
index 3fb7c97d5..79972adb8 100644
--- a/src/core/content_utility_client_qt.h
+++ b/src/core/content_utility_client_qt.h
@@ -53,7 +53,9 @@ public:
~ContentUtilityClientQt() override;
// content::ContentUtilityClient:
- void RegisterServices(StaticServiceMap *services) override;
+ bool HandleServiceRequest(const std::string &service_name,
+ service_manager::mojom::ServiceRequest request) override;
+
};
} // namespace
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index 5566dbef7..8ff79c782 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -1,10 +1,5 @@
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
-QT_FOR_CONFIG += webenginecore webenginecore-private
-
qtConfig(debug_and_release): CONFIG += debug_and_release
-include(core_common.pri)
-
macos {
# This fixes namespace builds on macOS. Specifically namespace ambiguity issues between Qt and
# Chromium forward declarations of NSString.
@@ -35,7 +30,13 @@ qtConfig(webengine-embedded-build): DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES
INCLUDEPATH += $$PWD $$PWD/api
+clang_cl {
+ QMAKE_CFLAGS -= $$QMAKE_CFLAGS_MSVC_COMPAT
+ QMAKE_CXXFLAGS -= $$QMAKE_CFLAGS_MSVC_COMPAT
+}
+
SOURCES = \
+ accessibility_activation_observer.cpp \
accessibility_tree_formatter_qt.cpp \
authentication_dialog_controller.cpp \
browser_accessibility_manager_qt.cpp \
@@ -44,21 +45,24 @@ SOURCES = \
browser_main_parts_qt.cpp \
browser_message_filter_qt.cpp \
certificate_error_controller.cpp \
- chromium_gpu_helper.cpp \
chromium_overrides.cpp \
client_cert_select_controller.cpp \
clipboard_qt.cpp \
color_chooser_qt.cpp \
color_chooser_controller.cpp \
+ command_line_pref_store_qt.cpp \
common/qt_ipc_logging.cpp \
common/qt_messages.cpp \
common/user_script_data.cpp \
- compositor.cpp \
+ compositor/chromium_gpu_helper.cpp \
+ compositor/compositor.cpp \
+ compositor/compositor_resource_tracker.cpp \
+ compositor/content_gpu_client_qt.cpp \
+ compositor/delegated_frame_node.cpp \
content_client_qt.cpp \
content_browser_client_qt.cpp \
content_main_delegate_qt.cpp \
content_utility_client_qt.cpp \
- delegated_frame_node.cpp \
desktop_screen_qt.cpp \
devtools_frontend_qt.cpp \
devtools_manager_delegate_qt.cpp \
@@ -70,27 +74,29 @@ SOURCES = \
login_delegate_qt.cpp \
media_capture_devices_dispatcher.cpp \
native_web_keyboard_event_qt.cpp \
+ net/client_cert_override.cpp \
+ net/client_cert_store_data.cpp \
net/cookie_monster_delegate_qt.cpp \
net/custom_protocol_handler.cpp \
net/network_delegate_qt.cpp \
net/proxy_config_service_qt.cpp \
- net/qrc_protocol_handler_qt.cpp \
+ net/qrc_url_scheme_handler.cpp \
net/ssl_host_state_delegate_qt.cpp \
net/url_request_context_getter_qt.cpp \
net/url_request_custom_job.cpp \
net/url_request_custom_job_delegate.cpp \
net/url_request_custom_job_proxy.cpp \
- net/url_request_qrc_job_qt.cpp \
+ net/url_request_notification.cpp \
net/webui_controller_factory_qt.cpp \
ozone/gl_context_qt.cpp \
ozone/gl_ozone_egl_qt.cpp \
ozone/gl_surface_qt.cpp \
ozone/gl_surface_egl_qt.cpp \
ozone/gl_surface_wgl_qt.cpp \
- ozone/ozone_platform_qt.cpp \
ozone/platform_window_qt.cpp \
ozone/surface_factory_qt.cpp \
permission_manager_qt.cpp \
+ platform_notification_service_qt.cpp \
process_main.cpp \
profile_adapter.cpp \
profile_adapter_client.cpp \
@@ -100,30 +106,37 @@ SOURCES = \
quota_request_controller_impl.cpp \
register_protocol_handler_request_controller_impl.cpp \
render_view_context_menu_qt.cpp \
- render_view_observer_host_qt.cpp \
render_widget_host_view_qt.cpp \
renderer/content_renderer_client_qt.cpp \
renderer/content_settings_observer_qt.cpp \
renderer/render_frame_observer_qt.cpp \
renderer/render_view_observer_qt.cpp \
+ renderer/render_thread_observer_qt.cpp \
renderer/user_resource_controller.cpp \
+ renderer_host/render_view_observer_host_qt.cpp \
renderer_host/user_resource_controller_host.cpp \
resource_bundle_qt.cpp \
resource_context_qt.cpp \
service/service_qt.cpp \
+ touch_handle_drawable_qt.cpp \
+ touch_selection_controller_client_qt.cpp \
+ touch_selection_menu_controller.cpp \
type_conversion.cpp \
+ user_notification_controller.cpp \
user_script.cpp \
visited_links_manager_qt.cpp \
web_contents_adapter.cpp \
web_contents_delegate_qt.cpp \
web_contents_view_qt.cpp \
web_engine_context.cpp \
+ web_engine_context_threads.cpp \
web_engine_error.cpp \
web_engine_library_info.cpp \
web_engine_settings.cpp \
web_event_factory.cpp
HEADERS = \
+ accessibility_activation_observer.h \
authentication_dialog_controller_p.h \
authentication_dialog_controller.h \
build_config_qt.h \
@@ -134,53 +147,60 @@ HEADERS = \
browser_message_filter_qt.h \
certificate_error_controller_p.h \
certificate_error_controller.h \
- chromium_overrides.h \
client_cert_select_controller.h \
+ clipboard_change_observer.h \
clipboard_qt.h \
+ command_line_pref_store_qt.h \
color_chooser_qt.h \
color_chooser_controller_p.h \
color_chooser_controller.h \
common/qt_messages.h \
common/user_script_data.h \
- compositor.h \
+ compositor/chromium_gpu_helper.h \
+ compositor/compositor.h \
+ compositor/compositor_resource.h \
+ compositor/compositor_resource_tracker.h \
+ compositor/content_gpu_client_qt.h \
+ compositor/delegated_frame_node.h \
content_client_qt.h \
content_browser_client_qt.h \
content_main_delegate_qt.h \
content_utility_client_qt.h \
- delegated_frame_node.h \
desktop_screen_qt.h \
devtools_frontend_qt.h \
devtools_manager_delegate_qt.h \
download_manager_delegate_qt.h \
- chromium_gpu_helper.h \
favicon_manager.h \
file_picker_controller.h \
global_descriptors_qt.h \
javascript_dialog_controller_p.h \
javascript_dialog_controller.h \
javascript_dialog_manager_qt.h \
+ locked_ptr.h \
login_delegate_qt.h \
media_capture_devices_dispatcher.h \
+ net/client_cert_override.h \
+ net/client_cert_store_data.h \
net/cookie_monster_delegate_qt.h \
net/custom_protocol_handler.h \
net/network_delegate_qt.h \
- net/qrc_protocol_handler_qt.h \
+ net/qrc_url_scheme_handler.h \
net/ssl_host_state_delegate_qt.h \
net/url_request_context_getter_qt.h \
net/url_request_custom_job.h \
net/url_request_custom_job_delegate.h \
net/url_request_custom_job_proxy.h \
- net/url_request_qrc_job_qt.h \
+ net/url_request_notification.h \
net/webui_controller_factory_qt.h \
ozone/gl_context_qt.h \
ozone/gl_ozone_egl_qt.h \
ozone/gl_surface_qt.h \
ozone/gl_surface_egl_qt.h \
ozone/gl_surface_wgl_qt.h \
- ozone/ozone_platform_qt.h \
ozone/platform_window_qt.h \
ozone/surface_factory_qt.h \
permission_manager_qt.h \
+ platform_notification_service_qt.h \
process_main.h \
profile_adapter.h \
profile_adapter_client.h \
@@ -193,19 +213,25 @@ HEADERS = \
register_protocol_handler_request_controller.h \
register_protocol_handler_request_controller_impl.h \
render_view_context_menu_qt.h \
- render_view_observer_host_qt.h \
render_widget_host_view_qt.h \
render_widget_host_view_qt_delegate.h \
renderer/content_renderer_client_qt.h \
renderer/content_settings_observer_qt.h \
renderer/render_frame_observer_qt.h \
renderer/render_view_observer_qt.h \
+ renderer/render_thread_observer_qt.h \
renderer/user_resource_controller.h \
+ renderer_host/render_view_observer_host_qt.h \
renderer_host/user_resource_controller_host.h \
request_controller.h \
resource_context_qt.h \
service/service_qt.h \
+ touch_handle_drawable_client.h \
+ touch_handle_drawable_qt.h \
+ touch_selection_controller_client_qt.h \
+ touch_selection_menu_controller.h \
type_conversion.h \
+ user_notification_controller.h \
user_script.h \
visited_links_manager_qt.h \
web_contents_adapter.h \
@@ -264,12 +290,14 @@ qtConfig(webengine-printing-and-pdf) {
contains(QT_CONFIG, opengl) {
SOURCES += \
- yuv_video_node.cpp \
- stream_video_node.cpp
+ compositor/compositor_resource_fence.cpp \
+ compositor/stream_video_node.cpp \
+ compositor/yuv_video_node.cpp
HEADERS += \
- yuv_video_node.h \
- stream_video_node.h
+ compositor/compositor_resource_fence.h \
+ compositor/stream_video_node.h \
+ compositor/yuv_video_node.h
}
qtConfig(webengine-geolocation) {
@@ -284,3 +312,39 @@ qtConfig(webengine-webchannel) {
SOURCES += renderer/web_channel_ipc_transport.cpp \
renderer_host/web_channel_ipc_transport_host.cpp
}
+
+qtConfig(webengine-extensions) {
+ SOURCES += \
+ common/extensions/extensions_api_provider_qt.cpp \
+ common/extensions/extensions_client_qt.cpp \
+ extensions/component_extension_resource_manager_qt.cpp \
+ extensions/extension_system_qt.cpp \
+ extensions/extension_system_factory_qt.cpp \
+ extensions/extension_web_contents_observer_qt.cpp \
+ extensions/extensions_api_client_qt.cpp \
+ extensions/extensions_browser_api_provider_qt.cpp \
+ extensions/extensions_browser_client_qt.cpp \
+ extensions/mime_handler_view_guest_delegate_qt.cpp \
+ renderer/extensions/extensions_dispatcher_delegate_qt.cpp \
+ renderer/extensions/extensions_renderer_client_qt.cpp \
+ renderer/extensions/renderer_permissions_policy_delegate_qt.cpp \
+ renderer/extensions/resource_request_policy_qt.cpp \
+ renderer_host/resource_dispatcher_host_delegate_qt.cpp
+
+ HEADERS += \
+ common/extensions/extensions_api_provider_qt.h \
+ common/extensions/extensions_client_qt.h \
+ extensions/component_extension_resource_manager_qt.h \
+ extensions/extension_system_qt.h \
+ extensions/extension_system_factory_qt.h \
+ extensions/extension_web_contents_observer_qt.h \
+ extensions/extensions_api_client_qt.h \
+ extensions/extensions_browser_api_provider_qt.h \
+ extensions/extensions_browser_client_qt.h \
+ extensions/mime_handler_view_guest_delegate_qt.h \
+ renderer/extensions/extensions_dispatcher_delegate_qt.h \
+ renderer/extensions/extensions_renderer_client_qt.h \
+ renderer/extensions/renderer_permissions_policy_delegate_qt.h \
+ renderer/extensions/resource_request_policy_qt.h \
+ renderer_host/resource_dispatcher_host_delegate_qt.h
+}
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
index 01f40eb09..c92278657 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -1,3 +1,6 @@
+include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
+QT_FOR_CONFIG += webenginecore webenginecore-private
+
# NOTE: The TARGET, QT, QT_PRIVATE variables are used in both core_module.pro and core_gyp_generator.pro
# gyp/ninja will take care of the compilation, qmake/make will finish with linking and install.
@@ -13,3 +16,7 @@ CONFIG -= ltcg
# Chromium requires C++14
CONFIG += c++14
+
+#QTBUG-73216 ci has to be updated with latest yocto
+boot2qt: CONFIG -= use_gold_linker
+
diff --git a/src/core/core_generator.pro b/src/core/core_generator.pro
index 916c211f9..935c653a4 100644
--- a/src/core/core_generator.pro
+++ b/src/core/core_generator.pro
@@ -1,3 +1,5 @@
+include(core_common.pri)
+
include(core_gn_config.pri)
TEMPLATE = lib
diff --git a/src/core/core_gn_config.pri b/src/core/core_gn_config.pri
index 9b0145dfc..a089eecd0 100644
--- a/src/core/core_gn_config.pri
+++ b/src/core/core_gn_config.pri
@@ -4,8 +4,13 @@ GN_FILE = $$OUT_PWD/$$getConfigDir()/BUILD.gn
GN_FIND_MOCABLES_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_find_mocables.py)
GN_RUN_BINARY_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_run_binary.py)
GN_IMPORTS = $$PWD/qtwebengine.gni
-GN_INCLUDES = $$PWD/qtwebengine_sources.gni $$PWD/qtwebengine_resources.gni
+qtConfig (webengine-extensions) {
+ GN_INCLUDES += $$PWD/qtwebengine_sources.gni $$PWD/qtwebengine_resources.gni $$PWD/common/extensions/api/qtwebengine_extensions_features.gni
+} else {
+ GN_INCLUDES = $$PWD/qtwebengine_sources.gni $$PWD/qtwebengine_resources.gni
+}
GN_CORE_INCLUDE_DIRS = $$PWD/service
GN_CREATE_PRI = true
QMAKE_INTERNAL_INCLUDED_FILES = $$GN_IMPORTS $$GN_INCLUDES $$GN_FILE
+
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 7bcd916a1..b220af4a5 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -62,12 +62,12 @@ LIBS_PRIVATE += -L$$api_library_path
CONFIG *= no_smart_library_merge
osx {
LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
-} else:msvc {
+} else: win32 {
!isDeveloperBuild() {
# Remove unused functions and data in debug non-developer builds, because the binaries will
# be smaller in the shipped packages.
QMAKE_LFLAGS += /OPT:REF
- } else:CONFIG(debug, debug|release) {
+ } else:CONFIG(debug, debug|release):!clang_cl {
# Make sure to override qtbase's QMAKE_LFLAGS_DEBUG option in debug developer builds,
# because qmake chooses and overrides the option when it gets appended to QMAKE_LFLAGS in
# qtbase\mkspecs\features\default_post.prf, regardless of what Chromium passes back from GN.
@@ -81,7 +81,7 @@ osx {
QMAKE_LFLAGS += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive
}
-win32-msvc* {
+win32 {
POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib
} else {
POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
diff --git a/src/core/core_project.pro b/src/core/core_project.pro
index ecb4a3ab5..9c8e20808 100644
--- a/src/core/core_project.pro
+++ b/src/core/core_project.pro
@@ -3,6 +3,7 @@ TEMPLATE = lib
include(core_common.pri)
+
linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
!include($$linking_pri) {
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index fc91fd75f..28af84bd3 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -48,6 +48,7 @@
#include "profile_qt.h"
#include "web_contents_adapter.h"
+#include "base/base64.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/json/string_escape.h"
@@ -56,11 +57,13 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/values.h"
#include "chrome/common/url_constants.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_handle.h"
@@ -71,12 +74,10 @@
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
#include "ipc/ipc_channel.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_fetcher_response_writer.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
using namespace QtWebEngineCore;
@@ -100,66 +101,77 @@ std::unique_ptr<base::DictionaryValue> BuildObjectForResponse(const net::HttpRes
return response;
}
-// ResponseWriter -------------------------------------------------------------
-
-class ResponseWriter : public net::URLFetcherResponseWriter {
-public:
- ResponseWriter(base::WeakPtr<DevToolsFrontendQt> shell_devtools_, int stream_id);
- ~ResponseWriter() override;
-
- // URLFetcherResponseWriter overrides:
- int Initialize(const net::CompletionCallback &callback) override;
- int Write(net::IOBuffer *buffer, int num_bytes, const net::CompletionCallback &callback) override;
- int Finish(int net_error, const net::CompletionCallback &callback) override;
+static std::string GetFrontendURL()
+{
+ return "chrome-devtools://devtools/bundled/devtools_app.html";
+}
-private:
- base::WeakPtr<DevToolsFrontendQt> shell_devtools_;
- int stream_id_;
+} // namespace
- DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
-};
+namespace QtWebEngineCore {
-ResponseWriter::ResponseWriter(base::WeakPtr<DevToolsFrontendQt> shell_devtools, int stream_id)
- : shell_devtools_(shell_devtools), stream_id_(stream_id)
-{}
+class DevToolsFrontendQt::NetworkResourceLoader
+ : public network::SimpleURLLoaderStreamConsumer {
+public:
+ NetworkResourceLoader(int stream_id,
+ int request_id,
+ DevToolsFrontendQt *bindings,
+ std::unique_ptr<network::SimpleURLLoader> loader,
+ network::mojom::URLLoaderFactory *url_loader_factory)
+ : stream_id_(stream_id),
+ request_id_(request_id),
+ bindings_(bindings),
+ loader_(std::move(loader))
+ {
+ loader_->SetOnResponseStartedCallback(base::BindOnce(
+ &NetworkResourceLoader::OnResponseStarted, base::Unretained(this)));
+ loader_->DownloadAsStream(url_loader_factory, this);
+ }
-ResponseWriter::~ResponseWriter() {}
+private:
+ void OnResponseStarted(const GURL &final_url,
+ const network::ResourceResponseHead &response_head)
+ {
+ response_headers_ = response_head.headers;
+ }
-int ResponseWriter::Initialize(const net::CompletionCallback& callback)
-{
- return net::OK;
-}
+ void OnDataReceived(base::StringPiece chunk, base::OnceClosure resume) override
+ {
+ base::Value chunkValue;
+
+ bool encoded = !base::IsStringUTF8(chunk);
+ if (encoded) {
+ std::string encoded_string;
+ base::Base64Encode(chunk, &encoded_string);
+ chunkValue = base::Value(std::move(encoded_string));
+ } else {
+ chunkValue = base::Value(chunk);
+ }
+ base::Value id(stream_id_);
+ base::Value encodedValue(encoded);
-int ResponseWriter::Write(net::IOBuffer *buffer, int num_bytes, const net::CompletionCallback &callback)
-{
- std::string chunk = std::string(buffer->data(), num_bytes);
- if (!base::IsStringUTF8(chunk))
- return num_bytes;
-
- base::Value *id = new base::Value(stream_id_);
- base::Value *chunkValue = new base::Value(chunk);
-
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::BindOnce(&DevToolsFrontendQt::CallClientFunction,
- shell_devtools_, "DevToolsAPI.streamWrite",
- base::Owned(id), base::Owned(chunkValue), nullptr));
- return num_bytes;
-}
+ bindings_->CallClientFunction("DevToolsAPI.streamWrite", &id, &chunkValue, &encodedValue);
+ std::move(resume).Run();
+ }
-int ResponseWriter::Finish(int net_error, const net::CompletionCallback &callback)
-{
- return net::OK;
-}
+ void OnComplete(bool success) override
+ {
+ Q_UNUSED(success);
+ auto response = BuildObjectForResponse(response_headers_.get());
+ bindings_->SendMessageAck(request_id_, response.get());
+ bindings_->m_loaders.erase(bindings_->m_loaders.find(this));
+ }
-static std::string GetFrontendURL()
-{
- return "chrome-devtools://devtools/bundled/devtools_app.html";
-}
+ void OnRetry(base::OnceClosure start_retry) override { NOTREACHED(); }
-} // namespace
+ const int stream_id_;
+ const int request_id_;
+ DevToolsFrontendQt *const bindings_;
+ std::unique_ptr<network::SimpleURLLoader> loader_;
+ scoped_refptr<net::HttpResponseHeaders> response_headers_;
-namespace QtWebEngineCore {
+ DISALLOW_COPY_AND_ASSIGN(NetworkResourceLoader);
+};
// This constant should be in sync with
// the constant at devtools_ui_bindings.cc.
@@ -209,7 +221,7 @@ DevToolsFrontendQt::DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webCon
// We use a separate prefstore than one in ProfileQt, because that one is in-memory only, and this
// needs to be stored or it will show introduction text on every load.
if (webContentsAdapter->profileAdapter()->isOffTheRecord())
- m_prefStore = std::move(scoped_refptr<PersistentPrefStore>(new InMemoryPrefStore()));
+ m_prefStore = scoped_refptr<PersistentPrefStore>(new InMemoryPrefStore());
else
CreateJsonPreferences(false);
@@ -219,8 +231,6 @@ DevToolsFrontendQt::DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webCon
DevToolsFrontendQt::~DevToolsFrontendQt()
{
- for (const auto &pair : m_pendingRequests)
- delete pair.first;
}
void DevToolsFrontendQt::Activate()
@@ -267,9 +277,10 @@ void DevToolsFrontendQt::ReadyToCommitNavigation(content::NavigationHandle *navi
if (navigationHandle->GetURL() != GetFrontendURL())
m_frontendHost.reset(nullptr);
else
- m_frontendHost.reset(content::DevToolsFrontendHost::Create(frame,
- base::Bind(&DevToolsFrontendQt::HandleMessageFromDevToolsFrontend,
- base::Unretained(this))));
+ m_frontendHost = content::DevToolsFrontendHost::Create(
+ frame,
+ base::Bind(&DevToolsFrontendQt::HandleMessageFromDevToolsFrontend,
+ base::Unretained(this)));
}
}
@@ -396,20 +407,29 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
setting:
"It's not possible to disable this feature from settings."
chrome_policy {
- DeveloperToolsDisabled {
+ DeveloperToolsAvailability {
policy_options {mode: MANDATORY}
- DeveloperToolsDisabled: true
+ DeveloperToolsAvailability: 2
}
}
})");
- net::URLFetcher *fetcher = net::URLFetcher::Create(gurl, net::URLFetcher::GET, this, traffic_annotation).release();
- m_pendingRequests[fetcher] = request_id;
- fetcher->SetRequestContext(content::BrowserContext::GetDefaultStoragePartition(
- web_contents()->GetBrowserContext())->GetURLRequestContext());
- fetcher->SetExtraRequestHeaders(headers);
- fetcher->SaveResponseWithWriter(std::unique_ptr<net::URLFetcherResponseWriter>(
- new ResponseWriter(m_weakFactory.GetWeakPtr(), stream_id)));
- fetcher->Start();
+ auto resource_request = std::make_unique<network::ResourceRequest>();
+ resource_request->url = gurl;
+ // TODO(caseq): this preserves behavior of URLFetcher-based implementation.
+ // We really need to pass proper first party origin from the front-end.
+ resource_request->site_for_cookies = gurl;
+ resource_request->headers.AddHeadersFromString(headers);
+
+ auto *partition = content::BrowserContext::GetStoragePartitionForSite(
+ web_contents()->GetBrowserContext(), gurl);
+ auto factory = partition->GetURLLoaderFactoryForBrowserProcess();
+
+ auto simple_url_loader = network::SimpleURLLoader::Create(
+ std::move(resource_request), traffic_annotation);
+ auto resource_loader = std::make_unique<NetworkResourceLoader>(
+ stream_id, request_id, this, std::move(simple_url_loader),
+ factory.get());
+ m_loaders.insert(std::move(resource_loader));
return;
} else if (method == "getPreferences") {
m_preferences = std::move(*m_prefStore->GetValues());
@@ -489,21 +509,6 @@ void DevToolsFrontendQt::DispatchProtocolMessage(content::DevToolsAgentHost *age
}
}
-void DevToolsFrontendQt::OnURLFetchComplete(const net::URLFetcher *source)
-{
- // TODO(pfeldman): this is a copy of chrome's devtools_ui_bindings.cc.
- // We should handle some of the commands including this one in content.
- DCHECK(source);
- PendingRequestsMap::iterator it = m_pendingRequests.find(source);
- DCHECK(it != m_pendingRequests.end());
-
- auto response = BuildObjectForResponse(source->GetResponseHeaders());
-
- SendMessageAck(it->second, response.get());
- m_pendingRequests.erase(it);
- delete source;
-}
-
void DevToolsFrontendQt::CallClientFunction(const std::string &function_name,
const base::Value *arg1,
const base::Value *arg2,
diff --git a/src/core/devtools_frontend_qt.h b/src/core/devtools_frontend_qt.h
index 88cc7aeac..fed2d47fc 100644
--- a/src/core/devtools_frontend_qt.h
+++ b/src/core/devtools_frontend_qt.h
@@ -41,10 +41,12 @@
#define DEVTOOLS_FRONTEND_QT_H
#include <memory>
+#include <set>
#include "web_contents_delegate_qt.h"
#include "base/compiler_specific.h"
+#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -52,7 +54,6 @@
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_frontend_host.h"
#include "content/public/browser/web_contents_observer.h"
-#include "net/url_request/url_fetcher_delegate.h"
namespace base {
class Value;
@@ -69,8 +70,7 @@ class PersistentPrefStore;
namespace QtWebEngineCore {
class DevToolsFrontendQt : public content::WebContentsObserver
- , public content::DevToolsAgentHostClient
- , public net::URLFetcherDelegate {
+ , public content::DevToolsAgentHostClient {
public:
static DevToolsFrontendQt *Show(QSharedPointer<WebContentsAdapter> frontendAdapter, content::WebContents *inspectedContents);
@@ -108,9 +108,6 @@ private:
void DocumentAvailableInMainFrame() override;
void WebContentsDestroyed() override;
- // net::URLFetcherDelegate overrides.
- void OnURLFetchComplete(const net::URLFetcher* source) override;
-
void SendMessageAck(int request_id, const base::Value* arg1);
void SetPreference(const std::string &name, const std::string &value);
void RemovePreference(const std::string &name);
@@ -125,8 +122,10 @@ private:
int m_inspect_element_at_x;
int m_inspect_element_at_y;
std::unique_ptr<content::DevToolsFrontendHost> m_frontendHost;
- using PendingRequestsMap = std::map<const net::URLFetcher*, int>;
- PendingRequestsMap m_pendingRequests;
+
+ class NetworkResourceLoader;
+ std::set<std::unique_ptr<NetworkResourceLoader>, base::UniquePtrComparator> m_loaders;
+
base::DictionaryValue m_preferences;
scoped_refptr<PersistentPrefStore> m_prefStore;
base::WeakPtrFactory<DevToolsFrontendQt> m_weakFactory;
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index f39830ff2..2af958068 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -112,7 +112,7 @@ void DownloadManagerDelegateQt::pauseDownload(quint32 downloadId)
void DownloadManagerDelegateQt::resumeDownload(quint32 downloadId)
{
if (download::DownloadItem *download = findDownloadById(downloadId))
- download->Resume();
+ download->Resume(/* user_resume */ true);
}
void DownloadManagerDelegateQt::removeDownload(quint32 downloadId)
@@ -166,7 +166,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem*
suggestedFilename += QStringLiteral(".") + mimeType.preferredSuffix();
}
- QDir defaultDownloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+ QDir defaultDownloadDirectory(m_profileAdapter->downloadPath());
QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(suggestedFilename));
QString suggestedFilePath = suggestedFile.absoluteFilePath();
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index db965b12d..382c57524 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -104,7 +104,7 @@ private:
void savePackageDownloadCreated(download::DownloadItem *download);
ProfileAdapter *m_profileAdapter;
- uint64_t m_currentId;
+ uint32_t m_currentId;
base::WeakPtrFactory<DownloadManagerDelegateQt> m_weakPtrFactory;
bool m_nextDownloadIsUserRequested;
diff --git a/src/core/extensions/component_extension_resource_manager_qt.cpp b/src/core/extensions/component_extension_resource_manager_qt.cpp
new file mode 100644
index 000000000..57e35c231
--- /dev/null
+++ b/src/core/extensions/component_extension_resource_manager_qt.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// based on chrome/browser/extensions/chrome_component_extension_resource_manager.cc:
+// 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 "component_extension_resource_manager_qt.h"
+
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "chrome/grit/component_extension_resources_map.h"
+
+namespace extensions {
+
+ComponentExtensionResourceManagerQt::ComponentExtensionResourceManagerQt()
+{
+ AddComponentResourceEntries(kComponentExtensionResources,
+ kComponentExtensionResourcesSize);
+}
+
+ComponentExtensionResourceManagerQt::~ComponentExtensionResourceManagerQt() {}
+
+bool ComponentExtensionResourceManagerQt::IsComponentExtensionResource(const base::FilePath &extension_path,
+ const base::FilePath &resource_path,
+ int *resource_id) const
+{
+ base::FilePath directory_path = extension_path;
+ base::FilePath resources_dir;
+ base::FilePath relative_path;
+ if (!base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &resources_dir)
+ || !resources_dir.AppendRelativePath(directory_path, &relative_path)) {
+ return false;
+ }
+
+ relative_path = relative_path.Append(resource_path);
+ relative_path = relative_path.NormalizePathSeparators();
+
+ std::map<base::FilePath, int>::const_iterator entry = path_to_resource_id_.find(relative_path);
+ if (entry != path_to_resource_id_.end())
+ *resource_id = entry->second;
+
+ return entry != path_to_resource_id_.end();
+}
+
+const ui::TemplateReplacements *ComponentExtensionResourceManagerQt::GetTemplateReplacementsForExtension(const std::string &) const
+{
+ return nullptr;
+}
+
+void ComponentExtensionResourceManagerQt::AddComponentResourceEntries(const GritResourceMap *entries, size_t size)
+{
+ for (size_t i = 0; i < size; ++i) {
+ base::FilePath resource_path = base::FilePath().AppendASCII(entries[i].name);
+ resource_path = resource_path.NormalizePathSeparators();
+
+ DCHECK(path_to_resource_id_.find(resource_path) == path_to_resource_id_.end());
+ path_to_resource_id_[resource_path] = entries[i].value;
+ }
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/component_extension_resource_manager_qt.h b/src/core/extensions/component_extension_resource_manager_qt.h
new file mode 100644
index 000000000..2d858630f
--- /dev/null
+++ b/src/core/extensions/component_extension_resource_manager_qt.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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 COMPONENT_EXTENSION_RESOURCE_MANAGER_QT_H_
+#define COMPONENT_EXTENSION_RESOURCE_MANAGER_QT_H_
+
+#include <map>
+
+#include "base/files/file_path.h"
+#include "extensions/browser/component_extension_resource_manager.h"
+
+struct GritResourceMap;
+
+namespace extensions {
+
+class ComponentExtensionResourceManagerQt : public ComponentExtensionResourceManager
+{
+public:
+ ComponentExtensionResourceManagerQt();
+ ~ComponentExtensionResourceManagerQt() override;
+
+ // Overridden from ComponentExtensionResourceManager:
+ bool IsComponentExtensionResource(const base::FilePath &extension_path,
+ const base::FilePath &resource_path,
+ int *resource_id) const override;
+ const ui::TemplateReplacements *GetTemplateReplacementsForExtension(const std::string& extension_id) const override;
+
+private:
+ void AddComponentResourceEntries(const GritResourceMap* entries, size_t size);
+
+ // A map from a resource path to the resource ID. Used by
+ // IsComponentExtensionResource.
+ std::map<base::FilePath, int> path_to_resource_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(ComponentExtensionResourceManagerQt);
+};
+
+} // namespace extensions
+
+#endif // COMPONENT_EXTENSION_RESOURCE_MANAGER_QT_H_
diff --git a/src/core/extensions/extension_system_factory_qt.cpp b/src/core/extensions/extension_system_factory_qt.cpp
new file mode 100644
index 000000000..41ba31214
--- /dev/null
+++ b/src/core/extensions/extension_system_factory_qt.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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 "extension_system_factory_qt.h"
+
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "extensions/browser/declarative_user_script_manager_factory.h"
+#include "extensions/browser/event_router_factory.h"
+#include "extensions/browser/extension_prefs_factory.h"
+#include "extensions/browser/extension_registry_factory.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/extensions_browser_client.h"
+#include "extensions/browser/process_manager_factory.h"
+#include "extensions/browser/renderer_startup_helper.h"
+
+namespace extensions {
+
+// static
+ExtensionSystem *ExtensionSystemFactoryQt::GetForBrowserContext(content::BrowserContext *context)
+{
+ return static_cast<ExtensionSystem *>(GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+ExtensionSystemFactoryQt *ExtensionSystemFactoryQt::GetInstance()
+{
+ return base::Singleton<ExtensionSystemFactoryQt>::get();
+}
+
+ExtensionSystemFactoryQt::ExtensionSystemFactoryQt()
+ : ExtensionSystemProvider("ExtensionSystem", BrowserContextDependencyManager::GetInstance())
+{
+ DCHECK(ExtensionsBrowserClient::Get()) << "ExtensionSystemFactory must be initialized after BrowserProcess";
+ DependsOn(ExtensionPrefsFactory::GetInstance());
+ DependsOn(ExtensionRegistryFactory::GetInstance());
+}
+
+ExtensionSystemFactoryQt::~ExtensionSystemFactoryQt()
+{
+}
+
+KeyedService *ExtensionSystemFactoryQt::BuildServiceInstanceFor(content::BrowserContext *context) const
+{
+ return new ExtensionSystemQt(context);
+}
+
+content::BrowserContext *ExtensionSystemFactoryQt::GetBrowserContextToUse(content::BrowserContext *context) const
+{
+ // Separate instance in incognito.
+ return context;
+}
+
+bool ExtensionSystemFactoryQt::ServiceIsCreatedWithBrowserContext() const
+{
+ return true;
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/extension_system_factory_qt.h b/src/core/extensions/extension_system_factory_qt.h
new file mode 100644
index 000000000..6e840b6d6
--- /dev/null
+++ b/src/core/extensions/extension_system_factory_qt.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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 EXTENSION_SYSTEM_FACTORY_QT_H_
+#define EXTENSION_SYSTEM_FACTORY_QT_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "extensions/browser/extension_system_provider.h"
+#include "extension_system_qt.h"
+
+namespace extensions {
+class ExtensionSystem;
+
+// BrowserContextKeyedServiceFactory for ExtensionSystemImpl.
+// TODO(yoz): Rename to ExtensionSystemImplFactory.
+class ExtensionSystemFactoryQt : public ExtensionSystemProvider
+{
+public:
+ // ExtensionSystem provider implementation:
+ ExtensionSystem *GetForBrowserContext(content::BrowserContext *context) override;
+
+ static ExtensionSystemFactoryQt *GetInstance();
+
+private:
+ friend struct base::DefaultSingletonTraits<ExtensionSystemFactoryQt>;
+
+ ExtensionSystemFactoryQt();
+ ~ExtensionSystemFactoryQt() override;
+
+ // BrowserContextKeyedServiceFactory implementation:
+ KeyedService *BuildServiceInstanceFor(content::BrowserContext *context) const override;
+ content::BrowserContext *GetBrowserContextToUse(content::BrowserContext *context) const override;
+ bool ServiceIsCreatedWithBrowserContext() const override;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionSystemFactoryQt);
+};
+
+} // namespace extensions
+
+#endif // EXTENSION_SYSTEM_FACTORY_QT_H_
diff --git a/src/core/extensions/extension_system_qt.cpp b/src/core/extensions/extension_system_qt.cpp
new file mode 100644
index 000000000..4ca407421
--- /dev/null
+++ b/src/core/extensions/extension_system_qt.cpp
@@ -0,0 +1,447 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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 "extension_system_qt.h"
+
+#include <algorithm>
+
+#include "base/base_paths.h"
+#include "base/base_switches.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/weak_ptr.h"
+#include "base/path_service.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "base/time/time.h"
+#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
+#include "components/crx_file/id_util.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/plugin_service.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/url_data_source.h"
+#include "content/public/common/webplugininfo.h"
+#include "extensions/browser/content_verifier.h"
+#include "extensions/browser/content_verifier_delegate.h"
+#include "extensions/browser/extension_pref_store.h"
+#include "extensions/browser/extension_pref_value_map.h"
+#include "extensions/browser/extension_pref_value_map_factory.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/info_map.h"
+#include "extensions/browser/notification_types.h"
+#include "extensions/browser/null_app_sorting.h"
+#include "extensions/browser/quota_service.h"
+#include "extensions/browser/renderer_startup_helper.h"
+#include "extensions/browser/runtime_data.h"
+#include "extensions/browser/shared_user_script_master.h"
+#include "extensions/browser/service_worker_manager.h"
+#include "extensions/browser/value_store/value_store_factory_impl.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
+#include "extensions/common/manifest_url_handlers.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "chrome/grit/component_extension_resources.h"
+#include "chrome/grit/browser_resources.h"
+#include "net/base/mime_util.h"
+
+using content::BrowserThread;
+
+namespace extensions {
+
+namespace {
+
+std::string GenerateId(const base::DictionaryValue *manifest,
+ const base::FilePath &path)
+{
+ std::string raw_key;
+ std::string id_input;
+ CHECK(manifest->GetString(manifest_keys::kPublicKey, &raw_key));
+ CHECK(Extension::ParsePEMKeyBytes(raw_key, &id_input));
+ std::string id = crx_file::id_util::GenerateId(id_input);
+ return id;
+}
+
+// Implementation based on ComponentLoader::ParseManifest.
+std::unique_ptr<base::DictionaryValue> ParseManifest(const std::string &manifest_contents)
+{
+ JSONStringValueDeserializer deserializer(manifest_contents);
+ std::unique_ptr<base::Value> manifest(deserializer.Deserialize(NULL, NULL));
+
+ if (!manifest.get() || !manifest->is_dict()) {
+ LOG(ERROR) << "Failed to parse extension manifest.";
+ return NULL;
+ }
+ // Transfer ownership to the caller.
+ return base::DictionaryValue::From(std::move(manifest));
+}
+
+} // namespace
+
+// Dummy Content Verifier Delegate. Added to prevent crashes.
+class ContentVerifierDelegateQt
+ : public ContentVerifierDelegate {
+ public:
+ ~ContentVerifierDelegateQt() override {}
+
+ // This should return what verification mode is appropriate for the given
+ // extension, if any.
+ Mode ShouldBeVerified(const Extension& extension) override {
+ return NONE;
+ }
+
+ // Should return the public key to use for validating signatures via the two
+ // out parameters.
+ ContentVerifierKey GetPublicKey() override {
+ return ContentVerifierKey();
+ }
+ // This should return a URL that can be used to fetch the
+ // verified_contents.json containing signatures for the given extension
+ // id/version pair.
+ GURL GetSignatureFetchUrl(const std::string& extension_id,
+ const base::Version& version) override {
+ return GURL();
+ }
+
+ // This should return the set of file paths for images used within the
+ // browser process. (These may get transcoded during the install process).
+ std::set<base::FilePath> GetBrowserImagePaths(
+ const extensions::Extension* extension) override {
+ return std::set<base::FilePath>();
+ }
+
+ // Called when the content verifier detects that a read of a file inside
+ // an extension did not match its expected hash.
+ void VerifyFailed(const std::string& extension_id,
+ ContentVerifyJob::FailureReason reason) override {
+
+ }
+
+ // Called when ExtensionSystem is shutting down.
+ void Shutdown() override {
+
+ }
+};
+
+void ExtensionSystemQt::LoadExtension(std::string extension_id, std::unique_ptr<base::DictionaryValue> manifest, const base::FilePath &directory)
+{
+ int flags = Extension::REQUIRE_KEY;
+ std::string error;
+ scoped_refptr<const Extension> extension = Extension::Create(
+ directory,
+ Manifest::COMPONENT,
+ *manifest,
+ flags,
+ &error);
+ if (!extension.get())
+ LOG(ERROR) << error;
+
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::Bind(&InfoMap::AddExtension,
+ base::Unretained(info_map()),
+ base::RetainedRef(extension),
+ base::Time::Now(),
+ true,
+ false));
+ extension_registry_->AddEnabled(extension.get());
+
+ NotifyExtensionLoaded(extension.get());
+}
+
+void ExtensionSystemQt::OnExtensionRegisteredWithRequestContexts(scoped_refptr<const extensions::Extension> extension)
+{
+ extension_registry_->AddReady(extension);
+ if (extension_registry_->enabled_extensions().Contains(extension->id()))
+ extension_registry_->TriggerOnReady(extension.get());
+}
+
+// Implementation based on ExtensionService::NotifyExtensionLoaded.
+void ExtensionSystemQt::NotifyExtensionLoaded(const Extension *extension)
+{
+ // The URLRequestContexts need to be first to know that the extension
+ // was loaded, otherwise a race can arise where a renderer that is created
+ // for the extension may try to load an extension URL with an extension id
+ // that the request context doesn't yet know about. The profile is responsible
+ // for ensuring its URLRequestContexts appropriately discover the loaded
+ // extension.
+ RegisterExtensionWithRequestContexts(
+ extension,
+ base::Bind(&ExtensionSystemQt::OnExtensionRegisteredWithRequestContexts,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::WrapRefCounted(extension)));
+
+ // Tell renderers about the loaded extension.
+ renderer_helper_->OnExtensionLoaded(*extension);
+
+ // Tell subsystems that use the ExtensionRegistryObserver::OnExtensionLoaded
+ // about the new extension.
+ //
+ // NOTE: It is important that this happen after notifying the renderers about
+ // the new extensions so that if we navigate to an extension URL in
+ // ExtensionRegistryObserver::OnExtensionLoaded the renderer is guaranteed to
+ // know about it.
+ extension_registry_->TriggerOnLoaded(extension);
+
+ // Register plugins included with the extension.
+ // Implementation based on PluginManager::OnExtensionLoaded.
+ const MimeTypesHandler *handler = MimeTypesHandler::GetHandler(extension);
+ if (handler && !handler->handler_url().empty()) {
+ content::WebPluginInfo info;
+ info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
+ info.name = base::UTF8ToUTF16(extension->name());
+ info.path = base::FilePath::FromUTF8Unsafe(extension->url().spec());
+ for (std::set<std::string>::const_iterator mime_type = handler->mime_type_set().begin();
+ mime_type != handler->mime_type_set().end(); ++mime_type) {
+ content::WebPluginMimeType mime_type_info;
+ mime_type_info.mime_type = *mime_type;
+ base::FilePath::StringType file_extension;
+ if (net::GetPreferredExtensionForMimeType(*mime_type, &file_extension)) {
+ mime_type_info.file_extensions.push_back(
+ base::FilePath(file_extension).AsUTF8Unsafe());
+ }
+ info.mime_types.push_back(mime_type_info);
+ }
+ content::PluginService *plugin_service =
+ content::PluginService::GetInstance();
+ plugin_service->RefreshPlugins();
+ plugin_service->RegisterInternalPlugin(info, true);
+ }
+}
+
+bool ExtensionSystemQt::FinishDelayedInstallationIfReady(const std::string &extension_id, bool install_immediately)
+{
+ // TODO mibrunin
+ return false;
+}
+
+void ExtensionSystemQt::Shutdown()
+{
+ if (content_verifier_.get())
+ content_verifier_->Shutdown();
+}
+
+ServiceWorkerManager *ExtensionSystemQt::service_worker_manager()
+{
+ return service_worker_manager_.get();
+}
+
+ExtensionService *ExtensionSystemQt::extension_service()
+{
+ return nullptr;
+}
+
+RuntimeData *ExtensionSystemQt::runtime_data()
+{
+ return runtime_data_.get();
+}
+
+ManagementPolicy *ExtensionSystemQt::management_policy()
+{
+ return nullptr;
+}
+
+SharedUserScriptMaster *ExtensionSystemQt::shared_user_script_master()
+{
+ return shared_user_script_master_.get();
+}
+
+StateStore *ExtensionSystemQt::state_store()
+{
+ return nullptr;
+}
+
+StateStore *ExtensionSystemQt::rules_store()
+{
+ return nullptr;
+}
+
+scoped_refptr<ValueStoreFactory> ExtensionSystemQt::store_factory()
+{
+ return store_factory_;
+}
+
+InfoMap *ExtensionSystemQt::info_map()
+{
+ if (!info_map_.get())
+ info_map_ = new InfoMap;
+ return info_map_.get();
+}
+
+QuotaService *ExtensionSystemQt::quota_service()
+{
+ return quota_service_.get();
+}
+
+AppSorting *ExtensionSystemQt::app_sorting()
+{
+ return app_sorting_.get();
+}
+
+ContentVerifier *ExtensionSystemQt::content_verifier()
+{
+ if (!content_verifier_.get()) {
+ content_verifier_ = new ContentVerifier(browser_context_, std::make_unique<ContentVerifierDelegateQt>());
+ }
+ return content_verifier_.get();
+}
+
+ExtensionSystemQt::ExtensionSystemQt(content::BrowserContext *browserContext)
+ : browser_context_(browserContext)
+ , store_factory_(new ValueStoreFactoryImpl(browserContext->GetPath()))
+ , extension_registry_(ExtensionRegistry::Get(browserContext))
+ , renderer_helper_(extensions::RendererStartupHelperFactory::GetForBrowserContext(browserContext))
+ , initialized_(false)
+ , weak_ptr_factory_(this)
+{
+}
+
+ExtensionSystemQt::~ExtensionSystemQt()
+{
+}
+
+void ExtensionSystemQt::Init(bool extensions_enabled)
+{
+ if (initialized_)
+ return;
+
+ initialized_ = true;
+
+ service_worker_manager_.reset(new ServiceWorkerManager(browser_context_));
+ runtime_data_.reset(new RuntimeData(extension_registry_));
+ quota_service_.reset(new QuotaService);
+ app_sorting_.reset(new NullAppSorting);
+
+ shared_user_script_master_ =
+ std::make_unique<SharedUserScriptMaster>(browser_context_);
+
+ // Make the chrome://extension-icon/ resource available.
+ // content::URLDataSource::Add(browser_context_, new ExtensionIconSource(browser_context_));
+
+ if (extensions_enabled) {
+ // Inform the rest of the extensions system to start.
+ ready_.Signal();
+ content::NotificationService::current()->Notify(
+ NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
+ content::Source<content::BrowserContext>(browser_context_),
+ content::NotificationService::NoDetails());
+
+ std::string pdf_manifest = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_PDF_MANIFEST).as_string();
+ base::ReplaceFirstSubstringAfterOffset(&pdf_manifest, 0, "<NAME>", "chromium-pdf");
+
+ std::unique_ptr<base::DictionaryValue> pdfManifestDict = ParseManifest(pdf_manifest);
+ base::FilePath path;
+ base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &path);
+ path = path.Append(base::FilePath(FILE_PATH_LITERAL("pdf")));
+ std::string id = GenerateId(pdfManifestDict.get(), path);
+ LoadExtension(id, std::move(pdfManifestDict), path);
+ }
+}
+
+void ExtensionSystemQt::InitForRegularProfile(bool extensions_enabled)
+{
+ if (initialized_)
+ return; // Already initialized.
+ // The InfoMap needs to be created before the ProcessManager.
+ info_map();
+
+ Init(extensions_enabled);
+}
+
+void ExtensionSystemQt::InitForIncognitoProfile()
+{
+ NOTIMPLEMENTED();
+}
+
+std::unique_ptr<ExtensionSet> ExtensionSystemQt::GetDependentExtensions(const Extension *extension)
+{
+ return base::WrapUnique(new ExtensionSet());
+}
+
+#if !defined(TOOLKIT_QT)
+void ExtensionSystemQt::InstallUpdate(const std::string &extension_id,
+ const std::string &public_key,
+ const base::FilePath &unpacked_dir,
+ bool install_immediately,
+ InstallUpdateCallback install_update_callback)
+{
+ NOTREACHED() << "Not yet implemented";
+ base::DeleteFile(unpacked_dir, true /* recursive */);
+ std::move(install_update_callback).Run(CrxInstallError(CrxInstallErrorType::DECLINED, CrxInstallErrorDetail::DISALLOWED_BY_POLICY));
+}
+#endif
+
+void ExtensionSystemQt::RegisterExtensionWithRequestContexts(const Extension *extension,
+ const base::Closure &callback)
+{
+ base::Time install_time = base::Time::Now();
+
+ bool incognito_enabled = false;
+ bool notifications_disabled = false;
+
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::IO},
+ base::Bind(&InfoMap::AddExtension, info_map(),
+ base::RetainedRef(extension), install_time, incognito_enabled,
+ notifications_disabled),
+ callback);
+}
+
+void ExtensionSystemQt::UnregisterExtensionWithRequestContexts(const std::string &extension_id,
+ const UnloadedExtensionReason reason)
+{
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::Bind(&InfoMap::RemoveExtension, info_map(), extension_id, reason));
+}
+} // namespace extensions
diff --git a/src/core/extensions/extension_system_qt.h b/src/core/extensions/extension_system_qt.h
new file mode 100644
index 000000000..0ebe1d044
--- /dev/null
+++ b/src/core/extensions/extension_system_qt.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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.
+
+// Large parts of this file are based on the source code from the file
+// chrome/browser/extensions/extension_system_impl.h from the Chromium sources.
+
+#ifndef EXTENSION_SYSTEM_QT_H
+#define EXTENSION_SYSTEM_QT_H
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/common/extension_set.h"
+#include "extensions/common/one_shot_event.h"
+
+namespace extensions {
+
+class ExtensionRegistry;
+class InfoMap;
+class RendererStartupHelper;
+class ServiceWorkerManager;
+class StateStoreNotificationObserver;
+class ValueStoreFactory;
+class ValueStoreFactoryImpl;
+
+// The ExtensionSystem for ProfileImpl and OffTheRecordProfileImpl.
+// Implementation details: non-shared services are owned by
+// ExtensionSystemImpl, a KeyedService with separate incognito
+// instances. A private Shared class (also a KeyedService,
+// but with a shared instance for incognito) keeps the common services.
+class ExtensionSystemQt : public ExtensionSystem
+{
+public:
+ explicit ExtensionSystemQt(content::BrowserContext *browserContext);
+ ~ExtensionSystemQt() override;
+
+ // Initializes the extension system.
+ void Initialize();
+
+ // KeyedService implementation:
+ void Shutdown() override;
+
+ // ExtensionSystem implementation:
+ void InitForRegularProfile(bool extensions_enabled) override;
+ void InitForIncognitoProfile() override;
+ ExtensionService *extension_service() override;
+ RuntimeData *runtime_data() override;
+ ManagementPolicy *management_policy() override;
+ ServiceWorkerManager *service_worker_manager() override;
+ SharedUserScriptMaster *shared_user_script_master() override;
+ StateStore* state_store() override;
+ StateStore* rules_store() override;
+ scoped_refptr<ValueStoreFactory> store_factory() override;
+ InfoMap *info_map() override;
+ QuotaService *quota_service() override;
+ AppSorting *app_sorting() override;
+
+ void RegisterExtensionWithRequestContexts(const Extension *extension,
+ const base::Closure &callback) override;
+
+ void UnregisterExtensionWithRequestContexts(const std::string &extension_id,
+ const UnloadedExtensionReason reason) override;
+
+ ContentVerifier *content_verifier() override;
+ std::unique_ptr<ExtensionSet> GetDependentExtensions(const Extension *extension) override;
+
+#if !defined(TOOLKIT_QT)
+ void InstallUpdate(const std::string &extension_id,
+ const std::string &public_key,
+ const base::FilePath &unpacked_dir,
+ bool install_immediately,
+ InstallUpdateCallback install_update_callback) override;
+#endif // TOOLKIT_QT
+ //friend class ExtensionSystemSharedFactory;
+
+ bool FinishDelayedInstallationIfReady(const std::string &extension_id, bool install_immediately) override;
+
+ void Init(bool extensions_enabled);
+
+ const OneShotEvent &ready() const override { return ready_; }
+
+private:
+ void OnExtensionRegisteredWithRequestContexts(scoped_refptr<const extensions::Extension> extension);
+
+ void NotifyExtensionLoaded(const Extension *extension);
+ void LoadExtension(std::string extension_id, std::unique_ptr<base::DictionaryValue> manifest, const base::FilePath &directory);
+ // The services that are shared between normal and incognito profiles.
+
+ // Data to be accessed on the IO thread. Must outlive process_manager_.
+ scoped_refptr<InfoMap> info_map_;
+
+ std::unique_ptr<ServiceWorkerManager> service_worker_manager_;
+ std::unique_ptr<RuntimeData> runtime_data_;
+ std::unique_ptr<QuotaService> quota_service_;
+ std::unique_ptr<AppSorting> app_sorting_;
+ std::unique_ptr<SharedUserScriptMaster> shared_user_script_master_;
+
+
+ // For verifying the contents of extensions read from disk.
+ scoped_refptr<ContentVerifier> content_verifier_;
+ OneShotEvent ready_;
+
+ content::BrowserContext *browser_context_;
+ scoped_refptr<ValueStoreFactory> store_factory_;
+ ExtensionRegistry *extension_registry_;
+ extensions::RendererStartupHelper *renderer_helper_;
+ bool initialized_;
+
+ base::WeakPtrFactory<ExtensionSystemQt> weak_ptr_factory_;
+ DISALLOW_COPY_AND_ASSIGN(ExtensionSystemQt);
+};
+
+} // namespace extensions
+
+#endif // EXTENSION_SYSTEM_QT_H
diff --git a/src/core/extensions/extension_web_contents_observer_qt.cpp b/src/core/extensions/extension_web_contents_observer_qt.cpp
new file mode 100644
index 000000000..365f04e46
--- /dev/null
+++ b/src/core/extensions/extension_web_contents_observer_qt.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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 "extension_web_contents_observer_qt.h"
+
+#include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/common/url_constants.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/manifest.h"
+
+namespace extensions {
+
+ExtensionWebContentsObserverQt::ExtensionWebContentsObserverQt(content::WebContents *web_contents)
+ : ExtensionWebContentsObserver(web_contents)
+{
+}
+
+ExtensionWebContentsObserverQt::~ExtensionWebContentsObserverQt()
+{
+}
+
+// static
+void ExtensionWebContentsObserverQt::CreateForWebContents(content::WebContents *web_contents)
+{
+ content::WebContentsUserData<ExtensionWebContentsObserverQt>::CreateForWebContents(web_contents);
+
+ // Initialize this instance if necessary.
+ FromWebContents(web_contents)->Initialize();
+}
+
+std::string ExtensionWebContentsObserverQt::GetExtensionIdFromFrame(content::RenderFrameHost *render_frame_host) const
+{
+ const GURL &site = render_frame_host->GetSiteInstance()->GetSiteURL();
+ if (!site.SchemeIs(kExtensionScheme))
+ return std::string();
+
+ return site.host();
+}
+
+const Extension *ExtensionWebContentsObserverQt::GetExtensionFromFrame(content::RenderFrameHost *render_frame_host, bool verify_url) const
+{
+ std::string extension_id = GetExtensionIdFromFrame(render_frame_host);
+ if (extension_id.empty())
+ return nullptr;
+
+ content::BrowserContext *browser_context =
+ render_frame_host->GetProcess()->GetBrowserContext();
+ const Extension *extension = ExtensionRegistry::Get(browser_context)
+ ->enabled_extensions()
+ .GetByID(extension_id);
+ if (!extension)
+ return nullptr;
+
+ if (verify_url) {
+ const url::Origin &origin(render_frame_host->GetLastCommittedOrigin());
+ // Without site isolation, this check is needed to eliminate non-extension
+ // schemes. With site isolation, this is still needed to exclude sandboxed
+ // extension frames with a unique origin.
+ const GURL site_url(render_frame_host->GetSiteInstance()->GetSiteURL());
+ if (origin.opaque() || site_url != content::SiteInstance::GetSiteForURL(browser_context, origin.GetURL()))
+ return nullptr;
+ }
+
+ return extension;
+}
+
+void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost *render_frame_host)
+{
+ ExtensionWebContentsObserver::RenderFrameCreated(render_frame_host);
+
+ const Extension *extension = GetExtensionFromFrame(render_frame_host, false);
+ if (!extension)
+ return;
+
+ int process_id = render_frame_host->GetProcess()->GetID();
+ auto *policy = content::ChildProcessSecurityPolicy::GetInstance();
+
+ if (extension->is_extension() && Manifest::IsComponentLocation(extension->location()))
+ policy->GrantRequestOrigin(process_id, url::Origin::Create(GURL(content::kChromeUIResourcesURL)));
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(ExtensionWebContentsObserverQt)
+
+} // namespace extensions
diff --git a/src/core/extensions/extension_web_contents_observer_qt.h b/src/core/extensions/extension_web_contents_observer_qt.h
new file mode 100644
index 000000000..267a1095c
--- /dev/null
+++ b/src/core/extensions/extension_web_contents_observer_qt.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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 EXTENSION_WEB_CONTENTS_OBSERVER_QT_H_
+#define EXTENSION_WEB_CONTENTS_OBSERVER_QT_H_
+
+#include "content/public/browser/web_contents_user_data.h"
+#include "extensions/browser/extension_web_contents_observer.h"
+
+namespace extensions {
+
+class ExtensionWebContentsObserverQt
+ : public ExtensionWebContentsObserver,
+ public content::WebContentsUserData<ExtensionWebContentsObserverQt>
+{
+public:
+ explicit ExtensionWebContentsObserverQt(content::WebContents *web_contents);
+ ~ExtensionWebContentsObserverQt() override;
+
+ static void CreateForWebContents(content::WebContents *web_contents);
+
+ std::string GetExtensionIdFromFrame(content::RenderFrameHost *) const;
+ const Extension *GetExtensionFromFrame(content::RenderFrameHost *, bool) const;
+
+ // content::WebContentsObserver overrides.
+ void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
+
+private:
+ friend class content::WebContentsUserData<ExtensionWebContentsObserverQt>;
+ WEB_CONTENTS_USER_DATA_KEY_DECL()
+ DISALLOW_COPY_AND_ASSIGN(ExtensionWebContentsObserverQt);
+};
+
+} // namespace extensions
+
+#endif // EXTENSION_WEB_CONTENTS_OBSERVER_QT_H_
diff --git a/src/core/extensions/extensions_api_client_qt.cpp b/src/core/extensions/extensions_api_client_qt.cpp
new file mode 100644
index 000000000..731b79a63
--- /dev/null
+++ b/src/core/extensions/extensions_api_client_qt.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions copyright 2015 The Chromium Embedded Framework Authors.
+// Portions 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 "extensions_api_client_qt.h"
+
+#include <memory>
+//#include "base/memory/ptr_util.h"
+#include "extension_web_contents_observer_qt.h"
+#include "components/pdf/browser/pdf_web_contents_helper.h"
+#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
+#include "printing/print_view_manager_qt.h"
+
+namespace extensions {
+
+ExtensionsAPIClientQt::ExtensionsAPIClientQt()
+{
+}
+
+AppViewGuestDelegate *ExtensionsAPIClientQt::CreateAppViewGuestDelegate() const
+{
+ // TODO(extensions): Implement to support Apps.
+ NOTREACHED();
+ return nullptr;
+}
+
+std::unique_ptr<guest_view::GuestViewManagerDelegate> ExtensionsAPIClientQt::CreateGuestViewManagerDelegate(content::BrowserContext *context) const
+{
+ return std::make_unique<guest_view::GuestViewManagerDelegate>();
+}
+
+std::unique_ptr<MimeHandlerViewGuestDelegate> ExtensionsAPIClientQt::CreateMimeHandlerViewGuestDelegate(MimeHandlerViewGuest *guest) const
+{
+ return std::make_unique<MimeHandlerViewGuestDelegate>();
+}
+
+void ExtensionsAPIClientQt::AttachWebContentsHelpers(content::WebContents *web_contents) const
+{
+ // PrefsTabHelper::CreateForWebContents(web_contents);
+ QtWebEngineCore::PrintViewManagerQt::CreateForWebContents(web_contents);
+ ExtensionWebContentsObserverQt::CreateForWebContents(web_contents);
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/extensions_api_client_qt.h b/src/core/extensions/extensions_api_client_qt.h
new file mode 100644
index 000000000..2fa69f539
--- /dev/null
+++ b/src/core/extensions/extensions_api_client_qt.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions copyright 2015 The Chromium Embedded Framework Authors.
+// Portions 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 EXTENSIONS_API_CLIENT_QT_H_
+#define EXTENSIONS_API_CLIENT_QT_H_
+
+#include "extensions/browser/api/extensions_api_client.h"
+
+namespace extensions {
+
+class ExtensionsAPIClientQt : public ExtensionsAPIClient
+{
+public:
+ ExtensionsAPIClientQt();
+
+ // ExtensionsAPIClient implementation.
+ AppViewGuestDelegate *CreateAppViewGuestDelegate() const override;
+ std::unique_ptr<guest_view::GuestViewManagerDelegate>
+ CreateGuestViewManagerDelegate(content::BrowserContext *context) const override;
+ std::unique_ptr<MimeHandlerViewGuestDelegate>
+ CreateMimeHandlerViewGuestDelegate(MimeHandlerViewGuest *guest) const override;
+ void AttachWebContentsHelpers(content::WebContents *web_contents) const override;
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_API_CLIENT_QT_H_
diff --git a/src/core/extensions/extensions_browser_api_provider_qt.cpp b/src/core/extensions/extensions_browser_api_provider_qt.cpp
new file mode 100644
index 000000000..cc1932c64
--- /dev/null
+++ b/src/core/extensions/extensions_browser_api_provider_qt.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "extensions_browser_api_provider_qt.h"
+
+#include "extensions/browser/api/generated_api_registration.h"
+
+namespace extensions {
+ExtensionsBrowserAPIProviderQt::ExtensionsBrowserAPIProviderQt() =
+ default;
+ExtensionsBrowserAPIProviderQt::~ExtensionsBrowserAPIProviderQt() =
+ default;
+
+void ExtensionsBrowserAPIProviderQt::RegisterExtensionFunctions(
+ ExtensionFunctionRegistry* registry) {
+ api::GeneratedFunctionRegistry::RegisterAll(registry);
+}
+
+
+}
+
diff --git a/src/core/extensions/extensions_browser_api_provider_qt.h b/src/core/extensions/extensions_browser_api_provider_qt.h
new file mode 100644
index 000000000..612df3825
--- /dev/null
+++ b/src/core/extensions/extensions_browser_api_provider_qt.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EXTENSIONS_API_PROVIDER_QT_H
+#define EXTENSIONS_API_PROVIDER_QT_H
+
+#include "extensions/browser/extensions_browser_api_provider.h"
+#include "base/macros.h"
+
+namespace extensions {
+
+class ExtensionsBrowserAPIProviderQt : public ExtensionsBrowserAPIProvider {
+public:
+ ExtensionsBrowserAPIProviderQt();
+ ~ExtensionsBrowserAPIProviderQt() override;
+
+ void RegisterExtensionFunctions(ExtensionFunctionRegistry *registry) override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ExtensionsBrowserAPIProviderQt);
+};
+
+}
+
+#endif // EXTENSIONS_API_PROVIDER_QT_H
diff --git a/src/core/extensions/extensions_browser_client_qt.cpp b/src/core/extensions/extensions_browser_client_qt.cpp
new file mode 100644
index 000000000..8bba4128f
--- /dev/null
+++ b/src/core/extensions/extensions_browser_client_qt.cpp
@@ -0,0 +1,499 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions copyright 2015 The Chromium Embedded Framework Authors.
+// Portions 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 "extensions_browser_client_qt.h"
+
+#include <utility>
+
+#include "base/files/file_path.h"
+#include "base/memory/weak_ptr.h"
+#include "base/path_service.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "base/memory/ref_counted_memory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
+#include "extensions/browser/api/extensions_api_client.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+#include "extensions/browser/app_sorting.h"
+#include "extensions/browser/core_extensions_browser_api_provider.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_host_delegate.h"
+#include "extensions/browser/extension_protocols.h"
+#include "extensions/browser/mojo/interface_registration.h"
+#include "extensions/browser/url_request_util.h"
+#include "extensions/common/file_util.h"
+#include "net/base/completion_once_callback.h"
+#include "net/base/mime_util.h"
+#include "net/url_request/url_request_simple_job.h"
+#include "ui/base/resource/resource_bundle.h"
+
+#include "component_extension_resource_manager_qt.h"
+#include "extension_system_factory_qt.h"
+#include "extension_web_contents_observer_qt.h"
+#include "extensions_api_client_qt.h"
+#include "extensions_browser_api_provider_qt.h"
+#include "extensions_browser_client_qt.h"
+#include "web_engine_library_info.h"
+
+using content::BrowserContext;
+using content::BrowserThread;
+
+namespace {
+
+// helpers based on implementation in chrome_url_request_util.cc:
+// 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.
+
+void DetermineCharset(const std::string &mime_type,
+ const base::RefCountedMemory *data,
+ std::string *out_charset)
+{
+ if (base::StartsWith(mime_type, "text/", base::CompareCase::INSENSITIVE_ASCII)) {
+ // All of our HTML files should be UTF-8 and for other resource types
+ // (like images), charset doesn't matter.
+ DCHECK(base::IsStringUTF8(base::StringPiece(reinterpret_cast<const char*>(data->front()), data->size())));
+ *out_charset = "utf-8";
+ }
+}
+
+// A request for an extension resource in a Chrome .pak file. These are used
+// by component extensions.
+class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
+public:
+ URLRequestResourceBundleJob(net::URLRequest *request,
+ net::NetworkDelegate *network_delegate,
+ const base::FilePath &filename,
+ int resource_id,
+ const std::string &content_security_policy,
+ bool send_cors_header)
+ : net::URLRequestSimpleJob(request, network_delegate)
+ , filename_(filename)
+ , resource_id_(resource_id)
+ , weak_factory_(this)
+ {
+ // Leave cache headers out of resource bundle requests.
+ response_info_.headers = extensions::BuildHttpHeaders(content_security_policy, send_cors_header, base::Time());
+ }
+ int GetRefCountedData(std::string* mime_type,
+ std::string* charset,
+ scoped_refptr<base::RefCountedMemory>* data,
+ net::CompletionOnceCallback callback) const override
+ {
+ const ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ *data = rb.LoadDataResourceBytes(resource_id_);
+
+ // Add the Content-Length header now that we know the resource length.
+ response_info_.headers->AddHeader(
+ base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentLength,
+ base::NumberToString((*data)->size()).c_str()));
+
+ std::string* read_mime_type = new std::string;
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {base::MayBlock()},
+ base::BindOnce(&net::GetMimeTypeFromFile, filename_,
+ base::Unretained(read_mime_type)),
+ base::BindOnce(&URLRequestResourceBundleJob::OnMimeTypeRead,
+ weak_factory_.GetWeakPtr(), mime_type, charset, *data,
+ base::Owned(read_mime_type), std::move(callback)));
+
+ return net::ERR_IO_PENDING;
+ }
+
+ void GetResponseInfo(net::HttpResponseInfo* info) override
+ {
+ *info = response_info_;
+ }
+
+private:
+ ~URLRequestResourceBundleJob() override {}
+
+ void OnMimeTypeRead(std::string *out_mime_type,
+ std::string *charset,
+ scoped_refptr<base::RefCountedMemory> data,
+ std::string *read_mime_type,
+ net::CompletionOnceCallback callback,
+ bool read_result)
+ {
+ response_info_.headers->AddHeader(
+ base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentType,
+ read_mime_type->c_str()));
+ *out_mime_type = *read_mime_type;
+ DetermineCharset(*read_mime_type, data.get(), charset);
+ int result = read_result ? net::OK : net::ERR_INVALID_URL;
+ std::move(callback).Run(result);
+ }
+
+ // We need the filename of the resource to determine the mime type.
+ base::FilePath filename_;
+
+ // The resource bundle id to load.
+ int resource_id_;
+
+ net::HttpResponseInfo response_info_;
+
+ mutable base::WeakPtrFactory<URLRequestResourceBundleJob> weak_factory_;
+};
+
+} // namespace
+
+namespace extensions {
+
+ExtensionsBrowserClientQt::ExtensionsBrowserClientQt()
+ : api_client_(new ExtensionsAPIClientQt)
+ , resource_manager_(new ComponentExtensionResourceManagerQt)
+{
+ AddAPIProvider(std::make_unique<CoreExtensionsBrowserAPIProvider>());
+ AddAPIProvider(std::make_unique<ExtensionsBrowserAPIProviderQt>());
+}
+
+ExtensionsBrowserClientQt::~ExtensionsBrowserClientQt()
+{
+}
+
+bool ExtensionsBrowserClientQt::IsShuttingDown()
+{
+ return false;
+}
+
+bool ExtensionsBrowserClientQt::AreExtensionsDisabled(const base::CommandLine &command_line, BrowserContext *context)
+{
+ return false;
+}
+
+bool ExtensionsBrowserClientQt::IsValidContext(BrowserContext *context)
+{
+ return true;
+}
+
+bool ExtensionsBrowserClientQt::IsSameContext(BrowserContext *first,
+ BrowserContext *second)
+{
+ return first == second;
+}
+
+bool ExtensionsBrowserClientQt::HasOffTheRecordContext(BrowserContext *context)
+{
+ return false;
+}
+
+BrowserContext *ExtensionsBrowserClientQt::GetOffTheRecordContext(BrowserContext *context)
+{
+ // TODO(extensions): Do we need to support this?
+ return nullptr;
+}
+
+BrowserContext *ExtensionsBrowserClientQt::GetOriginalContext(BrowserContext *context)
+{
+ return context;
+}
+
+bool ExtensionsBrowserClientQt::IsGuestSession(BrowserContext *context) const
+{
+ return false;
+}
+
+bool ExtensionsBrowserClientQt::IsExtensionIncognitoEnabled(const std::string &extension_id,
+ content::BrowserContext *context) const
+{
+ return false;
+}
+
+bool ExtensionsBrowserClientQt::CanExtensionCrossIncognito(const Extension *extension,
+ content::BrowserContext *context) const
+{
+ return false;
+}
+
+net::URLRequestJob *ExtensionsBrowserClientQt::MaybeCreateResourceBundleRequestJob(net::URLRequest *request,
+ net::NetworkDelegate *network_delegate,
+ const base::FilePath &directory_path,
+ const std::string &content_security_policy,
+ bool send_cors_header)
+{
+ base::FilePath resources_path;
+ base::FilePath relative_path;
+ // Try to load extension resources from chrome resource file if
+ // directory_path is a descendant of resources_path. resources_path
+ // corresponds to src/chrome/browser/resources in source tree.
+ if (base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &resources_path) &&
+ // Since component extension resources are included in
+ // component_extension_resources.pak file in resources_path, calculate
+ // extension relative path against resources_path.
+ resources_path.AppendRelativePath(directory_path, &relative_path)) {
+ base::FilePath request_path = extensions::file_util::ExtensionURLToRelativeFilePath(request->url());
+ int resource_id = 0;
+ if (GetComponentExtensionResourceManager()->IsComponentExtensionResource(directory_path, request_path, &resource_id)) {
+ relative_path = relative_path.Append(request_path);
+ relative_path = relative_path.NormalizePathSeparators();
+ return new URLRequestResourceBundleJob(request,
+ network_delegate,
+ relative_path,
+ resource_id,
+ content_security_policy,
+ send_cors_header);
+ }
+ }
+ return nullptr;
+}
+
+// Return the resource relative path and id for the given request.
+base::FilePath ExtensionsBrowserClientQt::GetBundleResourcePath(const network::ResourceRequest &request,
+ const base::FilePath &extension_resources_path,
+ int *resource_id) const
+{
+ *resource_id = 0;
+ // |chrome_resources_path| corresponds to src/chrome/browser/resources in
+ // source tree.
+ base::FilePath resources_path;
+ if (!base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &resources_path))
+ return base::FilePath();
+
+ // Since component extension resources are included in
+ // component_extension_resources.pak file in |chrome_resources_path|,
+ // calculate the extension |request_relative_path| against
+ // |chrome_resources_path|.
+ if (!resources_path.IsParent(extension_resources_path))
+ return base::FilePath();
+
+ const base::FilePath request_relative_path =
+ extensions::file_util::ExtensionURLToRelativeFilePath(request.url);
+ if (!ExtensionsBrowserClient::Get()->GetComponentExtensionResourceManager()->IsComponentExtensionResource(
+ extension_resources_path, request_relative_path, resource_id)) {
+ return base::FilePath();
+ }
+ DCHECK_NE(0, *resource_id);
+
+ return request_relative_path;
+}
+
+// Creates and starts a URLLoader to load an extension resource from the
+// embedder's resource bundle (.pak) files. Used for component extensions.
+void ExtensionsBrowserClientQt::LoadResourceFromResourceBundle(const network::ResourceRequest &request,
+ network::mojom::URLLoaderRequest loader,
+ const base::FilePath &resource_relative_path,
+ int resource_id,
+ const std::string &content_security_policy,
+ network::mojom::URLLoaderClientPtr client,
+ bool send_cors_header)
+{
+ NOTIMPLEMENTED();
+}
+
+
+bool ExtensionsBrowserClientQt::AllowCrossRendererResourceLoad(const GURL &url,
+ content::ResourceType resource_type,
+ ui::PageTransition page_transition,
+ int child_id,
+ bool is_incognito,
+ const Extension *extension,
+ const ExtensionSet &extensions,
+ const ProcessMap &process_map)
+{
+
+ if (extension && extension->id() == extension_misc::kPdfExtensionId)
+ return true;
+
+ bool allowed = false;
+ if (url_request_util::AllowCrossRendererResourceLoad(url, resource_type,
+ page_transition, child_id,
+ is_incognito, extension, extensions,
+ process_map, &allowed)) {
+ return allowed;
+ }
+ // Couldn't determine if resource is allowed. Block the load.
+ return false;
+}
+
+PrefService *ExtensionsBrowserClientQt::GetPrefServiceForContext(BrowserContext *context)
+{
+ return static_cast<Profile *>(context)->GetPrefs();
+}
+
+void ExtensionsBrowserClientQt::GetEarlyExtensionPrefsObservers(content::BrowserContext *context,
+ std::vector<ExtensionPrefsObserver *> *observers) const
+{
+}
+
+ProcessManagerDelegate *ExtensionsBrowserClientQt::GetProcessManagerDelegate() const
+{
+ return nullptr;
+}
+
+std::unique_ptr<ExtensionHostDelegate> ExtensionsBrowserClientQt::CreateExtensionHostDelegate()
+{
+ // TODO(extensions): Implement to support Apps.
+ NOTREACHED();
+ return std::unique_ptr<ExtensionHostDelegate>();
+}
+
+bool ExtensionsBrowserClientQt::DidVersionUpdate(BrowserContext *context)
+{
+ // TODO(jamescook): We might want to tell extensions when app_shell updates.
+ return false;
+}
+
+void ExtensionsBrowserClientQt::PermitExternalProtocolHandler()
+{
+}
+
+bool ExtensionsBrowserClientQt::IsRunningInForcedAppMode()
+{
+ return false;
+}
+
+bool ExtensionsBrowserClientQt::IsLoggedInAsPublicAccount()
+{
+ return false;
+}
+
+ExtensionSystemProvider *ExtensionsBrowserClientQt::GetExtensionSystemFactory()
+{
+ return ExtensionSystemFactoryQt::GetInstance();
+}
+
+// void ExtensionsBrowserClientQt::RegisterExtensionFunctions(ExtensionFunctionRegistry *registry) const
+//{
+// // Register core extension-system APIs.
+// api::GeneratedFunctionRegistry::RegisterAll(registry);
+//}
+
+void ExtensionsBrowserClientQt::RegisterExtensionInterfaces(service_manager::BinderRegistryWithArgs<content::RenderFrameHost *> *registry,
+ content::RenderFrameHost *render_frame_host,
+ const Extension *extension) const
+{
+ RegisterInterfacesForExtension(registry, render_frame_host, extension);
+}
+
+std::unique_ptr<RuntimeAPIDelegate> ExtensionsBrowserClientQt::CreateRuntimeAPIDelegate(content::BrowserContext *context) const
+{
+ // TODO(extensions): Implement to support Apps.
+ NOTREACHED();
+ return std::unique_ptr<RuntimeAPIDelegate>();
+}
+
+const ComponentExtensionResourceManager *ExtensionsBrowserClientQt::GetComponentExtensionResourceManager()
+{
+ return resource_manager_.get();
+}
+
+void ExtensionsBrowserClientQt::BroadcastEventToRenderers(events::HistogramValue histogram_value,
+ const std::string &event_name,
+ std::unique_ptr<base::ListValue> args)
+{
+ NOTIMPLEMENTED();
+ // TODO : do the event routing
+ // event_router_forwarder_->BroadcastEventToRenderers(
+ // histogram_value, event_name, std::move(args), GURL());
+}
+
+net::NetLog *ExtensionsBrowserClientQt::GetNetLog()
+{
+ return nullptr;
+}
+
+ExtensionCache *ExtensionsBrowserClientQt::GetExtensionCache()
+{
+ // Only used by Chrome via ExtensionService.
+ NOTREACHED();
+ return nullptr;
+}
+
+bool ExtensionsBrowserClientQt::IsBackgroundUpdateAllowed()
+{
+ return true;
+}
+
+bool ExtensionsBrowserClientQt::IsMinBrowserVersionSupported(
+ const std::string &min_version)
+{
+ return true;
+}
+
+bool ExtensionsBrowserClientQt::IsLockScreenContext(content::BrowserContext *context)
+{
+ return false;
+}
+
+// Returns the locale used by the application.
+std::string ExtensionsBrowserClientQt::GetApplicationLocale()
+{
+ return WebEngineLibraryInfo::getApplicationLocale();
+}
+
+bool ExtensionsBrowserClientQt::IsAppModeForcedForApp(const ExtensionId &id)
+{
+ return false;
+}
+
+bool ExtensionsBrowserClientQt::IsInDemoMode()
+{
+ return false;
+}
+
+ExtensionWebContentsObserver *ExtensionsBrowserClientQt::GetExtensionWebContentsObserver(content::WebContents *web_contents)
+{
+ return ExtensionWebContentsObserverQt::FromWebContents(web_contents);
+}
+
+KioskDelegate *ExtensionsBrowserClientQt::GetKioskDelegate()
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+bool ExtensionsBrowserClientQt::IsScreensaverInDemoMode(const std::string& app_id)
+{
+ return false;
+}
+
+void ExtensionsBrowserClientQt::SetAPIClientForTest(ExtensionsAPIClient *api_client)
+{
+ api_client_.reset(api_client);
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/extensions_browser_client_qt.h b/src/core/extensions/extensions_browser_client_qt.h
new file mode 100644
index 000000000..f766b96a7
--- /dev/null
+++ b/src/core/extensions/extensions_browser_client_qt.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions copyright 2015 The Chromium Embedded Framework Authors.
+// Portions 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 EXTENSIONS_BROWSER_CLIENT_QT_H_
+#define EXTENSIONS_BROWSER_CLIENT_QT_H_
+
+#include "base/compiler_specific.h"
+#include "extensions/browser/extensions_browser_client.h"
+
+namespace extensions {
+
+class ExtensionsAPIClient;
+
+// An ExtensionsBrowserClient that supports a single content::BrowserContent
+// with no related incognito context.
+class ExtensionsBrowserClientQt : public ExtensionsBrowserClient
+{
+public:
+ ExtensionsBrowserClientQt();
+ ~ExtensionsBrowserClientQt() override;
+
+ // ExtensionsBrowserClient overrides:
+ bool IsShuttingDown() override;
+ bool AreExtensionsDisabled(const base::CommandLine &command_line,
+ content::BrowserContext *context) override;
+ bool IsValidContext(content::BrowserContext *context) override;
+ bool IsSameContext(content::BrowserContext *first,
+ content::BrowserContext *second) override;
+ bool HasOffTheRecordContext(content::BrowserContext *context) override;
+ content::BrowserContext *GetOffTheRecordContext(content::BrowserContext *context) override;
+ content::BrowserContext *GetOriginalContext(content::BrowserContext *context) override;
+ bool IsGuestSession(content::BrowserContext *context) const override;
+ bool IsExtensionIncognitoEnabled(const std::string &extension_id, content::BrowserContext *context) const override;
+ bool CanExtensionCrossIncognito(const Extension *extension, content::BrowserContext *context) const override;
+ net::URLRequestJob *MaybeCreateResourceBundleRequestJob(net::URLRequest *request,
+ net::NetworkDelegate *network_delegate,
+ const base::FilePath &directory_path,
+ const std::string &content_security_policy,
+ bool send_cors_header) override;
+ bool AllowCrossRendererResourceLoad(const GURL &url,
+ content::ResourceType resource_type,
+ ui::PageTransition page_transition,
+ int child_id,
+ bool is_incognito,
+ const Extension *extension,
+ const ExtensionSet &extensions,
+ const ProcessMap &process_map) override;
+ PrefService *GetPrefServiceForContext(content::BrowserContext *context) override;
+ void GetEarlyExtensionPrefsObservers(content::BrowserContext *context, std::vector<ExtensionPrefsObserver *> *observers) const
+ override;
+ ProcessManagerDelegate *GetProcessManagerDelegate() const override;
+ std::unique_ptr<ExtensionHostDelegate>
+ CreateExtensionHostDelegate() override;
+ bool DidVersionUpdate(content::BrowserContext *context) override;
+ void PermitExternalProtocolHandler() override;
+ bool IsRunningInForcedAppMode() override;
+ bool IsLoggedInAsPublicAccount() override;
+ ExtensionSystemProvider *GetExtensionSystemFactory() override;
+// void RegisterExtensionFunctions(ExtensionFunctionRegistry *registry) const;
+ std::unique_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(content::BrowserContext *context) const override;
+ void RegisterExtensionInterfaces(service_manager::BinderRegistryWithArgs<content::RenderFrameHost *> *registry,
+ content::RenderFrameHost *render_frame_host,
+ const Extension *extension) const override;
+ const ComponentExtensionResourceManager *
+ GetComponentExtensionResourceManager() override;
+ void BroadcastEventToRenderers(events::HistogramValue histogram_value,
+ const std::string &event_name,
+ std::unique_ptr<base::ListValue> args) override;
+ net::NetLog *GetNetLog() override;
+ ExtensionCache *GetExtensionCache() override;
+ bool IsBackgroundUpdateAllowed() override;
+ bool IsMinBrowserVersionSupported(const std::string &min_version) override;
+ ExtensionWebContentsObserver *GetExtensionWebContentsObserver(
+ content::WebContents *web_contents) override;
+ KioskDelegate *GetKioskDelegate() override;
+
+ // Whether the browser context is associated with Chrome OS lock screen.
+ bool IsLockScreenContext(content::BrowserContext *context) override;
+
+ bool IsAppModeForcedForApp(const ExtensionId &id) override;
+ bool IsInDemoMode() override;
+
+ // Return the resource relative path and id for the given request.
+ base::FilePath GetBundleResourcePath(const network::ResourceRequest &request,
+ const base::FilePath &extension_resources_path,
+ int *resource_id) const override;
+
+ // Creates and starts a URLLoader to load an extension resource from the
+ // embedder's resource bundle (.pak) files. Used for component extensions.
+ void LoadResourceFromResourceBundle(const network::ResourceRequest &request,
+ network::mojom::URLLoaderRequest loader,
+ const base::FilePath &resource_relative_path,
+ int resource_id,
+ const std::string &content_security_policy,
+ network::mojom::URLLoaderClientPtr client,
+ bool send_cors_header) override;
+
+ // Returns the locale used by the application.
+ std::string GetApplicationLocale() override;
+
+ bool IsScreensaverInDemoMode(const std::string& app_id) override;
+
+ // Sets the API client.
+ void SetAPIClientForTest(ExtensionsAPIClient *api_client);
+
+private:
+ // Support for extension APIs.
+ std::unique_ptr<ExtensionsAPIClient> api_client_;
+
+ // Resource manager used to supply resources from pak files.
+ std::unique_ptr<ComponentExtensionResourceManager> resource_manager_;
+
+ //scoped_refptr<EventRouterForwarder> event_router_forwarder_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionsBrowserClientQt);
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_CLIENT_QT_H_
diff --git a/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp b/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
new file mode 100644
index 000000000..438b8a83e
--- /dev/null
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions copyright 2015 The Chromium Embedded Framework Authors.
+// Portions 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 "mime_handler_view_guest_delegate_qt.h"
+
+#include "content/browser/browser_plugin/browser_plugin_guest.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/context_menu_params.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+
+namespace extensions {
+
+MimeHandlerViewGuestDelegateQt::MimeHandlerViewGuestDelegateQt(MimeHandlerViewGuest *guest)
+ : MimeHandlerViewGuestDelegate()
+{
+}
+
+MimeHandlerViewGuestDelegateQt::~MimeHandlerViewGuestDelegateQt()
+{
+}
+
+bool MimeHandlerViewGuestDelegateQt::HandleContextMenu(content::WebContents *web_contents, const content::ContextMenuParams &params)
+{
+ content::ContextMenuParams new_params = params;
+
+ gfx::Point guest_coordinates =
+ static_cast<content::WebContentsImpl *>(web_contents)->GetBrowserPluginGuest()->GetScreenCoordinates(gfx::Point());
+
+ // Adjust (x,y) position for offset from guest to embedder.
+ new_params.x += guest_coordinates.x();
+ new_params.y += guest_coordinates.y();
+
+ return false;
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/mime_handler_view_guest_delegate_qt.h b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
new file mode 100644
index 000000000..b679c7a38
--- /dev/null
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Portions copyright 2015 The Chromium Embedded Framework Authors.
+// Portions 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 MIME_HANDLER_VIEW_GUEST_DELEGATE_QT_H_
+#define MIME_HANDLER_VIEW_GUEST_DELEGATE_QT_H_
+
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
+#include "content/browser/web_contents/web_contents_view.h"
+#include "content/public/browser/web_contents.h"
+
+namespace content {
+struct ContextMenuParams;
+}
+
+namespace extensions {
+class MimeHandlerViewGuest;
+
+class MimeHandlerViewGuestDelegateQt : public MimeHandlerViewGuestDelegate
+{
+public:
+ explicit MimeHandlerViewGuestDelegateQt(MimeHandlerViewGuest *guest);
+ ~MimeHandlerViewGuestDelegateQt() override;
+
+ bool HandleContextMenu(content::WebContents *web_contents,
+ const content::ContextMenuParams &params) override;
+
+private:
+ MimeHandlerViewGuest *guest_; // Owns us.
+
+ DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewGuestDelegateQt);
+};
+
+} // namespace extensions
+
+#endif // MIME_HANDLER_VIEW_GUEST_DELEGATE_QT_H_
diff --git a/src/core/extensions/pdf_web_contents_helper_client_qt.h b/src/core/extensions/pdf_web_contents_helper_client_qt.h
new file mode 100644
index 000000000..a22feb138
--- /dev/null
+++ b/src/core/extensions/pdf_web_contents_helper_client_qt.h
@@ -0,0 +1,29 @@
+// 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 PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
+#define PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
+
+#include "base/macros.h"
+#include "components/pdf/browser/pdf_web_contents_helper_client.h"
+
+namespace extensions {
+
+class PDFWebContentsHelperClientQt : public pdf::PDFWebContentsHelperClient {
+public:
+ PDFWebContentsHelperClientQt();
+ ~PDFWebContentsHelperClientQt() override;
+
+private:
+ // pdf::PDFWebContentsHelperClient:
+ void UpdateContentRestrictions(content::WebContents* contents, int content_restrictions) override;
+ void OnPDFHasUnsupportedFeature(content::WebContents* contents) override;
+ void OnSaveURL(content::WebContents* contents) override;
+
+ DISALLOW_COPY_AND_ASSIGN(PDFWebContentsHelperClientQt);
+};
+
+} // namespace extensions
+
+#endif // PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h
index 60d194c4b..75d6aa75b 100644
--- a/src/core/favicon_manager.h
+++ b/src/core/favicon_manager.h
@@ -82,7 +82,7 @@ namespace QtWebEngineCore {
class WebContentsAdapterClient;
// Based on src/3rdparty/chromium/content/public/common/favicon_url.h
-class QWEBENGINECORE_PRIVATE_EXPORT FaviconInfo {
+class Q_WEBENGINECORE_PRIVATE_EXPORT FaviconInfo {
public:
enum FaviconTypeFlag {
InvalidIcon = 0,
@@ -109,7 +109,7 @@ public:
};
-class QWEBENGINECORE_PRIVATE_EXPORT FaviconManager {
+class Q_WEBENGINECORE_PRIVATE_EXPORT FaviconManager {
public:
FaviconManager(content::WebContents *, WebContentsAdapterClient *);
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 3ded5ec41..63b93c502 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -39,8 +39,12 @@
#include "file_picker_controller.h"
#include "type_conversion.h"
+#if defined(OS_WIN)
+#include "base/files/file_path.h"
+#endif
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/file_select_listener.h"
#include <QFileInfo>
#include <QDir>
@@ -49,40 +53,61 @@
namespace QtWebEngineCore {
-FilePickerController::FilePickerController(FileChooserMode mode, content::RenderFrameHost *frameHost, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject *parent)
+FilePickerController::FilePickerController(FileChooserMode mode, std::unique_ptr<content::FileSelectListener> listener, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject *parent)
: QObject(parent)
, m_defaultFileName(defaultFileName)
, m_acceptedMimeTypes(acceptedMimeTypes)
- , m_frameHost(frameHost)
+ , m_listener(std::move(listener))
, m_mode(mode)
{
}
+FilePickerController::~FilePickerController() = default;
+
void FilePickerController::accepted(const QStringList &files)
{
- FilePickerController::filesSelectedInChooser(files, m_frameHost);
+ QStringList stringList;
+ stringList.reserve(files.count());
+
+ for (const QString &urlString : files) {
+ // We accept strings on both absolute-path and file-URL form:
+ if (QDir::isAbsolutePath(urlString)) {
+ QString absolutePath = QDir::fromNativeSeparators(urlString);
+#if defined(OS_WIN)
+ if (absolutePath.at(0).isLetter() && absolutePath.at(1) == QLatin1Char(':') && !base::FilePath::IsSeparator(absolutePath.at(2).toLatin1()))
+ qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
+ else
+#endif
+ stringList.append(absolutePath);
+ } else {
+ QUrl url(urlString, QUrl::StrictMode);
+ if (url.isLocalFile() && QDir::isAbsolutePath(url.toLocalFile())) {
+ QString absolutePath = url.toLocalFile();
+#if defined(OS_WIN)
+ if (absolutePath.at(0).isLetter() && absolutePath.at(1) == QLatin1Char(':') && !base::FilePath::IsSeparator(absolutePath.at(2).toLatin1()))
+ qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
+ else
+#endif
+ stringList.append(absolutePath);
+ } else
+ qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
+ }
+ }
+
+ FilePickerController::filesSelectedInChooser(stringList);
}
void FilePickerController::accepted(const QVariant &files)
{
- QStringList stringList;
-
- if (files.canConvert(QVariant::StringList)) {
- stringList = files.toStringList();
- } else if (files.canConvert<QList<QUrl> >()) {
- const QList<QUrl> urls = files.value<QList<QUrl>>();
- for (const QUrl &url : urls)
- stringList.append(url.toLocalFile());
- } else {
+ if (!files.canConvert(QVariant::StringList))
qWarning("An unhandled type '%s' was provided in FilePickerController::accepted(QVariant)", files.typeName());
- }
- FilePickerController::filesSelectedInChooser(stringList, m_frameHost);
+ accepted(files.toStringList());
}
void FilePickerController::rejected()
{
- FilePickerController::filesSelectedInChooser(QStringList(), m_frameHost);
+ FilePickerController::filesSelectedInChooser(QStringList());
}
static QStringList listRecursively(const QDir &dir)
@@ -99,19 +124,30 @@ static QStringList listRecursively(const QDir &dir)
return ret;
}
-ASSERT_ENUMS_MATCH(FilePickerController::Open, content::FileChooserParams::Open)
-ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, content::FileChooserParams::OpenMultiple)
-ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, content::FileChooserParams::UploadFolder)
-ASSERT_ENUMS_MATCH(FilePickerController::Save, content::FileChooserParams::Save)
+ASSERT_ENUMS_MATCH(FilePickerController::Open, blink::mojom::FileChooserParams_Mode::kOpen)
+ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, blink::mojom::FileChooserParams_Mode::kOpenMultiple)
+ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, blink::mojom::FileChooserParams_Mode::kUploadFolder)
+ASSERT_ENUMS_MATCH(FilePickerController::Save, blink::mojom::FileChooserParams_Mode::kSave)
-void FilePickerController::filesSelectedInChooser(const QStringList &filesList, content::RenderFrameHost *frameHost)
+void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
{
- Q_ASSERT(frameHost);
QStringList files(filesList);
if (this->m_mode == UploadFolder && !filesList.isEmpty()
&& QFileInfo(filesList.first()).isDir()) // Enumerate the directory
files = listRecursively(QDir(filesList.first()));
- frameHost->FilesSelectedInChooser(toVector<content::FileChooserFileInfo>(files), static_cast<content::FileChooserParams::Mode>(this->m_mode));
+
+ std::vector<blink::mojom::FileChooserFileInfoPtr> chooser_files;
+ for (const auto &file : qAsConst(files)) {
+ chooser_files.push_back(blink::mojom::FileChooserFileInfo::NewNativeFile(
+ blink::mojom::NativeFileInfo::New(toFilePath(file), base::string16())));
+ }
+
+ if (files.isEmpty())
+ m_listener->FileSelectionCanceled();
+ else
+ m_listener->FileSelected(std::move(chooser_files),
+ /* FIXME? */ base::FilePath(),
+ static_cast<blink::mojom::FileChooserParams::Mode>(this->m_mode));
}
QStringList FilePickerController::acceptedMimeTypes() const
diff --git a/src/core/file_picker_controller.h b/src/core/file_picker_controller.h
index 7507cf358..dc8c0eddf 100644
--- a/src/core/file_picker_controller.h
+++ b/src/core/file_picker_controller.h
@@ -52,16 +52,19 @@
#define FILE_PICKER_CONTROLLER_H
#include "qtwebenginecoreglobal_p.h"
+
+#include <memory>
+
#include <QObject>
#include <QStringList>
namespace content {
- class RenderFrameHost;
+ class FileSelectListener;
}
namespace QtWebEngineCore {
-class QWEBENGINECORE_PRIVATE_EXPORT FilePickerController : public QObject {
+class Q_WEBENGINECORE_PRIVATE_EXPORT FilePickerController : public QObject {
Q_OBJECT
public:
enum FileChooserMode {
@@ -71,7 +74,8 @@ public:
Save
};
- FilePickerController(FileChooserMode mode, content::RenderFrameHost *contents, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject * = 0);
+ FilePickerController(FileChooserMode mode, std::unique_ptr<content::FileSelectListener> listener, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject * = 0);
+ ~FilePickerController() override;
QStringList acceptedMimeTypes() const;
QString defaultFileName() const;
FileChooserMode mode() const;
@@ -82,10 +86,10 @@ public Q_SLOTS:
void rejected();
private:
- void filesSelectedInChooser(const QStringList &filesList, content::RenderFrameHost *contents);
+ void filesSelectedInChooser(const QStringList &filesList);
QString m_defaultFileName;
QStringList m_acceptedMimeTypes;
- content::RenderFrameHost *m_frameHost;
+ std::unique_ptr<content::FileSelectListener> m_listener;
FileChooserMode m_mode;
};
diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro
index 9860c4541..0219a2be9 100644
--- a/src/core/gn_run.pro
+++ b/src/core/gn_run.pro
@@ -49,7 +49,7 @@ build_pass|!debug_and_release {
ninjaflags = $$(NINJAFLAGS)
isEmpty(ninjaflags):!silent: ninjaflags = "-v"
- runninja.commands = $$NINJA $$ninjaflags -C $$gn_build_root QtWebEngineCore
+ runninja.commands = $$NINJA $$ninjaflags \$\(NINJAJOBS\) -C $$gn_build_root QtWebEngineCore
QMAKE_EXTRA_TARGETS += runninja
build_pass:build_all: default_target.target = all
diff --git a/src/core/javascript_dialog_controller.h b/src/core/javascript_dialog_controller.h
index 1ba94e095..ba9f51944 100644
--- a/src/core/javascript_dialog_controller.h
+++ b/src/core/javascript_dialog_controller.h
@@ -59,7 +59,7 @@ namespace QtWebEngineCore {
class JavaScriptDialogControllerPrivate;
-class QWEBENGINECORE_PRIVATE_EXPORT JavaScriptDialogController : public QObject {
+class Q_WEBENGINECORE_PRIVATE_EXPORT JavaScriptDialogController : public QObject {
Q_OBJECT
public:
~JavaScriptDialogController();
diff --git a/src/core/locked_ptr.h b/src/core/locked_ptr.h
new file mode 100644
index 000000000..46d89819b
--- /dev/null
+++ b/src/core/locked_ptr.h
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LOCKED_PTR_H
+#define LOCKED_PTR_H
+
+#include <base/bind_internal.h>
+
+#include <QtCore/qreadwritelock.h>
+
+namespace base {
+
+struct LockedPtrCore
+{
+ LockedPtrCore(uintptr_t data) : data(data) {}
+
+ std::atomic<size_t> refCount{1};
+ // Atomic so that WeakLockedPtr::get can still read it.
+ std::atomic<uintptr_t> data;
+ QReadWriteLock lock{QReadWriteLock::Recursive};
+};
+
+enum class LockedPtrMode { Weak, Shared, Exclusive };
+
+template<class T, LockedPtrMode mode> class LockedPtr;
+
+// A WeakLockedPtr<T> is something like shared_ptr<T*>. The T* value can only be
+// accessed by atomic read.
+template<class T> using WeakLockedPtr = LockedPtr<T, LockedPtrMode::Weak>;
+
+// A SharedLockedPtr<T> is like WeakLockedPtr<T>, but the T* value is prevented
+// from changing for the lifetime of the SharedLockedPtr by holding a
+// shared-exclusive mutex in shared mode.
+template<class T> using SharedLockedPtr = LockedPtr<T, LockedPtrMode::Shared>;
+
+// An ExclusiveLockedPtr<T> is like SharedLockedPtr<T>, but the mutex is held in
+// exclusive mode. Only in this mode can the T* value be changed.
+template<class T> using ExclusiveLockedPtr = LockedPtr<T, LockedPtrMode::Exclusive>;
+
+template<class T, LockedPtrMode mode>
+class LockedPtr
+{
+ template<class T1>
+ static constexpr bool canConstructFrom =
+ std::is_same<T, T1>::value ||
+ std::is_same<T, const T1>::value;
+
+public:
+ constexpr LockedPtr() {}
+ constexpr LockedPtr(std::nullptr_t) {}
+
+ LockedPtr(const LockedPtr &that)
+ {
+ m_core = that.m_core;
+ lock();
+ }
+
+ LockedPtr &operator=(const LockedPtr &that)
+ {
+ unlock();
+ m_core = that.m_core;
+ lock();
+ }
+
+ LockedPtr(LockedPtr &&that)
+ {
+ m_core = that.m_core;
+ that.m_core = nullptr;
+ }
+
+ LockedPtr &operator=(LockedPtr &&that)
+ {
+ unlock();
+ m_core = that.m_core;
+ that.m_core = nullptr;
+ }
+
+ template<class T1, LockedPtrMode mode1,
+ class Enable = std::enable_if_t<canConstructFrom<T1>>>
+ LockedPtr(const LockedPtr<T1, mode1> &that)
+ {
+ m_core = that.m_core;
+ lock();
+ }
+
+ template<class T1, LockedPtrMode mode1,
+ class Enable = std::enable_if_t<canConstructFrom<T1>>>
+ LockedPtr &operator=(const LockedPtr<T1, mode1> &that)
+ {
+ unlock();
+ m_core = that.m_core;
+ lock();
+ }
+
+ template<class T1,
+ class Enable = std::enable_if_t<canConstructFrom<T1>>>
+ LockedPtr(LockedPtr<T1, mode> &&that)
+ {
+ m_core = that.m_core;
+ that.m_core = nullptr;
+ }
+
+ template<class T1,
+ class Enable = std::enable_if_t<canConstructFrom<T1>>>
+ LockedPtr &operator=(LockedPtr<T1, mode> &&that)
+ {
+ unlock();
+ m_core = that.m_core;
+ that.m_core = nullptr;
+ }
+
+ ~LockedPtr()
+ {
+ unlock();
+ }
+
+ T *get() const
+ {
+ if (m_core) {
+ if (mode == LockedPtrMode::Weak)
+ return reinterpret_cast<T *>(m_core->data.load(std::memory_order_acquire));
+ else
+ return reinterpret_cast<T *>(m_core->data.load(std::memory_order_relaxed));
+ }
+ return nullptr;
+ }
+
+ void set(T *value)
+ {
+ static_assert(mode == LockedPtrMode::Exclusive, "");
+ DCHECK(m_core);
+ m_core->data.store(reinterpret_cast<uintptr_t>(value), std::memory_order_release);
+ }
+
+ T &operator*() const { return *get(); }
+ T *operator->() const { return get(); }
+ explicit operator bool() const { return get(); }
+
+ bool MaybeValid() const { return m_core; }
+
+ static LockedPtr create(T *value)
+ {
+ return new LockedPtrCore(reinterpret_cast<uintptr_t>(value));
+ }
+
+private:
+ template<class T1, LockedPtrMode mode1> friend class LockedPtr;
+
+ LockedPtr(LockedPtrCore *core)
+ : m_core(core)
+ {}
+
+ void lock()
+ {
+ if (m_core) {
+ ++m_core->refCount;
+
+ if (mode == LockedPtrMode::Shared)
+ m_core->lock.lockForRead();
+ else if (mode == LockedPtrMode::Exclusive)
+ m_core->lock.lockForWrite();
+ }
+ }
+
+ void unlock()
+ {
+ if (m_core) {
+ if (mode != LockedPtrMode::Weak)
+ m_core->lock.unlock();
+
+ if (--m_core->refCount == 0)
+ delete m_core;
+ }
+ }
+
+ LockedPtrCore *m_core = nullptr;
+};
+
+// This makes Bind check the pointer before calling the functor.
+template<class T>
+struct IsWeakReceiver<WeakLockedPtr<T>> : std::true_type {};
+
+// By converting the WeakLockedPtr into a SharedLockedPtr we prevent the
+// pointed-to object from being destroyed during the base::Callback::Run call.
+//
+// Unwrap() is called before checking the pointer, so there's no race condition.
+template<class T>
+struct BindUnwrapTraits<WeakLockedPtr<T>>
+{
+ static SharedLockedPtr<T> Unwrap(const WeakLockedPtr<T> &o)
+ {
+ return o;
+ }
+};
+
+// Like base::WeakPtrFactory, but InvalidateWeakPtrs *waits* until all currently
+// executing base::Callbacks are finished. Queued up base::Callbacks are still
+// canceled, exactly like with WeakPtrFactory.
+//
+// Consider, for example, the function
+//
+// void fun()
+// {
+// MyClass *myClass = new MyClass;
+// myClass->scheduleDoStuff();
+// delete myClass; // ???
+// }
+//
+// where
+//
+// class MyClass
+// {
+// public:
+// void scheduleDoStuff()
+// {
+// content::BrowserThread::PostTask(
+// content::BrowserThread::IO, FROM_HERE,
+// base::BindOnce(&MyClass::doStuff, m_weakPtrFactory.GetWeakPtr()));
+// }
+// void doStuff();
+// private:
+// //base::WeakPtrFactory m_weakPtrFactory{this};
+// base::LockedPtrFactory m_weakPtrFactory{this};
+// };
+//
+// What happens if the 'delete myClass' line is executed concurrently with
+// MyClass::doStuff?
+//
+// With WeakPtrs we get a segfault or perhaps memory corruption.
+//
+// With LockedPtrs we get no crash and no corruption: LockedPtrFactory's
+// destructor will wait until doStuff is done before continuing.
+template<class T>
+class LockedPtrFactory
+{
+public:
+ explicit LockedPtrFactory(T *value)
+ : m_ptr(WeakLockedPtr<T>::create(value))
+ {}
+
+ ~LockedPtrFactory()
+ {
+ InvalidateWeakPtrs();
+ }
+
+ WeakLockedPtr<T> GetWeakPtr() { return m_ptr; }
+ WeakLockedPtr<const T> GetWeakPtr() const { return m_ptr; }
+ SharedLockedPtr<T> GetSharedPtr() { return m_ptr; }
+ SharedLockedPtr<const T> GetSharedPtr() const { return m_ptr; }
+ ExclusiveLockedPtr<T> GetExclusivePtr() { return m_ptr; }
+ ExclusiveLockedPtr<const T> GetExclusivePtr() const { return m_ptr; }
+
+ void InvalidateWeakPtrs()
+ {
+ if (ExclusiveLockedPtr<T> ptr = m_ptr)
+ ptr.set(nullptr);
+ }
+
+private:
+ WeakLockedPtr<T> m_ptr;
+};
+
+} // namespace base
+
+#endif // !LOCKED_PTR_H
diff --git a/src/core/login_delegate_qt.cpp b/src/core/login_delegate_qt.cpp
index 9659b354a..0050f87c7 100644
--- a/src/core/login_delegate_qt.cpp
+++ b/src/core/login_delegate_qt.cpp
@@ -43,17 +43,32 @@
#include "login_delegate_qt.h"
+#include "base/task/post_task.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/stream_info.h"
+#include "extensions/buildflags/buildflags.h"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/browser/info_map.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
#include "net/url_request/url_request.h"
#include "authentication_dialog_controller.h"
#include "authentication_dialog_controller_p.h"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/extension_system_qt.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+#include "resource_context_qt.h"
#include "type_conversion.h"
#include "web_contents_view_qt.h"
+#include "web_engine_context.h"
namespace QtWebEngineCore {
@@ -66,14 +81,9 @@ LoginDelegateQt::LoginDelegateQt(
: m_authInfo(authInfo)
, m_url(url)
, m_auth_required_callback(std::move(auth_required_callback))
+ , m_webContentsGetter(web_contents_getter)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(&LoginDelegateQt::triggerDialog,
- this,
- web_contents_getter));
}
LoginDelegateQt::~LoginDelegateQt()
@@ -81,6 +91,13 @@ LoginDelegateQt::~LoginDelegateQt()
Q_ASSERT(m_dialogController.isNull());
}
+void LoginDelegateQt::triggerDialog()
+{
+ base::PostTaskWithTraits(
+ FROM_HERE, { content::BrowserThread::UI },
+ base::BindOnce(&LoginDelegateQt::triggerDialogOnUI, this));
+}
+
void LoginDelegateQt::OnRequestCancelled()
{
destroy();
@@ -102,16 +119,34 @@ QString LoginDelegateQt::host() const
return QString::fromStdString(m_authInfo->challenger.host());
}
+int LoginDelegateQt::port() const
+{
+ return m_authInfo->challenger.port();
+}
+
bool LoginDelegateQt::isProxy() const
{
return m_authInfo->is_proxy;
}
-void LoginDelegateQt::triggerDialog(const content::ResourceRequestInfo::WebContentsGetter &webContentsGetter)
+void LoginDelegateQt::triggerDialogOnUI()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ if (isProxy()) {
+ // workaround for 'ws' redefined symbols when including QNetworkProxy
+ auto authentication = WebEngineContext::qProxyNetworkAuthentication(host(), port());
+ if (std::get<0>(authentication)) {
+ base::PostTaskWithTraits(
+ FROM_HERE, { content::BrowserThread::IO },
+ base::BindOnce(&LoginDelegateQt::sendAuthToRequester, this, true,
+ std::get<1>(authentication), std::get<2>(authentication)));
+
+ return;
+ }
+ }
content::WebContentsImpl *webContents =
- static_cast<content::WebContentsImpl *>(webContentsGetter.Run());
+ static_cast<content::WebContentsImpl *>(m_webContentsGetter.Run());
if (!webContents)
return;
WebContentsAdapterClient *client = WebContentsViewQt::from(webContents->GetView())->client();
diff --git a/src/core/login_delegate_qt.h b/src/core/login_delegate_qt.h
index 9ce5df843..3a9c073cd 100644
--- a/src/core/login_delegate_qt.h
+++ b/src/core/login_delegate_qt.h
@@ -66,24 +66,28 @@ public:
~LoginDelegateQt();
+ void triggerDialog();
+
// LoginDelegate implementation
void OnRequestCancelled() override;
QUrl url() const;
QString realm() const;
QString host() const;
+ int port() const;
bool isProxy() const;
void sendAuthToRequester(bool success, const QString &user, const QString &password);
private:
- void triggerDialog(const content::ResourceRequestInfo::WebContentsGetter &);
+ void triggerDialogOnUI();
void destroy();
scoped_refptr<net::AuthChallengeInfo> m_authInfo;
GURL m_url;
LoginAuthRequiredCallback m_auth_required_callback;
+ content::ResourceRequestInfo::WebContentsGetter m_webContentsGetter;
// This member is used to keep authentication dialog controller alive until
// authorization is sent or cancelled.
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index 2bac62084..ecc46f244 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -49,17 +49,16 @@
#include "web_engine_settings.h"
#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/media/webrtc/desktop_streams_registry.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
+#include "content/public/browser/desktop_streams_registry.h"
#include "content/public/browser/media_capture_devices.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/origin_util.h"
-#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_manager_base.h"
#include "ui/base/l10n/l10n_util.h"
@@ -74,13 +73,12 @@
namespace QtWebEngineCore {
using content::BrowserThread;
-using content::MediaStreamDevices;
namespace {
-const content::MediaStreamDevice *findDeviceWithId(const content::MediaStreamDevices &devices, const std::string &deviceId)
+const blink::MediaStreamDevice *findDeviceWithId(const blink::MediaStreamDevices &devices, const std::string &deviceId)
{
- content::MediaStreamDevices::const_iterator iter = devices.begin();
+ blink::MediaStreamDevices::const_iterator iter = devices.begin();
for (; iter != devices.end(); ++iter) {
if (iter->id == deviceId) {
return &(*iter);
@@ -90,21 +88,21 @@ const content::MediaStreamDevice *findDeviceWithId(const content::MediaStreamDev
}
// Based on chrome/browser/media/desktop_capture_access_handler.cc:
-void getDevicesForDesktopCapture(content::MediaStreamDevices *devices, content::DesktopMediaID mediaId, bool captureAudio)
+void getDevicesForDesktopCapture(blink::MediaStreamDevices *devices, content::DesktopMediaID mediaId, bool captureAudio)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Add selected desktop source to the list.
- devices->push_back(content::MediaStreamDevice(content::MEDIA_DESKTOP_VIDEO_CAPTURE, mediaId.ToString(), "Screen"));
+ devices->push_back(blink::MediaStreamDevice(blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE, mediaId.ToString(), "Screen"));
if (captureAudio) {
if (mediaId.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
devices->push_back(
- content::MediaStreamDevice(content::MEDIA_DESKTOP_AUDIO_CAPTURE,
- mediaId.ToString(), "Tab audio"));
+ blink::MediaStreamDevice(blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE,
+ mediaId.ToString(), "Tab audio"));
} else {
// Use the special loopback device ID for system audio capture.
- devices->push_back(content::MediaStreamDevice(
- content::MEDIA_DESKTOP_AUDIO_CAPTURE,
+ devices->push_back(blink::MediaStreamDevice(
+ blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE,
media::AudioDeviceDescription::kLoopbackInputDeviceId,
"System Audio"));
}
@@ -155,14 +153,14 @@ WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const co
{
WebContentsAdapterClient::MediaRequestFlags requestFlags = WebContentsAdapterClient::MediaNone;
- if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE)
+ if (request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE)
requestFlags |= WebContentsAdapterClient::MediaAudioCapture;
- else if (request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE)
+ else if (request.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE)
requestFlags |= WebContentsAdapterClient::MediaDesktopAudioCapture;
- if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE)
+ if (request.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE)
requestFlags |= WebContentsAdapterClient::MediaVideoCapture;
- else if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE)
+ else if (request.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE)
requestFlags |= WebContentsAdapterClient::MediaDesktopVideoCapture;
return requestFlags;
@@ -185,7 +183,7 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- content::MediaStreamDevices devices;
+ blink::MediaStreamDevices devices;
auto it = m_pendingRequests.find(webContents);
if (it == m_pendingRequests.end() || it->second.empty())
return;
@@ -212,11 +210,12 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
if (securityOriginsMatch) {
if (microphoneRequested || webcamRequested) {
switch (request.request_type) {
- case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
+ case blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices);
break;
- case content::MEDIA_DEVICE_ACCESS:
- case content::MEDIA_GENERATE_STREAM:
+ case blink::MEDIA_DEVICE_ACCESS:
+ case blink::MEDIA_DEVICE_UPDATE:
+ case blink::MEDIA_GENERATE_STREAM:
getDefaultDevices(request.requested_audio_device_id, request.requested_video_device_id,
microphoneRequested, webcamRequested, &devices);
break;
@@ -233,11 +232,12 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
// Post a task to process next queued request. It has to be done
// asynchronously to make sure that calling infobar is not destroyed until
// after this function returns.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, base::BindOnce(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest, base::Unretained(this), webContents));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest,
+ base::Unretained(this), webContents));
}
- std::move(callback).Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK,
+ std::move(callback).Run(devices, devices.empty() ? blink::MEDIA_DEVICE_INVALID_STATE : blink::MEDIA_DEVICE_OK,
std::unique_ptr<content::MediaStreamUI>());
}
@@ -275,17 +275,17 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Let's not support tab capture for now.
- if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) {
- std::move(callback).Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>());
+ if (request.video_type == blink::MEDIA_GUM_TAB_VIDEO_CAPTURE || request.audio_type == blink::MEDIA_GUM_TAB_AUDIO_CAPTURE) {
+ std::move(callback).Run(blink::MediaStreamDevices(), blink::MEDIA_DEVICE_NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>());
return;
}
- if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) {
+ if (request.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE || request.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE) {
const bool screenCaptureEnabled =
adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::ScreenCaptureEnabled);
const bool originIsSecure = content::IsOriginSecure(request.security_origin);
if (!screenCaptureEnabled || !originIsSecure) {
- std::move(callback).Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
+ std::move(callback).Run(blink::MediaStreamDevices(), blink::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -303,10 +303,10 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter
void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
{
- content::MediaStreamDevices devices;
+ blink::MediaStreamDevices devices;
- if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.requested_video_device_id.empty()) {
- std::move(callback).Run(devices, content::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
+ if (request.video_type != blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE || request.requested_video_device_id.empty()) {
+ std::move(callback).Run(devices, blink::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -319,24 +319,24 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
// The extension name that the stream is registered with.
std::string originalExtensionName;
// Resolve DesktopMediaID for the specified device id.
- mediaId = getDesktopStreamsRegistry()->RequestMediaForStreamId(
+ mediaId = content::DesktopStreamsRegistry::GetInstance()->RequestMediaForStreamId(
request.requested_video_device_id, main_frame->GetProcess()->GetID(),
main_frame->GetRoutingID(), request.security_origin,
- &originalExtensionName);
+ &originalExtensionName, content::kRegistryStreamTypeDesktop);
}
// Received invalid device id.
if (mediaId.type == content::DesktopMediaID::TYPE_NONE) {
- std::move(callback).Run(devices, content::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
+ std::move(callback).Run(devices, blink::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
}
// Audio is only supported for screen capture streams.
- bool capture_audio = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE);
+ bool capture_audio = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && request.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE);
getDevicesForDesktopCapture(&devices, mediaId, capture_audio);
- std::move(callback).Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK,
+ std::move(callback).Run(devices, devices.empty() ? blink::MEDIA_DEVICE_INVALID_STATE : blink::MEDIA_DEVICE_OK,
std::unique_ptr<content::MediaStreamUI>());
}
@@ -366,14 +366,14 @@ void MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest(content::WebConte
}
void MediaCaptureDevicesDispatcher::getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId,
- bool audio, bool video, content::MediaStreamDevices *devices)
+ bool audio, bool video, blink::MediaStreamDevices *devices)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(audio || video);
if (audio) {
- const content::MediaStreamDevices &audioDevices = content::MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices();
- const content::MediaStreamDevice *device = findDeviceWithId(audioDevices, audioDeviceId);
+ const blink::MediaStreamDevices &audioDevices = content::MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices();
+ const blink::MediaStreamDevice *device = findDeviceWithId(audioDevices, audioDeviceId);
if (!device && !audioDevices.empty())
device = &audioDevices.front();
if (device)
@@ -381,8 +381,8 @@ void MediaCaptureDevicesDispatcher::getDefaultDevices(const std::string &audioDe
}
if (video) {
- const content::MediaStreamDevices &videoDevices = content::MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices();
- const content::MediaStreamDevice *device = findDeviceWithId(videoDevices, videoDeviceId);
+ const blink::MediaStreamDevices &videoDevices = content::MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices();
+ const blink::MediaStreamDevice *device = findDeviceWithId(videoDevices, videoDeviceId);
if (!device && !videoDevices.empty())
device = &videoDevices.front();
if (device)
@@ -390,29 +390,20 @@ void MediaCaptureDevicesDispatcher::getDefaultDevices(const std::string &audioDe
}
}
-DesktopStreamsRegistry *MediaCaptureDevicesDispatcher::getDesktopStreamsRegistry()
-{
- if (!m_desktopStreamsRegistry)
- m_desktopStreamsRegistry.reset(new DesktopStreamsRegistry());
- return m_desktopStreamsRegistry.get();
-}
-
-void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(int render_process_id, int render_frame_id, int page_request_id, const GURL &security_origin, content::MediaStreamType stream_type, content::MediaRequestState state)
+void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(int render_process_id, int render_frame_id, int page_request_id, const GURL &security_origin, blink::MediaStreamType stream_type, content::MediaRequestState state)
{
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(
- &MediaCaptureDevicesDispatcher::updateMediaRequestStateOnUIThread,
- base::Unretained(this), render_process_id, render_frame_id,
- page_request_id, security_origin, stream_type, state));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&MediaCaptureDevicesDispatcher::updateMediaRequestStateOnUIThread,
+ base::Unretained(this), render_process_id, render_frame_id,
+ page_request_id, security_origin, stream_type, state));
}
void MediaCaptureDevicesDispatcher::updateMediaRequestStateOnUIThread(int render_process_id,
int render_frame_id,
int page_request_id,
const GURL & /*security_origin*/,
- content::MediaStreamType /*stream_type*/,
+ blink::MediaStreamType /*stream_type*/,
content::MediaRequestState state)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/src/core/media_capture_devices_dispatcher.h b/src/core/media_capture_devices_dispatcher.h
index 0e5aa38be..07afd54bf 100644
--- a/src/core/media_capture_devices_dispatcher.h
+++ b/src/core/media_capture_devices_dispatcher.h
@@ -55,9 +55,6 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_delegate.h"
-#include "content/public/common/media_stream_request.h"
-
-class DesktopStreamsRegistry;
namespace QtWebEngineCore {
@@ -75,7 +72,7 @@ public:
void handleMediaAccessPermissionResponse(content::WebContents *, const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags);
private:
- void getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId, bool audio, bool video, content::MediaStreamDevices *);
+ void getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId, bool audio, bool video, blink::MediaStreamDevices *);
// Overridden from content::MediaObserver:
void OnAudioCaptureDevicesChanged() override {}
@@ -84,22 +81,20 @@ private:
int render_frame_id,
int page_request_id,
const GURL &security_origin,
- content::MediaStreamType stream_type,
+ blink::MediaStreamType stream_type,
content::MediaRequestState state) override;
void OnCreatingAudioStream(int /*render_process_id*/, int /*render_frame_id*/) override {}
void OnSetCapturingLinkSecured(int /*render_process_id*/,
int /*render_frame_id*/,
int /*page_request_id*/,
- content::MediaStreamType /*stream_type*/,
+ blink::MediaStreamType /*stream_type*/,
bool /*is_secure*/) override {}
- DesktopStreamsRegistry *getDesktopStreamsRegistry();
-
friend struct base::DefaultSingletonTraits<MediaCaptureDevicesDispatcher>;
- typedef base::RepeatingCallback<void(const content::MediaStreamDevices &devices,
- content::MediaStreamRequestResult result,
+ typedef base::RepeatingCallback<void(const blink::MediaStreamDevices &devices,
+ blink::MediaStreamRequestResult result,
std::unique_ptr<content::MediaStreamUI> ui)>
RepeatingMediaResponseCallback;
@@ -125,12 +120,11 @@ private:
void ProcessQueuedAccessRequest(content::WebContents *);
// Called by the MediaObserver() functions, executed on UI thread.
- void updateMediaRequestStateOnUIThread(int render_process_id, int render_frame_id, int page_request_id, const GURL &security_origin, content::MediaStreamType stream_type, content::MediaRequestState state);
+ void updateMediaRequestStateOnUIThread(int render_process_id, int render_frame_id, int page_request_id, const GURL &security_origin,
+ blink::MediaStreamType stream_type, content::MediaRequestState state);
RequestsQueues m_pendingRequests;
- std::unique_ptr<DesktopStreamsRegistry> m_desktopStreamsRegistry;
-
content::NotificationRegistrar m_notificationsRegistrar;
DISALLOW_COPY_AND_ASSIGN(MediaCaptureDevicesDispatcher);
diff --git a/src/core/net/client_cert_override.cpp b/src/core/net/client_cert_override.cpp
new file mode 100644
index 000000000..305f0cef0
--- /dev/null
+++ b/src/core/net/client_cert_override.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "client_cert_override.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
+#include "base/callback_forward.h"
+#include "content/public/browser/browser_task_traits.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/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/pem.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+#include "client_cert_store_data.h"
+#include "profile_io_data_qt.h"
+
+#include <QtNetwork/qtnetworkglobal.h>
+
+#if defined(USE_NSS_CERTS)
+#include "net/ssl/client_cert_store_nss.h"
+#endif
+
+#if defined(OS_WIN)
+#include "net/ssl/client_cert_store_win.h"
+#endif
+
+#if defined(OS_MACOSX)
+#include "net/ssl/client_cert_store_mac.h"
+#endif
+
+namespace {
+
+class ClientCertIdentityOverride : public net::ClientCertIdentity
+{
+public:
+ ClientCertIdentityOverride(scoped_refptr<net::X509Certificate> cert, scoped_refptr<net::SSLPrivateKey> key)
+ : net::ClientCertIdentity(std::move(cert)), m_key(std::move(key)) {}
+ ~ClientCertIdentityOverride() override = default;
+
+ void AcquirePrivateKey(const base::Callback<void(scoped_refptr<net::SSLPrivateKey>)> &private_key_callback) override
+ {
+ private_key_callback.Run(m_key);
+ }
+
+#if defined(OS_MACOSX)
+ SecIdentityRef sec_identity_ref() const override
+ {
+ return nullptr;
+ }
+#endif
+
+private:
+ scoped_refptr<net::SSLPrivateKey> m_key;
+};
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+ClientCertOverrideStore::ClientCertOverrideStore(ClientCertificateStoreData *storeData)
+ : ClientCertStore()
+ , m_storeData(storeData)
+ , m_nativeStore(createNativeStore())
+{
+}
+
+ClientCertOverrideStore::~ClientCertOverrideStore() = default;
+
+#if QT_CONFIG(ssl)
+net::ClientCertIdentityList ClientCertOverrideStore::GetClientCertsOnUIThread(const net::SSLCertRequestInfo &cert_request_info)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ const auto &clientCertOverrideData = m_storeData->extraCerts;
+ // Look for certificates in memory store
+ for (int i = 0; i < clientCertOverrideData.length(); i++) {
+ scoped_refptr<net::X509Certificate> cert = clientCertOverrideData[i]->certPtr;
+ if (cert != NULL && cert->IsIssuedByEncoded(cert_request_info.cert_authorities)) {
+ net::ClientCertIdentityList selected_identities;
+ selected_identities.push_back(std::make_unique<ClientCertIdentityOverride>(cert, clientCertOverrideData[i]->keyPtr));
+ return selected_identities;
+ }
+ }
+ return net::ClientCertIdentityList();
+}
+
+void ClientCertOverrideStore::GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
+ const ClientCertListCallback &callback,
+ net::ClientCertIdentityList &&result)
+{
+ // Continue with native cert store if matching certificatse were not found in memory
+ if (result.empty() && m_nativeStore)
+ m_nativeStore->GetClientCerts(cert_request_info, callback);
+ else
+ callback.Run(std::move(result));
+}
+
+#endif // QT_CONFIG(ssl)
+
+void ClientCertOverrideStore::GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
+ const ClientCertListCallback &callback)
+{
+#if QT_CONFIG(ssl)
+ // Access the user-provided data from the UI thread, but return on whatever thread this is.
+ if (base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, { content::BrowserThread::UI },
+ base::BindOnce(&ClientCertOverrideStore::GetClientCertsOnUIThread,
+ base::Unretained(this), base::ConstRef(cert_request_info)),
+ base::BindOnce(&ClientCertOverrideStore::GetClientCertsReturn,
+ base::Unretained(this), base::ConstRef(cert_request_info), callback))
+ ) {
+ return;
+ }
+#endif // QT_CONFIG(ssl)
+
+ // Continue with native cert store if we failed to post task
+ if (m_nativeStore)
+ m_nativeStore->GetClientCerts(cert_request_info, callback);
+ else
+ callback.Run(net::ClientCertIdentityList());
+}
+
+// static
+std::unique_ptr<net::ClientCertStore> ClientCertOverrideStore::createNativeStore()
+{
+#if defined(USE_NSS_CERTS)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory()));
+#elif defined(OS_WIN)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
+#elif defined(OS_MACOSX)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
+#else
+ return nullptr;
+#endif
+}
+} // namespace QtWebEngineCore
diff --git a/src/core/net/client_cert_override.h b/src/core/net/client_cert_override.h
new file mode 100644
index 000000000..35c1f96af
--- /dev/null
+++ b/src/core/net/client_cert_override.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CLIENT_CERT_OVERRIDE_P_H
+#define CLIENT_CERT_OVERRIDE_P_H
+
+#include "net/ssl/client_cert_store.h"
+#include "base/callback_forward.h"
+#include "net/cert/x509_certificate.h"
+
+namespace net {
+class SSLCertRequestInfo;
+} // namespace net
+
+namespace QtWebEngineCore {
+struct ClientCertificateStoreData;
+
+class ClientCertOverrideStore : public net::ClientCertStore
+{
+public:
+ ClientCertOverrideStore(ClientCertificateStoreData *storeData);
+ virtual ~ClientCertOverrideStore() override;
+ void GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
+ const ClientCertListCallback &callback) override;
+private:
+ static std::unique_ptr<net::ClientCertStore> createNativeStore();
+ net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
+ void GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
+ const ClientCertListCallback &callback,
+ net::ClientCertIdentityList &&result);
+ ClientCertificateStoreData *m_storeData;
+ std::unique_ptr<net::ClientCertStore> m_nativeStore;
+};
+
+} // QtWebEngineCore
+
+#endif
+
+
diff --git a/src/core/net/client_cert_store_data.cpp b/src/core/net/client_cert_store_data.cpp
new file mode 100644
index 000000000..5a62cb6fe
--- /dev/null
+++ b/src/core/net/client_cert_store_data.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "net/client_cert_store_data.h"
+
+#if QT_CONFIG(ssl)
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "net/base/net_errors.h"
+#include "net/cert/x509_certificate.h"
+#include "net/ssl/ssl_platform_key_util.h"
+#include "net/ssl/ssl_private_key.h"
+#include "net/ssl/threaded_ssl_private_key.h"
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
+#include "third_party/boringssl/src/include/openssl/pem.h"
+
+#include "QtCore/qbytearray.h"
+
+namespace {
+
+class SSLPlatformKeyOverride : public net::ThreadedSSLPrivateKey::Delegate {
+public:
+ SSLPlatformKeyOverride(const QByteArray &sslKeyInBytes)
+ {
+ m_mem = BIO_new_mem_buf(sslKeyInBytes, -1);
+ m_key = PEM_read_bio_PrivateKey(m_mem, nullptr, nullptr, nullptr);
+ }
+
+ ~SSLPlatformKeyOverride() override
+ {
+ if (m_key)
+ EVP_PKEY_free(m_key);
+ if (m_mem)
+ BIO_free(m_mem);
+ }
+
+ net::Error Sign(uint16_t algorithm, base::span<const uint8_t> input, std::vector<uint8_t> *signature) override
+ {
+ bssl::ScopedEVP_MD_CTX ctx;
+ EVP_PKEY_CTX *pctx;
+ if (!EVP_DigestSignInit(ctx.get(), &pctx,
+ SSL_get_signature_algorithm_digest(algorithm),
+ nullptr, m_key)) {
+ return net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ }
+
+ if (SSL_is_signature_algorithm_rsa_pss(algorithm)) {
+ if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+ !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* hash length */)) {
+ return net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ }
+ }
+ size_t sig_len = 0;
+ if (!EVP_DigestSign(ctx.get(), NULL, &sig_len, input.data(), input.size()))
+ return net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ signature->resize(sig_len);
+ if (!EVP_DigestSign(ctx.get(), signature->data(), &sig_len, input.data(), input.size()))
+ return net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ signature->resize(sig_len);
+ return net::OK;
+ }
+
+ std::vector<uint16_t> GetAlgorithmPreferences() override
+ {
+ return { SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA512
+ , SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA256 };
+ }
+ std::string GetProviderName() override {
+ return "qtwebengine";
+ }
+private:
+ EVP_PKEY *m_key;
+ BIO *m_mem;
+
+ DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyOverride);
+};
+
+scoped_refptr<net::SSLPrivateKey> wrapOpenSSLPrivateKey(const QByteArray &sslKeyInBytes)
+{
+ if (sslKeyInBytes.isEmpty())
+ return nullptr;
+
+ return base::MakeRefCounted<net::ThreadedSSLPrivateKey>(
+ std::make_unique<SSLPlatformKeyOverride>(sslKeyInBytes),
+ net::GetSSLPlatformKeyTaskRunner());
+}
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+void ClientCertificateStoreData::add(const QSslCertificate &certificate, const QSslKey &privateKey)
+{
+ QByteArray sslKeyInBytes = privateKey.toPem();
+ QByteArray certInBytes = certificate.toDer();
+
+ Entry *data = new Entry;
+ data->keyPtr = wrapOpenSSLPrivateKey(sslKeyInBytes);
+ data->certPtr = net::X509Certificate::CreateFromBytes(certInBytes.data(), certInBytes.length());
+ data->key = privateKey;
+ data->certificate = certificate;
+ extraCerts.append(data);
+}
+
+void ClientCertificateStoreData::remove(const QSslCertificate &certificate)
+{
+ auto it = extraCerts.begin();
+ while (it != extraCerts.end()) {
+ const QtWebEngineCore::ClientCertificateStoreData::Entry *overrideData = *it;
+ if (certificate.toDer() == overrideData->certificate.toDer()) {
+ it = extraCerts.erase(it);
+ delete overrideData;
+ continue;
+ }
+ ++it;
+ }
+}
+
+void ClientCertificateStoreData::clear()
+{
+ qDeleteAll(extraCerts);
+ extraCerts.clear();
+}
+
+} // namespace QtWebEngineCore
+
+#endif
diff --git a/src/core/net/client_cert_store_data.h b/src/core/net/client_cert_store_data.h
new file mode 100644
index 000000000..7f83f4b60
--- /dev/null
+++ b/src/core/net/client_cert_store_data.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CLIENT_CERT_STORE_DATA_H
+#define CLIENT_CERT_STORE_DATA_H
+
+#include "qtwebenginecoreglobal.h"
+#include "qtnetworkglobal.h"
+
+#if QT_CONFIG(ssl)
+#include "base/memory/ref_counted.h"
+
+#include <QtCore/qvector.h>
+#include <QtNetwork/qsslcertificate.h>
+#include <QtNetwork/qsslkey.h>
+
+namespace net {
+class SSLPrivateKey;
+class X509Certificate;
+}
+
+namespace QtWebEngineCore {
+
+struct ClientCertificateStoreData {
+ struct Entry {
+ QSslKey key;
+ QSslCertificate certificate;
+ scoped_refptr<net::X509Certificate> certPtr;
+ scoped_refptr<net::SSLPrivateKey> keyPtr;
+ };
+
+ void add(const QSslCertificate &certificate, const QSslKey &privateKey);
+ void remove(const QSslCertificate &certificate);
+ void clear();
+
+ QVector<Entry*> extraCerts;
+};
+
+} // namespace QtWebEngineCore
+
+#endif
+#endif // CLIENT_CERT_STORE_DATA_H
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index bb89e9e5f..3253b08b9 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -41,6 +41,8 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/cookies/cookie_util.h"
@@ -87,8 +89,8 @@ void CookieMonsterDelegateQt::getAllCookies(quint64 callbackId)
net::CookieMonster::GetCookieListCallback callback =
base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread, this, callbackId);
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesOnIOThread, this, std::move(callback)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesOnIOThread, this, std::move(callback)));
}
void CookieMonsterDelegateQt::GetAllCookiesOnIOThread(net::CookieMonster::GetCookieListCallback callback)
@@ -108,9 +110,9 @@ void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie
GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::SetCookieOnIOThread, this,
- gurl, cookie.toRawForm().toStdString(), std::move(callback)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&CookieMonsterDelegateQt::SetCookieOnIOThread, this,
+ gurl, cookie.toRawForm().toStdString(), std::move(callback)));
}
void CookieMonsterDelegateQt::SetCookieOnIOThread(
@@ -131,9 +133,9 @@ void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const Q
GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin);
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::DeleteCookieOnIOThread, this,
- gurl, cookie.name().toStdString()));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteCookieOnIOThread, this,
+ gurl, cookie.name().toStdString()));
}
void CookieMonsterDelegateQt::DeleteCookieOnIOThread(const GURL& url, const std::string& cookie_name)
@@ -149,8 +151,8 @@ void CookieMonsterDelegateQt::deleteSessionCookies(quint64 callbackId)
net::CookieMonster::DeleteCallback callback =
base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnIOThread, this, callbackId);
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread, this, std::move(callback)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread, this, std::move(callback)));
}
void CookieMonsterDelegateQt::DeleteSessionCookiesOnIOThread(net::CookieMonster::DeleteCallback callback)
@@ -166,8 +168,8 @@ void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId)
net::CookieMonster::DeleteCallback callback =
base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnIOThread, this, callbackId);
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::DeleteAllOnIOThread, this, std::move(callback)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteAllOnIOThread, this, std::move(callback)));
}
void CookieMonsterDelegateQt::DeleteAllOnIOThread(net::CookieMonster::DeleteCallback callback)
@@ -238,26 +240,23 @@ void CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread(qint64 callbackId,
for (auto &&cookie : cookies)
rawCookies += toQt(cookie).toRawForm() % QByteArrayLiteral("\n");
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread, this, callbackId, rawCookies));
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread, this, callbackId, rawCookies));
}
void CookieMonsterDelegateQt::SetCookieCallbackOnIOThread(qint64 callbackId, bool success)
{
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId, success));
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId, success));
}
void CookieMonsterDelegateQt::DeleteCookiesCallbackOnIOThread(qint64 callbackId, uint numCookies)
{
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread, this, callbackId, numCookies));
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread, this, callbackId, numCookies));
}
void CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread(qint64 callbackId, const QByteArray &cookies)
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
index 7933ba329..88e92b560 100644
--- a/src/core/net/cookie_monster_delegate_qt.h
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -75,7 +75,7 @@ namespace QtWebEngineCore {
static const char* const kCookieableSchemes[] =
{ "http", "https", "qrc", "ws", "wss" };
-class QWEBENGINECORE_PRIVATE_EXPORT CookieMonsterDelegateQt : public base::RefCountedThreadSafe<CookieMonsterDelegateQt> {
+class Q_WEBENGINECORE_PRIVATE_EXPORT CookieMonsterDelegateQt : public base::RefCountedThreadSafe<CookieMonsterDelegateQt> {
QPointer<QWebEngineCookieStore> m_client;
net::CookieMonster *m_cookieMonster;
std::vector<std::unique_ptr<net::CookieChangeSubscription>> m_subscriptions;
diff --git a/src/core/net/custom_protocol_handler.cpp b/src/core/net/custom_protocol_handler.cpp
index 5132782c2..7e8ee47ab 100644
--- a/src/core/net/custom_protocol_handler.cpp
+++ b/src/core/net/custom_protocol_handler.cpp
@@ -54,7 +54,7 @@ CustomProtocolHandler::CustomProtocolHandler(QPointer<ProfileAdapter> profileAda
net::URLRequestJob *CustomProtocolHandler::MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const
{
if (!networkDelegate)
- return new net::URLRequestErrorJob(request, Q_NULLPTR, net::ERR_ACCESS_DENIED);
+ return new net::URLRequestErrorJob(request, nullptr, net::ERR_ACCESS_DENIED);
return new URLRequestCustomJob(request, networkDelegate, request->url().scheme(), m_profileAdapter);
}
diff --git a/src/core/net/custom_protocol_handler.h b/src/core/net/custom_protocol_handler.h
index d5b512b03..7b189763c 100644
--- a/src/core/net/custom_protocol_handler.h
+++ b/src/core/net/custom_protocol_handler.h
@@ -71,7 +71,7 @@ class ProfileAdapter;
// Implements a ProtocolHandler for custom URL schemes.
// If |network_delegate_| is NULL then all file requests will fail with ERR_ACCESS_DENIED.
-class QWEBENGINECORE_PRIVATE_EXPORT CustomProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
+class Q_WEBENGINECORE_PRIVATE_EXPORT CustomProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
CustomProtocolHandler(QPointer<ProfileAdapter> profileAdapter);
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index f6202cf1b..7f278fd92 100644
--- a/src/core/net/network_delegate_qt.cpp
+++ b/src/core/net/network_delegate_qt.cpp
@@ -39,22 +39,26 @@
#include "network_delegate_qt.h"
-#include "profile_adapter.h"
+#include "base/task/post_task.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_request_info.h"
-#include "cookie_monster_delegate_qt.h"
-#include "ui/base/page_transition_types.h"
-#include "profile_io_data_qt.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request.h"
+#include "ui/base/page_transition_types.h"
+
+#include "profile_adapter.h"
+#include "cookie_monster_delegate_qt.h"
+#include "profile_io_data_qt.h"
#include "qwebengineurlrequestinfo.h"
#include "qwebengineurlrequestinfo_p.h"
#include "qwebengineurlrequestinterceptor.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
+#include "url_request_notification.h"
namespace QtWebEngineCore {
@@ -84,128 +88,18 @@ WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::Page
}
}
-namespace {
-
-QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourceType)
+static QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourceType)
{
if (resourceType >= 0 && resourceType < content::ResourceType(QWebEngineUrlRequestInfo::ResourceTypeLast))
return static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType);
return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
}
-QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
+static QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
{
return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
}
-// Notifies WebContentsAdapterClient of a new URLRequest.
-class URLRequestNotification {
-public:
- URLRequestNotification(net::URLRequest *request,
- const QUrl &url,
- bool isMainFrameRequest,
- int navigationType,
- int frameTreeNodeId,
- net::CompletionOnceCallback callback)
- : m_request(request)
- , m_url(url)
- , m_isMainFrameRequest(isMainFrameRequest)
- , m_navigationType(navigationType)
- , m_frameTreeNodeId(frameTreeNodeId)
- , m_callback(std::move(callback))
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- m_request->SetUserData(UserData::key, std::make_unique<UserData>(this));
-
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(&URLRequestNotification::notify, base::Unretained(this)));
- }
-
-private:
- // Calls cancel() when the URLRequest is destroyed.
- class UserData : public base::SupportsUserData::Data {
- public:
- UserData(URLRequestNotification *ptr) : m_ptr(ptr) {}
- ~UserData() { m_ptr->cancel(); }
- static const char key[];
- private:
- URLRequestNotification *m_ptr;
- };
-
- void cancel()
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- // May run concurrently with notify() but we only touch m_request here.
-
- m_request = nullptr;
- }
-
- void notify()
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- // May run concurrently with cancel() so no peeking at m_request here.
-
- int error = net::OK;
- content::WebContents *webContents = content::WebContents::FromFrameTreeNodeId(m_frameTreeNodeId);
- if (webContents) {
- int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
- WebContentsAdapterClient *client =
- WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();
- client->navigationRequested(m_navigationType,
- m_url,
- navigationRequestAction,
- m_isMainFrameRequest);
- error = net::ERR_FAILED;
- switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
- case WebContentsAdapterClient::AcceptRequest:
- error = net::OK;
- break;
- case WebContentsAdapterClient::IgnoreRequest:
- error = net::ERR_ABORTED;
- break;
- }
- DCHECK(error != net::ERR_FAILED);
- }
-
- // Run the callback on the IO thread.
- content::BrowserThread::PostTask(
- content::BrowserThread::IO,
- FROM_HERE,
- base::BindOnce(&URLRequestNotification::complete, base::Unretained(this), error));
- }
-
- void complete(int error)
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (m_request) {
- if (m_request->status().status() != net::URLRequestStatus::CANCELED)
- std::move(m_callback).Run(error);
- m_request->RemoveUserData(UserData::key);
- }
-
- delete this;
- }
-
- ~URLRequestNotification() {}
-
- net::URLRequest *m_request;
- QUrl m_url;
- bool m_isMainFrameRequest;
- int m_navigationType;
- int m_frameTreeNodeId;
- net::CompletionOnceCallback m_callback;
-};
-
-const char URLRequestNotification::UserData::key[] = "QtWebEngineCore::URLRequestNotification";
-
-} // namespace
-
NetworkDelegateQt::NetworkDelegateQt(ProfileIODataQt *data)
: m_profileIOData(data)
{
@@ -215,7 +109,6 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_profileIOData);
-
const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
content::ResourceType resourceType = content::RESOURCE_TYPE_LAST_TYPE;
@@ -234,56 +127,65 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
else
firstPartyUrl = toQt(request->site_for_cookies());
- QWebEngineUrlRequestInterceptor* interceptor = m_profileIOData->acquireInterceptor();
- if (interceptor) {
- QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
- toQt(navigationType),
- qUrl,
- firstPartyUrl,
- QByteArray::fromStdString(request->method()));
- QWebEngineUrlRequestInfo requestInfo(infoPrivate);
- interceptor->interceptRequest(requestInfo);
- m_profileIOData->releaseInterceptor();
- if (requestInfo.changed()) {
- int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
-
- if (qUrl != infoPrivate->url)
- *newUrl = toGurl(infoPrivate->url);
-
- if (!infoPrivate->extraHeaders.isEmpty()) {
- auto end = infoPrivate->extraHeaders.constEnd();
- for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header) {
- std::string h = header.key().toStdString();
- if (base::LowerCaseEqualsASCII(h, "referer")) {
- request->SetReferrer(header.value().toStdString());
- } else {
- request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
+ QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
+ toQt(navigationType),
+ qUrl,
+ firstPartyUrl,
+ QByteArray::fromStdString(request->method()));
+ QWebEngineUrlRequestInfo requestInfo(infoPrivate);
+
+ // Deprecated =begin
+ // quick peek if deprecated
+ QWebEngineUrlRequestInterceptor* profileInterceptor = m_profileIOData->requestInterceptor();
+ if (profileInterceptor && profileInterceptor->property("deprecated").toBool()) {
+ profileInterceptor = nullptr;
+ if (QWebEngineUrlRequestInterceptor* interceptor = m_profileIOData->acquireInterceptor()) {
+ interceptor->interceptRequest(requestInfo);
+ m_profileIOData->releaseInterceptor();
+ if (requestInfo.changed()) {
+ int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
+
+ if (qUrl != infoPrivate->url)
+ *newUrl = toGurl(infoPrivate->url);
+
+ if (!infoPrivate->extraHeaders.isEmpty()) {
+ auto end = infoPrivate->extraHeaders.constEnd();
+ for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header) {
+ std::string h = header.key().toStdString();
+ if (base::LowerCaseEqualsASCII(h, "referer")) {
+ request->SetReferrer(header.value().toStdString());
+ } else {
+ request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
+ }
}
}
- }
- if (result != net::OK)
- return result;
+ if (result != net::OK)
+ return result;
+
+ requestInfo.resetChanged();
+ }
+ } else {
+ m_profileIOData->releaseInterceptor();
}
- } else {
- m_profileIOData->releaseInterceptor();
}
+ // Deprecated =cut
if (!resourceInfo)
return net::OK;
- int frameTreeNodeId = resourceInfo->GetFrameTreeNodeId();
- // Only intercept MAIN_FRAME and SUB_FRAME with an associated render frame.
- if (!content::IsResourceTypeFrame(resourceType) || frameTreeNodeId == -1)
+ if (!m_profileIOData->hasPageInterceptors() && !profileInterceptor && !content::IsResourceTypeFrame(resourceType))
return net::OK;
+ auto webContentsGetter = resourceInfo->GetWebContentsGetterForRequest();
new URLRequestNotification(
request,
- qUrl,
resourceInfo->IsMainFrame(),
- navigationType,
- frameTreeNodeId,
- std::move(callback)
+ newUrl,
+ std::move(requestInfo),
+ webContentsGetter,
+ std::move(callback),
+ profileInterceptor ? m_profileIOData->profileAdapter() : nullptr
);
// We'll run the callback after we notified the UI thread.
@@ -300,19 +202,26 @@ void NetworkDelegateQt::OnCompleted(net::URLRequest */*request*/, bool /*started
bool NetworkDelegateQt::OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie & /*cookie*/,
- net::CookieOptions*)
+ net::CookieOptions*,
+ bool allowedFromCaller)
{
+ if (!allowedFromCaller)
+ return false;
return canSetCookies(request.site_for_cookies(), request.url(), std::string());
}
-bool NetworkDelegateQt::OnCanGetCookies(const net::URLRequest& request, const net::CookieList&)
+bool NetworkDelegateQt::OnCanGetCookies(const net::URLRequest& request, const net::CookieList&, bool allowedFromCaller)
{
+ if (!allowedFromCaller)
+ return false;
return canGetCookies(request.site_for_cookies(), request.url());
}
-bool NetworkDelegateQt::OnCanEnablePrivacyMode(const GURL &url, const GURL &site_for_cookies) const
+bool NetworkDelegateQt::OnForcePrivacyMode(const GURL &url, const GURL &site_for_cookies) const
{
- return !canGetCookies(site_for_cookies, url);
+ return false;
+// FIXME: This is what the NetworkContext implementation does (changes tst_QWebEngineCookieStore tests since 72)
+// return !canGetCookies(site_for_cookies, url);
}
bool NetworkDelegateQt::canSetCookies(const GURL &first_party, const GURL &url, const std::string &cookie_line) const
@@ -376,11 +285,6 @@ bool NetworkDelegateQt::OnCanAccessFile(const net::URLRequest&, const base::File
return true;
}
-bool NetworkDelegateQt::OnAreExperimentalCookieFeaturesEnabled() const
-{
- return false;
-}
-
bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const
{
return false;
diff --git a/src/core/net/network_delegate_qt.h b/src/core/net/network_delegate_qt.h
index e4ff196aa..53debadcd 100644
--- a/src/core/net/network_delegate_qt.h
+++ b/src/core/net/network_delegate_qt.h
@@ -62,7 +62,7 @@ public:
// net::NetworkDelegate implementation
int OnBeforeURLRequest(net::URLRequest* request, net::CompletionOnceCallback callback, GURL* new_url) override;
void OnURLRequestDestroyed(net::URLRequest* request) override;
- bool OnCanSetCookie(const net::URLRequest& request, const net::CanonicalCookie& cookie, net::CookieOptions* options) override;
+ bool OnCanSetCookie(const net::URLRequest& request, const net::CanonicalCookie& cookie, net::CookieOptions* options, bool) override;
int OnBeforeStartTransaction(net::URLRequest *request, const net::CompletionOnceCallback callback, net::HttpRequestHeaders *headers) override;
void OnBeforeSendHeaders(net::URLRequest* request, const net::ProxyInfo& proxy_info,
const net::ProxyRetryInfoMap& proxy_retry_info, net::HttpRequestHeaders* headers) override;
@@ -75,10 +75,9 @@ public:
void OnCompleted(net::URLRequest *request, bool started, int net_error) override;
void OnPACScriptError(int, const base::string16&) override;
net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(net::URLRequest*, const net::AuthChallengeInfo&, AuthCallback, net::AuthCredentials*) override;
- bool OnCanGetCookies(const net::URLRequest&, const net::CookieList&) override;
+ bool OnCanGetCookies(const net::URLRequest&, const net::CookieList&, bool) override;
bool OnCanAccessFile(const net::URLRequest&, const base::FilePath&, const base::FilePath&) const override;
- bool OnCanEnablePrivacyMode(const GURL&, const GURL&) const override;
- bool OnAreExperimentalCookieFeaturesEnabled() const override;
+ bool OnForcePrivacyMode(const GURL&, const GURL&) const override;
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const override;
bool OnCanQueueReportingReport(const url::Origin& origin) const override;
diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp
index 13b969281..00ff1c54d 100644
--- a/src/core/net/proxy_config_service_qt.cpp
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -47,6 +47,7 @@
#include "base/bind.h"
#include "content/public/browser/browser_thread.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
using content::BrowserThread;
@@ -68,10 +69,13 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
}
}
-ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService)
+ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService,
+ const net::ProxyConfigWithAnnotation& initialConfig, ProxyPrefs::ConfigState initialState)
: m_baseService(baseService.release()),
m_usesSystemConfiguration(false),
- m_registeredObserver(false)
+ m_registeredObserver(false),
+ m_prefConfig(initialConfig),
+ m_perfState(initialState)
{
}
@@ -100,8 +104,10 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy
ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
if (m_baseService.get())
systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
- *config = systemConfig;
- // make sure to get updates via OnProxyConfigChanged
+ ProxyPrefs::ConfigState configState;
+ systemAvailability = PrefProxyConfigTrackerImpl::GetEffectiveProxyConfig(
+ m_perfState, m_prefConfig, systemAvailability, systemConfig,
+ false, &configState, config);
RegisterObserver();
return systemAvailability;
}
@@ -137,7 +143,7 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy
qtRules.type = net::ProxyConfig::ProxyRules::Type::EMPTY;
}
- qtRules.bypass_rules.AddRuleToBypassLocal(); // don't use proxy for connections to localhost
+ qtRules.bypass_rules.PrependRuleToBypassSimpleHostnames(); // don't use proxy for connections to localhost
m_qtProxyConfig.proxy_rules() = qtRules;
*config = net::ProxyConfigWithAnnotation(m_qtProxyConfig, config->traffic_annotation());
return CONFIG_VALID;
diff --git a/src/core/net/proxy_config_service_qt.h b/src/core/net/proxy_config_service_qt.h
index dcd303894..09e88d445 100644
--- a/src/core/net/proxy_config_service_qt.h
+++ b/src/core/net/proxy_config_service_qt.h
@@ -43,8 +43,10 @@
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
+#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
+#include "components/proxy_config/proxy_prefs.h"
#include <QNetworkProxy>
@@ -55,7 +57,9 @@ public:
static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &);
- explicit ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService);
+ explicit ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService,
+ const net::ProxyConfigWithAnnotation& initialConfig,
+ ProxyPrefs::ConfigState initialState);
~ProxyConfigServiceQt() override;
// ProxyConfigService implementation:
@@ -76,7 +80,7 @@ private:
void RegisterObserver();
std::unique_ptr<net::ProxyConfigService> m_baseService;
- base::ObserverList<net::ProxyConfigService::Observer, true> m_observers;
+ base::ObserverList<net::ProxyConfigService::Observer, true>::Unchecked m_observers;
// Keep the last state around.
bool m_usesSystemConfiguration;
@@ -86,6 +90,10 @@ private:
// Indicates whether the base service registration is done.
bool m_registeredObserver;
+ // Configuration as defined by prefs.
+ net::ProxyConfigWithAnnotation m_prefConfig;
+ ProxyPrefs::ConfigState m_perfState;
+
DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
};
diff --git a/src/core/net/url_request_qrc_job_qt.h b/src/core/net/qrc_url_scheme_handler.cpp
index 11c130693..73bf24f1d 100644
--- a/src/core/net/url_request_qrc_job_qt.h
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,40 +37,37 @@
**
****************************************************************************/
-#ifndef URL_REQUEST_QRC_JOB_QT_H_
-#define URL_REQUEST_QRC_JOB_QT_H_
+#include "qrc_url_scheme_handler.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_job.h"
+#include <QtWebEngineCore/qwebengineurlrequestjob.h>
#include <QFile>
+#include <QFileInfo>
+#include <QMimeDatabase>
+#include <QMimeType>
namespace QtWebEngineCore {
-// A request job that handles reading qrc file URLs
-class URLRequestQrcJobQt : public net::URLRequestJob {
+void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
+{
+ QByteArray requestMethod = job->requestMethod();
+ if (requestMethod != "GET") {
+ job->fail(QWebEngineUrlRequestJob::RequestDenied);
+ return;
+ }
-public:
- URLRequestQrcJobQt(net::URLRequest *request, net::NetworkDelegate *networkDelegate);
- void Start() override;
- void Kill() override;
- int ReadRawData(net::IOBuffer* buf, int buf_size) override;;
- bool GetMimeType(std::string *mimeType) const override;
-
-protected:
- virtual ~URLRequestQrcJobQt();
- // Get file mime type and try open file on a background thread.
- void startGetHead();
-
-private:
- qint64 m_remainingBytes;
- QFile m_file;
- std::string m_mimeType;
- base::WeakPtrFactory<URLRequestQrcJobQt> m_weakFactory;
-
- DISALLOW_COPY_AND_ASSIGN(URLRequestQrcJobQt);
-};
+ QUrl requestUrl = job->requestUrl();
+ QString requestPath = requestUrl.path();
+ QScopedPointer<QFile> file(new QFile(':' + requestPath, job));
+ if (!file->exists() || file->size() == 0) {
+ qWarning("QResource '%s' not found or is empty", qUtf8Printable(requestPath));
+ job->fail(QWebEngineUrlRequestJob::UrlNotFound);
+ return;
+ }
+ QFileInfo fileInfo(*file);
+ QMimeDatabase mimeDatabase;
+ QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
+ job->reply(mimeType.name().toUtf8(), file.take());
+}
} // namespace QtWebEngineCore
-
-#endif // URL_REQUEST_QRC_JOB_QT_H_
diff --git a/src/core/net/qrc_url_scheme_handler.h b/src/core/net/qrc_url_scheme_handler.h
new file mode 100644
index 000000000..f6ca92879
--- /dev/null
+++ b/src/core/net/qrc_url_scheme_handler.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRC_URL_SCHEME_HANDLER_H
+#define QRC_URL_SCHEME_HANDLER_H
+
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtWebEngineCore/qwebengineurlschemehandler.h>
+
+namespace QtWebEngineCore {
+
+class QrcUrlSchemeHandler final : public QWebEngineUrlSchemeHandler {
+public:
+ void requestStarted(QWebEngineUrlRequestJob *) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !QRC_URL_SCHEME_HANDLER_H
diff --git a/src/core/net/url_request_context_getter_qt.cpp b/src/core/net/url_request_context_getter_qt.cpp
index 636d27358..6081a5e9f 100644
--- a/src/core/net/url_request_context_getter_qt.cpp
+++ b/src/core/net/url_request_context_getter_qt.cpp
@@ -40,6 +40,10 @@
#include "url_request_context_getter_qt.h"
#include "profile_io_data_qt.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+
namespace QtWebEngineCore {
URLRequestContextGetterQt::URLRequestContextGetterQt(ProfileIODataQt *data)
@@ -59,7 +63,7 @@ net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
scoped_refptr<base::SingleThreadTaskRunner> URLRequestContextGetterQt::GetNetworkTaskRunner() const
{
- return content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO);
+ return base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO});
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/url_request_custom_job.cpp b/src/core/net/url_request_custom_job.cpp
index d371c7bff..cba9b4dc5 100644
--- a/src/core/net/url_request_custom_job.cpp
+++ b/src/core/net/url_request_custom_job.cpp
@@ -39,6 +39,9 @@
#include "url_request_custom_job.h"
#include "url_request_custom_job_proxy.h"
+
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
@@ -68,17 +71,30 @@ URLRequestCustomJob::~URLRequestCustomJob()
if (m_device && m_device->isOpen())
m_device->close();
m_device = nullptr;
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::release,
- m_proxy));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
}
void URLRequestCustomJob::Start()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::initialize,
- m_proxy, request()->url(), request()->method(), request()->initiator()));
+ HttpRequestHeaders requestHeaders = request()->extra_request_headers();
+ std::map<std::string, std::string> headers;
+ net::HttpRequestHeaders::Iterator it(requestHeaders);
+ while (it.GetNext())
+ headers.emplace(it.name(), it.value());
+ if (!request()->referrer().empty())
+ headers.emplace("Referer", request()->referrer());
+
+ // TODO: handle UploadDataStream, for instance using a QIODevice wrapper.
+
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&URLRequestCustomJobProxy::initialize,
+ m_proxy,
+ request()->url(),
+ request()->method(),
+ request()->initiator(),
+ std::move(headers)));
}
void URLRequestCustomJob::Kill()
@@ -94,9 +110,9 @@ void URLRequestCustomJob::Kill()
m_pendingReadPos = 0;
}
m_device = nullptr;
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::release,
- m_proxy));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&URLRequestCustomJobProxy::release,
+ m_proxy));
URLRequestJob::Kill();
}
diff --git a/src/core/net/url_request_custom_job_delegate.cpp b/src/core/net/url_request_custom_job_delegate.cpp
index 338bd7137..b5a7a55a7 100644
--- a/src/core/net/url_request_custom_job_delegate.cpp
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -40,9 +40,12 @@
#include "url_request_custom_job_delegate.h"
#include "url_request_custom_job_proxy.h"
-#include "type_conversion.h"
-#include "net/base/net_errors.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "net/base/net_errors.h"
+
+#include "type_conversion.h"
#include <QByteArray>
@@ -51,11 +54,13 @@ namespace QtWebEngineCore {
URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
const QUrl &url,
const QByteArray &method,
- const QUrl &initiatorOrigin)
+ const QUrl &initiatorOrigin,
+ const QMap<QByteArray, QByteArray> &headers)
: m_proxy(proxy),
m_request(url),
m_method(method),
- m_initiatorOrigin(initiatorOrigin)
+ m_initiatorOrigin(initiatorOrigin),
+ m_requestHeaders(headers)
{
}
@@ -78,32 +83,36 @@ QUrl URLRequestCustomJobDelegate::initiator() const
return m_initiatorOrigin;
}
+QMap<QByteArray, QByteArray> URLRequestCustomJobDelegate::requestHeaders() const
+{
+ return m_requestHeaders;
+}
+
void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device)
{
if (device)
QObject::connect(device, &QIODevice::readyRead, this, &URLRequestCustomJobDelegate::slotReadyRead);
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::reply,
- m_proxy,contentType.toStdString(),device));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&URLRequestCustomJobProxy::reply,
+ m_proxy,contentType.toStdString(),device));
}
void URLRequestCustomJobDelegate::slotReadyRead()
{
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::readyRead, m_proxy));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&URLRequestCustomJobProxy::readyRead, m_proxy));
}
void URLRequestCustomJobDelegate::abort()
{
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::abort, m_proxy));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&URLRequestCustomJobProxy::abort, m_proxy));
}
void URLRequestCustomJobDelegate::redirect(const QUrl &url)
{
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::redirect,
- m_proxy, toGurl(url)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&URLRequestCustomJobProxy::redirect, m_proxy, toGurl(url)));
}
void URLRequestCustomJobDelegate::fail(Error error)
@@ -129,9 +138,8 @@ void URLRequestCustomJobDelegate::fail(Error error)
break;
}
if (net_error) {
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestCustomJobProxy::fail,
- m_proxy, net_error));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&URLRequestCustomJobProxy::fail, m_proxy, net_error));
}
}
diff --git a/src/core/net/url_request_custom_job_delegate.h b/src/core/net/url_request_custom_job_delegate.h
index caabfcf99..0ab1a82c7 100644
--- a/src/core/net/url_request_custom_job_delegate.h
+++ b/src/core/net/url_request_custom_job_delegate.h
@@ -54,6 +54,7 @@
#include "base/memory/ref_counted.h"
#include "qtwebenginecoreglobal_p.h"
+#include <QMap>
#include <QObject>
#include <QUrl>
@@ -63,7 +64,7 @@ namespace QtWebEngineCore {
class URLRequestCustomJobProxy;
-class QWEBENGINECORE_PRIVATE_EXPORT URLRequestCustomJobDelegate : public QObject {
+class Q_WEBENGINECORE_PRIVATE_EXPORT URLRequestCustomJobDelegate : public QObject {
Q_OBJECT
public:
~URLRequestCustomJobDelegate();
@@ -80,6 +81,7 @@ public:
QUrl url() const;
QByteArray method() const;
QUrl initiator() const;
+ QMap<QByteArray, QByteArray> requestHeaders() const;
void reply(const QByteArray &contentType, QIODevice *device);
void redirect(const QUrl& url);
@@ -93,13 +95,15 @@ private:
URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
const QUrl &url,
const QByteArray &method,
- const QUrl &initiatorOrigin);
+ const QUrl &initiatorOrigin,
+ const QMap<QByteArray, QByteArray> &requestHeaders);
friend class URLRequestCustomJobProxy;
scoped_refptr<URLRequestCustomJobProxy> m_proxy;
QUrl m_request;
QByteArray m_method;
QUrl m_initiatorOrigin;
+ const QMap<QByteArray, QByteArray> m_requestHeaders;
};
} // namespace
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index b5f10388c..72d14450e 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -152,7 +152,9 @@ void URLRequestCustomJobProxy::readyRead()
m_job->notifyReadyRead();
}
-void URLRequestCustomJobProxy::initialize(GURL url, std::string method, base::Optional<url::Origin> initiator)
+void URLRequestCustomJobProxy::initialize(GURL url, std::string method,
+ base::Optional<url::Origin> initiator,
+ std::map<std::string, std::string> headers)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Q_ASSERT(!m_delegate);
@@ -164,12 +166,16 @@ void URLRequestCustomJobProxy::initialize(GURL url, std::string method, base::Op
QWebEngineUrlSchemeHandler *schemeHandler = nullptr;
if (m_profileAdapter)
- schemeHandler = m_profileAdapter->customUrlSchemeHandlers()[toQByteArray(m_scheme)];
+ schemeHandler = m_profileAdapter->urlSchemeHandler(toQByteArray(m_scheme));
+ QMap<QByteArray, QByteArray> qHeaders;
+ for (auto it = headers.cbegin(); it != headers.cend(); ++it)
+ qHeaders.insert(toQByteArray(it->first), toQByteArray(it->second));
if (schemeHandler) {
m_delegate = new URLRequestCustomJobDelegate(this, toQt(url),
QByteArray::fromStdString(method),
- initiatorOrigin);
+ initiatorOrigin,
+ qHeaders);
QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate);
schemeHandler->requestStarted(requestJob);
}
diff --git a/src/core/net/url_request_custom_job_proxy.h b/src/core/net/url_request_custom_job_proxy.h
index 3986fe119..aa55db07c 100644
--- a/src/core/net/url_request_custom_job_proxy.h
+++ b/src/core/net/url_request_custom_job_proxy.h
@@ -72,7 +72,7 @@ public:
void abort();
void fail(int error);
void release();
- void initialize(GURL url, std::string method, base::Optional<url::Origin> initiatorOrigin);
+ void initialize(GURL url, std::string method, base::Optional<url::Origin> initiatorOrigin, std::map<std::string, std::string> headers);
void readyRead();
// IO thread owned:
diff --git a/src/core/net/url_request_notification.cpp b/src/core/net/url_request_notification.cpp
new file mode 100644
index 000000000..e37ad35bc
--- /dev/null
+++ b/src/core/net/url_request_notification.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "url_request_notification.h"
+
+#include "base/supports_user_data.h"
+#include "base/task/post_task.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/url_request/url_request.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+#include "profile_io_data_qt.h"
+#include "qwebengineurlrequestinfo_p.h"
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+// Calls cancel() when the URLRequest is destroyed.
+class UserData : public base::SupportsUserData::Data {
+public:
+ UserData(URLRequestNotification *ptr) : m_ptr(ptr) {}
+ ~UserData() { m_ptr->cancel(); }
+ static const char key[];
+private:
+ URLRequestNotification *m_ptr;
+};
+
+const char UserData::key[] = "QtWebEngineCore::URLRequestNotification";
+
+static content::ResourceType fromQt(QWebEngineUrlRequestInfo::ResourceType resourceType)
+{
+ return static_cast<content::ResourceType>(resourceType);
+}
+
+URLRequestNotification::URLRequestNotification(net::URLRequest *request,
+ bool isMainFrameRequest,
+ GURL *newUrl,
+ QWebEngineUrlRequestInfo &&requestInfo,
+ content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
+ net::CompletionOnceCallback callback,
+ QPointer<ProfileAdapter> adapter)
+ : m_request(request)
+ , m_isMainFrameRequest(isMainFrameRequest)
+ , m_newUrl(newUrl)
+ , m_originalUrl(requestInfo.requestUrl())
+ , m_requestInfo(std::move(requestInfo))
+ , m_webContentsGetter(webContentsGetter)
+ , m_callback(std::move(callback))
+ , m_profileAdapter(adapter)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ m_request->SetUserData(UserData::key, std::make_unique<UserData>(this));
+
+ base::PostTaskWithTraits(
+ FROM_HERE,
+ {content::BrowserThread::UI},
+ base::BindOnce(&URLRequestNotification::notify, base::Unretained(this)));
+}
+
+
+void URLRequestNotification::notify()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ // May run concurrently with cancel() so no peeking at m_request here.
+
+ int result = net::OK;
+ content::WebContents *webContents = m_webContentsGetter.Run();
+
+ if (webContents) {
+
+ if (m_profileAdapter) {
+ QWebEngineUrlRequestInterceptor* interceptor = m_profileAdapter->requestInterceptor();
+ if (!interceptor->property("deprecated").toBool())
+ interceptor->interceptRequest(m_requestInfo);
+ }
+
+ WebContentsAdapterClient *client =
+ WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();
+
+ if (!m_requestInfo.changed()) {
+ client->interceptRequest(m_requestInfo);
+ }
+
+ if (m_requestInfo.changed()) {
+ result = m_requestInfo.d_ptr->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
+ // We handle the rest of the changes later when we are back in I/O thread
+ }
+
+ // Only do navigationRequested on MAIN_FRAME and SUB_FRAME resources
+ if (result == net::OK && content::IsResourceTypeFrame(fromQt(m_requestInfo.resourceType()))) {
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ client->navigationRequested(m_requestInfo.navigationType(),
+ m_requestInfo.requestUrl(),
+ navigationRequestAction,
+ m_isMainFrameRequest);
+ result = net::ERR_FAILED;
+ switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
+ case WebContentsAdapterClient::AcceptRequest:
+ result = net::OK;
+ break;
+ case WebContentsAdapterClient::IgnoreRequest:
+ result = net::ERR_ABORTED;
+ break;
+ }
+ DCHECK(result != net::ERR_FAILED);
+ }
+ }
+
+ // Run the callback on the IO thread.
+ base::PostTaskWithTraits(
+ FROM_HERE,
+ {content::BrowserThread::IO},
+ base::BindOnce(&URLRequestNotification::complete, base::Unretained(this), result));
+}
+
+void URLRequestNotification::cancel()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ // May run concurrently with notify() but we only touch m_request here.
+
+ m_request = nullptr;
+}
+
+void URLRequestNotification::complete(int error)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (m_request) {
+ if (m_requestInfo.changed()) {
+ if (m_originalUrl != m_requestInfo.d_ptr->url)
+ *m_newUrl = toGurl(m_requestInfo.d_ptr->url);
+
+ if (!m_requestInfo.d_ptr->extraHeaders.isEmpty()) {
+ auto end = m_requestInfo.d_ptr->extraHeaders.constEnd();
+ for (auto header = m_requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header) {
+ std::string h = header.key().toStdString();
+ if (base::LowerCaseEqualsASCII(h, "referer")) {
+ m_request->SetReferrer(header.value().toStdString());
+ } else {
+ m_request->SetExtraRequestHeaderByName(h, header.value().toStdString(), /* overwrite */ true);
+ }
+ }
+ }
+ }
+
+ if (m_request->status().status() != net::URLRequestStatus::CANCELED)
+ std::move(m_callback).Run(error);
+ m_request->RemoveUserData(UserData::key);
+ }
+
+ delete this;
+}
+
+}
diff --git a/src/core/net/url_request_notification.h b/src/core/net/url_request_notification.h
new file mode 100644
index 000000000..1d9acf12f
--- /dev/null
+++ b/src/core/net/url_request_notification.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef URL_REQUEST_NOTIFIACTION_H
+#define URL_REQUEST_NOTIFIACTION_H
+
+#include "content/public/browser/resource_request_info.h"
+#include "net/base/completion_once_callback.h"
+#include "qwebengineurlrequestinfo.h"
+#include <QPointer>
+
+class GURL;
+
+namespace net {
+class URLRequest;
+}
+
+namespace QtWebEngineCore {
+
+class ProfileAdapter;
+class ProfileIoDataQt;
+
+// Notifies WebContentsAdapterClient of a new URLRequest.
+class URLRequestNotification {
+public:
+ URLRequestNotification(net::URLRequest *request,
+ bool isMainFrameRequest,
+ GURL *newUrl,
+ QWebEngineUrlRequestInfo &&requestInfo,
+ content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
+ net::CompletionOnceCallback callback,
+ QPointer<ProfileAdapter> adapter);
+ ~URLRequestNotification() = default;
+ void cancel();
+ void notify();
+ void complete(int error);
+
+private:
+ net::URLRequest *m_request; //used only by io thread
+ bool m_isMainFrameRequest;
+ GURL *m_newUrl;
+ const QUrl m_originalUrl;
+ QWebEngineUrlRequestInfo m_requestInfo;
+ content::ResourceRequestInfo::WebContentsGetter m_webContentsGetter;
+ net::CompletionOnceCallback m_callback;
+ QPointer<ProfileAdapter> m_profileAdapter;
+};
+}
+#endif
diff --git a/src/core/net/url_request_qrc_job_qt.cpp b/src/core/net/url_request_qrc_job_qt.cpp
deleted file mode 100644
index 4ac45e7c8..000000000
--- a/src/core/net/url_request_qrc_job_qt.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "url_request_qrc_job_qt.h"
-
-#include "type_conversion.h"
-
-#include "base/pending_task.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "net/base/net_errors.h"
-#include "net/base/io_buffer.h"
-
-#include <QUrl>
-#include <QFileInfo>
-#include <QMimeDatabase>
-#include <QMimeType>
-
-using namespace net;
-namespace QtWebEngineCore {
-
-URLRequestQrcJobQt::URLRequestQrcJobQt(URLRequest *request, NetworkDelegate *networkDelegate)
- : URLRequestJob(request, networkDelegate)
- , m_remainingBytes(0)
- , m_weakFactory(this)
-{
-}
-
-URLRequestQrcJobQt::~URLRequestQrcJobQt()
-{
- if (m_file.isOpen())
- m_file.close();
-}
-
-void URLRequestQrcJobQt::Start()
-{
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&URLRequestQrcJobQt::startGetHead, m_weakFactory.GetWeakPtr()));
-}
-
-void URLRequestQrcJobQt::Kill()
-{
- if (m_file.isOpen())
- m_file.close();
- m_weakFactory.InvalidateWeakPtrs();
-
- URLRequestJob::Kill();
-}
-
-bool URLRequestQrcJobQt::GetMimeType(std::string *mimeType) const
-{
- DCHECK(request_);
- if (m_mimeType.size() > 0) {
- *mimeType = m_mimeType;
- return true;
- }
- return false;
-}
-
-int URLRequestQrcJobQt::ReadRawData(IOBuffer *buf, int bufSize)
-{
- DCHECK_GE(m_remainingBytes, 0);
- // File has been read finished.
- if (!m_remainingBytes || !bufSize) {
- return 0;
- }
- if (m_remainingBytes < bufSize)
- bufSize = static_cast<int>(m_remainingBytes);
- qint64 rv = m_file.read(buf->data(), bufSize);
- if (rv >= 0) {
- m_remainingBytes -= rv;
- DCHECK_GE(m_remainingBytes, 0);
- return static_cast<int>(rv);
- }
- return static_cast<int>(rv);
-}
-
-void URLRequestQrcJobQt::startGetHead()
-{
- // Get qrc file path.
- QString qrcFilePath = ':' + toQt(request_->url()).path();
- m_file.setFileName(qrcFilePath);
- QFileInfo qrcFileInfo(m_file);
- // Get qrc file mime type.
- QMimeDatabase mimeDatabase;
- QMimeType mimeType = mimeDatabase.mimeTypeForFile(qrcFileInfo);
- m_mimeType = mimeType.name().toStdString();
- // Open file
- if (m_file.open(QIODevice::ReadOnly) && m_file.size() > 0) {
- m_remainingBytes = m_file.size();
- set_expected_content_size(m_remainingBytes);
- // Notify that the headers are complete
- NotifyHeadersComplete();
- return;
- }
- qWarning("Resource %s not found or is empty", qUtf8Printable(qrcFilePath));
- NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, ERR_INVALID_URL));
-}
-} // namespace QtWebEngineCore
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index 918500b58..ec36e70d9 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -48,6 +48,7 @@
#include "base/location.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
+#include "chrome/browser/accessibility/accessibility_ui.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/devtools_ui.h"
#include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
@@ -136,6 +137,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
// return nullptr;
return &NewWebUI<DevToolsUI>;
}
+ if (url.host() == chrome::kChromeUIAccessibilityHost)
+ return &NewWebUI<AccessibilityUI>;
// if (url.host_piece() == chrome::kChromeUIUserActionsHost)
// return &NewWebUI<UserActionsUI>;
diff --git a/src/core/ozone/BUILD.gn b/src/core/ozone/BUILD.gn
new file mode 100644
index 000000000..b96d8a47a
--- /dev/null
+++ b/src/core/ozone/BUILD.gn
@@ -0,0 +1,25 @@
+# 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.
+
+source_set("qt") {
+ sources = [
+ "ozone_platform_qt.h",
+ "ozone_platform_qt.cpp",
+ ]
+
+ import("//ui/base/ui_features.gni")
+ import("//ui/gl/features.gni")
+
+ deps = [
+ "//base",
+ "//ui/ozone:ozone_base",
+ "//ui/ozone/common",
+ ]
+
+ defines = [ "OZONE_IMPLEMENTATION" ]
+
+ if (is_linux && !is_desktop_linux) {
+ deps += [ "//ui/events/ozone:events_ozone_evdev"]
+ }
+}
diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index ec49414b0..c4a075544 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -119,14 +119,21 @@ void* GLContextHelper::getGlXConfig()
void* GLContextHelper::getEGLDisplay()
{
+#ifdef Q_OS_WIN
+ // Windows QPA plugin does not implement resourceForIntegration for "egldisplay".
+ // Use resourceForContext instead.
+ return resourceForContext(QByteArrayLiteral("egldisplay"));
+#else
return resourceForIntegration(QByteArrayLiteral("egldisplay"));
+#endif
}
void* GLContextHelper::getXDisplay()
{
- if (QGuiApplication::platformName() != QLatin1String("xcb"))
- return nullptr;
- return qApp->platformNativeInterface()->nativeResourceForScreen(QByteArrayLiteral("display"), qApp->primaryScreen());
+ QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface();
+ if (pni)
+ return pni->nativeResourceForScreen(QByteArrayLiteral("display"), qApp->primaryScreen());
+ return nullptr;
}
void* GLContextHelper::getNativeDisplay()
diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp
index 9fe5985ce..8715a5095 100644
--- a/src/core/ozone/gl_surface_egl_qt.cpp
+++ b/src/core/ozone/gl_surface_egl_qt.cpp
@@ -44,9 +44,9 @@
#include "gl_context_qt.h"
#include "ozone/gl_surface_egl_qt.h"
-#include "ui/gl/gl_surface_egl.h"
#if !defined(OS_MACOSX)
#include "ui/gl/egl_util.h"
+#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/init/gl_factory.h"
// From ANGLE's egl/eglext.h.
@@ -302,10 +302,6 @@ void* GLSurfacelessQtEGL::GetShareHandle()
return NULL;
}
-} // namespace gl
-#endif // !defined(OS_MACOSX)
-
-namespace gl {
std::string DriverEGL::GetPlatformExtensions()
{
EGLDisplay display = GLContextHelper::getEGLDisplay();
@@ -317,3 +313,15 @@ std::string DriverEGL::GetPlatformExtensions()
return str ? std::string(str) : "";
}
} // namespace gl
+#else
+namespace gl {
+struct GL_EXPORT DriverEGL {
+ static std::string GetPlatformExtensions();
+};
+
+std::string DriverEGL::GetPlatformExtensions()
+{
+ return "";
+}
+} // namespace gl
+#endif // !defined(OS_MACOSX)
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index 7cde289ae..551ba888c 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -64,7 +64,6 @@
#include "ozone/gl_surface_wgl_qt.h"
#include "gpu/ipc/service/direct_composition_surface_win.h"
-#include "ui/gl/gl_context_wgl.h"
#include "ui/gl/vsync_provider_win.h"
#endif
@@ -141,9 +140,6 @@ bool InitializeGLOneOffPlatform()
{
VSyncProviderWin::InitializeOneOff();
- if (GetGLImplementation() == kGLImplementationOSMesaGL)
- return false;
-
if (GetGLImplementation() == kGLImplementationEGLGLES2)
return GLSurfaceEGLQt::InitializeOneOff();
diff --git a/src/core/ozone/gl_surface_wgl_qt.cpp b/src/core/ozone/gl_surface_wgl_qt.cpp
index 7c9e87b86..ac27a9c20 100644
--- a/src/core/ozone/gl_surface_wgl_qt.cpp
+++ b/src/core/ozone/gl_surface_wgl_qt.cpp
@@ -37,9 +37,9 @@
**
****************************************************************************/
-#if defined(OS_WIN)
-
#include "gl_surface_wgl_qt.h"
+
+#if defined(OS_WIN)
#include "ui/gl/gl_surface_wgl.h"
namespace gl {
diff --git a/src/core/ozone/ozone_extra.gni b/src/core/ozone/ozone_extra.gni
new file mode 100644
index 000000000..a832f741a
--- /dev/null
+++ b/src/core/ozone/ozone_extra.gni
@@ -0,0 +1,19 @@
+# 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.
+
+# This list contains the name of external platforms that are passed to the
+# --ozone-platform command line argument or used for the ozone_platform build
+# config. For example ozone_external_platforms = [ "foo1", "foo2", ... ]
+ozone_external_platforms = [ "qt" ]
+
+# This list contains dependencies for external platforms. Typically, the Ozone
+# implementations are placed into ui/ozone/platform/ and so this will look
+# something like:
+# ozone_external_platform_deps = [ "platform/foo1", "platform/foo_2", ... ]
+ozone_external_platform_deps = []
+
+# If a platform has unit tests, the corresponding source_set can be listed here
+# so that they get included into ozone_unittests.
+# ozone_external_platform_test_deps = [ "platform/foo1:foo1_unitests", ... ]
+ozone_external_platform_test_deps = []
diff --git a/src/core/ozone/ozone_platform_qt.cpp b/src/core/ozone/ozone_platform_qt.cpp
index 905e8f403..eb7610c0f 100644
--- a/src/core/ozone/ozone_platform_qt.cpp
+++ b/src/core/ozone/ozone_platform_qt.cpp
@@ -37,12 +37,11 @@
**
****************************************************************************/
-#include "ozone/ozone_platform_qt.h"
+#include "ozone_platform_qt.h"
#if defined(USE_OZONE)
-#include "ozone/surface_factory_qt.h"
-#include "ozone/platform_window_qt.h"
#include "ui/display/types/native_display_delegate.h"
+#include "ui/events/system_input_injector.h"
#include "ui/ozone/common/stub_client_native_pixmap_factory.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/public/cursor_factory_ozone.h"
@@ -53,6 +52,9 @@
#include "ui/platform_window/platform_window_init_properties.h"
#include "ui/platform_window/platform_window.h"
+#include "surface_factory_qt.h"
+#include "platform_window_qt.h"
+
namespace ui {
namespace {
diff --git a/src/core/ozone/platform_window_qt.h b/src/core/ozone/platform_window_qt.h
index b712b706a..bb2fc714b 100644
--- a/src/core/ozone/platform_window_qt.h
+++ b/src/core/ozone/platform_window_qt.h
@@ -75,6 +75,9 @@ public:
void MoveCursorTo(const gfx::Point&) override { }
void ConfineCursorToBounds(const gfx::Rect&) override { }
PlatformImeController* GetPlatformImeController() override { return nullptr; }
+ void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override { }
+ gfx::Rect GetRestoredBoundsInPixels() const override { return gfx::Rect(); }
+
// PlatformEventDispatcher:
bool CanDispatchEvent(const PlatformEvent& event) override;
uint32_t DispatchEvent(const PlatformEvent& event) override;
diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp
index f69520b70..5420b4809 100644
--- a/src/core/ozone/surface_factory_qt.cpp
+++ b/src/core/ozone/surface_factory_qt.cpp
@@ -38,10 +38,9 @@
****************************************************************************/
#include "surface_factory_qt.h"
-#include "qtwebenginecoreglobal_p.h"
#include "gl_context_qt.h"
#include "gl_ozone_egl_qt.h"
-#if QT_CONFIG(webengine_ozone_x11)
+#if defined(USE_GLX)
#include "gl_ozone_glx_qt.h"
#endif
@@ -58,7 +57,7 @@ namespace QtWebEngineCore {
SurfaceFactoryQt::SurfaceFactoryQt()
{
Q_ASSERT(qApp);
-#if QT_CONFIG(webengine_ozone_x11)
+#if defined(USE_GLX)
if (GLContextHelper::getGlXConfig()) {
m_impl = gl::kGLImplementationDesktopGL;
m_ozone.reset(new ui::GLOzoneGLXQt());
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index b999f4186..be4d6e598 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -61,8 +61,13 @@ ProfileAdapter::PermissionType toQt(content::PermissionType type)
return ProfileAdapter::AudioCapturePermission;
case content::PermissionType::VIDEO_CAPTURE:
return ProfileAdapter::VideoCapturePermission;
- case content::PermissionType::FLASH:
+ case content::PermissionType::CLIPBOARD_READ:
+ return ProfileAdapter::ClipboardRead;
+ case content::PermissionType::CLIPBOARD_WRITE:
+ return ProfileAdapter::ClipboardWrite;
case content::PermissionType::NOTIFICATIONS:
+ return ProfileAdapter::NotificationPermission;
+ case content::PermissionType::FLASH:
case content::PermissionType::MIDI_SYSEX:
case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
case content::PermissionType::MIDI:
@@ -70,13 +75,11 @@ ProfileAdapter::PermissionType toQt(content::PermissionType type)
case content::PermissionType::BACKGROUND_SYNC:
case content::PermissionType::SENSORS:
case content::PermissionType::ACCESSIBILITY_EVENTS:
- break;
- case content::PermissionType::CLIPBOARD_READ:
- return ProfileAdapter::ClipboardRead;
- case content::PermissionType::CLIPBOARD_WRITE:
- return ProfileAdapter::ClipboardWrite;
case content::PermissionType::PAYMENT_HANDLER:
+ case content::PermissionType::BACKGROUND_FETCH:
+ case content::PermissionType::IDLE_DETECTION:
case content::PermissionType::NUM:
+ NOTIMPLEMENTED() << "Unsupported permission type: " << static_cast<int>(type);
break;
}
return ProfileAdapter::UnsupportedPermission;
@@ -187,6 +190,9 @@ int PermissionManagerQt::RequestPermission(content::PermissionType permission,
m_requests.insert(request_id, request);
if (permissionType == ProfileAdapter::GeolocationPermission)
contentsDelegate->requestGeolocationPermission(request.origin);
+ else if (permissionType == ProfileAdapter::NotificationPermission)
+ contentsDelegate->requestUserNotificationPermission(request.origin);
+
return request_id;
}
@@ -235,6 +241,8 @@ int PermissionManagerQt::RequestPermissions(const std::vector<content::Permissio
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == ProfileAdapter::GeolocationPermission)
contentsDelegate->requestGeolocationPermission(request.origin);
+ else if (permissionType == ProfileAdapter::NotificationPermission)
+ contentsDelegate->requestUserNotificationPermission(request.origin);
}
return request_id;
}
@@ -294,8 +302,8 @@ void PermissionManagerQt::ResetPermission(
int PermissionManagerQt::SubscribePermissionStatusChange(
content::PermissionType permission,
+ content::RenderFrameHost * /* render_frame_host */,
const GURL& requesting_origin,
- const GURL& /*embedding_origin*/,
const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
{
int subscriber_id = ++m_subscriberIdCount;
@@ -311,7 +319,7 @@ int PermissionManagerQt::SubscribePermissionStatusChange(
void PermissionManagerQt::UnsubscribePermissionStatusChange(int subscription_id)
{
if (!m_subscribers.remove(subscription_id))
- qWarning() << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id;
+ LOG(WARNING) << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id;
}
} // namespace QtWebEngineCore
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index b3bd3dc7a..89eb6cf85 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -92,8 +92,8 @@ public:
int SubscribePermissionStatusChange(
content::PermissionType permission,
+ content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
- const GURL& embedding_origin,
const base::Callback<void(blink::mojom::PermissionStatus)>& callback) override;
void UnsubscribePermissionStatusChange(int subscription_id) override;
diff --git a/src/core/platform_notification_service_qt.cpp b/src/core/platform_notification_service_qt.cpp
new file mode 100644
index 000000000..f3457c7aa
--- /dev/null
+++ b/src/core/platform_notification_service_qt.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "platform_notification_service_qt.h"
+
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/permission_type.h"
+#include "content/public/browser/notification_event_dispatcher.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
+
+#include "profile_adapter.h"
+#include "profile_adapter_client.h"
+#include "profile_qt.h"
+#include "user_notification_controller.h"
+#include "resource_context_qt.h"
+#include "type_conversion.h"
+
+#include <QSharedPointer>
+
+namespace QtWebEngineCore {
+
+struct NonPersistentNotificationDelegate : UserNotificationController::Delegate {
+ NonPersistentNotificationDelegate(const std::string &id) : notification_id(id) { }
+
+ virtual void shown() override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNonPersistentShowEvent(notification_id);
+ }
+
+ virtual void clicked() override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNonPersistentClickEvent(notification_id, base::DoNothing());
+ }
+
+ virtual void closed(bool /*by_user*/) override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNonPersistentCloseEvent(notification_id, base::DoNothing());
+ }
+
+ const std::string notification_id;
+};
+
+struct PersistentNotificationDelegate : UserNotificationController::Delegate {
+ PersistentNotificationDelegate(content::BrowserContext *context, const std::string &id, const GURL &origin)
+ : browser_context(context), notification_id(id), origin(origin) { }
+
+ virtual void shown() override { }
+
+ virtual void clicked() override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNotificationClickEvent(browser_context, notification_id, origin, base::nullopt, base::nullopt, base::DoNothing());
+ }
+
+ virtual void closed(bool by_user) override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNotificationCloseEvent(browser_context, notification_id, origin, by_user, base::DoNothing());
+ }
+
+ content::BrowserContext *browser_context;
+ const std::string notification_id;
+ const GURL origin;
+};
+
+
+PlatformNotificationServiceQt::PlatformNotificationServiceQt() {}
+
+PlatformNotificationServiceQt::~PlatformNotificationServiceQt() {}
+
+void PlatformNotificationServiceQt::DisplayNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id,
+ const GURL &origin,
+ const blink::PlatformNotificationData &notificationData,
+ const blink::NotificationResources &notificationResources)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
+
+ auto delegate = new NonPersistentNotificationDelegate(notification_id);
+ QSharedPointer<UserNotificationController> controller(
+ new UserNotificationController(notificationData, notificationResources, origin, delegate));
+
+ profile->profileAdapter()->ephemeralNotifications().insert(QByteArray::fromStdString(notification_id), controller);
+
+ const QList<ProfileAdapterClient *> clients = profile->profileAdapter()->clients();
+ for (ProfileAdapterClient *client : clients)
+ client->showNotification(controller);
+}
+
+void PlatformNotificationServiceQt::DisplayPersistentNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id,
+ const GURL &service_worker_origin,
+ const GURL &origin,
+ const blink::PlatformNotificationData &notificationData,
+ const blink::NotificationResources &notificationResources)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt * profile = static_cast<ProfileQt*>(browser_context);
+
+ auto delegate = new PersistentNotificationDelegate(profile, notification_id, service_worker_origin);
+ QSharedPointer<UserNotificationController> controller(
+ new UserNotificationController(notificationData, notificationResources, service_worker_origin, delegate));
+
+ profile->profileAdapter()->persistentNotifications().insert(QByteArray::fromStdString(notification_id), controller);
+ const QList<ProfileAdapterClient *> clients = profile->profileAdapter()->clients();
+ for (ProfileAdapterClient *client : clients)
+ client->showNotification(controller);
+}
+
+void PlatformNotificationServiceQt::CloseNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
+
+ QSharedPointer<UserNotificationController> notificationController =
+ profile->profileAdapter()->ephemeralNotifications().take(QByteArray::fromStdString(notification_id)).lock();
+ if (notificationController)
+ notificationController->closeNotification();
+}
+
+void PlatformNotificationServiceQt::ClosePersistentNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
+
+ QSharedPointer<UserNotificationController> notificationController =
+ profile->profileAdapter()->persistentNotifications().take(QByteArray::fromStdString(notification_id));
+ if (notificationController)
+ notificationController->closeNotification();
+}
+
+void PlatformNotificationServiceQt::GetDisplayedNotifications(
+ content::BrowserContext *browser_context,
+ const DisplayedNotificationsCallback &callback)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+
+ std::unique_ptr<std::set<std::string>> movableStdStringSet = std::make_unique<std::set<std::string>>();
+ auto it = profile->profileAdapter()->persistentNotifications().constBegin();
+ const auto end = profile->profileAdapter()->persistentNotifications().constEnd();
+ while (it != end) {
+ if (it.value()->isShown())
+ movableStdStringSet->insert(it.key().toStdString());
+ ++it;
+ }
+
+ callback.Run(std::move(movableStdStringSet), true /* supports_synchronization */);
+}
+
+int64_t PlatformNotificationServiceQt::ReadNextPersistentNotificationId(content::BrowserContext *browser_context)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ auto prefs = static_cast<ProfileQt *>(browser_context)->GetPrefs();
+ int64_t nextId = prefs->GetInteger(prefs::kNotificationNextPersistentId) + 1;
+ prefs->SetInteger(prefs::kNotificationNextPersistentId, nextId);
+ return nextId;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/platform_notification_service_qt.h b/src/core/platform_notification_service_qt.h
new file mode 100644
index 000000000..66cee9ed0
--- /dev/null
+++ b/src/core/platform_notification_service_qt.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PLATFORM_NOTIFICATION_SERVICE_QT_H
+#define PLATFORM_NOTIFICATION_SERVICE_QT_H
+
+#include "content/public/browser/platform_notification_service.h"
+
+namespace QtWebEngineCore {
+
+class PlatformNotificationServiceQt : public content::PlatformNotificationService {
+public:
+ PlatformNotificationServiceQt();
+ ~PlatformNotificationServiceQt() override;
+
+ // Displays the notification described in |notification_data| to the user. A
+ // closure through which the notification can be closed will be stored in the
+ // |cancel_callback| argument. This method must be called on the UI thread.
+ void DisplayNotification(content::BrowserContext* browser_context,
+ const std::string& notification_id,
+ const GURL& origin,
+ const blink::PlatformNotificationData& notificationData,
+ const blink::NotificationResources& notificationResources) override;
+
+ // Displays the persistent notification described in |notification_data| to
+ // the user. This method must be called on the UI thread.
+ void DisplayPersistentNotification(content::BrowserContext* browser_context,
+ const std::string& notification_id,
+ const GURL& service_worker_origin,
+ const GURL& origin,
+ const blink::PlatformNotificationData& notification_data,
+ const blink::NotificationResources& notification_resources) override;
+
+ // Closes the notification identified by |notification_id|.
+ // This method must be called on the UI thread.
+ void CloseNotification(content::BrowserContext* browser_context, const std::string& notification_id) override;
+
+ // Closes the persistent notification identified by |persistent_notification_id|.
+ // This method must be called on the UI thread.
+ void ClosePersistentNotification(content::BrowserContext* browser_context, const std::string& notification_id) override;
+
+ // Retrieves the ids of all currently displaying notifications and
+ // posts |callback| with the result.
+ void GetDisplayedNotifications(content::BrowserContext* browser_context, const DisplayedNotificationsCallback& callback) override;
+
+ // Reads the value of the next persistent notification ID from the profile and
+ // increments the value, as it is called once per notification write.
+ virtual int64_t ReadNextPersistentNotificationId(content::BrowserContext* browser_context) override;
+
+ // Records a given notification to UKM.
+ virtual void RecordNotificationUkmEvent(content::BrowserContext*, const content::NotificationDatabaseData&) override { }
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PLATFORM_NOTIFICATION_SERVICE_QT_H
diff --git a/src/core/printing/pdfium_document_wrapper_qt.cpp b/src/core/printing/pdfium_document_wrapper_qt.cpp
index a18258d0e..6f415b50b 100644
--- a/src/core/printing/pdfium_document_wrapper_qt.cpp
+++ b/src/core/printing/pdfium_document_wrapper_qt.cpp
@@ -48,14 +48,13 @@
namespace QtWebEngineCore {
int PdfiumDocumentWrapperQt::m_libraryUsers = 0;
-class QWEBENGINECORE_PRIVATE_EXPORT PdfiumPageWrapperQt {
+class PdfiumPageWrapperQt {
public:
- PdfiumPageWrapperQt(FPDF_DOCUMENT data, int pageIndex, int targetWidth, int targetHeight)
+ PdfiumPageWrapperQt(FPDF_DOCUMENT data, int pageIndex)
: m_pageData(FPDF_LoadPage(data, pageIndex))
, m_width(FPDF_GetPageWidth(m_pageData))
, m_height(FPDF_GetPageHeight(m_pageData))
- , m_index(pageIndex)
- , m_image(createImage(targetWidth, targetHeight))
+ , m_image(createImage())
{
}
@@ -63,7 +62,6 @@ public:
: m_pageData(nullptr)
, m_width(-1)
, m_height(-1)
- , m_index(-1)
, m_image(QImage())
{
}
@@ -79,16 +77,11 @@ public:
}
private:
- QImage createImage(int targetWidth, int targetHeight)
+ QImage createImage()
{
Q_ASSERT(m_pageData);
- if (targetWidth <= 0)
- targetWidth = m_width;
- if (targetHeight <= 0)
- targetHeight = m_height;
-
- QImage image(targetWidth, targetHeight, QImage::Format_ARGB32);
+ QImage image(m_width * 2, m_height * 2, QImage::Format_ARGB32);
Q_ASSERT(!image.isNull());
image.fill(0xFFFFFFFF);
@@ -102,22 +95,19 @@ private:
0, 0);
FPDFBitmap_Destroy(bitmap);
bitmap = nullptr;
- return std::move(image);
+ return image;
}
private:
FPDF_PAGE m_pageData;
int m_width;
int m_height;
- int m_index;
QImage m_image;
};
PdfiumDocumentWrapperQt::PdfiumDocumentWrapperQt(const void *pdfData, size_t size,
- const QSize& imageSize,
const char *password)
- : m_imageSize(imageSize * 2.0)
{
Q_ASSERT(pdfData);
Q_ASSERT(size);
@@ -140,11 +130,17 @@ QImage PdfiumDocumentWrapperQt::pageAsQImage(size_t index)
return QImage();
}
- PdfiumPageWrapperQt pageWrapper((FPDF_DOCUMENT)m_documentHandle, index,
- m_imageSize.width(), m_imageSize.height());
+ PdfiumPageWrapperQt pageWrapper((FPDF_DOCUMENT)m_documentHandle, index);
return pageWrapper.image();
}
+bool PdfiumDocumentWrapperQt::pageIsLandscape(size_t index)
+{
+ double width = 0, height = 0;
+ FPDF_GetPageSizeByIndex((FPDF_DOCUMENT)m_documentHandle, index, &width, &height);
+ return (width > height);
+}
+
PdfiumDocumentWrapperQt::~PdfiumDocumentWrapperQt()
{
FPDF_CloseDocument((FPDF_DOCUMENT)m_documentHandle);
diff --git a/src/core/printing/pdfium_document_wrapper_qt.h b/src/core/printing/pdfium_document_wrapper_qt.h
index f4ac557a0..121742aa3 100644
--- a/src/core/printing/pdfium_document_wrapper_qt.h
+++ b/src/core/printing/pdfium_document_wrapper_qt.h
@@ -58,20 +58,19 @@
namespace QtWebEngineCore {
class PdfiumPageWrapperQt;
-class QWEBENGINECORE_PRIVATE_EXPORT PdfiumDocumentWrapperQt
+class Q_WEBENGINECORE_PRIVATE_EXPORT PdfiumDocumentWrapperQt
{
public:
- PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const QSize &imageSize,
- const char *password = nullptr);
+ PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const char *password = nullptr);
virtual ~PdfiumDocumentWrapperQt();
QImage pageAsQImage(size_t index);
+ bool pageIsLandscape(size_t index);
int pageCount() const { return m_pageCount; }
private:
static int m_libraryUsers;
int m_pageCount;
void *m_documentHandle;
- QSize m_imageSize;
};
} // namespace QtWebEngineCore
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp
index 0e7239ef8..52f4481bb 100644
--- a/src/core/printing/print_view_manager_base_qt.cpp
+++ b/src/core/printing/print_view_manager_base_qt.cpp
@@ -52,6 +52,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
@@ -59,12 +60,13 @@
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.h"
#include "components/printing/common/print_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
-#include "printing/pdf_metafile_skia.h"
+#include "printing/metafile_skia.h"
#include "printing/print_job_constants.h"
#include "printing/printed_document.h"
@@ -123,8 +125,8 @@ void PrintViewManagerBaseQt::PrintDocument(printing::PrintedDocument *document,
const gfx::Rect &content_area,
const gfx::Point &offsets)
{
- std::unique_ptr<printing::PdfMetafileSkia> metafile =
- std::make_unique<printing::PdfMetafileSkia>();
+ std::unique_ptr<printing::MetafileSkia> metafile =
+ std::make_unique<printing::MetafileSkia>();
CHECK(metafile->InitFromData(print_data->front(), print_data->size()));
// Update the rendered document. It will send notifications to the listener.
@@ -155,21 +157,19 @@ void PrintViewManagerBaseQt::OnDidPrintDocument(content::RenderFrameHost* /*rend
return;
const PrintHostMsg_DidPrintContent_Params &content = params.content;
- if (!base::SharedMemory::IsHandleValid(content.metafile_data_handle)) {
+ if (!content.metafile_data_region.IsValid()) {
NOTREACHED() << "invalid memory handle";
web_contents()->Stop();
return;
}
- std::unique_ptr<base::SharedMemory> shared_buf =
- std::make_unique<base::SharedMemory>(content.metafile_data_handle, true);
- if (!shared_buf->Map(content.data_size)) {
+ auto data = base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(content.metafile_data_region);
+ if (!data) {
NOTREACHED() << "couldn't map";
web_contents()->Stop();
return;
}
- auto data = base::MakeRefCounted<base::RefCountedSharedMemory>(
- std::move(shared_buf), content.data_size);
+
PrintDocument(document, data, params.page_size, params.content_area,
params.physical_offsets);
}
@@ -455,7 +455,7 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() {
// Need to enable recursive task.
{
- base::MessageLoop::ScopedNestableTaskAllower allow;
+ base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
run_loop.Run();
}
@@ -516,9 +516,8 @@ void PrintViewManagerBaseQt::ReleasePrinterQuery()
printerQuery = m_printerQueriesQueue->PopPrinterQuery(cookie);
if (!printerQuery.get())
return;
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&printing::PrinterQuery::StopWorker, printerQuery.get()));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&printing::PrinterQuery::StopWorker, printerQuery.get()));
}
// Originally from print_preview_message_handler.cc:
@@ -528,7 +527,7 @@ void PrintViewManagerBaseQt::StopWorker(int documentCookie) {
scoped_refptr<printing::PrinterQuery> printer_query =
m_printerQueriesQueue->PopPrinterQuery(documentCookie);
if (printer_query.get()) {
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&printing::PrinterQuery::StopWorker, printer_query));
}
}
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index 65c059d88..b6a2b42ec 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -53,50 +53,43 @@
#include "base/values.h"
#include "base/memory/ref_counted_memory.h"
-#include "base/task_scheduler/post_task.h"
+#include "base/task/post_task.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.h"
#include "components/printing/common/print_messages.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/web_preferences.h"
-#include "printing/pdf_metafile_skia.h"
+#include "printing/metafile_skia.h"
#include "printing/print_job_constants.h"
#include "printing/units.h"
-DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::PrintViewManagerQt);
-
namespace {
static const qreal kMicronsToMillimeter = 1000.0f;
-static std::vector<char>
-GetStdVectorFromHandle(base::SharedMemoryHandle handle, uint32_t data_size)
+static QSharedPointer<QByteArray> GetStdVectorFromHandle(const base::ReadOnlySharedMemoryRegion &handle)
{
- std::unique_ptr<base::SharedMemory> shared_buf(
- new base::SharedMemory(handle, true));
-
- if (!shared_buf->Map(data_size)) {
- return std::vector<char>();
- }
+ base::ReadOnlySharedMemoryMapping map = handle.Map();
+ if (!map.IsValid())
+ return QSharedPointer<QByteArray>(new QByteArray);
- char* data = static_cast<char*>(shared_buf->memory());
- return std::vector<char>(data, data + data_size);
+ const char* data = static_cast<const char*>(map.memory());
+ return QSharedPointer<QByteArray>(new QByteArray(data, map.size()));
}
static scoped_refptr<base::RefCountedBytes>
-GetBytesFromHandle(base::SharedMemoryHandle handle, uint32_t data_size)
+GetBytesFromHandle(const base::ReadOnlySharedMemoryRegion &handle)
{
- std::unique_ptr<base::SharedMemory> shared_buf(new base::SharedMemory(handle, true));
-
- if (!shared_buf->Map(data_size)) {
+ base::ReadOnlySharedMemoryMapping map = handle.Map();
+ if (!map.IsValid())
return nullptr;
- }
- unsigned char* data = static_cast<unsigned char*>(shared_buf->memory());
- std::vector<unsigned char> dataVector(data, data + data_size);
+ const unsigned char* data = static_cast<const unsigned char*>(map.memory());
+ std::vector<unsigned char> dataVector(data, data + map.size());
return base::RefCountedBytes::TakeVector(&dataVector);
}
@@ -105,18 +98,17 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
const base::FilePath &path,
const QtWebEngineCore::PrintViewManagerQt::PrintToPDFFileCallback &saveCallback)
{
- base::AssertBlockingAllowed();
+ base::AssertBlockingAllowedDeprecated();
DCHECK_GT(data->size(), 0U);
- printing::PdfMetafileSkia metafile;
+ printing::MetafileSkia metafile;
metafile.InitFromData(static_cast<const void*>(data->front()), data->size());
base::File file(path,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
bool success = file.IsValid() && metafile.SaveTo(&file);
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(saveCallback, success));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(saveCallback, success));
}
static base::DictionaryValue *createPrintSettings()
@@ -139,14 +131,15 @@ static base::DictionaryValue *createPrintSettings()
printSettings->SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX);
printSettings->SetInteger(printing::kSettingCopies, 1);
+ printSettings->SetInteger(printing::kSettingPagesPerSheet, 1);
printSettings->SetBoolean(printing::kSettingCollate, false);
// printSettings->SetBoolean(printing::kSettingGenerateDraftData, false);
printSettings->SetBoolean(printing::kSettingPreviewModifiable, false);
- printSettings->SetBoolean(printing::kSettingShouldPrintSelectionOnly, false);
- printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds, true);
- printSettings->SetBoolean(printing::kSettingHeaderFooterEnabled, false);
- printSettings->SetBoolean(printing::kSettingRasterizePdf, false);
+ printSettings->SetKey(printing::kSettingShouldPrintSelectionOnly, base::Value(false));
+ printSettings->SetKey(printing::kSettingShouldPrintBackgrounds, base::Value(true));
+ printSettings->SetKey(printing::kSettingHeaderFooterEnabled, base::Value(false));
+ printSettings->SetKey(printing::kSettingRasterizePdf, base::Value(false));
printSettings->SetInteger(printing::kSettingScaleFactor, 100);
printSettings->SetString(printing::kSettingDeviceName, "");
printSettings->SetInteger(printing::kPreviewUIID, 12345678);
@@ -224,16 +217,16 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
return;
if (m_printSettings || !filePath.length()) {
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(callback, false));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(callback, false));
return;
}
m_pdfOutputPath = toFilePath(filePath);
m_pdfSaveCallback = callback;
if (!PrintToPDFInternal(pageLayout, printInColor)) {
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(callback, false));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(callback, false));
resetPdfState();
}
}
@@ -248,16 +241,15 @@ void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout,
// If there already is a pending print in progress, don't try starting another one.
if (m_printSettings) {
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(callback, std::vector<char>()));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(callback, QSharedPointer<QByteArray>()));
return;
}
m_pdfPrintCallback = callback;
if (!PrintToPDFInternal(pageLayout, printInColor, useCustomMargins)) {
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(callback, std::vector<char>()));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(callback, QSharedPointer<QByteArray>()));
resetPdfState();
}
@@ -360,21 +352,18 @@ void PrintViewManagerQt::OnMetafileReadyForPrinting(content::RenderFrameHost* rf
StopWorker(params.document_cookie);
// Create local copies so we can reset the state and take a new pdf print job.
- base::Callback<void(const std::vector<char>&)> pdf_print_callback = m_pdfPrintCallback;
- base::Callback<void(bool)> pdf_save_callback = m_pdfSaveCallback;
+ PrintToPDFCallback pdf_print_callback = std::move(m_pdfPrintCallback);
+ PrintToPDFFileCallback pdf_save_callback = std::move(m_pdfSaveCallback);
base::FilePath pdfOutputPath = m_pdfOutputPath;
resetPdfState();
if (!pdf_print_callback.is_null()) {
- std::vector<char> data_vector = GetStdVectorFromHandle(params.content.metafile_data_handle,
- params.content.data_size);
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(pdf_print_callback, data_vector));
+ QSharedPointer<QByteArray> data_array = GetStdVectorFromHandle(params.content.metafile_data_region);
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(pdf_print_callback, data_array));
} else {
- scoped_refptr<base::RefCountedBytes> data_bytes
- = GetBytesFromHandle(params.content.metafile_data_handle, params.content.data_size);
+ scoped_refptr<base::RefCountedBytes> data_bytes = GetBytesFromHandle(params.content.metafile_data_region);
base::PostTaskWithTraits(FROM_HERE, {base::MayBlock()},
base::BindOnce(&SavePdfFile, data_bytes, pdfOutputPath, pdf_save_callback));
}
@@ -394,9 +383,8 @@ void PrintViewManagerQt::DidStartLoading()
void PrintViewManagerQt::NavigationStopped()
{
if (!m_pdfPrintCallback.is_null()) {
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(m_pdfPrintCallback, std::vector<char>()));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(m_pdfPrintCallback, QSharedPointer<QByteArray>()));
}
resetPdfState();
PrintViewManagerBaseQt::NavigationStopped();
@@ -406,9 +394,8 @@ void PrintViewManagerQt::RenderProcessGone(base::TerminationStatus status)
{
PrintViewManagerBaseQt::RenderProcessGone(status);
if (!m_pdfPrintCallback.is_null()) {
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(m_pdfPrintCallback, std::vector<char>()));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(m_pdfPrintCallback, QSharedPointer<QByteArray>()));
}
resetPdfState();
}
@@ -450,4 +437,6 @@ void PrintViewManagerQt::PrintPreviewDone() {
m_printPreviewRfh = nullptr;
}
+WEB_CONTENTS_USER_DATA_KEY_IMPL(PrintViewManagerQt)
+
} // namespace QtWebEngineCore
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index 209be8782..20b988200 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -56,6 +56,8 @@
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_user_data.h"
+#include <QSharedPointer>
+
struct PrintHostMsg_RequestPrintPreview_Params;
struct PrintHostMsg_DidPreviewDocument_Params;
@@ -83,7 +85,7 @@ class PrintViewManagerQt
{
public:
~PrintViewManagerQt() override;
- typedef base::Callback<void(const std::vector<char> &result)> PrintToPDFCallback;
+ typedef base::Callback<void(QSharedPointer<QByteArray> result)> PrintToPDFCallback;
typedef base::Callback<void(bool success)> PrintToPDFFileCallback;
// Method to print a page to a Pdf document with page size \a pageSize in location \a filePath.
@@ -135,6 +137,7 @@ private:
void PrintPreviewDone();
private:
+ WEB_CONTENTS_USER_DATA_KEY_DECL()
content::RenderFrameHost *m_printPreviewRfh;
base::FilePath m_pdfOutputPath;
PrintToPDFCallback m_pdfPrintCallback;
diff --git a/src/core/printing/printing_message_filter_qt.cpp b/src/core/printing/printing_message_filter_qt.cpp
index db59a0807..d1e86343f 100644
--- a/src/core/printing/printing_message_filter_qt.cpp
+++ b/src/core/printing/printing_message_filter_qt.cpp
@@ -183,11 +183,9 @@ void PrintingMessageFilterQt::OnScriptedPrintReply(
}
}
-void PrintingMessageFilterQt::OnUpdatePrintSettings(
- int document_cookie, const base::DictionaryValue& job_settings,
- IPC::Message* reply_msg) {
- std::unique_ptr<base::DictionaryValue> new_settings(job_settings.DeepCopy());
-
+void PrintingMessageFilterQt::OnUpdatePrintSettings(int document_cookie,
+ base::Value job_settings,
+ IPC::Message* reply_msg) {
scoped_refptr<printing::PrinterQuery> printer_query;
printer_query = queue_->PopPrinterQuery(document_cookie);
if (!printer_query.get()) {
@@ -195,7 +193,7 @@ void PrintingMessageFilterQt::OnUpdatePrintSettings(
content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
}
printer_query->SetSettings(
- std::move(new_settings),
+ std::move(job_settings),
base::Bind(&PrintingMessageFilterQt::OnUpdatePrintSettingsReply, this,
printer_query, reply_msg));
}
diff --git a/src/core/printing/printing_message_filter_qt.h b/src/core/printing/printing_message_filter_qt.h
index 72e4b43b4..f1a3514c5 100644
--- a/src/core/printing/printing_message_filter_qt.h
+++ b/src/core/printing/printing_message_filter_qt.h
@@ -110,7 +110,7 @@ class PrintingMessageFilterQt : public content::BrowserMessageFilter {
// handled by the print worker thread and the UI thread. The reply occurs on
// the IO thread.
void OnUpdatePrintSettings(int document_cookie,
- const base::DictionaryValue& job_settings,
+ base::Value job_settings,
IPC::Message* reply_msg);
void OnUpdatePrintSettingsReply(scoped_refptr<printing::PrinterQuery> printer_query,
IPC::Message* reply_msg);
diff --git a/src/core/process_main.cpp b/src/core/process_main.cpp
index 677f0b10a..d661d3b90 100644
--- a/src/core/process_main.cpp
+++ b/src/core/process_main.cpp
@@ -44,7 +44,10 @@
#if defined(OS_WIN)
#include "sandbox/win/src/sandbox_types.h"
#include "content/public/app/sandbox_helper_win.h"
-#endif // OS_WIN
+#elif defined(OS_MACOSX)
+#include "base/logging.h"
+#include "sandbox/mac/seatbelt_exec.h"
+#endif
namespace QtWebEngine {
@@ -64,6 +67,13 @@ int processMain(int argc, const char **argv)
params.argc = argc;
params.argv = argv;
#endif // OS_WIN
+#if defined(OS_MACOSX)
+ sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt =
+ sandbox::SeatbeltExecServer::CreateFromArguments(argv[0], argc, const_cast<char**>(argv));
+ if (seatbelt.sandbox_required) {
+ CHECK(seatbelt.server->InitializeSandbox());
+ }
+#endif // defined(OS_MACOSX)
return content::ContentMain(params);
}
diff --git a/src/core/process_main.h b/src/core/process_main.h
index d171828d5..00c029d9f 100644
--- a/src/core/process_main.h
+++ b/src/core/process_main.h
@@ -52,6 +52,6 @@
namespace QtWebEngine {
-QWEBENGINECORE_PRIVATE_EXPORT int processMain(int argc, const char **argv);
+Q_WEBENGINECORE_PRIVATE_EXPORT int processMain(int argc, const char **argv);
} // namespace
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index b04fa0d46..ebb533206 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -45,10 +45,11 @@
#include "content/public/browser/download_manager.h"
#include "api/qwebengineurlscheme.h"
-#include "content_client_qt.h"
+#include "content_browser_client_qt.h"
#include "download_manager_delegate_qt.h"
#include "net/url_request_context_getter_qt.h"
#include "permission_manager_qt.h"
+#include "profile_adapter_client.h"
#include "profile_qt.h"
#include "renderer_host/user_resource_controller_host.h"
#include "type_conversion.h"
@@ -58,6 +59,10 @@
#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/browser/extension_system.h"
+#endif
+
#include <QCoreApplication>
#include <QDir>
#include <QString>
@@ -79,10 +84,12 @@ namespace QtWebEngineCore {
ProfileAdapter::ProfileAdapter(const QString &storageName):
m_name(storageName)
, m_offTheRecord(storageName.isEmpty())
+ , m_downloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
, m_httpCacheMaxSize(0)
+ , m_pageRequestInterceptors(0)
{
WebEngineContext::current()->addProfileAdapter(this);
// creation of profile requires webengine context
@@ -90,6 +97,11 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
content::BrowserContext::Initialize(m_profile.data(), toFilePath(dataPath()));
// fixme: this should not be here
m_profile->m_profileIOData->initializeOnUIThread();
+ m_customUrlSchemeHandlers.insert(QByteArrayLiteral("qrc"), &m_qrcHandler);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (!storageName.isEmpty())
+ extensions::ExtensionSystem::Get(m_profile.data())->InitForRegularProfile(true);
+#endif
}
ProfileAdapter::~ProfileAdapter()
@@ -102,6 +114,10 @@ ProfileAdapter::~ProfileAdapter()
m_profile->GetDownloadManager(m_profile.data())->Shutdown();
m_downloadManagerDelegate.reset();
}
+#if QT_CONFIG(ssl)
+ delete m_clientCertificateStore;
+#endif
+ Q_ASSERT(m_pageRequestInterceptors == 0);
}
void ProfileAdapter::setStorageName(const QString &storageName)
@@ -178,6 +194,22 @@ void ProfileAdapter::removeClient(ProfileAdapterClient *adapterClient)
m_clients.removeOne(adapterClient);
}
+void ProfileAdapter::addPageRequestInterceptor()
+{
+ ++m_pageRequestInterceptors;
+ if (m_profile->m_urlRequestContextGetter.get())
+ m_profile->m_profileIOData->updateRequestInterceptor();
+}
+
+void ProfileAdapter::removePageRequestInterceptor()
+{
+ Q_ASSERT(m_pageRequestInterceptors > 0);
+ --m_pageRequestInterceptors;
+ if (m_profile->m_urlRequestContextGetter.get())
+ m_profile->m_profileIOData->updateRequestInterceptor();
+}
+
+
void ProfileAdapter::cancelDownload(quint32 downloadId)
{
downloadManagerDelegate()->cancelDownload(downloadId);
@@ -238,6 +270,11 @@ void ProfileAdapter::setDataPath(const QString &path)
}
}
+void ProfileAdapter::setDownloadPath(const QString &path)
+{
+ m_downloadPath = path.isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) : path;
+}
+
QString ProfileAdapter::cachePath() const
{
if (m_offTheRecord)
@@ -296,7 +333,7 @@ QString ProfileAdapter::httpCachePath() const
QString ProfileAdapter::httpUserAgent() const
{
if (m_httpUserAgent.isNull())
- return QString::fromStdString(ContentClientQt::getUserAgent());
+ return QString::fromStdString(ContentBrowserClientQt::getUserAgent());
return m_httpUserAgent;
}
@@ -406,9 +443,39 @@ void ProfileAdapter::setHttpCacheMaxSize(int maxSize)
m_profile->m_profileIOData->updateHttpCache();
}
-const QHash<QByteArray, QWebEngineUrlSchemeHandler *> &ProfileAdapter::customUrlSchemeHandlers() const
+enum class SchemeType { Protected, Overridable, Custom, Unknown };
+static SchemeType schemeType(const QByteArray &canonicalScheme)
{
- return m_customUrlSchemeHandlers;
+ static const QSet<QByteArray> blacklist{
+ QByteArrayLiteral("about"),
+ QByteArrayLiteral("blob"),
+ QByteArrayLiteral("data"),
+ QByteArrayLiteral("javascript"),
+ QByteArrayLiteral("qrc"),
+ // See also kStandardURLSchemes in url/url_util.cc (through url::IsStandard below)
+ };
+
+ static const QSet<QByteArray> whitelist{
+ QByteArrayLiteral("gopher"),
+ };
+
+ bool standardSyntax = url::IsStandard(canonicalScheme.data(), url::Component(0, canonicalScheme.size()));
+ bool customScheme = QWebEngineUrlScheme::schemeByName(canonicalScheme) != QWebEngineUrlScheme();
+ bool blacklisted = blacklist.contains(canonicalScheme);
+ bool whitelisted = whitelist.contains(canonicalScheme);
+
+ if (whitelisted)
+ return SchemeType::Overridable;
+ if (blacklisted || (standardSyntax && !customScheme))
+ return SchemeType::Protected;
+ if (customScheme)
+ return SchemeType::Custom;
+ return SchemeType::Unknown;
+}
+
+QWebEngineUrlSchemeHandler *ProfileAdapter::urlSchemeHandler(const QByteArray &scheme)
+{
+ return m_customUrlSchemeHandlers.value(scheme.toLower()).data();
}
const QList<QByteArray> ProfileAdapter::customUrlSchemes() const
@@ -422,12 +489,17 @@ void ProfileAdapter::updateCustomUrlSchemeHandlers()
m_profile->m_profileIOData->updateJobFactory();
}
-bool ProfileAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+void ProfileAdapter::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
{
+ Q_ASSERT(handler);
bool removedOneOrMore = false;
auto it = m_customUrlSchemeHandlers.begin();
while (it != m_customUrlSchemeHandlers.end()) {
if (it.value() == handler) {
+ if (schemeType(it.key()) == SchemeType::Protected) {
+ qWarning("Cannot remove the URL scheme handler for an internal scheme: %s", it.key().constData());
+ continue;
+ }
it = m_customUrlSchemeHandlers.erase(it);
removedOneOrMore = true;
continue;
@@ -436,60 +508,47 @@ bool ProfileAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *ha
}
if (removedOneOrMore)
updateCustomUrlSchemeHandlers();
- return removedOneOrMore;
}
-QWebEngineUrlSchemeHandler *ProfileAdapter::takeCustomUrlSchemeHandler(const QByteArray &scheme)
+void ProfileAdapter::removeUrlScheme(const QByteArray &scheme)
{
- QWebEngineUrlSchemeHandler *handler = m_customUrlSchemeHandlers.take(scheme.toLower());
- if (handler)
+ QByteArray canonicalScheme = scheme.toLower();
+ if (schemeType(canonicalScheme) == SchemeType::Protected) {
+ qWarning("Cannot remove the URL scheme handler for an internal scheme: %s", scheme.constData());
+ return;
+ }
+ if (m_customUrlSchemeHandlers.remove(canonicalScheme))
updateCustomUrlSchemeHandlers();
- return handler;
}
-bool ProfileAdapter::addCustomUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
+void ProfileAdapter::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
- static const QSet<QByteArray> blacklist{
- QByteArrayLiteral("about"),
- QByteArrayLiteral("blob"),
- QByteArrayLiteral("data"),
- QByteArrayLiteral("javascript"),
- QByteArrayLiteral("qrc"),
- // See also kStandardURLSchemes in url/url_util.cc (through url::IsStandard below)
- };
-
- static const QSet<QByteArray> whitelist{
- QByteArrayLiteral("gopher"),
- };
-
- const QByteArray canonicalScheme = scheme.toLower();
- bool standardSyntax = url::IsStandard(canonicalScheme.data(), url::Component(0, canonicalScheme.size()));
- bool customScheme = QWebEngineUrlScheme::schemeByName(canonicalScheme) != QWebEngineUrlScheme();
- bool blacklisted = blacklist.contains(canonicalScheme) || (standardSyntax && !customScheme);
- bool whitelisted = whitelist.contains(canonicalScheme);
+ Q_ASSERT(handler);
+ QByteArray canonicalScheme = scheme.toLower();
+ SchemeType type = schemeType(canonicalScheme);
- if (blacklisted && !whitelisted) {
+ if (type == SchemeType::Protected) {
qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData());
- return false;
+ return;
}
if (m_customUrlSchemeHandlers.value(canonicalScheme, handler) != handler) {
qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
- return false;
+ return;
}
- if (!whitelisted && !customScheme)
+ if (type == SchemeType::Unknown)
qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() "
"before installing the custom scheme handler.", scheme.constData());
m_customUrlSchemeHandlers.insert(canonicalScheme, handler);
updateCustomUrlSchemeHandlers();
- return true;
}
-void ProfileAdapter::clearCustomUrlSchemeHandlers()
+void ProfileAdapter::removeAllUrlSchemeHandlers()
{
m_customUrlSchemeHandlers.clear();
+ m_customUrlSchemeHandlers.insert(QByteArrayLiteral("qrc"), &m_qrcHandler);
updateCustomUrlSchemeHandlers();
}
@@ -598,7 +657,46 @@ void ProfileAdapter::removeWebContentsAdapterClient(WebContentsAdapterClient *cl
void ProfileAdapter::resetVisitedLinksManager()
{
- m_visitedLinksManager.reset(new VisitedLinksManagerQt(this));
+ m_visitedLinksManager.reset(new VisitedLinksManagerQt(m_profile.data(), persistVisitedLinks()));
}
+void ProfileAdapter::setUseForGlobalCertificateVerification(bool enable)
+{
+ if (m_usedForGlobalCertificateVerification == enable)
+ return;
+
+ static QPointer<ProfileAdapter> profileForglobalCertificateVerification;
+
+ m_usedForGlobalCertificateVerification = enable;
+ if (enable) {
+ if (profileForglobalCertificateVerification) {
+ profileForglobalCertificateVerification->m_usedForGlobalCertificateVerification = false;
+ for (auto *client : qAsConst(profileForglobalCertificateVerification->m_clients))
+ client->useForGlobalCertificateVerificationChanged();
+ }
+ profileForglobalCertificateVerification = this;
+ } else {
+ Q_ASSERT(profileForglobalCertificateVerification);
+ Q_ASSERT(profileForglobalCertificateVerification == this);
+ profileForglobalCertificateVerification = nullptr;
+ }
+
+ if (m_profile->m_urlRequestContextGetter.get())
+ m_profile->m_profileIOData->updateUsedForGlobalCertificateVerification();
+}
+
+bool ProfileAdapter::isUsedForGlobalCertificateVerification() const
+{
+ return m_usedForGlobalCertificateVerification;
+}
+
+#if QT_CONFIG(ssl)
+QWebEngineClientCertificateStore *ProfileAdapter::clientCertificateStore()
+{
+ if (!m_clientCertificateStore)
+ m_clientCertificateStore = new QWebEngineClientCertificateStore(m_profile->m_profileIOData->clientCertificateStoreData());
+ return m_clientCertificateStore;
+}
+#endif
+
} // namespace QtWebEngineCore
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index e92fb524b..1f94f59a9 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -60,22 +60,25 @@
#include <QString>
#include <QVector>
+#include "api/qwebengineclientcertificatestore.h"
#include "api/qwebenginecookiestore.h"
#include "api/qwebengineurlrequestinterceptor.h"
#include "api/qwebengineurlschemehandler.h"
+#include "net/qrc_url_scheme_handler.h"
QT_FORWARD_DECLARE_CLASS(QObject)
namespace QtWebEngineCore {
-class ProfileAdapterClient;
+class UserNotificationController;
class DownloadManagerDelegateQt;
+class ProfileAdapterClient;
class ProfileQt;
class UserResourceControllerHost;
class VisitedLinksManagerQt;
class WebContentsAdapterClient;
-class QWEBENGINECORE_PRIVATE_EXPORT ProfileAdapter : public QObject
+class Q_WEBENGINECORE_PRIVATE_EXPORT ProfileAdapter : public QObject
{
public:
explicit ProfileAdapter(const QString &storagePrefix = QString());
@@ -113,6 +116,9 @@ public:
QString dataPath() const;
void setDataPath(const QString &path);
+ QString downloadPath() const { return m_downloadPath; }
+ void setDownloadPath(const QString &path);
+
QString cachePath() const;
void setCachePath(const QString &path);
@@ -153,8 +159,7 @@ public:
enum PermissionType {
UnsupportedPermission = 0,
GeolocationPermission = 1,
-// Reserved:
-// NotificationPermission = 2,
+ NotificationPermission = 2,
AudioCapturePermission = 3,
VideoCapturePermission = 4,
ClipboardRead = 5,
@@ -174,14 +179,14 @@ public:
void setHttpCacheMaxSize(int maxSize);
bool trackVisitedLinks() const;
- bool persistVisitedLinks() const;
- const QHash<QByteArray, QWebEngineUrlSchemeHandler *> &customUrlSchemeHandlers() const;
+ QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &scheme);
+ void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler);
+ void removeUrlScheme(const QByteArray &scheme);
+ void removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler);
+ void removeAllUrlSchemeHandlers();
+
const QList<QByteArray> customUrlSchemes() const;
- void clearCustomUrlSchemeHandlers();
- bool addCustomUrlSchemeHandler(const QByteArray &, QWebEngineUrlSchemeHandler *);
- bool removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *);
- QWebEngineUrlSchemeHandler *takeCustomUrlSchemeHandler(const QByteArray &);
UserResourceControllerHost *userResourceController();
void permissionRequestReply(const QUrl &origin, PermissionType type, bool reply);
@@ -193,30 +198,57 @@ public:
void clearHttpCache();
+ void setUseForGlobalCertificateVerification(bool enable = true);
+ bool isUsedForGlobalCertificateVerification() const;
+
+ void addPageRequestInterceptor();
+ void removePageRequestInterceptor();
+ bool hasPageRequestInterceptor() const { return m_pageRequestInterceptors > 0; }
+
+#if QT_CONFIG(ssl)
+ QWebEngineClientCertificateStore *clientCertificateStore();
+#endif
+
+ QHash<QByteArray, QWeakPointer<UserNotificationController>> &ephemeralNotifications()
+ { return m_ephemeralNotifications; }
+ QHash<QByteArray, QSharedPointer<UserNotificationController>> &persistentNotifications()
+ { return m_persistentNotifications; }
+
private:
void updateCustomUrlSchemeHandlers();
void resetVisitedLinksManager();
+ bool persistVisitedLinks() const;
QString m_name;
bool m_offTheRecord;
+ bool m_usedForGlobalCertificateVerification = false;
QScopedPointer<ProfileQt> m_profile;
QScopedPointer<VisitedLinksManagerQt> m_visitedLinksManager;
QScopedPointer<DownloadManagerDelegateQt> m_downloadManagerDelegate;
QScopedPointer<UserResourceControllerHost> m_userResourceController;
QScopedPointer<QWebEngineCookieStore> m_cookieStore;
+#if QT_CONFIG(ssl)
+ QWebEngineClientCertificateStore *m_clientCertificateStore = nullptr;
+#endif
QPointer<QWebEngineUrlRequestInterceptor> m_requestInterceptor;
QString m_dataPath;
+ QString m_downloadPath;
QString m_cachePath;
QString m_httpUserAgent;
HttpCacheType m_httpCacheType;
QString m_httpAcceptLanguage;
PersistentCookiesPolicy m_persistentCookiesPolicy;
VisitedLinksPolicy m_visitedLinksPolicy;
- QHash<QByteArray, QWebEngineUrlSchemeHandler *> m_customUrlSchemeHandlers;
+ QHash<QByteArray, QPointer<QWebEngineUrlSchemeHandler>> m_customUrlSchemeHandlers;
+ QHash<QByteArray, QWeakPointer<UserNotificationController>> m_ephemeralNotifications;
+ QHash<QByteArray, QSharedPointer<UserNotificationController>> m_persistentNotifications;
+
QList<ProfileAdapterClient*> m_clients;
QVector<WebContentsAdapterClient *> m_webContentsAdapterClients;
int m_httpCacheMaxSize;
+ int m_pageRequestInterceptors;
+ QrcUrlSchemeHandler m_qrcHandler;
Q_DISABLE_COPY(ProfileAdapter)
};
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index 19af12ca4..b463043da 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -52,14 +52,16 @@
#define PROFILE_ADAPTER_CLIENT_H
#include "qtwebenginecoreglobal_p.h"
+#include <QSharedPointer>
#include <QString>
#include <QUrl>
namespace QtWebEngineCore {
class WebContentsAdapterClient;
+class UserNotificationController;
-class QWEBENGINECORE_PRIVATE_EXPORT ProfileAdapterClient
+class Q_WEBENGINECORE_PRIVATE_EXPORT ProfileAdapterClient
{
public:
// Keep in sync with content::DownloadItem::DownloadState
@@ -142,6 +144,9 @@ public:
virtual void downloadRequested(DownloadItemInfo &info) = 0;
virtual void downloadUpdated(const DownloadItemInfo &info) = 0;
+ virtual void useForGlobalCertificateVerificationChanged() {}
+ virtual void showNotification(QSharedPointer<UserNotificationController> &) { }
+
virtual void addWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
virtual void removeWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
static QString downloadInterruptReasonToString(DownloadInterruptReason reason);
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 99a6f6db0..27c97a986 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -39,9 +39,10 @@
#include "profile_io_data_qt.h"
-#include "base/task_scheduler/post_task.h"
+#include "base/task/post_task.h"
#include "components/certificate_transparency/ct_known_logs.h"
#include "components/network_session_configurator/common/network_features.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/cookie_store_factory.h"
@@ -49,6 +50,7 @@
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
#include "chrome/common/chrome_switches.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
@@ -77,16 +79,26 @@
#include "services/file/user_id_map.h"
#include "services/network/proxy_service_mojo.h"
+#include "net/client_cert_override.h"
+#include "net/client_cert_store_data.h"
#include "net/cookie_monster_delegate_qt.h"
#include "net/custom_protocol_handler.h"
#include "net/network_delegate_qt.h"
#include "net/proxy_config_service_qt.h"
-#include "net/qrc_protocol_handler_qt.h"
#include "net/url_request_context_getter_qt.h"
#include "profile_qt.h"
#include "resource_context_qt.h"
#include "type_conversion.h"
+#if defined(USE_NSS_CERTS)
+#include "net/cert_net/nss_ocsp.h"
+#endif
+
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+#include "net/cert/cert_net_fetcher.h"
+#include "net/cert_net/cert_net_fetcher_impl.h"
+#endif
+
namespace QtWebEngineCore {
static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first,
@@ -96,8 +108,6 @@ static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &f
return false;
if (first.enable_channel_id != second.enable_channel_id)
return false;
- if (first.enable_token_binding != second.enable_token_binding)
- return false;
return true;
}
@@ -147,14 +157,16 @@ static net::HttpNetworkSession::Params generateNetworkSessionParams(bool ignoreC
{
net::HttpNetworkSession::Params network_session_params;
network_session_params.ignore_certificate_errors = ignoreCertificateErrors;
- network_session_params.enable_token_binding = base::FeatureList::IsEnabled(features::kTokenBinding);
- network_session_params.enable_channel_id = base::FeatureList::IsEnabled(features::kChannelID);
return network_session_params;
}
ProfileIODataQt::ProfileIODataQt(ProfileQt *profile)
: m_profile(profile),
+#if QT_CONFIG(ssl)
+ m_clientCertificateStoreData(new ClientCertificateStoreData),
+#endif
m_mutex(QMutex::Recursive),
+ m_removerObserver(this),
m_weakPtrFactory(this)
{
if (content::BrowserThread::IsThreadInitialized(content::BrowserThread::UI))
@@ -165,8 +177,19 @@ ProfileIODataQt::~ProfileIODataQt()
{
if (content::BrowserThread::IsThreadInitialized(content::BrowserThread::IO))
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (m_useForGlobalCertificateVerification) {
+#if defined(USE_NSS_CERTS)
+ net::SetURLRequestContextForNSSHttpIO(nullptr);
+#endif
+#if defined(OS_LINUX) ||defined(OS_MACOSX)
+ net::ShutdownGlobalCertNetFetcher();
+#endif
+ }
+
if (m_urlRequestContext && m_urlRequestContext->proxy_resolution_service())
m_urlRequestContext->proxy_resolution_service()->OnShutdown();
+
m_resourceContext.reset();
if (m_cookieDelegate)
m_cookieDelegate->setCookieMonster(0); // this will let CookieMonsterDelegateQt be deleted
@@ -174,9 +197,18 @@ ProfileIODataQt::~ProfileIODataQt()
delete m_proxyConfigService.fetchAndStoreAcquire(0);
}
+QPointer<ProfileAdapter> ProfileIODataQt::profileAdapter()
+{
+ return m_profileAdapter;
+}
+
void ProfileIODataQt::shutdownOnUIThread()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+#if QT_CONFIG(ssl)
+ delete m_clientCertificateStoreData;
+ m_clientCertificateStoreData = nullptr;
+#endif
bool posted = content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, this);
if (!posted) {
qWarning() << "Could not delete ProfileIODataQt on io thread !";
@@ -197,6 +229,13 @@ content::ResourceContext *ProfileIODataQt::resourceContext()
return m_resourceContext.get();
}
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+extensions::ExtensionSystemQt* ProfileIODataQt::GetExtensionSystem()
+{
+ return m_profile->GetExtensionSystem();
+}
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
void ProfileIODataQt::initializeOnIOThread()
{
m_networkDelegate.reset(new NetworkDelegateQt(this));
@@ -210,6 +249,7 @@ void ProfileIODataQt::initializeOnIOThread()
QMutexLocker lock(&m_mutex);
generateAllStorage();
generateJobFactory();
+ setGlobalCertificateVerification();
m_initialized = true;
}
@@ -276,7 +316,15 @@ void ProfileIODataQt::generateStorage()
net::ProxyConfigService *proxyConfigService = m_proxyConfigService.fetchAndStoreAcquire(0);
Q_ASSERT(proxyConfigService);
- m_storage->set_cert_verifier(net::CertVerifier::CreateDefault());
+ std::unique_ptr<net::CertVerifier> cert_verifier = net::CertVerifier::CreateDefault();
+ net::CertVerifier::Config config;
+ // Enable revocation checking:
+ config.enable_rev_checking = true;
+ // Mirroring Android WebView (we have no beef with Symantec, and our users might use them):
+ config.disable_symantec_enforcement = true;
+ cert_verifier->SetConfig(config);
+
+ m_storage->set_cert_verifier(std::move(cert_verifier));
std::unique_ptr<net::MultiLogCTVerifier> ct_verifier(new net::MultiLogCTVerifier());
std::vector<scoped_refptr<const net::CTLogVerifier>> ct_logs;
for (const auto &ct_log : certificate_transparency::GetKnownLogs()) {
@@ -306,7 +354,7 @@ void ProfileIODataQt::generateStorage()
scoped_refptr<base::SequencedTaskRunner> background_task_runner(
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(),
- base::TaskPriority::BACKGROUND,
+ base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN}));
m_transportSecurityPersister =
std::make_unique<net::TransportSecurityPersister>(
@@ -347,7 +395,7 @@ void ProfileIODataQt::generateCookieStore()
channel_id_db = new net::SQLiteChannelIDStore(
toFilePath(m_channelIdPath),
base::CreateSequencedTaskRunnerWithTraits(
- {base::MayBlock(), base::TaskPriority::BACKGROUND}));
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT}));
}
m_storage->set_channel_id_service(
@@ -362,8 +410,8 @@ void ProfileIODataQt::generateCookieStore()
base::FilePath(),
false,
false,
- nullptr)
- );
+ nullptr),
+ nullptr);
break;
case ProfileAdapter::AllowPersistentCookies:
cookieStore = content::CreateCookieStore(
@@ -371,8 +419,8 @@ void ProfileIODataQt::generateCookieStore()
toFilePath(m_cookiesPath),
false,
true,
- nullptr)
- );
+ nullptr),
+ nullptr);
break;
case ProfileAdapter::ForcePersistentCookies:
cookieStore = content::CreateCookieStore(
@@ -380,8 +428,8 @@ void ProfileIODataQt::generateCookieStore()
toFilePath(m_cookiesPath),
true,
true,
- nullptr)
- );
+ nullptr),
+ nullptr);
break;
}
@@ -391,7 +439,7 @@ void ProfileIODataQt::generateCookieStore()
m_storage->set_cookie_store(std::move(cookieStore));
const std::vector<std::string> cookieableSchemes(kCookieableSchemes,
- kCookieableSchemes + arraysize(kCookieableSchemes));
+ kCookieableSchemes + base::size(kCookieableSchemes));
cookieMonster->SetCookieableSchemes(cookieableSchemes);
}
@@ -478,13 +526,10 @@ void ProfileIODataQt::generateJobFactory()
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>(
new net::DataProtocolHandler()));
scoped_refptr<base::TaskRunner> taskRunner(base::CreateTaskRunnerWithTraits({base::MayBlock(),
- base::TaskPriority::BACKGROUND,
+ base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
jobFactory->SetProtocolHandler(url::kFileScheme,
std::make_unique<net::FileProtocolHandler>(taskRunner));
- jobFactory->SetProtocolHandler(kQrcSchemeQt,
- std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>(
- new QrcProtocolHandlerQt()));
jobFactory->SetProtocolHandler(url::kFtpScheme,
net::FtpProtocolHandler::Create(m_urlRequestContext->host_resolver()));
@@ -542,6 +587,21 @@ void ProfileIODataQt::regenerateJobFactory()
}
}
+void ProfileIODataQt::setGlobalCertificateVerification()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ QMutexLocker lock(&m_mutex);
+ if (m_useForGlobalCertificateVerification) {
+#if defined(USE_NSS_CERTS)
+ // Set request context used by NSS for OCSP requests.
+ net::SetURLRequestContextForNSSHttpIO(m_urlRequestContext.get());
+#endif
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+ net::SetGlobalCertNetFetcher(net::CreateCertNetFetcher(m_urlRequestContext.get()));
+#endif
+ }
+}
+
void ProfileIODataQt::setRequestContextData(content::ProtocolHandlerMap *protocolHandlers,
content::URLRequestInterceptorScopedVector request_interceptors)
{
@@ -564,6 +624,7 @@ void ProfileIODataQt::setFullConfiguration()
m_httpCachePath = m_profileAdapter->httpCachePath();
m_httpCacheMaxSize = m_profileAdapter->httpCacheMaxSize();
m_customUrlSchemes = m_profileAdapter->customUrlSchemes();
+ m_useForGlobalCertificateVerification = m_profileAdapter->isUsedForGlobalCertificateVerification();
m_dataPath = m_profileAdapter->dataPath();
}
@@ -573,8 +634,8 @@ void ProfileIODataQt::requestStorageGeneration() {
if (m_initialized && !m_updateAllStorage) {
m_updateAllStorage = true;
createProxyConfig();
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&ProfileIODataQt::generateAllStorage, m_weakPtr));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&ProfileIODataQt::generateAllStorage, m_weakPtr));
}
}
@@ -587,10 +648,14 @@ void ProfileIODataQt::createProxyConfig()
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
Q_ASSERT(m_proxyConfigService == 0);
+ net::ProxyConfigWithAnnotation initialConfig;
+ ProxyPrefs::ConfigState initialConfigState = PrefProxyConfigTrackerImpl::ReadPrefConfig(
+ m_profileAdapter->profile()->GetPrefs(), &initialConfig);
m_proxyConfigService =
new ProxyConfigServiceQt(
net::ProxyResolutionService::CreateSystemProxyConfigService(
- content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO)));
+ base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})),
+ initialConfig, initialConfigState);
//pass interface to io thread
m_proxyResolverFactoryInterface = ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface();
}
@@ -602,12 +667,13 @@ void ProfileIODataQt::updateStorageSettings()
QMutexLocker lock(&m_mutex);
setFullConfiguration();
- std::string userId = content::BrowserContext::GetServiceUserIdFor(m_profile);
- if (file::GetUserDirForUserId(userId) != toFilePath(m_profileAdapter->dataPath())) {
- file::ForgetServiceUserIdUserDirAssociation(userId);
- file::AssociateServiceUserIdWithUserDir(userId, toFilePath(m_profileAdapter->dataPath()));
+ base::Token groupId = content::BrowserContext::GetServiceInstanceGroupFor(m_profile);
+ if (file::GetUserDirForInstanceGroup(groupId) != toFilePath(m_profileAdapter->dataPath())) {
+ file::ForgetServiceInstanceGroupUserDirAssociation(groupId);
+ file::AssociateServiceInstanceGroupWithUserDir(groupId, toFilePath(m_profileAdapter->dataPath()));
}
- requestStorageGeneration();
+ if (!m_pendingStorageRequestGeneration)
+ requestStorageGeneration();
}
void ProfileIODataQt::updateCookieStore()
@@ -617,7 +683,8 @@ void ProfileIODataQt::updateCookieStore()
m_persistentCookiesPolicy = m_profileAdapter->persistentCookiesPolicy();
m_cookiesPath = m_profileAdapter->cookiesPath();
m_channelIdPath = m_profileAdapter->channelIdPath();
- requestStorageGeneration();
+ if (!m_pendingStorageRequestGeneration)
+ requestStorageGeneration();
}
void ProfileIODataQt::updateUserAgent()
@@ -626,7 +693,8 @@ void ProfileIODataQt::updateUserAgent()
QMutexLocker lock(&m_mutex);
m_httpAcceptLanguage = m_profileAdapter->httpAcceptLanguage();
m_httpUserAgent = m_profileAdapter->httpUserAgent();
- requestStorageGeneration();
+ if (!m_pendingStorageRequestGeneration)
+ requestStorageGeneration();
}
void ProfileIODataQt::updateHttpCache()
@@ -638,14 +706,19 @@ void ProfileIODataQt::updateHttpCache()
m_httpCacheMaxSize = m_profileAdapter->httpCacheMaxSize();
if (m_httpCacheType == ProfileAdapter::NoCache) {
+ m_pendingStorageRequestGeneration = true;
content::BrowsingDataRemover *remover =
content::BrowserContext::GetBrowsingDataRemover(m_profileAdapter->profile());
- remover->Remove(base::Time(), base::Time::Max(),
+ remover->AddObserver(&m_removerObserver);
+ remover->RemoveAndReply(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_CACHE,
content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
- content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);
+ content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
+ &m_removerObserver);
+ return;
}
- requestStorageGeneration();
+ if (!m_pendingStorageRequestGeneration)
+ requestStorageGeneration();
}
void ProfileIODataQt::updateJobFactory()
@@ -657,8 +730,8 @@ void ProfileIODataQt::updateJobFactory()
if (m_initialized && !m_updateJobFactory) {
m_updateJobFactory = true;
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&ProfileIODataQt::regenerateJobFactory, m_weakPtr));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&ProfileIODataQt::regenerateJobFactory, m_weakPtr));
}
}
@@ -667,6 +740,7 @@ void ProfileIODataQt::updateRequestInterceptor()
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
QMutexLocker lock(&m_mutex);
m_requestInterceptor = m_profileAdapter->requestInterceptor();
+ m_hasPageInterceptors = m_profileAdapter->hasPageRequestInterceptor();
// We in this case do not need to regenerate any Chromium classes.
}
@@ -676,6 +750,18 @@ QWebEngineUrlRequestInterceptor *ProfileIODataQt::acquireInterceptor()
return m_requestInterceptor;
}
+QWebEngineUrlRequestInterceptor *ProfileIODataQt::requestInterceptor()
+{
+ return m_requestInterceptor;
+}
+
+bool ProfileIODataQt::hasPageInterceptors()
+{
+ // used in NetworkDelegateQt::OnBeforeURLRequest
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ return m_hasPageInterceptors;
+}
+
void ProfileIODataQt::releaseInterceptor()
{
m_mutex.unlock();
@@ -691,4 +777,57 @@ bool ProfileIODataQt::canGetCookies(const QUrl &firstPartyUrl, const QUrl &url)
return m_cookieDelegate->canGetCookies(firstPartyUrl, url);
}
+void ProfileIODataQt::updateUsedForGlobalCertificateVerification()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_useForGlobalCertificateVerification = m_profileAdapter->isUsedForGlobalCertificateVerification();
+
+ if (m_useForGlobalCertificateVerification)
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&ProfileIODataQt::setGlobalCertificateVerification, m_weakPtr));
+}
+
+#if QT_CONFIG(ssl)
+ClientCertificateStoreData *ProfileIODataQt::clientCertificateStoreData()
+{
+ return m_clientCertificateStoreData;
+}
+#endif
+
+std::unique_ptr<net::ClientCertStore> ProfileIODataQt::CreateClientCertStore()
+{
+#if QT_CONFIG(ssl)
+ return std::unique_ptr<net::ClientCertStore>(new ClientCertOverrideStore(m_clientCertificateStoreData));
+#else
+ return nullptr;
+#endif
+}
+
+// static
+ProfileIODataQt *ProfileIODataQt::FromResourceContext(content::ResourceContext *resource_context)
+{
+ return static_cast<ResourceContextQt *>(resource_context)->m_io_data;
+}
+
+void ProfileIODataQt::removeBrowsingDataRemoverObserver()
+{
+ content::BrowsingDataRemover *remover =
+ content::BrowserContext::GetBrowsingDataRemover(m_profileAdapter->profile());
+ remover->RemoveObserver(&m_removerObserver);
+}
+
+BrowsingDataRemoverObserverQt::BrowsingDataRemoverObserverQt(ProfileIODataQt *profileIOData)
+ : m_profileIOData(profileIOData)
+{
+}
+
+void BrowsingDataRemoverObserverQt::OnBrowsingDataRemoverDone()
+{
+ Q_ASSERT(m_profileIOData->m_pendingStorageRequestGeneration);
+ m_profileIOData->requestStorageGeneration();
+ m_profileIOData->removeBrowsingDataRemoverObserver();
+ m_profileIOData->m_pendingStorageRequestGeneration = false;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 8ce6185b5..570365085 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -41,8 +41,10 @@
#define PROFILE_IO_DATA_QT_H
#include "profile_adapter.h"
+#include "content/public/browser/browsing_data_remover.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include "extensions/buildflags/buildflags.h"
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
#include <QtCore/QString>
@@ -50,6 +52,7 @@
#include <QtCore/QMutex>
namespace net {
+class ClientCertStore;
class DhcpPacFileFetcherFactory;
class HttpAuthPreferences;
class HttpNetworkSession;
@@ -61,10 +64,28 @@ class URLRequestJobFactoryImpl;
class TransportSecurityPersister;
}
+namespace extensions {
+class ExtensionSystemQt;
+}
+
namespace QtWebEngineCore {
+struct ClientCertificateStoreData;
+class ProfileIODataQt;
class ProfileQt;
+
+class BrowsingDataRemoverObserverQt : public content::BrowsingDataRemover::Observer {
+public:
+ BrowsingDataRemoverObserverQt(ProfileIODataQt *profileIOData);
+
+ void OnBrowsingDataRemoverDone() override;
+
+private:
+ ProfileIODataQt *m_profileIOData;
+};
+
+
// ProfileIOData contains data that lives on the IOthread
// we still use shared memebers and use mutex which breaks
// idea for this object, but this is wip.
@@ -75,8 +96,13 @@ public:
ProfileIODataQt(ProfileQt *profile); // runs on ui thread
virtual ~ProfileIODataQt();
+ QPointer<ProfileAdapter> profileAdapter();
content::ResourceContext *resourceContext();
net::URLRequestContext *urlRequestContext();
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::ExtensionSystemQt* GetExtensionSystem();
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
void initializeOnIOThread();
void initializeOnUIThread(); // runs on ui thread
void shutdownOnUIThread(); // runs on ui thread
@@ -91,10 +117,12 @@ public:
void regenerateJobFactory();
bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url) const;
bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const;
+ void setGlobalCertificateVerification();
// Used in NetworkDelegateQt::OnBeforeURLRequest.
QWebEngineUrlRequestInterceptor *acquireInterceptor();
void releaseInterceptor();
+ QWebEngineUrlRequestInterceptor *requestInterceptor();
void setRequestContextData(content::ProtocolHandlerMap *protocolHandlers,
content::URLRequestInterceptorScopedVector request_interceptors);
@@ -107,8 +135,17 @@ public:
void updateRequestInterceptor(); // runs on ui thread
void requestStorageGeneration(); //runs on ui thread
void createProxyConfig(); //runs on ui thread
+ void updateUsedForGlobalCertificateVerification(); // runs on ui thread
+ bool hasPageInterceptors();
+#if QT_CONFIG(ssl)
+ ClientCertificateStoreData *clientCertificateStoreData();
+#endif
+ std::unique_ptr<net::ClientCertStore> CreateClientCertStore();
+ static ProfileIODataQt *FromResourceContext(content::ResourceContext *resource_context);
private:
+ void removeBrowsingDataRemoverObserver();
+
ProfileQt *m_profile;
std::unique_ptr<net::URLRequestContextStorage> m_storage;
std::unique_ptr<net::NetworkDelegate> m_networkDelegate;
@@ -130,6 +167,9 @@ private:
QAtomicPointer<net::ProxyConfigService> m_proxyConfigService;
QPointer<ProfileAdapter> m_profileAdapter; // never dereferenced in IO thread and it is passed by qpointer
ProfileAdapter::PersistentCookiesPolicy m_persistentCookiesPolicy;
+#if QT_CONFIG(ssl)
+ ClientCertificateStoreData *m_clientCertificateStoreData;
+#endif
QString m_cookiesPath;
QString m_channelIdPath;
QString m_httpAcceptLanguage;
@@ -145,9 +185,15 @@ private:
bool m_updateAllStorage = false;
bool m_updateJobFactory = false;
bool m_ignoreCertificateErrors = false;
+ bool m_useForGlobalCertificateVerification = false;
+ bool m_hasPageInterceptors = false;
+ BrowsingDataRemoverObserverQt m_removerObserver;
base::WeakPtrFactory<ProfileIODataQt> m_weakPtrFactory; // this should be always the last member
QString m_dataPath;
+ bool m_pendingStorageRequestGeneration = false;
DISALLOW_COPY_AND_ASSIGN(ProfileIODataQt);
+
+ friend class BrowsingDataRemoverObserverQt;
};
} // namespace QtWebEngineCore
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 2387eba1b..5977a28a8 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -41,6 +41,7 @@
#include "profile_adapter.h"
#include "browsing_data_remover_delegate_qt.h"
+#include "command_line_pref_store_qt.h"
#include "download_manager_delegate_qt.h"
#include "net/ssl_host_state_delegate_qt.h"
#include "net/url_request_context_getter_qt.h"
@@ -48,9 +49,11 @@
#include "qtwebenginecoreglobal_p.h"
#include "type_conversion.h"
#include "web_engine_library_info.h"
+#include "web_engine_context.h"
#include "base/time/time.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/browser/storage_partition.h"
#include "base/base_paths.h"
@@ -62,22 +65,39 @@
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/user_prefs/user_prefs.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "chrome/common/pref_names.h"
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spellcheck_service.h"
-#include "chrome/common/pref_names.h"
#include "components/spellcheck/browser/pref_names.h"
#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "components/guest_view/browser/guest_view_manager.h"
+#include "extensions/browser/extension_protocols.h"
+#include "extensions/browser/pref_names.h"
+#include "extensions/browser/process_manager.h"
+#include "extensions/common/constants.h"
+
+#include "extensions/extension_system_qt.h"
+#endif
+
namespace QtWebEngineCore {
ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
- : m_profileIOData(new ProfileIODataQt(this)),
- m_profileAdapter(profileAdapter)
+ : m_sharedCorsOriginAccessList(content::SharedCorsOriginAccessList::Create())
+ , m_profileIOData(new ProfileIODataQt(this))
+ , m_profileAdapter(profileAdapter)
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ , m_extensionSystem(nullptr)
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
{
PrefServiceFactory factory;
factory.set_user_prefs(new InMemoryPrefStore);
+ factory.set_command_line_prefs(base::MakeRefCounted<CommandLinePrefStoreQt>(
+ WebEngineContext::commandLine()));
PrefRegistrySimple *registry = new PrefRegistrySimple();
-
+ PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
#if QT_CONFIG(webengine_spellchecker)
// Initial spellcheck settings
registry->RegisterStringPref(prefs::kAcceptLanguages, std::string());
@@ -87,6 +107,24 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckEnable, false);
registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false);
#endif // QT_CONFIG(webengine_spellchecker)
+ registry->RegisterBooleanPref(prefs::kShowInternalAccessibilityTree, false);
+ registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ registry->RegisterDictionaryPref(extensions::pref_names::kExtensions);
+ registry->RegisterListPref(extensions::pref_names::kInstallAllowList);
+ registry->RegisterListPref(extensions::pref_names::kInstallDenyList);
+ registry->RegisterDictionaryPref(extensions::pref_names::kInstallForceList);
+ registry->RegisterDictionaryPref(extensions::pref_names::kInstallLoginScreenAppList);
+ registry->RegisterListPref(extensions::pref_names::kAllowedTypes);
+ registry->RegisterBooleanPref(extensions::pref_names::kStorageGarbageCollect, false);
+ registry->RegisterListPref(extensions::pref_names::kAllowedInstallSites);
+ registry->RegisterStringPref(extensions::pref_names::kLastChromeVersion, std::string());
+ registry->RegisterListPref(extensions::pref_names::kNativeMessagingBlacklist);
+ registry->RegisterListPref(extensions::pref_names::kNativeMessagingWhitelist);
+ registry->RegisterBooleanPref(extensions::pref_names::kNativeMessagingUserLevelHosts, true);
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
m_prefService = factory.Create(registry);
user_prefs::UserPrefs::Set(this, m_prefService.get());
@@ -95,6 +133,11 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
// ProfileQt object is allocated at the same address as a previously
// destroyed one. Needs to be called after WebEngineContext initialization.
BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive(this);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ m_extensionSystem = static_cast<extensions::ExtensionSystemQt*>(extensions::ExtensionSystem::Get(this));
+ m_extensionSystem->InitForRegularProfile(true);
+#endif
}
ProfileQt::~ProfileQt()
@@ -123,6 +166,11 @@ base::FilePath ProfileQt::GetPath() const
return toFilePath(m_profileAdapter->dataPath());
}
+base::FilePath ProfileQt::GetCachePath() const
+{
+ return toFilePath(m_profileAdapter->cachePath());
+}
+
bool ProfileQt::IsOffTheRecord() const
{
return m_profileAdapter->isOffTheRecord();
@@ -156,7 +204,11 @@ content::DownloadManagerDelegate *ProfileQt::GetDownloadManagerDelegate()
content::BrowserPluginGuestManager *ProfileQt::GetGuestManager()
{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ return guest_view::GuestViewManager::FromBrowserContext(this);
+#else
return nullptr;
+#endif
}
storage::SpecialStoragePolicy *ProfileQt::GetSpecialStoragePolicy()
@@ -212,6 +264,12 @@ net::URLRequestContextGetter *ProfileQt::CreateRequestContext(
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!m_urlRequestContextGetter.get());
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::InfoMap* extension_info_map = GetExtensionSystem()->info_map();
+ (*protocol_handlers)[extensions::kExtensionScheme] =
+ extensions::CreateExtensionProtocolHandler(IsOffTheRecord(),extension_info_map);
+#endif
+
m_profileIOData->setRequestContextData(protocol_handlers, std::move(request_interceptors));
m_profileIOData->updateStorageSettings();
m_urlRequestContextGetter = new URLRequestContextGetterQt(m_profileIOData.get());
@@ -227,12 +285,33 @@ net::URLRequestContextGetter *ProfileQt::CreateRequestContextForStoragePartition
return nullptr;
}
+content::ClientHintsControllerDelegate *ProfileQt::GetClientHintsControllerDelegate()
+{
+ return nullptr;
+}
+
+void ProfileQt::SetCorsOriginAccessListForOrigin(const url::Origin &source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure)
+{
+ m_sharedCorsOriginAccessList->SetForOrigin(source_origin,
+ std::move(allow_patterns),
+ std::move(block_patterns),
+ std::move(closure));
+}
+
+const content::SharedCorsOriginAccessList *ProfileQt::GetSharedCorsOriginAccessList() const
+{
+ return m_sharedCorsOriginAccessList.get();
+}
+
#if QT_CONFIG(webengine_spellchecker)
void ProfileQt::FailedToLoadDictionary(const std::string &language)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- qWarning() << "Could not load dictionary for:" << toQt(language) << endl
- << "Make sure that correct bdic file is in:" << toQt(WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES).value());
+ LOG(WARNING) << "Could not load dictionary for:" << language;
+ LOG(INFO) << "Make sure that correct bdic file is in:" << WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES);
}
void ProfileQt::setSpellCheckLanguages(const QStringList &languages)
@@ -268,4 +347,12 @@ bool ProfileQt::isSpellCheckEnabled() const
return m_prefService->GetBoolean(spellcheck::prefs::kSpellCheckEnable);
}
#endif // QT_CONFIG(webengine_spellchecker)
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+extensions::ExtensionSystemQt* ProfileQt::GetExtensionSystem()
+{
+ return m_extensionSystem;
+}
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
} // namespace QtWebEngineCore
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index b25ea047b..704c5a6e4 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -43,6 +43,7 @@
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_context.h"
+#include "extensions/buildflags/buildflags.h"
#include "net/url_request/url_request_context.h"
#include "profile_io_data_qt.h"
#include <QtGlobal>
@@ -53,6 +54,10 @@ QT_END_NAMESPACE
class InMemoryPrefStore;
class PrefService;
+namespace extensions {
+class ExtensionSystemQt;
+}
+
namespace QtWebEngineCore {
class BrowsingDataRemoverDelegateQt;
@@ -67,6 +72,8 @@ public:
virtual ~ProfileQt();
+ base::FilePath GetCachePath() const;
+
// BrowserContext implementation:
base::FilePath GetPath() const override;
bool IsOffTheRecord() const override;
@@ -94,11 +101,18 @@ public:
content::BackgroundFetchDelegate *GetBackgroundFetchDelegate() override;
content::BackgroundSyncController *GetBackgroundSyncController() override;
content::BrowsingDataRemoverDelegate *GetBrowsingDataRemoverDelegate() override;
+ content::ClientHintsControllerDelegate *GetClientHintsControllerDelegate() override;
+ void SetCorsOriginAccessListForOrigin(const url::Origin &source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure) override;
+ const content::SharedCorsOriginAccessList* GetSharedCorsOriginAccessList() const override;
// Profile implementation:
PrefService *GetPrefs() override;
const PrefService *GetPrefs() const override;
net::URLRequestContextGetter *GetRequestContext() override;
+ void Initialize();
ProfileAdapter *profileAdapter() { return m_profileAdapter; }
@@ -109,6 +123,9 @@ public:
void setSpellCheckEnabled(bool enabled);
bool isSpellCheckEnabled() const;
#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::ExtensionSystemQt* GetExtensionSystem();
+#endif // defined(ENABLE_EXTENSIONS)
private:
friend class ContentBrowserClientQt;
@@ -118,9 +135,14 @@ private:
std::unique_ptr<PermissionManagerQt> m_permissionManager;
std::unique_ptr<SSLHostStateDelegateQt> m_sslHostStateDelegate;
std::unique_ptr<PrefService> m_prefService;
+ scoped_refptr<content::SharedCorsOriginAccessList> m_sharedCorsOriginAccessList;
std::unique_ptr<ProfileIODataQt> m_profileIOData;
ProfileAdapter *m_profileAdapter;
friend class ProfileAdapter;
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::ExtensionSystemQt *m_extensionSystem;
+#endif //ENABLE_EXTENSIONS
+ friend class BrowserContextAdapter;
DISALLOW_COPY_AND_ASSIGN(ProfileQt);
};
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index 14da1e6cf..11a72a2e9 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -1,6 +1,8 @@
import("//build/config/ui.gni")
import("//media/media_options.gni")
+import("//extensions/buildflags/buildflags.gni")
import("//third_party/widevine/cdm/widevine.gni")
+import("//ui/ozone/ozone.gni")
chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("//chrome/VERSION"),
"-t", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"],
@@ -9,6 +11,7 @@ chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("/
include_dirs = [
"//skia/config",
"//third_party",
+ "//third_party/boringssl/src/include",
"//third_party/skia/include/core"
]
@@ -25,37 +28,45 @@ deps = [
"//components/web_cache/browser",
"//components/web_cache/renderer",
"//components/spellcheck:buildflags",
+ "//components/proxy_config",
"//content/public/app:browser",
- "//content/public/browser",
- "//content/public/common",
- "//content/public/renderer",
+ "//content",
"//media:media_buildflags",
"//net:net_with_v8",
"//services/proxy_resolver:lib",
"//skia",
"//third_party/blink/public:blink",
- "//third_party/mesa:mesa_headers",
"//ui/accessibility",
+ "//ui/gl",
"//qtwebengine/browser:interfaces",
+ "//qtwebengine/browser:service_manifests",
+ "//qtwebengine/common:mojo_bindings",
":qtwebengine_sources",
- ":qtwebengine_resources"
+ ":qtwebengine_resources",
]
if (enable_webrtc) {
deps += [ "//third_party/webrtc_overrides" ]
}
-if (is_linux && !is_desktop_linux) {
- deps += [ "//ui/events/ozone:events_ozone_evdev"]
+if (use_ozone) {
+ _ozone_extra_directory = get_path_info(ozone_extra_path, "dir")
+ deps += [ "$_ozone_extra_directory:qt" ]
}
-if (use_ozone) {
+if (use_xscrnsaver) {
+ deps += [ "//ui/base/x" ]
+}
+
+if (enable_extensions) {
deps += [
- "//ui/ozone/common"
+ ":qtwebengine_extensions_features"
]
}
-data_deps = [ "//qtwebengine/browser:service_manifests" ]
+assert_no_deps = [
+ "//ui/views/mus",
+]
defines = [
"CHROMIUM_VERSION=\"" + chromium_version[0] + "\""
diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni
index 6e8c3c6eb..4df1760da 100644
--- a/src/core/qtwebengine_resources.gni
+++ b/src/core/qtwebengine_resources.gni
@@ -1,10 +1,14 @@
import("//tools/grit/repack.gni")
import("//build/config/locales.gni")
import("//chrome/chrome_repack_locales.gni")
+import("//extensions/buildflags/buildflags.gni")
group("qtwebengine_resources") {
deps = [
"//chrome/app:generated_resources",
+ "//chrome/browser:resources",
+ "//chrome/browser/resources:component_extension_resources",
+ "//chrome/common:resources",
"//components/resources:components_resources",
":qtwebengine_repack_resources",
":qtwebengine_repack_resources_100",
@@ -17,6 +21,8 @@ group("qtwebengine_resources") {
repack("qtwebengine_repack_resources") {
sources = [
"$root_gen_dir/qtwebengine/qt_webengine_resources.pak",
+ "$root_gen_dir/chrome/browser_resources.pak",
+ "$root_gen_dir/chrome/common_resources.pak",
"$root_gen_dir/chrome/quota_internals_resources.pak",
"$root_gen_dir/chrome/task_scheduler_internals_resources.pak",
"$root_gen_dir/components/components_resources.pak",
@@ -31,6 +37,8 @@ repack("qtwebengine_repack_resources") {
"//qtwebengine/browser:qt_webengine_resources",
"//chrome/browser/resources:quota_internals_resources",
"//chrome/browser/resources:task_scheduler_internals_resources",
+ "//chrome/browser:resources_grit",
+ "//chrome/common:resources_grit",
"//components/resources:components_resources_grit",
"//content:resources_grit",
"//mojo/public/js:resources",
@@ -38,6 +46,20 @@ repack("qtwebengine_repack_resources") {
"//third_party/blink/public:resources_grit",
"//ui/resources:webui_resources_grd_grit",
]
+
+ if (enable_extensions) {
+ sources += [
+ "$root_gen_dir/chrome/component_extension_resources.pak",
+ "$root_gen_dir/extensions/extensions_renderer_resources.pak",
+ "$root_gen_dir/extensions/extensions_resources.pak",
+ ]
+ deps += [
+ "//chrome/browser/resources:component_extension_resources_grit",
+ "//extensions:extensions_renderer_resources_grit",
+ "//extensions:extensions_resources_grd_grit",
+ ]
+ }
+
}
repack("qtwebengine_repack_resources_100") {
@@ -56,6 +78,14 @@ repack("qtwebengine_repack_resources_100") {
"//third_party/blink/public:scaled_resources_100_percent",
"//ui/resources:ui_resources_grd_grit"
]
+ if (enable_extensions) {
+ sources += [
+ "$root_gen_dir/extensions/extensions_browser_resources_100_percent.pak"
+ ]
+ deps += [
+ "//extensions:extensions_browser_resources_grit"
+ ]
+ }
}
repack("qtwebengine_repack_resources_200") {
@@ -74,6 +104,14 @@ repack("qtwebengine_repack_resources_200") {
"//third_party/blink/public:scaled_resources_200_percent",
"//ui/resources:ui_resources_grd_grit"
]
+ if (enable_extensions) {
+ sources += [
+ "$root_gen_dir/extensions/extensions_browser_resources_200_percent.pak"
+ ]
+ deps += [
+ "//extensions:extensions_browser_resources_grit"
+ ]
+ }
}
repack("qtwebengine_repack_resources_devtools") {
@@ -82,7 +120,7 @@ repack("qtwebengine_repack_resources_devtools") {
]
output = "$root_out_dir/qtwebengine_devtools_resources.pak"
deps = [
- "//content/browser/devtools:devtools_resources_grit"
+ "//content/browser/devtools:devtools_resources_grit",
]
}
diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni
index b1361e727..58df7096b 100644
--- a/src/core/qtwebengine_sources.gni
+++ b/src/core/qtwebengine_sources.gni
@@ -1,9 +1,11 @@
import("//build/config/features.gni")
import("//build/config/ui.gni")
+import("//chrome/common/features.gni")
import("//components/spellcheck/spellcheck_build_features.gni")
import("//pdf/features.gni")
import("//ppapi/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni")
+import("//extensions/buildflags/buildflags.gni")
source_set("qtwebengine_spellcheck_sources") {
include_dirs = core_include_dirs
@@ -40,22 +42,22 @@ source_set("qtwebengine_sources") {
"//skia:skia_config",
"//third_party/boringssl:external_config",
]
+
deps = [
"//chrome/common:buildflags",
"//components/nacl/common:buildflags",
"//extensions/buildflags:buildflags",
"//third_party/blink/public/mojom:mojom_platform",
]
+
sources = [
- "//chrome/common/custom_handlers/protocol_handler.cc",
- "//chrome/common/custom_handlers/protocol_handler.h",
+ "//chrome/browser/accessibility/accessibility_ui.cc",
+ "//chrome/browser/accessibility/accessibility_ui.h",
"//chrome/browser/custom_handlers/protocol_handler_registry.cc",
"//chrome/browser/custom_handlers/protocol_handler_registry.h",
"//chrome/browser/custom_handlers/protocol_handler_registry_factory.cc",
"//chrome/browser/custom_handlers/protocol_handler_registry_factory.h",
"//chrome/browser/media/webrtc/desktop_media_list.h",
- "//chrome/browser/media/webrtc/desktop_streams_registry.cc",
- "//chrome/browser/media/webrtc/desktop_streams_registry.h",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
"//chrome/browser/profiles/profile.cc",
@@ -72,6 +74,8 @@ source_set("qtwebengine_sources") {
"//chrome/browser/ui/webui/quota_internals/quota_internals_ui.h",
"//chrome/browser/ui/webui/task_scheduler_internals/task_scheduler_internals_ui.cc",
"//chrome/browser/ui/webui/task_scheduler_internals/task_scheduler_internals_ui.h",
+ "//chrome/common/custom_handlers/protocol_handler.cc",
+ "//chrome/common/custom_handlers/protocol_handler.h",
"//chrome/common/chrome_switches.cc",
"//chrome/common/chrome_switches.h",
"//chrome/common/pref_names.cc",
@@ -80,12 +84,47 @@ source_set("qtwebengine_sources") {
"//chrome/common/url_constants.h",
"//chrome/common/webui_url_constants.cc",
"//chrome/common/webui_url_constants.h",
- "//extensions/common/constants.cc",
- "//extensions/common/constants.h",
- "//extensions/common/url_pattern.cc",
- "//extensions/common/url_pattern.h",
+ "//components/prefs/in_memory_pref_store.cc",
+ "//components/prefs/in_memory_pref_store.h",
]
+ if (enable_extensions) {
+ deps += [
+ ":qtwebengine_extensions_features",
+ "//chrome/browser/resources:component_extension_resources_grit",
+ "//chrome/common/extensions/api",
+ "//chrome/common/extensions/api:extensions_features",
+ "//components/crx_file",
+ "//components/crx_file:crx_creator",
+ "//components/spellcheck:buildflags",
+ "//extensions/buildflags:buildflags",
+ "//extensions/common",
+ "//extensions/common/api",
+ "//extensions/common:core_api_provider",
+ "//extensions/browser",
+ "//extensions/browser/api",
+ "//extensions/browser:core_api_provider",
+ "//extensions/renderer",
+ "//extensions:extensions_resources",
+ "//extensions/strings",
+ ]
+ sources += [
+ "//chrome/common/extensions/permissions/chrome_api_permissions.cc",
+ "//chrome/common/extensions/permissions/chrome_api_permissions.h",
+ "//chrome/common/extensions/permissions/chrome_permission_message_provider.cc",
+ "//chrome/common/extensions/permissions/chrome_permission_message_provider.h",
+ "//chrome/common/extensions/permissions/chrome_permission_message_rules.cc",
+ "//chrome/common/extensions/permissions/chrome_permission_message_rules.h",
+ ]
+ } else {
+ sources += [
+ "//extensions/common/constants.cc",
+ "//extensions/common/constants.h",
+ "//extensions/common/url_pattern.cc",
+ "//extensions/common/url_pattern.h",
+ ]
+ }
+
if (is_linux) {
sources += [
"//chrome/browser/ui/webui/sandbox_internals_ui.cc",
@@ -109,11 +148,6 @@ source_set("qtwebengine_sources") {
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
]
-
- deps += [
- # Need to depend on //content/ppapi_plugin, which is private, thus depending on parent.
- "//content",
- ]
}
if (enable_basic_printing || enable_print_preview) {
@@ -136,6 +170,8 @@ source_set("qtwebengine_sources") {
deps += [
"//pdf",
"//pdf:buildflags",
+ "//components/pdf/browser:browser",
+ "//components/pdf/renderer:renderer",
"//components/printing/browser",
"//components/printing/renderer",
]
diff --git a/src/core/quota_permission_context_qt.cpp b/src/core/quota_permission_context_qt.cpp
index cb1467364..a502e7fc8 100644
--- a/src/core/quota_permission_context_qt.cpp
+++ b/src/core/quota_permission_context_qt.cpp
@@ -39,7 +39,9 @@
#include "quota_permission_context_qt.h"
+#include "base/task/post_task.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "quota_request_controller_impl.h"
@@ -64,10 +66,10 @@ void QuotaPermissionContextQt::RequestQuotaPermission(const StorageQuotaParams &
}
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(&QuotaPermissionContextQt::RequestQuotaPermission, this,
- params, render_process_id, callback));
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&QuotaPermissionContextQt::RequestQuotaPermission, this,
+ params, render_process_id, callback));
return;
}
@@ -95,10 +97,10 @@ void QuotaPermissionContextQt::dispatchCallbackOnIOThread(const PermissionCallba
return;
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&QuotaPermissionContextQt::dispatchCallbackOnIOThread,
- this, callback, response));
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&QuotaPermissionContextQt::dispatchCallbackOnIOThread,
+ this, callback, response));
return;
}
diff --git a/src/core/render_view_context_menu_qt.h b/src/core/render_view_context_menu_qt.h
index d8ca2775c..e1ee301fc 100644
--- a/src/core/render_view_context_menu_qt.h
+++ b/src/core/render_view_context_menu_qt.h
@@ -55,7 +55,7 @@
namespace QtWebEngineCore {
-class QWEBENGINECORE_PRIVATE_EXPORT RenderViewContextMenuQt
+class Q_WEBENGINECORE_PRIVATE_EXPORT RenderViewContextMenuQt
{
public:
enum ContextMenuItem {
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index a5aba92bc..3be0c9390 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -40,19 +40,23 @@
#include "render_widget_host_view_qt.h"
#include "browser_accessibility_manager_qt.h"
-#include "chromium_overrides.h"
#include "common/qt_messages.h"
-#include "compositor.h"
+#include "compositor/compositor.h"
#include "qtwebenginecoreglobal_p.h"
#include "render_widget_host_view_qt_delegate.h"
+#include "touch_handle_drawable_client.h"
+#include "touch_selection_controller_client_qt.h"
+#include "touch_selection_menu_controller.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
#include "web_event_factory.h"
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
-#include "content/browser/accessibility/browser_accessibility_state_impl.h"
-#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "components/viz/host/host_frame_sink_manager.h"
+#include "content/browser/compositor/surface_utils.h"
#include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/common/content_switches_internal.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
@@ -62,9 +66,11 @@
#include "third_party/blink/public/platform/web_cursor_info.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/event.h"
+#include "ui/events/gesture_detection/gesture_configuration.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
#include "ui/events/gesture_detection/motion_event.h"
-#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/touch_selection/touch_selection_controller.h"
#if defined(USE_OZONE)
#include "ui/base/clipboard/scoped_clipboard_writer.h"
@@ -83,7 +89,6 @@
#include <QFocusEvent>
#include <QGuiApplication>
#include <QInputMethodEvent>
-#include <QLoggingCategory>
#include <QTextFormat>
#include <QKeyEvent>
#include <QMouseEvent>
@@ -94,7 +99,6 @@
#include <QWheelEvent>
#include <QWindow>
#include <QtGui/private/qinputcontrol_p.h>
-#include <QtGui/qaccessible.h>
namespace QtWebEngineCore {
@@ -185,14 +189,13 @@ static inline bool isCommonTextEditShortcut(const QKeyEvent *ke)
static uint32_t s_eventId = 0;
class MotionEventQt : public ui::MotionEvent {
public:
- MotionEventQt(const QList<QTouchEvent::TouchPoint> &touchPoints, const base::TimeTicks &eventTime, Action action, const Qt::KeyboardModifiers modifiers, float dpiScale, int index = -1)
+ MotionEventQt(const QList<QTouchEvent::TouchPoint> &touchPoints, const base::TimeTicks &eventTime, Action action, const Qt::KeyboardModifiers modifiers, int index = -1)
: touchPoints(touchPoints)
, eventTime(eventTime)
, action(action)
, eventId(++s_eventId)
, flags(flagsFromModifiers(modifiers))
, index(index)
- , dpiScale(dpiScale)
{
// ACTION_DOWN and ACTION_UP must be accesssed through pointer_index 0
Q_ASSERT((action != Action::DOWN && action != Action::UP) || index == 0);
@@ -203,8 +206,8 @@ public:
int GetActionIndex() const override { return index; }
size_t GetPointerCount() const override { return touchPoints.size(); }
int GetPointerId(size_t pointer_index) const override { return touchPoints.at(pointer_index).id(); }
- float GetX(size_t pointer_index) const override { return touchPoints.at(pointer_index).pos().x() / dpiScale; }
- float GetY(size_t pointer_index) const override { return touchPoints.at(pointer_index).pos().y() / dpiScale; }
+ float GetX(size_t pointer_index) const override { return touchPoints.at(pointer_index).pos().x(); }
+ float GetY(size_t pointer_index) const override { return touchPoints.at(pointer_index).pos().y(); }
float GetRawX(size_t pointer_index) const override { return touchPoints.at(pointer_index).screenPos().x(); }
float GetRawY(size_t pointer_index) const override { return touchPoints.at(pointer_index).screenPos().y(); }
float GetTouchMajor(size_t pointer_index) const override
@@ -225,6 +228,8 @@ public:
float GetPressure(size_t pointer_index) const override { return touchPoints.at(pointer_index).pressure(); }
float GetTiltX(size_t pointer_index) const override { return 0; }
float GetTiltY(size_t pointer_index) const override { return 0; }
+ float GetTwist(size_t) const override { return 0; }
+ float GetTangentialPressure(size_t) const override { return 0; }
base::TimeTicks GetEventTime() const override { return eventTime; }
size_t GetHistorySize() const override { return 0; }
@@ -232,7 +237,10 @@ public:
float GetHistoricalTouchMajor(size_t pointer_index, size_t historical_index) const override { return 0; }
float GetHistoricalX(size_t pointer_index, size_t historical_index) const override { return 0; }
float GetHistoricalY(size_t pointer_index, size_t historical_index) const override { return 0; }
- ToolType GetToolType(size_t pointer_index) const override { return ui::MotionEvent::ToolType::FINGER; }
+ ToolType GetToolType(size_t pointer_index) const override {
+ return (touchPoints.at(pointer_index).flags() & QTouchEvent::TouchPoint::InfoFlag::Pen) ? ui::MotionEvent::ToolType::STYLUS
+ : ui::MotionEvent::ToolType::FINGER;
+ }
int GetButtonState() const override { return 0; }
private:
@@ -242,20 +250,22 @@ private:
const uint32_t eventId;
int flags;
int index;
- float dpiScale;
};
-bool isAccessibilityEnabled() {
- // On Linux accessibility is disabled by default due to performance issues,
- // and can be re-enabled by setting the QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
- // variable. For details, see QTBUG-59922.
-#ifdef Q_OS_LINUX
- static bool accessibility_enabled
- = qEnvironmentVariableIsSet("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY");
-#else
- const bool accessibility_enabled = true;
-#endif
- return accessibility_enabled;
+static content::ScreenInfo screenInfoFromQScreen(QScreen *screen)
+{
+ content::ScreenInfo r;
+ if (screen) {
+ r.device_scale_factor = screen->devicePixelRatio();
+ r.depth_per_component = 8;
+ r.depth = screen->depth();
+ r.is_monochrome = (r.depth == 1);
+ r.rect = toGfx(screen->geometry());
+ r.available_rect = toGfx(screen->availableGeometry());
+ } else {
+ r.device_scale_factor = qGuiApp->devicePixelRatio();
+ }
+ return r;
}
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget)
@@ -263,7 +273,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
, m_touchMotionStarted(false)
- , m_compositor(new Compositor(this))
+ , m_compositor(new Compositor(widget))
, m_loadVisuallyCommittedState(NotCommitted)
, m_adapterClient(0)
, m_imeInProgress(false)
@@ -274,20 +284,10 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
, m_cursorPosition(0)
, m_emptyPreviousSelection(true)
, m_wheelAckPending(false)
- , m_pendingResize(false)
, m_mouseWheelPhaseHandler(this)
- // This frame-sink id is based on what RenderWidgetHostViewChildFrame does:
- , m_frameSinkId(base::checked_cast<uint32_t>(widget->GetProcess()->GetID()),
- base::checked_cast<uint32_t>(widget->GetRoutingID()))
+ , m_frameSinkId(host()->GetFrameSinkId())
{
host()->SetView(this);
-#ifndef QT_NO_ACCESSIBILITY
- if (isAccessibilityEnabled()) {
- QAccessible::installActivationObserver(this);
- if (QAccessible::isActive())
- content::BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility();
- }
-#endif // QT_NO_ACCESSIBILITY
if (GetTextInputManager())
GetTextInputManager()->AddObserver(this);
@@ -295,27 +295,32 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
const QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
m_imeHasHiddenTextCapability = context && context->hasCapability(QPlatformInputContext::HiddenTextCapability);
- m_localSurfaceId = m_localSurfaceIdAllocator.GenerateId();
-
if (host()->delegate() && host()->delegate()->GetInputEventRouter())
host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this);
+
+ m_touchSelectionControllerClient.reset(new TouchSelectionControllerClientQt(this));
+ ui::TouchSelectionController::Config config;
+ config.max_tap_duration = base::TimeDelta::FromMilliseconds(ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
+ config.tap_slop = ui::GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click();
+ config.enable_longpress_drag_selection = false;
+ m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config));
}
RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
{
QObject::disconnect(m_adapterClientDestroyedConnection);
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::removeActivationObserver(this);
-#endif // QT_NO_ACCESSIBILITY
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
+
+ m_touchSelectionController.reset();
+ m_touchSelectionControllerClient.reset();
}
void RenderWidgetHostViewQt::setDelegate(RenderWidgetHostViewQtDelegate* delegate)
{
m_delegate.reset(delegate);
- m_compositor->setViewDelegate(delegate);
+ visualPropertiesChanged();
}
void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterClient)
@@ -342,30 +347,16 @@ void RenderWidgetHostViewQt::InitAsFullscreen(content::RenderWidgetHostView*)
{
}
-void RenderWidgetHostViewQt::SetSize(const gfx::Size& size)
+void RenderWidgetHostViewQt::SetSize(const gfx::Size &sizeInDips)
{
- int width = size.width();
- int height = size.height();
-
- m_delegate->resize(width,height);
+ m_delegate->resize(sizeInDips.width(), sizeInDips.height());
}
-void RenderWidgetHostViewQt::SetBounds(const gfx::Rect& screenRect)
+void RenderWidgetHostViewQt::SetBounds(const gfx::Rect &windowRectInDips)
{
- // This is called when webkit has sent us a Move message.
- if (IsPopup())
- m_delegate->move(toQt(screenRect.origin()));
- SetSize(screenRect.size());
-}
-
-gfx::Size RenderWidgetHostViewQt::GetCompositorViewportPixelSize() const
-{
- if (!m_delegate || !m_delegate->window() || !m_delegate->window()->screen())
- return gfx::Size();
-
- const QScreen* screen = m_delegate->window()->screen();
- gfx::SizeF size = toGfx(m_delegate->screenRect().size());
- return gfx::ToCeiledSize(gfx::ScaleSize(size, screen->devicePixelRatio()));
+ DCHECK(IsPopup());
+ m_delegate->move(toQt(windowRectInDips.origin()));
+ m_delegate->resize(windowRectInDips.width(), windowRectInDips.height());
}
gfx::NativeView RenderWidgetHostViewQt::GetNativeView() const
@@ -444,11 +435,7 @@ bool RenderWidgetHostViewQt::IsShowing()
// Retrieve the bounds of the View, in screen coordinates.
gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const
{
- QRectF p = m_delegate->contentsRect();
- float s = dpiScale();
- gfx::Point p1(floor(p.x() / s), floor(p.y() / s));
- gfx::Point p2(ceil(p.right() /s), ceil(p.bottom() / s));
- return gfx::BoundingRect(p1, p2);
+ return m_viewRectInDips;
}
void RenderWidgetHostViewQt::UpdateBackgroundColor()
@@ -603,15 +590,13 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
}
#if defined(USE_AURA)
if (auraType != ui::CursorType::kNull) {
- QWindow *window = m_delegate->window();
- qreal windowDpr = window ? window->devicePixelRatio() : 1.0f;
int resourceId;
gfx::Point hotspot;
// GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels.
- qreal hotspotDpr = windowDpr <= 1.0f ? 1.0f : 2.0f;
+ qreal hotspotDpr = m_screenInfo.device_scale_factor <= 1.0f ? 1.0f : 2.0f;
if (ui::GetCursorDataFor(ui::CursorSize::kNormal, auraType, hotspotDpr, &resourceId, &hotspot)) {
if (const gfx::ImageSkia *imageSkia = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resourceId)) {
- QImage imageQt = toQImage(imageSkia->GetRepresentation(windowDpr));
+ QImage imageQt = toQImage(imageSkia->GetRepresentation(m_screenInfo.device_scale_factor));
// Convert hotspot coordinates into device-independent pixels.
qreal hotX = hotspot.x() / hotspotDpr;
@@ -693,12 +678,9 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo
if (frame_token)
OnFrameTokenChangedForView(frame_token);
- // Support experimental.viewport.devicePixelRatio, see GetScreenInfo implementation below.
- float dpiScale = this->dpiScale();
- if (dpiScale != 0 && dpiScale != 1)
- frame.metadata.device_scale_factor /= dpiScale;
-
- m_compositor->submitFrame(std::move(frame));
+ m_compositor->submitFrame(
+ std::move(frame),
+ base::BindOnce(&RenderWidgetHostViewQtDelegate::update, base::Unretained(m_delegate.get())));
if (m_loadVisuallyCommittedState == NotCommitted) {
m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
@@ -711,31 +693,16 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo
m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset));
if (contentsSizeChanged)
m_adapterClient->updateContentsSize(toQt(m_lastContentsSize));
-
- if (m_pendingResize && host()) {
- if (host()->SynchronizeVisualProperties())
- m_pendingResize = false;
- }
}
void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo *results) const
{
- QWindow *window = m_delegate->window();
- if (!window)
- return;
- GetScreenInfoFromNativeWindow(window, results);
-
- // Support experimental.viewport.devicePixelRatio
- results->device_scale_factor *= dpiScale();
+ *results = m_screenInfo;
}
gfx::Rect RenderWidgetHostViewQt::GetBoundsInRootWindow()
{
- if (!m_delegate->window())
- return gfx::Rect();
-
- QRect r = m_delegate->window()->frameGeometry();
- return gfx::Rect(r.x(), r.y(), r.width(), r.height());
+ return m_windowRectInDips;
}
void RenderWidgetHostViewQt::ClearCompositorFrame()
@@ -756,9 +723,12 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
}
ui::TextInputType type = getTextInputType();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
m_delegate->setInputMethodHints(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu);
-
- m_surroundingText = QString::fromStdString(state->value);
+#else
+ m_delegate->setInputMethodHints(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText);
+#endif
+ m_surroundingText = toQt(state->value);
// Remove IME composition text from the surrounding text
if (state->composition_start != -1 && state->composition_end != -1)
m_surroundingText.remove(state->composition_start, state->composition_end - state->composition_start);
@@ -904,7 +874,33 @@ void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture)
return;
}
- host()->ForwardGestureEvent(ui::CreateWebGestureEventFromGestureEventData(gesture));
+ blink::WebGestureEvent event = ui::CreateWebGestureEventFromGestureEventData(gesture);
+
+ if (m_touchSelectionController && m_touchSelectionControllerClient) {
+ switch (event.GetType()) {
+ case blink::WebInputEvent::kGestureLongPress:
+ m_touchSelectionController->HandleLongPressEvent(event.TimeStamp(), event.PositionInWidget());
+ break;
+ case blink::WebInputEvent::kGestureTap:
+ m_touchSelectionController->HandleTapEvent(event.PositionInWidget(), event.data.tap.tap_count);
+ break;
+ case blink::WebInputEvent::kGestureScrollBegin:
+ m_touchSelectionControllerClient->onScrollBegin();
+ break;
+ case blink::WebInputEvent::kGestureScrollEnd:
+ m_touchSelectionControllerClient->onScrollEnd();
+ break;
+ default:
+ break;
+ }
+ }
+
+ host()->ForwardGestureEvent(event);
+}
+
+void RenderWidgetHostViewQt::DidStopFlinging()
+{
+ m_touchSelectionControllerClient->DidStopFlinging();
}
viz::ScopedSurfaceIdAllocator RenderWidgetHostViewQt::DidUpdateVisualProperties(const cc::RenderFrameMetadata &metadata)
@@ -917,27 +913,12 @@ viz::ScopedSurfaceIdAllocator RenderWidgetHostViewQt::DidUpdateVisualProperties(
void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata)
{
- if (metadata.local_surface_id)
- m_localSurfaceIdAllocator.UpdateFromChild(*metadata.local_surface_id);
-
- m_localSurfaceId = m_localSurfaceIdAllocator.GenerateId();
- host()->SendScreenRects();
- if (m_pendingResize) {
- if (host()->SynchronizeVisualProperties())
- m_pendingResize = false;
- }
+ synchronizeVisualProperties(metadata.local_surface_id_allocation);
}
QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
{
- return m_compositor->updatePaintNode(oldNode);
-}
-
-void RenderWidgetHostViewQt::notifyResize()
-{
- m_pendingResize = true;
- if (host()->SynchronizeVisualProperties())
- m_pendingResize = false;
+ return m_compositor->updatePaintNode(oldNode, m_delegate.get());
}
void RenderWidgetHostViewQt::notifyShown()
@@ -950,17 +931,26 @@ void RenderWidgetHostViewQt::notifyHidden()
host()->WasHidden();
}
-void RenderWidgetHostViewQt::windowBoundsChanged()
+void RenderWidgetHostViewQt::visualPropertiesChanged()
{
- host()->SendScreenRects();
- if (m_delegate && m_delegate->window())
- host()->NotifyScreenInfoChanged();
-}
+ if (!m_delegate)
+ return;
-void RenderWidgetHostViewQt::windowChanged()
-{
- if (m_delegate && m_delegate->window())
- host()->NotifyScreenInfoChanged();
+ gfx::Rect oldViewRect = m_viewRectInDips;
+ m_viewRectInDips = toGfx(m_delegate->viewGeometry().toAlignedRect());
+
+ gfx::Rect oldWindowRect = m_windowRectInDips;
+ m_windowRectInDips = toGfx(m_delegate->windowGeometry());
+
+ QWindow *window = m_delegate->window();
+ content::ScreenInfo oldScreenInfo = m_screenInfo;
+ m_screenInfo = screenInfoFromQScreen(window ? window->screen() : nullptr);
+
+ if (m_viewRectInDips != oldViewRect || m_windowRectInDips != oldWindowRect)
+ host()->SendScreenRects();
+
+ if (m_viewRectInDips.size() != oldViewRect.size() || m_screenInfo != oldScreenInfo)
+ synchronizeVisualProperties(base::nullopt);
}
bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
@@ -1114,7 +1104,11 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query)
// TODO: Implement this
return QVariant(); // No limit.
case Qt::ImHints:
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
return int(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu);
+#else
+ return int(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText);
+#endif
default:
return QVariant();
}
@@ -1166,14 +1160,9 @@ QList<QTouchEvent::TouchPoint> RenderWidgetHostViewQt::mapTouchPointIds(const QL
return outputPoints;
}
-float RenderWidgetHostViewQt::dpiScale() const
-{
- return m_adapterClient ? m_adapterClient->dpiScale() : 1.0;
-}
-
bool RenderWidgetHostViewQt::IsPopup() const
{
- return popup_type_ != blink::kWebPopupTypeNone;
+ return widget_type_ == content::WidgetType::kPopup;
}
void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event)
@@ -1315,9 +1304,9 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
}
if (hasSelection) {
- content::RenderFrameHostImpl *frameHost = static_cast<content::RenderFrameHostImpl *>(getFocusedFrameHost());
- if (frameHost)
- frameHost->GetFrameInputHandler()->SetEditableSelectionOffsets(selectionRange.start(), selectionRange.end());
+ content::mojom::FrameInputHandler *frameInputHandler = getFrameInputHandler();
+ if (frameInputHandler)
+ frameInputHandler->SetEditableSelectionOffsets(selectionRange.start(), selectionRange.end());
}
int replacementLength = ev->replacementLength();
@@ -1394,21 +1383,11 @@ void RenderWidgetHostViewQt::handleInputMethodQueryEvent(QInputMethodQueryEvent
ev->accept();
}
-#ifndef QT_NO_ACCESSIBILITY
-void RenderWidgetHostViewQt::accessibilityActiveChanged(bool active)
-{
- if (active)
- content::BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility();
- else
- content::BrowserAccessibilityStateImpl::GetInstance()->DisableAccessibility();
-}
-#endif // QT_NO_ACCESSIBILITY
-
void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *ev)
{
if (!m_wheelAckPending) {
Q_ASSERT(m_pendingWheelEvents.isEmpty());
- blink::WebMouseWheelEvent webEvent = WebEventFactory::toWebWheelEvent(ev, dpiScale());
+ blink::WebMouseWheelEvent webEvent = WebEventFactory::toWebWheelEvent(ev);
m_wheelAckPending = (webEvent.phase != blink::WebMouseWheelEvent::kPhaseEnded);
m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, false);
host()->ForwardWheelEvent(webEvent);
@@ -1416,10 +1395,10 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *ev)
}
if (!m_pendingWheelEvents.isEmpty()) {
// Try to combine with this wheel event with the last pending one.
- if (WebEventFactory::coalesceWebWheelEvent(m_pendingWheelEvents.last(), ev, dpiScale()))
+ if (WebEventFactory::coalesceWebWheelEvent(m_pendingWheelEvents.last(), ev))
return;
}
- m_pendingWheelEvents.append(WebEventFactory::toWebWheelEvent(ev, dpiScale()));
+ m_pendingWheelEvents.append(WebEventFactory::toWebWheelEvent(ev));
}
void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &event, content::InputEventAckState /*ack_result*/)
@@ -1454,16 +1433,11 @@ void RenderWidgetHostViewQt::handleGestureEvent(QNativeGestureEvent *ev)
const Qt::NativeGestureType type = ev->gestureType();
// These are the only supported gestures by Chromium so far.
if (type == Qt::ZoomNativeGesture || type == Qt::SmartZoomNativeGesture) {
- host()->ForwardGestureEvent(WebEventFactory::toWebGestureEvent(
- ev,
- static_cast<double>(dpiScale())));
+ host()->ForwardGestureEvent(WebEventFactory::toWebGestureEvent(ev));
}
}
#endif
-Q_DECLARE_LOGGING_CATEGORY(QWEBENGINE_TOUCH_HANDLING);
-Q_LOGGING_CATEGORY(QWEBENGINE_TOUCH_HANDLING, "qt.webengine.touch");
-
void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
{
// On macOS instead of handling touch events, we use the OS provided QNativeGestureEvents.
@@ -1471,7 +1445,7 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
if (ev->spontaneous()) {
return;
} else {
- qCWarning(QWEBENGINE_TOUCH_HANDLING)
+ VLOG(1)
<< "Sending simulated touch events to Chromium does not work properly on macOS. "
"Consider using QNativeGestureEvents or QMouseEvents.";
}
@@ -1488,11 +1462,35 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
eventTimestamp += m_eventsToNowDelta;
QList<QTouchEvent::TouchPoint> touchPoints = mapTouchPointIds(ev->touchPoints());
+ {
+ ui::MotionEvent::Action action;
+ switch (touchPoints[0].state()) {
+ case Qt::TouchPointPressed:
+ action = ui::MotionEvent::Action::DOWN;
+ break;
+ case Qt::TouchPointMoved:
+ action = ui::MotionEvent::Action::MOVE;
+ break;
+ case Qt::TouchPointReleased:
+ action = ui::MotionEvent::Action::UP;
+ break;
+ default:
+ action = ui::MotionEvent::Action::NONE;
+ break;
+ }
+
+ MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), 0);
+ if (m_touchSelectionController->WillHandleTouchEvent(motionEvent)) {
+ ev->accept();
+ return;
+ }
+ }
switch (ev->type()) {
case QEvent::TouchBegin:
m_sendMotionActionDown = true;
m_touchMotionStarted = true;
+ m_touchSelectionControllerClient->onTouchDown();
break;
case QEvent::TouchUpdate:
m_touchMotionStarted = true;
@@ -1512,13 +1510,13 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
if (touchPoints.isEmpty())
touchPoints = m_previousTouchPoints;
clearPreviousTouchMotionState();
- MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::Action::CANCEL,
- ev->modifiers(), dpiScale());
+ MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::Action::CANCEL, ev->modifiers());
processMotionEvent(cancelEvent);
return;
}
case QEvent::TouchEnd:
clearPreviousTouchMotionState();
+ m_touchSelectionControllerClient->onTouchUp();
break;
default:
break;
@@ -1565,8 +1563,7 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
continue;
}
- MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), dpiScale(),
- i);
+ MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), i);
processMotionEvent(motionEvent);
}
}
@@ -1583,7 +1580,7 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event)
{
// Currently WebMouseEvent is a subclass of WebPointerProperties, so basically
// tablet events are mouse events with extra properties.
- blink::WebMouseEvent webEvent = WebEventFactory::toWebMouseEvent(event, dpiScale());
+ blink::WebMouseEvent webEvent = WebEventFactory::toWebMouseEvent(event);
if ((webEvent.GetType() == blink::WebInputEvent::kMouseDown || webEvent.GetType() == blink::WebInputEvent::kMouseUp)
&& webEvent.button == blink::WebMouseEvent::Button::kNoButton) {
// Blink can only handle the 3 main mouse-buttons and may assert when processing mouse-down for no button.
@@ -1629,7 +1626,7 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event)
void RenderWidgetHostViewQt::handleHoverEvent(QHoverEvent *ev)
{
- host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(ev, dpiScale()));
+ host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(ev));
}
void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
@@ -1656,11 +1653,6 @@ void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames)
m_compositor->setNeedsBeginFrames(needs_begin_frames);
}
-void RenderWidgetHostViewQt::OnBeginFrame(base::TimeTicks frame_time)
-{
- host()->ProgressFlingIfNeeded(frame_time);
-}
-
content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost()
{
content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(host());
@@ -1674,6 +1666,15 @@ content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost()
return focusedFrame->current_frame_host();
}
+content::mojom::FrameInputHandler *RenderWidgetHostViewQt::getFrameInputHandler()
+{
+ content::RenderFrameHostImpl *frameHost = static_cast<content::RenderFrameHostImpl *>(getFocusedFrameHost());
+ if (!frameHost)
+ return nullptr;
+
+ return frameHost->GetFrameInputHandler();
+}
+
ui::TextInputType RenderWidgetHostViewQt::getTextInputType() const
{
if (text_input_manager_ && text_input_manager_->GetTextInputState())
@@ -1696,9 +1697,9 @@ const viz::FrameSinkId &RenderWidgetHostViewQt::GetFrameSinkId() const
return m_frameSinkId;
}
-const viz::LocalSurfaceId &RenderWidgetHostViewQt::GetLocalSurfaceId() const
+const viz::LocalSurfaceIdAllocation &RenderWidgetHostViewQt::GetLocalSurfaceIdAllocation() const
{
- return m_localSurfaceId;
+ return m_localSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation();
}
void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostView *view)
@@ -1710,16 +1711,40 @@ void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostVi
SetBackgroundColor(*color);
}
-void RenderWidgetHostViewQt::EnsureSurfaceSynchronizedForLayoutTest()
+void RenderWidgetHostViewQt::EnsureSurfaceSynchronizedForWebTest()
{
- ++m_latestCaptureSequenceNumber;
- if (host())
- host()->SynchronizeVisualProperties();
+ NOTIMPLEMENTED();
}
uint32_t RenderWidgetHostViewQt::GetCaptureSequenceNumber() const
{
- return m_latestCaptureSequenceNumber;
+ return 0;
+}
+
+void RenderWidgetHostViewQt::ResetFallbackToFirstNavigationSurface()
+{
+}
+
+void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation()
+{
+ content::RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation();
+
+ const cc::RenderFrameMetadata &metadata = host()->render_frame_metadata_provider()->LastRenderFrameMetadata();
+ if (metadata.selection.start != m_selectionStart || metadata.selection.end != m_selectionEnd) {
+ m_selectionStart = metadata.selection.start;
+ m_selectionEnd = metadata.selection.end;
+ m_touchSelectionControllerClient->UpdateClientSelectionBounds(m_selectionStart, m_selectionEnd);
+ }
+}
+
+void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceIdAllocation> &childSurfaceId)
+{
+ if (childSurfaceId)
+ m_localSurfaceIdAllocator.UpdateFromChild(*childSurfaceId);
+ else
+ m_localSurfaceIdAllocator.GenerateId();
+
+ host()->SynchronizeVisualProperties();
}
} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index a12ffe636..6e9ddabb9 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -46,18 +46,17 @@
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
+#include "components/viz/host/host_frame_sink_client.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
-#include "content/common/view_messages.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
#include "qtwebenginecoreglobal_p.h"
#include <QMap>
#include <QPoint>
#include <QtGlobal>
-#include <QtGui/qaccessible.h>
#include <QtGui/QTouchEvent>
QT_BEGIN_NAMESPACE
@@ -67,11 +66,21 @@ QT_END_NAMESPACE
namespace content {
class RenderFrameHost;
class RenderWidgetHostImpl;
+namespace mojom {
+class FrameInputHandler;
+}
+}
+
+namespace ui {
+class TouchSelectionController;
}
namespace QtWebEngineCore {
class Compositor;
+class TouchHandleDrawableClient;
+class TouchSelectionControllerClientQt;
+class TouchSelectionMenuController;
struct MultipleMouseClickHelper
{
@@ -94,9 +103,6 @@ class RenderWidgetHostViewQt
, public ui::GestureProviderClient
, public RenderWidgetHostViewQtDelegateClient
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
-#ifndef QT_NO_ACCESSIBILITY
- , public QAccessible::ActivationObserver
-#endif // QT_NO_ACCESSIBILITY
, public content::TextInputManager::Observer
{
public:
@@ -111,15 +117,14 @@ public:
RenderWidgetHostViewQtDelegate *delegate() { return m_delegate.get(); }
void setDelegate(RenderWidgetHostViewQtDelegate *delegate);
+ WebContentsAdapterClient *adapterClient() { return m_adapterClient; }
void setAdapterClient(WebContentsAdapterClient *adapterClient);
- void OnBeginFrame(base::TimeTicks frame_time);
void InitAsChild(gfx::NativeView) override;
void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&) override;
void InitAsFullscreen(content::RenderWidgetHostView*) override;
void SetSize(const gfx::Size& size) override;
void SetBounds(const gfx::Rect&) override;
- gfx::Size GetCompositorViewportPixelSize() const override;
gfx::NativeView GetNativeView() const override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
void Focus() override;
@@ -159,21 +164,21 @@ public:
void SetWantsAnimateOnlyBeginFrames() override;
viz::SurfaceId GetCurrentSurfaceId() const override;
const viz::FrameSinkId &GetFrameSinkId() const override;
- const viz::LocalSurfaceId &GetLocalSurfaceId() const override;
+ const viz::LocalSurfaceIdAllocation &GetLocalSurfaceIdAllocation() const override;
void TakeFallbackContentFrom(content::RenderWidgetHostView *view) override;
- void EnsureSurfaceSynchronizedForLayoutTest() override;
+ void EnsureSurfaceSynchronizedForWebTest() override;
uint32_t GetCaptureSequenceNumber() const override;
+ void ResetFallbackToFirstNavigationSurface() override;
+ void DidStopFlinging() override;
// Overridden from ui::GestureProviderClient.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
// Overridden from RenderWidgetHostViewQtDelegateClient.
QSGNode *updatePaintNode(QSGNode *) override;
- void notifyResize() override;
void notifyShown() override;
void notifyHidden() override;
- void windowBoundsChanged() override;
- void windowChanged() override;
+ void visualPropertiesChanged() override;
bool forwardEvent(QEvent *) override;
QVariant inputMethodQuery(Qt::InputMethodQuery query) override;
void closePopup() override;
@@ -209,27 +214,37 @@ public:
// Overridden from content::BrowserAccessibilityDelegate
content::BrowserAccessibilityManager* CreateBrowserAccessibilityManager(content::BrowserAccessibilityDelegate* delegate, bool for_root_frame) override;
-#ifndef QT_NO_ACCESSIBILITY
- void accessibilityActiveChanged(bool active) override;
-#endif // QT_NO_ACCESSIBILITY
LoadVisuallyCommittedState getLoadVisuallyCommittedState() const { return m_loadVisuallyCommittedState; }
void setLoadVisuallyCommittedState(LoadVisuallyCommittedState state) { m_loadVisuallyCommittedState = state; }
+ // Overridden from content::RenderFrameMetadataProvider::Observer
+ void OnRenderFrameMetadataChangedAfterActivation() override;
+
gfx::SizeF lastContentsSize() const { return m_lastContentsSize; }
gfx::Vector2dF lastScrollOffset() const { return m_lastScrollOffset; }
+ ui::TouchSelectionController *getTouchSelectionController() const { return m_touchSelectionController.get(); }
+ TouchSelectionControllerClientQt *getTouchSelectionControllerClient() const { return m_touchSelectionControllerClient.get(); }
+ content::mojom::FrameInputHandler *getFrameInputHandler();
+ ui::TextInputType getTextInputType() const;
+
private:
void processMotionEvent(const ui::MotionEvent &motionEvent);
void clearPreviousTouchMotionState();
QList<QTouchEvent::TouchPoint> mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints);
- float dpiScale() const;
- void updateNeedsBeginFramesInternal();
bool IsPopup() const;
void selectionChanged();
content::RenderFrameHost *getFocusedFrameHost();
- ui::TextInputType getTextInputType() const;
+
+ void synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceIdAllocation> &childSurfaceId);
+
+ // Geometry of the view in screen DIPs.
+ gfx::Rect m_viewRectInDips;
+ // Geometry of the window, including frame, in screen DIPs.
+ gfx::Rect m_windowRectInDips;
+ content::ScreenInfo m_screenInfo;
ui::FilteredGestureProvider m_gestureProvider;
base::TimeDelta m_eventsToNowDelta;
@@ -252,7 +267,6 @@ private:
gfx::Vector2dF m_lastScrollOffset;
gfx::SizeF m_lastContentsSize;
- viz::LocalSurfaceId m_localSurfaceId;
viz::ParentLocalSurfaceIdAllocator m_localSurfaceIdAllocator;
uint m_imState;
@@ -265,13 +279,16 @@ private:
bool m_imeHasHiddenTextCapability;
bool m_wheelAckPending;
- bool m_pendingResize;
QList<blink::WebMouseWheelEvent> m_pendingWheelEvents;
content::MouseWheelPhaseHandler m_mouseWheelPhaseHandler;
viz::FrameSinkId m_frameSinkId;
- uint32_t m_latestCaptureSequenceNumber = 0u;
std::string m_editCommand;
+
+ std::unique_ptr<TouchSelectionControllerClientQt> m_touchSelectionControllerClient;
+ std::unique_ptr<ui::TouchSelectionController> m_touchSelectionController;
+ gfx::SelectionBound m_selectionStart;
+ gfx::SelectionBound m_selectionEnd;
};
} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 5ce595502..6066284d9 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -74,26 +74,24 @@ namespace QtWebEngineCore {
class WebContentsAdapterClient;
-class QWEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegateClient {
+class Q_WEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegateClient {
public:
virtual ~RenderWidgetHostViewQtDelegateClient() { }
virtual QSGNode *updatePaintNode(QSGNode *) = 0;
- virtual void notifyResize() = 0;
virtual void notifyShown() = 0;
virtual void notifyHidden() = 0;
- virtual void windowBoundsChanged() = 0;
- virtual void windowChanged() = 0;
+ virtual void visualPropertiesChanged() = 0;
virtual bool forwardEvent(QEvent *) = 0;
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) = 0;
virtual void closePopup() = 0;
};
-class QWEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegate {
+class Q_WEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegate {
public:
virtual ~RenderWidgetHostViewQtDelegate() { }
virtual void initAsPopup(const QRect&) = 0;
- virtual QRectF screenRect() const = 0;
- virtual QRectF contentsRect() const = 0;
+ virtual QRectF viewGeometry() const = 0;
+ virtual QRect windowGeometry() const = 0;
virtual void setKeyboardFocus() = 0;
virtual bool hasKeyboardFocus() = 0;
virtual void lockMouse() = 0;
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 403448b91..5fd4c7d65 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -40,6 +40,8 @@
#include "renderer/content_renderer_client_qt.h"
#include "common/qt_messages.h"
+#include "extensions/buildflags/buildflags.h"
+#include "printing/buildflags/buildflags.h"
#include "renderer/content_settings_observer_qt.h"
#include "base/strings/string_split.h"
#if QT_CONFIG(webengine_spellchecker)
@@ -66,7 +68,8 @@
#include "media/base/key_system_properties.h"
#include "media/media_buildflags.h"
#include "net/base/net_errors.h"
-#include "services/service_manager/public/cpp/service_context.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/web_url_error.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/web/web_security_policy.h"
@@ -81,10 +84,17 @@
#include "renderer/render_frame_observer_qt.h"
#include "renderer/render_view_observer_qt.h"
+#include "renderer/render_thread_observer_qt.h"
#include "renderer/user_resource_controller.h"
#if QT_CONFIG(webengine_webchannel)
#include "renderer/web_channel_ipc_transport.h"
#endif
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "common/extensions/extensions_client_qt.h"
+#include "extensions/extensions_renderer_client_qt.h"
+#endif //ENABLE_EXTENSIONS
+
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -95,9 +105,8 @@
#include "content/public/renderer/key_system_support.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
+#include "third_party/widevine/cdm/buildflags.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
-
-#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
#endif
namespace QtWebEngineCore {
@@ -105,7 +114,12 @@ namespace QtWebEngineCore {
static const char kHttpErrorDomain[] = "http";
ContentRendererClientQt::ContentRendererClientQt()
+ : m_serviceBinding(this)
{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::ExtensionsClient::Set(extensions::ExtensionsClientQt::GetInstance());
+ extensions::ExtensionsRendererClient::Set(ExtensionsRendererClientQt::GetInstance());
+#endif
}
ContentRendererClientQt::~ContentRendererClientQt()
@@ -116,6 +130,7 @@ void ContentRendererClientQt::RenderThreadStarted()
{
content::RenderThread *renderThread = content::RenderThread::Get();
(void)GetConnector();
+ m_renderThreadObserver.reset(new RenderThreadObserverQt());
m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave);
m_webCacheImpl.reset(new web_cache::WebCacheImpl());
@@ -127,6 +142,7 @@ void ContentRendererClientQt::RenderThreadStarted()
content::ChildThread::Get()->GetServiceManagerConnection()->AddConnectionFilter(
std::make_unique<content::SimpleConnectionFilter>(std::move(registry)));
+ renderThread->AddObserver(m_renderThreadObserver.data());
renderThread->AddObserver(UserResourceController::instance());
#if QT_CONFIG(webengine_spellchecker)
@@ -137,7 +153,18 @@ void ContentRendererClientQt::RenderThreadStarted()
// Allow XMLHttpRequests from qrc to file.
blink::WebURL qrc(blink::KURL("qrc:"));
blink::WebString file(blink::WebString::FromASCII("file"));
- blink::WebSecurityPolicy::AddOriginAccessWhitelistEntry(qrc, file, blink::WebString(), true);
+ blink::WebSecurityPolicy::AddOriginAccessAllowListEntry(qrc, file, blink::WebString(), true,
+ network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ // Allow the pdf viewer extension to access chrome resources
+ blink::WebURL pdfViewerExtension(blink::KURL("chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai"));
+ blink::WebString chromeResources(blink::WebString::FromASCII("chrome"));
+ blink::WebSecurityPolicy::AddOriginAccessAllowListEntry(pdfViewerExtension, chromeResources, blink::WebString(), true,
+ network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority);
+
+ ExtensionsRendererClientQt::GetInstance()->RenderThreadStarted();
+#endif
}
void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view)
@@ -149,11 +176,12 @@ void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view
void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame)
{
- new QtWebEngineCore::RenderFrameObserverQt(render_frame);
+ QtWebEngineCore::RenderFrameObserverQt *render_frame_observer = new QtWebEngineCore::RenderFrameObserverQt(render_frame);
#if QT_CONFIG(webengine_webchannel)
if (render_frame->IsMainFrame())
new WebChannelIPCTransport(render_frame);
#endif
+
UserResourceController::instance()->renderFrameCreated(render_frame);
new QtWebEngineCore::ContentSettingsObserverQt(render_frame);
@@ -166,17 +194,41 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_fr
render_frame,
base::WrapUnique(new PrintWebViewHelperDelegateQt()));
#endif // QT_CONFIG(webengine_printing_and_pdf)
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ auto registry = std::make_unique<service_manager::BinderRegistry>();
+ ExtensionsRendererClientQt::GetInstance()->RenderFrameCreated(render_frame, render_frame_observer->registry());
+#endif
+}
+
+void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame *render_frame)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ExtensionsRendererClientQt::GetInstance()->RunScriptsAtDocumentStart(render_frame);
+ // |render_frame| might be dead by now.
+#endif
}
-void ContentRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame* render_frame)
+void ContentRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame *render_frame)
{
// Check whether the render_frame has been created and has not been detached yet.
// Otherwise the WebFrame is not available.
RenderFrameObserverQt *render_frame_observer = RenderFrameObserverQt::Get(render_frame);
- if (!render_frame_observer || render_frame_observer->isFrameDetached())
- return; // The frame is invisible to scripts.
- UserResourceController::instance()->RunScriptsAtDocumentEnd(render_frame);
+ if (render_frame_observer && !render_frame_observer->isFrameDetached())
+ UserResourceController::instance()->RunScriptsAtDocumentEnd(render_frame);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ExtensionsRendererClientQt::GetInstance()->RunScriptsAtDocumentEnd(render_frame);
+ // |render_frame| might be dead by now.
+#endif
+}
+
+void ContentRendererClientQt::RunScriptsAtDocumentIdle(content::RenderFrame *render_frame)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ExtensionsRendererClientQt::GetInstance()->RunScriptsAtDocumentIdle(render_frame);
+ // |render_frame| might be dead by now.
+#endif
}
bool ContentRendererClientQt::HasErrorPage(int httpStatusCode)
@@ -195,28 +247,35 @@ bool ContentRendererClientQt::ShouldSuppressErrorPage(content::RenderFrame *fram
}
// To tap into the chromium localized strings. Ripped from the chrome layer (highly simplified).
-void ContentRendererClientQt::PrepareErrorPage(content::RenderFrame* renderFrame, const blink::WebURLRequest &failedRequest,
+void ContentRendererClientQt::PrepareErrorPage(content::RenderFrame *renderFrame,
const blink::WebURLError &web_error,
- std::string *errorHtml, base::string16 *errorDescription)
+ const std::string &httpMethod,
+ bool ignoring_cache,
+ std::string *errorHtml)
{
- GetNavigationErrorStringsInternal(renderFrame, failedRequest,
+ Q_UNUSED(ignoring_cache);
+ GetNavigationErrorStringsInternal(renderFrame, httpMethod,
error_page::Error::NetError(web_error.url(), web_error.reason(), web_error.has_copy_in_cache()),
- errorHtml, errorDescription);
+ errorHtml);
}
-void ContentRendererClientQt::PrepareErrorPageForHttpStatusError(content::RenderFrame* renderFrame, const blink::WebURLRequest& failedRequest,
- const GURL& unreachable_url, int http_status,
- std::string* errorHtml, base::string16* errorDescription)
+void ContentRendererClientQt::PrepareErrorPageForHttpStatusError(content::RenderFrame *renderFrame,
+ const GURL &unreachable_url,
+ const std::string &httpMethod,
+ bool ignoring_cache,
+ int http_status,
+ std::string *errorHtml)
{
- GetNavigationErrorStringsInternal(renderFrame, failedRequest,
+ Q_UNUSED(ignoring_cache);
+ GetNavigationErrorStringsInternal(renderFrame, httpMethod,
error_page::Error::HttpError(unreachable_url, http_status),
- errorHtml, errorDescription);
+ errorHtml);
}
-void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderFrame *renderFrame, const blink::WebURLRequest &failedRequest, const error_page::Error &error, std::string *errorHtml, base::string16 *errorDescription)
+void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderFrame *renderFrame, const std::string &httpMethod, const error_page::Error &error, std::string *errorHtml)
{
Q_UNUSED(renderFrame)
- const bool isPost = QByteArray::fromStdString(failedRequest.HttpMethod().Utf8()) == QByteArrayLiteral("POST");
+ const bool isPost = QByteArray::fromStdString(httpMethod) == QByteArrayLiteral("POST");
if (errorHtml) {
// Use a local error page.
@@ -229,8 +288,9 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
error_page::LocalizedError::GetStrings(
error.reason(), error.domain(), error.url(), isPost,
- error.stale_copy_in_cache(), false, false,
- locale, std::unique_ptr<error_page::ErrorPageParams>(), &errorStrings);
+ error.stale_copy_in_cache(), false, RenderThreadObserverQt::is_incognito_process(),
+ error_page::LocalizedError::OfflineContentOnNetErrorFeatureState::kDisabled,
+ false, locale, std::unique_ptr<error_page::ErrorPageParams>(), &errorStrings);
resourceId = IDR_NET_ERROR_HTML;
const base::StringPiece template_html(ui::ResourceBundle::GetSharedInstance().GetRawDataResource(resourceId));
@@ -239,9 +299,6 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
else // "t" is the id of the templates root node.
*errorHtml = webui::GetTemplatesHtml(template_html, &errorStrings, "t");
}
-
- if (errorDescription)
- *errorDescription = error_page::LocalizedError::GetErrorDetails(error.domain(), error.reason(), isPost);
}
unsigned long long ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length)
@@ -259,9 +316,27 @@ blink::WebPrescientNetworking *ContentRendererClientQt::GetPrescientNetworking()
return m_prescientNetworkingDispatcher.get();
}
-void ContentRendererClientQt::OnStart()
+bool ContentRendererClientQt::OverrideCreatePlugin(
+ content::RenderFrame* render_frame,
+ const blink::WebPluginParams& params, blink::WebPlugin** plugin)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (!ExtensionsRendererClientQt::GetInstance()->OverrideCreatePlugin(render_frame, params))
+ return false;
+#endif //ENABLE_EXTENSIONS
+ return content::ContentRendererClient::OverrideCreatePlugin(render_frame, params, plugin);
+}
+
+content::BrowserPluginDelegate* ContentRendererClientQt::CreateBrowserPluginDelegate(content::RenderFrame *render_frame,
+ const content::WebPluginInfo &info,
+ const std::string &mime_type,
+ const GURL &original_url)
{
- context()->connector()->BindConnectorRequest(std::move(m_connectorRequest));
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ return ExtensionsRendererClientQt::GetInstance()->CreateBrowserPluginDelegate(render_frame, info, mime_type, original_url);
+#else
+ return nullptr;
+#endif
}
void ContentRendererClientQt::OnBindInterface(const service_manager::BindSourceInfo &remote_info,
@@ -274,11 +349,9 @@ void ContentRendererClientQt::OnBindInterface(const service_manager::BindSourceI
void ContentRendererClientQt::GetInterface(const std::string &interface_name, mojo::ScopedMessagePipeHandle interface_pipe)
{
- if (!m_connector)
- return;
- m_connector->BindInterface(service_manager::Identity("qtwebengine"),
- interface_name,
- std::move(interface_pipe));
+ m_serviceBinding.GetConnector()->BindInterface(
+ service_manager::ServiceFilter::ByName("qtwebengine"),
+ interface_name, std::move(interface_pipe));
}
// The following is based on chrome/renderer/media/chrome_key_systems.cc:
@@ -373,7 +446,7 @@ static void AddExternalClearKey(std::vector<std::unique_ptr<media::KeySystemProp
kExternalClearKeyCdmProxyTestKeySystem));
}
-#if defined(WIDEVINE_CDM_AVAILABLE)
+#if BUILDFLAG(ENABLE_WIDEVINE)
static media::SupportedCodecs GetSupportedCodecs(const std::vector<media::VideoCodec> &supported_video_codecs, bool is_secure)
{
media::SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
@@ -385,11 +458,11 @@ static media::SupportedCodecs GetSupportedCodecs(const std::vector<media::VideoC
// TODO(sandersd): Distinguish these from those that are directly supported,
// as those may offer a higher level of protection.
if (!supported_video_codecs.empty() || !is_secure) {
- supported_codecs |= media::EME_CODEC_WEBM_OPUS;
- supported_codecs |= media::EME_CODEC_WEBM_VORBIS;
- supported_codecs |= media::EME_CODEC_MP4_FLAC;
+ supported_codecs |= media::EME_CODEC_OPUS;
+ supported_codecs |= media::EME_CODEC_VORBIS;
+ supported_codecs |= media::EME_CODEC_FLAC;
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
- supported_codecs |= media::EME_CODEC_MP4_AAC;
+ supported_codecs |= media::EME_CODEC_AAC;
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
}
@@ -397,15 +470,15 @@ static media::SupportedCodecs GetSupportedCodecs(const std::vector<media::VideoC
for (const auto &codec : supported_video_codecs) {
switch (codec) {
case media::VideoCodec::kCodecVP8:
- supported_codecs |= media::EME_CODEC_WEBM_VP8;
+ supported_codecs |= media::EME_CODEC_VP8;
break;
case media::VideoCodec::kCodecVP9:
- supported_codecs |= media::EME_CODEC_WEBM_VP9;
- supported_codecs |= media::EME_CODEC_COMMON_VP9;
+ supported_codecs |= media::EME_CODEC_VP9_PROFILE0;
+ supported_codecs |= media::EME_CODEC_VP9_PROFILE2;
break;
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
case media::VideoCodec::kCodecH264:
- supported_codecs |= media::EME_CODEC_MP4_AVC1;
+ supported_codecs |= media::EME_CODEC_AVC1;
break;
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
default:
@@ -464,7 +537,7 @@ static void AddWidevine(std::vector<std::unique_ptr<media::KeySystemProperties>>
persistent_license_support, persistent_usage_record_support,
persistent_state_support, distinctive_identifier_support));
}
-#endif // defined(WIDEVINE_CDM_AVAILABLE)
+#endif // BUILDFLAG(ENABLE_WIDEVINE)
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
void ContentRendererClientQt::AddSupportedKeySystems(std::vector<std::unique_ptr<media::KeySystemProperties>> *key_systems)
@@ -473,9 +546,9 @@ void ContentRendererClientQt::AddSupportedKeySystems(std::vector<std::unique_ptr
if (base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting))
AddExternalClearKey(key_systems);
-#if defined(WIDEVINE_CDM_AVAILABLE)
+#if BUILDFLAG(ENABLE_WIDEVINE)
AddWidevine(key_systems);
-#endif // defined(WIDEVINE_CDM_AVAILABLE)
+#endif // BUILDFLAG(ENABLE_WIDEVINE)
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
}
@@ -487,18 +560,30 @@ void ContentRendererClientQt::InitSpellCheck()
}
#endif
+void ContentRendererClientQt::WillSendRequest(blink::WebLocalFrame *frame,
+ ui::PageTransition transition_type,
+ const blink::WebURL &url,
+ const url::Origin *initiator_origin,
+ GURL *new_url,
+ bool *attach_same_site_cookies)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ExtensionsRendererClientQt::GetInstance()->WillSendRequest(frame, transition_type, url, initiator_origin, new_url, attach_same_site_cookies);
+ if (!new_url->is_empty())
+ return;
+#endif
+ content::ContentRendererClient::WillSendRequest(frame, transition_type, url, initiator_origin, new_url, attach_same_site_cookies);
+}
+
void ContentRendererClientQt::CreateRendererService(service_manager::mojom::ServiceRequest service_request)
{
- m_serviceContext = std::make_unique<service_manager::ServiceContext>(
- std::make_unique<service_manager::ForwardingService>(this),
- std::move(service_request));
+ DCHECK(!m_serviceBinding.is_bound());
+ m_serviceBinding.Bind(std::move(service_request));
}
service_manager::Connector* ContentRendererClientQt::GetConnector()
{
- if (!m_connector)
- m_connector = service_manager::Connector::Create(&m_connectorRequest);
- return m_connector.get();
+ return m_serviceBinding.GetConnector();
}
} // namespace
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index 2a353caa6..dd164fa3a 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -46,6 +46,7 @@
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/local_interface_provider.h"
#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_binding.h"
#include <QScopedPointer>
@@ -71,6 +72,8 @@ class SpellCheck;
namespace QtWebEngineCore {
+class RenderThreadObserverQt;
+
class ContentRendererClientQt : public content::ContentRendererClient
, public service_manager::Service
, public service_manager::LocalInterfaceProvider
@@ -85,18 +88,38 @@ public:
void RenderFrameCreated(content::RenderFrame* render_frame) override;
bool ShouldSuppressErrorPage(content::RenderFrame *, const GURL &) override;
bool HasErrorPage(int http_status_code) override;
- void PrepareErrorPage(content::RenderFrame* renderFrame, const blink::WebURLRequest& failedRequest,
- const blink::WebURLError& error, std::string* errorHtml, base::string16* errorDescription) override;
- void PrepareErrorPageForHttpStatusError(content::RenderFrame* render_frame, const blink::WebURLRequest& failed_request,
- const GURL& unreachable_url, int http_status,
- std::string* error_html, base::string16* error_description) override;
+
+ void PrepareErrorPage(content::RenderFrame *render_frame,
+ const blink::WebURLError &error,
+ const std::string &http_method,
+ bool ignoring_cache,
+ std::string *error_html) override;
+ void PrepareErrorPageForHttpStatusError(content::RenderFrame *render_frame,
+ const GURL &unreachable_url,
+ const std::string &http_method,
+ bool ignoring_cache,
+ int http_status,
+ std::string *error_html) override;
unsigned long long VisitedLinkHash(const char *canonicalUrl, size_t length) override;
bool IsLinkVisited(unsigned long long linkHash) override;
blink::WebPrescientNetworking* GetPrescientNetworking() override;
void AddSupportedKeySystems(std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) override;
- void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override;
+ void RunScriptsAtDocumentStart(content::RenderFrame *render_frame) override;
+ void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame) override;
+ void RunScriptsAtDocumentIdle(content::RenderFrame *render_frame) override;
+ bool OverrideCreatePlugin(content::RenderFrame* render_frame,
+ const blink::WebPluginParams& params, blink::WebPlugin** plugin) override;
+ content::BrowserPluginDelegate* CreateBrowserPluginDelegate(content::RenderFrame* render_frame,
+ const content::WebPluginInfo& info, const std::string& mime_type, const GURL& original_url) override;
+
+ void WillSendRequest(blink::WebLocalFrame *frame,
+ ui::PageTransition transition_type,
+ const blink::WebURL &url,
+ const url::Origin *initiator_origin,
+ GURL *new_url,
+ bool *attach_same_site_cookies) override;
void CreateRendererService(service_manager::mojom::ServiceRequest service_request) override;
@@ -107,7 +130,6 @@ private:
service_manager::Connector *GetConnector();
// service_manager::Service:
- void OnStart() override;
void OnBindInterface(const service_manager::BindSourceInfo &remote_info,
const std::string &name,
mojo::ScopedMessagePipeHandle handle) override;
@@ -115,18 +137,18 @@ private:
// service_manager::LocalInterfaceProvider:
void GetInterface(const std::string& name, mojo::ScopedMessagePipeHandle request_handle) override;
- void GetNavigationErrorStringsInternal(content::RenderFrame* renderFrame, const blink::WebURLRequest& failedRequest,
- const error_page::Error& error, std::string* errorHtml, base::string16* errorDescription);
+ void GetNavigationErrorStringsInternal(content::RenderFrame* renderFrame, const std::string &httpMethod,
+ const error_page::Error& error, std::string* errorHtml);
+ QScopedPointer<RenderThreadObserverQt> m_renderThreadObserver;
QScopedPointer<visitedlink::VisitedLinkSlave> m_visitedLinkSlave;
QScopedPointer<web_cache::WebCacheImpl> m_webCacheImpl;
#if QT_CONFIG(webengine_spellchecker)
QScopedPointer<SpellCheck> m_spellCheck;
#endif
- std::unique_ptr<service_manager::Connector> m_connector;
service_manager::mojom::ConnectorRequest m_connectorRequest;
- std::unique_ptr<service_manager::ServiceContext> m_serviceContext;
+ service_manager::ServiceBinding m_serviceBinding;
service_manager::BinderRegistry m_registry;
std::unique_ptr<network_hints::PrescientNetworkingDispatcher> m_prescientNetworkingDispatcher;
diff --git a/src/core/renderer/content_settings_observer_qt.cpp b/src/core/renderer/content_settings_observer_qt.cpp
index 045098457..98954eb4a 100644
--- a/src/core/renderer/content_settings_observer_qt.cpp
+++ b/src/core/renderer/content_settings_observer_qt.cpp
@@ -93,8 +93,8 @@ bool ContentSettingsObserverQt::OnMessageReceived(const IPC::Message& message)
return handled;
}
-void ContentSettingsObserverQt::DidCommitProvisionalLoad(bool /*is_new_navigation*/,
- bool is_same_document_navigation)
+void ContentSettingsObserverQt::DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition /*transition*/)
{
blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
if (frame->Parent())
@@ -151,8 +151,7 @@ void ContentSettingsObserverQt::RequestFileSystemAccessAsync(const WebContentSet
url::Origin(frame->Top()->GetSecurityOrigin()).GetURL()));
}
-bool ContentSettingsObserverQt::AllowIndexedDB(const WebString &name,
- const WebSecurityOrigin &/*origin*/)
+bool ContentSettingsObserverQt::AllowIndexedDB(const WebSecurityOrigin &origin)
{
blink::WebFrame *frame = render_frame()->GetWebFrame();
if (IsUniqueFrame(frame))
@@ -160,8 +159,8 @@ bool ContentSettingsObserverQt::AllowIndexedDB(const WebString &name,
bool result = false;
Send(new QtWebEngineHostMsg_AllowIndexedDB(
- routing_id(), url::Origin(frame->GetSecurityOrigin()).GetURL(),
- url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(), name.Utf16(),
+ routing_id(), url::Origin(origin).GetURL(),
+ url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(),
&result));
return result;
}
diff --git a/src/core/renderer/content_settings_observer_qt.h b/src/core/renderer/content_settings_observer_qt.h
index 981655f20..69b0eda9e 100644
--- a/src/core/renderer/content_settings_observer_qt.h
+++ b/src/core/renderer/content_settings_observer_qt.h
@@ -72,16 +72,15 @@ public:
const blink::WebString &display_name,
unsigned estimated_size) override;
void RequestFileSystemAccessAsync(const blink::WebContentSettingCallbacks &callbacks) override;
- bool AllowIndexedDB(const blink::WebString &name,
- const blink::WebSecurityOrigin &origin) override;
+ bool AllowIndexedDB(const blink::WebSecurityOrigin &origin) override;
bool AllowStorage(bool local) override;
private:
// RenderFrameObserver implementation:
bool OnMessageReceived(const IPC::Message &message) override;
- void DidCommitProvisionalLoad(bool is_new_navigation,
- bool is_same_document_navigation) override;
+ void DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) override;
void OnDestruct() override;
// Message handlers.
diff --git a/src/core/chromium_overrides.h b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
index b27bf309c..418429330 100644
--- a/src/core/chromium_overrides.h
+++ b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,18 +37,16 @@
**
****************************************************************************/
-#ifndef CHROMIUM_OVERRIDES_H
-#define CHROMIUM_OVERRIDES_H
+#include "extensions_dispatcher_delegate_qt.h"
-#include "content/public/common/screen_info.h"
-#include <QtGlobal>
+namespace QtWebEngineCore {
-QT_BEGIN_NAMESPACE
-class QWindow;
-QT_END_NAMESPACE
+ExtensionsDispatcherDelegateQt::ExtensionsDispatcherDelegateQt()
+{
+}
-namespace QtWebEngineCore {
-void GetScreenInfoFromNativeWindow(QWindow* window, content::ScreenInfo* results);
+ExtensionsDispatcherDelegateQt::~ExtensionsDispatcherDelegateQt()
+{
}
-#endif
+} //namespace QtWebEngineCore
diff --git a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
new file mode 100644
index 000000000..25aa18e71
--- /dev/null
+++ b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EXTENSIONSDISPATCHERDELEGATEQT_H
+#define EXTENSIONSDISPATCHERDELEGATEQT_H
+
+#include "base/macros.h"
+#include "extensions/renderer/dispatcher_delegate.h"
+
+namespace QtWebEngineCore {
+
+class ExtensionsDispatcherDelegateQt : public extensions::DispatcherDelegate
+{
+public:
+ ExtensionsDispatcherDelegateQt();
+ ~ExtensionsDispatcherDelegateQt() override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ExtensionsDispatcherDelegateQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // EXTENSIONSDISPATCHERDELEGATEQT_H
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
new file mode 100644
index 000000000..c25494590
--- /dev/null
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// based on chrome/renderer/extensions/chrome_extensions_renderer_client.cc:
+// Copyright (c) 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 "extensions_renderer_client_qt.h"
+
+#include "extensions_dispatcher_delegate_qt.h"
+#include "renderer/render_thread_observer_qt.h"
+#include "renderer_permissions_policy_delegate_qt.h"
+#include "resource_request_policy_qt.h"
+
+#include "base/command_line.h"
+#include "base/lazy_instance.h"
+#include "content/public/common/content_constants.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_thread.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/switches.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_frame_helper.h"
+#include "extensions/renderer/extensions_render_frame_observer.h"
+#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
+#include "extensions/renderer/guest_view/extensions_guest_view_container_dispatcher.h"
+#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
+#include "extensions/renderer/renderer_extension_registry.h"
+#include "extensions/renderer/script_context.h"
+#include "third_party/blink/public/platform/web_url.h"
+#include "third_party/blink/public/web/web_plugin_params.h"
+
+namespace chrome {
+const char kExtensionInvalidRequestURL[] = "chrome-extension://invalid/";
+const char kExtensionResourceInvalidRequestURL[] = "chrome-extension-resource://invalid/";
+}
+
+namespace QtWebEngineCore {
+
+ExtensionsRendererClientQt::ExtensionsRendererClientQt()
+{
+}
+
+ExtensionsRendererClientQt::~ExtensionsRendererClientQt()
+{
+}
+
+// Returns true if the current render process was launched incognito.
+bool ExtensionsRendererClientQt::IsIncognitoProcess() const
+{
+ return RenderThreadObserverQt::is_incognito_process();
+}
+
+// Returns the lowest isolated world ID available to extensions.
+// Must be greater than 0. See blink::WebFrame::executeScriptInIsolatedWorld
+// (third_party/WebKit/public/web/WebFrame.h) for additional context.
+int ExtensionsRendererClientQt::GetLowestIsolatedWorldId() const
+{
+ return 257;
+}
+
+// static
+ExtensionsRendererClientQt *ExtensionsRendererClientQt::GetInstance()
+{
+ static base::LazyInstance<ExtensionsRendererClientQt>::Leaky client =
+ LAZY_INSTANCE_INITIALIZER;
+ return client.Pointer();
+}
+
+extensions::Dispatcher *ExtensionsRendererClientQt::GetDispatcher()
+{
+ return extension_dispatcher_.get();
+}
+
+void ExtensionsRendererClientQt::OnExtensionLoaded(const extensions::Extension &extension)
+{
+ resource_request_policy_->OnExtensionLoaded(extension);
+}
+
+void ExtensionsRendererClientQt::OnExtensionUnloaded(const extensions::ExtensionId &extension_id)
+{
+ resource_request_policy_->OnExtensionUnloaded(extension_id);
+}
+
+void ExtensionsRendererClientQt::RenderThreadStarted()
+{
+ content::RenderThread *thread = content::RenderThread::Get();
+ // ChromeRenderViewTest::SetUp() creates its own ExtensionDispatcher and
+ // injects it using SetExtensionDispatcher(). Don't overwrite it.
+ if (!extension_dispatcher_)
+ extension_dispatcher_.reset(new extensions::Dispatcher(std::make_unique<ExtensionsDispatcherDelegateQt>()));
+ extension_dispatcher_->OnRenderThreadStarted(thread);
+ permissions_policy_delegate_.reset(new RendererPermissionsPolicyDelegateQt(extension_dispatcher_.get()));
+ resource_request_policy_.reset(new extensions::ResourceRequestPolicyQt(extension_dispatcher_.get()));
+ guest_view_container_dispatcher_.reset(new extensions::ExtensionsGuestViewContainerDispatcher());
+
+ thread->AddObserver(extension_dispatcher_.get());
+ thread->AddObserver(guest_view_container_dispatcher_.get());
+}
+
+void ExtensionsRendererClientQt::RenderFrameCreated(content::RenderFrame *render_frame,
+ service_manager::BinderRegistry *registry)
+{
+ new extensions::ExtensionsRenderFrameObserver(render_frame, registry);
+ new extensions::ExtensionFrameHelper(render_frame,
+ extension_dispatcher_.get());
+ extension_dispatcher_->OnRenderFrameCreated(render_frame);
+}
+
+bool ExtensionsRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_frame,
+ const blink::WebPluginParams &params)
+{
+ if (params.mime_type.Utf8() != content::kBrowserPluginMimeType)
+ return true;
+ bool guest_view_api_available = false;
+ return !guest_view_api_available;
+}
+
+void ExtensionsRendererClientQt::WillSendRequest(blink::WebLocalFrame *frame,
+ ui::PageTransition transition_type,
+ const blink::WebURL &url,
+ const url::Origin *initiator_origin,
+ GURL *new_url,
+ bool *attach_same_site_cookies)
+{
+ if (url.ProtocolIs(extensions::kExtensionScheme) &&
+ !resource_request_policy_->CanRequestResource(url, frame, transition_type)) {
+ *new_url = GURL(chrome::kExtensionInvalidRequestURL);
+ }
+}
+
+bool ExtensionsRendererClientQt::ShouldFork(blink::WebLocalFrame *frame,
+ const GURL &url,
+ bool is_initial_navigation,
+ bool is_server_redirect,
+ bool *send_referrer)
+{
+ return false; // TODO: Fix this to a sensible value
+}
+
+content::BrowserPluginDelegate *ExtensionsRendererClientQt::CreateBrowserPluginDelegate(content::RenderFrame *render_frame,
+ const content::WebPluginInfo &info,
+ const std::string &mime_type,
+ const GURL &original_url)
+{
+ if (mime_type == content::kBrowserPluginMimeType)
+ return new extensions::ExtensionsGuestViewContainer(render_frame);
+ return new extensions::MimeHandlerViewContainer(render_frame, info, mime_type, original_url);
+}
+
+void ExtensionsRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame *render_frame)
+{
+ extension_dispatcher_->RunScriptsAtDocumentStart(render_frame);
+}
+
+void ExtensionsRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame *render_frame)
+{
+ extension_dispatcher_->RunScriptsAtDocumentEnd(render_frame);
+}
+
+void ExtensionsRendererClientQt::RunScriptsAtDocumentIdle(content::RenderFrame *render_frame)
+{
+ extension_dispatcher_->RunScriptsAtDocumentIdle(render_frame);
+}
+
+
+} // namespace QtWebEngineCore
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.h b/src/core/renderer/extensions/extensions_renderer_client_qt.h
new file mode 100644
index 000000000..2d45d255a
--- /dev/null
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EXTENSIONSRENDERERCLIENTQT_H
+#define EXTENSIONSRENDERERCLIENTQT_H
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "extensions/renderer/extensions_renderer_client.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
+#include "ui/base/page_transition_types.h"
+
+class GURL;
+
+namespace blink {
+class WebLocalFrame;
+struct WebPluginParams;
+class WebURL;
+}
+
+namespace content {
+class BrowserPluginDelegate;
+class RenderFrame;
+class RenderView;
+struct WebPluginInfo;
+}
+
+namespace url {
+class Origin;
+}
+
+namespace extensions {
+class Dispatcher;
+class ExtensionsGuestViewContainerDispatcher;
+class ResourceRequestPolicyQt;
+}
+
+namespace QtWebEngineCore {
+
+class ExtensionsDispatcherDelegateQt;
+class RendererPermissionsPolicyDelegateQt;
+
+class ExtensionsRendererClientQt : public extensions::ExtensionsRendererClient
+{
+public:
+ ExtensionsRendererClientQt();
+ ~ExtensionsRendererClientQt() override;
+
+ // extensions::ExtensionsRendererClient implementation.
+ bool IsIncognitoProcess() const override;
+ int GetLowestIsolatedWorldId() const override;
+ extensions::Dispatcher *GetDispatcher() override;
+ void OnExtensionLoaded(const extensions::Extension &extension) override;
+ void OnExtensionUnloaded(const extensions::ExtensionId &extension_id) override;
+
+ // Match ContentRendererClientQt's method names...
+ void RenderThreadStarted();
+ void RenderFrameCreated(content::RenderFrame *, service_manager::BinderRegistry *);
+ bool OverrideCreatePlugin(content::RenderFrame *render_frame,
+ const blink::WebPluginParams &params);
+ void WillSendRequest(blink::WebLocalFrame *frame,
+ ui::PageTransition transition_type,
+ const blink::WebURL &url,
+ const url::Origin *initiator_origin,
+ GURL *new_url,
+ bool *attach_same_site_cookies);
+
+ static bool ShouldFork(blink::WebLocalFrame *frame,
+ const GURL &url,
+ bool is_initial_navigation,
+ bool is_server_redirect,
+ bool *send_referrer);
+ static content::BrowserPluginDelegate *CreateBrowserPluginDelegate(content::RenderFrame *render_frame,
+ const content::WebPluginInfo &info,
+ const std::string &mime_type,
+ const GURL &original_url);
+
+ void RunScriptsAtDocumentStart(content::RenderFrame *render_frame);
+ void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame);
+ void RunScriptsAtDocumentIdle(content::RenderFrame *render_frame);
+
+ extensions::Dispatcher *extension_dispatcher()
+ { return extension_dispatcher_.get(); }
+
+ static ExtensionsRendererClientQt *GetInstance();
+
+private:
+ std::unique_ptr<ExtensionsDispatcherDelegateQt> extension_dispatcher_delegate_;
+ std::unique_ptr<RendererPermissionsPolicyDelegateQt> permissions_policy_delegate_;
+ std::unique_ptr<extensions::Dispatcher> extension_dispatcher_;
+ std::unique_ptr<extensions::ExtensionsGuestViewContainerDispatcher> guest_view_container_dispatcher_;
+ std::unique_ptr<extensions::ResourceRequestPolicyQt> resource_request_policy_;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // EXTENSIONSRENDERERCLIENTQT_H
diff --git a/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp
new file mode 100644
index 000000000..39412b76c
--- /dev/null
+++ b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderer_permissions_policy_delegate_qt.h"
+
+#include "extensions/common/constants.h"
+#include "extensions/common/extensions_client.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/switches.h"
+#include "extensions/renderer/dispatcher.h"
+
+namespace QtWebEngineCore {
+
+RendererPermissionsPolicyDelegateQt::RendererPermissionsPolicyDelegateQt(extensions::Dispatcher *dispatcher)
+ : m_dispatcher(dispatcher)
+{
+ extensions::PermissionsData::SetPolicyDelegate(this);
+}
+
+RendererPermissionsPolicyDelegateQt::~RendererPermissionsPolicyDelegateQt()
+{
+ extensions::PermissionsData::SetPolicyDelegate(nullptr);
+}
+
+bool RendererPermissionsPolicyDelegateQt::IsRestrictedUrl(const GURL &, std::string *)
+{
+ return false;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/qrc_protocol_handler_qt.h b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h
index f2849c1ef..e2af47657 100644
--- a/src/core/net/qrc_protocol_handler_qt.h
+++ b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,34 +37,32 @@
**
****************************************************************************/
-#ifndef QRC_PROTOCOL_HANDLER_QT_H_
-#define QRC_PROTOCOL_HANDLER_QT_H_
+#ifndef RENDERERPERMISSIONSPOLICYDELEGATEQT_H
+#define RENDERERPERMISSIONSPOLICYDELEGATEQT_H
-#include "net/url_request/url_request_job_factory.h"
+#include "base/macros.h"
+#include "extensions/common/permissions/permissions_data.h"
-namespace net {
-
-class NetworkDelegate;
-class URLRequestJob;
-
-} // namespace
+namespace extensions {
+class Dispatcher;
+}
namespace QtWebEngineCore {
-extern const char kQrcSchemeQt[];
-
-// Implements a ProtocolHandler for qrc file jobs. If |network_delegate_| is NULL,
-// then all file requests will fail with ERR_ACCESS_DENIED.
-class QrcProtocolHandlerQt : public net::URLRequestJobFactory::ProtocolHandler {
-
+class RendererPermissionsPolicyDelegateQt : public extensions::PermissionsData::PolicyDelegate
+{
public:
- QrcProtocolHandlerQt();
- net::URLRequestJob *MaybeCreateJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate) const override;
+ explicit RendererPermissionsPolicyDelegateQt(extensions::Dispatcher *dispatcher);
+ ~RendererPermissionsPolicyDelegateQt() override;
+
+ bool IsRestrictedUrl(const GURL &, std::string *) override;
private:
- DISALLOW_COPY_AND_ASSIGN(QrcProtocolHandlerQt);
+ extensions::Dispatcher *m_dispatcher;
+
+ DISALLOW_COPY_AND_ASSIGN(RendererPermissionsPolicyDelegateQt);
};
} // namespace QtWebEngineCore
-#endif // QRC_PROTOCOL_HANDLER_QT_H_
+#endif // RENDERERPERMISSIONSPOLICYDELEGATEQT_H
diff --git a/src/core/renderer/extensions/resource_request_policy_qt.cpp b/src/core/renderer/extensions/resource_request_policy_qt.cpp
new file mode 100644
index 000000000..a64b1fef8
--- /dev/null
+++ b/src/core/renderer/extensions/resource_request_policy_qt.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// based on chrome/renderer/extensions/resource_request_policy.cc:
+// 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 "resource_request_policy_qt.h"
+
+#include "base/strings/stringprintf.h"
+#include "chrome/common/url_constants.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
+#include "extensions/common/manifest_handlers/webview_info.h"
+#include "extensions/renderer/dispatcher.h"
+#include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h"
+#include "third_party/blink/public/web/web_console_message.h"
+#include "third_party/blink/public/web/web_document.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+
+namespace extensions {
+ResourceRequestPolicyQt::ResourceRequestPolicyQt(Dispatcher *dispatcher)
+ : m_dispatcher(dispatcher)
+{
+}
+
+void ResourceRequestPolicyQt::OnExtensionLoaded(const Extension &extension)
+{
+ if (WebAccessibleResourcesInfo::HasWebAccessibleResources(&extension)
+ || WebviewInfo::HasWebviewAccessibleResources(extension, m_dispatcher->webview_partition_id())
+// // Hosted app icons are accessible.
+// // TODO(devlin): Should we incorporate this into
+// // WebAccessibleResourcesInfo?
+// || (extension.is_hosted_app() && !IconsInfo::GetIcons(&extension).empty())
+ ) {
+ m_web_accessible_ids.insert(extension.id());
+ }
+}
+
+void ResourceRequestPolicyQt::OnExtensionUnloaded(const ExtensionId &extension_id)
+{
+ m_web_accessible_ids.erase(extension_id);
+}
+
+// Returns true if the chrome-extension:// |resource_url| can be requested
+// from |frame_url|. In some cases this decision is made based upon how
+// this request was generated. Web triggered transitions are more restrictive
+// than those triggered through UI.
+bool ResourceRequestPolicyQt::CanRequestResource(const GURL &resource_url,
+ blink::WebLocalFrame *frame,
+ ui::PageTransition transition_type)
+{
+ CHECK(resource_url.SchemeIs(kExtensionScheme));
+
+ GURL frame_url = frame->GetDocument().Url();
+
+ // The page_origin may be GURL("null") for unique origins like data URLs,
+ // but this is ok for the checks below. We only care if it matches the
+ // current extension or has a devtools scheme.
+ GURL page_origin = url::Origin(frame->Top()->GetSecurityOrigin()).GetURL();
+
+ GURL extension_origin = resource_url.GetOrigin();
+
+ // We always allow loads in the following cases, regardless of web accessible
+ // resources:
+
+ // Empty urls (needed for some edge cases when we have empty urls).
+ if (frame_url.is_empty())
+ return true;
+
+ // Extensions requesting their own resources (frame_url check is for images,
+ // page_url check is for iframes).
+ // TODO(devlin): We should be checking the ancestor chain, not just the
+ // top-level frame. Additionally, we should be checking the security origin
+ // of the frame, to account for about:blank subframes being scripted by an
+ // extension parent (though we'll still need the frame origin check for
+ // sandboxed frames).
+ if (frame_url.GetOrigin() == extension_origin || page_origin == extension_origin)
+ return true;
+
+ if (!ui::PageTransitionIsWebTriggerable(transition_type))
+ return true;
+
+ // Unreachable web page error page (to allow showing the icon of the
+ // unreachable app on this page).
+ if (frame_url == content::kUnreachableWebDataURL)
+ return true;
+
+ bool is_dev_tools = page_origin.SchemeIs(content::kChromeDevToolsScheme);
+ // Note: we check |web_accessible_ids_| (rather than first looking up the
+ // extension in the registry and checking that) to be more resistant against
+ // timing attacks. This way, determining access for an extension that isn't
+ // installed takes the same amount of time as determining access for an
+ // extension with no web accessible resources. We aren't worried about any
+ // extensions with web accessible resources, since those are inherently
+ // identifiable.
+ if (!is_dev_tools && !m_web_accessible_ids.count(extension_origin.host()))
+ return false;
+
+ const Extension* extension = RendererExtensionRegistry::Get()->GetExtensionOrAppByURL(resource_url);
+ if (is_dev_tools) {
+ // Allow the load in the case of a non-existent extension. We'll just get a
+ // 404 from the browser process.
+ // TODO(devlin): Can this happen? Does devtools potentially make requests
+ // to non-existent extensions?
+ if (!extension)
+ return true;
+// // Devtools (chrome-extension:// URLs are loaded into frames of devtools to
+// // support the devtools extension APIs).
+// if (!chrome_manifest_urls::GetDevToolsPage(extension).is_empty())
+// return true;
+ }
+
+ DCHECK(extension);
+
+ // Disallow loading of packaged resources for hosted apps. We don't allow
+ // hybrid hosted/packaged apps. The one exception is access to icons, since
+ // some extensions want to be able to do things like create their own
+ // launchers.
+ base::StringPiece resource_root_relative_path =
+ resource_url.path_piece().empty() ? base::StringPiece()
+ : resource_url.path_piece().substr(1);
+ if (extension->is_hosted_app() /*&& !IconsInfo::GetIcons(extension).ContainsPath(resource_root_relative_path)*/) {
+ LOG(ERROR) << "Denying load of " << resource_url.spec() << " from "
+ << "hosted app.";
+ return false;
+ }
+
+ // Disallow loading of extension resources which are not explicitly listed
+ // as web or WebView accessible if the manifest version is 2 or greater.
+ if (!WebAccessibleResourcesInfo::IsResourceWebAccessible(extension, resource_url.path()) &&
+ !WebviewInfo::IsResourceWebviewAccessible(extension, m_dispatcher->webview_partition_id(), resource_url.path()))
+ {
+ std::string message = base::StringPrintf(
+ "Denying load of %s. Resources must be listed in the "
+ "web_accessible_resources manifest key in order to be loaded by "
+ "pages outside the extension.",
+ resource_url.spec().c_str());
+ frame->AddMessageToConsole(blink::WebConsoleMessage(blink::mojom::ConsoleMessageLevel::kError, blink::WebString::FromUTF8(message)));
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace extensions
diff --git a/src/core/renderer/extensions/resource_request_policy_qt.h b/src/core/renderer/extensions/resource_request_policy_qt.h
new file mode 100644
index 000000000..e6d4e79bb
--- /dev/null
+++ b/src/core/renderer/extensions/resource_request_policy_qt.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RESOURCEREQUESTPOLICYQT_H
+#define RESOURCEREQUESTPOLICYQT_H
+
+#include <set>
+
+#include "base/macros.h"
+#include "extensions/common/extension_id.h"
+#include "ui/base/page_transition_types.h"
+
+class GURL;
+
+namespace blink {
+class WebLocalFrame;
+}
+
+namespace extensions {
+
+class Dispatcher;
+class Extension;
+
+// Encapsulates the policy for when chrome-extension:// and
+// chrome-extension-resource:// URLs can be requested.
+class ResourceRequestPolicyQt
+{
+public:
+ explicit ResourceRequestPolicyQt(Dispatcher *dispatcher);
+
+ void OnExtensionLoaded(const Extension &extension);
+ void OnExtensionUnloaded(const ExtensionId &extension);
+
+ // Returns true if the chrome-extension:// |resource_url| can be requested
+ // from |frame_url|. In some cases this decision is made based upon how
+ // this request was generated. Web triggered transitions are more restrictive
+ // than those triggered through UI.
+ bool CanRequestResource(const GURL &resource_url,
+ blink::WebLocalFrame *frame,
+ ui::PageTransition transition_type);
+
+private:
+ Dispatcher *m_dispatcher;
+
+ // The set of extension IDs with any potentially web- or webview-accessible
+ // resources.
+ std::set<ExtensionId> m_web_accessible_ids;
+
+ DISALLOW_COPY_AND_ASSIGN(ResourceRequestPolicyQt);
+};
+} // namespace extensions
+
+#endif // RESOURCEREQUESTPOLICYQT_H
diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp
index 5d21201ba..9af05fd08 100644
--- a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp
+++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp
@@ -70,6 +70,7 @@
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPoint.h"
+#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/private/SkTemplates.h"
#include "ui/gfx/geometry/rect.h"
@@ -299,14 +300,12 @@ int32_t PepperFlashRendererHostQt::OnDrawGlyphs(
SkPaint paint;
paint.setColor(params.color);
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- paint.setAntiAlias(true);
- paint.setHinting(SkPaint::kFull_Hinting);
- paint.setTextSize(SkIntToScalar(params.font_desc.size));
- paint.setTypeface(std::move(typeface));
+
+ SkFont font(std::move(typeface), SkIntToScalar(params.font_desc.size));
+ font.setHinting(SkFontHinting::kFull);
if (params.allow_subpixel_aa) {
- paint.setSubpixelText(true);
- paint.setLCDRenderText(true);
+ font.setSubpixel(true);
+ font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
}
SkScalar x = SkIntToScalar(params.position.x);
@@ -315,15 +314,16 @@ int32_t PepperFlashRendererHostQt::OnDrawGlyphs(
// Build up the skia advances.
size_t glyph_count = params.glyph_indices.size();
if (glyph_count) {
- std::vector<SkPoint> sk_positions(glyph_count);
+ SkTextBlobBuilder builder;
+ auto rec = builder.allocRunPos(font, glyph_count);
+ memcpy(rec.glyphs, &params.glyph_indices[0], glyph_count * 2);
+ SkPoint* pos = reinterpret_cast<SkPoint*>(rec.pos);
for (uint32_t i = 0; i < glyph_count; i++) {
- sk_positions[i].set(x, y);
+ pos[i].set(x, y);
x += SkFloatToScalar(params.glyph_advances[i].x);
y += SkFloatToScalar(params.glyph_advances[i].y);
}
-
- canvas->drawPosText(
- &params.glyph_indices[0], glyph_count * 2, &sk_positions[0], paint);
+ canvas->drawTextBlob(builder.make(), 0, 0, paint);
}
if (needs_unmapping)
@@ -351,7 +351,7 @@ int32_t PepperFlashRendererHostQt::OnNavigate(
std::map<std::string, FlashNavigateUsage>& rejected_headers =
g_rejected_headers.Get();
if (rejected_headers.empty()) {
- for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i)
+ for (size_t i = 0; i < base::size(kRejectedHttpRequestHeaders); ++i)
rejected_headers[kRejectedHttpRequestHeaders[i]] =
static_cast<FlashNavigateUsage>(i);
}
diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
index 4acf69043..33c744f13 100644
--- a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
@@ -44,9 +44,13 @@
#include "pepper_renderer_host_factory_qt.h"
#include "pepper_flash_renderer_host_qt.h"
+#include "qtwebenginecoreglobal_p.h"
#include "base/memory/ptr_util.h"
#include "chrome/renderer/pepper/pepper_flash_font_file_host.h"
+#if QT_CONFIG(webengine_printing_and_pdf)
+#include "components/pdf/renderer/pepper_pdf_host.h"
+#endif // QT_CONFIG(webengine_printing_and_pdf)
#include "content/public/renderer/renderer_ppapi_host.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/host/resource_host.h"
@@ -100,7 +104,7 @@ std::unique_ptr<ppapi::host::ResourceHost> PepperRendererHostFactoryQt::CreateRe
// We should either rename PPB_FlashFont_File to PPB_FontFile_Private or get
// rid of its use in PDF if possible.
if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)
- || host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)) {
+ || host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_PDF)) {
switch (message.type()) {
case PpapiHostMsg_FlashFontFile_Create::ID: {
ppapi::proxy::SerializedFontDescription description;
@@ -115,14 +119,14 @@ std::unique_ptr<ppapi::host::ResourceHost> PepperRendererHostFactoryQt::CreateRe
}
}
- if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)) {
+#if QT_CONFIG(webengine_printing_and_pdf)
+ if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_PDF)) {
switch (message.type()) {
case PpapiHostMsg_PDF_Create::ID:
- // Not implemented
- break;
+ return std::make_unique<pdf::PepperPDFHost>(host_, instance, resource);
}
}
-
+#endif // QT_CONFIG(webengine_printing_and_pdf)
return nullptr;
}
diff --git a/src/core/renderer/print_web_view_helper_delegate_qt.cpp b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
index e693cf096..67cdd6b66 100644
--- a/src/core/renderer/print_web_view_helper_delegate_qt.cpp
+++ b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
@@ -41,8 +41,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.Chromium file.
-#include "print_web_view_helper_delegate_qt.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_view.h"
+#include "extensions/common/constants.h"
+#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+
+#include "print_web_view_helper_delegate_qt.h"
#include "web_engine_library_info.h"
namespace QtWebEngineCore {
@@ -58,6 +64,15 @@ bool PrintWebViewHelperDelegateQt::CancelPrerender(content::RenderFrame *)
blink::WebElement PrintWebViewHelperDelegateQt::GetPdfElement(blink::WebLocalFrame* frame)
{
+ GURL url = frame->GetDocument().Url();
+ if (url.SchemeIs(extensions::kExtensionScheme) && url.host() == extension_misc::kPdfExtensionId)
+ {
+ // <object> with id="plugin" is created in
+ // chrome/browser/resources/pdf/pdf.js.
+ auto plugin_element = frame->GetDocument().GetElementById("plugin");
+ CHECK(!plugin_element.IsNull());
+ return plugin_element;
+ }
return blink::WebElement();
}
diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h
index bca45bd8e..4c05422bb 100644
--- a/src/core/renderer/render_frame_observer_qt.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -44,6 +44,8 @@
#include "base/compiler_specific.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
+#include "ppapi/buildflags/buildflags.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
namespace content {
class RenderFrame;
@@ -67,10 +69,13 @@ public:
bool isFrameDetached() const;
+ service_manager::BinderRegistry* registry() { return &registry_; }
+
private:
DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt);
bool m_isFrameDetached;
+ service_manager::BinderRegistry registry_;
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/render_thread_observer_qt.cpp b/src/core/renderer/render_thread_observer_qt.cpp
new file mode 100644
index 000000000..64b9fd961
--- /dev/null
+++ b/src/core/renderer/render_thread_observer_qt.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// based on chrome/renderer/chrome_render_thread_observer.cc:
+// 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 "renderer/render_thread_observer_qt.h"
+
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
+
+namespace QtWebEngineCore {
+
+bool RenderThreadObserverQt::m_isIncognitoProcess = false;
+
+void RenderThreadObserverQt::RegisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces)
+{
+ associated_interfaces->AddInterface(base::Bind(&RenderThreadObserverQt::OnRendererConfigurationAssociatedRequest, base::Unretained(this)));
+}
+
+void RenderThreadObserverQt::UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces)
+{
+ associated_interfaces->RemoveInterface(qtwebengine::mojom::RendererConfiguration::Name_);
+}
+
+void RenderThreadObserverQt::SetInitialConfiguration(bool is_incognito_process)
+{
+ m_isIncognitoProcess = is_incognito_process;
+}
+
+void RenderThreadObserverQt::OnRendererConfigurationAssociatedRequest(qtwebengine::mojom::RendererConfigurationAssociatedRequest request)
+{
+ m_rendererConfigurationBindings.AddBinding(this, std::move(request));
+}
+
+} // namespace
diff --git a/src/core/renderer/render_thread_observer_qt.h b/src/core/renderer/render_thread_observer_qt.h
new file mode 100644
index 000000000..29b842ab4
--- /dev/null
+++ b/src/core/renderer/render_thread_observer_qt.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDER_THREAD_OBSERVER_QT_H
+#define RENDER_THREAD_OBSERVER_QT_H
+
+#include "content/public/renderer/render_thread_observer.h"
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
+#include "qtwebengine/common/renderer_configuration.mojom.h"
+
+namespace QtWebEngineCore {
+
+class RenderThreadObserverQt : public content::RenderThreadObserver,
+ public qtwebengine::mojom::RendererConfiguration {
+public:
+
+ RenderThreadObserverQt() = default;
+ ~RenderThreadObserverQt() override = default;
+
+ static bool is_incognito_process() { return m_isIncognitoProcess; }
+
+private:
+ // content::RenderThreadObserver:
+ void RegisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override;
+ void UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override;
+
+ // qtwebengine::mojom::RendererConfiguration:
+ void SetInitialConfiguration(bool is_incognito_process) override;
+
+ void OnRendererConfigurationAssociatedRequest(qtwebengine::mojom::RendererConfigurationAssociatedRequest request);
+
+ static bool m_isIncognitoProcess;
+
+ mojo::AssociatedBindingSet<qtwebengine::mojom::RendererConfiguration> m_rendererConfigurationBindings;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderThreadObserverQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // RENDER_THREAD_OBSERVER_QT_H
diff --git a/src/core/renderer/render_view_observer_qt.cpp b/src/core/renderer/render_view_observer_qt.cpp
index d37b67ebc..2795de4b9 100644
--- a/src/core/renderer/render_view_observer_qt.cpp
+++ b/src/core/renderer/render_view_observer_qt.cpp
@@ -80,7 +80,7 @@ void RenderViewObserverQt::onFetchDocumentInnerText(quint64 requestId)
void RenderViewObserverQt::onSetBackgroundColor(quint32 color)
{
- render_view()->GetWebFrameWidget()->SetBaseBackgroundColor(color);
+ render_view()->GetWebView()->SetBaseBackgroundColor(color);
}
void RenderViewObserverQt::OnDestruct()
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp
index 9c03cd651..be5e6f043 100644
--- a/src/core/renderer/user_resource_controller.cpp
+++ b/src/core/renderer/user_resource_controller.cpp
@@ -103,7 +103,7 @@ static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url)
matchFound = false;
for (auto it = scriptData.urlPatterns.begin(), end = scriptData.urlPatterns.end(); it != end; ++it) {
URLPattern urlPattern(validUserScriptSchemes());
- if (urlPattern.Parse(*it) == URLPattern::PARSE_SUCCESS && urlPattern.MatchesURL(url))
+ if (urlPattern.Parse(*it) == URLPattern::ParseResult::kSuccess && urlPattern.MatchesURL(url))
matchFound = true;
}
if (!matchFound)
@@ -137,7 +137,7 @@ public:
private:
// RenderFrameObserver implementation.
- void DidCommitProvisionalLoad(bool is_new_navigation, bool is_same_document_navigation) override;
+ void DidCommitProvisionalLoad(bool is_same_document_navigation, ui::PageTransition transition) override;
void DidFinishDocumentLoad() override;
void DidFinishLoad() override;
void FrameDetached() override;
@@ -229,8 +229,8 @@ UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(conte
{
}
-void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad(bool /* is_new_navigation */,
- bool is_same_document_navigation)
+void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition /*transitionbool*/)
{
if (is_same_document_navigation)
return;
diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
index 1f496e810..3b9c17b6a 100644
--- a/src/core/renderer/web_channel_ipc_transport.cpp
+++ b/src/core/renderer/web_channel_ipc_transport.cpp
@@ -119,7 +119,9 @@ void WebChannelTransport::Uninstall(blink::WebLocalFrame *frame, uint worldId)
if (qtObjectValue.IsEmpty() || !qtObjectValue->IsObject())
return;
v8::Local<v8::Object> qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
- qtObject->Delete(gin::StringToV8(isolate, "webChannelTransport"));
+ // FIXME: ?
+ auto whocares = qtObject->Delete(context, gin::StringToV8(isolate, "webChannelTransport"));
+ Q_UNUSED(whocares);
}
void WebChannelTransport::NativeQtSendMessage(gin::Arguments *args)
@@ -137,6 +139,8 @@ void WebChannelTransport::NativeQtSendMessage(gin::Arguments *args)
args->ThrowTypeError("Missing argument");
return;
}
+ v8::Isolate *isolate = blink::MainThreadIsolate();
+ v8::HandleScope handleScope(isolate);
if (!jsonValue->IsString()) {
args->ThrowTypeError("Expected string");
@@ -144,10 +148,10 @@ void WebChannelTransport::NativeQtSendMessage(gin::Arguments *args)
}
v8::Local<v8::String> jsonString = v8::Local<v8::String>::Cast(jsonValue);
- QByteArray json(jsonString->Utf8Length(), 0);
- jsonString->WriteUtf8(json.data(), json.size(),
- nullptr,
- v8::String::REPLACE_INVALID_UTF8);
+ QByteArray json(jsonString->Utf8Length(isolate), 0);
+ jsonString->WriteUtf8(isolate,
+ json.data(), json.size(),
+ nullptr, v8::String::REPLACE_INVALID_UTF8);
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(json, &error);
diff --git a/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp b/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp
index 2c8b1246a..5d7c3973f 100644
--- a/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp
+++ b/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp
@@ -45,8 +45,10 @@
#include "pepper_isolated_file_system_message_filter.h"
#include "base/macros.h"
+#include "base/task/post_task.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/render_view_host.h"
@@ -83,7 +85,7 @@ scoped_refptr<base::TaskRunner> PepperIsolatedFileSystemMessageFilter::OverrideT
{
// In order to reach ExtensionSystem, we need to get ProfileManager first.
// ProfileManager lives in UI thread, so we need to do this in UI thread.
- return content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI);
+ return base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI});
}
int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived(const IPC::Message& msg, ppapi::host::HostMessageContext *context)
diff --git a/src/core/render_view_observer_host_qt.cpp b/src/core/renderer_host/render_view_observer_host_qt.cpp
index c097e102d..c097e102d 100644
--- a/src/core/render_view_observer_host_qt.cpp
+++ b/src/core/renderer_host/render_view_observer_host_qt.cpp
diff --git a/src/core/render_view_observer_host_qt.h b/src/core/renderer_host/render_view_observer_host_qt.h
index a08263e07..a08263e07 100644
--- a/src/core/render_view_observer_host_qt.h
+++ b/src/core/renderer_host/render_view_observer_host_qt.h
diff --git a/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
new file mode 100644
index 000000000..36c5e6ed1
--- /dev/null
+++ b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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.Chromium file.
+
+#include "resource_dispatcher_host_delegate_qt.h"
+
+#include "base/bind.h"
+#include "base/guid.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_manager.h"
+#include "content/public/browser/download_request_utils.h"
+#include "content/public/browser/navigation_controller.h"
+
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/resource_dispatcher_host.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/stream_info.h"
+#include "content/public/browser/web_contents.h"
+
+#include "extensions/extension_system_qt.h"
+#include "extensions/browser/info_map.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
+
+#include "net/base/escape.h"
+#include "net/url_request/url_request.h"
+
+#include "profile_io_data_qt.h"
+#include "type_conversion.h"
+#include "web_contents_delegate_qt.h"
+#include "web_engine_settings.h"
+
+namespace QtWebEngineCore {
+
+void OnPdfStreamIntercepted(
+ const GURL& original_url,
+ std::string extension_id,
+ int frame_tree_node_id,
+ const content::ResourceRequestInfo::WebContentsGetter&
+ web_contents_getter) {
+ content::WebContents* web_contents = web_contents_getter.Run();
+ if (!web_contents)
+ return;
+
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(web_contents->GetDelegate());
+ if (!contentsDelegate)
+ return;
+
+ WebEngineSettings *settings = contentsDelegate->webEngineSettings();
+ if (!settings->testAttribute(WebEngineSettings::PdfViewerEnabled)
+ || !settings->testAttribute(WebEngineSettings::PluginsEnabled)) {
+ // If the applications has been set up to always download PDF files to open them in an
+ // external viewer, trigger the download.
+ std::unique_ptr<download::DownloadUrlParameters> params(
+ content::DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(
+ web_contents, original_url, NO_TRAFFIC_ANNOTATION_YET));
+ content::BrowserContext::GetDownloadManager(web_contents->GetBrowserContext())
+ ->DownloadUrl(std::move(params));
+ return;
+ }
+
+ // The URL passes the original pdf resource url, that will be requested
+ // by the pdf viewer extension page.
+ content::NavigationController::LoadURLParams params(
+ GURL(base::StringPrintf("%s://%s/index.html?%s", extensions::kExtensionScheme,
+ extension_id.c_str(),
+ original_url.spec().c_str())));
+
+ params.frame_tree_node_id = frame_tree_node_id;
+ web_contents->GetController().LoadURLWithParams(params);
+}
+
+bool ResourceDispatcherHostDelegateQt::ShouldInterceptResourceAsStream(net::URLRequest *request,
+ const std::string &mime_type,
+ GURL *origin,
+ std::string *payload)
+{
+ const content::ResourceRequestInfo* info =
+ content::ResourceRequestInfo::ForRequest(request);
+
+ int render_process_host_id = -1;
+ int render_frame_id = -1;
+ if (!content::ResourceRequestInfo::GetRenderFrameForRequest(request, &render_process_host_id, &render_frame_id))
+ return false;
+
+ std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist();
+
+ extensions::ExtensionSystemQt *extensionSystem = ProfileIODataQt::FromResourceContext(info->GetContext())->GetExtensionSystem();
+ if (!extensionSystem)
+ return false;
+
+ const scoped_refptr<const extensions::InfoMap> extension_info_map(extensionSystem->info_map());
+
+ for (const std::string &extension_id : whitelist) {
+ const extensions::Extension *extension = extension_info_map->extensions().GetByID(extension_id);
+ if (!extension)
+ continue;
+
+ MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
+ if (!handler)
+ continue;
+ if (handler->CanHandleMIMEType(mime_type)) {
+ StreamTargetInfo target_info;
+ *origin = extensions::Extension::GetBaseURLFromExtensionId(extension_id);
+ target_info.extension_id = extension_id;
+ target_info.view_id = base::GenerateGUID();
+ *payload = target_info.view_id;
+ stream_target_info_[request] = target_info;
+ return true;
+ }
+ }
+ return false;
+}
+
+// Informs the delegate that a Stream was created. The Stream can be read from
+// the blob URL of the Stream, but can only be read once.
+void ResourceDispatcherHostDelegateQt::OnStreamCreated(net::URLRequest *request,
+ std::unique_ptr<content::StreamInfo> stream)
+{
+ const content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request);
+ std::map<net::URLRequest *, StreamTargetInfo>::iterator ix = stream_target_info_.find(request);
+ CHECK(ix != stream_target_info_.end());
+ int render_frame_id = -1;
+ int render_process_id = -1;
+ if (!content::ResourceRequestInfo::GetRenderFrameForRequest(request, &render_process_id, &render_frame_id)) {
+ stream_target_info_.erase(request);
+ request->Cancel();
+ return;
+ }
+
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&OnPdfStreamIntercepted,
+ request->url(), ix->second.extension_id,
+ info->GetFrameTreeNodeId(), info->GetWebContentsGetterForRequest()
+ )
+ );
+ stream_target_info_.erase(request);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/renderer_host/resource_dispatcher_host_delegate_qt.h b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.h
new file mode 100644
index 000000000..3039fd03e
--- /dev/null
+++ b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RESOURCE_DISPATCHER_HOST_DELEGATE_QT_H
+#define RESOURCE_DISPATCHER_HOST_DELEGATE_QT_H
+
+#include "content/public/browser/resource_dispatcher_host_delegate.h"
+#include "extensions/buildflags/buildflags.h"
+
+#include "web_contents_adapter_client.h"
+
+namespace QtWebEngineCore {
+
+class ResourceDispatcherHostDelegateQt : public content::ResourceDispatcherHostDelegate {
+public:
+ // If the stream will be rendered in a BrowserPlugin, |payload| will contain
+ // the data that should be given to the old ResourceHandler to forward to the
+ // renderer process.
+ bool ShouldInterceptResourceAsStream(net::URLRequest *request,
+ const std::string &mime_type,
+ GURL *origin,
+ std::string *payload) override;
+
+ // Informs the delegate that a Stream was created. The Stream can be read from
+ // the blob URL of the Stream, but can only be read once.
+ void OnStreamCreated(net::URLRequest *request,
+ std::unique_ptr<content::StreamInfo> stream) override;
+private:
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ struct StreamTargetInfo {
+ std::string extension_id;
+ std::string view_id;
+ };
+ std::map<net::URLRequest *, StreamTargetInfo> stream_target_info_;
+#endif
+
+};
+
+} // namespace QtWebEngineCore
+
+#endif // RESOURCE_DISPATCHER_HOST_DELEGATE_QT_H
diff --git a/src/core/renderer_host/user_resource_controller_host.h b/src/core/renderer_host/user_resource_controller_host.h
index 40b685163..16a73f5fb 100644
--- a/src/core/renderer_host/user_resource_controller_host.h
+++ b/src/core/renderer_host/user_resource_controller_host.h
@@ -66,7 +66,7 @@ namespace QtWebEngineCore {
class WebContentsAdapter;
-class QWEBENGINECORE_PRIVATE_EXPORT UserResourceControllerHost {
+class Q_WEBENGINECORE_PRIVATE_EXPORT UserResourceControllerHost {
public:
UserResourceControllerHost();
diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp
index 428faa34e..dc7507f34 100644
--- a/src/core/resource_bundle_qt.cpp
+++ b/src/core/resource_bundle_qt.cpp
@@ -71,6 +71,7 @@ gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id)
return GetEmptyImage();
}
+// static
bool ResourceBundle::LocaleDataPakExists(const std::string& locale)
{
#if defined(OS_LINUX)
diff --git a/src/core/resource_context_qt.cpp b/src/core/resource_context_qt.cpp
index 6dfa5064e..79c105956 100644
--- a/src/core/resource_context_qt.cpp
+++ b/src/core/resource_context_qt.cpp
@@ -39,15 +39,6 @@
#include "resource_context_qt.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/storage_partition.h"
-#include "net/dns/host_resolver.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "profile_io_data_qt.h"
-
-#include <qglobal.h>
-
namespace QtWebEngineCore {
ResourceContextQt::ResourceContextQt(ProfileIODataQt *io_data)
@@ -55,13 +46,4 @@ ResourceContextQt::ResourceContextQt(ProfileIODataQt *io_data)
{
}
-net::URLRequestContext* ResourceContextQt::GetRequestContext()
-{
- Q_ASSERT(m_io_data);
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- // FIXME: This is the only remaining use of GetRequestContext(),
- // but we are on the wrong thread for calling BrowserContext::GetDefaultStoragePartition
- return m_io_data->urlRequestContext();
-}
-
} // namespace QtWebEngineCore
diff --git a/src/core/resource_context_qt.h b/src/core/resource_context_qt.h
index 6a5e7a74e..4107e7c24 100644
--- a/src/core/resource_context_qt.h
+++ b/src/core/resource_context_qt.h
@@ -42,6 +42,21 @@
#include "content/public/browser/resource_context.h"
+#include "extensions/buildflags/buildflags.h"
+
+namespace net {
+class URLRequestContext;
+class URLRequestContextGetter;
+}
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+namespace extensions {
+class ExtensionSystemQt;
+}
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
+class GURL;
+
namespace QtWebEngineCore {
class ProfileIODataQt;
@@ -50,8 +65,8 @@ class ResourceContextQt : public content::ResourceContext
{
public:
ResourceContextQt(ProfileIODataQt *io_data);
- net::URLRequestContext *GetRequestContext() override;
private:
+ friend class ProfileIODataQt;
ProfileIODataQt* m_io_data;
DISALLOW_COPY_AND_ASSIGN(ResourceContextQt);
};
diff --git a/src/core/service/service_qt.cpp b/src/core/service/service_qt.cpp
index 30ed269e8..83948e396 100644
--- a/src/core/service/service_qt.cpp
+++ b/src/core/service/service_qt.cpp
@@ -45,13 +45,15 @@
#include "service_qt.h"
#include "base/no_destructor.h"
+#include "base/task/post_task.h"
#include "components/spellcheck/spellcheck_buildflags.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h"
-#include "services/service_manager/public/cpp/service_context.h"
+#include "services/service_manager/public/cpp/service_binding.h"
#if BUILDFLAG(ENABLE_SPELLCHECK)
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
@@ -62,6 +64,7 @@ public:
IOThreadContext();
~IOThreadContext() override = default;
+ void BindServiceRequest(service_manager::mojom::ServiceRequest request);
void BindConnector(service_manager::mojom::ConnectorRequest connector_request);
private:
@@ -74,6 +77,7 @@ private:
mojo::ScopedMessagePipeHandle handle) override;
service_manager::mojom::ConnectorRequest m_connectorRequest;
+ service_manager::ServiceBinding m_serviceBinding{this};
service_manager::BinderRegistry m_registry;
service_manager::BinderRegistryWithArgs<const service_manager::BindSourceInfo&> m_registry_with_source_info;
@@ -82,13 +86,18 @@ private:
ServiceQt::IOThreadContext::IOThreadContext()
{
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner =
- content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI);
#if BUILDFLAG(ENABLE_SPELLCHECK)
- m_registry_with_source_info.AddInterface(base::Bind(&SpellCheckHostChromeImpl::Create), ui_task_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner =
+ base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI});
+ m_registry_with_source_info.AddInterface(base::BindRepeating(&SpellCheckHostChromeImpl::Create), ui_task_runner);
#endif
}
+void ServiceQt::IOThreadContext::BindServiceRequest(service_manager::mojom::ServiceRequest request)
+{
+ m_serviceBinding.Bind(std::move(request));
+}
+
void ServiceQt::IOThreadContext::BindConnector(service_manager::mojom::ConnectorRequest connector_request)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -97,7 +106,7 @@ void ServiceQt::IOThreadContext::BindConnector(service_manager::mojom::Connector
// on the IO thread. Post a task instead. As long as this task is posted
// before any code attempts to connect to the chrome service, there's no
// race.
- content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO)->PostTask(
+ base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})->PostTask(
FROM_HERE,
base::BindOnce(&IOThreadContext::BindConnectorOnIOThread,
base::Unretained(this),
@@ -114,7 +123,7 @@ void ServiceQt::IOThreadContext::OnStart()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
DCHECK(m_connectorRequest.is_pending());
- context()->connector()->BindConnectorRequest(std::move(m_connectorRequest));
+ m_serviceBinding.GetConnector()->BindConnectorRequest(std::move(m_connectorRequest));
}
void ServiceQt::IOThreadContext::OnBindInterface(const service_manager::BindSourceInfo &remote_info,
@@ -136,9 +145,9 @@ ServiceQt *ServiceQt::GetInstance()
return service.get();
}
-service_manager::EmbeddedServiceInfo::ServiceFactory ServiceQt::CreateServiceQtFactory()
+content::ServiceManagerConnection::ServiceRequestHandler ServiceQt::CreateServiceQtRequestHandler()
{
- return base::BindRepeating(&ServiceQt::CreateServiceQtWrapper, base::Unretained(this));
+ return base::BindRepeating(&ServiceQt::BindServiceQtRequest, base::Unretained(this));
}
ServiceQt::ServiceQt() : m_ioThreadContext(std::make_unique<IOThreadContext>())
@@ -153,8 +162,8 @@ void ServiceQt::InitConnector()
m_ioThreadContext->BindConnector(std::move(request));
}
-std::unique_ptr<service_manager::Service> ServiceQt::CreateServiceQtWrapper()
+void ServiceQt::BindServiceQtRequest(service_manager::mojom::ServiceRequest request)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- return std::make_unique<service_manager::ForwardingService>(m_ioThreadContext.get());
+ m_ioThreadContext->BindServiceRequest(std::move(request));
}
diff --git a/src/core/service/service_qt.h b/src/core/service/service_qt.h
index 4aa0a3996..d4c89065c 100644
--- a/src/core/service/service_qt.h
+++ b/src/core/service/service_qt.h
@@ -41,7 +41,7 @@
#define SERVICE_QT_H
#include "base/no_destructor.h"
-#include "services/service_manager/embedder/embedded_service_info.h"
+#include "content/public/common/service_manager_connection.h"
namespace service_manager {
class Connector;
@@ -53,7 +53,7 @@ public:
static ServiceQt *GetInstance();
void InitConnector();
- service_manager::EmbeddedServiceInfo::ServiceFactory CreateServiceQtFactory();
+ content::ServiceManagerConnection::ServiceRequestHandler CreateServiceQtRequestHandler();
service_manager::Connector *connector() { return m_connector.get(); }
private:
@@ -63,7 +63,7 @@ private:
ServiceQt();
~ServiceQt();
- std::unique_ptr<service_manager::Service> CreateServiceQtWrapper();
+ void BindServiceQtRequest(service_manager::mojom::ServiceRequest request);
const std::unique_ptr<IOThreadContext> m_ioThreadContext;
diff --git a/src/core/touch_handle_drawable_client.h b/src/core/touch_handle_drawable_client.h
new file mode 100644
index 000000000..a2c87948a
--- /dev/null
+++ b/src/core/touch_handle_drawable_client.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOUCH_HANDLE_DRAWABLE_CLIENT_H
+#define TOUCH_HANDLE_DRAWABLE_CLIENT_H
+
+#include "qtwebenginecoreglobal_p.h"
+#include <QRect>
+
+namespace QtWebEngineCore {
+
+class Q_WEBENGINECORE_PRIVATE_EXPORT TouchHandleDrawableClient {
+public:
+ virtual ~TouchHandleDrawableClient() { }
+
+ virtual void setImage(int orientation) = 0;
+ virtual void setBounds(const QRect &bounds) = 0;
+ virtual void setVisible(bool visible) = 0;
+ virtual void setOpacity(float opacity) = 0;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // TOUCH_HANDLE_DRAWABLE_CLIENT_H
diff --git a/src/core/touch_handle_drawable_qt.cpp b/src/core/touch_handle_drawable_qt.cpp
new file mode 100644
index 000000000..66b1cf40e
--- /dev/null
+++ b/src/core/touch_handle_drawable_qt.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// 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.Chromium file.
+
+// This implementation is based on chromium/ui/touch_selection/touch_handle_drawable_aura.cc
+
+#include "render_widget_host_view_qt.h"
+#include "touch_handle_drawable_client.h"
+#include "touch_handle_drawable_qt.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+
+#include "ui/gfx/image/image.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/resources/grit/ui_resources.h"
+
+namespace QtWebEngineCore {
+
+namespace {
+// The distance by which a handle image is offset from the focal point (i.e.
+// text baseline) downwards.
+const int kSelectionHandleVerticalVisualOffset = 2;
+
+// The padding around the selection handle image can be used to extend the
+// handle window so that touch events near the selection handle image are
+// targeted to the selection handle window.
+const int kSelectionHandlePadding = 0;
+
+// Epsilon value used to compare float values to zero.
+const float kEpsilon = 1e-8f;
+
+// Returns the appropriate handle image based on the handle orientation.
+gfx::Image* GetHandleImage(ui::TouchHandleOrientation orientation)
+{
+ int resource_id = 0;
+ switch (orientation) {
+ case ui::TouchHandleOrientation::LEFT:
+ resource_id = IDR_TEXT_SELECTION_HANDLE_LEFT;
+ break;
+ case ui::TouchHandleOrientation::CENTER:
+ resource_id = IDR_TEXT_SELECTION_HANDLE_CENTER;
+ break;
+ case ui::TouchHandleOrientation::RIGHT:
+ resource_id = IDR_TEXT_SELECTION_HANDLE_RIGHT;
+ break;
+ case ui::TouchHandleOrientation::UNDEFINED:
+ NOTREACHED() << "Invalid touch handle bound type.";
+ return nullptr;
+ };
+ return &ui::ResourceBundle::GetSharedInstance().GetImageNamed(resource_id);
+}
+
+bool IsNearlyZero(float value)
+{
+ return std::abs(value) < kEpsilon;
+}
+
+} // namespace
+
+TouchHandleDrawableQt::TouchHandleDrawableQt(RenderWidgetHostViewQt *rwhv)
+ : m_rwhv(rwhv)
+ , m_enabled(false)
+ , m_alpha(0)
+ , m_orientation(ui::TouchHandleOrientation::UNDEFINED)
+{
+ QMap<int, QImage> images;
+ for (int orientation = 0; orientation < static_cast<int>(ui::TouchHandleOrientation::UNDEFINED); ++orientation) {
+ gfx::Image* image = GetHandleImage(static_cast<ui::TouchHandleOrientation>(orientation));
+ images.insert(orientation, toQImage(image->AsBitmap()));
+ }
+
+ Q_ASSERT(m_rwhv);
+ Q_ASSERT(m_rwhv->adapterClient());
+ m_client.reset(m_rwhv->adapterClient()->createTouchHandle(images));
+}
+
+TouchHandleDrawableQt::~TouchHandleDrawableQt()
+{
+}
+
+void TouchHandleDrawableQt::UpdateBounds()
+{
+ if (!m_client)
+ return;
+
+ gfx::RectF newBounds = m_relativeBounds;
+ newBounds.Offset(m_originPosition.x(), m_originPosition.y());
+ m_client->setBounds(toQt(gfx::ToEnclosingRect(newBounds)));
+}
+
+bool TouchHandleDrawableQt::IsVisible() const
+{
+ return m_enabled && !IsNearlyZero(m_alpha);
+}
+
+void TouchHandleDrawableQt::SetEnabled(bool enabled)
+{
+ if (!m_client)
+ return;
+
+ if (enabled == m_enabled)
+ return;
+
+ m_enabled = enabled;
+ m_client->setVisible(enabled);
+}
+
+void TouchHandleDrawableQt::SetOrientation(ui::TouchHandleOrientation orientation, bool mirror_vertical, bool mirror_horizontal)
+{
+ if (!m_client)
+ return;
+
+ // TODO: Implement adaptive handle orientation logic
+ DCHECK(!mirror_vertical);
+ DCHECK(!mirror_horizontal);
+
+ if (m_orientation == orientation)
+ return;
+ m_orientation = orientation;
+ gfx::Image* image = GetHandleImage(orientation);
+ m_client->setImage(static_cast<int>(orientation));
+
+ // Calculate the relative bounds.
+ gfx::Size image_size = image->Size();
+ int window_width = image_size.width() + 2 * kSelectionHandlePadding;
+ int window_height = image_size.height() + 2 * kSelectionHandlePadding;
+ m_relativeBounds =
+ gfx::RectF(-kSelectionHandlePadding,
+ kSelectionHandleVerticalVisualOffset - kSelectionHandlePadding,
+ window_width, window_height);
+ UpdateBounds();
+}
+
+void TouchHandleDrawableQt::SetOrigin(const gfx::PointF& position)
+{
+ m_originPosition = position;
+ UpdateBounds();
+}
+
+void TouchHandleDrawableQt::SetAlpha(float alpha)
+{
+ if (!m_client)
+ return;
+
+ if (alpha == m_alpha)
+ return;
+
+ m_alpha = alpha;
+ m_client->setOpacity(m_alpha);
+ m_client->setVisible(IsVisible());
+}
+
+gfx::RectF TouchHandleDrawableQt::GetVisibleBounds() const
+{
+ gfx::RectF bounds = m_relativeBounds;
+ bounds.Offset(m_originPosition.x(), m_originPosition.y());
+
+ gfx::RectF visibleBounds(bounds);
+ visibleBounds.Inset(kSelectionHandlePadding,
+ kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset,
+ kSelectionHandlePadding,
+ kSelectionHandlePadding);
+ return visibleBounds;
+}
+
+float TouchHandleDrawableQt::GetDrawableHorizontalPaddingRatio() const
+{
+ // Qt does not have any transparent padding for its handle drawable.
+ return 0.0;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/touch_handle_drawable_qt.h b/src/core/touch_handle_drawable_qt.h
new file mode 100644
index 000000000..46fa217b7
--- /dev/null
+++ b/src/core/touch_handle_drawable_qt.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOUCH_HANDLE_DRAWABLE_QT_H
+#define TOUCH_HANDLE_DRAWABLE_QT_H
+
+#include "ui/touch_selection/touch_handle.h"
+#include "ui/touch_selection/touch_handle_orientation.h"
+
+#include <QtCore/QScopedPointer>
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQt;
+class TouchHandleDrawableClient;
+
+class TouchHandleDrawableQt : public ui::TouchHandleDrawable
+{
+public:
+ explicit TouchHandleDrawableQt(RenderWidgetHostViewQt *rwhv);
+ ~TouchHandleDrawableQt() override;
+
+private:
+ void UpdateBounds();
+ bool IsVisible() const;
+
+ // ui::TouchHandleDrawable overrides
+ void SetEnabled(bool enabled) override;
+ void SetOrientation(ui::TouchHandleOrientation orientation,
+ bool mirror_vertical,
+ bool mirror_horizontal) override;
+ void SetOrigin(const gfx::PointF& position) override;
+ void SetAlpha(float alpha) override;
+ gfx::RectF GetVisibleBounds() const override;
+ float GetDrawableHorizontalPaddingRatio() const override;
+
+ RenderWidgetHostViewQt *m_rwhv;
+ QScopedPointer<TouchHandleDrawableClient> m_client;
+
+ bool m_enabled;
+ float m_alpha;
+ ui::TouchHandleOrientation m_orientation;
+ gfx::RectF m_relativeBounds;
+ gfx::PointF m_originPosition;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchHandleDrawableQt);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // TOUCH_HANDLE_DRAWABLE_QT_H
diff --git a/src/core/touch_selection_controller_client_qt.cpp b/src/core/touch_selection_controller_client_qt.cpp
new file mode 100644
index 000000000..0f44210d1
--- /dev/null
+++ b/src/core/touch_selection_controller_client_qt.cpp
@@ -0,0 +1,343 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render_widget_host_view_qt.h"
+#include "touch_handle_drawable_qt.h"
+#include "touch_selection_controller_client_qt.h"
+#include "touch_selection_menu_controller.h"
+#include "type_conversion.h"
+#include "web_contents_adapter.h"
+#include "web_contents_adapter_client.h"
+
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "ui/gfx/geometry/size_conversions.h"
+
+#include <QClipboard>
+#include <QGuiApplication>
+
+namespace QtWebEngineCore {
+
+TouchSelectionControllerClientQt::TouchSelectionControllerClientQt(RenderWidgetHostViewQt *rwhv)
+ : m_rwhv(rwhv)
+ , m_menuController(new TouchSelectionMenuController(this))
+ , m_menuShowing(false)
+ , m_menuRequested(false)
+ , m_touchDown(false)
+ , m_scrollInProgress(false)
+ , m_handleDragInProgress(false)
+{
+ Q_ASSERT(rwhv);
+}
+
+TouchSelectionControllerClientQt::~TouchSelectionControllerClientQt()
+{
+}
+
+bool TouchSelectionControllerClientQt::handleContextMenu(const content::ContextMenuParams& params)
+{
+ if ((params.source_type == ui::MENU_SOURCE_LONG_PRESS ||
+ params.source_type == ui::MENU_SOURCE_LONG_TAP) &&
+ params.is_editable && params.selection_text.empty()) {
+ m_menuRequested = true;
+ updateMenu();
+ return true;
+ }
+
+ const bool from_touch = params.source_type == ui::MENU_SOURCE_LONG_PRESS ||
+ params.source_type == ui::MENU_SOURCE_LONG_TAP ||
+ params.source_type == ui::MENU_SOURCE_TOUCH;
+ if (from_touch && !params.selection_text.empty())
+ return true;
+
+ GetTouchSelectionController()->HideAndDisallowShowingAutomatically();
+ return false;
+}
+
+void TouchSelectionControllerClientQt::onTouchDown()
+{
+ m_touchDown = true;
+ updateMenu();
+}
+
+void TouchSelectionControllerClientQt::onTouchUp()
+{
+ m_touchDown = false;
+ updateMenu();
+}
+
+void TouchSelectionControllerClientQt::onScrollBegin()
+{
+ m_scrollInProgress = true;
+ GetTouchSelectionController()->SetTemporarilyHidden(true);
+ updateMenu();
+}
+
+void TouchSelectionControllerClientQt::onScrollEnd()
+{
+ m_scrollInProgress = false;
+ GetTouchSelectionController()->SetTemporarilyHidden(false);
+ updateMenu();
+}
+
+bool TouchSelectionControllerClientQt::IsCommandIdEnabled(int command_id) const
+{
+ bool editable = m_rwhv->getTextInputType() != ui::TEXT_INPUT_TYPE_NONE;
+ bool readable = m_rwhv->getTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD;
+ bool hasSelection = !m_rwhv->GetSelectedText().empty();
+
+ switch (command_id) {
+ case TouchSelectionMenuController::Cut:
+ return editable && readable && hasSelection;
+ case TouchSelectionMenuController::Copy:
+ return readable && hasSelection;
+ case TouchSelectionMenuController::Paste:
+ return editable && !QGuiApplication::clipboard()->text().isEmpty();
+ default:
+ return false;
+ }
+}
+
+void TouchSelectionControllerClientQt::ExecuteCommand(int command_id, int event_flags)
+{
+ Q_UNUSED(event_flags);
+ GetTouchSelectionController()->HideAndDisallowShowingAutomatically();
+
+ WebContentsAdapterClient *adapterClient = m_rwhv->adapterClient();
+ Q_ASSERT(adapterClient);
+ WebContentsAdapter *adapter = adapterClient->webContentsAdapter();
+ Q_ASSERT(adapter);
+
+ switch (command_id) {
+ case TouchSelectionMenuController::Cut:
+ adapter->cut();
+ break;
+ case TouchSelectionMenuController::Copy:
+ adapter->copy();
+ break;
+ case TouchSelectionMenuController::Paste:
+ adapter->paste();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void TouchSelectionControllerClientQt::RunContextMenu()
+{
+ gfx::RectF anchorRect = GetTouchSelectionController()->GetRectBetweenBounds();
+ gfx::PointF anchorPoint = gfx::PointF(anchorRect.CenterPoint().x(), anchorRect.y());
+
+ content::RenderWidgetHostImpl *host = m_rwhv->host();
+ host->ShowContextMenuAtPoint(gfx::ToRoundedPoint(anchorPoint),
+ ui::MENU_SOURCE_TOUCH_EDIT_MENU);
+
+ // Hide selection handles after getting rect-between-bounds from touch
+ // selection controller; otherwise, rect would be empty and the above
+ // calculations would be invalid.
+ GetTouchSelectionController()->HideAndDisallowShowingAutomatically();
+}
+
+void TouchSelectionControllerClientQt::DidStopFlinging()
+{
+ onScrollEnd();
+}
+
+void TouchSelectionControllerClientQt::UpdateClientSelectionBounds(const gfx::SelectionBound& start,
+ const gfx::SelectionBound& end)
+{
+ UpdateClientSelectionBounds(start, end, this, this);
+}
+
+void TouchSelectionControllerClientQt::UpdateClientSelectionBounds(const gfx::SelectionBound& start,
+ const gfx::SelectionBound& end,
+ ui::TouchSelectionControllerClient* client,
+ ui::TouchSelectionMenuClient* menu_client)
+{
+ Q_UNUSED(client);
+ Q_UNUSED(menu_client);
+
+ GetTouchSelectionController()->OnSelectionBoundsChanged(start, end);
+}
+
+void TouchSelectionControllerClientQt::InvalidateClient(ui::TouchSelectionControllerClient* client)
+{
+ Q_UNUSED(client);
+}
+
+ui::TouchSelectionController* TouchSelectionControllerClientQt::GetTouchSelectionController()
+{
+ return m_rwhv->getTouchSelectionController();
+}
+
+void TouchSelectionControllerClientQt::AddObserver(Observer* observer)
+{
+ Q_UNUSED(observer);
+}
+
+void TouchSelectionControllerClientQt::RemoveObserver(Observer* observer)
+{
+ Q_UNUSED(observer);
+}
+
+bool TouchSelectionControllerClientQt::SupportsAnimation() const
+{
+ return false;
+}
+
+void TouchSelectionControllerClientQt::SetNeedsAnimate()
+{
+ NOTREACHED();
+}
+
+void TouchSelectionControllerClientQt::MoveCaret(const gfx::PointF& position)
+{
+ content::mojom::FrameInputHandler *frameInputHandler = m_rwhv->getFrameInputHandler();
+ if (!frameInputHandler)
+ return;
+
+ frameInputHandler->MoveCaret(gfx::ToRoundedPoint(position));
+}
+
+void TouchSelectionControllerClientQt::MoveRangeSelectionExtent(const gfx::PointF& extent)
+{
+ content::mojom::FrameInputHandler *frameInputHandler = m_rwhv->getFrameInputHandler();
+ if (!frameInputHandler)
+ return;
+
+ frameInputHandler->MoveRangeSelectionExtent(gfx::ToRoundedPoint(extent));
+}
+
+void TouchSelectionControllerClientQt::SelectBetweenCoordinates(const gfx::PointF& base, const gfx::PointF& extent)
+{
+ content::mojom::FrameInputHandler *frameInputHandler = m_rwhv->getFrameInputHandler();
+ if (!frameInputHandler)
+ return;
+
+ frameInputHandler->SelectRange(gfx::ToRoundedPoint(base), gfx::ToRoundedPoint(extent));
+}
+
+void TouchSelectionControllerClientQt::OnSelectionEvent(ui::SelectionEventType event)
+{
+ switch (event) {
+ case ui::SELECTION_HANDLES_SHOWN:
+ m_menuRequested = true;
+ break;
+ case ui::INSERTION_HANDLE_SHOWN:
+ break;
+ case ui::SELECTION_HANDLES_CLEARED:
+ case ui::INSERTION_HANDLE_CLEARED:
+ m_menuRequested = false;
+ break;
+ case ui::SELECTION_HANDLE_DRAG_STARTED:
+ case ui::INSERTION_HANDLE_DRAG_STARTED:
+ m_handleDragInProgress = true;
+ break;
+ case ui::SELECTION_HANDLE_DRAG_STOPPED:
+ case ui::INSERTION_HANDLE_DRAG_STOPPED:
+ m_handleDragInProgress = false;
+ break;
+ case ui::SELECTION_HANDLES_MOVED:
+ case ui::INSERTION_HANDLE_MOVED:
+ break;
+ case ui::INSERTION_HANDLE_TAPPED:
+ m_menuRequested = !m_menuRequested;
+ break;
+ }
+
+ updateMenu();
+}
+
+void TouchSelectionControllerClientQt::OnDragUpdate(const gfx::PointF& position)
+{
+ Q_UNUSED(position);
+}
+
+std::unique_ptr<ui::TouchHandleDrawable> TouchSelectionControllerClientQt::CreateDrawable()
+{
+ return std::unique_ptr<ui::TouchHandleDrawable>(new TouchHandleDrawableQt(m_rwhv));
+}
+
+void TouchSelectionControllerClientQt::DidScroll()
+{
+}
+
+void TouchSelectionControllerClientQt::showMenu()
+{
+ gfx::RectF rect = GetTouchSelectionController()->GetRectBetweenBounds();
+ gfx::PointF origin = rect.origin();
+ gfx::PointF bottom_right = rect.bottom_right();
+
+ gfx::Vector2dF diagonal = bottom_right - origin;
+ gfx::SizeF size(diagonal.x(), diagonal.y());
+ gfx::RectF anchor_rect(origin, size);
+
+ // Calculate maximum handle image size;
+ gfx::SizeF max_handle_size = GetTouchSelectionController()->GetStartHandleRect().size();
+ max_handle_size.SetToMax(GetTouchSelectionController()->GetEndHandleRect().size());
+
+ WebContentsAdapterClient *adapterClient = m_rwhv->adapterClient();
+ Q_ASSERT(adapterClient);
+ adapterClient->showTouchSelectionMenu(m_menuController.data(),
+ QRect(toQt(gfx::ToEnclosingRect(anchor_rect))),
+ QSize(toQt(gfx::ToRoundedSize(max_handle_size))));
+ m_menuShowing = true;
+}
+
+void TouchSelectionControllerClientQt::hideMenu()
+{
+ WebContentsAdapterClient *adapterClient = m_rwhv->adapterClient();
+ Q_ASSERT(adapterClient);
+ adapterClient->hideTouchSelectionMenu();
+ m_menuShowing = false;
+}
+
+void TouchSelectionControllerClientQt::updateMenu()
+{
+ if (m_menuShowing)
+ hideMenu();
+
+ if (m_menuRequested && !m_touchDown &&
+ !m_scrollInProgress && !m_handleDragInProgress) {
+ showMenu();
+ }
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/touch_selection_controller_client_qt.h b/src/core/touch_selection_controller_client_qt.h
new file mode 100644
index 000000000..0d8dcf696
--- /dev/null
+++ b/src/core/touch_selection_controller_client_qt.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOUCH_SELECTION_CONTROLLER_CLIENT_QT_H
+#define TOUCH_SELECTION_CONTROLLER_CLIENT_QT_H
+
+#include "content/public/browser/touch_selection_controller_client_manager.h"
+#include "content/public/common/context_menu_params.h"
+#include "ui/touch_selection/touch_selection_controller.h"
+#include "ui/touch_selection/touch_selection_menu_runner.h"
+
+#include <QtCore/QScopedPointer>
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQt;
+class TouchSelectionMenuController;
+
+class TouchSelectionControllerClientQt
+ : public ui::TouchSelectionControllerClient
+ , public ui::TouchSelectionMenuClient
+ , public content::TouchSelectionControllerClientManager
+{
+public:
+ explicit TouchSelectionControllerClientQt(RenderWidgetHostViewQt *rwhv);
+ ~TouchSelectionControllerClientQt() override;
+
+ void UpdateClientSelectionBounds(const gfx::SelectionBound& start,
+ const gfx::SelectionBound& end);
+ bool handleContextMenu(const content::ContextMenuParams& params);
+ void onTouchDown();
+ void onTouchUp();
+ void onScrollBegin();
+ void onScrollEnd();
+
+ // ui::TouchSelectionMenuClient overrides
+ bool IsCommandIdEnabled(int command_id) const override;
+ void ExecuteCommand(int command_id, int event_flags) override;
+ void RunContextMenu() override;
+ bool ShouldShowQuickMenu() override { return false; }
+ base::string16 GetSelectedText() override { return base::string16(); }
+
+ // content::TouchSelectionControllerClientManager overrides
+ void DidStopFlinging() override;
+ void UpdateClientSelectionBounds(const gfx::SelectionBound& start,
+ const gfx::SelectionBound& end,
+ ui::TouchSelectionControllerClient* client,
+ ui::TouchSelectionMenuClient* menu_client) override;
+ void InvalidateClient(ui::TouchSelectionControllerClient* client) override;
+ ui::TouchSelectionController* GetTouchSelectionController() override;
+ void AddObserver(Observer* observer) override;
+ void RemoveObserver(Observer* observer) override;
+
+ // ui::TouchSelectionControllerClient overrides
+ bool SupportsAnimation() const override;
+ void SetNeedsAnimate() override;
+ void MoveCaret(const gfx::PointF& position) override;
+ void MoveRangeSelectionExtent(const gfx::PointF& extent) override;
+ void SelectBetweenCoordinates(const gfx::PointF& base, const gfx::PointF& extent) override;
+ void OnSelectionEvent(ui::SelectionEventType event) override;
+ void OnDragUpdate(const gfx::PointF& position) override;
+ std::unique_ptr<ui::TouchHandleDrawable> CreateDrawable() override;
+ void DidScroll() override;
+
+private:
+ void showMenu();
+ void hideMenu();
+ void updateMenu();
+
+ RenderWidgetHostViewQt *m_rwhv;
+ QScopedPointer<TouchSelectionMenuController> m_menuController;
+
+ bool m_menuShowing;
+ bool m_menuRequested;
+ bool m_touchDown;
+ bool m_scrollInProgress;
+ bool m_handleDragInProgress;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // TOUCH_SELECTION_CONTROLLER_CLIENT_QT_H
diff --git a/src/core/touch_selection_menu_controller.cpp b/src/core/touch_selection_menu_controller.cpp
new file mode 100644
index 000000000..cdec9a064
--- /dev/null
+++ b/src/core/touch_selection_menu_controller.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "touch_selection_controller_client_qt.h"
+#include "touch_selection_menu_controller.h"
+
+namespace QtWebEngineCore {
+
+TouchSelectionMenuController::TouchSelectionMenuController(TouchSelectionControllerClientQt *touchSelectionControllerClient)
+ : m_touchSelectionControllerClient(touchSelectionControllerClient)
+{
+}
+
+TouchSelectionMenuController::~TouchSelectionMenuController()
+{
+}
+
+int TouchSelectionMenuController::buttonCount()
+{
+ int buttonCount = 1;
+
+ for (int commandId = 0; commandId <= static_cast<int>(Paste); ++commandId) {
+ if (m_touchSelectionControllerClient->IsCommandIdEnabled(commandId))
+ buttonCount++;
+ }
+
+ return buttonCount;
+}
+
+bool TouchSelectionMenuController::isCommandEnabled(TouchSelectionCommand command)
+{
+ return m_touchSelectionControllerClient->IsCommandIdEnabled(static_cast<int>(command));
+}
+
+void TouchSelectionMenuController::cut()
+{
+ m_touchSelectionControllerClient->ExecuteCommand(static_cast<int>(Cut), 0);
+}
+
+void TouchSelectionMenuController::copy()
+{
+ m_touchSelectionControllerClient->ExecuteCommand(static_cast<int>(Copy), 0);
+}
+
+void TouchSelectionMenuController::paste()
+{
+ m_touchSelectionControllerClient->ExecuteCommand(static_cast<int>(Paste), 0);
+}
+
+void TouchSelectionMenuController::runContextMenu()
+{
+ return m_touchSelectionControllerClient->RunContextMenu();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/touch_selection_menu_controller.h b/src/core/touch_selection_menu_controller.h
new file mode 100644
index 000000000..34137b05b
--- /dev/null
+++ b/src/core/touch_selection_menu_controller.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOUCH_SELECTION_MENU_CONTROLLER_H
+#define TOUCH_SELECTION_MENU_CONTROLLER_H
+
+#include "qtwebenginecoreglobal_p.h"
+#include <QtCore/QObject>
+
+namespace QtWebEngineCore {
+
+class TouchSelectionControllerClientQt;
+
+class Q_WEBENGINECORE_PRIVATE_EXPORT TouchSelectionMenuController : public QObject {
+ Q_OBJECT
+public:
+ enum TouchSelectionCommand {
+ Cut,
+ Copy,
+ Paste
+ };
+
+ TouchSelectionMenuController(TouchSelectionControllerClientQt *touchSelectionControllerClient);
+ ~TouchSelectionMenuController();
+ int buttonCount();
+ bool isCommandEnabled(TouchSelectionCommand);
+
+public Q_SLOTS:
+ void cut();
+ void copy();
+ void paste();
+ void runContextMenu();
+
+private:
+ TouchSelectionControllerClientQt *m_touchSelectionControllerClient;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // TOUCH_SELECTION_CONTROLLER_CLIENT_QT_H
diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index f69b2a297..02d2db448 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -42,7 +42,9 @@
#include <content/public/common/favicon_url.h>
#include <ui/events/event_constants.h>
#include <ui/gfx/image/image_skia.h>
+
#include <QtCore/qcoreapplication.h>
+#include <QtGui/qmatrix4x4.h>
namespace QtWebEngineCore {
@@ -131,7 +133,7 @@ QImage toQImage(const SkBitmap &bitmap)
QImage toQImage(const gfx::ImageSkiaRep &imageSkiaRep)
{
- QImage image = toQImage(imageSkiaRep.sk_bitmap());
+ QImage image = toQImage(imageSkiaRep.GetBitmap());
if (!image.isNull() && imageSkiaRep.scale() != 1.0f)
image.setDevicePixelRatio(imageSkiaRep.scale());
return image;
@@ -243,4 +245,15 @@ FaviconInfo toFaviconInfo(const content::FaviconURL &favicon_url)
return info;
}
+void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c)
+{
+ QMatrix4x4 qtMatrix(
+ m.get(0, 0), m.get(0, 1), m.get(0, 2), m.get(0, 3),
+ m.get(1, 0), m.get(1, 1), m.get(1, 2), m.get(1, 3),
+ m.get(2, 0), m.get(2, 1), m.get(2, 2), m.get(2, 3),
+ m.get(3, 0), m.get(3, 1), m.get(3, 2), m.get(3, 3));
+ qtMatrix.optimize();
+ c = qtMatrix;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index afc3c3336..7b1f1b4d6 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -45,7 +45,6 @@
#include <QDir>
#include <QIcon>
#include <QImage>
-#include <QMatrix4x4>
#include <QNetworkCookie>
#include <QRect>
#include <QString>
@@ -64,6 +63,8 @@
#include "ui/gfx/geometry/rect_f.h"
#include "url/gurl.h"
+QT_FORWARD_DECLARE_CLASS(QMatrix4x4)
+
namespace content {
struct FaviconURL;
}
@@ -171,6 +172,11 @@ inline gfx::SizeF toGfx(const QSizeF& size)
return gfx::SizeF(size.width(), size.height());
}
+inline gfx::Rect toGfx(const QRect &rect)
+{
+ return gfx::Rect(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
inline QSizeF toQt(const gfx::SizeF &size)
{
return QSizeF(size.width(), size.height());
@@ -198,16 +204,7 @@ SkBitmap toSkBitmap(const QImage &image);
QIcon toQIcon(const std::vector<SkBitmap> &bitmaps);
-inline QMatrix4x4 toQt(const SkMatrix44 &m)
-{
- QMatrix4x4 qtMatrix(
- m.get(0, 0), m.get(0, 1), m.get(0, 2), m.get(0, 3),
- m.get(1, 0), m.get(1, 1), m.get(1, 2), m.get(1, 3),
- m.get(2, 0), m.get(2, 1), m.get(2, 2), m.get(2, 3),
- m.get(3, 0), m.get(3, 1), m.get(3, 2), m.get(3, 3));
- qtMatrix.optimize();
- return qtMatrix;
-}
+void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c);
inline QDateTime toQt(base::Time time)
{
diff --git a/src/core/user_notification_controller.cpp b/src/core/user_notification_controller.cpp
new file mode 100644
index 000000000..d169bf854
--- /dev/null
+++ b/src/core/user_notification_controller.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "user_notification_controller.h"
+
+#include "type_conversion.h"
+
+#include "base/callback.h"
+#include "content/public/browser/notification_event_dispatcher.h"
+#include "third_party/blink/public/common/notifications/notification_resources.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
+
+#include <memory>
+
+namespace QtWebEngineCore {
+
+static Qt::LayoutDirection toDirection(blink::PlatformNotificationData::Direction direction)
+{
+ switch (direction) {
+ case blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
+ return Qt::LeftToRight;
+ case blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
+ return Qt::RightToLeft;
+ case blink::PlatformNotificationData::DIRECTION_AUTO:
+ default:
+ break;
+ }
+ return Qt::LayoutDirectionAuto;
+}
+
+class UserNotificationControllerPrivate {
+public:
+ UserNotificationControllerPrivate(const blink::PlatformNotificationData &params,
+ const blink::NotificationResources &resources,
+ const GURL &origin)
+ : m_params(params)
+ , m_origin(origin)
+ , m_delegate(nullptr)
+ , m_resources(resources)
+ , m_client(nullptr)
+ , m_iconGenerated(false)
+ , m_imageGenerated(false)
+ , m_badgeGenerated(false)
+ , m_shown(false)
+ { }
+
+ blink::PlatformNotificationData m_params;
+ GURL m_origin;
+ std::unique_ptr<UserNotificationController::Delegate> m_delegate;
+ blink::NotificationResources m_resources;
+ UserNotificationController::Client *m_client;
+ QImage m_icon;
+ QImage m_image;
+ QImage m_badge;
+ bool m_iconGenerated;
+ bool m_imageGenerated;
+ bool m_badgeGenerated;
+ bool m_shown;
+};
+
+
+UserNotificationController::UserNotificationController(const blink::PlatformNotificationData &params,
+ const blink::NotificationResources &resources,
+ const GURL &origin,
+ Delegate *delegate)
+ : d(new UserNotificationControllerPrivate(params, resources, origin))
+{
+ d->m_delegate.reset(delegate);
+}
+
+UserNotificationController::~UserNotificationController()
+{
+ delete d;
+ d = nullptr;
+}
+
+void UserNotificationController::notificationDisplayed()
+{
+ if (!d->m_shown) {
+ d->m_shown = true;
+ if (d->m_delegate)
+ d->m_delegate->shown();
+ }
+}
+
+void UserNotificationController::notificationClosed()
+{
+ d->m_shown = false;
+ if (d->m_delegate)
+ d->m_delegate->closed(true);
+}
+
+void UserNotificationController::notificationClicked()
+{
+ if (d->m_delegate)
+ d->m_delegate->clicked();
+}
+
+void UserNotificationController::closeNotification()
+{
+ d->m_shown = false;
+ if (d->m_client)
+ d->m_client->notificationClosed(this);
+}
+
+void UserNotificationController::setClient(UserNotificationController::Client* client)
+{
+ d->m_client = client;
+}
+
+UserNotificationController::Client* UserNotificationController::client()
+{
+ return d->m_client;
+}
+
+QUrl UserNotificationController::origin() const
+{
+ return toQt(d->m_origin);
+}
+
+QImage UserNotificationController::icon() const
+{
+ if (!d->m_iconGenerated) {
+ d->m_iconGenerated = true;
+ if (!d->m_resources.notification_icon.isNull())
+ d->m_icon = toQImage(d->m_resources.notification_icon);
+ }
+ return d->m_icon;
+}
+
+QImage UserNotificationController::image() const
+{
+ if (d->m_imageGenerated)
+ return d->m_image;
+ d->m_image = toQImage(d->m_resources.image);
+ d->m_imageGenerated = true;
+ return d->m_image;
+}
+
+QImage UserNotificationController::badge() const
+{
+ if (d->m_badgeGenerated)
+ return d->m_badge;
+ d->m_badge = toQImage(d->m_resources.badge);
+ d->m_badgeGenerated = true;
+ return d->m_badge;
+}
+
+QString UserNotificationController::title() const
+{
+ return toQt(d->m_params.title);
+}
+
+QString UserNotificationController::body() const
+{
+ return toQt(d->m_params.body);
+}
+
+QString UserNotificationController::tag() const
+{
+ return toQt(d->m_params.tag);
+}
+
+QString UserNotificationController::language() const
+{
+ return toQt(d->m_params.lang);
+}
+
+Qt::LayoutDirection UserNotificationController::direction() const
+{
+ return toDirection(d->m_params.direction);
+}
+
+bool UserNotificationController::isShown() const
+{
+ return d->m_shown;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/user_notification_controller.h b/src/core/user_notification_controller.h
new file mode 100644
index 000000000..bab85c7ec
--- /dev/null
+++ b/src/core/user_notification_controller.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESKTOP_NOTIFICATION_CONTROLLER_H
+#define DESKTOP_NOTIFICATION_CONTROLLER_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QtCore/QSharedPointer>
+#include <QtCore/QUrl>
+#include <QtGui/QIcon>
+
+class GURL;
+
+namespace blink {
+ struct NotificationResources;
+ struct PlatformNotificationData;
+}
+
+namespace QtWebEngineCore {
+
+class UserNotificationControllerPrivate;
+
+// Works as an accessor and owner of chromium objects related to showing desktop notifications.
+class Q_WEBENGINECORE_EXPORT UserNotificationController : public QEnableSharedFromThis<UserNotificationController> {
+public:
+ struct Delegate {
+ virtual ~Delegate() { }
+ virtual void shown() = 0;
+ virtual void clicked() = 0;
+ virtual void closed(bool byUser) = 0;
+ };
+
+ UserNotificationController(const blink::PlatformNotificationData &params,
+ const blink::NotificationResources &resources,
+ const GURL &origin,
+ Delegate *delegate);
+ ~UserNotificationController();
+
+ // The notification was shown.
+ void notificationDisplayed();
+
+ // The notification was closed.
+ void notificationClosed();
+
+ // The user clicked on the notification.
+ void notificationClicked();
+
+ // Chromium requests to close the notification.
+ void closeNotification();
+
+ QUrl origin() const;
+ QImage icon() const;
+ QImage image() const;
+ QImage badge() const;
+ QString title() const;
+ QString body() const;
+ QString tag() const;
+ QString language() const;
+ Qt::LayoutDirection direction() const;
+
+ bool isShown() const;
+
+ class Client {
+ public:
+ virtual ~Client() { }
+ virtual void notificationClosed(const UserNotificationController *) = 0;
+ };
+ void setClient(Client *client);
+ Client* client();
+
+private:
+ UserNotificationControllerPrivate *d;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // DESKTOP_NOTIFICATION_CONTROLLER_H
diff --git a/src/core/user_script.h b/src/core/user_script.h
index 5ad53fdc1..8f65f4b74 100644
--- a/src/core/user_script.h
+++ b/src/core/user_script.h
@@ -63,7 +63,7 @@ namespace QtWebEngineCore {
class UserResourceControllerHost;
-class QWEBENGINECORE_PRIVATE_EXPORT UserScript : public QSharedData {
+class Q_WEBENGINECORE_PRIVATE_EXPORT UserScript : public QSharedData {
public:
enum InjectionPoint {
AfterLoad,
diff --git a/src/core/visited_links_manager_qt.cpp b/src/core/visited_links_manager_qt.cpp
index ac27446b8..d4885e8e8 100644
--- a/src/core/visited_links_manager_qt.cpp
+++ b/src/core/visited_links_manager_qt.cpp
@@ -39,7 +39,6 @@
#include "visited_links_manager_qt.h"
-#include "profile_adapter.h"
#include "content_browser_client_qt.h"
#include "profile_qt.h"
#include "type_conversion.h"
@@ -106,14 +105,13 @@ static void ensureDirectoryExists(const base::FilePath &path)
errorstr.c_str());
}
-VisitedLinksManagerQt::VisitedLinksManagerQt(ProfileAdapter *adapter)
+VisitedLinksManagerQt::VisitedLinksManagerQt(ProfileQt *profile, bool persistVisitedLinks)
: m_delegate(new VisitedLinkDelegateQt)
{
- Q_ASSERT(adapter && adapter->profile());
- ProfileQt *profile = adapter->profile();
- if (adapter->persistVisitedLinks())
+ Q_ASSERT(profile);
+ if (persistVisitedLinks)
ensureDirectoryExists(profile->GetPath());
- m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(profile, m_delegate.data(), adapter->persistVisitedLinks()));
+ m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(profile, m_delegate.data(), persistVisitedLinks));
m_visitedLinkMaster->Init();
}
diff --git a/src/core/visited_links_manager_qt.h b/src/core/visited_links_manager_qt.h
index 8d9a7495b..ecac8f30f 100644
--- a/src/core/visited_links_manager_qt.h
+++ b/src/core/visited_links_manager_qt.h
@@ -67,14 +67,14 @@ class GURL;
namespace QtWebEngineCore {
-class ProfileAdapter;
+class ProfileQt;
class VisitedLinkDelegateQt;
-class QWEBENGINECORE_PRIVATE_EXPORT VisitedLinksManagerQt {
+class Q_WEBENGINECORE_PRIVATE_EXPORT VisitedLinksManagerQt {
public:
virtual~VisitedLinksManagerQt();
- VisitedLinksManagerQt(ProfileAdapter *profileAdapter);
+ VisitedLinksManagerQt(ProfileQt *profile, bool persistVisitedLinks);
void deleteAllVisitedLinkData();
void deleteVisitedLinkDataForUrls(const QList<QUrl> &);
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index f74f16bc3..ca2479965 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -43,18 +43,17 @@
#include "web_contents_adapter.h"
-#include "browser_accessibility_qt.h"
-#include "profile_adapter_client.h"
-#include "profile_adapter.h"
#include "devtools_frontend_qt.h"
#include "download_manager_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/print_view_manager_qt.h"
#endif
+#include "profile_adapter_client.h"
+#include "profile_adapter.h"
#include "profile_qt.h"
#include "qwebenginecallback_p.h"
-#include "render_view_observer_host_qt.h"
+#include "renderer_host/render_view_observer_host_qt.h"
#include "render_widget_host_view_qt.h"
#include "type_conversion.h"
#include "web_contents_view_qt.h"
@@ -62,10 +61,13 @@
#include "web_engine_settings.h"
#include "base/command_line.h"
+#include "base/message_loop/message_loop_impl.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/download_manager.h"
@@ -83,10 +85,13 @@
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
#include "content/public/common/webrtc_ip_handling_policy.h"
-#include "third_party/blink/public/web/web_find_options.h"
+#include "extensions/buildflags/buildflags.h"
+#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
+//#include "third_party/blink/public/web/web_find_options.h"
#include "third_party/blink/public/web/web_media_player_action.h"
#include "printing/buildflags/buildflags.h"
#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/font_render_params.h"
@@ -95,6 +100,10 @@
#include <QtWebChannel/QWebChannel>
#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/extension_web_contents_observer_qt.h"
+#endif
+
#include <QDir>
#include <QGuiApplication>
#include <QPageLayout>
@@ -105,10 +114,14 @@
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmimedata.h>
#include <QtCore/qtemporarydir.h>
-#include <QtGui/qaccessible.h>
#include <QtGui/qdrag.h>
#include <QtGui/qpixmap.h>
+// Can't include headers as qaccessible.h conflicts with Chromium headers.
+namespace content {
+extern QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *acc);
+}
+
namespace QtWebEngineCore {
#define CHECK_INITIALIZED(return_value) \
@@ -117,7 +130,7 @@ namespace QtWebEngineCore {
#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_view_host) \
if (!render_view_host->IsRenderViewLive() && render_view_host->GetWidget()->GetView()) { \
- qWarning("Ignore navigation due to terminated render process with invalid RenderWidgetHostView."); \
+ LOG(WARNING) << "Ignore navigation due to terminated render process with invalid RenderWidgetHostView."; \
return; \
}
@@ -190,7 +203,7 @@ static QVariant fromJSValue(const base::Value *result)
}
case base::Value::Type::BINARY:
{
- QByteArray data(result->GetBlob().data(), result->GetBlob().size());
+ QByteArray data(reinterpret_cast<const char *>(result->GetBlob().data()), result->GetBlob().size());
ret.setValue(data);
break;
}
@@ -210,10 +223,10 @@ static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint6
#if QT_CONFIG(webengine_printing_and_pdf)
static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient,
int requestId,
- const std::vector<char>& result)
+ QSharedPointer<QByteArray> result)
{
if (requestId)
- adapterClient->didPrintPage(requestId, QByteArray(result.data(), result.size()));
+ adapterClient->didPrintPage(requestId, result);
}
static void callbackOnPdfSavingFinished(WebContentsAdapterClient *adapterClient,
@@ -229,12 +242,16 @@ static std::unique_ptr<content::WebContents> createBlankWebContents(WebContentsA
content::WebContents::CreateParams create_params(browserContext, NULL);
create_params.routing_id = MSG_ROUTING_NONE;
create_params.initial_size = gfx::Size(kTestWindowWidth, kTestWindowHeight);
- create_params.context = reinterpret_cast<gfx::NativeView>(adapterClient);
create_params.initially_hidden = true;
- return content::WebContents::Create(create_params);
+
+ std::unique_ptr<content::WebContents> webContents = content::WebContents::Create(create_params);
+ WebContentsViewQt* contentsView = static_cast<WebContentsViewQt*>(static_cast<content::WebContentsImpl*>(webContents.get())->GetView());
+ contentsView->setClient(adapterClient);
+
+ return webContents;
}
-static void serializeNavigationHistory(const content::NavigationController &controller, QDataStream &output)
+static void serializeNavigationHistory(content::NavigationController &controller, QDataStream &output)
{
const int currentIndex = controller.GetCurrentEntryIndex();
const int count = controller.GetEntryCount();
@@ -246,7 +263,7 @@ static void serializeNavigationHistory(const content::NavigationController &cont
// Logic taken from SerializedNavigationEntry::WriteToPickle.
for (int i = 0; i < count; ++i) {
- const content::NavigationEntry* entry = (i == pendingIndex)
+ content::NavigationEntry* entry = (i == pendingIndex)
? controller.GetPendingEntry()
: controller.GetEntryAtIndex(i);
if (entry->GetVirtualURL().is_valid()) {
@@ -318,7 +335,7 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
std::unique_ptr<content::NavigationEntry> entry = content::NavigationController::CreateNavigationEntry(
toGurl(virtualUrl),
- content::Referrer(toGurl(referrerUrl), static_cast<blink::WebReferrerPolicy>(referrerPolicy)),
+ content::Referrer(toGurl(referrerUrl), static_cast<network::mojom::ReferrerPolicy>(referrerPolicy)),
// Use a transition type of reload so that we don't incorrectly
// increase the typed count.
ui::PAGE_TRANSITION_RELOAD,
@@ -457,7 +474,6 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
if (!m_webContents) {
content::WebContents::CreateParams create_params(m_profileAdapter->profile(), site);
create_params.initial_size = gfx::Size(kTestWindowWidth, kTestWindowHeight);
- create_params.context = reinterpret_cast<gfx::NativeView>(m_adapterClient);
create_params.initially_hidden = true;
m_webContents = content::WebContents::Create(create_params);
}
@@ -480,7 +496,7 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
#endif
// Set web-contents font settings to the default font settings as Chromium constantly overrides
// the global font defaults with the font settings of the latest web-contents created.
- CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params, (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL)));
+ static const gfx::FontRenderParams params = gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr);
rendererPrefs->should_antialias_text = params.antialiasing;
rendererPrefs->use_subpixel_positioning = params.subpixel_positioning;
rendererPrefs->hinting = params.hinting;
@@ -495,7 +511,7 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
// Let the WebContent's view know about the WebContentsAdapterClient.
WebContentsViewQt* contentsView = static_cast<WebContentsViewQt*>(static_cast<content::WebContentsImpl*>(m_webContents.get())->GetView());
- contentsView->initialize(m_adapterClient);
+ contentsView->setClient(m_adapterClient);
// This should only be necessary after having restored the history to a new WebContentsAdapter.
m_webContents->GetController().LoadIfNecessary();
@@ -503,6 +519,9 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
#if QT_CONFIG(webengine_printing_and_pdf)
PrintViewManagerQt::CreateForWebContents(webContents());
#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::ExtensionWebContentsObserverQt::CreateForWebContents(webContents());
+#endif
// Create an instance of WebEngineVisitedLinksManager to catch the first
// content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will
@@ -630,7 +649,6 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
"HTTP-POST data can only be sent over HTTP(S) protocol"));
return;
}
-
params.post_data = network::ResourceRequestBody::CreateFromBytes(
(const char*)request.postData().constData(),
request.postData().length());
@@ -666,8 +684,8 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
QWeakPointer<WebContentsAdapter> weakThis(sharedFromThis());
if (resizeNeeded) {
// Schedule navigation on the event loop.
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE, base::BindOnce(navigate, std::move(weakThis), std::move(params)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(navigate, std::move(weakThis), std::move(params)));
} else {
navigate(std::move(weakThis), params);
}
@@ -804,7 +822,7 @@ void WebContentsAdapter::selectAll()
void WebContentsAdapter::requestClose()
{
CHECK_INITIALIZED();
- m_webContents->DispatchBeforeUnload();
+ m_webContents->DispatchBeforeUnload(false /* auto_cancel */);
}
void WebContentsAdapter::unselect()
@@ -936,8 +954,8 @@ QAccessibleInterface *WebContentsAdapter::browserAccessible()
if (!manager) // FIXME!
return nullptr;
content::BrowserAccessibility *acc = manager->GetRoot();
- content::BrowserAccessibilityQt *accQt = static_cast<content::BrowserAccessibilityQt*>(acc);
- return accQt;
+
+ return content::toQAccessibleInterface(acc);
}
#endif // QT_NO_ACCESSIBILITY
@@ -995,16 +1013,16 @@ quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitiv
m_adapterClient->didFindText(m_lastFindRequestId, 0);
}
- blink::WebFindOptions options;
- options.forward = !findBackward;
- options.match_case = caseSensitively;
- options.find_next = subString == m_webContentsDelegate->lastSearchedString();
+ blink::mojom::FindOptionsPtr options = blink::mojom::FindOptions::New();
+ options->forward = !findBackward;
+ options->match_case = caseSensitively;
+ options->find_next = subString == m_webContentsDelegate->lastSearchedString();
m_webContentsDelegate->setLastSearchedString(subString);
// Find already allows a request ID as input, but only as an int.
// Use the same counter but mod it to MAX_INT, this keeps the same likeliness of request ID clashing.
int shrunkRequestId = m_nextRequestId++ & 0x7fffffff;
- m_webContents->Find(shrunkRequestId, toString16(subString), options);
+ m_webContents->Find(shrunkRequestId, toString16(subString), std::move(options));
m_lastFindRequestId = shrunkRequestId;
return shrunkRequestId;
}
@@ -1074,7 +1092,7 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN
content::Referrer referrer = content::Referrer::SanitizeForRequest(
gurl,
content::Referrer(toGurl(referrerUrl).GetAsReferrer(),
- static_cast<blink::WebReferrerPolicy>(referrerPolicy)));
+ static_cast<network::mojom::ReferrerPolicy>(referrerPolicy)));
params->set_referrer(referrer.url);
params->set_referrer_policy(content::Referrer::ReferrerPolicyForUrlRequest(referrer.policy));
@@ -1106,16 +1124,30 @@ void WebContentsAdapter::copyImageAt(const QPoint &location)
m_webContents->GetRenderViewHost()->GetMainFrame()->CopyImageAt(location.x(), location.y());
}
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::kUnknown)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::kPlay)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::kMute)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::kLoop)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::kControls)
+static blink::WebMediaPlayerAction::Type toBlinkMediaPlayerActionType(WebContentsAdapter::MediaPlayerAction action)
+{
+ switch (action) {
+ case WebContentsAdapter::MediaPlayerPlay:
+ return blink::WebMediaPlayerAction::Type::kPlay;
+ case WebContentsAdapter::MediaPlayerMute:
+ return blink::WebMediaPlayerAction::Type::kMute;
+ case WebContentsAdapter::MediaPlayerLoop:
+ return blink::WebMediaPlayerAction::Type::kLoop;
+ case WebContentsAdapter::MediaPlayerControls:
+ return blink::WebMediaPlayerAction::Type::kControls;
+ case WebContentsAdapter::MediaPlayerNoAction:
+ break;
+ }
+ NOTREACHED();
+ return (blink::WebMediaPlayerAction::Type)-1;
+}
void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable)
{
CHECK_INITIALIZED();
- blink::WebMediaPlayerAction blinkAction((blink::WebMediaPlayerAction::Type)action, enable);
+ if (action == MediaPlayerNoAction)
+ return;
+ blink::WebMediaPlayerAction blinkAction(toBlinkMediaPlayerActionType(action), enable);
m_webContents->GetRenderViewHost()->GetMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction);
}
@@ -1263,6 +1295,12 @@ void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigi
m_profileAdapter->permissionRequestReply(securityOrigin, ProfileAdapter::GeolocationPermission, allowed);
}
+void WebContentsAdapter::runUserNotificationRequestCallback(const QUrl &securityOrigin, bool allowed)
+{
+ CHECK_INITIALIZED();
+ m_profileAdapter->permissionRequestReply(securityOrigin, ProfileAdapter::NotificationPermission, allowed);
+}
+
void WebContentsAdapter::grantMouseLockPermission(bool granted)
{
CHECK_INITIALIZED();
@@ -1277,16 +1315,6 @@ void WebContentsAdapter::grantMouseLockPermission(bool granted)
m_webContents->GotResponseToLockMouseRequest(granted);
}
-void WebContentsAdapter::dpiScaleChanged()
-{
- CHECK_INITIALIZED();
- content::RenderWidgetHostImpl* impl = NULL;
- if (m_webContents->GetRenderViewHost())
- impl = content::RenderWidgetHostImpl::From(m_webContents->GetRenderViewHost()->GetWidget());
- if (impl)
- impl->NotifyScreenInfoChanged();
-}
-
void WebContentsAdapter::setBackgroundColor(const QColor &color)
{
CHECK_INITIALIZED();
@@ -1344,7 +1372,7 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData)
if (!dropData.custom_data.empty()) {
base::Pickle pickle;
ui::WriteCustomDataToPickle(dropData.custom_data, &pickle);
- mimeData->setData(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()), QByteArray((const char*)pickle.data(), pickle.size()));
+ mimeData->setData(QLatin1String(ui::kMimeTypeWebCustomData), QByteArray((const char*)pickle.data(), pickle.size()));
}
return mimeData;
}
@@ -1396,7 +1424,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
}
{
- base::MessageLoop::ScopedNestableTaskAllower allow;
+ base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
drag->exec(allowedActions);
}
@@ -1462,8 +1490,8 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
dropData->html = toNullableString16(mimeData->html());
if (mimeData->hasText())
dropData->text = toNullableString16(mimeData->text());
- if (mimeData->hasFormat(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()))) {
- QByteArray customData = mimeData->data(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()));
+ if (mimeData->hasFormat(QLatin1String(ui::kMimeTypeWebCustomData))) {
+ QByteArray customData = mimeData->data(QLatin1String(ui::kMimeTypeWebCustomData));
ui::ReadCustomDataIntoMap(customData.constData(), customData.length(), &dropData->custom_data);
}
}
@@ -1540,7 +1568,7 @@ void WebContentsAdapter::waitForUpdateDragActionCalled()
const qint64 timeout = 3000;
QElapsedTimer t;
t.start();
- base::MessagePump::Delegate *delegate = base::MessageLoop::current();
+ base::MessagePump::Delegate *delegate = static_cast<base::MessageLoopImpl *>(base::MessageLoopCurrent::Get().ToMessageLoopBaseDeprecated());
DCHECK(delegate);
m_updateDragActionCalled = false;
for (;;) {
@@ -1675,15 +1703,15 @@ ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SaveToDiskDisposition, WindowOpenDi
ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OffTheRecordDisposition, WindowOpenDisposition::OFF_THE_RECORD)
ASSERT_ENUMS_MATCH(WebContentsAdapterClient::IgnoreActionDisposition, WindowOpenDisposition::IGNORE_ACTION)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, blink::kWebReferrerPolicyAlways)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, blink::kWebReferrerPolicyDefault)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, blink::kWebReferrerPolicyNoReferrerWhenDowngrade)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, blink::kWebReferrerPolicyNever)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, blink::kWebReferrerPolicyOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, blink::kWebReferrerPolicyOriginWhenCrossOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::SameOrigin, blink::kWebReferrerPolicySameOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::StrictOrigin, blink::kWebReferrerPolicyStrictOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, blink::kWebReferrerPolicyLast)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, network::mojom::ReferrerPolicy::kAlways)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, network::mojom::ReferrerPolicy::kDefault)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, network::mojom::ReferrerPolicy::kNever)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, network::mojom::ReferrerPolicy::kOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, network::mojom::ReferrerPolicy::kNoReferrerWhenDowngradeOriginWhenCrossOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::SameOrigin, network::mojom::ReferrerPolicy::kSameOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::StrictOrigin, network::mojom::ReferrerPolicy::kStrictOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, network::mojom::ReferrerPolicy::kLast)
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 9f9d0ed03..da4bc9190 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -91,7 +91,7 @@ class RenderViewObserverHostQt;
class WebChannelIPCTransportHost;
class WebEngineContext;
-class QWEBENGINECORE_PRIVATE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<WebContentsAdapter> {
+class Q_WEBENGINECORE_PRIVATE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<WebContentsAdapter> {
public:
static QSharedPointer<WebContentsAdapter> createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient);
WebContentsAdapter();
@@ -183,8 +183,8 @@ public:
void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags);
void runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed);
void grantMouseLockPermission(bool granted);
+ void runUserNotificationRequestCallback(const QUrl &securityOrigin, bool allowed);
- void dpiScaleChanged();
void setBackgroundColor(const QColor &color);
QAccessibleInterface *browserAccessible();
ProfileQt* profile();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 129e97c5b..540dd5f1f 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -66,6 +66,7 @@ QT_FORWARD_DECLARE_CLASS(QKeyEvent)
QT_FORWARD_DECLARE_CLASS(QVariant)
QT_FORWARD_DECLARE_CLASS(QWebEngineQuotaRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineRegisterProtocolHandlerRequest)
+QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInfo)
namespace content {
struct DropData;
@@ -81,6 +82,8 @@ class JavaScriptDialogController;
class RenderWidgetHostViewQt;
class RenderWidgetHostViewQtDelegate;
class RenderWidgetHostViewQtDelegateClient;
+class TouchHandleDrawableClient;
+class TouchSelectionMenuController;
class WebContentsAdapter;
class WebContentsDelegateQt;
class WebEngineSettings;
@@ -340,7 +343,7 @@ private:
};
-class QWEBENGINECORE_PRIVATE_EXPORT WebContentsAdapterClient {
+class Q_WEBENGINECORE_PRIVATE_EXPORT WebContentsAdapterClient {
public:
// This must match window_open_disposition_list.h.
enum WindowOpenDisposition {
@@ -421,7 +424,6 @@ public:
virtual void selectionChanged() = 0;
virtual void recentlyAudibleChanged(bool recentlyAudible) = 0;
virtual QRectF viewportRect() const = 0;
- virtual qreal dpiScale() const = 0;
virtual QColor backgroundColor() const = 0;
virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0;
virtual void loadCommitted() = 0;
@@ -444,7 +446,7 @@ public:
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
virtual void didFindText(quint64 requestId, int matchCount) = 0;
- virtual void didPrintPage(quint64 requestId, const QByteArray &result) = 0;
+ virtual void didPrintPage(quint64 requestId, QSharedPointer<QByteArray>) = 0;
virtual void didPrintPageToPdf(const QString &filePath, bool success) = 0;
virtual bool passOnFocus(bool reverse) = 0;
// returns the last QObject (QWidget/QQuickItem) based object in the accessibility
@@ -457,6 +459,7 @@ public:
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
virtual void runQuotaRequest(QWebEngineQuotaRequest) = 0;
virtual void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) = 0;
+ virtual void runUserNotificationPermissionRequest(const QUrl &securityOrigin) = 0;
virtual WebEngineSettings *webEngineSettings() const = 0;
RenderProcessTerminationStatus renderProcessExitStatus(int);
virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0;
@@ -476,6 +479,10 @@ public:
virtual ClientType clientType() = 0;
virtual void printRequested() = 0;
virtual void widgetChanged(RenderWidgetHostViewQtDelegate *newWidget) = 0;
+ virtual void interceptRequest(QWebEngineUrlRequestInfo &) { }
+ virtual TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &images) = 0;
+ virtual void showTouchSelectionMenu(TouchSelectionMenuController *menuController, const QRect &bounds, const QSize &handleSize) = 0;
+ virtual void hideTouchSelectionMenu() = 0;
virtual ProfileAdapter *profileAdapter() = 0;
virtual WebContentsAdapter* webContentsAdapter() = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 20de0546f..7719e78d7 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -58,6 +58,7 @@
#include "visited_links_manager_qt.h"
#include "web_contents_adapter_client.h"
#include "web_contents_adapter.h"
+#include "web_contents_view_qt.h"
#include "web_engine_context.h"
#include "web_engine_settings.h"
@@ -65,7 +66,9 @@
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
@@ -74,7 +77,6 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/favicon_url.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
@@ -136,6 +138,7 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
Q_ASSERT(target);
content::NavigationController::LoadURLParams load_url_params(params.url);
+ load_url_params.initiator_origin = params.initiator_origin;
load_url_params.source_site_instance = target_site_instance;
load_url_params.referrer = referrer;
load_url_params.frame_tree_node_id = params.frame_tree_node_id;
@@ -145,7 +148,11 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
load_url_params.should_replace_current_entry = params.should_replace_current_entry;
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.started_from_context_menu = params.started_from_context_menu;
+ load_url_params.has_user_gesture = params.user_gesture;
+ load_url_params.blob_url_loader_factory = params.blob_url_loader_factory;
load_url_params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
+ load_url_params.href_translate = params.href_translate;
+ load_url_params.reload_type = params.reload_type;
if (params.uses_post) {
load_url_params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST;
load_url_params.post_data = params.post_data;
@@ -155,7 +162,7 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
return target;
}
-static bool shouldUseActualURL(const content::NavigationEntry *entry)
+static bool shouldUseActualURL(content::NavigationEntry *entry)
{
Q_ASSERT(entry);
@@ -253,11 +260,13 @@ void WebContentsDelegateQt::LoadProgressChanged(content::WebContents */*source*/
m_viewClient->loadProgressChanged(m_lastLoadProgress);
}
-void WebContentsDelegateQt::HandleKeyboardEvent(content::WebContents *, const content::NativeWebKeyboardEvent &event)
+bool WebContentsDelegateQt::HandleKeyboardEvent(content::WebContents *, const content::NativeWebKeyboardEvent &event)
{
Q_ASSERT(!event.skip_in_browser);
if (event.os_event)
m_viewClient->unhandledKeyEvent(reinterpret_cast<QKeyEvent *>(event.os_event));
+ // FIXME: ?
+ return true;
}
void WebContentsDelegateQt::RenderFrameCreated(content::RenderFrameHost *render_frame_host)
@@ -437,12 +446,14 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::Favic
m_faviconManager->update(faviconCandidates);
}
-void WebContentsDelegateQt::WebContentsCreated(content::WebContents */*source_contents*/,
+void WebContentsDelegateQt::WebContentsCreated(content::WebContents * /*source_contents*/,
int /*opener_render_process_id*/, int /*opener_render_frame_id*/,
const std::string &/*frame_name*/,
- const GURL &target_url, content::WebContents */*new_contents*/)
+ const GURL &target_url, content::WebContents *newContents)
{
m_initialTargetUrl = toQt(target_url);
+ if (auto *view = static_cast<content::WebContentsImpl *>(newContents)->GetView())
+ static_cast<WebContentsViewQt *>(view)->setFactoryClient(m_viewClient);
}
content::ColorChooser *WebContentsDelegateQt::OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<blink::mojom::ColorSuggestionPtr> &suggestion)
@@ -477,12 +488,14 @@ bool WebContentsDelegateQt::IsFullscreenForTabOrPending(const content::WebConten
return m_viewClient->isFullScreenMode();
}
-ASSERT_ENUMS_MATCH(FilePickerController::Open, content::FileChooserParams::Open)
-ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, content::FileChooserParams::OpenMultiple)
-ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, content::FileChooserParams::UploadFolder)
-ASSERT_ENUMS_MATCH(FilePickerController::Save, content::FileChooserParams::Save)
+ASSERT_ENUMS_MATCH(FilePickerController::Open, blink::mojom::FileChooserParams::Mode::kOpen)
+ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, blink::mojom::FileChooserParams::Mode::kOpenMultiple)
+ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, blink::mojom::FileChooserParams::Mode::kUploadFolder)
+ASSERT_ENUMS_MATCH(FilePickerController::Save, blink::mojom::FileChooserParams::Mode::kSave)
-void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost *frameHost, const content::FileChooserParams &params)
+void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost * /*frameHost*/,
+ std::unique_ptr<content::FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params)
{
QStringList acceptedMimeTypes;
acceptedMimeTypes.reserve(params.accept_types.size());
@@ -490,7 +503,7 @@ void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost *frameHost,
acceptedMimeTypes.append(toQt(*it));
m_filePickerController.reset(new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode),
- frameHost, toQt(params.default_file_name.value()), acceptedMimeTypes));
+ std::move(listener), toQt(params.default_file_name.value()), acceptedMimeTypes));
// Defer the call to not block base::MessageLoop::RunTask with modal dialogs.
QTimer::singleShot(0, [this] () {
@@ -609,6 +622,11 @@ void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingO
m_viewClient->runGeolocationPermissionRequest(requestingOrigin);
}
+void WebContentsDelegateQt::requestUserNotificationPermission(const QUrl &requestingOrigin)
+{
+ m_viewClient->runUserNotificationPermissionRequest(requestingOrigin);
+}
+
extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture)
@@ -659,16 +677,18 @@ void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool pr
m_viewClient->windowCloseRejected();
}
-void WebContentsDelegateQt::BeforeUnloadFired(const base::TimeTicks &proceed_time) {
+void WebContentsDelegateQt::BeforeUnloadFired(bool proceed, const base::TimeTicks &proceed_time)
+{
+ Q_UNUSED(proceed);
Q_UNUSED(proceed_time);
}
-bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *, const GURL& security_origin, content::MediaStreamType type)
+bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *, const GURL& security_origin, blink::MediaStreamType type)
{
switch (type) {
- case content::MEDIA_DEVICE_AUDIO_CAPTURE:
+ case blink::MEDIA_DEVICE_AUDIO_CAPTURE:
return m_viewClient->profileAdapter()->checkPermission(toQt(security_origin), ProfileAdapter::AudioCapturePermission);
- case content::MEDIA_DEVICE_VIDEO_CAPTURE:
+ case blink::MEDIA_DEVICE_VIDEO_CAPTURE:
return m_viewClient->profileAdapter()->checkPermission(toQt(security_origin), ProfileAdapter::VideoCapturePermission);
default:
LOG(INFO) << "WebContentsDelegateQt::CheckMediaAccessPermission: "
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index b88b56dc1..9a3afebed 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -125,7 +125,7 @@ public:
void AddNewContents(content::WebContents *source, std::unique_ptr<content::WebContents> new_contents, WindowOpenDisposition disposition, const gfx::Rect &initial_pos, bool user_gesture, bool *was_blocked) override;
void CloseContents(content::WebContents *source) override;
void LoadProgressChanged(content::WebContents* source, double progress) override;
- void HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override;
+ bool HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override;
content::ColorChooser* OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<blink::mojom::ColorSuggestionPtr> &suggestions) override;
void WebContentsCreated(content::WebContents *source_contents, int opener_render_process_id, int opener_render_frame_id,
const std::string &frame_name, const GURL &target_url, content::WebContents *new_contents) override;
@@ -133,7 +133,9 @@ public:
void EnterFullscreenModeForTab(content::WebContents *web_contents, const GURL &origin, const blink::WebFullscreenOptions &) override;
void ExitFullscreenModeForTab(content::WebContents*) override;
bool IsFullscreenForTabOrPending(const content::WebContents* web_contents) const override;
- void RunFileChooser(content::RenderFrameHost* render_frame_host, const content::FileChooserParams& params) override;
+ void RunFileChooser(content::RenderFrameHost* render_frame_host,
+ std::unique_ptr<content::FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params) override;
bool DidAddMessageToConsole(content::WebContents* source, int32_t level, const base::string16& message, int32_t line_no, const base::string16& source_id) override;
void FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) override;
void RequestMediaAccessPermission(content::WebContents *web_contents,
@@ -143,7 +145,7 @@ public:
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) override;
void BeforeUnloadFired(content::WebContents* tab, bool proceed, bool* proceed_to_fire_unload) override;
- bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host, const GURL& security_origin, content::MediaStreamType type) override;
+ bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host, const GURL& security_origin, blink::MediaStreamType type) override;
void RegisterProtocolHandler(content::WebContents* web_contents, const std::string& protocol, const GURL& url, bool user_gesture) override;
void UnregisterProtocolHandler(content::WebContents* web_contents, const std::string& protocol, const GURL& url, bool user_gesture) override;
bool TakeFocus(content::WebContents *source, bool reverse) override;
@@ -157,7 +159,7 @@ public:
void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description) override;
void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override;
- void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
+ void BeforeUnloadFired(bool proceed, const base::TimeTicks& proceed_time) override;
void DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates) override;
void OnVisibilityChanged(content::Visibility visibility) override;
void DidFirstVisuallyNonEmptyPaint() override;
@@ -168,6 +170,7 @@ public:
void allowCertificateError(const QSharedPointer<CertificateErrorController> &);
void selectClientCert(const QSharedPointer<ClientCertSelectController> &);
void requestGeolocationPermission(const QUrl &requestingOrigin);
+ void requestUserNotificationPermission(const QUrl &requestingOrigin);
void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
FaviconManager *faviconManager();
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 7e0275aa0..ef7c09665 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -41,11 +41,15 @@
#include "profile_adapter.h"
#include "content_browser_client_qt.h"
+#include "render_widget_host_view_qt.h"
#include "render_widget_host_view_qt_delegate.h"
#include "render_widget_host_view_qt.h"
+#include "touch_selection_controller_client_qt.h"
#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
#include "web_contents_adapter.h"
#include "web_engine_context.h"
+#include "web_contents_delegate_qt.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -53,13 +57,25 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/context_menu_params.h"
-#include <ui/gfx/image/image_skia.h>
+#include "ui/gfx/image/image_skia.h"
#include <QtGui/qpixmap.h>
namespace QtWebEngineCore {
-void WebContentsViewQt::initialize(WebContentsAdapterClient* client)
+void WebContentsViewQt::setFactoryClient(WebContentsAdapterClient* client)
+{
+ if (m_factoryClient)
+ return;
+ m_factoryClient = client;
+
+ // Check if a RWHV was created before the pre-initialization.
+ if (auto view = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) {
+ view->setDelegate(m_factoryClient->CreateRenderWidgetHostViewQtDelegate(view));
+ }
+}
+
+void WebContentsViewQt::setClient(WebContentsAdapterClient* client)
{
m_client = client;
m_factoryClient = client;
@@ -75,15 +91,16 @@ content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForWidget(conten
{
RenderWidgetHostViewQt *view = new RenderWidgetHostViewQt(render_widget_host);
- Q_ASSERT(m_factoryClient);
- view->setDelegate(m_factoryClient->CreateRenderWidgetHostViewQtDelegate(view));
- if (m_client)
- view->setAdapterClient(m_client);
+ if (m_factoryClient) {
+ view->setDelegate(m_factoryClient->CreateRenderWidgetHostViewQtDelegate(view));
+ if (m_client)
+ view->setAdapterClient(m_client);
+ }
return view;
}
-content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForPopupWidget(content::RenderWidgetHost* render_widget_host)
+content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForChildWidget(content::RenderWidgetHost* render_widget_host)
{
RenderWidgetHostViewQt *view = new RenderWidgetHostViewQt(render_widget_host);
@@ -96,15 +113,11 @@ content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForPopupWidget(c
void WebContentsViewQt::CreateView(const gfx::Size& initial_size, gfx::NativeView context)
{
- // This is passed through content::WebContents::CreateParams::context either as the native view's client
- // directly or, in the case of a page-created new window, the client of the creating window's native view.
- m_factoryClient = reinterpret_cast<WebContentsAdapterClient *>(context);
}
gfx::NativeView WebContentsViewQt::GetNativeView() const
{
- // Hack to provide the client to WebContentsImpl::CreateNewWindow.
- return reinterpret_cast<gfx::NativeView>(m_client);
+ return nullptr;
}
void WebContentsViewQt::GetContainerBounds(gfx::Rect* out) const
@@ -203,6 +216,11 @@ static inline WebEngineContextMenuData fromParams(const content::ContextMenuPara
void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const content::ContextMenuParams &params)
{
+ if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) {
+ if (rwhv && rwhv->getTouchSelectionControllerClient()->handleContextMenu(params))
+ return;
+ }
+
WebEngineContextMenuData contextMenuData(fromParams(params));
#if QT_CONFIG(webengine_spellchecker)
// Do not use params.spellcheck_enabled, since it is never
@@ -247,7 +265,7 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
QPixmap pixmap;
QPoint hotspot;
- pixmap = QPixmap::fromImage(toQImage(image.GetRepresentation(m_client->dpiScale())));
+ pixmap = QPixmap::fromImage(toQImage(image.GetRepresentation(1.0)));
if (!pixmap.isNull()) {
hotspot.setX(image_offset.x());
hotspot.setY(image_offset.y());
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 7036907c5..ec09f9aae 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -63,10 +63,10 @@ public:
: m_webContents(webContents)
, m_client(nullptr)
, m_factoryClient(nullptr)
- , m_allowOtherViews(false)
{ }
- void initialize(WebContentsAdapterClient* client);
+ void setFactoryClient(WebContentsAdapterClient* client);
+ void setClient(WebContentsAdapterClient* client);
WebContentsAdapterClient *client() { return m_client; }
// content::WebContentsView overrides:
@@ -74,7 +74,7 @@ public:
void CreateView(const gfx::Size& initial_size, gfx::NativeView context) override;
- content::RenderWidgetHostViewBase* CreateViewForPopupWidget(content::RenderWidgetHost* render_widget_host) override;
+ content::RenderWidgetHostViewBase *CreateViewForChildWidget(content::RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override { }
@@ -84,35 +84,33 @@ public:
void RenderViewHostChanged(content::RenderViewHost*, content::RenderViewHost*) override { }
- void SetOverscrollControllerEnabled(bool enabled) override { QT_NOT_YET_IMPLEMENTED }
+ void SetOverscrollControllerEnabled(bool enabled) override { }
gfx::NativeView GetNativeView() const override;
- gfx::NativeView GetContentNativeView() const override { QT_NOT_USED return 0; }
+ gfx::NativeView GetContentNativeView() const override { return nullptr; }
- gfx::NativeWindow GetTopLevelNativeWindow() const override { QT_NOT_USED return 0; }
+ gfx::NativeWindow GetTopLevelNativeWindow() const override { return nullptr; }
void GetContainerBounds(gfx::Rect* out) const override;
- void SizeContents(const gfx::Size& size) override { QT_NOT_YET_IMPLEMENTED }
+ void SizeContents(const gfx::Size& size) override { }
void Focus() override;
void SetInitialFocus() override;
- void StoreFocus() override { QT_NOT_USED }
+ void StoreFocus() override { }
- void RestoreFocus() override { QT_NOT_USED }
+ void RestoreFocus() override { }
content::DropData* GetDropData() const override { QT_NOT_YET_IMPLEMENTED return nullptr; }
- gfx::Rect GetViewBounds() const override { QT_NOT_YET_IMPLEMENTED return gfx::Rect(); }
+ gfx::Rect GetViewBounds() const override { return gfx::Rect(); }
void FocusThroughTabTraversal(bool reverse) override;
#if defined(OS_MACOSX)
- void SetAllowOtherViews(bool allow) override { m_allowOtherViews = allow; }
- bool GetAllowOtherViews() const override { return m_allowOtherViews; }
void CloseTabAfterEventTracking() override { QT_NOT_YET_IMPLEMENTED }
bool IsEventTracking() const override { QT_NOT_YET_IMPLEMENTED; return false; }
#endif // defined(OS_MACOSX)
@@ -135,7 +133,6 @@ private:
content::WebContents *m_webContents;
WebContentsAdapterClient *m_client;
WebContentsAdapterClient *m_factoryClient;
- bool m_allowOtherViews;
};
} // namespace QtWebEngineCore
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 4af486456..a3a5881bf 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -44,23 +44,25 @@
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_impl.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "chrome/browser/printing/print_job_manager.h"
+#include "components/printing/browser/features.h"
#endif
#include "components/viz/common/features.h"
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/browser/devtools/devtools_http_handler.h"
-#include "content/browser/gpu/gpu_main_thread_factory.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
-#include "content/browser/utility_process_host.h"
-#include "content/gpu/in_process_gpu_thread.h"
+#include "content/browser/scheduler/browser_task_executor.h"
+#include "content/browser/startup_helper.h"
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/browser/browser_main_runner.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -68,17 +70,16 @@
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
-#include "content/renderer/in_process_renderer_thread.h"
-#include "content/utility/in_process_utility_thread.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/ipc/host/gpu_switches.h"
#include "media/audio/audio_manager.h"
-#include "media/base/media_switches.h"
#include "mojo/core/embedder/embedder.h"
#include "net/base/port_util.h"
#include "ppapi/buildflags/buildflags.h"
-#include "services/service_manager/sandbox/switches.h"
+#include "services/network/public/cpp/network_switches.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
+#include "services/service_manager/sandbox/switches.h"
#include "ui/events/event_switches.h"
#include "ui/native_theme/native_theme_features.h"
#include "ui/gl/gl_switches.h"
@@ -87,20 +88,24 @@
#include "content/public/app/sandbox_helper_win.h"
#endif // OS_WIN
+#ifndef QT_NO_ACCESSIBILITY
+#include "accessibility_activation_observer.h"
+#endif
#include "api/qwebengineurlscheme.h"
-#include "profile_adapter.h"
#include "content_browser_client_qt.h"
#include "content_client_qt.h"
#include "content_main_delegate_qt.h"
#include "devtools_manager_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
#include "net/webui_controller_factory_qt.h"
-#include "type_conversion.h"
#include "ozone/gl_context_qt.h"
+#include "profile_adapter.h"
+#include "type_conversion.h"
#include "web_engine_library_info.h"
#include <QFileInfo>
#include <QGuiApplication>
+#include <QMutex>
#include <QOffscreenSurface>
#ifndef QT_NO_OPENGL
# include <QOpenGLContext>
@@ -109,7 +114,9 @@
#include <QStringList>
#include <QSurfaceFormat>
#include <QVector>
-#include <qpa/qplatformnativeinterface.h>
+#include <QNetworkProxy>
+#include <QtGui/qpa/qplatformintegration.h>
+#include <QtGui/private/qguiapplication_p.h>
using namespace QtWebEngineCore;
@@ -133,10 +140,13 @@ bool usingANGLE()
#endif
}
-bool usingQtQuick2DRenderer()
+bool usingDefaultSGBackend()
{
const QStringList args = QGuiApplication::arguments();
- QString device;
+
+ //folow logic from contextFactory in src/quick/scenegraph/qsgcontextplugin.cpp
+ QString device = QQuickWindow::sceneGraphBackend();
+
for (int index = 0; index < args.count(); ++index) {
if (args.at(index).startsWith(QLatin1String("--device="))) {
device = args.at(index).mid(9);
@@ -145,16 +155,11 @@ bool usingQtQuick2DRenderer()
}
if (device.isEmpty())
- device = QQuickWindow::sceneGraphBackend();
- if (device.isEmpty())
device = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND"));
if (device.isEmpty())
device = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE"));
- if (device.isEmpty())
- device = QLatin1String("default");
- // Anything other than the default OpenGL device will need to render in 2D mode.
- return device != QLatin1String("default");
+ return device.isEmpty();
}
#endif //QT_NO_OPENGL
#if QT_CONFIG(webengine_pepper_plugins)
@@ -167,6 +172,8 @@ void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
namespace QtWebEngineCore {
+extern std::unique_ptr<base::MessagePump> messagePumpFactory();
+
bool usingSoftwareDynamicGL()
{
if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
@@ -189,9 +196,9 @@ void WebEngineContext::destroyProfileAdapter()
{
if (content::RenderProcessHost::run_renderer_in_process()) {
Q_ASSERT(m_profileAdapters.count() == 1);
- // this might be default profile
- m_defaultProfileAdapter.release();
- delete m_profileAdapters.first();
+ // this is a default profile
+ m_defaultProfileAdapter.reset();
+ Q_ASSERT(m_profileAdapters.isEmpty());
}
}
@@ -209,9 +216,11 @@ void WebEngineContext::addProfileAdapter(ProfileAdapter *profileAdapter)
}
}
- if (content::RenderProcessHost::run_renderer_in_process() &&
- !m_profileAdapters.isEmpty()) {
- qFatal("Single mode supports only single profile.");
+ if (content::RenderProcessHost::run_renderer_in_process()){
+ if (!m_profileAdapters.isEmpty())
+ qFatal("Single mode supports only single profile.");
+ // there is only one profle therefore make it 'default'
+ m_defaultProfileAdapter.reset(profileAdapter);
}
m_profileAdapters.append(profileAdapter);
}
@@ -225,8 +234,14 @@ void WebEngineContext::destroy()
{
if (m_devtoolsServer)
m_devtoolsServer->stop();
+
+ // Normally the GPU thread is shut down when the GpuProcessHost is destroyed
+ // on IO thread (triggered by ~BrowserMainRunner). But by that time the UI
+ // task runner is not working anymore so we need to do this earlier.
+ destroyGpuProcess();
+
base::MessagePump::Delegate *delegate =
- static_cast<base::MessageLoop *>(m_runLoop->delegate_);
+ static_cast<base::MessageLoopImpl *>(m_runLoop->delegate_);
// Flush the UI message loop before quitting.
while (delegate->DoWork()) { }
@@ -274,6 +289,7 @@ WebEngineContext::~WebEngineContext()
Q_ASSERT(!m_devtoolsServer);
Q_ASSERT(!m_browserRunner);
Q_ASSERT(m_profileAdapters.isEmpty());
+ delete s_syncPointManager.fetchAndStoreRelaxed(nullptr);
}
WebEngineContext *WebEngineContext::current()
@@ -293,8 +309,13 @@ WebEngineContext *WebEngineContext::current()
ProfileAdapter *WebEngineContext::createDefaultProfileAdapter()
{
Q_ASSERT(!m_destroyed);
- if (!m_defaultProfileAdapter)
- m_defaultProfileAdapter.reset(new ProfileAdapter(QStringLiteral("Default")));
+ if (!m_defaultProfileAdapter) {
+ ProfileAdapter *profile = new ProfileAdapter(QStringLiteral("Default"));
+ // profile when added to m_profileAdapters might be set default
+ // profile in case of single-process
+ if (!m_defaultProfileAdapter)
+ m_defaultProfileAdapter.reset(profile);
+ }
return m_defaultProfileAdapter.get();
}
@@ -313,7 +334,7 @@ void WebEngineContext::destroyContextPostRoutine()
// Destroy WebEngineContext before its static pointer is zeroed and destructor called.
// Before destroying MessageLoop via destroying BrowserMainRunner destructor
// WebEngineContext's pointer is used.
- m_handle->destroy();
+ m_handle->destroy();
#if !defined(NDEBUG)
if (!m_handle->HasOneRef())
qWarning("WebEngineContext leaked on exit, likely due to leaked WebEngine View or Page");
@@ -322,6 +343,18 @@ void WebEngineContext::destroyContextPostRoutine()
m_destroyed = true;
}
+ProxyAuthentication WebEngineContext::qProxyNetworkAuthentication(QString host, int port)
+{
+ if (!QNetworkProxyFactory::usesSystemConfiguration()) {
+ QNetworkProxy proxy = QNetworkProxy::applicationProxy();
+ if (host == proxy.hostName() && port == proxy.port() && !proxy.user().isEmpty()
+ && !proxy.password().isEmpty()) {
+ return std::make_tuple(true, proxy.user(), proxy.password());
+ }
+ }
+ return std::make_tuple(false, QString(), QString());
+}
+
#ifndef CHROMIUM_VERSION
#error Chromium version should be defined at gyp-time. Something must have gone wrong
#define CHROMIUM_VERSION // This is solely to keep Qt Creator happy.
@@ -330,7 +363,15 @@ void WebEngineContext::destroyContextPostRoutine()
const static char kChromiumFlagsEnv[] = "QTWEBENGINE_CHROMIUM_FLAGS";
const static char kDisableSandboxEnv[] = "QTWEBENGINE_DISABLE_SANDBOX";
-static void appendToFeatureSwitch(base::CommandLine *commandLine, const char *featureSwitch, const char *feature)
+static void appendToFeatureList(std::string &featureList, const char *feature)
+{
+ if (featureList.empty())
+ featureList = feature;
+ else
+ featureList = featureList + "," + feature;
+}
+
+static void appendToFeatureSwitch(base::CommandLine *commandLine, const char *featureSwitch, std::string feature)
{
if (!commandLine->HasSwitch(featureSwitch)) {
commandLine->AppendSwitchASCII(featureSwitch, feature);
@@ -347,7 +388,8 @@ WebEngineContext::WebEngineContext()
{
base::TaskScheduler::Create("Browser");
m_contentRunner.reset(content::ContentMainRunner::Create());
- m_browserRunner.reset(content::BrowserMainRunner::Create());
+ m_browserRunner = content::BrowserMainRunner::Create();
+
#ifdef Q_OS_LINUX
// Call qputenv before BrowserMainRunnerImpl::Initialize is called.
// http://crbug.com/245466
@@ -366,35 +408,24 @@ WebEngineContext::WebEngineContext()
QWebEngineUrlScheme::lockSchemes();
// Allow us to inject javascript like any webview toolkit.
- content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
+ content::RenderFrameHost::AllowInjectingJavaScript();
- base::CommandLine::CreateEmpty();
- base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
QStringList appArgs = QCoreApplication::arguments();
- if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
- appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
- appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' '));
- }
- bool enableWebGLSoftwareRendering =
- appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+ // If user requested GL support instead of using Skia rendering to
+ // bitmaps, use software rendering via software OpenGL. This might be less
+ // performant, but at least provides WebGL support.
+ // TODO(miklocek), check if this still works with latest chromium
+ bool enableGLSoftwareRendering = appArgs.contains(QStringLiteral("--enable-webgl-software-rendering"));
bool useEmbeddedSwitches = false;
#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
- useEmbeddedSwitches = !appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
-#else
- useEmbeddedSwitches = appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
-#endif
- base::CommandLine::StringVector argv;
- argv.resize(appArgs.size());
-#if defined(Q_OS_WIN)
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = toString16(appArgs[i]);
+ useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
#else
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = appArgs[i].toStdString();
+ useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
#endif
- parsedCommandLine->InitFromArgv(argv);
+
+ base::CommandLine* parsedCommandLine = commandLine();
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
@@ -427,8 +458,6 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kDisablePepper3DImageChromium);
// Same problem with select popups.
parsedCommandLine->AppendSwitch(switches::kDisableNativeGpuMemoryBuffers);
- // SandboxV2 doesn't currently work for us
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kMacV2Sandbox.name);
#endif
#if defined(Q_OS_WIN)
@@ -436,35 +465,59 @@ WebEngineContext::WebEngineContext()
// an OpenGL Core Profile context. If the switch is not set, it would always try to create a
// Core Profile context, even if Qt uses a legacy profile, which causes
// "Could not share GL contexts" warnings, because it's not possible to share between Core and
- // legacy profiles.
- // Given that Core profile is not currently supported on Windows anyway, pass this switch to
- // get rid of the warnings.
- parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
+ // legacy profiles. See GLContextWGL::Initialize().
+ // Given that Desktop GL Core profile is not currently supported on Windows anyway, pass this
+ // switch to get rid of the warnings.
+ //
+ // The switch is also used to determine which version of OpenGL ES to use (2 or 3) when using
+ // ANGLE.
+ // If the switch is not set, Chromium will always try to create an ES3 context, even if Qt uses
+ // an ES2 context, which causes resource sharing issues (black screen),
+ // see gpu::gles2::GenerateGLContextAttribs().
+ // Make sure to disable ES3 context creation when using ES2.
+ const bool isGLES2Context = qt_gl_global_share_context()
+ && qt_gl_global_share_context()->isOpenGLES()
+ && qt_gl_global_share_context()->format().majorVersion() == 2;
+ const bool isDesktopGLOrSoftware = !usingANGLE();
+
+ if (isDesktopGLOrSoftware || isGLES2Context)
+ parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
#endif
+
+ std::string disableFeatures;
+ std::string enableFeatures;
// Needed to allow navigations within pages that were set using setHtml(). One example is
// tst_QWebEnginePage::acceptNavigationRequest.
// This is deprecated behavior, and will be removed in a future Chromium version, as per
// upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422.
- appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
+ appendToFeatureList(enableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
// Surface synchronization breaks our current graphics integration (since 65)
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kEnableSurfaceSynchronization.name);
+ appendToFeatureList(disableFeatures, features::kEnableSurfaceSynchronization.name);
+ // Viz Display Compositor is enabled by default since 73. Doesn't work for us (also implies SurfaceSynchronization)
+ appendToFeatureList(disableFeatures, features::kVizDisplayCompositor.name);
// The video-capture service is not functioning at this moment (since 69)
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kMojoVideoCapture.name);
- // We do not yet support the internal video capture API.
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kUseVideoCaptureApiForDevToolsSnapshots.name);
- // Qt 5.12 only: The modern media controls are not yet good enough in 69-based,
- // so we stick to the old style
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, media::kUseModernMediaControls.name);
+ appendToFeatureList(disableFeatures, features::kMojoVideoCapture.name);
+ // Breaks WebEngineNewViewRequest.userInitiated API (since 73)
+ appendToFeatureList(disableFeatures, features::kUserActivationV2.name);
+
+ appendToFeatureList(disableFeatures, features::kBackgroundFetch.name);
+
+#if QT_CONFIG(webengine_printing_and_pdf)
+ appendToFeatureList(disableFeatures, printing::features::kUsePdfCompositorServiceForPrint.name);
+#endif
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
- appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, features::kOverlayScrollbar.name);
+ appendToFeatureList(enableFeatures, features::kOverlayScrollbar.name);
if (!parsedCommandLine->HasSwitch(switches::kDisablePinch))
parsedCommandLine->AppendSwitch(switches::kEnablePinch);
parsedCommandLine->AppendSwitch(switches::kEnableViewport);
parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
+
+ appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, disableFeatures);
+ appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, enableFeatures);
base::FeatureList::InitializeInstance(
parsedCommandLine->GetSwitchValueASCII(switches::kEnableFeatures),
parsedCommandLine->GetSwitchValueASCII(switches::kDisableFeatures));
@@ -474,22 +527,18 @@ WebEngineContext::WebEngineContext()
const char *glType = 0;
#ifndef QT_NO_OPENGL
- bool tryGL =
- !usingANGLE()
- && (!usingSoftwareDynamicGL()
- // If user requested WebGL support instead of using Skia rendering to
- // bitmaps, use software rendering via software OpenGL. This might be less
- // performant, but at least provides WebGL support.
- || enableWebGLSoftwareRendering
- )
- && !usingQtQuick2DRenderer();
-
+ const bool tryGL = (usingDefaultSGBackend() && !usingSoftwareDynamicGL() &&
+ QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ || enableGLSoftwareRendering;
if (tryGL) {
if (qt_gl_global_share_context() && qt_gl_global_share_context()->isValid()) {
- // If the native handle is QEGLNativeContext try to use GL ES/2, if there is no native handle
- // assume we are using wayland and try GL ES/2, and finally Ozone demands GL ES/2 too.
+ // If the native handle is QEGLNativeContext try to use GL ES/2.
+ // If there is no native handle, assume we are using wayland and try GL ES/2.
+ // If we are using ANGLE on Windows, use OpenGL ES (2 or 3).
if (qt_gl_global_share_context()->nativeHandle().isNull()
- || !strcmp(qt_gl_global_share_context()->nativeHandle().typeName(), "QEGLNativeContext"))
+ || !strcmp(qt_gl_global_share_context()->nativeHandle().typeName(),
+ "QEGLNativeContext")
+ || usingANGLE())
{
if (qt_gl_global_share_context()->isOpenGLES()) {
glType = gl::kGLImplementationEGLName;
@@ -547,7 +596,7 @@ WebEngineContext::WebEngineContext()
if (glType) {
parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
- if (enableWebGLSoftwareRendering) {
+ if (enableGLSoftwareRendering) {
parsedCommandLine->AppendSwitch(switches::kDisableGpuRasterization);
parsedCommandLine->AppendSwitch(switches::kIgnoreGpuBlacklist);
}
@@ -555,9 +604,16 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kDisableGpu);
}
- content::UtilityProcessHost::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
- content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread);
- content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread);
+ bool threadedGpu = true;
+#ifndef QT_NO_OPENGL
+ threadedGpu = QOpenGLContext::supportsThreadedOpenGL();
+#endif
+ registerMainThreadFactories(threadedGpu);
+
+ SetContentClient(new ContentClientQt);
+
+ content::StartBrowserTaskScheduler();
+ content::BrowserTaskExecutor::Create();
mojo::core::Init();
@@ -586,8 +642,8 @@ WebEngineContext::WebEngineContext()
base::ThreadRestrictions::SetIOAllowed(true);
- if (parsedCommandLine->HasSwitch(switches::kExplicitlyAllowedPorts)) {
- std::string allowedPorts = parsedCommandLine->GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
+ if (parsedCommandLine->HasSwitch(network::switches::kExplicitlyAllowedPorts)) {
+ std::string allowedPorts = parsedCommandLine->GetSwitchValueASCII(network::switches::kExplicitlyAllowedPorts);
net::SetExplicitlyAllowedPorts(allowedPorts);
}
@@ -609,6 +665,10 @@ WebEngineContext::WebEngineContext()
m_printJobManager.reset(new printing::PrintJobManager());
#endif
+#ifndef QT_NO_ACCESSIBILITY
+ m_accessibilityActivationObserver.reset(new AccessibilityActivationObserver());
+#endif
+
content::WebUIControllerFactory::RegisterFactory(WebUIControllerFactoryQt::GetInstance());
}
@@ -618,4 +678,48 @@ printing::PrintJobManager* WebEngineContext::getPrintJobManager()
return m_printJobManager.get();
}
#endif
+
+static QMutex s_spmMutex;
+QAtomicPointer<gpu::SyncPointManager> WebEngineContext::s_syncPointManager;
+
+gpu::SyncPointManager *WebEngineContext::syncPointManager()
+{
+ if (gpu::SyncPointManager *spm = s_syncPointManager.loadAcquire())
+ return spm;
+ QMutexLocker lock(&s_spmMutex);
+ if (!s_syncPointManager)
+ s_syncPointManager.store(new gpu::SyncPointManager());
+ return s_syncPointManager.load();
+}
+
+base::CommandLine* WebEngineContext::commandLine() {
+ if (base::CommandLine::CreateEmpty()) {
+ base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ QStringList appArgs = QCoreApplication::arguments();
+ if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
+ appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
+ appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' '));
+ }
+#ifdef Q_OS_WIN
+ appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+#endif
+ appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
+ appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+
+ base::CommandLine::StringVector argv;
+ argv.resize(appArgs.size());
+#if defined(Q_OS_WIN)
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = toString16(appArgs[i]);
+#else
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdString();
+#endif
+ parsedCommandLine->InitFromArgv(argv);
+ return parsedCommandLine;
+ } else {
+ return base::CommandLine::ForCurrentProcess();
+ }
+}
+
} // namespace
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 604c85a61..2364bacbe 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -47,11 +47,20 @@
namespace base {
class RunLoop;
+class CommandLine;
}
namespace content {
class BrowserMainRunner;
class ContentMainRunner;
+class GpuProcess;
+class GpuThreadController;
+class InProcessChildThreadParams;
+}
+
+namespace gpu {
+struct GpuPreferences;
+class SyncPointManager;
}
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -64,16 +73,20 @@ QT_FORWARD_DECLARE_CLASS(QObject)
namespace QtWebEngineCore {
-class ProfileAdapter;
+class AccessibilityActivationObserver;
class ContentMainDelegateQt;
class DevToolsServerQt;
+class ProfileAdapter;
bool usingSoftwareDynamicGL();
+typedef std::tuple<bool, QString, QString> ProxyAuthentication;
+
class WebEngineContext : public base::RefCounted<WebEngineContext> {
public:
static WebEngineContext *current();
static void destroyContextPostRoutine();
+ static ProxyAuthentication qProxyNetworkAuthentication(QString host, int port);
ProfileAdapter *createDefaultProfileAdapter();
ProfileAdapter *defaultProfileAdapter();
@@ -86,6 +99,9 @@ public:
void addProfileAdapter(ProfileAdapter *profileAdapter);
void removeProfileAdapter(ProfileAdapter *profileAdapter);
void destroy();
+ static base::CommandLine* commandLine();
+
+ static gpu::SyncPointManager *syncPointManager();
private:
friend class base::RefCounted<WebEngineContext>;
@@ -93,6 +109,9 @@ private:
WebEngineContext();
~WebEngineContext();
+ static void registerMainThreadFactories(bool threaded);
+ static void destroyGpuProcess();
+
std::unique_ptr<base::RunLoop> m_runLoop;
std::unique_ptr<ContentMainDelegateQt> m_mainDelegate;
std::unique_ptr<content::ContentMainRunner> m_contentRunner;
@@ -101,12 +120,16 @@ private:
std::unique_ptr<ProfileAdapter> m_defaultProfileAdapter;
std::unique_ptr<DevToolsServerQt> m_devtoolsServer;
QVector<ProfileAdapter*> m_profileAdapters;
+#ifndef QT_NO_ACCESSIBILITY
+ std::unique_ptr<AccessibilityActivationObserver> m_accessibilityActivationObserver;
+#endif
#if QT_CONFIG(webengine_printing_and_pdf)
std::unique_ptr<printing::PrintJobManager> m_printJobManager;
#endif
static scoped_refptr<QtWebEngineCore::WebEngineContext> m_handle;
static bool m_destroyed;
+ static QAtomicPointer<gpu::SyncPointManager> s_syncPointManager;
};
} // namespace
diff --git a/src/core/web_engine_context_threads.cpp b/src/core/web_engine_context_threads.cpp
new file mode 100644
index 000000000..e92cf3e9b
--- /dev/null
+++ b/src/core/web_engine_context_threads.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "web_engine_context.h"
+
+#include "base/bind.h"
+#include "base/task/post_task.h"
+#include "base/threading/platform_thread.h"
+#include "base/threading/thread_restrictions.h"
+#include "content/browser/gpu/gpu_main_thread_factory.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/utility_process_host.h"
+#include "content/gpu/gpu_child_thread.h"
+#include "content/gpu/gpu_process.h"
+#include "content/gpu/in_process_gpu_thread.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/renderer/in_process_renderer_thread.h"
+#include "content/utility/in_process_utility_thread.h"
+#include "gpu/ipc/service/gpu_init.h"
+
+#include <memory>
+
+namespace QtWebEngineCore {
+
+struct GpuThreadControllerQt : content::GpuThreadController
+{
+ GpuThreadControllerQt(const content::InProcessChildThreadParams &params, const gpu::GpuPreferences &gpuPreferences)
+ {
+ base::PostTaskWithTraits(
+ FROM_HERE, { content::BrowserThread::UI },
+ base::BindOnce(&GpuThreadControllerQt::createGpuProcess, params, gpuPreferences));
+ }
+ ~GpuThreadControllerQt() override
+ {
+ base::PostTaskWithTraits(
+ FROM_HERE, { content::BrowserThread::UI },
+ base::BindOnce(&GpuThreadControllerQt::destroyGpuProcess));
+ }
+
+ static void createGpuProcess(
+ const content::InProcessChildThreadParams &params,
+ const gpu::GpuPreferences &gpuPreferences)
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (s_gpuProcessDestroyed)
+ return;
+
+ s_gpuProcess = std::make_unique<content::GpuProcess>(base::ThreadPriority::DISPLAY);
+ auto gpuInit = std::make_unique<gpu::GpuInit>();
+ gpuInit->InitializeInProcess(base::CommandLine::ForCurrentProcess(), gpuPreferences);
+ auto childThread = new content::GpuChildThread(params, std::move(gpuInit));
+ childThread->Init(base::Time::Now());
+ s_gpuProcess->set_main_thread(childThread);
+ }
+
+ static void destroyGpuProcess()
+ {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (s_gpuProcessDestroyed)
+ return;
+
+ // viz::GpuServiceImpl::~GpuServiceImpl waits for io task.
+ base::ScopedAllowBaseSyncPrimitivesForTesting allow;
+ s_gpuProcess.reset();
+ s_gpuProcessDestroyed = true;
+ }
+
+ static std::unique_ptr<content::GpuProcess> s_gpuProcess;
+ static bool s_gpuProcessDestroyed;
+};
+
+std::unique_ptr<content::GpuProcess> GpuThreadControllerQt::s_gpuProcess;
+bool GpuThreadControllerQt::s_gpuProcessDestroyed = false;
+
+static std::unique_ptr<content::GpuThreadController> createGpuThreadController(
+ const content::InProcessChildThreadParams &params,
+ const gpu::GpuPreferences &gpuPreferences)
+{
+ return std::make_unique<GpuThreadControllerQt>(params, gpuPreferences);
+}
+
+// static
+void WebEngineContext::destroyGpuProcess()
+{
+ GpuThreadControllerQt::destroyGpuProcess();
+}
+
+// static
+void WebEngineContext::registerMainThreadFactories(bool threaded)
+{
+ content::UtilityProcessHost::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
+ content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread);
+ if (threaded)
+ content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread);
+ else
+ content::RegisterGpuMainThreadFactory(createGpuThreadController);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/web_engine_error.h b/src/core/web_engine_error.h
index 20af6d31f..cda9e4625 100644
--- a/src/core/web_engine_error.h
+++ b/src/core/web_engine_error.h
@@ -53,7 +53,7 @@
#include "qtwebenginecoreglobal_p.h"
-class QWEBENGINECORE_PRIVATE_EXPORT WebEngineError
+class Q_WEBENGINECORE_PRIVATE_EXPORT WebEngineError
{
public:
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 3899ced25..1c8316430 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -54,6 +54,7 @@
#include <QDir>
#include <QFileInfo>
#include <QLibraryInfo>
+#include <QLocale>
#include <QStandardPaths>
#include <QString>
@@ -256,34 +257,6 @@ QString dictionariesPath()
}
#endif // QT_CONFIG(webengine_spellchecker)
-QString icuDataPath()
-{
- static bool initialized = false;
- static QString potentialResourcesPath =
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
- getResourcesPath(frameworkBundle());
-#else
- QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/resources");
-#endif
- if (!initialized) {
- initialized = true;
- if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) {
- qWarning("Qt WebEngine ICU data not found at %s. Trying parent directory...", qPrintable(potentialResourcesPath));
- potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath);
- }
- if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) {
- qWarning("Qt WebEngine ICU data not found at %s. Trying application directory...", qPrintable(potentialResourcesPath));
- potentialResourcesPath = QCoreApplication::applicationDirPath();
- }
- if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) {
- qWarning("Qt WebEngine ICU data not found at %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialResourcesPath));
- potentialResourcesPath = fallbackDir();
- }
- }
-
- return potentialResourcesPath;
-}
-
QString resourcesDataPath()
{
static bool initialized = false;
@@ -340,7 +313,7 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
directory = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
break;
case base::DIR_QT_LIBRARY_DATA:
- return toFilePath(icuDataPath());
+ return toFilePath(resourcesDataPath());
case ui::DIR_LOCALES:
return toFilePath(localesPath());
#if QT_CONFIG(webengine_spellchecker)
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 664951e66..b6250a65f 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -283,6 +283,11 @@ void WebEngineSettings::initDefaults()
s_defaultAttributes.insert(WebRTCPublicInterfacesOnly, false);
s_defaultAttributes.insert(JavascriptCanPaste, false);
s_defaultAttributes.insert(DnsPrefetchEnabled, false);
+#if QT_CONFIG(webengine_extensions)
+ s_defaultAttributes.insert(PdfViewerEnabled, true);
+#else
+ s_defaultAttributes.insert(PdfViewerEnabled, false);
+#endif
}
if (s_defaultFontFamilies.isEmpty()) {
@@ -340,6 +345,10 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p
{
// Override for now
prefs->touch_event_feature_detection_enabled = isTouchEventsAPIEnabled();
+#if !QT_CONFIG(webengine_embedded_build)
+ prefs->available_hover_types = ui::HOVER_TYPE_HOVER;
+ prefs->primary_hover_type = ui::HOVER_TYPE_HOVER;
+#endif
if (prefs->viewport_enabled) {
// We need to enable the viewport options together as it doesn't really work
// to enable them separately. With viewport-enabled we match Android defaults.
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index 8930d7c27..b2a45098a 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -68,7 +68,7 @@ namespace QtWebEngineCore {
class WebContentsAdapter;
-class QWEBENGINECORE_PRIVATE_EXPORT WebEngineSettings {
+class Q_WEBENGINECORE_PRIVATE_EXPORT WebEngineSettings {
public:
// Attributes. Names match the ones from the public widgets API.
enum Attribute {
@@ -103,6 +103,7 @@ public:
WebRTCPublicInterfacesOnly,
JavascriptCanPaste,
DnsPrefetchEnabled,
+ PdfViewerEnabled,
};
// Must match the values from the public API in qwebenginesettings.h.
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index fc6287dd9..a0fac73ec 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -101,7 +101,7 @@ static KeyboardDriver keyboardDriverImpl()
if (platformName == QLatin1Literal("xcb") || platformName == QLatin1Literal("wayland"))
return KeyboardDriver::Xkb;
-#if QT_CONFIG(libinput) && QT_CONFIG(xkbcommon)
+#if QT_CONFIG(libinput)
// Based on QEglFSIntegration::createInputHandlers and QLibInputKeyboard::processKey.
if (platformName == QLatin1Literal("eglfs") && !qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT"))
return KeyboardDriver::Xkb;
@@ -926,7 +926,7 @@ static ui::DomKey domKeyForQtKey(int qtKey)
return ui::DomKey::ZENKAKU;
case Qt::Key_Zenkaku_Hankaku:
return ui::DomKey::ZENKAKU_HANKAKU;
-
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
// Dead keys (ui/events/keycodes/keyboard_code_conversion_xkb.cc)
case Qt::Key_Dead_Grave:
return ui::DomKey::DeadKeyFromCombiningCharacter(0x0300);
@@ -994,7 +994,7 @@ static ui::DomKey domKeyForQtKey(int qtKey)
return ui::DomKey::DeadKeyFromCombiningCharacter(0x00A4);
case Qt::Key_Dead_Greek:
return ui::DomKey::DeadKeyFromCombiningCharacter(0x037E);
-
+#endif
// General-Purpose Function Keys
case Qt::Key_F1:
return ui::DomKey::F1;
@@ -1354,10 +1354,10 @@ static WebPointerProperties::PointerType pointerTypeForTabletEvent(const QTablet
}
#endif
-WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale)
+WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev)
{
WebMouseEvent webKitEvent(webEventTypeForEvent(ev),
- WebFloatPoint(ev->x() / dpiScale, ev->y() / dpiScale),
+ WebFloatPoint(ev->x(), ev->y()),
WebFloatPoint(ev->globalX(), ev->globalY()),
mouseButtonForEvent<QMouseEvent>(ev),
0,
@@ -1369,14 +1369,14 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale)
return webKitEvent;
}
-WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale)
+WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev)
{
WebMouseEvent webKitEvent;
webKitEvent.SetTimeStamp(base::TimeTicks::Now());
webKitEvent.SetModifiers(modifiersForEvent(ev));
webKitEvent.SetType(webEventTypeForEvent(ev));
- webKitEvent.SetPositionInWidget(ev->pos().x() / dpiScale, ev->pos().y() / dpiScale);
+ webKitEvent.SetPositionInWidget(ev->pos().x(), ev->pos().y());
webKitEvent.movement_x = ev->pos().x() - ev->oldPos().x();
webKitEvent.movement_y = ev->pos().y() - ev->oldPos().y();
webKitEvent.pointer_type = WebPointerProperties::PointerType::kMouse;
@@ -1385,10 +1385,10 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale)
}
#if QT_CONFIG(tabletevent)
-WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev, double dpiScale)
+WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev)
{
WebMouseEvent webKitEvent(webEventTypeForEvent(ev),
- WebFloatPoint(ev->x() / dpiScale, ev->y() / dpiScale),
+ WebFloatPoint(ev->x(), ev->y()),
WebFloatPoint(ev->globalX(), ev->globalY()),
mouseButtonForEvent<QTabletEvent>(ev),
0,
@@ -1416,17 +1416,17 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev)
}
#ifndef QT_NO_GESTURES
-WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, double dpiScale)
+WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev)
{
WebGestureEvent webKitEvent;
webKitEvent.SetTimeStamp(base::TimeTicks::Now());
webKitEvent.SetModifiers(modifiersForEvent(ev));
- webKitEvent.SetPositionInWidget(WebFloatPoint(ev->localPos().x() / dpiScale,
- ev->localPos().y() / dpiScale));
+ webKitEvent.SetPositionInWidget(WebFloatPoint(ev->localPos().x(),
+ ev->localPos().y()));
- webKitEvent.SetPositionInScreen(WebFloatPoint(ev->screenPos().x() / dpiScale,
- ev->screenPos().y() / dpiScale));
+ webKitEvent.SetPositionInScreen(WebFloatPoint(ev->screenPos().x(),
+ ev->screenPos().y()));
webKitEvent.SetSourceDevice(blink::kWebGestureDeviceTouchpad);
@@ -1484,13 +1484,13 @@ blink::WebMouseWheelEvent::Phase toBlinkPhase(QWheelEvent *ev)
return blink::WebMouseWheelEvent::kPhaseNone;
}
-blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, double dpiScale)
+blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev)
{
WebMouseWheelEvent webEvent;
webEvent.SetType(webEventTypeForEvent(ev));
webEvent.SetModifiers(modifiersForEvent(ev));
webEvent.SetTimeStamp(base::TimeTicks::Now());
- webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale);
+ webEvent.SetPositionInWidget(ev->x(), ev->y());
webEvent.SetPositionInScreen(ev->globalX(), ev->globalY());
webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep;
@@ -1506,7 +1506,7 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, doub
return webEvent;
}
-bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent, QWheelEvent *ev, double dpiScale)
+bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent, QWheelEvent *ev)
{
if (webEventTypeForEvent(ev) != webEvent.GetType())
return false;
@@ -1520,7 +1520,7 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent,
#endif
webEvent.SetTimeStamp(base::TimeTicks::Now());
- webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale);
+ webEvent.SetPositionInWidget(ev->x(), ev->y());
webEvent.SetPositionInScreen(ev->globalX(), ev->globalY());
webEvent.wheel_ticks_x += static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep;
diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h
index 4b22de7d7..526202cfb 100644
--- a/src/core/web_event_factory.h
+++ b/src/core/web_event_factory.h
@@ -66,17 +66,17 @@ QT_END_NAMESPACE
class WebEventFactory {
public:
- static blink::WebMouseEvent toWebMouseEvent(QMouseEvent*, double dpiScale);
- static blink::WebMouseEvent toWebMouseEvent(QHoverEvent*, double dpiScale);
+ static blink::WebMouseEvent toWebMouseEvent(QMouseEvent *);
+ static blink::WebMouseEvent toWebMouseEvent(QHoverEvent *);
#ifndef QT_NO_TABLETEVENT
- static blink::WebMouseEvent toWebMouseEvent(QTabletEvent*, double dpiScale);
+ static blink::WebMouseEvent toWebMouseEvent(QTabletEvent *);
#endif
static blink::WebMouseEvent toWebMouseEvent(QEvent *);
#ifndef QT_NO_GESTURES
- static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *, double dpiScale);
+ static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *);
#endif
- static blink::WebMouseWheelEvent toWebWheelEvent(QWheelEvent*, double dpiScale);
- static bool coalesceWebWheelEvent(blink::WebMouseWheelEvent &, QWheelEvent*, double dpiScale);
+ static blink::WebMouseWheelEvent toWebWheelEvent(QWheelEvent *);
+ static bool coalesceWebWheelEvent(blink::WebMouseWheelEvent &, QWheelEvent *);
static content::NativeWebKeyboardEvent toWebKeyboardEvent(QKeyEvent*);
static bool getEditCommand(QKeyEvent *event, std::string *editCommand);
};
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 32fce325b..6698a9736 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-qtHaveModule(designer):qtHaveModule(webenginewidgets): SUBDIRS += qwebengineview
+qtHaveModule(designer): SUBDIRS += qwebengineview
diff --git a/src/src.pro b/src/src.pro
index 218cdb66d..30562686a 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -14,11 +14,7 @@ core.depends = buildtools
SUBDIRS += buildtools \
core \
- process \
- webengine \
- webengine_plugin \
- plugins
-
+ process
qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile {
SUBDIRS += qwebengine_convert_dict
@@ -26,19 +22,11 @@ qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross
qwebengine_convert_dict.depends = core
}
-qtConfig(webengine-testsupport) {
- webengine_testsupport_plugin.subdir = webengine/plugin/testsupport
- webengine_testsupport_plugin.target = sub-webengine-testsupport-plugin
- webengine_testsupport_plugin.depends = webengine
- SUBDIRS += webengine_testsupport_plugin
-}
-
-qtConfig(webengine-ui-delegates) {
- SUBDIRS += webengine/ui \
- webengine/ui2
+qtConfig(webengine-qml) {
+ SUBDIRS += webengine
}
-qtHaveModule(widgets) {
- SUBDIRS += webenginewidgets
+qtConfig(webengine-widgets) {
+ SUBDIRS += plugins webenginewidgets
plugins.depends = webenginewidgets
}
diff --git a/src/tools/qwebengine_convert_dict/main.cpp b/src/tools/qwebengine_convert_dict/main.cpp
index 9d3888ad6..1694dbcef 100644
--- a/src/tools/qwebengine_convert_dict/main.cpp
+++ b/src/tools/qwebengine_convert_dict/main.cpp
@@ -111,7 +111,9 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
base::span<const int> expectedAffixes(org_words[i].second);
base::span<const int> actualAffixes(affix_ids, affix_matches);
- if (expectedAffixes != actualAffixes) {
+ if (!std::equal(expectedAffixes.begin(), expectedAffixes.end(),
+ actualAffixes.begin(), actualAffixes.end(),
+ [](int a, int b) { return a == b; })) {
out << "Affixes do not match!\n"
<< " Index: " << i << "\n"
<< " Word: " << QString::fromUtf8(buf) << "\n"
diff --git a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro
index ced90655e..27edd66d8 100644
--- a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro
+++ b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro
@@ -39,6 +39,8 @@ SOURCES += \
QMAKE_TARGET_DESCRIPTION = "Qt WebEngine Dictionary Converter"
+CONFIG += c++14
+
# Support converting dictionaries in a prefix build, by supplying
# the path to the ICU data file located in the Qt build path, rather
# than the install path (which is not present at build time).
diff --git a/src/webengine/api/qquickwebengineclientcertificateselection.cpp b/src/webengine/api/qquickwebengineclientcertificateselection.cpp
new file mode 100644
index 000000000..c48a59887
--- /dev/null
+++ b/src/webengine/api/qquickwebengineclientcertificateselection.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickwebengineclientcertificateselection_p.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+
+#include "client_cert_select_controller.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype WebEngineClientCertificateOption
+ \instantiates QQuickWebEngineClientCertificateOption
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 1.9
+ \brief Represents a client certificate option.
+
+ \sa {WebEngineClientCertificateSelection::certificates} {WebEngineClientCertificateSelection.certificates}
+*/
+
+QQuickWebEngineClientCertificateOption::QQuickWebEngineClientCertificateOption(QQuickWebEngineClientCertificateSelection *selection, int index)
+ : QObject(selection), m_selection(selection), m_index(index)
+{}
+
+/*!
+ \qmlproperty string WebEngineClientCertificateOption::issuer
+ \brief The issuer of the certificate.
+*/
+
+QString QQuickWebEngineClientCertificateOption::issuer() const
+{
+ return m_selection->d_ptr->certificates().at(m_index).issuerDisplayName();
+}
+
+/*!
+ \qmlproperty string WebEngineClientCertificateOption::subject
+ \brief The subject of the certificate.
+*/
+QString QQuickWebEngineClientCertificateOption::subject() const
+{
+ return m_selection->d_ptr->certificates().at(m_index).subjectDisplayName();
+}
+
+/*!
+ \qmlproperty datetime WebEngineClientCertificateOption::effectiveDate
+ \brief The date and time when the certificate becomes valid.
+*/
+QDateTime QQuickWebEngineClientCertificateOption::effectiveDate() const
+{
+ return m_selection->d_ptr->certificates().at(m_index).effectiveDate();
+}
+
+/*!
+ \qmlproperty datetime WebEngineClientCertificateOption::expiryDate
+ \brief The date and time when the certificate becomes invalid.
+*/
+QDateTime QQuickWebEngineClientCertificateOption::expiryDate() const
+{
+ return m_selection->d_ptr->certificates().at(m_index).expiryDate();
+}
+
+/*!
+ \qmlproperty bool WebEngineClientCertificateOption::isSelfSigned
+ \brief Whether the certificate is only self-signed.
+*/
+bool QQuickWebEngineClientCertificateOption::isSelfSigned() const
+{
+ return m_selection->d_ptr->certificates().at(m_index).isSelfSigned();
+}
+
+/*!
+ \qmlmethod void WebEngineClientCertificateOption::select()
+
+ Selects this client certificate option.
+*/
+void QQuickWebEngineClientCertificateOption::select()
+{
+ m_selection->select(m_index);
+}
+
+/*!
+ \qmltype WebEngineClientCertificateSelection
+ \instantiates QQuickWebEngineClientCertificateSelection
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 1.9
+ \brief Provides a selection of client certificates.
+
+ When a web site requests an SSL client certificate, and one or more certificates
+ are found in the system's client certificate store, this type provides access to
+ the certificates to choose from, as well as a method for selecting one.
+
+ The selection is asynchronous. If no certificate is selected and no copy of the
+ object is kept alive, loading will continue without a certificate.
+
+ \sa {WebEngineView::selectClientCertificate}{WebEngineView.selectClientCertificate}
+*/
+
+QQuickWebEngineClientCertificateSelection::QQuickWebEngineClientCertificateSelection(QSharedPointer<ClientCertSelectController> selectController)
+ : QObject(), d_ptr(selectController)
+{}
+
+int QQuickWebEngineClientCertificateSelection::certificates_count(
+ QQmlListProperty<QQuickWebEngineClientCertificateOption> *p)
+{
+ Q_ASSERT(p && p->object);
+ QQuickWebEngineClientCertificateSelection *d = static_cast<QQuickWebEngineClientCertificateSelection *>(p->object);
+ return d->m_certificates.size();
+}
+
+QQuickWebEngineClientCertificateOption *QQuickWebEngineClientCertificateSelection::certificates_at(
+ QQmlListProperty<QQuickWebEngineClientCertificateOption> *p, int idx)
+{
+ Q_ASSERT(p && p->object);
+ QQuickWebEngineClientCertificateSelection *d = static_cast<QQuickWebEngineClientCertificateSelection *>(p->object);
+ if (idx < 0 || idx >= d->m_certificates.size())
+ return nullptr;
+ return d->m_certificates[idx];
+}
+
+/*!
+ \qmlproperty list<WebEngineClientCertificateOption> WebEngineClientCertificateSelection::certificates
+ \brief The client certificates available to choose from.
+*/
+
+QQmlListProperty<QQuickWebEngineClientCertificateOption> QQuickWebEngineClientCertificateSelection::certificates()
+{
+ if (m_certificates.empty()) {
+ QVector<QSslCertificate> certificates = d_ptr->certificates();
+ for (int i = 0; i < certificates.count(); ++i)
+ m_certificates.push_back(new QQuickWebEngineClientCertificateOption(this, i));
+ }
+
+ return QQmlListProperty<QQuickWebEngineClientCertificateOption>(
+ this, nullptr,
+ certificates_count,
+ certificates_at);
+}
+
+/*!
+ \qmlmethod void WebEngineClientCertificateSelection::select(WebEngineClientCertificateOption certificate)
+
+ Selects the client certificate \a certificate. The certificate must be one
+ of the offered certificates.
+
+ \sa selectNone()
+*/
+void QQuickWebEngineClientCertificateSelection::select(const QQuickWebEngineClientCertificateOption *certificate)
+{
+ select(certificate->m_index);
+}
+
+/*!
+ \qmlmethod void WebEngineClientCertificateSelection::select(int index)
+
+ Selects the client certificate at the index \a index in the list of offered certificates.
+
+ \sa selectNone()
+*/
+void QQuickWebEngineClientCertificateSelection::select(int index)
+{
+ d_ptr->select(index);
+}
+
+/*!
+ \qmlmethod void WebEngineClientCertificateSelection::selectNone()
+
+ Continues without using any of the offered certificates. This is the same
+ action as taken when destroying the last copy of this object if no
+ selection has been made.
+
+ \sa select()
+*/
+void QQuickWebEngineClientCertificateSelection::selectNone()
+{
+ d_ptr->selectNone();
+}
+
+/*!
+ \qmlproperty url WebEngineClientCertificateSelection::host
+ \brief The host and port of the server requesting the client certificate.
+*/
+QUrl QQuickWebEngineClientCertificateSelection::host() const
+{
+ return d_ptr->hostAndPort();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
diff --git a/src/webengine/api/qquickwebengineclientcertificateselection_p.h b/src/webengine/api/qquickwebengineclientcertificateselection_p.h
new file mode 100644
index 000000000..adf8b5f7c
--- /dev/null
+++ b/src/webengine/api/qquickwebengineclientcertificateselection_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINECERTSELECTION_P_H
+#define QQUICKWEBENGINECERTSELECTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWebEngine/private/qtwebengineglobal_p.h>
+
+#include <QtCore/QDateTime>
+#include <QtCore/QObject>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QUrl>
+#include <QtCore/QVector>
+#include <QtQml/QQmlListProperty>
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+
+QT_BEGIN_NAMESPACE
+
+class ClientCertSelectController;
+class QQuickWebEngineClientCertificateSelection;
+
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineClientCertificateOption : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QString issuer READ issuer CONSTANT FINAL)
+ Q_PROPERTY(QString subject READ subject CONSTANT FINAL)
+ Q_PROPERTY(QDateTime effectiveDate READ effectiveDate CONSTANT FINAL)
+ Q_PROPERTY(QDateTime expiryDate READ expiryDate CONSTANT FINAL)
+ Q_PROPERTY(bool isSelfSigned READ isSelfSigned CONSTANT FINAL)
+
+public:
+ QString issuer() const;
+ QString subject() const;
+ QDateTime effectiveDate() const;
+ QDateTime expiryDate() const;
+ bool isSelfSigned() const;
+
+ Q_INVOKABLE void select();
+
+private:
+ friend class QQuickWebEngineClientCertificateSelection;
+ QQuickWebEngineClientCertificateOption(QQuickWebEngineClientCertificateSelection *selection, int index);
+
+ QQuickWebEngineClientCertificateSelection *m_selection;
+ int m_index;
+};
+
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineClientCertificateSelection : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QUrl host READ host CONSTANT FINAL)
+ Q_PROPERTY(QQmlListProperty<QQuickWebEngineClientCertificateOption> certificates READ certificates CONSTANT FINAL)
+
+public:
+ QQuickWebEngineClientCertificateSelection() = default;
+
+ QUrl host() const;
+
+ Q_INVOKABLE void select(int idx);
+ Q_INVOKABLE void select(const QQuickWebEngineClientCertificateOption *certificate);
+ Q_INVOKABLE void selectNone();
+ QQmlListProperty<QQuickWebEngineClientCertificateOption> certificates();
+
+private:
+ friend class QQuickWebEngineViewPrivate;
+ friend class QQuickWebEngineClientCertificateOption;
+
+ static int certificates_count(QQmlListProperty<QQuickWebEngineClientCertificateOption> *p);
+ static QQuickWebEngineClientCertificateOption *certificates_at(QQmlListProperty<QQuickWebEngineClientCertificateOption> *p, int idx);
+
+ explicit QQuickWebEngineClientCertificateSelection(QSharedPointer<ClientCertSelectController>);
+
+ mutable QVector<QQuickWebEngineClientCertificateOption *> m_certificates;
+ QSharedPointer<ClientCertSelectController> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QQuickWebEngineClientCertificateOption *)
+Q_DECLARE_METATYPE(QQmlListProperty<QQuickWebEngineClientCertificateOption>)
+Q_DECLARE_METATYPE(QQuickWebEngineClientCertificateSelection *)
+
+#endif
+
+#endif // QQUICKWEBENGINECERTSELECTION_P_H
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index f77f376aa..7630587fe 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -46,6 +46,7 @@
#include "qquickwebenginesettings_p.h"
#include "qquickwebengineview_p_p.h"
#include "qwebenginecookiestore.h"
+#include "qwebenginenotification.h"
#include <QQmlEngine>
@@ -150,6 +151,16 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineDownloadItem::MimeHtmlSaveFormat, QtWebEngineC
The \a download argument holds the state of the finished download instance.
*/
+/*!
+ \fn QQuickWebEngineProfile::presentNotification(QWebEngineNotification *notification)
+
+ This signal is emitted whenever there is a newly created user notification.
+ The \a notification argument holds the \l {QWebEngineNotification} instance
+ to query data and interact with.
+
+ \sa WebEngineProfile::presentNotification
+*/
+
QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter)
: m_settings(new QQuickWebEngineSettings())
, m_profileAdapter(profileAdapter)
@@ -285,6 +296,20 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info
}
}
+void QQuickWebEngineProfilePrivate::useForGlobalCertificateVerificationChanged()
+{
+ Q_Q(QQuickWebEngineProfile);
+ Q_EMIT q->useForGlobalCertificateVerificationChanged();
+}
+
+void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller)
+{
+ Q_Q(QQuickWebEngineProfile);
+ auto notification = new QWebEngineNotification(controller);
+ QQmlEngine::setObjectOwnership(notification, QQmlEngine::JavaScriptOwnership);
+ Q_EMIT q->presentNotification(notification);
+}
+
void QQuickWebEngineProfilePrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script)
{
Q_ASSERT(p && p->data);
@@ -365,6 +390,15 @@ void QQuickWebEngineProfilePrivate::userScripts_clear(QQmlListProperty<QQuickWeb
*/
/*!
+ \qmlsignal WebEngineProfile::presentNotification(WebEngineNotification notification)
+ \since QtWebEngine 1.9
+
+ This signal is emitted whenever there is a newly created user notification.
+ The \a notification argument holds the \l {WebEngineNotification} instance
+ to query data and interact with.
+*/
+
+/*!
Constructs a new profile with the parent \a parent.
*/
QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent)
@@ -796,6 +830,102 @@ bool QQuickWebEngineProfile::isSpellCheckEnabled() const
}
/*!
+ \property QQuickWebEngineProfile::useForGlobalCertificateVerification
+ \since 5.13
+
+ This property holds whether this profile is used for downloading and
+ caching during global certificate verification when using the online
+ certificate status protocol (OCSP), certificate revokation lists (CRLs),
+ and authority information access (AIA), for example.
+
+ As long as one profile has this option enabled, all other profiles will be
+ able to use it for certificate verification. Only one profile at a time can
+ have this option enabled. It is recommended that the profile has a disk HTTP
+ cache to avoid needlessly re-downloading.
+
+ By default, no profile has this property enabled.
+
+ Currently, only affects Linux/NSS installations, where having a profile with
+ this role enables OCSP.
+*/
+
+/*!
+ \qmlproperty bool WebEngineProfile::useForGlobalCertificateVerification
+ \since QtWebEngine 1.9
+
+ This property holds whether this profile is used for downloading and
+ caching during global certificate verification when using the online
+ certificate status protocol (OCSP), certificate revokation lists (CRLs),
+ and authority information access (AIA), for example.
+
+ As long as one profile has this option enabled, all other profiles will be
+ able to use it for certificate verification. Only one profile at a time can
+ have this option enabled. It is recommended that the profile has a disk HTTP
+ cache to avoid needlessly re-downloading.
+
+ By default, no profile has this property enabled.
+
+ Currently, only affects Linux/NSS installations, where having a profile with
+ this role enables OCSP.
+*/
+
+void QQuickWebEngineProfile::setUseForGlobalCertificateVerification(bool enable)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (enable != d->profileAdapter()->isUsedForGlobalCertificateVerification()) {
+ d->profileAdapter()->setUseForGlobalCertificateVerification(enable);
+ emit useForGlobalCertificateVerificationChanged();
+ }
+}
+
+bool QQuickWebEngineProfile::isUsedForGlobalCertificateVerification() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->profileAdapter()->isUsedForGlobalCertificateVerification();
+}
+
+/*!
+ \qmlproperty string WebEngineProfile::downloadPath
+ \since QtWebEngine 1.9
+
+ The path to the location where the downloaded files are stored.
+
+ Overrides the default path used for download location.
+
+ If set to an empty string, the default path is restored.
+
+ \note By default, the download path is QStandardPaths::DownloadLocation.
+*/
+
+/*!
+ \property QQuickWebEngineProfile::downloadPath
+ \since QtWebEngine 1.9
+
+ The path to the location where the downloaded files are stored.
+
+ Overrides the default path used for download location, setting it to \a path.
+
+ If set to an empty string, the default path is restored.
+
+ \note By default, the download path is QStandardPaths::DownloadLocation.
+*/
+
+void QQuickWebEngineProfile::setDownloadPath(const QString &path)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (downloadPath() == path)
+ return;
+ d->profileAdapter()->setDownloadPath(path);
+ emit downloadPathChanged();
+}
+
+QString QQuickWebEngineProfile::downloadPath() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->profileAdapter()->downloadPath();
+}
+
+/*!
Returns the cookie store for this profile.
*/
@@ -827,27 +957,52 @@ void QQuickWebEngineProfile::clearHttpCache()
d->profileAdapter()->clearHttpCache();
}
-
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Registers a request interceptor singleton \a interceptor to intercept URL requests.
The profile does not take ownership of the pointer.
+ \obsolete
+
+ Interceptors installed with this method will call
+ QWebEngineUrlRequestInterceptor::interceptRequest on the I/O thread. Therefore
+ the user has to provide thread-safe interaction with the other user classes.
+ Use setUrlRequestInterceptor instead.
+
\sa QWebEngineUrlRequestInterceptor
+
*/
void QQuickWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
Q_D(QQuickWebEngineProfile);
+ interceptor->setProperty("deprecated", true);
+ d->profileAdapter()->setRequestInterceptor(interceptor);
+ qWarning("Use of deprecated not tread-safe setter, use setUrlRequestInterceptor instead.");
+}
+#endif
+
+/*!
+ Registers a request interceptor singleton \a interceptor to intercept URL requests.
+
+ The profile does not take ownership of the pointer.
+
+ \sa QWebEngineUrlRequestInfo QWebEngineUrlRequestInterceptor
+*/
+void QQuickWebEngineProfile::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ Q_D(QQuickWebEngineProfile);
d->profileAdapter()->setRequestInterceptor(interceptor);
}
+
/*!
Returns the custom URL scheme handler register for the URL scheme \a scheme.
*/
const QWebEngineUrlSchemeHandler *QQuickWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const
{
const Q_D(QQuickWebEngineProfile);
- return d->profileAdapter()->customUrlSchemeHandlers().value(scheme.toLower());
+ return d->profileAdapter()->urlSchemeHandler(scheme);
}
/*!
@@ -859,10 +1014,7 @@ const QWebEngineUrlSchemeHandler *QQuickWebEngineProfile::urlSchemeHandler(const
void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
Q_D(QQuickWebEngineProfile);
- Q_ASSERT(handler);
- if (!d->profileAdapter()->addCustomUrlSchemeHandler(scheme, handler))
- return;
- connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->installUrlSchemeHandler(scheme, handler);
}
/*!
@@ -873,10 +1025,7 @@ void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, Q
void QQuickWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
{
Q_D(QQuickWebEngineProfile);
- Q_ASSERT(handler);
- if (!d->profileAdapter()->removeCustomUrlSchemeHandler(handler))
- return;
- disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->removeUrlSchemeHandler(handler);
}
/*!
@@ -887,10 +1036,7 @@ void QQuickWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *
void QQuickWebEngineProfile::removeUrlScheme(const QByteArray &scheme)
{
Q_D(QQuickWebEngineProfile);
- QWebEngineUrlSchemeHandler *handler = d->profileAdapter()->takeCustomUrlSchemeHandler(scheme);
- if (!handler)
- return;
- disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->removeUrlScheme(scheme);
}
/*!
@@ -899,12 +1045,7 @@ void QQuickWebEngineProfile::removeUrlScheme(const QByteArray &scheme)
void QQuickWebEngineProfile::removeAllUrlSchemeHandlers()
{
Q_D(QQuickWebEngineProfile);
- d->profileAdapter()->clearCustomUrlSchemeHandlers();
-}
-
-void QQuickWebEngineProfile::destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj)
-{
- removeUrlSchemeHandler(obj);
+ d->profileAdapter()->removeAllUrlSchemeHandlers();
}
QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
@@ -942,4 +1083,19 @@ QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineProfile::userScripts()
d->userScripts_clear);
}
+/*!
+ \since 5.13
+
+ Returns the profile's client certificate store.
+*/
+QWebEngineClientCertificateStore *QQuickWebEngineProfile::clientCertificateStore()
+{
+#if QT_CONFIG(ssl)
+ Q_D(QQuickWebEngineProfile);
+ return d->profileAdapter()->clientCertificateStore();
+#else
+ return nullptr;
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index 9fc4f9eca..e5f7ff713 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -54,7 +54,9 @@ class QQuickWebEngineDownloadItem;
class QQuickWebEngineProfilePrivate;
class QQuickWebEngineScript;
class QQuickWebEngineSettings;
+class QWebEngineClientCertificateStore;
class QWebEngineCookieStore;
+class QWebEngineNotification;
class QWebEngineUrlRequestInterceptor;
class QWebEngineUrlSchemeHandler;
@@ -72,6 +74,12 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject {
Q_PROPERTY(QStringList spellCheckLanguages READ spellCheckLanguages WRITE setSpellCheckLanguages NOTIFY spellCheckLanguagesChanged FINAL REVISION 3)
Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION 3)
Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 4)
+ Q_PROPERTY(bool useForGlobalCertificateVerification
+ READ isUsedForGlobalCertificateVerification
+ WRITE setUseForGlobalCertificateVerification
+ NOTIFY useForGlobalCertificateVerificationChanged
+ FINAL REVISION 5)
+ Q_PROPERTY(QString downloadPath READ downloadPath WRITE setDownloadPath NOTIFY downloadPathChanged FINAL REVISION 5)
public:
QQuickWebEngineProfile(QObject *parent = Q_NULLPTR);
@@ -120,7 +128,10 @@ public:
QWebEngineCookieStore *cookieStore() const;
+#if QT_DEPRECATED_SINCE(5, 13)
void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+#endif
+ void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const;
void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *);
@@ -137,6 +148,14 @@ public:
QQmlListProperty<QQuickWebEngineScript> userScripts();
+ void setUseForGlobalCertificateVerification(bool b);
+ bool isUsedForGlobalCertificateVerification() const;
+
+ QString downloadPath() const;
+ void setDownloadPath(const QString &path);
+
+ QWebEngineClientCertificateStore *clientCertificateStore();
+
static QQuickWebEngineProfile *defaultProfile();
Q_SIGNALS:
@@ -151,12 +170,13 @@ Q_SIGNALS:
Q_REVISION(1) void httpAcceptLanguageChanged();
Q_REVISION(3) void spellCheckLanguagesChanged();
Q_REVISION(3) void spellCheckEnabledChanged();
+ Q_REVISION(5) void useForGlobalCertificateVerificationChanged();
+ Q_REVISION(5) void downloadPathChanged();
void downloadRequested(QQuickWebEngineDownloadItem *download);
void downloadFinished(QQuickWebEngineDownloadItem *download);
-private Q_SLOTS:
- void destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj);
+ Q_REVISION(5) void presentNotification(QWebEngineNotification *notification);
private:
Q_DECLARE_PRIVATE(QQuickWebEngineProfile)
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 41e513f4c..c6d412ab3 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -85,6 +85,10 @@ public:
void downloadRequested(DownloadItemInfo &info) override;
void downloadUpdated(const DownloadItemInfo &info) override;
+ void useForGlobalCertificateVerificationChanged() override;
+
+ void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) override;
+
// QQmlListPropertyHelpers
static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script);
static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p);
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 6e96e76cf..9a102a504 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -250,7 +250,7 @@ bool QQuickWebEngineSettings::pluginsEnabled() const
Tells the web engine whether fullscreen is supported in this application or not.
- Enabled by default.
+ Disabled by default.
*/
bool QQuickWebEngineSettings::fullScreenSupportEnabled() const
{
@@ -457,6 +457,20 @@ bool QQuickWebEngineSettings::dnsPrefetchEnabled() const
}
/*!
+ \qmlproperty bool WebEngineSettings::pdfViewerEnabled
+ \since QtWebEngine 1.9
+
+ Specifies that PDF documents will be opened in the internal PDF viewer
+ instead of being downloaded.
+
+ Enabled by default.
+*/
+bool QQuickWebEngineSettings::pdfViewerEnabled() const
+{
+ return d_ptr->testAttribute(WebEngineSettings::PdfViewerEnabled);
+}
+
+/*!
\qmlproperty string WebEngineSettings::defaultTextEncoding
\since QtWebEngine 1.2
@@ -714,6 +728,14 @@ void QQuickWebEngineSettings::setDnsPrefetchEnabled(bool on)
Q_EMIT dnsPrefetchEnabledChanged();
}
+void QQuickWebEngineSettings::setPdfViewerEnabled(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(WebEngineSettings::PdfViewerEnabled);
+ d_ptr->setAttribute(WebEngineSettings::PdfViewerEnabled, on);
+ if (wasOn != on)
+ Q_EMIT pdfViewerEnabledChanged();
+}
+
void QQuickWebEngineSettings::setUnknownUrlSchemePolicy(QQuickWebEngineSettings::UnknownUrlSchemePolicy policy)
{
WebEngineSettings::UnknownUrlSchemePolicy oldPolicy = d_ptr->unknownUrlSchemePolicy();
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 6e1aaca39..ce43e0e9c 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -93,6 +93,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_PROPERTY(bool webRTCPublicInterfacesOnly READ webRTCPublicInterfacesOnly WRITE setWebRTCPublicInterfacesOnly NOTIFY webRTCPublicInterfacesOnlyChanged REVISION 6 FINAL)
Q_PROPERTY(bool javascriptCanPaste READ javascriptCanPaste WRITE setJavascriptCanPaste NOTIFY javascriptCanPasteChanged REVISION 6 FINAL)
Q_PROPERTY(bool dnsPrefetchEnabled READ dnsPrefetchEnabled WRITE setDnsPrefetchEnabled NOTIFY dnsPrefetchEnabledChanged REVISION 7 FINAL)
+ Q_PROPERTY(bool pdfViewerEnabled READ pdfViewerEnabled WRITE setPdfViewerEnabled NOTIFY pdfViewerEnabledChanged REVISION 8 FINAL)
public:
enum UnknownUrlSchemePolicy {
@@ -135,6 +136,7 @@ public:
bool webRTCPublicInterfacesOnly() const;
bool javascriptCanPaste() const;
bool dnsPrefetchEnabled() const;
+ bool pdfViewerEnabled() const;
void setAutoLoadImages(bool on);
void setJavascriptEnabled(bool on);
@@ -166,6 +168,7 @@ public:
void setWebRTCPublicInterfacesOnly(bool on);
void setJavascriptCanPaste(bool on);
void setDnsPrefetchEnabled(bool on);
+ void setPdfViewerEnabled(bool on);
signals:
void autoLoadImagesChanged();
@@ -198,6 +201,7 @@ signals:
Q_REVISION(6) void webRTCPublicInterfacesOnlyChanged();
Q_REVISION(6) void javascriptCanPasteChanged();
Q_REVISION(7) void dnsPrefetchEnabledChanged();
+ Q_REVISION(8) void pdfViewerEnabledChanged();
private:
explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = 0);
diff --git a/src/webengine/api/qquickwebenginetouchhandleprovider.cpp b/src/webengine/api/qquickwebenginetouchhandleprovider.cpp
new file mode 100644
index 000000000..80f4727b6
--- /dev/null
+++ b/src/webengine/api/qquickwebenginetouchhandleprovider.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickwebenginetouchhandleprovider_p_p.h"
+
+// static
+QString QQuickWebEngineTouchHandleProvider::identifier()
+{
+ return QStringLiteral("touchhandle");
+}
+
+// static
+QUrl QQuickWebEngineTouchHandleProvider::url(int orientation)
+{
+ return QUrl(QStringLiteral("image://%1/%2").arg(identifier(), QString::number(orientation)));
+}
+
+QQuickWebEngineTouchHandleProvider::QQuickWebEngineTouchHandleProvider()
+ : QQuickImageProvider(QQuickImageProvider::Image)
+{
+}
+
+QQuickWebEngineTouchHandleProvider::~QQuickWebEngineTouchHandleProvider()
+{
+}
+
+void QQuickWebEngineTouchHandleProvider::init(const QMap<int, QImage> &images)
+{
+ if (!m_touchHandleMap.empty()) {
+ Q_ASSERT(images.size() == m_touchHandleMap.size());
+ return;
+ }
+
+ m_touchHandleMap.unite(images);
+}
+
+QImage QQuickWebEngineTouchHandleProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
+{
+ Q_UNUSED(size);
+ Q_UNUSED(requestedSize);
+
+ Q_ASSERT(m_touchHandleMap.contains(id.toInt()));
+ return m_touchHandleMap.value(id.toInt());
+}
diff --git a/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h b/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h
new file mode 100644
index 000000000..277436289
--- /dev/null
+++ b/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
+#define QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuick/QQuickImageProvider>
+#include <QtWebEngine/private/qtwebengineglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTouchHandleProvider : public QQuickImageProvider {
+public:
+ static QString identifier();
+ static QUrl url(int orientation);
+
+ QQuickWebEngineTouchHandleProvider();
+ ~QQuickWebEngineTouchHandleProvider();
+
+ void init(const QMap<int, QImage> &images);
+ virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
+
+private:
+ QMap<int, QImage> m_touchHandleMap;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 8097689ad..fca69121a 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -39,17 +39,18 @@
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
-#include "qtwebenginecoreglobal_p.h"
#include "authentication_dialog_controller.h"
#include "profile_adapter.h"
#include "certificate_error_controller.h"
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
+#include "touch_selection_menu_controller.h"
#include "qquickwebengineaction_p.h"
#include "qquickwebengineaction_p_p.h"
#include "qquickwebenginehistory_p.h"
#include "qquickwebenginecertificateerror_p.h"
+#include "qquickwebengineclientcertificateselection_p.h"
#include "qquickwebenginecontextmenurequest_p.h"
#include "qquickwebenginedialogrequests_p.h"
#include "qquickwebenginefaviconprovider_p_p.h"
@@ -59,6 +60,7 @@
#include "qquickwebengineprofile_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginescript_p.h"
+#include "qquickwebenginetouchhandleprovider_p_p.h"
#include "qwebenginequotarequest.h"
#include "qwebengineregisterprotocolhandlerrequest.h"
@@ -126,7 +128,6 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_webChannel(0)
, m_webChannelWorld(0)
, m_isBeingAdopted(false)
- , m_dpiScale(1.0)
, m_backgroundColor(Qt::white)
, m_zoomFactor(1.0)
, m_ui2Enabled(false)
@@ -218,6 +219,7 @@ RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHo
RenderWidgetHostViewQtDelegateQuick *quickDelegate = new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ true);
if (hasWindowCapability) {
RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow = new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate);
+ wrapperWindow->setVirtualParent(q);
quickDelegate->setParentItem(wrapperWindow->contentItem());
return wrapperWindow;
}
@@ -300,9 +302,17 @@ void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<Cert
m_certificateErrorControllers.append(errorController);
}
-void QQuickWebEngineViewPrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &)
+void QQuickWebEngineViewPrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &controller)
{
- // Doing nothing will free the select-controller and perform default continue.
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ Q_Q(QQuickWebEngineView);
+ QQuickWebEngineClientCertificateSelection *certSelection = new QQuickWebEngineClientCertificateSelection(controller);
+ // mark the object for gc by creating temporary jsvalue
+ qmlEngine(q)->newQObject(certSelection);
+ Q_EMIT q->selectClientCertificate(certSelection);
+#else
+ Q_UNUSED(controller);
+#endif
}
void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url)
@@ -311,6 +321,12 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url
Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation);
}
+void QQuickWebEngineViewPrivate::runUserNotificationPermissionRequest(const QUrl &url)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Notifications);
+}
+
void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
{
Q_Q(QQuickWebEngineView);
@@ -409,11 +425,6 @@ QRectF QQuickWebEngineViewPrivate::viewportRect() const
return QRectF(q->x(), q->y(), q->width(), q->height());
}
-qreal QQuickWebEngineViewPrivate::dpiScale() const
-{
- return m_dpiScale;
-}
-
QColor QQuickWebEngineViewPrivate::backgroundColor() const
{
return m_backgroundColor;
@@ -1108,9 +1119,7 @@ void QQuickWebEngineViewPrivate::updateAdapter()
adapter->setClient(this);
if (wasInitialized) {
if (!m_html.isEmpty())
- adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url);
- else if (m_url.isValid())
- adapter->load(m_url);
+ adapter->setContent(m_html.toUtf8(), defaultMimeType, activeUrl);
else if (activeUrl.isValid())
adapter->load(activeUrl);
else
@@ -1156,12 +1165,12 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount)
callback.call(args);
}
-void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, const QByteArray &result)
+void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
{
Q_Q(QQuickWebEngineView);
QJSValue callback = m_callbacks.take(requestId);
QJSValueList args;
- args.append(qmlEngine(q)->toScriptValue(result));
+ args.append(qmlEngine(q)->toScriptValue(*(result.data())));
callback.call(args);
}
@@ -1229,6 +1238,39 @@ void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText)
ui()->showToolTip(toolTipText);
}
+QtWebEngineCore::TouchHandleDrawableClient *QQuickWebEngineViewPrivate::createTouchHandle(const QMap<int, QImage> &images)
+{
+ return new QQuickWebEngineTouchHandle(ui(), images);
+}
+
+void QQuickWebEngineViewPrivate::showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *menuController, const QRect &selectionBounds, const QSize &handleSize)
+{
+ Q_UNUSED(handleSize);
+
+ const int kSpacingBetweenButtons = 2;
+ const int kMenuButtonMinWidth = 63;
+ const int kMenuButtonMinHeight = 38;
+
+ int buttonCount = menuController->buttonCount();
+ if (buttonCount == 1) {
+ menuController->runContextMenu();
+ return;
+ }
+
+ int width = (kSpacingBetweenButtons * (buttonCount + 1)) + (kMenuButtonMinWidth * buttonCount);
+ int height = kMenuButtonMinHeight + kSpacingBetweenButtons;
+ int x = (selectionBounds.x() + selectionBounds.x() + selectionBounds.width() - width) / 2;
+ int y = selectionBounds.y() - height - 2;
+
+ QRect bounds(x, y, width, height);
+ ui()->showTouchSelectionMenu(menuController, bounds, kSpacingBetweenButtons);
+}
+
+void QQuickWebEngineViewPrivate::hideTouchSelectionMenu()
+{
+ ui()->hideTouchSelectionMenu();
+}
+
bool QQuickWebEngineView::isLoading() const
{
Q_D(const QQuickWebEngineView);
@@ -1539,6 +1581,9 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu
WebContentsAdapterClient::MediaDesktopAudioCapture |
WebContentsAdapterClient::MediaDesktopVideoCapture));
break;
+ case Notifications:
+ d_ptr->adapter->runUserNotificationRequestCallback(securityOrigin, granted);
+ break;
default:
Q_UNREACHABLE();
}
@@ -2303,5 +2348,43 @@ bool QQuickContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem)
Q_UNREACHABLE();
}
+
+QQuickWebEngineTouchHandle::QQuickWebEngineTouchHandle(QtWebEngineCore::UIDelegatesManager *ui, const QMap<int, QImage> &images)
+{
+ Q_ASSERT(ui);
+ m_item.reset(ui->createTouchHandle());
+
+ QQmlEngine *engine = qmlEngine(m_item.data());
+ Q_ASSERT(engine);
+ QQuickWebEngineTouchHandleProvider *touchHandleProvider =
+ static_cast<QQuickWebEngineTouchHandleProvider *>(engine->imageProvider(QQuickWebEngineTouchHandleProvider::identifier()));
+ Q_ASSERT(touchHandleProvider);
+ touchHandleProvider->init(images);
+}
+
+void QQuickWebEngineTouchHandle::setImage(int orientation)
+{
+ QUrl url = QQuickWebEngineTouchHandleProvider::url(orientation);
+ m_item->setProperty("source", url);
+}
+
+void QQuickWebEngineTouchHandle::setBounds(const QRect &bounds)
+{
+ m_item->setProperty("x", bounds.x());
+ m_item->setProperty("y", bounds.y());
+ m_item->setProperty("width", bounds.width());
+ m_item->setProperty("height", bounds.height());
+}
+
+void QQuickWebEngineTouchHandle::setVisible(bool visible)
+{
+ m_item->setProperty("visible", visible);
+}
+
+void QQuickWebEngineTouchHandle::setOpacity(float opacity)
+{
+ m_item->setProperty("opacity", opacity);
+}
+
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index ae92b6df0..c851dcb8d 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -51,12 +51,11 @@
// We mean it.
//
-#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include <QtWebEngine/private/qtwebengineglobal_p.h>
-#include "qquickwebenginescript.h"
#include <QQuickItem>
#include <QtGui/qcolor.h>
+#include "qquickwebenginescript.h"
QT_BEGIN_NAMESPACE
@@ -65,6 +64,7 @@ class QQuickContextMenuBuilder;
class QQuickWebEngineAction;
class QQuickWebEngineAuthenticationDialogRequest;
class QQuickWebEngineCertificateError;
+class QQuickWebEngineClientCertificateSelection;
class QQuickWebEngineColorDialogRequest;
class QQuickWebEngineContextMenuRequest;
class QQuickWebEngineFaviconProvider;
@@ -104,7 +104,7 @@ private:
const bool m_toggleOn;
};
-#define LATEST_WEBENGINEVIEW_REVISION 7
+#define LATEST_WEBENGINEVIEW_REVISION 9
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_OBJECT
@@ -209,7 +209,8 @@ public:
MediaAudioVideoCapture,
Geolocation,
DesktopVideoCapture,
- DesktopAudioVideoCapture
+ DesktopAudioVideoCapture,
+ Notifications,
};
Q_ENUM(Feature)
@@ -550,6 +551,7 @@ Q_SIGNALS:
Q_REVISION(7) void devToolsViewChanged();
Q_REVISION(7) void registerProtocolHandlerRequested(const QWebEngineRegisterProtocolHandlerRequest &request);
Q_REVISION(8) void printRequested();
+ Q_REVISION(9) void selectClientCertificate(QQuickWebEngineClientCertificateSelection *clientCertSelection);
#if QT_CONFIG(webengine_testsupport)
void testSupportChanged();
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 3b6300d5f..10fe5c2fd 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -53,6 +53,7 @@
#include "qquickwebengineview_p.h"
#include "render_view_context_menu_qt.h"
+#include "touch_handle_drawable_client.h"
#include "web_contents_adapter_client.h"
#include <QPointer>
@@ -64,6 +65,8 @@
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateQuick;
+class TouchHandleDrawableClient;
+class TouchSelectionMenuController;
class UIDelegatesManager;
class WebContentsAdapter;
}
@@ -76,6 +79,7 @@ class QQuickWebEngineContextMenuRequest;
class QQuickWebEngineSettings;
class QQuickWebEngineFaviconProvider;
class QQuickWebEngineProfilePrivate;
+class QQuickWebEngineTouchHandleProvider;
QQuickWebEngineView::WebAction editorActionForKeyEvent(QKeyEvent* event);
@@ -105,7 +109,6 @@ public:
void selectionChanged() override { }
void recentlyAudibleChanged(bool recentlyAudible) override;
QRectF viewportRect() const override;
- qreal dpiScale() const override;
QColor backgroundColor() const override;
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override;
@@ -128,7 +131,7 @@ public:
void didFetchDocumentMarkup(quint64, const QString&) override { }
void didFetchDocumentInnerText(quint64, const QString&) override { }
void didFindText(quint64, int) override;
- void didPrintPage(quint64 requestId, const QByteArray &result) override;
+ void didPrintPage(quint64 requestId, QSharedPointer<QByteArray>) override;
void didPrintPageToPdf(const QString &filePath, bool success) override;
bool passOnFocus(bool reverse) override;
void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override;
@@ -142,6 +145,7 @@ public:
void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) override;
void selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController) override;
void runGeolocationPermissionRequest(QUrl const&) override;
+ void runUserNotificationPermissionRequest(QUrl const&) override;
void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override;
void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override;
void updateScrollPosition(const QPointF &position) override;
@@ -153,6 +157,9 @@ public:
bool supportsDragging() const override;
bool isEnabled() const override;
void setToolTip(const QString &toolTipText) override;
+ QtWebEngineCore::TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &images) override;
+ void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &, const QSize &) override;
+ void hideTouchSelectionMenu() override;
const QObject *holdingQObject() const override;
ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::QmlClient; }
@@ -212,7 +219,6 @@ public:
private:
QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
QList<QQuickWebEngineScript *> m_userScripts;
- qreal m_dpiScale;
QColor m_backgroundColor;
qreal m_zoomFactor;
bool m_ui2Enabled;
@@ -254,6 +260,19 @@ private:
QObject *m_menu;
};
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTouchHandle : public QtWebEngineCore::TouchHandleDrawableClient {
+public:
+ QQuickWebEngineTouchHandle(QtWebEngineCore::UIDelegatesManager *ui, const QMap<int, QImage> &images);
+
+ void setImage(int orientation) override;
+ void setBounds(const QRect &bounds) override;
+ void setVisible(bool visible) override;
+ void setOpacity(float opacity) override;
+
+private:
+ QScopedPointer<QQuickItem> m_item;
+};
+
QT_END_NAMESPACE
#endif // QQUICKWEBENGINEVIEW_P_P_H
diff --git a/src/webengine/api/qtwebengineglobal.h b/src/webengine/api/qtwebengineglobal.h
index 2d83be674..c2b33778a 100644
--- a/src/webengine/api/qtwebengineglobal.h
+++ b/src/webengine/api/qtwebengineglobal.h
@@ -41,6 +41,7 @@
#define QTWEBENGINEGLOBAL_H
#include <QtCore/qglobal.h>
+#include <QtWebEngine/qtwebengine-config.h>
QT_BEGIN_NAMESPACE
diff --git a/src/webengine/api/qtwebengineglobal_p.h b/src/webengine/api/qtwebengineglobal_p.h
index 7058bef09..2d30f75b0 100644
--- a/src/webengine/api/qtwebengineglobal_p.h
+++ b/src/webengine/api/qtwebengineglobal_p.h
@@ -51,7 +51,9 @@
// We mean it.
//
-#include "qtwebengineglobal.h"
+#include <QtWebEngine/qtwebengineglobal.h>
+#include <QtCore/private/qglobal_p.h>
+#include <QtWebEngine/private/qtwebengine-config_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/webengine/configure.json b/src/webengine/configure.json
new file mode 100644
index 000000000..ca0e5c2fd
--- /dev/null
+++ b/src/webengine/configure.json
@@ -0,0 +1,30 @@
+{
+ "module": "webengine",
+ "depends": [
+ "webenginecore-private"
+ ],
+ "condition": "module.webenginecore",
+ "features": {
+ "webengine-ui-delegates": {
+ "label": "UI Delegates",
+ "section": "WebEngine",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-testsupport": {
+ "label": "Test Support",
+ "autoDetect": "features.private_tests || call.isTestsInBuildParts",
+ "output": [ "privateFeature" ]
+ }
+ },
+ "summary": [
+ {
+ "section": "Qt WebEngineQml",
+ "condition": "features.webengine-qml",
+ "entries": [
+ "webengine-ui-delegates",
+ "webengine-testsupport"
+ ]
+ }
+ ]
+}
+
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index 50f2e2ceb..be5db9c19 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtwebengine.qdocconf)
project = QtWebEngine
description = Qt WebEngine Reference Documentation
@@ -60,12 +61,14 @@ depends += qtcore \
qtwidgets
headerdirs += .. \
- ../../core \
- ../../webenginewidgets
+ ../../core/api \
+ ../../webenginewidgets/api
sourcedirs += .. \
- ../../core/ \
- ../../webenginewidgets \
+ ../../core/api \
+ ../../core/doc \
+ ../../webenginewidgets/api \
+ ../../webenginewidgets/doc
exampledirs += . \
../../../examples \
@@ -84,4 +87,4 @@ navigation.qmltypespage = "Qt WebEngine QML Types"
# \QWE macro expands to 'Qt WebEngine' without auto-linking anywhere.
macro.QWE = "Qt \\WebEngine"
-Cpp.ignoretokens += Q_WEBENGINE_EXPORT QWEBENGINEWIDGETS_EXPORT
+Cpp.ignoretokens += Q_WEBENGINE_EXPORT Q_WEBENGINECORE_EXPORT QWEBENGINEWIDGETS_EXPORT
diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc
index ba9823047..55f6a68a3 100644
--- a/src/webengine/doc/src/external-resources.qdoc
+++ b/src/webengine/doc/src/external-resources.qdoc
@@ -134,3 +134,8 @@
\externalpage https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler
\title registerProtocolHandler
*/
+
+/*!
+ \externalpage https://www.w3.org/TR/notifications
+ \title Web Notifications API
+*/
diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc
index 6522fb6f7..00b9cb496 100644
--- a/src/webengine/doc/src/qtwebengine-features.qdoc
+++ b/src/webengine/doc/src/qtwebengine-features.qdoc
@@ -44,12 +44,14 @@
\li \l{HTTP/2 Protocol}
\li \l{Native Dialogs}
\li \l{Pepper Plugin API}
+ \li \l{PDF File Viewing}
\li \l{Print to PDF}
\li \l{Process Models}
\li \l{Spellchecker}
\li \l{Touch}
\li \l{View Source}
\li \l{WebRTC}
+ \li \l{Web Notifications}
\endlist
\section1 Audio and Video Codecs
@@ -124,7 +126,9 @@
so uniquely identifies the user and might violate privacy expectations.
To activate support for client certificates, an application needs to listen to
- the QWebEnginePage::selectClientCertificate signal and select one of the offered
+ the QWebEnginePage::selectClientCertificate or
+ \l{WebEnginePage::selectClientCertificate}{WebEnginePage.selectClientCertificate}
+ signals and select one of the offered
certificates. For applications that can navigate to untrusted web sites, it is
recommended to always give the user a choice before uniquely identifying them
to a remote server.
@@ -318,6 +322,21 @@
feature, the \c https://helpx.adobe.com/flash-player.html page can be opened
in the browser.
+ \section1 PDF File Viewing
+
+ \QWE supports viewing PDF documents by navigating to them. This feature uses the Chromium
+ extensions API and PDF viewer plugin to display the PDF documents.
+ It can be tested in \l{WebEngine Widgets Simple Browser Example}{Simple Browser} or
+ \l{WebEngine Quick Nano Browser}{Nano Browser}.
+
+ Loading plugins needs to be enabled using QWebEngineSettings::PluginsEnabled or
+ WebEngineSettings::pluginsEnabled in order to use this feature.
+
+ This feature can be turned on (default) or off via the QWebEngineSettings::PdfViewerEnabled or
+ WebEngineSettings::pdfViewerEnabled setting.
+
+ Support for this feature was added in Qt 5.13.0.
+
\section1 Print to PDF
\QWE supports printing a web page to a PDF file. For more
@@ -511,4 +530,13 @@
This feature can be tested by setting up a webcam or microphone and then
opening \c https://test.webrtc.org/ in \l{WebEngine Widgets Simple Browser
Example}{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}.
+
+ \section1 Web Notifications
+
+ Qt WebEngine supports JavaScript \l{Web Notifications API}.
+ The application has to explicitly allow the feature by using
+ QWebEnginePage::Notifications or \l{WebEngineView::Feature}
+ {WebEngineView.Notifications}.
+
+ Support for this feature was added in Qt 5.13.0.
*/
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index 8feb38eca..6aa1af89e 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -89,8 +89,8 @@
\l{https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md}{overview}
that is part of the documentation in the \l {Chromium Project} upstream source tree.
- This version of \QWE is based on Chromium version 69.0.3497.128, with
- additional security fixes from newer versions.
+ This version of \QWE is based on Chromium version 73.0.3683, with additional security
+ fixes from newer versions.
\section2 Qt WebEngine Process
@@ -238,14 +238,18 @@
are automatically retrieved from the system. Settings from an installed QNetworkProxyFactory
will be ignored, though.
- Not all properties of QNetworkProxy are supported by \QWE. That is,
- QNetworkProxy::type(), QNetworkProxy::hostName() and QNetworkProxy::port() are taken into
- account. All other proxy settings such as QNetworkProxy::rawHeader(), QNetworkProxy::user(), or
- QNetworkProxy::password() are ignored.
+ In case QNetworkProxy::user() and QNetworkProxy::password() are set, these credentials
+ will be automatically used for proxy authentication. It is up to the user to provide valid
+ credentials, since there is no error handling callback.
- If a proxy requires authentication, QWebEnginePage::proxyAuthenticationRequired is emitted.
+ If no credentials are set with QNetworkProxy, but the proxy requires authentication,
+ QWebEnginePage::proxyAuthenticationRequired is emitted.
For Qt Quick, a dialog is shown.
+ Not all properties of QNetworkProxy are supported by \QWE. That is,
+ QNetworkProxy::type(), QNetworkProxy::hostName() and QNetworkProxy::port() are taken into
+ account. All other proxy settings such as QNetworkProxy::rawHeader() are ignored.
+
\section1 High DPI Support
To support High DPI devices, it is recommended that the application attribute
diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
index 5e172087d..540d74035 100644
--- a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
+++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
- \qmlmodule QtWebEngine 1.8
+ \qmlmodule QtWebEngine 1.9
\title Qt WebEngine QML Types
\brief Provides QML types for rendering web content within a QML application.
\ingroup qtwebengine-modules
@@ -36,7 +36,7 @@
your .qml file:
\badcode
- import QtWebEngine 1.8
+ import QtWebEngine 1.9
\endcode
To link against the module, add the following QT variable to your qmake .pro
diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc
index a4f07ddd9..7efe447ac 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -870,6 +870,8 @@
(Added in Qt 5.10)
\value DesktopAudioVideoCapture
Both audio and video output capture. (Added in Qt 5.10)
+ \value WebEnginView.Notifications
+ Web notifications for the end-user.
\sa featurePermissionRequested(), grantFeaturePermission()
*/
@@ -1488,3 +1490,19 @@
\sa printToPdf
*/
+
+/*!
+ \qmlsignal WebEngineView::selectClientCertificate(WebEngineClientCertificateSelection clientCertificateSelection)
+ \since QtWebEngine 1.9
+
+ This signal is emitted when a web site requests an SSL client certificate, and one or more were
+ found in the system's client certificate store.
+
+ Handling the signal is asynchronous, and loading will be waiting until a certificate is selected,
+ or the last copy of \a clientCertificateSelection is destroyed.
+
+ If the signal is not handled, \a clientCertificateSelection is automatically destroyed, and loading
+ will continue without a client certificate.
+
+ \sa WebEngineClientCertificateSelection
+*/
diff --git a/src/webengine/module.pro b/src/webengine/module.pro
new file mode 100644
index 000000000..49a1086b2
--- /dev/null
+++ b/src/webengine/module.pro
@@ -0,0 +1,94 @@
+include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri)
+QT_FOR_CONFIG += webengine-private
+
+TARGET = QtWebEngine
+MODULE = webengine
+
+# For our export macros
+DEFINES += QT_BUILD_WEBENGINE_LIB
+
+QT += qml quick webenginecore
+QT_PRIVATE += quick-private gui-private core-private webenginecore-private
+
+QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf
+
+INCLUDEPATH += $$PWD api ../core ../core/api
+
+SOURCES = \
+ api/qquickwebengineaction.cpp \
+ api/qquickwebenginecertificateerror.cpp \
+ api/qquickwebengineclientcertificateselection.cpp \
+ api/qquickwebenginecontextmenurequest.cpp \
+ api/qquickwebenginedialogrequests.cpp \
+ api/qquickwebenginedownloaditem.cpp \
+ api/qquickwebenginehistory.cpp \
+ api/qquickwebenginefaviconprovider.cpp \
+ api/qquickwebengineloadrequest.cpp \
+ api/qquickwebenginenavigationrequest.cpp \
+ api/qquickwebenginenewviewrequest.cpp \
+ api/qquickwebengineprofile.cpp \
+ api/qquickwebenginescript.cpp \
+ api/qquickwebenginesettings.cpp \
+ api/qquickwebenginesingleton.cpp \
+ api/qquickwebenginetouchhandleprovider.cpp \
+ api/qquickwebengineview.cpp \
+ api/qtwebengineglobal.cpp \
+ render_widget_host_view_qt_delegate_quick.cpp \
+ render_widget_host_view_qt_delegate_quickwindow.cpp \
+ ui_delegates_manager.cpp
+
+HEADERS = \
+ api/qtwebengineglobal.h \
+ api/qtwebengineglobal_p.h \
+ api/qquickwebengineaction_p.h \
+ api/qquickwebengineaction_p_p.h \
+ api/qquickwebenginecertificateerror_p.h \
+ api/qquickwebengineclientcertificateselection_p.h \
+ api/qquickwebenginecontextmenurequest_p.h \
+ api/qquickwebenginedialogrequests_p.h \
+ api/qquickwebenginedownloaditem_p.h \
+ api/qquickwebenginedownloaditem_p_p.h \
+ api/qquickwebenginehistory_p.h \
+ api/qquickwebenginefaviconprovider_p_p.h \
+ api/qquickwebengineloadrequest_p.h \
+ api/qquickwebenginenavigationrequest_p.h \
+ api/qquickwebenginenewviewrequest_p.h \
+ api/qquickwebengineprofile.h \
+ api/qquickwebengineprofile_p.h \
+ api/qquickwebenginescript.h \
+ api/qquickwebenginescript_p.h \
+ api/qquickwebenginesettings_p.h \
+ api/qquickwebenginesingleton_p.h \
+ api/qquickwebenginetouchhandleprovider_p_p.h \
+ api/qquickwebengineview_p.h \
+ api/qquickwebengineview_p_p.h \
+ render_widget_host_view_qt_delegate_quick.h \
+ render_widget_host_view_qt_delegate_quickwindow.h \
+ ui_delegates_manager.h
+
+qtConfig(webengine-testsupport) {
+ QT_PRIVATE += testlib
+ SOURCES += api/qquickwebenginetestsupport.cpp
+ HEADERS += api/qquickwebenginetestsupport_p.h
+}
+
+!build_pass {
+ python = $$pythonPathForShell()
+ chromium_attributions.commands = \
+ cd $$shell_quote($$shell_path($$PWD/../3rdparty)) && \
+ $$python chromium/tools/licenses.py \
+ --file-template ../../tools/about_credits.tmpl \
+ --entry-template ../../tools/about_credits_entry.tmpl credits \
+ $$shell_quote($$shell_path($$OUT_PWD/chromium_attributions.qdoc))
+ chromium_attributions.CONFIG += phony
+
+ QMAKE_EXTRA_TARGETS += chromium_attributions
+
+ prepare_docs {
+ prepare_docs.depends += chromium_attributions
+ } else {
+ html_docs.depends += chromium_attributions
+ }
+}
+
+load(qt_module)
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index 84a12c930..a332288d4 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -40,22 +40,24 @@
#include <QtQml/qqmlextensionplugin.h>
#include <QtWebEngine/QQuickWebEngineProfile>
-#include "qquickwebenginecertificateerror_p.h"
-#include "qquickwebenginecontextmenurequest_p.h"
-#include "qquickwebenginedialogrequests_p.h"
-#include "qquickwebenginedownloaditem_p.h"
-#include "qquickwebenginehistory_p.h"
-#include "qquickwebenginefaviconprovider_p_p.h"
-#include "qquickwebengineloadrequest_p.h"
-#include "qquickwebenginenavigationrequest_p.h"
-#include "qquickwebenginenewviewrequest_p.h"
-#include "qquickwebenginesettings_p.h"
-#include "qquickwebenginesingleton_p.h"
-#include "qquickwebengineview_p.h"
-#include "qquickwebengineaction_p.h"
-#include "qwebenginequotarequest.h"
-#include "qwebengineregisterprotocolhandlerrequest.h"
-#include "qtwebengineversion.h"
+#include <QtWebEngine/private/qquickwebenginecertificateerror_p.h>
+#include <QtWebEngine/private/qquickwebengineclientcertificateselection_p.h>
+#include <QtWebEngine/private/qquickwebenginecontextmenurequest_p.h>
+#include <QtWebEngine/private/qquickwebenginedialogrequests_p.h>
+#include <QtWebEngine/private/qquickwebenginedownloaditem_p.h>
+#include <QtWebEngine/private/qquickwebenginehistory_p.h>
+#include <QtWebEngine/private/qquickwebenginefaviconprovider_p_p.h>
+#include <QtWebEngine/private/qquickwebengineloadrequest_p.h>
+#include <QtWebEngine/private/qquickwebenginenavigationrequest_p.h>
+#include <QtWebEngine/private/qquickwebenginenewviewrequest_p.h>
+#include <QtWebEngine/private/qquickwebenginesettings_p.h>
+#include <QtWebEngine/private/qquickwebenginesingleton_p.h>
+#include <QtWebEngine/private/qquickwebenginetouchhandleprovider_p_p.h>
+#include <QtWebEngine/private/qquickwebengineview_p.h>
+#include <QtWebEngine/private/qquickwebengineaction_p.h>
+#include <QtWebEngineCore/qwebenginenotification.h>
+#include <QtWebEngineCore/qwebenginequotarequest.h>
+#include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
QT_BEGIN_NAMESPACE
@@ -73,6 +75,7 @@ public:
{
Q_UNUSED(uri);
engine->addImageProvider(QQuickWebEngineFaviconProvider::identifier(), new QQuickWebEngineFaviconProvider);
+ engine->addImageProvider(QQuickWebEngineTouchHandleProvider::identifier(), new QQuickWebEngineTouchHandleProvider);
}
void registerTypes(const char *uri) override
@@ -91,11 +94,13 @@ public:
qmlRegisterType<QQuickWebEngineView, 6>(uri, 1, 6, "WebEngineView");
qmlRegisterType<QQuickWebEngineView, 7>(uri, 1, 7, "WebEngineView");
qmlRegisterType<QQuickWebEngineView, 8>(uri, 1, 8, "WebEngineView");
+ qmlRegisterType<QQuickWebEngineView, 9>(uri, 1, 9, "WebEngineView");
qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineProfile, 3>(uri, 1, 4, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineProfile, 4>(uri, 1, 5, "WebEngineProfile");
+ qmlRegisterType<QQuickWebEngineProfile, 5>(uri, 1, 9, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript");
qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", msgUncreatableType("WebEngineCertificateError"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem",
@@ -116,14 +121,15 @@ public:
tr("Cannot create a separate instance of WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", msgUncreatableType("WebEngineNewViewRequest"));
qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest, 1>(uri, 1, 5, "WebEngineNewViewRequest", tr("Cannot create separate instance of WebEngineNewViewRequest"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 2>(uri, 1, 3, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 3>(uri, 1, 4, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 4>(uri, 1, 5, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 5>(uri, 1, 6, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 6>(uri, 1, 7, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterUncreatableType<QQuickWebEngineSettings, 7>(uri, 1, 8, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 2>(uri, 1, 3, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 3>(uri, 1, 4, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 4>(uri, 1, 5, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 5>(uri, 1, 6, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 6>(uri, 1, 7, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 7>(uri, 1, 8, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
+ qmlRegisterUncreatableType<QQuickWebEngineSettings, 8>(uri, 1, 9, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider);
qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 1, "NavigationHistory",
tr("Cannot create a separate instance of NavigationHistory"));
@@ -153,6 +159,13 @@ public:
qmlRegisterUncreatableType<QWebEngineRegisterProtocolHandlerRequest>(uri, 1, 7, "RegisterProtocolHandlerRequest",
msgUncreatableType("RegisterProtocolHandlerRequest"));
qmlRegisterUncreatableType<QQuickWebEngineAction>(uri, 1, 8, "WebEngineAction", msgUncreatableType("WebEngineAction"));
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ qmlRegisterUncreatableType<QQuickWebEngineClientCertificateSelection>(uri, 1, 9, "WebEngineClientCertificateSelection",
+ msgUncreatableType("WebEngineClientCertificateSelection"));
+ qmlRegisterUncreatableType<QQuickWebEngineClientCertificateOption>(uri, 1, 9, "WebEngineClientCertificateOption",
+ msgUncreatableType("WebEngineClientCertificateOption"));
+#endif
+ qmlRegisterUncreatableType<QWebEngineNotification>(uri, 1, 9, "WebEngineNotification", msgUncreatableType("WebEngineNotification"));
}
private:
diff --git a/src/webengine/plugin/plugin.pro b/src/webengine/plugin/plugin.pro
index b6652fa26..0c1310de3 100644
--- a/src/webengine/plugin/plugin.pro
+++ b/src/webengine/plugin/plugin.pro
@@ -1,13 +1,12 @@
CXX_MODULE = qml
TARGET = qtwebengineplugin
TARGETPATH = QtWebEngine
-IMPORT_VERSION = 1.8
+IMPORT_VERSION = 1.9
-QT += webengine qml quick
+QT += qml quick
QT_PRIVATE += core-private webenginecore-private webengine-private
-INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/core/api $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api $$QTWEBENGINE_ROOT/include/QtWebEngine
-
SOURCES = plugin.cpp
+QMAKE_QMLPLUGINDUMP_FLAGS = -defaultplatform
load(qml_plugin)
diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes
index 1f295ac57..0037861e5 100644
--- a/src/webengine/plugin/plugins.qmltypes
+++ b/src/webengine/plugin/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -defaultplatform -dependencies dependencies.json -nonrelocatable QtWebEngine 1.8'
+// 'qmlplugindump -nonrelocatable -defaultplatform -dependencies dependencies.json QtWebEngine 1.9'
Module {
dependencies: ["QtQuick 2.8"]
@@ -80,6 +80,46 @@ Module {
Method { name: "rejectCertificate" }
}
Component {
+ name: "QQuickWebEngineClientCertificateOption"
+ prototype: "QObject"
+ exports: ["QtWebEngine/WebEngineClientCertificateOption 1.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "issuer"; type: "string"; isReadonly: true }
+ Property { name: "subject"; type: "string"; isReadonly: true }
+ Property { name: "effectiveDate"; type: "QDateTime"; isReadonly: true }
+ Property { name: "expiryDate"; type: "QDateTime"; isReadonly: true }
+ Property { name: "isSelfSigned"; type: "bool"; isReadonly: true }
+ Method { name: "select" }
+ }
+ Component {
+ name: "QQuickWebEngineClientCertificateSelection"
+ prototype: "QObject"
+ exports: ["QtWebEngine/WebEngineClientCertificateSelection 1.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "host"; type: "QUrl"; isReadonly: true }
+ Property {
+ name: "certificates"
+ type: "QQuickWebEngineClientCertificateOption"
+ isList: true
+ isReadonly: true
+ }
+ Method {
+ name: "select"
+ Parameter { name: "idx"; type: "int" }
+ }
+ Method {
+ name: "select"
+ Parameter {
+ name: "certificate"
+ type: "const QQuickWebEngineClientCertificateOption"
+ isPointer: true
+ }
+ }
+ Method { name: "selectNone" }
+ }
+ Component {
name: "QQuickWebEngineColorDialogRequest"
prototype: "QObject"
exports: ["QtWebEngine/ColorDialogRequest 1.4"]
@@ -437,9 +477,10 @@ Module {
"QtWebEngine/WebEngineProfile 1.2",
"QtWebEngine/WebEngineProfile 1.3",
"QtWebEngine/WebEngineProfile 1.4",
- "QtWebEngine/WebEngineProfile 1.5"
+ "QtWebEngine/WebEngineProfile 1.5",
+ "QtWebEngine/WebEngineProfile 1.9"
]
- exportMetaObjectRevisions: [0, 1, 2, 3, 4]
+ exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5]
Enum {
name: "HttpCacheType"
values: {
@@ -474,9 +515,13 @@ Module {
isList: true
isReadonly: true
}
+ Property { name: "useForGlobalCertificateVerification"; revision: 5; type: "bool" }
+ Property { name: "downloadPath"; revision: 5; type: "string" }
Signal { name: "httpAcceptLanguageChanged"; revision: 1 }
Signal { name: "spellCheckLanguagesChanged"; revision: 3 }
Signal { name: "spellCheckEnabledChanged"; revision: 3 }
+ Signal { name: "useForGlobalCertificateVerificationChanged"; revision: 5 }
+ Signal { name: "downloadPathChanged"; revision: 5 }
Signal {
name: "downloadRequested"
Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true }
@@ -485,6 +530,11 @@ Module {
name: "downloadFinished"
Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true }
}
+ Signal {
+ name: "presentNotification"
+ revision: 5
+ Parameter { name: "notification"; type: "QWebEngineNotification"; isPointer: true }
+ }
Method { name: "clearHttpCache"; revision: 2 }
}
Component {
@@ -617,6 +667,7 @@ Module {
Property { name: "webRTCPublicInterfacesOnly"; revision: 6; type: "bool" }
Property { name: "javascriptCanPaste"; revision: 6; type: "bool" }
Property { name: "dnsPrefetchEnabled"; revision: 7; type: "bool" }
+ Property { name: "pdfViewerEnabled"; revision: 8; type: "bool" }
Signal { name: "fullScreenSupportEnabledChanged"; revision: 1 }
Signal { name: "screenCaptureEnabledChanged"; revision: 2 }
Signal { name: "webGLEnabledChanged"; revision: 2 }
@@ -634,6 +685,7 @@ Module {
Signal { name: "webRTCPublicInterfacesOnlyChanged"; revision: 6 }
Signal { name: "javascriptCanPasteChanged"; revision: 6 }
Signal { name: "dnsPrefetchEnabledChanged"; revision: 7 }
+ Signal { name: "pdfViewerEnabledChanged"; revision: 8 }
}
Component {
name: "QQuickWebEngineSingleton"
@@ -664,9 +716,10 @@ Module {
"QtWebEngine/WebEngineView 1.5",
"QtWebEngine/WebEngineView 1.6",
"QtWebEngine/WebEngineView 1.7",
- "QtWebEngine/WebEngineView 1.8"
+ "QtWebEngine/WebEngineView 1.8",
+ "QtWebEngine/WebEngineView 1.9"
]
- exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7, 8]
+ exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Enum {
name: "NavigationRequestAction"
values: {
@@ -723,7 +776,8 @@ Module {
"MediaAudioVideoCapture": 2,
"Geolocation": 3,
"DesktopVideoCapture": 4,
- "DesktopAudioVideoCapture": 5
+ "DesktopAudioVideoCapture": 5,
+ "Notifications": 6
}
}
Enum {
@@ -1131,6 +1185,15 @@ Module {
Parameter { name: "request"; type: "QWebEngineRegisterProtocolHandlerRequest" }
}
Signal { name: "printRequested"; revision: 8 }
+ Signal {
+ name: "selectClientCertificate"
+ revision: 9
+ Parameter {
+ name: "clientCertSelection"
+ type: "QQuickWebEngineClientCertificateSelection"
+ isPointer: true
+ }
+ }
Method {
name: "runJavaScript"
Parameter { type: "string" }
@@ -1257,6 +1320,32 @@ Module {
}
}
Component {
+ name: "QWebEngineNotification"
+ prototype: "QObject"
+ exports: ["QtWebEngine/WebEngineNotification 1.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "Direction"
+ values: {
+ "LeftToRight": 0,
+ "RightToLeft": 1,
+ "DirectionAuto": 2
+ }
+ }
+ Property { name: "origin"; type: "QUrl"; isReadonly: true }
+ Property { name: "icon"; type: "QIcon"; isReadonly: true }
+ Property { name: "title"; type: "string"; isReadonly: true }
+ Property { name: "message"; type: "string"; isReadonly: true }
+ Property { name: "tag"; type: "string"; isReadonly: true }
+ Property { name: "language"; type: "string"; isReadonly: true }
+ Property { name: "direction"; type: "Direction"; isReadonly: true }
+ Signal { name: "closed" }
+ Method { name: "show" }
+ Method { name: "click" }
+ Method { name: "close" }
+ }
+ Component {
name: "QWebEngineQuotaRequest"
exports: ["QtWebEngine/QuotaRequest 1.7"]
isCreatable: false
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index 8aaf4c714..55ec19fc9 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -99,19 +99,26 @@ void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
setVisible(true);
}
-QRectF RenderWidgetHostViewQtDelegateQuick::screenRect() const
-{
- QPointF pos = mapToScene(QPointF(0,0));
- return QRectF(pos.x(), pos.y(), width(), height());
+QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const
+{
+ // Transform the entire rect to find the correct top left corner.
+ const QPointF p1 = mapToGlobal(mapFromScene(QPointF(0, 0)));
+ const QPointF p2 = mapToGlobal(mapFromScene(QPointF(width(), height())));
+ QRectF geometry = QRectF(p1, p2).normalized();
+ // But keep the size untransformed to behave like other QQuickItems.
+#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+ geometry.setSize(size());
+#else
+ geometry.setSize(QSizeF(width(), height()));
+#endif
+ return geometry;
}
-QRectF RenderWidgetHostViewQtDelegateQuick::contentsRect() const
+QRect RenderWidgetHostViewQtDelegateQuick::windowGeometry() const
{
- QPointF scenePoint = mapToScene(QPointF(0, 0));
- QPointF screenPos;
- if (window())
- screenPos = window()->mapToGlobal(scenePoint.toPoint());
- return QRectF(screenPos.x(), screenPos.y(), width(), height());
+ if (!window())
+ return QRect();
+ return window()->frameGeometry();
}
void RenderWidgetHostViewQtDelegateQuick::setKeyboardFocus()
@@ -322,16 +329,7 @@ void RenderWidgetHostViewQtDelegateQuick::inputMethodEvent(QInputMethodEvent *ev
void RenderWidgetHostViewQtDelegateQuick::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickItem::geometryChanged(newGeometry, oldGeometry);
-
- if (window()) {
- const QPointF globalPos = QQuickItem::mapToGlobal(position());
- if (globalPos != m_lastGlobalPos) {
- m_lastGlobalPos = globalPos;
- m_client->windowBoundsChanged();
- }
- }
-
- m_client->notifyResize();
+ m_client->visualPropertiesChanged();
}
void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const ItemChangeData &value)
@@ -347,8 +345,7 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
if (!m_isPopup)
m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
}
-
- m_client->windowChanged();
+ m_client->visualPropertiesChanged();
} else if (change == QQuickItem::ItemVisibleHasChanged) {
if (!m_isPopup && !value.boolValue)
onHide();
@@ -362,9 +359,7 @@ QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode,
void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged()
{
- if (window())
- m_lastGlobalPos = QQuickItem::mapToGlobal(position());
- m_client->windowBoundsChanged();
+ m_client->visualPropertiesChanged();
}
void RenderWidgetHostViewQtDelegateQuick::onHide()
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index d4d64804a..00158b3ac 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -59,8 +59,8 @@ public:
~RenderWidgetHostViewQtDelegateQuick();
void initAsPopup(const QRect&) override;
- QRectF screenRect() const override;
- QRectF contentsRect() const override;
+ QRectF viewGeometry() const override;
+ QRect windowGeometry() const override;
void setKeyboardFocus() override;
bool hasKeyboardFocus() override;
void lockMouse() override;
@@ -113,7 +113,6 @@ private:
RenderWidgetHostViewQtDelegateClient *m_client;
QList<QMetaObject::Connection> m_windowConnections;
bool m_isPopup;
- QPointF m_lastGlobalPos;
QQuickWebEngineView *m_view = nullptr;
};
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
index d3c88148e..3648df3c1 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -44,32 +44,59 @@
namespace QtWebEngineCore {
-RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegate *realDelegate)
+RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate)
: m_realDelegate(realDelegate)
+ , m_virtualParent(nullptr)
{
- setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+ setFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
}
RenderWidgetHostViewQtDelegateQuickWindow::~RenderWidgetHostViewQtDelegateQuickWindow()
{
}
+void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *virtualParent)
+{
+ Q_ASSERT(virtualParent);
+ m_virtualParent = virtualParent;
+}
+
+static inline QRectF mapRectToGlobal(const QQuickItem *item, const QRectF &rect)
+{
+ const QPointF p1 = item->mapToGlobal(rect.topLeft());
+ const QPointF p2 = item->mapToGlobal(rect.bottomRight());
+ return QRectF(p1, p2).normalized();
+}
+
+static inline QRectF mapRectFromGlobal(const QQuickItem *item, const QRectF &rect)
+{
+ const QPointF p1 = item->mapFromGlobal(rect.topLeft());
+ const QPointF p2 = item->mapFromGlobal(rect.bottomRight());
+ return QRectF(p1, p2).normalized();
+}
+
void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &screenRect)
{
- m_realDelegate->initAsPopup(QRect(QPoint(0, 0), screenRect.size()));
- setGeometry(screenRect);
+ QRectF popupRect(screenRect);
+ popupRect = mapRectFromGlobal(m_virtualParent, popupRect);
+ popupRect = m_virtualParent->mapRectToScene(popupRect);
+ popupRect = mapRectToGlobal(m_virtualParent, popupRect);
+
+ m_realDelegate->initAsPopup(QRect(QPoint(0, 0), popupRect.size().toSize()));
+ popupRect.setSize(screenRect.size());
+ setGeometry(popupRect.toAlignedRect());
raise();
show();
}
-QRectF RenderWidgetHostViewQtDelegateQuickWindow::screenRect() const
+QRectF RenderWidgetHostViewQtDelegateQuickWindow::viewGeometry() const
{
- return QRectF(x(), y(), width(), height());
+ return geometry();
}
-QRectF RenderWidgetHostViewQtDelegateQuickWindow::contentsRect() const
+QRect RenderWidgetHostViewQtDelegateQuickWindow::windowGeometry() const
{
- return geometry();
+ return frameGeometry();
}
void RenderWidgetHostViewQtDelegateQuickWindow::show()
@@ -138,7 +165,12 @@ void RenderWidgetHostViewQtDelegateQuickWindow::resize(int width, int height)
void RenderWidgetHostViewQtDelegateQuickWindow::move(const QPoint &screenPos)
{
- QQuickWindow::setPosition(screenPos);
+ QRectF popupRect(screenPos, size());
+ popupRect = mapRectFromGlobal(m_virtualParent, popupRect);
+ popupRect = m_virtualParent->mapRectToScene(popupRect);
+ popupRect = mapRectToGlobal(m_virtualParent, popupRect);
+
+ QQuickWindow::setPosition(popupRect.topLeft().toPoint());
}
} // namespace QtWebEngineCore
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index 36e4ddd8a..ab583bd63 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -52,12 +52,12 @@ namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public RenderWidgetHostViewQtDelegate {
public:
- RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegate *realDelegate);
+ RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate);
~RenderWidgetHostViewQtDelegateQuickWindow();
void initAsPopup(const QRect&) override;
- QRectF screenRect() const override;
- QRectF contentsRect() const override;
+ QRectF viewGeometry() const override;
+ QRect windowGeometry() const override;
void setKeyboardFocus() override {}
bool hasKeyboardFocus() override { return false; }
void lockMouse() override {}
@@ -80,8 +80,11 @@ public:
void setClearColor(const QColor &) override { }
bool copySurface(const QRect &, const QSize &, QImage &) override { return false; }
+ void setVirtualParent(QQuickItem *virtualParent);
+
private:
- QScopedPointer<RenderWidgetHostViewQtDelegate> m_realDelegate;
+ QScopedPointer<RenderWidgetHostViewQtDelegateQuick> m_realDelegate;
+ QQuickItem *m_virtualParent;
};
} // namespace QtWebEngineCore
diff --git a/src/webengine/plugin/testsupport/plugin.cpp b/src/webengine/testsupport/plugin.cpp
index d5c43a859..7a1e73d8b 100644
--- a/src/webengine/plugin/testsupport/plugin.cpp
+++ b/src/webengine/testsupport/plugin.cpp
@@ -39,7 +39,7 @@
#include <QtQml>
-#include "qquickwebenginetestsupport_p.h"
+#include <QtWebEngine/private/qquickwebenginetestsupport_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/webengine/testsupport/plugins.qmltypes b/src/webengine/testsupport/plugins.qmltypes
new file mode 100644
index 000000000..12c763724
--- /dev/null
+++ b/src/webengine/testsupport/plugins.qmltypes
@@ -0,0 +1,73 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable QtWebEngine.testsupport 1.0'
+
+Module {
+ dependencies: ["QtQuick 2.0"]
+ Component { name: "QPlatformInputContext"; prototype: "QObject" }
+ Component {
+ name: "QQuickWebEngineErrorPage"
+ prototype: "QObject"
+ exports: ["QtWebEngine.testsupport/WebEngineErrorPage 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Signal {
+ name: "loadingChanged"
+ Parameter { name: "loadRequest"; type: "QQuickWebEngineLoadRequest"; isPointer: true }
+ }
+ }
+ Component {
+ name: "QQuickWebEngineTestEvent"
+ prototype: "QObject"
+ exports: ["QtWebEngine.testsupport/WebEngineTestEvent 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Method {
+ name: "mouseMultiClick"
+ type: "bool"
+ Parameter { name: "item"; type: "QObject"; isPointer: true }
+ Parameter { name: "x"; type: "double" }
+ Parameter { name: "y"; type: "double" }
+ Parameter { name: "clickCount"; type: "int" }
+ }
+ }
+ Component {
+ name: "QQuickWebEngineTestInputContext"
+ prototype: "QPlatformInputContext"
+ exports: ["QtWebEngine.testsupport/TestInputContext 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Method { name: "create" }
+ Method { name: "release" }
+ }
+ Component {
+ name: "QQuickWebEngineTestSupport"
+ prototype: "QObject"
+ exports: ["QtWebEngine.testsupport/WebEngineTestSupport 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property {
+ name: "errorPage"
+ type: "QQuickWebEngineErrorPage"
+ isReadonly: true
+ isPointer: true
+ }
+ Property {
+ name: "testInputContext"
+ type: "QQuickWebEngineTestInputContext"
+ isReadonly: true
+ isPointer: true
+ }
+ Property {
+ name: "testEvent"
+ type: "QQuickWebEngineTestEvent"
+ isReadonly: true
+ isPointer: true
+ }
+ Signal { name: "windowCloseRejected" }
+ Signal { name: "loadVisuallyCommitted" }
+ }
+}
diff --git a/src/webengine/plugin/testsupport/qmldir b/src/webengine/testsupport/qmldir
index 7fff80251..7fff80251 100644
--- a/src/webengine/plugin/testsupport/qmldir
+++ b/src/webengine/testsupport/qmldir
diff --git a/src/webengine/plugin/testsupport/testsupport.pro b/src/webengine/testsupport/testsupport.pro
index 2804635f8..a24796675 100644
--- a/src/webengine/plugin/testsupport/testsupport.pro
+++ b/src/webengine/testsupport/testsupport.pro
@@ -3,11 +3,9 @@ TARGET = qtwebenginetestsupportplugin
TARGETPATH = QtWebEngine/testsupport
IMPORT_VERSION = 1.0
-QT += webengine qml quick
+QT += qml quick
QT_PRIVATE += webengine-private gui-private
-INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api
-
SOURCES = plugin.cpp
load(qml_plugin)
diff --git a/src/webengine/ui/TouchHandle.qml b/src/webengine/ui/TouchHandle.qml
new file mode 100644
index 000000000..76a93829e
--- /dev/null
+++ b/src/webengine/ui/TouchHandle.qml
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+
+Image { }
diff --git a/src/webengine/ui/TouchSelectionMenu.qml b/src/webengine/ui/TouchSelectionMenu.qml
new file mode 100644
index 000000000..7cf16b554
--- /dev/null
+++ b/src/webengine/ui/TouchSelectionMenu.qml
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Layouts 1.3
+
+Rectangle {
+ id: menu
+
+ signal cutTriggered
+ signal copyTriggered
+ signal pasteTriggered
+ signal contextMenuTriggered
+
+ property bool isCutEnabled: false
+ property bool isCopyEnabled: false
+ property bool isPasteEnabled: false
+
+ property color borderColor: "darkGray"
+ property color bgColor: "white"
+
+ radius: 4
+ border.color: borderColor
+ color: borderColor
+ antialiasing: true
+
+ RowLayout {
+ anchors.fill: parent
+ spacing: parent.border.width
+ anchors.margins: parent.border.width
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ radius: menu.radius
+ color: bgColor
+ visible: isCutEnabled
+
+ Text {
+ id: cutText
+ anchors.centerIn: parent
+ text: "Cut"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ parent.color = borderColor;
+ cutText.color = "white";
+ }
+ onReleased: {
+ parent.color = bgColor;
+ cutText.color = "black";
+ cutTriggered();
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ radius: menu.radius
+ color: bgColor
+ visible: isCopyEnabled
+
+ Text {
+ id: copyText
+ anchors.centerIn: parent
+ text: "Copy"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ parent.color = borderColor;
+ copyText.color = "white";
+ }
+ onReleased: {
+ parent.color = bgColor;
+ copyText.color = "black";
+ copyTriggered();
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ radius: menu.radius
+ color: bgColor
+ visible: isPasteEnabled
+
+ Text {
+ id: pasteText
+ anchors.centerIn: parent
+ text: "Paste"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ parent.color = borderColor;
+ pasteText.color = "white";
+ }
+ onReleased: {
+ parent.color = bgColor;
+ pasteText.color = "black";
+ pasteTriggered();
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ radius: menu.radius
+ color: bgColor
+
+ Text {
+ id: contextMenuText
+ anchors.centerIn: parent
+ text: "..."
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ parent.color = borderColor;
+ contextMenuText.color = "white";
+ }
+ onReleased: {
+ parent.color = bgColor;
+ contextMenuText.color = "black";
+ contextMenuTriggered();
+ }
+ }
+ }
+ }
+}
diff --git a/src/webengine/ui/ui.pro b/src/webengine/ui/ui.pro
index eb6bf435c..69f754e0c 100644
--- a/src/webengine/ui/ui.pro
+++ b/src/webengine/ui/ui.pro
@@ -13,6 +13,8 @@ QML_FILES += \
Menu.qml \
MenuItem.qml \
MenuSeparator.qml \
- ToolTip.qml
+ ToolTip.qml \
+ TouchHandle.qml \
+ TouchSelectionMenu.qml
load(qml_module)
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index 7e49bc77d..2f371efd5 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -44,6 +44,7 @@
#include <color_chooser_controller.h>
#include <file_picker_controller.h>
#include <javascript_dialog_controller.h>
+#include <touch_selection_menu_controller.h>
#include <web_contents_adapter_client.h>
#include <QFileInfo>
@@ -54,6 +55,7 @@
#include <QCursor>
#include <QList>
#include <QScreen>
+#include <QTimer>
#include <QGuiApplication>
// Uncomment for QML debugging
@@ -62,7 +64,7 @@
namespace QtWebEngineCore {
#define NO_SEPARATOR
-#if defined(Q_OS_WIN)
+#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
case UIDelegatesManager::TYPE:\
return QString::fromLatin1(#TYPE ##".qml");
@@ -125,6 +127,7 @@ const char *defaultPropertyName(QObject *obj)
UIDelegatesManager::UIDelegatesManager(QQuickWebEngineView *view)
: m_view(view)
, m_toolTip(nullptr)
+ , m_touchSelectionMenu(nullptr)
FOR_EACH_COMPONENT_TYPE(COMPONENT_MEMBER_INIT, NO_SEPARATOR)
{
}
@@ -321,7 +324,7 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d
return;
}
- QQmlComponent *dialogComponent = Q_NULLPTR;
+ QQmlComponent *dialogComponent = nullptr;
switch (dialogComponentType) {
FOR_EACH_COMPONENT_TYPE(ASSIGN_DIALOG_COMPONENT_DATA_CASE_STATEMENT, NO_SEPARATOR)
default:
@@ -568,6 +571,82 @@ void UIDelegatesManager::showToolTip(const QString &text)
QMetaObject::invokeMethod(m_toolTip.data(), "open");
}
+QQuickItem *UIDelegatesManager::createTouchHandle()
+{
+ if (!ensureComponentLoaded(TouchHandle))
+ return nullptr;
+
+ QQmlContext *context = qmlContext(m_view);
+ QObject *touchHandle = touchHandleComponent->beginCreate(context);
+ QQuickItem *item = qobject_cast<QQuickItem *>(touchHandle);
+ Q_ASSERT(item);
+ item->setParentItem(m_view);
+ touchHandleComponent->completeCreate();
+
+ return item;
+}
+
+void UIDelegatesManager::showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *menuController, const QRect &bounds, const int spacing)
+{
+ if (!ensureComponentLoaded(TouchSelectionMenu))
+ return;
+
+ QQmlContext *context = qmlContext(m_view);
+ m_touchSelectionMenu.reset(touchSelectionMenuComponent->beginCreate(context));
+ if (QQuickItem *item = qobject_cast<QQuickItem *>(m_touchSelectionMenu.data()))
+ item->setParentItem(m_view);
+ m_touchSelectionMenu->setParent(m_view);
+
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("width")).write(bounds.width());
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("height")).write(bounds.height());
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("x")).write(bounds.x());
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("y")).write(bounds.y());
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("border.width")).write(spacing);
+
+ // Cut button
+ bool cutEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Cut);
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isCutEnabled")).write(cutEnabled);
+ if (cutEnabled) {
+ QQmlProperty cutSignal(m_touchSelectionMenu.data(), QStringLiteral("onCutTriggered"));
+ CHECK_QML_SIGNAL_PROPERTY(cutSignal, touchSelectionMenuComponent->url());
+ int cutIndex = menuController->metaObject()->indexOfSlot("cut()");
+ QObject::connect(m_touchSelectionMenu.data(), cutSignal.method(), menuController, menuController->metaObject()->method(cutIndex));
+ }
+
+ // Copy button
+ bool copyEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Copy);
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isCopyEnabled")).write(copyEnabled);
+ if (copyEnabled) {
+ QQmlProperty copySignal(m_touchSelectionMenu.data(), QStringLiteral("onCopyTriggered"));
+ CHECK_QML_SIGNAL_PROPERTY(copySignal, touchSelectionMenuComponent->url());
+ int copyIndex = menuController->metaObject()->indexOfSlot("copy()");
+ QObject::connect(m_touchSelectionMenu.data(), copySignal.method(), menuController, menuController->metaObject()->method(copyIndex));
+ }
+
+ // Paste button
+ bool pasteEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Paste);
+ QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isPasteEnabled")).write(pasteEnabled);
+ if (pasteEnabled) {
+ QQmlProperty pasteSignal(m_touchSelectionMenu.data(), QStringLiteral("onPasteTriggered"));
+ CHECK_QML_SIGNAL_PROPERTY(pasteSignal, touchSelectionMenuComponent->url());
+ int pasteIndex = menuController->metaObject()->indexOfSlot("paste()");
+ QObject::connect(m_touchSelectionMenu.data(), pasteSignal.method(), menuController, menuController->metaObject()->method(pasteIndex));
+ }
+
+ // Context menu button
+ QQmlProperty contextMenuSignal(m_touchSelectionMenu.data(), QStringLiteral("onContextMenuTriggered"));
+ CHECK_QML_SIGNAL_PROPERTY(contextMenuSignal, touchSelectionMenuComponent->url());
+ int contextMenuIndex = menuController->metaObject()->indexOfSlot("runContextMenu()");
+ QObject::connect(m_touchSelectionMenu.data(), contextMenuSignal.method(), menuController, menuController->metaObject()->method(contextMenuIndex));
+
+ touchSelectionMenuComponent->completeCreate();
+}
+
+void UIDelegatesManager::hideTouchSelectionMenu()
+{
+ QTimer::singleShot(0, m_view, [this] { m_touchSelectionMenu.reset(); });
+}
+
UI2DelegatesManager::UI2DelegatesManager(QQuickWebEngineView *view) : UIDelegatesManager(view)
{
diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h
index 18457e4ed..4b6e291b2 100644
--- a/src/webengine/ui_delegates_manager.h
+++ b/src/webengine/ui_delegates_manager.h
@@ -61,6 +61,8 @@
F(FilePicker, filePicker) SEPARATOR \
F(AuthenticationDialog, authenticationDialog) SEPARATOR \
F(ToolTip, toolTip) SEPARATOR \
+ F(TouchHandle, touchHandle) SEPARATOR \
+ F(TouchSelectionMenu, touchSelectionMenu) SEPARATOR \
#define COMMA_SEPARATOR ,
#define SEMICOLON_SEPARATOR ;
@@ -81,6 +83,7 @@ namespace QtWebEngineCore {
class AuthenticationDialogController;
class JavaScriptDialogController;
class FilePickerController;
+class TouchSelectionMenuController;
const char *defaultPropertyName(QObject *obj);
@@ -110,6 +113,9 @@ public:
void showFilePicker(QSharedPointer<FilePickerController>);
virtual void showMenu(QObject *menu);
void showToolTip(const QString &text);
+ QQuickItem *createTouchHandle();
+ void showTouchSelectionMenu(TouchSelectionMenuController *, const QRect &, const int spacing);
+ void hideTouchSelectionMenu();
protected:
bool ensureComponentLoaded(ComponentType);
@@ -117,6 +123,7 @@ protected:
QQuickWebEngineView *m_view;
QScopedPointer<QObject> m_toolTip;
QStringList m_importDirs;
+ QScopedPointer<QObject> m_touchSelectionMenu;
FOR_EACH_COMPONENT_TYPE(MEMBER_DECLARATION, SEMICOLON_SEPARATOR)
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 418ade9a8..23668229e 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -1,89 +1,19 @@
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
-QT_FOR_CONFIG += webenginecore-private
+TEMPLATE = subdirs
-TARGET = QtWebEngine
+qml_module.file = module.pro
+qml_plugin.file = plugin/plugin.pro
-# For our export macros
-DEFINES += QT_BUILD_WEBENGINE_LIB
+qml_plugin.depends = qml_module
-QT += qml quick webenginecore
-QT_PRIVATE += quick-private gui-private core-private webenginecore-private
-
-QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf
-
-INCLUDEPATH += $$PWD api ../core ../core/api
-
-SOURCES = \
- api/qquickwebengineaction.cpp \
- api/qquickwebenginecertificateerror.cpp \
- api/qquickwebenginecontextmenurequest.cpp \
- api/qquickwebenginedialogrequests.cpp \
- api/qquickwebenginedownloaditem.cpp \
- api/qquickwebenginehistory.cpp \
- api/qquickwebenginefaviconprovider.cpp \
- api/qquickwebengineloadrequest.cpp \
- api/qquickwebenginenavigationrequest.cpp \
- api/qquickwebenginenewviewrequest.cpp \
- api/qquickwebengineprofile.cpp \
- api/qquickwebenginescript.cpp \
- api/qquickwebenginesettings.cpp \
- api/qquickwebenginesingleton.cpp \
- api/qquickwebengineview.cpp \
- api/qtwebengineglobal.cpp \
- render_widget_host_view_qt_delegate_quick.cpp \
- render_widget_host_view_qt_delegate_quickwindow.cpp \
- ui_delegates_manager.cpp
-
-HEADERS = \
- api/qtwebengineglobal.h \
- api/qtwebengineglobal_p.h \
- api/qquickwebengineaction_p.h \
- api/qquickwebengineaction_p_p.h \
- api/qquickwebenginecertificateerror_p.h \
- api/qquickwebenginecontextmenurequest_p.h \
- api/qquickwebenginedialogrequests_p.h \
- api/qquickwebenginedownloaditem_p.h \
- api/qquickwebenginedownloaditem_p_p.h \
- api/qquickwebenginehistory_p.h \
- api/qquickwebenginefaviconprovider_p_p.h \
- api/qquickwebengineloadrequest_p.h \
- api/qquickwebenginenavigationrequest_p.h \
- api/qquickwebenginenewviewrequest_p.h \
- api/qquickwebengineprofile.h \
- api/qquickwebengineprofile_p.h \
- api/qquickwebenginescript.h \
- api/qquickwebenginescript_p.h \
- api/qquickwebenginesettings_p.h \
- api/qquickwebenginesingleton_p.h \
- api/qquickwebengineview_p.h \
- api/qquickwebengineview_p_p.h \
- render_widget_host_view_qt_delegate_quick.h \
- render_widget_host_view_qt_delegate_quickwindow.h \
- ui_delegates_manager.h
+SUBDIRS += qml_module qml_plugin
qtConfig(webengine-testsupport) {
- QT_PRIVATE += testlib
- SOURCES += api/qquickwebenginetestsupport.cpp
- HEADERS += api/qquickwebenginetestsupport_p.h
+ testsupport_plugin.file = testsupport/testsupport.pro
+ testsupport_plugin.depends = qml_module
+ SUBDIRS += testsupport_plugin
}
-!build_pass {
- python = $$pythonPathForShell()
- chromium_attributions.commands = \
- cd $$shell_quote($$shell_path($$PWD/../3rdparty)) && \
- $$python chromium/tools/licenses.py \
- --file-template ../../tools/about_credits.tmpl \
- --entry-template ../../tools/about_credits_entry.tmpl credits \
- $$shell_quote($$shell_path($$OUT_PWD/chromium_attributions.qdoc))
- chromium_attributions.CONFIG += phony
-
- QMAKE_EXTRA_TARGETS += chromium_attributions
-
- prepare_docs {
- prepare_docs.depends += chromium_attributions
- } else {
- html_docs.depends += chromium_attributions
- }
+qtConfig(webengine-ui-delegates) {
+ SUBDIRS += ui \
+ ui2
}
-
-load(qt_module)
diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
new file mode 100644
index 000000000..667605c37
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginenotificationpresenter_p.h"
+
+#include <QApplication>
+#include <QSystemTrayIcon>
+
+QT_BEGIN_NAMESPACE
+
+DefaultNotificationPresenter::DefaultNotificationPresenter(QObject *parent) : QObject(parent)
+{
+#ifndef QT_NO_SYSTEMTRAYICON
+ m_systemTrayIcon = new QSystemTrayIcon(this);
+ connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked, this, &DefaultNotificationPresenter::messageClicked);
+#endif
+}
+
+DefaultNotificationPresenter::~DefaultNotificationPresenter()
+{
+}
+
+void DefaultNotificationPresenter::show(std::unique_ptr<QWebEngineNotification> notification)
+{
+ Q_ASSERT(notification);
+ if (m_activeNotification) {
+ m_activeNotification->close();
+ m_activeNotification->disconnect(this);
+ }
+
+ m_activeNotification = std::move(notification);
+
+#ifndef QT_NO_SYSTEMTRAYICON
+ if (m_activeNotification && m_systemTrayIcon) {
+ m_systemTrayIcon->setIcon(qApp->windowIcon());
+ m_systemTrayIcon->show();
+ QImage notificationIconImage = m_activeNotification->icon();
+ m_notificationIcon = QIcon(QPixmap::fromImage(std::move(notificationIconImage), Qt::NoFormatConversion));
+ if (!m_notificationIcon.isNull())
+ m_systemTrayIcon->showMessage(m_activeNotification->title(), m_activeNotification->message(), m_notificationIcon);
+ else
+ m_systemTrayIcon->showMessage(m_activeNotification->title(), m_activeNotification->message());
+ m_activeNotification->show();
+ connect(m_activeNotification.get(), &QWebEngineNotification::closed, this, &DefaultNotificationPresenter::closeNotification);
+ }
+#endif
+}
+
+void DefaultNotificationPresenter::messageClicked()
+{
+ if (m_activeNotification)
+ m_activeNotification->click();
+}
+
+void DefaultNotificationPresenter::closeNotification()
+{
+#ifndef QT_NO_SYSTEMTRAYICON
+ const QWebEngineNotification *canceled = static_cast<const QWebEngineNotification *>(QObject::sender());
+ if (m_systemTrayIcon && canceled->matches(m_activeNotification.get()))
+ m_systemTrayIcon->hide();
+#endif
+}
+
+void defaultNotificationPresenter(std::unique_ptr<QWebEngineNotification> notification)
+{
+ static DefaultNotificationPresenter *presenter = nullptr;
+ if (!presenter)
+ presenter = new DefaultNotificationPresenter();
+ presenter->show(std::move(notification));
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
new file mode 100644
index 000000000..49d774806
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINENOTIFICATIONPRESENTER_P_H
+#define QWEBENGINENOTIFICATIONPRESENTER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWebEngineCore/QWebEngineNotification>
+
+#include <QtCore/QObject>
+#include <QtGui/QIcon>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+class QSystemTrayIcon;
+
+class DefaultNotificationPresenter : public QObject {
+ Q_OBJECT
+public:
+ DefaultNotificationPresenter(QObject *parent = nullptr);
+ virtual ~DefaultNotificationPresenter();
+
+ void show(std::unique_ptr<QWebEngineNotification> notification);
+
+private Q_SLOTS:
+ void messageClicked();
+ void closeNotification();
+
+private:
+ QSystemTrayIcon *m_systemTrayIcon;
+ QIcon m_notificationIcon;
+ std::unique_ptr<QWebEngineNotification> m_activeNotification;
+};
+
+void defaultNotificationPresenter(std::unique_ptr<QWebEngineNotification> notification);
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINENOTIFICATIONPRESENTER_P_H
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index aeed6ce85..7b66ac876 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -48,12 +48,13 @@
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
#if QT_CONFIG(webengine_printing_and_pdf)
-#include "printing/pdfium_document_wrapper_qt.h"
+#include "printer_worker.h"
#endif
#include "qwebenginecertificateerror.h"
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
+#include "qwebenginenotification.h"
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
#include "qwebenginequotarequest.h"
@@ -62,6 +63,7 @@
#include "qwebenginesettings.h"
#include "qwebengineview.h"
#include "qwebengineview_p.h"
+#include "user_notification_controller.h"
#include "render_widget_host_view_qt_delegate_widget.h"
#include "web_contents_adapter.h"
#include "web_engine_settings.h"
@@ -94,6 +96,7 @@
#include <QMimeData>
#if QT_CONFIG(webengine_printing_and_pdf)
#include <QPrinter>
+#include <QThread>
#endif
#include <QStandardPaths>
#include <QStyle>
@@ -106,89 +109,6 @@ using namespace QtWebEngineCore;
static const int MaxTooltipLength = 1024;
-#if QT_CONFIG(webengine_printing_and_pdf)
-static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer)
-{
- if (!data.size()) {
- qWarning("Failure to print on printer %ls: Print result data is empty.",
- qUtf16Printable(printer.printerName()));
- return false;
- }
-
- QSize pageSize = printer.pageRect().size();
- PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), pageSize);
-
- int toPage = printer.toPage();
- int fromPage = printer.fromPage();
- bool ascendingOrder = true;
-
- if (fromPage == 0 && toPage == 0) {
- fromPage = 1;
- toPage = pdfiumWrapper.pageCount();
- }
- fromPage = qMax(1, fromPage);
- toPage = qMin(pdfiumWrapper.pageCount(), toPage);
-
- if (printer.pageOrder() == QPrinter::LastPageFirst) {
- qSwap(fromPage, toPage);
- ascendingOrder = false;
- }
-
- int pageCopies = 1;
- int documentCopies = 1;
-
- if (!printer.supportsMultipleCopies())
- documentCopies = printer.copyCount();
-
- if (printer.collateCopies()) {
- pageCopies = documentCopies;
- documentCopies = 1;
- }
-
- QPainter painter;
- if (!painter.begin(&printer)) {
- qWarning("Failure to print on printer %ls: Could not open printer for painting.",
- qUtf16Printable(printer.printerName()));
- return false;
- }
-
- for (int printedDocuments = 0; printedDocuments < documentCopies; printedDocuments++) {
- int currentPageIndex = fromPage;
- while (true) {
- for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
- if (printer.printerState() == QPrinter::Aborted
- || printer.printerState() == QPrinter::Error)
- return false;
-
- QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1);
- if (currentImage.isNull())
- return false;
-
- // Painting operations are automatically clipped to the bounds of the drawable part of the page.
- painter.drawImage(QRect(0, 0, pageSize.width(), pageSize.height()), currentImage, currentImage.rect());
- if (printedPages < pageCopies - 1)
- printer.newPage();
- }
-
- if (currentPageIndex == toPage)
- break;
-
- if (ascendingOrder)
- currentPageIndex++;
- else
- currentPageIndex--;
-
- printer.newPage();
- }
- if (printedDocuments < documentCopies - 1)
- printer.newPage();
- }
- painter.end();
-
- return true;
-}
-#endif // QT_CONFIG(webengine_printing_and_pdf)
-
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
@@ -241,6 +161,7 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
, webChannelWorldId(QWebEngineScript::MainWorld)
, defaultAudioMuted(false)
, defaultZoomFactor(1.0)
+ , requestInterceptor(nullptr)
#if QT_CONFIG(webengine_printing_and_pdf)
, currentPrinter(nullptr)
#endif
@@ -254,7 +175,6 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
wasShownTimer.setSingleShot(true);
QObject::connect(&wasShownTimer, &QTimer::timeout, [this](){
ensureInitialized();
- wasShown();
});
profile->d_ptr->addWebContentsAdapterClient(this);
@@ -262,6 +182,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
QWebEnginePagePrivate::~QWebEnginePagePrivate()
{
+ if (requestInterceptor)
+ profile->d_ptr->profileAdapter()->removePageRequestInterceptor();
delete history;
delete settings;
profile->d_ptr->removeWebContentsAdapterClient(this);
@@ -292,6 +214,9 @@ void QWebEnginePagePrivate::initializationFinished()
if (!qFuzzyCompare(adapter->currentZoomFactor(), defaultZoomFactor))
adapter->setZoomFactor(defaultZoomFactor);
+ if (view && view->isVisible())
+ adapter->wasShown();
+
scriptCollection.d->initializationFinished(adapter);
m_isBeingAdopted = false;
@@ -335,7 +260,7 @@ void QWebEnginePagePrivate::didUpdateTargetURL(const QUrl &hoveredUrl)
void QWebEnginePagePrivate::selectionChanged()
{
Q_Q(QWebEnginePage);
- Q_EMIT q->selectionChanged();
+ QTimer::singleShot(0, q, &QWebEnginePage::selectionChanged);
}
void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible)
@@ -349,11 +274,6 @@ QRectF QWebEnginePagePrivate::viewportRect() const
return view ? view->rect() : QRectF();
}
-qreal QWebEnginePagePrivate::dpiScale() const
-{
- return 1.0;
-}
-
QColor QWebEnginePagePrivate::backgroundColor() const
{
return m_backgroundColor;
@@ -502,19 +422,35 @@ void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount)
m_callbacks.invoke(requestId, matchCount > 0);
}
-void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &result)
+void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
{
#if QT_CONFIG(webengine_printing_and_pdf)
+ Q_Q(QWebEnginePage);
+
// If no currentPrinter is set that means that were printing to PDF only.
if (!currentPrinter) {
- m_callbacks.invoke(requestId, result);
+ if (!result.data())
+ return;
+ m_callbacks.invoke(requestId, *(result.data()));
return;
}
- bool printerResult = printPdfDataOnPrinter(result, *currentPrinter);
+ QThread *printerThread = new QThread;
+ QObject::connect(printerThread, &QThread::finished, printerThread, &QThread::deleteLater);
+ printerThread->start();
+
+ PrinterWorker *printerWorker = new PrinterWorker(result, currentPrinter);
+ QObject::connect(printerWorker, &PrinterWorker::resultReady, q, [requestId, this](bool success) {
+ currentPrinter = nullptr;
+ m_callbacks.invoke(requestId, success);
+ });
+
+ QObject::connect(printerWorker, &PrinterWorker::resultReady, printerThread, &QThread::quit);
+ QObject::connect(printerThread, &QThread::finished, printerWorker, &PrinterWorker::deleteLater);
+
+ printerWorker->moveToThread(printerThread);
+ QMetaObject::invokeMethod(printerWorker, "print");
- currentPrinter = nullptr;
- m_callbacks.invoke(requestId, printerResult);
#else
// we should never enter this branch, but just for safe-keeping...
Q_UNUSED(result);
@@ -551,7 +487,7 @@ void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<Authentication
void QWebEnginePagePrivate::releaseProfile()
{
- qDebug("Release of profile requested but WebEnginePage still not deleted. Expect troubles !");
+ qWarning("Release of profile requested but WebEnginePage still not deleted. Expect troubles !");
// this is not the way to go, but might avoid the crash if user code does not make any calls to page.
delete q_ptr->d_ptr.take();
}
@@ -617,6 +553,12 @@ void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegister
Q_EMIT q->registerProtocolHandlerRequested(request);
}
+void QWebEnginePagePrivate::runUserNotificationPermissionRequest(const QUrl &securityOrigin)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::Notifications);
+}
+
QObject *QWebEnginePagePrivate::accessibilityParentObject()
{
return view;
@@ -1900,6 +1842,40 @@ void QWebEnginePagePrivate::printRequested()
});
}
+/*!
+ \since 5.13
+
+ Registers the request interceptor \a interceptor to intercept URL requests.
+
+ The page does not take ownership of the pointer. This interceptor is called
+ after any interceptors on the profile, and unlike profile interceptors, is run
+ on the UI thread, making it thread-safer. Only URL requests from this page are
+ intercepted.
+
+ To unset the request interceptor, set a \c nullptr.
+
+ \sa QWebEngineUrlRequestInfo, QWebEngineProfile::setRequestInterceptor()
+*/
+
+void QWebEnginePage::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ Q_D(QWebEnginePage);
+ bool hadInterceptorChanged = bool(d->requestInterceptor) != bool(interceptor);
+ d->requestInterceptor = interceptor;
+ if (hadInterceptorChanged) {
+ if (interceptor)
+ d->profile->d_ptr->profileAdapter()->addPageRequestInterceptor();
+ else
+ d->profile->d_ptr->profileAdapter()->removePageRequestInterceptor();
+ }
+}
+
+void QWebEnginePagePrivate::interceptRequest(QWebEngineUrlRequestInfo &info)
+{
+ if (requestInterceptor)
+ requestInterceptor->interceptRequest(info);
+}
+
#if QT_CONFIG(menu)
QMenu *QWebEnginePage::createStandardContextMenu()
{
@@ -1958,6 +1934,7 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
d->adapter->grantMouseLockPermission(true);
break;
case Notifications:
+ d->adapter->runUserNotificationRequestCallback(securityOrigin, true);
break;
}
} else { // if (policy == PermissionDeniedByUser)
@@ -1976,6 +1953,7 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
d->adapter->grantMouseLockPermission(false);
break;
case Notifications:
+ d->adapter->runUserNotificationRequestCallback(securityOrigin, false);
break;
}
}
@@ -2488,10 +2466,7 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
It is the users responsibility to ensure the \a printer remains valid until \a resultCallback
has been called.
- \note The rendering of the current content into a temporary PDF document is asynchronous and does
- not block the main thread. However, the subsequent rendering of PDF into \a printer runs on the
- main thread and will therefore block the event loop. Moreover, printing runs on the browser
- process, which is by default not sandboxed.
+ \note Printing runs on the browser process, which is by default not sandboxed.
The \a resultCallback must take a boolean as parameter. If printing was successful, this
boolean will have the value \c true, otherwise, its value will be \c false.
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 028f1a441..4956877a9 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -71,6 +71,7 @@ class QWebEngineQuotaRequest;
class QWebEngineRegisterProtocolHandlerRequest;
class QWebEngineScriptCollection;
class QWebEngineSettings;
+class QWebEngineUrlRequestInterceptor;
class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject {
Q_OBJECT
@@ -184,9 +185,7 @@ public:
Q_ENUM(NavigationType)
enum Feature {
-#ifndef Q_QDOC
Notifications = 0,
-#endif
Geolocation = 1,
MediaAudioCapture = 2,
MediaVideoCapture,
@@ -303,6 +302,8 @@ public:
void setDevToolsPage(QWebEnginePage *page);
QWebEnginePage *devToolsPage() const;
+ void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+
const QWebEngineContextMenuData &contextMenuData() const;
Q_SIGNALS:
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index f8f67d341..dc0ead534 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -66,6 +66,8 @@
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegate;
class RenderWidgetHostViewQtDelegateWidget;
+class TouchHandleDrawableClient;
+class TouchSelectionMenuController;
class WebContentsAdapter;
}
@@ -98,7 +100,6 @@ public:
void selectionChanged() override;
void recentlyAudibleChanged(bool recentlyAudible) override;
QRectF viewportRect() const override;
- qreal dpiScale() const override;
QColor backgroundColor() const override;
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override { }
@@ -124,7 +125,7 @@ public:
void didFetchDocumentMarkup(quint64 requestId, const QString& result) override;
void didFetchDocumentInnerText(quint64 requestId, const QString& result) override;
void didFindText(quint64 requestId, int matchCount) override;
- void didPrintPage(quint64 requestId, const QByteArray &result) override;
+ void didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result) override;
void didPrintPageToPdf(const QString &filePath, bool success) override;
bool passOnFocus(bool reverse) override;
void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override;
@@ -132,6 +133,7 @@ public:
void releaseProfile() override;
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runGeolocationPermissionRequest(const QUrl &securityOrigin) override;
+ void runUserNotificationPermissionRequest(const QUrl &securityOrigin) override;
void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
void runQuotaRequest(QWebEngineQuotaRequest) override;
void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
@@ -151,8 +153,12 @@ public:
bool isEnabled() const override;
void setToolTip(const QString &toolTipText) override;
void printRequested() override;
+ QtWebEngineCore::TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &) override { return nullptr; }
+ void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &, const QSize &) override { }
+ void hideTouchSelectionMenu() override { }
const QObject *holdingQObject() const override;
ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; }
+ void interceptRequest(QWebEngineUrlRequestInfo &) override;
void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidget) override;
QtWebEngineCore::ProfileAdapter *profileAdapter() override;
@@ -195,6 +201,7 @@ public:
bool defaultAudioMuted;
qreal defaultZoomFactor;
QTimer wasShownTimer;
+ QWebEngineUrlRequestInterceptor *requestInterceptor;
QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget = nullptr;
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 6644af3ff..f9fcc6136 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -43,6 +43,7 @@
#include "qwebenginecookiestore.h"
#include "qwebenginedownloaditem.h"
#include "qwebenginedownloaditem_p.h"
+#include "qwebenginenotificationpresenter_p.h"
#include "qwebenginepage.h"
#include "qwebenginepage_p.h"
#include "qwebenginesettings.h"
@@ -140,6 +141,14 @@ using QtWebEngineCore::ProfileAdapter;
Both session and persistent cookies are saved to and restored from disk.
*/
+void QWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller)
+{
+ if (m_notificationPresenter) {
+ std::unique_ptr<QWebEngineNotification> notification(new QWebEngineNotification(controller));
+ m_notificationPresenter(std::move(notification));
+ }
+}
+
/*!
\fn QWebEngineProfile::downloadRequested(QWebEngineDownloadItem *download)
@@ -379,6 +388,36 @@ void QWebEngineProfile::setPersistentStoragePath(const QString &path)
}
/*!
+ \since 5.13
+
+ The path to the location where the downloaded files are stored.
+
+ \note By default, the download path is QStandardPaths::DownloadLocation.
+
+ \sa setDownloadPath(), QStandardPaths::writableLocation()
+*/
+QString QWebEngineProfile::downloadPath() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->profileAdapter()->downloadPath();
+}
+
+/*!
+ \since 5.13
+
+ Overrides the default path used for download location, setting it to \a path.
+
+ If set to the null string, the default path is restored.
+
+ \sa downloadPath()
+*/
+void QWebEngineProfile::setDownloadPath(const QString &path)
+{
+ Q_D(QWebEngineProfile);
+ d->profileAdapter()->setDownloadPath(path);
+}
+
+/*!
Returns the path used for caches.
By default, this is below StandardPaths::CacheLocation in a QtWebengine/StorageName specific
@@ -542,19 +581,45 @@ QWebEngineCookieStore* QWebEngineProfile::cookieStore()
return d->profileAdapter()->cookieStore();
}
-
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Registers a request interceptor singleton \a interceptor to intercept URL requests.
The profile does not take ownership of the pointer.
+ \obsolete
+
+ Interceptors installed with this method will call
+ QWebEngineUrlRequestInterceptor::interceptRequest on the I/O thread. Therefore
+ the user has to provide thread-safe interaction with the other user classes.
+ Use setUrlRequestInterceptor instead.
+
\since 5.6
\sa QWebEngineUrlRequestInfo
-*/
+*/
void QWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
Q_D(QWebEngineProfile);
+ if (interceptor)
+ interceptor->setProperty("deprecated", true);
+ d->profileAdapter()->setRequestInterceptor(interceptor);
+ if (interceptor)
+ qDebug("Use of deprecated not thread-safe setter, use setUrlRequestInterceptor instead.");
+}
+#endif
+/*!
+ Registers a request interceptor singleton \a interceptor to intercept URL requests.
+
+ The profile does not take ownership of the pointer.
+
+ \since 5.13
+ \sa QWebEngineUrlRequestInfo QWebEngineUrlRequestInterceptor
+*/
+
+void QWebEngineProfile::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ Q_D(QWebEngineProfile);
d->profileAdapter()->setRequestInterceptor(interceptor);
}
@@ -603,6 +668,18 @@ QWebEngineScriptCollection *QWebEngineProfile::scripts() const
}
/*!
+ Sets the function \a notificationPresenter as responsible for presenting sent notifications.
+
+ \since 5.13
+ \sa QWebEngineNotification
+*/
+void QWebEngineProfile::setNotificationPresenter(std::function<void(std::unique_ptr<QWebEngineNotification>)> notificationPresenter)
+{
+ Q_D(QWebEngineProfile);
+ d->m_notificationPresenter = std::move(notificationPresenter);
+}
+
+/*!
Returns the default profile.
The default profile uses the storage name "Default".
@@ -614,6 +691,8 @@ QWebEngineProfile *QWebEngineProfile::defaultProfile()
static QWebEngineProfile* profile = new QWebEngineProfile(
new QWebEngineProfilePrivate(ProfileAdapter::createDefaultProfileAdapter()),
ProfileAdapter::globalQObjectRoot());
+ if (!profile->d_ptr->m_notificationPresenter)
+ profile->setNotificationPresenter(&defaultNotificationPresenter);
return profile;
}
@@ -689,7 +768,7 @@ QWebEngineSettings *QWebEngineProfile::settings() const
const QWebEngineUrlSchemeHandler *QWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const
{
const Q_D(QWebEngineProfile);
- return d->profileAdapter()->customUrlSchemeHandlers().value(scheme.toLower());
+ return d->profileAdapter()->urlSchemeHandler(scheme);
}
/*!
@@ -703,10 +782,7 @@ const QWebEngineUrlSchemeHandler *QWebEngineProfile::urlSchemeHandler(const QByt
void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
Q_D(QWebEngineProfile);
- Q_ASSERT(handler);
- if (!d->profileAdapter()->addCustomUrlSchemeHandler(scheme, handler))
- return;
- connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->installUrlSchemeHandler(scheme, handler);
}
/*!
@@ -719,10 +795,7 @@ void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEn
void QWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
{
Q_D(QWebEngineProfile);
- Q_ASSERT(handler);
- if (!d->profileAdapter()->removeCustomUrlSchemeHandler(handler))
- return;
- disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->removeUrlSchemeHandler(handler);
}
/*!
@@ -735,10 +808,7 @@ void QWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handl
void QWebEngineProfile::removeUrlScheme(const QByteArray &scheme)
{
Q_D(QWebEngineProfile);
- QWebEngineUrlSchemeHandler *handler = d->profileAdapter()->takeCustomUrlSchemeHandler(scheme);
- if (!handler)
- return;
- disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->removeUrlScheme(scheme);
}
/*!
@@ -749,12 +819,43 @@ void QWebEngineProfile::removeUrlScheme(const QByteArray &scheme)
void QWebEngineProfile::removeAllUrlSchemeHandlers()
{
Q_D(QWebEngineProfile);
- d->profileAdapter()->clearCustomUrlSchemeHandlers();
+ d->profileAdapter()->removeAllUrlSchemeHandlers();
}
-void QWebEngineProfile::destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj)
+/*!
+ \since 5.13
+
+ Sets if this profile is to be used for downloading and caching when needed
+ during certificate verification, for instance for OCSP, CRLs, and AIA.
+
+ Only one QWebEngineProfile can do this at a time, and it is recommended
+ that the profile fullfilling this role has a disk HTTP cache to avoid
+ needlessly re-downloading. If you set the option on a second profile,
+ it will be disabled on the profile it is currently set.
+
+ Currently only affects Linux/NSS installations where it enables OCSP.
+
+ As long as one profile has \a enabled set to \c true, all other profiles
+ will be able to use it for their certificate verification.
+
+ \sa isUsedForGlobalCertificateVerification(), httpCacheType()
+*/
+void QWebEngineProfile::setUseForGlobalCertificateVerification(bool enabled)
{
- removeUrlSchemeHandler(obj);
+ Q_D(QWebEngineProfile);
+ d->profileAdapter()->setUseForGlobalCertificateVerification(enabled);
+}
+
+/*!
+ \since 5.13
+
+ Returns \c true if this profile is currently being used for global
+ certificate verification.
+*/
+bool QWebEngineProfile::isUsedForGlobalCertificateVerification() const
+{
+ Q_D(const QWebEngineProfile);
+ return d->profileAdapter()->isUsedForGlobalCertificateVerification();
}
/*!
@@ -768,4 +869,19 @@ void QWebEngineProfile::clearHttpCache()
d->profileAdapter()->clearHttpCache();
}
+/*!
+ \since 5.13
+
+ Returns the profile's client certificate store.
+*/
+QWebEngineClientCertificateStore *QWebEngineProfile::clientCertificateStore()
+{
+#if QT_CONFIG(ssl)
+ Q_D(QWebEngineProfile);
+ return d->profileAdapter()->clientCertificateStore();
+#else
+ return nullptr;
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index f9a564cd2..794ba6279 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -46,12 +46,17 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qstring.h>
+#include <functional>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QObject;
class QUrl;
+class QWebEngineClientCertificateStore;
class QWebEngineCookieStore;
class QWebEngineDownloadItem;
+class QWebEngineNotification;
class QWebEnginePage;
class QWebEnginePagePrivate;
class QWebEngineProfilePrivate;
@@ -106,7 +111,10 @@ public:
void setHttpCacheMaximumSize(int maxSize);
QWebEngineCookieStore* cookieStore();
+#if QT_DEPRECATED_SINCE(5, 13)
void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+#endif
+ void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
void clearAllVisitedLinks();
void clearVisitedLinks(const QList<QUrl> &urls);
@@ -128,19 +136,27 @@ public:
void setSpellCheckEnabled(bool enabled);
bool isSpellCheckEnabled() const;
+ void setUseForGlobalCertificateVerification(bool enabled = true);
+ bool isUsedForGlobalCertificateVerification() const;
+
+ QString downloadPath() const;
+ void setDownloadPath(const QString &path);
+
+ void setNotificationPresenter(std::function<void(std::unique_ptr<QWebEngineNotification>)> notificationPresenter);
+
+ QWebEngineClientCertificateStore *clientCertificateStore();
+
static QWebEngineProfile *defaultProfile();
Q_SIGNALS:
void downloadRequested(QWebEngineDownloadItem *download);
-private Q_SLOTS:
- void destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj);
-
private:
Q_DISABLE_COPY(QWebEngineProfile)
Q_DECLARE_PRIVATE(QWebEngineProfile)
QWebEngineProfile(QWebEngineProfilePrivate *, QObject *parent = Q_NULLPTR);
+ friend class QWebEnginePage;
friend class QWebEnginePagePrivate;
friend class QWebEngineUrlSchemeHandler;
QScopedPointer<QWebEngineProfilePrivate> d_ptr;
diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h
index cb43dace5..64e9500b0 100644
--- a/src/webenginewidgets/api/qwebengineprofile_p.h
+++ b/src/webenginewidgets/api/qwebengineprofile_p.h
@@ -60,6 +60,8 @@
#include <QScopedPointer>
#include <QSharedPointer>
+#include <functional>
+
namespace QtWebEngineCore {
class ProfileAdapter;
}
@@ -68,6 +70,7 @@ QT_BEGIN_NAMESPACE
class QWebEngineBrowserContext;
class QWebEngineProfilePrivate;
+class QWebEngineNotification;
class QWebEngineSettings;
class QWebEngineProfilePrivate : public QtWebEngineCore::ProfileAdapterClient {
@@ -86,6 +89,8 @@ public:
void downloadRequested(DownloadItemInfo &info) override;
void downloadUpdated(const DownloadItemInfo &info) override;
+ void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &) override;
+
void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
@@ -95,6 +100,7 @@ private:
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QScopedPointer<QWebEngineScriptCollection> m_scriptCollection;
QMap<quint32, QPointer<QWebEngineDownloadItem> > m_ongoingDownloads;
+ std::function<void(std::unique_ptr<QWebEngineNotification>)> m_notificationPresenter;
};
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index d91eb3f97..d9fb3b000 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -109,7 +109,8 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
return WebEngineSettings::JavascriptCanPaste;
case QWebEngineSettings::DnsPrefetchEnabled:
return WebEngineSettings::DnsPrefetchEnabled;
-
+ case QWebEngineSettings::PdfViewerEnabled:
+ return WebEngineSettings::PdfViewerEnabled;
default:
return WebEngineSettings::UnsupportedInCoreSettings;
}
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index 9100e32d5..d39291fed 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -96,6 +96,7 @@ public:
WebRTCPublicInterfacesOnly,
JavascriptCanPaste,
DnsPrefetchEnabled,
+ PdfViewerEnabled,
};
enum FontSize {
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 381f1385c..6e1138522 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -61,6 +61,7 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage
Q_Q(QWebEngineView);
if (oldPage) {
+ oldPage->d_ptr->wasHidden();
oldPage->disconnect(q);
}
@@ -74,6 +75,8 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage
QObject::connect(newPage, &QWebEnginePage::loadFinished, q, &QWebEngineView::loadFinished);
QObject::connect(newPage, &QWebEnginePage::selectionChanged, q, &QWebEngineView::selectionChanged);
QObject::connect(newPage, &QWebEnginePage::renderProcessTerminated, q, &QWebEngineView::renderProcessTerminated);
+ if (q->isVisible())
+ newPage->d_ptr->wasShown();
}
auto oldUrl = oldPage ? oldPage->url() : QUrl();
@@ -119,7 +122,7 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje
{
if (QWebEngineView *v = qobject_cast<QWebEngineView*>(object))
return new QWebEngineViewAccessible(v);
- return Q_NULLPTR;
+ return nullptr;
}
#endif // QT_NO_ACCESSIBILITY
@@ -461,7 +464,7 @@ QAccessibleInterface *QWebEngineViewAccessible::child(int index) const
{
if (index == 0 && view() && view()->page())
return view()->page()->d_func()->adapter->browserAccessible();
- return Q_NULLPTR;
+ return nullptr;
}
int QWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 2bf4d0413..e5c0c0c3e 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -287,6 +287,8 @@
This enum describes the platform feature access categories that the user may be asked to grant
or deny access to:
+ \value Notifications
+ Web notifications for the end-user.
\value Geolocation
Location hardware or service.
\value MediaAudioCapture
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index 88f6e05c2..ce75a4203 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -188,7 +188,9 @@
\value DnsPrefetchEnabled Specifies whether WebEngine will try to pre-fetch DNS entries to
speed up browsing.
Disabled by default. (Added in Qt 5.12)
-
+ \value PdfViewerEnabled Specifies that PDF documents will be opened in the internal PDF viewer
+ instead of being downloaded.
+ Enabled by default. (Added in Qt 5.13)
*/
/*!
diff --git a/src/webenginewidgets/printer_worker.cpp b/src/webenginewidgets/printer_worker.cpp
new file mode 100644
index 000000000..94a862cda
--- /dev/null
+++ b/src/webenginewidgets/printer_worker.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "printer_worker.h"
+
+#include "printing/pdfium_document_wrapper_qt.h"
+
+#include <QPainter>
+#include <QPrinter>
+
+namespace QtWebEngineCore {
+
+PrinterWorker::PrinterWorker(QSharedPointer<QByteArray> data, QPrinter *printer)
+ : m_data(data)
+ , m_printer(printer)
+{
+}
+
+PrinterWorker::~PrinterWorker()
+{
+}
+
+void PrinterWorker::print()
+{
+ if (!m_data->size()) {
+ qWarning("Failure to print on printer %ls: Print result data is empty.",
+ qUtf16Printable(m_printer->printerName()));
+ Q_EMIT resultReady(false);
+ return;
+ }
+
+ PdfiumDocumentWrapperQt pdfiumWrapper(m_data->constData(), m_data->size());
+
+ int toPage = m_printer->toPage();
+ int fromPage = m_printer->fromPage();
+ bool ascendingOrder = true;
+
+ if (fromPage == 0 && toPage == 0) {
+ fromPage = 1;
+ toPage = pdfiumWrapper.pageCount();
+ }
+ fromPage = qMax(1, fromPage);
+ toPage = qMin(pdfiumWrapper.pageCount(), toPage);
+
+ if (m_printer->pageOrder() == QPrinter::LastPageFirst) {
+ qSwap(fromPage, toPage);
+ ascendingOrder = false;
+ }
+
+ int pageCopies = 1;
+ int documentCopies = 1;
+
+ if (!m_printer->supportsMultipleCopies())
+ documentCopies = m_printer->copyCount();
+
+ if (m_printer->collateCopies()) {
+ pageCopies = documentCopies;
+ documentCopies = 1;
+ }
+
+ bool isLandscape = pdfiumWrapper.pageIsLandscape(0);
+ QPageLayout::Orientation prevOrientation = m_printer->pageLayout().orientation();
+ m_printer->setPageOrientation(isLandscape ? QPageLayout::Landscape : QPageLayout::Portrait);
+
+ QPainter painter;
+ if (!painter.begin(m_printer)) {
+ qWarning("Failure to print on printer %ls: Could not open printer for painting.",
+ qUtf16Printable(m_printer->printerName()));
+ Q_EMIT resultReady(false);
+ return;
+ }
+
+ for (int printedDocuments = 0; printedDocuments < documentCopies; printedDocuments++) {
+ if (printedDocuments > 0)
+ m_printer->newPage();
+
+ int currentPageIndex = fromPage;
+
+ for (int i = 0; true; i++) {
+ prevOrientation = m_printer->pageLayout().orientation();
+ isLandscape = pdfiumWrapper.pageIsLandscape(currentPageIndex - 1);
+ m_printer->setPageOrientation(isLandscape ? QPageLayout::Landscape : QPageLayout::Portrait);
+
+ QSize pageSize = m_printer->pageRect().size();
+
+ if (i > 0)
+ m_printer->newPage();
+
+ for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
+ if (m_printer->printerState() == QPrinter::Aborted
+ || m_printer->printerState() == QPrinter::Error) {
+ Q_EMIT resultReady(false);
+ return;
+ }
+
+ if (printedPages > 0)
+ m_printer->newPage();
+
+ QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1);
+ if (currentImage.isNull()) {
+ Q_EMIT resultReady(false);
+ return;
+ }
+
+ QRect targetRect = currentImage.rect();
+ // Scale down currentImage by both width and height to fit into the drawable area of the page.
+ float scaleFactor = (float)pageSize.width() / (float)targetRect.width();
+ targetRect = QRect(0, 0, targetRect.width() * scaleFactor, targetRect.height() * scaleFactor);
+ scaleFactor = (float)pageSize.height() / (float)targetRect.height();
+ targetRect = QRect(0, 0, targetRect.width() * scaleFactor, targetRect.height() * scaleFactor);
+
+ // Painting operations are automatically clipped to the bounds of the drawable part of the page.
+ painter.drawImage(targetRect, currentImage, currentImage.rect());
+ }
+
+ if (currentPageIndex == toPage)
+ break;
+
+ if (ascendingOrder)
+ currentPageIndex++;
+ else
+ currentPageIndex--;
+
+ m_printer->setPageOrientation(prevOrientation);
+ }
+ }
+ painter.end();
+
+ Q_EMIT resultReady(true);
+ return;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/webenginewidgets/printer_worker.h b/src/webenginewidgets/printer_worker.h
new file mode 100644
index 000000000..96025c90e
--- /dev/null
+++ b/src/webenginewidgets/printer_worker.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PRINTER_WORKER_H
+#define PRINTER_WORKER_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include <QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+class QPrinter;
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+class PrinterWorker : public QObject
+{
+ Q_OBJECT
+public:
+ PrinterWorker(QSharedPointer<QByteArray> data, QPrinter *printer);
+ virtual ~PrinterWorker();
+
+public Q_SLOTS:
+ void print();
+
+Q_SIGNALS:
+ void resultReady(bool success);
+
+private:
+ Q_DISABLE_COPY(PrinterWorker)
+
+ QSharedPointer<QByteArray> m_data;
+ QPrinter *m_printer;
+};
+
+} // namespace QtWebEngineCore
+
+Q_DECLARE_METATYPE(QtWebEngineCore::PrinterWorker*)
+
+#endif // PRINTER_WORKER_H
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index 18f1e97d0..88eb9843b 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -124,25 +124,31 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
"QSurfaceFormat before the QtGui application instance is created.");
}
#endif
-
- // Make sure the OpenGL profile of the QQuickWidget matches the shared context profile.
- if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
- int major;
- int minor;
- QSurfaceFormat::OpenGLContextProfile profile;
-
+ int major;
+ int minor;
+ QSurfaceFormat::OpenGLContextProfile profile;
#ifdef Q_OS_MACOS
- // Due to QTBUG-63180, requesting the sharedFormat.majorVersion() on macOS will lead to
- // a failed creation of QQuickWidget shared context. Thus make sure to request the
- // major version specified in the defaultFormat instead.
- major = defaultFormat.majorVersion();
- minor = defaultFormat.minorVersion();
- profile = defaultFormat.profile();
+ // Due to QTBUG-63180, requesting the sharedFormat.majorVersion() on macOS will lead to
+ // a failed creation of QQuickWidget shared context. Thus make sure to request the
+ // major version specified in the defaultFormat instead.
+ major = defaultFormat.majorVersion();
+ minor = defaultFormat.minorVersion();
+ profile = defaultFormat.profile();
#else
- major = sharedFormat.majorVersion();
- minor = sharedFormat.minorVersion();
- profile = sharedFormat.profile();
+ major = sharedFormat.majorVersion();
+ minor = sharedFormat.minorVersion();
+ profile = sharedFormat.profile();
#endif
+
+ // Make sure the OpenGL profile of the QQuickWidget matches the shared context profile.
+ // It covers the following cases:
+ // 1) Desktop OpenGL Core Profile.
+ // 2) Windows ANGLE OpenGL ES profile.
+ if (sharedFormat.profile() == QSurfaceFormat::CoreProfile
+#ifdef Q_OS_WIN
+ || globalSharedContext->isOpenGLES()
+#endif
+ ) {
format.setMajorVersion(major);
format.setMinorVersion(minor);
format.setProfile(profile);
@@ -183,7 +189,7 @@ void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
{
// Unset the parent, because parent is being destroyed, but the owner of this
// RenderWidgetHostViewQtDelegateWidget is actually a RenderWidgetHostViewQt instance.
- setParent(Q_NULLPTR);
+ setParent(nullptr);
// If this widget represents a popup window, make sure to close it, so that if the popup was the
// last visible top level window, the application event loop can quit if it deems it necessarry.
@@ -219,15 +225,16 @@ void RenderWidgetHostViewQtDelegateWidget::closeEvent(QCloseEvent *event)
m_client->closePopup();
}
-QRectF RenderWidgetHostViewQtDelegateWidget::screenRect() const
+QRectF RenderWidgetHostViewQtDelegateWidget::viewGeometry() const
{
- return QRectF(x(), y(), width(), height());
+ return QRectF(mapToGlobal(pos()), size());
}
-QRectF RenderWidgetHostViewQtDelegateWidget::contentsRect() const
+QRect RenderWidgetHostViewQtDelegateWidget::windowGeometry() const
{
- QPointF pos = mapToGlobal(QPoint(0, 0));
- return QRectF(pos.x(), pos.y(), width(), height());
+ if (!window())
+ return QRect();
+ return window()->frameGeometry();
}
void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus()
@@ -365,14 +372,7 @@ QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQ
void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent)
{
QQuickWidget::resizeEvent(resizeEvent);
-
- const QPoint globalPos = mapToGlobal(pos());
- if (globalPos != m_lastGlobalPos) {
- m_lastGlobalPos = globalPos;
- m_client->windowBoundsChanged();
- }
-
- m_client->notifyResize();
+ m_client->visualPropertiesChanged();
}
void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
@@ -388,7 +388,7 @@ void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
m_windowConnections.append(connect(w, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
}
- m_client->windowChanged();
+ m_client->visualPropertiesChanged();
m_client->notifyShown();
}
@@ -486,8 +486,7 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
void RenderWidgetHostViewQtDelegateWidget::onWindowPosChanged()
{
- m_lastGlobalPos = mapToGlobal(pos());
- m_client->windowBoundsChanged();
+ m_client->visualPropertiesChanged();
}
} // namespace QtWebEngineCore
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index c1cd90093..7746c4405 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -66,8 +66,8 @@ public:
~RenderWidgetHostViewQtDelegateWidget();
void initAsPopup(const QRect&) override;
- QRectF screenRect() const override;
- QRectF contentsRect() const override;
+ QRectF viewGeometry() const override;
+ QRect windowGeometry() const override;
void setKeyboardFocus() override;
bool hasKeyboardFocus() override;
void lockMouse() override;
@@ -111,7 +111,6 @@ private:
QScopedPointer<QQuickItem> m_rootItem;
bool m_isPopup;
QColor m_clearColor;
- QPoint m_lastGlobalPos;
QList<QMetaObject::Connection> m_windowConnections;
QWebEnginePage *m_page = nullptr;
QMetaObject::Connection m_parentDestroyedConnection;
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index e61575d3a..d4fb40dc7 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -19,6 +19,7 @@ SOURCES = \
api/qwebenginedownloaditem.cpp \
api/qwebenginefullscreenrequest.cpp \
api/qwebenginehistory.cpp \
+ api/qwebenginenotificationpresenter.cpp \
api/qwebenginepage.cpp \
api/qwebengineprofile.cpp \
api/qwebenginescript.cpp \
@@ -36,6 +37,7 @@ HEADERS = \
api/qwebenginedownloaditem_p.h \
api/qwebenginefullscreenrequest.h \
api/qwebenginehistory.h \
+ api/qwebenginenotificationpresenter_p.h \
api/qwebenginepage.h \
api/qwebenginepage_p.h \
api/qwebengineprofile.h \
@@ -49,6 +51,9 @@ HEADERS = \
qtConfig(webengine-printing-and-pdf) {
QT += printsupport
+
+ SOURCES += printer_worker.cpp
+ HEADERS += printer_worker.h
}
load(qt_module)