summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--config.tests/winversion/winversion.cpp2
-rw-r--r--configure.json3
-rw-r--r--configure.pri5
-rw-r--r--examples/webengine/quicknanobrowser/ApplicationRoot.qml3
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml14
-rw-r--r--examples/webengine/webengine.pro3
-rw-r--r--examples/webengine/webengineaction/doc/images/webengineaction-example.pngbin0 -> 100266 bytes
-rw-r--r--examples/webengine/webengineaction/doc/src/webengineaction.qdoc68
-rw-r--r--examples/webengine/webengineaction/main.cpp67
-rw-r--r--examples/webengine/webengineaction/main.qml166
-rw-r--r--examples/webengine/webengineaction/qml.qrc5
-rw-r--r--examples/webengine/webengineaction/webengineaction.pro10
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.cpp3
-rw-r--r--examples/webenginewidgets/simplebrowser/main.cpp3
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.cpp2
-rw-r--r--mkspecs/features/gn_generator.prf4
m---------src/3rdparty0
-rw-r--r--src/buildtools/gn.pro8
-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/qwebengineclientcertificatestore.cpp128
-rw-r--r--src/core/api/qwebengineclientcertificatestore.h79
-rw-r--r--src/core/api/qwebenginenotification.cpp280
-rw-r--r--src/core/api/qwebenginenotification.h105
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp24
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h5
-rw-r--r--src/core/api/qwebengineurlrequestinterceptor.h2
-rw-r--r--src/core/api/qwebengineurlrequestjob.cpp9
-rw-r--r--src/core/api/qwebengineurlrequestjob.h1
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp1
-rw-r--r--src/core/api/qwebengineurlschemehandler.h5
-rw-r--r--src/core/authentication_dialog_controller.cpp9
-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/chromium_overrides.cpp81
-rw-r--r--src/core/client_cert_select_controller.cpp40
-rw-r--r--src/core/client_cert_select_controller.h2
-rw-r--r--src/core/clipboard_qt.cpp124
-rw-r--r--src/core/clipboard_qt.h6
-rw-r--r--src/core/color_chooser_controller.cpp3
-rw-r--r--src/core/color_chooser_controller.h3
-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.cpp259
-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)561
-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.pri23
-rw-r--r--src/core/config/linux.pri12
-rw-r--r--src/core/config/mac_osx.pri2
-rw-r--r--src/core/configure.json45
-rw-r--r--src/core/content_browser_client_qt.cpp264
-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.cpp21
-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.pri99
-rw-r--r--src/core/core_common.pri4
-rw-r--r--src/core/core_gn_config.pri10
-rw-r--r--src/core/devtools_frontend_qt.cpp27
-rw-r--r--src/core/download_manager_delegate_qt.cpp6
-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/file_picker_controller.cpp38
-rw-r--r--src/core/file_picker_controller.h12
-rw-r--r--src/core/gn_run.pro2
-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/network_delegate_qt.cpp221
-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.cpp68
-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.h6
-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.cpp187
-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.cpp5
-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/profile_adapter.cpp141
-rw-r--r--src/core/profile_adapter.h52
-rw-r--r--src/core/profile_adapter_client.h5
-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.gni30
-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_widget_host_view_qt.cpp355
-rw-r--r--src/core/render_widget_host_view_qt.h59
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h7
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp173
-rw-r--r--src/core/renderer/content_renderer_client_qt.h41
-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.cpp204
-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_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/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.cpp219
-rw-r--r--src/core/user_notification_controller.h114
-rw-r--r--src/core/visited_links_manager_qt.cpp10
-rw-r--r--src/core/visited_links_manager_qt.h4
-rw-r--r--src/core/web_contents_adapter.cpp156
-rw-r--r--src/core/web_contents_adapter.h2
-rw-r--r--src/core/web_contents_adapter_client.h11
-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.cpp231
-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_library_info.cpp1
-rw-r--r--src/core/web_engine_settings.cpp5
-rw-r--r--src/core/web_engine_settings.h1
-rw-r--r--src/core/web_event_factory.cpp32
-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.cpp220
-rw-r--r--src/webengine/api/qquickwebengineprofile.h24
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h4
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp22
-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.h (renamed from src/core/net/url_request_qrc_job_qt.h)55
-rw-r--r--src/webengine/api/qquickwebengineview.cpp106
-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.json29
-rw-r--r--src/webengine/doc/src/external-resources.qdoc5
-rw-r--r--src/webengine/doc/src/qtwebengine-features.qdoc10
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc14
-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.cpp59
-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.cpp32
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h4
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp9
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h3
-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.cpp79
-rw-r--r--src/webengine/ui_delegates_manager.h7
-rw-r--r--src/webengine/webengine.pro92
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter.cpp105
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter_p.h83
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp171
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h5
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h11
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp176
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h21
-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/doc/src/qwebenginepage_lgpl.qdoc2
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc4
-rw-r--r--src/webenginewidgets/printer_worker.cpp147
-rw-r--r--src/webenginewidgets/printer_worker.h88
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp62
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h4
-rw-r--r--src/webenginewidgets/webenginewidgets.pro5
-rw-r--r--tests/auto/core/core.pro7
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro1
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt23
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt23
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key28
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key28
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp98
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc8
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp51
-rw-r--r--tests/auto/quick/dialogs/BLACKLIST2
-rw-r--r--tests/auto/quick/dialogs/dialogs.pro2
-rw-r--r--tests/auto/quick/dialogs/tst_dialogs.cpp1
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp39
-rw-r--r--tests/auto/quick/qmltests/data/tst_download.qml20
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml4
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml5
-rw-r--r--tests/auto/quick/qmltests/data/tst_notification.qml122
-rw-r--r--tests/auto/quick/qmltests/data/tst_profile.qml66
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro2
-rw-r--r--tests/auto/quick/qquickwebengineview/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickwebengineview/qquickwebengineview.pro2
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp11
-rw-r--r--tests/auto/quick/quick.pro6
-rw-r--r--tests/auto/quick/tests.pri4
-rw-r--r--tests/auto/shared/data/notification.html70
-rw-r--r--tests/auto/widgets/offscreen/offscreen.pro6
-rw-r--r--tests/auto/widgets/offscreen/tst_offscreen.cpp60
-rw-r--r--tests/auto/widgets/origins/tst_origins.cpp25
-rw-r--r--tests/auto/widgets/proxy/proxy.pro9
-rw-r--r--tests/auto/widgets/proxy/proxy_server.cpp90
-rw-r--r--tests/auto/widgets/proxy/proxy_server.h59
-rw-r--r--tests/auto/widgets/proxy/tst_proxy.cpp69
-rw-r--r--tests/auto/widgets/proxypac/proxypac.pro24
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/BLACKLIST2
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp268
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST6
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp1502
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc3
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp65
-rw-r--r--tests/auto/widgets/qwebenginescript/BLACKLIST3
-rw-r--r--tests/auto/widgets/qwebengineview/resources/image2.pngbin0 -> 14743 bytes
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp11
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc1
-rw-r--r--tests/auto/widgets/widgets.pro15
-rw-r--r--tests/manual/widgets/inputmethods/testview.cpp11
-rw-r--r--tests/manual/widgets/webgl/main.cpp184
-rw-r--r--tests/manual/widgets/webgl/webgl.pro6
-rw-r--r--tests/manual/widgets/widgets.pro3
-rw-r--r--tests/quicktestbrowser/ApplicationRoot.qml1
-rw-r--r--tests/quicktestbrowser/BrowserWindow.qml12
-rw-r--r--tests/quicktestbrowser/FeaturePermissionBar.qml29
-rwxr-xr-xtools/buildscripts/repack_locales.py15
-rw-r--r--tools/scripts/gn_find_mocables.py3
-rwxr-xr-xtools/scripts/take_snapshot.py267
-rw-r--r--tools/scripts/version_resolver.py7
344 files changed, 15907 insertions, 4282 deletions
diff --git a/.qmake.conf b/.qmake.conf
index b6a222b54..26852b80b 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -5,4 +5,4 @@ QTWEBENGINE_OUT_ROOT = $$shadowed($$PWD)
load(qt_build_config)
CONFIG += warning_clean
-MODULE_VERSION = 5.12.3
+MODULE_VERSION = 5.13.0
diff --git a/config.tests/winversion/winversion.cpp b/config.tests/winversion/winversion.cpp
index 4d117b945..e9a4cff59 100644
--- a/config.tests/winversion/winversion.cpp
+++ b/config.tests/winversion/winversion.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#if !defined(__clang__) && _MSC_FULL_VER < 191125507
+#if !defined(__clang__) && _MSC_FULL_VER < 191426428
#error unsupported Visual Studio version
#endif
diff --git a/configure.json b/configure.json
index 40d6bfe56..60b7342f7 100644
--- a/configure.json
+++ b/configure.json
@@ -1,5 +1,6 @@
{
"subconfigs": [
- "src/core"
+ "src/core",
+ "src/webengine"
]
}
diff --git a/configure.pri b/configure.pri
index 26c57ce61..8db31ddd3 100644
--- a/configure.pri
+++ b/configure.pri
@@ -312,3 +312,8 @@ defineTest(qtConfTest_hasThumbFlag) {
# no flag assume mthumb
return(true)
}
+
+defineTest(qtConfTest_hasGcc6OrNewer) {
+ greaterThan(QMAKE_GCC_MAJOR_VERSION, 5):return(true)
+ return(false)
+}
diff --git a/examples/webengine/quicknanobrowser/ApplicationRoot.qml b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
index 67b686541..3bc571546 100644
--- a/examples/webengine/quicknanobrowser/ApplicationRoot.qml
+++ b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
@@ -49,7 +49,7 @@
****************************************************************************/
import QtQuick 2.1
-import QtWebEngine 1.2
+import QtWebEngine 1.9
QtObject {
id: root
@@ -57,6 +57,7 @@ QtObject {
property QtObject defaultProfile: WebEngineProfile {
storageName: "Profile"
offTheRecord: false
+ useForGlobalCertificateVerification: true
}
property QtObject otrProfile: WebEngineProfile {
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index 0ac69ef24..d3d597e2b 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -57,7 +57,7 @@ import QtQuick.Controls.Styles 1.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.0
import QtQuick.Window 2.1
-import QtWebEngine 1.7
+import QtWebEngine 1.9
ApplicationWindow {
id: browserWindow
@@ -89,6 +89,7 @@ ApplicationWindow {
property alias touchIconsEnabled: touchIconsEnabled.checked
property alias webRTCPublicInterfacesOnly : webRTCPublicInterfacesOnly.checked
property alias devToolsEnabled: devToolsEnabled.checked
+ property alias pdfViewerEnabled: pdfViewerEnabled.checked
}
Action {
@@ -333,6 +334,12 @@ ApplicationWindow {
checkable: true
checked: false
}
+ MenuItem {
+ id: pdfViewerEnabled
+ text: "PDF viewer enabled"
+ checkable: true
+ checked: WebEngine.settings.pdfViewerEnabled
+ }
}
}
}
@@ -411,6 +418,7 @@ ApplicationWindow {
settings.autoLoadIconsForPage: appSettings.autoLoadIconsForPage
settings.touchIconsEnabled: appSettings.touchIconsEnabled
settings.webRTCPublicInterfacesOnly: appSettings.webRTCPublicInterfacesOnly
+ settings.pdfViewerEnabled: appSettings.pdfViewerEnabled
onCertificateError: function(error) {
error.defer();
@@ -491,6 +499,10 @@ ApplicationWindow {
tabs.removeTab(tabs.currentIndex);
}
+ onSelectClientCertificate: function(selection) {
+ selection.certificates[0].select();
+ }
+
Timer {
id: reloadTimer
interval: 0
diff --git a/examples/webengine/webengine.pro b/examples/webengine/webengine.pro
index b20b8f118..5ad620390 100644
--- a/examples/webengine/webengine.pro
+++ b/examples/webengine/webengine.pro
@@ -3,7 +3,8 @@ TEMPLATE=subdirs
SUBDIRS += \
customdialogs \
minimal \
- quicknanobrowser
+ quicknanobrowser \
+ webengineaction
qtHaveModule(quickcontrols2) {
SUBDIRS += \
diff --git a/examples/webengine/webengineaction/doc/images/webengineaction-example.png b/examples/webengine/webengineaction/doc/images/webengineaction-example.png
new file mode 100644
index 000000000..2e34bbf63
--- /dev/null
+++ b/examples/webengine/webengineaction/doc/images/webengineaction-example.png
Binary files differ
diff --git a/examples/webengine/webengineaction/doc/src/webengineaction.qdoc b/examples/webengine/webengineaction/doc/src/webengineaction.qdoc
new file mode 100644
index 000000000..672f86f0f
--- /dev/null
+++ b/examples/webengine/webengineaction/doc/src/webengineaction.qdoc
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webengine/webengineaction
+ \title WebEngine Action Example
+ \ingroup webengine-examples
+ \brief A simple browser implemented using WebEngineActions.
+
+ \image webengineaction-example.png
+
+ \e {WebEngine Action Example} demonstrates how to perform actions on a web page
+ using the \l{WebEngineAction} type. It shows the minimum amount of code needed
+ to bind browser functionalities to input elements and build up a custom context
+ menu.
+
+ \include examples-run.qdocinc
+
+ \section1 Working With Web Engine Actions
+
+ An intended use of \l{WebEngineAction} is building a connection between UI
+ elements and browser commands. It can be added to menus and toolbars via
+ assigning its properties to the corresponding ones of the element.
+
+ The \l{ToolButton} relies on the properties provided by a
+ \l{WebEngineAction}. Clicking the button triggers backwards navigation on the
+ originating \l{WebEngineView} of the action.
+
+ \quotefromfile webengine/webengineaction/main.qml
+ \skipto ToolButton {
+ \printuntil }
+
+ The simplest way to create custom context menus is enumerating the required
+ \l{WebEngineAction} types in a data model and instantiating \l{MenuItem} types
+ for them, for example using a \l{Repeater}.
+
+ \quotefromfile webengine/webengineaction/main.qml
+ \skipto property Menu contextMenu: Menu {
+ \printuntil /^ {8}\}/
+
+ Assigning a \l{WebEngineAction} to multiple UI elements will keep them in sync.
+ As it can be seen in the picture above, if the browser engine disables a
+ navigation action, both corresponding menu items will be disabled.
+*/
diff --git a/examples/webengine/webengineaction/main.cpp b/examples/webengine/webengineaction/main.cpp
new file mode 100644
index 000000000..ce723a99b
--- /dev/null
+++ b/examples/webengine/webengineaction/main.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <qtwebengineglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+}
diff --git a/examples/webengine/webengineaction/main.qml b/examples/webengine/webengineaction/main.qml
new file mode 100644
index 000000000..a3933ee41
--- /dev/null
+++ b/examples/webengine/webengineaction/main.qml
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Window 2.0
+import QtWebEngine 1.7
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.11
+
+ApplicationWindow {
+ id: window
+ visible: true
+ width: 800
+ height: 600
+ title: qsTr("WebEngineAction Example")
+
+ header: ToolBar {
+ RowLayout {
+ anchors.fill: parent
+
+ ToolButton {
+ property int itemAction: WebEngineView.Back
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ ToolButton {
+ property int itemAction: WebEngineView.Forward
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ ToolButton {
+ property int itemAction: webEngineView.loading ? WebEngineView.Stop : WebEngineView.Reload
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ TextField {
+ Layout.fillWidth: true
+
+ text: webEngineView.url
+ selectByMouse: true
+ onEditingFinished: webEngineView.url = text
+ }
+
+ ToolButton {
+ id: settingsButton
+ text: "Settings"
+ icon.name: "settings-configure"
+ display: AbstractButton.TextUnderIcon
+ onClicked: settingsMenu.open()
+ checked: settingsMenu.visible
+
+ Menu {
+ id: settingsMenu
+ y: settingsButton.height
+
+ MenuItem {
+ id: customContextMenuOption
+ checkable: true
+ checked: true
+
+ text: "Custom context menu"
+ }
+ }
+ }
+ }
+ }
+
+ WebEngineView {
+ id: webEngineView
+ url: "https://qt.io"
+ anchors.fill: parent
+
+ Component.onCompleted: {
+ profile.downloadRequested.connect(function(download){
+ download.accept();
+ })
+ }
+
+ property Menu contextMenu: Menu {
+ Repeater {
+ model: [
+ WebEngineView.Back,
+ WebEngineView.Forward,
+ WebEngineView.Reload,
+ WebEngineView.SavePage,
+ WebEngineView.Copy,
+ WebEngineView.Paste,
+ WebEngineView.Cut
+ ]
+ MenuItem {
+ text: webEngineView.action(modelData).text
+ enabled: webEngineView.action(modelData).enabled
+ onClicked: webEngineView.action(modelData).trigger()
+ icon.name: webEngineView.action(modelData).iconName
+ display: MenuItem.TextBesideIcon
+ }
+ }
+ }
+
+ onContextMenuRequested: function(request) {
+ if (customContextMenuOption.checked) {
+ request.accepted = true;
+ contextMenu.popup();
+ }
+ }
+ }
+}
diff --git a/examples/webengine/webengineaction/qml.qrc b/examples/webengine/webengineaction/qml.qrc
new file mode 100644
index 000000000..5f6483ac3
--- /dev/null
+++ b/examples/webengine/webengineaction/qml.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/webengine/webengineaction/webengineaction.pro b/examples/webengine/webengineaction/webengineaction.pro
new file mode 100644
index 000000000..13cc4602d
--- /dev/null
+++ b/examples/webengine/webengineaction/webengineaction.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+
+QT += webengine
+
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webengine/webengineaction
+INSTALLS += target
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
index 4351dfe71..5d00cd19a 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
@@ -62,6 +62,7 @@
#include <QMenuBar>
#include <QMessageBox>
#include <QProgressBar>
+#include <QScreen>
#include <QStatusBar>
#include <QToolBar>
#include <QVBoxLayout>
@@ -143,7 +144,7 @@ BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool
QSize BrowserWindow::sizeHint() const
{
- QRect desktopRect = QApplication::desktop()->screenGeometry();
+ QRect desktopRect = QApplication::primaryScreen()->geometry();
QSize size = desktopRect.size() * qreal(0.9);
return size;
}
diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp
index 0e8f86c8f..7b77a4bd2 100644
--- a/examples/webenginewidgets/simplebrowser/main.cpp
+++ b/examples/webenginewidgets/simplebrowser/main.cpp
@@ -52,6 +52,7 @@
#include "browserwindow.h"
#include "tabwidget.h"
#include <QApplication>
+#include <QWebEngineProfile>
#include <QWebEngineSettings>
QUrl commandLineUrlArgument()
@@ -74,6 +75,8 @@ int main(int argc, char **argv)
app.setWindowIcon(QIcon(QStringLiteral(":AppLogoColor.png")));
QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
+ QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, true);
+ QWebEngineProfile::defaultProfile()->setUseForGlobalCertificateVerification();
QUrl url = commandLineUrlArgument();
diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp
index e44410284..99849c77d 100644
--- a/examples/webenginewidgets/simplebrowser/webpage.cpp
+++ b/examples/webenginewidgets/simplebrowser/webpage.cpp
@@ -138,7 +138,7 @@ inline QString questionForFeature(QWebEnginePage::Feature feature)
case QWebEnginePage::DesktopAudioVideoCapture:
return WebPage::tr("Allow %1 to capture audio and video of your desktop?");
case QWebEnginePage::Notifications:
- return QString();
+ return WebPage::tr("Allow %1 to show notification on your desktop?");
}
return QString();
}
diff --git a/mkspecs/features/gn_generator.prf b/mkspecs/features/gn_generator.prf
index c1399a453..e6ae263ac 100644
--- a/mkspecs/features/gn_generator.prf
+++ b/mkspecs/features/gn_generator.prf
@@ -29,12 +29,12 @@ isEmpty(GN_FIND_MOCABLES_SCRIPT): GN_FIND_MOCABLES_SCRIPT = "//build/gn_find_moc
# MOC SETUP
GN_CONTENTS += "moc_source_h_files = exec_script(\"$$GN_FIND_MOCABLES_SCRIPT\","
-GN_CONTENTS += " [ \"$$_PRO_FILE_PWD_\","
+GN_CONTENTS += " ["
for (headerfile, HEADERS): GN_CONTENTS += " \"$$GN_SRC_DIR/$$headerfile\","
GN_CONTENTS += " ], \"list lines\", [\"$$system_path($$_PRO_FILE_)\"]"\
")"
GN_CONTENTS += "moc_source_cpp_files = exec_script(\"$$GN_FIND_MOCABLES_SCRIPT\","
-GN_CONTENTS += " [ \"$$_PRO_FILE_PWD_\","
+GN_CONTENTS += " ["
for (sourcefile, SOURCES): GN_CONTENTS += " \"$$GN_SRC_DIR/$$sourcefile\","
GN_CONTENTS += " ], \"list lines\", [\"$$system_path($$_PRO_FILE_)\"]"\
")"
diff --git a/src/3rdparty b/src/3rdparty
-Subproject e8bb1f1a6b2877c86519749ffab34f94bb6a102
+Subproject 10fd63a07a381a3ab3b27ef8906817173e3ffbb
diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro
index 559cdf183..30ada9357 100644
--- a/src/buildtools/gn.pro
+++ b/src/buildtools/gn.pro
@@ -18,7 +18,13 @@ 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_configure = $$system_quote($$gn_bootstrap) --no-last-commit-position --out-path $$out_path \
+ --cc \"$$which($$QMAKE_CC)\" --cxx \"$$which($$QMAKE_CXX)\" \
+ --ld \"$$which($$QMAKE_LINK)\"
+ 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/qwebengineclientcertificatestore.cpp b/src/core/api/qwebengineclientcertificatestore.cpp
new file mode 100644
index 000000000..854628b29
--- /dev/null
+++ b/src/core/api/qwebengineclientcertificatestore.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** 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::Entry
+ \inmodule QtWebEngineCore
+ \since 5.13
+ \brief This structure holds the certificate and the private key.
+*/
+
+/*!
+ \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..d9a1a0545
--- /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;
+}
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(ssl)
+
+class QWEBENGINECORE_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/qwebenginenotification.cpp b/src/core/api/qwebenginenotification.cpp
new file mode 100644
index 000000000..89fd1eff9
--- /dev/null
+++ b/src/core/api/qwebenginenotification.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** 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;
+
+/*!
+ \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 in the
+ \l QWebEngineProfile::setNotificationPresenter() and
+ \l QQuickWebEngineProfile::userNotification() calls and the
+ \l WebEngineProfile::userNotification() signal.
+*/
+
+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 *) Q_DECL_OVERRIDE
+ {
+ Q_EMIT q->closed();
+ }
+
+ QSharedPointer<UserNotificationController> controller;
+ QWebEngineNotification *q;
+};
+
+
+/*!
+ Creates a null QWebEngineNotification.
+
+ \sa isNull()
+*/
+QWebEngineNotification::QWebEngineNotification() { }
+
+/*! \internal
+*/
+QWebEngineNotification::QWebEngineNotification(const QSharedPointer<UserNotificationController> &controller)
+ : d_ptr(new QWebEngineNotificationPrivate(this, controller))
+{ }
+
+/*! \internal
+*/
+QWebEngineNotification::QWebEngineNotification(const QWebEngineNotification &other)
+ : QObject()
+ , d_ptr(new QWebEngineNotificationPrivate(this, other.d_ptr->controller))
+{ }
+
+/*! \internal
+*/
+QWebEngineNotification::~QWebEngineNotification()
+{
+}
+
+/*! \internal
+*/
+const QWebEngineNotification &QWebEngineNotification::operator=(const QWebEngineNotification &other)
+{
+ d_ptr.reset(new QWebEngineNotificationPrivate(this, other.d_ptr->controller));
+ return *this;
+}
+
+/*!
+ 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 (!d_ptr)
+ return !other.d_ptr;
+ if (!other.d_ptr)
+ return false;
+ return tag() == other.tag() && origin() == other.origin();
+}
+
+/*!
+ \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();
+}
+
+/*!
+ \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();
+}
+
+/*!
+ \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();
+}
+
+/*!
+ \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();
+}
+
+/*!
+ \property QWebEngineNotification::icon
+ \brief The icon to be shown with the notification.
+
+ If no icon is set by the sender, an null QIcon is returned.
+*/
+QIcon QWebEngineNotification::icon() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->icon() : QIcon();
+}
+
+/*!
+ \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();
+}
+
+/*!
+ \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;
+}
+
+/*!
+ Returns \c true if the notification is not a default constructed null notification.
+*/
+bool QWebEngineNotification::isValid() const
+{
+ return !d_ptr.isNull();
+}
+
+/*!
+ 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();
+}
+
+/*!
+ 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();
+}
+
+/*!
+ 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();
+}
+
+/*!
+ \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..0012e5d78
--- /dev/null
+++ b/src/core/api/qwebenginenotification.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** 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>
+#include <QtGui/QIcon>
+
+namespace QtWebEngineCore {
+class UserNotificationController;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineNotificationPrivate;
+
+class QWEBENGINECORE_EXPORT QWebEngineNotification : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
+ Q_PROPERTY(QIcon icon READ icon 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:
+ QWebEngineNotification();
+ QWebEngineNotification(const QWebEngineNotification &other);
+ virtual ~QWebEngineNotification();
+ const QWebEngineNotification &operator=(const QWebEngineNotification &other);
+
+ bool matches(const QWebEngineNotification &other) const;
+
+ QUrl origin() const;
+ QIcon icon() const;
+ QString title() const;
+ QString message() const;
+ QString tag() const;
+ QString language() const;
+ Qt::LayoutDirection direction() const;
+
+ bool isValid() const;
+
+public Q_SLOTS:
+ void show() const;
+ void click() const;
+ void close() const;
+
+Q_SIGNALS:
+ void closed();
+
+private:
+ QWebEngineNotification(const QSharedPointer<QtWebEngineCore::UserNotificationController> &controller);
+ Q_DECLARE_PRIVATE(QWebEngineNotification)
+ QScopedPointer<QWebEngineNotificationPrivate> d_ptr;
+ friend class QQuickWebEngineProfilePrivate;
+ friend class QWebEngineProfilePrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINENOTIFICATION_H
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index ea9081fc1..dc2d07740 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -96,8 +96,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 +115,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.
@@ -140,10 +139,17 @@ QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRe
/*!
\internal
*/
+QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfo &&p)
+ : d_ptr(p.d_ptr.take())
+{
+}
+
+/*!
+ \internal
+*/
QWebEngineUrlRequestInfo::~QWebEngineUrlRequestInfo()
{
-
}
/*!
@@ -260,6 +266,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..e1f9ca6ef 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -47,6 +47,7 @@
namespace QtWebEngineCore {
class NetworkDelegateQt;
+class URLRequestNotification;
}
QT_BEGIN_NAMESPACE
@@ -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/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h
index dc2a15ee3..2b07681ca 100644
--- a/src/core/api/qwebengineurlrequestinterceptor.h
+++ b/src/core/api/qwebengineurlrequestinterceptor.h
@@ -55,7 +55,7 @@ class QWEBENGINECORE_EXPORT QWebEngineUrlRequestInterceptor : public QObject
Q_OBJECT
Q_DISABLE_COPY(QWebEngineUrlRequestInterceptor)
public:
- explicit QWebEngineUrlRequestInterceptor(QObject *p = Q_NULLPTR)
+ explicit QWebEngineUrlRequestInterceptor(QObject *p = nullptr)
: QObject (p)
{
}
diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index c3541598b..bc860b3b3 100644
--- a/src/core/api/qwebengineurlrequestjob.cpp
+++ b/src/core/api/qwebengineurlrequestjob.cpp
@@ -140,6 +140,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..b2dd8baa3 100644
--- a/src/core/api/qwebengineurlrequestjob.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -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);
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..549778561 100644
--- a/src/core/api/qwebengineurlschemehandler.h
+++ b/src/core/api/qwebengineurlschemehandler.h
@@ -60,11 +60,6 @@ public:
virtual void requestStarted(QWebEngineUrlRequestJob*) = 0;
-#ifndef Q_QDOC
-Q_SIGNALS:
- void _q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*);
-#endif
-
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/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/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..8f4f78d94 100644
--- a/src/core/client_cert_select_controller.h
+++ b/src/core/client_cert_select_controller.h
@@ -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_qt.cpp b/src/core/clipboard_qt.cpp
index 44756bdfe..d7fa225cd 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -43,6 +43,8 @@
#include "clipboard_qt.h"
#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_format_type.h"
#include "type_conversion.h"
@@ -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()
{
@@ -104,104 +100,6 @@ 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()
-{
- 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;
-}
-#endif
-
} // namespace ui
namespace QtWebEngineCore {
@@ -240,12 +138,12 @@ void ClipboardQt::WriteHTML(const char* markup_data, size_t markup_len, const ch
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)
@@ -264,15 +162,15 @@ void ClipboardQt::WriteBookmark(const char* title_data, size_t title_len, const
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);
+ 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);
return mimeData && mimeData->hasFormat(QString::fromStdString(format.ToString()));
@@ -301,7 +199,7 @@ 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);
}
@@ -340,7 +238,7 @@ 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);
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());
}
@@ -374,7 +272,7 @@ void ClipboardQt::ReadCustomData(ui::ClipboardType clipboard_type, const base::s
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);
}
@@ -383,7 +281,7 @@ 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)
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
index 2089208bf..d5fa35af6 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -66,7 +66,7 @@ private:
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;
@@ -80,7 +80,7 @@ public:
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 ReadData(const ui::ClipboardFormatType& format, std::string* result) const override;
void OnPreShutdown() override { }
@@ -92,7 +92,7 @@ protected:
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 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..e5daa09a8 100644
--- a/src/core/color_chooser_controller.h
+++ b/src/core/color_chooser_controller.h
@@ -55,6 +55,9 @@
#include <QObject>
+QT_FORWARD_DECLARE_CLASS(QColor)
+QT_FORWARD_DECLARE_CLASS(QVariant)
+
namespace QtWebEngineCore {
class ColorChooserControllerPrivate;
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..cc45db9e7 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});
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..6530f3249
--- /dev/null
+++ b/src/core/compositor/compositor_resource_tracker.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** 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);
+ return service_id(mailboxManager->ConsumeTexture(mailboxHolder.mailbox));
+#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);
+ 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()
+{
+ base::PostTaskWithTraits(
+ FROM_HERE, { content::BrowserThread::UI },
+ 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..4fb05051b 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,100 @@ 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 {
+ 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();
}
+}
-#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 +1074,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 +1118,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 c8c3d55f6..6f3ce75b3 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,8 @@ 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
}
!webcore_debug: gn_args += remove_webcore_debug_symbols=true
@@ -91,7 +105,6 @@ 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
@@ -112,5 +125,3 @@ qtConfig(webengine-kerberos) {
} else {
gn_args += use_kerberos=false
}
-
-!msvc: gn_args += enable_iterator_debugging=false
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index 9fc8c6e82..3eb436910 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -16,15 +16,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.
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/configure.json b/src/core/configure.json
index 044d85527..f111247e4 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -20,11 +20,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" } },
@@ -34,6 +37,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" }
}
},
@@ -82,9 +86,9 @@
]
},
"webengine-harfbuzz": {
- "label": "harfbuzz >= 1.4.2",
+ "label": "harfbuzz >= 2.0.0",
"sources": [
- { "type": "pkgConfig", "args": "harfbuzz >= 1.4.2" }
+ { "type": "pkgConfig", "args": "harfbuzz >= 2.0.0" }
]
},
"webengine-glib": {
@@ -326,6 +330,10 @@
"webengine-arm-thumb" : {
"label": "thumb instruction set",
"type": "hasThumbFlag"
+ },
+ "webengine-extensions-gcc-version" : {
+ "label": "GCC 6 or newer",
+ "type": "hasGcc6OrNewer"
}
},
@@ -546,14 +554,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",
@@ -657,6 +664,19 @@
"label": "Thumb instruction set",
"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" ]
}
},
@@ -705,8 +725,10 @@
"summary": [
{
- "section": "Qt WebEngine",
+ "section": "Qt WebEngineCore",
"entries": [
+ "webengine-widgets",
+ "webengine-qml",
"webengine-embedded-build",
"webengine-pepper-plugins",
"webengine-printing-and-pdf",
@@ -719,6 +741,7 @@
"webengine-webchannel",
"webengine-v8-snapshot",
"webengine-kerberos",
+ "webengine-extensions",
{
"type": "feature",
"args": "webengine-v8-snapshot-support",
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 0a51cc261..673ab32e7 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,11 +70,18 @@
#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"
@@ -95,12 +107,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 +127,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 +137,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 +168,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 +259,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 +271,31 @@ 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
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 +314,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 +407,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 +437,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 +462,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 +471,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 +513,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 +543,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 +556,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 +640,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 +660,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 +671,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 +679,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 +732,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 +762,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..dc32bb8c1 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)
@@ -221,7 +233,8 @@ bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
#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 e92dd60ff..89fb40864 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -38,6 +38,7 @@ qtConfig(egl): CONFIG += egl
INCLUDEPATH += $$PWD $$PWD/api
SOURCES = \
+ accessibility_activation_observer.cpp \
accessibility_tree_formatter_qt.cpp \
authentication_dialog_controller.cpp \
browser_accessibility_manager_qt.cpp \
@@ -46,21 +47,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 \
@@ -72,27 +76,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 \
@@ -102,30 +108,36 @@ 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/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 \
@@ -136,53 +148,59 @@ HEADERS = \
browser_message_filter_qt.h \
certificate_error_controller_p.h \
certificate_error_controller.h \
- chromium_overrides.h \
client_cert_select_controller.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 \
@@ -195,7 +213,6 @@ 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 \
@@ -203,11 +220,17 @@ HEADERS = \
renderer/render_frame_observer_qt.h \
renderer/render_view_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 \
@@ -266,12 +289,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) {
@@ -286,3 +311,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 5f9f3c4f6..8375d89e5 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -13,3 +13,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_gn_config.pri b/src/core/core_gn_config.pri
index 9b0145dfc..b76cdc81a 100644
--- a/src/core/core_gn_config.pri
+++ b/src/core/core_gn_config.pri
@@ -1,11 +1,19 @@
+include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
+QT_FOR_CONFIG += webenginecore webenginecore-private
+
CONFIG = gn_generator $$CONFIG
GN_SRC_DIR = $$PWD
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/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index bd9e0ebe7..0977f5afb 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -56,11 +56,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"
@@ -109,9 +111,9 @@ public:
~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;
+ int Initialize(net::CompletionOnceCallback callback) override;
+ int Write(net::IOBuffer *buffer, int num_bytes, net::CompletionOnceCallback callback) override;
+ int Finish(int net_error, net::CompletionOnceCallback callback) override;
private:
base::WeakPtr<DevToolsFrontendQt> shell_devtools_;
@@ -126,12 +128,12 @@ ResponseWriter::ResponseWriter(base::WeakPtr<DevToolsFrontendQt> shell_devtools,
ResponseWriter::~ResponseWriter() {}
-int ResponseWriter::Initialize(const net::CompletionCallback& callback)
+int ResponseWriter::Initialize(net::CompletionOnceCallback callback)
{
return net::OK;
}
-int ResponseWriter::Write(net::IOBuffer *buffer, int num_bytes, const net::CompletionCallback &callback)
+int ResponseWriter::Write(net::IOBuffer *buffer, int num_bytes, net::CompletionOnceCallback callback)
{
std::string chunk = std::string(buffer->data(), num_bytes);
if (!base::IsStringUTF8(chunk))
@@ -140,15 +142,15 @@ int ResponseWriter::Write(net::IOBuffer *buffer, int num_bytes, const net::Compl
base::Value *id = new base::Value(stream_id_);
base::Value *chunkValue = new base::Value(chunk);
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&DevToolsFrontendQt::CallClientFunction,
shell_devtools_, "DevToolsAPI.streamWrite",
base::Owned(id), base::Owned(chunkValue), nullptr));
return num_bytes;
}
-int ResponseWriter::Finish(int net_error, const net::CompletionCallback &callback)
+int ResponseWriter::Finish(int net_error, net::CompletionOnceCallback callback)
{
return net::OK;
}
@@ -210,7 +212,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);
@@ -268,9 +270,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)));
}
}
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index f0f0c93b9..724b33a7a 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,11 +166,11 @@ 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();
- base::FilePath tmpFilePath(toFilePathString(suggestedFilePath));
+ base::FilePath tmpFilePath(toFilePath(suggestedFilePath).NormalizePathSeparatorsTo('/'));
int uniquifier = base::GetUniquePathNumber(tmpFilePath, base::FilePath::StringType());
if (uniquifier > 0)
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/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 3ded5ec41..05aed8d2b 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -41,6 +41,7 @@
#include "type_conversion.h"
#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,18 +50,20 @@
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);
+ FilePickerController::filesSelectedInChooser(files);
}
void FilePickerController::accepted(const QVariant &files)
@@ -77,12 +80,12 @@ void FilePickerController::accepted(const QVariant &files)
qWarning("An unhandled type '%s' was provided in FilePickerController::accepted(QVariant)", files.typeName());
}
- FilePickerController::filesSelectedInChooser(stringList, m_frameHost);
+ FilePickerController::filesSelectedInChooser(stringList);
}
void FilePickerController::rejected()
{
- FilePickerController::filesSelectedInChooser(QStringList(), m_frameHost);
+ FilePickerController::filesSelectedInChooser(QStringList());
}
static QStringList listRecursively(const QDir &dir)
@@ -99,19 +102,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..613d3ad9b 100644
--- a/src/core/file_picker_controller.h
+++ b/src/core/file_picker_controller.h
@@ -52,11 +52,14 @@
#define FILE_PICKER_CONTROLLER_H
#include "qtwebenginecoreglobal_p.h"
+
+#include <memory>
+
#include <QObject>
#include <QStringList>
namespace content {
- class RenderFrameHost;
+ class FileSelectListener;
}
namespace QtWebEngineCore {
@@ -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/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/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index 1441ec336..31da45314 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,49 +127,59 @@ 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)
- request->SetExtraRequestHeaderByName(header.key().toStdString(), 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)
+ request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ }
+
+ if (result != net::OK)
+ return result;
+
+ requestInfo.resetChanged();
}
-
- if (result != net::OK)
- return result;
+ } 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.
@@ -293,19 +196,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
@@ -369,11 +279,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/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp
new file mode 100644
index 000000000..74a77a7ec
--- /dev/null
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -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$
+**
+****************************************************************************/
+
+#include "qrc_url_scheme_handler.h"
+
+#include <QtWebEngineCore/qwebengineurlrequestjob.h>
+
+#include <QFile>
+#include <QFileInfo>
+#include <QMimeDatabase>
+#include <QMimeType>
+
+namespace QtWebEngineCore {
+
+void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
+{
+ QByteArray requestMethod = job->requestMethod();
+ if (requestMethod != "GET") {
+ job->fail(QWebEngineUrlRequestJob::RequestDenied);
+ return;
+ }
+
+ QUrl requestUrl = job->requestUrl();
+ QString requestPath = requestUrl.path();
+ QScopedPointer<QFile> file(new QFile(':' + requestPath, job));
+ QFileInfo fileInfo(*file);
+ QMimeDatabase mimeDatabase;
+ QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
+ job->reply(mimeType.name().toUtf8(), file.take());
+}
+
+} // namespace QtWebEngineCore
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..1bf3ade1f 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>
@@ -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..6da661cff
--- /dev/null
+++ b/src/core/net/url_request_notification.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** 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();
+ 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)
+ m_request->SetExtraRequestHeaderByName(header.key().toStdString(), 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 a2712653d..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_remainingBytes = m_file.size();
- set_expected_content_size(m_remainingBytes);
- // Notify that the headers are complete
- NotifyHeadersComplete();
- } else {
- 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 9570852c9..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_system_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_system_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..6dbdf64ef 100644
--- a/src/core/printing/pdfium_document_wrapper_qt.cpp
+++ b/src/core/printing/pdfium_document_wrapper_qt.cpp
@@ -54,7 +54,6 @@ public:
: 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))
{
}
@@ -63,7 +62,6 @@ public:
: m_pageData(nullptr)
, m_width(-1)
, m_height(-1)
- , m_index(-1)
, m_image(QImage())
{
}
@@ -102,14 +100,13 @@ 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;
};
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 ff9fc76be..2bf11990a 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);
@@ -222,16 +215,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();
}
}
@@ -246,16 +239,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();
}
@@ -358,21 +350,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));
}
@@ -392,9 +381,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();
@@ -404,9 +392,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();
}
@@ -448,4 +435,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/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 1b946949a..a275952e7 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -44,10 +44,12 @@
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/download_manager.h"
-#include "content_client_qt.h"
+#include "api/qwebengineurlscheme.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"
@@ -57,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>
@@ -78,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
@@ -89,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()
@@ -101,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)
@@ -177,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);
@@ -237,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)
@@ -295,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;
}
@@ -405,9 +443,23 @@ void ProfileAdapter::setHttpCacheMaxSize(int maxSize)
m_profile->m_profileIOData->updateHttpCache();
}
-const QHash<QByteArray, QWebEngineUrlSchemeHandler *> &ProfileAdapter::customUrlSchemeHandlers() const
+static bool isInternalScheme(const QByteArray &scheme)
{
- return m_customUrlSchemeHandlers;
+ static QSet<QByteArray> internalSchemes{
+ QByteArrayLiteral("qrc"),
+ QByteArrayLiteral("data"),
+ QByteArrayLiteral("blob"),
+ QByteArrayLiteral("http"),
+ QByteArrayLiteral("https"),
+ QByteArrayLiteral("ftp"),
+ QByteArrayLiteral("javascript"),
+ };
+ return internalSchemes.contains(scheme);
+}
+
+QWebEngineUrlSchemeHandler *ProfileAdapter::urlSchemeHandler(const QByteArray &scheme)
+{
+ return m_customUrlSchemeHandlers.value(scheme.toLower()).data();
}
const QList<QByteArray> ProfileAdapter::customUrlSchemes() const
@@ -421,12 +473,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 (isInternalScheme(it.key())) {
+ qWarning("Cannot remove the URL scheme handler for an internal scheme: %s", it.key().constData());
+ continue;
+ }
it = m_customUrlSchemeHandlers.erase(it);
removedOneOrMore = true;
continue;
@@ -435,26 +492,43 @@ 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);
- if (handler)
+ QByteArray canonicalScheme = scheme.toLower();
+ if (isInternalScheme(canonicalScheme)) {
+ qWarning("Cannot remove the URL scheme handler for an internal scheme: %s", scheme.constData());
+ return;
+ }
+ if (m_customUrlSchemeHandlers.remove(canonicalScheme))
updateCustomUrlSchemeHandlers();
- return handler;
}
-void ProfileAdapter::addCustomUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
+void ProfileAdapter::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
- m_customUrlSchemeHandlers.insert(scheme, handler);
+ Q_ASSERT(handler);
+ QByteArray canonicalScheme = scheme.toLower();
+ if (isInternalScheme(canonicalScheme)) {
+ qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData());
+ return;
+ }
+ if (m_customUrlSchemeHandlers.value(canonicalScheme, handler) != handler) {
+ qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
+ return;
+ }
+ if (QWebEngineUrlScheme::schemeByName(canonicalScheme) == QWebEngineUrlScheme())
+ qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() "
+ "before installing the custom scheme handler.", scheme.constData());
+
+ m_customUrlSchemeHandlers.insert(canonicalScheme, handler);
updateCustomUrlSchemeHandlers();
}
-void ProfileAdapter::clearCustomUrlSchemeHandlers()
+void ProfileAdapter::removeAllUrlSchemeHandlers()
{
m_customUrlSchemeHandlers.clear();
+ m_customUrlSchemeHandlers.insert(QByteArrayLiteral("qrc"), &m_qrcHandler);
updateCustomUrlSchemeHandlers();
}
@@ -563,7 +637,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 7ed5c13f5..48094a3d8 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -60,16 +60,19 @@
#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;
@@ -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();
- void 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..8ee9d240e 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -52,12 +52,14 @@
#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
{
@@ -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 63585b2c3..5d317b7f0 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -39,15 +39,17 @@
#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"
#include "content/public/common/content_features.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.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"
@@ -76,16 +78,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 const char* const kDefaultAuthSchemes[] = { net::kBasicAuthScheme,
@@ -102,8 +114,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;
}
@@ -153,14 +163,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))
@@ -171,8 +183,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
@@ -180,9 +203,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 !";
@@ -203,6 +235,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));
@@ -214,6 +253,7 @@ void ProfileIODataQt::initializeOnIOThread()
QMutexLocker lock(&m_mutex);
generateAllStorage();
generateJobFactory();
+ setGlobalCertificateVerification();
m_initialized = true;
}
@@ -280,7 +320,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()) {
@@ -305,7 +353,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>(
@@ -346,7 +394,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(
@@ -361,8 +409,8 @@ void ProfileIODataQt::generateCookieStore()
base::FilePath(),
false,
false,
- nullptr)
- );
+ nullptr),
+ nullptr);
break;
case ProfileAdapter::AllowPersistentCookies:
cookieStore = content::CreateCookieStore(
@@ -370,8 +418,8 @@ void ProfileIODataQt::generateCookieStore()
toFilePath(m_cookiesPath),
false,
true,
- nullptr)
- );
+ nullptr),
+ nullptr);
break;
case ProfileAdapter::ForcePersistentCookies:
cookieStore = content::CreateCookieStore(
@@ -379,8 +427,8 @@ void ProfileIODataQt::generateCookieStore()
toFilePath(m_cookiesPath),
true,
true,
- nullptr)
- );
+ nullptr),
+ nullptr);
break;
}
@@ -390,7 +438,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);
}
@@ -477,13 +525,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()));
@@ -541,6 +586,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)
{
@@ -563,6 +623,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();
}
@@ -572,8 +633,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));
}
}
@@ -586,10 +647,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();
}
@@ -601,12 +666,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()
@@ -616,7 +682,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()
@@ -625,7 +692,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()
@@ -637,14 +705,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()
@@ -656,8 +729,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));
}
}
@@ -666,6 +739,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.
}
@@ -675,6 +749,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();
@@ -690,4 +776,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 2d4706bf4..3d9a5ef19 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 {
+class 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;
@@ -129,6 +166,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;
@@ -144,9 +184,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 df05d891e..14a39de49 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()
@@ -210,6 +262,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());
@@ -225,12 +283,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)
@@ -266,4 +345,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 00119c053..5a602f56a 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 ProfileAdapter;
@@ -66,6 +71,8 @@ public:
virtual ~ProfileQt();
+ base::FilePath GetCachePath() const;
+
// BrowserContext implementation:
base::FilePath GetPath() const override;
bool IsOffTheRecord() const override;
@@ -93,11 +100,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; }
@@ -108,6 +122,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;
@@ -116,9 +133,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..702943261 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,44 @@ 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_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_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index a5aba92bc..414fc6582 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; }
@@ -242,20 +247,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 +270,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 +281,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 +292,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 +344,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 +432,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 +587,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;
@@ -684,21 +666,18 @@ void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom:
void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, base::Optional<viz::HitTestRegionList>)
{
bool scrollOffsetChanged = (m_lastScrollOffset != frame.metadata.root_scroll_offset);
- bool contentsSizeChanged = (m_lastContentsSize != frame.metadata.root_layer_size);
+ bool contentsSizeChanged = (m_lastContentsSize != frame.metadata.scrollable_viewport_size);
m_lastScrollOffset = frame.metadata.root_scroll_offset;
- m_lastContentsSize = frame.metadata.root_layer_size;
+ m_lastContentsSize = frame.metadata.scrollable_viewport_size;
// Force to process swap messages
uint32_t frame_token = frame.metadata.frame_token;
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 +690,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()
@@ -758,7 +722,7 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
ui::TextInputType type = getTextInputType();
m_delegate->setInputMethodHints(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu);
- m_surroundingText = QString::fromStdString(state->value);
+ 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 +868,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 +907,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 +925,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;
+ QWindow *window = m_delegate->window();
+ m_windowRectInDips = window ? toGfx(window->frameGeometry()) : gfx::Rect();
+
+ 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)
@@ -1166,14 +1150,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 +1294,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 +1373,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 +1385,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 +1423,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 +1435,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 +1452,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 +1500,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 +1553,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 +1570,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 +1616,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 +1643,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 +1656,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 +1687,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 +1701,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..e2c98360d 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -78,11 +78,9 @@ class QWEBENGINECORE_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;
@@ -92,8 +90,7 @@ class QWEBENGINECORE_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 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..fa1e20f24 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"
@@ -85,6 +88,12 @@
#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 +104,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 +113,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()
@@ -137,7 +150,11 @@ 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)
+ ExtensionsRendererClientQt::GetInstance()->RenderThreadStarted();
+#endif
}
void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view)
@@ -149,11 +166,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 +184,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 +237,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.
@@ -230,7 +279,8 @@ 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_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 +289,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 +306,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)
{
- context()->connector()->BindConnectorRequest(std::move(m_connectorRequest));
+#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)
+{
+#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 +339,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 +436,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 +448,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 +460,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 +527,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 +536,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 +550,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..9aebe5bb3 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>
@@ -85,18 +86,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 +128,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,8 +135,8 @@ 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<visitedlink::VisitedLinkSlave> m_visitedLinkSlave;
QScopedPointer<web_cache::WebCacheImpl> m_webCacheImpl;
@@ -124,9 +144,8 @@ private:
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..f36c679bf
--- /dev/null
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** 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_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 false;
+}
+
+// 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_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 920fda72e..46f5de2c2 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 DidClearWindowObject() override;
void DidFinishDocumentLoad() override;
void DidFinishLoad() override;
@@ -230,8 +230,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..442694bb9
--- /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(),
+ net::EscapeUrlEncodedData(original_url.spec(), false).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/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..42d907d75
--- /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 QWEBENGINECORE_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..da3c78b8a
--- /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.get(),
+ 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..fd61ae709
--- /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 QWEBENGINECORE_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..82cb57e51
--- /dev/null
+++ b/src/core/user_notification_controller.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** 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;
+ QIcon 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);
+}
+
+QIcon UserNotificationController::icon() const
+{
+ if (!d->m_iconGenerated) {
+ d->m_iconGenerated = true;
+ if (!d->m_resources.notification_icon.isNull()) {
+ QImage image = toQImage(d->m_resources.notification_icon);
+ if (!image.isNull())
+ d->m_icon = QIcon(QPixmap::fromImage(std::move(image), Qt::NoFormatConversion));
+ }
+ }
+ 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..840074843
--- /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 QWEBENGINECORE_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;
+ QIcon 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/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..5bbcc5983 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 {
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 21540f5da..c4f4591e3 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,13 +649,12 @@ 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());
break;
}
- params.post_data = network::ResourceRequestBody::CreateFromBytes(
- (const char*)request.postData().constData(),
- request.postData().length());
-
// convert the custom headers into the format that chromium expects
QVector<QByteArray> headers = request.headers();
for (QVector<QByteArray>::const_iterator it = headers.cbegin(); it != headers.cend(); ++it) {
@@ -662,8 +680,8 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
if (resizeNeeded) {
// Schedule navigation on the event loop.
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE, base::BindOnce(navigate, this, std::move(params)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(navigate, this, std::move(params)));
} else {
navigate(this, params);
}
@@ -800,7 +818,7 @@ void WebContentsAdapter::selectAll()
void WebContentsAdapter::requestClose()
{
CHECK_INITIALIZED();
- m_webContents->DispatchBeforeUnload();
+ m_webContents->DispatchBeforeUnload(false /* auto_cancel */);
}
void WebContentsAdapter::unselect()
@@ -932,8 +950,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
@@ -990,16 +1008,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;
}
@@ -1068,7 +1086,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));
@@ -1100,16 +1118,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);
}
@@ -1257,6 +1289,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();
@@ -1271,16 +1309,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();
@@ -1338,7 +1366,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;
}
@@ -1390,7 +1418,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
}
{
- base::MessageLoop::ScopedNestableTaskAllower allow;
+ base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
drag->exec(allowedActions);
}
@@ -1456,8 +1484,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);
}
}
@@ -1534,7 +1562,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 (;;) {
@@ -1663,15 +1691,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 e8e5359be..c6e4f2256 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -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 75d010865..beb41e17f 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;
@@ -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;
@@ -475,6 +478,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 5cb94de5c..021044a71 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -58,13 +58,16 @@
#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"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "components/web_cache/browser/web_cache_manager.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"
@@ -73,7 +76,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"
@@ -134,6 +136,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;
@@ -143,7 +146,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;
@@ -153,7 +160,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);
@@ -246,11 +253,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::RenderFrameDeleted(content::RenderFrameHost *render_frame_host)
@@ -411,12 +420,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)
@@ -451,12 +462,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());
@@ -464,7 +477,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] () {
@@ -583,6 +596,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)
@@ -633,16 +651,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 2baa1176f..1629222c2 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -106,7 +106,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;
@@ -114,7 +114,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,
@@ -124,7 +126,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;
@@ -136,7 +138,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;
@@ -147,6 +149,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..7c6b6669d 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))
@@ -225,8 +232,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 +287,7 @@ WebEngineContext::~WebEngineContext()
Q_ASSERT(!m_devtoolsServer);
Q_ASSERT(!m_browserRunner);
Q_ASSERT(m_profileAdapters.isEmpty());
+ delete s_syncPointManager.fetchAndStoreRelaxed(nullptr);
}
WebEngineContext *WebEngineContext::current()
@@ -313,7 +327,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 +336,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.
@@ -347,7 +373,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 +393,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 +443,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,10 +450,23 @@ 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
// Needed to allow navigations within pages that were set using setHtml(). One example is
// tst_QWebEnginePage::acceptNavigationRequest.
@@ -448,13 +475,18 @@ WebEngineContext::WebEngineContext()
appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
// Surface synchronization breaks our current graphics integration (since 65)
appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kEnableSurfaceSynchronization.name);
+ // Viz Display Compositor is enabled by default since 73. Doesn't work for us (also implies SurfaceSynchronization)
+ appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, 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);
+ // Breaks WebEngineNewViewRequest.userInitiated API (since 73)
+ appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kUserActivationV2.name);
+
+ appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kBackgroundFetch.name);
+
+#if QT_CONFIG(webengine_printing_and_pdf)
+ appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, printing::features::kUsePdfCompositorServiceForPrint.name);
+#endif
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
@@ -474,22 +506,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 +575,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 +583,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 +621,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 +644,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 +657,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..75f8bd470
--- /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::NORMAL);
+ 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_library_info.cpp b/src/core/web_engine_library_info.cpp
index 3899ced25..12ffd91e6 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>
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 664951e66..5a01308a1 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()) {
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index 8930d7c27..d7eeaa560 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -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..b97696030 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;
@@ -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 73577a04c..ac75b5356 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,13 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineDownloadItem::MimeHtmlSaveFormat, QtWebEngineC
The \a download argument holds the state of the finished download instance.
*/
+/*!
+ \fn QQuickWebEngineProfile::userNotification(QWebEngineNotification *notification)
+
+ This signal is emitted whenever there is a newly created user notification.
+ The \a notification argument holds the notification instance to query data and interact with.
+*/
+
QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter)
: m_settings(new QQuickWebEngineSettings())
, m_profileAdapter(profileAdapter)
@@ -285,6 +293,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->userNotification(notification);
+}
+
void QQuickWebEngineProfilePrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script)
{
Q_ASSERT(p && p->data);
@@ -365,6 +387,14 @@ void QQuickWebEngineProfilePrivate::userScripts_clear(QQmlListProperty<QQuickWeb
*/
/*!
+ \qmlsignal WebEngineProfile::userNotification(WebEngineNotification notification)
+ \since QtWebEngine 1.9
+
+ This signal is emitted whenever there is a newly created user notification.
+ The \a notification argument holds the notification instance to query data and interact with.
+*/
+
+/*!
Constructs a new profile with the parent \a parent.
*/
QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent)
@@ -796,6 +826,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,40 +953,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
/*!
- Returns the custom URL scheme handler register for the URL scheme \a scheme.
+ Registers a request interceptor singleton \a interceptor to intercept URL requests.
+
+ The profile does not take ownership of the pointer.
+
+ \sa QWebEngineUrlRequestInfo QWebEngineUrlRequestInterceptor
*/
-const QWebEngineUrlSchemeHandler *QQuickWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const
+void QQuickWebEngineProfile::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
- const Q_D(QQuickWebEngineProfile);
- if (d->profileAdapter()->customUrlSchemeHandlers().contains(scheme))
- return d->profileAdapter()->customUrlSchemeHandlers().value(scheme);
- return 0;
+ Q_D(QQuickWebEngineProfile);
+ d->profileAdapter()->setRequestInterceptor(interceptor);
}
-static bool checkInternalScheme(const QByteArray &scheme)
+
+/*!
+ Returns the custom URL scheme handler register for the URL scheme \a scheme.
+*/
+const QWebEngineUrlSchemeHandler *QQuickWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const
{
- static QSet<QByteArray> internalSchemes;
- if (internalSchemes.isEmpty()) {
- internalSchemes << QByteArrayLiteral("qrc") << QByteArrayLiteral("data") << QByteArrayLiteral("blob")
- << QByteArrayLiteral("http") << QByteArrayLiteral("https") << QByteArrayLiteral("ftp")
- << QByteArrayLiteral("javascript");
- }
- return internalSchemes.contains(scheme);
+ const Q_D(QQuickWebEngineProfile);
+ return d->profileAdapter()->urlSchemeHandler(scheme);
}
/*!
@@ -872,25 +1010,7 @@ static bool checkInternalScheme(const QByteArray &scheme)
void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
Q_D(QQuickWebEngineProfile);
- Q_ASSERT(handler);
- QByteArray canonicalScheme = scheme.toLower();
- if (checkInternalScheme(canonicalScheme)) {
- qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData());
- return;
- }
-
- if (d->profileAdapter()->customUrlSchemeHandlers().contains(canonicalScheme)) {
- if (d->profileAdapter()->customUrlSchemeHandlers().value(canonicalScheme) != handler)
- qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
- return;
- }
-
- if (QWebEngineUrlScheme::schemeByName(canonicalScheme) == QWebEngineUrlScheme())
- qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() "
- "before installing the custom scheme handler.", scheme.constData());
-
- d->profileAdapter()->addCustomUrlSchemeHandler(canonicalScheme, handler);
- connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->installUrlSchemeHandler(scheme, handler);
}
/*!
@@ -901,10 +1021,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);
}
/*!
@@ -915,10 +1032,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);
}
/*!
@@ -927,12 +1041,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
@@ -970,4 +1079,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..e6f9fb73d 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 userNotification(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..93a3668ed 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -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/core/net/url_request_qrc_job_qt.h b/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h
index 11c130693..277436289 100644
--- a/src/core/net/url_request_qrc_job_qt.h
+++ b/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.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,40 +37,41 @@
**
****************************************************************************/
-#ifndef URL_REQUEST_QRC_JOB_QT_H_
-#define URL_REQUEST_QRC_JOB_QT_H_
+#ifndef QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
+#define QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_job.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 <QFile>
+#include <QtQuick/QQuickImageProvider>
+#include <QtWebEngine/private/qtwebengineglobal_p.h>
-namespace QtWebEngineCore {
-
-// A request job that handles reading qrc file URLs
-class URLRequestQrcJobQt : public net::URLRequestJob {
+QT_BEGIN_NAMESPACE
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTouchHandleProvider : public QQuickImageProvider {
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;
+ static QString identifier();
+ static QUrl url(int orientation);
-protected:
- virtual ~URLRequestQrcJobQt();
- // Get file mime type and try open file on a background thread.
- void startGetHead();
+ QQuickWebEngineTouchHandleProvider();
+ ~QQuickWebEngineTouchHandleProvider();
-private:
- qint64 m_remainingBytes;
- QFile m_file;
- std::string m_mimeType;
- base::WeakPtrFactory<URLRequestQrcJobQt> m_weakFactory;
+ void init(const QMap<int, QImage> &images);
+ virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
- DISALLOW_COPY_AND_ASSIGN(URLRequestQrcJobQt);
+private:
+ QMap<int, QImage> m_touchHandleMap;
};
-} // namespace QtWebEngineCore
-#endif // URL_REQUEST_QRC_JOB_QT_H_
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index fd3cc8e82..9826ebfe2 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)
@@ -300,9 +301,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 +320,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 +424,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;
@@ -1134,12 +1144,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);
}
@@ -1207,6 +1217,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);
@@ -1517,6 +1560,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();
}
@@ -2281,5 +2327,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 3c4189fd9..aa0a765f8 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;
@@ -152,6 +156,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; }
@@ -211,7 +218,6 @@ public:
private:
QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
QList<QQuickWebEngineScript *> m_userScripts;
- qreal m_dpiScale;
QColor m_backgroundColor;
qreal m_zoomFactor;
bool m_ui2Enabled;
@@ -253,6 +259,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..ec5ad34d9
--- /dev/null
+++ b/src/webengine/configure.json
@@ -0,0 +1,29 @@
+{
+ "module": "webengine",
+ "depends": [
+ "webenginecore-private"
+ ],
+ "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/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc
index 7ff6eea6b..e4fe9bba6 100644
--- a/src/webengine/doc/src/external-resources.qdoc
+++ b/src/webengine/doc/src/external-resources.qdoc
@@ -146,3 +146,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 1dce17e08..f53c118a8 100644
--- a/src/webengine/doc/src/qtwebengine-features.qdoc
+++ b/src/webengine/doc/src/qtwebengine-features.qdoc
@@ -50,6 +50,7 @@
\li \l{Touch}
\li \l{View Source}
\li \l{WebRTC}
+ \li \l{Web Notifications}
\endlist
\section1 Audio and Video Codecs
@@ -511,4 +512,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 d83a65bdb..58c0708cc 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -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 Qt WebEngine. 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 Qt WebEngine. 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 0e25e16f3..a6f2af39e 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -858,6 +858,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()
*/
@@ -1475,3 +1477,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..56e5c5c9f 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,11 @@ public:
qmlRegisterUncreatableType<QWebEngineRegisterProtocolHandlerRequest>(uri, 1, 7, "RegisterProtocolHandlerRequest",
msgUncreatableType("RegisterProtocolHandlerRequest"));
qmlRegisterUncreatableType<QQuickWebEngineAction>(uri, 1, 8, "WebEngineAction", msgUncreatableType("WebEngineAction"));
+ qmlRegisterUncreatableType<QQuickWebEngineClientCertificateSelection>(uri, 1, 9, "WebEngineClientCertificateSelection",
+ msgUncreatableType("WebEngineClientCertificateSelection"));
+ qmlRegisterUncreatableType<QQuickWebEngineClientCertificateOption>(uri, 1, 9, "WebEngineClientCertificateOption",
+ msgUncreatableType("WebEngineClientCertificateOption"));
+ 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..cc2ed502d 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: "userNotification"
+ 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..e756ee157 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,9 @@ void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
setVisible(true);
}
-QRectF RenderWidgetHostViewQtDelegateQuick::screenRect() const
+QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const
{
- QPointF pos = mapToScene(QPointF(0,0));
- return QRectF(pos.x(), pos.y(), width(), height());
-}
-
-QRectF RenderWidgetHostViewQtDelegateQuick::contentsRect() const
-{
- QPointF scenePoint = mapToScene(QPointF(0, 0));
- QPointF screenPos;
- if (window())
- screenPos = window()->mapToGlobal(scenePoint.toPoint());
- return QRectF(screenPos.x(), screenPos.y(), width(), height());
+ return QRectF(mapToGlobal(QPointF(0, 0)), size());
}
void RenderWidgetHostViewQtDelegateQuick::setKeyboardFocus()
@@ -322,16 +312,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 +328,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 +342,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..4edf37cff 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,7 @@ public:
~RenderWidgetHostViewQtDelegateQuick();
void initAsPopup(const QRect&) override;
- QRectF screenRect() const override;
- QRectF contentsRect() const override;
+ QRectF viewGeometry() const override;
void setKeyboardFocus() override;
bool hasKeyboardFocus() override;
void lockMouse() override;
@@ -113,7 +112,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..3c6c743e0 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -62,14 +62,9 @@ void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &screenR
show();
}
-QRectF RenderWidgetHostViewQtDelegateQuickWindow::screenRect() const
+QRectF RenderWidgetHostViewQtDelegateQuickWindow::viewGeometry() const
{
- return QRectF(x(), y(), width(), height());
-}
-
-QRectF RenderWidgetHostViewQtDelegateQuickWindow::contentsRect() const
-{
- return geometry();
+ return m_realDelegate->viewGeometry();
}
void RenderWidgetHostViewQtDelegateQuickWindow::show()
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..039f6102a 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -56,8 +56,7 @@ public:
~RenderWidgetHostViewQtDelegateQuickWindow();
void initAsPopup(const QRect&) override;
- QRectF screenRect() const override;
- QRectF contentsRect() const override;
+ QRectF viewGeometry() const override;
void setKeyboardFocus() override {}
bool hasKeyboardFocus() override { return false; }
void lockMouse() override {}
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..da120ab69 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
@@ -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)
{
}
@@ -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..da97c4662
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** 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 <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(const QWebEngineNotification &notification)
+{
+ if (m_activeNotification.isValid()) {
+ m_activeNotification.close();
+ m_activeNotification.disconnect(this);
+ }
+
+ m_activeNotification = notification;
+
+#ifndef QT_NO_SYSTEMTRAYICON
+ if (m_activeNotification.isValid() && m_systemTrayIcon) {
+ m_systemTrayIcon->show();
+ QIcon icon = notification.icon();
+ if (!icon.isNull())
+ m_systemTrayIcon->showMessage(notification.title(), notification.message(), icon);
+ else
+ m_systemTrayIcon->showMessage(notification.title(), notification.message());
+ notification.show();
+ connect(&m_activeNotification, &QWebEngineNotification::closed, this, &DefaultNotificationPresenter::closeNotification);
+ }
+#endif
+}
+
+void DefaultNotificationPresenter::messageClicked()
+{
+ if (m_activeNotification.isValid())
+ 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))
+ m_systemTrayIcon->hide();
+#endif
+}
+
+void defaultNotificationPresenter(const QWebEngineNotification &notification)
+{
+ static DefaultNotificationPresenter *presenter = nullptr;
+ if (!presenter)
+ presenter = new DefaultNotificationPresenter();
+ presenter->show(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..a66dbc1b2
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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>
+
+QT_BEGIN_NAMESPACE
+
+class QSystemTrayIcon;
+
+class DefaultNotificationPresenter : public QObject {
+ Q_OBJECT
+public:
+ DefaultNotificationPresenter(QObject *parent = nullptr);
+ virtual ~DefaultNotificationPresenter();
+
+ void show(const QWebEngineNotification &notification);
+
+private Q_SLOTS:
+ void messageClicked();
+ void closeNotification();
+
+private:
+ QSystemTrayIcon *m_systemTrayIcon;
+ QWebEngineNotification m_activeNotification;
+};
+
+void defaultNotificationPresenter(const QWebEngineNotification &notification);
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINENOTIFICATIONPRESENTER_P_H
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index dd720a41b..9c6749f39 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
@@ -262,6 +183,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
QWebEnginePagePrivate::~QWebEnginePagePrivate()
{
+ if (requestInterceptor)
+ profile->d_ptr->profileAdapter()->removePageRequestInterceptor();
delete history;
delete settings;
profile->d_ptr->removeWebContentsAdapterClient(this);
@@ -335,7 +258,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 +272,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 +420,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, [=](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);
@@ -617,6 +551,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;
@@ -1865,6 +1805,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()
{
@@ -1923,6 +1897,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)
@@ -1941,6 +1916,7 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
d->adapter->grantMouseLockPermission(false);
break;
case Notifications:
+ d->adapter->runUserNotificationRequestCallback(securityOrigin, false);
break;
}
}
@@ -2453,10 +2429,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 25ed89371..5feefeb0e 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;
@@ -150,8 +152,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;
@@ -194,6 +200,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 929c2aaa1..d69ddb343 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,12 @@ using QtWebEngineCore::ProfileAdapter;
Both session and persistent cookies are saved to and restored from disk.
*/
+void QWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &notification)
+{
+ if (m_notificationPresenter)
+ m_notificationPresenter(QWebEngineNotification(notification));
+}
+
/*!
\fn QWebEngineProfile::downloadRequested(QWebEngineDownloadItem *download)
@@ -379,6 +386,34 @@ 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();
+}
+
+/*!
+ 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 +577,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);
}
@@ -602,6 +663,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(const QWebEngineNotification &)> notificationPresenter)
+{
+ Q_D(QWebEngineProfile);
+ d->m_notificationPresenter = std::move(notificationPresenter);
+}
+
+/*!
Returns the default profile.
The default profile uses the storage name "Default".
@@ -613,6 +686,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;
}
@@ -688,20 +763,7 @@ QWebEngineSettings *QWebEngineProfile::settings() const
const QWebEngineUrlSchemeHandler *QWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const
{
const Q_D(QWebEngineProfile);
- if (d->profileAdapter()->customUrlSchemeHandlers().contains(scheme))
- return d->profileAdapter()->customUrlSchemeHandlers().value(scheme);
- return 0;
-}
-
-static bool checkInternalScheme(const QByteArray &scheme)
-{
- static QSet<QByteArray> internalSchemes;
- if (internalSchemes.isEmpty()) {
- internalSchemes << QByteArrayLiteral("qrc") << QByteArrayLiteral("data") << QByteArrayLiteral("blob")
- << QByteArrayLiteral("http") << QByteArrayLiteral("https") << QByteArrayLiteral("ftp")
- << QByteArrayLiteral("javascript");
- }
- return internalSchemes.contains(scheme);
+ return d->profileAdapter()->urlSchemeHandler(scheme);
}
/*!
@@ -715,25 +777,7 @@ static bool checkInternalScheme(const QByteArray &scheme)
void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
Q_D(QWebEngineProfile);
- Q_ASSERT(handler);
- QByteArray canonicalScheme = scheme.toLower();
- if (checkInternalScheme(canonicalScheme)) {
- qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData());
- return;
- }
-
- if (d->profileAdapter()->customUrlSchemeHandlers().contains(canonicalScheme)) {
- if (d->profileAdapter()->customUrlSchemeHandlers().value(canonicalScheme) != handler)
- qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
- return;
- }
-
- if (QWebEngineUrlScheme::schemeByName(canonicalScheme) == QWebEngineUrlScheme())
- qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() "
- "before installing the custom scheme handler.", scheme.constData());
-
- d->profileAdapter()->addCustomUrlSchemeHandler(canonicalScheme, handler);
- connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)));
+ d->profileAdapter()->installUrlSchemeHandler(scheme, handler);
}
/*!
@@ -746,10 +790,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);
}
/*!
@@ -762,10 +803,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);
}
/*!
@@ -776,12 +814,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 this option enabled, 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();
}
/*!
@@ -795,4 +864,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..e3ddb594a 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -46,12 +46,16 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qstring.h>
+#include <functional>
+
QT_BEGIN_NAMESPACE
class QObject;
class QUrl;
+class QWebEngineClientCertificateStore;
class QWebEngineCookieStore;
class QWebEngineDownloadItem;
+class QWebEngineNotification;
class QWebEnginePage;
class QWebEnginePagePrivate;
class QWebEngineProfilePrivate;
@@ -106,7 +110,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 +135,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(const 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..91c43cf0a 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(const 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/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 517fdc7d9..f9ab710d1 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -285,6 +285,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..3a670ad49
--- /dev/null
+++ b/src/webenginewidgets/printer_worker.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** 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;
+ }
+
+ QSize pageSize = m_printer->pageRect().size();
+ PdfiumDocumentWrapperQt pdfiumWrapper(m_data->constData(), m_data->size(), pageSize);
+
+ 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;
+ }
+
+ 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++) {
+ int currentPageIndex = fromPage;
+ while (true) {
+ for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
+ if (m_printer->printerState() == QPrinter::Aborted
+ || m_printer->printerState() == QPrinter::Error) {
+ Q_EMIT resultReady(false);
+ return;
+ }
+
+ QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1);
+ if (currentImage.isNull()) {
+ Q_EMIT resultReady(false);
+ return;
+ }
+
+ // 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)
+ m_printer->newPage();
+ }
+
+ if (currentPageIndex == toPage)
+ break;
+
+ if (ascendingOrder)
+ currentPageIndex++;
+ else
+ currentPageIndex--;
+
+ m_printer->newPage();
+ }
+ if (printedDocuments < documentCopies - 1)
+ m_printer->newPage();
+ }
+ 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 55bdb3a62..951360c05 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -132,25 +132,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);
@@ -227,15 +233,9 @@ void RenderWidgetHostViewQtDelegateWidget::closeEvent(QCloseEvent *event)
m_client->closePopup();
}
-QRectF RenderWidgetHostViewQtDelegateWidget::screenRect() const
+QRectF RenderWidgetHostViewQtDelegateWidget::viewGeometry() const
{
- return QRectF(x(), y(), width(), height());
-}
-
-QRectF RenderWidgetHostViewQtDelegateWidget::contentsRect() const
-{
- QPointF pos = mapToGlobal(QPoint(0, 0));
- return QRectF(pos.x(), pos.y(), width(), height());
+ return QRectF(mapToGlobal(pos()), size());
}
void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus()
@@ -373,14 +373,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)
@@ -396,7 +389,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();
}
@@ -492,8 +485,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..a736aa5cf 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,7 @@ public:
~RenderWidgetHostViewQtDelegateWidget();
void initAsPopup(const QRect&) override;
- QRectF screenRect() const override;
- QRectF contentsRect() const override;
+ QRectF viewGeometry() const override;
void setKeyboardFocus() override;
bool hasKeyboardFocus() override;
void lockMouse() override;
@@ -111,7 +110,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)
diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro
index c1b2147bd..1dc5e052c 100644
--- a/tests/auto/core/core.pro
+++ b/tests/auto/core/core.pro
@@ -1,8 +1,9 @@
TEMPLATE = subdirs
+QT_FOR_CONFIG += network-private
SUBDIRS += \
qwebenginecookiestore \
- qwebengineurlrequestinterceptor \
+ qwebengineurlrequestinterceptor
+
+qtConfig(ssl): SUBDIRS += qwebengineclientcertificatestore
-# QTBUG-60268
-boot2qt: SUBDIRS = ""
diff --git a/tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro b/tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro
new file mode 100644
index 000000000..e99c7f493
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/qwebengineclientcertificatestore.pro
@@ -0,0 +1 @@
+include(../tests.pri)
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt
new file mode 100644
index 000000000..1c7a4e6a1
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID6zCCAtOgAwIBAgIUR7/FZjFjCH94EgGF1VOOca1p8PUwDQYJKoZIhvcNAQEL
+BQAwgYQxCzAJBgNVBAYTAkVVMREwDwYDVQQIDAhIRUxTSU5LSTERMA8GA1UEBwwI
+SEVMU0lOS0kxFzAVBgNVBAoMDlRoZSBRdCBDb21wYW55MQ4wDAYDVQQDDAVxdC5p
+bzEmMCQGCSqGSIb3DQEJARYXdmlqaXRoLmtpbmlAY2xheXNvbC5jb20wHhcNMTkw
+MjE5MTIzNjE5WhcNMjAwMjE5MTIzNjE5WjCBhDELMAkGA1UEBhMCRVUxETAPBgNV
+BAgMCEhFTFNJTktJMREwDwYDVQQHDAhIRUxTSU5LSTEXMBUGA1UECgwOVGhlIFF0
+IENvbXBhbnkxDjAMBgNVBAMMBXF0LmlvMSYwJAYJKoZIhvcNAQkBFhd2aWppdGgu
+a2luaUBjbGF5c29sLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AOprCpRWsPUda98sp2iQse8bUcwaaRaWl2LqKXu9ELpeInS1dq+v8/NMx7c67N2B
++1l5dOM1CPsIZ27mIL2Y04fy58lGOtwtpJg5MnR50Vl8lG/NxoAWjc2XJYhhVHfJ
+k+KOME2Z4gMGU/2UoMkN/la/sSDFtApJKhYgRwjvPdDXDNr/QxpNLmSaYwd+Bx/P
+MqEEcUkk+tGHWI+XTvUuFczSGpjTZ+QdgYg4w/WjDD0z+cSOJ553EoeswRZHY35O
+pqwgIBMFwoUPpXb5TfOm6fBeb8i8MbReR1NV2XXPQ2aPcmuY9Cmi8Tol+sXy0MvY
+Yd16eZb0eD5oIGr9UjvfJMsCAwEAAaNTMFEwHQYDVR0OBBYEFHJG773IyFWSDBvD
+tvm1fmP5UbEfMB8GA1UdIwQYMBaAFHJG773IyFWSDBvDtvm1fmP5UbEfMA8GA1Ud
+EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAcaPiAufSZwrALeT1BRiBAj
+TdeC2ly1EBw8BwmEhVmma9GRslZzxcTUiZ+W3aYdPOFFDXE+HyAKY2WBQ1iETpIa
+oeqJKzBTzXXXnXT3Wu9BCD928SH8Srtays9yEZO1DRtSKcBrsipdH3KKu3kkAIVL
+GJ4igY2+2EO+64usMROzaL0WiNexHLPCm9KkURPvGRE3GJULYHEEw15ClYryJI5A
+fwVbcMKhQAQipIgrdoPe6aXfTeELD2RpRvU9nMKTelJI5czx4dYGRXVjjF21qiTr
+ov7+d2rXx/133K13kmeeMzOIJkDX3QJwlcKvegygU6QfJwnkRM7ZUAXGTlt3jW0=
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt
new file mode 100644
index 000000000..cd3ee969e
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/certificate1.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID4zCCAsugAwIBAgIUcEB7LtzUwdKmEY5b8yDuC/rvMLswDQYJKoZIhvcNAQEL
+BQAwgYAxCzAJBgNVBAYTAklOMRIwEAYDVQQIDAlLYXJuYXRha2ExEjAQBgNVBAcM
+CUJBTkdBTE9SRTEQMA4GA1UECgwHQ2xheXNvbDEUMBIGA1UEAwwLY2xheXNvbC5j
+b20xITAfBgkqhkiG9w0BCQEWEnZpaml0aEBjbGF5c29sLmNvbTAeFw0xOTAyMTkx
+MjM4NDhaFw0yMDAyMTkxMjM4NDhaMIGAMQswCQYDVQQGEwJJTjESMBAGA1UECAwJ
+S2FybmF0YWthMRIwEAYDVQQHDAlCQU5HQUxPUkUxEDAOBgNVBAoMB0NsYXlzb2wx
+FDASBgNVBAMMC2NsYXlzb2wuY29tMSEwHwYJKoZIhvcNAQkBFhJ2aWppdGhAY2xh
+eXNvbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9pvbiJJnL
+oe5YA6MCUryOYiTmj3PVdPpKMrBe2sdzvO0cx2NXpxWERK9QNnFaJb4fTY+j9fgv
+ru1tsIH3AbnDbXfpEPSD4DmpSXiKgB2+KZhA82ZerJendxqaXaj2BgTG2Tc++Chk
+0wzx/3KRSb97mgPKJK5yNwx3KQjeXAhR5Mkwmmf+ZUfoYHRu4BNneYs7qX9rEPDl
+vrd3AaPTgjapz7EEnSO19BrZHgLWFsM0Kni2vux1jHq1wYRXRTaOG0MrNuvuHuNC
+2j5C+N/MPcuuN9izbshrlteIi2a4526V4Hp1KX1BKAI2LgI+ufzdDEkuPs/u28J7
+tGiXjAmf4YUBAgMBAAGjUzBRMB0GA1UdDgQWBBQFfq9BP0BwBToA5U6gfNaxPDFt
+3jAfBgNVHSMEGDAWgBQFfq9BP0BwBToA5U6gfNaxPDFt3jAPBgNVHRMBAf8EBTAD
+AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBmruPekYCAAgHig66OBEHcl2jCp+MH1dmW
+amM5ET3X0mC588S4+JXCVOOh2XJ2ZSRiy0syPbGd0lG6niX5h35gsqSx9uZyXW/+
+KcTf+LsaxZNusLFtAOExnYuTeeAzofMvIGQpujMhD0p/gk8s64gXnlJZZh8S1OGV
+3Me8PV/cat0nuGpLi/0CYj2lAquG0LfeoGZAp+JHAMJTl/xyK4B/KMvbZ7USK9zz
+gqwLag93s4vBW0dpgu+g80GGhb0bF2ZFjD+j8I0i9OjFbTWxAiHomofQ6Qx12eVY
+rfJs/kVG86cOLJarFHBadjlLz4pu1/sp97TsohFYDy7isRbOQdO2
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key
new file mode 100644
index 000000000..ff9ce14df
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDqawqUVrD1HWvf
+LKdokLHvG1HMGmkWlpdi6il7vRC6XiJ0tXavr/PzTMe3OuzdgftZeXTjNQj7CGdu
+5iC9mNOH8ufJRjrcLaSYOTJ0edFZfJRvzcaAFo3NlyWIYVR3yZPijjBNmeIDBlP9
+lKDJDf5Wv7EgxbQKSSoWIEcI7z3Q1wza/0MaTS5kmmMHfgcfzzKhBHFJJPrRh1iP
+l071LhXM0hqY02fkHYGIOMP1oww9M/nEjieedxKHrMEWR2N+TqasICATBcKFD6V2
++U3zpunwXm/IvDG0XkdTVdl1z0Nmj3JrmPQpovE6JfrF8tDL2GHdenmW9Hg+aCBq
+/VI73yTLAgMBAAECggEAXfjLJOwbxCcnNzAPbDuVGOU6xTdRKVz1ExILzy7bpdpW
+tbKJAaTnhoEhDrLwgVu6BwRJd0urbfbQgASA24CIS9d0U5tzvRAPC3biYw7yfY0T
+dD5pdK+V6PTOdv2Nfvev8QJPGsy1bcD7qowKaI7ThrMRrrGSmwz5ciU+VLaTcUP/
+u8H22Wq+nZZGDtzmAgmHLZzOt79QlBDGsO4y15mss46AKan+ameI+iUjrRzSxZAO
+uT+YHPezWE6M8lYSntvmDFxxhkrdHC8qDsmI+AChs+ELu30zsbbj7fdH1esS9/7q
+PLfd0rHv3H3IfR7nvr0wIyX7DIUI3DhuGRvnRS8wAQKBgQD9vrzppukAIfoawlQW
+XFhDFAC89nReMx7T1r68E8VU4Ng/61KeV+sP269jbPHC0K2/bzHbth4im05oZkcZ
+ZaPWeKGmYCUr+lnV6148iFPeVKX4KROvsgIvJ4LVpJUNO4V5Jg2jQcVlkPN2yc7G
+EssVH4ywREedtCFMui1lGJ46wQKBgQDsgFXP/EM0uijSWqZ2it/tdFeeS7F3Uu+V
+2vErnP/xH8i1BkV2t8sLYeAVNW7fEmHcEx3DrZJ2yH3J3h7MivY5g5su1iXHHcRn
+ux9bnb6uzKYS8PRxVnJVjSg9X9q1q6Tsh6Dia5wKHf60rX3MEi7UsJ36uKNKeC3H
++4zh5tq+iwKBgQDQjbmlbRsqkcKHxdro+gNNNp6YsRPZ7LhUsrbXzIQvDBKRDrA8
+FtTLlutjk8JtNajoo9Ld26SPGwjpw86CMEjl2QY7weArcjvuF+K/a+lK3lX/Tnuw
+t2UWLqpZQEmFs7szZLRmz4MXxHhm1N2PbRjfhqvSoHwgQVHxR0BSTFaYwQKBgQDQ
+8+Zdd4UtXdjZWcw/ah3En4kWS8xFH9qcbS+tl+4t7SYYgqz24hYcPWKNeoM1xfj+
+R0mB7KY+Go/AvmY51AEN+bAvJneEQFGaUKK5AFtL93Y3v/pI9NbZrXjDGSCUaE2z
+yXUk92yLJ8s1eR9vIRWNR2qc7WsgTaQtT5w+rwfPVwKBgQC3udM2j59yDCoAOk3g
+Myz3PU9I3gLk+yQ2yHWRjE0Cundr3zQ7PqlsITUe9xhUfj+soBsRw7yeg5/wYcVJ
+F3hDmAOFb54pW912sD9CQbkhJMX6oVuSegUghPrXDhgiJ9i3TArc9xOKoER4A1s6
+N10tV3NPQprnu2m4jTBykPUJBw==
+-----END PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key
new file mode 100644
index 000000000..f4ae0d2d0
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/privatekey1.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9pvbiJJnLoe5Y
+A6MCUryOYiTmj3PVdPpKMrBe2sdzvO0cx2NXpxWERK9QNnFaJb4fTY+j9fgvru1t
+sIH3AbnDbXfpEPSD4DmpSXiKgB2+KZhA82ZerJendxqaXaj2BgTG2Tc++Chk0wzx
+/3KRSb97mgPKJK5yNwx3KQjeXAhR5Mkwmmf+ZUfoYHRu4BNneYs7qX9rEPDlvrd3
+AaPTgjapz7EEnSO19BrZHgLWFsM0Kni2vux1jHq1wYRXRTaOG0MrNuvuHuNC2j5C
++N/MPcuuN9izbshrlteIi2a4526V4Hp1KX1BKAI2LgI+ufzdDEkuPs/u28J7tGiX
+jAmf4YUBAgMBAAECggEADLcnEl512UtQGaKUyVEWx00ZQEQZ9hPTvCnN3W45tS7T
+jvxnUrcnICkiv/QGgY7KQnsGyG1zaG8ICDSvYgpBlDLAuWWjnzvnYcxFQrP4Somr
+ZZ9sG6jiuh2oMPVaoLQimdpyc8xbmPb1hTwlSExzhCv9WQ5Ai/PY6BxeNdphzGu2
+sNXm0+BBiwX+UdoVYg9nNEzJe8x1xKIjIw4CWk61ZclLsoScjNOZE7RJ3oqXeYnw
+EqBVqAJTZHYpS3e1LxsstOsZfI4kxdbnGjBydz1aHSP19tycY39kUFmjNq6oiSlv
+22+B1WdZ87POXTF0ISL8l+9HIVOKBCeuDmZ+KgS7KQKBgQD6FunVLHxVtQPS2/e0
+yvtHFqSBHuzL2FMIt6vfl4VhQ6QZ5aNPhbGv1WNcb9Z3pqLPp7zRgIPz63l6yHDT
+xTJEjCAseMoJIb/7ji1/RYE1eOhf3ie1BAuAxjdZ8rNVliZ2i3bt5aOUf4MOQdqE
+HY3/yXqMr1qPJThbyTk4bB3V1wKBgQDCImT4UvQqheMFF9Yev6MhUljm9XOjamk/
+v54pW4De7NR2J+4dR+enEHeO0EKCE+olAXfGztChbY4ytkW5bh5BndGCiYLq6NdS
+X4a1Bf1pM6y9/+QxHIQ99G+TGyfoiTmMT1eZNXZAF4MZN36Qe/Y0P9YlJmnRXDY9
+n8yM4+Tw5wKBgHGr0ITQP4NFT4Ob768BQ81AAW2e/Mp6fONNeJWcbUeUUxZiRiRz
+BByDxTHSs4yW9RGlkDE5VMCdmw2v5Xib/QkjF8ye6lXUPUq9iPh8Qwpm9lf8xdeF
+CyVw8t+zbMfOA5WGNnxTEFMC0jK8w/Gg7VYB4e3oFiVSKZeuko+OtNDpAoGAWFwZ
+QuFW2sfnpVjND1/AGxmE91I+mOGFGAvaLA7G4DBBH6pa+Z7RtDuNf0YRD22LA97g
+Km/Vi7P2peRKZfTV9p2jT1vRZ6Qk5QwvntMkHS707+G5dhT5p81Kv1T73B4hQFiY
+kVZBBTjuZZrZk1+olu17RZtvTGhBE9lY28OaX38CgYEAirReFhouOZc7Ng9gCfTM
+XYzIVZszQ8l8dD2fPhbYw9qSRNvST28s4lLtyRPvoKCpmlUMm5F6Xb65rvICMxc3
+DPnB9iLY6fLY7tETVeV9DEOXki3hoZQ4qkI7OIVbZQn1rA1Du95ZZEGdgE5eEMOC
+SQ9g3B7NYJT3Zs8rkxKajWM=
+-----END PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
new file mode 100644
index 000000000..6d51bf7af
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineclientcertificatestore.h>
+#include <QtWebEngineWidgets/qwebengineprofile.h>
+
+class tst_QWebEngineClientCertificateStore : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineClientCertificateStore();
+ ~tst_QWebEngineClientCertificateStore();
+
+private Q_SLOTS:
+ void addAndListCertificates();
+ void removeAndClearCertificates();
+};
+
+tst_QWebEngineClientCertificateStore::tst_QWebEngineClientCertificateStore()
+{
+}
+
+tst_QWebEngineClientCertificateStore::~tst_QWebEngineClientCertificateStore()
+{
+}
+
+void tst_QWebEngineClientCertificateStore::addAndListCertificates()
+{
+ // Load QSslCertificate
+ QFile certFile(":/resources/certificate.crt");
+ certFile.open(QIODevice::ReadOnly);
+ const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
+
+ // Load QSslKey
+ QFile keyFile(":/resources/privatekey.key");
+ keyFile.open(QIODevice::ReadOnly);
+ const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ // Load second QSslCertificate
+ QFile certFileSecond(":/resources/certificate1.crt");
+ certFileSecond.open(QIODevice::ReadOnly);
+ const QSslCertificate certSecond(certFileSecond.readAll(), QSsl::Pem);
+
+ // Load second QSslKey
+ QFile keyFileSecond(":/resources/privatekey1.key");
+ keyFileSecond.open(QIODevice::ReadOnly);
+ const QSslKey sslKeySecond(keyFileSecond.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ // Add certificates to in-memory store
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(cert, sslKey);
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(certSecond, sslKeySecond);
+
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+}
+
+void tst_QWebEngineClientCertificateStore::removeAndClearCertificates()
+{
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+
+ // Remove one certificate from in-memory store
+ auto list = QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates();
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->remove(list[0]);
+ QCOMPARE(1, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+
+ // Remove all certificates in-memory store
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->clear();
+ QCOMPARE(0, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+}
+
+QTEST_MAIN(tst_QWebEngineClientCertificateStore)
+#include "tst_qwebengineclientcertificatestore.moc"
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc
new file mode 100644
index 000000000..db481fef6
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/">
+ <file>resources/certificate.crt</file>
+ <file>resources/privatekey.key</file>
+ <file>resources/certificate1.crt</file>
+ <file>resources/privatekey1.key</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index b24c05a37..4ff33dbac 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -205,7 +205,7 @@ void tst_QWebEngineCookieStore::basicFilter()
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QTRY_COMPARE(cookieAddedSpy.count(), 2);
- QTRY_COMPARE(accessTested.loadAcquire(), 2);
+ QTRY_COMPARE(accessTested.loadAcquire(), 2); // FIXME?
client->deleteAllCookies();
QTRY_COMPARE(cookieRemovedSpy.count(), 2);
@@ -214,7 +214,7 @@ void tst_QWebEngineCookieStore::basicFilter()
page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
- QTRY_COMPARE(accessTested.loadAcquire(), 4);
+ QTRY_COMPARE(accessTested.loadAcquire(), 4); // FIXME?
// Test cookies are NOT added:
QTest::qWait(100);
QCOMPARE(cookieAddedSpy.count(), 2);
@@ -234,7 +234,7 @@ void tst_QWebEngineCookieStore::html5featureFilter()
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
- QCOMPARE(accessTested.loadAcquire(), 0);
+ QCOMPARE(accessTested.loadAcquire(), 0); // FIXME?
QTest::ignoreMessage(QtCriticalMsg, QRegularExpression(".*Uncaught SecurityError.*sessionStorage.*"));
page.runJavaScript("sessionStorage.test = 5;");
QTRY_COMPARE(accessTested.loadAcquire(), 1);
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 23bf88417..5629998fd 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -51,7 +51,9 @@ private Q_SLOTS:
void cleanupTestCase();
void interceptRequest();
void ipv6HostEncoding();
+ void requestedUrl_data();
void requestedUrl();
+ void setUrlSameUrl_data();
void setUrlSameUrl();
void firstPartyUrl();
void firstPartyUrlNestedIframes_data();
@@ -105,6 +107,7 @@ public:
void interceptRequest(QWebEngineUrlRequestInfo &info) override
{
+ QVERIFY(QThread::currentThread() == QCoreApplication::instance()->thread());
// Since 63 we also intercept some unrelated blob requests..
if (info.requestUrl().scheme() == QLatin1String("blob"))
return;
@@ -123,10 +126,7 @@ public:
// Skip import documents and sandboxed documents.
// See Document::SiteForCookies() in chromium/third_party/blink/renderer/core/dom/document.cc.
- //
- // TODO: Change this to empty URL during the next chromium update:
- // https://chromium-review.googlesource.com/c/chromium/src/+/1213082/
- return requestInfo.firstPartyUrl == QUrl("data:,");
+ return requestInfo.firstPartyUrl == QUrl("");
}
QList<RequestInfo> getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceType type)
@@ -168,7 +168,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
QWebEngineProfile profile;
profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
TestRequestInterceptor interceptor(/* intercept */ true);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -198,7 +198,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
// Make sure that registering an observer does not modify the request.
TestRequestInterceptor observer(/* intercept */ false);
- profile.setRequestInterceptor(&observer);
+ profile.setUrlRequestInterceptor(&observer);
page.load(QUrl("qrc:///resources/__placeholder__"));
QTRY_COMPARE(loadSpy.count(), 1);
success = loadSpy.takeFirst().takeFirst();
@@ -231,7 +231,7 @@ void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
{
QWebEngineProfile profile;
LocalhostContentProvider contentProvider;
- profile.setRequestInterceptor(&contentProvider);
+ profile.setUrlRequestInterceptor(&contentProvider);
QWebEnginePage page(&profile);
QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));
@@ -249,14 +249,27 @@ void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
QCOMPARE(contentProvider.requestedUrls.at(0), QUrl::fromEncoded("http://[::1]/test.xml"));
}
+void tst_QWebEngineUrlRequestInterceptor::requestedUrl_data()
+{
+ QTest::addColumn<bool>("interceptInPage");
+
+ QTest::newRow("Profile intercept") << false;
+ QTest::newRow("Page intercept") << true;
+}
+
void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
{
+ QFETCH(bool, interceptInPage);
+
QWebEngineProfile profile;
profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
TestRequestInterceptor interceptor(/* intercept */ true);
- profile.setRequestInterceptor(&interceptor);
+ if (!interceptInPage)
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
+ if (interceptInPage)
+ page.setUrlRequestInterceptor(&interceptor);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
@@ -273,19 +286,29 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
page.setUrl(QUrl("http://abcdef.abcdef"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 3, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 3, 15000);
QCOMPARE(interceptor.requestInfos.at(3).requestUrl, QUrl("http://abcdef.abcdef/"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
}
+void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl_data()
+{
+ requestedUrl_data();
+}
+
void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl()
{
+ QFETCH(bool, interceptInPage);
+
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ true);
- profile.setRequestInterceptor(&interceptor);
+ if (!interceptInPage)
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
+ if (interceptInPage)
+ page.setUrlRequestInterceptor(&interceptor);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
@@ -314,7 +337,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
{
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
@@ -348,7 +371,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -409,7 +432,7 @@ void tst_QWebEngineUrlRequestInterceptor::requestInterceptorByResourceType()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -427,7 +450,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
{
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
diff --git a/tests/auto/quick/dialogs/BLACKLIST b/tests/auto/quick/dialogs/BLACKLIST
new file mode 100644
index 000000000..19380e01e
--- /dev/null
+++ b/tests/auto/quick/dialogs/BLACKLIST
@@ -0,0 +1,2 @@
+[authenticationDialogRequested:Proxy Authentication Dialog]
+*
diff --git a/tests/auto/quick/dialogs/dialogs.pro b/tests/auto/quick/dialogs/dialogs.pro
index e262c3814..29d509b20 100644
--- a/tests/auto/quick/dialogs/dialogs.pro
+++ b/tests/auto/quick/dialogs/dialogs.pro
@@ -1,5 +1,5 @@
include(../tests.pri)
-QT += webengine webengine-private
+QT += core-private webengine webengine-private
HEADERS += \
server.h \
diff --git a/tests/auto/quick/dialogs/tst_dialogs.cpp b/tests/auto/quick/dialogs/tst_dialogs.cpp
index ecc2764fd..cecea1831 100644
--- a/tests/auto/quick/dialogs/tst_dialogs.cpp
+++ b/tests/auto/quick/dialogs/tst_dialogs.cpp
@@ -26,7 +26,6 @@
**
****************************************************************************/
-#include "qtwebengineglobal.h"
#include "testhandler.h"
#include "server.h"
#include <QtWebEngine/private/qquickwebenginedialogrequests_p.h>
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 59973f7d0..0012249c8 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -35,11 +35,13 @@
#include <QtTest/QtTest>
#include <QtWebEngine/QQuickWebEngineProfile>
#include <QtWebEngine/QQuickWebEngineScript>
+#include <QtWebEngineCore/QWebEngineNotification>
#include <QtWebEngineCore/QWebEngineQuotaRequest>
#include <QtWebEngineCore/QWebEngineRegisterProtocolHandlerRequest>
#include <private/qquickwebengineview_p.h>
#include <private/qquickwebengineaction_p.h>
#include <private/qquickwebenginecertificateerror_p.h>
+#include <private/qquickwebengineclientcertificateselection_p.h>
#include <private/qquickwebenginedialogrequests_p.h>
#include <private/qquickwebenginedownloaditem_p.h>
#include <private/qquickwebenginehistory_p.h>
@@ -60,6 +62,8 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
<< &QQuickWebEngineView::staticMetaObject
<< &QQuickWebEngineAction::staticMetaObject
<< &QQuickWebEngineCertificateError::staticMetaObject
+ << &QQuickWebEngineClientCertificateOption::staticMetaObject
+ << &QQuickWebEngineClientCertificateSelection::staticMetaObject
<< &QQuickWebEngineDownloadItem::staticMetaObject
<< &QQuickWebEngineHistory::staticMetaObject
<< &QQuickWebEngineHistoryListModel::staticMetaObject
@@ -79,6 +83,7 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
<< &QQuickWebEngineContextMenuRequest::staticMetaObject
<< &QWebEngineQuotaRequest::staticMetaObject
<< &QWebEngineRegisterProtocolHandlerRequest::staticMetaObject
+ << &QWebEngineNotification::staticMetaObject
;
static QList<const char *> knownEnumNames = QList<const char *>();
@@ -86,12 +91,15 @@ static QList<const char *> knownEnumNames = QList<const char *>();
static const QStringList hardcodedTypes = QStringList()
<< "QJSValue"
<< "QQmlListProperty<QQuickWebEngineScript>"
+ << "QQmlListProperty<QQuickWebEngineClientCertificateOption>"
+ << "const QQuickWebEngineClientCertificateOption*"
<< "QQmlWebChannel*"
// Ignore the testSupport types without making a fuss.
<< "QQuickWebEngineTestSupport*"
<< "QQuickWebEngineErrorPage*"
<< "const QQuickWebEngineContextMenuData*"
<< "QWebEngineCookieStore*"
+ << "Qt::LayoutDirection"
;
static const QStringList expectedAPI = QStringList()
@@ -132,6 +140,17 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineCertificateError.overridable --> bool"
<< "QQuickWebEngineCertificateError.rejectCertificate() --> void"
<< "QQuickWebEngineCertificateError.url --> QUrl"
+ << "QQuickWebEngineClientCertificateOption.issuer --> QString"
+ << "QQuickWebEngineClientCertificateOption.subject --> QString"
+ << "QQuickWebEngineClientCertificateOption.effectiveDate --> QDateTime"
+ << "QQuickWebEngineClientCertificateOption.expiryDate --> QDateTime"
+ << "QQuickWebEngineClientCertificateOption.isSelfSigned --> bool"
+ << "QQuickWebEngineClientCertificateOption.select() --> void"
+ << "QQuickWebEngineClientCertificateSelection.host --> QUrl"
+ << "QQuickWebEngineClientCertificateSelection.certificates --> QQmlListProperty<QQuickWebEngineClientCertificateOption>"
+ << "QQuickWebEngineClientCertificateSelection.select(int) --> void"
+ << "QQuickWebEngineClientCertificateSelection.select(const QQuickWebEngineClientCertificateOption*) --> void"
+ << "QQuickWebEngineClientCertificateSelection.selectNone() --> void"
<< "QQuickWebEngineColorDialogRequest.accepted --> bool"
<< "QQuickWebEngineColorDialogRequest.color --> QColor"
<< "QQuickWebEngineContextMenuRequest.CanUndo --> EditFlags"
@@ -303,6 +322,9 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.clearHttpCache() --> void"
<< "QQuickWebEngineProfile.downloadFinished(QQuickWebEngineDownloadItem*) --> void"
<< "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadItem*) --> void"
+ << "QQuickWebEngineProfile.downloadPath --> QString"
+ << "QQuickWebEngineProfile.downloadPathChanged() --> void"
+ << "QQuickWebEngineProfile.userNotification(QWebEngineNotification*) --> void"
<< "QQuickWebEngineProfile.httpAcceptLanguage --> QString"
<< "QQuickWebEngineProfile.httpAcceptLanguageChanged() --> void"
<< "QQuickWebEngineProfile.httpCacheMaximumSize --> int"
@@ -323,6 +345,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.spellCheckLanguagesChanged() --> void"
<< "QQuickWebEngineProfile.storageName --> QString"
<< "QQuickWebEngineProfile.storageNameChanged() --> void"
+ << "QQuickWebEngineProfile.useForGlobalCertificateVerification --> bool"
+ << "QQuickWebEngineProfile.useForGlobalCertificateVerificationChanged() --> void"
<< "QQuickWebEngineProfile.userScripts --> QQmlListProperty<QQuickWebEngineScript>"
<< "QQuickWebEngineScript.ApplicationWorld --> ScriptWorldId"
<< "QQuickWebEngineScript.Deferred --> InjectionPoint"
@@ -392,6 +416,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.localContentCanAccessRemoteUrlsChanged() --> void"
<< "QQuickWebEngineSettings.localStorageEnabled --> bool"
<< "QQuickWebEngineSettings.localStorageEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.pdfViewerEnabled --> bool"
+ << "QQuickWebEngineSettings.pdfViewerEnabledChanged() --> void"
<< "QQuickWebEngineSettings.playbackRequiresUserGesture --> bool"
<< "QQuickWebEngineSettings.playbackRequiresUserGestureChanged() --> void"
<< "QQuickWebEngineSettings.pluginsEnabled --> bool"
@@ -585,6 +611,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.NewViewInTab --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInWindow --> NewViewDestination"
<< "QQuickWebEngineView.NoErrorDomain --> ErrorDomain"
+ << "QQuickWebEngineView.Notifications --> Feature"
<< "QQuickWebEngineView.NoWebAction --> WebAction"
<< "QQuickWebEngineView.NormalTerminationStatus --> RenderProcessTerminationStatus"
<< "QQuickWebEngineView.Note --> PrintedPageSizeId"
@@ -699,6 +726,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.runJavaScript(QString,uint,QJSValue) --> void"
<< "QQuickWebEngineView.scrollPosition --> QPointF"
<< "QQuickWebEngineView.scrollPositionChanged(QPointF) --> void"
+ << "QQuickWebEngineView.selectClientCertificate(QQuickWebEngineClientCertificateSelection*) --> void"
<< "QQuickWebEngineView.setActiveFocusOnPress(bool) --> void"
<< "QQuickWebEngineView.settings --> QQuickWebEngineSettings*"
<< "QQuickWebEngineView.stop() --> void"
@@ -727,6 +755,17 @@ static const QStringList expectedAPI = QStringList()
<< "QWebEngineRegisterProtocolHandlerRequest.origin --> QUrl"
<< "QWebEngineRegisterProtocolHandlerRequest.reject() --> void"
<< "QWebEngineRegisterProtocolHandlerRequest.scheme --> QString"
+ << "QWebEngineNotification.origin --> QUrl"
+ << "QWebEngineNotification.icon --> QIcon"
+ << "QWebEngineNotification.title --> QString"
+ << "QWebEngineNotification.message --> QString"
+ << "QWebEngineNotification.tag --> QString"
+ << "QWebEngineNotification.language --> QString"
+ << "QWebEngineNotification.direction --> Qt::LayoutDirection"
+ << "QWebEngineNotification.show() --> void"
+ << "QWebEngineNotification.click() --> void"
+ << "QWebEngineNotification.close() --> void"
+ << "QWebEngineNotification.closed() --> void"
;
static bool isCheckedEnum(const QByteArray &typeName)
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index 019ebd9dc..5eb704cce 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -28,7 +28,8 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.5
+import QtWebEngine 1.9
+import Qt.labs.platform 1.0
TestWebEngineView {
id: webEngineView
@@ -42,6 +43,12 @@ TestWebEngineView {
property var downloadState: []
property var downloadInterruptReason: null
+ function urlToPath(url) {
+ var path = url.toString()
+ path = path.replace(/^(file:\/{2})/,"")
+ return path
+ }
+
SignalSpy {
id: downLoadRequestedSpy
target: testDownloadProfile
@@ -135,5 +142,16 @@ TestWebEngineView {
tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadCancelled)
tryCompare(webEngineView, "downloadInterruptReason", WebEngineDownloadItem.UserCanceled)
}
+
+ function test_downloadLocation() {
+ var tmpPath = urlToPath(StandardPaths.writableLocation(StandardPaths.TempLocation));
+ var downloadPath = urlToPath(StandardPaths.writableLocation(StandardPaths.DownloadLocation));
+
+ testDownloadProfile.downloadPath = tmpPath;
+ compare(testDownloadProfile.downloadPath, tmpPath);
+
+ testDownloadProfile.downloadPath = downloadPath;
+ compare(testDownloadProfile.downloadPath, downloadPath);
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index dfcfd586f..1ec574fae 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -116,7 +116,7 @@ TestWebEngineView {
webEngineView.clear()
webEngineView.findText("bla", findFlags, webEngineView.findTextCallback)
- tryCompare(webEngineView, "matchCount", 100)
+ tryCompare(webEngineView, "matchCount", 100, 20000)
verify(!findFailed)
}
@@ -172,7 +172,7 @@ TestWebEngineView {
webEngineView.clear()
webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
- tryCompare(webEngineView, "matchCount", 0)
+ tryCompare(webEngineView, "matchCount", 0, 20000)
verify(findFailed)
runJavaScript("document.body.innerHTML = 'blahellobla'");
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index 4becbb620..a671c2ec7 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -98,7 +98,8 @@ TestWebEngineView {
verify(dialog.webEngineView.waitForLoadSucceeded());
compare(dialog.webEngineView.url, "");
- compare(newViewRequest.requestedUrl, 'about:blank');
+ // https://chromium-review.googlesource.com/c/chromium/src/+/1300395
+ compare(newViewRequest.requestedUrl, 'about:blank#blocked');
newViewRequestedSpy.clear();
dialog.destroy();
@@ -129,8 +130,8 @@ TestWebEngineView {
verify(webEngineView.waitForLoadSucceeded());
verifyElementHasFocus("popupButton");
keyPress(Qt.Key_Enter);
- compare(newViewRequest.requestedUrl, url);
tryCompare(newViewRequestedSpy, "count", 1);
+ compare(newViewRequest.requestedUrl, url);
compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
verify(newViewRequest.userInitiated);
diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
new file mode 100644
index 000000000..af4aebafc
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtTest 1.0
+import QtWebEngine 1.9
+
+TestWebEngineView {
+ id: view
+ width: 320
+ height: 320
+
+ property bool permissionRequested: false
+ property bool grantPermission: false
+ property url securityOrigin: ''
+
+ signal consoleMessage(string message)
+
+ SignalSpy {
+ id: spyRequest
+ target: view
+ signalName: 'featurePermissionRequested'
+ }
+
+ onFeaturePermissionRequested: {
+ if (feature === WebEngineView.Notifications) {
+ view.permissionRequested = true
+ view.securityOrigin = securityOrigin
+ view.grantFeaturePermission(securityOrigin, feature, grantPermission)
+ }
+ }
+
+ TestCase {
+ name: 'WebEngineNotification'
+ when: windowShown
+
+ function resolverUrl(html) {
+ return Qt.resolvedUrl('../../../shared/data/' + html)
+ }
+
+ function init() {
+ permissionRequested = false
+ spyRequest.clear()
+ }
+
+ function test_request_data() {
+ return [
+ { tag: 'grant', grant: true, permission: 'granted' },
+ { tag: 'deny', grant: false, permission: 'denied' },
+ ]
+ }
+
+ function test_request(data) {
+ grantPermission = data.grant
+
+ view.url = resolverUrl('notification.html')
+ verify(view.waitForLoadSucceeded())
+
+ view.runJavaScript('resetPermission()')
+ let result = {}
+
+ view.runJavaScript('getPermission()', function (permission) { result.permission = permission })
+ tryCompare(result, 'permission', 'default')
+
+ view.runJavaScript('requestPermission()')
+ spyRequest.wait()
+ verify(permissionRequested)
+ compare(spyRequest.count, 1)
+
+ view.runJavaScript('getPermission()', function (permission) { result.permission = permission })
+ tryCompare(result, 'permission', data.permission)
+ }
+
+ function test_notification() {
+ grantPermission = true
+
+ view.url = resolverUrl('notification.html')
+ view.waitForLoadSucceeded()
+
+ view.runJavaScript('requestPermission()')
+ spyRequest.wait()
+ verify(permissionRequested)
+
+ let title = 'Title', message = 'Message', notification = null
+ view.profile.userNotification.connect(function (n) { notification = n })
+
+ view.runJavaScript('sendNotification("' + title + '", "' + message + '")')
+ tryVerify(function () { return notification !== null })
+ compare(notification.title, title)
+ compare(notification.message, message)
+ compare(notification.direction, Qt.RightToLeft)
+ compare(notification.origin, securityOrigin)
+ compare(notification.tag, 'tst')
+ compare(notification.language, 'de')
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_profile.qml b/tests/auto/quick/qmltests/data/tst_profile.qml
new file mode 100644
index 000000000..ee7fa4e99
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_profile.qml
@@ -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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebEngine 1.9
+
+TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 300
+
+
+ WebEngineProfile {
+ id: profile1
+ }
+ WebEngineProfile {
+ id: profile2
+ }
+ property bool profile1UsedForGlobalCertificateVerification: profile1.useForGlobalCertificateVerification
+
+ TestCase {
+ name: "WebEngineProfile"
+
+ function test_useForGlobalCertificateVerification() {
+ verify(!profile1.useForGlobalCertificateVerification);
+ verify(!profile2.useForGlobalCertificateVerification);
+ verify(!webEngineView.profile1UsedForGlobalCertificateVerification);
+
+ profile1.useForGlobalCertificateVerification = true;
+ verify(profile1.useForGlobalCertificateVerification);
+ verify(!profile2.useForGlobalCertificateVerification);
+ verify(webEngineView.profile1UsedForGlobalCertificateVerification);
+
+ profile2.useForGlobalCertificateVerification = true;
+ verify(!webEngineView.profile1UsedForGlobalCertificateVerification);
+ verify(!profile1.useForGlobalCertificateVerification);
+ verify(profile2.useForGlobalCertificateVerification);
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index a2b05e091..00e884e11 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -67,6 +67,8 @@ OTHER_FILES += \
$$PWD/data/tst_navigationHistory.qml \
$$PWD/data/tst_navigationRequested.qml \
$$PWD/data/tst_newViewRequest.qml \
+ $$PWD/data/tst_notification.qml \
+ $$PWD/data/tst_profile.qml \
$$PWD/data/tst_properties.qml \
$$PWD/data/tst_runJavaScript.qml \
$$PWD/data/tst_scrollPosition.qml \
diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
index 76cb18c1e..166a6894e 100644
--- a/tests/auto/quick/qquickwebengineview/BLACKLIST
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -9,8 +9,9 @@ windows
[basicRenderingSanity]
*
+
[javascriptClipboard:default]
opensuse-leap
+
[javascriptClipboard:canPaste]
opensuse-leap
-
diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
index c253bc2a6..38c130aa3 100644
--- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
+++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
@@ -1,6 +1,6 @@
include(../tests.pri)
exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
-QT_PRIVATE += webengine-private gui-private webenginecore-private
+QT_PRIVATE += core_private gui-private webengine-private webenginecore-private
HEADERS += ../shared/util.h
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 007acb8b0..eb76be6db 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -31,6 +31,7 @@
#include <QScopedPointer>
#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qregularexpression.h>
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
@@ -40,6 +41,7 @@
#include <QtGui/private/qinputmethod_p.h>
#include <QtWebEngine/private/qquickwebengineview_p.h>
#include <QtWebEngine/private/qquickwebenginesettings_p.h>
+#include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
#include <qpa/qplatforminputcontext.h>
#include <functional>
@@ -999,8 +1001,9 @@ void tst_QQuickWebEngineView::changeLocale()
viewDE->setUrl(url);
QVERIFY(waitForLoadFailed(viewDE.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
- errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
QLocale::setDefault(QLocale("en"));
@@ -1008,8 +1011,9 @@ void tst_QQuickWebEngineView::changeLocale()
viewEN->setUrl(url);
QVERIFY(waitForLoadFailed(viewEN.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").isNull());
- errorLines = evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").toString().split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached"));
// Reset error page
@@ -1020,8 +1024,9 @@ void tst_QQuickWebEngineView::changeLocale()
viewDE->setUrl(url);
QVERIFY(waitForLoadFailed(viewDE.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
- errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
}
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 50a6a8587..81b62b4e7 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -1,5 +1,5 @@
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
-QT_FOR_CONFIG += webenginecore-private
+include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) # workaround for QTBUG-68093
+QT_FOR_CONFIG += webengine-private
TEMPLATE = subdirs
@@ -18,4 +18,4 @@ qtConfig(webengine-testsupport) {
}
# QTBUG-66055
-boot2qt: SUBDIRS -= inspectorserver qquickwebenginedefaultsurfaceformat qquickwebengineview qmltests dialogs qtbug-70248
+boot2qt: SUBDIRS -= inspectorserver qquickwebengineview qmltests
diff --git a/tests/auto/quick/tests.pri b/tests/auto/quick/tests.pri
index f7104ad9c..1bf69da43 100644
--- a/tests/auto/quick/tests.pri
+++ b/tests/auto/quick/tests.pri
@@ -1,5 +1,5 @@
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
-QT_FOR_CONFIG += webenginecore-private
+include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) # workaround for QTBUG-68093
+QT_FOR_CONFIG += webengine-private
TEMPLATE = app
diff --git a/tests/auto/shared/data/notification.html b/tests/auto/shared/data/notification.html
new file mode 100644
index 000000000..1d1e9c411
--- /dev/null
+++ b/tests/auto/shared/data/notification.html
@@ -0,0 +1,70 @@
+<!doctype html>
+<html>
+<head>
+<title>Desktop Notifications Demo</title>
+<script>
+ function resetPermission() { document.Notification = 'default' }
+
+ function getPermission() { return document.Notification }
+
+ function sendNotification(title, body) {
+ let notification = new Notification(title, { body: body, dir: 'rtl', lang: 'de', tag: 'tst' })
+ notification.onclick = function() { console.info('onclick') }
+ notification.onclose = function() { console.info('onclose') }
+ notification.onerror = function(error) { console.info('onerror: ' + error) }
+ notification.onshow = function() { console.info('onshow') }
+ }
+
+ function makeNotification() {
+ let title = document.getElementById("title").value
+ let body = document.getElementById("body").value
+ console.log('making notification:', title)
+ sendNotification(title, body)
+ }
+
+ function requestPermission(callback) {
+ Notification.requestPermission().then(function (permission) {
+ document.Notification = permission
+ if (callback)
+ callback(permission)
+ })
+ }
+
+ function displayNotification() {
+ console.info('notifications are ' + document.Notification)
+
+ let state = document.getElementById('state')
+
+ if (document.Notification === 'denied') {
+ state.innerHTML = 'Notifications disabled'
+ } else if (document.Notification === 'granted') {
+ makeNotification()
+ state.innerHTML = 'notification created'
+ } else {
+ state.innerHTML = 'requesting permission...'
+ requestPermission(function (permission) {
+ console.info('notifications request: ' + permission)
+ if (permission === 'granted') {
+ makeNotification()
+ state.innerHTML = 'permission granted, notification created'
+ } else if (permission === 'denied')
+ state.innerHTML = 'Notifications are disabled'
+ })
+ }
+ }
+
+ document.addEventListener("DOMContentLoaded", function() {
+ document.Notification = Notification.permission
+ })
+</script>
+</head>
+<body>
+ <form name="NotificationForm" id="notificationForm">
+ Title: <input type="text" id="title" placeholder="Notification title" value='sample title'><br>
+ Body: <input type="text" id="body" placeholder="Notification body" value='default body'><br>
+ <input type="button" value="Display Notification" onclick="displayNotification()"><br>
+ <input type="button" value="Reset Permission" onclick="resetPermission()">
+ </form>
+ <div id='state'></div>
+</body>
+</html>
diff --git a/tests/auto/widgets/offscreen/offscreen.pro b/tests/auto/widgets/offscreen/offscreen.pro
new file mode 100644
index 000000000..b8e5632f9
--- /dev/null
+++ b/tests/auto/widgets/offscreen/offscreen.pro
@@ -0,0 +1,6 @@
+include(../tests.pri)
+QT += webengine
+qpa.name = QT_QPA_PLATFORM
+qpa.value = offscreen
+QT_TOOL_ENV += qpa
+
diff --git a/tests/auto/widgets/offscreen/tst_offscreen.cpp b/tests/auto/widgets/offscreen/tst_offscreen.cpp
new file mode 100644
index 000000000..98cbe55fe
--- /dev/null
+++ b/tests/auto/widgets/offscreen/tst_offscreen.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtwebengineglobal.h"
+#include <QTest>
+#include <QSignalSpy>
+#include <QWebEngineProfile>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+
+class tst_OffScreen : public QObject {
+ Q_OBJECT
+public:
+ tst_OffScreen(){}
+
+private slots:
+ void offscreen();
+};
+
+void tst_OffScreen::offscreen()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ view.setPage(&page);
+ page.load(QUrl("http://qt.io"));
+ view.show();
+ QTRY_COMPARE(view.isVisible(), true);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count() > 0, true, 20000);
+}
+
+#include "tst_offscreen.moc"
+QTEST_MAIN(tst_OffScreen)
+
diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp
index 59cbdae13..61d16bc8a 100644
--- a/tests/auto/widgets/origins/tst_origins.cpp
+++ b/tests/auto/widgets/origins/tst_origins.cpp
@@ -301,7 +301,7 @@ void tst_Origins::jsUrlOrigin()
QCOMPARE(eval(QSL("new URL(\"qrc:/crysis.css\").origin")), QVariant(QSL("qrc://")));
QCOMPARE(eval(QSL("new URL(\"qrc://foo.com/crysis.css\").origin")), QVariant(QSL("qrc://")));
- // Same with unregistered schemes.
+ // Unregistered schemes behaves like opaque origins.
QCOMPARE(eval(QSL("new URL(\"tst:/banana\").origin")), QVariant(QSL("tst://")));
QCOMPARE(eval(QSL("new URL(\"tst://foo.com/banana\").origin")), QVariant(QSL("tst://")));
@@ -564,8 +564,6 @@ private:
// Try opening a WebSocket from pages loaded over various URL schemes.
void tst_Origins::webSocket()
{
- const int kAbnormalClosure = 1006;
-
EchoServer echoServer;
QWebChannel channel;
channel.registerObject(QSL("echoServer"), &echoServer);
@@ -578,9 +576,9 @@ void tst_Origins::webSocket()
QVERIFY(load(QSL("qrc:/resources/websocket.html")));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
- // Only registered schemes can open WebSockets.
+ // Unregistered schemes can also open WebSockets (since Chromium 71)
QVERIFY(load(QSL("tst:/resources/websocket.html")));
- QTRY_COMPARE(eval(QSL("result")), QVariant(kAbnormalClosure));
+ QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
// Even an insecure registered scheme can open WebSockets.
QVERIFY(load(QSL("PathSyntax:/resources/websocket.html")));
@@ -599,11 +597,10 @@ void tst_Origins::dedicatedWorker()
QTRY_VERIFY(eval(QSL("done")).toBool());
QCOMPARE(eval(QSL("result")), QVariant(42));
- // Unregistered schemes cannot create Workers.
+ // Unregistered schemes can also create Workers (since Chromium 71)
QVERIFY(load(QSL("tst:/resources/dedicatedWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
- QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("Access to dedicated workers is denied to origin 'tst://'")));
+ QCOMPARE(eval(QSL("result")), QVariant(42));
// Even an insecure registered scheme can create Workers.
QVERIFY(load(QSL("PathSyntax:/resources/dedicatedWorker.html")));
@@ -724,15 +721,9 @@ void tst_Origins::createObjectURL()
QVERIFY(load(QSL("qrc:/resources/createObjectURL.html")));
QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:qrc:")));
- // Illegal for unregistered schemes (renderer gets terminated).
- qRegisterMetaType<QWebEnginePage::RenderProcessTerminationStatus>("RenderProcessTerminationStatus");
- QSignalSpy loadFinishedSpy(m_page, &QWebEnginePage::loadFinished);
- QSignalSpy renderProcessTerminatedSpy(m_page, &QWebEnginePage::renderProcessTerminated);
- m_page->load(QSL("tst:/resources/createObjectURL.html"));
- QVERIFY(!renderProcessTerminatedSpy.empty() || renderProcessTerminatedSpy.wait(20000));
- QVERIFY(renderProcessTerminatedSpy.front().value(0).value<QWebEnginePage::RenderProcessTerminationStatus>()
- != QWebEnginePage::NormalTerminationStatus);
- QVERIFY(loadFinishedSpy.empty());
+ // Also legal for unregistered schemes (since Chromium 71)
+ QVERIFY(load(QSL("tst:/resources/createObjectURL.html")));
+ QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:tst:")));
}
QTEST_MAIN(tst_Origins)
diff --git a/tests/auto/widgets/proxy/proxy.pro b/tests/auto/widgets/proxy/proxy.pro
new file mode 100644
index 000000000..802dfad05
--- /dev/null
+++ b/tests/auto/widgets/proxy/proxy.pro
@@ -0,0 +1,9 @@
+include(../tests.pri)
+QT += core-private webengine webengine-private
+
+HEADERS += \
+ proxy_server.h
+
+SOURCES += \
+ proxy_server.cpp
+
diff --git a/tests/auto/widgets/proxy/proxy_server.cpp b/tests/auto/widgets/proxy/proxy_server.cpp
new file mode 100644
index 000000000..55f014914
--- /dev/null
+++ b/tests/auto/widgets/proxy/proxy_server.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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "proxy_server.h"
+#include <QDataStream>
+#include <QTcpSocket>
+#include <QDebug>
+
+ProxyServer::ProxyServer(QObject *parent) : QObject(parent)
+{
+ connect(&m_server, &QTcpServer::newConnection, this, &ProxyServer::handleNewConnection);
+}
+
+void ProxyServer::setCredentials(const QByteArray &user, const QByteArray password)
+{
+ m_auth.append(user);
+ m_auth.append(QChar(':'));
+ m_auth.append(password);
+ m_auth = m_auth.toBase64();
+}
+
+bool ProxyServer::isListening()
+{
+ return m_server.isListening();
+}
+
+void ProxyServer::run()
+{
+ if (!m_server.listen(QHostAddress::LocalHost, 5555))
+ qFatal("Could not start the test server");
+}
+
+void ProxyServer::handleNewConnection()
+{
+ // do one connection at the time
+ Q_ASSERT(m_data.isEmpty());
+ QTcpSocket *socket = m_server.nextPendingConnection();
+ Q_ASSERT(socket);
+ connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
+ connect(socket, &QAbstractSocket::readyRead, this, &ProxyServer::handleReadReady);
+}
+
+void ProxyServer::handleReadReady()
+{
+ QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
+ Q_ASSERT(socket);
+
+ m_data.append(socket->readAll());
+
+ if (!m_data.endsWith("\r\n\r\n"))
+ return;
+
+ if (!m_data.contains(QByteArrayLiteral("Proxy-Authorization: Basic"))) {
+ socket->write("HTTP/1.1 407 Proxy Authentication Required\nProxy-Authenticate: "
+ "Basic realm=\"Proxy requires authentication\"\r\n"
+ "content-length: 0\r\n"
+ "\r\n");
+ return;
+ }
+
+ if (m_data.contains(m_auth)) {
+ emit success();
+ }
+ m_data.clear();
+}
diff --git a/tests/auto/widgets/proxy/proxy_server.h b/tests/auto/widgets/proxy/proxy_server.h
new file mode 100644
index 000000000..cb7c30600
--- /dev/null
+++ b/tests/auto/widgets/proxy/proxy_server.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROXY_SERVER_H
+#define PROXY_SERVER_H
+
+#include <QObject>
+#include <QTcpServer>
+
+class ProxyServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit ProxyServer(QObject *parent = nullptr);
+ void setCredentials(const QByteArray &user, const QByteArray password);
+ bool isListening();
+
+public slots:
+ void run();
+
+private slots:
+ void handleNewConnection();
+ void handleReadReady();
+
+signals:
+ void success();
+private:
+ QByteArray m_data;
+ QTcpServer m_server;
+ QByteArray m_auth;
+};
+
+#endif // PROXY_SERVER_H
diff --git a/tests/auto/widgets/proxy/tst_proxy.cpp b/tests/auto/widgets/proxy/tst_proxy.cpp
new file mode 100644
index 000000000..5f5dec016
--- /dev/null
+++ b/tests/auto/widgets/proxy/tst_proxy.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "proxy_server.h"
+#include <QTest>
+#include <QSignalSpy>
+#include <QNetworkProxy>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+
+
+class tst_Proxy : public QObject {
+ Q_OBJECT
+public:
+ tst_Proxy(){}
+
+private slots:
+ void proxyAuthentication();
+};
+
+void tst_Proxy::proxyAuthentication()
+{
+ QByteArray user(QByteArrayLiteral("test"));
+ QByteArray password(QByteArrayLiteral("pass"));
+ QNetworkProxy proxy;
+ proxy.setType(QNetworkProxy::HttpProxy);
+ proxy.setHostName("localhost");
+ proxy.setPort(5555);
+ proxy.setUser(user);
+ proxy.setPassword(password);
+ QNetworkProxy::setApplicationProxy(proxy);
+ ProxyServer server;
+ server.setCredentials(user,password);
+ server.run();
+ QTRY_VERIFY2(server.isListening(), "Could not setup authentication server");
+ QWebEnginePage page;
+ QSignalSpy successSpy(&server, &ProxyServer::success);
+ page.load(QUrl("http://www.qt.io"));
+ QTRY_VERIFY2(successSpy.count() > 0, "Could not get authentication token");
+}
+
+#include "tst_proxy.moc"
+QTEST_MAIN(tst_Proxy)
+
diff --git a/tests/auto/widgets/proxypac/proxypac.pro b/tests/auto/widgets/proxypac/proxypac.pro
index 00ae90977..1c2958d3a 100644
--- a/tests/auto/widgets/proxypac/proxypac.pro
+++ b/tests/auto/widgets/proxypac/proxypac.pro
@@ -3,26 +3,8 @@ QT += webengine
HEADERS += proxyserver.h
SOURCES += proxyserver.cpp
-# QTBUG-71229
-xgd_desktop.name=XDG_CURRENT_DESKTOP
-xgd_desktop.value=KDE
-QT_TOOL_ENV += xgd_desktop
+proxy_pac.name = QTWEBENGINE_CHROMIUM_FLAGS
+proxy_pac.value = --proxy-pac-url="file://$$PWD/proxy.pac"
-kde_home.name=KDEHOME
-kde_home.value=$$OUT_PWD
-QT_TOOL_ENV += kde_home
-
-PROXY_CONFIG= \
- "[Proxy Settings]" \
- "Proxy Config Script=$$PWD/proxy.pac" \
- "ProxyType=2"
-
-mkpath($$OUT_PWD/share/config)
-KDE_FILE = $$OUT_PWD/share/config/kioslaverc
-
-!build_pass {
- write_file($$KDE_FILE, PROXY_CONFIG)
-}
-
-QMAKE_DISTCLEAN += $$KDE_FILE
+QT_TOOL_ENV += proxy_pac
diff --git a/tests/auto/widgets/qwebenginedownloaditem/BLACKLIST b/tests/auto/widgets/qwebenginedownloaditem/BLACKLIST
new file mode 100644
index 000000000..a51117ae0
--- /dev/null
+++ b/tests/auto/widgets/qwebenginedownloaditem/BLACKLIST
@@ -0,0 +1,2 @@
+[downloadToReadOnlyDir]
+windows
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index b30fc7258..ee1e6ee04 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -31,6 +31,7 @@
#include <QStandardPaths>
#include <QTemporaryDir>
#include <QTest>
+#include <QRegularExpression>
#include <QWebEngineDownloadItem>
#include <QWebEnginePage>
#include <QWebEngineProfile>
@@ -70,6 +71,12 @@ private Q_SLOTS:
void downloadFileNot2();
void downloadDeleted();
void downloadDeletedByProfile();
+ void downloadUniqueFilename_data();
+ void downloadUniqueFilename();
+ void downloadUniqueFileNameWithTimeStamp();
+ void downloadToDefaultLocation();
+ void downloadToNonExistentDir();
+ void downloadToReadOnlyDir();
private:
void saveLink(QPoint linkPos);
@@ -135,6 +142,8 @@ void tst_QWebEngineDownloadItem::cleanup()
QTRY_COMPARE(m_requestedDownloads.count(), 0);
QCOMPARE(m_finishedDownloads.count(), 0);
QVERIFY(m_server->stop());
+ // Set download path to default.
+ m_profile->setDownloadPath("");
}
void tst_QWebEngineDownloadItem::cleanupTestCase()
@@ -844,5 +853,264 @@ void tst_QWebEngineDownloadItem::downloadDeletedByProfile()
QTRY_COMPARE(downloadItem.isNull(), true);
}
+void tst_QWebEngineDownloadItem::downloadUniqueFilename_data()
+{
+ QTest::addColumn<QString>("baseName");
+ QTest::addColumn<QString>("extension");
+
+ QTest::newRow("txt") << QString("test(1.test)") << QString("txt");
+ QTest::newRow("tar.gz") << QString("test(1.test)") << QString("tar.gz");
+}
+
+void tst_QWebEngineDownloadItem::downloadUniqueFilename()
+{
+ QFETCH(QString, baseName);
+ QFETCH(QString, extension);
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->type(), QWebEngineDownloadItem::Attachment);
+ QCOMPARE(item->isSavePageDownload(), false);
+ downloadedFilePath = item->path();
+ downloadFinished = true;
+ });
+ });
+
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + "." + extension);
+
+ for (int i = 1; i <= 2; ++i) {
+ downloadFinished = false;
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension);
+ }
+}
+
+void tst_QWebEngineDownloadItem::downloadUniqueFileNameWithTimeStamp()
+{
+ // Set up HTTP server
+ QString baseName("test(1.test)");
+ QString extension("txt");
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->page(), m_page);
+ downloadFinished = true;
+ downloadedFilePath = item->path();
+ });
+ });
+
+ // Create the first empty file without uniquifier.
+ {
+ QFile file(m_profile->downloadPath() + "/" + fileName);
+ file.open(QIODevice::ReadWrite);
+ }
+
+ // Create 99 empty files with uniquifier.
+ for (int i = 1; i < 100; i++) {
+ QFile file(m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension);
+ file.open(QIODevice::ReadWrite);
+ }
+
+ // Create 100th (kMaxUniqueFiles) empty file with uniquifier.
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (100)." + extension);
+
+ // Check if the downloaded files are suffixed with timestamp after the 100th download.
+ for (int i = 101; i < 103; i++) {
+ downloadFinished = false;
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QRegularExpression fileNameCheck("^.*" + QRegularExpression::escape(baseName) + " - (.*)[.]" + QRegularExpression::escape(extension) + "$");
+ QRegularExpressionMatch match = fileNameCheck.match(downloadedFilePath);
+ QVERIFY(match.hasMatch());
+ // ISO 8601 Date and time in UTC
+ QRegExp timeStamp("^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])([.][0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$");
+ QVERIFY(timeStamp.exactMatch(match.captured(1)));
+ }
+}
+
+void tst_QWebEngineDownloadItem::downloadToDefaultLocation()
+{
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+
+ QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+
+ m_profile->setDownloadPath("");
+ QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+
+ m_profile->setDownloadPath(tmpDir.path());
+ QCOMPARE(m_profile->downloadPath(), tmpDir.path());
+
+ m_profile->setDownloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+ QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+}
+
+void tst_QWebEngineDownloadItem::downloadToNonExistentDir()
+{
+ QString baseName("test(1.test)");
+ QString extension("txt");
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->page(), m_page);
+ downloadFinished = true;
+ downloadedFilePath = item->path();
+ });
+ });
+
+ // Set a non-existent directory for the default download location.
+ QString nonExistentDownloadPath(m_profile->downloadPath() + "/non_existent_dir");
+ m_profile->setDownloadPath(nonExistentDownloadPath);
+ QCOMPARE(m_profile->downloadPath(), nonExistentDownloadPath);
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, nonExistentDownloadPath + "/" + fileName);
+}
+
+void tst_QWebEngineDownloadItem::downloadToReadOnlyDir()
+{
+ QString baseName("test(1.test)");
+ QString extension("txt");
+ QString fileName = QString("%1.%2").arg(baseName).arg(extension);
+ QString downloadedFilePath;
+ bool downloadAccepted = false;
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ QPointer<QWebEngineDownloadItem> downloadItem;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ downloadItem = item;
+ item->accept();
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ downloadFinished = true;
+ });
+ downloadAccepted = true;
+ });
+
+ // Change permission for directory.
+ QFile(m_profile->downloadPath()).setPermissions(QFileDevice::ReadOwner);
+ QVERIFY(QFile(m_profile->downloadPath()).exists());
+
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadAccepted);
+
+ QVERIFY(downloadItem);
+ QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadInterrupted);
+ QCOMPARE(downloadItem->isFinished(), false);
+ QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileAccessDenied);
+ QVERIFY(!QFile(downloadedFilePath).exists());
+
+ // Clear m_requestedDownloads explicitly because download is accepted but never finished.
+ m_requestedDownloads.clear();
+ QVERIFY(!downloadFinished);
+ QFile(m_profile->downloadPath()).setPermissions(QFileDevice::WriteOwner);
+}
+
QTEST_MAIN(tst_QWebEngineDownloadItem)
#include "tst_qwebenginedownloaditem.moc"
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 228efd61c..f3dc51fdd 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -1,9 +1,3 @@
-[comboBoxPopupPositionAfterMove]
-*
-
-[comboBoxPopupPositionAfterChildMove]
-*
-
[macCopyUnicodeToClipboard]
osx
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 8c3b4002c..3792b5522 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -34,7 +34,6 @@
#include <QOpenGLWidget>
#include <QPaintEngine>
#include <QPushButton>
-#include <QRegExp>
#include <QScreen>
#include <QStateMachine>
#include <QtGui/QClipboard>
@@ -50,6 +49,7 @@
#include <qwebenginedownloaditem.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
+#include <qwebenginenotification.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
#include <qwebenginequotarequest.h>
@@ -90,11 +90,8 @@ public Q_SLOTS:
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
- void thirdPartyCookiePolicy();
void comboBoxPopupPositionAfterMove();
void comboBoxPopupPositionAfterChildMove();
- void contextMenuCopy();
- void contextMenuPopulatedOnce();
void acceptNavigationRequest();
void acceptNavigationRequestNavigationType();
void geolocationRequestJS_data();
@@ -103,26 +100,13 @@ private Q_SLOTS:
void actionStates();
void pasteImage();
void popupFormSubmission();
- void userStyleSheet();
- void userStyleSheetFromLocalFileUrl();
- void userStyleSheetFromQrcUrl();
- void modified();
- void contextMenuCrash();
- void updatePositionDependentActionsCrash();
void callbackSpyDeleted();
void multipleProfilesAndLocalStorage();
- void cursorMovements();
void textSelection();
- void textEditing();
void backActionUpdate();
- void testOptionalJSObjects();
- void testLocalStorageVisibility();
- void testEnablePersistentStorage();
+ void localStorageVisibility();
void consoleOutput();
- void errorPageExtension();
- void errorPageExtensionLoadFinished();
void userAgentNewlineStripping();
- void undoActionHaveCustomText();
void renderWidgetHostViewNotShowTopLevel();
void getUserMediaRequest_data();
void getUserMediaRequest();
@@ -134,30 +118,19 @@ private Q_SLOTS:
void crashTests_LazyInitializationOfMainFrame();
- void screenshot_data();
- void screenshot();
-
#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
void acceleratedWebGLScreenshotWithoutView();
void unacceleratedWebGLScreenshotWithoutView();
#endif
void testJSPrompt();
- void testStopScheduledPageRefresh();
void findText();
void findTextResult();
void findTextSuccessiveShouldCallAllCallbacks();
- void supportedContentType();
- // [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT
- // https://bugs.webkit.org/show_bug.cgi?id=79040
- // void infiniteLoopJS();
void deleteQWebEngineViewTwice();
- void renderOnRepaintRequestedShouldNotRecurse();
void loadSignalsOrder_data();
void loadSignalsOrder();
void openWindowDefaultSize();
- void cssMediaTypeGlobalSetting();
- void cssMediaTypePageSetting();
#ifdef Q_OS_MAC
void macCopyUnicodeToClipboard();
@@ -165,12 +138,12 @@ private Q_SLOTS:
void runJavaScript();
void runJavaScriptDisabled();
+ void runJavaScriptFromSlot();
void fullScreenRequested();
void quotaRequested();
// Tests from tst_QWebEngineFrame
- void horizontalScrollAfterBack();
void symmetricUrl();
void progressSignal();
void urlChange();
@@ -182,8 +155,6 @@ private Q_SLOTS:
void setHtmlWithStylesheetResource();
void setHtmlWithBaseURL();
void setHtmlWithJSAlert();
- void inputFieldFocus();
- void hitTestContent();
void baseUrl_data();
void baseUrl();
void scrollPosition();
@@ -191,7 +162,6 @@ private Q_SLOTS:
void evaluateWillCauseRepaint();
void setContent_data();
void setContent();
- void setCacheLoadControlAttribute();
void setUrlWithPendingLoads();
void setUrlToEmpty();
void setUrlToInvalid();
@@ -227,6 +197,10 @@ private Q_SLOTS:
void triggerActionWithoutMenu();
void dynamicFrame();
+ void notificationRequest_data();
+ void notificationRequest();
+ void sendNotification();
+
private:
static QPoint elementCenter(QWebEnginePage *page, const QString &id);
@@ -368,18 +342,6 @@ private:
bool m_allowGeolocation;
};
-// [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT
-// https://bugs.webkit.org/show_bug.cgi?id=79040
-/*
-void tst_QWebEnginePage::infiniteLoopJS()
-{
- JSTestPage newPage(m_view);
- m_view->setPage(&newPage);
- m_view->setHtml(QString("<html><body>test</body></html>"), QUrl());
- m_view->page()->evaluateJavaScript("var run = true; var a = 1; while (run) { a++; }");
-}
-*/
-
void tst_QWebEnginePage::geolocationRequestJS_data()
{
QTest::addColumn<bool>("allowed");
@@ -659,170 +621,6 @@ protected:
}
};
-void tst_QWebEnginePage::userStyleSheet()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
-
- m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64,"
- + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64()));
- m_view->setHtml("<p>hello world</p>");
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(networkManager->requestedUrls.count() >= 1);
- QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
-#endif
-}
-
-void tst_QWebEnginePage::userStyleSheetFromLocalFileUrl()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
-
- QUrl styleSheetUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginepage/resources/user.css"));
- m_page->settings()->setUserStyleSheetUrl(styleSheetUrl);
- m_view->setHtml("<p>hello world</p>");
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(networkManager->requestedUrls.count() >= 1);
- QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
-#endif
-}
-
-void tst_QWebEnginePage::userStyleSheetFromQrcUrl()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- TestNetworkManager* networkManager = new TestNetworkManager(m_page);
- m_page->setNetworkAccessManager(networkManager);
-
- m_page->settings()->setUserStyleSheetUrl(QUrl("qrc:///resources/user.css"));
- m_view->setHtml("<p>hello world</p>");
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(networkManager->requestedUrls.count() >= 1);
- QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
-#endif
-}
-
-void tst_QWebEnginePage::modified()
-{
-#if !defined(QWEBENGINEPAGE_ISMODIFIED)
- QSKIP("QWEBENGINEPAGE_ISMODIFIED");
-#else
- m_page->setUrl(QUrl("data:text/html,<body>blub"));
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- m_page->setUrl(QUrl("data:text/html,<body id=foo contenteditable>blah"));
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(!m_page->isModified());
-
- m_page->runJavaScript("document.getElementById('foo').focus()");
- evaluateJavaScriptSync(m_page, "document.execCommand('InsertText', true, 'Test');");
-
- QVERIFY(m_page->isModified());
-
- evaluateJavaScriptSync(m_page, "document.execCommand('Undo', true);");
-
- QVERIFY(!m_page->isModified());
-
- evaluateJavaScriptSync(m_page, "document.execCommand('Redo', true);");
-
- QVERIFY(m_page->isModified());
-
- QVERIFY(m_page->history()->canGoBack());
- QVERIFY(!m_page->history()->canGoForward());
- QCOMPARE(m_page->history()->count(), 2);
- QVERIFY(m_page->history()->backItem().isValid());
- QVERIFY(!m_page->history()->forwardItem().isValid());
-
- m_page->history()->back();
- QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
-
- QVERIFY(!m_page->history()->canGoBack());
- QVERIFY(m_page->history()->canGoForward());
-
- QVERIFY(!m_page->isModified());
-
- QCOMPARE(m_page->history()->currentItemIndex(), 0);
-
- m_page->history()->setMaximumItemCount(3);
- QCOMPARE(m_page->history()->maximumItemCount(), 3);
-
- QVariant variant("string test");
- m_page->history()->currentItem().setUserData(variant);
- QVERIFY(m_page->history()->currentItem().userData().toString() == "string test");
-
- m_page->setUrl(QUrl("data:text/html,<body>This is second page"));
- m_page->setUrl(QUrl("data:text/html,<body>This is third page"));
- QCOMPARE(m_page->history()->count(), 2);
- m_page->setUrl(QUrl("data:text/html,<body>This is fourth page"));
- QCOMPARE(m_page->history()->count(), 2);
- m_page->setUrl(QUrl("data:text/html,<body>This is fifth page"));
- QSignalSpy spy(m_page, &QWebEnginePage::saveFrameStateRequested);
- QVERIFY(spy.wait());
-#endif
-}
-
-// https://bugs.webkit.org/show_bug.cgi?id=51331
-void tst_QWebEnginePage::updatePositionDependentActionsCrash()
-{
-#if !defined(QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS)
- QSKIP("QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS");
-#else
- QWebEngineView view;
- view.setHtml("<p>test");
- QPoint pos(0, 0);
- view.page()->updatePositionDependentActions(pos);
- QMenu* contextMenu = 0;
- const QList<QObject *> children = view.children();
- for (QObject *child : children) {
- contextMenu = qobject_cast<QMenu*>(child);
- if (contextMenu)
- break;
- }
- QVERIFY(!contextMenu);
-#endif
-}
-
-// https://bugs.webkit.org/show_bug.cgi?id=20357
-void tst_QWebEnginePage::contextMenuCrash()
-{
-#if !defined(QWEBENGINEPAGE_SWALLOWCONTEXTMENUEVENT)
- QSKIP("QWEBENGINEPAGE_SWALLOWCONTEXTMENUEVENT");
-#else
- QWebEngineView view;
- view.setHtml("<p>test");
- QPoint pos(0, 0);
- QContextMenuEvent event(QContextMenuEvent::Mouse, pos);
- view.page()->swallowContextMenuEvent(&event);
- view.page()->updatePositionDependentActions(pos);
- QMenu* contextMenu = 0;
- const QList<QObject *> children = view.children();
- for (QObject *child : children) {
- contextMenu = qobject_cast<QMenu*>(child);
- if (contextMenu)
- break;
- }
- QVERIFY(contextMenu);
- delete contextMenu;
-#endif
-}
-
void tst_QWebEnginePage::multipleProfilesAndLocalStorage()
{
QDir dir(tmpDirPath());
@@ -895,204 +693,6 @@ public:
}
};
-void tst_QWebEnginePage::cursorMovements()
-{
-#if !defined(QWEBENGINEPAGE_SELECTEDTEXT)
- QSKIP("QWEBENGINEPAGE_SELECTEDTEXT");
-#else
- QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage);
- QString content("<html><body><p id=one>The quick brown fox</p><p id=two>jumps over the lazy dog</p><p>May the source<br/>be with you!</p></body></html>");
- page->setHtml(content);
-
- // this will select the first paragraph
- QString script = "var range = document.createRange(); " \
- "var node = document.getElementById(\"one\"); " \
- "range.selectNode(node); " \
- "getSelection().addRange(range);";
- evaluateJavaScriptSync(page.data(), script);
- QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
-
- QRegExp regExp(" style=\".*\"");
- regExp.setMinimal(true);
- QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>"));
-
- // these actions must exist
- QVERIFY(page->action(QWebEnginePage::MoveToNextChar) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToPreviousChar) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToNextWord) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToPreviousWord) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToNextLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToPreviousLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToStartOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToEndOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToStartOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToEndOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToStartOfDocument) != 0);
- QVERIFY(page->action(QWebEnginePage::MoveToEndOfDocument) != 0);
-
- // right now they are disabled because contentEditable is false
- QCOMPARE(page->action(QWebEnginePage::MoveToNextChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfDocument)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfDocument)->isEnabled(), false);
-
- // make it editable before navigating the cursor
- page->setContentEditable(true);
-
- // here the actions are enabled after contentEditable is true
- QCOMPARE(page->action(QWebEnginePage::MoveToNextChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToNextLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToPreviousLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToStartOfDocument)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::MoveToEndOfDocument)->isEnabled(), true);
-
- // cursor will be before the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be between 'j' and 'u' in the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 1);
-
- // cursor will be between 'u' and 'm' in the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 2);
-
- // cursor will be after the word "jump"
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 5);
-
- // cursor will be after the word "lazy"
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 19);
-
- // cursor will be between 'z' and 'y' in "lazy"
- page->triggerAction(QWebEnginePage::MoveToPreviousChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 18);
-
- // cursor will be between 'a' and 'z' in "lazy"
- page->triggerAction(QWebEnginePage::MoveToPreviousChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 17);
-
- // cursor will be before the word "lazy"
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 15);
-
- // cursor will be before the word "quick"
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 4);
-
- // cursor will be between 'p' and 's' in the word "jumps"
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 4);
-
- // cursor will be before the word "jumps"
- page->triggerAction(QWebEnginePage::MoveToStartOfLine);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be after the word "dog"
- page->triggerAction(QWebEnginePage::MoveToEndOfLine);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 23);
-
- // cursor will be between 'w' and 'n' in "brown"
- page->triggerAction(QWebEnginePage::MoveToStartOfLine);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 14);
-
- // cursor will be after the word "fox"
- page->triggerAction(QWebEnginePage::MoveToEndOfLine);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 19);
-
- // cursor will be before the word "The"
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be after the word "you!"
- page->triggerAction(QWebEnginePage::MoveToEndOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
-
- // cursor will be before the word "be"
- page->triggerAction(QWebEnginePage::MoveToStartOfBlock);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // cursor will be after the word "you!"
- page->triggerAction(QWebEnginePage::MoveToEndOfBlock);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
-
- // try to move before the document start
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- page->triggerAction(QWebEnginePage::MoveToPreviousChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- page->triggerAction(QWebEnginePage::MoveToPreviousWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // try to move past the document end
- page->triggerAction(QWebEnginePage::MoveToEndOfDocument);
- page->triggerAction(QWebEnginePage::MoveToNextChar);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
- page->triggerAction(QWebEnginePage::MoveToEndOfDocument);
- page->triggerAction(QWebEnginePage::MoveToNextWord);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 12);
-#endif
-}
-
void tst_QWebEnginePage::textSelection()
{
QWebEngineView view;
@@ -1107,35 +707,6 @@ void tst_QWebEnginePage::textSelection()
// these actions must exist
QVERIFY(page->action(QWebEnginePage::SelectAll) != 0);
-#if defined(QWEBENGINEPAGE_SELECTACTIONS)
- QVERIFY(page->action(QWebEnginePage::SelectNextChar) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectPreviousChar) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectNextWord) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectPreviousWord) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectNextLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectPreviousLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectStartOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectEndOfLine) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectStartOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectEndOfBlock) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectStartOfDocument) != 0);
- QVERIFY(page->action(QWebEnginePage::SelectEndOfDocument) != 0);
-
- // right now they are disabled because contentEditable is false and
- // there isn't an existing selection to modify
- QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), false);
-#endif
// ..but SelectAll is awalys enabled
QCOMPARE(page->action(QWebEnginePage::SelectAll)->isEnabled(), true);
@@ -1150,173 +721,10 @@ void tst_QWebEnginePage::textSelection()
"getSelection().addRange(range);";
evaluateJavaScriptSync(page, selectScript);
QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
-#if defined(QWEBENGINEPAGE_SELECTEDHTML)
- QRegExp regExp(" style=\".*\"");
- regExp.setMinimal(true);
- QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>"));
-#endif
// Make sure hasSelection returns true, since there is selected text now...
QCOMPARE(page->hasSelection(), true);
-
-#if defined(QWEBENGINEPAGE_SELECTACTIONS)
- // here the actions are enabled after a selection has been created
- QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true);
-
- // make it editable before navigating the cursor
- page->setContentEditable(true);
-
- // cursor will be before the word "The", this makes sure there is a charet
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // here the actions are enabled after contentEditable is true
- QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true);
-#endif
}
-void tst_QWebEnginePage::textEditing()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage);
- QString content("<html><body><p id=one>The quick brown fox</p>" \
- "<p id=two>jumps over the lazy dog</p>" \
- "<p>May the source<br/>be with you!</p></body></html>");
- page->setHtml(content);
-
- // these actions must exist
- QVERIFY(page->action(QWebEnginePage::Cut) != 0);
- QVERIFY(page->action(QWebEnginePage::Copy) != 0);
- QVERIFY(page->action(QWebEnginePage::Paste) != 0);
- QVERIFY(page->action(QWebEnginePage::DeleteStartOfWord) != 0);
- QVERIFY(page->action(QWebEnginePage::DeleteEndOfWord) != 0);
- QVERIFY(page->action(QWebEnginePage::SetTextDirectionDefault) != 0);
- QVERIFY(page->action(QWebEnginePage::SetTextDirectionLeftToRight) != 0);
- QVERIFY(page->action(QWebEnginePage::SetTextDirectionRightToLeft) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleBold) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleItalic) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleUnderline) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertParagraphSeparator) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertLineSeparator) != 0);
- QVERIFY(page->action(QWebEnginePage::PasteAndMatchStyle) != 0);
- QVERIFY(page->action(QWebEnginePage::RemoveFormat) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleStrikethrough) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleSubscript) != 0);
- QVERIFY(page->action(QWebEnginePage::ToggleSuperscript) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertUnorderedList) != 0);
- QVERIFY(page->action(QWebEnginePage::InsertOrderedList) != 0);
- QVERIFY(page->action(QWebEnginePage::Indent) != 0);
- QVERIFY(page->action(QWebEnginePage::Outdent) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignCenter) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignJustified) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignLeft) != 0);
- QVERIFY(page->action(QWebEnginePage::AlignRight) != 0);
-
- // right now they are disabled because contentEditable is false
- QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::Paste)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::DeleteStartOfWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::DeleteEndOfWord)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionDefault)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionLeftToRight)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionRightToLeft)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleBold)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleItalic)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleUnderline)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertParagraphSeparator)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertLineSeparator)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleStrikethrough)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleSubscript)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::ToggleSuperscript)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertUnorderedList)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::InsertOrderedList)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::Indent)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::Outdent)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignCenter)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignJustified)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignLeft)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::AlignRight)->isEnabled(), false);
-
- // Select everything
- page->triggerAction(QWebEnginePage::SelectAll);
-
- // make sure it is enabled since there is a selection
- QCOMPARE(page->action(QWebEnginePage::Copy)->isEnabled(), true);
-
- // make it editable before navigating the cursor
- page->setContentEditable(true);
-
- // clear the selection
- page->triggerAction(QWebEnginePage::MoveToStartOfDocument);
- QVERIFY(page->isSelectionCollapsed());
- QCOMPARE(page->selectionStartOffset(), 0);
-
- // make sure it is disabled since there isn't a selection
- QCOMPARE(page->action(QWebEnginePage::Copy)->isEnabled(), false);
-
- // here the actions are enabled after contentEditable is true
- QCOMPARE(page->action(QWebEnginePage::Paste)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::DeleteStartOfWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::DeleteEndOfWord)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionDefault)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionLeftToRight)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::SetTextDirectionRightToLeft)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleBold)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleItalic)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleUnderline)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertParagraphSeparator)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertLineSeparator)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleStrikethrough)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleSubscript)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::ToggleSuperscript)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertUnorderedList)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::InsertOrderedList)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::Indent)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::Outdent)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignCenter)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignJustified)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignLeft)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::AlignRight)->isEnabled(), true);
-
- // make sure these are disabled since there isn't a selection
- QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), false);
- QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), false);
-
- // make sure everything is selected
- page->triggerAction(QWebEnginePage::SelectAll);
-
- // this is only true if there is an editable selection
- QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), true);
- QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), true);
-#endif
-}
void tst_QWebEnginePage::backActionUpdate()
{
@@ -1337,243 +745,39 @@ void tst_QWebEnginePage::backActionUpdate()
QVERIFY(action->isEnabled());
}
-#if defined(QWEBENGINEPAGE_SETTINGS)
-static inline bool testFlag(QWebEnginePage& webPage, QWebEngineSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue)
+void tst_QWebEnginePage::localStorageVisibility()
{
- webPage.settings()->setAttribute(settingAttribute, settingValue);
- return evaluateJavaScriptSync(&webPage, QString("(window.%1 != undefined)").arg(jsObjectName)).toBool();
-}
-#endif
-
-void tst_QWebEnginePage::testOptionalJSObjects()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINSETTINGS");
-#else
- // Once a feature is enabled and the JS object is accessed turning off the setting will not turn off
- // the visibility of the JS object any more. For this reason this test uses two QWebEnginePage instances.
- // Part of the test is to make sure that the QWebEnginePage instances do not interfere with each other so turning on
- // a feature for one instance will not turn it on for another.
-
- QWebEnginePage webPage1;
- QWebEnginePage webPage2;
-
- webPage1.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
- webPage2.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
-
- QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue);
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", true), true);
- QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue);
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), true);
-
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::LocalStorageEnabled, "localStorage", true), true);
- QCOMPARE(testFlag(webPage1, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), false);
- QCOMPARE(testFlag(webPage2, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), true);
-#endif
-}
-
-#if defined(QWEBENGINEPAGE_SETTINGS)
-static inline bool checkLocalStorageVisibility(QWebEnginePage& webPage, bool localStorageEnabled)
-{
- webPage.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, localStorageEnabled);
- return evaluateJavaScriptSync(&webPage, QString("(window.localStorage != undefined)")).toBool();
-}
-#endif
-
-void tst_QWebEnginePage::testLocalStorageVisibility()
-{
-#if !defined(QWEBENGINEPAGE_SETTINGS)
- QSKIP("QWEBENGINEPAGE_SETTINGS");
-#else
- // Local storage's visibility depends on its security origin, which depends on base url.
- // Initially, it will test it with base urls that get a globally unique origin, which may not
- // be able to use local storage even if the feature is enabled. Then later the same test is
- // done but with urls that would get a valid origin, so local storage could be used.
- // Before every test case it checks if local storage is not already visible.
-
- QWebEnginePage webPage;
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl());
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("invalid"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("://misparsed.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("about:blank"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("data:text/html,test"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), false);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("file:///"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("https://www.example.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("ftp://files.example.com"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-
- webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("file:///path/to/index.html"));
-
- QCOMPARE(checkLocalStorageVisibility(webPage, false), false);
- QCOMPARE(checkLocalStorageVisibility(webPage, true), true);
-#endif
-}
-
-void tst_QWebEnginePage::testEnablePersistentStorage()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- QWebEnginePage webPage;
-
- // By default all persistent options should be disabled
- QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::LocalStorageEnabled), false);
- QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled), false);
- QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled), false);
- QVERIFY(webPage.settings()->iconDatabasePath().isEmpty());
-
- QWebEngineSettings::enablePersistentStorage();
-
-
- QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::LocalStorageEnabled), true);
- QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled), true);
- QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled), true);
-
- QTRY_VERIFY(!webPage.settings()->offlineStoragePath().isEmpty());
- QTRY_VERIFY(!webPage.settings()->offlineWebApplicationCachePath().isEmpty());
- QTRY_VERIFY(!webPage.settings()->iconDatabasePath().isEmpty());
-#endif
-}
-
-
-#if defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION)
-class ErrorPage : public QWebEnginePage
-{
-public:
-
- ErrorPage(QWidget* parent = 0): QWebEnginePage(parent)
- {
- }
-
- virtual bool supportsExtension(Extension extension) const
- {
- return extension == ErrorPageExtension;
- }
-
- virtual bool extension(Extension, const ExtensionOption* option, ExtensionReturn* output)
- {
- ErrorPageExtensionReturn* errorPage = static_cast<ErrorPageExtensionReturn*>(output);
-
- errorPage->contentType = "text/html";
- errorPage->content = "error";
- return true;
- }
-};
-#endif
-
-void tst_QWebEnginePage::errorPageExtension()
-{
-#if !defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION)
- QSKIP("QWEBENGINEPAGE_ERRORPAGEEXTENSION");
-#else
- ErrorPage page;
- m_view->setPage(&page);
-
- QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool)));
-
- m_view->setUrl(QUrl("data:text/html,foo"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
-
- page.setUrl(QUrl("http://non.existent/url"));
- QTRY_COMPARE(spyLoadFinished.count(), 2);
- QCOMPARE(toPlainTextSync(&page), QString("error"));
- QCOMPARE(page.history()->count(), 2);
- QCOMPARE(page.history()->currentItem().url(), QUrl("http://non.existent/url"));
- QCOMPARE(page.history()->canGoBack(), true);
- QCOMPARE(page.history()->canGoForward(), false);
-
- page.triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(page.history()->canGoBack(), false);
- QTRY_COMPARE(page.history()->canGoForward(), true);
-
- page.triggerAction(QWebEnginePage::Forward);
- QTRY_COMPARE(page.history()->canGoBack(), true);
- QTRY_COMPARE(page.history()->canGoForward(), false);
-
- page.triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(page.history()->canGoBack(), false);
- QTRY_COMPARE(page.history()->canGoForward(), true);
- QTRY_COMPARE(page.history()->currentItem().url(), QUrl("data:text/html,foo"));
-
- m_view->setPage(0);
-#endif
-}
-
-void tst_QWebEnginePage::errorPageExtensionLoadFinished()
-{
-#if !defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION)
- QSKIP("QWEBENGINEPAGE_ERRORPAGEEXTENSION");
-#else
- ErrorPage page;
- m_view->setPage(&page);
-
- QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool)));
- QSignalSpy spyFrameLoadFinished(m_view->page(), SIGNAL(loadFinished(bool)));
-
- m_view->setUrl(QUrl("data:text/html,foo"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
- QTRY_COMPARE(spyFrameLoadFinished.count(), 1);
-
- const bool loadSucceded = spyLoadFinished.at(0).at(0).toBool();
- QVERIFY(loadSucceded);
- const bool frameLoadSucceded = spyFrameLoadFinished.at(0).at(0).toBool();
- QVERIFY(frameLoadSucceded);
-
- m_view->page()->setUrl(QUrl("http://non.existent/url"));
- QTRY_COMPARE(spyLoadFinished.count(), 2);
- QTRY_COMPARE(spyFrameLoadFinished.count(), 2);
-
- const bool nonExistantLoadSucceded = spyLoadFinished.at(1).at(0).toBool();
- QVERIFY(nonExistantLoadSucceded);
- const bool nonExistantFrameLoadSucceded = spyFrameLoadFinished.at(1).at(0).toBool();
- QVERIFY(nonExistantFrameLoadSucceded);
-
- m_view->setPage(0);
-#endif
+ QWebEngineProfile profile;
+ QWebEnginePage webPage1(&profile);
+ QWebEnginePage webPage2(&profile);
+
+ webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
+ webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
+
+ QSignalSpy loadSpy1(&webPage1, &QWebEnginePage::loadFinished);
+ QSignalSpy loadSpy2(&webPage2, &QWebEnginePage::loadFinished);
+ webPage1.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
+ webPage2.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
+ QTRY_COMPARE(loadSpy1.count(), 1);
+ QTRY_COMPARE(loadSpy2.count(), 1);
+
+ // The attribute determines the visibility of the window.localStorage object.
+ QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+ QVERIFY(!evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
+
+ // Switching the feature off does not actively remove the object from webPage1.
+ webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
+ webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
+ QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+ QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
+
+ // The object disappears only after reloading.
+ webPage1.triggerAction(QWebEnginePage::Reload);
+ webPage2.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy1.count(), 2);
+ QTRY_COMPARE(loadSpy2.count(), 2);
+ QVERIFY(!evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+ QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
}
void tst_QWebEnginePage::userAgentNewlineStripping()
@@ -1598,70 +802,9 @@ void tst_QWebEnginePage::crashTests_LazyInitializationOfMainFrame()
webPage.selectedText();
}
{
-#if defined(QWEBENGINEPAGE_SELECTEDHTML)
- QWebEnginePage webPage;
- webPage.selectedHtml();
-#endif
- }
- {
QWebEnginePage webPage;
webPage.triggerAction(QWebEnginePage::Back, true);
}
- {
-#if defined(QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS)
- QWebEnginePage webPage;
- QPoint pos(10,10);
- webPage.updatePositionDependentActions(pos);
-#endif
- }
-}
-
-#if defined(QWEBENGINEPAGE_RENDER)
-static void takeScreenshot(QWebEnginePage* page)
-{
- page->setViewportSize(page->contentsSize());
- QImage image(page->viewportSize(), QImage::Format_ARGB32);
- QPainter painter(&image);
- page->render(&painter);
- painter.end();
-}
-#endif
-
-void tst_QWebEnginePage::screenshot_data()
-{
- QTest::addColumn<QString>("html");
- QTest::newRow("WithoutPlugin") << "<html><body id='b'>text</body></html>";
- QTest::newRow("WindowedPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf'></embed></body></html>");
- QTest::newRow("WindowlessPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf' wmode='transparent'></embed></body></html>");
-}
-
-void tst_QWebEnginePage::screenshot()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- if (!QDir(TESTS_SOURCE_DIR).exists())
- W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);
-
- QDir::setCurrent(TESTS_SOURCE_DIR);
-
- QFETCH(QString, html);
- QWebEnginePage page;
- page.settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
- page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
- QVERIFY(spyFinished.wait(2000));
-
- // take screenshot without a view
- takeScreenshot(&page);
-
- QWebEngineView view;
- view.setPage(&page);
-
- // take screenshot when attached to a view
- takeScreenshot(&page);
-
- QDir::setCurrent(QApplication::applicationDirPath());
-#endif
}
#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
@@ -1760,37 +903,6 @@ void tst_QWebEnginePage::testJSPrompt()
QVERIFY(res);
}
-void tst_QWebEnginePage::testStopScheduledPageRefresh()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- // Without QWebEnginePage::StopScheduledPageRefresh
- QWebEnginePage page1;
- page1.setNetworkAccessManager(new TestNetworkManager(&page1));
- page1.setHtml("<html><head>"
- "<meta http-equiv=\"refresh\"content=\"0;URL=qrc:///resources/index.html\">"
- "</head><body><h1>Page redirects immediately...</h1>"
- "</body></html>");
- QSignalSpy spyFinished(&page1, &QWebEnginePage::loadFinished);
- QVERIFY(spyFinished.wait();
- QTest::qWait(500);
- QCOMPARE(page1.url(), QUrl(QLatin1String("qrc:///resources/index.html")));
-
- // With QWebEnginePage::StopScheduledPageRefresh
- QWebEnginePage page2;
- page2.setNetworkAccessManager(new TestNetworkManager(&page2));
- page2.setHtml("<html><head>"
- "<meta http-equiv=\"refresh\"content=\"1;URL=qrc:///resources/index.html\">"
- "</head><body><h1>Page redirect test with 1 sec timeout...</h1>"
- "</body></html>");
- page2.triggerAction(QWebEnginePage::StopScheduledPageRefresh);
- QTest::qWait(1500);
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118673", Continue);
- QCOMPARE(page2.url().toString(), QLatin1String("about:blank"));
-#endif
-}
-
void tst_QWebEnginePage::findText()
{
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
@@ -1890,95 +1002,6 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
QVERIFY(spy5.wasCalled());
}
-#if defined(QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES)
-static QString getMimeTypeForExtension(const QString &ext)
-{
- QMimeType mimeType = QMimeDatabase().mimeTypeForFile(QStringLiteral("filename.") + ext.toLower(), QMimeDatabase::MatchExtension);
- if (mimeType.isValid() && !mimeType.isDefault())
- return mimeType.name();
-
- return QString();
-}
-#endif
-
-void tst_QWebEnginePage::supportedContentType()
-{
-#if !defined(QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES)
- QSKIP("QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES");
-#else
- QStringList contentTypes;
-
- // Add supported non image types...
- contentTypes << "text/html" << "text/xml" << "text/xsl" << "text/plain" << "text/"
- << "application/xml" << "application/xhtml+xml" << "application/vnd.wap.xhtml+xml"
- << "application/rss+xml" << "application/atom+xml" << "application/json";
-
-#if ENABLE_MHTML
- contentTypes << "application/x-mimearchive";
-#endif
-
- // Add supported image types...
- const QList<QByteArray> supportedImageFormats = QImageWriter::supportedImageFormats();
- for (const QByteArray &imageType : supportedImageFormats) {
- const QString mimeType = getMimeTypeForExtension(imageType);
- if (!mimeType.isEmpty())
- contentTypes << mimeType;
- }
-
- // Get the mime types supported by webengine...
- const QStringList supportedContentTypes = m_page->supportedContentTypes();
-
- for (const QString &mimeType : qAsConst(contentTypes))
- QVERIFY2(supportedContentTypes.contains(mimeType), QString("'%1' is not a supported content type!").arg(mimeType).toLatin1());
-
- for (const QString &mimeType : qAsConst(contentTypes))
- QVERIFY2(m_page->supportsContentType(mimeType), QString("Cannot handle content types '%1'!").arg(mimeType).toLatin1());
-#endif
-}
-
-void tst_QWebEnginePage::thirdPartyCookiePolicy()
-{
-#if !defined(DUMPRENDERTREESUPPORTQT)
- QSKIP("DUMPRENDERTREESUPPORTQT");
-#else
- QWebEngineSettings::globalSettings()->setThirdPartyCookiePolicy(QWebEngineSettings::AlwaysBlockThirdPartyCookies);
- m_page->networkAccessManager()->setCookieJar(new QNetworkCookieJar());
- QVERIFY(m_page->networkAccessManager()->cookieJar());
-
- // These are all first-party cookies, so should pass.
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.com"), QUrl("http://example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.com"), QUrl("http://doc.example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://aaa.www.example.com"), QUrl("http://doc.example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.com"), QUrl("http://www.example.com")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.co.uk"), QUrl("http://example.co.uk")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.co.uk"), QUrl("http://doc.example.co.uk")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://aaa.www.example.co.uk"), QUrl("http://doc.example.co.uk")));
- QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.co.uk"), QUrl("http://www.example.co.uk")));
-
- // These are all third-party cookies, so should fail.
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.com"), QUrl("http://slashdot.org")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.com"), QUrl("http://anotherexample.com")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://anotherexample.com"), QUrl("http://example.com")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://www.example.co.uk"), QUrl("http://slashdot.co.uk")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://example.co.uk"), QUrl("http://anotherexample.co.uk")));
- QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(),
- QUrl("http://anotherexample.co.uk"), QUrl("http://example.co.uk")));
-#endif
-}
-
static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
{
const auto tlws = QGuiApplication::topLevelWindows();
@@ -1992,9 +1015,8 @@ static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
{
- QScreen *screen = QGuiApplication::primaryScreen();
QWebEngineView view;
- view.move(screen->availableGeometry().topLeft());
+ view.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
view.resize(640, 480);
view.show();
@@ -2010,18 +1032,29 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
QWindow *popup = nullptr;
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
+ QTRY_VERIFY(!popup->position().isNull());
QPoint popupPos = popup->position();
// Close the popup by clicking somewhere into the page.
QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
+ auto jsViewPosition = [&view]() {
+ QLatin1String script("(function() { return [window.screenX, window.screenY]; })()");
+ QVariantList posList = evaluateJavaScriptSync(view.page(), script).toList();
+ return QPoint(posList.at(0).toInt(), posList.at(1).toInt());
+ };
+
// Move the top-level QWebEngineView a little and check the popup's position.
const QPoint offset(12, 13);
- view.move(screen->availableGeometry().topLeft() + offset);
+ view.move(view.pos() + offset);
+ QTRY_COMPARE(jsViewPosition(), view.pos());
QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
elementCenter(view.page(), "foo"));
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
+ QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + offset, popup->position());
}
@@ -2031,7 +1064,6 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
mainWidget.setLayout(new QHBoxLayout);
QWidget spacer;
- spacer.setMinimumWidth(50);
mainWidget.layout()->addWidget(&spacer);
QWebEngineView view;
@@ -2054,6 +1086,8 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
QWindow *popup = nullptr;
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
+ QTRY_VERIFY(!popup->position().isNull());
QPoint popupPos = popup->position();
// Close the popup by clicking somewhere into the page.
@@ -2061,11 +1095,22 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
view.mapTo(view.window(), QPoint(1, 1)));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
+ int originalViewWidth = view.size().width();
+ auto jsViewWidth = [&view]() {
+ QLatin1String script("(function() { return window.innerWidth; })()");
+ int viewWidth = evaluateJavaScriptSync(view.page(), script).toInt();
+ return viewWidth;
+ };
+
// Resize the "spacer" widget, and implicitly change the global position of the QWebEngineView.
- spacer.setMinimumWidth(100);
+ const int offset = 50;
+ spacer.setMinimumWidth(spacer.size().width() + offset);
+ QTRY_COMPARE(jsViewWidth(), originalViewWidth - offset);
+
QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
view.mapTo(view.window(), elementCenter(view.page(), "foo")));
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + QPoint(50, 0), popup->position());
}
@@ -2084,66 +1129,6 @@ void tst_QWebEnginePage::macCopyUnicodeToClipboard()
}
#endif
-void tst_QWebEnginePage::contextMenuCopy()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
-
- view.setHtml("<a href=\"http://www.google.com\">You cant miss this</a>");
-
- view.page()->triggerAction(QWebEnginePage::SelectAll);
- QVERIFY(!view.page()->selectedText().isEmpty());
-
- QWebEngineElement link = view.page()->mainFrame()->findFirstElement("a");
- QPoint pos(link.geometry().center());
- QContextMenuEvent event(QContextMenuEvent::Mouse, pos);
- view.page()->swallowContextMenuEvent(&event);
- view.page()->updatePositionDependentActions(pos);
-
- QList<QMenu*> contextMenus = view.findChildren<QMenu*>();
- QVERIFY(!contextMenus.isEmpty());
- QMenu* contextMenu = contextMenus.first();
- QVERIFY(contextMenu);
-
- QList<QAction *> list = contextMenu->actions();
- int index = list.indexOf(view.page()->action(QWebEnginePage::Copy));
- QVERIFY(index != -1);
-#endif
-}
-
-// https://bugs.webkit.org/show_bug.cgi?id=62139
-void tst_QWebEnginePage::contextMenuPopulatedOnce()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
-
- view.setHtml("<input type=\"text\">");
-
- QWebEngineElement link = view.page()->mainFrame()->findFirstElement("input");
- QPoint pos(link.geometry().center());
- QContextMenuEvent event(QContextMenuEvent::Mouse, pos);
- view.page()->swallowContextMenuEvent(&event);
- view.page()->updatePositionDependentActions(pos);
-
- QList<QMenu*> contextMenus = view.findChildren<QMenu*>();
- QVERIFY(!contextMenus.isEmpty());
- QMenu* contextMenu = contextMenus.first();
- QVERIFY(contextMenu);
-
- QList<QAction *> list = contextMenu->actions();
- QStringList entries;
- while (!list.isEmpty()) {
- QString entry = list.takeFirst()->text();
- QVERIFY(!entries.contains(entry));
- entries << entry;
- }
-#endif
-}
-
void tst_QWebEnginePage::deleteQWebEngineViewTwice()
{
for (int i = 0; i < 2; ++i) {
@@ -2157,62 +1142,6 @@ void tst_QWebEnginePage::deleteQWebEngineViewTwice()
}
}
-#if defined(QWEBENGINEPAGE_RENDER)
-class RepaintRequestedRenderer : public QObject {
- Q_OBJECT
-public:
- RepaintRequestedRenderer(QWebEnginePage* page, QPainter* painter)
- : m_page(page)
- , m_painter(painter)
- , m_recursionCount(0)
- {
- connect(m_page, SIGNAL(repaintRequested(QRect)), this, SLOT(onRepaintRequested(QRect)));
- }
-
-Q_SIGNALS:
- void finished();
-
-private Q_SLOTS:
- void onRepaintRequested(const QRect& rect)
- {
- QCOMPARE(m_recursionCount, 0);
-
- m_recursionCount++;
- m_page->render(m_painter, rect);
- m_recursionCount--;
-
- QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
- }
-
-private:
- QWebEnginePage* m_page;
- QPainter* m_painter;
- int m_recursionCount;
-};
-#endif
-
-void tst_QWebEnginePage::renderOnRepaintRequestedShouldNotRecurse()
-{
-#if !defined(QWEBENGINEPAGE_RENDER)
- QSKIP("QWEBENGINEPAGE_RENDER");
-#else
- QSize viewportSize(720, 576);
- QWebEnginePage page;
-
- QImage image(viewportSize, QImage::Format_ARGB32);
- QPainter painter(&image);
-
- page.setPreferredContentsSize(viewportSize);
- page.setViewportSize(viewportSize);
- RepaintRequestedRenderer r(&page, &painter);
-
- page.setHtml("zalan loves trunk", QUrl());
-
- QSignalSpy spyFinished(&r, &RepaintRequestedRenderer::finished);
- QVERIFY(spyFinished.wait());
-#endif
-}
-
class SpyForLoadSignalsOrder : public QStateMachine {
Q_OBJECT
public:
@@ -2271,24 +1200,6 @@ void tst_QWebEnginePage::loadSignalsOrder()
QTRY_VERIFY(loadSpy.isFinished());
}
-void tst_QWebEnginePage::undoActionHaveCustomText()
-{
-#if !defined(QWEBENGINEPAGE_UNDOACTION)
- QSKIP("QWEBENGINEPAGE_UNDOACTION");
-#else
- m_page->setHtml("<div id=test contenteditable></div>");
- evaluateJavaScriptSync(m_page, "document.getElementById('test').focus()");
-
- evaluateJavaScriptSync(m_page, "document.execCommand('insertText', true, 'Test');");
- QString typingActionText = m_page->action(QWebEnginePage::Undo)->text();
-
- evaluateJavaScriptSync(m_page, "document.execCommand('indent', true);");
- QString alignActionText = m_page->action(QWebEnginePage::Undo)->text();
-
- QVERIFY(typingActionText != alignActionText);
-#endif
-}
-
void tst_QWebEnginePage::renderWidgetHostViewNotShowTopLevel()
{
QWebEnginePage page;
@@ -2607,68 +1518,6 @@ void tst_QWebEnginePage::openWindowDefaultSize()
QCOMPARE(requestedGeometry.height(), 100);
}
-void tst_QWebEnginePage::cssMediaTypeGlobalSetting()
-{
-#if !defined(QWEBENGINESETTINGS_SETCSSMEDIATYPE)
- QSKIP("QWEBENGINESETTINGS_SETCSSMEDIATYPE");
-#else
- QString testHtml("<style>@media tv {body{background-color:red;}}@media handheld {body{background-color:green;}}@media screen {body{background-color:blue;}}</style>");
- QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
-
- QWebEngineSettings::globalSettings()->setCSSMediaType("tv");
- // Clear page specific setting to read from global setting
- m_view->page()->settings()->setCSSMediaType(QString());
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 1);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('tv').matches == true").toBool());
- QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "tv");
-
- QWebEngineSettings::globalSettings()->setCSSMediaType("handheld");
- // Clear page specific setting to read from global setting
- m_view->page()->settings()->setCSSMediaType(QString());
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 2);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('handheld').matches == true").toBool());
- QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "handheld");
-
- QWebEngineSettings::globalSettings()->setCSSMediaType("screen");
- // Clear page specific setting to read from global setting
- m_view->page()->settings()->setCSSMediaType(QString());
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 3);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('screen').matches == true").toBool());
- QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "screen");
-#endif
-}
-
-void tst_QWebEnginePage::cssMediaTypePageSetting()
-{
-#if !defined(QWEBENGINESETTINGS_SETCSSMEDIATYPE)
- QSKIP("QWEBENGINESETTINGS_SETCSSMEDIATYPE");
-#else
- QString testHtml("<style>@media tv {body{background-color:red;}}@media handheld {body{background-color:green;}}@media screen {body{background-color:blue;}}</style>");
- QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
-
- m_view->page()->settings()->setCSSMediaType("tv");
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 1);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('tv').matches == true").toBool());
- QVERIFY(m_view->page()->settings()->cssMediaType() == "tv");
-
- m_view->page()->settings()->setCSSMediaType("handheld");
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 2);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('handheld').matches == true").toBool());
- QVERIFY(m_view->page()->settings()->cssMediaType() == "handheld");
-
- m_view->page()->settings()->setCSSMediaType("screen");
- m_view->setHtml(testHtml);
- QTRY_COMPARE(loadSpy.count(), 3);
- QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('screen').matches == true").toBool());
- QVERIFY(m_view->page()->settings()->cssMediaType() == "screen");
-#endif
-}
-
class JavaScriptCallbackBase
{
public:
@@ -2824,6 +1673,28 @@ void tst_QWebEnginePage::runJavaScriptDisabled()
QVariant(2));
}
+// Based on https://bugreports.qt.io/browse/QTBUG-73876
+void tst_QWebEnginePage::runJavaScriptFromSlot()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ page.setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine' size='50' />"
+ "</body></html>");
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+
+ QVariant result(-1);
+ connect(&page, &QWebEnginePage::selectionChanged, [&]() {
+ result = evaluateJavaScriptSync(&page, QStringLiteral("2+2"));
+ });
+ evaluateJavaScriptSync(&page, QStringLiteral("const input = document.getElementById('input1');"
+ "input.focus();"
+ "input.select();"));
+ QTRY_COMPARE(result, QVariant(4));
+}
+
void tst_QWebEnginePage::fullScreenRequested()
{
JavaScriptCallbackWatcher watcher;
@@ -3250,55 +2121,6 @@ void tst_QWebEnginePage::setHtmlWithJSAlert()
QCOMPARE(toHtmlSync(&page), html);
}
-void tst_QWebEnginePage::inputFieldFocus()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEngineView view;
- view.setHtml("<html><body><input type=\"text\"></input></body></html>");
- view.resize(400, 100);
- view.show();
- QTest::qWaitForWindowExposed(&view);
- view.activateWindow();
- view.setFocus();
- QTRY_VERIFY(view.hasFocus());
-
- // double the flashing time, should at least blink once already
- int delay = qApp->cursorFlashTime() * 2;
-
- // focus the lineedit and check if it blinks
- bool autoSipEnabled = qApp->autoSipEnabled();
- qApp->setAutoSipEnabled(false);
- const QWebEngineElement inputElement = view.page()->documentElement().findFirst(QLatin1String("input[type=text]"));
- QTest::mouseClick(&view, Qt::LeftButton, 0, inputElement.geometry().center());
- m_inputFieldsTestView = &view;
- view.installEventFilter( this );
- QTest::qWait(delay);
- QVERIFY2(m_inputFieldTestPaintCount >= 3,
- "The input field should have a blinking caret");
- qApp->setAutoSipEnabled(autoSipEnabled);
-#endif
-}
-
-void tst_QWebEnginePage::hitTestContent()
-{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QString html("<html><body><p>A paragraph</p><br/><br/><br/><a href=\"about:blank\" target=\"_foo\" id=\"link\">link text</a></body></html>");
-
- QWebEnginePage page;
- page.setHtml(html);
- page.setViewportSize(QSize(200, 0)); //no height so link is not visible
- const QWebEngineElement linkElement = page.documentElement().findFirst(QLatin1String("a#link"));
- QWebEngineHitTestResult result = page.hitTestContent(linkElement.geometry().center());
- QCOMPARE(result.linkText(), QString("link text"));
- QWebEngineElement link = result.linkElement();
- QCOMPARE(link.attribute("target"), QString("_foo"));
-#endif
-}
-
void tst_QWebEnginePage::baseUrl_data()
{
QTest::addColumn<QString>("html");
@@ -3379,32 +2201,6 @@ void tst_QWebEnginePage::scrollbarsOff()
QVERIFY(evaluateJavaScriptSync(view.page(), "innerWidth == document.documentElement.offsetWidth").toBool());
}
-void tst_QWebEnginePage::horizontalScrollAfterBack()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- QWebEngineView view;
- QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
-
- view.page()->settings()->setMaximumPagesInCache(2);
- view.page()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
- view.page()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded);
-
- view.load(QUrl("qrc:/resources/testiframe2.html"));
- view.resize(200, 200);
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
-
- view.load(QUrl("qrc:/resources/testiframe.html"));
- QTRY_COMPARE(loadSpy.count(), 2);
-
- view.page()->triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(loadSpy.count(), 3);
- QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height());
-#endif
-}
-
class WebView : public QWebEngineView
{
Q_OBJECT
@@ -3499,35 +2295,6 @@ private:
QNetworkRequest::CacheLoadControl m_lastCacheLoad;
};
-void tst_QWebEnginePage::setCacheLoadControlAttribute()
-{
-#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER)
- QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER");
-#else
- QWebEnginePage page;
- CacheNetworkAccessManager* manager = new CacheNetworkAccessManager(&page);
- page.setNetworkAccessManager(manager);
-
- QNetworkRequest request(QUrl("http://abcdef.abcdef/"));
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysCache);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferCache);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysNetwork);
-
- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
- page.load(request);
- QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferNetwork);
-#endif
-}
-
void tst_QWebEnginePage::setUrlWithPendingLoads()
{
QWebEnginePage page;
@@ -4491,6 +3258,99 @@ void tst_QWebEnginePage::dynamicFrame()
QCOMPARE(toPlainTextSync(&page).trimmed(), QStringLiteral("foo"));
}
+struct NotificationPage : ConsolePage {
+ Q_OBJECT
+ const QWebEnginePage::PermissionPolicy policy;
+
+public:
+ NotificationPage(QWebEnginePage::PermissionPolicy ppolicy) : policy(ppolicy) {
+ connect(this, &QWebEnginePage::loadFinished, [load = spyLoad.ref()] (bool result) mutable { load(result); });
+
+ connect(this, &QWebEnginePage::featurePermissionRequested,
+ [this] (const QUrl &origin, QWebEnginePage::Feature feature) {
+ if (feature != QWebEnginePage::Notifications)
+ return;
+ if (spyRequest.wasCalled())
+ QFAIL("request executed twise!");
+ setFeaturePermission(origin, feature, policy);
+ spyRequest.ref()(origin);
+ });
+
+ load(QStringLiteral("qrc:///shared/notification.html"));
+ }
+
+ CallbackSpy<bool> spyLoad;
+ CallbackSpy<QUrl> spyRequest;
+
+ QString getPermission() { return evaluateJavaScriptSync(this, "getPermission()").toString(); }
+ void requestPermission() { runJavaScript("requestPermission()"); }
+ void resetPermission() { runJavaScript("resetPermission()"); }
+ void sendNotification(const QString &title, const QString &body) {
+ runJavaScript("sendNotification('" + title + "', '" + body + "')");
+ }
+};
+
+void tst_QWebEnginePage::notificationRequest_data()
+{
+ QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
+ QTest::addColumn<QString>("permission");
+ QTest::newRow("deny") << QWebEnginePage::PermissionDeniedByUser << "denied";
+ QTest::newRow("grant") << QWebEnginePage::PermissionGrantedByUser << "granted";
+}
+
+void tst_QWebEnginePage::notificationRequest()
+{
+ QFETCH(QWebEnginePage::PermissionPolicy, policy);
+ QFETCH(QString, permission);
+
+ NotificationPage page(policy);
+ QVERIFY(page.spyLoad.waitForResult());
+
+ page.resetPermission();
+ QCOMPARE(page.getPermission(), "default");
+
+ page.requestPermission();
+ page.spyRequest.waitForResult();
+ QVERIFY(page.spyRequest.wasCalled());
+
+ QCOMPARE(page.getPermission(), permission);
+}
+
+void tst_QWebEnginePage::sendNotification()
+{
+ NotificationPage page(QWebEnginePage::PermissionGrantedByUser);
+ QVERIFY(page.spyLoad.waitForResult());
+
+ page.resetPermission();
+ page.requestPermission();
+ auto origin = page.spyRequest.waitForResult();
+ QVERIFY(page.spyRequest.wasCalled());
+ QCOMPARE(page.getPermission(), "granted");
+
+ CallbackSpy<QWebEngineNotification> presenter;
+ page.profile()->setNotificationPresenter([callback = presenter.ref()] (const QWebEngineNotification &notification) mutable { callback(notification); });
+
+ QString title("Title"), message("Message");
+ page.sendNotification(title, message);
+
+ auto notification = presenter.waitForResult();
+ QVERIFY(presenter.wasCalled());
+ QVERIFY(notification.isValid());
+ QCOMPARE(notification.title(), title);
+ QCOMPARE(notification.message(), message);
+ QCOMPARE(notification.origin(), origin);
+ QCOMPARE(notification.direction(), Qt::RightToLeft);
+ QCOMPARE(notification.language(), "de");
+ QCOMPARE(notification.tag(), "tst");
+
+ notification.show();
+ QTRY_VERIFY2(page.messages.contains("onshow"), page.messages.join("\n").toLatin1().constData());
+ notification.click();
+ QTRY_VERIFY2(page.messages.contains("onclick"), page.messages.join("\n").toLatin1().constData());
+ notification.close();
+ QTRY_VERIFY2(page.messages.contains("onclose"), page.messages.join("\n").toLatin1().constData());
+}
+
static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index f2bf8c6ff..cf32486e7 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -24,4 +24,7 @@
<file>resources/bar.txt</file>
<file>resources/path with spaces.txt</file>
</qresource>
+<qresource prefix='/shared'>
+ <file alias='notification.html'>../../shared/data/notification.html</file>
+</qresource>
</RCC>
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 98b4fa6a8..8bd68bb97 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -29,6 +29,7 @@
#include "../util.h"
#include <QtCore/qbuffer.h>
#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
#include <QtWebEngineCore/qwebengineurlrequestjob.h>
#include <QtWebEngineCore/qwebenginecookiestore.h>
#include <QtWebEngineCore/qwebengineurlschemehandler.h>
@@ -53,12 +54,13 @@ private Q_SLOTS:
void urlSchemeHandlerFailRequest();
void urlSchemeHandlerFailOnRead();
void urlSchemeHandlerStreaming();
+ void urlSchemeHandlerRequestHeaders();
void customUserAgent();
void httpAcceptLanguage();
void downloadItem();
void changePersistentPath();
void initiator();
- void qtbug_72299(); // this should be the last test
+ void qtbug_71895(); // this should be the last test
};
void tst_QWebEngineProfile::init()
@@ -446,6 +448,65 @@ void tst_QWebEngineProfile::urlSchemeHandlerStreaming()
QCOMPARE(toPlainTextSync(view.page()), QString::fromLatin1(result));
}
+class ExtraHeaderInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ ExtraHeaderInterceptor() { }
+
+ void setExtraHeader(const QByteArray &key, const QByteArray &value)
+ {
+ m_extraKey = key;
+ m_extraValue = value;
+ }
+
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ if (info.requestUrl().scheme() == QLatin1String("myscheme"))
+ info.setHttpHeader(m_extraKey, m_extraValue);
+ }
+
+ QByteArray m_extraKey;
+ QByteArray m_extraValue;
+};
+
+class RequestHeadersUrlSchemeHandler : public ReplyingUrlSchemeHandler
+{
+public:
+ void setExpectedHeader(const QByteArray &key, const QByteArray &value)
+ {
+ m_expectedKey = key;
+ m_expectedValue = value;
+ }
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ const auto requestHeaders = job->requestHeaders();
+ QVERIFY(requestHeaders.contains(m_expectedKey));
+ QCOMPARE(requestHeaders.value(m_expectedKey), m_expectedValue);
+ ReplyingUrlSchemeHandler::requestStarted(job);
+ }
+ QByteArray m_expectedKey;
+ QByteArray m_expectedValue;
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders()
+{
+ RequestHeadersUrlSchemeHandler handler;
+ ExtraHeaderInterceptor interceptor;
+
+ handler.setExpectedHeader("Hello", "World");
+ interceptor.setExtraHeader("Hello", "World");
+
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("myscheme", &handler);
+ profile.setRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl(QStringLiteral("myscheme://whatever")));
+ QVERIFY(loadFinishedSpy.wait());
+}
+
+
void tst_QWebEngineProfile::customUserAgent()
{
QString defaultUserAgent = QWebEngineProfile::defaultProfile()->httpUserAgent();
@@ -570,7 +631,7 @@ void tst_QWebEngineProfile::initiator()
QCOMPARE(handler.initiator, QUrl());
}
-void tst_QWebEngineProfile::qtbug_72299()
+void tst_QWebEngineProfile::qtbug_71895()
{
QWebEngineView view;
view.setUrl(QUrl("https://www.qt.io"));
diff --git a/tests/auto/widgets/qwebenginescript/BLACKLIST b/tests/auto/widgets/qwebenginescript/BLACKLIST
new file mode 100644
index 000000000..b641aaf04
--- /dev/null
+++ b/tests/auto/widgets/qwebenginescript/BLACKLIST
@@ -0,0 +1,3 @@
+# FIXME post 72-merge
+[webChannelWithBadString]
+*
diff --git a/tests/auto/widgets/qwebengineview/resources/image2.png b/tests/auto/widgets/qwebengineview/resources/image2.png
new file mode 100644
index 000000000..8d703640c
--- /dev/null
+++ b/tests/auto/widgets/qwebengineview/resources/image2.png
Binary files differ
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 5f05f70ab..17177c7fb 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -47,6 +47,7 @@
#include <QStyle>
#include <QtWidgets/qaction.h>
#include <QWebEngineProfile>
+#include <QtCore/qregularexpression.h>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
QVERIFY(actual == (expect | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu));
@@ -269,7 +270,7 @@ void tst_QWebEngineView::getWebKitVersion()
void tst_QWebEngineView::changePage_data()
{
QString html = "<html><head><title>%1</title>"
- "<link rel='icon' href='file://" TESTS_SOURCE_DIR "/resources/image2.png'></head></html>";
+ "<link rel='icon' href='qrc:///resources/image2.png'></head></html>";
QUrl urlFrom("data:text/html," + html.arg("TitleFrom"));
QUrl urlTo("data:text/html," + html.arg("TitleTo"));
QUrl nullPage("data:text/html,<html/>");
@@ -1182,7 +1183,7 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
- errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
QLocale::setDefault(QLocale("en"));
@@ -1192,7 +1193,7 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewEN.page()).isEmpty());
- errorLines = toPlainTextSync(viewEN.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached"));
// Reset error page
@@ -1205,7 +1206,7 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
- errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
}
@@ -2636,7 +2637,7 @@ void tst_QWebEngineView::imeJSInputEvents()
view.show();
auto logLines = [&view]() -> QStringList {
- return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegExp(".+"));
+ return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegularExpression(".+"));
};
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
index 53b11bca8..a09be0399 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
@@ -5,5 +5,6 @@
<file>resources/input_types.html</file>
<file>resources/scrolltest_page.html</file>
<file>resources/keyboardEvents.html</file>
+ <file>resources/image2.png</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index eec8bb389..15b3efd3b 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -8,7 +8,10 @@ SUBDIRS += \
devtools \
faviconmanager \
loadsignals \
+ offscreen \
origins \
+ proxy \
+ proxypac \
schemes \
shutdown \
qwebenginedownloaditem \
@@ -27,9 +30,6 @@ qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printing
}
-# QTBUG-71229
-linux:!boot2qt: SUBDIRS += proxypac
-
qtConfig(webengine-spellchecker):!cross_compile {
!qtConfig(webengine-native-spellchecker) {
SUBDIRS += spellchecking
@@ -40,7 +40,8 @@ qtConfig(webengine-spellchecker):!cross_compile {
# QTBUG-60268
boot2qt: SUBDIRS -= accessibility defaultsurfaceformat devtools \
- faviconmanager qwebenginepage qwebenginehistory \
- qwebengineprofile qwebenginescript \
- qwebengineview qwebenginedownloaditem qwebenginesettings \
- schemes origins loadsignals
+ qwebenginepage \
+ qwebengineprofile \
+ qwebengineview \
+ qwebenginescript \
+ proxypac offscreen
diff --git a/tests/manual/widgets/inputmethods/testview.cpp b/tests/manual/widgets/inputmethods/testview.cpp
index d41734c2d..14e355caf 100644
--- a/tests/manual/widgets/inputmethods/testview.cpp
+++ b/tests/manual/widgets/inputmethods/testview.cpp
@@ -31,7 +31,7 @@
#include <QDebug>
#include <QFile>
#include <QPushButton>
-#include <QRegExp>
+#include <QRegularExpression>
#include <QStandardItemModel>
#include <QTableView>
#include <QTest>
@@ -77,15 +77,16 @@ void TestView::loadTestData(const QString &testDataPath)
QTextStream testDataStream(&testDataFile);
while (!testDataStream.atEnd()) {
QString line = testDataStream.readLine();
- QRegExp data("^\"(.*)\"\\s*,\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*,\\s*(\\d+)\\s*,\\s*\"(.*)\"\\s*,\\s*\"(.*)\"\\s*$");
- if (!data.exactMatch(line))
+ QRegularExpression data(QRegularExpression::anchoredPattern("^\"(.*)\"\\s*,\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*,\\s*(\\d+)\\s*,\\s*\"(.*)\"\\s*,\\s*\"(.*)\"\\s*$"));
+ QRegularExpressionMatch match = data.match(line);
+ if (!match.hasMatch())
continue;
QStandardItemModel *model = qobject_cast<QStandardItemModel *>(m_tableView->model());
QList<QStandardItem *> row;
- for (int i = 1; i <= data.captureCount(); ++i)
- row.append(new QStandardItem(data.cap(i)));
+ for (int i = 1; i <= match.lastCapturedIndex(); ++i)
+ row.append(new QStandardItem(match.captured(i)));
model->appendRow(row);
}
diff --git a/tests/manual/widgets/webgl/main.cpp b/tests/manual/widgets/webgl/main.cpp
new file mode 100644
index 000000000..364eda8b9
--- /dev/null
+++ b/tests/manual/widgets/webgl/main.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QDebug>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QOperatingSystemVersion>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QSurfaceFormat>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QDesktopWidget>
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QHBoxLayout>
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWebEngineWidgets/QWebEngineView>
+
+// Manual test for checking if WebGL (1 or 2) works.
+// Set environment variable QTWEBENGINE_GL_TYPE to one of the following to try and switch
+// the underlying GL implementation (mostly Windows): "desktop", "gles", "gles3", "software".
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit MainWindow(QWidget *parent = nullptr);
+ QSize sizeHint() const;
+
+private:
+ QWebEngineView *view = nullptr;
+};
+
+MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
+{
+ QWidget *centralWidget = new QWidget;
+
+ QGroupBox *horizontalGroupBox = new QGroupBox;
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ QPushButton *exButton1 = new QPushButton(QStringLiteral("Aquarium (WebGL 1)"));
+ QPushButton *exButton2 = new QPushButton(QStringLiteral("Lots of objects (WebGL 1)"));
+ QPushButton *exButton3 = new QPushButton(QStringLiteral("Instanced triangles (WebGL 2)"));
+
+ buttonLayout->addWidget(exButton1);
+ buttonLayout->addWidget(exButton2);
+ buttonLayout->addWidget(exButton3);
+ horizontalGroupBox->setLayout(buttonLayout);
+
+ const QUrl exUrl1 =
+ QUrl(QStringLiteral(
+ "http://webglsamples.org/aquarium/aquarium.html"));
+ const QUrl exUrl2 =
+ QUrl(QStringLiteral(
+ "http://webglsamples.org/lots-o-objects/lots-o-objects-draw-elements.html"));
+ const QUrl exUrl3 =
+ QUrl(QStringLiteral(
+ "http://webglsamples.org/WebGL2Samples/#transform_feedback_instanced"));
+
+ view = new QWebEngineView;
+ connect(exButton1, &QPushButton::clicked, view, [=](){
+ view->setUrl(exUrl1);
+ });
+ connect(exButton2, &QPushButton::clicked, view, [=](){
+ view->setUrl(exUrl2);
+ });
+ connect(exButton3, &QPushButton::clicked, view, [=](){
+ view->setUrl(exUrl3);
+ });
+
+ QVBoxLayout *centralLayout = new QVBoxLayout;
+ centralLayout->addWidget(horizontalGroupBox);
+ centralLayout->addWidget(view, 1);
+
+ centralWidget->setLayout(centralLayout);
+ setCentralWidget(centralWidget);
+
+ view->setUrl(QUrl(QStringLiteral("http://webglsamples.org/aquarium/aquarium.html")));
+ setWindowTitle(tr("WebGL 1 and 2 examples"));
+}
+
+QSize MainWindow::sizeHint() const
+{
+ const QRect desktopRect = QApplication::desktop()->screenGeometry();
+ const QSize size = desktopRect.size() * qreal(0.9);
+ return size;
+}
+
+bool isWindows()
+{
+ return QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows;
+}
+
+// Easy snippets to copy to command line for testing for UNIX only.
+// QTWEBENGINE_GL_TYPE=desktop ./webgl
+// QTWEBENGINE_GL_TYPE=gles ./webgl
+// QTWEBENGINE_GL_TYPE=gles3 ./webgl
+// QTWEBENGINE_GL_TYPE=software ./webgl
+int main(int argc, char *argv[])
+{
+ // Not all options are relevant for all platforms.
+ const QString desktopGL = QStringLiteral("desktop");
+ const QString angle = QStringLiteral("angle"); // Same as gles really, just an alias.
+ const QString gles = QStringLiteral("gles"); // ANGLE on Windows.
+ const QString gles3 = QStringLiteral("gles3"); // ANGLE on Windows.
+ const QString softwareGL = QStringLiteral("software");
+
+ QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+
+ QString glType = qEnvironmentVariable("QTWEBENGINE_GL_TYPE");
+ if (glType.isEmpty()) {
+ if (isWindows())
+ glType = gles3;
+ else
+ glType = desktopGL;
+ }
+
+ if (glType == desktopGL) {
+ QApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
+ qInfo() << QStringLiteral("Trying to use Desktop OpenGL.\n");
+ } else if (glType == gles || glType == gles3 || glType == angle) {
+ QApplication::setAttribute(Qt::AA_UseOpenGLES);
+ if (glType == gles || glType == angle)
+ qInfo() << QStringLiteral("Trying to use OpenGL ES 2.\n");
+ if (glType == gles3)
+ qInfo() << QStringLiteral("Trying to use OpenGL ES 3.\n");
+ } else if (glType == softwareGL) {
+ QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
+ qInfo() << QStringLiteral("Trying to use software OpenGL.\n");
+ }
+
+ if (glType == gles3) {
+ // Set OpenGL ES version 3.
+ QSurfaceFormat format;
+ format.setSamples(4);
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+ format.setVersion(3, 0);
+ QSurfaceFormat::setDefaultFormat(format);
+ }
+
+ QApplication a(argc, argv);
+
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.scenegraph.general=true"));
+ QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext();
+ qInfo() << "Global OpenGL context format: " << globalSharedContext->format() << "\n";
+
+ MainWindow w;
+
+ // Move middle-ish.
+ const QRect desktopRect = QApplication::desktop()->screenGeometry();
+ const QSize pos = desktopRect.size() * qreal(0.1);
+ w.move(pos.width(), pos.height());
+
+ w.show();
+
+ return a.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/webgl/webgl.pro b/tests/manual/widgets/webgl/webgl.pro
new file mode 100644
index 000000000..9141d0221
--- /dev/null
+++ b/tests/manual/widgets/webgl/webgl.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+TARGET = webgl
+QT += core gui widgets webenginewidgets
+CONFIG += c++11
+SOURCES += main.cpp
+
diff --git a/tests/manual/widgets/widgets.pro b/tests/manual/widgets/widgets.pro
index f06d3e1c3..34e88f0e3 100644
--- a/tests/manual/widgets/widgets.pro
+++ b/tests/manual/widgets/widgets.pro
@@ -1,4 +1,5 @@
TEMPLATE= subdirs
SUBDIRS += \
- inputmethods
+ inputmethods \
+ webgl
diff --git a/tests/quicktestbrowser/ApplicationRoot.qml b/tests/quicktestbrowser/ApplicationRoot.qml
index 980016535..e2248e350 100644
--- a/tests/quicktestbrowser/ApplicationRoot.qml
+++ b/tests/quicktestbrowser/ApplicationRoot.qml
@@ -53,6 +53,7 @@ QtObject {
var newWindow = browserWindowComponent.createObject(root)
newWindow.currentWebView.profile = profile
profile.downloadRequested.connect(newWindow.onDownloadRequested)
+ profile.userNotification.connect(newWindow.onUserNotification)
return newWindow
}
function createDialog(profile) {
diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml
index 22f98e1c5..381e9c142 100644
--- a/tests/quicktestbrowser/BrowserWindow.qml
+++ b/tests/quicktestbrowser/BrowserWindow.qml
@@ -505,6 +505,18 @@ ApplicationWindow {
download.accept()
}
+ MessageDialog {
+ id: notificationDialog
+ width: 200
+ standardButtons: StandardButton.Ok
+ }
+
+ function onUserNotification(notification) {
+ notificationDialog.title = notification.title
+ notificationDialog.text = notification.origin.toString() + '\n' + notification.message
+ notificationDialog.open()
+ }
+
ZoomController {
id: zoomController
y: parent.mapFromItem(currentWebView, 0 , 0).y - 4
diff --git a/tests/quicktestbrowser/FeaturePermissionBar.qml b/tests/quicktestbrowser/FeaturePermissionBar.qml
index 9c0b25966..500d13206 100644
--- a/tests/quicktestbrowser/FeaturePermissionBar.qml
+++ b/tests/quicktestbrowser/FeaturePermissionBar.qml
@@ -40,10 +40,24 @@ Rectangle {
visible: false
height: acceptButton.height + 4
- onRequestedFeatureChanged: {
- message.text = securityOrigin + " wants to access " + message.textForFeature(requestedFeature);
+
+ function textForFeature(feature) {
+ switch (feature) {
+ case WebEngineView.Geolocation: return 'Allow %1 to access your location information?'
+ case WebEngineView.MediaAudioCapture: return 'Allow %1 to access your microphone?'
+ case WebEngineView.MediaVideoCapture: return 'Allow %1 to access your webcam?'
+ case WebEngineView.MediaAudioVideoCapture: return 'Allow %1 to access your microphone and webcam?'
+ case WebEngineView.DesktopVideoCapture: return 'Allow %1 to capture video of your desktop?'
+ case WebEngineView.DesktopAudioVideoCapture: return 'Allow %1 to capture audio and video of your desktop?'
+ case WebEngineView.Notifications: return 'Allow %1 to show notification on your desktop?'
+ default: break
+ }
+ return 'Grant permission for %1 to unknown or unsupported feature [' + feature + ']?'
}
+ onRequestedFeatureChanged: {
+ message.text = textForFeature(requestedFeature).arg(securityOrigin);
+ }
RowLayout {
anchors {
@@ -54,17 +68,6 @@ Rectangle {
Label {
id: message
Layout.fillWidth: true
-
- function textForFeature(feature) {
- if (feature === WebEngineView.MediaAudioCapture)
- return "your microphone"
- if (feature === WebEngineView.MediaVideoCapture)
- return "your camera"
- if (feature === WebEngineView.MediaAudioVideoCapture)
- return "your camera and microphone"
- if (feature === WebEngineView.Geolocation)
- return "your position"
- }
}
Button {
diff --git a/tools/buildscripts/repack_locales.py b/tools/buildscripts/repack_locales.py
index 103fdaf69..8f1ae190b 100755
--- a/tools/buildscripts/repack_locales.py
+++ b/tools/buildscripts/repack_locales.py
@@ -56,6 +56,8 @@ INT_DIR = None
# The target platform. If it is not defined, sys.platform will be used.
OS = None
+ENABLE_EXTENSIONS = False
+
# Extra input files.
EXTRA_INPUT_FILES = []
@@ -109,6 +111,14 @@ def calc_inputs(locale):
inputs.append(os.path.join(SHARE_INT_DIR, 'chrome',
'chromium_strings_%s.pak' % locale))
+ if ENABLE_EXTENSIONS:
+ # For example:
+ # '<(SHARED_INTERMEDIATE_DIR)/extensions/strings/extensions_strings_da.pak
+ # TODO(jamescook): When Android stops building extensions code move this
+ # to the OS != 'ios' and OS != 'android' section below.
+ inputs.append(os.path.join(SHARE_INT_DIR, 'extensions', 'strings',
+ 'extensions_strings_%s.pak' % locale))
+
# Add any extra input files.
for extra_file in EXTRA_INPUT_FILES:
inputs.append('%s_%s.pak' % (extra_file, locale))
@@ -158,6 +168,7 @@ def DoMain(argv):
global INT_DIR
global OS
global EXTRA_INPUT_FILES
+ global ENABLE_EXTENSIONS
parser = optparse.OptionParser("usage: %prog [options] locales")
parser.add_option("-i", action="store_true", dest="inputs", default=False,
@@ -177,6 +188,9 @@ def DoMain(argv):
locale suffix and \".pak\" extension.")
parser.add_option("-p", action="store", dest="os",
help="The target OS. (e.g. mac, linux, win, etc.)")
+ parser.add_option("--enable-extensions", action="store",
+ dest="enable_extensions",
+ help="Whether to include strings for extensions")
options, locales = parser.parse_args(argv)
if not locales:
@@ -188,6 +202,7 @@ def DoMain(argv):
SHARE_INT_DIR = options.share_int_dir
EXTRA_INPUT_FILES = options.extra_input
OS = options.os
+ ENABLE_EXTENSIONS = options.enable_extensions == '1'
if not OS:
if sys.platform == 'darwin':
diff --git a/tools/scripts/gn_find_mocables.py b/tools/scripts/gn_find_mocables.py
index d97dcb534..d1f682456 100644
--- a/tools/scripts/gn_find_mocables.py
+++ b/tools/scripts/gn_find_mocables.py
@@ -32,10 +32,9 @@ import os
mocables = set()
includedMocs = set()
-dir = sys.argv[1]
files = sys.argv[2:]
-for f in filter(os.path.isfile, [os.path.join(dir, f) for f in files]):
+for f in filter(os.path.isfile, files):
inBlockComment = False
for line in open(f).readlines():
# Block comments handling
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 4bf4381cb..c6de5977d 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -43,7 +43,7 @@ qtwebengine_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
os.chdir(qtwebengine_root)
def isInGitBlacklist(file_path):
- # We do need all the gyp files.
+ # We need all the git files.
if ( '.gitignore' in file_path
or '.gitmodules' in file_path
or '.gitattributes' in file_path
@@ -54,33 +54,14 @@ def isInChromiumBlacklist(file_path):
# Filter out empty submodule directories.
if (os.path.isdir(file_path)):
return True
- # We do need all the gyp files.
- if file_path.endswith('.gyp') or file_path.endswith('.gypi') or file_path.endswith('.isolate'):
- return False
- # We do need all the gn file.
+ # We do need all the gn files.
if file_path.endswith('.gn') or file_path.endswith('.gni') or file_path.endswith('.typemap') or \
file_path.endswith('.mojom'):
return False
- if ( '_jni' in file_path
- or 'jni_' in file_path
- or 'testdata/' in file_path
- or '/tests/' in file_path
- or ('/test/' in file_path and
- not '/webrtc/' in file_path and
- not file_path.startswith('net/test/') and
- not file_path.endswith('mock_chrome_application_mac.h') and
- not file_path.endswith('perftimer.h') and
- not file_path.endswith('test-torque.tq') and
- not 'ozone' in file_path and
- not 'fontconfig_util_linux' in file_path and
- not 'core/mojo/test/' in file_path and
- not file_path.startswith('extensions/browser/'))
- or file_path.endswith('.java')
- or file_path.startswith('android_webview')
+ if (file_path.startswith('android_webview')
or file_path.startswith('apps/')
or file_path.startswith('ash/')
or file_path.startswith('base/android')
- or file_path.startswith('breakpad')
or file_path.startswith('buildtools/clang_format/script')
or file_path.startswith('buildtools/third_party/libc++')
or file_path.startswith('buildtools/third_party/libc++abi')
@@ -98,6 +79,7 @@ def isInChromiumBlacklist(file_path):
not 'media/webrtc/desktop_media_list.h' in file_path and
not 'media/webrtc/desktop_streams_registry.' in file_path and
not 'browser/net/chrome_mojo_proxy_resolver_factory.' in file_path and
+ not '/browser/accessibility/' in file_path and
not '/browser/custom_handlers/' in file_path and
not '/browser/devtools/' in file_path and
not '/browser/ui/webui/' in file_path and
@@ -122,25 +104,27 @@ def isInChromiumBlacklist(file_path):
not file_path.endswith('.grdp') and
not file_path.endswith('.json') and
not file_path.endswith('chrome_version.rc.version'))
- or file_path.startswith('chrome_frame')
+ or file_path.startswith('chrome_elf')
or file_path.startswith('chromecast')
or file_path.startswith('chromeos')
or file_path.startswith('cloud_print')
- or file_path.startswith('components/chrome_apps/')
- or file_path.startswith('components/cronet/')
- or file_path.startswith('components/drive/')
- or file_path.startswith('components/invalidation/')
- or file_path.startswith('components/gcm_driver/')
- or file_path.startswith('components/nacl/')
- or file_path.startswith('components/omnibox/')
- or file_path.startswith('components/policy/')
- or file_path.startswith('components/proximity_auth/')
- or (file_path.startswith('components/resources/terms/') and not file_path.endswith('terms_chromium.html'))
- or file_path.startswith('components/rlz/')
- or file_path.startswith('components/sync/') and not file_path.endswith('ordinal.h')
- or file_path.startswith('components/test/')
- or file_path.startswith('components/test_runner/')
- or file_path.startswith('components/translate/')
+ or (file_path.startswith('components/') and (
+ file_path.startswith('components/chrome_apps/')
+ or file_path.startswith('components/cronet/')
+ or file_path.startswith('components/drive/')
+ or file_path.startswith('components/invalidation/')
+ or file_path.startswith('components/gcm_driver/')
+ or file_path.startswith('components/nacl/')
+ or file_path.startswith('components/omnibox/')
+ or file_path.startswith('components/policy/')
+ or file_path.startswith('components/proximity_auth/')
+ or (file_path.startswith('components/resources/terms/') and not file_path.endswith('terms_chromium.html'))
+ or file_path.startswith('components/rlz/')
+ or file_path.startswith('components/sync/') and not file_path.endswith('ordinal.h')
+ or file_path.startswith('components/test/')
+ or file_path.startswith('components/test_runner/')
+ or file_path.startswith('components/translate/')
+ ))
or file_path.startswith('content/public/android/java')
or (file_path.startswith('content/shell') and
not file_path.startswith('content/shell/common') and
@@ -149,109 +133,123 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('google_update')
or file_path.startswith('ios')
or file_path.startswith('media/base/android/java')
- or file_path.startswith('native_client')
+ or file_path.startswith('native_client_sdk')
or file_path.startswith('net/android/java')
or (file_path.startswith('net/data/') and '_unittest/' in file_path)
or file_path.startswith('net/data/fuzzer_data/')
+ or file_path.startswith('net/third_party/quic/core/qpack/fuzzer')
or file_path.startswith('remoting')
or file_path.startswith('rlz')
or file_path.startswith('testing/android')
or file_path.startswith('testing/buildbot')
- or file_path.startswith('third_party/WebKit/LayoutTests')
- or file_path.startswith('third_party/WebKit/ManualTests')
- or file_path.startswith('third_party/WebKit/Source/core/testing/data/')
- or file_path.startswith('third_party/WebKit/Source/devtools/devtools-node-modules')
- or file_path.startswith('third_party/WebKit/PerformanceTests')
- or file_path.startswith('third_party/accessibility-audit')
- or file_path.startswith('third_party/afl')
- or file_path.startswith('third_party/android_')
- or file_path.startswith('third_party/apache-win32')
- or file_path.startswith('third_party/apple_sample_code')
- or file_path.startswith('third_party/ashmem')
- or file_path.startswith('third_party/binutils')
- or file_path.startswith('third_party/bison')
- or file_path.startswith('third_party/blink/perf_tests/')
- or file_path.startswith('third_party/breakpad/src/processor/testdata/')
- or file_path.startswith('third_party/boringssl/crypto_test_data.cc')
- or file_path.startswith('third_party/boringssl/src/fuzz')
- or (file_path.startswith('third_party/cacheinvalidation') and
- not file_path.endswith('isolate'))
- or file_path.startswith('third_party/catapult')
- or file_path.startswith('third_party/chromite')
- or file_path.startswith('third_party/cld_2')
- or file_path.startswith('third_party/closure_compiler')
- or file_path.startswith('third_party/codesighs')
- or file_path.startswith('third_party/colorama')
- or file_path.startswith('third_party/cygwin')
- or file_path.startswith('third_party/cython')
- or file_path.startswith('third_party/deqp')
- or file_path.startswith('third_party/depot_tools')
- or file_path.startswith('third_party/elfutils')
- or file_path.startswith('third_party/freetype-android')
- or file_path.startswith('third_party/google_input_tools')
- or file_path.startswith('third_party/gperf')
- or file_path.startswith('third_party/gnu_binutils')
- or file_path.startswith('third_party/grpc')
- or file_path.startswith('third_party/gtk+')
- or file_path.startswith('third_party/google_appengine_cloudstorage')
- or file_path.startswith('third_party/google_toolbox_for_mac')
- or file_path.startswith('third_party/hunspell_dictionaries')
- or (file_path.startswith('third_party/icu') and file_path.endswith('icudtl_dat.S'))
- or file_path.startswith('third_party/icu/android')
- or file_path.startswith('third_party/icu/ios')
- or file_path.startswith('third_party/instrumented_libraries')
- or file_path.startswith('third_party/jsr-305')
- or file_path.startswith('third_party/junit')
- or file_path.startswith('third_party/lcov')
- or file_path.startswith('third_party/libphonenumber')
- or file_path.startswith('third_party/libaddressinput/src/testdata')
- or file_path.startswith('third_party/libaddressinput/src/common/src/test')
- or file_path.startswith('third_party/libc++')
- or file_path.startswith('third_party/liblouis')
- or file_path.startswith('third_party/lighttpd')
- or file_path.startswith('third_party/libwebm/source/webm_parser/fuzzing')
- or file_path.startswith('third_party/logilab')
- or file_path.startswith('third_party/markdown')
- or file_path.startswith('third_party/mingw-w64')
- or file_path.startswith('third_party/nacl_sdk_binaries')
- or (file_path.startswith('third_party/polymer') and
- not file_path.startswith('third_party/polymer/v1_0/components-chromium/'))
- or file_path.startswith('third_party/openh264/src/res')
- or file_path.startswith('third_party/pdfium/testing/resources')
- or file_path.startswith('third_party/pdfium/tools')
- or file_path.startswith('third_party/pdfsqueeze')
- or file_path.startswith('third_party/pefile')
- or file_path.startswith('third_party/perl')
- or file_path.startswith('third_party/psyco_win32')
- or file_path.startswith('third_party/pylint')
- or file_path.startswith('third_party/scons-2.0.1')
- or file_path.startswith('third_party/sfntly/src/cpp/data/fonts')
- or file_path.startswith('third_party/sfntly/src/java')
- or file_path.startswith('third_party/skia/infra')
- or file_path.startswith('third_party/speech-dispatcher')
- or file_path.startswith('third_party/talloc')
- or file_path.startswith('third_party/trace-viewer')
- or file_path.startswith('third_party/undoview')
- or file_path.startswith('third_party/wayland')
- or file_path.startswith('third_party/webgl')
- or file_path.startswith('third_party/webrtc/resources/')
- or file_path.startswith('third_party/webrtc/third_party/boringssl/crypto_test_data.cc')
- or file_path.startswith('third_party/webrtc/third_party/boringssl/src/fuzz')
- or file_path.startswith('tools/android')
- or file_path.startswith('tools/luci_go')
- or file_path.startswith('tools/memory_inspector')
- or file_path.startswith('tools/perf')
- or file_path.startswith('tools/swarming_client')
- or file_path.startswith('ui/android/java')
- or file_path.startswith('ui/app_list')
- or file_path.startswith('ui/base/ime/chromeos')
- or file_path.startswith('ui/chromeos')
- or file_path.startswith('ui/display/chromeos')
- or file_path.startswith('ui/events/ozone/chromeos')
- or file_path.startswith('ui/file_manager')
- or file_path.startswith('ui/gfx/chromeos')
-
- ):
+ or (file_path.startswith('third_party/') and (
+ file_path.startswith('third_party/WebKit/LayoutTests')
+ or file_path.startswith('third_party/accessibility-audit')
+ or file_path.startswith('third_party/afl')
+ or file_path.startswith('third_party/android_')
+ or file_path.startswith('third_party/apache-win32')
+ or file_path.startswith('third_party/arcode-android-sdk')
+ or file_path.startswith('third_party/ashmem')
+ or file_path.startswith('third_party/binutils')
+ or file_path.startswith('third_party/bison')
+ or file_path.startswith('third_party/blink/perf_tests/')
+ or file_path.startswith('third_party/blink/web_tests/')
+ or file_path.startswith('third_party/breakpad/src/processor/testdata/')
+ or file_path.startswith('third_party/boringssl/crypto_test_data.cc')
+ or file_path.startswith('third_party/boringssl/src/fuzz')
+ or (file_path.startswith('third_party/cacheinvalidation') and
+ not file_path.endswith('isolate'))
+ or (file_path.startswith('third_party/catapult/')
+ and not file_path.startswith('third_party/catapult/catapult_build')
+ and not file_path.startswith('third_party/catapult/common')
+ and not file_path.startswith('third_party/catapult/third_party/polymer/components/polymer')
+ and not file_path.startswith('third_party/catapult/tracing'))
+ or file_path.startswith('third_party/catapult/tracing/test_data/')
+ or file_path.startswith('third_party/chromevox')
+ or file_path.startswith('third_party/chromite')
+ or file_path.startswith('third_party/cld_3')
+ or file_path.startswith('third_party/closure_compiler')
+ or file_path.startswith('third_party/colorama')
+ or file_path.startswith('third_party/depot_tools')
+ or file_path.startswith('third_party/elfutils')
+ or file_path.startswith('third_party/fuschsia-sdk/')
+ or file_path.startswith('third_party/glslang/src/Test/')
+ or file_path.startswith('third_party/google_')
+ or file_path.startswith('third_party/hunspell_dictionaries')
+ or (file_path.startswith('third_party/icu') and file_path.endswith('icudtl_dat.S'))
+ or file_path.startswith('third_party/icu/android')
+ or file_path.startswith('third_party/icu/ios')
+ or file_path.startswith('third_party/instrumented_libraries')
+ or file_path.startswith('third_party/jsr-305')
+ or file_path.startswith('third_party/junit')
+ or file_path.startswith('third_party/lcov')
+ or file_path.startswith('third_party/libaddressinput/src/testdata')
+ or file_path.startswith('third_party/libaddressinput/src/common/src/test')
+ or file_path.startswith('third_party/libFuzzer')
+ or file_path.startswith('third_party/liblouis')
+ or file_path.startswith('third_party/libphonenumber')
+ or file_path.startswith('third_party/libwebp/fuzzing')
+ or file_path.startswith('third_party/libwebm/source/webm_parser/fuzzing')
+ or file_path.startswith('third_party/logilab')
+ or file_path.startswith('third_party/markdown')
+ or (file_path.startswith('third_party/polymer') and
+ not file_path.startswith('third_party/polymer/v1_0/components-chromium/'))
+ or file_path.startswith('third_party/openh264/src/res')
+ or file_path.startswith('third_party/pdfium/testing/resources')
+ or file_path.startswith('third_party/pdfium/tools')
+ or file_path.startswith('third_party/perl')
+ or file_path.startswith('third_party/pylint')
+ or file_path.startswith('third_party/sfntly/src/cpp/data/fonts')
+ or file_path.startswith('third_party/sfntly/src/java')
+ or file_path.startswith('third_party/skia/infra')
+ or file_path.startswith('third_party/sqlite/sqlite-src-')
+ or file_path.startswith('third_party/speech-dispatcher')
+ or file_path.startswith('third_party/spirv-cross/')
+ or file_path.startswith('third_party/swiftshader/third_party/llvm')
+ or file_path.startswith('third_party/wayland')
+ or file_path.startswith('third_party/webgl')
+ or file_path.startswith('third_party/webrtc/resources/')
+ or file_path.startswith('third_party/webrtc/third_party/boringssl/crypto_test_data.cc')
+ or file_path.startswith('third_party/webrtc/third_party/boringssl/src/fuzz')
+ ))
+ or (file_path.startswith('tools/') and (
+ file_path.startswith('tools/android')
+ or file_path.startswith('tools/luci_go')
+ or file_path.startswith('tools/memory_inspector')
+ or file_path.startswith('tools/perf')
+ or file_path.startswith('tools/swarming_client')
+ ))
+ or (file_path.startswith('ui/') and (
+ file_path.startswith('ui/android/java')
+ or file_path.startswith('ui/app_list')
+ or file_path.startswith('ui/base/ime/chromeos')
+ or file_path.startswith('ui/chromeos')
+ or file_path.startswith('ui/display/chromeos')
+ or file_path.startswith('ui/events/ozone/chromeos')
+ or file_path.startswith('ui/file_manager')
+ or file_path.startswith('ui/gfx/chromeos')
+ ))
+ or ('/fuzz' in file_path and (
+ '/fuzz/' in file_path
+ or '/fuzzer/' in file_path
+ or '/fuzzing/' in file_path
+ ))
+ or ('/test' in file_path and (
+ '/testdata/' in file_path
+ or '/tests/' in file_path
+ or ('/test/' in file_path and
+ not '/webrtc/' in file_path and
+ not file_path.startswith('net/test/') and
+ not file_path.endswith('mock_chrome_application_mac.h') and
+ not file_path.endswith('perftimer.h') and
+ not file_path.endswith('test-torque.tq') and
+ not 'ozone' in file_path and
+ not 'clang_coverage' in file_path and
+ not 'crypto/test/trampoline' in file_path and
+ not 'fontconfig_util_linux' in file_path and
+ not 'core/mojo/test/' in file_path and
+ not file_path.startswith('extensions/browser/'))
+ ))):
return True
return False
@@ -342,6 +340,7 @@ def exportChromium():
files = listFilesInCurrentRepository()
# Add LASTCHANGE files which are not tracked by git.
files.append('build/util/LASTCHANGE')
+ files.append('build/util/LASTCHANGE.committime')
files.append('skia/ext/skia_commit_hash.h')
files.append('gpu/config/gpu_lists_version.h')
print 'copying files to ' + third_party_chromium
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index 27062fbcf..6bce380e7 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -38,9 +38,9 @@ import json
import urllib2
import git_submodule as GitSubmodule
-chromium_version = '69.0.3497.113'
-chromium_branch = '3497'
-ninja_version = 'v1.8.2'
+chromium_version = '73.0.3683.64'
+chromium_branch = '3683'
+ninja_version = 'v1.9.0'
json_url = 'http://omahaproxy.appspot.com/all.json'
@@ -51,7 +51,6 @@ upstream_src_dir = os.path.abspath(snapshot_src_dir + '_upstream')
submodule_blacklist = [
'third_party/WebKit/LayoutTests/w3c/csswg-test'
, 'third_party/WebKit/LayoutTests/w3c/web-platform-tests'
- , 'third_party/jsoncpp/source'
, 'chrome/tools/test/reference_build/chrome_mac'
, 'chrome/tools/test/reference_build/chrome_linux'
, 'chrome/tools/test/reference_build/chrome_win'