summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--CHROMIUM_VERSION2
-rw-r--r--coin/product_dependencies.yaml3
-rw-r--r--coin/qt-installer-package-config.json15
-rw-r--r--config_help.txt1
-rw-r--r--configure.pri80
-rw-r--r--dist/changes-5.12.106
-rw-r--r--dist/changes-5.15.286
-rw-r--r--examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml3
-rw-r--r--examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml1
-rw-r--r--examples/webengine/quicknanobrowser/ApplicationRoot.qml1
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml12
-rw-r--r--examples/webenginewidgets/cookiebrowser/mainwindow.cpp2
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp2
-rw-r--r--examples/webenginewidgets/printme/printhandler.cpp1
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.cpp4
-rw-r--r--examples/webenginewidgets/webenginewidgets.pro4
-rw-r--r--mkspecs/features/functions.prf6
-rw-r--r--mkspecs/features/gn_generator.prf9
m---------src/3rdparty0
-rw-r--r--src/buildtools/config/common.pri15
-rw-r--r--src/buildtools/config/linux.pri2
-rw-r--r--src/buildtools/config/lipo.pri85
-rw-r--r--src/buildtools/config/lipo_linking.pri15
-rw-r--r--src/buildtools/config/mac_osx.pri6
-rw-r--r--src/buildtools/config/support.pri20
-rw-r--r--src/buildtools/config/windows.pri3
-rw-r--r--src/buildtools/configure.json165
-rw-r--r--src/buildtools/gn.pro1
-rw-r--r--src/core/accessibility_activation_observer.cpp9
-rw-r--r--src/core/accessibility_tree_formatter_qt.cpp53
-rw-r--r--src/core/api/core_api.pro8
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp7
-rw-r--r--src/core/api/qtwebenginecoreglobal_p.h3
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h4
-rw-r--r--src/core/api/qwebengineurlschemehandler.h4
-rw-r--r--src/core/browser_accessibility_manager_qt.cpp10
-rw-r--r--src/core/browser_accessibility_manager_qt.h7
-rw-r--r--src/core/browser_accessibility_qt.cpp34
-rw-r--r--src/core/browser_accessibility_qt.h4
-rw-r--r--src/core/browser_main_parts_qt.cpp16
-rw-r--r--src/core/browser_message_filter_qt.cpp99
-rw-r--r--src/core/browser_message_filter_qt.h57
-rw-r--r--src/core/browsing_data_remover_delegate_qt.cpp15
-rw-r--r--src/core/browsing_data_remover_delegate_qt.h9
-rw-r--r--src/core/chromium_overrides.cpp100
-rw-r--r--src/core/clipboard_qt.cpp91
-rw-r--r--src/core/clipboard_qt.h48
-rw-r--r--src/core/common/extensions/api/qtwebengine_extensions_features.gni4
-rw-r--r--src/core/common/extensions/extensions_api_provider_qt.cpp21
-rw-r--r--src/core/common/extensions/extensions_client_qt.cpp12
-rw-r--r--src/core/common/extensions/extensions_client_qt.h10
-rw-r--r--src/core/common/qt_messages.h80
-rw-r--r--src/core/common/user_script_data.h74
-rw-r--r--src/core/compositor/content_gpu_client_qt.cpp137
-rw-r--r--src/core/compositor/content_gpu_client_qt.h6
-rw-r--r--src/core/config/common.pri10
-rw-r--r--src/core/config/linux.pri7
-rw-r--r--src/core/config/windows.pri3
-rw-r--r--src/core/configure.json15
-rw-r--r--src/core/content_browser_client_qt.cpp540
-rw-r--r--src/core/content_browser_client_qt.h87
-rw-r--r--src/core/content_client_qt.cpp21
-rw-r--r--src/core/content_main_delegate_qt.cpp18
-rw-r--r--src/core/core.pro6
-rw-r--r--src/core/core_chromium.pri34
-rw-r--r--src/core/core_gn_config.pri10
-rw-r--r--src/core/core_lipo.pro9
-rw-r--r--src/core/core_module.pro22
-rw-r--r--src/core/desktop_screen_qt.cpp117
-rw-r--r--src/core/desktop_screen_qt.h30
-rw-r--r--src/core/devtools_frontend_qt.cpp38
-rw-r--r--src/core/devtools_frontend_qt.h4
-rw-r--r--src/core/devtools_manager_delegate_qt.cpp2
-rw-r--r--src/core/download_manager_delegate_qt.cpp12
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.cpp25
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.h4
-rw-r--r--src/core/extensions/extension_host_delegate_qt.cpp125
-rw-r--r--src/core/extensions/extension_host_delegate_qt.h77
-rw-r--r--src/core/extensions/extension_system_qt.cpp74
-rw-r--r--src/core/extensions/extension_system_qt.h16
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.cpp16
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.h1
-rw-r--r--src/core/extensions/extensions_api_client_qt.cpp16
-rw-r--r--src/core/extensions/extensions_api_client_qt.h6
-rw-r--r--src/core/extensions/extensions_browser_client_qt.cpp94
-rw-r--r--src/core/extensions/extensions_browser_client_qt.h3
-rw-r--r--src/core/extensions/messaging_delegate_qt.cpp (renamed from src/core/common/user_script_data.cpp)23
-rw-r--r--src/core/extensions/messaging_delegate_qt.h (renamed from src/core/renderer/render_view_observer_qt.h)37
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.cpp26
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.h3
-rw-r--r--src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp219
-rw-r--r--src/core/extensions/pdf_iframe_navigation_throttle_qt.h (renamed from src/core/renderer/plugins/plugin_placeholder_qt.h)54
-rw-r--r--src/core/extensions/plugin_service_filter_qt.cpp99
-rw-r--r--src/core/extensions/plugin_service_filter_qt.h (renamed from src/core/renderer_host/render_view_observer_host_qt.h)43
-rw-r--r--src/core/file_picker_controller.cpp54
-rw-r--r--src/core/file_picker_controller.h18
-rw-r--r--src/core/find_text_helper.cpp12
-rw-r--r--src/core/gn_run.pro45
-rw-r--r--src/core/location_provider_qt.cpp1
-rw-r--r--src/core/location_provider_qt.h4
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp102
-rw-r--r--src/core/media_capture_devices_dispatcher.h4
-rw-r--r--src/core/net/client_cert_override.cpp6
-rw-r--r--src/core/net/client_cert_store_data.cpp4
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp11
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h2
-rw-r--r--src/core/net/custom_url_loader_factory.cpp40
-rw-r--r--src/core/net/custom_url_loader_factory.h4
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp156
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.h12
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp4
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp268
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.h18
-rw-r--r--src/core/net/qrc_url_scheme_handler.cpp5
-rw-r--r--src/core/net/system_network_context_manager.cpp57
-rw-r--r--src/core/net/system_network_context_manager.h14
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp40
-rw-r--r--src/core/net/webui_controller_factory_qt.h8
-rw-r--r--src/core/ozone/BUILD.gn5
-rw-r--r--src/core/ozone/gl_context_qt.cpp4
-rw-r--r--src/core/ozone/gl_ozone_egl_qt.cpp14
-rw-r--r--src/core/ozone/gl_surface_egl_qt.cpp23
-rw-r--r--src/core/ozone/gl_surface_glx_qt.cpp26
-rw-r--r--src/core/ozone/gl_surface_glx_qt.h4
-rw-r--r--src/core/ozone/gl_surface_qt.cpp12
-rw-r--r--src/core/ozone/gl_surface_qt.h6
-rw-r--r--src/core/ozone/ozone_platform_qt.cpp91
-rw-r--r--src/core/permission_manager_qt.cpp12
-rw-r--r--src/core/permission_manager_qt.h8
-rw-r--r--src/core/pref_service_adapter.cpp6
-rw-r--r--src/core/printing/print_view_manager_base_qt.cpp190
-rw-r--r--src/core/printing/print_view_manager_base_qt.h107
-rw-r--r--src/core/printing/print_view_manager_qt.cpp41
-rw-r--r--src/core/printing/print_view_manager_qt.h29
-rw-r--r--src/core/printing/printing_message_filter_qt.cpp101
-rw-r--r--src/core/printing/printing_message_filter_qt.h39
-rw-r--r--src/core/process_main.cpp6
-rw-r--r--src/core/profile_adapter.cpp35
-rw-r--r--src/core/profile_adapter.h1
-rw-r--r--src/core/profile_io_data_qt.cpp27
-rw-r--r--src/core/profile_io_data_qt.h10
-rw-r--r--src/core/profile_qt.cpp1
-rw-r--r--src/core/qtwebengine.gni3
-rw-r--r--src/core/qtwebengine_resources.gni15
-rw-r--r--src/core/qtwebengine_sources.gni67
-rw-r--r--src/core/quota_permission_context_qt.cpp18
-rw-r--r--src/core/quota_permission_context_qt.h2
-rw-r--r--src/core/quota_request_controller_impl.cpp7
-rw-r--r--src/core/render_widget_host_view_qt.cpp584
-rw-r--r--src/core/render_widget_host_view_qt.h53
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h4
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp136
-rw-r--r--src/core/renderer/content_renderer_client_qt.h35
-rw-r--r--src/core/renderer/content_settings_observer_qt.cpp66
-rw-r--r--src/core/renderer/content_settings_observer_qt.h13
-rw-r--r--src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp9
-rw-r--r--src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h3
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.cpp16
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.h4
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp9
-rw-r--r--src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp2
-rw-r--r--src/core/renderer/print_web_view_helper_delegate_qt.cpp25
-rw-r--r--src/core/renderer/render_configuration.cpp (renamed from src/core/renderer/render_thread_observer_qt.cpp)19
-rw-r--r--src/core/renderer/render_configuration.h (renamed from src/core/renderer/render_thread_observer_qt.h)20
-rw-r--r--src/core/renderer/render_frame_observer_qt.cpp8
-rw-r--r--src/core/renderer/render_frame_observer_qt.h10
-rw-r--r--src/core/renderer/user_resource_controller.cpp240
-rw-r--r--src/core/renderer/user_resource_controller.h47
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp21
-rw-r--r--src/core/renderer/web_channel_ipc_transport.h2
-rw-r--r--src/core/renderer/web_engine_page_render_frame.cpp (renamed from src/core/renderer/render_view_observer_qt.cpp)62
-rw-r--r--src/core/renderer/web_engine_page_render_frame.h (renamed from src/core/renderer/plugins/plugin_placeholder_qt.cpp)58
-rw-r--r--src/core/renderer_host/pepper/pepper_flash_browser_host_qt.cpp14
-rw-r--r--src/core/renderer_host/pepper/pepper_flash_browser_host_qt.h8
-rw-r--r--src/core/renderer_host/user_resource_controller_host.cpp78
-rw-r--r--src/core/renderer_host/user_resource_controller_host.h23
-rw-r--r--src/core/renderer_host/web_channel_ipc_transport_host.cpp34
-rw-r--r--src/core/renderer_host/web_channel_ipc_transport_host.h8
-rw-r--r--src/core/renderer_host/web_engine_page_host.cpp (renamed from src/core/renderer_host/render_view_observer_host_qt.cpp)73
-rw-r--r--src/core/renderer_host/web_engine_page_host.h90
-rw-r--r--src/core/resource_bundle_qt.cpp14
-rw-r--r--src/core/resource_context_qt.h15
-rw-r--r--src/core/touch_selection_controller_client_qt.cpp20
-rw-r--r--src/core/type_conversion.cpp15
-rw-r--r--src/core/type_conversion.h56
-rw-r--r--src/core/user_notification_controller.h2
-rw-r--r--src/core/user_script.cpp11
-rw-r--r--src/core/user_script.h3
-rw-r--r--src/core/web_contents_adapter.cpp185
-rw-r--r--src/core/web_contents_adapter.h14
-rw-r--r--src/core/web_contents_adapter_client.h3
-rw-r--r--src/core/web_contents_delegate_qt.cpp184
-rw-r--r--src/core/web_contents_delegate_qt.h50
-rw-r--r--src/core/web_contents_view_qt.cpp45
-rw-r--r--src/core/web_contents_view_qt.h25
-rw-r--r--src/core/web_engine_context.cpp159
-rw-r--r--src/core/web_engine_context.h11
-rw-r--r--src/core/web_engine_context_threads.cpp2
-rw-r--r--src/core/web_engine_library_info.cpp49
-rw-r--r--src/core/web_engine_library_info.h1
-rw-r--r--src/core/web_engine_settings.cpp53
-rw-r--r--src/core/web_engine_settings.h11
-rw-r--r--src/core/web_event_factory.cpp72
-rw-r--r--src/pdf/config/common.pri50
-rw-r--r--src/pdf/config/ios.pri3
-rw-r--r--src/pdf/configure.json20
-rw-r--r--src/pdf/gn_run.pro47
-rw-r--r--src/pdf/pdf.pro18
-rw-r--r--src/pdf/pdfcore.pro15
-rw-r--r--src/pdf/pdfcore_generator.pro8
-rw-r--r--src/pdf/pdfcore_lipo.pro5
-rw-r--r--src/pdf/qpdfdocument.cpp31
-rw-r--r--src/pdf/quick/qquickpdfdocument.cpp2
-rw-r--r--src/pdf/quick/qquickpdfsearchmodel.cpp4
-rw-r--r--src/pdfwidgets/configure.json2
-rw-r--r--src/pdfwidgets/qpdfview.cpp4
-rw-r--r--src/plugins/qwebengineview/qwebengineview.pro1
-rw-r--r--src/process/process.pro4
-rw-r--r--src/process/support_win.cpp1
-rw-r--r--src/src.pro2
-rw-r--r--src/tools/qwebengine_convert_dict/main.cpp4
-rw-r--r--src/webengine/api/qquickwebengineloadrequest.cpp9
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp16
-rw-r--r--src/webengine/api/qquickwebenginetouchhandleprovider.cpp2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp34
-rw-r--r--src/webengine/api/qquickwebengineview_p.h6
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h3
-rw-r--r--src/webengine/api/qtwebengineglobal.cpp3
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc20
-rw-r--r--src/webengine/doc/src/webengineview_lgpl.qdoc4
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp31
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h2
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp61
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h5
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp46
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h3
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp12
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp15
-rw-r--r--src/webenginewidgets/configure.json2
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc6
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc13
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp36
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h2
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp42
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html3
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/content2.html6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp277
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc2
-rw-r--r--tests/auto/quick/dialogs/testhandler.cpp2
-rw-r--r--tests/auto/quick/dialogs/tst_dialogs.cpp79
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp2
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST5
-rw-r--r--tests/auto/quick/qmltests/data/TestWebEngineView.qml7
-rw-r--r--tests/auto/quick/qmltests/data/test2.html2
-rw-r--r--tests/auto/quick/qmltests/data/test4.html1
-rw-r--r--tests/auto/quick/qmltests/data/tst_action.qml10
-rw-r--r--tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_audioMuted.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_contextMenu.qml4
-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_focusOnNavigation.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardEvents.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadHtml.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadUrl.qml18
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationHistory.qml48
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationRequested.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_settings.qml3
-rw-r--r--tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml1
-rw-r--r--tests/auto/quick/qmltests/data/tst_viewSource.qml30
-rw-r--r--tests/auto/quick/qmltests2/data/tst_favicon.qml14
-rw-r--r--tests/auto/quick/qmltests2/data/tst_faviconDownload.qml2
-rw-r--r--tests/auto/quick/qmltests2/data/tst_filePicker.qml22
-rw-r--r--tests/auto/quick/qmltests2/data/tst_inputMethod.qml1
-rw-r--r--tests/auto/quick/qmltests2/data/tst_javaScriptDialogs.qml15
-rw-r--r--tests/auto/quick/qmltests2/data/tst_loadFail.qml7
-rw-r--r--tests/auto/quick/qmltests2/data/tst_mouseClick.qml1
-rw-r--r--tests/auto/quick/qmltests2/data/tst_viewSoure.qml137
-rw-r--r--tests/auto/quick/qmltests2/qmltests2.pro1
-rw-r--r--tests/auto/quick/qmltests_ssl/BLACKLIST2
-rw-r--r--tests/auto/quick/qmltests_ssl/data/tst_certificateError.qml2
-rw-r--r--tests/auto/quick/qquickwebengineprofile/tst_qquickwebengineprofile.cpp73
-rw-r--r--tests/auto/quick/qquickwebengineview/BLACKLIST2
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp51
-rw-r--r--tests/auto/quick/quick.pro2
-rw-r--r--tests/auto/shared/data/loadprogress/page1.html2
-rw-r--r--tests/auto/shared/data/loadprogress/page2.html1
-rw-r--r--tests/auto/shared/data/loadprogress/page5.html20
-rw-r--r--tests/auto/shared/data/loadprogress/page6.html13
-rw-r--r--tests/auto/shared/data/loadprogress/page7.html13
-rw-r--r--tests/auto/shared/data/loadprogress/page8.html20
-rw-r--r--tests/auto/shared/httpserver.cpp10
-rw-r--r--tests/auto/shared/httpserver.h3
-rw-r--r--tests/auto/shared/resources/cert.pem97
-rw-r--r--tests/auto/shared/resources/key.pem50
-rw-r--r--tests/auto/widgets/accessibility/tst_accessibility.cpp3
-rw-r--r--tests/auto/widgets/certificateerror/BLACKLIST2
-rw-r--r--tests/auto/widgets/certificateerror/tst_certificateerror.cpp6
-rw-r--r--tests/auto/widgets/loadsignals/BLACKLIST14
-rw-r--r--tests/auto/widgets/loadsignals/tst_loadsignals.cpp419
-rw-r--r--tests/auto/widgets/loadsignals/tst_loadsignals.qrc4
-rw-r--r--tests/auto/widgets/origins/origins.pro1
-rw-r--r--tests/auto/widgets/origins/tst_origins.cpp30
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp55
-rw-r--r--tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp3
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST7
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/redirect.html8
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp146
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc1
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp6
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp2
-rw-r--r--tests/auto/widgets/qwebenginesettings/BLACKLIST2
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST10
-rw-r--r--tests/auto/widgets/qwebengineview/resources/dummy.html6
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp387
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc1
-rw-r--r--tests/auto/widgets/touchinput/BLACKLIST2
-rw-r--r--tests/auto/widgets/touchinput/touchinput.pro (renamed from tests/auto/quick/qquickwebengineprofile/qquickwebengineprofile.pro)1
-rw-r--r--tests/auto/widgets/touchinput/tst_touchinput.cpp349
-rw-r--r--tests/auto/widgets/util.h37
-rw-r--r--tests/auto/widgets/widgets.pro7
-rw-r--r--tools/scripts/git_submodule.py5
-rwxr-xr-xtools/scripts/take_snapshot.py185
-rw-r--r--tools/scripts/version_resolver.py6
329 files changed, 7465 insertions, 3958 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 8de72145c..04aa122a8 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.15.2
+MODULE_VERSION = 5.15.17
diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
new file mode 100644
index 000000000..cfc4c49b3
--- /dev/null
+++ b/CHROMIUM_VERSION
@@ -0,0 +1,2 @@
+Based on Chromium version: 87.0.4280.144
+Patched with security patches up to Chromium version: 123.0.6312.58
diff --git a/coin/product_dependencies.yaml b/coin/product_dependencies.yaml
new file mode 100644
index 000000000..3b8e9011c
--- /dev/null
+++ b/coin/product_dependencies.yaml
@@ -0,0 +1,3 @@
+dependencies:
+ ../tqtc-qt5.git:
+ ref: "tqtc/lts-5.15"
diff --git a/coin/qt-installer-package-config.json b/coin/qt-installer-package-config.json
index 0ba69adac..d556d245f 100644
--- a/coin/qt-installer-package-config.json
+++ b/coin/qt-installer-package-config.json
@@ -2,16 +2,19 @@
"version": "1",
"module-split": {
"qtpdf": [
+ "**/bin/*Pdf*",
"**/include/*QtPdf*/**/*",
- "**/lib/cmake/Qt5Gui/*",
- "**/lib/cmake/Qt5Pdf/*",
- "**/lib/cmake/Qt5PdfWidgets/*",
- "**/lib/pkgconfig/Qt5Pdf*",
- "**/lib/libQt5Pdf*",
+ "**/lib/cmake/Qt*Gui/*Pdf*",
+ "**/lib/cmake/Qt*Pdf*/*",
+ "**/lib/cmake/Qt*Qml/QmlPlugins/*pdf*",
+ "**/lib/metatypes/*pdf*",
+ "**/lib/pkgconfig/*Pdf*",
+ "**/lib/*Pdf*",
"**/lib/static_chrome/*",
- "**/lib/QtPdf.framework/*",
+ "**/lib/QtPdf*.framework/**",
"**/mkspecs/modules/qt_lib_pdf*",
"**/mkspecs/modules/qt_plugin_qpdf.pri",
+ "**/modules/Pdf*",
"**/plugins/imageformats/*",
"**/qml/QtQuick/**/*"
]
diff --git a/config_help.txt b/config_help.txt
index 48236c18a..d50892121 100644
--- a/config_help.txt
+++ b/config_help.txt
@@ -15,6 +15,7 @@ WebEngine options:
(Linux only)
-webengine-pepper-plugins ...... Enable use of Pepper Flash and Widevine
plugins [auto]
+ -webengine-python-version ...... Use specific python version for building [python2/python3]
-webengine-printing-and-pdf .... Enable use of printing and output to PDF
[auto]
-webengine-proprietary-codecs .. Enable support for proprietary codecs [no]
diff --git a/configure.pri b/configure.pri
index d3ba9b147..cb53c93b0 100644
--- a/configure.pri
+++ b/configure.pri
@@ -12,12 +12,9 @@ defineTest(isPythonVersionSupported) {
python_version ~= s/[()]//g
python_version = $$split(python_version, ',')
python_major_version = $$first(python_version)
- greaterThan(python_major_version, 2) {
- qtLog("Python version 3 is not supported by Chromium.")
- return(false)
- }
python_minor_version = $$member(python_version, 1)
python_patch_version = $$member(python_version, 2)
+ greaterThan(python_major_version, 2): greaterThan(python_minor_version, 7): return(true)
greaterThan(python_major_version, 1): greaterThan(python_minor_version, 6): greaterThan(python_patch_version, 4): return(true)
qtLog("Unsupported python version: $${python_major_version}.$${python_minor_version}.$${python_patch_version}.")
return(false)
@@ -53,21 +50,37 @@ defineTest(qtConfReport_jumboBuild) {
}
defineTest(qtConfTest_detectPython2) {
- python = $$qtConfFindInPath("python2$$EXE_SUFFIX")
- isEmpty(python) {
- qtLog("'python2$$EXE_SUFFIX' not found in PATH. Checking for 'python$$EXE_SUFFIX'.")
- python = $$qtConfFindInPath("python$$EXE_SUFFIX")
+ pythonOverride = $$eval(config.input.python_override)
+ !isEmpty(pythonOverride) {
+ python = $$qtConfFindInPath("$$pythonOverride$$EXE_SUFFIX")
+ isEmpty(python) {
+ qtLog("User selected '$$pythonOverride$$EXE_SUFFIX' was not found in PATH. Giving up.")
+ return(false)
+ }
+ }
+
+ win32 {
+ # the default name of the python 2 executable on windows is just
+ # python, so try that first
+ isEmpty(python):python = $$qtConfFindInPath("python$$EXE_SUFFIX")
+ isEmpty(python):python = $$qtConfFindInPath("python2$$EXE_SUFFIX")
+ isEmpty(python):python = $$qtConfFindInPath("python3$$EXE_SUFFIX")
+ } else {
+ isEmpty(python):python = $$qtConfFindInPath("python2$$EXE_SUFFIX")
+ isEmpty(python):python = $$qtConfFindInPath("python3$$EXE_SUFFIX")
+ isEmpty(python):python = $$qtConfFindInPath("python$$EXE_SUFFIX")
}
+
isEmpty(python) {
- qtLog("'python$$EXE_SUFFIX' not found in PATH. Giving up.")
+ qtLog("Python not found in PATH. Giving up.")
return(false)
}
!isPythonVersionSupported($$python) {
- qtLog("A suitable Python 2 executable could not be located.")
+ qtLog("A suitable Python executable could not be located.")
return(false)
}
- # Make tests.python2.location available in configure.json.
+ # Make tests.python.location available in configure.json.
$${1}.location = $$clean_path($$python)
export($${1}.location)
$${1}.cache += location
@@ -143,6 +156,7 @@ defineTest(qtConfTest_detectArch) {
contains(QT_ARCH, "i386")|contains(QT_ARCH, "x86_64"): return(true)
contains(QT_ARCH, "arm")|contains(QT_ARCH, "arm64"): return(true)
contains(QT_ARCH, "mips"): return(true)
+ contains(QT_ARCH, "mips64"): return(true)
qtLog("Architecture not supported.")
return(false)
}
@@ -169,16 +183,6 @@ defineTest(qtConfTest_detectNinja) {
return(false)
}
-defineTest(qtConfTest_detectProtoc) {
- protoc = $$qtConfFindInPath("protoc")
- isEmpty(protoc) {
- qtLog("Optional protoc could not be found.")
- return(false)
- }
- qtLog("Found protoc from path: $$protoc")
- return(true)
-}
-
defineTest(qtConfTest_detectGn) {
gn = $$qtConfFindInPath("gn$$EXE_SUFFIX")
!isEmpty(gn) {
@@ -201,6 +205,19 @@ defineTest(qtConfTest_detectNodeJS) {
return(false)
}
}
+ nodejs = $$system_quote($$system_path($$nodejs))
+ !qtRunLoggedCommand("$$nodejs --version", version) {
+ qtLog("'$$nodejs' didn't run.")
+ return(false)
+ }
+ # at least version 10
+ version10 = false
+ contains(version, "v([1-9][0-9])\..*"): version10 = true
+
+ $${1}.version10 = $$version10
+ export($${1}.version10)
+ $${1}.cache += version10
+ export($${1}.cache)
return(true)
}
@@ -430,8 +447,8 @@ defineTest(qtwebengine_isWindowsPlatformSupported) {
qtwebengine_platformError("requires MSVC or Clang (MSVC mode).")
return(false)
}
- !qtwebengine_isMinWinSDKVersion(10, 18362): {
- qtwebengine_platformError("requires a Windows SDK version 10.0.18362 or newer.")
+ !qtwebengine_isMinWinSDKVersion(10, 19041): {
+ qtwebengine_platformError("requires a Windows SDK version 10.0.19041 or newer.")
return(false)
}
return(true)
@@ -456,15 +473,26 @@ defineTest(qtwebengine_isMacOsPlatformSupported) {
qtwebengine_platformError("requires a macOS SDK version of 10.13 or newer. Current version is $${WEBENGINE_OSX_SDK_PRODUCT_VERSION}.")
return(false)
}
+ CONFIG(debug, debug|release):isUniversal(){
+ qtwebengine_platformError("Universal builds can not be done with debug configuration due to large binary size.")
+ return(false)
+ }
return(true)
}
defineTest(qtwebengine_isGCCVersionSupported) {
# Keep in sync with src/webengine/doc/src/qtwebengine-platform-notes.qdoc
- greaterThan(QMAKE_GCC_MAJOR_VERSION, 4):return(true)
+ lessThan(QMAKE_GCC_MAJOR_VERSION, 5) {
+ qtwebengine_platformError("requires at least gcc version 5, but using gcc version $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.")
+ return(false)
+ }
- qtwebengine_platformError("requires at least gcc version 5, but using gcc version $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.")
- return(false)
+ equals(QMAKE_GCC_MAJOR_VERSION, 5): equals(QMAKE_GCC_MINOR_VERSION, 4): equals(QMAKE_GCC_PATCH_VERSION, 0) {
+ qtwebengine_platformError("gcc version 5.4.0 is blacklisted due to internal compiler errors.")
+ return(false)
+ }
+
+ return(true)
}
defineTest(qtwebengine_isBuildingOnWin32) {
diff --git a/dist/changes-5.12.10 b/dist/changes-5.12.10
index 12e0c46d8..48862b226 100644
--- a/dist/changes-5.12.10
+++ b/dist/changes-5.12.10
@@ -32,7 +32,7 @@ General
Chromium
--------
- - Security fixes from Chromium up to version 86.0.4240.75, including:
+ - Security fixes from Chromium up to version 86.0.4240.111, including:
- CVE-2020-6459
- CVE-2020-6462: Use after free in task scheduling
@@ -71,6 +71,10 @@ Chromium
- CVE-2020-15965: Out of bounds write in V8
- CVE-2020-15968: Use after free in Blink
- CVE-2020-15969: Use after free in WebRTC.
+ - CVE-2020-15999: Heap buffer overflow in freetype
+ - CVE-2020-16001: Use after free in media.
+ - CVE-2020-16002: Use after free in PDFium.
+ - CVE-2020-16003: Use after free in printing.
- Security Bug 1051439
- Security bug 1052492
- Security bug 1054229
diff --git a/dist/changes-5.15.2 b/dist/changes-5.15.2
new file mode 100644
index 000000000..792b9afd6
--- /dev/null
+++ b/dist/changes-5.15.2
@@ -0,0 +1,86 @@
+Qt 5.15.2 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.15.1.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ https://doc.qt.io/qt-5.15/index.html
+
+The Qt version 5.15 series is binary compatible with the 5.14.x series.
+Applications compiled for 5.14 will continue to run with 5.15.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+General
+-------
+ - [QTBUG-84632] Warn about QtWebengineProcess launching from network share
+ on Windows.
+ - [QTBUG-85363] Handle non-ASCII names for PulseAudio
+ - [QTBUG-85494] Fix regression crash when not handling QQuickWebEngineNewViewRequest
+ - [QTBUG-85817] Fix crashes on resize
+ - [QTBUG-86672] Fix remapped menu key being mapped back to menu key
+ - [QTBUG-86945] Fix crash when opening a PDF in debug build on windows.
+ - [QTBUG-87129] Mention node.js build-time dependency
+ - The QtWebEngineProcess now has a version number
+ - The old compositor has been removed and can no longer be restored using
+ command line argument.
+
+Chromium
+--------
+
+ - The Chromium version has been updated to 83.0.4103.122
+ - Security fixes from Chromium up to version 86.0.4240.183, including:
+ - CVE-2020-6540: Heap buffer overflow in Skia
+ - CVE-2020-6557: Inappropriate implementation in networking
+ - CVE-2020-6561: Inappropriate implementation in Content Security Policy
+ - CVE-2020-6562: Insufficient policy enforcement in Blink
+ - CVE-2020-6569: Integer overflow in WebUSB
+ - CVE-2020-6570: Side-channel information leakage in WebRTC
+ - CVE-2020-6573: Use after free in video
+ - CVE-2020-6571: Incorrect security UI in Omnibox
+ - CVE-2020-6575: Race in Mojo
+ - CVE-2020-6576: Use after free in offscreen canvas
+ - CVE-2020-15959: Insufficient policy enforcement in networking
+ - CVE-2020-15960: Out of bounds read in storage
+ - CVE-2020-15961: Insufficient policy enforcement in extensions
+ - CVE-2020-15962: Insufficient policy enforcement in serial
+ - CVE-2020-15963
+ - CVE-2020-15964: Insufficient data validation in media
+ - CVE-2020-15965: Out of bounds write in V8
+ - CVE-2020-15966
+ - CVE-2020-15968: Use after free in Blink
+ - CVE-2020-15969: Use after free in WebRTC.
+ - CVE-2020-15972: Use after free in audio.
+ - CVE-2020—15973: Insufficient policy enforcement in extensions
+ - CVE-2020-15974: Integer overflow in Blink
+ - CVE-2020-15976: Use after free in WebXR
+ - CVE-2020-15977: Insufficient data validation in dialogs.
+ - CVE-2020-15978: Insufficient data validation in navigation
+ - CVE-2020-15979: Inappropriate implementation in V8.
+ - CVE-2020-15985: Inappropriate implementation in Blink.
+ - CVE-2020-15987: Use after free in WebRTC
+ - CVE-2020-15989: Uninitialized Use in PDFium
+ - CVE-2020-15992: Insufficient policy enforcement in networking
+ - CVE-2020-15999: Heap buffer overflow in freetype
+ - CVE-2020-16001: Use after free in media.
+ - CVE-2020-16002: Use after free in PDFium
+ - CVE-2020-16003: Use after free in printing
+ - CVE-2020-16005: Insufficient policy enforcement in ANGLE
+ - CVE-2020-16008: Stack buffer overflow in WebRTC
+ - CVE-2020-16009: Inappropriate implementation in V8
+ - CVE-2020-16011: Heap buffer overflow in UI on Windows.
+ - Security bug 1106091
+ - Security bug 1107824
+ - Security bug 1111149
+ - Security bug 1125199
+ - Security bug 1137608
diff --git a/examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml b/examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml
index 8b8523388..ecbe8d3af 100644
--- a/examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml
+++ b/examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml
@@ -122,6 +122,7 @@ Item {
height: 22
Layout.fillWidth: true
font.pointSize: 12
+ textColor: "black"
}
Text {
@@ -136,6 +137,8 @@ Item {
height: 26
Layout.fillWidth: true
font.pointSize: 12
+ textColor: "black"
+ echoMode: TextInput.Password
}
Item {
diff --git a/examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml b/examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml
index 1c7fd29ed..7dad1090a 100644
--- a/examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml
+++ b/examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml
@@ -124,6 +124,7 @@ Item {
height: 22
Layout.fillWidth: true
font.pointSize: 12
+ textColor: "black"
}
Item {
diff --git a/examples/webengine/quicknanobrowser/ApplicationRoot.qml b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
index df4bbdb4a..22ca87dc1 100644
--- a/examples/webengine/quicknanobrowser/ApplicationRoot.qml
+++ b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
@@ -66,7 +66,6 @@ QtObject {
property Component browserWindowComponent: BrowserWindow {
applicationRoot: root
- onClosing: destroy()
}
property Component browserDialogComponent: BrowserDialog {
onClosing: destroy()
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index c595c3bc5..1b8915df2 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -624,6 +624,18 @@ ApplicationWindow {
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
}
+
+ Timer {
+ id: hideTimer
+ interval: 0
+ running: false
+ repeat: false
+ onTriggered: devToolsEnabled.checked = false
+ }
+ onWindowCloseRequested: function(request) {
+ // Delay hiding for keep the inspectedView set to receive the ACK message of close.
+ hideTimer.running = true;
+ }
}
MessageDialog {
id: sslDialog
diff --git a/examples/webenginewidgets/cookiebrowser/mainwindow.cpp b/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
index 970381d4d..0171b9c7f 100644
--- a/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
+++ b/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
@@ -107,7 +107,7 @@ CookieWidget::CookieWidget(const QNetworkCookie &cookie, QWidget *parent): QWidg
void CookieWidget::setHighlighted(bool enabled)
{
QPalette p = palette();
- p.setColor(backgroundRole(), enabled ? QColor(0xF0, 0xF8, 0xFF) : Qt::white);
+ p.setColor(backgroundRole(), enabled ? p.alternateBase().color() : p.base().color());
setPalette(p);
}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.cpp b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
index 28d6f5641..4ce2c1618 100644
--- a/examples/webenginewidgets/markdowneditor/mainwindow.cpp
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
@@ -170,7 +170,7 @@ void MainWindow::onFileSave()
void MainWindow::onFileSaveAs()
{
QString path = QFileDialog::getSaveFileName(this,
- tr("Save MarkDown File"), "", tr("MarkDown File (*.md, *.markdown)"));
+ tr("Save MarkDown File"), "", tr("MarkDown File (*.md *.markdown)"));
if (path.isEmpty())
return;
m_filePath = path;
diff --git a/examples/webenginewidgets/printme/printhandler.cpp b/examples/webenginewidgets/printme/printhandler.cpp
index d8c4fc177..b1eb037e6 100644
--- a/examples/webenginewidgets/printme/printhandler.cpp
+++ b/examples/webenginewidgets/printme/printhandler.cpp
@@ -107,6 +107,7 @@ void PrintHandler::printPreview()
return;
m_inPrintPreview = true;
QPrinter printer;
+ printer.setResolution(300);
QPrintPreviewDialog preview(&printer, m_page->view());
connect(&preview, &QPrintPreviewDialog::paintRequested,
this, &PrintHandler::printDocument);
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
index d7a69e61f..10ccdad59 100644
--- a/examples/webenginewidgets/simplebrowser/tabwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
@@ -196,7 +196,9 @@ void TabWidget::setupView(WebView *webView)
});
connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() {
int index = indexOf(webView);
- if (index >= 0)
+ if (webView->page()->inspectedPage())
+ window()->close();
+ else if (index >= 0)
closeTab(index);
});
connect(webView, &WebView::devToolsRequested, this, &TabWidget::devToolsRequested);
diff --git a/examples/webenginewidgets/webenginewidgets.pro b/examples/webenginewidgets/webenginewidgets.pro
index deb42a8cd..31a214ceb 100644
--- a/examples/webenginewidgets/webenginewidgets.pro
+++ b/examples/webenginewidgets/webenginewidgets.pro
@@ -1,3 +1,5 @@
+load(functions)
+
include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
QT_FOR_CONFIG += webenginecore webenginecore-private
@@ -20,7 +22,7 @@ qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printme html2pdf
}
-qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile {
+qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile:!isUniversal() {
SUBDIRS += spellchecker
} else {
message("Spellcheck example will not be built because it depends on usage of Hunspell dictionaries.")
diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf
index d3ceb4c5e..7f630588a 100644
--- a/mkspecs/features/functions.prf
+++ b/mkspecs/features/functions.prf
@@ -5,6 +5,11 @@ defineReplace(getConfigDir) {
return("debug")
}
+defineTest(isUniversal) {
+ macos:count(QT_ARCHS, 1, >):return(true)
+ return(false)
+}
+
defineReplace(getChromiumSrcDir) {
exists($$QTWEBENGINE_ROOT/.git): git_chromium_src_dir = $$system("git config qtwebengine.chromiumsrcdir")
# Fall back to the snapshot path if git does not know about chromium sources (i.e. init-repository.py has not been used)
@@ -106,6 +111,7 @@ defineReplace(gnArch) {
contains(qtArch, "arm64"): return(arm64)
contains(qtArch, "mips"): return(mipsel)
contains(qtArch, "mips64"): return(mips64el)
+ contains(qtArch, "mips64el"): return(mips64el)
return(unknown)
}
diff --git a/mkspecs/features/gn_generator.prf b/mkspecs/features/gn_generator.prf
index a83b59847..306e58db1 100644
--- a/mkspecs/features/gn_generator.prf
+++ b/mkspecs/features/gn_generator.prf
@@ -27,7 +27,7 @@ defineReplace(filter_flag_values) {
return($$value_to_check)
}
-isEmpty(GN_FILE): GN_FILE = $$system_path($$_PRO_FILE_PWD_/BUILD.gn)
+isEmpty(GN_FILES): GN_FILES = $$system_path($$_PRO_FILE_PWD_/BUILD.gn)
isEmpty(GN_RUN_BINARY_SCRIPT): GN_RUN_BINARY_SCRIPT = "//build/gn_run_binary.py"
isEmpty(GN_FIND_MOCABLES_SCRIPT): GN_FIND_MOCABLES_SCRIPT = "//build/gn_find_mocables.py"
@@ -260,12 +260,13 @@ GN_CONTENTS += "}"
for (inc, GN_INCLUDES): GN_CONTENTS += $$cat($$inc,lines)
}
-build_pass|!debug_and_release: write_file($$GN_FILE, GN_CONTENTS)
-
+build_pass|!debug_and_release {
+ for(gnFile, GN_FILES): write_file($$gnFile, GN_CONTENTS)
+}
# The generated Makefile shouldn't build anything by itself, just re-run qmake if necessary
TEMPLATE = aux
SOURCES =
HEADERS =
RESOURCES =
-QMAKE_DISTCLEAN += $$GN_FILE
+QMAKE_DISTCLEAN += $$GN_FILES
diff --git a/src/3rdparty b/src/3rdparty
-Subproject c5637fa9071bb6d53b5d21ac713f2a5191f8c16
+Subproject fdfef5b37af3bed8402d7c7e20a5487f2602b0a
diff --git a/src/buildtools/config/common.pri b/src/buildtools/config/common.pri
index 85781d251..cf990c79b 100644
--- a/src/buildtools/config/common.pri
+++ b/src/buildtools/config/common.pri
@@ -14,25 +14,28 @@ gn_args += \
enable_nacl=false \
enable_remoting=false \
enable_reporting=false \
- enable_resource_whitelist_generation=false \
+ enable_resource_allowlist_generation=false \
enable_swiftshader=false \
+ enable_swiftshader_vulkan=false \
angle_enable_swiftshader=false \
- enable_web_auth=true \
enable_web_speech=false \
enable_widevine=true \
forbid_non_component_debug_builds=false \
has_native_accessibility=false \
safe_browsing_mode=0 \
+ skia_use_dawn=false \
toolkit_views=false \
treat_warnings_as_errors=false \
use_allocator_shim=false \
use_allocator=\"none\" \
- use_custom_libcxx=false
+ use_custom_libcxx=false \
+ chrome_pgo_phase=0 \
+ enable_hangout_services_extension=true
-# No closure compile supported at this time
+# Closure compile requires Java
gn_args += \
- closure_compile=false \
- optimize_webui=false
+ optimize_webui=false \
+ enable_js_type_check=false
# We always embed v8 startup data currently
gn_args += \
diff --git a/src/buildtools/config/linux.pri b/src/buildtools/config/linux.pri
index 56c18bdb5..7507d51ef 100644
--- a/src/buildtools/config/linux.pri
+++ b/src/buildtools/config/linux.pri
@@ -11,13 +11,13 @@ gn_args += \
use_cups=false \
use_gio=false \
use_gnome_keyring=false \
- linux_use_bundled_binutils=false \
use_udev=true \
use_bundled_fontconfig=false \
use_sysroot=false \
enable_session_service=false \
is_cfi=false \
use_ozone=true \
+ use_x11=false \
ozone_auto_platforms=false \
ozone_platform_headless=false \
ozone_platform_external=true \
diff --git a/src/buildtools/config/lipo.pri b/src/buildtools/config/lipo.pri
new file mode 100644
index 000000000..f065c8ee9
--- /dev/null
+++ b/src/buildtools/config/lipo.pri
@@ -0,0 +1,85 @@
+for(arch, QT_ARCHS) {
+
+ linking_pri = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}.pri
+
+ !include($$linking_pri) {
+ message("Could not find the linking information that gn should have generated.")
+ }
+
+ # Do not precompile any headers. We are only interested in the linker step.
+ PRECOMPILED_HEADER =
+
+ isEmpty(NINJA_OBJECTS): error("Missing object files from linking pri.")
+ isEmpty(NINJA_LFLAGS): error("Missing linker flags from linking pri")
+ isEmpty(NINJA_ARCHIVES): error("Missing archive files from linking pri")
+ isEmpty(NINJA_LIBS): error("Missing library files from linking pri")
+ NINJA_OBJECTS = $$eval($$list($$NINJA_OBJECTS))
+ # Do manual response files
+
+
+ RSP_OBJECT_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}_objects.rsp
+ for(object, NINJA_OBJECTS): RSP_OBJECTS_CONTENT += $$object
+ write_file($$RSP_OBJECT_FILE, RSP_OBJECTS_CONTENT)
+ RSP_ARCHIVE_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}_archives.rsp
+ for(archive, NINJA_ARCHIVES): RSP_ARCHIVES_CONTENT += $$archive
+ write_file($$RSP_ARCHIVE_FILE, RSP_ARCHIVES_CONTENT)
+ RSP_LIBS_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}_libs.rsp
+ for(lib, NINJA_LIBS): RSP_LIBS_CONTENT += $$lib
+ write_file($$RSP_LIBS_FILE, RSP_LIBS_CONTENT)
+
+ unset(RSP_OBJECTS_CONTENT)
+ unset(RSP_ARCHIVES_CONTENT)
+ unset(RSP_LIBS_CONTENT)
+ unset(NINJA_OBJECTS)
+ unset(NINJA_LFLAGS)
+ unset(NINJA_ARCHIVES)
+ unset(NINJA_LIBS)
+}
+
+LIPO_OUT_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}.a
+INPUT_FILE = .
+lipo.name = lipo
+lipo.output = $$LIPO_OUT_FILE
+lipo.input = INPUT_FILE
+lipo.CONFIG += target_predeps no_link
+lipo.commands = lipo -create -output $$LIPO_OUT_FILE
+QMAKE_EXTRA_COMPILERS += lipo
+
+include($$QTWEBENGINE_ROOT/src/buildtools/config/mac_osx.pri)
+
+for(arch, QT_ARCHS) {
+
+ RSP_OBJECT_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}_objects.rsp
+ OBJECT_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}_objects.o
+ RSP_ARCHIVE_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}_archives.rsp
+ ARCHIVE_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}_archives.o
+ OUT_FILE = $$OUT_PWD/$$arch/$$getConfigDir()/$${TARGET}.a
+
+ intermediate_archive_$${arch}.name = build_intermediate_archive_$${arch}
+ intermediate_archive_$${arch}.output= $$OUT_FILE
+ intermediate_archive_$${arch}.input = INPUT_FILE
+ intermediate_archive_$${arch}.depends = $$RSP_OBJECT_FILE $$RSP_ARCHIVE_FILE $$NINJA_TARGETDEPS
+ intermediate_archive_$${arch}.CONFIG += target_predeps no_link
+ intermediate_archive_$${arch}.commands = \
+ clang++ -r -nostdlib -arch $$arch \
+ -mmacosx-version-min=$${QMAKE_MACOSX_DEPLOYMENT_TARGET} \
+ -o $$OBJECT_FILE \
+ -Wl,-keep_private_externs \
+ @$$RSP_OBJECT_FILE ;\
+ $$QMAKE_CC -r -nostdlib -arch $$arch \
+ -mmacosx-version-min=$${QMAKE_MACOSX_DEPLOYMENT_TARGET} \
+ -o $$ARCHIVE_FILE \
+ -Wl,-keep_private_externs \
+ -Wl,-all_load \
+ @$$RSP_ARCHIVE_FILE ;\
+ ar -crs $$OUT_FILE $$OBJECT_FILE $$ARCHIVE_FILE
+ lipo.depends += $$OUT_FILE
+ lipo.commands += $$OUT_FILE
+ QMAKE_EXTRA_COMPILERS += intermediate_archive_$$arch
+
+ unset(RSP_OBJECT_FILE)
+ unset(OBJECT_FILE)
+ unset(RSP_ARCHVIE_FILE)
+ unset(OUT_FILE)
+}
+
diff --git a/src/buildtools/config/lipo_linking.pri b/src/buildtools/config/lipo_linking.pri
new file mode 100644
index 000000000..c65fef059
--- /dev/null
+++ b/src/buildtools/config/lipo_linking.pri
@@ -0,0 +1,15 @@
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
+QT_FOR_CONFIG += buildtools-private
+
+LIPO_OUT_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}.a
+!static {
+ QMAKE_LFLAGS += $${LIPO_OUT_FILE}
+} else {
+ LIBS_PRIVATE += $${LIPO_OUT_FILE}
+}
+
+LIBS_PRIVATE += @$$OUT_PWD/$$QT_ARCH/$$getConfigDir()/$${TARGET}_libs.rsp
+
+qtConfig(webengine-noexecstack): QMAKE_LFLAGS += -Wl,-z,noexecstack
+
+POST_TARGETDEPS += $$LIPO_OUT_FILE
diff --git a/src/buildtools/config/mac_osx.pri b/src/buildtools/config/mac_osx.pri
index b53f91706..b82186083 100644
--- a/src/buildtools/config/mac_osx.pri
+++ b/src/buildtools/config/mac_osx.pri
@@ -34,5 +34,9 @@ gn_args += \
mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION_MAJOR_MINOR}\" \
use_external_popup_menu=false \
- angle_enable_vulkan=false
+ angle_enable_vulkan=false \
+ fatal_linker_warnings=false
+cross_compile:!host_build {
+ gn_args += target_cpu=\"$$gnArch($$QT_ARCH)\"
+}
diff --git a/src/buildtools/config/support.pri b/src/buildtools/config/support.pri
index e192f8777..a9df3d243 100644
--- a/src/buildtools/config/support.pri
+++ b/src/buildtools/config/support.pri
@@ -21,7 +21,8 @@ defineReplace(qtwebengine_checkWebEngineCoreError) {
!qtwebengine_checkForGperf(QtWebEngine):return(false)
!qtwebengine_checkForBison(QtWebEngine):return(false)
!qtwebengine_checkForFlex(QtWebEngine):return(false)
- !qtwebengine_checkForPython2(QtWebengine):return(false)
+ !qtwebengine_checkForPython(QtWebEngine):return(false)
+ !qtwebengine_checkForNodejs(QtWebEngine):return(false)
!qtwebengine_checkForSanitizer(QtWebEngine):return(false)
linux:!qtwebengine_checkForPkgCfg(QtWebEngine):return(false)
linux:!qtwebengine_checkForHostPkgCfg(QtWebEngine):return(false)
@@ -50,7 +51,7 @@ defineReplace(qtwebengine_checkPdfError) {
!qtwebengine_checkForGperf(QtPdf):return(false)
!qtwebengine_checkForBison(QtPdf):return(false)
!qtwebengine_checkForFlex(QtPdf):return(false)
- !qtwebengine_checkForPython2(QtPdf):return(false)
+ !qtwebengine_checkForPython(QtPdf):return(false)
!qtwebengine_checkForSanitizer(QtPdf):return(false)
linux:!qtwebengine_checkForPkgCfg(QtPdf):return(false)
linux:!qtwebengine_checkForHostPkgCfg(QtPdf):return(false)
@@ -142,10 +143,19 @@ defineTest(qtwebengine_checkForFlex) {
return(true)
}
-defineTest(qtwebengine_checkForPython2) {
+defineTest(qtwebengine_checkForPython) {
module = $$1
- !qtConfig(webengine-python2) {
- qtwebengine_skipBuild("Python version 2 (2.7.5 or later) is required to build $${module}.")
+ !qtConfig(webengine-python) {
+ qtwebengine_skipBuild("Python version 2 (2.7.5 or later) or Python version 3 (3.6 or later) is required to build $${module}.")
+ return(false)
+ }
+ return(true)
+}
+
+defineTest(qtwebengine_checkForNodejs) {
+ module = $$1
+ !qtConfig(webengine-nodejs) {
+ qtwebengine_skipBuild("Nodejs is required to build $${module}.")
return(false)
}
return(true)
diff --git a/src/buildtools/config/windows.pri b/src/buildtools/config/windows.pri
index bd236e1a5..f7b80e6e4 100644
--- a/src/buildtools/config/windows.pri
+++ b/src/buildtools/config/windows.pri
@@ -4,7 +4,6 @@ gn_args += \
use_sysroot=false \
enable_session_service=false \
ninja_use_custom_environment_files=false \
- is_multi_dll_chrome=false \
win_linker_timing=true \
com_init_check_hook_disabled=true \
heterogeneous_executables=true \
@@ -72,7 +71,7 @@ msvc:contains(QT_ARCH, "i386"):!usingMSVC32BitCrossCompiler() {
msvc {
equals(MSVC_VER, 15.0) {
MSVS_VERSION = 2017
- } else: equals(MSVC_VER, 16.0) {
+ } else: versionAtLeast(MSVC_VER, 16.0) {
MSVS_VERSION = 2019
} else {
error("Visual Studio compiler version \"$$MSVC_VER\" is not supported by gn.")
diff --git a/src/buildtools/configure.json b/src/buildtools/configure.json
index 1ca6214a0..5e5d9d725 100644
--- a/src/buildtools/configure.json
+++ b/src/buildtools/configure.json
@@ -10,7 +10,8 @@
"options": {
"build-qtwebengine-core": "boolean",
"build-qtpdf": "boolean",
- "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"}
+ "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"},
+ "webengine-python-version": { "type": "optionalString", "name": "python_override", "values": ["python2", "python3"] }
}
},
"libraries": {
@@ -56,6 +57,12 @@
{ "type": "pkgConfig", "args": "xtst" }
]
},
+ "webengine-xkbfile": {
+ "label": "xkbfile",
+ "sources": [
+ { "type": "pkgConfig", "args": "xkbfile" }
+ ]
+ },
"webengine-nss": {
"label": "nss >= 3.26",
"sources": [
@@ -68,6 +75,12 @@
{ "type": "pkgConfig", "args": "x11" }
]
},
+ "webengine-xproto-gl": {
+ "label": "xproto (glproto)",
+ "sources": [
+ { "type": "pkgConfig", "args": "glproto" }
+ ]
+ },
"webengine-glib": {
"label": "glib-2.0 >= 2.32.0",
"sources": [
@@ -75,9 +88,9 @@
]
},
"webengine-harfbuzz": {
- "label": "harfbuzz >= 2.2.0",
+ "label": "harfbuzz >= 2.4.0",
"sources": [
- { "type": "pkgConfig", "args": "harfbuzz >= 2.2.0" }
+ { "type": "pkgConfig", "args": "harfbuzz >= 2.4.0 harfbuzz-subset >= 2.4.0" }
]
},
"webengine-jpeglib": {
@@ -102,12 +115,6 @@
"-ljpeg"
]
},
- "webengine-jsoncpp": {
- "label": "jsoncpp",
- "sources": [
- { "type": "pkgConfig", "args": "jsoncpp" }
- ]
- },
"webengine-libevent": {
"label": "libevent",
"sources": [
@@ -126,12 +133,6 @@
{ "type": "pkgConfig", "args": "libpng >= 1.6.0" }
]
},
- "webengine-protobuf": {
- "label": "protobuf",
- "sources": [
- { "type": "pkgConfig", "args": "protobuf" }
- ]
- },
"webengine-zlib": {
"label": "zlib",
"sources": [
@@ -155,9 +156,9 @@
]
},
"webengine-icu": {
- "label": "icu >= 64",
+ "label": "icu >= 65",
"sources": [
- { "type": "pkgConfig", "args": "icu-uc >= 64 icu-i18n >= 64" }
+ { "type": "pkgConfig", "args": "icu-uc >= 65 icu-i18n >= 65" }
]
},
"webengine-webp": {
@@ -212,6 +213,27 @@
{ "type": "pkgConfig", "args": "libavcodec libavformat libavutil" }
]
},
+ "webengine-ffmpeg-support": {
+ "label": "compatible ffmpeg",
+ "type": "compile",
+ "test": {
+ "head": [
+ "#include <libavformat/version.h>",
+ "extern \"C\" {",
+ "#include <libavformat/avformat.h>",
+ "}"
+ ],
+ "main": [
+ "#if LIBAVFORMAT_VERSION_MAJOR >= 59",
+ "AVStream stream;",
+ "auto first_dts = av_stream_get_first_dts(&stream);",
+ "#endif"
+ ]
+ },
+ "sources": [
+ { "type": "pkgConfig", "args": "libavformat" }
+ ]
+ },
"webengine-opus": {
"label": "opus",
"sources": [
@@ -238,10 +260,11 @@
"vpx_codec_cx_pkt pkt;",
"pkt.data.frame.width[0] = 0u;",
"pkt.data.frame.height[0] = 0u;",
- "auto a = CONSTRAINED_FROM_ABOVE_DROP;"
+ "auto a = CONSTRAINED_FROM_ABOVE_DROP;",
+ "auto b = VPX_IMG_FMT_NV12;"
]
},
- "headers": [ "vpx/vpx_encoder.h", "vpx/vp8cx.h" ],
+ "headers": [ "vpx/vpx_encoder.h", "vpx/vp8cx.h", "vpx/vpx_image.h" ],
"sources": [
{ "type": "pkgConfig", "args": "vpx" },
"-lvpx"
@@ -294,7 +317,7 @@
"label": "system ninja",
"type": "detectNinja"
},
- "webengine-python2": {
+ "webengine-python": {
"label": "python2",
"type": "detectPython2",
"log": "location"
@@ -320,10 +343,6 @@
"type": "detectJumboBuild",
"log": "merge_limit"
},
- "webengine-protoc": {
- "label": "protoc",
- "type": "detectProtoc"
- },
"webengine-win-compiler64": {
"label": "64bit compiler",
"type": "isWindowsHostCompiler64"
@@ -357,6 +376,11 @@
"label": "linker supports -z noexecstack",
"type": "linkerSupportsFlag",
"flag": "-z,noexecstack"
+ },
+ "webengine-nodejs": {
+ "label": "node.js",
+ "type": "detectNodeJS",
+ "log": "version10"
}
},
"features": {
@@ -372,7 +396,8 @@
&& features.webengine-gperf
&& features.webengine-bison
&& features.webengine-flex
- && features.webengine-python2
+ && features.webengine-python
+ && features.webengine-nodejs
&& (!config.sanitizer || features.webengine-sanitizer)
&& (!config.linux || features.pkg-config)
&& (!config.linux || features.webengine-host-pkg-config)
@@ -397,7 +422,7 @@
&& features.webengine-gperf
&& features.webengine-bison
&& features.webengine-flex
- && features.webengine-python2
+ && features.webengine-python
&& (!config.sanitizer || features.webengine-sanitizer)
&& (!config.linux || features.pkg-config)
&& (!config.linux || features.webengine-host-pkg-config)
@@ -420,12 +445,12 @@
"autoDetect": "features.private_tests",
"output": [ "privateFeature" ]
},
- "webengine-python2": {
+ "webengine-python": {
"label": "python2",
- "condition": "tests.webengine-python2",
+ "condition": "tests.webengine-python",
"output": [
"privateFeature",
- { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" }
+ { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python.location" }
]
},
"webengine-gperf": {
@@ -443,6 +468,16 @@
"condition": "tests.webengine-flex",
"output": [ "privateFeature" ]
},
+ "webengine-nodejs": {
+ "label": "node.js",
+ "condition": "tests.webengine-nodejs",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-nodejs10": {
+ "label": "node.js",
+ "condition": "tests.webengine-nodejs && tests.webengine-nodejs.version10",
+ "output": [ "privateFeature" ]
+ },
"webengine-system-ninja": {
"label": "Use System Ninja",
"condition": "tests.webengine-ninja",
@@ -483,6 +518,11 @@
"condition": "libs.webengine-xtst",
"output": [ "privateFeature" ]
},
+ "webengine-system-xkbfile": {
+ "label": "xkbfile",
+ "condition": "libs.webengine-xkbfile",
+ "output": [ "privateFeature" ]
+ },
"webengine-system-gn": {
"label": "Use System Gn",
"autoDetect": "false",
@@ -509,6 +549,11 @@
"condition": "config.unix && libs.webengine-x11",
"output": [ "privateFeature" ]
},
+ "webengine-system-xproto-gl" : {
+ "label": "xproto (glproto)",
+ "condition": "config.unix && libs.webengine-xproto-gl",
+ "output": [ "privateFeature" ]
+ },
"webengine-host-pkg-config": {
"label": "host-pkg-config",
"condition": "config.unix && tests.webengine-host-pkg-config",
@@ -525,7 +570,9 @@
&& features.webengine-system-xcomposite
&& features.webengine-system-xcursor
&& features.webengine-system-xi
- && features.webengine-system-xtst",
+ && features.webengine-system-xproto-gl
+ && features.webengine-system-xtst
+ && features.webengine-system-xkbfile",
"output": [ "privateFeature" ]
},
"webengine-jumbo-build": {
@@ -541,6 +588,11 @@
"condition": "config.unix && features.system-harfbuzz && libs.webengine-harfbuzz",
"output": [ "privateFeature" ]
},
+ "webengine-qt-harfbuzz" : {
+ "label": "qtharfbuzz",
+ "condition": "config.static && !features.system-harfbuzz && features.harfbuzz",
+ "output": [ "privateFeature" ]
+ },
"webengine-system-glib" : {
"label": "glib",
"condition": "config.unix && libs.webengine-glib",
@@ -556,31 +608,36 @@
"condition": "config.unix && features.system-zlib && libs.webengine-zlib",
"output": [ "privateFeature" ]
},
+ "webengine-qt-zlib" : {
+ "label": "QtZlib",
+ "condition": "config.static && !features.system-zlib",
+ "output": [ "privateFeature" ]
+ },
"webengine-system-libevent" : {
"label": "libevent",
"condition": "config.unix && libs.webengine-libevent",
"output": [ "privateFeature" ]
},
- "webengine-system-jsoncpp" : {
- "label": "jsoncpp",
- "condition": "config.unix && libs.webengine-jsoncpp",
- "output": [ "privateFeature" ]
- },
- "webengine-system-protobuf" : {
- "label": "protobuf",
- "condition": "config.unix && libs.webengine-protobuf && tests.webengine-protoc",
- "output": [ "privateFeature" ]
- },
"webengine-system-png" : {
"label": "png",
"condition": "config.unix && features.system-png && libs.webengine-png",
"output": [ "privateFeature" ]
},
+ "webengine-qt-png" : {
+ "label": "qtlibpng",
+ "condition" : "config.static && !features.system-png && features.png",
+ "output": [ "privateFeature" ]
+ },
"webengine-system-jpeg" : {
"label": "JPEG",
"condition": "config.unix && features.system-jpeg && libs.webengine-jpeglib",
"output": [ "privateFeature" ]
},
+ "webengine-qt-jpeg" : {
+ "label": "qtlibjpeg",
+ "condition": "config.static && !features.system-jpeg && features.jpeg",
+ "output": [ "privateFeature" ]
+ },
"webengine-system-re2": {
"label": "re2",
"condition": "config.unix && libs.webengine-re2",
@@ -623,6 +680,11 @@
"condition": "config.unix && features.system-freetype && libs.webengine-freetype",
"output": [ "privateFeature" ]
},
+ "webengine-qt-freetype" : {
+ "label": "qtfreetype",
+ "condition": "config.static && !features.system-freetype && features.freetype",
+ "output": [ "privateFeature" ]
+ },
"webengine-system-libvpx" : {
"label": "libvpx",
"condition": "config.unix && libs.webengine-libvpx",
@@ -718,6 +780,11 @@
"type": "warning",
"condition": "config.ios && config.simulator && config.device && features.build-qtpdf",
"message": "Building fat libray with device and simulator architectures will disable NEON."
+ },
+ {
+ "type": "fatal",
+ "condition": "features.webengine-system-ffmpeg && !libs.webengine-ffmpeg-support",
+ "message": "Unmodified ffmpeg >= 5.0 is not supported. Please configure with -qt-webengine-ffmpeg."
}
],
"summary": [
@@ -725,7 +792,6 @@
"section": "Qt WebEngine Build Tools",
"entries": [
"webengine-system-ninja",
- "webengine-system-gn",
{
"message": "Jumbo Build Merge Limit",
"type": "jumboBuild"
@@ -756,7 +822,9 @@
"webengine-system-xcomposite",
"webengine-system-xcursor",
"webengine-system-xi",
- "webengine-system-xtst"
+ "webengine-system-xproto-gl",
+ "webengine-system-xtst",
+ "webengine-system-xkbfile"
]
},
{
@@ -774,8 +842,6 @@
"webengine-system-zlib",
"webengine-system-minizip",
"webengine-system-libevent",
- "webengine-system-jsoncpp",
- "webengine-system-protobuf",
"webengine-system-libxml2",
"webengine-system-lcms2",
"webengine-system-png",
@@ -783,6 +849,17 @@
"webengine-system-harfbuzz",
"webengine-system-freetype"
]
+ },
+ {
+ "section": "Qt 3rdparty libs",
+ "condition": "config.static",
+ "entries": [
+ "webengine-qt-freetype",
+ "webengine-qt-harfbuzz",
+ "webengine-qt-png",
+ "webengine-qt-jpeg",
+ "webengine-qt-zlib"
+ ]
}
]
}
diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro
index 033202e6e..f94694da0 100644
--- a/src/buildtools/gn.pro
+++ b/src/buildtools/gn.pro
@@ -21,6 +21,7 @@ build_pass|!debug_and_release {
gn_gen_args = --no-last-commit-position --out-path $$out_path \
--cc \"$$which($$QMAKE_CC)\" --cxx \"$$which($$QMAKE_CXX)\" \
--ld \"$$which($$QMAKE_LINK)\"
+ !isEmpty(QMAKE_AR): gn_gen_args += --ar \"$$which($$first(QMAKE_AR))\"
msvc:!clang_cl: gn_gen_args += --use-lto
diff --git a/src/core/accessibility_activation_observer.cpp b/src/core/accessibility_activation_observer.cpp
index 833190844..b9d73cb68 100644
--- a/src/core/accessibility_activation_observer.cpp
+++ b/src/core/accessibility_activation_observer.cpp
@@ -48,12 +48,13 @@ 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.
+ // On Linux accessibility can be disabled due to performance issues by setting the
+ // QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment variable to 0. For details,
+ // see QTBUG-59922.
#ifdef Q_OS_LINUX
static bool accessibility_enabled
- = qEnvironmentVariableIsSet("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY");
+ = qEnvironmentVariable("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY", QLatin1String("1"))
+ == QLatin1String("1");
#else
const bool accessibility_enabled = true;
#endif
diff --git a/src/core/accessibility_tree_formatter_qt.cpp b/src/core/accessibility_tree_formatter_qt.cpp
index 081856b37..51d33534b 100644
--- a/src/core/accessibility_tree_formatter_qt.cpp
+++ b/src/core/accessibility_tree_formatter_qt.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "content/browser/accessibility/accessibility_tree_formatter_browser.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_base.h"
#include <utility>
@@ -53,19 +53,26 @@
namespace content {
#if QT_CONFIG(accessibility)
-class AccessibilityTreeFormatterQt : public AccessibilityTreeFormatterBrowser {
+class AccessibilityTreeFormatterQt : public AccessibilityTreeFormatterBase {
public:
explicit AccessibilityTreeFormatterQt();
~AccessibilityTreeFormatterQt() override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForSelector(const content::AccessibilityTreeFormatter::TreeSelector &)
+ { return nullptr; }
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForWindow(gfx::AcceleratedWidget) override { return nullptr; }
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree(content::BrowserAccessibility *) override;
+
private:
base::FilePath::StringType GetExpectedFileSuffix() override;
const std::string GetAllowEmptyString() override;
const std::string GetAllowString() override;
const std::string GetDenyString() override;
const std::string GetDenyNodeString() override;
- void AddProperties(const BrowserAccessibility &node, base::DictionaryValue* dict) override;
- base::string16 ProcessTreeForOutput(const base::DictionaryValue &node, base::DictionaryValue * = nullptr) override;
+ const std::string GetRunUntilEventString() override;
+ void RecursiveBuildAccessibilityTree(const content::BrowserAccessibility &node, base::DictionaryValue *dict) const;
+ void AddProperties(const BrowserAccessibility &node, base::DictionaryValue *dict) const;
+ std::string ProcessTreeForOutput(const base::DictionaryValue &node, base::DictionaryValue * = nullptr) override;
};
AccessibilityTreeFormatterQt::AccessibilityTreeFormatterQt()
@@ -76,7 +83,30 @@ AccessibilityTreeFormatterQt::~AccessibilityTreeFormatterQt()
{
}
-void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &node, base::DictionaryValue *dict)
+std::unique_ptr<base::DictionaryValue> AccessibilityTreeFormatterQt::BuildAccessibilityTree(content::BrowserAccessibility *root)
+{
+ std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
+ RecursiveBuildAccessibilityTree(*root, dict.get());
+ return dict;
+}
+
+void AccessibilityTreeFormatterQt::RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::DictionaryValue *dict) const
+{
+ AddProperties(node, dict);
+
+ auto children = std::make_unique<base::ListValue>();
+ for (size_t i = 0; i < node.PlatformChildCount(); ++i) {
+ std::unique_ptr<base::DictionaryValue> child_dict(new base::DictionaryValue);
+
+ content::BrowserAccessibility *child_node = node.PlatformGetChild(i);
+
+ RecursiveBuildAccessibilityTree(*child_node, child_dict.get());
+ children->Append(std::move(child_dict));
+ }
+ dict->Set(kChildrenDictAttr, std::move(children));
+}
+
+void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &node, base::DictionaryValue *dict) const
{
dict->SetInteger("id", node.GetId());
const BrowserAccessibilityQt *acc_node = ToBrowserAccessibilityQt(&node);
@@ -142,13 +172,13 @@ void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &nod
dict->SetString("description", acc_node->text(QAccessible::Description).toStdString());
}
-base::string16 AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::DictionaryValue &node, base::DictionaryValue *)
+std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::DictionaryValue &node, base::DictionaryValue *)
{
- base::string16 error_value;
+ std::string error_value;
if (node.GetString("error", &error_value))
return error_value;
- base::string16 line;
+ std::string line;
std::string role_value;
node.GetString("role", &role_value);
if (!role_value.empty())
@@ -176,7 +206,7 @@ base::string16 AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::Di
node.GetInteger("id", &id_value);
WriteAttribute(false, base::StringPrintf("id=%d", id_value), &line);
- return line + base::ASCIIToUTF16("\n");
+ return line + "\n";
}
base::FilePath::StringType AccessibilityTreeFormatterQt::GetExpectedFileSuffix()
@@ -204,6 +234,11 @@ const std::string AccessibilityTreeFormatterQt::GetDenyNodeString()
return "@QT-DENY-NODE:";
}
+const std::string AccessibilityTreeFormatterQt::GetRunUntilEventString()
+{
+ return "@QT-RUN-UNTIL-EVENT:";
+}
+
#endif // QT_CONFIG(accessibility)
// static
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index d53fb6942..28d5586ba 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -23,9 +23,15 @@ DEFINES += \
NOMINMAX
CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
-CHROMIUM_GEN_DIR = $$OUT_PWD/../$$getConfigDir()/gen
+
+isUniversal() {
+ CHROMIUM_GEN_DIR = $$OUT_PWD/../$$QT_ARCH/$$getConfigDir()/gen
+} else {
+ CHROMIUM_GEN_DIR = $$OUT_PWD/../$$getConfigDir()/gen
+}
INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core \
$$CHROMIUM_GEN_DIR \
+ $$CHROMIUM_SRC_DIR/third_party/abseil-cpp \
$$CHROMIUM_SRC_DIR
gcc: QMAKE_CXXFLAGS_WARN_ON = -Wno-unused-parameter
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index 3c9387a10..f51aa25c3 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -50,6 +50,7 @@
#endif
#endif
#include <QThread>
+#include "web_engine_context.h"
#if QT_CONFIG(opengl)
QT_BEGIN_NAMESPACE
@@ -184,4 +185,10 @@ Q_WEBENGINECORE_PRIVATE_EXPORT void initialize()
app->setAttribute(Qt::AA_ShareOpenGLContexts);
#endif // QT_CONFIG(opengl)
}
+
+bool closingDown()
+{
+ return WebEngineContext::closingDown();
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/api/qtwebenginecoreglobal_p.h b/src/core/api/qtwebenginecoreglobal_p.h
index 655b2a814..3a3496e04 100644
--- a/src/core/api/qtwebenginecoreglobal_p.h
+++ b/src/core/api/qtwebenginecoreglobal_p.h
@@ -65,4 +65,7 @@
#define Q_WEBENGINECORE_PRIVATE_EXPORT Q_WEBENGINECORE_EXPORT
+namespace QtWebEngineCore {
+Q_WEBENGINECORE_PRIVATE_EXPORT bool closingDown();
+} // namespace
#endif // QTWEBENGINECOREGLOBAL_P_H
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
index 21e44d2f1..7c12f1861 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -47,8 +47,6 @@
namespace QtWebEngineCore {
class InterceptedRequest;
-class NetworkDelegateQt;
-class URLRequestNotification;
} // namespace QtWebEngineCore
QT_BEGIN_NAMESPACE
@@ -109,8 +107,6 @@ public:
void setHttpHeader(const QByteArray &name, const QByteArray &value);
private:
- friend class QtWebEngineCore::NetworkDelegateQt;
- friend class QtWebEngineCore::URLRequestNotification;
friend class QtWebEngineCore::InterceptedRequest;
Q_DISABLE_COPY(QWebEngineUrlRequestInfo)
Q_DECLARE_PRIVATE(QWebEngineUrlRequestInfo)
diff --git a/src/core/api/qwebengineurlschemehandler.h b/src/core/api/qwebengineurlschemehandler.h
index 09c5b08cb..4574bf8b0 100644
--- a/src/core/api/qwebengineurlschemehandler.h
+++ b/src/core/api/qwebengineurlschemehandler.h
@@ -44,10 +44,6 @@
#include <QtCore/qobject.h>
-namespace QtWebEngineCore {
-class URLRequestContextGetterQt;
-}
-
QT_BEGIN_NAMESPACE
class QWebEngineUrlRequestJob;
diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp
index 5968bfd30..1d635a6e9 100644
--- a/src/core/browser_accessibility_manager_qt.cpp
+++ b/src/core/browser_accessibility_manager_qt.cpp
@@ -48,13 +48,11 @@ namespace content {
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
const ui::AXTreeUpdate& initialTree,
- BrowserAccessibilityDelegate* delegate,
- BrowserAccessibilityFactory* factory)
+ BrowserAccessibilityDelegate* delegate)
{
#if QT_CONFIG(accessibility)
- return new BrowserAccessibilityManagerQt(nullptr, initialTree, delegate, factory);
+ return new BrowserAccessibilityManagerQt(nullptr, initialTree, delegate);
#else
- delete factory;
return nullptr;
#endif // QT_CONFIG(accessibility)
}
@@ -71,8 +69,8 @@ BrowserAccessibility *BrowserAccessibility::Create()
#if QT_CONFIG(accessibility)
BrowserAccessibilityManagerQt::BrowserAccessibilityManagerQt(
QObject *parentObject, const ui::AXTreeUpdate &initialTree,
- BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory)
- : BrowserAccessibilityManager(delegate, factory)
+ BrowserAccessibilityDelegate* delegate)
+ : BrowserAccessibilityManager(delegate)
, m_parentObject(parentObject)
{
Initialize(initialTree);
diff --git a/src/core/browser_accessibility_manager_qt.h b/src/core/browser_accessibility_manager_qt.h
index 6d6086811..600ad673c 100644
--- a/src/core/browser_accessibility_manager_qt.h
+++ b/src/core/browser_accessibility_manager_qt.h
@@ -56,10 +56,9 @@ namespace content {
class BrowserAccessibilityManagerQt : public BrowserAccessibilityManager
{
public:
- BrowserAccessibilityManagerQt(QObject* parentObject,
- const ui::AXTreeUpdate& initialTree,
- BrowserAccessibilityDelegate* delegate,
- BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
+ BrowserAccessibilityManagerQt(QObject *parentObject,
+ const ui::AXTreeUpdate &initialTree,
+ BrowserAccessibilityDelegate *delegate);
~BrowserAccessibilityManagerQt() override;
void FireBlinkEvent(ax::mojom::Event event_type,
BrowserAccessibility* node) override;
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index f4fe2f694..fabad0609 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -79,7 +79,7 @@ bool BrowserAccessibilityQt::isValid() const
QObject *BrowserAccessibilityQt::object() const
{
- return 0;
+ return nullptr;
}
QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const
@@ -90,7 +90,7 @@ QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const
if (childIface->rect().contains(x,y))
return childIface;
}
- return 0;
+ return nullptr;
}
void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
@@ -132,7 +132,7 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
default:
break;
}
- return 0;
+ return nullptr;
}
QAccessibleInterface *BrowserAccessibilityQt::parent() const
@@ -209,6 +209,13 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kUnknown:
return QAccessible::NoRole;
+ // Internal roles (matching auralinux and win)
+ case ax::mojom::Role::kKeyboard:
+ case ax::mojom::Role::kIgnored:
+ case ax::mojom::Role::kImeCandidate:
+ case ax::mojom::Role::kPresentational:
+ return QAccessible::NoRole;
+
// Used by Chromium to distinguish between the root of the tree
// for this page, and a web area for a frame within this page.
case ax::mojom::Role::kWebArea:
@@ -376,8 +383,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::WebDocument;
case ax::mojom::Role::kIframePresentational:
return QAccessible::Grouping;
- case ax::mojom::Role::kIgnored:
- return QAccessible::NoRole;
case ax::mojom::Role::kImage:
return QAccessible::Graphic;
case ax::mojom::Role::kImageMap:
@@ -386,8 +391,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::StaticText;
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:
@@ -432,8 +435,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::CheckBox;
case ax::mojom::Role::kMenuItemRadio:
return QAccessible::RadioButton;
- case ax::mojom::Role::kMenuButton:
- return QAccessible::MenuItem;
case ax::mojom::Role::kMenuListOption:
return QAccessible::MenuItem;
case ax::mojom::Role::kMenuListPopup:
@@ -458,8 +459,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Button;
case ax::mojom::Role::kPre:
return QAccessible::Section;
- case ax::mojom::Role::kPresentational:
- return QAccessible::NoRole; // FIXME
case ax::mojom::Role::kProgressIndicator:
return QAccessible::ProgressBar;
case ax::mojom::Role::kRadioButton:
@@ -646,16 +645,7 @@ QAccessible::State BrowserAccessibilityQt::state() const
return state;
}
-// Qt does not reference count accessibles
-void BrowserAccessibilityQt::NativeAddReference()
-{
-}
-
-// there is no reference counting, but BrowserAccessibility::Destroy
-// calls this (and that is the only place in the chromium sources,
-// so we can safely use it to dispose of ourselves here
-// (the default implementation of this function just contains a "delete this")
-void BrowserAccessibilityQt::NativeReleaseReference()
+void BrowserAccessibilityQt::Destroy()
{
// delete this
QAccessible::Id interfaceId = QAccessible::uniqueId(this);
@@ -987,7 +977,7 @@ QAccessibleInterface *BrowserAccessibilityQt::table() const
while (find_table && find_table->GetRole() != ax::mojom::Role::kTable)
find_table = find_table->PlatformGetParent();
if (!find_table)
- return 0;
+ return nullptr;
return static_cast<BrowserAccessibilityQt*>(find_table);
}
diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h
index 19c7a1e54..32a4fc76b 100644
--- a/src/core/browser_accessibility_qt.h
+++ b/src/core/browser_accessibility_qt.h
@@ -80,9 +80,7 @@ public:
QAccessible::State state() const override;
// BrowserAccessible
- void NativeAddReference() override;
- void NativeReleaseReference() override;
- bool IsNative() const override { return true; }
+ void Destroy() override;
// QAccessibleActionInterface
QStringList actionNames() const override;
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index c1f4cbb2d..bc0499bca 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -41,10 +41,9 @@
#include "api/qwebenginemessagepumpscheduler_p.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_current.h"
#include "base/message_loop/message_pump_for_ui.h"
#include "base/process/process.h"
+#include "base/task/current_thread.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/threading/thread_restrictions.h"
@@ -60,10 +59,12 @@
#include "content/public/common/service_manager_connection.h"
#include "extensions/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "content/public/browser/plugin_service.h"
#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 "extensions/plugin_service_filter_qt.h"
#include "common/extensions/extensions_client_qt.h"
#endif //BUILDFLAG(ENABLE_EXTENSIONS)
#include "services/service_manager/public/cpp/connector.h"
@@ -79,7 +80,7 @@
#include <QOpenGLContext>
#endif
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
#include "base/message_loop/message_pump_mac.h"
#include "ui/base/idle/idle.h"
#endif
@@ -150,7 +151,7 @@ private:
void ensureDelegate()
{
if (!m_delegate) {
- auto seqMan = base::MessageLoopCurrent::GetCurrentSequenceManagerImpl();
+ auto seqMan = base::CurrentThread::Get()->GetCurrentSequenceManagerImpl();
m_delegate = static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
seqMan->controller_.get());
}
@@ -226,7 +227,7 @@ std::unique_ptr<base::MessagePump> messagePumpFactory()
madePrimaryPump = true;
return std::make_unique<MessagePumpForUIQt>();
}
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
return base::MessagePumpMac::Create();
#else
return std::make_unique<base::MessagePumpForUI>();
@@ -251,6 +252,9 @@ void BrowserMainPartsQt::PreMainMessageLoopRun()
extensions::ExtensionsClient::Set(new extensions::ExtensionsClientQt());
extensions::ExtensionsBrowserClient::Set(new extensions::ExtensionsBrowserClientQt());
extensions::ExtensionSystemFactoryQt::GetInstance();
+
+ content::PluginService *plugin_service = content::PluginService::GetInstance();
+ plugin_service->SetFilter(extensions::PluginServiceFilterQt::GetInstance());
#endif //ENABLE_EXTENSIONS
}
@@ -269,7 +273,7 @@ int BrowserMainPartsQt::PreCreateThreads()
{
base::ThreadRestrictions::SetIOAllowed(true);
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
ui::InitIdleMonitor();
#endif
diff --git a/src/core/browser_message_filter_qt.cpp b/src/core/browser_message_filter_qt.cpp
index a4b75f075..54d6551e4 100644
--- a/src/core/browser_message_filter_qt.cpp
+++ b/src/core/browser_message_filter_qt.cpp
@@ -64,90 +64,77 @@ BrowserMessageFilterQt::BrowserMessageFilterQt(int /*render_process_id*/, Profil
bool BrowserMessageFilterQt::OnMessageReceived(const IPC::Message& message)
{
IPC_BEGIN_MESSAGE_MAP(BrowserMessageFilterQt, message)
- IPC_MESSAGE_HANDLER(QtWebEngineHostMsg_AllowDatabase, OnAllowDatabase)
- IPC_MESSAGE_HANDLER(QtWebEngineHostMsg_AllowDOMStorage, OnAllowDOMStorage)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(QtWebEngineHostMsg_RequestFileSystemAccessSync,
- OnRequestFileSystemAccessSync)
- IPC_MESSAGE_HANDLER(QtWebEngineHostMsg_RequestFileSystemAccessAsync,
- OnRequestFileSystemAccessAsync)
- IPC_MESSAGE_HANDLER(QtWebEngineHostMsg_AllowIndexedDB, OnAllowIndexedDB)
+ IPC_MESSAGE_HANDLER(QtWebEngineHostMsg_AllowStorageAccess, OnAllowStorageAccess)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(QtWebEngineHostMsg_RequestStorageAccessSync,
+ OnRequestStorageAccessSync)
+ IPC_MESSAGE_HANDLER(QtWebEngineHostMsg_RequestStorageAccessAsync,
+ OnRequestStorageAccessAsync)
IPC_MESSAGE_UNHANDLED(return false)
IPC_END_MESSAGE_MAP()
return true;
}
-void BrowserMessageFilterQt::OnAllowDatabase(int /*render_frame_id*/,
- const GURL &origin_url,
- const GURL &top_origin_url,
- bool* allowed)
+void BrowserMessageFilterQt::OnAllowStorageAccess(int /*render_frame_id*/,
+ const GURL &origin_url,
+ const GURL &top_origin_url,
+ int /*storage_type*/,
+ bool *allowed)
{
*allowed = m_profileData->canGetCookies(toQt(top_origin_url), toQt(origin_url));
}
-void BrowserMessageFilterQt::OnAllowDOMStorage(int /*render_frame_id*/,
- const GURL &origin_url,
- const GURL &top_origin_url,
- bool /*local*/,
- bool *allowed)
-{
- *allowed = m_profileData->canGetCookies(toQt(top_origin_url), toQt(origin_url));
-}
-
-void BrowserMessageFilterQt::OnAllowIndexedDB(int /*render_frame_id*/,
- const GURL &origin_url,
- const GURL &top_origin_url,
- bool *allowed)
-{
- *allowed = m_profileData->canGetCookies(toQt(top_origin_url), toQt(origin_url));
-}
-
-void BrowserMessageFilterQt::OnRequestFileSystemAccessSync(int render_frame_id,
- const GURL& origin_url,
- const GURL& top_origin_url,
- IPC::Message* reply_msg)
+void BrowserMessageFilterQt::OnRequestStorageAccessSync(int render_frame_id,
+ const GURL& origin_url,
+ const GURL& top_origin_url,
+ int storage_type,
+ IPC::Message* reply_msg)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
base::Callback<void(bool)> callback = base::Bind(
- &BrowserMessageFilterQt::OnRequestFileSystemAccessSyncResponse,
+ &BrowserMessageFilterQt::OnRequestStorageAccessSyncResponse,
base::WrapRefCounted(this), reply_msg);
- OnRequestFileSystemAccess(render_frame_id,
- origin_url,
- top_origin_url,
- callback);
+ OnRequestStorageAccess(render_frame_id,
+ origin_url,
+ top_origin_url,
+ storage_type,
+ callback);
}
-void BrowserMessageFilterQt::OnRequestFileSystemAccessSyncResponse(IPC::Message *reply_msg, bool allowed)
+void BrowserMessageFilterQt::OnRequestStorageAccessSyncResponse(IPC::Message *reply_msg, bool allowed)
{
- QtWebEngineHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg, allowed);
+ QtWebEngineHostMsg_RequestStorageAccessSync::WriteReplyParams(reply_msg, allowed);
Send(reply_msg);
}
-void BrowserMessageFilterQt::OnRequestFileSystemAccessAsync(int render_frame_id,
- int request_id,
- const GURL& origin_url,
- const GURL& top_origin_url)
+void BrowserMessageFilterQt::OnRequestStorageAccessAsync(int render_frame_id,
+ int request_id,
+ const GURL& origin_url,
+ const GURL& top_origin_url,
+ int storage_type)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
base::Callback<void(bool)> callback = base::Bind(
- &BrowserMessageFilterQt::OnRequestFileSystemAccessAsyncResponse,
+ &BrowserMessageFilterQt::OnRequestStorageAccessAsyncResponse,
base::WrapRefCounted(this), render_frame_id, request_id);
- OnRequestFileSystemAccess(render_frame_id,
- origin_url,
- top_origin_url,
- callback);
+ OnRequestStorageAccess(render_frame_id,
+ origin_url,
+ top_origin_url,
+ storage_type,
+ callback);
}
-void BrowserMessageFilterQt::OnRequestFileSystemAccessAsyncResponse(int render_frame_id,
- int request_id,
- bool allowed)
+void BrowserMessageFilterQt::OnRequestStorageAccessAsyncResponse(int render_frame_id,
+ int request_id,
+ bool allowed)
{
- Send(new QtWebEngineMsg_RequestFileSystemAccessAsyncResponse(render_frame_id, request_id, allowed));
+ Send(new QtWebEngineMsg_RequestStorageAccessAsyncResponse(render_frame_id, request_id, allowed));
}
-void BrowserMessageFilterQt::OnRequestFileSystemAccess(int /*render_frame_id*/,
- const GURL &origin_url,
- const GURL &top_origin_url,
- base::Callback<void(bool)> callback)
+void BrowserMessageFilterQt::OnRequestStorageAccess(int /*render_frame_id*/,
+ const GURL &origin_url,
+ const GURL &top_origin_url,
+ int /*storage_type*/,
+ base::Callback<void(bool)> callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
bool allowed = m_profileData->canGetCookies(toQt(top_origin_url), toQt(origin_url));
diff --git a/src/core/browser_message_filter_qt.h b/src/core/browser_message_filter_qt.h
index 4abc612f8..85de0486a 100644
--- a/src/core/browser_message_filter_qt.h
+++ b/src/core/browser_message_filter_qt.h
@@ -42,7 +42,6 @@
#include "base/callback.h"
#include "content/public/browser/browser_message_filter.h"
-#include "content/public/common/webplugininfo.h"
class GURL;
class Profile;
@@ -59,39 +58,33 @@ public:
private:
bool OnMessageReceived(const IPC::Message& message) override;
- void OnAllowDatabase(int render_frame_id,
- const GURL &origin_url,
- const GURL &top_origin_url,
- bool *allowed);
- void OnAllowDOMStorage(int render_frame_id,
- const GURL &origin_url,
- const GURL &top_origin_url,
- bool local,
- bool *allowed);
+ void OnAllowStorageAccess(int render_frame_id,
+ const GURL &origin_url,
+ const GURL &top_origin_url,
+ int storage_type,
+ bool *allowed);
- void OnAllowIndexedDB(int render_frame_id,
- const GURL &origin_url,
- const GURL &top_origin_url,
- bool *allowed);
-
- void OnRequestFileSystemAccessSync(int render_frame_id,
- const GURL &origin_url,
- const GURL &top_origin_url,
- IPC::Message *message);
- void OnRequestFileSystemAccessAsync(int render_frame_id,
- int request_id,
- const GURL &origin_url,
- const GURL &top_origin_url);
- void OnRequestFileSystemAccessSyncResponse(IPC::Message *reply_msg,
- bool allowed);
- void OnRequestFileSystemAccessAsyncResponse(int render_frame_id,
- int request_id,
- bool allowed);
- void OnRequestFileSystemAccess(int render_frame_id,
- const GURL &origin_url,
- const GURL &top_origin_url,
- base::Callback<void(bool)> callback);
+ void OnRequestStorageAccessSync(int render_frame_id,
+ const GURL &origin_url,
+ const GURL &top_origin_url,
+ int storage_type,
+ IPC::Message *message);
+ void OnRequestStorageAccessAsync(int render_frame_id,
+ int request_id,
+ const GURL &origin_url,
+ const GURL &top_origin_url,
+ int storage_type);
+ void OnRequestStorageAccessSyncResponse(IPC::Message *reply_msg,
+ bool allowed);
+ void OnRequestStorageAccessAsyncResponse(int render_frame_id,
+ int request_id,
+ bool allowed);
+ void OnRequestStorageAccess(int render_frame_id,
+ const GURL &origin_url,
+ const GURL &top_origin_url,
+ int storage_type,
+ base::Callback<void(bool)> callback);
ProfileIODataQt *m_profileData;
};
diff --git a/src/core/browsing_data_remover_delegate_qt.cpp b/src/core/browsing_data_remover_delegate_qt.cpp
index 344ba817f..6e79ab6c6 100644
--- a/src/core/browsing_data_remover_delegate_qt.cpp
+++ b/src/core/browsing_data_remover_delegate_qt.cpp
@@ -48,7 +48,7 @@
namespace QtWebEngineCore {
-bool DoesOriginMatchEmbedderMask(int origin_type_mask,
+bool DoesOriginMatchEmbedderMask(uint64_t origin_type_mask,
const url::Origin &origin,
storage::SpecialStoragePolicy *policy)
{
@@ -70,10 +70,10 @@ bool BrowsingDataRemoverDelegateQt::MayRemoveDownloadHistory()
void BrowsingDataRemoverDelegateQt::RemoveEmbedderData(const base::Time &delete_begin,
const base::Time &delete_end,
- int remove_mask,
+ uint64_t remove_mask,
content::BrowsingDataFilterBuilder *filter_builder,
- int origin_type_mask,
- base::OnceClosure callback)
+ uint64_t origin_type_mask,
+ base::OnceCallback<void(/*failed_data_types=*/uint64_t)> callback)
{
Q_UNUSED(delete_begin);
Q_UNUSED(delete_end);
@@ -83,7 +83,12 @@ void BrowsingDataRemoverDelegateQt::RemoveEmbedderData(const base::Time &delete_
if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_CACHE)
web_cache::WebCacheManager::GetInstance()->ClearCache();
- std::move(callback).Run();
+ std::move(callback).Run(0);
+}
+
+std::vector<std::string> BrowsingDataRemoverDelegateQt::GetDomainsForDeferredCookieDeletion(uint64_t)
+{
+ return {};
}
} // namespace QtWebEngineCore
diff --git a/src/core/browsing_data_remover_delegate_qt.h b/src/core/browsing_data_remover_delegate_qt.h
index dc2761ffc..5adfbbe7e 100644
--- a/src/core/browsing_data_remover_delegate_qt.h
+++ b/src/core/browsing_data_remover_delegate_qt.h
@@ -40,6 +40,8 @@
#ifndef BROWSING_DATA_REMOVER_DELEGATE_QT_H
#define BROWSING_DATA_REMOVER_DELEGATE_QT_H
+#include <cstdint>
+
#include "content/public/browser/browsing_data_remover_delegate.h"
namespace QtWebEngineCore {
@@ -55,10 +57,11 @@ public:
void RemoveEmbedderData(
const base::Time &delete_begin,
const base::Time &delete_end,
- int remove_mask,
+ uint64_t remove_mask,
content::BrowsingDataFilterBuilder *filter_builder,
- int origin_type_mask,
- base::OnceClosure callback) override;
+ uint64_t origin_type_mask,
+ base::OnceCallback<void(/*failed_data_types=*/uint64_t)> callback) override;
+ std::vector<std::string> GetDomainsForDeferredCookieDeletion(uint64_t) override;
};
} // namespace QtWebEngineCore
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 01937d3e7..8a385e4a8 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -43,7 +43,6 @@
#include "base/values.h"
#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
-#include "content/browser/accessibility/accessibility_tree_formatter_browser.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/font_list.h"
@@ -51,7 +50,6 @@
#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>
@@ -63,7 +61,6 @@
#if defined(USE_AURA) && !defined(USE_OZONE)
#include "ui/base/dragdrop/os_exchange_data.h"
-#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
#include "ui/gfx/render_text.h"
#include "ui/gfx/platform_font.h"
#endif
@@ -72,6 +69,10 @@
#include "net/ssl/openssl_client_key_store.h"
#endif
+#if !QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+#include "chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h"
+#endif
+
void *GetQtXDisplay()
{
return GLContextHelper::getXDisplay();
@@ -148,54 +149,81 @@ std::vector<AccessibilityTreeFormatter::TestPass> AccessibilityTreeFormatter::Ge
}
} // namespace content
-#if defined(USE_AURA)
-namespace ui {
+std::unique_ptr<ui::OSExchangeDataProvider> ui::OSExchangeDataProviderFactory::CreateProvider()
+{
+ return nullptr;
+}
-bool GrabWindowSnapshot(gfx::NativeWindow window,
- const gfx::Rect& snapshot_bounds,
- gfx::Image* image)
+#if !QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+namespace extensions {
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateSetMetaDataFunction::Run()
{
- NOTIMPLEMENTED();
- return false;
+ return RespondNow(NoArguments());
}
-bool GrabViewSnapshot(gfx::NativeView view,
- const gfx::Rect& snapshot_bounds,
- gfx::Image* image)
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStartFunction::Run()
{
- NOTIMPLEMENTED();
- return false;
+ return RespondNow(NoArguments());
}
-void GrabWindowSnapshotAndScaleAsync(gfx::NativeWindow window,
- const gfx::Rect& source_rect,
- const gfx::Size& target_size,
- GrabWindowSnapshotAsyncCallback callback)
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::Run()
{
- NOTIMPLEMENTED();
- std::move(callback).Run(gfx::Image());
+ return RespondNow(NoArguments());
}
-void GrabWindowSnapshotAsync(gfx::NativeWindow window,
- const gfx::Rect& source_rect,
- GrabWindowSnapshotAsyncCallback callback)
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStopFunction::Run()
{
- NOTIMPLEMENTED();
- std::move(callback).Run(gfx::Image());
+ return RespondNow(NoArguments());
}
-void GrabViewSnapshotAsync(gfx::NativeView view,
- const gfx::Rect& source_rect,
- GrabWindowSnapshotAsyncCallback callback)
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStoreFunction::Run()
{
- NOTIMPLEMENTED();
- std::move(callback).Run(gfx::Image());
+ return RespondNow(NoArguments());
}
-} // namespace ui
-#endif // defined(USE_AURA)
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateUploadStoredFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
-std::unique_ptr<ui::OSExchangeData::Provider>
-ui::OSExchangeDataProviderFactory::CreateProvider() {
- return nullptr;
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateUploadFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateDiscardFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStartRtpDumpFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStopRtpDumpFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStartAudioDebugRecordingsFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStopAudioDebugRecordingsFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateStartEventLoggingFunction::Run()
+{
+ return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction WebrtcLoggingPrivateGetLogsDirectoryFunction::Run()
+{
+ return RespondNow(NoArguments());
}
+} // namespace extensions
+#endif // !QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index a1dba8150..65e3e90ac 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -51,6 +51,7 @@
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_constants.h"
+#include "ui/base/clipboard/clipboard_data_endpoint.h"
#include "ui/base/clipboard/clipboard_format_type.h"
#include <QGuiApplication>
@@ -106,7 +107,7 @@ Clipboard *Clipboard::Create()
namespace QtWebEngineCore {
-void ClipboardQt::WritePortableRepresentations(ui::ClipboardBuffer type, const ObjectMap &objects)
+void ClipboardQt::WritePortableRepresentations(ui::ClipboardBuffer type, const ObjectMap &objects, std::unique_ptr<ui::ClipboardDataEndpoint> data_src)
{
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardBuffer(type));
@@ -125,12 +126,15 @@ void ClipboardQt::WritePortableRepresentations(ui::ClipboardBuffer type, const O
if (text_iter != objects.end()) {
// Copy text and SourceTag to the selection clipboard.
WritePortableRepresentations(ui::ClipboardBuffer::kSelection,
- ObjectMap(text_iter, text_iter + 1));
+ ObjectMap(text_iter, text_iter + 1),
+ std::move(data_src));
}
}
}
-void ClipboardQt::WritePlatformRepresentations(ui::ClipboardBuffer buffer, std::vector<ui::Clipboard::PlatformRepresentation> platform_representations)
+void ClipboardQt::WritePlatformRepresentations(ui::ClipboardBuffer buffer,
+ std::vector<ui::Clipboard::PlatformRepresentation> platform_representations,
+ std::unique_ptr<ui::ClipboardDataEndpoint> data_src)
{
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardBuffer(buffer));
@@ -188,7 +192,9 @@ void ClipboardQt::WriteData(const ui::ClipboardFormatType &format, const char *d
getUncommittedData()->setData(QString::fromStdString(format.GetName()), QByteArray(data_data, data_len));
}
-bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format, ui::ClipboardBuffer type) const
+bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format,
+ ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -201,10 +207,11 @@ void ClipboardQt::Clear(ui::ClipboardBuffer type)
: QClipboard::Selection);
}
-void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type, std::vector<base::string16> *types,
- bool *contains_filenames) const
+void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ std::vector<base::string16> *types) const
{
- if (!types || !contains_filenames) {
+ if (!types) {
NOTREACHED();
return;
}
@@ -219,13 +226,14 @@ void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type, std::vector<base:
const QStringList formats = mimeData->formats();
for (const QString &mimeType : formats)
types->push_back(toString16(mimeType));
- *contains_filenames = false;
const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
ui::ReadCustomDataTypes(customData.constData(), customData.size(), types);
}
-void ClipboardQt::ReadText(ui::ClipboardBuffer type, base::string16 *result) const
+void ClipboardQt::ReadText(ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ base::string16 *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -233,7 +241,9 @@ void ClipboardQt::ReadText(ui::ClipboardBuffer type, base::string16 *result) con
*result = toString16(mimeData->text());
}
-void ClipboardQt::ReadAsciiText(ui::ClipboardBuffer type, std::string *result) const
+void ClipboardQt::ReadAsciiText(ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ std::string *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -241,7 +251,9 @@ void ClipboardQt::ReadAsciiText(ui::ClipboardBuffer type, std::string *result) c
*result = mimeData->text().toStdString();
}
-void ClipboardQt::ReadHTML(ui::ClipboardBuffer type, base::string16 *markup, std::string *src_url,
+void ClipboardQt::ReadHTML(ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ base::string16 *markup, std::string *src_url,
uint32_t *fragment_start, uint32_t *fragment_end) const
{
markup->clear();
@@ -258,7 +270,9 @@ void ClipboardQt::ReadHTML(ui::ClipboardBuffer type, base::string16 *markup, std
*fragment_end = static_cast<uint32_t>(markup->length());
}
-void ClipboardQt::ReadRTF(ui::ClipboardBuffer type, std::string *result) const
+void ClipboardQt::ReadRTF(ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ std::string *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -268,7 +282,9 @@ void ClipboardQt::ReadRTF(ui::ClipboardBuffer type, std::string *result) const
*result = std::string(byteArray.constData(), byteArray.length());
}
-void ClipboardQt::ReadImage(ui::ClipboardBuffer type, ReadImageCallback callback) const
+void ClipboardQt::ReadImage(ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ ReadImageCallback callback) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -294,7 +310,9 @@ void ClipboardQt::ReadImage(ui::ClipboardBuffer type, ReadImageCallback callback
return std::move(callback).Run(bitmap);
}
-void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const base::string16 &type, base::string16 *result) const
+void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const base::string16 &type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ base::string16 *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
clipboard_type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -304,12 +322,33 @@ void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const base:
ui::ReadCustomDataForType(customData.constData(), customData.size(), type, result);
}
-void ClipboardQt::ReadBookmark(base::string16 *title, std::string *url) const
+void ClipboardQt::ReadBookmark(const ui::ClipboardDataEndpoint *data_dst, base::string16 *title, std::string *url) const
{
NOTIMPLEMENTED();
}
-void ClipboardQt::ReadData(const ui::ClipboardFormatType &format, std::string *result) const
+void ClipboardQt::ReadSvg(ui::ClipboardBuffer clipboard_type,
+ const ui::ClipboardDataEndpoint *,
+ base::string16 *result) const
+{
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
+ clipboard_type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
+ if (!mimeData)
+ return;
+ const QByteArray svgData = mimeData->data(QString::fromLatin1(ui::kMimeTypeSvg));
+ if (!svgData.isEmpty())
+ *result = toString16(QString::fromUtf8(svgData));
+}
+
+void ClipboardQt::WriteSvg(const char *svg_data, size_t data_len)
+{
+ getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeSvg),
+ QByteArray(svg_data, data_len));
+}
+
+void ClipboardQt::ReadData(const ui::ClipboardFormatType &format,
+ const ui::ClipboardDataEndpoint *data_dst,
+ std::string *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData();
if (!mimeData)
@@ -324,18 +363,28 @@ uint64_t ClipboardQt::GetSequenceNumber(ui::ClipboardBuffer type) const
: QClipboard::Selection);
}
-std::vector<base::string16> ClipboardQt::ReadAvailablePlatformSpecificFormatNames(ui::ClipboardBuffer buffer) const
+
+#if defined(USE_OZONE)
+bool ClipboardQt::IsSelectionBufferAvailable() const
+{
+ return QGuiApplication::clipboard()->supportsSelection();
+}
+#endif
+
+std::vector<base::string16> ClipboardQt::ReadAvailablePlatformSpecificFormatNames(ui::ClipboardBuffer buffer, const ui::ClipboardDataEndpoint *data_dst) const
{
// based on ClipboardAura
std::vector<base::string16> types;
- if (IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextType(), buffer))
+ if (IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextType(), buffer, data_dst))
types.push_back(base::UTF8ToUTF16(ui::ClipboardFormatType::GetPlainTextType().GetName()));
- if (IsFormatAvailable(ui::ClipboardFormatType::GetHtmlType(), buffer))
+ if (IsFormatAvailable(ui::ClipboardFormatType::GetHtmlType(), buffer, data_dst))
types.push_back(base::UTF8ToUTF16(ui::ClipboardFormatType::GetHtmlType().GetName()));
- if (IsFormatAvailable(ui::ClipboardFormatType::GetRtfType(), buffer))
+ if (IsFormatAvailable(ui::ClipboardFormatType::GetRtfType(), buffer, data_dst))
types.push_back(base::UTF8ToUTF16(ui::ClipboardFormatType::GetRtfType().GetName()));
- if (IsFormatAvailable(ui::ClipboardFormatType::GetBitmapType(), buffer))
+ if (IsFormatAvailable(ui::ClipboardFormatType::GetBitmapType(), buffer, data_dst))
types.push_back(base::UTF8ToUTF16(ui::kMimeTypePNG));
+ if (IsFormatAvailable(ui::ClipboardFormatType::GetSvgType(), buffer, data_dst))
+ types.push_back(base::UTF8ToUTF16(ui::kMimeTypeSvg));
return types;
}
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
index cc1b95a32..b4c9d4c7d 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -44,31 +44,43 @@
namespace QtWebEngineCore {
-class ClipboardQt : public ui::Clipboard {
+class ClipboardQt : public ui::Clipboard
+{
public:
uint64_t GetSequenceNumber(ui::ClipboardBuffer type) const override;
- bool IsFormatAvailable(const ui::ClipboardFormatType &format, ui::ClipboardBuffer type) const override;
+ bool IsFormatAvailable(const ui::ClipboardFormatType &format,
+ ui::ClipboardBuffer buffer,
+ const ui::ClipboardDataEndpoint *data_dst) const override;
void Clear(ui::ClipboardBuffer type) override;
- void ReadAvailableTypes(ui::ClipboardBuffer type, std::vector<base::string16> *types,
- bool *contains_filenames) const override;
- void ReadText(ui::ClipboardBuffer type, base::string16 *result) const override;
- void ReadAsciiText(ui::ClipboardBuffer type, std::string *result) const override;
- void ReadHTML(ui::ClipboardBuffer type, base::string16 *markup, std::string *src_url, uint32_t *fragment_start,
+ void ReadAvailableTypes(ui::ClipboardBuffer type,
+ const ui::ClipboardDataEndpoint *data_dst,
+ std::vector<base::string16> *types) const override;
+ void ReadText(ui::ClipboardBuffer type, const ui::ClipboardDataEndpoint *data_dst, base::string16 *result) const override;
+ void ReadAsciiText(ui::ClipboardBuffer type, const ui::ClipboardDataEndpoint *data_dst, std::string *result) const override;
+ void ReadHTML(ui::ClipboardBuffer type, const ui::ClipboardDataEndpoint *data_dst, base::string16 *markup, std::string *src_url, uint32_t *fragment_start,
uint32_t *fragment_end) const override;
- void ReadRTF(ui::ClipboardBuffer type, std::string *result) const override;
- void ReadImage(ui::ClipboardBuffer buffer, ReadImageCallback callback) const override;
- void ReadCustomData(ui::ClipboardBuffer clipboard_type, const base::string16 &type, base::string16 *result) const override;
- void ReadBookmark(base::string16 *title, std::string *url) const override;
- void ReadData(const ui::ClipboardFormatType &format, std::string *result) const override;
-
+ void ReadRTF(ui::ClipboardBuffer type, const ui::ClipboardDataEndpoint *data_dst, std::string *result) const override;
+ void ReadImage(ui::ClipboardBuffer buffer, const ui::ClipboardDataEndpoint *data_dst, ReadImageCallback callback) const override;
+ void ReadCustomData(ui::ClipboardBuffer clipboard_type, const base::string16 &type, const ui::ClipboardDataEndpoint *data_dst, base::string16 *result) const override;
+ void ReadBookmark(const ui::ClipboardDataEndpoint *data_dst, base::string16 *title, std::string *url) const override;
+ void ReadData(const ui::ClipboardFormatType &format, const ui::ClipboardDataEndpoint *data_dst, std::string *result) const override;
+#if defined(USE_OZONE)
+ bool IsSelectionBufferAvailable() const override;
+#endif
void OnPreShutdown() override {}
-
- std::vector<base::string16> ReadAvailablePlatformSpecificFormatNames(ui::ClipboardBuffer buffer) const override;
+ void ReadSvg(ui::ClipboardBuffer, const ui::ClipboardDataEndpoint *, base::string16 *) const override;
+ void WriteSvg(const char *, size_t) override;
+ std::vector<base::string16> ReadAvailablePlatformSpecificFormatNames(ui::ClipboardBuffer buffer, const ui::ClipboardDataEndpoint *data_dst) const override;
protected:
- void WritePortableRepresentations(ui::ClipboardBuffer type, const ObjectMap &objects) override;
- void WritePlatformRepresentations(ui::ClipboardBuffer type,
- std::vector<ui::Clipboard::PlatformRepresentation> platform_representations) override;
+ void WritePortableRepresentations(
+ ui::ClipboardBuffer buffer,
+ const ObjectMap &objects,
+ std::unique_ptr<ui::ClipboardDataEndpoint> data_src) override;
+ void WritePlatformRepresentations(
+ ui::ClipboardBuffer buffer,
+ std::vector<Clipboard::PlatformRepresentation> platform_representations,
+ std::unique_ptr<ui::ClipboardDataEndpoint> data_src) override;
void WriteText(const char *text_data, size_t text_len) override;
void WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len) override;
void WriteRTF(const char *rtf_data, size_t data_len) override;
diff --git a/src/core/common/extensions/api/qtwebengine_extensions_features.gni b/src/core/common/extensions/api/qtwebengine_extensions_features.gni
index ed7e713c6..3873e235a 100644
--- a/src/core/common/extensions/api/qtwebengine_extensions_features.gni
+++ b/src/core/common/extensions/api/qtwebengine_extensions_features.gni
@@ -12,7 +12,8 @@ json_features("qt_permission_features") {
feature_type = "PermissionFeature"
method_name = "AddQtPermissionFeatures"
sources = [
- "//extensions/common/api/_permission_features.json"
+ "//chrome/common/extensions/api/_permission_features.json",
+ "//extensions/common/api/_permission_features.json",
]
}
@@ -20,6 +21,7 @@ group("qtwebengine_extensions_features") {
public_deps = [
":qt_api_features",
":qt_permission_features",
+ "//chrome/common/extensions/api:extensions_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
index 22154a9d1..81eb76f3e 100644
--- a/src/core/common/extensions/extensions_api_provider_qt.cpp
+++ b/src/core/common/extensions/extensions_api_provider_qt.cpp
@@ -39,6 +39,8 @@
#include "extensions_api_provider_qt.h"
+#include "chrome/common/extensions/permissions/chrome_api_permissions.h"
+#include "chrome/common/extensions/api/generated_schemas.h"
#include "chrome/grit/common_resources.h"
#include "extensions/common/api/api_features.h"
@@ -51,6 +53,7 @@
#include "extensions/common/features/json_feature_provider_source.h"
#include "extensions/common/permissions/permissions_info.h"
#include "extensions/grit/extensions_resources.h"
+#include "qtwebengine/common/extensions/api/generated_schemas.h"
#include "qt_api_features.h"
//#include "qt_behavior_features.h"
@@ -85,16 +88,30 @@ void ExtensionsAPIProviderQt::AddPermissionFeatures(FeatureProvider *provider)
bool ExtensionsAPIProviderQt::IsAPISchemaGenerated(const std::string &name)
{
- return api::GeneratedSchemas::IsGenerated(name);
+ return api::GeneratedSchemas::IsGenerated(name) ||
+ api::ChromeGeneratedSchemas::IsGenerated(name) ||
+ api::QtWebEngineGeneratedSchemas::IsGenerated(name);
}
base::StringPiece ExtensionsAPIProviderQt::GetAPISchema(const std::string &name)
{
- return api::GeneratedSchemas::Get(name);
+ if (!api::GeneratedSchemas::Get(name).empty())
+ return api::GeneratedSchemas::Get(name);
+
+ if (!api::ChromeGeneratedSchemas::Get(name).empty())
+ return api::ChromeGeneratedSchemas::Get(name);
+
+ if (!api::QtWebEngineGeneratedSchemas::Get(name).empty())
+ return api::QtWebEngineGeneratedSchemas::Get(name);
+
+ return "";
}
void ExtensionsAPIProviderQt::RegisterPermissions(PermissionsInfo* permissions_info)
{
+ permissions_info->RegisterPermissions(
+ chrome_api_permissions::GetPermissionInfos(),
+ chrome_api_permissions::GetPermissionAliases());
}
}
diff --git a/src/core/common/extensions/extensions_client_qt.cpp b/src/core/common/extensions/extensions_client_qt.cpp
index dd1de1483..c4cc2321a 100644
--- a/src/core/common/extensions/extensions_client_qt.cpp
+++ b/src/core/common/extensions/extensions_client_qt.cpp
@@ -108,18 +108,18 @@ void ExtensionsClientQt::FilterHostPermissions(const URLPatternSet &hosts,
{
}
-// Replaces the scripting whitelist with |whitelist|. Used in the renderer{}
+// Replaces the scripting allowlist with |allowlist|. Used in the renderer{}
// only used for testing in the browser process.
-void ExtensionsClientQt::SetScriptingWhitelist(const ExtensionsClient::ScriptingWhitelist &whitelist)
+void ExtensionsClientQt::SetScriptingAllowlist(const ExtensionsClient::ScriptingAllowlist &allowlist)
{
- scripting_whitelist_ = whitelist;
+ scripting_allowlist_ = allowlist;
}
-// Return the whitelist of extensions that can run content scripts on
+// Return the allowlist of extensions that can run content scripts on
// any origin.
-const ExtensionsClient::ScriptingWhitelist &ExtensionsClientQt::GetScriptingWhitelist() const
+const ExtensionsClient::ScriptingAllowlist &ExtensionsClientQt::GetScriptingAllowlist() const
{
- return scripting_whitelist_;
+ return scripting_allowlist_;
}
// Get the set of chrome:// hosts that |extension| can run content scripts on.
diff --git a/src/core/common/extensions/extensions_client_qt.h b/src/core/common/extensions/extensions_client_qt.h
index e689f76b7..2466e14e3 100644
--- a/src/core/common/extensions/extensions_client_qt.h
+++ b/src/core/common/extensions/extensions_client_qt.h
@@ -87,13 +87,13 @@ public:
URLPatternSet *new_hosts,
PermissionIDSet *permissions) const override;
- // Replaces the scripting whitelist with |whitelist|. Used in the renderer;
+ // Replaces the scripting allowlist with |allowlist|. Used in the renderer;
// only used for testing in the browser process.
- void SetScriptingWhitelist(const ScriptingWhitelist &whitelist) override;
+ void SetScriptingAllowlist(const ScriptingAllowlist &allowlist) override;
- // Return the whitelist of extensions that can run content scripts on
+ // Return the allowlist of extensions that can run content scripts on
// any origin.
- const ScriptingWhitelist &GetScriptingWhitelist() const override;
+ const ScriptingAllowlist &GetScriptingAllowlist() const override;
// Get the set of chrome:// hosts that |extension| can run content scripts on.
URLPatternSet GetPermittedChromeSchemeHosts(const Extension *extension,
@@ -127,7 +127,7 @@ public:
static ExtensionsClientQt *GetInstance();
private:
- ScriptingWhitelist scripting_whitelist_;
+ ScriptingAllowlist scripting_allowlist_;
const ChromePermissionMessageProvider permission_message_provider_;
mutable GURL update_url_;
mutable GURL base_url_;
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index 43f07c9a6..ebf49e8c3 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -9,20 +9,6 @@
#include "content/public/common/webplugininfo.h"
#include "ipc/ipc_message_macros.h"
#include "ppapi/buildflags/buildflags.h"
-#include "user_script_data.h"
-
-IPC_STRUCT_TRAITS_BEGIN(UserScriptData)
- IPC_STRUCT_TRAITS_MEMBER(source)
- IPC_STRUCT_TRAITS_MEMBER(url)
- IPC_STRUCT_TRAITS_MEMBER(injectionPoint)
- IPC_STRUCT_TRAITS_MEMBER(injectForSubframes)
- IPC_STRUCT_TRAITS_MEMBER(worldId)
- IPC_STRUCT_TRAITS_MEMBER(scriptId)
- IPC_STRUCT_TRAITS_MEMBER(globs)
- IPC_STRUCT_TRAITS_MEMBER(excludeGlobs)
- IPC_STRUCT_TRAITS_MEMBER(urlPatterns)
-IPC_STRUCT_TRAITS_END()
-
#define IPC_MESSAGE_START QtMsgStart
@@ -30,87 +16,41 @@ IPC_STRUCT_TRAITS_END()
// RenderView messages
// These are messages sent from the browser to the renderer process.
-IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentMarkup,
- uint64_t /* requestId */)
-
-IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentInnerText,
- uint64_t /* requestId */)
-
-IPC_MESSAGE_ROUTED1(RenderViewObserverQt_SetBackgroundColor,
- uint32_t /* color */)
-
-// User scripts messages
-IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_AddScript,
- UserScriptData /* script */)
-IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_RemoveScript,
- UserScriptData /* script */)
-IPC_MESSAGE_ROUTED0(RenderFrameObserverHelper_ClearScripts)
-
-IPC_MESSAGE_CONTROL1(UserResourceController_AddScript, UserScriptData /* scriptContents */)
-IPC_MESSAGE_CONTROL1(UserResourceController_RemoveScript, UserScriptData /* scriptContents */)
-IPC_MESSAGE_CONTROL0(UserResourceController_ClearScripts)
-
-// Tells the renderer whether or not a file system access has been allowed.
-IPC_MESSAGE_ROUTED2(QtWebEngineMsg_RequestFileSystemAccessAsyncResponse,
+// Tells the renderer whether or not a storage access has been allowed.
+IPC_MESSAGE_ROUTED2(QtWebEngineMsg_RequestStorageAccessAsyncResponse,
int /* request_id */,
bool /* allowed */)
-
//-----------------------------------------------------------------------------
// WebContents messages
// These are messages sent from the renderer back to the browser process.
-IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentMarkup,
- uint64_t /* requestId */,
- base::string16 /* markup */)
-
-IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentInnerText,
- uint64_t /* requestId */,
- base::string16 /* innerText */)
-
IPC_MESSAGE_ROUTED0(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout)
//-----------------------------------------------------------------------------
// Misc messages
// These are messages sent from the renderer to the browser process.
-// Sent by the renderer process to check whether access to web databases is
-// granted by content settings.
-IPC_SYNC_MESSAGE_CONTROL3_1(QtWebEngineHostMsg_AllowDatabase,
+IPC_SYNC_MESSAGE_CONTROL4_1(QtWebEngineHostMsg_AllowStorageAccess,
int /* render_frame_id */,
GURL /* origin_url */,
GURL /* top origin url */,
+ int /* storage_type */,
bool /* allowed */)
-// Sent by the renderer process to check whether access to DOM Storage is
-// granted by content settings.
-IPC_SYNC_MESSAGE_CONTROL4_1(QtWebEngineHostMsg_AllowDOMStorage,
+IPC_SYNC_MESSAGE_CONTROL4_1(QtWebEngineHostMsg_RequestStorageAccessSync,
int /* render_frame_id */,
GURL /* origin_url */,
GURL /* top origin url */,
- bool /* if true local storage, otherwise session */,
+ int /* storage_type */,
bool /* allowed */)
-// Sent by the renderer process to check whether access to FileSystem is
+// Sent by the renderer process to check whether access to storage is
// granted by content settings.
-IPC_SYNC_MESSAGE_CONTROL3_1(QtWebEngineHostMsg_RequestFileSystemAccessSync,
- int /* render_frame_id */,
- GURL /* origin_url */,
- GURL /* top origin url */,
- bool /* allowed */)
-
-// Sent by the renderer process to check whether access to FileSystem is
-// granted by content settings.
-IPC_MESSAGE_CONTROL4(QtWebEngineHostMsg_RequestFileSystemAccessAsync,
+IPC_MESSAGE_CONTROL5(QtWebEngineHostMsg_RequestStorageAccessAsync,
int /* render_frame_id */,
int /* request_id */,
GURL /* origin_url */,
- GURL /* top origin url */)
+ GURL /* top origin url */,
+ int /* storage_type */)
-// Sent by the renderer process to check whether access to Indexed DB is
-// granted by content settings.
-IPC_SYNC_MESSAGE_CONTROL3_1(QtWebEngineHostMsg_AllowIndexedDB,
- int /* render_frame_id */,
- GURL /* origin_url */,
- GURL /* top origin url */,
- bool /* allowed */)
diff --git a/src/core/common/user_script_data.h b/src/core/common/user_script_data.h
deleted file mode 100644
index 8d98890e3..000000000
--- a/src/core/common/user_script_data.h
+++ /dev/null
@@ -1,74 +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$
-**
-****************************************************************************/
-
-#ifndef USER_SCRIPT_DATA_H
-#define USER_SCRIPT_DATA_H
-
-#include <QtCore/QHash>
-#include <string>
-#include "ipc/ipc_message_utils.h"
-#include "url/gurl.h"
-
-struct UserScriptData {
- enum InjectionPoint {
- AfterLoad,
- DocumentLoadFinished,
- DocumentElementCreation
- };
-
- UserScriptData();
-
- std::string source;
- GURL url;
- /*InjectionPoint*/uint8_t injectionPoint;
- bool injectForSubframes;
- uint worldId;
- uint64_t scriptId;
- std::vector<std::string> globs;
- std::vector<std::string> excludeGlobs;
- std::vector<std::string> urlPatterns;
-};
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_TYPEINFO(UserScriptData, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-#endif // USER_SCRIPT_DATA_H
diff --git a/src/core/compositor/content_gpu_client_qt.cpp b/src/core/compositor/content_gpu_client_qt.cpp
index f934979a0..2c0f78548 100644
--- a/src/core/compositor/content_gpu_client_qt.cpp
+++ b/src/core/compositor/content_gpu_client_qt.cpp
@@ -38,22 +38,151 @@
****************************************************************************/
#include "content_gpu_client_qt.h"
-
#include "web_engine_context.h"
+#include "ui/gl/gl_share_group.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gpu_timing.h"
+
+#if QT_CONFIG(opengl)
+#include <QOpenGLContext>
+#include <QOpenGLExtraFunctions>
+#endif
+
+#include <QGuiApplication>
+#include <qpa/qplatformnativeinterface.h>
+
+#if QT_CONFIG(opengl)
+QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
+QT_END_NAMESPACE
+#endif
namespace QtWebEngineCore {
-ContentGpuClientQt::ContentGpuClientQt()
+class QtShareGLContext : public gl::GLContext
{
-}
+public:
+ QtShareGLContext(QOpenGLContext *qtContext) : gl::GLContext(0), m_handle(0)
+ {
+ QString platform = qApp->platformName().toLower();
+ QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface();
+ if (platform == QLatin1String("xcb") || platform == QLatin1String("offscreen")) {
+ if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2)
+ m_handle =
+ pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
+ else
+ m_handle =
+ pni->nativeResourceForContext(QByteArrayLiteral("glxcontext"), qtContext);
+ } else if (platform == QLatin1String("cocoa"))
+ m_handle = pni->nativeResourceForContext(QByteArrayLiteral("cglcontextobj"), qtContext);
+ else if (platform == QLatin1String("qnx"))
+ m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
+ else if (platform == QLatin1String("eglfs") || platform == QLatin1String("wayland")
+ || platform == QLatin1String("wayland-egl"))
+ m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
+ else if (platform == QLatin1String("windows")) {
+ if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2)
+ m_handle =
+ pni->nativeResourceForContext(QByteArrayLiteral("eglContext"), qtContext);
+ else
+ m_handle = pni->nativeResourceForContext(QByteArrayLiteral("renderingcontext"),
+ qtContext);
+ } else {
+ qFatal("%s platform not yet supported", platform.toLatin1().constData());
+ // Add missing platforms once they work.
+ Q_UNREACHABLE();
+ }
+ }
+
+ void *GetHandle() override { return m_handle; }
+ unsigned int CheckStickyGraphicsResetStatusImpl() override
+ {
+#if QT_CONFIG(opengl)
+ if (QOpenGLContext *context = qt_gl_global_share_context()) {
+ if (context->format().testOption(QSurfaceFormat::ResetNotification))
+ return context->extraFunctions()->glGetGraphicsResetStatus();
+ }
+#endif
+ return 0 /*GL_NO_ERROR*/;
+ }
+
+ // We don't care about the rest, this context shouldn't be used except for its handle.
+ bool Initialize(gl::GLSurface *, const gl::GLContextAttribs &) override
+ {
+ Q_UNREACHABLE();
+ return false;
+ }
+ bool MakeCurrentImpl(gl::GLSurface *) override
+ {
+ Q_UNREACHABLE();
+ return false;
+ }
+ void ReleaseCurrent(gl::GLSurface *) override
+ {
+ Q_UNREACHABLE();
+ }
+ bool IsCurrent(gl::GLSurface *) override
+ {
+ Q_UNREACHABLE();
+ return false;
+ }
+ scoped_refptr<gl::GPUTimingClient> CreateGPUTimingClient() override
+ {
+ return nullptr;
+ }
+ const gfx::ExtensionSet &GetExtensions() override
+ {
+ static const gfx::ExtensionSet s_emptySet;
+ return s_emptySet;
+ }
+ void ResetExtensions() override { }
+
+private:
+ void *m_handle;
+};
-ContentGpuClientQt::~ContentGpuClientQt()
+class ShareGroupQtQuick : public gl::GLShareGroup
{
+public:
+ gl::GLContext *GetContext() override { return m_shareContextQtQuick.get(); }
+ void AboutToAddFirstContext() override;
+
+private:
+ scoped_refptr<QtShareGLContext> m_shareContextQtQuick;
+};
+
+void ShareGroupQtQuick::AboutToAddFirstContext()
+{
+#if QT_CONFIG(opengl)
+ // This currently has to be setup by ::main in all applications using QQuickWebEngineView
+ // with de legated rendering.
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext) {
+ qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure "
+ "to"
+ "call QtWebEngine::initialize() in your main() function before QCoreApplication "
+ "is "
+ "created.");
+ }
+ m_shareContextQtQuick = new QtShareGLContext(shareContext);
+#endif
}
+ContentGpuClientQt::ContentGpuClientQt() { }
+
+ContentGpuClientQt::~ContentGpuClientQt() { }
+
gpu::SyncPointManager *ContentGpuClientQt::GetSyncPointManager()
{
return WebEngineContext::syncPointManager();
}
+gl::GLShareGroup *ContentGpuClientQt::GetInProcessGpuShareGroup()
+{
+ if (!m_shareGroupQtQuick.get())
+ m_shareGroupQtQuick = new ShareGroupQtQuick;
+ return m_shareGroupQtQuick.get();
+}
+
} // namespace
diff --git a/src/core/compositor/content_gpu_client_qt.h b/src/core/compositor/content_gpu_client_qt.h
index d7ad43881..5288c65bd 100644
--- a/src/core/compositor/content_gpu_client_qt.h
+++ b/src/core/compositor/content_gpu_client_qt.h
@@ -43,6 +43,8 @@
namespace QtWebEngineCore {
+class ShareGroupQtQuick;
+
class ContentGpuClientQt : public content::ContentGpuClient {
public:
explicit ContentGpuClientQt();
@@ -50,6 +52,10 @@ public:
// content::ContentGpuClient implementation.
gpu::SyncPointManager *GetSyncPointManager() override;
+ gl::GLShareGroup *GetInProcessGpuShareGroup() override;
+
+private:
+ scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick;
};
}
diff --git a/src/core/config/common.pri b/src/core/config/common.pri
index 9432fac7d..fc46d55ce 100644
--- a/src/core/config/common.pri
+++ b/src/core/config/common.pri
@@ -1,4 +1,3 @@
-
qtConfig(webengine-printing-and-pdf) {
gn_args += enable_basic_printing=true enable_print_preview=true
gn_args += enable_pdf=true
@@ -22,7 +21,7 @@ qtConfig(webengine-spellchecker) {
qtConfig(webengine-webrtc) {
gn_args += enable_webrtc=true
} else {
- gn_args += enable_webrtc=false audio_processing_in_audio_service_supported=false
+ gn_args += enable_webrtc=false
}
qtConfig(webengine-proprietary-codecs) {
@@ -46,8 +45,5 @@ qtConfig(webengine-kerberos) {
gn_args += use_kerberos=false
}
-qtConfig(webengine-nodejs) {
- gn_args += have_nodejs=true
-} else {
- gn_args += have_nodejs=false
-}
+!qtConfig(webengine-nodejs10): gn_args += use_rollup=false
+gn_args += enable_ipc_logging=false
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index 26d0dcf7d..33dd28b42 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -27,6 +27,8 @@ qtConfig(webengine-embedded-build) {
gn_args += use_xkbcommon=true
packagesExist(xscrnsaver): gn_args += use_xscrnsaver=true
qtConfig(webengine-webrtc): gn_args += rtc_use_x11=true
+ } else {
+ gn_args += use_xkbcommon=false
}
qtConfig(webengine-webrtc): qtConfig(webengine-webrtc-pipewire): gn_args += rtc_use_pipewire=true
@@ -41,9 +43,4 @@ qtConfig(webengine-embedded-build) {
qtConfig(webengine-system-ffmpeg): gn_args += use_system_ffmpeg=true
qtConfig(webengine-system-re2): gn_args += use_system_re2=true
qtConfig(webengine-system-lcms2): gn_args += use_system_lcms2=true
-
- # FIXME:
- #qtConfig(webengine-system-protobuf): gn_args += use_system_protobuf=true
- #qtConfig(webengine-system-jsoncpp): gn_args += use_system_jsoncpp=true
- #qtConfig(webengine-system-libsrtp: gn_args += use_system_libsrtp=true
}
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index 732a61e28..9543daf90 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -6,6 +6,3 @@ qtConfig(build-qtwebengine-core):qtConfig(webengine-spellchecker) {
} else {
gn_args += use_browser_spellchecker=false
}
-
-# Avoid conflicting vulkan.h headers
-gn_args += enable_vulkan=false
diff --git a/src/core/configure.json b/src/core/configure.json
index 4cd6174fc..9e39ae59a 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -91,10 +91,6 @@
"webengine-embedded-build": {
"label": "embedded build",
"type": "detectEmbedded"
- },
- "webengine-nodejs": {
- "label": "node.js",
- "type": "detectNodeJS"
}
},
"features": {
@@ -212,11 +208,6 @@
{ "type": "privateConfig", "name": "v8base_debug" },
{ "type": "privateConfig", "name": "webcore_debug" }
]
- },
- "webengine-nodejs": {
- "label": "Node.js",
- "condition": "tests.webengine-nodejs",
- "output": [ "privateFeature" ]
}
},
@@ -235,11 +226,6 @@
"type": "warning",
"condition": "config.unix && config.cross_compile && !features.webengine-v8-snapshot-support",
"message": "V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work. Please make sure you have 32-bit devel environment installed."
- },
- {
- "type": "warning",
- "condition": "!features.webengine-nodejs",
- "message": "Building without node.js will disable some features of QtWebEngine DevTools."
}
],
@@ -261,7 +247,6 @@
"webengine-webchannel",
"webengine-kerberos",
"webengine-extensions",
- "webengine-nodejs",
{
"type": "feature",
"args": "webengine-ozone",
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index d3181c555..e15bd05f3 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -39,71 +39,40 @@
#include "content_browser_client_qt.h"
-#include "base/memory/ptr_util.h"
+#include "base/files/file_util.h"
#include "base/optional.h"
-#include "base/path_service.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"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.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 "chrome/browser/tab_contents/form_interaction_tab_helper.h"
#include "components/navigation_interception/intercept_navigation_throttle.h"
#include "components/navigation_interception/navigation_params.h"
#include "components/network_hints/browser/simple_network_hints_handler_impl.h"
#include "components/performance_manager/embedder/performance_manager_registry.h"
-#include "components/performance_manager/graph/process_node_impl.h"
-#include "components/performance_manager/performance_manager_impl.h"
-#include "components/performance_manager/public/mojom/coordination_unit.mojom.h"
#include "components/performance_manager/public/performance_manager.h"
-#include "components/performance_manager/render_process_user_data.h"
-#include "components/spellcheck/spellcheck_buildflags.h"
-#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/common/url_schemes.h"
-#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_main_runner.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"
#include "content/public/browser/file_url_loader.h"
#include "content/public/browser/media_observer.h"
-#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
-#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
-#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 "extensions/browser/extension_protocols.h"
-#include "extensions/browser/guest_view/web_view/web_view_guest.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/remote.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 "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/client_cert_store.h"
#include "services/network/network_service.h"
-#include "services/network/public/cpp/features.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/service.h"
-#include "services/service_manager/sandbox/switches.h"
-#include "storage/browser/quota/quota_settings.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/mojom/insecure_input/insecure_input_service.mojom.h"
@@ -111,10 +80,11 @@
#include "ui/base/ui_base_switches.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_share_group.h"
#include "ui/gl/gpu_timing.h"
#include "url/url_util_qt.h"
+#include "qtwebengine/browser/qtwebengine_content_browser_overlay_manifest.h"
+#include "qtwebengine/browser/qtwebengine_content_renderer_overlay_manifest.h"
#include "qtwebengine/common/renderer_configuration.mojom.h"
#include "qtwebengine/grit/qt_webengine_resources.h"
@@ -131,12 +101,8 @@
#include "net/custom_url_loader_factory.h"
#include "net/proxying_restricted_cookie_manager_qt.h"
#include "net/proxying_url_loader_factory_qt.h"
-#include "net/qrc_url_scheme_handler.h"
#include "net/system_network_context_manager.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"
@@ -145,16 +111,15 @@
#include "web_contents_adapter_client.h"
#include "web_contents_adapter.h"
#include "web_contents_delegate_qt.h"
-#include "web_engine_context.h"
#include "web_contents_view_qt.h"
+#include "web_engine_context.h"
#include "web_engine_library_info.h"
#include "api/qwebenginecookiestore.h"
#include "api/qwebenginecookiestore_p.h"
-#include "api/qwebengineurlscheme.h"
-#if defined(Q_OS_LINUX)
-#include "global_descriptors_qt.h"
-#include "ui/base/resource/resource_bundle.h"
+#if QT_CONFIG(webengine_geolocation)
+#include "base/memory/ptr_util.h"
+#include "location_provider_qt.h"
#endif
#if QT_CONFIG(webengine_pepper_plugins)
@@ -163,20 +128,41 @@
#include "renderer_host/pepper/pepper_host_factory_qt.h"
#endif
-#if QT_CONFIG(webengine_geolocation)
-#include "location_provider_qt.h"
+#if QT_CONFIG(webengine_printing_and_pdf)
+#include "printing/printing_message_filter_qt.h"
+#endif
+
+#if QT_CONFIG(webengine_spellchecker)
+#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
+#include "components/spellcheck/common/spellcheck.mojom.h"
+#endif
+
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+#include "chrome/browser/media/webrtc/webrtc_logging_controller.h"
+#endif
+
+#if defined(Q_OS_LINUX)
+#include "global_descriptors_qt.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
-#include "content/public/browser/file_url_loader.h"
+#include "common/extensions/extensions_client_qt.h"
+#include "components/guest_view/browser/guest_view_base.h"
+#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
#include "extensions/browser/extension_message_filter.h"
+#include "extensions/browser/extension_protocols.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_util.h"
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/browser/guest_view/web_view/web_view_guest.h"
+#include "extensions/browser/process_map.h"
#include "extensions/browser/url_loader_factory_manager.h"
#include "extensions/common/constants.h"
-
-#include "common/extensions/extensions_client_qt.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
#include "extensions/extension_web_contents_observer_qt.h"
#include "extensions/extensions_browser_client_qt.h"
+#include "extensions/pdf_iframe_navigation_throttle_qt.h"
#include "net/plugin_response_interceptor_url_loader_throttle.h"
#endif
@@ -185,23 +171,8 @@
#include "media/mojo/services/media_service_factory.h"
#endif
-#if BUILDFLAG(ENABLE_SPELLCHECK)
-#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
-#include "components/spellcheck/common/spellcheck.mojom.h"
-#endif
-
#include <QGuiApplication>
-#include <QLocale>
#include <QStandardPaths>
-#if QT_CONFIG(opengl)
-# include <QOpenGLContext>
-# include <QOpenGLExtraFunctions>
-#endif
-#include <qpa/qplatformnativeinterface.h>
-
-QT_BEGIN_NAMESPACE
-Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
-QT_END_NAMESPACE
// Implement IsHandledProtocol as declared in //url/url_util_qt.h.
namespace url {
@@ -242,91 +213,11 @@ bool IsHandledProtocol(base::StringPiece scheme)
namespace QtWebEngineCore {
-class QtShareGLContext : public gl::GLContext {
-public:
- QtShareGLContext(QOpenGLContext *qtContext)
- : gl::GLContext(0)
- , m_handle(0)
- {
- QString platform = qApp->platformName().toLower();
- QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface();
- if (platform == QLatin1String("xcb") || platform == QLatin1String("offscreen")) {
- if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2)
- m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
- else
- m_handle = pni->nativeResourceForContext(QByteArrayLiteral("glxcontext"), qtContext);
- } else if (platform == QLatin1String("cocoa"))
- m_handle = pni->nativeResourceForContext(QByteArrayLiteral("cglcontextobj"), qtContext);
- else if (platform == QLatin1String("qnx"))
- m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
- else if (platform == QLatin1String("eglfs") || platform == QLatin1String("wayland")
- || platform == QLatin1String("wayland-egl"))
- m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext);
- else if (platform == QLatin1String("windows")) {
- if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2)
- m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglContext"), qtContext);
- else
- m_handle = pni->nativeResourceForContext(QByteArrayLiteral("renderingcontext"), qtContext);
- } else {
- qFatal("%s platform not yet supported", platform.toLatin1().constData());
- // Add missing platforms once they work.
- Q_UNREACHABLE();
- }
- }
-
- void* GetHandle() override { return m_handle; }
- unsigned int CheckStickyGraphicsResetStatus() override
- {
-#if QT_CONFIG(opengl)
- if (QOpenGLContext *context = qt_gl_global_share_context()) {
- if (context->format().testOption(QSurfaceFormat::ResetNotification))
- return context->extraFunctions()->glGetGraphicsResetStatus();
- }
-#endif
- return 0 /*GL_NO_ERROR*/;
- }
-
- // We don't care about the rest, this context shouldn't be used except for its handle.
- bool Initialize(gl::GLSurface *, const gl::GLContextAttribs &) override { Q_UNREACHABLE(); return false; }
- bool MakeCurrent(gl::GLSurface *) override { Q_UNREACHABLE(); return false; }
- void ReleaseCurrent(gl::GLSurface *) override { Q_UNREACHABLE(); }
- bool IsCurrent(gl::GLSurface *) override { Q_UNREACHABLE(); return false; }
- scoped_refptr<gl::GPUTimingClient> CreateGPUTimingClient() override
- {
- return nullptr;
- }
- const gfx::ExtensionSet& GetExtensions() override
- {
- static const gfx::ExtensionSet s_emptySet;
- return s_emptySet;
- }
- void ResetExtensions() override
- {
- }
-
-private:
- void *m_handle;
-};
-
-class ShareGroupQtQuick : public gl::GLShareGroup {
-public:
- gl::GLContext* GetContext() override { return m_shareContextQtQuick.get(); }
- void AboutToAddFirstContext() override;
-
-private:
- scoped_refptr<QtShareGLContext> m_shareContextQtQuick;
-};
-
-void ShareGroupQtQuick::AboutToAddFirstContext()
-{
-#if QT_CONFIG(opengl)
- // This currently has to be setup by ::main in all applications using QQuickWebEngineView with delegated rendering.
- QOpenGLContext *shareContext = qt_gl_global_share_context();
- if (!shareContext) {
- qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to call QtWebEngine::initialize() in your main() function before QCoreApplication is created.");
- }
- m_shareContextQtQuick = new QtShareGLContext(shareContext);
-#endif
+void MaybeAddThrottle(
+ std::unique_ptr<content::NavigationThrottle> maybe_throttle,
+ std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) {
+ if (maybe_throttle)
+ throttles->push_back(std::move(maybe_throttle));
}
ContentBrowserClientQt::ContentBrowserClientQt()
@@ -347,6 +238,10 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
const int id = host->GetID();
Profile *profile = Profile::FromBrowserContext(host->GetBrowserContext());
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ WebRtcLoggingController::AttachToRenderProcessHost(host, WebEngineContext::current()->webRtcLogUploader());
+#endif
+
// Allow requesting custom schemes.
const auto policy = content::ChildProcessSecurityPolicy::GetInstance();
const auto profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
@@ -366,29 +261,26 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
#endif //ENABLE_EXTENSIONS
bool is_incognito_process = profile->IsOffTheRecord();
- qtwebengine::mojom::RendererConfigurationAssociatedPtr renderer_configuration;
+ mojo::AssociatedRemote<qtwebengine::mojom::RendererConfiguration> renderer_configuration;
host->GetChannel()->GetRemoteAssociatedInterface(&renderer_configuration);
renderer_configuration->SetInitialConfiguration(is_incognito_process);
}
-gl::GLShareGroup *ContentBrowserClientQt::GetInProcessGpuShareGroup()
-{
- if (!m_shareGroupQtQuick.get())
- m_shareGroupQtQuick = new ShareGroupQtQuick;
- return m_shareGroupQtQuick.get();
-}
-
content::MediaObserver *ContentBrowserClientQt::GetMediaObserver()
{
return MediaCaptureDevicesDispatcher::GetInstance();
}
-void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, content::WebPreferences *web_prefs)
+void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, blink::web_pref::WebPreferences *web_prefs)
{
if (content::WebContents *webContents = rvh->GetDelegate()->GetAsWebContents()) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
if (guest_view::GuestViewBase::IsGuest(webContents))
return;
+
+ WebContentsViewQt *view = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(webContents)->GetView());
+ if (!view->client())
+ return;
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
WebContentsDelegateQt* delegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
if (delegate)
@@ -498,8 +390,8 @@ void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* c
url::CustomScheme::SaveSchemes(command_line);
std::string processType = command_line->GetSwitchValueASCII(switches::kProcessType);
- if (processType == service_manager::switches::kZygoteProcess)
- command_line->AppendSwitchASCII(switches::kLang, GetApplicationLocale());
+ if (processType == switches::kZygoteProcess)
+ command_line->AppendSwitchASCII(switches::kLang, WebEngineLibraryInfo::getApplicationLocale());
}
void ContentBrowserClientQt::GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes)
@@ -527,9 +419,8 @@ void ContentBrowserClientQt::GetAdditionalAllowedSchemesForFileSystem(std::vecto
#if defined(Q_OS_LINUX)
void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings)
{
- const std::string &locale = GetApplicationLocale();
- const base::FilePath &locale_file_path = ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale);
- if (locale_file_path.empty())
+ const base::FilePath &locale_file_path = ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(WebEngineLibraryInfo::getResolvedLocale());
+ if (locale_file_path.empty() || !base::PathExists(locale_file_path))
return;
// Open pak file of the current locale in the Browser process and pass its file descriptor to the sandboxed
@@ -607,32 +498,15 @@ private:
WEB_CONTENTS_USER_DATA_KEY_IMPL(ServiceDriver)
-void ContentBrowserClientQt::InitFrameInterfaces()
-{
- m_frameInterfaces = std::make_unique<service_manager::BinderRegistry>();
- m_frameInterfacesParameterized = std::make_unique<service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>>();
-}
-
-void ContentBrowserClientQt::BindInterfaceRequestFromFrame(content::RenderFrameHost* render_frame_host,
- const std::string& interface_name,
- mojo::ScopedMessagePipeHandle interface_pipe)
-{
- if (!m_frameInterfaces.get() && !m_frameInterfacesParameterized.get())
- InitFrameInterfaces();
-
- if (!m_frameInterfacesParameterized->TryBindInterface(interface_name, &interface_pipe, render_frame_host))
- m_frameInterfaces->TryBindInterface(interface_name, &interface_pipe);
-}
-
void ContentBrowserClientQt::BindHostReceiverForRenderer(content::RenderProcessHost *render_process_host,
mojo::GenericPendingReceiver receiver)
{
-#if BUILDFLAG(ENABLE_SPELLCHECK)
+#if QT_CONFIG(webengine_spellchecker)
if (auto host_receiver = receiver.As<spellcheck::mojom::SpellCheckHost>()) {
SpellCheckHostChromeImpl::Create(render_process_host->GetID(), std::move(host_receiver));
return;
}
-#endif // BUILDFLAG(ENABLE_SPELLCHECK)
+#endif
}
static void BindNetworkHintsHandler(content::RenderFrameHost *frame_host,
@@ -641,43 +515,63 @@ static void BindNetworkHintsHandler(content::RenderFrameHost *frame_host,
network_hints::SimpleNetworkHintsHandlerImpl::Create(frame_host, std::move(receiver));
}
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+static void BindMimeHandlerService(content::RenderFrameHost *frame_host,
+ mojo::PendingReceiver<extensions::mime_handler::MimeHandlerService>
+ receiver) {
+ auto *web_contents = content::WebContents::FromRenderFrameHost(frame_host);
+ if (!web_contents)
+ return;
+ auto *guest_view = extensions::MimeHandlerViewGuest::FromWebContents(web_contents);
+ if (!guest_view)
+ return;
+ extensions::MimeHandlerServiceImpl::Create(guest_view->GetStreamWeakPtr(), std::move(receiver));
+}
+
+static void BindBeforeUnloadControl(content::RenderFrameHost *frame_host,
+ mojo::PendingReceiver<extensions::mime_handler::BeforeUnloadControl>
+ receiver) {
+ auto *web_contents = content::WebContents::FromRenderFrameHost(frame_host);
+ if (!web_contents)
+ return;
+ auto *guest_view = extensions::MimeHandlerViewGuest::FromWebContents(web_contents);
+ if (!guest_view)
+ return;
+ guest_view->FuseBeforeUnloadControl(std::move(receiver));
+}
+#endif
+
void ContentBrowserClientQt::RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost *render_frame_host,
- service_manager::BinderMapWithContext<content::RenderFrameHost *> *map)
+ mojo::BinderMapWithContext<content::RenderFrameHost *> *map)
{
Q_UNUSED(render_frame_host);
map->Add<blink::mojom::InsecureInputService>(base::BindRepeating(&ServiceDriver::BindInsecureInputService));
map->Add<network_hints::mojom::NetworkHintsHandler>(base::BindRepeating(&BindNetworkHintsHandler));
-}
-
-namespace {
-void BindProcessNode(int render_process_host_id,
- mojo::PendingReceiver<performance_manager::mojom::ProcessCoordinationUnit> receiver)
-{
- content::RenderProcessHost *render_process_host = content::RenderProcessHost::FromID(render_process_host_id);
- if (!render_process_host)
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ map->Add<extensions::mime_handler::MimeHandlerService>(base::BindRepeating(&BindMimeHandlerService));
+ map->Add<extensions::mime_handler::BeforeUnloadControl>(base::BindRepeating(&BindBeforeUnloadControl));
+ const GURL &site = render_frame_host->GetSiteInstance()->GetSiteURL();
+ if (!site.SchemeIs(extensions::kExtensionScheme))
return;
-
- performance_manager::RenderProcessUserData *user_data =
- performance_manager::RenderProcessUserData::GetForRenderProcessHost(render_process_host);
-
- DCHECK(performance_manager::PerformanceManagerImpl::IsAvailable());
- performance_manager::PerformanceManagerImpl::CallOnGraphImpl(
- FROM_HERE, base::BindOnce(&performance_manager::ProcessNodeImpl::Bind,
- base::Unretained(user_data->process_node()),
- std::move(receiver)));
+ content::BrowserContext *browser_context = render_frame_host->GetProcess()->GetBrowserContext();
+ auto *extension = extensions::ExtensionRegistry::Get(browser_context)
+ ->enabled_extensions()
+ .GetByID(site.host());
+ if (!extension)
+ return;
+ extensions::ExtensionsBrowserClient::Get()->RegisterBrowserInterfaceBindersForFrame(map,
+ render_frame_host,
+ extension);
+#endif
}
-} // namespace
void ContentBrowserClientQt::ExposeInterfacesToRenderer(service_manager::BinderRegistry *registry,
blink::AssociatedInterfaceRegistry *associated_registry,
content::RenderProcessHost *render_process_host)
{
Q_UNUSED(associated_registry);
- registry->AddInterface(base::BindRepeating(&BindProcessNode, render_process_host->GetID()),
- base::SequencedTaskRunnerHandle::Get());
-
- performance_manager::PerformanceManagerRegistry::GetInstance()->CreateProcessNodeForRenderProcessHost(render_process_host);
+ performance_manager::PerformanceManagerRegistry::GetInstance()->CreateProcessNodeAndExposeInterfacesToRendererProcess(registry, render_process_host);
}
void ContentBrowserClientQt::RunServiceInstance(const service_manager::Identity &identity,
@@ -788,36 +682,45 @@ bool ContentBrowserClientQt::WillCreateRestrictedCookieManager(network::mojom::R
bool ContentBrowserClientQt::AllowAppCache(const GURL &manifest_url,
const GURL &first_party,
+ const base::Optional<url::Origin> &top_frame_origin,
content::BrowserContext *context)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return false;
return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(first_party), toQt(manifest_url));
}
-bool ContentBrowserClientQt::AllowServiceWorkerOnIO(const GURL &scope,
+content::AllowServiceWorkerResult
+ContentBrowserClientQt::AllowServiceWorkerOnIO(const GURL &scope,
const GURL &site_for_cookies,
const base::Optional<url::Origin> & /*top_frame_origin*/,
const GURL & /*script_url*/,
- content::ResourceContext *context,
- base::RepeatingCallback<content::WebContents*()> wc_getter)
+ content::ResourceContext *context)
{
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.
- return ProfileIODataQt::FromResourceContext(context)->canGetCookies(toQt(site_for_cookies), toQt(scope));
+ return ProfileIODataQt::FromResourceContext(context)->canGetCookies(toQt(site_for_cookies), toQt(scope))
+ ? content::AllowServiceWorkerResult::Yes()
+ : content::AllowServiceWorkerResult::No();
}
-bool ContentBrowserClientQt::AllowServiceWorkerOnUI(const GURL &scope,
+content::AllowServiceWorkerResult
+ContentBrowserClientQt::AllowServiceWorkerOnUI(const GURL &scope,
const GURL &site_for_cookies,
const base::Optional<url::Origin> & /*top_frame_origin*/,
const GURL & /*script_url*/,
- content::BrowserContext *context,
- base::RepeatingCallback<content::WebContents*()> wc_getter)
+ content::BrowserContext *context)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return content::AllowServiceWorkerResult::No();
// FIXME: Chrome also checks if javascript is enabled here to check if has been disabled since the service worker
// was started.
- return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(site_for_cookies), toQt(scope));
+ return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(site_for_cookies), toQt(scope))
+ ? content::AllowServiceWorkerResult::Yes()
+ : content::AllowServiceWorkerResult::No();
}
// We control worker access to FS and indexed-db using cookie permissions, this is mirroring Chromium's logic.
@@ -827,6 +730,8 @@ void ContentBrowserClientQt::AllowWorkerFileSystem(const GURL &url,
base::OnceCallback<void(bool)> callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return std::move(callback).Run(false);
std::move(callback).Run(
static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(url), toQt(url)));
}
@@ -837,6 +742,8 @@ bool ContentBrowserClientQt::AllowWorkerIndexedDB(const GURL &url,
const std::vector<content::GlobalFrameRoutingId> &/*render_frames*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return false;
return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(url), toQt(url));
}
@@ -856,6 +763,15 @@ static void LaunchURL(const GURL& url,
protocolHandlerRegistry->IsHandledProtocol(url.scheme()))
return;
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (guest_view::GuestViewBase::IsGuest(webContents)) {
+ // Use parent / top level contents delegate for launching URLs from guest views.
+ webContents = guest_view::GuestViewBase::GetTopLevelWebContents(webContents);
+ if (!webContents)
+ return;
+ }
+#endif //BUILDFLAG(ENABLE_EXTENSIONS)
+
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame, has_user_gesture);
}
@@ -871,7 +787,6 @@ bool ContentBrowserClientQt::HandleExternalProtocol(const GURL &url,
const base::Optional<url::Origin> &initiating_origin,
mojo::PendingRemote<network::mojom::URLLoaderFactory> *out_factory)
{
-// Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_UNUSED(child_id);
Q_UNUSED(navigation_data);
Q_UNUSED(initiating_origin);
@@ -907,7 +822,8 @@ public:
const network::mojom::URLResponseHead &response_head,
bool *defer,
std::vector<std::string> *to_be_removed_headers,
- net::HttpRequestHeaders *modified_headers) override
+ net::HttpRequestHeaders *modified_headers,
+ net::HttpRequestHeaders *modified_cors_exempt_headers) override
{
TranslateUrl(&redirect_info->new_url);
}
@@ -977,10 +893,24 @@ static bool navigationThrottleCallback(content::WebContents *source,
ProfileQt *profile = static_cast<ProfileQt *>(source->GetBrowserContext());
if (params.is_external_protocol() && !profile->profileAdapter()->urlSchemeHandler(toQByteArray(params.url().scheme())))
return false;
+
+ WebContentsViewQt *view = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(source)->GetView());
+ if (!view->client())
+ return false;
+
int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
- WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(source->GetDelegate());
- WebContentsAdapterClient *client = delegate->adapterClient();
- client->navigationRequested(pageTransitionToNavigationType(params.transition_type()),
+
+ WebContentsAdapterClient *client =
+ WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(source)->GetView())->client();
+ if (!client)
+ return false;
+
+ // Redirects might not be reflected in transition_type at this point (see also chrome/.../web_navigation_api_helpers.cc)
+ auto transition_type = params.transition_type();
+ if (params.is_redirect())
+ transition_type = ui::PageTransitionFromInt(transition_type | ui::PAGE_TRANSITION_SERVER_REDIRECT);
+
+ client->navigationRequested(pageTransitionToNavigationType(transition_type),
toQt(params.url()),
navigationRequestAction,
params.is_main_frame());
@@ -995,6 +925,11 @@ std::vector<std::unique_ptr<content::NavigationThrottle>> ContentBrowserClientQt
navigation_handle,
base::BindRepeating(&navigationThrottleCallback),
navigation_interception::SynchronyMode::kSync));
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ MaybeAddThrottle(extensions::PDFIFrameNavigationThrottleQt::MaybeCreateThrottleFor(navigation_handle), &throttles);
+#endif
+
return throttles;
}
@@ -1063,6 +998,16 @@ bool ContentBrowserClientQt::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(base::
#endif
}
+bool ContentBrowserClientQt::DoesSchemeAllowCrossOriginSharedWorker(const std::string &scheme)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ // Extensions are allowed to start cross-origin shared workers.
+ return scheme == extensions::kExtensionScheme;
+#else
+ return false;
+#endif
+}
+
void ContentBrowserClientQt::OverrideURLLoaderFactoryParams(content::BrowserContext *browser_context,
const url::Origin &origin,
bool is_for_isolated_world,
@@ -1109,22 +1054,19 @@ void ContentBrowserClientQt::OnNetworkServiceCreated(network::mojom::NetworkServ
SystemNetworkContextManager::GetInstance()->OnNetworkServiceCreated(network_service);
}
-mojo::Remote<network::mojom::NetworkContext> ContentBrowserClientQt::CreateNetworkContext(
+void ContentBrowserClientQt::ConfigureNetworkContextParams(
content::BrowserContext *context,
bool in_memory,
- const base::FilePath &relative_partition_path)
+ const base::FilePath &relative_partition_path,
+ network::mojom::NetworkContextParams *network_context_params,
+ network::mojom::CertVerifierCreationParams *cert_verifier_creation_params)
{
- mojo::Remote<network::mojom::NetworkContext> network_context;
- // ### do we need to pass in_memory and relative_partition_path to ProfileIODataQt::CreateNetworkContextParams() ?
- network::mojom::NetworkContextParamsPtr context_params = ProfileIODataQt::FromBrowserContext(context)->CreateNetworkContextParams();
- content::GetNetworkService()->CreateNetworkContext(
- network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
+ ProfileIODataQt::FromBrowserContext(context)->ConfigureNetworkContextParams(in_memory, relative_partition_path,
+ network_context_params, cert_verifier_creation_params);
- network::mojom::CookieManagerPtrInfo cookie_manager_info;
- network_context->GetCookieManager(mojo::MakeRequest(&cookie_manager_info));
- ProfileIODataQt::FromBrowserContext(context)->cookieDelegate()->setMojoCookieManager(std::move(cookie_manager_info));
-
- return network_context;
+ mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote;
+ network_context_params->cookie_manager = cookie_manager_remote.InitWithNewPipeAndPassReceiver();
+ ProfileIODataQt::FromBrowserContext(context)->cookieDelegate()->setMojoCookieManager(std::move(cookie_manager_remote));
}
std::vector<base::FilePath> ContentBrowserClientQt::GetNetworkContextsParentDirectory()
@@ -1135,8 +1077,11 @@ std::vector<base::FilePath> ContentBrowserClientQt::GetNetworkContextsParentDire
}
void ContentBrowserClientQt::RegisterNonNetworkNavigationURLLoaderFactories(int frame_tree_node_id,
+ base::UkmSourceId ukm_source_id,
+ NonNetworkURLLoaderFactoryDeprecatedMap *uniquely_owned_factories,
NonNetworkURLLoaderFactoryMap *factories)
{
+ Q_UNUSED(uniquely_owned_factories);
content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
Profile *profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
@@ -1147,7 +1092,7 @@ void ContentBrowserClientQt::RegisterNonNetworkNavigationURLLoaderFactories(int
#if BUILDFLAG(ENABLE_EXTENSIONS)
factories->emplace(
extensions::kExtensionScheme,
- extensions::CreateExtensionNavigationURLLoaderFactory(profile,
+ extensions::CreateExtensionNavigationURLLoaderFactory(profile, ukm_source_id,
!!extensions::WebViewGuest::FromWebContents(web_contents)));
#endif
}
@@ -1160,11 +1105,31 @@ void ContentBrowserClientQt::RegisterNonNetworkWorkerMainResourceURLLoaderFactor
for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ factories->emplace(
+ extensions::kExtensionScheme,
+ extensions::CreateExtensionWorkerMainResourceURLLoaderFactory(browser_context));
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+}
+
+void ContentBrowserClientQt::RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(content::BrowserContext* browser_context,
+ NonNetworkURLLoaderFactoryMap* factories)
+{
+ DCHECK(browser_context);
+ DCHECK(factories);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ factories->emplace(
+ extensions::kExtensionScheme,
+ extensions::CreateExtensionServiceWorkerScriptURLLoaderFactory(browser_context));
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
}
void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int render_process_id, int render_frame_id,
+ NonNetworkURLLoaderFactoryDeprecatedMap *uniquely_owned_factories,
NonNetworkURLLoaderFactoryMap *factories)
{
+ Q_UNUSED(uniquely_owned_factories);
content::RenderProcessHost *process_host = content::RenderProcessHost::FromID(render_process_id);
Profile *profile = Profile::FromBrowserContext(process_host->GetBrowserContext());
ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
@@ -1186,7 +1151,7 @@ void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int
install_file_scheme = install_file_scheme || url.SchemeIs(extensions::kExtensionScheme);
#endif
if (!install_file_scheme && web_contents) {
- const auto *settings = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())->webEngineSettings();
+ const auto *settings = static_cast<WebContentsDelegateQt *>(web_contents->GetResponsibleWebContents()->GetDelegate())->webEngineSettings();
if (settings->testAttribute(WebEngineSettings::LocalContentCanAccessFileUrls)) {
for (const auto &local_scheme : url::GetLocalSchemes()) {
if (url.SchemeIs(local_scheme)) {
@@ -1230,11 +1195,38 @@ void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int
}
if (!allowed_webui_hosts.empty()) {
factories->emplace(content::kChromeUIScheme,
- content::CreateWebUIURLLoader(frame_host,
- content::kChromeUIScheme,
- std::move(allowed_webui_hosts)));
+ content::CreateWebUIURLLoaderFactory(frame_host,
+ content::kChromeUIScheme,
+ std::move(allowed_webui_hosts)));
+ }
+#endif
+}
+
+base::flat_set<std::string> ContentBrowserClientQt::GetPluginMimeTypesWithExternalHandlers(
+ content::BrowserContext *browser_context)
+{
+ base::flat_set<std::string> mime_types;
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+ for (const std::string &extension_id : MimeTypesHandler::GetMIMETypeAllowlist()) {
+ const extensions::Extension *extension =
+ extensions::ExtensionRegistry::Get(browser_context)
+ ->enabled_extensions()
+ .GetByID(extension_id);
+ // The allowed extension may not be installed, so we have to nullptr
+ // check |extension|.
+ if (!extension ||
+ (profile->IsOffTheRecord() && !extensions::util::IsIncognitoEnabled(
+ extension_id, browser_context))) {
+ continue;
+ }
+ if (MimeTypesHandler *handler = MimeTypesHandler::GetHandler(extension)) {
+ for (const auto &supported_mime_type : handler->mime_type_set())
+ mime_types.insert(supported_mime_type);
+ }
}
#endif
+ return mime_types;
}
bool ContentBrowserClientQt::WillCreateURLLoaderFactory(
@@ -1244,35 +1236,71 @@ bool ContentBrowserClientQt::WillCreateURLLoaderFactory(
URLLoaderFactoryType type,
const url::Origin &request_initiator,
base::Optional<int64_t> navigation_id,
+ base::UkmSourceId ukm_source_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> *factory_receiver,
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient> *header_client,
bool *bypass_redirect_checks,
bool *disable_secure_dns,
network::mojom::URLLoaderFactoryOverridePtr *factory_override)
{
- auto *web_contents = content::WebContents::FromRenderFrameHost(frame);
- ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+ auto adapter = static_cast<ProfileQt *>(browser_context)->profileAdapter();
+ int process_id = type == URLLoaderFactoryType::kNavigation ? 0 : render_process_id;
+ auto proxied_receiver = std::move(*factory_receiver);
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory;
+ *factory_receiver = pending_url_loader_factory.InitWithNewPipeAndPassReceiver();
+ // Will manage its own lifetime
+ new ProxyingURLLoaderFactoryQt(adapter, process_id, std::move(proxied_receiver), std::move(pending_url_loader_factory));
+ return true;
+}
- QWebEngineUrlRequestInterceptor *profile_interceptor = profile->profileAdapter()->requestInterceptor();
- QWebEngineUrlRequestInterceptor *page_interceptor = nullptr;
+void ContentBrowserClientQt::SiteInstanceGotProcess(content::SiteInstance *site_instance)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ content::BrowserContext *context = site_instance->GetBrowserContext();
+ extensions::ExtensionRegistry *registry = extensions::ExtensionRegistry::Get(context);
+ const extensions::Extension *extension = registry->enabled_extensions().GetExtensionOrAppByURL(site_instance->GetSiteURL());
+ if (!extension)
+ return;
- if (web_contents) {
- WebContentsAdapterClient *client =
- WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(web_contents)->GetView())->client();
- page_interceptor = client->webContentsAdapter()->requestInterceptor();
- }
+ extensions::ProcessMap *processMap = extensions::ProcessMap::Get(context);
+ processMap->Insert(extension->id(), site_instance->GetProcess()->GetID(), site_instance->GetId());
+#endif
+}
- if (profile_interceptor || page_interceptor) {
- int process_id = type == URLLoaderFactoryType::kNavigation ? 0 : render_process_id;
- auto proxied_receiver = std::move(*factory_receiver);
- mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory;
- *factory_receiver = pending_url_loader_factory.InitWithNewPipeAndPassReceiver();
- // Will manage its own lifetime
- new ProxyingURLLoaderFactoryQt(process_id, profile_interceptor, page_interceptor, std::move(proxied_receiver),
- std::move(pending_url_loader_factory));
- return true;
- }
- return false;
+void ContentBrowserClientQt::SiteInstanceDeleting(content::SiteInstance *site_instance)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ // Don't do anything if we're shutting down.
+ if (content::BrowserMainRunner::ExitedMainMessageLoop() || !site_instance->HasProcess())
+ return;
+
+ content::BrowserContext *context = site_instance->GetBrowserContext();
+ extensions::ExtensionRegistry *registry = extensions::ExtensionRegistry::Get(context);
+ const extensions::Extension *extension = registry->enabled_extensions().GetExtensionOrAppByURL(site_instance->GetSiteURL());
+ if (!extension)
+ return;
+
+ extensions::ProcessMap *processMap = extensions::ProcessMap::Get(context);
+ processMap->Remove(extension->id(), site_instance->GetProcess()->GetID(), site_instance->GetId());
+#endif
+}
+
+content::WebContentsViewDelegate *ContentBrowserClientQt::GetWebContentsViewDelegate(content::WebContents *web_contents)
+{
+ FormInteractionTabHelper::CreateForWebContents(web_contents);
+ if (auto *registry = performance_manager::PerformanceManagerRegistry::GetInstance())
+ registry->MaybeCreatePageNodeForWebContents(web_contents);
+
+ return nullptr;
+}
+
+content::ContentBrowserClient::AllowWebBluetoothResult
+ContentBrowserClientQt::AllowWebBluetooth(content::BrowserContext *browser_context,
+ const url::Origin &requesting_origin,
+ const url::Origin &embedding_origin)
+{
+ DCHECK(browser_context);
+ return content::ContentBrowserClient::AllowWebBluetoothResult::BLOCK_GLOBALLY_DISABLED;
}
} // namespace QtWebEngineCore
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index fe6d8a076..06e2e9a20 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -41,13 +41,8 @@
#define CONTENT_BROWSER_CLIENT_QT_H
#include "qtwebenginecoreglobal_p.h"
-#include "base/memory/ref_counted.h"
#include "content/public/browser/content_browser_client.h"
-namespace net {
-class URLRequestContextGetter;
-}
-
namespace content {
class BrowserContext;
class BrowserMainParts;
@@ -59,25 +54,14 @@ class BrowserPpapiHost;
class DevToolsManagerDelegate;
class RenderFrameHost;
class RenderProcessHost;
-class RenderViewHostDelegateView;
class ResourceContext;
-class ResourceDispatcherHostDelegate;
-class WebContentsViewPort;
class WebContents;
struct MainFunctionParams;
struct Referrer;
}
-namespace gl {
-class GLShareGroup;
-}
-
namespace QtWebEngineCore {
-class BrowserMainPartsQt;
-class ProfileQt;
-class ShareGroupQtQuick;
-
class ContentBrowserClientQt : public content::ContentBrowserClient
{
public:
@@ -85,10 +69,10 @@ public:
~ContentBrowserClientQt();
std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(const content::MainFunctionParams&) override;
void RenderProcessWillLaunch(content::RenderProcessHost *host) override;
- gl::GLShareGroup* GetInProcessGpuShareGroup() override;
content::MediaObserver* GetMediaObserver() override;
scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override;
- void OverrideWebkitPrefs(content::RenderViewHost *, content::WebPreferences *) override;
+ void OverrideWebkitPrefs(content::RenderViewHost *render_view_host,
+ blink::web_pref::WebPreferences *prefs) override;
void AllowCertificateError(content::WebContents *web_contents,
int cert_error,
const net::SSLInfo &ssl_info,
@@ -112,13 +96,10 @@ public:
void GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes) override;
void GetAdditionalAllowedSchemesForFileSystem(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 BindHostReceiverForRenderer(content::RenderProcessHost *render_process_host,
mojo::GenericPendingReceiver receiver) override;
void RegisterBrowserInterfaceBindersForFrame(content::RenderFrameHost *render_frame_host,
- service_manager::BinderMapWithContext<content::RenderFrameHost *> *map) override;
+ mojo::BinderMapWithContext<content::RenderFrameHost *> *map) override;
void RunServiceInstance(const service_manager::Identity &identity,
mojo::PendingReceiver<service_manager::mojom::Service> *receiver) override;
void ExposeInterfacesToRenderer(service_manager::BinderRegistry *registry,
@@ -155,21 +136,20 @@ public:
bool AllowAppCache(const GURL &manifest_url,
const GURL &first_party,
+ const base::Optional<url::Origin> &top_frame_origin,
content::BrowserContext *context) override;
-
- bool AllowServiceWorkerOnIO(const GURL &scope,
- const GURL &site_for_cookies,
- const base::Optional<url::Origin> &top_frame_origin,
- const GURL &script_url,
- content::ResourceContext *context,
- base::RepeatingCallback<content::WebContents*()> wc_getter) override;
-
- bool AllowServiceWorkerOnUI(const GURL &scope,
- const GURL &site_for_cookies,
- const base::Optional<url::Origin> &top_frame_origin,
- const GURL &script_url,
- content::BrowserContext *context,
- base::RepeatingCallback<content::WebContents*()> wc_getter) override;
+ content::AllowServiceWorkerResult AllowServiceWorkerOnIO(
+ const GURL &scope,
+ const GURL &site_for_cookies,
+ const base::Optional<url::Origin> &top_frame_origin,
+ const GURL &script_url,
+ content::ResourceContext *context) override;
+ content::AllowServiceWorkerResult AllowServiceWorkerOnUI(
+ const GURL &scope,
+ const GURL &site_for_cookies,
+ const base::Optional<url::Origin> &top_frame_origin,
+ const GURL &script_url,
+ content::BrowserContext *context) override;
void AllowWorkerFileSystem(const GURL &url,
content::BrowserContext *context,
@@ -179,6 +159,9 @@ public:
bool AllowWorkerIndexedDB(const GURL &url,
content::BrowserContext *context,
const std::vector<content::GlobalFrameRoutingId> &render_frames) override;
+ AllowWebBluetoothResult AllowWebBluetooth(content::BrowserContext *browser_context,
+ const url::Origin &requesting_origin,
+ const url::Origin &embedding_origin) override;
#if QT_CONFIG(webengine_geolocation)
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider() override;
@@ -190,6 +173,7 @@ public:
bool ShouldUseSpareRenderProcessHost(content::BrowserContext *browser_context, const GURL& site_url) override;
bool ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(base::StringPiece scheme,
bool is_embedded_origin_secure) override;
+ bool DoesSchemeAllowCrossOriginSharedWorker(const std::string &scheme) override;
void OverrideURLLoaderFactoryParams(content::BrowserContext *browser_context,
const url::Origin &origin,
bool is_for_isolated_world,
@@ -239,6 +223,7 @@ public:
URLLoaderFactoryType type,
const url::Origin &request_initiator,
base::Optional<int64_t> navigation_id,
+ base::UkmSourceId ukm_source_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> *factory_receiver,
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient> *header_client,
bool *bypass_redirect_checks,
@@ -247,27 +232,33 @@ public:
scoped_refptr<network::SharedURLLoaderFactory> GetSystemSharedURLLoaderFactory() override;
network::mojom::NetworkContext *GetSystemNetworkContext() override;
void OnNetworkServiceCreated(network::mojom::NetworkService *network_service) override;
- mojo::Remote<network::mojom::NetworkContext> CreateNetworkContext(content::BrowserContext *context,
- bool in_memory,
- const base::FilePath &relative_partition_path) override;
+ void ConfigureNetworkContextParams(content::BrowserContext *context,
+ bool in_memory,
+ const base::FilePath &relative_partition_path,
+ network::mojom::NetworkContextParams *network_context_params,
+ network::mojom::CertVerifierCreationParams *cert_verifier_creation_params) override;
+
std::vector<base::FilePath> GetNetworkContextsParentDirectory() override;
- void RegisterNonNetworkNavigationURLLoaderFactories(int frame_tree_node_id, NonNetworkURLLoaderFactoryMap *factories) override;
+ void RegisterNonNetworkNavigationURLLoaderFactories(int frame_tree_node_id, base::UkmSourceId ukm_source_id,
+ NonNetworkURLLoaderFactoryDeprecatedMap *uniquely_owned_factories,
+ NonNetworkURLLoaderFactoryMap *factories) override;
void RegisterNonNetworkSubresourceURLLoaderFactories(int render_process_id, int render_frame_id,
- NonNetworkURLLoaderFactoryMap* factories) override;
+ NonNetworkURLLoaderFactoryDeprecatedMap *uniquely_owned_factories,
+ NonNetworkURLLoaderFactoryMap *factories) override;
void RegisterNonNetworkWorkerMainResourceURLLoaderFactories(content::BrowserContext* browser_context,
NonNetworkURLLoaderFactoryMap* factories) override;
+ void RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(content::BrowserContext* browser_context,
+ NonNetworkURLLoaderFactoryMap* factories) override;
+ void SiteInstanceGotProcess(content::SiteInstance *site_instance) override;
+ void SiteInstanceDeleting(content::SiteInstance *site_instance) override;
+ base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(content::BrowserContext *browser_context) override;
+
+ content::WebContentsViewDelegate* GetWebContentsViewDelegate(content::WebContents* web_contents) override;
static std::string getUserAgent();
std::string GetUserAgent() override { return getUserAgent(); }
std::string GetProduct() override;
-
-private:
- void InitFrameInterfaces();
-
- scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick;
- std::unique_ptr<service_manager::BinderRegistry> m_frameInterfaces;
- std::unique_ptr<service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>> m_frameInterfacesParameterized;
};
} // namespace QtWebEngineCore
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 647d45819..560cdbf54 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -48,13 +48,15 @@
#include "base/version.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_constants.h"
+#include "extensions/buildflags/buildflags.h"
+#include "extensions/common/constants.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
#include "media/media_buildflags.h"
#include "ui/base/layout.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
-#include "services/service_manager/embedder/switches.h"
+#include "services/service_manager/switches.h"
#include "type_conversion.h"
#include <QCoreApplication>
@@ -71,7 +73,7 @@
// File name of the CDM on different platforms.
const char kWidevineCdmFileName[] =
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
"widevinecdm.plugin";
#elif defined(OS_WIN)
"widevinecdm.dll";
@@ -84,7 +86,7 @@ const char kWidevineCdmFileName[] =
#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 kPdfPluginPath[] = "internal-pdf-viewer";
const char kPdfPluginSrc[] = "src";
#endif // QT_CONFIG(webengine_printing_and_pdf)
@@ -422,8 +424,7 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo>
content::CdmCapability capability(
{}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs},
{media::CdmSessionType::kTemporary,
- media::CdmSessionType::kPersistentLicense},
- {});
+ media::CdmSessionType::kPersistentLicense});
// Register kExternalClearKeyDifferentGuidTestKeySystem first separately.
// Otherwise, it'll be treated as a sub-key-system of normal
@@ -446,7 +447,15 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo>
void ContentClientQt::AddAdditionalSchemes(Schemes* schemes)
{
- schemes->standard_schemes.push_back("chrome-extension");
+ // Matching ChromeContentClient::AddAdditionalSchemes
+ schemes->standard_schemes.push_back(extensions::kExtensionScheme);
+ schemes->secure_schemes.push_back(extensions::kExtensionScheme);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ schemes->service_worker_schemes.push_back(extensions::kExtensionScheme);
+ schemes->cors_enabled_schemes.push_back(extensions::kExtensionScheme);
+ schemes->csp_bypassing_schemes.push_back(extensions::kExtensionScheme);
+#endif
}
base::StringPiece ContentClientQt::GetDataResource(int resource_id, ui::ScaleFactor scale_factor)
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 2d7d1eb57..6137b0bea 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -42,6 +42,7 @@
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
+#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/grit/generated_resources.h"
@@ -55,8 +56,8 @@
#include "ui/base/webui/jstemplate_builder.h"
#include "net/grit/net_resources.h"
#include "net/base/net_module.h"
-#include "services/service_manager/embedder/switches.h"
-#include "services/service_manager/sandbox/switches.h"
+#include "sandbox/policy/switches.h"
+#include "services/service_manager/switches.h"
#include "url/url_util_qt.h"
#include "content_client_qt.h"
@@ -82,7 +83,7 @@
#include "media/gpu/windows/media_foundation_video_encode_accelerator_win.h"
#endif
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
#include "content/public/common/content_features.h"
#include "media/gpu/mac/vt_video_decode_accelerator_mac.h"
#endif
@@ -178,7 +179,9 @@ void ContentMainDelegateQt::PreSandboxStartup()
#endif
net::NetModule::SetResourceProvider(PlatformResourceProvider);
- ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getApplicationLocale(), nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
+
+ base::i18n::SetICUDefaultLocale(WebEngineLibraryInfo::getApplicationLocale());
+ ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getResolvedLocale(), nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
logging::LoggingSettings settings;
@@ -216,7 +219,7 @@ void ContentMainDelegateQt::PreSandboxStartup()
media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
#endif
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
if (base::FeatureList::IsEnabled(features::kMacV2GPUSandbox)) {
TRACE_EVENT0("gpu", "Initialize VideoToolbox");
media::InitializeVideoToolbox();
@@ -224,7 +227,8 @@ void ContentMainDelegateQt::PreSandboxStartup()
#endif
if (parsedCommandLine->HasSwitch(service_manager::switches::kApplicationName)) {
- const std::string appName = parsedCommandLine->GetSwitchValueASCII(service_manager::switches::kApplicationName);
+ std::string appName = parsedCommandLine->GetSwitchValueASCII(service_manager::switches::kApplicationName);
+ appName = QByteArray::fromPercentEncoding(QByteArray::fromStdString(appName)).toStdString();
QCoreApplication::setApplicationName(QString::fromStdString(appName));
#if defined(OS_LINUX)
media::AudioManager::SetGlobalAppName(appName);
@@ -259,7 +263,7 @@ content::ContentRendererClient *ContentMainDelegateQt::CreateContentRendererClie
#if defined(OS_LINUX)
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
std::string process_type = parsedCommandLine->GetSwitchValueASCII(switches::kProcessType);
- bool no_sandbox = parsedCommandLine->HasSwitch(service_manager::switches::kNoSandbox);
+ bool no_sandbox = parsedCommandLine->HasSwitch(sandbox::policy::switches::kNoSandbox);
// Reload locale if the renderer process is sandboxed
if (process_type == switches::kRendererProcess && !no_sandbox) {
diff --git a/src/core/core.pro b/src/core/core.pro
index f2d3fd307..fa1d7f6a7 100644
--- a/src/core/core.pro
+++ b/src/core/core.pro
@@ -7,9 +7,13 @@ TEMPLATE = subdirs
core_headers.file = core_headers.pro
core_api.file = api/core_api.pro
+core_lipo.file = core_lipo.pro
+core_lipo.depends = gn_run
+
# This will take the compile output of ninja, and link+deploy the final binary.
core_module.file = core_module.pro
core_module.depends = core_api
+isUniversal(): core_module.depends += core_lipo
core_generator.file = core_generator.pro
core_generator.depends = core_headers
@@ -44,5 +48,7 @@ core_project.depends = gn_run
core_api \
core_module
+ isUniversal(): SUBDIRS += core_lipo
+
false: SUBDIRS += core_project
}
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index 836d30c0e..a846f2fbc 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -21,9 +21,13 @@ DEFINES += QT_NO_KEYWORDS \
BUILDING_CHROMIUM
# Ensure that response files, generated by qtbase/mkspecs/features/moc.prf, are found by moc.
-MOC_DIR = $$OUT_PWD/$$getConfigDir()/.moc
-RCC_DIR = $$OUT_PWD/$$getConfigDir()/.rcc
-
+isUniversal() {
+ MOC_DIR = $$OUT_PWD/$$QT_ARCH/$$getConfigDir()/.moc
+ RCC_DIR = $$OUT_PWD/$$QT_ARCH/$$getConfigDir()/.rcc
+} else {
+ MOC_DIR = $$OUT_PWD/$$getConfigDir()/.moc
+ RCC_DIR = $$OUT_PWD/$$getConfigDir()/.rcc
+}
# Assume that we want mobile touch and low-end hardware behaviors
# whenever we are cross compiling.
qtConfig(webengine-embedded-build): DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES
@@ -52,7 +56,6 @@ SOURCES = \
color_chooser_controller.cpp \
common/qt_ipc_logging.cpp \
common/qt_messages.cpp \
- common/user_script_data.cpp \
compositor/content_gpu_client_qt.cpp \
compositor/display_frame_sink.cpp \
compositor/display_overrides.cpp \
@@ -111,11 +114,10 @@ SOURCES = \
renderer/content_renderer_client_qt.cpp \
renderer/content_settings_observer_qt.cpp \
renderer/render_frame_observer_qt.cpp \
- renderer/render_view_observer_qt.cpp \
- renderer/render_thread_observer_qt.cpp \
+ renderer/web_engine_page_render_frame.cpp \
+ renderer/render_configuration.cpp \
renderer/user_resource_controller.cpp \
- renderer/plugins/plugin_placeholder_qt.cpp \
- renderer_host/render_view_observer_host_qt.cpp \
+ renderer_host/web_engine_page_host.cpp \
renderer_host/user_resource_controller_host.cpp \
resource_bundle_qt.cpp \
resource_context_qt.cpp \
@@ -155,7 +157,6 @@ HEADERS = \
color_chooser_controller_p.h \
color_chooser_controller.h \
common/qt_messages.h \
- common/user_script_data.h \
compositor/content_gpu_client_qt.h \
compositor/display_frame_sink.h \
compositor/display_software_output_surface.h \
@@ -217,11 +218,10 @@ HEADERS = \
renderer/content_renderer_client_qt.h \
renderer/content_settings_observer_qt.h \
renderer/render_frame_observer_qt.h \
- renderer/render_view_observer_qt.h \
- renderer/render_thread_observer_qt.h \
+ renderer/web_engine_page_render_frame.h \
+ renderer/render_configuration.h \
renderer/user_resource_controller.h \
- renderer/plugins/plugin_placeholder_qt.h \
- renderer_host/render_view_observer_host_qt.h \
+ renderer_host/web_engine_page_host.h \
renderer_host/user_resource_controller_host.h \
request_controller.h \
resource_context_qt.h \
@@ -320,12 +320,16 @@ qtConfig(webengine-extensions) {
common/extensions/extensions_api_provider_qt.cpp \
common/extensions/extensions_client_qt.cpp \
extensions/component_extension_resource_manager_qt.cpp \
+ extensions/extension_host_delegate_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_client_qt.cpp \
+ extensions/messaging_delegate_qt.cpp \
extensions/mime_handler_view_guest_delegate_qt.cpp \
+ extensions/pdf_iframe_navigation_throttle_qt.cpp \
+ extensions/plugin_service_filter_qt.cpp \
net/plugin_response_interceptor_url_loader_throttle.cpp \
renderer/extensions/extensions_dispatcher_delegate_qt.cpp \
renderer/extensions/extensions_renderer_client_qt.cpp \
@@ -336,12 +340,16 @@ qtConfig(webengine-extensions) {
common/extensions/extensions_api_provider_qt.h \
common/extensions/extensions_client_qt.h \
extensions/component_extension_resource_manager_qt.h \
+ extensions/extension_host_delegate_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_client_qt.h \
+ extensions/messaging_delegate_qt.h \
extensions/mime_handler_view_guest_delegate_qt.h \
+ extensions/pdf_iframe_navigation_throttle_qt.h \
+ extensions/plugin_service_filter_qt.h \
net/plugin_response_interceptor_url_loader_throttle.h \
renderer/extensions/extensions_dispatcher_delegate_qt.h \
renderer/extensions/extensions_renderer_client_qt.h \
diff --git a/src/core/core_gn_config.pri b/src/core/core_gn_config.pri
index 2b8f2e18f..379bbac94 100644
--- a/src/core/core_gn_config.pri
+++ b/src/core/core_gn_config.pri
@@ -1,10 +1,16 @@
CONFIG = gn_generator $$CONFIG
GN_SRC_DIR = $$PWD
-GN_FILE = $$OUT_PWD/$$getConfigDir()/BUILD.gn
+isUniversal() {
+ for(arch, QT_ARCHS) {
+ GN_FILES += $$OUT_PWD/$$arch/$$getConfigDir()/BUILD.gn
+ }
+} else {
+ GN_FILES = $$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
-qtConfig (webengine-extensions) {
+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
diff --git a/src/core/core_lipo.pro b/src/core/core_lipo.pro
new file mode 100644
index 000000000..41846b7f2
--- /dev/null
+++ b/src/core/core_lipo.pro
@@ -0,0 +1,9 @@
+TEMPLATE = aux
+
+qtConfig(debug_and_release): CONFIG += debug_and_release
+qtConfig(build_all): CONFIG += build_all
+
+TARGET= QtWebEngineCore
+include($${QTWEBENGINE_ROOT}/src/buildtools/config/lipo.pri)
+
+
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 3b439e818..9e087c815 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -1,7 +1,11 @@
MODULE = webenginecore
include(core_common.pri)
-include($${QTWEBENGINE_ROOT}/src/buildtools/config/linking.pri)
+isUniversal() {
+ include($${QTWEBENGINE_ROOT}/src/buildtools/config/lipo_linking.pri)
+} else {
+ include($${QTWEBENGINE_ROOT}/src/buildtools/config/linking.pri)
+}
api_library_name = qtwebenginecoreapi$$qtPlatformTargetSuffix()
api_library_path = $$OUT_PWD/api/$$getConfigDir()
@@ -41,9 +45,19 @@ QMAKE_INFO_PLIST = Info_mac.plist
# and doesn't let Chromium get access to libc symbols through dlsym.
CONFIG -= bsymbolic_functions
-linux:qtConfig(separate_debug_info): QMAKE_POST_LINK="cd $(DESTDIR) && $(STRIP) --strip-unneeded $(TARGET)"
+linux {
+ !ccache:!use_gold_linker:!use_lld_linker {
+ QMAKE_LINK="ulimit -n 4096 && $$QMAKE_LINK"
+ QMAKE_LINK_SHLIB="ulimit -n 4096 && $$QMAKE_LINK_SHLIB"
+ }
+ qtConfig(separate_debug_info): QMAKE_POST_LINK="cd $(DESTDIR) && $(STRIP) --strip-unneeded $(TARGET)"
+}
-REPACK_DIR = $$OUT_PWD/$$getConfigDir()
+isUniversal() {
+ REPACK_DIR = $$OUT_PWD/$$QT_ARCH/$$getConfigDir()
+} else {
+ REPACK_DIR = $$OUT_PWD/$$getConfigDir()
+}
# Duplicated from resources/resources.gyp
LOCALE_LIST = am ar bg bn ca cs da de el en-GB en-US es-419 es et fa fi fil fr gu he hi hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv sw ta te th tr uk vi zh-CN zh-TW
@@ -55,7 +69,7 @@ resources.files = $$REPACK_DIR/qtwebengine_resources.pak \
$$REPACK_DIR/qtwebengine_resources_200p.pak \
$$REPACK_DIR/qtwebengine_devtools_resources.pak
-icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
+icu.files = $$REPACK_DIR/icudtl.dat
!qtConfig(debug_and_release)|!qtConfig(build_all)|CONFIG(release, debug|release) {
qtConfig(framework) {
diff --git a/src/core/desktop_screen_qt.cpp b/src/core/desktop_screen_qt.cpp
index 15a3856fc..fd7a2c54f 100644
--- a/src/core/desktop_screen_qt.cpp
+++ b/src/core/desktop_screen_qt.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -40,74 +40,101 @@
#include "desktop_screen_qt.h"
#include "ui/display/display.h"
-#include "ui/gfx/geometry/point.h"
-#include <QtGlobal>
+#include "type_conversion.h"
-namespace QtWebEngineCore {
-
-gfx::Point DesktopScreenQt::GetCursorScreenPoint()
-{
- Q_UNREACHABLE();
- return gfx::Point();
-}
-
-bool DesktopScreenQt::IsWindowUnderCursor(gfx::NativeWindow)
-{
- Q_UNREACHABLE();
- return false;
-}
+#include <QGuiApplication>
+#include <QScreen>
-gfx::NativeWindow DesktopScreenQt::GetWindowAtScreenPoint(const gfx::Point& point)
-{
- Q_UNREACHABLE();
- return gfx::NativeWindow();
-}
+#include <cmath>
-int DesktopScreenQt::GetNumDisplays() const
-{
- Q_UNREACHABLE();
- return 0;
-}
+namespace QtWebEngineCore {
-std::vector<display::Display>& DesktopScreenQt::GetAllDisplays() const
+static display::Display::Rotation toDisplayRotation(Qt::ScreenOrientation orientation)
{
- static std::vector<display::Display> empty;
- return empty;
+ switch (orientation) {
+ case Qt::PrimaryOrientation:
+ case Qt::LandscapeOrientation:
+ return display::Display::ROTATE_0;
+ case Qt::PortraitOrientation:
+ return display::Display::ROTATE_90;
+ case Qt::InvertedLandscapeOrientation:
+ return display::Display::ROTATE_180;
+ case Qt::InvertedPortraitOrientation:
+ return display::Display::ROTATE_270;
+ }
}
-display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeWindow window) const
+display::Display toDisplayDisplay(int id, const QScreen *screen)
{
- // RenderViewHostImpl::OnStartDragging uses this to determine
- // the scale factor for the view.
- return display::Display(0);
+ auto display = display::Display(id, toGfx(screen->geometry()));
+ display.set_work_area(toGfx(screen->availableGeometry()));
+ display.set_device_scale_factor(screen->devicePixelRatio());
+ display.set_is_monochrome(screen->depth() == 1);
+ display.set_color_depth(screen->depth());
+ display.set_depth_per_component(8); // FIXME: find the real value
+ display.set_display_frequency(std::ceil(screen->refreshRate()));
+ display.set_rotation(toDisplayRotation(screen->orientation()));
+ if (screen->nativeOrientation() != Qt::PrimaryOrientation)
+ display.set_panel_rotation(toDisplayRotation(screen->nativeOrientation()));
+ return display;
}
-display::Display DesktopScreenQt::GetDisplayNearestPoint(const gfx::Point& point) const
+DesktopScreenQt::DesktopScreenQt()
{
- Q_UNREACHABLE();
- return display::Display();
+ initializeScreens();
}
-display::Display DesktopScreenQt::GetDisplayMatching(const gfx::Rect& match_rect) const
+DesktopScreenQt::~DesktopScreenQt()
{
- Q_UNREACHABLE();
- return display::Display();
+ for (auto conn : qAsConst(m_connections))
+ QObject::disconnect(conn);
}
-display::Display DesktopScreenQt::GetPrimaryDisplay() const
+void DesktopScreenQt::initializeScreens()
{
- return display::Display(0);
+ if (updateAllScreens()) {
+ m_connections[0] =
+ QObject::connect(qApp, &QGuiApplication::primaryScreenChanged, [this] (QScreen *screen) {
+ ProcessDisplayChanged(toDisplayDisplay(0, screen), true /* is_primary */);
+ });
+ // no guarantees how these will affect ids:
+ m_connections[1] =
+ QObject::connect(qApp, &QGuiApplication::screenAdded, [this] (QScreen *) {
+ updateAllScreens();
+ });
+ m_connections[2] =
+ QObject::connect(qApp, &QGuiApplication::screenRemoved, [this] (QScreen *) {
+ updateAllScreens();
+ });
+ } else {
+ // Running headless
+ ProcessDisplayChanged(display::Display::GetDefaultDisplay(), true /* is_primary */);
+ m_connections[0] =
+ QObject::connect(qApp, &QGuiApplication::screenAdded, [this] (QScreen *) {
+ display_list().RemoveDisplay(display::kDefaultDisplayId);
+ QObject::disconnect(m_connections[0]);
+ initializeScreens();
+ });
+ }
}
-void DesktopScreenQt::AddObserver(display::DisplayObserver* observer)
+bool DesktopScreenQt::updateAllScreens()
{
- Q_UNREACHABLE();
+ Q_ASSERT(qApp->primaryScreen() == qApp->screens().first());
+ const auto screens = qApp->screens();
+ const int oldLen = GetNumDisplays();
+ for (int i = screens.length(); i < oldLen; ++i)
+ display_list().RemoveDisplay(i);
+ for (int i = 0; i < screens.length(); ++i)
+ ProcessDisplayChanged(toDisplayDisplay(i, screens.at(i)), i == 0 /* is_primary */);
+
+ return screens.length() > 0;
}
-void DesktopScreenQt::RemoveObserver(display::DisplayObserver* observer)
+display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeWindow /*window*/) const
{
- Q_UNREACHABLE();
+ return GetPrimaryDisplay();
}
} // namespace QtWebEngineCore
diff --git a/src/core/desktop_screen_qt.h b/src/core/desktop_screen_qt.h
index 0c52c615a..1b2e095a4 100644
--- a/src/core/desktop_screen_qt.h
+++ b/src/core/desktop_screen_qt.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -40,24 +40,24 @@
#ifndef DESKTOP_SCREEN_QT_H
#define DESKTOP_SCREEN_QT_H
-#include "ui/display/screen.h"
+#include "ui/display/screen_base.h"
+
+#include <qmetaobject.h>
namespace QtWebEngineCore {
-class DesktopScreenQt : public display::Screen {
+class DesktopScreenQt : public display::ScreenBase
+{
public:
- // Overridden from gfx::Screen:
- gfx::Point GetCursorScreenPoint() override;
- bool IsWindowUnderCursor(gfx::NativeWindow) override;
- gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
- int GetNumDisplays() const override;
- std::vector<display::Display>& GetAllDisplays() const override;
- display::Display GetDisplayNearestWindow(gfx::NativeWindow window) const override;
- display::Display GetDisplayNearestPoint(const gfx::Point& point) const override;
- display::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
- display::Display GetPrimaryDisplay() const override;
- void AddObserver(display::DisplayObserver* observer) override;
- void RemoveObserver(display::DisplayObserver* observer) override;
+ DesktopScreenQt();
+ ~DesktopScreenQt() override;
+
+ display::Display GetDisplayNearestWindow(gfx::NativeWindow /*window*/) const override;
+
+private:
+ void initializeScreens();
+ bool updateAllScreens();
+ QMetaObject::Connection m_connections[3];
};
} // namespace QtWebEngineCore
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index da82a46d3..440c52d33 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -59,6 +59,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/values.h"
+#include "chrome/browser/devtools/devtools_eye_dropper.h"
#include "chrome/common/url_constants.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
@@ -117,7 +118,7 @@ std::unique_ptr<base::DictionaryValue> BuildObjectForResponse(const net::HttpRes
static std::string GetFrontendURL()
{
- return "devtools://devtools/bundled/devtools_app.html";
+ return "devtools://devtools/bundled/inspector.html";
}
} // namespace
@@ -442,11 +443,11 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
resource_request->site_for_cookies = net::SiteForCookies::FromUrl(gurl);
resource_request->headers.AddHeadersFromString(headers);
- std::unique_ptr<network::mojom::URLLoaderFactory> file_url_loader_factory;
+ mojo::Remote<network::mojom::URLLoaderFactory> file_url_loader_factory;
scoped_refptr<network::SharedURLLoaderFactory> network_url_loader_factory;
network::mojom::URLLoaderFactory *url_loader_factory;
if (gurl.SchemeIsFile()) {
- file_url_loader_factory = content::CreateFileURLLoaderFactory(base::FilePath(), nullptr);
+ file_url_loader_factory.Bind(content::CreateFileURLLoaderFactory(base::FilePath(), nullptr));
url_loader_factory = file_url_loader_factory.get();
} else if (content::HasWebUIScheme(gurl)) {
base::DictionaryValue response;
@@ -529,6 +530,13 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
return;
} else if (method == "bringToFront") {
Activate();
+ } else if (method == "closeWindow") {
+ web_contents()->Close();
+ } else if (method == "setEyeDropperActive" && params->GetSize() == 1) {
+ bool active;
+ if (!params->GetBoolean(0, &active))
+ return;
+ SetEyeDropperActive(active);
} else {
VLOG(1) << "Unimplemented devtools method: " << message;
return;
@@ -538,6 +546,30 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
SendMessageAck(request_id, nullptr);
}
+void DevToolsFrontendQt::SetEyeDropperActive(bool active)
+{
+ if (!m_inspectedContents)
+ return;
+ if (active) {
+ m_eyeDropper.reset(new DevToolsEyeDropper(
+ m_inspectedContents,
+ base::Bind(&DevToolsFrontendQt::ColorPickedInEyeDropper,
+ base::Unretained(this))));
+ } else {
+ m_eyeDropper.reset();
+ }
+}
+
+void DevToolsFrontendQt::ColorPickedInEyeDropper(int r, int g, int b, int a)
+{
+ base::DictionaryValue color;
+ color.SetInteger("r", r);
+ color.SetInteger("g", g);
+ color.SetInteger("b", b);
+ color.SetInteger("a", a);
+ CallClientFunction("DevToolsAPI.eyeDropperPickedColor", &color, nullptr, nullptr);
+}
+
void DevToolsFrontendQt::DispatchProtocolMessage(content::DevToolsAgentHost *agentHost, base::span<const uint8_t> message)
{
Q_UNUSED(agentHost);
diff --git a/src/core/devtools_frontend_qt.h b/src/core/devtools_frontend_qt.h
index 423131c4e..aac5909dc 100644
--- a/src/core/devtools_frontend_qt.h
+++ b/src/core/devtools_frontend_qt.h
@@ -65,6 +65,7 @@ class RenderViewHost;
class WebContents;
} // namespace content
+class DevToolsEyeDropper;
class PersistentPrefStore;
namespace QtWebEngineCore {
@@ -113,6 +114,8 @@ private:
void RemovePreference(const std::string &name);
void ClearPreferences();
void CreateJsonPreferences(bool clear);
+ void SetEyeDropperActive(bool active);
+ void ColorPickedInEyeDropper(int r, int g, int b, int a);
// We shouldn't be keeping it alive
QWeakPointer<WebContentsAdapter> m_frontendAdapter;
@@ -123,6 +126,7 @@ private:
int m_inspect_element_at_x;
int m_inspect_element_at_y;
std::unique_ptr<content::DevToolsFrontendHost> m_frontendHost;
+ std::unique_ptr<DevToolsEyeDropper> m_eyeDropper;
class NetworkResourceLoader;
std::set<std::unique_ptr<NetworkResourceLoader>, base::UniquePtrComparator> m_loaders;
diff --git a/src/core/devtools_manager_delegate_qt.cpp b/src/core/devtools_manager_delegate_qt.cpp
index 8c4037879..51f00d3e5 100644
--- a/src/core/devtools_manager_delegate_qt.cpp
+++ b/src/core/devtools_manager_delegate_qt.cpp
@@ -181,7 +181,7 @@ void DevToolsManagerDelegateQt::Initialized(const net::IPEndPoint *ip_address)
std::string DevToolsManagerDelegateQt::GetDiscoveryPageHTML()
{
- return ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_DEVTOOLS_DISCOVERY_PAGE_HTML).as_string();
+ return ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_DEVTOOLS_DISCOVERY_PAGE_HTML);
}
bool DevToolsManagerDelegateQt::HasBundledFrontendResources()
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index b3c0c7c07..b694d1759 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -95,6 +95,7 @@ void DownloadManagerDelegateQt::cancelDownload(content::DownloadTargetCallback c
download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
download::DownloadItem::UNKNOWN,
base::FilePath(),
+ base::nullopt,
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
}
@@ -135,6 +136,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download::DownloadItem::VALIDATED,
item->GetForcedFilePath(),
+ base::nullopt,
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
return true;
}
@@ -160,8 +162,11 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
if (suggestedFilename.isEmpty())
suggestedFilename = toQt(item->GetTargetFilePath().AsUTF8Unsafe());
- if (suggestedFilename.isEmpty())
- suggestedFilename = QUrl::fromPercentEncoding(toQByteArray(item->GetURL().ExtractFileName()));
+ if (suggestedFilename.isEmpty()) {
+ GURL itemUrl = item->GetURL();
+ if (!itemUrl.SchemeIs("about") && !itemUrl.SchemeIs("data"))
+ suggestedFilename = QUrl::fromPercentEncoding(toQByteArray(itemUrl.ExtractFileName()));
+ }
if (suggestedFilename.isEmpty()) {
suggestedFilename = QStringLiteral("qwe_download");
@@ -226,6 +231,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
download::DownloadItem::VALIDATED,
filePathForCallback.AddExtension(toFilePathString("download")),
+ base::nullopt,
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
} else
cancelDownload(std::move(*callback));
@@ -289,7 +295,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
++m_currentId,
toQt(web_contents->GetURL()),
download::DownloadItem::IN_PROGRESS,
- 0, /* totalBytes */
+ -1, /* totalBytes */
0, /* receivedBytes */
QStringLiteral("application/x-mimearchive"),
suggestedFilePath,
diff --git a/src/core/extensions/component_extension_resource_manager_qt.cpp b/src/core/extensions/component_extension_resource_manager_qt.cpp
index 1f58de151..fb6bb5950 100644
--- a/src/core/extensions/component_extension_resource_manager_qt.cpp
+++ b/src/core/extensions/component_extension_resource_manager_qt.cpp
@@ -44,12 +44,19 @@
#include "component_extension_resource_manager_qt.h"
+#include "base/check.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/values.h"
-
#include "chrome/grit/component_extension_resources_map.h"
+#include "content/public/browser/browser_thread.h"
+#include "extensions/common/constants.h"
+#include "pdf/buildflags.h"
+
+#if BUILDFLAG(ENABLE_PDF)
+#include "qtwebengine/browser/pdf/pdf_extension_util.h"
+#endif // BUILDFLAG(ENABLE_PDF)
namespace extensions {
@@ -57,6 +64,16 @@ ComponentExtensionResourceManagerQt::ComponentExtensionResourceManagerQt()
{
AddComponentResourceEntries(kComponentExtensionResources,
kComponentExtensionResourcesSize);
+
+#if BUILDFLAG(ENABLE_PDF)
+ base::Value dict(base::Value::Type::DICTIONARY);
+ pdf_extension_util::AddStrings(pdf_extension_util::PdfViewerContext::kPdfViewer, &dict);
+ pdf_extension_util::AddAdditionalData(&dict);
+
+ ui::TemplateReplacements pdf_viewer_replacements;
+ ui::TemplateReplacementsFromDictionaryValue(base::Value::AsDictionaryValue(dict), &pdf_viewer_replacements);
+ template_replacements_[extension_misc::kPdfExtensionId] = std::move(pdf_viewer_replacements);
+#endif
}
ComponentExtensionResourceManagerQt::~ComponentExtensionResourceManagerQt() {}
@@ -85,9 +102,11 @@ bool ComponentExtensionResourceManagerQt::IsComponentExtensionResource(const bas
return false;
}
-const ui::TemplateReplacements *ComponentExtensionResourceManagerQt::GetTemplateReplacementsForExtension(const std::string &) const
+const ui::TemplateReplacements *ComponentExtensionResourceManagerQt::GetTemplateReplacementsForExtension(const std::string &extension_id) const
{
- return nullptr;
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ auto it = template_replacements_.find(extension_id);
+ return it != template_replacements_.end() ? &it->second : nullptr;
}
void ComponentExtensionResourceManagerQt::AddComponentResourceEntries(const GritResourceMap *entries, size_t size)
diff --git a/src/core/extensions/component_extension_resource_manager_qt.h b/src/core/extensions/component_extension_resource_manager_qt.h
index b719c8960..6131e91aa 100644
--- a/src/core/extensions/component_extension_resource_manager_qt.h
+++ b/src/core/extensions/component_extension_resource_manager_qt.h
@@ -47,6 +47,7 @@
#include <map>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "extensions/browser/component_extension_resource_manager.h"
struct GritResourceMap;
@@ -72,6 +73,9 @@ private:
// IsComponentExtensionResource.
std::map<base::FilePath, int> path_to_resource_id_;
+ // A map from an extension ID to its i18n template replacements.
+ std::map<std::string, ui::TemplateReplacements> template_replacements_;
+
DISALLOW_COPY_AND_ASSIGN(ComponentExtensionResourceManagerQt);
};
diff --git a/src/core/extensions/extension_host_delegate_qt.cpp b/src/core/extensions/extension_host_delegate_qt.cpp
new file mode 100644
index 000000000..1a44dee7a
--- /dev/null
+++ b/src/core/extensions/extension_host_delegate_qt.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 "extension_host_delegate_qt.h"
+#include "extension_web_contents_observer_qt.h"
+#include "media_capture_devices_dispatcher.h"
+#include "extension_system_qt.h"
+
+#include "extensions/browser/extension_host.h"
+
+namespace extensions {
+
+ExtensionHostDelegateQt::ExtensionHostDelegateQt()
+{
+}
+
+void ExtensionHostDelegateQt::OnExtensionHostCreated(content::WebContents *web_contents)
+{
+ extensions::ExtensionWebContentsObserverQt::CreateForWebContents(web_contents);
+}
+
+void ExtensionHostDelegateQt::OnRenderViewCreatedForBackgroundPage(ExtensionHost *host)
+{
+ Q_UNUSED(host);
+}
+
+content::JavaScriptDialogManager *ExtensionHostDelegateQt::GetJavaScriptDialogManager()
+{
+ Q_UNREACHABLE();
+ return nullptr;
+}
+
+void ExtensionHostDelegateQt::CreateTab(std::unique_ptr<content::WebContents> web_contents,
+ const std::string &extension_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect &initial_rect,
+ bool user_gesture)
+{
+ Q_UNUSED(web_contents);
+ Q_UNUSED(extension_id);
+ Q_UNUSED(disposition);
+ Q_UNUSED(initial_rect);
+ Q_UNUSED(user_gesture);
+
+ Q_UNREACHABLE();
+}
+
+void ExtensionHostDelegateQt::ProcessMediaAccessRequest(content::WebContents *web_contents,
+ const content::MediaStreamRequest &request,
+ content::MediaResponseCallback callback,
+ const Extension *extension)
+{
+ Q_UNUSED(extension);
+
+ QtWebEngineCore::MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(web_contents, request, std::move(callback));
+}
+
+bool ExtensionHostDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *render_frame_host,
+ const GURL &security_origin,
+ blink::mojom::MediaStreamType type,
+ const Extension *extension)
+{
+ Q_UNUSED(render_frame_host);
+ Q_UNUSED(security_origin);
+ Q_UNUSED(type);
+ Q_UNUSED(extension);
+
+ Q_UNREACHABLE();
+ return false;
+}
+
+content::PictureInPictureResult ExtensionHostDelegateQt::EnterPictureInPicture(content::WebContents *web_contents,
+ const viz::SurfaceId &surface_id,
+ const gfx::Size &natural_size)
+{
+ Q_UNUSED(web_contents);
+ Q_UNUSED(surface_id);
+ Q_UNUSED(natural_size);
+
+ Q_UNREACHABLE();
+ return content::PictureInPictureResult::kNotSupported;
+}
+
+void ExtensionHostDelegateQt::ExitPictureInPicture()
+{
+ Q_UNREACHABLE();
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/extension_host_delegate_qt.h b/src/core/extensions/extension_host_delegate_qt.h
new file mode 100644
index 000000000..42ff56a53
--- /dev/null
+++ b/src/core/extensions/extension_host_delegate_qt.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 EXTENSION_HOST_DELEGATE_QT_H
+#define EXTENSION_HOST_DELEGATE_QT_H
+
+#include "extensions/browser/extension_host_delegate.h"
+
+namespace extensions {
+
+class ExtensionHostDelegateQt : public ExtensionHostDelegate
+{
+public:
+ ExtensionHostDelegateQt();
+
+ // EtensionHostDelegate implementation.
+ void OnExtensionHostCreated(content::WebContents *web_contents) override;
+ void OnRenderViewCreatedForBackgroundPage(ExtensionHost *host) override;
+ content::JavaScriptDialogManager *GetJavaScriptDialogManager() override;
+ void CreateTab(std::unique_ptr<content::WebContents> web_contents,
+ const std::string &extension_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect &initial_rect,
+ bool user_gesture) override;
+ void ProcessMediaAccessRequest(content::WebContents *web_contents,
+ const content::MediaStreamRequest &request,
+ content::MediaResponseCallback callback,
+ const Extension *extension) override;
+ bool CheckMediaAccessPermission(content::RenderFrameHost *render_frame_host,
+ const GURL &security_origin,
+ blink::mojom::MediaStreamType type,
+ const Extension *extension) override;
+ content::PictureInPictureResult EnterPictureInPicture(content::WebContents *web_contents,
+ const viz::SurfaceId &surface_id,
+ const gfx::Size &natural_size) override;
+ void ExitPictureInPicture() override;
+};
+
+} // namespace extensions
+
+#endif // EXTENSION_HOST_DELEGATE_QT_H
diff --git a/src/core/extensions/extension_system_qt.cpp b/src/core/extensions/extension_system_qt.cpp
index 96532d9f6..285b27729 100644
--- a/src/core/extensions/extension_system_qt.cpp
+++ b/src/core/extensions/extension_system_qt.cpp
@@ -61,6 +61,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "chrome/common/buildflags.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
@@ -83,11 +84,10 @@
#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/shared_user_script_manager.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"
@@ -223,11 +223,12 @@ void ExtensionSystemQt::NotifyExtensionLoaded(const Extension *extension)
// Register plugins included with the extension.
// Implementation based on PluginManager::OnExtensionLoaded.
const MimeTypesHandler *handler = MimeTypesHandler::GetHandler(extension);
- if (handler && !handler->handler_url().empty()) {
+ if (handler && handler->HasPlugin()) {
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());
+ info.path = handler->GetPluginPath();
+ info.background_color = handler->GetBackgroundColor();
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;
@@ -278,9 +279,9 @@ ManagementPolicy *ExtensionSystemQt::management_policy()
return nullptr;
}
-SharedUserScriptMaster *ExtensionSystemQt::shared_user_script_master()
+SharedUserScriptManager *ExtensionSystemQt::shared_user_script_manager()
{
- return shared_user_script_master_.get();
+ return shared_user_script_manager_.get();
}
StateStore *ExtensionSystemQt::state_store()
@@ -349,8 +350,8 @@ void ExtensionSystemQt::Init(bool extensions_enabled)
quota_service_.reset(new QuotaService);
app_sorting_.reset(new NullAppSorting);
- shared_user_script_master_ =
- std::make_unique<SharedUserScriptMaster>(browser_context_);
+ shared_user_script_manager_ =
+ std::make_unique<SharedUserScriptManager>(browser_context_);
// Make the chrome://extension-icon/ resource available.
// content::URLDataSource::Add(browser_context_, new ExtensionIconSource(browser_context_));
@@ -358,20 +359,30 @@ void ExtensionSystemQt::Init(bool extensions_enabled)
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);
+
+ {
+ 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);
+ }
+
+#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
+ {
+ std::string hangout_manifest = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_HANGOUT_SERVICES_MANIFEST).as_string();
+ std::unique_ptr<base::DictionaryValue> hangoutManifestDict = ParseManifest(hangout_manifest);
+ base::FilePath path;
+ base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &path);
+ path = path.Append(base::FilePath(FILE_PATH_LITERAL("hangout_services")));
+ std::string id = GenerateId(hangoutManifestDict.get(), path);
+ LoadExtension(id, std::move(hangoutManifestDict), path);
+ }
+#endif // BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
}
}
@@ -390,19 +401,6 @@ std::unique_ptr<ExtensionSet> ExtensionSystemQt::GetDependentExtensions(const Ex
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,
base::OnceClosure callback)
{
@@ -426,4 +424,10 @@ void ExtensionSystemQt::UnregisterExtensionWithRequestContexts(const std::string
FROM_HERE, {BrowserThread::IO},
base::Bind(&InfoMap::RemoveExtension, info_map(), extension_id, reason));
}
+
+bool ExtensionSystemQt::is_ready() const
+{
+ return ready_.is_signaled();
+}
+
} // namespace extensions
diff --git a/src/core/extensions/extension_system_qt.h b/src/core/extensions/extension_system_qt.h
index e3762e8a6..59835657a 100644
--- a/src/core/extensions/extension_system_qt.h
+++ b/src/core/extensions/extension_system_qt.h
@@ -89,7 +89,7 @@ public:
RuntimeData *runtime_data() override;
ManagementPolicy *management_policy() override;
ServiceWorkerManager *service_worker_manager() override;
- SharedUserScriptMaster *shared_user_script_master() override;
+ SharedUserScriptManager *shared_user_script_manager() override;
StateStore *state_store() override;
StateStore *rules_store() override;
scoped_refptr<ValueStoreFactory> store_factory() override;
@@ -106,20 +106,14 @@ public:
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 base::OneShotEvent &ready() const override { return ready_; }
+ bool is_ready() const override;
+
+ void PerformActionBasedOnOmahaAttributes(const std::string &, const base::Value &) override { /* fixme? */}
private:
void OnExtensionRegisteredWithRequestContexts(scoped_refptr<const extensions::Extension> extension);
@@ -135,7 +129,7 @@ private:
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_;
+ std::unique_ptr<SharedUserScriptManager> shared_user_script_manager_;
// For verifying the contents of extensions read from disk.
diff --git a/src/core/extensions/extension_web_contents_observer_qt.cpp b/src/core/extensions/extension_web_contents_observer_qt.cpp
index 5b1514bb4..e336f70b4 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.cpp
+++ b/src/core/extensions/extension_web_contents_observer_qt.cpp
@@ -43,13 +43,17 @@
#include "extension_web_contents_observer_qt.h"
+#include "components/guest_view/browser/guest_view_base.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/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/manifest.h"
+#include "render_widget_host_view_qt.h"
+
namespace extensions {
ExtensionWebContentsObserverQt::ExtensionWebContentsObserverQt(content::WebContents *web_contents)
@@ -85,6 +89,16 @@ void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost
policy->GrantRequestOrigin(process_id, url::Origin::Create(GURL(content::kChromeUIResourcesURL)));
}
+void ExtensionWebContentsObserverQt::RenderViewCreated(content::RenderViewHost *render_view_host)
+{
+ if (web_contents()->IsInnerWebContentsForGuest()) {
+ content::RenderWidgetHost *render_widget_host = render_view_host->GetWidget();
+ content::WebContents *parent_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents());
+ QtWebEngineCore::RenderWidgetHostViewQt *parent_rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent_web_contents->GetRenderWidgetHostView());
+ parent_rwhv->setGuest(static_cast<content::RenderWidgetHostImpl *>(render_widget_host));
+ }
+}
+
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
index 658966b31..c0269e4f5 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.h
+++ b/src/core/extensions/extension_web_contents_observer_qt.h
@@ -61,6 +61,7 @@ public:
// content::WebContentsObserver overrides.
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
+ void RenderViewCreated(content::RenderViewHost *render_view_host) override;
private:
friend class content::WebContentsUserData<ExtensionWebContentsObserverQt>;
diff --git a/src/core/extensions/extensions_api_client_qt.cpp b/src/core/extensions/extensions_api_client_qt.cpp
index 731b79a63..925fd10da 100644
--- a/src/core/extensions/extensions_api_client_qt.cpp
+++ b/src/core/extensions/extensions_api_client_qt.cpp
@@ -43,13 +43,14 @@
// found in the LICENSE file.
#include "extensions_api_client_qt.h"
+#include "messaging_delegate_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 "extension_web_contents_observer_qt.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 "mime_handler_view_guest_delegate_qt.h"
#include "printing/print_view_manager_qt.h"
namespace extensions {
@@ -67,12 +68,12 @@ AppViewGuestDelegate *ExtensionsAPIClientQt::CreateAppViewGuestDelegate() const
std::unique_ptr<guest_view::GuestViewManagerDelegate> ExtensionsAPIClientQt::CreateGuestViewManagerDelegate(content::BrowserContext *context) const
{
- return std::make_unique<guest_view::GuestViewManagerDelegate>();
+ return std::make_unique<extensions::ExtensionsGuestViewManagerDelegate>(context);
}
std::unique_ptr<MimeHandlerViewGuestDelegate> ExtensionsAPIClientQt::CreateMimeHandlerViewGuestDelegate(MimeHandlerViewGuest *guest) const
{
- return std::make_unique<MimeHandlerViewGuestDelegate>();
+ return std::make_unique<MimeHandlerViewGuestDelegateQt>(guest);
}
void ExtensionsAPIClientQt::AttachWebContentsHelpers(content::WebContents *web_contents) const
@@ -82,4 +83,11 @@ void ExtensionsAPIClientQt::AttachWebContentsHelpers(content::WebContents *web_c
ExtensionWebContentsObserverQt::CreateForWebContents(web_contents);
}
+MessagingDelegate *ExtensionsAPIClientQt::GetMessagingDelegate()
+{
+ if (!m_messagingDelegate)
+ m_messagingDelegate = std::make_unique<MessagingDelegateQt>();
+ return m_messagingDelegate.get();
+}
+
} // namespace extensions
diff --git a/src/core/extensions/extensions_api_client_qt.h b/src/core/extensions/extensions_api_client_qt.h
index 2fa69f539..b1b6356e8 100644
--- a/src/core/extensions/extensions_api_client_qt.h
+++ b/src/core/extensions/extensions_api_client_qt.h
@@ -49,6 +49,8 @@
namespace extensions {
+class MessagingDelegate;
+
class ExtensionsAPIClientQt : public ExtensionsAPIClient
{
public:
@@ -61,6 +63,10 @@ public:
std::unique_ptr<MimeHandlerViewGuestDelegate>
CreateMimeHandlerViewGuestDelegate(MimeHandlerViewGuest *guest) const override;
void AttachWebContentsHelpers(content::WebContents *web_contents) const override;
+ MessagingDelegate *GetMessagingDelegate() override;
+
+private:
+ std::unique_ptr<MessagingDelegate> m_messagingDelegate;
};
} // namespace extensions
diff --git a/src/core/extensions/extensions_browser_client_qt.cpp b/src/core/extensions/extensions_browser_client_qt.cpp
index b285aadd8..501252823 100644
--- a/src/core/extensions/extensions_browser_client_qt.cpp
+++ b/src/core/extensions/extensions_browser_client_qt.cpp
@@ -49,25 +49,24 @@
#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/extensions/api/generated_api_registration.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/extensions_browser_api_provider.h"
#include "extensions/browser/extensions_browser_interface_binders.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 "qtwebengine/browser/extensions/api/generated_api_registration.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/zlib/google/compression_utils.h"
@@ -78,10 +77,10 @@
#include "extension_web_contents_observer_qt.h"
#include "extensions_api_client_qt.h"
#include "extensions_browser_client_qt.h"
+#include "extension_host_delegate_qt.h"
#include "web_engine_library_info.h"
using content::BrowserContext;
-using content::BrowserThread;
namespace {
@@ -111,29 +110,13 @@ scoped_refptr<base::RefCountedMemory> GetResource(int resource_id, const std::st
extension_id)
: nullptr;
- bool is_gzipped = rb.IsGzipped(resource_id);
- if (!bytes->size() || (!replacements && !is_gzipped)) {
- return bytes;
- }
-
- base::StringPiece input(reinterpret_cast<const char *>(bytes->front()), bytes->size());
-
- std::string temp_str;
-
- base::StringPiece source = input;
- if (is_gzipped) {
- temp_str.resize(compression::GetUncompressedSize(input));
- source = temp_str;
- CHECK(compression::GzipUncompress(input, source));
- }
-
if (replacements) {
- temp_str = ui::ReplaceTemplateExpressions(source, *replacements);
+ base::StringPiece input(reinterpret_cast<const char *>(bytes->front()), bytes->size());
+ std::string temp_str = ui::ReplaceTemplateExpressions(input, *replacements);
+ DCHECK(!temp_str.empty());
+ return base::RefCountedString::TakeString(&temp_str);
}
-
- DCHECK(!temp_str.empty());
-
- return base::RefCountedString::TakeString(&temp_str);
+ return bytes;
}
// Loads an extension resource in a Chrome .pak file. These are used by
@@ -156,7 +139,9 @@ public:
// mojom::URLLoader implementation:
void FollowRedirect(const std::vector<std::string> &removed_headers,
- const net::HttpRequestHeaders &modified_headers, const base::Optional<GURL> &new_url) override
+ const net::HttpRequestHeaders &modified_headers,
+ const net::HttpRequestHeaders &modified_cors_exempt_headers,
+ const base::Optional<GURL> &new_url) override
{
NOTREACHED() << "No redirects for local file loads.";
}
@@ -210,11 +195,10 @@ private:
return;
}
head->headers = response_headers_;
- head->headers->AddHeader(base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentLength,
- base::NumberToString(head->content_length).c_str()));
+ head->headers->AddHeader(net::HttpRequestHeaders::kContentLength,
+ base::NumberToString(head->content_length).c_str());
if (!head->mime_type.empty()) {
- head->headers->AddHeader(
- base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentType, head->mime_type.c_str()));
+ head->headers->AddHeader(net::HttpRequestHeaders::kContentType, head->mime_type.c_str());
}
client_->OnReceiveResponse(std::move(head));
client_->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
@@ -266,11 +250,46 @@ private:
namespace extensions {
+// Copied from chrome/browser/extensions/chrome_extensions_browser_api_provider.(h|cc)
+class ChromeExtensionsBrowserAPIProvider : public ExtensionsBrowserAPIProvider
+{
+public:
+ ChromeExtensionsBrowserAPIProvider() = default;
+ ~ChromeExtensionsBrowserAPIProvider() override = default;
+
+ void RegisterExtensionFunctions(ExtensionFunctionRegistry *registry) override
+ {
+ // Generated APIs from Chrome.
+ api::ChromeGeneratedFunctionRegistry::RegisterAll(registry);
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsBrowserAPIProvider);
+};
+
+class QtWebEngineExtensionsBrowserAPIProvider : public ExtensionsBrowserAPIProvider
+{
+public:
+ QtWebEngineExtensionsBrowserAPIProvider() = default;
+ ~QtWebEngineExtensionsBrowserAPIProvider() override = default;
+
+ void RegisterExtensionFunctions(ExtensionFunctionRegistry *registry) override
+ {
+ // Generated APIs from QtWebEngine.
+ api::QtWebEngineGeneratedFunctionRegistry::RegisterAll(registry);
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(QtWebEngineExtensionsBrowserAPIProvider);
+};
+
ExtensionsBrowserClientQt::ExtensionsBrowserClientQt()
: api_client_(new ExtensionsAPIClientQt)
, resource_manager_(new ComponentExtensionResourceManagerQt)
{
AddAPIProvider(std::make_unique<CoreExtensionsBrowserAPIProvider>());
+ AddAPIProvider(std::make_unique<ChromeExtensionsBrowserAPIProvider>());
+ AddAPIProvider(std::make_unique<QtWebEngineExtensionsBrowserAPIProvider>());
}
ExtensionsBrowserClientQt::~ExtensionsBrowserClientQt()
@@ -316,7 +335,7 @@ BrowserContext *ExtensionsBrowserClientQt::GetOriginalContext(BrowserContext *co
bool ExtensionsBrowserClientQt::IsGuestSession(BrowserContext *context) const
{
- return false;
+ return context->IsOffTheRecord();
}
bool ExtensionsBrowserClientQt::IsExtensionIncognitoEnabled(const std::string &extension_id,
@@ -385,10 +404,13 @@ bool ExtensionsBrowserClientQt::AllowCrossRendererResourceLoad(const GURL &url,
const ExtensionSet &extensions,
const ProcessMap &process_map)
{
-
if (extension && extension->id() == extension_misc::kPdfExtensionId)
return true;
+ // hangout services id
+ if (extension && extension->id() == "nkeimhogjdpnpccoofpliimaahmaaome")
+ return true;
+
bool allowed = false;
if (url_request_util::AllowCrossRendererResourceLoad(url, resource_type,
page_transition, child_id,
@@ -417,9 +439,7 @@ ProcessManagerDelegate *ExtensionsBrowserClientQt::GetProcessManagerDelegate() c
std::unique_ptr<ExtensionHostDelegate> ExtensionsBrowserClientQt::CreateExtensionHostDelegate()
{
- // TODO(extensions): Implement to support Apps.
- NOTREACHED();
- return std::unique_ptr<ExtensionHostDelegate>();
+ return std::unique_ptr<ExtensionHostDelegate>(new ExtensionHostDelegateQt);
}
bool ExtensionsBrowserClientQt::DidVersionUpdate(BrowserContext *context)
@@ -448,7 +468,7 @@ ExtensionSystemProvider *ExtensionsBrowserClientQt::GetExtensionSystemFactory()
}
void ExtensionsBrowserClientQt::RegisterBrowserInterfaceBindersForFrame(
- service_manager::BinderMapWithContext<content::RenderFrameHost*> *binder_map,
+ mojo::BinderMapWithContext<content::RenderFrameHost*> *binder_map,
content::RenderFrameHost* render_frame_host,
const Extension* extension) const
{
diff --git a/src/core/extensions/extensions_browser_client_qt.h b/src/core/extensions/extensions_browser_client_qt.h
index b7f944635..5889694b7 100644
--- a/src/core/extensions/extensions_browser_client_qt.h
+++ b/src/core/extensions/extensions_browser_client_qt.h
@@ -93,8 +93,9 @@ public:
bool IsRunningInForcedAppMode() override;
bool IsLoggedInAsPublicAccount() override;
ExtensionSystemProvider *GetExtensionSystemFactory() override;
- void RegisterBrowserInterfaceBindersForFrame(service_manager::BinderMapWithContext<content::RenderFrameHost*> *,
+ void RegisterBrowserInterfaceBindersForFrame(mojo::BinderMapWithContext<content::RenderFrameHost*> *,
content::RenderFrameHost *, const extensions::Extension *) const override;
+
std::unique_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(content::BrowserContext *context) const override;
const ComponentExtensionResourceManager *
GetComponentExtensionResourceManager() override;
diff --git a/src/core/common/user_script_data.cpp b/src/core/extensions/messaging_delegate_qt.cpp
index 6f4b8cb05..c666daa09 100644
--- a/src/core/common/user_script_data.cpp
+++ b/src/core/extensions/messaging_delegate_qt.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,13 +37,20 @@
**
****************************************************************************/
-#include "user_script_data.h"
-#include "base/pickle.h"
+#include "messaging_delegate_qt.h"
-UserScriptData::UserScriptData() : injectionPoint(AfterLoad)
- , injectForSubframes(false)
- , worldId(1)
+#include <QtGlobal>
+
+namespace extensions {
+
+MessagingDelegateQt::MessagingDelegateQt()
+{
+}
+
+std::unique_ptr<base::DictionaryValue> MessagingDelegateQt::MaybeGetTabInfo(content::WebContents *web_contents)
{
- static uint64_t idCount = 0;
- scriptId = idCount++;
+ Q_UNUSED(web_contents);
+ return nullptr;
}
+
+} // namespace extensions
diff --git a/src/core/renderer/render_view_observer_qt.h b/src/core/extensions/messaging_delegate_qt.h
index 5c555b222..44bfdc2d5 100644
--- a/src/core/renderer/render_view_observer_qt.h
+++ b/src/core/extensions/messaging_delegate_qt.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -36,28 +36,31 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef RENDER_VIEW_OBSERVER_QT_H
-#define RENDER_VIEW_OBSERVER_QT_H
-#include "content/public/renderer/render_view_observer.h"
+#ifndef MESSAGING_DELEGATE_QT_H
+#define MESSAGING_DELEGATE_QT_H
-#include <QtGlobal>
+#include "extensions/browser/api/messaging/messaging_delegate.h"
-class RenderViewObserverQt : public content::RenderViewObserver
-{
-public:
- RenderViewObserverQt(content::RenderView *render_view);
+namespace base {
+class DictionaryValue;
+}
-private:
- void onFetchDocumentMarkup(quint64 requestId);
- void onFetchDocumentInnerText(quint64 requestId);
- void onSetBackgroundColor(quint32 color);
+namespace content {
+class WebContents;
+}
- void OnDestruct() override;
+namespace extensions {
- bool OnMessageReceived(const IPC::Message &message) override;
+class MessagingDelegateQt : public MessagingDelegate
+{
+public:
+ MessagingDelegateQt();
- DISALLOW_COPY_AND_ASSIGN(RenderViewObserverQt);
+ // MessagingDelegate implementation.
+ std::unique_ptr<base::DictionaryValue> MaybeGetTabInfo(content::WebContents *web_contents) override;
};
-#endif // RENDER_VIEW_OBSERVER_QT_H
+} // namespace extensions
+
+#endif // MESSAGING_DELEGATE_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
index 58f4f209a..89d3d6f20 100644
--- a/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
@@ -44,12 +44,17 @@
#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/context_menu_params.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "profile_adapter.h"
+#include "render_widget_host_view_qt.h"
+#include "touch_selection_controller_client_qt.h"
+#include "web_contents_adapter.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+
namespace extensions {
MimeHandlerViewGuestDelegateQt::MimeHandlerViewGuestDelegateQt(MimeHandlerViewGuest *)
@@ -63,14 +68,17 @@ 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());
+ content::WebContents *parent_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents);
+ if (auto rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent_web_contents->GetRenderWidgetHostView())) {
+ if (rwhv->getTouchSelectionControllerClient()->handleContextMenu(params))
+ return true;
- // Adjust (x,y) position for offset from guest to embedder.
- new_params.x += guest_coordinates.x();
- new_params.y += guest_coordinates.y();
+ QtWebEngineCore::WebContentsAdapterClient *adapterClient = rwhv->adapterClient();
+ QtWebEngineCore::WebEngineContextMenuData contextMenuData(QtWebEngineCore::WebContentsViewQt::buildContextMenuData(params));
+ contextMenuData.setIsSpellCheckerEnabled(adapterClient->profileAdapter()->isSpellCheckEnabled());
+ adapterClient->contextMenuRequested(contextMenuData);
+ return true;
+ }
return false;
}
diff --git a/src/core/extensions/mime_handler_view_guest_delegate_qt.h b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
index 6cd80689c..8b2e29508 100644
--- a/src/core/extensions/mime_handler_view_guest_delegate_qt.h
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
@@ -46,8 +46,7 @@
#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"
+#include "api/qtwebenginecoreglobal_p.h"
namespace content {
struct ContextMenuParams;
diff --git a/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp b/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
new file mode 100644
index 000000000..7c2fe75f0
--- /dev/null
+++ b/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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/plugins/pdf_iframe_navigation_throttle.cc
+// Copyright 2017 The Chromium 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/pdf_iframe_navigation_throttle_qt.h"
+
+#include "chrome/grit/renderer_resources.h"
+#include "components/strings/grit/components_strings.h"
+#include "content/public/browser/download_utils.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/plugin_service.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "content/public/common/webplugininfo.h"
+#include "net/base/escape.h"
+#include "net/http/http_response_headers.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/webui/jstemplate_builder.h"
+#include "ui/base/webui/web_ui_util.h"
+
+namespace extensions {
+
+constexpr char kPDFMimeType[] = "application/pdf";
+
+// Used to scope the posted navigation task to the lifetime of |web_contents|.
+class PdfWebContentsLifetimeHelper : public content::WebContentsUserData<PdfWebContentsLifetimeHelper>
+{
+public:
+ explicit PdfWebContentsLifetimeHelper(content::WebContents *web_contents)
+ : web_contents_(web_contents)
+ {}
+
+ base::WeakPtr<PdfWebContentsLifetimeHelper> GetWeakPtr()
+ {
+ return weak_factory_.GetWeakPtr();
+ }
+
+ void NavigateIFrameToPlaceholder(const content::OpenURLParams &url_params)
+ {
+ web_contents_->OpenURL(url_params);
+ }
+
+private:
+ friend class content::WebContentsUserData<PdfWebContentsLifetimeHelper>;
+
+ content::WebContents* const web_contents_;
+ base::WeakPtrFactory<PdfWebContentsLifetimeHelper> weak_factory_{this};
+
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(PdfWebContentsLifetimeHelper)
+
+bool IsPDFPluginEnabled(content::NavigationHandle *navigation_handle, bool *is_stale)
+{
+ content::WebContents *web_contents = navigation_handle->GetWebContents();
+ int process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
+ int routing_id = web_contents->GetMainFrame()->GetRoutingID();
+ content::WebPluginInfo plugin_info;
+ // Will check WebEngineSettings by PluginServiceFilterQt
+ return content::PluginService::GetInstance()->GetPluginInfo(
+ process_id, routing_id, navigation_handle->GetURL(),
+ web_contents->GetMainFrame()->GetLastCommittedOrigin(), kPDFMimeType,
+ false /* allow_wildcard */, is_stale, &plugin_info,
+ nullptr /* actual_mime_type */);
+}
+
+std::string GetPDFPlaceholderHTML(const GURL &pdf_url)
+{
+ std::string template_html = ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_PDF_PLUGIN_HTML);
+ webui::AppendWebUiCssTextDefaults(&template_html);
+
+ base::DictionaryValue values;
+ values.SetString("fileName", pdf_url.ExtractFileName());
+ values.SetString("open", l10n_util::GetStringUTF8(IDS_ACCNAME_OPEN));
+ values.SetString("pdfUrl", pdf_url.spec());
+
+ return webui::GetI18nTemplateHtml(template_html, &values);
+}
+
+// static
+std::unique_ptr<content::NavigationThrottle>
+PDFIFrameNavigationThrottleQt::MaybeCreateThrottleFor(content::NavigationHandle *handle)
+{
+ if (handle->IsInMainFrame())
+ return nullptr;
+ return std::make_unique<PDFIFrameNavigationThrottleQt>(handle);
+}
+
+PDFIFrameNavigationThrottleQt::PDFIFrameNavigationThrottleQt(content::NavigationHandle *handle)
+ : content::NavigationThrottle(handle)
+{
+}
+
+PDFIFrameNavigationThrottleQt::~PDFIFrameNavigationThrottleQt()
+{
+}
+
+content::NavigationThrottle::ThrottleCheckResult PDFIFrameNavigationThrottleQt::WillProcessResponse()
+{
+ const net::HttpResponseHeaders *response_headers = navigation_handle()->GetResponseHeaders();
+ if (!response_headers)
+ return content::NavigationThrottle::PROCEED;
+
+ std::string mime_type;
+ response_headers->GetMimeType(&mime_type);
+ if (mime_type != kPDFMimeType)
+ return content::NavigationThrottle::PROCEED;
+
+ // We MUST download responses marked as attachments rather than showing
+ // a placeholder.
+ if (content::download_utils::MustDownload(navigation_handle()->GetURL(), response_headers, mime_type))
+ return content::NavigationThrottle::PROCEED;
+
+ bool is_stale = false;
+ bool pdf_plugin_enabled = IsPDFPluginEnabled(navigation_handle(), &is_stale);
+
+ if (is_stale) {
+ // On browser start, the plugin list may not be ready yet.
+ content::PluginService::GetInstance()->GetPlugins(
+ base::BindOnce(&PDFIFrameNavigationThrottleQt::OnPluginsLoaded,
+ weak_factory_.GetWeakPtr()));
+ return content::NavigationThrottle::DEFER;
+ }
+
+ // If the plugin was found, proceed on the navigation. Otherwise fall through
+ // to the placeholder case.
+ if (pdf_plugin_enabled)
+ return content::NavigationThrottle::PROCEED;
+
+ LoadPlaceholderHTML();
+ return content::NavigationThrottle::CANCEL_AND_IGNORE;
+}
+
+const char *PDFIFrameNavigationThrottleQt::GetNameForLogging()
+{
+ return "PDFIFrameNavigationThrottleQt";
+}
+
+void PDFIFrameNavigationThrottleQt::OnPluginsLoaded(
+ const std::vector<content::WebPluginInfo> &plugins)
+{
+ if (IsPDFPluginEnabled(navigation_handle(), nullptr /* is_stale */)) {
+ Resume();
+ } else {
+ LoadPlaceholderHTML();
+ CancelDeferredNavigation(content::NavigationThrottle::CANCEL_AND_IGNORE);
+ }
+}
+
+void PDFIFrameNavigationThrottleQt::LoadPlaceholderHTML()
+{
+ // Prepare the params to navigate to the placeholder.
+ std::string html = GetPDFPlaceholderHTML(navigation_handle()->GetURL());
+ GURL data_url("data:text/html," + net::EscapePath(html));
+ content::OpenURLParams params = content::OpenURLParams::FromNavigationHandle(navigation_handle());
+ params.url = data_url;
+ params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
+
+ // Post a task to navigate to the placeholder HTML. We don't navigate
+ // synchronously here, as starting a navigation within a navigation is
+ // an antipattern. Use a helper object scoped to the WebContents lifetime to
+ // scope the navigation task to the WebContents lifetime.
+ content::WebContents *web_contents = navigation_handle()->GetWebContents();
+ if (!web_contents)
+ return;
+
+ PdfWebContentsLifetimeHelper::CreateForWebContents(web_contents);
+ PdfWebContentsLifetimeHelper *helper = PdfWebContentsLifetimeHelper::FromWebContents(web_contents);
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&PdfWebContentsLifetimeHelper::NavigateIFrameToPlaceholder,
+ helper->GetWeakPtr(), std::move(params)));
+}
+
+} // namespace extensions
diff --git a/src/core/renderer/plugins/plugin_placeholder_qt.h b/src/core/extensions/pdf_iframe_navigation_throttle_qt.h
index a99c0d045..37f5bf1d6 100644
--- a/src/core/renderer/plugins/plugin_placeholder_qt.h
+++ b/src/core/extensions/pdf_iframe_navigation_throttle_qt.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,42 +37,46 @@
**
****************************************************************************/
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// based on //chrome/browser/plugins/pdf_iframe_navigation_throttle.h
+// Copyright 2017 The Chromium 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 PLUGIN_PLACEHOLDER_QT_H
-#define PLUGIN_PLACEHOLDER_QT_H
+#ifndef PDF_IFRAME_NAVIGATION_THROTTLE_QT
+#define PDF_IFRAME_NAVIGATION_THROTTLE_QT
-#include "base/macros.h"
-#include "components/plugins/renderer/plugin_placeholder.h"
-#include "gin/handle.h"
-#include "gin/wrappable.h"
-#include "third_party/blink/public/web/web_plugin_params.h"
+#include "content/public/browser/navigation_throttle.h"
-namespace QtWebEngineCore {
+#include "base/memory/weak_ptr.h"
-// A basic placeholder that supports only hiding.
-class PluginPlaceholderQt final : public plugins::PluginPlaceholderBase
- , public gin::Wrappable<PluginPlaceholderQt>
+namespace content {
+class NavigationHandle;
+struct WebPluginInfo;
+}
+
+namespace extensions {
+
+// This class prevents automatical download of PDFs when they are embedded
+// in subframes and plugins are disabled in API.
+class PDFIFrameNavigationThrottleQt : public content::NavigationThrottle
{
public:
- static gin::WrapperInfo kWrapperInfo;
+ static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor(content::NavigationHandle *handle);
+
+ explicit PDFIFrameNavigationThrottleQt(content::NavigationHandle *handle);
+ ~PDFIFrameNavigationThrottleQt() override;
- PluginPlaceholderQt(content::RenderFrame* render_frame,
- const blink::WebPluginParams& params,
- const std::string& html_data);
- ~PluginPlaceholderQt() override;
+ // content::NavigationThrottle
+ content::NavigationThrottle::ThrottleCheckResult WillProcessResponse() override;
+ const char *GetNameForLogging() override;
private:
- // WebViewPlugin::Delegate methods:
- v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) final;
+ void OnPluginsLoaded(const std::vector<content::WebPluginInfo> &plugins);
+ void LoadPlaceholderHTML();
- // gin::Wrappable method:
- gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override;
+ base::WeakPtrFactory<PDFIFrameNavigationThrottleQt> weak_factory_{this};
};
-} // namespace QtWebEngineCore
+} // namespace extensions
-#endif // PLUGIN_PLACEHOLDER_QT_H
+#endif // PDF_IFRAME_NAVIGATION_THROTTLE_QT
diff --git a/src/core/extensions/plugin_service_filter_qt.cpp b/src/core/extensions/plugin_service_filter_qt.cpp
new file mode 100644
index 000000000..b29dbbeab
--- /dev/null
+++ b/src/core/extensions/plugin_service_filter_qt.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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/plugin_service_filter_qt.h"
+
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+
+#include "web_contents_delegate_qt.h"
+
+using namespace QtWebEngineCore;
+
+namespace extensions {
+
+// static
+PluginServiceFilterQt *PluginServiceFilterQt::GetInstance() {
+ return base::Singleton<PluginServiceFilterQt>::get();
+}
+
+bool PluginServiceFilterQt::IsPluginAvailable(int render_process_id,
+ int render_frame_id,
+ const GURL &url,
+ const url::Origin &main_frame_origin,
+ content::WebPluginInfo *plugin)
+{
+ content::RenderFrameHost *frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+ content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(frame_host);
+ if (!web_contents) {
+ // Availability checked somewhere before/during WebContents initialization. Let it load and enable
+ // all the plugins at this phase. This information will be queried again when receiving the response
+ // for the requested content. Postponing our decision and enabling/blocking there makes WebEngineSettings
+ // modifiable in runtime without reconstructing WebContents.
+ return true;
+ }
+
+ if (web_contents->IsInnerWebContentsForGuest())
+ web_contents = web_contents->GetOuterWebContents();
+
+ if (auto *delegate = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())) {
+ const WebEngineSettings *settings = delegate->webEngineSettings();
+ if (!settings->testAttribute(WebEngineSettings::PdfViewerEnabled)
+ || !settings->testAttribute(WebEngineSettings::PluginsEnabled))
+ return false;
+ }
+
+ return true;
+}
+
+bool PluginServiceFilterQt::CanLoadPlugin(int render_process_id,
+ const base::FilePath &path)
+{
+ return true;
+}
+
+PluginServiceFilterQt::PluginServiceFilterQt()
+{
+}
+
+PluginServiceFilterQt::~PluginServiceFilterQt()
+{
+}
+
+} // namespace extensions
diff --git a/src/core/renderer_host/render_view_observer_host_qt.h b/src/core/extensions/plugin_service_filter_qt.h
index 8590ecbc5..ea5f082f2 100644
--- a/src/core/renderer_host/render_view_observer_host_qt.h
+++ b/src/core/extensions/plugin_service_filter_qt.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,36 +37,35 @@
**
****************************************************************************/
-#ifndef RENDER_VIEW_OBSERVER_HOST_QT_H
-#define RENDER_VIEW_OBSERVER_HOST_QT_H
+#ifndef PLUGIN_SERVICE_FILTER_QT
+#define PLUGIN_SERVICE_FILTER_QT
-#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/plugin_service_filter.h"
-#include <QtGlobal>
+#include "base/memory/singleton.h"
-namespace content {
-class WebContents;
-}
+namespace extensions {
-namespace QtWebEngineCore {
+class PluginServiceFilterQt : public content::PluginServiceFilter {
+public:
+ static PluginServiceFilterQt* GetInstance();
-class WebContentsAdapterClient;
+ bool IsPluginAvailable(int render_process_id,
+ int render_frame_id,
+ const GURL &url,
+ const url::Origin &main_frame_origin,
+ content::WebPluginInfo *plugin) override;
-class RenderViewObserverHostQt : public content::WebContentsObserver
-{
-public:
- RenderViewObserverHostQt(content::WebContents *, WebContentsAdapterClient *adapterClient);
- void fetchDocumentMarkup(quint64 requestId);
- void fetchDocumentInnerText(quint64 requestId);
+ bool CanLoadPlugin(int render_process_id,
+ const base::FilePath &path) override;
private:
- bool OnMessageReceived(const IPC::Message &message) override;
- void onDidFetchDocumentMarkup(quint64 requestId, const base::string16 &markup);
- void onDidFetchDocumentInnerText(quint64 requestId, const base::string16 &innerText);
+ friend struct base::DefaultSingletonTraits<PluginServiceFilterQt>;
- WebContentsAdapterClient *m_adapterClient;
+ PluginServiceFilterQt();
+ ~PluginServiceFilterQt();
};
-} // namespace QtWebEngineCore
+} // namespace extensions
-#endif // RENDER_VIEW_OBSERVER_HOST_QT_H
+#endif // PLUGIN_SERVICE_FILTER_QT
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 65e2c6f00..22c18ec6f 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -53,16 +53,32 @@
namespace QtWebEngineCore {
-FilePickerController::FilePickerController(FileChooserMode mode, std::unique_ptr<content::FileSelectListener> listener, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject *parent)
+class FilePickerControllerPrivate {
+public:
+ FilePickerController::FileChooserMode mode;
+ scoped_refptr<content::FileSelectListener> listener;
+ QString defaultFileName;
+ QStringList acceptedMimeTypes;
+};
+
+FilePickerController *createFilePickerController(
+ FilePickerController::FileChooserMode mode, scoped_refptr<content::FileSelectListener> listener,
+ const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject *parent = nullptr)
+{
+ auto priv = new FilePickerControllerPrivate{mode, listener, defaultFileName, acceptedMimeTypes};
+ return new FilePickerController(priv, parent);
+}
+
+FilePickerController::FilePickerController(FilePickerControllerPrivate *priv, QObject *parent)
: QObject(parent)
- , m_defaultFileName(defaultFileName)
- , m_acceptedMimeTypes(acceptedMimeTypes)
- , m_listener(std::move(listener))
- , m_mode(mode)
+ , d_ptr(priv)
{
}
-FilePickerController::~FilePickerController() = default;
+FilePickerController::~FilePickerController()
+{
+ delete d_ptr;
+}
void FilePickerController::accepted(const QStringList &files)
{
@@ -79,7 +95,7 @@ void FilePickerController::accepted(const QStringList &files)
if (urlString.startsWith("file:")) {
base::FilePath filePath = toFilePath(urlString).NormalizePathSeparators();
std::vector<base::FilePath::StringType> pathComponents;
- // Splits the file URL into host name, path and file name.
+ // Splits the file URL into scheme, host name, path and file name.
filePath.GetComponents(&pathComponents);
QString absolutePath;
@@ -91,7 +107,7 @@ void FilePickerController::accepted(const QStringList &files)
if (scheme.size() > 5) {
#if defined(OS_WIN)
// There is no slash at the end of the file scheme and it is valid on Windows: file:C:/
- if (scheme.at(5).isLetter() && scheme.at(6) != ':') {
+ if (scheme.size() == 7 && scheme.at(5).isLetter() && scheme.at(6) == ':') {
absolutePath += scheme.at(5) + ":/";
} else {
#endif
@@ -178,9 +194,13 @@ ASSERT_ENUMS_MATCH(FilePickerController::Save, blink::mojom::FileChooserParams_M
void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
{
QStringList files(filesList);
- if (this->m_mode == UploadFolder && !filesList.isEmpty()
- && QFileInfo(filesList.first()).isDir()) // Enumerate the directory
+ base::FilePath baseDir;
+ if (d_ptr->mode == UploadFolder && !filesList.isEmpty()
+ && QFileInfo(filesList.first()).isDir()) {
+ // Enumerate the directory
files = listRecursively(QDir(filesList.first()));
+ baseDir = toFilePath(filesList.first());
+ }
std::vector<blink::mojom::FileChooserFileInfoPtr> chooser_files;
for (const auto &file : qAsConst(files)) {
@@ -189,26 +209,26 @@ void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
}
if (files.isEmpty())
- m_listener->FileSelectionCanceled();
+ d_ptr->listener->FileSelectionCanceled();
else
- m_listener->FileSelected(std::move(chooser_files),
- /* FIXME? */ base::FilePath(),
- static_cast<blink::mojom::FileChooserParams::Mode>(this->m_mode));
+ d_ptr->listener->FileSelected(std::move(chooser_files),
+ baseDir,
+ static_cast<blink::mojom::FileChooserParams::Mode>(d_ptr->mode));
}
QStringList FilePickerController::acceptedMimeTypes() const
{
- return m_acceptedMimeTypes;
+ return d_ptr->acceptedMimeTypes;
}
FilePickerController::FileChooserMode FilePickerController::mode() const
{
- return m_mode;
+ return d_ptr->mode;
}
QString FilePickerController::defaultFileName() const
{
- return m_defaultFileName;
+ return d_ptr->defaultFileName;
}
QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTypes)
diff --git a/src/core/file_picker_controller.h b/src/core/file_picker_controller.h
index 0b680161a..0b84c889e 100644
--- a/src/core/file_picker_controller.h
+++ b/src/core/file_picker_controller.h
@@ -53,17 +53,12 @@
#include "qtwebenginecoreglobal_p.h"
-#include <memory>
-
#include <QObject>
#include <QStringList>
-namespace content {
- class FileSelectListener;
-}
-
namespace QtWebEngineCore {
+class FilePickerControllerPrivate;
class Q_WEBENGINECORE_PRIVATE_EXPORT FilePickerController : public QObject {
Q_OBJECT
public:
@@ -74,8 +69,9 @@ public:
Save
};
- FilePickerController(FileChooserMode mode, std::unique_ptr<content::FileSelectListener> listener, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject * = 0);
+ FilePickerController(FilePickerControllerPrivate *priv, QObject *parent = nullptr);
~FilePickerController() override;
+
QStringList acceptedMimeTypes() const;
QString defaultFileName() const;
FileChooserMode mode() const;
@@ -89,13 +85,9 @@ public Q_SLOTS:
private:
void filesSelectedInChooser(const QStringList &filesList);
- QString m_defaultFileName;
- QStringList m_acceptedMimeTypes;
- std::unique_ptr<content::FileSelectListener> m_listener;
- FileChooserMode m_mode;
-
+ FilePickerControllerPrivate *d_ptr;
};
-} // namespace
+} // namespace QtWebEngineCore
#endif // FILE_PICKER_CONTROLLER_H
diff --git a/src/core/find_text_helper.cpp b/src/core/find_text_helper.cpp
index da9d7f352..534e25862 100644
--- a/src/core/find_text_helper.cpp
+++ b/src/core/find_text_helper.cpp
@@ -97,18 +97,18 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively,
void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, bool findBackward)
{
- if (findText.isEmpty()) {
- stopFinding();
- return;
- }
+ Q_ASSERT(!findText.isEmpty());
- if (m_currentFindRequestId > m_lastCompletedFindRequestId) {
+ const bool findNext = !m_previousFindText.isEmpty() && findText == m_previousFindText;
+ if (isFindTextInProgress()) {
// There are cases where the render process will overwrite a previous request
// with the new search and we'll have a dangling callback, leaving the application
// waiting for it forever.
// Assume that any unfinished find has been unsuccessful when a new one is started
// to cover that case.
m_lastCompletedFindRequestId = m_currentFindRequestId;
+ if (!findNext)
+ m_webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION);
m_viewClient->findTextFinished(QWebEngineFindTextResult());
invokeResultCallback(m_currentFindRequestId, 0);
}
@@ -116,7 +116,7 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively,
blink::mojom::FindOptionsPtr options = blink::mojom::FindOptions::New();
options->forward = !findBackward;
options->match_case = caseSensitively;
- options->find_next = findText == m_previousFindText;
+ options->new_session = !findNext;
m_previousFindText = findText;
m_currentFindRequestId = m_findRequestIdCounter++;
diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro
index 3d6fda80e..9f6e64504 100644
--- a/src/core/gn_run.pro
+++ b/src/core/gn_run.pro
@@ -28,36 +28,55 @@ build_pass|!debug_and_release {
gn_binary = gn
runninja.target = run_ninja
+ QMAKE_EXTRA_TARGETS += runninja
gn_args = $$gnWebEngineArgs()
- gn_args += "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\""
!qtConfig(webengine-system-gn) {
gn_binary = $$system_quote($$system_path($$gnPath()))
}
- gn_args = $$system_quote($$gn_args)
gn_src_root = $$system_quote($$system_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir()))
- gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$getConfigDir()))
gn_python = "--script-executable=$$pythonPathForSystem()"
- gn_run = $$gn_binary gen $$gn_build_root $$gn_python --args=$$gn_args --root=$$gn_src_root
-
- message("Running: $$gn_run ")
- !system($$gn_run) {
- error("GN run error!")
- }
ninjaflags = $$(NINJAFLAGS)
+ enableThreads = $$(GN_MORE_THREADS)
+ isEmpty(enableThreads):macos {
+ gn_threads = "--threads=1"
+ }
isEmpty(ninjaflags):!silent: ninjaflags = "-v"
-
- runninja.commands = $$NINJA $$ninjaflags \$\(NINJAJOBS\) -C $$gn_build_root QtWebEngineCore
- QMAKE_EXTRA_TARGETS += runninja
-
build_pass:build_all: default_target.target = all
else: default_target.target = first
default_target.depends = runninja
QMAKE_EXTRA_TARGETS += default_target
+
+ isUniversal(){
+ for(arch, QT_ARCHS) {
+ gn_target = "qtwebengine_target=\"$$system_path($$OUT_PWD/$$arch/$$getConfigDir()):QtWebEngineCore\""
+ gn_args_per_arch = $$system_quote($$gn_args $$gn_target target_cpu=\"$$gnArch($$arch)\")
+ gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$arch/$$getConfigDir()))
+ gn_run = $$gn_binary gen $$gn_build_root $$gn_python $$gn_threads --args=$$gn_args_per_arch --root=$$gn_src_root
+ message("Running for $$arch: $$gn_run")
+ !system($$gn_run) {
+ error("GN run error for $$arch!")
+ }
+ runninja_$${arch}.target = run_ninja_$${arch}
+ runninja_$${arch}.commands = $$NINJA $$ninjaflags \$\(NINJAJOBS\) -C $$gn_build_root QtWebEngineCore
+ QMAKE_EXTRA_TARGETS += runninja_$${arch}
+ runninja.depends += runninja_$${arch}
+ }
+ } else {
+ gn_args+= "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\""
+ gn_args = $$system_quote($$gn_args)
+ gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$getConfigDir()))
+ gn_run = $$gn_binary gen $$gn_build_root $$gn_python $$gn_threads --args=$$gn_args --root=$$gn_src_root
+ message("Running: $$gn_run")
+ !system($$gn_run) {
+ error("GN run error!")
+ }
+ runninja.commands = $$NINJA $$ninjaflags \$\(NINJAJOBS\) -C $$gn_build_root QtWebEngineCore
+ }
}
!build_pass:debug_and_release {
diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
index d5a7f1297..94f6c6c9a 100644
--- a/src/core/location_provider_qt.cpp
+++ b/src/core/location_provider_qt.cpp
@@ -50,7 +50,6 @@
#include "base/bind.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
#include "content/public/browser/browser_thread.h"
#include "services/device/geolocation/geolocation_provider.h"
#include "services/device/geolocation/geolocation_provider_impl.h"
diff --git a/src/core/location_provider_qt.h b/src/core/location_provider_qt.h
index 8e5ad0e54..db6b94e20 100644
--- a/src/core/location_provider_qt.h
+++ b/src/core/location_provider_qt.h
@@ -47,10 +47,6 @@
QT_FORWARD_DECLARE_CLASS(QThread)
-namespace base {
-class MessageLoop;
-}
-
namespace QtWebEngineCore {
class QtPositioningHelper;
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index 693cfa2e3..fc436cff2 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -59,9 +59,9 @@
#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 "media/audio/audio_device_description.h"
#include "media/audio/audio_manager_base.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
#include "ui/base/l10n/l10n_util.h"
#if QT_CONFIG(webengine_webrtc)
@@ -70,6 +70,13 @@
#endif
#include <QtCore/qcoreapplication.h>
+#include <QtCore/qscopeguard.h>
+
+#if defined(WEBRTC_USE_X11)
+#include <dlfcn.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/Xlib.h>
+#endif
namespace QtWebEngineCore {
@@ -117,25 +124,16 @@ void getDevicesForDesktopCapture(blink::MediaStreamDevices *devices,
content::DesktopMediaID getDefaultScreenId()
{
- // While this function is executing another thread may also want to create a
- // DesktopCapturer [1]. Unfortunately, creating a DesktopCapturer is not
- // thread safe on X11 due to the use of webrtc::XErrorTrap. It's safe to
- // disable this code on X11 since we don't actually need to create a
- // DesktopCapturer to get the screen id anyway
- // (ScreenCapturerLinux::GetSourceList always returns 0 as the id).
- //
- // [1]: webrtc::InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread
-
-#if QT_CONFIG(webengine_webrtc) && !defined(WEBRTC_USE_X11)
+#if QT_CONFIG(webengine_webrtc)
// Source id patterns are different across platforms.
- // On Linux, the hardcoded value "0" is used.
+ // On Linux and macOS, the source ids are randomish numbers assigned by the OS.
// On Windows, the screens are enumerated consecutively in increasing order from 0.
- // On macOS the source ids are randomish numbers assigned by the OS.
// In order to provide a correct screen id, we query for the available screen ids, and
// select the first one as the main display id.
+#if !defined(WEBRTC_USE_X11)
// The code is based on the file
- // src/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc.
+ // chrome/browser/media/webrtc/native_desktop_media_list.cc.
webrtc::DesktopCaptureOptions options =
webrtc::DesktopCaptureOptions::CreateDefault();
options.set_disable_effects(false);
@@ -150,7 +148,61 @@ content::DesktopMediaID getDefaultScreenId()
}
}
}
-#endif
+#else
+ // This is a workaround to avoid thread issues with DesktopCapturer [1]. Unfortunately,
+ // creating a DesktopCapturer is not thread safe on X11 due to the use of webrtc::XErrorTrap.
+ // Can be removed if https://crbug.com/2022 and/or https://crbug.com/570852 are fixed.
+ // The code is based on the file
+ // third_party/webrtc/modules/desktop_capture/linux/screen_capturer_x11.cc.
+ //
+ // [1]: webrtc::InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread
+ Display *display = XOpenDisplay(nullptr);
+ if (!display) {
+ qWarning("Unable to open display.");
+ return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ }
+
+ int randrEventBase = 0;
+ int errorBaseIgnored = 0;
+ if (!XRRQueryExtension(display, &randrEventBase, &errorBaseIgnored)) {
+ qWarning("X server does not support XRandR.");
+ return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ }
+
+ int majorVersion = 0;
+ int minorVersion = 0;
+ if (!XRRQueryVersion(display, &majorVersion, &minorVersion)) {
+ qWarning("X server does not support XRandR.");
+ return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ }
+
+ if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 5)) {
+ qWarning("XRandR entension is older than v1.5.");
+ return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ }
+
+ typedef XRRMonitorInfo *(*GetMonitorsFunc)(Display *, Window, Bool, int *);
+ GetMonitorsFunc getMonitors = reinterpret_cast<GetMonitorsFunc>(dlsym(RTLD_DEFAULT, "XRRGetMonitors"));
+ typedef void (*FreeMonitorsFunc)(XRRMonitorInfo*);
+ FreeMonitorsFunc freeMonitors = reinterpret_cast<FreeMonitorsFunc>(dlsym(RTLD_DEFAULT, "XRRFreeMonitors"));
+ if (!getMonitors || !freeMonitors) {
+ qWarning("Unable to link XRandR monitor functions.");
+ return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ }
+
+ Window rootWindow = RootWindow(display, DefaultScreen(display));
+ if (rootWindow == BadValue) {
+ qWarning("Unable to get the root window.");
+ return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ }
+
+ int numMonitors = 0;
+ XRRMonitorInfo *monitors = getMonitors(display, rootWindow, true, &numMonitors);
+ auto cleanup = qScopeGuard([&] () { freeMonitors(monitors); });
+ if (numMonitors > 0)
+ return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, monitors[0].name);
+#endif // !defined(WEBRTC_USE_X11)
+#endif // QT_CONFIG(webengine_webrtc)
return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
}
@@ -272,7 +324,8 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
break;
}
} else if (desktopVideoRequested) {
- getDevicesForDesktopCapture(&devices, getDefaultScreenId(), desktopAudioRequested,
+ bool captureAudio = desktopAudioRequested && m_loopbackAudioSupported;
+ getDevicesForDesktopCapture(&devices, getDefaultScreenId(), captureAudio,
request.video_type, request.audio_type);
}
}
@@ -309,6 +362,10 @@ MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher()
// content::NOTIFICATION_WEB_CONTENTS_DESTROYED, and that will result in
// possible use after free.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+#if defined(OS_WIN)
+ // Currently loopback audio capture is supported only on Windows.
+ m_loopbackAudioSupported = true;
+#endif
m_notificationsRegistrar.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
content::NotificationService::AllSources());
}
@@ -326,7 +383,7 @@ void MediaCaptureDevicesDispatcher::Observe(int type, const content::Notificatio
}
}
-void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapterClient *adapterClient, content::WebContents *webContents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
+void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -336,10 +393,13 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter
return;
}
+ WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate());
+ WebContentsAdapterClient *adapterClient = delegate->adapterClient();
+
if (flags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) {
const bool screenCaptureEnabled =
adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::ScreenCaptureEnabled);
- const bool originIsSecure = content::IsOriginSecure(request.security_origin);
+ const bool originIsSecure = blink::network_utils::IsOriginSecure(request.security_origin);
if (!screenCaptureEnabled || !originIsSecure) {
std::move(callback).Run(blink::MediaStreamDevices(), MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
@@ -383,9 +443,11 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
}
// Audio is only supported for screen capture streams.
- bool capture_audio = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && request.audio_type == MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE);
+ bool audioRequested = request.audio_type == MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE;
+ bool audioSupported = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && m_loopbackAudioSupported);
+ bool captureAudio = (audioRequested && audioSupported);
- getDevicesForDesktopCapture(&devices, mediaId, capture_audio, request.video_type, request.audio_type);
+ getDevicesForDesktopCapture(&devices, mediaId, captureAudio, request.video_type, request.audio_type);
if (devices.empty())
std::move(callback).Run(devices, MediaStreamRequestResult::INVALID_STATE,
diff --git a/src/core/media_capture_devices_dispatcher.h b/src/core/media_capture_devices_dispatcher.h
index 6a67a53e9..2db457d33 100644
--- a/src/core/media_capture_devices_dispatcher.h
+++ b/src/core/media_capture_devices_dispatcher.h
@@ -66,7 +66,7 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver,
public:
static MediaCaptureDevicesDispatcher *GetInstance();
- void processMediaAccessRequest(WebContentsAdapterClient *, content::WebContents *, const content::MediaStreamRequest &, content::MediaResponseCallback);
+ void processMediaAccessRequest(content::WebContents *, const content::MediaStreamRequest &, content::MediaResponseCallback);
// Called back from our WebContentsAdapter to grant the requested permission.
void handleMediaAccessPermissionResponse(content::WebContents *, const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags);
@@ -127,6 +127,8 @@ private:
content::NotificationRegistrar m_notificationsRegistrar;
+ bool m_loopbackAudioSupported = false;
+
DISALLOW_COPY_AND_ASSIGN(MediaCaptureDevicesDispatcher);
};
diff --git a/src/core/net/client_cert_override.cpp b/src/core/net/client_cert_override.cpp
index f33515f63..d768092e8 100644
--- a/src/core/net/client_cert_override.cpp
+++ b/src/core/net/client_cert_override.cpp
@@ -65,7 +65,7 @@
#include "net/ssl/client_cert_store_win.h"
#endif
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
#include "net/ssl/client_cert_store_mac.h"
#endif
@@ -83,7 +83,7 @@ public:
std::move(private_key_callback).Run(m_key);
}
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
SecIdentityRef sec_identity_ref() const override
{
return nullptr;
@@ -167,7 +167,7 @@ std::unique_ptr<net::ClientCertStore> ClientCertOverrideStore::createNativeStore
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)
+#elif defined(OS_MAC)
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
#else
return nullptr;
diff --git a/src/core/net/client_cert_store_data.cpp b/src/core/net/client_cert_store_data.cpp
index 314e64145..a96e247b2 100644
--- a/src/core/net/client_cert_store_data.cpp
+++ b/src/core/net/client_cert_store_data.cpp
@@ -104,8 +104,8 @@ public:
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 };
+ return net::SSLPrivateKey::DefaultAlgorithmPreferences(EVP_PKEY_id(m_key),
+ /* supports pss */ true);
}
std::string GetProviderName() override {
return "qtwebengine";
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index a7a3a9348..6d72a622b 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -80,7 +80,7 @@ public:
void AllowedAccess(const GURL &url, const net::SiteForCookies &site_for_cookies, AllowedAccessCallback callback) override
{
- bool allow = m_delegate->canGetCookies(toQt(site_for_cookies.RepresentativeUrl()), toQt(url));
+ bool allow = m_delegate->canGetCookies(toQt(site_for_cookies.first_party_url()), toQt(url));
std::move(callback).Run(allow);
}
@@ -143,7 +143,7 @@ void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie
if (callbackId != CallbackDirectory::NoCallbackId)
callback = base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId);
- net::CanonicalCookie::CookieInclusionStatus inclusion;
+ net::CookieInclusionStatus inclusion;
auto canonCookie = net::CanonicalCookie::Create(gurl, cookie_line, base::Time::Now(), base::nullopt, &inclusion);
if (!inclusion.IsInclude()) {
LOG(WARNING) << "QWebEngineCookieStore::setCookie() - Tried to set invalid cookie";
@@ -151,7 +151,8 @@ void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie
}
net::CookieOptions options;
options.set_include_httponly();
- m_mojoCookieManager->SetCanonicalCookie(*canonCookie.get(), gurl.scheme(), options, std::move(callback));
+ options.set_same_site_cookie_context(net::CookieOptions::SameSiteCookieContext::MakeInclusiveForSet());
+ m_mojoCookieManager->SetCanonicalCookie(*canonCookie.get(), gurl, options, std::move(callback));
}
void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin)
@@ -272,10 +273,10 @@ void CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread(qint64 callbackId,
m_client->d_func()->onGetAllCallbackResult(callbackId, rawCookies);
}
-void CookieMonsterDelegateQt::SetCookieCallbackOnUIThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status)
+void CookieMonsterDelegateQt::SetCookieCallbackOnUIThread(qint64 callbackId, net::CookieAccessResult status)
{
if (m_client)
- m_client->d_func()->onSetCallbackResult(callbackId, status.IsInclude());
+ m_client->d_func()->onSetCallbackResult(callbackId, status.status.IsInclude());
}
void CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread(qint64 callbackId, uint numCookies)
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
index 748e92da9..fe1ed5be6 100644
--- a/src/core/net/cookie_monster_delegate_qt.h
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -120,7 +120,7 @@ public:
private:
void GetAllCookiesCallbackOnUIThread(qint64 callbackId, const net::CookieList &cookies);
- void SetCookieCallbackOnUIThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status);
+ void SetCookieCallbackOnUIThread(qint64 callbackId, net::CookieAccessResult status);
void DeleteCookiesCallbackOnUIThread(qint64 callbackId, uint numCookies);
};
diff --git a/src/core/net/custom_url_loader_factory.cpp b/src/core/net/custom_url_loader_factory.cpp
index 709e4451b..c7426a5b9 100644
--- a/src/core/net/custom_url_loader_factory.cpp
+++ b/src/core/net/custom_url_loader_factory.cpp
@@ -91,6 +91,7 @@ public:
// network::mojom::URLLoader:
void FollowRedirect(const std::vector<std::string> &removed_headers,
const net::HttpRequestHeaders &modified_headers,
+ const net::HttpRequestHeaders &modified_cors_exempt_headers, // FIXME: do something with this?
const base::Optional<GURL> &new_url) override
{
// We can be asked for follow our own redirect
@@ -287,9 +288,9 @@ private:
if (!m_redirect.is_empty()) {
m_head->content_length = m_head->encoded_body_length = -1;
- net::URLRequest::FirstPartyURLPolicy first_party_url_policy =
- m_request.update_first_party_url_on_redirect ? net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT
- : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
+ net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy =
+ m_request.update_first_party_url_on_redirect ? net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT
+ : net::RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL;
net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(
m_request.method, m_request.url,
m_request.site_for_cookies,
@@ -309,15 +310,14 @@ private:
m_client->OnStartLoadingResponseBody(std::move(m_pipe.consumer_handle));
m_head = nullptr;
- if (readAvailableData()) // May delete this
- return;
-
m_watcher = std::make_unique<mojo::SimpleWatcher>(
- FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC, m_taskRunner);
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, m_taskRunner);
m_watcher->Watch(m_pipe.producer_handle.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
MOJO_WATCH_CONDITION_SATISFIED,
base::BindRepeating(&CustomURLLoader::notifyReadyWrite,
m_weakPtrFactory.GetWeakPtr()));
+
+ readAvailableData(); // May delete this
}
void notifyCanceled() override
{
@@ -385,8 +385,10 @@ private:
uint32_t bufferSize = 0;
MojoResult beginResult = m_pipe.producer_handle->BeginWriteData(
&buffer, &bufferSize, MOJO_BEGIN_WRITE_DATA_FLAG_NONE);
- if (beginResult == MOJO_RESULT_SHOULD_WAIT)
+ if (beginResult == MOJO_RESULT_SHOULD_WAIT) {
+ m_watcher->ArmOrNotify();
return false; // Wait for pipe watcher
+ }
if (beginResult != MOJO_RESULT_OK)
break;
if (m_maxBytesToRead > 0 && m_maxBytesToRead <= int64_t{std::numeric_limits<uint32_t>::max()})
@@ -457,10 +459,13 @@ private:
class CustomURLLoaderFactory : public network::mojom::URLLoaderFactory {
public:
- CustomURLLoaderFactory(ProfileAdapter *profileAdapter)
+ CustomURLLoaderFactory(ProfileAdapter *profileAdapter, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
: m_taskRunner(base::CreateSequencedTaskRunner({ content::BrowserThread::IO }))
, m_profileAdapter(profileAdapter)
{
+ m_receivers.set_disconnect_handler(base::BindRepeating(
+ &CustomURLLoaderFactory::OnDisconnect, base::Unretained(this)));
+ m_receivers.Add(this, std::move(receiver));
}
~CustomURLLoaderFactory() override = default;
@@ -491,6 +496,19 @@ public:
m_receivers.Add(this, std::move(receiver));
}
+ void OnDisconnect()
+ {
+ if (m_receivers.empty())
+ delete this;
+ }
+
+ static mojo::PendingRemote<network::mojom::URLLoaderFactory> Create(ProfileAdapter *profileAdapter)
+ {
+ mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote;
+ new CustomURLLoaderFactory(profileAdapter, pending_remote.InitWithNewPipeAndPassReceiver());
+ return pending_remote;
+ }
+
const scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> m_receivers;
QPointer<ProfileAdapter> m_profileAdapter;
@@ -499,9 +517,9 @@ public:
} // namespace
-std::unique_ptr<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter)
+mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter)
{
- return std::make_unique<CustomURLLoaderFactory>(profileAdapter);
+ return CustomURLLoaderFactory::Create(profileAdapter);
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/custom_url_loader_factory.h b/src/core/net/custom_url_loader_factory.h
index 58adf4b79..a9eecbd1c 100644
--- a/src/core/net/custom_url_loader_factory.h
+++ b/src/core/net/custom_url_loader_factory.h
@@ -51,7 +51,7 @@
#ifndef CUSTOM_URL_LOADER_FACTORY_H_
#define CUSTOM_URL_LOADER_FACTORY_H_
-#include <memory>
+#include "mojo/public/cpp/bindings/pending_remote.h"
namespace network {
namespace mojom {
@@ -62,7 +62,7 @@ class URLLoaderFactory;
namespace QtWebEngineCore {
class ProfileAdapter;
-std::unique_ptr<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter);
+mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter);
} // namespace QtWebEngineCore
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index 4641717f7..d868e4f54 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -40,63 +40,27 @@
#include "plugin_response_interceptor_url_loader_throttle.h"
#include "base/bind.h"
+#include "base/guid.h"
#include "base/task/post_task.h"
-#include "content/public/browser/browser_task_traits.h"
+#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
+#include "content/public/browser/browser_context.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/download_utils.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
+#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h"
#include "extensions/extension_system_qt.h"
-#include "profile_adapter.h"
-#include "profile_io_data_qt.h"
-#include "profile_qt.h"
#include "web_contents_delegate_qt.h"
#include <string>
namespace QtWebEngineCore {
-void onPdfStreamIntercepted(const GURL &original_url, std::string extension_id, int frame_tree_node_id)
-{
- content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
- 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,
- MISSING_TRAFFIC_ANNOTATION));
- content::BrowserContext::GetDownloadManager(web_contents->GetBrowserContext())->DownloadUrl(std::move(params));
- return;
- }
-
- // The URL passes the original pdf resource url, that will be requested
- // by the pdf viewer extension page.
- content::NavigationController::LoadURLParams params(
- GURL(base::StringPrintf("%s://%s/index.html?%s", extensions::kExtensionScheme,
- extension_id.c_str(), original_url.spec().c_str())));
-
- params.frame_tree_node_id = frame_tree_node_id;
- web_contents->GetController().LoadURLWithParams(params);
-}
-
-
-PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
- content::ResourceContext *resource_context, int resource_type, int frame_tree_node_id)
- : m_resource_context(resource_context), m_resource_type(resource_type), m_frame_tree_node_id(frame_tree_node_id)
-{}
-
PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
content::BrowserContext *browser_context, int resource_type, int frame_tree_node_id)
: m_browser_context(browser_context), m_resource_type(resource_type), m_frame_tree_node_id(frame_tree_node_id)
@@ -106,31 +70,111 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
network::mojom::URLResponseHead *response_head,
bool *defer)
{
- Q_UNUSED(defer);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (content::download_utils::MustDownload(response_url, response_head->headers.get(), response_head->mime_type))
return;
- if (m_resource_context) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- } else {
- DCHECK(m_browser_context);
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- }
+ content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(m_frame_tree_node_id);
+ if (!web_contents)
+ return;
std::string extension_id;
- // FIXME: We should use extensions::InfoMap in the future:
if (response_head->mime_type == "application/pdf")
extension_id = extension_misc::kPdfExtensionId;
if (extension_id.empty())
return;
- *defer = true;
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate());
+ if (!contentsDelegate)
+ return;
+
+ WebEngineSettings *settings = contentsDelegate->webEngineSettings();
+ if (!settings->testAttribute(WebEngineSettings::PdfViewerEnabled)
+ || !settings->testAttribute(WebEngineSettings::PluginsEnabled)) {
+ // PluginServiceFilterQt will inform the URLLoader about the disabled state of plugins
+ // and we can expect the download to be triggered automatically. It's unnecessary to
+ // go further and start the guest view embedding process.
+ return;
+ }
+
+ // Chrome's PDF Extension does not work properly in the face of a restrictive
+ // Content-Security-Policy, and does not currently respect the policy anyway.
+ // Ignore CSP served on a PDF response. https://crbug.com/271452
+ if (extension_id == extension_misc::kPdfExtensionId && response_head->headers)
+ response_head->headers->RemoveHeader("Content-Security-Policy");
+
+ MimeTypesHandler::ReportUsedHandler(extension_id);
+
+ std::string view_id = base::GenerateGUID();
+ // The string passed down to the original client with the response body.
+ std::string payload = view_id;
+
+ mojo::PendingRemote<network::mojom::URLLoader> dummy_new_loader;
+ ignore_result(dummy_new_loader.InitWithNewPipeAndPassReceiver());
+ mojo::Remote<network::mojom::URLLoaderClient> new_client;
+ mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver =
+ new_client.BindNewPipeAndPassReceiver();
+
+
+ uint32_t data_pipe_size = 64U;
+ // Provide the MimeHandlerView code a chance to override the payload. This is
+ // the case where the resource is handled by frame-based MimeHandlerView.
+ *defer = extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
+ m_frame_tree_node_id, response_url, response_head->mime_type, view_id,
+ &payload, &data_pipe_size,
+ base::BindOnce(
+ &PluginResponseInterceptorURLLoaderThrottle::ResumeLoad,
+ weak_factory_.GetWeakPtr()));
+
+ mojo::DataPipe data_pipe(data_pipe_size);
+ uint32_t len = static_cast<uint32_t>(payload.size());
+ CHECK_EQ(MOJO_RESULT_OK,
+ data_pipe.producer_handle->WriteData(
+ payload.c_str(), &len, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
+
+
+ new_client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
+
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.decoded_body_length = len;
+ new_client->OnComplete(status);
+
+ mojo::PendingRemote<network::mojom::URLLoader> original_loader;
+ mojo::PendingReceiver<network::mojom::URLLoaderClient> original_client;
+ delegate_->InterceptResponse(std::move(dummy_new_loader),
+ std::move(new_client_receiver), &original_loader,
+ &original_client);
+
+ // Make a deep copy of URLResponseHead before passing it cross-thread.
+ auto deep_copied_response = response_head->Clone();
+ if (response_head->headers) {
+ deep_copied_response->headers =
+ base::MakeRefCounted<net::HttpResponseHeaders>(
+ response_head->headers->raw_headers());
+ }
+
+ auto transferrable_loader = blink::mojom::TransferrableURLLoader::New();
+ transferrable_loader->url = GURL(
+ extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() +
+ base::GenerateGUID());
+ transferrable_loader->url_loader = std::move(original_loader);
+ transferrable_loader->url_loader_client = std::move(original_client);
+ transferrable_loader->head = std::move(deep_copied_response);
+ transferrable_loader->head->intercepted_by_plugin = true;
+
+ bool embedded = m_resource_type !=
+ static_cast<int>(blink::mojom::ResourceType::kMainFrame);
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
+ extension_id, view_id, embedded, m_frame_tree_node_id,
+ -1 /* render_process_id */, -1 /* render_frame_id */,
+ std::move(transferrable_loader), response_url));
+}
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&onPdfStreamIntercepted,
- response_url,
- extension_id,
- m_frame_tree_node_id));
+void PluginResponseInterceptorURLLoaderThrottle::ResumeLoad() {
+ delegate_->Resume();
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.h b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
index 7b9db6490..205ab25e6 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.h
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
@@ -41,11 +41,11 @@
#define PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
namespace content {
class BrowserContext;
-class ResourceContext;
}
namespace QtWebEngineCore {
@@ -53,8 +53,6 @@ namespace QtWebEngineCore {
class PluginResponseInterceptorURLLoaderThrottle : public blink::URLLoaderThrottle
{
public:
- PluginResponseInterceptorURLLoaderThrottle(content::ResourceContext *resource_context,
- int resource_type, int frame_tree_node_id);
PluginResponseInterceptorURLLoaderThrottle(content::BrowserContext *browser_context,
int resource_type, int frame_tree_node_id);
~PluginResponseInterceptorURLLoaderThrottle() override = default;
@@ -63,11 +61,17 @@ private:
// content::URLLoaderThrottle overrides;
void WillProcessResponse(const GURL &response_url, network::mojom::URLResponseHead *response_head, bool *defer) override;
- content::ResourceContext *m_resource_context = nullptr;
+ // Resumes loading for an intercepted response. This would give the extension
+ // layer chance to initialize its browser side state.
+ void ResumeLoad();
+
content::BrowserContext *m_browser_context = nullptr;
const int m_resource_type;
const int m_frame_tree_node_id;
+ base::WeakPtrFactory<PluginResponseInterceptorURLLoaderThrottle>
+ weak_factory_{this};
+
DISALLOW_COPY_AND_ASSIGN(PluginResponseInterceptorURLLoaderThrottle);
};
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
index b0b46c817..f86c0e997 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.cpp
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -126,7 +126,7 @@ void ProxyingRestrictedCookieManagerQt::GetAllForUrl(const GURL &url,
if (allowCookies(url, site_for_cookies)) {
underlying_restricted_cookie_manager_->GetAllForUrl(url, site_for_cookies, top_frame_origin, std::move(options), std::move(callback));
} else {
- std::move(callback).Run(std::vector<net::CanonicalCookie>());
+ std::move(callback).Run(std::vector<net::CookieWithAccessResult>());
}
}
@@ -197,7 +197,7 @@ bool ProxyingRestrictedCookieManagerQt::allowCookies(const GURL &url, const net:
{
if (!m_profileIoData)
return false;
- return m_profileIoData->canGetCookies(toQt(site_for_cookies.RepresentativeUrl()), toQt(url));
+ return m_profileIoData->canGetCookies(toQt(site_for_cookies.first_party_url()), toQt(url));
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index d63659d2d..a016cbc72 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -42,24 +42,20 @@
#include <utility>
#include "base/bind.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.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/global_request_id.h"
-#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_constants.h"
-#include "content/public/common/url_utils.h"
-#include "net/base/load_flags.h"
+#include "content/public/common/content_switches.h"
#include "net/http/http_status_code.h"
-#include "net/http/http_util.h"
+#include "services/network/public/cpp/cors/cors.h"
+#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
+#include "url/url_util.h"
#include "api/qwebengineurlrequestinfo_p.h"
-#include "profile_qt.h"
#include "type_conversion.h"
+#include "web_contents_adapter.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
@@ -70,6 +66,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+namespace {
+ network::mojom::URLResponseHeadPtr createResponse(const network::ResourceRequest &request) {
+ const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity);
+ network::mojom::URLResponseHeadPtr response = network::mojom::URLResponseHead::New();
+ response->response_type = network::cors::CalculateResponseType(
+ request.mode, disable_web_security || (
+ request.request_initiator && request.request_initiator->IsSameOriginWith(url::Origin::Create(request.url))));
+
+ return response;
+ }
+}
+
namespace QtWebEngineCore {
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, blink::mojom::ResourceType::kMainFrame)
@@ -114,11 +122,10 @@ class InterceptedRequest : public network::mojom::URLLoader
, public network::mojom::URLLoaderClient
{
public:
- InterceptedRequest(int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
+ InterceptedRequest(ProfileAdapter *profile_adapter,
+ int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
const network::ResourceRequest &request,
const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
- QWebEngineUrlRequestInterceptor *profile_request_interceptor,
- QWebEngineUrlRequestInterceptor *page_request_interceptor,
mojo::PendingReceiver<network::mojom::URLLoader> loader,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory);
@@ -137,14 +144,15 @@ public:
// network::mojom::URLLoader
void FollowRedirect(const std::vector<std::string> &removed_headers,
- const net::HttpRequestHeaders &modified_headers, const base::Optional<GURL> &new_url) override;
+ const net::HttpRequestHeaders &modified_headers,
+ const net::HttpRequestHeaders &modified_cors_exempt_headers,
+ const base::Optional<GURL> &new_url) override;
void SetPriority(net::RequestPriority priority, int32_t intra_priority_value) override;
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
-private:
- void InterceptOnUIThread();
- void InterceptOnIOThread(base::WaitableEvent *event);
+ void InterceptOnUIThread(QWebEngineUrlRequestInterceptor *profileInterceptor);
+ void InterceptOnIOThread(base::WaitableEvent *event, QWebEngineUrlRequestInterceptor *profileInterceptor);
void ContinueAfterIntercept();
// This is called when the original URLLoaderClient has a connection error.
@@ -160,12 +168,18 @@ private:
void SendErrorAndCompleteImmediately(int error_code);
+ content::WebContents* webContents();
+ QWebEngineUrlRequestInterceptor* getProfileInterceptor();
+ QWebEngineUrlRequestInterceptor* getPageInterceptor();
+
+ QPointer<ProfileAdapter> profile_adapter_;
const int process_id_;
const uint64_t request_id_;
const int32_t routing_id_;
const uint32_t options_;
- bool input_stream_previously_failed_ = false;
- bool request_was_redirected_ = false;
+ bool allowed_cors_ = true;
+
+ bool loader_error_seen_ = false;
// If the |target_loader_| called OnComplete with an error this stores it.
// That way the destructor can send it to OnReceivedError if safe browsing
@@ -176,9 +190,9 @@ private:
const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
- QWebEngineUrlRequestInfo request_info_;
- QPointer<QWebEngineUrlRequestInterceptor> profile_request_interceptor_;
- QPointer<QWebEngineUrlRequestInterceptor> page_request_interceptor_;
+ static inline void cleanup(QWebEngineUrlRequestInfo *info) { delete info; }
+ QScopedPointer<QWebEngineUrlRequestInfo, InterceptedRequest> request_info_;
+
mojo::Receiver<network::mojom::URLLoader> proxied_loader_receiver_;
mojo::Remote<network::mojom::URLLoaderClient> target_client_;
mojo::Receiver<network::mojom::URLLoaderClient> proxied_client_receiver_{this};
@@ -189,33 +203,52 @@ private:
DISALLOW_COPY_AND_ASSIGN(InterceptedRequest);
};
-InterceptedRequest::InterceptedRequest(int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
+InterceptedRequest::InterceptedRequest(ProfileAdapter *profile_adapter,
+ int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
const network::ResourceRequest &request,
const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
- QWebEngineUrlRequestInterceptor *profile_request_interceptor,
- QWebEngineUrlRequestInterceptor *page_request_interceptor,
mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory)
- : process_id_(process_id)
+ : profile_adapter_(profile_adapter)
+ , process_id_(process_id)
, request_id_(request_id)
, routing_id_(routing_id)
, options_(options)
, request_(request)
, traffic_annotation_(traffic_annotation)
- , profile_request_interceptor_(profile_request_interceptor)
- , page_request_interceptor_(page_request_interceptor)
, proxied_loader_receiver_(this, std::move(loader_receiver))
, target_client_(std::move(client))
, target_factory_(std::move(target_factory))
, weak_factory_(this)
{
- current_response_ = network::mojom::URLResponseHead::New();
+ const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity);
+ current_response_ = createResponse(request_);
// If there is a client error, clean up the request.
target_client_.set_disconnect_handler(
- base::BindOnce(&InterceptedRequest::OnURLLoaderClientError, weak_factory_.GetWeakPtr()));
+ base::BindOnce(&InterceptedRequest::OnURLLoaderClientError, base::Unretained(this)));
proxied_loader_receiver_.set_disconnect_with_reason_handler(
- base::BindOnce(&InterceptedRequest::OnURLLoaderError, weak_factory_.GetWeakPtr()));
+ base::BindOnce(&InterceptedRequest::OnURLLoaderError, base::Unretained(this)));
+ if (!disable_web_security && request_.request_initiator) {
+ const std::vector<std::string> &localSchemes = url::GetLocalSchemes();
+ std::string fromScheme = request_.request_initiator->GetTupleOrPrecursorTupleIfOpaque().scheme();
+ if (base::Contains(localSchemes, fromScheme)) {
+ content::WebContents *wc = webContents();
+ std::string toScheme = request_.url.scheme();
+ // local schemes must have universal access, or be accessing something local and have local access.
+ if (fromScheme != toScheme) {
+ // note allow_file_access_from_file_urls maps to LocalContentCanAccessFileUrls in our API
+ // and allow_universal_access_from_file_urls to LocalContentCanAccessRemoteUrls, so we are
+ // using them as proxies for our API here.
+ if (toScheme == "file")
+ allowed_cors_ = wc && wc->GetOrCreateWebPreferences().allow_file_access_from_file_urls;
+ else if (!base::Contains(localSchemes, toScheme))
+ allowed_cors_ = wc && wc->GetOrCreateWebPreferences().allow_universal_access_from_file_urls;
+ else
+ allowed_cors_ = true; // We should think about this for future patches
+ }
+ }
+ }
}
InterceptedRequest::~InterceptedRequest()
@@ -223,103 +256,122 @@ InterceptedRequest::~InterceptedRequest()
weak_factory_.InvalidateWeakPtrs();
}
+content::WebContents* InterceptedRequest::webContents()
+{
+ if (process_id_) {
+ content::RenderFrameHost *frameHost = content::RenderFrameHost::FromID(process_id_, request_.render_frame_id);
+ return content::WebContents::FromRenderFrameHost(frameHost);
+ }
+
+ return content::WebContents::FromFrameTreeNodeId(request_.render_frame_id);
+}
+
+QWebEngineUrlRequestInterceptor* InterceptedRequest::getProfileInterceptor()
+{
+ return profile_adapter_ ? profile_adapter_->requestInterceptor() : nullptr;
+}
+
+QWebEngineUrlRequestInterceptor* InterceptedRequest::getPageInterceptor()
+{
+ if (auto wc = webContents()) {
+ auto view = static_cast<content::WebContentsImpl *>(wc)->GetView();
+ if (WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client())
+ return client->webContentsAdapter()->requestInterceptor();
+ }
+ return nullptr;
+}
+
void InterceptedRequest::Restart()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- blink::mojom::ResourceType resourceType = blink::mojom::ResourceType(request_.resource_type);
- WebContentsAdapterClient::NavigationType navigationType =
- pageTransitionToNavigationType(ui::PageTransition(request_.transition_type));
- const QUrl originalUrl = toQt(request_.url);
- const QUrl initiator = request_.request_initiator.has_value() ? toQt(request_.request_initiator->GetURL()) : QUrl();
+ // This is a CORS check on the from URL, the normal check on the to URL is applied later
+ if (!allowed_cors_ && current_response_->response_type == network::mojom::FetchResponseType::kCors) {
+ target_client_->OnComplete(network::URLLoaderCompletionStatus(
+ network::CorsErrorStatus(network::mojom::CorsError::kCorsDisabledScheme)));
+ delete this;
+ return;
+ }
- content::WebContents *webContents = nullptr;
- if (process_id_) {
- content::RenderFrameHost *frameHost = content::RenderFrameHost::FromID(process_id_, request_.render_frame_id);
- webContents = content::WebContents::FromRenderFrameHost(frameHost);
- } else {
- webContents = content::WebContents::FromFrameTreeNodeId(request_.render_frame_id);
+ // MEMO since all codepatch leading to Restart scheduled and executed as asynchronous tasks in main thread,
+ // interceptors may change in meantime and also during intercept call, so they should be resolved anew.
+ // Set here only profile's interceptor since it runs first without going to user code.
+ auto profileInterceptor = getProfileInterceptor();
+ if (!profileInterceptor && !getPageInterceptor()) {
+ ContinueAfterIntercept();
+ return;
}
- GURL top_document_url = webContents ? webContents->GetVisibleURL() : GURL();
+ auto resourceType = toQt(blink::mojom::ResourceType(request_.resource_type));
+ auto navigationType = toQt(pageTransitionToNavigationType(ui::PageTransition(request_.transition_type)));
+ const QUrl originalUrl = toQt(request_.url);
+ const QUrl initiator = request_.request_initiator.has_value() ? toQt(request_.request_initiator->GetURL()) : QUrl();
+
+ auto wc = webContents();
+ GURL top_document_url = wc ? wc->GetVisibleURL() : GURL();
QUrl firstPartyUrl;
if (!top_document_url.is_empty())
firstPartyUrl = toQt(top_document_url);
else
- firstPartyUrl = toQt(request_.site_for_cookies.RepresentativeUrl()); // m_topDocumentUrl can be empty for the main-frame.
+ firstPartyUrl = toQt(request_.site_for_cookies.first_party_url()); // m_topDocumentUrl can be empty for the main-frame.
- QWebEngineUrlRequestInfoPrivate *infoPrivate =
- new QWebEngineUrlRequestInfoPrivate(toQt(resourceType), toQt(navigationType), originalUrl, firstPartyUrl,
- initiator, QByteArray::fromStdString(request_.method));
- request_info_ = QWebEngineUrlRequestInfo(infoPrivate);
+ auto info = new QWebEngineUrlRequestInfoPrivate(resourceType, navigationType, originalUrl, firstPartyUrl,
+ initiator, QByteArray::fromStdString(request_.method));
+ Q_ASSERT(!request_info_);
+ request_info_.reset(new QWebEngineUrlRequestInfo(info));
// TODO: remove for Qt6
- if (profile_request_interceptor_ && profile_request_interceptor_->property("deprecated").toBool()) {
+ bool isDeprecatedProfileInterceptor = profileInterceptor == nullptr;
+ if (profileInterceptor && profileInterceptor->property("deprecated").toBool()) {
+ isDeprecatedProfileInterceptor = true;
// sync call supports depracated call of an interceptor on io thread
base::WaitableEvent event;
base::PostTask(FROM_HERE, { content::BrowserThread::IO },
- base::BindOnce(&InterceptedRequest::InterceptOnIOThread, base::Unretained(this), &event));
+ base::BindOnce(&InterceptedRequest::InterceptOnIOThread,
+ base::Unretained(this), &event, profileInterceptor));
event.Wait();
- if (request_info_.changed()) {
+ if (request_info_->changed()) {
ContinueAfterIntercept();
return;
}
}
- InterceptOnUIThread();
+ InterceptOnUIThread(isDeprecatedProfileInterceptor ? nullptr : profileInterceptor);
ContinueAfterIntercept();
}
-void InterceptedRequest::InterceptOnIOThread(base::WaitableEvent *event)
+void InterceptedRequest::InterceptOnIOThread(base::WaitableEvent *event, QWebEngineUrlRequestInterceptor *interceptor)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (profile_request_interceptor_)
- profile_request_interceptor_->interceptRequest(request_info_);
+ interceptor->interceptRequest(*request_info_);
event->Signal();
}
-void InterceptedRequest::InterceptOnUIThread()
+void InterceptedRequest::InterceptOnUIThread(QWebEngineUrlRequestInterceptor *profileInterceptor)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (profile_request_interceptor_ && !profile_request_interceptor_->property("deprecated").toBool())
- profile_request_interceptor_->interceptRequest(request_info_);
+ if (profileInterceptor)
+ profileInterceptor->interceptRequest(*request_info_);
- if (!request_info_.changed() && page_request_interceptor_)
- page_request_interceptor_->interceptRequest(request_info_);
+ if (!request_info_->changed()) {
+ if (auto interceptor = getPageInterceptor())
+ interceptor->interceptRequest(*request_info_);
+ }
}
void InterceptedRequest::ContinueAfterIntercept()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (request_info_.changed()) {
- if (request_info_.d_ptr->shouldBlockRequest)
- return SendErrorAndCompleteImmediately(net::ERR_BLOCKED_BY_CLIENT);
- if (request_info_.d_ptr->shouldRedirectRequest) {
- net::URLRequest::FirstPartyURLPolicy first_party_url_policy =
- request_.update_first_party_url_on_redirect ? net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT
- : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
- net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(
- request_.method, request_.url, request_.site_for_cookies,
- first_party_url_policy, request_.referrer_policy, request_.referrer.spec(),
- net::HTTP_TEMPORARY_REDIRECT, toGurl(request_info_.requestUrl()), base::nullopt,
- false /*insecure_scheme_was_upgraded*/);
-
- // FIXME: Should probably create a new header.
- current_response_->encoded_data_length = 0;
- request_.method = redirectInfo.new_method;
- request_.url = redirectInfo.new_url;
- request_.site_for_cookies = redirectInfo.new_site_for_cookies;
- request_.referrer = GURL(redirectInfo.new_referrer);
- request_.referrer_policy = redirectInfo.new_referrer_policy;
- if (request_.method == net::HttpRequestHeaders::kGetMethod)
- request_.request_body = nullptr;
- target_client_->OnReceiveRedirect(redirectInfo, std::move(current_response_));
- return;
- }
+ if (request_info_) {
+ // cleanup in scope because of delete this and it's not needed else where after
+ decltype(request_info_) scoped_request_info(request_info_.take());
+ QWebEngineUrlRequestInfoPrivate &info = *scoped_request_info->d_ptr;
+
+ if (info.changed) {
+ if (info.shouldBlockRequest)
+ return SendErrorAndCompleteImmediately(net::ERR_BLOCKED_BY_CLIENT);
- if (!request_info_.d_ptr->extraHeaders.isEmpty()) {
- auto end = request_info_.d_ptr->extraHeaders.constEnd();
- for (auto header = request_info_.d_ptr->extraHeaders.constBegin(); header != end; ++header) {
+ for (auto header = info.extraHeaders.constBegin(); header != info.extraHeaders.constEnd(); ++header) {
std::string h = header.key().toStdString();
if (base::LowerCaseEqualsASCII(h, "referer")) {
request_.referrer = GURL(header.value().toStdString());
@@ -327,10 +379,36 @@ void InterceptedRequest::ContinueAfterIntercept()
request_.headers.SetHeader(h, header.value().toStdString());
}
}
+
+ if (info.shouldRedirectRequest) {
+ net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy =
+ request_.update_first_party_url_on_redirect ? net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT
+ : net::RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL;
+ net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(
+ request_.method, request_.url, request_.site_for_cookies,
+ first_party_url_policy, request_.referrer_policy, request_.referrer.spec(),
+ net::HTTP_TEMPORARY_REDIRECT, toGurl(info.url), base::nullopt,
+ false /*insecure_scheme_was_upgraded*/);
+ request_.method = redirectInfo.new_method;
+ request_.url = redirectInfo.new_url;
+ request_.site_for_cookies = redirectInfo.new_site_for_cookies;
+ request_.referrer = GURL(redirectInfo.new_referrer);
+ request_.referrer_policy = redirectInfo.new_referrer_policy;
+ if (request_.method == net::HttpRequestHeaders::kGetMethod)
+ request_.request_body = nullptr;
+ // In case of multiple sequential rediredts, current_response_ has previously been moved to target_client_
+ // so we create a new one using the redirect url.
+ if (!current_response_)
+ current_response_ = createResponse(request_);
+ current_response_->encoded_data_length = 0;
+ target_client_->OnReceiveRedirect(redirectInfo, std::move(current_response_));
+ return;
+ }
}
}
if (!target_loader_ && target_factory_) {
+ loader_error_seen_ = false;
target_factory_->CreateLoaderAndStart(target_loader_.BindNewPipeAndPassReceiver(), routing_id_, request_id_,
options_, request_, proxied_client_receiver_.BindNewPipeAndPassRemote(),
traffic_annotation_);
@@ -349,7 +427,6 @@ void InterceptedRequest::OnReceiveResponse(network::mojom::URLResponseHeadPtr he
void InterceptedRequest::OnReceiveRedirect(const net::RedirectInfo &redirect_info, network::mojom::URLResponseHeadPtr head)
{
// TODO(timvolodine): handle redirect override.
- request_was_redirected_ = true;
current_response_ = head.Clone();
target_client_->OnReceiveRedirect(redirect_info, std::move(head));
request_.url = redirect_info.new_url;
@@ -391,10 +468,11 @@ void InterceptedRequest::OnComplete(const network::URLLoaderCompletionStatus &st
void InterceptedRequest::FollowRedirect(const std::vector<std::string> &removed_headers,
const net::HttpRequestHeaders &modified_headers,
+ const net::HttpRequestHeaders &modified_cors_exempt_headers,
const base::Optional<GURL> &new_url)
{
if (target_loader_)
- target_loader_->FollowRedirect(removed_headers, modified_headers, new_url);
+ target_loader_->FollowRedirect(removed_headers, modified_headers, modified_cors_exempt_headers, new_url);
// If |OnURLLoaderClientError| was called then we're just waiting for the
// connection error handler of |proxied_loader_binding_|. Don't restart the
@@ -436,6 +514,8 @@ void InterceptedRequest::OnURLLoaderError(uint32_t custom_reason, const std::str
// If CallOnComplete was already called, then this object is ready to be deleted.
if (!target_client_)
delete this;
+ else
+ loader_error_seen_ = true;
}
void InterceptedRequest::CallOnComplete(const network::URLLoaderCompletionStatus &status, bool wait_for_loader_error)
@@ -449,7 +529,7 @@ void InterceptedRequest::CallOnComplete(const network::URLLoaderCompletionStatus
if (target_client_)
target_client_->OnComplete(status);
- if (proxied_loader_receiver_.is_bound() && wait_for_loader_error) {
+ if (proxied_loader_receiver_.is_bound() && wait_for_loader_error && !loader_error_seen_) {
// Since the original client is gone no need to continue loading the
// request.
proxied_client_receiver_.reset();
@@ -478,10 +558,10 @@ void InterceptedRequest::SendErrorAndCompleteImmediately(int error_code)
delete this;
}
-ProxyingURLLoaderFactoryQt::ProxyingURLLoaderFactoryQt(int process_id, QWebEngineUrlRequestInterceptor *profile, QWebEngineUrlRequestInterceptor *page,
+ProxyingURLLoaderFactoryQt::ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int process_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_info)
- : m_processId(process_id), m_profileRequestInterceptor(profile), m_pageRequestInterceptor(page), m_weakFactory(this)
+ : m_profileAdapter(adapter), m_processId(process_id), m_weakFactory(this)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (target_factory_info) {
@@ -510,8 +590,8 @@ void ProxyingURLLoaderFactoryQt::CreateLoaderAndStart(mojo::PendingReceiver<netw
m_targetFactory->Clone(target_factory_clone.InitWithNewPipeAndPassReceiver());
// Will manage its own lifetime
- InterceptedRequest *req = new InterceptedRequest(m_processId, request_id, routing_id, options, request, traffic_annotation,
- m_profileRequestInterceptor, m_pageRequestInterceptor, std::move(loader),
+ InterceptedRequest *req = new InterceptedRequest(m_profileAdapter, m_processId, request_id, routing_id, options,
+ request, traffic_annotation, std::move(loader),
std::move(url_loader_client), std::move(target_factory_clone));
req->Restart();
}
diff --git a/src/core/net/proxying_url_loader_factory_qt.h b/src/core/net/proxying_url_loader_factory_qt.h
index e1bcc276c..5345e3220 100644
--- a/src/core/net/proxying_url_loader_factory_qt.h
+++ b/src/core/net/proxying_url_loader_factory_qt.h
@@ -42,16 +42,12 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
-#include "url/gurl.h"
#include <QPointer>
// based on aw_proxying_url_loader_factory.h:
@@ -59,19 +55,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInterceptor)
-
-namespace content {
-class ResourceContext;
-}
-
namespace QtWebEngineCore {
+class ProfileAdapter;
+
class ProxyingURLLoaderFactoryQt : public network::mojom::URLLoaderFactory
{
public:
- ProxyingURLLoaderFactoryQt(int processId, QWebEngineUrlRequestInterceptor *profile,
- QWebEngineUrlRequestInterceptor *page,
+ ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int processId,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_target_factory_remote);
@@ -89,11 +80,10 @@ private:
void OnTargetFactoryError();
void OnProxyBindingError();
+ QPointer<ProfileAdapter> m_profileAdapter;
int m_processId;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> m_proxyReceivers;
mojo::Remote<network::mojom::URLLoaderFactory> m_targetFactory;
- QPointer<QWebEngineUrlRequestInterceptor> m_profileRequestInterceptor;
- QPointer<QWebEngineUrlRequestInterceptor> m_pageRequestInterceptor;
base::WeakPtrFactory<ProxyingURLLoaderFactoryQt> m_weakFactory;
DISALLOW_COPY_AND_ASSIGN(ProxyingURLLoaderFactoryQt);
diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp
index 73bf24f1d..0a9943431 100644
--- a/src/core/net/qrc_url_scheme_handler.cpp
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -67,7 +67,10 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
QFileInfo fileInfo(*file);
QMimeDatabase mimeDatabase;
QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
- job->reply(mimeType.name().toUtf8(), file.take());
+ if (mimeType.name() == QStringLiteral("application/x-extension-html"))
+ job->reply("text/html", file.take());
+ else
+ job->reply(mimeType.name().toUtf8(), file.take());
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/system_network_context_manager.cpp b/src/core/net/system_network_context_manager.cpp
index 611b5eafa..1fba115c6 100644
--- a/src/core/net/system_network_context_manager.cpp
+++ b/src/core/net/system_network_context_manager.cpp
@@ -44,36 +44,16 @@
#include "net/system_network_context_manager.h"
-#include <set>
-#include <unordered_map>
-#include <utility>
-
#include "base/bind.h"
#include "base/command_line.h"
-#include "base/feature_list.h"
-#include "base/logging.h"
-#include "base/sequence_checker.h"
-#include "base/strings/string_split.h"
-#include "base/task/post_task.h"
-#include "base/values.h"
-#include "build/build_config.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
#include "chrome/common/chrome_switches.h"
#include "components/certificate_transparency/ct_known_logs.h"
-#include "components/network_session_configurator/common/network_features.h"
#include "components/network_session_configurator/common/network_switches.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cors_exempt_headers.h"
#include "content/public/browser/network_service_instance.h"
-#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_names.mojom.h"
-#include "content/public/common/user_agent.h"
-#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
-#include "net/dns/public/util.h"
#include "net/net_buildflags.h"
-#include "net/third_party/uri_template/uri_template.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h"
#include "services/network/public/cpp/features.h"
@@ -81,7 +61,6 @@
#include "services/network/public/mojom/host_resolver.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
-#include "url/gurl.h"
namespace {
@@ -102,7 +81,7 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams()
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params = network::mojom::HttpAuthDynamicParams::New();
auto *command_line = base::CommandLine::ForCurrentProcess();
- auth_dynamic_params->server_allowlist = command_line->GetSwitchValueASCII(switches::kAuthServerWhitelist);
+ auth_dynamic_params->server_allowlist = command_line->GetSwitchValueASCII(switches::kAuthServerAllowlist);
// auth_dynamic_params->delegate_allowlist = command_line->GetSwitchValueASCII(switches::kAuthNegotiateDelegateWhitelist);
// auth_dynamic_params->enable_negotiate_port = command_line->HasSwitch(switches::kEnableAuthNegotiatePort);
@@ -241,8 +220,7 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(network::mojom::Networ
network_service->SetUpHttpAuth(CreateHttpAuthStaticParams());
network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams());
- // The system NetworkContext must be created first, since it sets
- // |primary_network_context| to true.
+ // The system NetworkContext is created first
network_service_network_context_.reset();
network_service->CreateNetworkContext(
network_service_network_context_.BindNewPipeAndPassReceiver(),
@@ -263,41 +241,21 @@ void SystemNetworkContextManager::AddSSLConfigToNetworkContextParams(network::mo
network_context_params->initial_ssl_config->symantec_enforcement_disabled = true;
}
-network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateDefaultNetworkContextParams()
+void SystemNetworkContextManager::ConfigureDefaultNetworkContextParams(network::mojom::NetworkContextParams *network_context_params)
{
- network::mojom::NetworkContextParamsPtr network_context_params = network::mojom::NetworkContextParams::New();
- content::UpdateCorsExemptHeader(network_context_params.get());
-
network_context_params->enable_brotli = true;
- // network_context_params->user_agent = GetUserAgent();
-
// Disable referrers by default. Any consumer that enables referrers should
// respect prefs::kEnableReferrers from the appropriate pref store.
network_context_params->enable_referrers = false;
- // const base::CommandLine& command_line =
- // *base::CommandLine::ForCurrentProcess();
-
- // // TODO(eroman): Figure out why this doesn't work in single-process mode,
- // // or if it does work, now.
- // // Should be possible now that a private isolate is used.
- // // http://crbug.com/474654
- // if (!command_line.HasSwitch(switches::kWinHttpProxyResolver)) {
- // if (command_line.HasSwitch(switches::kSingleProcess)) {
- // LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode.";
- // } else {
network_context_params->proxy_resolver_factory = ChromeMojoProxyResolverFactory::CreateWithSelfOwnedReceiver();
- // }
- // }
-
- // network_context_params->pac_quick_check_enabled = local_state_->GetBoolean(prefs::kQuickCheckEnabled);
// Use the SystemNetworkContextManager to populate and update SSL
// configuration. The SystemNetworkContextManager is owned by the
// BrowserProcess itself, so will only be destroyed on shutdown, at which
// point, all NetworkContexts will be destroyed as well.
- AddSSLConfigToNetworkContextParams(network_context_params.get());
+ AddSSLConfigToNetworkContextParams(network_context_params);
// CT is only enabled on Desktop platforms for now.
network_context_params->enforce_chrome_ct_policy = true;
@@ -308,14 +266,13 @@ network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateDefau
log_info->name = ct_log.log_name;
network_context_params->ct_logs.push_back(std::move(log_info));
}
-
- return network_context_params;
}
network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateNetworkContextParams()
{
// TODO(mmenke): Set up parameters here (in memory cookie store, etc).
- network::mojom::NetworkContextParamsPtr network_context_params = CreateDefaultNetworkContextParams();
+ network::mojom::NetworkContextParamsPtr network_context_params = network::mojom::NetworkContextParams::New();
+ ConfigureDefaultNetworkContextParams(network_context_params.get());
network_context_params->context_name = std::string("system");
@@ -328,8 +285,6 @@ network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateNetwo
network_context_params->enable_ftp_url_support = true;
#endif
- network_context_params->primary_network_context = false;
-
proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get());
return network_context_params;
diff --git a/src/core/net/system_network_context_manager.h b/src/core/net/system_network_context_manager.h
index 0dd503ce1..48cd99173 100644
--- a/src/core/net/system_network_context_manager.h
+++ b/src/core/net/system_network_context_manager.h
@@ -46,16 +46,10 @@
#define SYSTEM_NETWORK_CONTEXT_MANAGER_H_
#include <memory>
-#include <string>
-#include <vector>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/optional.h"
-#include "services/network/public/mojom/host_resolver.mojom-forward.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/network_service.mojom-forward.h"
-#include "services/network/public/mojom/ssl_config.mojom-forward.h"
#include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
#include "net/proxy_config_monitor.h"
@@ -67,10 +61,6 @@ class URLLoaderFactory;
class SharedURLLoaderFactory;
} // namespace network
-namespace net_log {
-class NetExportFileWriter;
-}
-
// Responsible for creating and managing access to the system NetworkContext.
// Lives on the UI thread. The NetworkContext this owns is intended for requests
// not associated with a profile. It stores no data on disk, and has no HTTP
@@ -130,8 +120,8 @@ public:
// SSL configuration updates.
void AddSSLConfigToNetworkContextParams(network::mojom::NetworkContextParams *network_context_params);
- // Returns default set of parameters for configuring the network service.
- network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams();
+ // Configures the default set of parameters for the network context.
+ void ConfigureDefaultNetworkContextParams(network::mojom::NetworkContextParams *);
private:
class URLLoaderFactoryForSystem;
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index 27e58d75f..b645a6d72 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -44,39 +44,37 @@
#include "webui_controller_factory_qt.h"
+#include "build_config_qt.h"
+
#include "base/bind.h"
-#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/net_internals/net_internals_ui.h"
#include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
+#include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
#include "chrome/common/url_constants.h"
-#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
-#include "content/public/common/content_client.h"
#include "content/public/common/url_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "media/media_buildflags.h"
#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
-#include "ui/web_dialogs/web_dialog_ui.h"
#include "url/gurl.h"
#if defined(OS_LINUX) || defined(OS_ANDROID)
#include "chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h"
#endif
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+#include "chrome/browser/ui/webui/media/webrtc_logs_ui.h"
+#endif
+
// The Following WebUIs are disabled because they currently doesn't build
// or doesn't work, but would be interesting for us if they did:
// #include "chrome/browser/ui/webui/inspect_ui.h"
-// #include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
-
-// #if BUILDFLAG(ENABLE_WEBRTC)
-// #include "chrome/browser/ui/webui/media/webrtc_logs_ui.h"
-// #endif
// #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
@@ -119,6 +117,8 @@ std::unique_ptr<WebUIController> NewWebUI(WebUI *web_ui, const GURL & /*url*/)
// with it.
WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, const GURL &url)
{
+ Q_UNUSED(web_ui);
+ Q_UNUSED(profile);
// This will get called a lot to check all URLs, so do a quick check of other
// schemes to filter out most URLs.
if (!content::HasWebUIScheme(url))
@@ -126,6 +126,9 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
// We must compare hosts only since some of the Web UIs append extra stuff
// after the host name.
+ if (url.host() == chrome::kChromeUINetInternalsHost)
+ return &NewWebUI<NetInternalsUI>;
+
if (url.host() == chrome::kChromeUIQuotaInternalsHost)
return &NewWebUI<QuotaInternalsUI>;
@@ -137,8 +140,9 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
if (url.host() == chrome::kChromeUIAccessibilityHost)
return &NewWebUI<AccessibilityUI>;
-// if (url.host_piece() == chrome::kChromeUIUserActionsHost)
-// return &NewWebUI<UserActionsUI>;
+ if (url.host_piece() == chrome::kChromeUIUserActionsHost)
+ return &NewWebUI<UserActionsUI>;
+
// if (url.host_piece() == chrome::kChromeUIInspectHost)
// return &NewWebUI<InspectUI>;
//
@@ -150,20 +154,16 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
// if (url.host_piece() == chrome::kChromeUIExtensionsFrameHost)
// return &NewWebUI<extensions::ExtensionsUI>;
//#endif
-//#if BUILDFLAG(ENABLE_PLUGINS)
-// if (url.host_piece() == chrome::kChromeUIFlashHost)
-// return &NewWebUI<FlashUI>;
-//#endif
//#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// if (url.host_piece() == chrome::kChromeUIPrintHost &&
// !profile->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled)) {
// return &NewWebUI<PrintPreviewUI>;
// }
//#endif
-//#if BUILDFLAG(ENABLE_WEBRTC)
-// if (url.host_piece() == chrome::kChromeUIWebRtcLogsHost)
-// return &NewWebUI<WebRtcLogsUI>;
-//#endif
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ if (url.host_piece() == chrome::kChromeUIWebRtcLogsHost)
+ return &NewWebUI<WebRtcLogsUI>;
+#endif
#if defined(OS_LINUX) || defined(OS_ANDROID)
if (url.host_piece() == chrome::kChromeUISandboxHost)
return &NewWebUI<SandboxInternalsUI>;
diff --git a/src/core/net/webui_controller_factory_qt.h b/src/core/net/webui_controller_factory_qt.h
index 1cc76349b..6dfc612e1 100644
--- a/src/core/net/webui_controller_factory_qt.h
+++ b/src/core/net/webui_controller_factory_qt.h
@@ -42,16 +42,8 @@
#include "base/macros.h"
#include "base/memory/singleton.h"
-#include "components/favicon_base/favicon_callback.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_controller_factory.h"
-#include "ui/base/layout.h"
-
-class Profile;
-
-namespace base {
-class RefCountedMemory;
-}
namespace QtWebEngineCore {
diff --git a/src/core/ozone/BUILD.gn b/src/core/ozone/BUILD.gn
index 4d27f8877..a01728842 100644
--- a/src/core/ozone/BUILD.gn
+++ b/src/core/ozone/BUILD.gn
@@ -1,6 +1,7 @@
# 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.
+import("//ui/base/ui_features.gni")
source_set("qt") {
sources = [
@@ -18,4 +19,8 @@ source_set("qt") {
]
defines = [ "OZONE_IMPLEMENTATION" ]
+
+ if (use_xkbcommon && use_x11) {
+ libs = [ "xkbfile" ]
+ }
}
diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index 9a24f6bf4..0e7213a3a 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -51,8 +51,10 @@
#endif
QT_BEGIN_NAMESPACE
-
+#if QT_CONFIG(opengl)
Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
+#endif
+
GLContextHelper* GLContextHelper::contextHelper = 0;
namespace {
diff --git a/src/core/ozone/gl_ozone_egl_qt.cpp b/src/core/ozone/gl_ozone_egl_qt.cpp
index c33570d44..04b336990 100644
--- a/src/core/ozone/gl_ozone_egl_qt.cpp
+++ b/src/core/ozone/gl_ozone_egl_qt.cpp
@@ -40,14 +40,6 @@
#if defined(USE_OZONE)
#include <QtCore/qobject.h>
#include <QtGui/qtgui-config.h>
-
-#if QT_CONFIG(opengl)
-#include <QOpenGLContext>
-QT_BEGIN_NAMESPACE
-Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
-QT_END_NAMESPACE
-#endif
-
#include "gl_context_qt.h"
#include "gl_ozone_egl_qt.h"
#include "gl_surface_egl_qt.h"
@@ -90,10 +82,8 @@ bool GLOzoneEGLQt::LoadGLES2Bindings(gl::GLImplementation /*implementation*/)
#if QT_CONFIG(opengl)
if (!get_proc_address) {
// QTBUG-63341 most likely libgles2 not linked with libegl -> fallback to qpa
- if (QOpenGLContext *context = qt_gl_global_share_context()) {
- get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(
- context->getProcAddress("eglGetProcAddress"));
- }
+ get_proc_address =
+ reinterpret_cast<gl::GLGetProcAddressProc>(GLContextHelper::getEglGetProcAddress());
}
#endif
diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp
index 8e8e66f63..447826baa 100644
--- a/src/core/ozone/gl_surface_egl_qt.cpp
+++ b/src/core/ozone/gl_surface_egl_qt.cpp
@@ -44,7 +44,7 @@
#include "gl_context_qt.h"
#include "ozone/gl_surface_egl_qt.h"
-#if !defined(OS_MACOSX)
+#if !defined(OS_MAC)
#include "ui/gl/egl_util.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/init/gl_factory.h"
@@ -93,7 +93,7 @@ bool GLSurfaceEGLQt::InitializeOneOff()
}
g_extensions = eglQueryString(g_display, EGL_EXTENSIONS);
- g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context");
+ g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions.c_str(), "EGL_KHR_surfaceless_context");
if (g_egl_surfaceless_context_supported) {
scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(gfx::Size(1, 1));
gl::GLContextAttribs attribs;
@@ -181,13 +181,28 @@ bool GLSurfaceEGL::IsANGLEFeatureControlSupported()
return false;
}
+bool GLSurfaceEGL::IsANGLEPowerPreferenceSupported()
+{
+ return false;
+}
+
+bool GLSurfaceEGL::IsDisplaySemaphoreShareGroupSupported()
+{
+ return false;
+}
+
+bool GLSurfaceEGL::IsRobustnessVideoMemoryPurgeSupported()
+{
+ return false;
+}
+
void GLSurfaceEGL::ShutdownOneOff()
{
}
const char* GLSurfaceEGL::GetEGLExtensions()
{
- return GLSurfaceQt::g_extensions;
+ return GLSurfaceQt::g_extensions.c_str();
}
bool GLSurfaceEGL::HasEGLExtension(const char* name)
@@ -340,4 +355,4 @@ std::string DriverEGL::GetPlatformExtensions()
return "";
}
} // namespace gl
-#endif // !defined(OS_MACOSX)
+#endif // !defined(OS_MAC)
diff --git a/src/core/ozone/gl_surface_glx_qt.cpp b/src/core/ozone/gl_surface_glx_qt.cpp
index e150c940a..c796444b1 100644
--- a/src/core/ozone/gl_surface_glx_qt.cpp
+++ b/src/core/ozone/gl_surface_glx_qt.cpp
@@ -45,8 +45,7 @@
#include "ozone/gl_surface_glx_qt.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_surface_glx.h"
-#include <GL/glx.h>
-#include <GL/glxext.h>
+#include "ui/gfx/x/x11_types.h"
namespace gl {
@@ -63,7 +62,7 @@ void GLSurfaceGLX::ShutdownOneOff()
bool GLSurfaceGLX::IsCreateContextSupported()
{
- return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context");
+ return HasGLXExtension("GLX_ARB_create_context");
}
bool GLSurfaceGLX::IsCreateContextRobustnessSupported()
@@ -88,7 +87,7 @@ bool GLSurfaceGLX::IsCreateContextProfileSupported()
bool GLSurfaceGLX::IsCreateContextES2ProfileSupported()
{
- return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context_es2_profile");
+ return HasGLXExtension("GLX_ARB_create_context_es2_profile");
}
bool GLSurfaceGLX::IsOMLSyncControlSupported()
@@ -98,17 +97,22 @@ bool GLSurfaceGLX::IsOMLSyncControlSupported()
bool GLSurfaceGLX::HasGLXExtension(const char *name)
{
- return ExtensionsContain(GLSurfaceQt::g_extensions, name);
+ return ExtensionsContain(GLSurfaceQt::g_extensions.c_str(), name);
}
bool GLSurfaceGLX::IsTextureFromPixmapSupported()
{
- return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_EXT_texture_from_pixmap");
+ return HasGLXExtension("GLX_EXT_texture_from_pixmap");
+}
+
+bool GLSurfaceGLX::IsRobustnessVideoMemoryPurgeSupported()
+{
+ return false;
}
const char* GLSurfaceGLX::GetGLXExtensions()
{
- return GLSurfaceQt::g_extensions;
+ return GLSurfaceQt::g_extensions.c_str();
}
bool GLSurfaceGLXQt::InitializeOneOff()
@@ -154,7 +158,7 @@ bool GLSurfaceGLXQt::InitializeExtensionSettingsOneOff()
Display* display = static_cast<Display*>(g_display);
GLSurfaceQt::g_extensions = glXQueryExtensionsString(display, 0);
- g_driver_glx.InitializeExtensionBindings(g_extensions);
+ g_driver_glx.InitializeExtensionBindings(g_extensions.c_str());
return true;
}
@@ -171,9 +175,9 @@ bool GLSurfaceGLXQt::Initialize(GLSurfaceFormat format)
const int pbuffer_attributes[] = {
GLX_PBUFFER_WIDTH, m_size.width(),
GLX_PBUFFER_HEIGHT, m_size.height(),
- GLX_LARGEST_PBUFFER, x11::False,
- GLX_PRESERVED_CONTENTS, x11::False,
- x11::None // MEMO doc: ...must be terminated with None or NULL
+ GLX_LARGEST_PBUFFER, GL_FALSE,
+ GLX_PRESERVED_CONTENTS, GL_FALSE,
+ GL_NONE // MEMO doc: ...must be terminated with None or NULL
};
m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes);
diff --git a/src/core/ozone/gl_surface_glx_qt.h b/src/core/ozone/gl_surface_glx_qt.h
index 3a465f448..e894423b7 100644
--- a/src/core/ozone/gl_surface_glx_qt.h
+++ b/src/core/ozone/gl_surface_glx_qt.h
@@ -42,9 +42,7 @@
#include "gl_surface_qt.h"
-extern "C" {
-#include <X11/Xlib.h>
-}
+#include "ui/gfx/x/x11_types.h"
namespace gl {
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index 90f486532..990a62f8b 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -43,7 +43,7 @@
#include "gl_surface_qt.h"
-#if !defined(OS_MACOSX)
+#if !defined(OS_MAC)
#include <QGuiApplication>
#include "gl_context_qt.h"
@@ -78,7 +78,7 @@ bool g_initializedEGL = false;
void* GLSurfaceQt::g_display = nullptr;
void* GLSurfaceQt::g_config = nullptr;
-const char* GLSurfaceQt::g_extensions = nullptr;
+std::string GLSurfaceQt::g_extensions;
GLSurfaceQt::~GLSurfaceQt()
{
@@ -99,7 +99,7 @@ GLSurfaceQt::GLSurfaceQt(const gfx::Size& size)
bool GLSurfaceQt::HasEGLExtension(const char* name)
{
- return ExtensionsContain(g_extensions, name);
+ return ExtensionsContain(g_extensions.c_str(), name);
}
bool GLSurfaceQt::IsOffscreen()
@@ -254,6 +254,10 @@ UINT DirectCompositionSurfaceWin::GetOverlaySupportFlags(DXGI_FORMAT format)
Q_UNUSED(format);
return 0;
}
+
+void DirectCompositionSurfaceWin::DisableDecodeSwapChain()
+{
+}
} // namespace gl
#endif
-#endif // !defined(OS_MACOSX)
+#endif // !defined(OS_MAC)
diff --git a/src/core/ozone/gl_surface_qt.h b/src/core/ozone/gl_surface_qt.h
index cbdc8876a..b3a53d6b3 100644
--- a/src/core/ozone/gl_surface_qt.h
+++ b/src/core/ozone/gl_surface_qt.h
@@ -37,11 +37,11 @@
**
****************************************************************************/
-
-
#ifndef GL_SURFACE_QT_H_
#define GL_SURFACE_QT_H_
+#include <string>
+
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_surface.h"
@@ -71,7 +71,7 @@ protected:
public:
static void* g_config;
static void* g_display;
- static const char* g_extensions;
+ static std::string g_extensions;
private:
DISALLOW_COPY_AND_ASSIGN(GLSurfaceQt);
diff --git a/src/core/ozone/ozone_platform_qt.cpp b/src/core/ozone/ozone_platform_qt.cpp
index 3674ccfe6..1d6fa1ed5 100644
--- a/src/core/ozone/ozone_platform_qt.cpp
+++ b/src/core/ozone/ozone_platform_qt.cpp
@@ -40,11 +40,14 @@
#include "ozone_platform_qt.h"
#if defined(USE_OZONE)
+#include "ui/base/buildflags.h"
+#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
#include "ui/base/ime/input_method.h"
#include "ui/display/types/native_display_delegate.h"
+#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
+#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.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"
#include "ui/ozone/public/gpu_platform_support_host.h"
#include "ui/ozone/public/input_controller.h"
#include "ui/ozone/public/ozone_platform.h"
@@ -56,6 +59,16 @@
#include "surface_factory_qt.h"
#include "platform_window_qt.h"
+#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11)
+#include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h"
+#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
+
+#include <X11/XKBlib.h>
+#include <X11/extensions/XKBrules.h>
+
+extern void *GetQtXDisplay();
+#endif // BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11)
+
namespace ui {
namespace {
@@ -66,7 +79,7 @@ public:
~OzonePlatformQt() override;
ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override;
- ui::CursorFactoryOzone* GetCursorFactoryOzone() override;
+ ui::CursorFactory* GetCursorFactory() override;
GpuPlatformSupportHost* GetGpuPlatformSupportHost() override;
std::unique_ptr<PlatformWindow> CreatePlatformWindow(PlatformWindowDelegate* delegate, PlatformWindowInitProperties properties) override;
std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate() override;
@@ -80,12 +93,17 @@ private:
void InitializeGPU(const ui::OzonePlatform::InitParams &) override;
std::unique_ptr<QtWebEngineCore::SurfaceFactoryQt> surface_factory_ozone_;
- std::unique_ptr<CursorFactoryOzone> cursor_factory_ozone_;
+ std::unique_ptr<CursorFactory> cursor_factory_ozone_;
std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
std::unique_ptr<InputController> input_controller_;
std::unique_ptr<OverlayManagerOzone> overlay_manager_;
+#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11)
+ XkbEvdevCodes m_xkbEvdevCodeConverter;
+#endif
+ std::unique_ptr<KeyboardLayoutEngine> m_keyboardLayoutEngine;
+
DISALLOW_COPY_AND_ASSIGN(OzonePlatformQt);
};
@@ -99,7 +117,7 @@ ui::SurfaceFactoryOzone* OzonePlatformQt::GetSurfaceFactoryOzone()
return surface_factory_ozone_.get();
}
-ui::CursorFactoryOzone* OzonePlatformQt::GetCursorFactoryOzone()
+ui::CursorFactory* OzonePlatformQt::GetCursorFactory()
{
return cursor_factory_ozone_.get();
}
@@ -135,12 +153,75 @@ std::unique_ptr<display::NativeDisplayDelegate> OzonePlatformQt::CreateNativeDis
return nullptr;
}
+#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11)
+static std::string getCurrentKeyboardLayout()
+{
+ Display *dpy = static_cast<Display *>(GetQtXDisplay());
+ if (dpy == nullptr)
+ return std::string();
+
+ XkbStateRec state;
+ if (XkbGetState(dpy, XkbUseCoreKbd, &state) != 0)
+ return std::string();
+
+ XkbRF_VarDefsRec vdr {}; // zero initialize it
+ struct Cleanup {
+ XkbRF_VarDefsRec &vdr;
+ Cleanup(XkbRF_VarDefsRec &vdr) : vdr(vdr) { }
+ ~Cleanup() {
+ free (vdr.model);
+ free (vdr.layout);
+ free (vdr.variant);
+ free (vdr.options);
+ }
+ } cleanup(vdr);
+ if (XkbRF_GetNamesProp(dpy, nullptr, &vdr) == 0)
+ return std::string();
+
+ char *layout = strtok(vdr.layout, ",");
+ for (int i = 0; i < state.group; i++) {
+ layout = strtok(nullptr, ",");
+ if (layout == nullptr)
+ return std::string();
+ }
+
+ char *variant = strtok(vdr.variant, ",");
+ if (!variant)
+ return layout;
+
+ for (int i = 0; i < state.group; i++) {
+ variant = strtok(nullptr, ",");
+ if (variant == nullptr)
+ return layout;
+ }
+
+ std::string layoutWithVariant = layout;
+ layoutWithVariant = layoutWithVariant.append("-");
+ layoutWithVariant = layoutWithVariant.append(variant);
+ return layoutWithVariant;
+}
+#endif // BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11)
+
void OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &)
{
overlay_manager_.reset(new StubOverlayManager());
- cursor_factory_ozone_.reset(new CursorFactoryOzone());
+ cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone());
gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost());
input_controller_ = CreateStubInputController();
+
+#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11)
+ std::string layout = getCurrentKeyboardLayout();
+ if (layout.empty()) {
+ m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>();
+ } else {
+ m_keyboardLayoutEngine = std::make_unique<XkbKeyboardLayoutEngine>(m_xkbEvdevCodeConverter);
+ m_keyboardLayoutEngine->SetCurrentLayoutByName(layout);
+ }
+#else
+ m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>();
+#endif // BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11)
+
+ KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(m_keyboardLayoutEngine.get());
}
void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &)
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index a1b481946..40090f8ec 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -68,6 +68,7 @@ static ProfileAdapter::PermissionType toQt(content::PermissionType type)
case content::PermissionType::NOTIFICATIONS:
return ProfileAdapter::NotificationPermission;
case content::PermissionType::ACCESSIBILITY_EVENTS:
+ case content::PermissionType::CAMERA_PAN_TILT_ZOOM:
return ProfileAdapter::UnsupportedPermission;
case content::PermissionType::FLASH:
case content::PermissionType::MIDI_SYSEX:
@@ -86,8 +87,10 @@ static ProfileAdapter::PermissionType toQt(content::PermissionType type)
case content::PermissionType::AR:
case content::PermissionType::VR:
case content::PermissionType::STORAGE_ACCESS_GRANT:
+ case content::PermissionType::WINDOW_PLACEMENT:
+ case content::PermissionType::FONT_ACCESS:
case content::PermissionType::NUM:
- LOG(INFO) << "Unsupported permission type: " << static_cast<int>(type);
+ LOG(INFO) << "Unexpected unsupported permission type: " << static_cast<int>(type);
break;
}
return ProfileAdapter::UnsupportedPermission;
@@ -119,7 +122,6 @@ static blink::mojom::PermissionStatus toBlink(ProfileAdapter::PermissionState re
PermissionManagerQt::PermissionManagerQt()
: m_requestIdCount(0)
- , m_subscriberIdCount(0)
{
}
@@ -336,19 +338,19 @@ void PermissionManagerQt::ResetPermission(
m_permissions.remove(key);
}
-int PermissionManagerQt::SubscribePermissionStatusChange(
+content::PermissionControllerDelegate::SubscriptionId PermissionManagerQt::SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost * /* render_frame_host */,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
{
- int subscriber_id = ++m_subscriberIdCount;
+ auto subscriber_id = subscription_id_generator_.GenerateNextId();
m_subscribers.insert( { subscriber_id,
Subscription { toQt(permission), toQt(requesting_origin), std::move(callback) } });
return subscriber_id;
}
-void PermissionManagerQt::UnsubscribePermissionStatusChange(int subscription_id)
+void PermissionManagerQt::UnsubscribePermissionStatusChange(content::PermissionControllerDelegate::SubscriptionId subscription_id)
{
if (!m_subscribers.erase(subscription_id))
LOG(WARNING) << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id;
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index e046174df..f8d7e0ee3 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -89,13 +89,13 @@ public:
base::OnceCallback<void(
const std::vector<blink::mojom::PermissionStatus>&)> callback) override;
- int SubscribePermissionStatusChange(
+ content::PermissionControllerDelegate::SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
const base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(content::PermissionControllerDelegate::SubscriptionId subscription_id) override;
private:
QHash<QPair<QUrl, ProfileAdapter::PermissionType>, bool> m_permissions;
@@ -118,9 +118,9 @@ private:
};
std::vector<Request> m_requests;
std::vector<MultiRequest> m_multiRequests;
- std::map<int, Subscription> m_subscribers;
+ std::map<content::PermissionControllerDelegate::SubscriptionId, Subscription> m_subscribers;
+ content::PermissionControllerDelegate::SubscriptionId::Generator subscription_id_generator_;
int m_requestIdCount;
- int m_subscriberIdCount;
};
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 65dfb73ee..ff653c066 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -101,7 +101,7 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
registry->RegisterStringPref(language::prefs::kAcceptLanguages, std::string());
registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries);
registry->RegisterListPref(spellcheck::prefs::kSpellCheckForcedDictionaries);
- registry->RegisterListPref(spellcheck::prefs::kSpellCheckBlacklistedDictionaries);
+ registry->RegisterListPref(spellcheck::prefs::kSpellCheckBlocklistedDictionaries);
registry->RegisterStringPref(spellcheck::prefs::kSpellCheckDictionary, std::string());
registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckEnable, false);
registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false);
@@ -120,8 +120,8 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
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->RegisterListPref(extensions::pref_names::kNativeMessagingBlocklist);
+ registry->RegisterListPref(extensions::pref_names::kNativeMessagingAllowlist);
registry->RegisterBooleanPref(extensions::pref_names::kNativeMessagingUserLevelHosts, true);
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp
index a6c478037..fe365df53 100644
--- a/src/core/printing/print_view_manager_base_qt.cpp
+++ b/src/core/printing/print_view_manager_base_qt.cpp
@@ -48,10 +48,9 @@
#include "web_engine_context.h"
#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_current.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/current_thread.h"
#include "base/task/post_task.h"
#include "base/timer/timer.h"
#include "base/values.h"
@@ -59,10 +58,13 @@
#include "chrome/browser/printing/print_job.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.h"
+#include "components/printing/browser/print_manager_utils.h"
+#include "components/printing/common/print.mojom.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_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
@@ -72,12 +74,71 @@
namespace QtWebEngineCore {
+namespace {
+
+// Runs |callback| with |params| to reply to
+// mojom::PrintManagerHost::GetDefaultPrintSettings.
+void GetDefaultPrintSettingsReply(printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback,
+ printing::mojom::PrintParamsPtr params)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ std::move(callback).Run(std::move(params));
+}
+
+void GetDefaultPrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
+ std::unique_ptr<printing::PrinterQuery> printer_query,
+ printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ printing::mojom::PrintParamsPtr params = printing::mojom::PrintParams::New();
+ if (printer_query && printer_query->last_status() == printing::PrintingContext::OK) {
+ RenderParamsFromPrintSettings(printer_query->settings(), params.get());
+ params->document_cookie = printer_query->cookie();
+ }
+
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&GetDefaultPrintSettingsReply,
+ std::move(callback), std::move(params)));
+
+ // If printing was enabled.
+ if (printer_query) {
+ // If user hasn't cancelled.
+ if (printer_query->cookie() && printer_query->settings().dpi()) {
+ queue->QueuePrinterQuery(std::move(printer_query));
+ } else {
+ printer_query->StopWorker();
+ }
+ }
+}
+
+void GetDefaultPrintSettingsOnIO(printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback,
+ scoped_refptr<printing::PrintQueriesQueue> queue,
+ int process_id, int routing_id)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(0);
+ if (!printer_query)
+ printer_query = queue->CreatePrinterQuery(process_id, routing_id);
+
+ // Loads default settings. This is asynchronous, only the mojo message sender
+ // will hang until the settings are retrieved.
+ auto *printer_query_ptr = printer_query.get();
+ printer_query_ptr->GetSettings(
+ printing::PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false,
+ printing::mojom::MarginType::kDefaultMargins, false, false,
+ base::BindOnce(&GetDefaultPrintSettingsReplyOnIO, queue,
+ std::move(printer_query), std::move(callback)));
+}
+
+} // namespace
+
PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents)
: printing::PrintManager(contents)
- , m_isInsideInnerMessageLoop(false)
+ , m_printingRFH(nullptr)
, m_didPrintingSucceed(false)
, m_printerQueriesQueue(WebEngineContext::current()->getPrintJobManager()->queue())
- , m_printingRFH(nullptr)
{
// FIXME: Check if this needs to be executed async:
// TODO: Add isEnabled to profile
@@ -119,8 +180,7 @@ base::string16 PrintViewManagerBaseQt::RenderSourceName()
return toString16(QLatin1String(""));
}
-void PrintViewManagerBaseQt::PrintDocument(printing::PrintedDocument *document,
- const scoped_refptr<base::RefCountedMemory> &print_data,
+void PrintViewManagerBaseQt::PrintDocument(scoped_refptr<base::RefCountedMemory> print_data,
const gfx::Size &page_size,
const gfx::Rect &content_area,
const gfx::Point &offsets)
@@ -130,34 +190,37 @@ void PrintViewManagerBaseQt::PrintDocument(printing::PrintedDocument *document,
CHECK(metafile->InitFromData(*print_data));
// Update the rendered document. It will send notifications to the listener.
- document->SetDocument(std::move(metafile), page_size, content_area);
+ printing::PrintedDocument* document = m_printJob->document();
+ document->SetDocument(std::move(metafile));
ShouldQuitFromInnerMessageLoop();
}
-printing::PrintedDocument *PrintViewManagerBaseQt::GetDocument(int cookie)
+void PrintViewManagerBaseQt::DidGetPrintedPagesCount(int32_t cookie, uint32_t number_pages)
+{
+ PrintManager::DidGetPrintedPagesCount(cookie, number_pages);
+ OpportunisticallyCreatePrintJob(cookie);
+}
+
+bool PrintViewManagerBaseQt::PrintJobHasDocument(int cookie)
{
if (!OpportunisticallyCreatePrintJob(cookie))
- return nullptr;
+ return false;
+ // These checks may fail since we are completely asynchronous. Old spurious
+ // messages can be received if one of the processes is overloaded.
printing::PrintedDocument* document = m_printJob->document();
- if (!document || cookie != document->cookie()) {
- // Out of sync. It may happen since we are completely asynchronous. Old
- // spurious messages can be received if one of the processes is overloaded.
- return nullptr;
- }
- return document;
+ return document && document->cookie() == cookie;
}
// IPC handlers
void PrintViewManagerBaseQt::OnDidPrintDocument(content::RenderFrameHost* /*render_frame_host*/,
- const PrintHostMsg_DidPrintDocument_Params &params,
+ const printing::mojom::DidPrintDocumentParams &params,
std::unique_ptr<DelayedFrameDispatchHelper> helper)
{
- printing::PrintedDocument *document = GetDocument(params.document_cookie);
- if (!document)
+ if (!PrintJobHasDocument(params.document_cookie))
return;
- const PrintHostMsg_DidPrintContent_Params &content = params.content;
+ const printing::mojom::DidPrintContentParams &content = *params.content;
if (!content.metafile_data_region.IsValid()) {
NOTREACHED() << "invalid memory handle";
web_contents()->Stop();
@@ -171,26 +234,49 @@ void PrintViewManagerBaseQt::OnDidPrintDocument(content::RenderFrameHost* /*rend
return;
}
- PrintDocument(document, data, params.page_size, params.content_area,
+ PrintDocument(data, params.page_size, params.content_area,
params.physical_offsets);
if (helper)
helper->SendCompleted();
}
-void PrintViewManagerBaseQt::OnGetDefaultPrintSettings(content::RenderFrameHost *render_frame_host,
- IPC::Message *reply_msg)
+void PrintViewManagerBaseQt::GetDefaultPrintSettings(GetDefaultPrintSettingsCallback callback)
{
- NOTREACHED() << "should be handled by printing::PrintingMessageFilter";
+ content::RenderFrameHost* render_frame_host =
+ print_manager_host_receivers_.GetCurrentTargetFrame();
+
+ content::GetIOThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&GetDefaultPrintSettingsOnIO, std::move(callback), m_printerQueriesQueue,
+ render_frame_host->GetProcess()->GetID(),
+ render_frame_host->GetRoutingID()));
+}
+
+void PrintViewManagerBaseQt::PrintingFailed(int32_t cookie)
+{
+ // Note: Not redundant with cookie checks in the same method in other parts of
+ // the class hierarchy.
+ if (!IsValidCookie(cookie))
+ return;
+
+ PrintManager::PrintingFailed(cookie);
+
+ ReleasePrinterQuery();
+
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_PRINT_JOB_RELEASED,
+ content::Source<content::WebContents>(web_contents()),
+ content::NotificationService::NoDetails());
}
void PrintViewManagerBaseQt::OnScriptedPrint(content::RenderFrameHost *render_frame_host,
- const PrintHostMsg_ScriptedPrint_Params &params,
+ const printing::mojom::ScriptedPrintParams &params,
IPC::Message *reply_msg)
{
NOTREACHED() << "should be handled by printing::PrintingMessageFilter";
}
-void PrintViewManagerBaseQt::OnShowInvalidPrinterSettingsError()
+void PrintViewManagerBaseQt::ShowInvalidPrinterSettingsError()
{
}
@@ -203,6 +289,8 @@ void PrintViewManagerBaseQt::DidStartLoading()
// so m_printingRFH is never set and used at the moment.
void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render_frame_host)
{
+ PrintManager::RenderFrameDeleted(render_frame_host);
+
// Terminates or cancels the print job if one was pending.
if (render_frame_host != m_printingRFH)
return;
@@ -216,7 +304,7 @@ void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render
return;
scoped_refptr<printing::PrintedDocument> document(m_printJob->document());
- if (document.get()) {
+ if (document) {
// If IsComplete() returns false, the document isn't completely rendered.
// Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
// the print job may finish without problem.
@@ -224,18 +312,6 @@ void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render
}
}
-bool PrintViewManagerBaseQt::OnMessageReceived(const IPC::Message& message,
- content::RenderFrameHost* render_frame_host)
-{
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBaseQt, message)
- IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError,
- OnShowInvalidPrinterSettingsError);
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled || PrintManager::OnMessageReceived(message, render_frame_host);
-}
-
void PrintViewManagerBaseQt::Observe(int type,
const content::NotificationSource& /*source*/,
const content::NotificationDetails& details)
@@ -333,28 +409,21 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow()
return true;
}
-// Quits the current message loop if these conditions hold true: a document is
-// loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This
-// function is called in DidPrintPage() or on ALL_PAGES_REQUESTED
-// notification. The inner message loop is created was created by
-// RenderAllMissingPagesNow().
void PrintViewManagerBaseQt::ShouldQuitFromInnerMessageLoop()
{
// Look at the reason.
DCHECK(m_printJob->document());
- if (m_printJob->document() &&
- m_printJob->document()->IsComplete() &&
- m_isInsideInnerMessageLoop) {
- // We are in a message loop created by RenderAllMissingPagesNow. Quit from
- // it.
- base::RunLoop::QuitCurrentWhenIdleDeprecated();
- m_isInsideInnerMessageLoop = false;
+ if (m_printJob->document() && m_printJob->document()->IsComplete() && m_quitInnerLoop) {
+ // We are in a message loop created by RenderAllMissingPagesNow. Quit from
+ // it.
+ std::move(m_quitInnerLoop).Run();
}
}
bool PrintViewManagerBaseQt::CreateNewPrintJob(std::unique_ptr<printing::PrinterQuery> query)
{
- DCHECK(!m_isInsideInnerMessageLoop);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(!m_quitInnerLoop);
DCHECK(query);
// Disconnect the current |m_printJob|.
@@ -405,9 +474,9 @@ void PrintViewManagerBaseQt::TerminatePrintJob(bool cancel)
if (cancel) {
// We don't need the metafile data anymore because the printing is canceled.
m_printJob->Cancel();
- m_isInsideInnerMessageLoop = false;
+ m_quitInnerLoop.Reset();
} else {
- DCHECK(!m_isInsideInnerMessageLoop);
+ DCHECK(!m_quitInnerLoop);
DCHECK(!m_printJob->document() || m_printJob->document()->IsComplete());
// WebContents is either dying or navigating elsewhere. We need to render
@@ -435,7 +504,8 @@ void PrintViewManagerBaseQt::ReleasePrintJob()
m_printJob = nullptr;
}
-bool PrintViewManagerBaseQt::RunInnerMessageLoop() {
+bool PrintViewManagerBaseQt::RunInnerMessageLoop()
+{
// This value may actually be too low:
//
// - If we're looping because of printer settings initialization, the premise
@@ -454,20 +524,16 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() {
base::TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
run_loop.QuitWhenIdleClosure());
- m_isInsideInnerMessageLoop = true;
+ m_quitInnerLoop = run_loop.QuitClosure();
// Need to enable recursive task.
{
- base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
+ base::CurrentThread::ScopedNestableTaskAllower allow;
run_loop.Run();
}
- bool success = true;
- if (m_isInsideInnerMessageLoop) {
- // Ok we timed out. That's sad.
- m_isInsideInnerMessageLoop = false;
- success = false;
- }
+ bool success = !m_quitInnerLoop;
+ m_quitInnerLoop.Reset();
return success;
}
diff --git a/src/core/printing/print_view_manager_base_qt.h b/src/core/printing/print_view_manager_base_qt.h
index 1217e8c11..3086d5d3a 100644
--- a/src/core/printing/print_view_manager_base_qt.h
+++ b/src/core/printing/print_view_manager_base_qt.h
@@ -48,27 +48,22 @@
#include "base/strings/string16.h"
#include "components/prefs/pref_member.h"
#include "components/printing/browser/print_manager.h"
+#include "components/printing/common/print.mojom-forward.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-struct PrintHostMsg_DidPrintDocument_Params;
-
namespace base {
class RefCountedBytes;
}
namespace content {
class RenderFrameHost;
-class RenderViewHost;
}
namespace printing {
class JobEventDetails;
-class MetafilePlayer;
class PrintJob;
-class PrintJobWorkerOwner;
class PrintQueriesQueue;
-class PrintedDocument;
class PrinterQuery;
}
@@ -82,62 +77,70 @@ public:
// Whether printing is enabled or not.
void UpdatePrintingEnabled();
- virtual base::string16 RenderSourceName();
+ base::string16 RenderSourceName();
+
+ // mojom::PrintManagerHost:
+ void DidGetPrintedPagesCount(int32_t cookie, uint32_t number_pages) override;
+ void GetDefaultPrintSettings(GetDefaultPrintSettingsCallback callback) override;
+ void ShowInvalidPrinterSettingsError() override;
+ void PrintingFailed(int32_t cookie) override;
protected:
explicit PrintViewManagerBaseQt(content::WebContents*);
void SetPrintingRFH(content::RenderFrameHost* rfh);
- // content::WebContentsObserver implementation.
// Cancels the print job.
void NavigationStopped() override;
// content::WebContentsObserver implementation.
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
- bool OnMessageReceived(const IPC::Message& message,
- content::RenderFrameHost* render_frame_host) override;
- // printing::PrintManager implementation:
- void OnDidPrintDocument(content::RenderFrameHost *render_frame_host,
- const PrintHostMsg_DidPrintDocument_Params &params,
- std::unique_ptr<DelayedFrameDispatchHelper> helper) override;
- void OnGetDefaultPrintSettings(content::RenderFrameHost* render_frame_host,
- IPC::Message* reply_msg) override;
- void OnScriptedPrint(content::RenderFrameHost* render_frame_host,
- const PrintHostMsg_ScriptedPrint_Params& params,
- IPC::Message* reply_msg) override;
+ // Creates a new empty print job. It has no settings loaded. If there is
+ // currently a print job, safely disconnect from it. Returns false if it is
+ // impossible to safely disconnect from the current print job or it is
+ // impossible to create a new print job.
+ virtual bool CreateNewPrintJob(std::unique_ptr<printing::PrinterQuery> query);
- void OnShowInvalidPrinterSettingsError();
+ // Makes sure the current print_job_ has all its data before continuing, and
+ // disconnect from it.
+ void DisconnectFromCurrentPrintJob();
- // Processes a NOTIFY_PRINT_JOB_EVENT notification.
- void OnNotifyPrintJobEvent(const printing::JobEventDetails& event_details);
+ void StopWorker(int documentCookie);
+private:
// content::NotificationObserver implementation.
void Observe(int,
const content::NotificationSource&,
const content::NotificationDetails&) override;
- void StopWorker(int document_cookie);
- // In the case of Scripted Printing, where the renderer is controlling the
- // control flow, print_job_ is initialized whenever possible. No-op is
- // print_job_ is initialized.
- bool OpportunisticallyCreatePrintJob(int cookie);
+ // content::WebContentsObserver implementation.
+ void DidStartLoading() override;
+
+ // printing::PrintManager:
+ void OnDidPrintDocument(
+ content::RenderFrameHost *render_frame_host,
+ const printing::mojom::DidPrintDocumentParams &params,
+ std::unique_ptr<DelayedFrameDispatchHelper> helper) override;
+ void OnScriptedPrint(content::RenderFrameHost *render_frame_host,
+ const printing::mojom::ScriptedPrintParams &params,
+ IPC::Message *reply_msg) override;
+
+ // Processes a NOTIFY_PRINT_JOB_EVENT notification.
+ void OnNotifyPrintJobEvent(const printing::JobEventDetails &event_details);
// Requests the RenderView to render all the missing pages for the print job.
// No-op if no print job is pending. Returns true if at least one page has
// been requested to the renderer.
bool RenderAllMissingPagesNow();
- // Checks that synchronization is correct and a print query exists for
- // |cookie|. If so, returns the document associated with the cookie.
- printing::PrintedDocument* GetDocument(int cookie);
+ // Checks that synchronization is correct with |print_job_| based on |cookie|.
+ bool PrintJobHasDocument(int cookie);
- // Starts printing a document with data given in |print_data|. |print_data|
- // must successfully initialize a metafile. |document| is the printed
- // document associated with the print job. Returns true if successful.
- void PrintDocument(printing::PrintedDocument *document,
- const scoped_refptr<base::RefCountedMemory> &print_data,
+ // Starts printing the |document| in |print_job_| with the given |print_data|.
+ // This method assumes PrintJobHasDocument() has been called, and |print_data|
+ // contains valid data.
+ void PrintDocument(scoped_refptr<base::RefCountedMemory> print_data,
const gfx::Size &page_size,
const gfx::Rect &content_area,
const gfx::Point &offsets);
@@ -149,29 +152,43 @@ protected:
// RenderAllMissingPagesNow().
void ShouldQuitFromInnerMessageLoop();
- bool RunInnerMessageLoop();
-
+ // Terminates the print job. No-op if no print job has been created. If
+ // |cancel| is true, cancel it instead of waiting for the job to finish. Will
+ // call ReleasePrintJob().
void TerminatePrintJob(bool cancel);
- void DisconnectFromCurrentPrintJob();
- bool CreateNewPrintJob(std::unique_ptr<printing::PrinterQuery> query);
+ // Releases print_job_. Correctly deregisters from notifications. No-op if
+ // no print job has been created.
void ReleasePrintJob();
+
+ // Runs an inner message loop. It will set inside_inner_message_loop_ to true
+ // while the blocking inner message loop is running. This is useful in cases
+ // where the RenderView is about to be destroyed while a printing job isn't
+ // finished.
+ bool RunInnerMessageLoop();
+
+ // In the case of Scripted Printing, where the renderer is controlling the
+ // control flow, print_job_ is initialized whenever possible. No-op is
+ // print_job_ is initialized.
+ bool OpportunisticallyCreatePrintJob(int cookie);
+
+ // Release the PrinterQuery associated with our |cookie_|.
void ReleasePrinterQuery();
-private:
// Helper method for UpdatePrintingEnabled().
void SendPrintingEnabled(bool enabled, content::RenderFrameHost* rfh);
- // content::WebContentsObserver implementation.
- void DidStartLoading() override;
private:
content::NotificationRegistrar m_registrar;
scoped_refptr<printing::PrintJob> m_printJob;
- bool m_isInsideInnerMessageLoop;
+ content::RenderFrameHost *m_printingRFH;
bool m_didPrintingSucceed;
+ // Set while running an inner message loop inside RenderAllMissingPagesNow().
+ // This means we are _blocking_ until all the necessary pages have been
+ // rendered or the print settings are being loaded.
+ base::OnceClosure m_quitInnerLoop;
scoped_refptr<printing::PrintQueriesQueue> m_printerQueriesQueue;
- // The current RFH that is printing with a system printing dialog.
- content::RenderFrameHost *m_printingRFH;
+
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBaseQt);
};
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index df7fcc0fc..de1b81fb9 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+// Loosely based on print_view_manager.cc and print_preview_message_handler.cc
// 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.
@@ -56,13 +57,13 @@
#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.mojom.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/metafile_skia.h"
#include "printing/print_job_constants.h"
#include "printing/units.h"
@@ -121,12 +122,12 @@ static base::DictionaryValue *createPrintSettings()
printSettings->SetInteger(printing::kPreviewRequestID, internalRequestId);
// The following are standard settings that Chromium expects to be set.
- printSettings->SetInteger(printing::kSettingPrinterType, printing::kPdfPrinter);
+ printSettings->SetInteger(printing::kSettingPrinterType, static_cast<int>(printing::PrinterType::kPdf));
printSettings->SetInteger(printing::kSettingDpiHorizontal, printing::kPointsPerInch);
printSettings->SetInteger(printing::kSettingDpiVertical, printing::kPointsPerInch);
- printSettings->SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX);
+ printSettings->SetInteger(printing::kSettingDuplexMode, static_cast<int>(printing::mojom::DuplexMode::kSimplex));
printSettings->SetInteger(printing::kSettingCopies, 1);
printSettings->SetInteger(printing::kSettingPagesPerSheet, 1);
printSettings->SetBoolean(printing::kSettingCollate, false);
@@ -162,14 +163,14 @@ static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayo
marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict));
- printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS);
+ printSettings->SetInteger(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kCustomMargins);
// pageSizeInMillimeter is in portrait orientation. Transpose it if necessary.
printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
} else {
// QPrinter will handle margins
pageSizeInMillimeter = pageLayout.paintRect(QPageLayout::Millimeter);
- printSettings->SetInteger(printing::kSettingMarginsType, printing::NO_MARGINS);
+ printSettings->SetInteger(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kNoMargins);
// pageSizeInMillimeter already contains the orientation.
printSettings->SetBoolean(printing::kSettingLandscape, false);
@@ -261,12 +262,11 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, useCustomMargins));
m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds,
- web_contents()->GetRenderViewHost()->
- GetWebkitPreferences().should_print_backgrounds);
+ web_contents()->GetOrCreateWebPreferences().should_print_backgrounds);
m_printSettings->SetInteger(printing::kSettingColor,
- printInColor ? printing::COLOR : printing::GRAYSCALE);
+ int(printInColor ? printing::mojom::ColorModel::kColor : printing::mojom::ColorModel::kGrayscale));
- if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed())
+ if (web_contents()->IsCrashed())
return false;
content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
@@ -277,12 +277,6 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
return true;
}
-// PrintedPagesSource implementation.
-base::string16 PrintViewManagerQt::RenderSourceName()
-{
- return base::string16();
-}
-
PrintViewManagerQt::PrintViewManagerQt(content::WebContents *contents)
: PrintViewManagerBaseQt(contents)
, m_printPreviewRfh(nullptr)
@@ -297,7 +291,6 @@ bool PrintViewManagerQt::OnMessageReceived(const IPC::Message& message,
FrameDispatchHelper helper = {this, render_frame_host};
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintViewManagerQt, message, render_frame_host);
- IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview, OnRequestPrintPreview)
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting, OnMetafileReadyForPrinting);
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage)
@@ -356,8 +349,8 @@ void PrintViewManagerQt::OnRequestPrintPreview(
}
void PrintViewManagerQt::OnMetafileReadyForPrinting(content::RenderFrameHost* rfh,
- const PrintHostMsg_DidPreviewDocument_Params& params,
- const PrintHostMsg_PreviewIds &ids)
+ const printing::mojom::DidPreviewDocumentParams& params,
+ const printing::mojom::PreviewIds &ids)
{
StopWorker(params.document_cookie);
@@ -369,20 +362,16 @@ void PrintViewManagerQt::OnMetafileReadyForPrinting(content::RenderFrameHost* rf
resetPdfState();
if (!pdf_print_callback.is_null()) {
- QSharedPointer<QByteArray> data_array = GetStdVectorFromHandle(params.content.metafile_data_region);
+ QSharedPointer<QByteArray> data_array = GetStdVectorFromHandle(params.content->metafile_data_region);
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(pdf_print_callback, data_array));
} else {
- scoped_refptr<base::RefCountedBytes> data_bytes = GetBytesFromHandle(params.content.metafile_data_region);
+ scoped_refptr<base::RefCountedBytes> data_bytes = GetBytesFromHandle(params.content->metafile_data_region);
base::PostTask(FROM_HERE, {base::ThreadPool(), base::MayBlock()},
base::BindOnce(&SavePdfFile, data_bytes, pdfOutputPath, pdf_save_callback));
}
}
-void PrintViewManagerQt::OnDidShowPrintDialog()
-{
-}
-
// content::WebContentsObserver implementation.
void PrintViewManagerQt::DidStartLoading()
{
@@ -411,8 +400,8 @@ void PrintViewManagerQt::RenderProcessGone(base::TerminationStatus status)
}
void PrintViewManagerQt::OnDidPreviewPage(content::RenderFrameHost* rfh,
- const PrintHostMsg_DidPreviewPage_Params& params,
- const PrintHostMsg_PreviewIds& ids)
+ const printing::mojom::DidPreviewPageParams &params,
+ const printing::mojom::PreviewIds& ids)
{
// just consume the message, this is just for sending 'page-preview-ready' for webui
}
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index 06c2f47ea..ecb3d6053 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -51,31 +51,13 @@
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "components/prefs/pref_member.h"
-#include "components/printing/browser/print_manager.h"
#include "components/printing/common/print.mojom.h"
#include "components/printing/common/print_messages.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include <QSharedPointer>
-struct PrintHostMsg_RequestPrintPreview_Params;
-struct PrintHostMsg_DidPreviewDocument_Params;
-
-namespace content {
-class RenderViewHost;
-}
-
-namespace printing {
-class JobEventDetails;
-class MetafilePlayer;
-class PrintJob;
-class PrintJobWorkerOwner;
-class PrintQueriesQueue;
-}
-
QT_BEGIN_NAMESPACE
class QPageLayout;
class QString;
@@ -101,8 +83,6 @@ public:
bool useCustomMargins,
const PrintToPDFCallback &callback);
- base::string16 RenderSourceName() override;
-
protected:
explicit PrintViewManagerQt(content::WebContents*);
@@ -119,16 +99,15 @@ protected:
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
// IPC handlers
- void OnDidShowPrintDialog();
void OnRequestPrintPreview(const PrintHostMsg_RequestPrintPreview_Params&);
void OnMetafileReadyForPrinting(content::RenderFrameHost* rfh,
- const PrintHostMsg_DidPreviewDocument_Params& params,
- const PrintHostMsg_PreviewIds &ids);
+ const printing::mojom::DidPreviewDocumentParams& params,
+ const printing::mojom::PreviewIds &ids);
void OnSetupScriptedPrintPreview(content::RenderFrameHost* rfh,
IPC::Message* reply_msg);
void OnDidPreviewPage(content::RenderFrameHost* rfh,
- const PrintHostMsg_DidPreviewPage_Params& params,
- const PrintHostMsg_PreviewIds& ids);
+ const printing::mojom::DidPreviewPageParams& params,
+ const printing::mojom::PreviewIds& ids);
void OnShowScriptedPrintPreview(content::RenderFrameHost* rfh,
bool source_is_modifiable);
bool PrintToPDFInternal(const QPageLayout &, bool printInColor, bool useCustomMargins = true);
diff --git a/src/core/printing/printing_message_filter_qt.cpp b/src/core/printing/printing_message_filter_qt.cpp
index 5b9228d20..8d6833dce 100644
--- a/src/core/printing/printing_message_filter_qt.cpp
+++ b/src/core/printing/printing_message_filter_qt.cpp
@@ -46,20 +46,14 @@
#include "web_engine_context.h"
-#include <string>
-
#include "base/bind.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.h"
#include "components/printing/browser/print_manager_utils.h"
#include "components/printing/common/print_messages.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
#include "content/public/common/child_process_host.h"
-using content::BrowserThread;
-
namespace QtWebEngineCore {
PrintingMessageFilterQt::PrintingMessageFilterQt(int render_process_id)
@@ -72,15 +66,14 @@ PrintingMessageFilterQt::PrintingMessageFilterQt(int render_process_id)
PrintingMessageFilterQt::~PrintingMessageFilterQt() {
}
-void PrintingMessageFilterQt::OverrideThreadForMessage(
- const IPC::Message& message, BrowserThread::ID* thread) {
+void PrintingMessageFilterQt::OnDestruct() const
+{
+ content::BrowserThread::DeleteOnUIThread::Destruct(this);
}
bool PrintingMessageFilterQt::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrintingMessageFilterQt, message)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
- OnGetDefaultPrintSettings)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
OnUpdatePrintSettings)
@@ -90,57 +83,8 @@ bool PrintingMessageFilterQt::OnMessageReceived(const IPC::Message& message) {
return handled;
}
-void PrintingMessageFilterQt::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- std::unique_ptr<printing::PrinterQuery> printer_query;
-
- printer_query = queue_->PopPrinterQuery(0);
- if (!printer_query) {
- printer_query =
- queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
- }
-
- // Loads default settings. This is asynchronous, only the IPC message sender
- // will hang until the settings are retrieved.
- printer_query->GetSettings(
- printing::PrinterQuery::GetSettingsAskParam::DEFAULTS,
- 0,
- false,
- printing::DEFAULT_MARGINS,
- false,
- false,
- base::BindOnce(&PrintingMessageFilterQt::OnGetDefaultPrintSettingsReply,
- this,
- std::move(printer_query),
- reply_msg));
-}
-
-void PrintingMessageFilterQt::OnGetDefaultPrintSettingsReply(
- std::unique_ptr<printing::PrinterQuery> printer_query,
- IPC::Message* reply_msg) {
- PrintMsg_Print_Params params;
- if (!printer_query.get() ||
- printer_query->last_status() != printing::PrintingContext::OK) {
- params.Reset();
- } else {
- RenderParamsFromPrintSettings(printer_query->settings(), &params);
- params.document_cookie = printer_query->cookie();
- }
- PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params);
- Send(reply_msg);
- // If printing was enabled.
- if (printer_query.get()) {
- // If user hasn't cancelled.
- if (printer_query->cookie() && printer_query->settings().dpi()) {
- queue_->QueuePrinterQuery(std::move(printer_query));
- } else {
- printer_query->StopWorker();
- }
- }
-}
-
void PrintingMessageFilterQt::OnScriptedPrint(
- const PrintHostMsg_ScriptedPrint_Params& params,
+ const printing::mojom::ScriptedPrintParams& params,
IPC::Message* reply_msg) {
std::unique_ptr<printing::PrinterQuery> printer_query =
queue_->PopPrinterQuery(params.cookie);
@@ -164,19 +108,19 @@ void PrintingMessageFilterQt::OnScriptedPrint(
void PrintingMessageFilterQt::OnScriptedPrintReply(
std::unique_ptr<printing::PrinterQuery> printer_query,
IPC::Message* reply_msg) {
- PrintMsg_PrintPages_Params params;
-
+ printing::mojom::PrintPagesParams params;
+ params.params = printing::mojom::PrintParams::New();
if (printer_query->last_status() != printing::PrintingContext::OK ||
!printer_query->settings().dpi()) {
- params.Reset();
+ params.params.reset();
} else {
- RenderParamsFromPrintSettings(printer_query->settings(), &params.params);
- params.params.document_cookie = printer_query->cookie();
+ RenderParamsFromPrintSettings(printer_query->settings(), params.params.get());
+ params.params->document_cookie = printer_query->cookie();
params.pages = printing::PageRange::GetPages(printer_query->settings().ranges());
}
PrintHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, params);
Send(reply_msg);
- if (!params.params.dpi.IsEmpty() && params.params.document_cookie) {
+ if (!params.params->dpi.IsEmpty() && params.params->document_cookie) {
queue_->QueuePrinterQuery(std::move(printer_query));
} else {
printer_query->StopWorker();
@@ -186,13 +130,21 @@ void PrintingMessageFilterQt::OnScriptedPrintReply(
void PrintingMessageFilterQt::OnUpdatePrintSettings(int document_cookie,
base::Value job_settings,
IPC::Message* reply_msg) {
- std::unique_ptr<printing::PrinterQuery> printer_query;
- printer_query = queue_->PopPrinterQuery(document_cookie);
+ if (!job_settings.is_dict() ||
+ !job_settings.FindIntKey(printing::kSettingPrinterType)) {
+ // Reply with null query.
+ OnUpdatePrintSettingsReply(nullptr, reply_msg);
+ return;
+ }
+
+ std::unique_ptr<printing::PrinterQuery> printer_query =
+ queue_->PopPrinterQuery(document_cookie);
if (!printer_query.get()) {
printer_query = queue_->CreatePrinterQuery(
content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
}
- printer_query->SetSettings(
+ auto* printer_query_ptr = printer_query.get();
+ printer_query_ptr->SetSettings(
std::move(job_settings),
base::BindOnce(&PrintingMessageFilterQt::OnUpdatePrintSettingsReply, this,
std::move(printer_query), reply_msg));
@@ -200,13 +152,14 @@ void PrintingMessageFilterQt::OnUpdatePrintSettings(int document_cookie,
void PrintingMessageFilterQt::OnUpdatePrintSettingsReply(std::unique_ptr<printing::PrinterQuery> printer_query,
IPC::Message* reply_msg) {
- PrintMsg_PrintPages_Params params;
+ printing::mojom::PrintPagesParams params;
+ params.params = printing::mojom::PrintParams::New();
if (!printer_query.get() ||
printer_query->last_status() != printing::PrintingContext::OK) {
- params.Reset();
+ params.params.reset();
} else {
- RenderParamsFromPrintSettings(printer_query->settings(), &params.params);
- params.params.document_cookie = printer_query->cookie();
+ RenderParamsFromPrintSettings(printer_query->settings(), params.params.get());
+ params.params->document_cookie = printer_query->cookie();
params.pages = printing::PageRange::GetPages(printer_query->settings().ranges());
}
@@ -226,7 +179,7 @@ void PrintingMessageFilterQt::OnUpdatePrintSettingsReply(std::unique_ptr<printin
}
}
-void PrintingMessageFilterQt::OnCheckForCancel(const PrintHostMsg_PreviewIds& ids,
+void PrintingMessageFilterQt::OnCheckForCancel(const printing::mojom::PreviewIds& ids,
bool* cancel) {
*cancel = false;
}
diff --git a/src/core/printing/printing_message_filter_qt.h b/src/core/printing/printing_message_filter_qt.h
index 89e473dcf..3a449af70 100644
--- a/src/core/printing/printing_message_filter_qt.h
+++ b/src/core/printing/printing_message_filter_qt.h
@@ -46,24 +46,13 @@
#include <string>
-#include "base/compiler_specific.h"
-#include "components/prefs/pref_member.h"
#include "content/public/browser/browser_message_filter.h"
-struct PrintHostMsg_PreviewIds;
-struct PrintHostMsg_ScriptedPrint_Params;
-
-namespace base {
-class DictionaryValue;
-class FilePath;
-}
-
-namespace content {
-class WebContents;
-}
-
namespace printing {
-class PrintJobManager;
+namespace mojom {
+class ScriptedPrintParams;
+class PreviewIds;
+}
class PrintQueriesQueue;
class PrinterQuery;
}
@@ -76,28 +65,20 @@ class PrintingMessageFilterQt : public content::BrowserMessageFilter {
PrintingMessageFilterQt(int render_process_id);
// content::BrowserMessageFilter methods.
- void OverrideThreadForMessage(const IPC::Message& message,
- content::BrowserThread::ID* thread) override;
bool OnMessageReceived(const IPC::Message& message) override;
private:
- ~PrintingMessageFilterQt() override;
+ friend class base::DeleteHelper<PrintingMessageFilterQt>;
+ friend class content::BrowserThread;
- // GetPrintSettingsForRenderView must be called via PostTask and
- // base::Bind. Collapse the settings-specific params into a
- // struct to avoid running into issues with too many params
- // to base::Bind.
- struct GetPrintSettingsForRenderViewParams;
+ ~PrintingMessageFilterQt() override;
- // Get the default print setting.
- void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
- void OnGetDefaultPrintSettingsReply(std::unique_ptr<printing::PrinterQuery> printer_query,
- IPC::Message* reply_msg);
+ void OnDestruct() const override;
// The renderer host have to show to the user the print dialog and returns
// the selected print settings. The task is handled by the print worker
// thread and the UI thread. The reply occurs on the IO thread.
- void OnScriptedPrint(const PrintHostMsg_ScriptedPrint_Params& params,
+ void OnScriptedPrint(const printing::mojom::ScriptedPrintParams& params,
IPC::Message* reply_msg);
void OnScriptedPrintReply(std::unique_ptr<printing::PrinterQuery> printer_query,
IPC::Message* reply_msg);
@@ -112,7 +93,7 @@ class PrintingMessageFilterQt : public content::BrowserMessageFilter {
IPC::Message* reply_msg);
// Check to see if print preview has been cancelled.
- void OnCheckForCancel(const PrintHostMsg_PreviewIds& ids, bool* cancel);
+ void OnCheckForCancel(const printing::mojom::PreviewIds& ids, bool* cancel);
const int render_process_id_;
diff --git a/src/core/process_main.cpp b/src/core/process_main.cpp
index ade0f6e99..827e31037 100644
--- a/src/core/process_main.cpp
+++ b/src/core/process_main.cpp
@@ -44,7 +44,7 @@
#if defined(OS_WIN)
#include "sandbox/win/src/sandbox_types.h"
#include "content/public/app/sandbox_helper_win.h"
-#elif defined(OS_MACOSX)
+#elif defined(OS_MAC)
#include "base/logging.h"
#include "sandbox/mac/seatbelt_exec.h"
#endif
@@ -74,13 +74,13 @@ int processMain(int argc, const char **argv)
params.argc = argc;
params.argv = argv;
#endif // OS_WIN
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
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)
+#endif // defined(OS_MAC)
return content::ContentMain(params);
}
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index b0b48af03..4dab8aa34 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -87,6 +87,9 @@ inline QString buildLocationFromStandardPath(const QString &standardPath, const
namespace QtWebEngineCore {
+// static
+QPointer<ProfileAdapter> ProfileAdapter::s_profileForGlobalCertificateVerification;
+
ProfileAdapter::ProfileAdapter(const QString &storageName):
m_name(storageName)
, m_offTheRecord(storageName.isEmpty())
@@ -99,7 +102,6 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
WebEngineContext::current()->addProfileAdapter(this);
// creation of profile requires webengine context
m_profile.reset(new ProfileQt(this));
- 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);
@@ -122,6 +124,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
ProfileAdapter::~ProfileAdapter()
{
+ content::BrowserContext::NotifyWillBeDestroyed(m_profile.data());
while (!m_webContentsAdapterClients.isEmpty()) {
m_webContentsAdapterClients.first()->releaseProfile();
}
@@ -132,7 +135,9 @@ ProfileAdapter::~ProfileAdapter()
}
#if QT_CONFIG(ssl)
delete m_clientCertificateStore;
+ m_clientCertificateStore = nullptr;
#endif
+ WebEngineContext::flushMessages();
}
void ProfileAdapter::setStorageName(const QString &storageName)
@@ -652,26 +657,26 @@ 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;
- if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
- profileForglobalCertificateVerification->m_profile->m_profileIOData->resetNetworkContext();
- for (auto *client : qAsConst(profileForglobalCertificateVerification->m_clients))
+ if (s_profileForGlobalCertificateVerification) {
+ s_profileForGlobalCertificateVerification->m_usedForGlobalCertificateVerification = false;
+ for (auto *client : qAsConst(s_profileForGlobalCertificateVerification->m_clients))
client->useForGlobalCertificateVerificationChanged();
+ } else {
+ // OCSP enabled
+ for (auto adapter : qAsConst(WebEngineContext::current()->m_profileAdapters))
+ adapter->m_profile->m_profileIOData->resetNetworkContext();
}
- profileForglobalCertificateVerification = this;
+ s_profileForGlobalCertificateVerification = this;
} else {
- Q_ASSERT(profileForglobalCertificateVerification);
- Q_ASSERT(profileForglobalCertificateVerification == this);
- profileForglobalCertificateVerification = nullptr;
+ Q_ASSERT(s_profileForGlobalCertificateVerification);
+ Q_ASSERT(s_profileForGlobalCertificateVerification == this);
+ s_profileForGlobalCertificateVerification = nullptr;
+ // OCSP disabled
+ for (auto adapter : qAsConst(WebEngineContext::current()->m_profileAdapters))
+ adapter->m_profile->m_profileIOData->resetNetworkContext();
}
-
- if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
- m_profile->m_profileIOData->resetNetworkContext();
}
bool ProfileAdapter::isUsedForGlobalCertificateVerification() const
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index efd56e50e..caeff246a 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -216,6 +216,7 @@ public:
QString determineDownloadPath(const QString &downloadDirectory, const QString &suggestedFilename, const time_t &startTime);
+ static QPointer<ProfileAdapter> s_profileForGlobalCertificateVerification;
private:
void updateCustomUrlSchemeHandlers();
void resetVisitedLinksManager();
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 91adbc57d..8e6c8fed3 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -160,7 +160,7 @@ BrowsingDataRemoverObserverQt::BrowsingDataRemoverObserverQt(ProfileIODataQt *pr
{
}
-void BrowsingDataRemoverObserverQt::OnBrowsingDataRemoverDone()
+void BrowsingDataRemoverObserverQt::OnBrowsingDataRemoverDone(uint64_t)
{
Q_ASSERT(m_profileIOData->m_clearHttpCacheInProgress);
m_profileIOData->removeBrowsingDataRemoverObserver();
@@ -177,7 +177,6 @@ void ProfileIODataQt::setFullConfiguration()
m_httpCacheType = m_profileAdapter->httpCacheType();
m_httpCachePath = m_profileAdapter->httpCachePath();
m_httpCacheMaxSize = m_profileAdapter->httpCacheMaxSize();
- m_useForGlobalCertificateVerification = m_profileAdapter->isUsedForGlobalCertificateVerification();
m_dataPath = m_profileAdapter->dataPath();
m_storageName = m_profileAdapter->storageName();
m_inMemoryOnly = m_profileAdapter->isOffTheRecord() || m_storageName.isEmpty();
@@ -216,12 +215,17 @@ std::unique_ptr<net::ClientCertStore> ProfileIODataQt::CreateClientCertStore()
#endif
}
-network::mojom::NetworkContextParamsPtr ProfileIODataQt::CreateNetworkContextParams()
+void ProfileIODataQt::ConfigureNetworkContextParams(bool in_memory,
+ const base::FilePath &relative_partition_path,
+ network::mojom::NetworkContextParams *network_context_params,
+ network::mojom::CertVerifierCreationParams *cert_verifier_creation_params)
{
setFullConfiguration();
- network::mojom::NetworkContextParamsPtr network_context_params =
- SystemNetworkContextManager::GetInstance()->CreateDefaultNetworkContextParams();
+ SystemNetworkContextManager::GetInstance()->ConfigureDefaultNetworkContextParams(network_context_params);
+
+ // FIXME: Faking old behavior to allow not enabling OCSP
+ network_context_params->initial_ssl_config->rev_checking_enabled = !ProfileAdapter::s_profileForGlobalCertificateVerification.isNull();
network_context_params->context_name = m_storageName.toStdString();
network_context_params->user_agent = m_httpUserAgent.toStdString();
@@ -233,10 +237,10 @@ network::mojom::NetworkContextParamsPtr ProfileIODataQt::CreateNetworkContextPar
network_context_params->http_cache_enabled = m_httpCacheType != ProfileAdapter::NoCache;
network_context_params->http_cache_max_size = m_httpCacheMaxSize;
- if (m_httpCacheType == ProfileAdapter::DiskHttpCache && !m_httpCachePath.isEmpty())
+ if (m_httpCacheType == ProfileAdapter::DiskHttpCache && !m_httpCachePath.isEmpty() && !m_inMemoryOnly && !in_memory)
network_context_params->http_cache_path = toFilePath(m_httpCachePath);
- if (m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies && !m_inMemoryOnly) {
+ if (m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies && !m_inMemoryOnly && !in_memory) {
base::FilePath cookie_path = toFilePath(m_dataPath);
cookie_path = cookie_path.AppendASCII("Cookies");
network_context_params->cookie_path = cookie_path;
@@ -244,7 +248,7 @@ network::mojom::NetworkContextParamsPtr ProfileIODataQt::CreateNetworkContextPar
network_context_params->restore_old_session_cookies = m_persistentCookiesPolicy == ProfileAdapter::ForcePersistentCookies;
network_context_params->persist_session_cookies = m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies;
}
- if (!m_inMemoryOnly) {
+ if (!m_inMemoryOnly && !in_memory) {
network_context_params->http_server_properties_path = toFilePath(m_dataPath).AppendASCII("Network Persistent State");
network_context_params->transport_security_persister_path = toFilePath(m_dataPath);
}
@@ -253,18 +257,13 @@ network::mojom::NetworkContextParamsPtr ProfileIODataQt::CreateNetworkContextPar
network_context_params->enable_ftp_url_support = true;
#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
-// network_context_params->enable_certificate_reporting = true;
-// network_context_params->enable_expect_ct_reporting = true;
network_context_params->enforce_chrome_ct_policy = false;
- network_context_params->primary_network_context = m_useForGlobalCertificateVerification;
// Should be initialized with existing per-profile CORS access lists.
network_context_params->cors_origin_access_list =
m_profile->GetSharedCorsOriginAccessList()->GetOriginAccessList().CreateCorsOriginAccessPatternsList();
- m_proxyConfigMonitor->AddToNetworkContextParams(network_context_params.get());
-
- return network_context_params;
+ m_proxyConfigMonitor->AddToNetworkContextParams(network_context_params);
}
// static
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 00d2c392c..e44d838dd 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -53,7 +53,6 @@
namespace net {
class ClientCertStore;
-class URLRequestContext;
}
namespace extensions {
@@ -70,7 +69,7 @@ class BrowsingDataRemoverObserverQt : public content::BrowsingDataRemover::Obser
public:
BrowsingDataRemoverObserverQt(ProfileIODataQt *profileIOData);
- void OnBrowsingDataRemoverDone() override;
+ void OnBrowsingDataRemoverDone(uint64_t) override;
private:
ProfileIODataQt *m_profileIOData;
@@ -97,13 +96,15 @@ public:
bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const;
- // Used in NetworkDelegateQt::OnBeforeURLRequest.
void setFullConfiguration(); // runs on ui thread
void resetNetworkContext(); // runs on ui thread
void clearHttpCache(); // runs on ui thread
bool isClearHttpCacheInProgress() { return m_clearHttpCacheInProgress; }
- network::mojom::NetworkContextParamsPtr CreateNetworkContextParams();
+ void ConfigureNetworkContextParams(bool in_memory,
+ const base::FilePath &relative_partition_path,
+ network::mojom::NetworkContextParams *network_context_params,
+ network::mojom::CertVerifierCreationParams *cert_verifier_creation_params);
#if QT_CONFIG(ssl)
ClientCertificateStoreData *clientCertificateStoreData();
@@ -142,7 +143,6 @@ private:
QRecursiveMutex m_mutex;
#endif
int m_httpCacheMaxSize = 0;
- bool m_useForGlobalCertificateVerification = false;
BrowsingDataRemoverObserverQt m_removerObserver;
QString m_dataPath;
bool m_clearHttpCacheInProgress = false;
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 748104312..36303605f 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -111,7 +111,6 @@ ProfileQt::~ProfileQt()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
m_prefServiceAdapter.commit();
- content::BrowserContext::NotifyWillBeDestroyed(this);
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(this);
ShutdownStoragePartitions();
m_profileIOData->shutdownOnUIThread();
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index a5628bb88..11352a3e8 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -31,7 +31,7 @@ deps = [
"//components/spellcheck:buildflags",
"//components/proxy_config",
"//components/user_prefs",
- "//content/public/app:browser",
+ "//content/public/app",
"//content",
"//media:media_buildflags",
"//net",
@@ -41,6 +41,7 @@ deps = [
"//ui/accessibility",
"//ui/gl",
"//qtwebengine/browser:interfaces",
+ "//qtwebengine/userscript",
"//qtwebengine/browser:service_manifests",
"//qtwebengine/common:mojo_bindings",
":qtwebengine_sources",
diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni
index 38e824f5e..3bf1a5d57 100644
--- a/src/core/qtwebengine_resources.gni
+++ b/src/core/qtwebengine_resources.gni
@@ -22,10 +22,12 @@ repack("qtwebengine_repack_resources") {
sources = [
"$root_gen_dir/qtwebengine/qt_webengine_resources.pak",
"$root_gen_dir/chrome/common_resources.pak",
+ "$root_gen_dir/chrome/net_internals_resources.pak",
"$root_gen_dir/chrome/quota_internals_resources.pak",
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/components/dev_ui_components_resources.pak",
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
+ "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/content/dev_ui_content_resources.pak",
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
@@ -36,11 +38,13 @@ repack("qtwebengine_repack_resources") {
output = "$root_out_dir/qtwebengine_resources.pak"
deps = [
"//qtwebengine/browser:qt_webengine_resources",
+ "//chrome/browser/resources/net_internals:net_internals_resources",
"//chrome/browser/resources/quota_internals:quota_internals_resources",
"//chrome/common:resources_grit",
"//components/resources:components_resources_grit",
"//components/resources:dev_ui_components_resources_grit",
"//content/browser/resources/media:media_internals_resources",
+ "//content/browser/tracing:resources",
"//content:content_resources_grit",
"//content:dev_ui_content_resources_grit",
"//mojo/public/js:resources",
@@ -70,6 +74,15 @@ repack("qtwebengine_repack_resources") {
"//content/browser/webrtc/resources",
]
}
+
+ if (enable_webrtc && enable_extensions) {
+ sources += [
+ "$root_gen_dir/chrome/webrtc_logs_resources.pak",
+ ]
+ deps += [
+ "//chrome/browser/resources/media:webrtc_logs_resources",
+ ]
+ }
}
repack("qtwebengine_repack_resources_100") {
@@ -127,10 +140,12 @@ repack("qtwebengine_repack_resources_200") {
repack("qtwebengine_repack_resources_devtools") {
sources = [
"$root_gen_dir/content/browser/devtools/devtools_resources.pak",
+ "$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
]
output = "$root_out_dir/qtwebengine_devtools_resources.pak"
deps = [
"//content/browser/devtools:devtools_resources_grit",
+ "//third_party/blink/public:devtools_inspector_resources",
]
}
diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni
index cbe51d052..97d51d68e 100644
--- a/src/core/qtwebengine_sources.gni
+++ b/src/core/qtwebengine_sources.gni
@@ -53,6 +53,7 @@ source_set("qtwebengine_sources") {
"//components/performance_manager",
"//components/plugins/renderer/",
"//extensions/buildflags:buildflags",
+ "//qtwebengine/common:mojo_bindings",
"//rlz/buildflags:buildflags",
"//third_party/blink/public/mojom:mojom_platform",
]
@@ -64,6 +65,8 @@ source_set("qtwebengine_sources") {
"//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/devtools/devtools_eye_dropper.cc",
+ "//chrome/browser/devtools/devtools_eye_dropper.h",
"//chrome/browser/media/webrtc/desktop_media_list.h",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
@@ -77,6 +80,8 @@ source_set("qtwebengine_sources") {
"//chrome/browser/ui/webui/devtools_ui.h",
"//chrome/browser/ui/webui/devtools_ui_data_source.cc",
"//chrome/browser/ui/webui/devtools_ui_data_source.h",
+ "//chrome/browser/ui/webui/net_internals/net_internals_ui.cc",
+ "//chrome/browser/ui/webui/net_internals/net_internals_ui.h",
"//chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc",
"//chrome/browser/ui/webui/quota_internals/quota_internals_handler.h",
"//chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc",
@@ -85,6 +90,12 @@ source_set("qtwebengine_sources") {
"//chrome/browser/ui/webui/quota_internals/quota_internals_types.h",
"//chrome/browser/ui/webui/quota_internals/quota_internals_ui.cc",
"//chrome/browser/ui/webui/quota_internals/quota_internals_ui.h",
+ "//chrome/browser/ui/webui/user_actions/user_actions_ui.cc",
+ "//chrome/browser/ui/webui/user_actions/user_actions_ui.h",
+ "//chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc",
+ "//chrome/browser/ui/webui/user_actions/user_actions_ui_handler.h",
+ "//chrome/browser/ui/webui/webui_util.cc",
+ "//chrome/browser/ui/webui/webui_util.h",
"//chrome/common/custom_handlers/protocol_handler.cc",
"//chrome/common/custom_handlers/protocol_handler.h",
"//chrome/common/chrome_switches.cc",
@@ -101,8 +112,10 @@ source_set("qtwebengine_sources") {
deps += [
":qtwebengine_extensions_features",
"//chrome/app:generated_resources",
+ "//chrome/browser/extensions/api:api_registration",
"//chrome/browser/resources:component_extension_resources_grit",
"//chrome/common/extensions/api",
+ "//chrome/common/extensions/api:api",
"//chrome/common/extensions/api:extensions_features",
"//components/crx_file",
"//components/crx_file:crx_creator",
@@ -117,8 +130,12 @@ source_set("qtwebengine_sources") {
"//extensions/renderer",
"//extensions:extensions_resources",
"//extensions/strings",
+ "//qtwebengine/browser/extensions/api:api_registration",
+ "//qtwebengine/common/extensions/api:api",
]
sources += [
+ "//chrome/browser/extensions/api/enterprise_hardware_platform/enterprise_hardware_platform_api.cc",
+ "//chrome/browser/extensions/api/enterprise_hardware_platform/enterprise_hardware_platform_api.h",
"//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",
@@ -181,11 +198,59 @@ source_set("qtwebengine_sources") {
deps += [
"//pdf",
"//pdf:buildflags",
+ "//pdf:pdf_ppapi",
"//components/pdf/browser:browser",
"//components/pdf/renderer:renderer",
"//components/printing/browser",
- "//components/printing/renderer",
+ "//components/printing/renderer"
]
+ sources += [
+ "//chrome/browser/extensions/api/streams_private/streams_private_api.cc",
+ ]
+ }
+
+ if (enable_webrtc && enable_extensions) {
+ deps += [
+ "//chrome/browser/resources/media:webrtc_logs_resources",
+ "//components/upload_list",
+ "//components/webrtc_logging/browser",
+ "//components/webrtc_logging/common",
+ ]
+
+ sources += [
+ "//chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc",
+ "//chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h",
+ "//chrome/browser/media/webrtc/audio_debug_recordings_handler.cc",
+ "//chrome/browser/media/webrtc/audio_debug_recordings_handler.h",
+ "//chrome/browser/media/webrtc/webrtc_event_log_history.cc",
+ "//chrome/browser/media/webrtc/webrtc_event_log_history.h",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager.cc",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager.h",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager_common.h",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager_local.cc",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager_local.h",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc",
+ "//chrome/browser/media/webrtc/webrtc_event_log_manager_remote.h",
+ "//chrome/browser/media/webrtc/webrtc_event_log_uploader.cc",
+ "//chrome/browser/media/webrtc/webrtc_event_log_uploader.h",
+ "//chrome/browser/media/webrtc/webrtc_log_buffer.cc",
+ "//chrome/browser/media/webrtc/webrtc_log_buffer.h",
+ "//chrome/browser/media/webrtc/webrtc_log_uploader.cc",
+ "//chrome/browser/media/webrtc/webrtc_log_uploader.h",
+ "//chrome/browser/media/webrtc/webrtc_logging_controller.cc",
+ "//chrome/browser/media/webrtc/webrtc_logging_controller.h",
+ "//chrome/browser/media/webrtc/webrtc_rtp_dump_handler.cc",
+ "//chrome/browser/media/webrtc/webrtc_rtp_dump_handler.h",
+ "//chrome/browser/media/webrtc/webrtc_rtp_dump_writer.cc",
+ "//chrome/browser/media/webrtc/webrtc_rtp_dump_writer.h",
+ "//chrome/browser/media/webrtc/webrtc_text_log_handler.cc",
+ "//chrome/browser/media/webrtc/webrtc_text_log_handler.h",
+ "//chrome/browser/ui/webui/media/webrtc_logs_ui.cc",
+ "//chrome/browser/ui/webui/media/webrtc_logs_ui.h",
+ "//chrome/renderer/media/webrtc_logging_agent_impl.cc",
+ "//chrome/renderer/media/webrtc_logging_agent_impl.h",
+ ]
}
}
diff --git a/src/core/quota_permission_context_qt.cpp b/src/core/quota_permission_context_qt.cpp
index c7f1e856c..549414d33 100644
--- a/src/core/quota_permission_context_qt.cpp
+++ b/src/core/quota_permission_context_qt.cpp
@@ -61,7 +61,7 @@ void QuotaPermissionContextQt::RequestQuotaPermission(const StorageQuotaParams &
if (params.storage_type != blink::mojom::StorageType::kPersistent) {
// For now we only support requesting quota with this interface
// for Persistent storage type.
- std::move(callback).Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
+ dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_DISALLOW);
return;
}
@@ -74,16 +74,26 @@ void QuotaPermissionContextQt::RequestQuotaPermission(const StorageQuotaParams &
}
RenderFrameHost *renderFrameHost = RenderFrameHost::FromID(render_process_id, params.render_frame_id);
- if (!renderFrameHost)
+ if (!renderFrameHost) {
+ LOG(WARNING) << "Attempt to request quota from frameless renderer: "
+ << render_process_id << "," << params.render_frame_id;
+ dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
return;
+ }
WebContents *webContents = WebContents::FromRenderFrameHost(renderFrameHost);
- if (!webContents)
+ if (!webContents) {
+ LOG(ERROR) << "Attempt to request quota from frame missing webcontents";
+ dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
return;
+ }
WebContentsAdapterClient *client = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(webContents)->GetView())->client();
- if (!client)
+ if (!client) {
+ LOG(ERROR) << "Attempt to request quota from content missing webcontents client";
+ dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
return;
+ }
QWebEngineQuotaRequest request(
QSharedPointer<QuotaRequestControllerImpl>::create(this, params, std::move(callback)));
diff --git a/src/core/quota_permission_context_qt.h b/src/core/quota_permission_context_qt.h
index 6d678c92a..528928c1a 100644
--- a/src/core/quota_permission_context_qt.h
+++ b/src/core/quota_permission_context_qt.h
@@ -42,8 +42,6 @@
#include "content/public/browser/quota_permission_context.h"
-#include <QtCore/qcompilerdetection.h> // Needed for override
-
namespace QtWebEngineCore {
class QuotaPermissionContextQt : public content::QuotaPermissionContext {
diff --git a/src/core/quota_request_controller_impl.cpp b/src/core/quota_request_controller_impl.cpp
index 514b85954..ea2526d45 100644
--- a/src/core/quota_request_controller_impl.cpp
+++ b/src/core/quota_request_controller_impl.cpp
@@ -55,17 +55,18 @@ QuotaRequestControllerImpl::QuotaRequestControllerImpl(QuotaPermissionContextQt
QuotaRequestControllerImpl::~QuotaRequestControllerImpl()
{
- reject();
+ if (m_callback)
+ m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
}
void QuotaRequestControllerImpl::accepted()
{
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), QuotaPermissionContextQt::QUOTA_PERMISSION_RESPONSE_ALLOW);
+ m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
}
void QuotaRequestControllerImpl::rejected()
{
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), QuotaPermissionContextQt::QUOTA_PERMISSION_RESPONSE_DISALLOW);
+ m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
}
} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 525e9924e..7acef2b15 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -59,22 +59,28 @@
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/image_transport_factory.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/display_util.h"
+#include "content/browser/renderer_host/frame_tree.h"
+#include "content/browser/renderer_host/frame_tree_node.h"
+#include "content/browser/renderer_host/cursor_manager.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+#include "content/browser/renderer_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"
+#include "content/browser/renderer_host/ui_events_helper.h"
+#include "content/common/content_switches_internal.h"
#include "content/common/cursors/webcursor.h"
#include "content/common/input_messages.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/cursor/cursor.h"
+#include "ui/base/resource/resource_bundle.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/events/keycodes/dom/dom_keyboard_layout_map.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/touch_selection/touch_selection_controller.h"
@@ -85,7 +91,10 @@
#if defined(USE_AURA)
#include "ui/base/cursor/cursor_size.h"
#include "ui/base/cursor/cursors_aura.h"
-#include "ui/base/resource/resource_bundle.h"
+#endif
+
+#if defined(Q_OS_MACOS)
+#include "content/app/resources/grit/content_resources.h"
#endif
#include <private/qguiapplication_p.h>
@@ -99,6 +108,7 @@
#include <QKeyEvent>
#include <QMouseEvent>
#include <QPixmap>
+#include <QScopeGuard>
#include <QScreen>
#include <QStyleHints>
#include <QVariant>
@@ -180,12 +190,6 @@ static inline ui::GestureProvider::Config QtGestureProviderConfig() {
return config;
}
-static inline bool compareTouchPoints(const QTouchEvent::TouchPoint &lhs, const QTouchEvent::TouchPoint &rhs)
-{
- // TouchPointPressed < TouchPointMoved < TouchPointReleased
- return lhs.state() < rhs.state();
-}
-
static inline bool isCommonTextEditShortcut(const QKeyEvent *ke)
{
return QInputControl::isCommonTextEditShortcut(ke);
@@ -194,35 +198,40 @@ 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, int index = -1)
- : touchPoints(touchPoints)
+ MotionEventQt(const QList<QPair<int, QTouchEvent::TouchPoint>> &points, const base::TimeTicks &eventTime,
+ Action action, const Qt::KeyboardModifiers modifiers, int index = -1)
+ : touchPoints(points)
, eventTime(eventTime)
, action(action)
, eventId(++s_eventId)
, flags(flagsFromModifiers(modifiers))
, index(index)
{
- // ACTION_DOWN and ACTION_UP must be accesssed through pointer_index 0
- Q_ASSERT((action != Action::DOWN && action != Action::UP) || index == 0);
+ // index is only valid for ACTION_DOWN and ACTION_UP and should correspond to the point causing it
+ // see blink_event_util.cc:ToWebTouchPointState for details
+ Q_ASSERT_X((action != Action::POINTER_DOWN && action != Action::POINTER_UP && index == -1)
+ || (action == Action::POINTER_DOWN && index >= 0 && touchPoint(index).state() == Qt::TouchPointPressed)
+ || (action == Action::POINTER_UP && index >= 0 && touchPoint(index).state() == Qt::TouchPointReleased),
+ "MotionEventQt", qPrintable(QString("action: %1, index: %2, state: %3").arg(int(action)).arg(index).arg(touchPoint(index).state())));
}
uint32_t GetUniqueEventId() const override { return eventId; }
Action GetAction() const override { return action; }
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(); }
- 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(); }
+ int GetPointerId(size_t pointer_index) const override { return touchPoints[pointer_index].first; }
+ float GetX(size_t pointer_index) const override { return touchPoint(pointer_index).pos().x(); }
+ float GetY(size_t pointer_index) const override { return touchPoint(pointer_index).pos().y(); }
+ float GetRawX(size_t pointer_index) const override { return touchPoint(pointer_index).screenPos().x(); }
+ float GetRawY(size_t pointer_index) const override { return touchPoint(pointer_index).screenPos().y(); }
float GetTouchMajor(size_t pointer_index) const override
{
- QSizeF diams = touchPoints.at(pointer_index).ellipseDiameters();
+ QSizeF diams = touchPoint(pointer_index).ellipseDiameters();
return std::max(diams.height(), diams.width());
}
float GetTouchMinor(size_t pointer_index) const override
{
- QSizeF diams = touchPoints.at(pointer_index).ellipseDiameters();
+ QSizeF diams = touchPoint(pointer_index).ellipseDiameters();
return std::min(diams.height(), diams.width());
}
float GetOrientation(size_t pointer_index) const override
@@ -230,7 +239,7 @@ public:
return 0;
}
int GetFlags() const override { return flags; }
- float GetPressure(size_t pointer_index) const override { return touchPoints.at(pointer_index).pressure(); }
+ float GetPressure(size_t pointer_index) const override { return touchPoint(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; }
@@ -243,33 +252,32 @@ public:
float GetHistoricalX(size_t pointer_index, size_t historical_index) const override { return 0; }
float GetHistoricalY(size_t pointer_index, size_t historical_index) const override { return 0; }
ToolType GetToolType(size_t pointer_index) const override {
- return (touchPoints.at(pointer_index).flags() & QTouchEvent::TouchPoint::InfoFlag::Pen) ? ui::MotionEvent::ToolType::STYLUS
- : ui::MotionEvent::ToolType::FINGER;
+ bool isPen = touchPoint(pointer_index).flags() & QTouchEvent::TouchPoint::InfoFlag::Pen;
+ return isPen ? ui::MotionEvent::ToolType::STYLUS : ui::MotionEvent::ToolType::FINGER;
}
int GetButtonState() const override { return 0; }
private:
- QList<QTouchEvent::TouchPoint> touchPoints;
+ QList<QPair<int, QTouchEvent::TouchPoint>> touchPoints;
base::TimeTicks eventTime;
Action action;
const uint32_t eventId;
int flags;
int index;
+ const QTouchEvent::TouchPoint& touchPoint(size_t i) const { return touchPoints[i].second; }
};
-static content::ScreenInfo screenInfoFromQScreen(QScreen *screen)
+extern display::Display toDisplayDisplay(int id, const QScreen *screen);
+
+static blink::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 {
+ blink::ScreenInfo r;
+ if (!screen)
+ screen = qApp->primaryScreen();
+ if (screen)
+ content::DisplayUtil::DisplayToScreenInfo(&r, toDisplayDisplay(0, screen));
+ else
r.device_scale_factor = qGuiApp->devicePixelRatio();
- }
return r;
}
@@ -300,12 +308,35 @@ public:
}
};
+class GuestInputEventObserverQt : public content::RenderWidgetHost::InputEventObserver
+{
+public:
+ GuestInputEventObserverQt(RenderWidgetHostViewQt *rwhv)
+ : m_rwhv(rwhv)
+ {
+ }
+ ~GuestInputEventObserverQt() {}
+
+ void OnInputEvent(const blink::WebInputEvent&) override {}
+ void OnInputEventAck(blink::mojom::InputEventResultSource,
+ blink::mojom::InputEventResultState state,
+ const blink::WebInputEvent &event) override
+ {
+ if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel)
+ m_rwhv->WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state);
+ }
+
+private:
+ RenderWidgetHostViewQt *m_rwhv;
+};
+
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget)
: content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget)
, m_taskRunner(base::ThreadTaskRunnerHandle::Get())
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
, m_touchMotionStarted(false)
+ , m_guestInputEventObserver(new GuestInputEventObserverQt(this))
, m_visible(false)
, m_loadVisuallyCommittedState(NotCommitted)
, m_adapterClient(0)
@@ -352,6 +383,8 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
if (host()->delegate() && host()->delegate()->GetInputEventRouter())
host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this);
+ m_cursorManager.reset(new content::CursorManager(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());
@@ -359,6 +392,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
config.enable_longpress_drag_selection = false;
m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config));
+ host()->render_frame_metadata_provider()->AddObserver(this);
host()->render_frame_metadata_provider()->ReportAllFrameSubmissionsForTesting(true);
host()->SetView(this);
@@ -377,6 +411,9 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
m_touchSelectionController.reset();
m_touchSelectionControllerClient.reset();
+
+ host()->render_frame_metadata_provider()->RemoveObserver(this);
+ host()->ViewDestroyed();
}
void RenderWidgetHostViewQt::setDelegate(RenderWidgetHostViewQtDelegate* delegate)
@@ -400,6 +437,11 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC
m_adapterClient = nullptr; });
}
+void RenderWidgetHostViewQt::setGuest(content::RenderWidgetHostImpl *rwh)
+{
+ rwh->AddInputEventObserver(m_guestInputEventObserver.get());
+}
+
void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView)
{
}
@@ -415,6 +457,9 @@ void RenderWidgetHostViewQt::InitAsFullscreen(content::RenderWidgetHostView*)
void RenderWidgetHostViewQt::SetSize(const gfx::Size &sizeInDips)
{
+ if (!m_delegate)
+ return;
+
m_delegate->resize(sizeInDips.width(), sizeInDips.height());
}
@@ -472,6 +517,11 @@ bool RenderWidgetHostViewQt::IsMouseLocked()
return m_isMouseLocked;
}
+viz::FrameSinkId RenderWidgetHostViewQt::GetRootFrameSinkId()
+{
+ return m_uiCompositor->frame_sink_id();
+}
+
bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy()
{
return m_delegatedFrameHost->CanCopyFromCompositingSurface();
@@ -525,8 +575,6 @@ void RenderWidgetHostViewQt::UpdateBackgroundColor()
content::RenderViewHost *rvh = content::RenderViewHost::From(host());
if (color == SK_ColorTRANSPARENT)
host()->owner_delegate()->SetBackgroundOpaque(false);
- else
- host()->Send(new RenderViewObserverQt_SetBackgroundColor(rvh->GetRoutingID(), color));
}
// Return value indicates whether the mouse is locked successfully or not.
@@ -557,6 +605,74 @@ void RenderWidgetHostViewQt::UnlockMouse()
host()->LostMouseLock();
}
+bool RenderWidgetHostViewQt::updateCursorFromResource(ui::mojom::CursorType type)
+{
+ int resourceId;
+ // GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels.
+ qreal hotspotDpr = m_screenInfo.device_scale_factor <= 1.0f ? 1.0f : 2.0f;
+ qreal hotX;
+ qreal hotY;
+
+#if defined(USE_AURA)
+ gfx::Point hotspot;
+ if (!ui::GetCursorDataFor(ui::CursorSize::kNormal, type, hotspotDpr, &resourceId, &hotspot))
+ return false;
+ hotX = hotspot.x();
+ hotY = hotspot.y();
+#elif defined(Q_OS_MACOS)
+ // See chromium/content/common/cursors/webcursor_mac.mm
+ switch (type) {
+ case ui::mojom::CursorType::kVerticalText:
+ // TODO: [NSCursor IBeamCursorForVerticalLayout]
+ return false;
+ case ui::mojom::CursorType::kCell:
+ resourceId = IDR_CELL_CURSOR;
+ hotX = 7;
+ hotY = 7;
+ break;
+ case ui::mojom::CursorType::kContextMenu:
+ // TODO: [NSCursor contextualMenuCursor]
+ return false;
+ case ui::mojom::CursorType::kZoomIn:
+ resourceId = IDR_ZOOMIN_CURSOR;
+ hotX = 7;
+ hotY = 7;
+ break;
+ case ui::mojom::CursorType::kZoomOut:
+ resourceId = IDR_ZOOMOUT_CURSOR;
+ hotX = 7;
+ hotY = 7;
+ break;
+ default:
+ Q_UNREACHABLE();
+ return false;
+ }
+#else
+ Q_UNREACHABLE();
+ return false;
+#endif
+
+ const gfx::ImageSkia *imageSkia = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resourceId);
+ if (!imageSkia)
+ return false;
+
+ QImage imageQt = toQImage(imageSkia->GetRepresentation(m_screenInfo.device_scale_factor));
+
+ // Convert hotspot coordinates into device-independent pixels.
+ hotX /= hotspotDpr;
+ hotY /= hotspotDpr;
+
+#if defined(Q_OS_LINUX)
+ // QTBUG-68571: On Linux (xcb, wayland, eglfs), hotspot coordinates must be in physical pixels.
+ qreal imageDpr = imageQt.devicePixelRatio();
+ hotX *= imageDpr;
+ hotY *= imageDpr;
+#endif
+
+ m_delegate->updateCursor(QCursor(QPixmap::fromImage(std::move(imageQt)), qRound(hotX), qRound(hotY)));
+ return true;
+}
+
void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor)
{
DisplayCursor(webCursor);
@@ -566,9 +682,6 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
{
const ui::Cursor &cursorInfo = webCursor.cursor();
Qt::CursorShape shape = Qt::ArrowCursor;
-#if defined(USE_AURA)
- ui::mojom::CursorType auraType = ui::mojom::CursorType::kNull;
-#endif
switch (cursorInfo.type()) {
case ui::mojom::CursorType::kNull:
case ui::mojom::CursorType::kPointer:
@@ -644,31 +757,14 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
case ui::mojom::CursorType::kAlias:
shape = Qt::DragLinkCursor;
break;
-#if defined(USE_AURA)
- case ui::mojom::CursorType::kVerticalText:
- auraType = ui::mojom::CursorType::kVerticalText;
- break;
- case ui::mojom::CursorType::kCell:
- auraType = ui::mojom::CursorType::kCell;
- break;
- case ui::mojom::CursorType::kContextMenu:
- auraType = ui::mojom::CursorType::kContextMenu;
- break;
- case ui::mojom::CursorType::kZoomIn:
- auraType = ui::mojom::CursorType::kZoomIn;
- break;
- case ui::mojom::CursorType::kZoomOut:
- auraType = ui::mojom::CursorType::kZoomOut;
- break;
-#else
case ui::mojom::CursorType::kVerticalText:
case ui::mojom::CursorType::kCell:
case ui::mojom::CursorType::kContextMenu:
case ui::mojom::CursorType::kZoomIn:
case ui::mojom::CursorType::kZoomOut:
- // FIXME: Support on OS X
+ if (updateCursorFromResource(cursorInfo.type()))
+ return;
break;
-#endif
case ui::mojom::CursorType::kNoDrop:
case ui::mojom::CursorType::kNotAllowed:
shape = Qt::ForbiddenCursor;
@@ -690,36 +786,14 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
}
break;
}
-#if defined(USE_AURA)
- if (auraType != ui::mojom::CursorType::kNull) {
- int resourceId;
- gfx::Point hotspot;
- // GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels.
- 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(m_screenInfo.device_scale_factor));
-
- // Convert hotspot coordinates into device-independent pixels.
- qreal hotX = hotspot.x() / hotspotDpr;
- qreal hotY = hotspot.y() / hotspotDpr;
-
-#if defined(Q_OS_LINUX)
- // QTBUG-68571: On Linux (xcb, wayland, eglfs), hotspot coordinates must be in physical pixels.
- qreal imageDpr = imageQt.devicePixelRatio();
- hotX *= imageDpr;
- hotY *= imageDpr;
-#endif
-
- m_delegate->updateCursor(QCursor(QPixmap::fromImage(std::move(imageQt)), qRound(hotX), qRound(hotY)));
- return;
- }
- }
- }
-#endif
m_delegate->updateCursor(QCursor(shape));
}
+content::CursorManager *RenderWidgetHostViewQt::GetCursorManager()
+{
+ return m_cursorManager.get();
+}
+
void RenderWidgetHostViewQt::SetIsLoading(bool)
{
// We use WebContentsDelegateQt::LoadingStateChanged to notify about loading state.
@@ -741,6 +815,18 @@ void RenderWidgetHostViewQt::RenderProcessGone()
Destroy();
}
+bool RenderWidgetHostViewQt::TransformPointToCoordSpaceForView(const gfx::PointF &point,
+ content::RenderWidgetHostViewBase *target_view,
+ gfx::PointF *transformed_point)
+{
+ if (target_view == this) {
+ *transformed_point = point;
+ return true;
+ }
+
+ return target_view->TransformPointToLocalCoordSpace(point, GetCurrentSurfaceId(), transformed_point);
+}
+
void RenderWidgetHostViewQt::Destroy()
{
delete this;
@@ -753,11 +839,11 @@ void RenderWidgetHostViewQt::SetTooltipText(const base::string16 &tooltip_text)
void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_text)
{
- if (m_adapterClient)
+ if (host()->delegate() && m_adapterClient)
m_adapterClient->setToolTip(toQt(tooltip_text));
}
-void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo *results)
+void RenderWidgetHostViewQt::GetScreenInfo(blink::ScreenInfo *results)
{
*results = m_screenInfo;
}
@@ -773,10 +859,10 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
Q_UNUSED(updated_view);
Q_UNUSED(did_update_state);
- const content::TextInputState *state = text_input_manager_->GetTextInputState();
+ const ui::mojom::TextInputState *state = text_input_manager_->GetTextInputState();
if (!state) {
- m_delegate->inputMethodStateChanged(false /*editorVisible*/, false /*passwordInput*/);
- m_delegate->setInputMethodHints(Qt::ImhNone);
+ // Do not reset input method state here because an editable node might be still focused and
+ // this would hide the virtual keyboard if a child of the focused node is removed.
return;
}
@@ -788,14 +874,14 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
#endif
m_surroundingText = toQt(state->value);
// Remove IME composition text from the surrounding text
- if (state->composition_start != -1 && state->composition_end != -1)
- m_surroundingText.remove(state->composition_start, state->composition_end - state->composition_start);
+ if (state->composition.has_value())
+ m_surroundingText.remove(state->composition->start(), state->composition->end() - state->composition->start());
// In case of text selection, the update is expected in RenderWidgetHostViewQt::selectionChanged().
if (GetSelectedText().empty()) {
// At this point it is unknown whether the text input state has been updated due to a text selection.
// Keep the cursor position updated for cursor movements too.
- m_cursorPosition = state->selection_start;
+ m_cursorPosition = state->selection.start();
m_delegate->inputMethodStateChanged(type != ui::TEXT_INPUT_TYPE_NONE, type == ui::TEXT_INPUT_TYPE_PASSWORD);
}
@@ -805,7 +891,7 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
}
// Ignore selection change triggered by ime composition unless it clears an actual text selection
- if (state->composition_start != -1 && m_emptyPreviousSelection) {
+ if (state->composition.has_value() && m_emptyPreviousSelection) {
m_imState = 0;
return;
}
@@ -877,7 +963,7 @@ void RenderWidgetHostViewQt::selectionChanged()
// RenderWidgetHostViewQt::OnUpdateTextInputStateCalled() does not update the cursor position
// if the selection is cleared because TextInputState changes before the TextSelection change.
Q_ASSERT(text_input_manager_->GetTextInputState());
- m_cursorPosition = text_input_manager_->GetTextInputState()->selection_start;
+ m_cursorPosition = text_input_manager_->GetTextInputState()->selection.start();
m_delegate->inputMethodStateChanged(true /*editorVisible*/, type == ui::TEXT_INPUT_TYPE_PASSWORD);
m_anchorPositionWithinSelection = m_cursorPosition;
@@ -936,16 +1022,16 @@ void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture)
if (m_touchSelectionController && m_touchSelectionControllerClient) {
switch (event.GetType()) {
- case blink::WebInputEvent::kGestureLongPress:
+ case blink::WebInputEvent::Type::kGestureLongPress:
m_touchSelectionController->HandleLongPressEvent(event.TimeStamp(), event.PositionInWidget());
break;
- case blink::WebInputEvent::kGestureTap:
+ case blink::WebInputEvent::Type::kGestureTap:
m_touchSelectionController->HandleTapEvent(event.PositionInWidget(), event.data.tap.tap_count);
break;
- case blink::WebInputEvent::kGestureScrollBegin:
+ case blink::WebInputEvent::Type::kGestureScrollBegin:
m_touchSelectionControllerClient->onScrollBegin();
break;
- case blink::WebInputEvent::kGestureScrollEnd:
+ case blink::WebInputEvent::Type::kGestureScrollEnd:
m_touchSelectionControllerClient->onScrollEnd();
break;
default:
@@ -953,7 +1039,8 @@ void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture)
}
}
- host()->ForwardGestureEvent(event);
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteGestureEvent(this, &event, ui::LatencyInfo());
}
void RenderWidgetHostViewQt::DidStopFlinging()
@@ -971,7 +1058,7 @@ viz::ScopedSurfaceIdAllocator RenderWidgetHostViewQt::DidUpdateVisualProperties(
void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata)
{
- synchronizeVisualProperties(metadata.local_surface_id_allocation);
+ synchronizeVisualProperties(metadata.local_surface_id);
}
void RenderWidgetHostViewQt::OnDidFirstVisuallyNonEmptyPaint()
@@ -1011,18 +1098,18 @@ QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
void RenderWidgetHostViewQt::notifyShown()
{
// Handle possible frame eviction:
- if (!m_dfhLocalSurfaceIdAllocator.HasValidLocalSurfaceIdAllocation())
+ if (!m_dfhLocalSurfaceIdAllocator.HasValidLocalSurfaceId())
m_dfhLocalSurfaceIdAllocator.GenerateId();
if (m_visible)
return;
m_visible = true;
- host()->WasShown(base::nullopt);
+ host()->WasShown(nullptr);
m_delegatedFrameHost->AttachToCompositor(m_uiCompositor.get());
- m_delegatedFrameHost->WasShown(GetLocalSurfaceIdAllocation().local_surface_id(),
+ m_delegatedFrameHost->WasShown(GetLocalSurfaceId(),
m_viewRectInDips.size(),
- base::nullopt);
+ nullptr);
}
void RenderWidgetHostViewQt::notifyHidden()
@@ -1047,7 +1134,7 @@ void RenderWidgetHostViewQt::visualPropertiesChanged()
m_windowRectInDips = toGfx(m_delegate->windowGeometry());
QWindow *window = m_delegate->window();
- content::ScreenInfo oldScreenInfo = m_screenInfo;
+ blink::ScreenInfo oldScreenInfo = m_screenInfo;
m_screenInfo = screenInfoFromQScreen(window ? window->screen() : nullptr);
if (m_viewRectInDips != oldViewRect || m_windowRectInDips != oldWindowRect)
@@ -1162,8 +1249,12 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
if (m_mouseButtonPressed > 0)
return false;
#endif
- case QEvent::HoverLeave:
- host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(event));
+ case QEvent::HoverLeave: {
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter()) {
+ auto webEvent = WebEventFactory::toWebMouseEvent(event);
+ host()->delegate()->GetInputEventRouter()->RouteMouseEvent(this, &webEvent, ui::LatencyInfo());
+ }
+ }
break;
default:
return false;
@@ -1231,10 +1322,12 @@ void RenderWidgetHostViewQt::closePopup()
host()->LostFocus();
}
-void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) {
+void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, blink::mojom::InputEventResultState ack_result)
+{
Q_UNUSED(touch);
- const bool eventConsumed = ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED;
- m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, /*fixme: ?? */false);
+ const bool eventConsumed = ack_result == blink::mojom::InputEventResultState::kConsumed;
+ const bool isSetNonBlocking = content::InputEventResultStateIsSetNonBlocking(ack_result);
+ m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, isSetNonBlocking);
}
void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent)
@@ -1242,30 +1335,35 @@ void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEve
auto result = m_gestureProvider.OnTouchEvent(motionEvent);
if (!result.succeeded)
return;
-
blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent,
result.moved_beyond_slop_region,
false /*hovering, FIXME ?*/);
- host()->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteTouchEvent(this, &touchEvent, CreateLatencyInfo(touchEvent));
}
-QList<QTouchEvent::TouchPoint> RenderWidgetHostViewQt::mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints)
+QList<RenderWidgetHostViewQt::TouchPoint> RenderWidgetHostViewQt::mapTouchPoints(const QList<QTouchEvent::TouchPoint> &input)
{
- QList<QTouchEvent::TouchPoint> outputPoints = inputPoints;
- for (int i = 0; i < outputPoints.size(); ++i) {
- QTouchEvent::TouchPoint &point = outputPoints[i];
+ QList<TouchPoint> output;
+ for (int i = 0; i < input.size(); ++i) {
+ const QTouchEvent::TouchPoint &point = input[i];
int qtId = point.id();
QMap<int, int>::const_iterator it = m_touchIdMapping.find(qtId);
if (it == m_touchIdMapping.end())
it = m_touchIdMapping.insert(qtId, firstAvailableId(m_touchIdMapping));
- point.setId(it.value());
- if (point.state() == Qt::TouchPointReleased)
- m_touchIdMapping.remove(qtId);
+ output.append(qMakePair(it.value(), point));
}
- return outputPoints;
+ Q_ASSERT(output.size() == std::accumulate(output.cbegin(), output.cend(), QSet<int>(),
+ [] (QSet<int> s, const TouchPoint &p) { s.insert(p.second.id()); return s; }).size());
+
+ for (auto &&point : qAsConst(input))
+ if (point.state() == Qt::TouchPointReleased)
+ m_touchIdMapping.remove(point.id());
+
+ return output;
}
bool RenderWidgetHostViewQt::IsPopup() const
@@ -1280,12 +1378,6 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event)
if (event->type() == QEvent::MouseButtonRelease)
m_mouseButtonPressed--;
- // Don't forward mouse events synthesized by the system, which are caused by genuine touch
- // events. Chromium would then process for e.g. a mouse click handler twice, once due to the
- // system synthesized mouse event, and another time due to a touch-to-gesture-to-mouse
- // transformation done by Chromium.
- if (event->source() == Qt::MouseEventSynthesizedBySystem)
- return;
handlePointerEvent<QMouseEvent>(event);
}
@@ -1323,27 +1415,27 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
return;
content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev);
- if (webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && !m_editCommand.empty()) {
+ if (webEvent.GetType() == blink::WebInputEvent::Type::kRawKeyDown && !m_editCommand.empty()) {
ui::LatencyInfo latency;
latency.set_source_event_type(ui::SourceEventType::KEY_PRESS);
- content::EditCommands commands;
- commands.emplace_back(m_editCommand, "");
+ std::vector<blink::mojom::EditCommandPtr> commands;
+ commands.emplace_back(blink::mojom::EditCommand::New(m_editCommand, ""));
m_editCommand.clear();
- host()->ForwardKeyboardEventWithCommands(webEvent, latency, &commands, nullptr);
+ GetFocusedWidget()->ForwardKeyboardEventWithCommands(webEvent, latency, std::move(commands), nullptr);
return;
}
- bool keyDownTextInsertion = webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && webEvent.text[0];
+ bool keyDownTextInsertion = webEvent.GetType() == blink::WebInputEvent::Type::kRawKeyDown && webEvent.text[0];
webEvent.skip_in_browser = keyDownTextInsertion;
- host()->ForwardKeyboardEvent(webEvent);
+ GetFocusedWidget()->ForwardKeyboardEvent(webEvent);
if (keyDownTextInsertion) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
// The RawKeyDown is skipped on the way back (see above).
// The same os_event will be set on both NativeWebKeyboardEvents.
webEvent.skip_in_browser = false;
- webEvent.SetType(blink::WebInputEvent::kChar);
- host()->ForwardKeyboardEvent(webEvent);
+ webEvent.SetType(blink::WebInputEvent::Type::kChar);
+ GetFocusedWidget()->ForwardKeyboardEvent(webEvent);
}
}
@@ -1427,9 +1519,8 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
}
if (hasSelection) {
- content::mojom::FrameInputHandler *frameInputHandler = getFrameInputHandler();
- if (frameInputHandler)
- frameInputHandler->SetEditableSelectionOffsets(selectionRange.start(), selectionRange.end());
+ if (auto *frameWidgetInputHandler = getFrameWidgetInputHandler())
+ frameWidgetInputHandler->SetEditableSelectionOffsets(selectionRange.start(), selectionRange.end());
}
int replacementLength = ev->replacementLength();
@@ -1512,8 +1603,9 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *ev)
Q_ASSERT(m_pendingWheelEvents.isEmpty());
blink::WebMouseWheelEvent webEvent = WebEventFactory::toWebWheelEvent(ev);
m_wheelAckPending = (webEvent.phase != blink::WebMouseWheelEvent::kPhaseEnded);
- m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, false);
- host()->ForwardWheelEvent(webEvent);
+ m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, true);
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(this, &webEvent, ui::LatencyInfo());
return;
}
if (!m_pendingWheelEvents.isEmpty()) {
@@ -1524,7 +1616,7 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *ev)
m_pendingWheelEvents.append(WebEventFactory::toWebWheelEvent(ev));
}
-void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &event, content::InputEventAckState /*ack_result*/)
+void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &event, blink::mojom::InputEventResultState /*ack_result*/)
{
if (event.phase == blink::WebMouseWheelEvent::kPhaseEnded)
return;
@@ -1533,19 +1625,20 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even
while (!m_pendingWheelEvents.isEmpty() && !m_wheelAckPending) {
blink::WebMouseWheelEvent webEvent = m_pendingWheelEvents.takeFirst();
m_wheelAckPending = (webEvent.phase != blink::WebMouseWheelEvent::kPhaseEnded);
- m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, false);
- host()->ForwardWheelEvent(webEvent);
+ m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, true);
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(this, &webEvent, ui::LatencyInfo());
}
}
-void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event, content::InputEventAckState ack_result)
+void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event, blink::mojom::InputEventResultState ack_result)
{
// Forward unhandled scroll events back as wheel events
- if (event.GetType() != blink::WebInputEvent::kGestureScrollUpdate)
+ if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollUpdate)
return;
switch (ack_result) {
- case content::INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
- case content::INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
+ case blink::mojom::InputEventResultState::kNotConsumed:
+ case blink::mojom::InputEventResultState::kNoConsumerExists:
WebEventFactory::sendUnhandledWheelEvent(event, delegate());
break;
default:
@@ -1558,19 +1651,17 @@ content::MouseWheelPhaseHandler *RenderWidgetHostViewQt::GetMouseWheelPhaseHandl
return &m_mouseWheelPhaseHandler;
}
-void RenderWidgetHostViewQt::clearPreviousTouchMotionState()
-{
- m_previousTouchPoints.clear();
- m_touchMotionStarted = false;
-}
-
#ifndef QT_NO_GESTURES
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));
+ if (type == Qt::ZoomNativeGesture || type == Qt::SmartZoomNativeGesture
+ || type == Qt::BeginNativeGesture || type == Qt::EndNativeGesture) {
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter()) {
+ auto webEvent = WebEventFactory::toWebGestureEvent(ev);
+ host()->delegate()->GetInputEventRouter()->RouteGestureEvent(this, &webEvent, ui::LatencyInfo());
+ }
}
}
#endif
@@ -1598,15 +1689,34 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
m_eventsToNowDelta = base::TimeTicks::Now() - eventTimestamp;
eventTimestamp += m_eventsToNowDelta;
- QList<QTouchEvent::TouchPoint> touchPoints = mapTouchPointIds(ev->touchPoints());
- // Make sure that ACTION_POINTER_DOWN is delivered before ACTION_MOVE,
- // and ACTION_MOVE before ACTION_POINTER_UP.
- std::sort(touchPoints.begin(), touchPoints.end(), compareTouchPoints);
+ auto touchPoints = mapTouchPoints(ev->touchPoints());
+ // Make sure that POINTER_DOWN action is delivered before MOVE, and MOVE before POINTER_UP
+ std::sort(touchPoints.begin(), touchPoints.end(), [] (const TouchPoint &l, const TouchPoint &r) {
+ return l.second.state() < r.second.state();
+ });
+
+ auto sc = qScopeGuard([&] () {
+ switch (ev->type()) {
+ case QEvent::TouchCancel:
+ for (auto &&it : qAsConst(touchPoints))
+ m_touchIdMapping.remove(it.second.id());
+ Q_FALLTHROUGH();
+
+ case QEvent::TouchEnd:
+ m_previousTouchPoints.clear();
+ m_touchMotionStarted = false;
+ break;
+
+ default:
+ m_previousTouchPoints = touchPoints;
+ break;
+ }
+ });
+ ui::MotionEvent::Action action;
// Check first if the touch event should be routed to the selectionController
if (!touchPoints.isEmpty()) {
- ui::MotionEvent::Action action;
- switch (touchPoints[0].state()) {
+ switch (touchPoints[0].second.state()) {
case Qt::TouchPointPressed:
action = ui::MotionEvent::Action::DOWN;
break;
@@ -1620,31 +1730,24 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
action = ui::MotionEvent::Action::NONE;
break;
}
-
- MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), 0);
- if (m_touchSelectionController->WillHandleTouchEvent(motionEvent)) {
- m_previousTouchPoints = touchPoints;
- ev->accept();
- return;
- }
} else {
// An empty touchPoints always corresponds to a TouchCancel event.
// We can't forward touch cancellations without a previously processed touch event,
// as Chromium expects the previous touchPoints for Action::CANCEL.
// If both are empty that means the TouchCancel was sent without an ongoing touch,
// so there's nothing to cancel anyway.
+ Q_ASSERT(ev->type() == QEvent::TouchCancel);
touchPoints = m_previousTouchPoints;
if (touchPoints.isEmpty())
return;
- MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::Action::CANCEL, ev->modifiers());
- if (m_touchSelectionController->WillHandleTouchEvent(cancelEvent)) {
- m_previousTouchPoints.clear();
- ev->accept();
- return;
- }
+ action = ui::MotionEvent::Action::CANCEL;
}
+ MotionEventQt me(touchPoints, eventTimestamp, action, ev->modifiers());
+ if (m_touchSelectionController->WillHandleTouchEvent(me))
+ return;
+
switch (ev->type()) {
case QEvent::TouchBegin:
m_sendMotionActionDown = true;
@@ -1662,11 +1765,9 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
processMotionEvent(cancelEvent);
}
- clearPreviousTouchMotionState();
return;
}
case QEvent::TouchEnd:
- clearPreviousTouchMotionState();
m_touchSelectionControllerClient->onTouchUp();
break;
default:
@@ -1686,34 +1787,50 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
#endif
}
- for (int i = 0; i < touchPoints.size(); ++i) {
- ui::MotionEvent::Action action;
- switch (touchPoints[i].state()) {
- case Qt::TouchPointPressed:
- if (m_sendMotionActionDown) {
- action = ui::MotionEvent::Action::DOWN;
- m_sendMotionActionDown = false;
- } else {
- action = ui::MotionEvent::Action::POINTER_DOWN;
+ // MEMO for the basis of this logic look into:
+ // * blink_event_util.cc:ToWebTouchPointState: which is used later to forward touch event
+ // composed from motion event after gesture recognition
+ // * gesture_detector.cc:GestureDetector::OnTouchEvent: contains logic for every motion
+ // event action and corresponding gesture recognition routines
+ // * input_router_imp.cc:InputRouterImp::SetMovementXYForTouchPoints: expectation about
+ // touch event content like number of points for different states
+
+ int lastPressIndex = -1;
+ while ((lastPressIndex + 1) < touchPoints.size() && touchPoints[lastPressIndex + 1].second.state() == Qt::TouchPointPressed)
+ ++lastPressIndex;
+
+ switch (ev->type()) {
+ case QEvent::TouchBegin:
+ processMotionEvent(MotionEventQt(touchPoints.mid(lastPressIndex),
+ eventTimestamp, ui::MotionEvent::Action::DOWN, ev->modifiers()));
+ --lastPressIndex;
+ Q_FALLTHROUGH();
+
+ case QEvent::TouchUpdate:
+ for (; lastPressIndex >= 0; --lastPressIndex) {
+ Q_ASSERT(touchPoints[lastPressIndex].second.state() == Qt::TouchPointPressed);
+ MotionEventQt me(touchPoints.mid(lastPressIndex), eventTimestamp, ui::MotionEvent::Action::POINTER_DOWN, ev->modifiers(), 0);
+ processMotionEvent(me);
+ }
+
+ if (ev->touchPointStates() & Qt::TouchPointMoved)
+ processMotionEvent(MotionEventQt(touchPoints, eventTimestamp, ui::MotionEvent::Action::MOVE, ev->modifiers()));
+
+ Q_FALLTHROUGH();
+
+ case QEvent::TouchEnd:
+ while (!touchPoints.isEmpty() && touchPoints.back().second.state() == Qt::TouchPointReleased) {
+ auto action = touchPoints.size() > 1 ? ui::MotionEvent::Action::POINTER_UP : ui::MotionEvent::Action::UP;
+ int index = action == ui::MotionEvent::Action::POINTER_UP ? touchPoints.size() - 1 : -1;
+ processMotionEvent(MotionEventQt(touchPoints, eventTimestamp, action, ev->modifiers(), index));
+ touchPoints.pop_back();
}
break;
- case Qt::TouchPointMoved:
- action = ui::MotionEvent::Action::MOVE;
- break;
- case Qt::TouchPointReleased:
- action = touchPoints.size() > 1 ? ui::MotionEvent::Action::POINTER_UP :
- ui::MotionEvent::Action::UP;
- break;
- default:
- // Ignore Qt::TouchPointStationary
- continue;
- }
- MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), i);
- processMotionEvent(motionEvent);
+ default:
+ Q_ASSERT_X(false, __FUNCTION__, "Other event types are expected to be already handled.");
+ break;
}
-
- m_previousTouchPoints = touchPoints;
}
#if QT_CONFIG(tabletevent)
@@ -1729,14 +1846,14 @@ 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);
- if ((webEvent.GetType() == blink::WebInputEvent::kMouseDown || webEvent.GetType() == blink::WebInputEvent::kMouseUp)
+ if ((webEvent.GetType() == blink::WebInputEvent::Type::kMouseDown || webEvent.GetType() == blink::WebInputEvent::Type::kMouseUp)
&& webEvent.button == blink::WebMouseEvent::Button::kNoButton) {
// Blink can only handle the 5 main mouse-buttons and may assert when processing mouse-down for no button.
LOG(INFO) << "Unhandled mouse button";
return;
}
- if (webEvent.GetType() == blink::WebInputEvent::kMouseDown) {
+ if (webEvent.GetType() == blink::WebInputEvent::Type::kMouseDown) {
if (event->button() != m_clickHelper.lastPressButton
|| (event->timestamp() - m_clickHelper.lastPressTimestamp > static_cast<ulong>(qGuiApp->styleHints()->mouseDoubleClickInterval()))
|| (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance()
@@ -1749,7 +1866,7 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event)
m_clickHelper.lastPressPosition = QPointF(event->pos()).toPoint();
}
- if (webEvent.GetType() == blink::WebInputEvent::kMouseUp)
+ if (webEvent.GetType() == blink::WebInputEvent::Type::kMouseUp)
webEvent.click_count = m_clickHelper.clickCounter;
webEvent.movement_x = event->globalX() - m_previousMousePosition.x();
@@ -1760,7 +1877,7 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event)
else
m_previousMousePosition = event->globalPos();
- if (m_imeInProgress && webEvent.GetType() == blink::WebInputEvent::kMouseDown) {
+ if (m_imeInProgress && webEvent.GetType() == blink::WebInputEvent::Type::kMouseDown) {
m_imeInProgress = false;
// Tell input method to commit the pre-edit string entered so far, and finish the
// composition operation.
@@ -1773,12 +1890,16 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event)
#endif
}
- host()->ForwardMouseEvent(webEvent);
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteMouseEvent(this, &webEvent, ui::LatencyInfo());
}
void RenderWidgetHostViewQt::handleHoverEvent(QHoverEvent *ev)
{
- host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(ev));
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter()) {
+ auto webEvent = WebEventFactory::toWebMouseEvent(ev);
+ host()->delegate()->GetInputEventRouter()->RouteMouseEvent(this, &webEvent, ui::LatencyInfo());
+ }
}
void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
@@ -1802,26 +1923,13 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
}
}
-content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost()
-{
- content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(host());
- if (!viewHost)
- return nullptr;
-
- content::FrameTreeNode *focusedFrame = viewHost->GetDelegate()->GetFrameTree()->GetFocusedFrame();
- if (!focusedFrame)
- return nullptr;
-
- return focusedFrame->current_frame_host();
-}
-
-content::mojom::FrameInputHandler *RenderWidgetHostViewQt::getFrameInputHandler()
+blink::mojom::FrameWidgetInputHandler *RenderWidgetHostViewQt::getFrameWidgetInputHandler()
{
- content::RenderFrameHostImpl *frameHost = static_cast<content::RenderFrameHostImpl *>(getFocusedFrameHost());
- if (!frameHost)
+ auto *focused_widget = GetFocusedWidget();
+ if (!focused_widget)
return nullptr;
- return frameHost->GetFrameInputHandler();
+ return focused_widget->GetFrameWidgetInputHandler();
}
ui::TextInputType RenderWidgetHostViewQt::getTextInputType() const
@@ -1842,9 +1950,23 @@ const viz::FrameSinkId &RenderWidgetHostViewQt::GetFrameSinkId() const
return m_delegatedFrameHost->frame_sink_id();
}
-const viz::LocalSurfaceIdAllocation &RenderWidgetHostViewQt::GetLocalSurfaceIdAllocation() const
+const viz::LocalSurfaceId &RenderWidgetHostViewQt::GetLocalSurfaceId() const
{
- return m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation();
+ return m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId();
+}
+
+void RenderWidgetHostViewQt::FocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen)
+{
+ Q_UNUSED(node_bounds_in_screen);
+ if (!is_editable_node) {
+ m_delegate->inputMethodStateChanged(false /*editorVisible*/, false /*passwordInput*/);
+ m_delegate->setInputMethodHints(Qt::ImhNone);
+ }
+}
+
+base::flat_map<std::string, std::string> RenderWidgetHostViewQt::GetKeyboardLayoutMap()
+{
+ return ui::GenerateDomKeyboardLayoutMap();
}
void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostView *view)
@@ -1874,8 +1996,6 @@ 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;
@@ -1893,7 +2013,7 @@ void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation()
m_adapterClient->updateContentsSize(toQt(m_lastContentsSize));
}
-void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceIdAllocation> &childSurfaceId)
+void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceId> &childSurfaceId)
{
if (childSurfaceId)
m_dfhLocalSurfaceIdAllocator.UpdateFromChild(*childSurfaceId);
@@ -1907,9 +2027,9 @@ void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<vi
m_uiCompositor->SetScaleAndSize(
m_screenInfo.device_scale_factor,
viewSizeInPixels,
- m_uiCompositorLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation());
+ m_uiCompositorLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId());
m_delegatedFrameHost->EmbedSurface(
- m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
+ m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId(),
viewSizeInDips,
cc::DeadlinePolicy::UseDefaultDeadline());
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 18ea8b9c2..46c2547da 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -68,9 +68,6 @@ QT_END_NAMESPACE
namespace content {
class RenderFrameHost;
class RenderWidgetHostImpl;
-namespace mojom {
-class FrameInputHandler;
-}
}
namespace ui {
@@ -79,6 +76,7 @@ class TouchSelectionController;
namespace QtWebEngineCore {
+class GuestInputEventObserverQt;
class TouchHandleDrawableClient;
class TouchSelectionControllerClientQt;
class TouchSelectionMenuController;
@@ -105,6 +103,7 @@ class RenderWidgetHostViewQt
, public RenderWidgetHostViewQtDelegateClient
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
, public content::TextInputManager::Observer
+ , public content::RenderFrameMetadataProvider::Observer
, public DisplayConsumer
{
public:
@@ -121,6 +120,7 @@ public:
void setDelegate(RenderWidgetHostViewQtDelegate *delegate);
WebContentsAdapterClient *adapterClient() { return m_adapterClient; }
void setAdapterClient(WebContentsAdapterClient *adapterClient);
+ void setGuest(content::RenderWidgetHostImpl *);
void InitAsChild(gfx::NativeView) override;
void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&) override;
@@ -132,6 +132,7 @@ public:
void Focus() override;
bool HasFocus() override;
bool IsMouseLocked() override;
+ viz::FrameSinkId GetRootFrameSinkId() override;
bool IsSurfaceAvailableForCopy() override;
void CopyFromSurface(const gfx::Rect &src_rect,
const gfx::Size &output_size,
@@ -146,25 +147,36 @@ public:
void UnlockMouse() override;
void UpdateCursor(const content::WebCursor&) override;
void DisplayCursor(const content::WebCursor&) override;
+ content::CursorManager *GetCursorManager() override;
void SetIsLoading(bool) override;
void ImeCancelComposition() override;
void ImeCompositionRangeChanged(const gfx::Range&, const std::vector<gfx::Rect>&) override;
void RenderProcessGone() override;
+ bool TransformPointToCoordSpaceForView(const gfx::PointF &point,
+ content::RenderWidgetHostViewBase *target_view,
+ gfx::PointF *transformed_point) override;
void Destroy() override;
void SetTooltipText(const base::string16 &tooltip_text) override;
void DisplayTooltipText(const base::string16& tooltip_text) override;
- void WheelEventAck(const blink::WebMouseWheelEvent &event, content::InputEventAckState ack_result) override;
- void GestureEventAck(const blink::WebGestureEvent &event, content::InputEventAckState ack_result) override;
+ void WheelEventAck(const blink::WebMouseWheelEvent &event,
+ blink::mojom::InputEventResultState ack_result) override;
+ void GestureEventAck(const blink::WebGestureEvent &event,
+ blink::mojom::InputEventResultState ack_result) override;
content::MouseWheelPhaseHandler *GetMouseWheelPhaseHandler() override;
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(const cc::RenderFrameMetadata &metadata) override;
void OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata);
- void GetScreenInfo(content::ScreenInfo *results) override;
+ // Overridden from RenderWidgetHostViewBase:
+ void GetScreenInfo(blink::ScreenInfo *results) override;
gfx::Rect GetBoundsInRootWindow() override;
- void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) override;
+ void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch,
+ blink::mojom::InputEventResultState ack_result) override;
viz::SurfaceId GetCurrentSurfaceId() const override;
const viz::FrameSinkId &GetFrameSinkId() const override;
- const viz::LocalSurfaceIdAllocation &GetLocalSurfaceIdAllocation() const override;
+ const viz::LocalSurfaceId &GetLocalSurfaceId() const override;
+ void FocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen) override;
+ base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
+
void TakeFallbackContentFrom(content::RenderWidgetHostView *view) override;
void EnsureSurfaceSynchronizedForWebTest() override;
uint32_t GetCaptureSequenceNumber() const override;
@@ -207,11 +219,12 @@ public:
template<class T> void handlePointerEvent(T*);
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
void SetActive(bool active) override { QT_NOT_YET_IMPLEMENTED }
void SpeakSelection() override { QT_NOT_YET_IMPLEMENTED }
void ShowDefinitionForSelection() override { QT_NOT_YET_IMPLEMENTED }
-#endif // defined(OS_MACOSX)
+ void SetWindowFrameInScreen(const gfx::Rect&) override { QT_NOT_YET_IMPLEMENTED }
+#endif // defined(OS_MAC)
// Overridden from content::BrowserAccessibilityDelegate
content::BrowserAccessibilityManager* CreateBrowserAccessibilityManager(content::BrowserAccessibilityDelegate* delegate, bool for_root_frame) override;
@@ -221,6 +234,9 @@ public:
// Overridden from content::RenderFrameMetadataProvider::Observer
void OnRenderFrameMetadataChangedAfterActivation() override;
+ void OnRenderFrameMetadataChangedBeforeActivation(const cc::RenderFrameMetadata &) override {}
+ void OnRenderFrameSubmission() override {}
+ void OnLocalSurfaceIdChanged(const cc::RenderFrameMetadata &) override {}
// Overridden from DisplayConsumer
void scheduleUpdate() override;
@@ -230,40 +246,43 @@ public:
ui::TouchSelectionController *getTouchSelectionController() const { return m_touchSelectionController.get(); }
TouchSelectionControllerClientQt *getTouchSelectionControllerClient() const { return m_touchSelectionControllerClient.get(); }
- content::mojom::FrameInputHandler *getFrameInputHandler();
+ blink::mojom::FrameWidgetInputHandler *getFrameWidgetInputHandler();
ui::TextInputType getTextInputType() const;
private:
friend class DelegatedFrameHostClientQt;
void processMotionEvent(const ui::MotionEvent &motionEvent);
- void clearPreviousTouchMotionState();
- QList<QTouchEvent::TouchPoint> mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints);
+ typedef QPair<int, QTouchEvent::TouchPoint> TouchPoint;
+ QList<TouchPoint> mapTouchPoints(const QList<QTouchEvent::TouchPoint> &input);
bool IsPopup() const;
void selectionChanged();
- content::RenderFrameHost *getFocusedFrameHost();
- void synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceIdAllocation> &childSurfaceId);
+ void synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceId> &childSurfaceId);
void callUpdate();
+ bool updateCursorFromResource(ui::mojom::CursorType type);
+
// 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;
+ blink::ScreenInfo m_screenInfo;
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+ std::unique_ptr<content::CursorManager> m_cursorManager;
ui::FilteredGestureProvider m_gestureProvider;
base::TimeDelta m_eventsToNowDelta;
bool m_sendMotionActionDown;
bool m_touchMotionStarted;
QMap<int, int> m_touchIdMapping;
- QList<QTouchEvent::TouchPoint> m_previousTouchPoints;
+ QList<TouchPoint> m_previousTouchPoints;
std::unique_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
+ std::unique_ptr<GuestInputEventObserverQt> m_guestInputEventObserver;
bool m_visible;
bool m_deferredShow = false;
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 46f1802a6..5fda0eeb7 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -59,9 +59,7 @@
QT_BEGIN_NAMESPACE
class QEvent;
class QInputMethodEvent;
-class QSGLayer;
class QSGNode;
-class QSGRectangleNode;
class QSGTexture;
class QVariant;
class QWheelEvent;
@@ -101,9 +99,7 @@ public:
virtual bool isVisible() const = 0;
virtual QWindow* window() const = 0;
virtual QSGTexture *createTextureFromImage(const QImage &) = 0;
- virtual QSGLayer *createLayer() = 0;
virtual QSGImageNode *createImageNode() = 0;
- virtual QSGRectangleNode *createRectangleNode() = 0;
virtual void update() = 0;
virtual void updateCursor(const QCursor &) = 0;
virtual void resize(int width, int height) = 0;
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 9f1f5bcf3..d704e81b1 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -50,7 +50,6 @@
#include "components/cdm/renderer/external_clear_key_key_system_properties.h"
#include "components/cdm/renderer/widevine_key_system_properties.h"
#include "components/error_page/common/error.h"
-#include "components/error_page/common/error_page_params.h"
#include "components/error_page/common/localized_error.h"
#include "components/network_hints/renderer/web_prescient_networking_impl.h"
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -75,7 +74,6 @@
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
-#include "content/public/common/web_preferences.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "renderer/print_web_view_helper_delegate_qt.h"
@@ -83,8 +81,8 @@
#include "common/qt_messages.h"
#include "renderer/render_frame_observer_qt.h"
-#include "renderer/render_view_observer_qt.h"
-#include "renderer/render_thread_observer_qt.h"
+#include "renderer/web_engine_page_render_frame.h"
+#include "renderer/render_configuration.h"
#include "renderer/user_resource_controller.h"
#if QT_CONFIG(webengine_webchannel)
#include "renderer/web_channel_ipc_transport.h"
@@ -93,17 +91,17 @@
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "common/extensions/extensions_client_qt.h"
#include "extensions/extensions_renderer_client_qt.h"
+#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
#endif //ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
#include "plugins/loadable_plugin_placeholder_qt.h"
-#include "plugins/plugin_placeholder_qt.h"
#include "content/common/frame_messages.h"
#endif // ENABLE_PLUGINS
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/service_binding.h"
#include "components/grit/components_resources.h"
@@ -116,6 +114,12 @@
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#endif
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+#include "chrome/renderer/media/webrtc_logging_agent_impl.h"
+#endif
+
+#include "web_engine_library_info.h"
+
namespace QtWebEngineCore {
static const char kHttpErrorDomain[] = "http";
@@ -132,13 +136,15 @@ ContentRendererClientQt::~ContentRendererClientQt() {}
void ContentRendererClientQt::RenderThreadStarted()
{
+ base::i18n::SetICUDefaultLocale(WebEngineLibraryInfo::getApplicationLocale());
content::RenderThread *renderThread = content::RenderThread::Get();
- m_renderThreadObserver.reset(new RenderThreadObserverQt());
+ m_renderConfiguration.reset(new RenderConfiguration());
+ m_userResourceController.reset(new UserResourceController());
m_visitedLinkReader.reset(new visitedlink::VisitedLinkReader);
m_webCacheImpl.reset(new web_cache::WebCacheImpl());
- renderThread->AddObserver(m_renderThreadObserver.data());
- renderThread->AddObserver(UserResourceController::instance());
+ renderThread->AddObserver(m_renderConfiguration.data());
+ renderThread->AddObserver(m_userResourceController.data());
#if QT_CONFIG(webengine_spellchecker)
if (!m_spellCheck)
@@ -185,25 +191,29 @@ void ContentRendererClientQt::ExposeInterfacesToBrowser(mojo::BinderMap* binders
}, this),
base::SequencedTaskRunnerHandle::Get());
#endif
-}
-void ContentRendererClientQt::RenderViewCreated(content::RenderView *render_view)
-{
- // RenderViewObservers destroy themselves with their RenderView.
- new RenderViewObserverQt(render_view);
- UserResourceController::instance()->renderViewCreated(render_view);
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ binders->Add(base::BindRepeating(
+ [](ContentRendererClientQt *client,
+ mojo::PendingReceiver<chrome::mojom::WebRtcLoggingAgent> receiver) {
+ client->GetWebRtcLoggingAgent()->AddReceiver(std::move(receiver));
+ }, this),
+ base::SequencedTaskRunnerHandle::Get());
+#endif
}
void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_frame)
{
QtWebEngineCore::RenderFrameObserverQt *render_frame_observer =
new QtWebEngineCore::RenderFrameObserverQt(render_frame, m_webCacheImpl.data());
+ if (render_frame->IsMainFrame()) {
#if QT_CONFIG(webengine_webchannel)
- if (render_frame->IsMainFrame())
new WebChannelIPCTransport(render_frame);
#endif
+ new WebEnginePageRenderFrame(render_frame);
+ }
- UserResourceController::instance()->renderFrameCreated(render_frame);
+ m_userResourceController->renderFrameCreated(render_frame);
new QtWebEngineCore::ContentSettingsObserverQt(render_frame);
@@ -214,6 +224,11 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
new printing::PrintRenderFrameHelper(render_frame, base::WrapUnique(new PrintWebViewHelperDelegateQt()));
#endif // QT_CONFIG(webengine_printing_and_pdf)
#if BUILDFLAG(ENABLE_EXTENSIONS)
+ blink::AssociatedInterfaceRegistry *associated_interfaces = render_frame_observer->associatedInterfaces();
+ associated_interfaces->AddInterface(base::BindRepeating(
+ &extensions::MimeHandlerViewContainerManager::BindReceiver,
+ render_frame->GetRoutingID()));
+
auto registry = std::make_unique<service_manager::BinderRegistry>();
ExtensionsRendererClientQt::GetInstance()->RenderFrameCreated(render_frame, render_frame_observer->registry());
#endif
@@ -234,7 +249,7 @@ void ContentRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame *rend
RenderFrameObserverQt *render_frame_observer = RenderFrameObserverQt::Get(render_frame);
if (render_frame_observer && !render_frame_observer->isFrameDetached())
- UserResourceController::instance()->RunScriptsAtDocumentEnd(render_frame);
+ m_userResourceController->RunScriptsAtDocumentEnd(render_frame);
#if BUILDFLAG(ENABLE_EXTENSIONS)
ExtensionsRendererClientQt::GetInstance()->RunScriptsAtDocumentEnd(render_frame);
@@ -260,11 +275,6 @@ bool ContentRendererClientQt::HasErrorPage(int httpStatusCode)
return true;
}
-bool ContentRendererClientQt::ShouldSuppressErrorPage(content::RenderFrame *frame, const GURL &)
-{
- return !(frame->GetWebkitPreferences().enable_error_page);
-}
-
// To tap into the chromium localized strings. Ripped from the chrome layer (highly simplified).
void ContentRendererClientQt::PrepareErrorPage(content::RenderFrame *renderFrame,
const blink::WebURLError &web_error,
@@ -305,10 +315,10 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
// NetErrorHelper::GetErrorStringsForDnsProbe, but that one is harder to untangle.
error_page::LocalizedError::PageState errorPageState =
- error_page::LocalizedError::GetPageState(
- error.reason(), error.domain(), error.url(), isPost,
- false, error.stale_copy_in_cache(), false, RenderThreadObserverQt::is_incognito_process(), false,
- false, false, locale, std::unique_ptr<error_page::ErrorPageParams>());
+ error_page::LocalizedError::GetPageState(
+ error.reason(), error.domain(), error.url(), isPost, false,
+ error.stale_copy_in_cache(), false,
+ RenderConfiguration::is_incognito_process(), false, false, false, locale);
resourceId = IDR_NET_ERROR_HTML;
@@ -336,6 +346,30 @@ std::unique_ptr<blink::WebPrescientNetworking> ContentRendererClientQt::CreatePr
return std::make_unique<network_hints::WebPrescientNetworkingImpl>(render_frame);
}
+bool ContentRendererClientQt::IsPluginHandledExternally(content::RenderFrame *render_frame,
+ const blink::WebElement &plugin_element,
+ const GURL &original_url,
+ const std::string &original_mime_type)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS)
+ bool found = false;
+ content::WebPluginInfo plugin_info;
+ std::string mime_type;
+
+ render_frame->Send(new FrameHostMsg_GetPluginInfo(render_frame->GetRoutingID(), original_url,
+ render_frame->GetWebFrame()->Top()->GetSecurityOrigin(),
+ original_mime_type, &found, &plugin_info, &mime_type));
+
+ return extensions::MimeHandlerViewContainerManager::Get(
+ content::RenderFrame::FromWebFrame(
+ plugin_element.GetDocument().GetFrame()),
+ true /* create_if_does_not_exist */)
+ ->CreateFrameContainer(plugin_element, original_url, mime_type, plugin_info);
+#else
+ return false;
+#endif
+}
+
bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_frame,
const blink::WebPluginParams &params,
blink::WebPlugin **plugin)
@@ -346,7 +380,6 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
#endif //ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
- chrome::mojom::PluginInfoPtr plugin_info = chrome::mojom::PluginInfo::New();
content::WebPluginInfo info;
std::string mime_type;
bool found = false;
@@ -354,50 +387,29 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
render_frame->Send(new FrameHostMsg_GetPluginInfo(render_frame->GetRoutingID(), params.url,
render_frame->GetWebFrame()->Top()->GetSecurityOrigin(),
params.mime_type.Utf8(), &found, &info, &mime_type));
- if (!found) {
- *plugin = CreatePlugin(render_frame, params, *plugin_info);
- return true;
- }
+ if (!found)
+ *plugin = LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(render_frame, params)->plugin();
+ else
+ *plugin = render_frame->CreatePlugin(info, params, nullptr);
#endif // BUILDFLAG(ENABLE_PLUGINS)
- return content::ContentRendererClient::OverrideCreatePlugin(render_frame, params, plugin);
+ return true;
}
bool ContentRendererClientQt::IsOriginIsolatedPepperPlugin(const base::FilePath& plugin_path)
{
- return plugin_path.value() == FILE_PATH_LITERAL("internal-pdf-viewer/");
+ return plugin_path.value() == FILE_PATH_LITERAL("internal-pdf-viewer");
}
-#if BUILDFLAG(ENABLE_PLUGINS)
-// static
-blink::WebPlugin* ContentRendererClientQt::CreatePlugin(content::RenderFrame* render_frame,
- const blink::WebPluginParams& original_params,
- const chrome::mojom::PluginInfo& plugin_info)
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+chrome::WebRtcLoggingAgentImpl *ContentRendererClientQt::GetWebRtcLoggingAgent()
{
- // If the browser plugin is to be enabled, this should be handled by the
- // renderer, so the code won't reach here due to the early exit in OverrideCreatePlugin.
- return LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(render_frame, original_params)->plugin();
-}
-#endif //BUILDFLAG(ENABLE_PLUGINS)
-
-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
-}
+ if (!m_webrtcLoggingAgentImpl) {
+ m_webrtcLoggingAgentImpl = std::make_unique<chrome::WebRtcLoggingAgentImpl>();
+ }
-void ContentRendererClientQt::BindReceiverOnMainThread(mojo::GenericPendingReceiver receiver)
-{
- std::string interface_name = *receiver.interface_name();
- auto pipe = receiver.PassPipe();
- m_registry.TryBindInterface(interface_name, &pipe);
+ return m_webrtcLoggingAgentImpl.get();
}
+#endif // QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
void ContentRendererClientQt::GetInterface(const std::string &interface_name, mojo::ScopedMessagePipeHandle interface_pipe)
{
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index 24a841cb8..a0faec531 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -47,12 +47,15 @@
#include "ppapi/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_PLUGINS)
-#include "qtwebengine/browser/plugin.mojom.h"
#include "third_party/blink/public/web/web_plugin_params.h"
#endif
#include <QScopedPointer>
+namespace chrome {
+class WebRtcLoggingAgentImpl;
+}
+
namespace error_page {
class Error;
}
@@ -75,8 +78,8 @@ struct WebPluginInfo;
namespace QtWebEngineCore {
-class RenderThreadObserverQt;
-
+class UserResourceController;
+class RenderConfiguration;
class ContentRendererClientQt
: public content::ContentRendererClient
, public service_manager::LocalInterfaceProvider
@@ -88,9 +91,7 @@ public:
// content::ContentRendererClient:
void RenderThreadStarted() override;
void ExposeInterfacesToBrowser(mojo::BinderMap* binders) override;
- void RenderViewCreated(content::RenderView *render_view) override;
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 *render_frame,
@@ -111,14 +112,14 @@ public:
void RunScriptsAtDocumentStart(content::RenderFrame *render_frame) override;
void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame) override;
void RunScriptsAtDocumentIdle(content::RenderFrame *render_frame) override;
+ bool IsPluginHandledExternally(content::RenderFrame *embedder_frame,
+ const blink::WebElement &plugin_element,
+ const GURL &original_url,
+ const std::string &original_mime_type);
bool OverrideCreatePlugin(content::RenderFrame *render_frame,
const blink::WebPluginParams &params,
blink::WebPlugin **plugin) override;
bool IsOriginIsolatedPepperPlugin(const base::FilePath& plugin_path) 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,
@@ -128,15 +129,13 @@ public:
GURL *new_url,
bool *attach_same_site_cookies) override;
- void BindReceiverOnMainThread(mojo::GenericPendingReceiver receiver) override;
bool RequiresWebComponentsV0(const GURL &url) override;
-#if BUILDFLAG(ENABLE_PLUGINS)
- static blink::WebPlugin* CreatePlugin(content::RenderFrame* render_frame,
- const blink::WebPluginParams& params,
- const chrome::mojom::PluginInfo& plugin_info);
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ chrome::WebRtcLoggingAgentImpl *GetWebRtcLoggingAgent();
#endif
+
private:
#if BUILDFLAG(ENABLE_SPELLCHECK)
void InitSpellCheck();
@@ -147,14 +146,16 @@ private:
void GetNavigationErrorStringsInternal(content::RenderFrame *renderFrame, const std::string &httpMethod,
const error_page::Error &error, std::string *errorHtml);
- QScopedPointer<RenderThreadObserverQt> m_renderThreadObserver;
+ QScopedPointer<RenderConfiguration> m_renderConfiguration;
+ QScopedPointer<UserResourceController> m_userResourceController;
QScopedPointer<visitedlink::VisitedLinkReader> m_visitedLinkReader;
QScopedPointer<web_cache::WebCacheImpl> m_webCacheImpl;
#if QT_CONFIG(webengine_spellchecker)
QScopedPointer<SpellCheck> m_spellCheck;
#endif
-
- service_manager::BinderRegistry m_registry;
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ std::unique_ptr<chrome::WebRtcLoggingAgentImpl> m_webrtcLoggingAgentImpl;
+#endif
DISALLOW_COPY_AND_ASSIGN(ContentRendererClientQt);
};
diff --git a/src/core/renderer/content_settings_observer_qt.cpp b/src/core/renderer/content_settings_observer_qt.cpp
index df9b77037..18d52b50a 100644
--- a/src/core/renderer/content_settings_observer_qt.cpp
+++ b/src/core/renderer/content_settings_observer_qt.cpp
@@ -82,21 +82,20 @@ bool ContentSettingsObserverQt::OnMessageReceived(const IPC::Message &message)
{
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserverQt, message)
- IPC_MESSAGE_HANDLER(QtWebEngineMsg_RequestFileSystemAccessAsyncResponse, OnRequestFileSystemAccessAsyncResponse)
+ IPC_MESSAGE_HANDLER(QtWebEngineMsg_RequestStorageAccessAsyncResponse, OnRequestStorageAccessAsyncResponse)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
-void ContentSettingsObserverQt::DidCommitProvisionalLoad(bool is_same_document_navigation, ui::PageTransition /*transition*/)
+void ContentSettingsObserverQt::DidCommitProvisionalLoad(ui::PageTransition /*transition*/)
{
blink::WebLocalFrame *frame = render_frame()->GetWebFrame();
if (frame->Parent())
return; // Not a top-level navigation.
- if (!is_same_document_navigation)
- ClearBlockedContentSettings();
+ ClearBlockedContentSettings();
GURL url = frame->GetDocument().Url();
// If we start failing this DCHECK, please makes sure we don't regress
@@ -109,68 +108,51 @@ void ContentSettingsObserverQt::OnDestruct()
delete this;
}
-bool ContentSettingsObserverQt::AllowDatabase()
-{
- blink::WebFrame *frame = render_frame()->GetWebFrame();
- if (IsUniqueFrame(frame))
- return false;
-
- bool result = false;
- Send(new QtWebEngineHostMsg_AllowDatabase(routing_id(), url::Origin(frame->GetSecurityOrigin()).GetURL(),
- url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(), &result));
- return result;
-}
-
-void ContentSettingsObserverQt::RequestFileSystemAccessAsync(base::OnceCallback<void(bool)> callback)
+void ContentSettingsObserverQt::AllowStorageAccess(StorageType storage_type,
+ base::OnceCallback<void(bool)> callback)
{
blink::WebFrame *frame = render_frame()->GetWebFrame();
if (IsUniqueFrame(frame)) {
std::move(callback).Run(false);
return;
}
+
++m_currentRequestId;
bool inserted = m_permissionRequests.insert(std::make_pair(m_currentRequestId, std::move(callback))).second;
// Verify there are no duplicate insertions.
DCHECK(inserted);
- Send(new QtWebEngineHostMsg_RequestFileSystemAccessAsync(routing_id(), m_currentRequestId,
- url::Origin(frame->GetSecurityOrigin()).GetURL(),
- url::Origin(frame->Top()->GetSecurityOrigin()).GetURL()));
+ Send(new QtWebEngineHostMsg_RequestStorageAccessAsync(routing_id(), m_currentRequestId,
+ url::Origin(frame->GetSecurityOrigin()).GetURL(),
+ url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(),
+ int(storage_type)));
}
-bool ContentSettingsObserverQt::AllowIndexedDB()
-{
- blink::WebFrame *frame = render_frame()->GetWebFrame();
- if (IsUniqueFrame(frame))
- return false;
-
- bool result = false;
- Send(new QtWebEngineHostMsg_AllowIndexedDB(routing_id(),
- url::Origin(frame->GetSecurityOrigin()).GetURL(),
- url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(), &result));
- return result;
-}
-
-bool ContentSettingsObserverQt::AllowStorage(bool local)
+bool ContentSettingsObserverQt::AllowStorageAccessSync(StorageType storage_type)
{
blink::WebLocalFrame *frame = render_frame()->GetWebFrame();
if (IsUniqueFrame(frame))
return false;
- StoragePermissionsKey key(url::Origin(frame->GetDocument().GetSecurityOrigin()).GetURL(), local);
- const auto permissions = m_cachedStoragePermissions.find(key);
- if (permissions != m_cachedStoragePermissions.end())
- return permissions->second;
+ bool sameOrigin = url::Origin(frame->Top()->GetSecurityOrigin()).IsSameOriginWith(url::Origin(frame->GetSecurityOrigin()));
+ StoragePermissionsKey key(url::Origin(frame->GetSecurityOrigin()).GetURL(), int(storage_type));
+ if (sameOrigin) {
+ const auto permissions = m_cachedStoragePermissions.find(key);
+ if (permissions != m_cachedStoragePermissions.end())
+ return permissions->second;
+ }
bool result = false;
- Send(new QtWebEngineHostMsg_AllowDOMStorage(routing_id(), url::Origin(frame->GetSecurityOrigin()).GetURL(),
- url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(), local, &result));
- m_cachedStoragePermissions[key] = result;
+ Send(new QtWebEngineHostMsg_AllowStorageAccess(routing_id(), url::Origin(frame->GetSecurityOrigin()).GetURL(),
+ url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(),
+ int(storage_type), &result));
+ if (sameOrigin)
+ m_cachedStoragePermissions[key] = result;
return result;
}
-void ContentSettingsObserverQt::OnRequestFileSystemAccessAsyncResponse(int request_id, bool allowed)
+void ContentSettingsObserverQt::OnRequestStorageAccessAsyncResponse(int request_id, bool allowed)
{
auto it = m_permissionRequests.find(request_id);
if (it == m_permissionRequests.end())
diff --git a/src/core/renderer/content_settings_observer_qt.h b/src/core/renderer/content_settings_observer_qt.h
index 0c69d289c..9268b4982 100644
--- a/src/core/renderer/content_settings_observer_qt.h
+++ b/src/core/renderer/content_settings_observer_qt.h
@@ -67,25 +67,24 @@ public:
~ContentSettingsObserverQt() override;
// blink::WebContentSettingsClient:
- bool AllowDatabase() override;
- void RequestFileSystemAccessAsync(base::OnceCallback<void(bool)> callback) override;
- bool AllowIndexedDB() override;
- bool AllowStorage(bool local) override;
+ void AllowStorageAccess(StorageType storage_type,
+ base::OnceCallback<void(bool)> callback) override;
+ bool AllowStorageAccessSync(StorageType storage_type) override;
private:
// RenderFrameObserver implementation:
bool OnMessageReceived(const IPC::Message &message) override;
- void DidCommitProvisionalLoad(bool is_same_document_navigation, ui::PageTransition transition) override;
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
void OnDestruct() override;
// Message handlers.
- void OnRequestFileSystemAccessAsyncResponse(int request_id, bool allowed);
+ void OnRequestStorageAccessAsyncResponse(int request_id, bool allowed);
// Clears m_cachedStoragePermissions
void ClearBlockedContentSettings();
// Caches the result of AllowStorage.
- using StoragePermissionsKey = std::pair<GURL, bool>;
+ using StoragePermissionsKey = std::pair<GURL, int>;
base::flat_map<StoragePermissionsKey, bool> m_cachedStoragePermissions;
int m_currentRequestId;
diff --git a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
index 418429330..d49845f55 100644
--- a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
+++ b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
@@ -39,6 +39,9 @@
#include "extensions_dispatcher_delegate_qt.h"
+#include "chrome/grit/renderer_resources.h"
+#include "extensions/renderer/resource_bundle_source_map.h"
+
namespace QtWebEngineCore {
ExtensionsDispatcherDelegateQt::ExtensionsDispatcherDelegateQt()
@@ -49,4 +52,10 @@ ExtensionsDispatcherDelegateQt::~ExtensionsDispatcherDelegateQt()
{
}
+void ExtensionsDispatcherDelegateQt::PopulateSourceMap(extensions::ResourceBundleSourceMap *source_map)
+{
+ // Custom binding for hangout services extension.
+ source_map->RegisterSource("webrtcDesktopCapturePrivate", IDR_WEBRTC_DESKTOP_CAPTURE_PRIVATE_CUSTOM_BINDINGS_JS);
+}
+
} //namespace QtWebEngineCore
diff --git a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
index 25aa18e71..1a19bcbbb 100644
--- a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
+++ b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
@@ -52,6 +52,9 @@ public:
~ExtensionsDispatcherDelegateQt() override;
private:
+ // extensions::DispatcherDelegate implementation.
+ void PopulateSourceMap(extensions::ResourceBundleSourceMap *source_map) override;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionsDispatcherDelegateQt);
};
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
index 7d4c9a83c..f72113018 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
@@ -45,7 +45,7 @@
#include "extensions_renderer_client_qt.h"
#include "extensions_dispatcher_delegate_qt.h"
-#include "renderer/render_thread_observer_qt.h"
+#include "renderer/render_configuration.h"
#include "renderer_permissions_policy_delegate_qt.h"
#include "resource_request_policy_qt.h"
@@ -88,7 +88,7 @@ ExtensionsRendererClientQt::~ExtensionsRendererClientQt()
// Returns true if the current render process was launched incognito.
bool ExtensionsRendererClientQt::IsIncognitoProcess() const
{
- return RenderThreadObserverQt::is_incognito_process();
+ return RenderConfiguration::is_incognito_process();
}
// Returns the lowest isolated world ID available to extensions.
@@ -147,8 +147,6 @@ bool ExtensionsRendererClientQt::ExtensionAPIEnabledForServiceWorkerScript(const
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);
@@ -200,16 +198,6 @@ bool ExtensionsRendererClientQt::ShouldFork(blink::WebLocalFrame *frame,
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);
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.h b/src/core/renderer/extensions/extensions_renderer_client_qt.h
index 87e324213..85cc7bf2d 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.h
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.h
@@ -108,10 +108,6 @@ public:
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);
bool ExtensionAPIEnabledForServiceWorkerScript(const GURL &scope, const GURL &script_url) const override;
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 33c744f13..1b9de4d4d 100644
--- a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
@@ -48,6 +48,7 @@
#include "base/memory/ptr_util.h"
#include "chrome/renderer/pepper/pepper_flash_font_file_host.h"
+#include "chrome/renderer/pepper/pepper_uma_host.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "components/pdf/renderer/pepper_pdf_host.h"
#endif // QT_CONFIG(webengine_printing_and_pdf)
@@ -127,6 +128,14 @@ std::unique_ptr<ppapi::host::ResourceHost> PepperRendererHostFactoryQt::CreateRe
}
}
#endif // QT_CONFIG(webengine_printing_and_pdf)
+
+ // Create a default ResourceHost for this message type to suppress
+ // "Failed to create PPAPI resource host" console error message.
+ switch (message.type()) {
+ case PpapiHostMsg_UMA_Create::ID:
+ return std::make_unique<ppapi::host::ResourceHost>(host_->GetPpapiHost(), instance, resource);
+ }
+
return nullptr;
}
diff --git a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
index b43d9a24b..9dc5fbd94 100644
--- a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
+++ b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
@@ -77,7 +77,7 @@ LoadablePluginPlaceholderQt::~LoadablePluginPlaceholderQt()
LoadablePluginPlaceholderQt* LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(content::RenderFrame* render_frame,
const blink::WebPluginParams& params)
{
- const base::StringPiece template_html(ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_BLOCKED_PLUGIN_HTML));
+ std::string template_html(ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_BLOCKED_PLUGIN_HTML));
base::DictionaryValue values;
values.SetString("name", "");
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 beae6ecfa..5dcfaafd6 100644
--- a/src/core/renderer/print_web_view_helper_delegate_qt.cpp
+++ b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
@@ -43,11 +43,17 @@
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
+#include "extensions/buildflags/buildflags.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"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "chrome/common/webui_url_constants.h"
+#include "extensions/common/constants.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
#include "print_web_view_helper_delegate_qt.h"
#include "web_engine_library_info.h"
@@ -56,14 +62,23 @@ PrintWebViewHelperDelegateQt::~PrintWebViewHelperDelegateQt() {}
blink::WebElement PrintWebViewHelperDelegateQt::GetPdfElement(blink::WebLocalFrame *frame)
{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
GURL url = frame->GetDocument().Url();
- if (url.SchemeIs(extensions::kExtensionScheme) && url.host() == extension_misc::kPdfExtensionId) {
+ bool inside_print_preview = url.GetOrigin() == chrome::kChromeUIPrintURL;
+ bool inside_pdf_extension = url.SchemeIs(extensions::kExtensionScheme) &&
+ url.host_piece() == extension_misc::kPdfExtensionId;
+ if (inside_print_preview || inside_pdf_extension) {
// <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;
+ // chrome/browser/resources/pdf/pdf_viewer_base.js.
+ auto viewer_element = frame->GetDocument().GetElementById("viewer");
+ if (!viewer_element.IsNull() && !viewer_element.ShadowRoot().IsNull()) {
+ auto plugin_element = viewer_element.ShadowRoot().QuerySelector("#plugin");
+ if (!plugin_element.IsNull())
+ return plugin_element;
+ }
+ NOTREACHED();
}
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
return blink::WebElement();
}
diff --git a/src/core/renderer/render_thread_observer_qt.cpp b/src/core/renderer/render_configuration.cpp
index 4912ebfc2..ef9da7af7 100644
--- a/src/core/renderer/render_thread_observer_qt.cpp
+++ b/src/core/renderer/render_configuration.cpp
@@ -42,31 +42,34 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "renderer/render_thread_observer_qt.h"
-
+#include "renderer/render_configuration.h"
+#include "user_resource_controller.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
namespace QtWebEngineCore {
-bool RenderThreadObserverQt::m_isIncognitoProcess = false;
+bool RenderConfiguration::m_isIncognitoProcess = false;
-void RenderThreadObserverQt::RegisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces)
+void RenderConfiguration::RegisterMojoInterfaces(
+ blink::AssociatedInterfaceRegistry *associated_interfaces)
{
associated_interfaces->AddInterface(
- base::Bind(&RenderThreadObserverQt::OnRendererConfigurationAssociatedRequest, base::Unretained(this)));
+ base::Bind(&RenderConfiguration::OnRendererConfigurationAssociatedRequest,
+ base::Unretained(this)));
}
-void RenderThreadObserverQt::UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces)
+void RenderConfiguration::UnregisterMojoInterfaces(
+ blink::AssociatedInterfaceRegistry *associated_interfaces)
{
associated_interfaces->RemoveInterface(qtwebengine::mojom::RendererConfiguration::Name_);
}
-void RenderThreadObserverQt::SetInitialConfiguration(bool is_incognito_process)
+void RenderConfiguration::SetInitialConfiguration(bool is_incognito_process)
{
m_isIncognitoProcess = is_incognito_process;
}
-void RenderThreadObserverQt::OnRendererConfigurationAssociatedRequest(
+void RenderConfiguration::OnRendererConfigurationAssociatedRequest(
mojo::PendingAssociatedReceiver<qtwebengine::mojom::RendererConfiguration> receiver)
{
m_rendererConfigurationReceivers.Add(this, std::move(receiver));
diff --git a/src/core/renderer/render_thread_observer_qt.h b/src/core/renderer/render_configuration.h
index 05372049b..138a85bdc 100644
--- a/src/core/renderer/render_thread_observer_qt.h
+++ b/src/core/renderer/render_configuration.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef RENDER_THREAD_OBSERVER_QT_H
-#define RENDER_THREAD_OBSERVER_QT_H
+#ifndef RENDER_CONFIGURATION_H
+#define RENDER_CONFIGURATION_H
#include "content/public/renderer/render_thread_observer.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
@@ -47,13 +47,12 @@
namespace QtWebEngineCore {
-class RenderThreadObserverQt
- : public content::RenderThreadObserver
- , public qtwebengine::mojom::RendererConfiguration
+class RenderConfiguration : public content::RenderThreadObserver,
+ public qtwebengine::mojom::RendererConfiguration
{
public:
- RenderThreadObserverQt() = default;
- ~RenderThreadObserverQt() override = default;
+ RenderConfiguration() = default;
+ ~RenderConfiguration() override = default;
static bool is_incognito_process() { return m_isIncognitoProcess; }
@@ -70,11 +69,12 @@ private:
static bool m_isIncognitoProcess;
- mojo::AssociatedReceiverSet<qtwebengine::mojom::RendererConfiguration> m_rendererConfigurationReceivers;
+ mojo::AssociatedReceiverSet<qtwebengine::mojom::RendererConfiguration>
+ m_rendererConfigurationReceivers;
- DISALLOW_COPY_AND_ASSIGN(RenderThreadObserverQt);
+ DISALLOW_COPY_AND_ASSIGN(RenderConfiguration);
};
} // namespace QtWebEngineCore
-#endif // RENDER_THREAD_OBSERVER_QT_H
+#endif // RENDER_CONFIGURATION_H
diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp
index cc01acec6..77d325f3c 100644
--- a/src/core/renderer/render_frame_observer_qt.cpp
+++ b/src/core/renderer/render_frame_observer_qt.cpp
@@ -77,7 +77,13 @@ void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost *ho
}
#endif
-void RenderFrameObserverQt::FrameDetached()
+bool RenderFrameObserverQt::OnAssociatedInterfaceRequestForFrame(const std::string &interface_name,
+ mojo::ScopedInterfaceEndpointHandle *handle)
+{
+ return m_associated_interfaces.TryBindInterface(interface_name, handle);
+}
+
+void RenderFrameObserverQt::WillDetach()
{
m_isFrameDetached = true;
}
diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h
index 6bdf4ad23..8803dde89 100644
--- a/src/core/renderer/render_frame_observer_qt.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -46,6 +46,7 @@
#include "content/public/renderer/render_frame_observer_tracker.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
namespace content {
class RenderFrame;
@@ -67,12 +68,18 @@ public:
#if QT_CONFIG(webengine_pepper_plugins)
void DidCreatePepperPlugin(content::RendererPpapiHost *host) override;
#endif
+ bool OnAssociatedInterfaceRequestForFrame(
+ const std::string &interface_name,
+ mojo::ScopedInterfaceEndpointHandle *handle) override;
void OnDestruct() override;
- void FrameDetached() override;
+ void WillDetach() override;
bool isFrameDetached() const;
service_manager::BinderRegistry *registry() { return &registry_; }
+ blink::AssociatedInterfaceRegistry *associatedInterfaces() {
+ return &m_associated_interfaces;
+ }
private:
DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt);
@@ -81,6 +88,7 @@ private:
bool m_isFrameDetached;
service_manager::BinderRegistry registry_;
+ blink::AssociatedInterfaceRegistry m_associated_interfaces;
web_cache::WebCacheImpl *m_web_cache_impl;
};
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp
index 5c1bd301f..c7b220fe6 100644
--- a/src/core/renderer/user_resource_controller.cpp
+++ b/src/core/renderer/user_resource_controller.cpp
@@ -52,9 +52,12 @@
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_view.h"
#include "v8/include/v8.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "common/qt_messages.h"
-#include "common/user_script_data.h"
+#include "qtwebengine/userscript/user_script_data.h"
#include "type_conversion.h"
#include "user_script.h"
@@ -62,9 +65,9 @@
#include <bitset>
-Q_GLOBAL_STATIC(UserResourceController, qt_webengine_userResourceController)
+namespace QtWebEngineCore {
-static content::RenderView *const globalScriptsIndex = nullptr;
+static content::RenderFrame *const globalScriptsIndex = nullptr;
// Scripts meant to run after the load event will be run 500ms after DOMContentLoaded if the load event doesn't come within that delay.
static const int afterLoadTimeout = 500;
@@ -97,7 +100,7 @@ static bool includeRuleMatchesURL(const std::string &pat, const GURL &url)
return false;
}
-static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url)
+static bool scriptMatchesURL(const QtWebEngineCore::UserScriptData &scriptData, const GURL &url)
{
// Logic taken from Chromium (extensions/common/user_script.cc)
bool matchFound;
@@ -132,26 +135,34 @@ static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url)
return true;
}
-class UserResourceController::RenderFrameObserverHelper : public content::RenderFrameObserver
+// using UserScriptDataPtr = mojo::StructPtr<qtwebengine::mojom::UserScriptData>;
+
+class UserResourceController::RenderFrameObserverHelper
+ : public content::RenderFrameObserver,
+ public qtwebengine::mojom::UserResourceControllerRenderFrame
{
public:
- RenderFrameObserverHelper(content::RenderFrame *render_frame);
+ RenderFrameObserverHelper(content::RenderFrame *render_frame,
+ UserResourceController *controller);
+ void BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceControllerRenderFrame>
+ receiver);
private:
// RenderFrameObserver implementation.
- void DidCommitProvisionalLoad(bool is_same_document_navigation, ui::PageTransition transition) override;
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
void DidFinishDocumentLoad() override;
void DidFinishLoad() override;
- void FrameDetached() override;
+ void WillDetach() override;
void OnDestruct() override;
- bool OnMessageReceived(const IPC::Message &message) override;
-
- void onUserScriptAdded(const UserScriptData &);
- void onUserScriptRemoved(const UserScriptData &);
- void onScriptsCleared();
+ void AddScript(const QtWebEngineCore::UserScriptData &data) override;
+ void RemoveScript(const QtWebEngineCore::UserScriptData &data) override;
+ void ClearScripts() override;
class Runner;
QScopedPointer<Runner> m_runner;
+ mojo::AssociatedReceiver<qtwebengine::mojom::UserResourceControllerRenderFrame> m_binding;
+ UserResourceController *m_userResourceController;
};
// Helper class to create WeakPtrs so the AfterLoad tasks can be canceled and to
@@ -159,13 +170,16 @@ private:
class UserResourceController::RenderFrameObserverHelper::Runner : public base::SupportsWeakPtr<Runner>
{
public:
- explicit Runner(blink::WebLocalFrame *frame) : m_frame(frame) {}
+ explicit Runner(blink::WebLocalFrame *frame, UserResourceController *controller)
+ : m_frame(frame), m_userResourceController(controller)
+ {
+ }
- void run(UserScriptData::InjectionPoint p)
+ void run(QtWebEngineCore::UserScriptData::InjectionPoint p)
{
DCHECK_LT(p, m_ran.size());
if (!m_ran[p]) {
- UserResourceController::instance()->runScripts(p, m_frame);
+ m_userResourceController->runScripts(p, m_frame);
m_ran[p] = true;
}
}
@@ -173,35 +187,22 @@ public:
private:
blink::WebLocalFrame *m_frame;
std::bitset<3> m_ran;
+ UserResourceController *m_userResourceController;
};
-// Used only for script cleanup on RenderView destruction.
-class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver
-{
-public:
- RenderViewObserverHelper(content::RenderView *render_view);
-
-private:
- // RenderViewObserver implementation.
- void OnDestruct() override;
-};
-
-void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame)
+void UserResourceController::runScripts(QtWebEngineCore::UserScriptData::InjectionPoint p,
+ blink::WebLocalFrame *frame)
{
content::RenderFrame *renderFrame = content::RenderFrame::FromWebFrame(frame);
if (!renderFrame)
return;
const bool isMainFrame = renderFrame->IsMainFrame();
- content::RenderView *renderView = renderFrame->GetRenderView();
- if (!renderView)
- return;
-
- QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(0).toList();
- scriptsToRun.append(m_viewUserScriptMap.value(renderView).toList());
+ QList<uint64_t> scriptsToRun = m_frameUserScriptMap.value(globalScriptsIndex).toList();
+ scriptsToRun.append(m_frameUserScriptMap.value(renderFrame).toList());
for (uint64_t id : qAsConst(scriptsToRun)) {
- const UserScriptData &script = m_scripts.value(id);
+ const QtWebEngineCore::UserScriptData &script = m_scripts.value(id);
if (script.injectionPoint != p || (!script.injectForSubframes && !isMainFrame))
continue;
if (!scriptMatchesURL(script, frame->GetDocument().Url()))
@@ -216,31 +217,40 @@ void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink:
void UserResourceController::RunScriptsAtDocumentEnd(content::RenderFrame *render_frame)
{
- runScripts(UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame());
+ runScripts(QtWebEngineCore::UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame());
}
-UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(content::RenderFrame *render_frame)
+UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(
+ content::RenderFrame *render_frame, UserResourceController *controller)
: content::RenderFrameObserver(render_frame)
-{}
+ , m_binding(this)
+ , m_userResourceController(controller)
+{
+ render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+ base::BindRepeating(&UserResourceController::RenderFrameObserverHelper::BindReceiver,
+ base::Unretained(this)));
+}
-UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *render_view)
- : content::RenderViewObserver(render_view)
-{}
-void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition /*transitionbool*/)
+void UserResourceController::RenderFrameObserverHelper::BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceControllerRenderFrame>
+ receiver)
{
- if (is_same_document_navigation)
- return;
+ m_binding.Bind(std::move(receiver));
+}
+void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad(ui::PageTransition /*transition*/)
+{
// We are almost ready to run scripts. We still have to wait until the host
// process has been notified of the DidCommitProvisionalLoad event to ensure
// that the WebChannelTransportHost is ready to receive messages.
- m_runner.reset(new Runner(render_frame()->GetWebFrame()));
+ m_runner.reset(new Runner(render_frame()->GetWebFrame(), m_userResourceController));
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), UserScriptData::DocumentElementCreation));
+ FROM_HERE,
+ base::BindOnce(&Runner::run, m_runner->AsWeakPtr(),
+ QtWebEngineCore::UserScriptData::DocumentElementCreation));
}
void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad()
@@ -249,7 +259,9 @@ void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad()
// called instead of DidCommitProvisionalLoad).
if (m_runner)
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), UserScriptData::AfterLoad),
+ FROM_HERE,
+ base::BindOnce(&Runner::run, m_runner->AsWeakPtr(),
+ QtWebEngineCore::UserScriptData::AfterLoad),
base::TimeDelta::FromMilliseconds(afterLoadTimeout));
}
@@ -257,78 +269,51 @@ void UserResourceController::RenderFrameObserverHelper::DidFinishLoad()
{
if (m_runner)
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), UserScriptData::AfterLoad));
+ FROM_HERE,
+ base::BindOnce(&Runner::run, m_runner->AsWeakPtr(),
+ QtWebEngineCore::UserScriptData::AfterLoad));
}
-void UserResourceController::RenderFrameObserverHelper::FrameDetached()
+void UserResourceController::RenderFrameObserverHelper::WillDetach()
{
m_runner.reset();
}
void UserResourceController::RenderFrameObserverHelper::OnDestruct()
{
+ if (content::RenderFrame *frame = render_frame()) {
+ m_userResourceController->renderFrameDestroyed(frame);
+ }
delete this;
}
-void UserResourceController::RenderViewObserverHelper::OnDestruct()
-{
- // Remove all scripts associated with the render view.
- if (content::RenderView *view = render_view())
- UserResourceController::instance()->renderViewDestroyed(view);
- delete this;
-}
-
-bool UserResourceController::RenderFrameObserverHelper::OnMessageReceived(const IPC::Message &message)
-{
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderFrameObserverHelper, message)
- IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_AddScript, onUserScriptAdded)
- IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_RemoveScript, onUserScriptRemoved)
- IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_ClearScripts, onScriptsCleared)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void UserResourceController::RenderFrameObserverHelper::onUserScriptAdded(const UserScriptData &script)
+void UserResourceController::RenderFrameObserverHelper::AddScript(
+ const QtWebEngineCore::UserScriptData &script)
{
if (content::RenderFrame *frame = render_frame())
- if (content::RenderView *view = frame->GetRenderView())
- UserResourceController::instance()->addScriptForView(script, view);
+ m_userResourceController->addScriptForFrame(script, frame);
}
-void UserResourceController::RenderFrameObserverHelper::onUserScriptRemoved(const UserScriptData &script)
+void UserResourceController::RenderFrameObserverHelper::RemoveScript(
+ const QtWebEngineCore::UserScriptData &script)
{
if (content::RenderFrame *frame = render_frame())
- if (content::RenderView *view = frame->GetRenderView())
- UserResourceController::instance()->removeScriptForView(script, view);
+ m_userResourceController->removeScriptForFrame(script, frame);
}
-void UserResourceController::RenderFrameObserverHelper::onScriptsCleared()
+void UserResourceController::RenderFrameObserverHelper::ClearScripts()
{
if (content::RenderFrame *frame = render_frame())
- if (content::RenderView *view = frame->GetRenderView())
- UserResourceController::instance()->clearScriptsForView(view);
+ m_userResourceController->clearScriptsForFrame(frame);
}
-UserResourceController *UserResourceController::instance()
+void UserResourceController::BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceController> receiver)
{
- return qt_webengine_userResourceController();
+ m_binding.Bind(std::move(receiver));
}
-bool UserResourceController::OnControlMessageReceived(const IPC::Message &message)
-{
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(UserResourceController, message)
- IPC_MESSAGE_HANDLER(UserResourceController_AddScript, onAddScript)
- IPC_MESSAGE_HANDLER(UserResourceController_RemoveScript, onRemoveScript)
- IPC_MESSAGE_HANDLER(UserResourceController_ClearScripts, onClearScripts)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-UserResourceController::UserResourceController()
+UserResourceController::UserResourceController() : m_binding(this)
{
#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
static bool onlyCalledOnce = true;
@@ -340,68 +325,79 @@ UserResourceController::UserResourceController()
void UserResourceController::renderFrameCreated(content::RenderFrame *renderFrame)
{
// Will destroy itself when the RenderFrame is destroyed.
- new RenderFrameObserverHelper(renderFrame);
+ new RenderFrameObserverHelper(renderFrame, this);
}
-void UserResourceController::renderViewCreated(content::RenderView *renderView)
+void UserResourceController::renderFrameDestroyed(content::RenderFrame *renderFrame)
{
- // Will destroy itself when the RenderView is destroyed.
- new RenderViewObserverHelper(renderView);
-}
-
-void UserResourceController::renderViewDestroyed(content::RenderView *renderView)
-{
- ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(renderView);
- if (it == m_viewUserScriptMap.end()) // ASSERT maybe?
+ FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(renderFrame);
+ if (it == m_frameUserScriptMap.end()) // ASSERT maybe?
return;
for (uint64_t id : qAsConst(it.value())) {
m_scripts.remove(id);
}
- m_viewUserScriptMap.remove(renderView);
+ m_frameUserScriptMap.remove(renderFrame);
}
-void UserResourceController::addScriptForView(const UserScriptData &script, content::RenderView *view)
+void UserResourceController::addScriptForFrame(const QtWebEngineCore::UserScriptData &script,
+ content::RenderFrame *frame)
{
- ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(view);
- if (it == m_viewUserScriptMap.end())
- it = m_viewUserScriptMap.insert(view, UserScriptSet());
+ FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame);
+ if (it == m_frameUserScriptMap.end())
+ it = m_frameUserScriptMap.insert(frame, UserScriptSet());
(*it).insert(script.scriptId);
m_scripts.insert(script.scriptId, script);
}
-void UserResourceController::removeScriptForView(const UserScriptData &script, content::RenderView *view)
+void UserResourceController::removeScriptForFrame(const QtWebEngineCore::UserScriptData &script,
+ content::RenderFrame *frame)
{
- ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(view);
- if (it == m_viewUserScriptMap.end())
+ FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame);
+ if (it == m_frameUserScriptMap.end())
return;
(*it).remove(script.scriptId);
m_scripts.remove(script.scriptId);
}
-void UserResourceController::clearScriptsForView(content::RenderView *view)
+void UserResourceController::clearScriptsForFrame(content::RenderFrame *frame)
{
- ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(view);
- if (it == m_viewUserScriptMap.end())
+ FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame);
+ if (it == m_frameUserScriptMap.end())
return;
for (uint64_t id : qAsConst(it.value()))
m_scripts.remove(id);
- m_viewUserScriptMap.remove(view);
+ m_frameUserScriptMap.remove(frame);
+}
+
+void UserResourceController::AddScript(const QtWebEngineCore::UserScriptData &script)
+{
+ addScriptForFrame(script, globalScriptsIndex);
}
-void UserResourceController::onAddScript(const UserScriptData &script)
+void UserResourceController::RemoveScript(const QtWebEngineCore::UserScriptData &script)
{
- addScriptForView(script, globalScriptsIndex);
+ removeScriptForFrame(script, globalScriptsIndex);
}
-void UserResourceController::onRemoveScript(const UserScriptData &script)
+void UserResourceController::ClearScripts()
{
- removeScriptForView(script, globalScriptsIndex);
+ clearScriptsForFrame(globalScriptsIndex);
}
-void UserResourceController::onClearScripts()
+void UserResourceController::RegisterMojoInterfaces(
+ blink::AssociatedInterfaceRegistry *associated_interfaces)
{
- clearScriptsForView(globalScriptsIndex);
+ associated_interfaces->AddInterface(
+ base::Bind(&UserResourceController::BindReceiver, base::Unretained(this)));
}
+
+void UserResourceController::UnregisterMojoInterfaces(
+ blink::AssociatedInterfaceRegistry *associated_interfaces)
+{
+ associated_interfaces->RemoveInterface(qtwebengine::mojom::UserResourceController::Name_);
+}
+
+} // namespace
diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h
index 3a493b9b7..6c79d96fc 100644
--- a/src/core/renderer/user_resource_controller.h
+++ b/src/core/renderer/user_resource_controller.h
@@ -41,8 +41,9 @@
#define USER_RESOURCE_CONTROLLER_H
#include "content/public/renderer/render_thread_observer.h"
-
-#include "common/user_script_data.h"
+#include "qtwebengine/userscript/userscript.mojom.h"
+#include "qtwebengine/userscript/user_script_data.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
#include <QtCore/QHash>
#include <QtCore/QSet>
@@ -56,42 +57,46 @@ class RenderFrame;
class RenderView;
}
-class UserResourceController : public content::RenderThreadObserver
+namespace QtWebEngineCore {
+
+class UserResourceController : public content::RenderThreadObserver,
+ qtwebengine::mojom::UserResourceController
{
public:
- static UserResourceController *instance();
UserResourceController();
void renderFrameCreated(content::RenderFrame *);
- void renderViewCreated(content::RenderView *);
- void renderViewDestroyed(content::RenderView *renderView);
- void addScriptForView(const UserScriptData &, content::RenderView *);
- void removeScriptForView(const UserScriptData &, content::RenderView *);
- void clearScriptsForView(content::RenderView *);
+ void renderFrameDestroyed(content::RenderFrame *);
+ void addScriptForFrame(const QtWebEngineCore::UserScriptData &, content::RenderFrame *);
+ void removeScriptForFrame(const QtWebEngineCore::UserScriptData &, content::RenderFrame *);
+ void clearScriptsForFrame(content::RenderFrame *);
void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame);
+ void BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceController> receiver);
private:
Q_DISABLE_COPY(UserResourceController)
+ // content::RenderThreadObserver:
+ void RegisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override;
+ void UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override;
+
class RenderFrameObserverHelper;
class RenderViewObserverHelper;
- // RenderProcessObserver implementation.
- bool OnControlMessageReceived(const IPC::Message &message) override;
+ void AddScript(const QtWebEngineCore::UserScriptData &data) override;
+ void RemoveScript(const QtWebEngineCore::UserScriptData &data) override;
+ void ClearScripts() override;
- void onAddScript(const UserScriptData &);
- void onRemoveScript(const UserScriptData &);
- void onClearScripts();
-
- void runScripts(UserScriptData::InjectionPoint, blink::WebLocalFrame *);
+ void runScripts(QtWebEngineCore::UserScriptData::InjectionPoint, blink::WebLocalFrame *);
typedef QSet<uint64_t> UserScriptSet;
- typedef QHash<const content::RenderView *, UserScriptSet> ViewUserScriptMap;
- ViewUserScriptMap m_viewUserScriptMap;
- QHash<uint64_t, UserScriptData> m_scripts;
-
+ typedef QHash<const content::RenderFrame *, UserScriptSet> FrameUserScriptMap;
+ FrameUserScriptMap m_frameUserScriptMap;
+ QHash<uint64_t, QtWebEngineCore::UserScriptData> m_scripts;
+ mojo::AssociatedReceiver<qtwebengine::mojom::UserResourceController> m_binding;
friend class RenderFrameObserverHelper;
};
-
+} // namespace
#endif // USER_RESOURCE_CONTROLLER_H
diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
index 1fb3bc678..520c492ea 100644
--- a/src/core/renderer/web_channel_ipc_transport.cpp
+++ b/src/core/renderer/web_channel_ipc_transport.cpp
@@ -74,7 +74,8 @@ private:
// gin::WrappableBase
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate *isolate) override;
-
+ mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportHost> m_remote;
+ content::RenderFrame *m_renderFrame = nullptr;
DISALLOW_COPY_AND_ASSIGN(WebChannelTransport);
};
@@ -165,9 +166,14 @@ void WebChannelTransport::NativeQtSendMessage(gin::Arguments *args)
int size = 0;
const char *rawData = doc.rawData(&size);
- mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportHost> webChannelTransport;
- renderFrame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport);
- webChannelTransport->DispatchWebChannelMessage(std::vector<uint8_t>(rawData, rawData + size));
+
+ if (!m_remote) {
+ renderFrame->GetRemoteAssociatedInterfaces()->GetInterface(&m_remote);
+ m_renderFrame = renderFrame;
+ }
+ DCHECK(renderFrame == m_renderFrame);
+
+ m_remote->DispatchWebChannelMessage(std::vector<uint8_t>(rawData, rawData + size));
}
gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Isolate *isolate)
@@ -177,7 +183,10 @@ gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Iso
}
WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame)
- : content::RenderFrameObserver(renderFrame), m_worldId(0), m_worldInitialized(false)
+ : content::RenderFrameObserver(renderFrame)
+ , m_worldId(0)
+ , m_worldInitialized(false)
+ , m_binding(this)
{
renderFrame->GetAssociatedInterfaceRegistry()->AddInterface(
base::BindRepeating(&WebChannelIPCTransport::BindReceiver, base::Unretained(this)));
@@ -186,7 +195,7 @@ WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame
void WebChannelIPCTransport::BindReceiver(
mojo::PendingAssociatedReceiver<qtwebchannel::mojom::WebChannelTransportRender> receiver)
{
- m_receivers.Add(this, std::move(receiver));
+ m_binding.Bind(std::move(receiver));
}
void WebChannelIPCTransport::SetWorldId(uint32_t worldId)
diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h
index 15778a7bc..4bed5f26d 100644
--- a/src/core/renderer/web_channel_ipc_transport.h
+++ b/src/core/renderer/web_channel_ipc_transport.h
@@ -76,7 +76,7 @@ private:
bool m_worldInitialized;
// True means it's currently OK to manipulate the frame's script context.
bool m_canUseContext = false;
- mojo::AssociatedReceiverSet<qtwebchannel::mojom::WebChannelTransportRender> m_receivers;
+ mojo::AssociatedReceiver<qtwebchannel::mojom::WebChannelTransportRender> m_binding;
};
} // namespace
diff --git a/src/core/renderer/render_view_observer_qt.cpp b/src/core/renderer/web_engine_page_render_frame.cpp
index 5b0b9a77d..add1788d6 100644
--- a/src/core/renderer/render_view_observer_qt.cpp
+++ b/src/core/renderer/web_engine_page_render_frame.cpp
@@ -37,11 +37,11 @@
**
****************************************************************************/
-#include "renderer/render_view_observer_qt.h"
+#include "renderer/web_engine_page_render_frame.h"
+#include "content/public/renderer/render_frame.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
-#include "common/qt_messages.h"
-
-#include "content/public/renderer/render_view.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_frame.h"
@@ -50,45 +50,45 @@
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
-RenderViewObserverQt::RenderViewObserverQt(content::RenderView *render_view) : content::RenderViewObserver(render_view)
-{}
+namespace QtWebEngineCore {
-void RenderViewObserverQt::onFetchDocumentMarkup(quint64 requestId)
+WebEnginePageRenderFrame::WebEnginePageRenderFrame(content::RenderFrame *render_frame)
+ : content::RenderFrameObserver(render_frame), m_binding(this)
{
- blink::WebString markup;
- if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame())
- markup = blink::WebFrameContentDumper::DumpAsMarkup(
- static_cast<blink::WebLocalFrame *>(render_view()->GetWebView()->MainFrame()));
- Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(routing_id(), requestId, markup.Utf16()));
+ render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+ base::BindRepeating(&WebEnginePageRenderFrame::BindReceiver, base::Unretained(this)));
}
-void RenderViewObserverQt::onFetchDocumentInnerText(quint64 requestId)
+void WebEnginePageRenderFrame::BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame> receiver)
{
- blink::WebString text;
- if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame())
- text = blink::WebFrameContentDumper::DumpWebViewAsText(render_view()->GetWebView(),
- std::numeric_limits<std::size_t>::max());
- Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(routing_id(), requestId, text.Utf16()));
+ m_binding.Bind(std::move(receiver));
}
-void RenderViewObserverQt::onSetBackgroundColor(quint32 color)
+void WebEnginePageRenderFrame::FetchDocumentMarkup(uint64_t requestId,
+ FetchDocumentMarkupCallback callback)
{
- render_view()->GetWebView()->SetBaseBackgroundColorOverride(color);
+ blink::WebString markup =
+ blink::WebFrameContentDumper::DumpAsMarkup(render_frame()->GetWebFrame());
+ std::move(callback).Run(requestId, markup.Utf8());
}
-void RenderViewObserverQt::OnDestruct()
+void WebEnginePageRenderFrame::FetchDocumentInnerText(uint64_t requestId,
+ FetchDocumentInnerTextCallback callback)
{
- delete this;
+ blink::WebString text = blink::WebFrameContentDumper::DumpWebViewAsText(
+ render_frame()->GetWebFrame()->View(), std::numeric_limits<std::size_t>::max());
+ std::move(callback).Run(requestId, text.Utf8());
+}
+
+void WebEnginePageRenderFrame::SetBackgroundColor(uint32_t color)
+{
+ render_frame()->GetWebFrame()->View()->SetBaseBackgroundColorOverride(color);
}
-bool RenderViewObserverQt::OnMessageReceived(const IPC::Message &message)
+void WebEnginePageRenderFrame::OnDestruct()
{
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(RenderViewObserverQt, message)
- IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentMarkup, onFetchDocumentMarkup)
- IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentInnerText, onFetchDocumentInnerText)
- IPC_MESSAGE_HANDLER(RenderViewObserverQt_SetBackgroundColor, onSetBackgroundColor)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
+ delete this;
+}
+
}
diff --git a/src/core/renderer/plugins/plugin_placeholder_qt.cpp b/src/core/renderer/web_engine_page_render_frame.h
index a72c29873..3fb4657c5 100644
--- a/src/core/renderer/plugins/plugin_placeholder_qt.cpp
+++ b/src/core/renderer/web_engine_page_render_frame.h
@@ -36,40 +36,40 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef WEB_ENGINE_PAGE_RENDER_FRAME_H
+#define WEB_ENGINE_PAGE_RENDER_FRAME_H
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+#include "content/public/renderer/render_frame_observer.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "qtwebengine/browser/qtwebenginepage.mojom.h"
-#include "plugin_placeholder_qt.h"
-
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/v8_value_converter.h"
-#include "gin/object_template_builder.h"
+namespace content {
+class RenderFrame;
+}
namespace QtWebEngineCore {
-// static
-gin::WrapperInfo PluginPlaceholderQt::kWrapperInfo = {gin::kEmbedderNativeGin};
-
-PluginPlaceholderQt::PluginPlaceholderQt(content::RenderFrame* render_frame,
- const blink::WebPluginParams& params,
- const std::string& html_data)
- : PluginPlaceholderBase(render_frame, params, html_data)
-{}
-
-PluginPlaceholderQt::~PluginPlaceholderQt() {}
-
-v8::Local<v8::Value> PluginPlaceholderQt::GetV8Handle(v8::Isolate* isolate)
+class WebEnginePageRenderFrame : private content::RenderFrameObserver,
+ public qtwebenginepage::mojom::WebEnginePageRenderFrame
{
- return gin::CreateHandle(isolate, this).ToV8();
-}
+public:
+ WebEnginePageRenderFrame(content::RenderFrame *render_frame);
+ WebEnginePageRenderFrame(const WebEnginePageRenderFrame &) = delete;
+ WebEnginePageRenderFrame &operator=(const WebEnginePageRenderFrame &) = delete;
-gin::ObjectTemplateBuilder PluginPlaceholderQt::GetObjectTemplateBuilder(v8::Isolate* isolate)
-{
- return gin::Wrappable<PluginPlaceholderQt>::GetObjectTemplateBuilder(isolate)
- .SetMethod<void (QtWebEngineCore::PluginPlaceholderQt::*)()>(
- "hide", &PluginPlaceholderQt::HideCallback);
-}
+private:
+ void FetchDocumentMarkup(uint64_t requestId, FetchDocumentMarkupCallback callback) override;
+ void FetchDocumentInnerText(uint64_t requestId,
+ FetchDocumentInnerTextCallback callback) override;
+ void SetBackgroundColor(uint32_t color) override;
+ void OnDestruct() override;
+ void
+ BindReceiver(mojo::PendingAssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame>
+ receiver);
+
+private:
+ mojo::AssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame> m_binding;
+};
+} // namespace
-} // namespace QtWebEngineCore
+#endif // WEB_ENGINE_PAGE_RENDER_FRAME_H
diff --git a/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.cpp b/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.cpp
index d54a9cdf2..8fa277e78 100644
--- a/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.cpp
+++ b/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.cpp
@@ -45,29 +45,22 @@
#include "pepper_flash_browser_host_qt.h"
#include "base/time/time.h"
-#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_ppapi_host.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_process_host.h"
#include "ipc/ipc_message_macros.h"
#include "ppapi/c/pp_errors.h"
-#include "ppapi/c/private/ppb_flash.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
#include "ppapi/shared_impl/time_conversion.h"
#include "qtwebenginecoreglobal_p.h"
-#include "url/gurl.h"
#if defined(OS_WIN)
#include <windows.h>
-#elif defined(OS_MACOSX)
+#elif defined(OS_MAC)
#include <CoreServices/CoreServices.h>
#endif
using content::BrowserPpapiHost;
-using content::BrowserThread;
-using content::RenderProcessHost;
namespace QtWebEngineCore {
@@ -75,11 +68,8 @@ PepperFlashBrowserHostQt::PepperFlashBrowserHostQt(BrowserPpapiHost* host,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
- host_(host),
weak_factory_(this)
{
- int unused;
- host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused);
}
PepperFlashBrowserHostQt::~PepperFlashBrowserHostQt() {}
@@ -109,7 +99,7 @@ int32_t PepperFlashBrowserHostQt::OnUpdateActivity(ppapi::host::HostMessageConte
int value = 0;
if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0))
SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0);
-#elif defined(OS_MACOSX)
+#elif defined(OS_MAC)
UpdateSystemActivity(OverallAct);
#endif
return PP_OK;
diff --git a/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.h b/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.h
index 5d1107dfb..d6d2c8656 100644
--- a/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.h
+++ b/src/core/renderer_host/pepper/pepper_flash_browser_host_qt.h
@@ -40,7 +40,6 @@
#ifndef PEPPER_FLASH_BROWSER_HOST_QT_H
#define PEPPER_FLASH_BROWSER_HOST_QT_H
-#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/resource_host.h"
@@ -51,7 +50,6 @@ class Time;
namespace content {
class BrowserPpapiHost;
-class ResourceContext;
}
class GURL;
@@ -77,12 +75,6 @@ private:
const base::Time& t);
int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context);
- void GetLocalDataRestrictions(ppapi::host::ReplyMessageContext reply_context,
- const GURL& document_url,
- const GURL& plugin_url);
-
- content::BrowserPpapiHost* host_;
- int render_process_id_;
base::WeakPtrFactory<PepperFlashBrowserHostQt> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHostQt);
diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp
index 6b9bb63fe..cea246c37 100644
--- a/src/core/renderer_host/user_resource_controller_host.cpp
+++ b/src/core/renderer_host/user_resource_controller_host.cpp
@@ -48,6 +48,8 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
+#include "qtwebengine/userscript/userscript.mojom.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
namespace QtWebEngineCore {
@@ -59,6 +61,7 @@ public:
// WebContentsObserver overrides:
void RenderFrameCreated(content::RenderFrameHost *renderFrameHost) override;
void RenderFrameHostChanged(content::RenderFrameHost *oldHost, content::RenderFrameHost *newHost) override;
+ void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
void WebContentsDestroyed() override;
private:
@@ -75,16 +78,25 @@ UserResourceControllerHost::WebContentsObserverHelper::WebContentsObserverHelper
void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameCreated(content::RenderFrameHost *renderFrameHost)
{
content::WebContents *contents = web_contents();
+ auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(renderFrameHost);
const QList<UserScript> scripts = m_controllerHost->m_perContentsScripts.value(contents);
for (const UserScript &script : scripts)
- renderFrameHost->Send(new RenderFrameObserverHelper_AddScript(renderFrameHost->GetRoutingID(), script.data()));
+ remote->AddScript(script.data());
}
void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameHostChanged(content::RenderFrameHost *oldHost,
content::RenderFrameHost *newHost)
{
- if (oldHost)
- oldHost->Send(new RenderFrameObserverHelper_ClearScripts(oldHost->GetRoutingID()));
+ if (oldHost) {
+ auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(oldHost);
+ remote->ClearScripts();
+ }
+}
+
+void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameDeleted(
+ content::RenderFrameHost *render_frame_host)
+{
+ m_controllerHost->m_renderFrames.erase(render_frame_host);
}
void UserResourceControllerHost::WebContentsObserverHelper::WebContentsDestroyed()
@@ -111,6 +123,7 @@ UserResourceControllerHost::RenderProcessObserverHelper::RenderProcessObserverHe
void UserResourceControllerHost::RenderProcessObserverHelper::RenderProcessHostDestroyed(content::RenderProcessHost *renderer)
{
Q_ASSERT(m_controllerHost);
+ delete m_controllerHost->m_observedProcesses[renderer];
m_controllerHost->m_observedProcesses.remove(renderer);
}
@@ -123,8 +136,8 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont
if (isProfileWideScript) {
if (!m_profileWideScripts.contains(script)) {
m_profileWideScripts.append(script);
- for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses))
- renderer->Send(new UserResourceController_AddScript(script.data()));
+ for (auto controller : m_observedProcesses.values())
+ (*controller)->AddScript(script.data());
}
} else {
content::WebContents *contents = adapter->webContents();
@@ -141,10 +154,8 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont
m_perContentsScripts.insert(contents, currentScripts);
}
}
- contents->GetRenderViewHost()->Send(
- new RenderFrameObserverHelper_AddScript(
- contents->GetRenderViewHost()->GetMainFrame()->GetRoutingID(),
- script.data()));
+ GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame())
+ ->AddScript(script.data());
}
}
@@ -157,8 +168,8 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC
QList<UserScript>::iterator it = std::find(m_profileWideScripts.begin(), m_profileWideScripts.end(), script);
if (it == m_profileWideScripts.end())
return false;
- for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses))
- renderer->Send(new UserResourceController_RemoveScript((*it).data()));
+ for (auto controller : m_observedProcesses.values())
+ (*controller)->RemoveScript((*it).data());
m_profileWideScripts.erase(it);
} else {
content::WebContents *contents = adapter->webContents();
@@ -168,8 +179,8 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC
QList<UserScript>::iterator it = std::find(list.begin(), list.end(), script);
if (it == list.end())
return false;
- contents->GetRenderViewHost()->Send(
- new RenderFrameObserverHelper_RemoveScript(contents->GetMainFrame()->GetRoutingID(), (*it).data()));
+ GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame())
+ ->RemoveScript((*it).data());
list.erase(it);
}
return true;
@@ -180,13 +191,15 @@ void UserResourceControllerHost::clearAllScripts(WebContentsAdapter *adapter)
const bool isProfileWideScript = !adapter;
if (isProfileWideScript) {
m_profileWideScripts.clear();
- for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses))
- renderer->Send(new UserResourceController_ClearScripts);
+ for (auto controller : m_observedProcesses.values())
+ (*controller)->ClearScripts();
} else {
content::WebContents *contents = adapter->webContents();
m_perContentsScripts.remove(contents);
- contents->GetRenderViewHost()->Send(
- new RenderFrameObserverHelper_ClearScripts(contents->GetMainFrame()->GetRoutingID()));
+ mojo::AssociatedRemote<qtwebengine::mojom::UserResourceControllerRenderFrame>
+ userResourceController;
+ GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame())
+ ->ClearScripts();
}
}
@@ -201,15 +214,18 @@ void UserResourceControllerHost::reserve(WebContentsAdapter *adapter, int count)
void UserResourceControllerHost::renderProcessStartedWithHost(content::RenderProcessHost *renderer)
{
- if (m_observedProcesses.contains(renderer))
+ if (m_observedProcesses.keys().contains(renderer))
return;
if (m_renderProcessObserver.isNull())
m_renderProcessObserver.reset(new RenderProcessObserverHelper(this));
renderer->AddObserver(m_renderProcessObserver.data());
- m_observedProcesses.insert(renderer);
- for (const UserScript &script : qAsConst(m_profileWideScripts))
- renderer->Send(new UserResourceController_AddScript(script.data()));
+ auto userResourceController = new UserResourceControllerRemote;
+ renderer->GetChannel()->GetRemoteAssociatedInterface(userResourceController);
+ m_observedProcesses.insert(renderer, userResourceController);
+ for (const UserScript &script : qAsConst(m_profileWideScripts)) {
+ (*userResourceController)->AddScript(script.data());
+ }
}
void UserResourceControllerHost::webContentsDestroyed(content::WebContents *contents)
@@ -223,8 +239,26 @@ UserResourceControllerHost::UserResourceControllerHost()
UserResourceControllerHost::~UserResourceControllerHost()
{
- for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses))
+ for (content::RenderProcessHost *renderer : m_observedProcesses.keys()) {
renderer->RemoveObserver(m_renderProcessObserver.data());
+ delete m_observedProcesses[renderer];
+ }
+}
+
+const UserResourceControllerRenderFrameRemote &
+UserResourceControllerHost::GetUserResourceControllerRenderFrame(content::RenderFrameHost *rfh)
+{
+ auto it = m_renderFrames.find(rfh);
+ if (it == m_renderFrames.end()) {
+ UserResourceControllerRenderFrameRemote remote;
+ rfh->GetRemoteAssociatedInterfaces()->GetInterface(remote.BindNewEndpointAndPassReceiver());
+ it = m_renderFrames.insert(std::make_pair(rfh, std::move(remote))).first;
+ } else if (it->second.is_bound() && !it->second.is_connected()) {
+ it->second.reset();
+ rfh->GetRemoteAssociatedInterfaces()->GetInterface(&it->second);
+ }
+
+ return it->second;
}
} // namespace
diff --git a/src/core/renderer_host/user_resource_controller_host.h b/src/core/renderer_host/user_resource_controller_host.h
index 7b89cb893..8b6099dcf 100644
--- a/src/core/renderer_host/user_resource_controller_host.h
+++ b/src/core/renderer_host/user_resource_controller_host.h
@@ -53,17 +53,33 @@
#include "qtwebenginecoreglobal_p.h"
-#include <QtCore/QSet>
+#include <QtCore/QHash>
#include <QtCore/QScopedPointer>
+#include <map>
#include "user_script.h"
namespace content {
class RenderProcessHost;
class WebContents;
+class RenderFrameHost;
+}
+
+namespace mojo {
+template <typename Type>
+class AssociatedRemote;
+}
+
+namespace qtwebengine {
+namespace mojom {
+class UserResourceController;
+class UserResourceControllerRenderFrame;
+}
}
namespace QtWebEngineCore {
+using UserResourceControllerRemote = mojo::AssociatedRemote<qtwebengine::mojom::UserResourceController>;
+using UserResourceControllerRenderFrameRemote = mojo::AssociatedRemote<qtwebengine::mojom::UserResourceControllerRenderFrame>;
class WebContentsAdapter;
class Q_WEBENGINECORE_PRIVATE_EXPORT UserResourceControllerHost
@@ -86,12 +102,15 @@ private:
class RenderProcessObserverHelper;
void webContentsDestroyed(content::WebContents *);
+ const UserResourceControllerRenderFrameRemote &
+ GetUserResourceControllerRenderFrame(content::RenderFrameHost *rfh);
QList<UserScript> m_profileWideScripts;
typedef QHash<content::WebContents *, QList<UserScript>> ContentsScriptsMap;
ContentsScriptsMap m_perContentsScripts;
- QSet<content::RenderProcessHost *> m_observedProcesses;
+ QHash<content::RenderProcessHost *, UserResourceControllerRemote *> m_observedProcesses;
QScopedPointer<RenderProcessObserverHelper> m_renderProcessObserver;
+ std::map<content::RenderFrameHost *, UserResourceControllerRenderFrameRemote> m_renderFrames;
};
} // namespace
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
index 9ed3749ad..087e0e83b 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
@@ -96,10 +96,9 @@ void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message)
int size = 0;
const char *rawData = doc.rawData(&size);
content::RenderFrameHost *frame = web_contents()->GetMainFrame();
- mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> webChannelTransport;
- frame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport);
qCDebug(log).nospace() << "sending webchannel message to " << frame << ": " << doc;
- webChannelTransport->DispatchWebChannelMessage(std::vector<uint8_t>(rawData, rawData + size), m_worldId);
+ GetWebChannelIPCTransportRemote(frame)->DispatchWebChannelMessage(
+ std::vector<uint8_t>(rawData, rawData + size), m_worldId);
}
void WebChannelIPCTransportHost::setWorldId(uint32_t worldId)
@@ -116,9 +115,7 @@ void WebChannelIPCTransportHost::setWorldId(content::RenderFrameHost *frame, uin
if (!frame->IsRenderFrameLive())
return;
qCDebug(log).nospace() << "sending setWorldId(" << worldId << ") message to " << frame;
- mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> webChannelTransport;
- frame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport);
- webChannelTransport->SetWorldId(worldId);
+ GetWebChannelIPCTransportRemote(frame)->SetWorldId(worldId);
}
void WebChannelIPCTransportHost::resetWorldId()
@@ -126,9 +123,7 @@ void WebChannelIPCTransportHost::resetWorldId()
for (content::RenderFrameHost *frame : web_contents()->GetAllFrames()) {
if (!frame->IsRenderFrameLive())
return;
- mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> webChannelTransport;
- frame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport);
- webChannelTransport->ResetWorldId();
+ GetWebChannelIPCTransportRemote(frame)->ResetWorldId();
}
}
@@ -156,4 +151,25 @@ void WebChannelIPCTransportHost::RenderFrameCreated(content::RenderFrameHost *fr
setWorldId(frame, m_worldId);
}
+void WebChannelIPCTransportHost::RenderFrameDeleted(content::RenderFrameHost *rfh)
+{
+ m_renderFrames.erase(rfh);
+}
+
+const mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> &
+WebChannelIPCTransportHost::GetWebChannelIPCTransportRemote(content::RenderFrameHost *rfh)
+{
+ auto it = m_renderFrames.find(rfh);
+ if (it == m_renderFrames.end()) {
+ mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> remote;
+ rfh->GetRemoteAssociatedInterfaces()->GetInterface(remote.BindNewEndpointAndPassReceiver());
+ it = m_renderFrames.insert(std::make_pair(rfh, std::move(remote))).first;
+ } else if (it->second.is_bound() && !it->second.is_connected()) {
+ it->second.reset();
+ rfh->GetRemoteAssociatedInterfaces()->GetInterface(&it->second);
+ }
+
+ return it->second;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.h b/src/core/renderer_host/web_channel_ipc_transport_host.h
index a1575355a..d06483ee6 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.h
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.h
@@ -47,6 +47,7 @@
#include "qtwebengine/browser/qtwebchannel.mojom.h"
#include <QWebChannelAbstractTransport>
+#include <map>
QT_FORWARD_DECLARE_CLASS(QString)
@@ -72,8 +73,12 @@ private:
void resetWorldId();
void onWebChannelMessage(const std::vector<char> &message);
+ const mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> &
+ GetWebChannelIPCTransportRemote(content::RenderFrameHost *rfh);
+
// WebContentsObserver
void RenderFrameCreated(content::RenderFrameHost *frame) override;
+ void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
// qtwebchannel::mojom::WebChannelTransportHost
void DispatchWebChannelMessage(const std::vector<uint8_t> &binaryJson) override;
@@ -82,6 +87,9 @@ private:
// WebChannelIPCTransports/RenderFrames in the observed WebContents.
uint32_t m_worldId;
content::WebContentsFrameReceiverSet<qtwebchannel::mojom::WebChannelTransportHost> m_receiver;
+ std::map<content::RenderFrameHost *,
+ mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender>>
+ m_renderFrames;
};
} // namespace
diff --git a/src/core/renderer_host/render_view_observer_host_qt.cpp b/src/core/renderer_host/web_engine_page_host.cpp
index 165a9d86a..36907ef5a 100644
--- a/src/core/renderer_host/render_view_observer_host_qt.cpp
+++ b/src/core/renderer_host/web_engine_page_host.cpp
@@ -37,59 +37,76 @@
**
****************************************************************************/
-#include "render_view_observer_host_qt.h"
+#include "web_engine_page_host.h"
-#include "common/qt_messages.h"
-#include "content/public/browser/render_view_host.h"
+#include "qtwebengine/browser/qtwebenginepage.mojom.h"
#include "content/public/browser/web_contents.h"
#include "render_widget_host_view_qt.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
namespace QtWebEngineCore {
-RenderViewObserverHostQt::RenderViewObserverHostQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
- : content::WebContentsObserver(webContents)
- , m_adapterClient(adapterClient)
+WebEnginePageHost::WebEnginePageHost(content::WebContents *webContents,
+ WebContentsAdapterClient *adapterClient)
+ : content::WebContentsObserver(webContents), m_adapterClient(adapterClient)
{
}
-void RenderViewObserverHostQt::fetchDocumentMarkup(quint64 requestId)
+void WebEnginePageHost::FetchDocumentMarkup(uint64_t requestId)
{
- web_contents()->GetRenderViewHost()->Send(
- new RenderViewObserverQt_FetchDocumentMarkup(
- web_contents()->GetRenderViewHost()->GetRoutingID(), requestId));
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ remote->FetchDocumentMarkup(
+ requestId,
+ base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentMarkup, base::Unretained(this)));
}
-void RenderViewObserverHostQt::fetchDocumentInnerText(quint64 requestId)
+void WebEnginePageHost::FetchDocumentInnerText(uint64_t requestId)
{
- web_contents()->GetRenderViewHost()->Send(
- new RenderViewObserverQt_FetchDocumentInnerText(
- web_contents()->GetRenderViewHost()->GetRoutingID(), requestId));
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ remote->FetchDocumentInnerText(requestId,
+ base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentInnerText,
+ base::Unretained(this)));
}
-bool RenderViewObserverHostQt::OnMessageReceived(const IPC::Message &message)
+void WebEnginePageHost::OnDidFetchDocumentMarkup(uint64_t requestId, const std::string &markup)
{
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(RenderViewObserverHostQt, message)
- IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentMarkup,
- onDidFetchDocumentMarkup)
- IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentInnerText,
- onDidFetchDocumentInnerText)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
+ m_adapterClient->didFetchDocumentMarkup(requestId, toQt(markup));
}
-void RenderViewObserverHostQt::onDidFetchDocumentMarkup(quint64 requestId, const base::string16 &markup)
+void WebEnginePageHost::OnDidFetchDocumentInnerText(uint64_t requestId,
+ const std::string &innerText)
{
- m_adapterClient->didFetchDocumentMarkup(requestId, toQt(markup));
+ m_adapterClient->didFetchDocumentInnerText(requestId, toQt(innerText));
}
-void RenderViewObserverHostQt::onDidFetchDocumentInnerText(quint64 requestId, const base::string16 &innerText)
+void WebEnginePageHost::RenderFrameDeleted(content::RenderFrameHost *render_frame)
{
- m_adapterClient->didFetchDocumentInnerText(requestId, toQt(innerText));
+ m_renderFrames.erase(render_frame);
+}
+
+void WebEnginePageHost::SetBackgroundColor(uint32_t color)
+{
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ remote->SetBackgroundColor(color);
+}
+
+const WebEnginePageRenderFrameRemote &
+WebEnginePageHost::GetWebEnginePageRenderFrame(content::RenderFrameHost *rfh)
+{
+ auto it = m_renderFrames.find(rfh);
+ if (it == m_renderFrames.end()) {
+ WebEnginePageRenderFrameRemote remote;
+ rfh->GetRemoteAssociatedInterfaces()->GetInterface(remote.BindNewEndpointAndPassReceiver());
+ it = m_renderFrames.insert(std::make_pair(rfh, std::move(remote))).first;
+ } else if (it->second.is_bound() && !it->second.is_connected()) {
+ it->second.reset();
+ rfh->GetRemoteAssociatedInterfaces()->GetInterface(&it->second);
+ }
+
+ return it->second;
}
} // namespace QtWebEngineCore
diff --git a/src/core/renderer_host/web_engine_page_host.h b/src/core/renderer_host/web_engine_page_host.h
new file mode 100644
index 000000000..f305d22ea
--- /dev/null
+++ b/src/core/renderer_host/web_engine_page_host.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef WEB_ENGINE_PAGE_HOST_H
+#define WEB_ENGINE_PAGE_HOST_H
+
+#include "content/public/browser/web_contents_observer.h"
+
+#include <QtGlobal>
+
+namespace content {
+class WebContents;
+}
+
+namespace mojo {
+template<typename Type>
+class AssociatedRemote;
+}
+
+namespace qtwebenginepage {
+namespace mojom {
+class WebEnginePageRenderFrame;
+}
+}
+
+namespace QtWebEngineCore {
+
+using WebEnginePageRenderFrameRemote = mojo::AssociatedRemote<qtwebenginepage::mojom::WebEnginePageRenderFrame>;
+
+class WebContentsAdapterClient;
+
+class WebEnginePageHost : public content::WebContentsObserver
+{
+public:
+ WebEnginePageHost(content::WebContents *, WebContentsAdapterClient *adapterClient);
+ void FetchDocumentMarkup(uint64_t requestId);
+ void FetchDocumentInnerText(uint64_t requestId);
+ void RenderFrameDeleted(content::RenderFrameHost *render_frame) override;
+ void SetBackgroundColor(uint32_t color);
+
+private:
+ void OnDidFetchDocumentMarkup(uint64_t requestId, const std::string &markup);
+ void OnDidFetchDocumentInnerText(uint64_t requestId, const std::string &innerText);
+ const WebEnginePageRenderFrameRemote &
+ GetWebEnginePageRenderFrame(content::RenderFrameHost *rfh);
+
+private:
+ WebContentsAdapterClient *m_adapterClient;
+ std::map<content::RenderFrameHost *, WebEnginePageRenderFrameRemote> m_renderFrames;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // WEB_ENGINE_PAGE_HOST_H
diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp
index 22b40a7ba..4e814a806 100644
--- a/src/core/resource_bundle_qt.cpp
+++ b/src/core/resource_bundle_qt.cpp
@@ -38,9 +38,12 @@
****************************************************************************/
#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/notreached.h"
#include "content/public/common/content_switches.h"
-#include "services/service_manager/sandbox/switches.h"
+#include "sandbox/policy/switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/data_pack.h"
#include "ui/base/resource/resource_bundle.h"
@@ -75,7 +78,7 @@ bool ResourceBundle::LocaleDataPakExists(const std::string& locale)
#if defined(OS_LINUX)
base::CommandLine *parsed_command_line = base::CommandLine::ForCurrentProcess();
std::string process_type = parsed_command_line->GetSwitchValueASCII(switches::kProcessType);
- bool no_sandbox = parsed_command_line->HasSwitch(service_manager::switches::kNoSandbox);
+ bool no_sandbox = parsed_command_line->HasSwitch(sandbox::policy::switches::kNoSandbox);
if (process_type == switches::kRendererProcess && !no_sandbox) {
// The Renderer Process is sandboxed thus only one locale is available in it.
// The particular one is passed by the --lang command line option.
@@ -87,14 +90,15 @@ bool ResourceBundle::LocaleDataPakExists(const std::string& locale)
}
#endif
- return !GetLocaleFilePath(locale).empty();
+ const auto path = GetLocaleFilePath(locale);
+ return !path.empty() && base::PathExists(path);
}
-std::string ResourceBundle::LoadLocaleResources(const std::string& pref_locale)
+std::string ResourceBundle::LoadLocaleResources(const std::string &pref_locale, bool /*crash_on_failure*/)
{
DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded";
- std::string app_locale = l10n_util::GetApplicationLocale(pref_locale);
+ std::string app_locale = l10n_util::GetApplicationLocale(pref_locale, false /* set_icu_locale */);
#if defined(OS_LINUX)
int locale_fd = base::GlobalDescriptors::GetInstance()->MaybeGet(kWebEngineLocale);
diff --git a/src/core/resource_context_qt.h b/src/core/resource_context_qt.h
index 4107e7c24..efd3d2e7e 100644
--- a/src/core/resource_context_qt.h
+++ b/src/core/resource_context_qt.h
@@ -42,21 +42,6 @@
#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;
diff --git a/src/core/touch_selection_controller_client_qt.cpp b/src/core/touch_selection_controller_client_qt.cpp
index 0f44210d1..ef7b22ecc 100644
--- a/src/core/touch_selection_controller_client_qt.cpp
+++ b/src/core/touch_selection_controller_client_qt.cpp
@@ -45,7 +45,7 @@
#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_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -229,29 +229,29 @@ void TouchSelectionControllerClientQt::SetNeedsAnimate()
void TouchSelectionControllerClientQt::MoveCaret(const gfx::PointF& position)
{
- content::mojom::FrameInputHandler *frameInputHandler = m_rwhv->getFrameInputHandler();
- if (!frameInputHandler)
+ auto *frameWidgetInputHandler = m_rwhv->getFrameWidgetInputHandler();
+ if (!frameWidgetInputHandler)
return;
- frameInputHandler->MoveCaret(gfx::ToRoundedPoint(position));
+ frameWidgetInputHandler->MoveCaret(gfx::ToRoundedPoint(position));
}
void TouchSelectionControllerClientQt::MoveRangeSelectionExtent(const gfx::PointF& extent)
{
- content::mojom::FrameInputHandler *frameInputHandler = m_rwhv->getFrameInputHandler();
- if (!frameInputHandler)
+ auto *frameWidgetInputHandler = m_rwhv->getFrameWidgetInputHandler();
+ if (!frameWidgetInputHandler)
return;
- frameInputHandler->MoveRangeSelectionExtent(gfx::ToRoundedPoint(extent));
+ frameWidgetInputHandler->MoveRangeSelectionExtent(gfx::ToRoundedPoint(extent));
}
void TouchSelectionControllerClientQt::SelectBetweenCoordinates(const gfx::PointF& base, const gfx::PointF& extent)
{
- content::mojom::FrameInputHandler *frameInputHandler = m_rwhv->getFrameInputHandler();
- if (!frameInputHandler)
+ auto *frameWidgetInputHandler = m_rwhv->getFrameWidgetInputHandler();
+ if (!frameWidgetInputHandler)
return;
- frameInputHandler->SelectRange(gfx::ToRoundedPoint(base), gfx::ToRoundedPoint(extent));
+ frameWidgetInputHandler->SelectRange(gfx::ToRoundedPoint(base), gfx::ToRoundedPoint(extent));
}
void TouchSelectionControllerClientQt::OnSelectionEvent(ui::SelectionEventType event)
diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index 1d8d63257..3723f97ea 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -133,6 +133,21 @@ QImage toQImage(const SkBitmap &bitmap)
break;
}
break;
+ case kBGR_101010x_SkColorType:
+ case kBGRA_1010102_SkColorType:
+ switch (bitmap.alphaType()) {
+ case kUnknown_SkAlphaType:
+ break;
+ case kUnpremul_SkAlphaType:
+ // not supported - treat as opaque
+ case kOpaque_SkAlphaType:
+ image = toQImage(bitmap, QImage::Format_BGR30);
+ break;
+ case kPremul_SkAlphaType:
+ image = toQImage(bitmap, QImage::Format_A2BGR30_Premultiplied);
+ break;
+ }
+ break;
case kGray_8_SkColorType:
image = toQImage(bitmap, QImage::Format_Grayscale8);
break;
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 83a499284..1152ed9a9 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -52,7 +52,6 @@
#include <base/strings/nullable_string16.h>
#include "base/files/file_path.h"
#include "base/time/time.h"
-#include "content/public/common/file_chooser_file_info.h"
#include "favicon_manager.h"
#include "net/cookies/canonical_cookie.h"
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h"
@@ -86,6 +85,17 @@ inline QString toQt(const base::string16 &string)
#endif
}
+inline QString toQt(const base::Optional<base::string16> &string)
+{
+ if (!string.has_value())
+ return QString();
+#if defined(OS_WIN)
+ return QString::fromStdWString(string->data());
+#else
+ return QString::fromUtf16(string->data());
+#endif
+}
+
inline QString toQString(const std::string &string)
{
return QString::fromStdString(string);
@@ -116,6 +126,13 @@ inline base::NullableString16 toNullableString16(const QString &qString)
return base::NullableString16(toString16(qString), qString.isNull());
}
+inline base::Optional<base::string16> toOptionalString16(const QString &qString)
+{
+ if (qString.isNull())
+ return base::nullopt;
+ return base::make_optional(toString16(qString));
+}
+
inline QUrl toQt(const GURL &url)
{
if (url.is_valid())
@@ -243,43 +260,6 @@ inline base::FilePath toFilePath(const QString &str)
return base::FilePath(toFilePathString(str));
}
-template <typename T>
-inline T fileListingHelper(const QString &)
-// Clang is still picky about this though it should be supported eventually.
-// See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#941
-#ifndef Q_CC_CLANG
-= delete;
-#else
-{ return T(); }
-#endif
-
-template <>
-inline content::FileChooserFileInfo fileListingHelper<content::FileChooserFileInfo>(const QString &file)
-{
- content::FileChooserFileInfo choose_file;
- base::FilePath fp(toFilePath(file));
- choose_file.file_path = fp;
- choose_file.display_name = fp.BaseName().value();
- return choose_file;
-}
-
-template <>
-inline base::FilePath fileListingHelper<base::FilePath>(const QString &file)
-{
- return base::FilePath(toFilePathString(file));
-}
-
-
-template <typename T>
-inline std::vector<T> toVector(const QStringList &fileList)
-{
- std::vector<T> selectedFiles;
- selectedFiles.reserve(fileList.size());
- for (const QString &file : fileList)
- selectedFiles.push_back(fileListingHelper<T>(file));
- return selectedFiles;
-}
-
int flagsFromModifiers(Qt::KeyboardModifiers modifiers);
inline QStringList fromVector(const std::vector<base::string16> &vector)
diff --git a/src/core/user_notification_controller.h b/src/core/user_notification_controller.h
index bab85c7ec..f0d7e348f 100644
--- a/src/core/user_notification_controller.h
+++ b/src/core/user_notification_controller.h
@@ -44,7 +44,7 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QUrl>
-#include <QtGui/QIcon>
+#include <QtGui/QImage>
class GURL;
diff --git a/src/core/user_script.cpp b/src/core/user_script.cpp
index 912b204b7..f4daaf7c6 100644
--- a/src/core/user_script.cpp
+++ b/src/core/user_script.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "common/user_script_data.h"
+#include "qtwebengine/userscript/user_script_data.h"
#include "user_script.h"
#include "type_conversion.h"
@@ -178,8 +178,11 @@ bool UserScript::operator==(const UserScript &other) const
void UserScript::initData()
{
- if (scriptData.isNull())
+ static uint64_t idCount = 0;
+ if (scriptData.isNull()) {
scriptData.reset(new UserScriptData);
+ scriptData->scriptId = idCount++;
+ }
}
bool UserScript::isNull() const
@@ -231,10 +234,10 @@ void UserScript::parseMetadataHeader()
line = base::StringPiece(script_text.data() + line_start, line_end - line_start);
if (!in_metadata) {
- if (line.starts_with(kUserScriptBegin))
+ if (base::StartsWith(line, kUserScriptBegin))
in_metadata = true;
} else {
- if (line.starts_with(kUserScriptEnd))
+ if (base::StartsWith(line, kUserScriptEnd))
break;
std::string value;
diff --git a/src/core/user_script.h b/src/core/user_script.h
index 8f65f4b74..e06141259 100644
--- a/src/core/user_script.h
+++ b/src/core/user_script.h
@@ -57,10 +57,9 @@
#include <QtCore/QSharedData>
#include <QtCore/QString>
-struct UserScriptData;
namespace QtWebEngineCore {
-
+struct UserScriptData;
class UserResourceControllerHost;
class Q_WEBENGINECORE_PRIVATE_EXPORT UserScript : public QSharedData {
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index a44b3316e..cca31e144 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -53,7 +53,7 @@
#include "profile_adapter.h"
#include "profile_qt.h"
#include "qwebenginecallback_p.h"
-#include "renderer_host/render_view_observer_host_qt.h"
+#include "renderer_host/web_engine_page_host.h"
#include "render_widget_host_view_qt.h"
#include "type_conversion.h"
#include "web_contents_view_qt.h"
@@ -61,13 +61,14 @@
#include "web_engine_settings.h"
#include "base/command_line.h"
+#include "base/metrics/user_metrics.h"
#include "base/run_loop.h"
+#include "base/task/current_thread.h"
#include "base/task/post_task.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/values.h"
#include "chrome/browser/tab_contents/form_interaction_tab_helper.h"
-#include "components/performance_manager/embedder/performance_manager_registry.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -86,16 +87,17 @@
#include "content/public/common/page_state.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/url_constants.h"
-#include "content/public/common/web_preferences.h"
#include "extensions/buildflags/buildflags.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h"
+#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/frame/media_player_action.mojom.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"
+#include "qtwebengine/browser/qtwebenginepage.mojom.h"
#if QT_CONFIG(webengine_webchannel)
#include "renderer_host/web_channel_ipc_transport_host.h"
@@ -371,15 +373,18 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
}
}
-static void Navigate(WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams &params)
+namespace {
+
+void Navigate(WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams &params)
{
Q_ASSERT(adapter);
adapter->webContents()->GetController().LoadURLWithParams(params);
adapter->focusIfNecessary();
adapter->resetSelection();
+ adapter->findTextHelper()->stopFinding();
}
-static void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams &params)
+void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams &params)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
const auto adapter = weakAdapter.toStrongRef();
@@ -388,7 +393,6 @@ static void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const con
Navigate(adapter.get(), params);
}
-namespace {
static QList<WebContentsAdapter *> recursive_guard_loading_adapters;
class LoadRecursionGuard {
@@ -449,7 +453,7 @@ WebContentsAdapter::WebContentsAdapter()
#endif
, m_adapterClient(nullptr)
, m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
- , m_currentDropAction(blink::kWebDragOperationNone)
+ , m_currentDropAction(blink::kDragOperationNone)
, m_devToolsFrontend(nullptr)
{
// This has to be the first thing we create, and the last we destroy.
@@ -465,7 +469,7 @@ WebContentsAdapter::WebContentsAdapter(std::unique_ptr<content::WebContents> web
#endif
, m_adapterClient(nullptr)
, m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
- , m_currentDropAction(blink::kWebDragOperationNone)
+ , m_currentDropAction(blink::kDragOperationNone)
, m_devToolsFrontend(nullptr)
{
// This has to be the first thing we create, and the last we destroy.
@@ -511,7 +515,7 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
// Create and attach observers to the WebContents.
m_webContentsDelegate.reset(new WebContentsDelegateQt(m_webContents.get(), m_adapterClient));
- m_renderViewObserverHost.reset(new RenderViewObserverHostQt(m_webContents.get(), m_adapterClient));
+ m_pageHost.reset(new WebEnginePageHost(m_webContents.get(), m_adapterClient));
// Let the WebContent's view know about the WebContentsAdapterClient.
WebContentsViewQt* contentsView = static_cast<WebContentsViewQt*>(static_cast<content::WebContentsImpl*>(m_webContents.get())->GetView());
@@ -526,9 +530,6 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionWebContentsObserverQt::CreateForWebContents(webContents());
#endif
- FormInteractionTabHelper::CreateForWebContents(webContents());
- if (auto *performance_manager_registry = performance_manager::PerformanceManagerRegistry::GetInstance())
- performance_manager_registry->CreatePageNodeForWebContents(webContents());
// Create an instance of WebEngineVisitedLinksManager to catch the first
// content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will
@@ -540,7 +541,8 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
if (!rvh->IsRenderViewLive())
- static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, base::UnguessableToken::Create(), content::FrameReplicationState());
+ static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager(
+ rvh, base::nullopt, MSG_ROUTING_NONE);
m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh);
@@ -602,8 +604,9 @@ bool WebContentsAdapter::canGoToOffset(int offset) const
void WebContentsAdapter::stop()
{
CHECK_INITIALIZED();
- content::NavigationController& controller = m_webContents->GetController();
+ base::RecordAction(base::UserMetricsAction("Stop"));
+ content::NavigationController& controller = m_webContents->GetController();
int index = controller.GetPendingEntryIndex();
if (index != -1)
controller.RemoveEntryAtIndex(index);
@@ -615,6 +618,8 @@ void WebContentsAdapter::stop()
void WebContentsAdapter::reload()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Reload"));
+
bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
setLifecycleState(LifecycleState::Active);
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
@@ -628,6 +633,8 @@ void WebContentsAdapter::reload()
void WebContentsAdapter::reloadAndBypassCache()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("ReloadBypassingCache"));
+
bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
setLifecycleState(LifecycleState::Active);
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
@@ -652,6 +659,7 @@ void WebContentsAdapter::load(const QUrl &url)
void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
{
+ base::RecordAction(base::UserMetricsAction("LoadURL"));
GURL gurl = toGurl(request.url());
if (!isInitialized()) {
scoped_refptr<content::SiteInstance> site =
@@ -706,9 +714,9 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
// chromium accepts LOAD_TYPE_HTTP_POST only for the HTTP and HTTPS protocols
if (!params.url.SchemeIsHTTPOrHTTPS()) {
m_adapterClient->loadFinished(false, request.url(), false,
- net::ERR_DISALLOWED_URL_SCHEME,
- QCoreApplication::translate("WebContentsAdapter",
- "HTTP-POST data can only be sent over HTTP(S) protocol"));
+ net::ERR_DISALLOWED_URL_SCHEME,
+ QCoreApplication::translate("WebContentsAdapter",
+ "HTTP-POST data can only be sent over HTTP(S) protocol"));
return;
}
params.post_data = network::ResourceRequestBody::CreateFromBytes(
@@ -764,7 +772,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
GURL dataUrlToLoad(urlString);
if (dataUrlToLoad.spec().size() > url::kMaxURLChars) {
- m_adapterClient->loadFinished(false, baseUrl, false, net::ERR_ABORTED);
+ m_adapterClient->loadFinished(false, baseUrl, false, net::ERR_ABORTED, QString());
return;
}
content::NavigationController::LoadURLParams params((dataUrlToLoad));
@@ -780,6 +788,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("SavePage"));
m_webContentsDelegate->setSavePageInfo(SavePageInfo(filePath, savePageFormat));
m_webContents->OnSavePage();
}
@@ -834,42 +843,49 @@ QString WebContentsAdapter::selectedText() const
void WebContentsAdapter::undo()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Undo"));
m_webContents->Undo();
}
void WebContentsAdapter::redo()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Redo"));
m_webContents->Redo();
}
void WebContentsAdapter::cut()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Cut"));
m_webContents->Cut();
}
void WebContentsAdapter::copy()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Copy"));
m_webContents->Copy();
}
void WebContentsAdapter::paste()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Paste"));
m_webContents->Paste();
}
void WebContentsAdapter::pasteAndMatchStyle()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("PasteAndMatchStyle"));
m_webContents->PasteAndMatchStyle();
}
void WebContentsAdapter::selectAll()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("SelectAll"));
m_webContents->SelectAll();
}
@@ -888,6 +904,7 @@ void WebContentsAdapter::unselect()
void WebContentsAdapter::navigateBack()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Back"));
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
if (!m_webContents->GetController().CanGoBack())
return;
@@ -898,6 +915,7 @@ void WebContentsAdapter::navigateBack()
void WebContentsAdapter::navigateForward()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("Forward"));
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
if (!m_webContents->GetController().CanGoForward())
return;
@@ -1052,13 +1070,10 @@ void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldI
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
// static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame())->NotifyUserActivation();
- if (worldId == 0) {
+ if (worldId == 0)
rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), base::NullCallback());
- return;
- }
-
- content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, CallbackDirectory::NoCallbackId);
- rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId);
+ else
+ rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), base::NullCallback(), worldId);
}
quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId)
@@ -1078,21 +1093,21 @@ quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScrip
quint64 WebContentsAdapter::fetchDocumentMarkup()
{
CHECK_INITIALIZED(0);
- m_renderViewObserverHost->fetchDocumentMarkup(m_nextRequestId);
+ m_pageHost->FetchDocumentMarkup(m_nextRequestId);
return m_nextRequestId++;
}
quint64 WebContentsAdapter::fetchDocumentInnerText()
{
CHECK_INITIALIZED(0);
- m_renderViewObserverHost->fetchDocumentInnerText(m_nextRequestId);
+ m_pageHost->FetchDocumentInnerText(m_nextRequestId);
return m_nextRequestId++;
}
-void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & webPreferences)
+void WebContentsAdapter::updateWebPreferences(const blink::web_pref::WebPreferences &webPreferences)
{
CHECK_INITIALIZED();
- m_webContents->GetRenderViewHost()->UpdateWebkitPreferences(webPreferences);
+ m_webContents->SetWebPreferences(webPreferences);
// In case of updating preferences during navigation, there might be a pending RVH what will
// be active on successful navigation.
@@ -1100,7 +1115,7 @@ void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & we
if (pendingRFH) {
content::RenderViewHost *pendingRVH = pendingRFH->GetRenderViewHost();
Q_ASSERT(pendingRVH);
- pendingRVH->UpdateWebkitPreferences(webPreferences);
+ static_cast<content::RenderViewHostImpl*>(pendingRVH)->SendWebPreferencesToRenderer();
}
}
@@ -1287,12 +1302,14 @@ void WebContentsAdapter::devToolsFrontendDestroyed(DevToolsFrontendQt *frontend)
void WebContentsAdapter::exitFullScreen()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("ToggleFullscreen"));
m_webContents->ExitFullscreen(false);
}
void WebContentsAdapter::changedFullScreen()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("ToggleFullscreen"));
m_webContents->NotifyFullscreenChanged(false);
}
@@ -1315,10 +1332,13 @@ void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString
PrintViewManagerQt::PrintToPDFFileCallback callback = base::Bind(&callbackOnPdfSavingFinished,
m_adapterClient,
filePath);
- PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFFileWithCallback(pageLayout,
- true,
- filePath,
- callback);
+ content::WebContents *webContents = m_webContents.get();
+ if (content::WebContents *guest = guestWebContents())
+ webContents = guest;
+ PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFFileWithCallback(pageLayout,
+ true,
+ filePath,
+ callback);
#endif // QT_CONFIG(webengine_printing_and_pdf)
}
@@ -1331,10 +1351,13 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo
PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished,
m_adapterClient,
m_nextRequestId);
- PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFWithCallback(pageLayout,
- colorMode,
- useCustomMargins,
- callback);
+ content::WebContents *webContents = m_webContents.get();
+ if (content::WebContents *guest = guestWebContents())
+ webContents = guest;
+ PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFWithCallback(pageLayout,
+ colorMode,
+ useCustomMargins,
+ callback);
return m_nextRequestId++;
#else
Q_UNUSED(pageLayout);
@@ -1415,8 +1438,11 @@ void WebContentsAdapter::handlePendingMouseLockPermission()
void WebContentsAdapter::setBackgroundColor(const QColor &color)
{
CHECK_INITIALIZED();
+ SkColor c = toSk(color);
if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView())
- rwhv->SetBackgroundColor(toSk(color));
+ rwhv->SetBackgroundColor(c);
+ if (color != Qt::transparent)
+ m_pageHost->SetBackgroundColor(c);
}
content::WebContents *WebContentsAdapter::webContents() const
@@ -1424,6 +1450,12 @@ content::WebContents *WebContentsAdapter::webContents() const
return m_webContents.get();
}
+content::WebContents *WebContentsAdapter::guestWebContents() const
+{
+ std::vector<content::WebContents *> innerWebContents = m_webContents->GetInnerWebContents();
+ return !innerWebContents.empty() ? innerWebContents[0] : nullptr;
+}
+
#if QT_CONFIG(webengine_webchannel)
QWebChannel *WebContentsAdapter::webChannel() const
{
@@ -1460,12 +1492,14 @@ void WebContentsAdapter::setWebChannel(QWebChannel *channel, uint worldId)
static QMimeData *mimeDataFromDropData(const content::DropData &dropData)
{
QMimeData *mimeData = new QMimeData();
- if (!dropData.text.is_null())
- mimeData->setText(toQt(dropData.text.string()));
- if (!dropData.html.is_null())
- mimeData->setHtml(toQt(dropData.html.string()));
- if (dropData.url.is_valid())
+ if (dropData.text.has_value())
+ mimeData->setText(toQt(*dropData.text));
+ if (dropData.html.has_value())
+ mimeData->setHtml(toQt(*dropData.html));
+ if (dropData.url.is_valid()) {
mimeData->setUrls(QList<QUrl>() << toQt(dropData.url));
+ mimeData->setText(toQt(dropData.url_title));
+ }
if (!dropData.custom_data.empty()) {
base::Pickle pickle;
ui::WriteCustomDataToPickle(dropData.custom_data, &pickle);
@@ -1474,16 +1508,16 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData)
return mimeData;
}
-static blink::WebDragOperationsMask toWeb(const Qt::DropActions action)
+static blink::DragOperationsMask toWeb(const Qt::DropActions action)
{
- int result = blink::kWebDragOperationNone;
+ int result = blink::kDragOperationNone;
if (action & Qt::CopyAction)
- result |= blink::kWebDragOperationCopy;
+ result |= blink::kDragOperationCopy;
if (action & Qt::LinkAction)
- result |= blink::kWebDragOperationLink;
+ result |= blink::kDragOperationLink;
if (action & Qt::MoveAction)
- result |= blink::kWebDragOperationMove;
- return static_cast<blink::WebDragOperationsMask>(result);
+ result |= blink::kDragOperationMove;
+ return static_cast<blink::DragOperationsMask>(result);
}
void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropData &dropData,
@@ -1502,7 +1536,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
m_currentDropData->file_contents.clear();
m_currentDropData->file_contents_content_disposition.clear();
- m_currentDropAction = blink::kWebDragOperationNone;
+ m_currentDropAction = blink::kDragOperationNone;
QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation
bool dValid = true;
QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){
@@ -1520,18 +1554,25 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
}
{
- base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
+ base::CurrentThread::ScopedNestableTaskAllower allow;
drag->exec(allowedActions);
}
QObject::disconnect(onDestroyed);
if (dValid) {
if (m_webContents) {
- content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
+ // This is the quickest and (at the moment) the most safe solution to not break guest views when
+ // dropping data into them. We don't even try to support dropping into PDF input fields,
+ // since it's not working in Chrome right now.
+ content::WebContents *targetWebContents = m_webContents.get();
+ if (content::WebContents *guest = guestWebContents())
+ targetWebContents = guest;
+
+ content::RenderViewHost *rvh = targetWebContents->GetRenderViewHost();
if (rvh) {
rvh->GetWidget()->DragSourceEndedAt(gfx::PointF(m_lastDragClientPos.x(), m_lastDragClientPos.y()),
gfx::PointF(m_lastDragScreenPos.x(), m_lastDragScreenPos.y()),
- blink::WebDragOperation(m_currentDropAction));
+ blink::DragOperation(m_currentDropAction));
rvh->GetWidget()->DragSourceSystemDragEnded();
}
}
@@ -1582,23 +1623,28 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
}
if (!dropData->filenames.empty())
return;
+ if (mimeData->hasUrls()) {
+ dropData->url = toGurl(urls.first());
+ if (mimeData->hasText())
+ dropData->url_title = toString16(mimeData->text());
+ }
if (mimeData->hasHtml())
- dropData->html = toNullableString16(mimeData->html());
+ dropData->html = toOptionalString16(mimeData->html());
if (mimeData->hasText())
- dropData->text = toNullableString16(mimeData->text());
+ dropData->text = toOptionalString16(mimeData->text());
if (mimeData->hasFormat(QLatin1String(ui::kMimeTypeWebCustomData))) {
QByteArray customData = mimeData->data(QLatin1String(ui::kMimeTypeWebCustomData));
ui::ReadCustomDataIntoMap(customData.constData(), customData.length(), &dropData->custom_data);
}
}
-Qt::DropAction toQt(blink::WebDragOperation op)
+Qt::DropAction toQt(blink::DragOperation op)
{
- if (op & blink::kWebDragOperationCopy)
+ if (op & blink::kDragOperationCopy)
return Qt::CopyAction;
- if (op & blink::kWebDragOperationLink)
+ if (op & blink::kDragOperationLink)
return Qt::LinkAction;
- if (op & blink::kWebDragOperationMove || op & blink::kWebDragOperationDelete)
+ if (op & blink::kDragOperationMove || op & blink::kDragOperationDelete)
return Qt::MoveAction;
return Qt::IgnoreAction;
}
@@ -1655,7 +1701,7 @@ Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const Q
rvh->GetWidget()->DragTargetDragOver(toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos), toWeb(e->possibleActions()),
toWeb(e->mouseButtons()) | toWeb(e->keyboardModifiers()));
waitForUpdateDragActionCalled();
- return toQt(blink::WebDragOperation(m_currentDropAction));
+ return toQt(blink::DragOperation(m_currentDropAction));
}
void WebContentsAdapter::waitForUpdateDragActionCalled()
@@ -1664,7 +1710,7 @@ void WebContentsAdapter::waitForUpdateDragActionCalled()
const qint64 timeout = 3000;
QElapsedTimer t;
t.start();
- auto seqMan = base::MessageLoopCurrent::GetCurrentSequenceManagerImpl();
+ auto seqMan = base::CurrentThread::GetCurrentSequenceManagerImpl();
base::MessagePump::Delegate *delegate =
static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
seqMan->controller_.get());
@@ -1688,7 +1734,7 @@ void WebContentsAdapter::updateDragAction(int action)
{
CHECK_INITIALIZED();
m_updateDragActionCalled = true;
- m_currentDropAction = static_cast<blink::WebDragOperation>(action);
+ m_currentDropAction = static_cast<blink::DragOperation>(action);
}
void WebContentsAdapter::endDragging(QDropEvent *e, const QPointF &screenPos)
@@ -1793,6 +1839,7 @@ FindTextHelper *WebContentsAdapter::findTextHelper()
void WebContentsAdapter::viewSource()
{
CHECK_INITIALIZED();
+ base::RecordAction(base::UserMetricsAction("ViewSource"));
m_webContents->GetMainFrame()->ViewSource();
}
@@ -1965,6 +2012,7 @@ void WebContentsAdapter::discard()
if (m_webContents->IsLoading()) {
m_webContentsDelegate->didFailLoad(m_webContentsDelegate->url(webContents()), net::Error::ERR_ABORTED,
QStringLiteral("Discarded"));
+ m_webContentsDelegate->DidStopLoading();
}
content::WebContents::CreateParams createParams(m_profileAdapter->profile());
@@ -1990,14 +2038,14 @@ void WebContentsAdapter::discard()
m_webChannel = nullptr;
m_webChannelWorld = 0;
#endif
- m_renderViewObserverHost.reset();
+ m_pageHost.reset();
m_webContentsDelegate.reset();
m_webContents.reset();
m_webContents = std::move(nullContents);
initializeRenderPrefs();
m_webContentsDelegate = std::move(nullDelegate);
- m_renderViewObserverHost.reset(new RenderViewObserverHostQt(m_webContents.get(), m_adapterClient));
+ m_pageHost.reset(new WebEnginePageHost(m_webContents.get(), m_adapterClient));
WebContentsViewQt *contentsView =
static_cast<WebContentsViewQt *>(static_cast<content::WebContentsImpl *>(m_webContents.get())->GetView());
contentsView->setClient(m_adapterClient);
@@ -2007,9 +2055,6 @@ void WebContentsAdapter::discard()
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionWebContentsObserverQt::CreateForWebContents(webContents());
#endif
- FormInteractionTabHelper::CreateForWebContents(webContents());
- if (auto *performance_manager_registry = performance_manager::PerformanceManagerRegistry::GetInstance())
- performance_manager_registry->CreatePageNodeForWebContents(webContents());
}
void WebContentsAdapter::undiscard()
@@ -2021,9 +2066,7 @@ void WebContentsAdapter::undiscard()
Q_ASSERT(rvh);
if (!rvh->IsRenderViewLive())
static_cast<content::WebContentsImpl *>(m_webContents.get())
- ->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
- base::UnguessableToken::Create(),
- content::FrameReplicationState());
+ ->CreateRenderViewForRenderManager(rvh, base::nullopt, MSG_ROUTING_NONE);
m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh);
m_adapterClient->initializationFinished();
m_adapterClient->selectionChanged();
@@ -2049,6 +2092,6 @@ ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, network::mojom::Referr
//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)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, network::mojom::ReferrerPolicy::kMaxValue)
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index d833314f2..ba02a0418 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -63,9 +63,14 @@
#include <QUrl>
#include <QPointer>
+namespace blink {
+namespace web_pref {
+struct WebPreferences;
+}
+}
+
namespace content {
class WebContents;
-struct WebPreferences;
struct OpenURLParams;
class SiteInstance;
}
@@ -90,7 +95,7 @@ class FaviconManager;
class FindTextHelper;
class MessagePassingInterface;
class ProfileQt;
-class RenderViewObserverHostQt;
+class WebEnginePageHost;
class WebChannelIPCTransportHost;
class WebEngineContext;
@@ -161,7 +166,7 @@ public:
quint64 runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId);
quint64 fetchDocumentMarkup();
quint64 fetchDocumentInnerText();
- void updateWebPreferences(const content::WebPreferences &webPreferences);
+ void updateWebPreferences(const blink::web_pref::WebPreferences &webPreferences);
void download(const QUrl &url, const QString &suggestedFileName,
const QUrl &referrerUrl = QUrl(),
ReferrerPolicy referrerPolicy = ReferrerPolicy::Default);
@@ -237,6 +242,7 @@ public:
// meant to be used within WebEngineCore only
void initialize(content::SiteInstance *site);
content::WebContents *webContents() const;
+ content::WebContents *guestWebContents() const;
void updateRecommendedState();
void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
QWebEngineUrlRequestInterceptor* requestInterceptor() const;
@@ -261,7 +267,7 @@ private:
ProfileAdapter *m_profileAdapter;
std::unique_ptr<content::WebContents> m_webContents;
std::unique_ptr<WebContentsDelegateQt> m_webContentsDelegate;
- std::unique_ptr<RenderViewObserverHostQt> m_renderViewObserverHost;
+ std::unique_ptr<WebEnginePageHost> m_pageHost;
#if QT_CONFIG(webengine_webchannel)
std::unique_ptr<WebChannelIPCTransportHost> m_webChannelTransport;
QWebChannel *m_webChannel;
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 04df99f0e..8203ce650 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -459,6 +459,7 @@ public:
virtual void loadProgressChanged(int progress) = 0;
virtual void didUpdateTargetURL(const QUrl&) = 0;
virtual void selectionChanged() = 0;
+ virtual void zoomUpdateIsNeeded() = 0;
virtual void recentlyAudibleChanged(bool recentlyAudible) = 0;
virtual void renderProcessPidChanged(qint64 pid) = 0;
virtual QRectF viewportRect() const = 0;
@@ -466,7 +467,7 @@ public:
virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0;
virtual void loadCommitted() = 0;
virtual void loadVisuallyCommitted() = 0;
- virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) = 0;
+ virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) = 0;
virtual void focusContainer() = 0;
virtual void unhandledKeyEvent(QKeyEvent *event) = 0;
virtual QSharedPointer<WebContentsAdapter>
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index d5a3934fe..d211bdbfc 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -65,7 +65,7 @@
#include "components/error_page/common/error.h"
#include "components/error_page/common/localized_error.h"
#include "components/web_cache/browser/web_cache_manager.h"
-#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
@@ -79,7 +79,6 @@
#include "content/public/browser/web_contents.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/url_constants.h"
-#include "content/public/common/web_preferences.h"
#include "net/base/data_url.h"
#include "net/base/url_util.h"
@@ -106,7 +105,6 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents,
: m_viewClient(adapterClient)
, m_faviconManager(new FaviconManager(webContents, adapterClient))
, m_findTextHelper(new FindTextHelper(webContents, adapterClient))
- , m_lastLoadProgress(-1)
, m_loadingState(determineLoadingState(webContents))
, m_didStartLoadingSeen(m_loadingState == LoadingState::Loading)
, m_frameFocusedObserver(adapterClient)
@@ -128,7 +126,7 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
content::SiteInstance *target_site_instance = params.source_site_instance.get();
content::Referrer referrer = params.referrer;
if (params.disposition != WindowOpenDisposition::CURRENT_TAB) {
- QSharedPointer<WebContentsAdapter> targetAdapter = createWindow(0, params.disposition, gfx::Rect(), params.user_gesture);
+ QSharedPointer<WebContentsAdapter> targetAdapter = createWindow(nullptr, params.disposition, gfx::Rect(), toQt(params.url), params.user_gesture);
if (targetAdapter) {
if (targetAdapter->profile() != source->GetBrowserContext()) {
target_site_instance = nullptr;
@@ -137,6 +135,8 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents
if (!targetAdapter->isInitialized())
targetAdapter->initialize(target_site_instance);
target = targetAdapter->webContents();
+ } else {
+ return target;
}
}
Q_ASSERT(target);
@@ -232,10 +232,11 @@ QUrl WebContentsDelegateQt::url(content::WebContents* source) const {
m_pendingUrlUpdate = false;
return newUrl;
}
-void WebContentsDelegateQt::AddNewContents(content::WebContents* source, std::unique_ptr<content::WebContents> new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked)
+void WebContentsDelegateQt::AddNewContents(content::WebContents* source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
+ WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked)
{
Q_UNUSED(source)
- QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, initial_pos, user_gesture);
+ QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, initial_pos, toQt(target_url), user_gesture);
// Chromium can forget to pass user-agent override settings to new windows (see QTBUG-61774 and QTBUG-76249),
// so set it here. Note the actual value doesn't really matter here. Only the second value does, but we try
// to give the correct user-agent anyway.
@@ -258,14 +259,12 @@ void WebContentsDelegateQt::CloseContents(content::WebContents *source)
void WebContentsDelegateQt::LoadProgressChanged(double progress)
{
- if (!m_loadingErrorFrameList.isEmpty())
- return;
- if (m_lastLoadProgress < 0) // suppress signals that aren't between loadStarted and loadFinished
+ if (!m_loadingInfo.isLoading()) // suppress signals that aren't between loadStarted and loadFinished
return;
int p = qMin(qRound(progress * 100), 100);
- if (p > m_lastLoadProgress) { // ensure strict monotonic increase
- m_lastLoadProgress = p;
+ if (p > m_loadingInfo.progress) { // ensure strict monotonic increase
+ m_loadingInfo.progress = p;
m_viewClient->loadProgressChanged(p);
}
}
@@ -285,11 +284,6 @@ void WebContentsDelegateQt::RenderFrameCreated(content::RenderFrameHost *render_
m_frameFocusedObserver.addNode(node);
}
-void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_frame_host)
-{
- m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
-}
-
void WebContentsDelegateQt::RenderProcessGone(base::TerminationStatus status)
{
// RenderProcessHost::FastShutdownIfPossible results in TERMINATION_STATUS_STILL_RUNNING
@@ -321,11 +315,13 @@ void WebContentsDelegateQt::RenderFrameHostChanged(content::RenderFrameHost *old
m_frameFocusedObserver.addNode(new_node);
// Is this a main frame?
- if (new_host->GetFrameOwnerElementType() == blink::FrameOwnerElementType::kNone) {
+ if (new_host->GetFrameOwnerElementType() == blink::mojom::FrameOwnerElementType::kNone) {
content::RenderProcessHost *renderProcessHost = new_host->GetProcess();
const base::Process &process = renderProcessHost->GetProcess();
- if (process.IsValid())
+ if (process.IsValid()) {
m_viewClient->renderProcessPidChanged(process.Pid());
+ m_viewClient->zoomUpdateIsNeeded();
+ }
}
}
}
@@ -335,44 +331,65 @@ void WebContentsDelegateQt::RenderViewHostChanged(content::RenderViewHost *, con
if (newHost && newHost->GetWidget() && newHost->GetWidget()->GetView()) {
auto rwhv = static_cast<RenderWidgetHostViewQt *>(newHost->GetWidget()->GetView());
m_viewClient->widgetChanged(rwhv->delegate());
+ m_viewClient->zoomUpdateIsNeeded();
}
}
-void WebContentsDelegateQt::EmitLoadStarted(const QUrl &url, bool isErrorPage)
+void WebContentsDelegateQt::emitLoadStarted(bool isErrorPage)
{
- if (m_lastLoadProgress >= 0 && m_lastLoadProgress < 100) // already running
+ // only report first ever load start or separate one for error page only
+ if (!isErrorPage && m_loadingInfo.isLoading()) // already running
return;
- m_viewClient->loadStarted(url, isErrorPage);
- m_viewClient->updateNavigationActions();
- m_viewClient->loadProgressChanged(0);
- m_lastLoadProgress = 0;
+
+ m_isDocumentEmpty = true; // reset to default which may only be overridden on actual resource load complete
+ if (!isErrorPage) {
+ m_loadingInfo.progress = 0;
+ m_viewClient->loadStarted(m_loadingInfo.url, false);
+ m_viewClient->updateNavigationActions();
+ m_viewClient->loadProgressChanged(0);
+ } else {
+ m_viewClient->loadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true);
+ }
}
void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *navigation_handle)
{
- if (!navigation_handle->IsInMainFrame())
- return;
+ if (!webEngineSettings()->testAttribute(WebEngineSettings::ErrorPageEnabled))
+ navigation_handle->SetSilentlyIgnoreErrors();
- // Error-pages are not reported as separate started navigations.
- Q_ASSERT(!navigation_handle->IsErrorPage());
+ if (!navigation_handle->IsInMainFrame() || navigation_handle->IsSameDocument())
+ return;
- m_loadingErrorFrameList.clear();
m_faviconManager->resetCandidates();
- EmitLoadStarted(toQt(navigation_handle->GetURL()));
+
+ m_loadingInfo.url = toQt(navigation_handle->GetURL());
+ // IsErrorPage is only set after navigation commit, so check it otherwise: error page shouldn't have navigation entry
+ bool isErrorPage = m_loadingInfo.triggersErrorPage && !navigation_handle->GetNavigationEntry();
+ emitLoadStarted(isErrorPage);
}
-void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription)
+void WebContentsDelegateQt::emitLoadFinished(bool isErrorPage)
{
- if (m_lastLoadProgress < 0) // not currently running
+ if (!m_loadingInfo.isLoading()) // not currently running
return;
- if (m_lastLoadProgress < 100)
- m_viewClient->loadProgressChanged(100);
- m_lastLoadProgress = -1;
- m_viewClient->loadFinished(success, url, isErrorPage, errorCode, errorDescription);
- m_viewClient->updateNavigationActions();
+
+ Q_ASSERT(!isErrorPage || webEngineSettings()->testAttribute(WebEngineSettings::ErrorPageEnabled));
+ Q_ASSERT((m_loadingInfo.triggersErrorPage && webEngineSettings()->testAttribute(WebEngineSettings::ErrorPageEnabled)) || !m_loadingInfo.triggersErrorPage);
+
+ if (!isErrorPage) {
+ if (m_loadingInfo.progress < 100) {
+ m_loadingInfo.progress = 100;
+ m_viewClient->loadProgressChanged(100);
+ }
+
+ m_viewClient->loadFinished(m_loadingInfo.success, m_loadingInfo.url, false, m_loadingInfo.errorCode, m_loadingInfo.errorDescription);
+ m_viewClient->updateNavigationActions();
+ } else {
+ m_viewClient->loadFinished(false, toQt(GURL(content::kUnreachableWebDataURL)), true, 0, QString());
+ }
}
-void WebContentsDelegateQt::EmitLoadCommitted()
+void WebContentsDelegateQt::emitLoadCommitted()
{
m_findTextHelper->handleLoadCommitted();
m_viewClient->loadCommitted();
@@ -392,8 +409,9 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
profileAdapter->visitedLinksManager()->addUrl(url);
}
- EmitLoadCommitted();
+ emitLoadCommitted();
}
+
// Success is reported by DidFinishLoad, but DidFailLoad is now dead code and needs to be handled below
if (navigation_handle->GetNetErrorCode() == net::OK)
return;
@@ -406,13 +424,12 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
// The load will succede as an error-page load later, and we reported the original error above
if (navigation_handle->IsErrorPage()) {
// Now report we are starting to load an error-page.
- m_loadingErrorFrameList.append(navigation_handle->GetRenderFrameHost()->GetRoutingID());
m_faviconManager->resetCandidates();
- EmitLoadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true);
+ emitLoadStarted(true);
// If it is already committed we will not see another DidFinishNavigation call or a DidFinishLoad call.
if (navigation_handle->HasCommitted())
- EmitLoadCommitted();
+ emitLoadCommitted();
}
}
@@ -454,12 +471,23 @@ void WebContentsDelegateQt::DidStopLoading()
if (m_loadingState == LoadingState::Loading)
setLoadingState(LoadingState::Loaded);
+
+ emitLoadFinished();
+ m_loadingInfo.clear();
}
void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription)
{
m_viewClient->iconChanged(QUrl());
- EmitLoadFinished(false /* success */ , url, false /* isErrorPage */, errorCode, errorDescription);
+ bool errorPageEnabled = webEngineSettings()->testAttribute(WebEngineSettings::ErrorPageEnabled);
+ // Delay notifying failure until the error-page is done loading.
+ // Error-pages are not loaded on failures due to abort.
+ bool aborted = (errorCode == -3 /* ERR_ABORTED*/ );
+ m_loadingInfo.success = false;
+ m_loadingInfo.url = url;
+ m_loadingInfo.errorCode = errorCode;
+ m_loadingInfo.errorDescription = errorDescription;
+ m_loadingInfo.triggersErrorPage = errorPageEnabled && !aborted;
}
void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code)
@@ -473,10 +501,8 @@ void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_h
if (validated_url.spec() == content::kUnreachableWebDataURL) {
// error-pages should only ever fail due to abort:
Q_ASSERT(error_code == -3 /* ERR_ABORTED */);
- m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
m_viewClient->iconChanged(QUrl());
-
- EmitLoadFinished(false /* success */, toQt(validated_url), true /* isErrorPage */);
+ emitLoadFinished(/* isErrorPage = */true);
return;
}
// Qt6: Consider getting rid of the error_description (Chromium already has)
@@ -491,12 +517,10 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
{
Q_ASSERT(validated_url.is_valid());
if (validated_url.spec() == content::kUnreachableWebDataURL) {
- m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
-
// Trigger LoadFinished signal for main frame's error page only.
if (!render_frame_host->GetParent()) {
m_viewClient->iconChanged(QUrl());
- EmitLoadFinished(true /* success */, toQt(validated_url), true /* isErrorPage */);
+ emitLoadFinished(/* isErrorPage = */true);
}
return;
@@ -511,14 +535,17 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
m_viewClient->iconChanged(QUrl());
content::NavigationEntry *entry = web_contents()->GetController().GetActiveEntry();
- int http_statuscode = 0;
- if (entry)
- http_statuscode = entry->GetHttpStatusCode();
- EmitLoadFinished(true /* success */ , toQt(validated_url), false /* isErrorPage */, http_statuscode);
-}
+ int http_statuscode = entry ? entry->GetHttpStatusCode() : 0;
+ bool errorPageEnabled = webEngineSettings()->testAttribute(WebEngineSettings::ErrorPageEnabled);
+ bool triggersErrorPage = errorPageEnabled && (http_statuscode >= 400) && m_isDocumentEmpty;
-void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<blink::mojom::FaviconURLPtr> &candidates)
+ m_loadingInfo.success = http_statuscode < 400;
+ m_loadingInfo.url = toQt(validated_url);
+ m_loadingInfo.errorCode = http_statuscode;
+ m_loadingInfo.triggersErrorPage = triggersErrorPage;
+}
+void WebContentsDelegateQt::DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, const std::vector<blink::mojom::FaviconURLPtr> &candidates)
{
QList<FaviconInfo> faviconCandidates;
faviconCandidates.reserve(static_cast<int>(candidates.size()));
@@ -536,9 +563,8 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<blink::mojom::
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 *newContents)
+ 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);
}
@@ -556,11 +582,11 @@ content::JavaScriptDialogManager *WebContentsDelegateQt::GetJavaScriptDialogMana
return JavaScriptDialogManagerQt::GetInstance();
}
-void WebContentsDelegateQt::EnterFullscreenModeForTab(content::WebContents *web_contents, const GURL& origin, const blink::mojom::FullscreenOptions &)
+void WebContentsDelegateQt::EnterFullscreenModeForTab(content::RenderFrameHost *requesting_frame, const blink::mojom::FullscreenOptions &options)
{
- Q_UNUSED(web_contents);
+ Q_UNUSED(options);
if (!m_viewClient->isFullScreenMode())
- m_viewClient->requestFullScreenMode(toQt(origin), true);
+ m_viewClient->requestFullScreenMode(toQt(requesting_frame->GetLastCommittedURL()), true);
}
void WebContentsDelegateQt::ExitFullscreenModeForTab(content::WebContents *web_contents)
@@ -580,8 +606,10 @@ ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, blink::mojom::FileChooser
ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, blink::mojom::FileChooserParams::Mode::kUploadFolder)
ASSERT_ENUMS_MATCH(FilePickerController::Save, blink::mojom::FileChooserParams::Mode::kSave)
+extern FilePickerController *createFilePickerController(FilePickerController::FileChooserMode mode, scoped_refptr<content::FileSelectListener> listener, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject *parent = nullptr);
+
void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost * /*frameHost*/,
- std::unique_ptr<content::FileSelectListener> listener,
+ scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params)
{
QStringList acceptedMimeTypes;
@@ -589,8 +617,8 @@ void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost * /*frameHos
for (std::vector<base::string16>::const_iterator it = params.accept_types.begin(); it < params.accept_types.end(); ++it)
acceptedMimeTypes.append(toQt(*it));
- m_filePickerController.reset(new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode),
- std::move(listener), toQt(params.default_file_name.value()), acceptedMimeTypes));
+ m_filePickerController.reset(createFilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode),
+ listener, toQt(params.default_file_name.value()), acceptedMimeTypes));
// Defer the call to not block base::MessageLoop::RunTask with modal dialogs.
QTimer::singleShot(0, [this] () {
@@ -613,7 +641,7 @@ void WebContentsDelegateQt::FindReply(content::WebContents *source, int request_
void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *web_contents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
{
- MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(m_viewClient, web_contents, request, std::move(callback));
+ MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(web_contents, request, std::move(callback));
}
void WebContentsDelegateQt::SetContentsBounds(content::WebContents *source, const gfx::Rect &bounds)
@@ -668,14 +696,14 @@ void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_content
m_viewClient->runMouseLockPermissionRequest(toQt(web_contents->GetLastCommittedURL().GetOrigin()));
}
-void WebContentsDelegateQt::overrideWebPreferences(content::WebContents *webContents, content::WebPreferences *webPreferences)
+void WebContentsDelegateQt::overrideWebPreferences(content::WebContents *webContents, blink::web_pref::WebPreferences *webPreferences)
{
m_viewClient->webEngineSettings()->overrideWebPreferences(webContents, webPreferences);
}
QSharedPointer<WebContentsAdapter>
WebContentsDelegateQt::createWindow(std::unique_ptr<content::WebContents> new_contents,
- WindowOpenDisposition disposition, const gfx::Rect &initial_pos,
+ WindowOpenDisposition disposition, const gfx::Rect &initial_pos, const QUrl &url,
bool user_gesture)
{
QSharedPointer<WebContentsAdapter> newAdapter = QSharedPointer<WebContentsAdapter>::create(std::move(new_contents));
@@ -683,7 +711,7 @@ WebContentsDelegateQt::createWindow(std::unique_ptr<content::WebContents> new_co
return m_viewClient->adoptNewWindow(
std::move(newAdapter),
static_cast<WebContentsAdapterClient::WindowOpenDisposition>(disposition), user_gesture,
- toQt(initial_pos), m_initialTargetUrl);
+ toQt(initial_pos), url);
}
void WebContentsDelegateQt::allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController)
@@ -771,9 +799,9 @@ bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost
}
}
-void WebContentsDelegateQt::RegisterProtocolHandler(content::WebContents *webContents, const std::string &protocol, const GURL &url, bool)
+void WebContentsDelegateQt::RegisterProtocolHandler(content::RenderFrameHost *frameHost, const std::string &protocol, const GURL &url, bool)
{
- content::BrowserContext *context = webContents->GetBrowserContext();
+ content::BrowserContext *context = frameHost->GetBrowserContext();
if (context->IsOffTheRecord())
return;
@@ -786,13 +814,13 @@ void WebContentsDelegateQt::RegisterProtocolHandler(content::WebContents *webCon
return;
QWebEngineRegisterProtocolHandlerRequest request(
- QSharedPointer<RegisterProtocolHandlerRequestControllerImpl>::create(webContents, handler));
+ QSharedPointer<RegisterProtocolHandlerRequestControllerImpl>::create(content::WebContents::FromRenderFrameHost(frameHost), handler));
m_viewClient->runRegisterProtocolHandlerRequest(std::move(request));
}
-void WebContentsDelegateQt::UnregisterProtocolHandler(content::WebContents *webContents, const std::string &protocol, const GURL &url, bool)
+void WebContentsDelegateQt::UnregisterProtocolHandler(content::RenderFrameHost *frameHost, const std::string &protocol, const GURL &url, bool)
{
- content::BrowserContext* context = webContents->GetBrowserContext();
+ content::BrowserContext* context = frameHost->GetBrowserContext();
if (context->IsOffTheRecord())
return;
@@ -828,6 +856,18 @@ bool WebContentsDelegateQt::ShouldNavigateOnBackForwardMouseButtons()
#endif
}
+void WebContentsDelegateQt::ResourceLoadComplete(content::RenderFrameHost* render_frame_host,
+ const content::GlobalRequestID& request_id,
+ const blink::mojom::ResourceLoadInfo& resource_load_info)
+{
+ Q_UNUSED(render_frame_host);
+ Q_UNUSED(request_id);
+
+ if (resource_load_info.request_destination == network::mojom::RequestDestination::kDocument) {
+ m_isDocumentEmpty = (resource_load_info.raw_body_bytes == 0);
+ }
+}
+
FaviconManager *WebContentsDelegateQt::faviconManager()
{
return m_faviconManager.data();
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 159803840..50027b6a8 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -40,7 +40,7 @@
#ifndef WEB_CONTENTS_DELEGATE_QT_H
#define WEB_CONTENTS_DELEGATE_QT_H
-#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/public/browser/media_capture_devices.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
@@ -58,12 +58,17 @@
QT_FORWARD_DECLARE_CLASS(CertificateErrorController)
QT_FORWARD_DECLARE_CLASS(ClientCertSelectController)
+namespace blink {
+ namespace web_pref {
+ struct WebPreferences;
+ }
+}
+
namespace content {
class ColorChooser;
class SiteInstance;
class JavaScriptDialogManager;
class WebContents;
- struct WebPreferences;
struct ColorSuggestion;
}
@@ -120,7 +125,8 @@ public:
// WebContentsDelegate overrides
content::WebContents *OpenURLFromTab(content::WebContents *source, const content::OpenURLParams &params) override;
void NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) override;
- 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 AddNewContents(content::WebContents *source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
+ WindowOpenDisposition disposition, const gfx::Rect &initial_pos, bool user_gesture, bool *was_blocked) override;
void CloseContents(content::WebContents *source) override;
void LoadProgressChanged(double progress) override;
bool HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override;
@@ -128,11 +134,11 @@ public:
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;
content::JavaScriptDialogManager *GetJavaScriptDialogManager(content::WebContents *source) override;
- void EnterFullscreenModeForTab(content::WebContents *web_contents, const GURL &origin, const blink::mojom::FullscreenOptions &options) override;
+ void EnterFullscreenModeForTab(content::RenderFrameHost *requesting_frame, const blink::mojom::FullscreenOptions &options) override;
void ExitFullscreenModeForTab(content::WebContents*) override;
bool IsFullscreenForTabOrPending(const content::WebContents* web_contents) override;
void RunFileChooser(content::RenderFrameHost* render_frame_host,
- std::unique_ptr<content::FileSelectListener> listener,
+ scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params) override;
bool DidAddMessageToConsole(content::WebContents *source, blink::mojom::ConsoleMessageLevel log_level,
const base::string16 &message, int32_t line_no, const base::string16 &source_id) override;
@@ -145,14 +151,13 @@ public:
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, blink::mojom::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;
+ void RegisterProtocolHandler(content::RenderFrameHost* frame_host, const std::string& protocol, const GURL& url, bool user_gesture) override;
+ void UnregisterProtocolHandler(content::RenderFrameHost* frame_host, const std::string& protocol, const GURL& url, bool user_gesture) override;
bool TakeFocus(content::WebContents *source, bool reverse) override;
void ContentsZoomChange(bool zoom_in) override;
// WebContentsObserver overrides
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
- void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
void RenderProcessGone(base::TerminationStatus status) override;
void RenderFrameHostChanged(content::RenderFrameHost *old_host, content::RenderFrameHost *new_host) override;
void RenderViewHostChanged(content::RenderViewHost *old_host, content::RenderViewHost *new_host) override;
@@ -164,14 +169,17 @@ public:
void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code) override;
void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override;
void BeforeUnloadFired(bool proceed, const base::TimeTicks& proceed_time) override;
- void DidUpdateFaviconURL(const std::vector<blink::mojom::FaviconURLPtr> &candidates) override;
+ void DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, const std::vector<blink::mojom::FaviconURLPtr> &candidates) override;
void OnVisibilityChanged(content::Visibility visibility) override;
void DidFirstVisuallyNonEmptyPaint() override;
void ActivateContents(content::WebContents* contents) override;
bool ShouldNavigateOnBackForwardMouseButtons() override;
+ void ResourceLoadComplete(content::RenderFrameHost* render_frame_host,
+ const content::GlobalRequestID& request_id,
+ const blink::mojom::ResourceLoadInfo& resource_load_info) override;
void didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription);
- void overrideWebPreferences(content::WebContents *, content::WebPreferences*);
+ void overrideWebPreferences(content::WebContents *, blink::web_pref::WebPreferences*);
void allowCertificateError(const QSharedPointer<CertificateErrorController> &);
void selectClientCert(const QSharedPointer<ClientCertSelectController> &);
void requestFeaturePermission(ProfileAdapter::PermissionType feature, const QUrl &requestingOrigin);
@@ -205,10 +213,11 @@ private:
QSharedPointer<WebContentsAdapter>
createWindow(std::unique_ptr<content::WebContents> new_contents,
WindowOpenDisposition disposition, const gfx::Rect &initial_pos,
+ const QUrl &url,
bool user_gesture);
- void EmitLoadStarted(const QUrl &url, bool isErrorPage = false);
- void EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString());
- void EmitLoadCommitted();
+ void emitLoadStarted(bool isErrorPage = false);
+ void emitLoadFinished(bool isErrorPage = false);
+ void emitLoadCommitted();
LoadingState determineLoadingState(content::WebContents *contents);
void setLoadingState(LoadingState state);
@@ -216,13 +225,10 @@ private:
int &streamCount(blink::mojom::MediaStreamType type);
WebContentsAdapterClient *m_viewClient;
- QVector<int64_t> m_loadingErrorFrameList;
QScopedPointer<FaviconManager> m_faviconManager;
QScopedPointer<FindTextHelper> m_findTextHelper;
SavePageInfo m_savePageInfo;
QSharedPointer<FilePickerController> m_filePickerController;
- QUrl m_initialTargetUrl;
- int m_lastLoadProgress;
LoadingState m_loadingState;
bool m_didStartLoadingSeen;
FrameFocusedObserver m_frameFocusedObserver;
@@ -234,6 +240,18 @@ private:
int m_desktopStreamCount = 0;
mutable bool m_pendingUrlUpdate = false;
+ struct LoadingInfo {
+ bool success = false;
+ int progress = -1;
+ bool isLoading() const { return progress >= 0; }
+ QUrl url;
+ int errorCode = 0;
+ QString errorDescription;
+ bool triggersErrorPage = false;
+ void clear() { *this = LoadingInfo(); }
+ } m_loadingInfo;
+
+ bool m_isDocumentEmpty = true;
base::WeakPtrFactory<WebContentsDelegateQt> m_weakPtrFactory { this };
};
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 4e20c86ea..900c53829 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -46,7 +46,6 @@
#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"
@@ -65,6 +64,13 @@
namespace QtWebEngineCore {
+WebContentsViewQt::WebContentsViewQt(content::WebContents *webContents)
+ : m_webContents(webContents)
+ , m_client(nullptr)
+ , m_factoryClient(nullptr)
+{
+}
+
void WebContentsViewQt::setFactoryClient(WebContentsAdapterClient* client)
{
if (m_factoryClient)
@@ -122,12 +128,13 @@ gfx::NativeView WebContentsViewQt::GetNativeView() const
return nullptr;
}
-void WebContentsViewQt::GetContainerBounds(gfx::Rect* out) const
+gfx::Rect WebContentsViewQt::GetContainerBounds() const
{
if (m_client) {
const QRectF r(m_client->viewportRect());
- *out = gfx::Rect(r.x(), r.y(), r.width(), r.height());
+ return gfx::Rect(r.x(), r.y(), r.width(), r.height());
}
+ return gfx::Rect();
}
void WebContentsViewQt::Focus()
@@ -147,10 +154,6 @@ void WebContentsViewQt::SetInitialFocus()
void WebContentsViewQt::FocusThroughTabTraversal(bool reverse)
{
content::WebContentsImpl *web_contents = static_cast<content::WebContentsImpl*>(m_webContents);
- if (web_contents->ShowingInterstitialPage()) {
- web_contents->GetInterstitialPage()->FocusThroughTabTraversal(reverse);
- return;
- }
content::RenderWidgetHostView *fullscreen_view = web_contents->GetFullscreenRenderWidgetHostView();
if (fullscreen_view) {
fullscreen_view->Focus();
@@ -191,22 +194,22 @@ ASSERT_ENUMS_MATCH(WebEngineContextMenuData::CanSelectAll, blink::kCanSelectAll)
ASSERT_ENUMS_MATCH(WebEngineContextMenuData::CanTranslate, blink::kCanTranslate)
ASSERT_ENUMS_MATCH(WebEngineContextMenuData::CanEditRichly, blink::kCanEditRichly)
-static inline WebEngineContextMenuData fromParams(const content::ContextMenuParams &params)
+WebEngineContextMenuData WebContentsViewQt::buildContextMenuData(const content::ContextMenuParams &params)
{
WebEngineContextMenuData ret;
ret.setPosition(QPoint(params.x, params.y));
ret.setLinkUrl(toQt(params.link_url));
- ret.setLinkText(toQt(params.link_text.data()));
- ret.setAltText(toQt(params.alt_text.data()));
- ret.setTitleText(toQt(params.title_text.data()));
+ ret.setLinkText(toQt(params.link_text));
+ ret.setAltText(toQt(params.alt_text));
+ ret.setTitleText(toQt(params.title_text));
ret.setUnfilteredLinkUrl(toQt(params.unfiltered_link_url));
- ret.setSelectedText(toQt(params.selection_text.data()));
+ ret.setSelectedText(toQt(params.selection_text));
ret.setMediaUrl(toQt(params.src_url));
ret.setMediaType((WebEngineContextMenuData::MediaType)params.media_type);
ret.setHasImageContent(params.has_image_contents);
ret.setMediaFlags((WebEngineContextMenuData::MediaFlags)params.media_flags);
ret.setEditFlags((WebEngineContextMenuData::EditFlags)params.edit_flags);
- ret.setSuggestedFileName(toQt(params.suggested_filename.data()));
+ ret.setSuggestedFileName(toQt(params.suggested_filename));
ret.setIsEditable(params.is_editable);
#if QT_CONFIG(webengine_spellchecker)
ret.setMisspelledWord(toQt(params.misspelled_word));
@@ -225,7 +228,7 @@ void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const conten
return;
}
- WebEngineContextMenuData contextMenuData(fromParams(params));
+ WebEngineContextMenuData contextMenuData(buildContextMenuData(params));
#if QT_CONFIG(webengine_spellchecker)
// Do not use params.spellcheck_enabled, since it is never
// correctly initialized for chrome asynchronous spellchecking.
@@ -239,23 +242,23 @@ void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const conten
m_client->contextMenuRequested(contextMenuData);
}
-Qt::DropActions toQtDropActions(blink::WebDragOperationsMask ops)
+static Qt::DropActions toQtDropActions(blink::DragOperationsMask ops)
{
Qt::DropActions result;
- if (ops & blink::kWebDragOperationCopy)
+ if (ops & blink::kDragOperationCopy)
result |= Qt::CopyAction;
- if (ops & blink::kWebDragOperationLink)
+ if (ops & blink::kDragOperationLink)
result |= Qt::LinkAction;
- if (ops & blink::kWebDragOperationMove || ops & blink::kWebDragOperationDelete)
+ if (ops & blink::kDragOperationMove || ops & blink::kDragOperationDelete)
result |= Qt::MoveAction;
return result;
}
void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
- blink::WebDragOperationsMask allowed_ops,
+ blink::DragOperationsMask allowed_ops,
const gfx::ImageSkia &image,
const gfx::Vector2d &image_offset,
- const content::DragEventSourceInfo &event_info,
+ const blink::mojom::DragEventSourceInfo &event_info,
content::RenderWidgetHostImpl* source_rwh)
{
#if QT_CONFIG(draganddrop)
@@ -279,7 +282,7 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
#endif // QT_CONFIG(draganddrop)
}
-void WebContentsViewQt::UpdateDragCursor(blink::WebDragOperation dragOperation)
+void WebContentsViewQt::UpdateDragCursor(blink::DragOperation dragOperation)
{
#if QT_CONFIG(draganddrop)
m_client->webContentsAdapter()->updateDragAction(dragOperation);
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 3c89bf3b0..da0c5d20c 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -44,6 +44,7 @@
#include "content/browser/web_contents/web_contents_view.h"
#include "api/qtwebenginecoreglobal_p.h"
+#include "web_contents_adapter_client.h"
namespace content {
class WebContents;
@@ -59,11 +60,7 @@ class WebContentsViewQt
public:
static inline WebContentsViewQt *from(WebContentsView *view) { return static_cast<WebContentsViewQt*>(view); }
- WebContentsViewQt(content::WebContents* webContents)
- : m_webContents(webContents)
- , m_client(nullptr)
- , m_factoryClient(nullptr)
- { }
+ WebContentsViewQt(content::WebContents *webContents);
void setFactoryClient(WebContentsAdapterClient* client);
void setClient(WebContentsAdapterClient* client);
@@ -90,9 +87,7 @@ public:
gfx::NativeWindow GetTopLevelNativeWindow() const override { return nullptr; }
- void GetContainerBounds(gfx::Rect* out) const override;
-
- void SizeContents(const gfx::Size& size) override { }
+ gfx::Rect GetContainerBounds() const override;
void Focus() override;
@@ -108,17 +103,17 @@ public:
void FocusThroughTabTraversal(bool reverse) override;
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
bool CloseTabAfterEventTrackingIfNeeded() override { QT_NOT_YET_IMPLEMENTED return false; }
-#endif // defined(OS_MACOSX)
+#endif // defined(OS_MAC)
// content::RenderViewHostDelegateView overrides:
- void StartDragging(const content::DropData& drop_data, blink::WebDragOperationsMask allowed_ops,
+ void StartDragging(const content::DropData& drop_data, blink::DragOperationsMask allowed_ops,
const gfx::ImageSkia& image, const gfx::Vector2d& image_offset,
- const content::DragEventSourceInfo& event_info,
- content::RenderWidgetHostImpl* source_rwh) override;
+ const blink::mojom::DragEventSourceInfo &event_info,
+ content::RenderWidgetHostImpl *source_rwh) override;
- void UpdateDragCursor(blink::WebDragOperation dragOperation) override;
+ void UpdateDragCursor(blink::DragOperation dragOperation) override;
void ShowContextMenu(content::RenderFrameHost *, const content::ContextMenuParams &params) override;
@@ -126,6 +121,8 @@ public:
void LostFocus(content::RenderWidgetHostImpl *render_widget_host) override;
void TakeFocus(bool reverse) override;
+ static WebEngineContextMenuData buildContextMenuData(const content::ContextMenuParams &params);
+
private:
content::WebContents *m_webContents;
WebContentsAdapterClient *m_client;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index c7add160b..184f78c3b 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -52,6 +52,9 @@
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h"
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+#include "chrome/browser/media/webrtc/webrtc_log_uploader.h"
+#endif
#include "chrome/common/chrome_switches.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/browser/compositor/surface_utils.h"
@@ -59,7 +62,6 @@
#include "components/viz/host/host_frame_sink_manager.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/discardable_memory/service/discardable_shared_memory_manager.h"
#include "components/viz/common/features.h"
@@ -89,10 +91,11 @@
#include "mojo/core/embedder/embedder.h"
#include "net/base/port_util.h"
#include "ppapi/buildflags/buildflags.h"
+#include "sandbox/policy/switches.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/mojom/network_context.mojom.h"
-#include "services/service_manager/sandbox/switches.h"
+#include "services/service_manager/switches.h"
#include "services/tracing/public/cpp/trace_startup.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "third_party/blink/public/common/features.h"
@@ -312,7 +315,7 @@ static QStringList parseEnvCommandLine(const QString &cmdLine)
scoped_refptr<QtWebEngineCore::WebEngineContext> WebEngineContext::m_handle;
bool WebEngineContext::m_destroyed = false;
-
+bool WebEngineContext::m_closingDown = false;
void WebEngineContext::destroyProfileAdapter()
{
if (content::RenderProcessHost::run_renderer_in_process()) {
@@ -351,26 +354,36 @@ void WebEngineContext::removeProfileAdapter(ProfileAdapter *profileAdapter)
m_profileAdapters.removeAll(profileAdapter);
}
+void WebEngineContext::flushMessages()
+{
+ if (!m_destroyed) {
+ base::MessagePump::Delegate *delegate = static_cast<
+ base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
+ WebEngineContext::current()->m_runLoop->delegate_);
+ while (delegate->DoWork().is_immediate()) { }
+ }
+}
void WebEngineContext::destroy()
{
if (m_devtoolsServer)
m_devtoolsServer->stop();
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ if (m_webrtcLogUploader)
+ m_webrtcLogUploader->Shutdown();
+#endif
- base::MessagePump::Delegate *delegate =
- static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
- m_runLoop->delegate_);
// 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.
cleanupVizProcess();
while (waitForViz) {
- while (delegate->DoWork().is_immediate()) { }
+ flushMessages();
QThread::msleep(50);
}
destroyGpuProcess();
// Flush the UI message loop before quitting.
- while (delegate->DoWork().is_immediate()) { }
+ flushMessages();
#if QT_CONFIG(webengine_printing_and_pdf)
// Kill print job manager early as it has a content::NotificationRegistrar
@@ -392,7 +405,7 @@ void WebEngineContext::destroy()
// Handle any events posted by browser-context shutdown.
// This should deliver all nessesery calls of DeleteSoon from PostTask
- while (delegate->DoWork().is_immediate()) { }
+ flushMessages();
m_devtoolsServer.reset();
m_runLoop->AfterRun();
@@ -413,6 +426,10 @@ void WebEngineContext::destroy()
// Drop the false reference.
m_handle->Release();
+
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ m_webrtcLogUploader.reset();
+#endif
}
WebEngineContext::~WebEngineContext()
@@ -467,6 +484,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_closingDown = true;
m_handle->destroy();
#if !defined(NDEBUG)
if (!m_handle->HasOneRef())
@@ -508,23 +526,47 @@ bool WebEngineContext::isGpuServiceOnUIThread()
return !threadedGpu;
}
-static void appendToFeatureList(std::string &featureList, const char *feature)
+static void initializeFeatureList(base::CommandLine *commandLine, std::vector<std::string> enableFeatures, std::vector<std::string> disableFeatures)
{
- if (featureList.empty())
- featureList = feature;
- else
- featureList = featureList + "," + feature;
-}
+ std::string enableFeaturesString = base::JoinString(enableFeatures, ",");
+ if (commandLine->HasSwitch(switches::kEnableFeatures)) {
+ std::string commandLineEnableFeatures = commandLine->GetSwitchValueASCII(switches::kEnableFeatures);
-static void appendToFeatureSwitch(base::CommandLine *commandLine, const char *featureSwitch, std::string feature)
-{
- if (!commandLine->HasSwitch(featureSwitch)) {
- commandLine->AppendSwitchASCII(featureSwitch, feature);
- } else {
- std::string featureList = commandLine->GetSwitchValueASCII(featureSwitch);
- featureList = featureList + "," + feature;
- commandLine->AppendSwitchASCII(featureSwitch, featureList);
+ for (const std::string &enableFeature : base::SplitString(commandLineEnableFeatures, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+ auto it = std::find(disableFeatures.begin(), disableFeatures.end(), enableFeature);
+ if (it == disableFeatures.end())
+ continue;
+
+ qWarning("An unsupported feature has been enabled from command line: %s\n"
+ "The feature is enabled but there is no guarantee that it will work or not break QtWebEngine.", enableFeature.c_str());
+
+ // If a feature is disabled and enabled at the same time, then it will be disabled.
+ // Remove feature from the disable list to make it possible to override from command line.
+ disableFeatures.erase(it);
+ }
+
+ enableFeaturesString = enableFeaturesString + "," + commandLineEnableFeatures;
}
+
+ std::string disableFeaturesString = base::JoinString(disableFeatures, ",");
+ if (commandLine->HasSwitch(switches::kDisableFeatures)) {
+ std::string commandLineDisableFeatures = commandLine->GetSwitchValueASCII(switches::kDisableFeatures);
+
+ for (const std::string &disableFeature : base::SplitString(commandLineDisableFeatures, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+ auto it = std::find(enableFeatures.begin(), enableFeatures.end(), disableFeature);
+ if (it == enableFeatures.end())
+ continue;
+
+ qWarning("An essential feature has been disabled from command line: %s\n"
+ "The feature is disabled but there is no guarantee that it will not break QtWebEngine.", disableFeature.c_str());
+ }
+
+ disableFeaturesString = disableFeaturesString + "," + commandLineDisableFeatures;
+ }
+
+ commandLine->AppendSwitchASCII(switches::kEnableFeatures, enableFeaturesString);
+ commandLine->AppendSwitchASCII(switches::kDisableFeatures, disableFeaturesString);
+ base::FeatureList::InitializeInstance(enableFeaturesString, disableFeaturesString);
}
WebEngineContext::WebEngineContext()
@@ -538,7 +580,7 @@ WebEngineContext::WebEngineContext()
#endif
base::ThreadPoolInstance::Create("Browser");
- m_contentRunner.reset(content::ContentMainRunner::Create());
+ m_contentRunner = content::ContentMainRunner::Create();
m_browserRunner = content::BrowserMainRunner::Create();
#ifdef Q_OS_LINUX
@@ -580,21 +622,22 @@ WebEngineContext::WebEngineContext()
setupProxyPac(parsedCommandLine);
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
- parsedCommandLine->AppendSwitchASCII(service_manager::switches::kApplicationName, QCoreApplication::applicationName().toStdString());
+ parsedCommandLine->AppendSwitchASCII(service_manager::switches::kApplicationName, QCoreApplication::applicationName().toUtf8().toPercentEncoding().toStdString());
// Enable sandboxing on OS X and Linux (Desktop / Embedded) by default.
bool disable_sandbox = qEnvironmentVariableIsSet(kDisableSandboxEnv);
if (!disable_sandbox) {
#if defined(Q_OS_LINUX)
- parsedCommandLine->AppendSwitch(service_manager::switches::kDisableSetuidSandbox);
+ parsedCommandLine->AppendSwitch(sandbox::policy::switches::kDisableSetuidSandbox);
#endif
} else {
- parsedCommandLine->AppendSwitch(service_manager::switches::kNoSandbox);
+ parsedCommandLine->AppendSwitch(sandbox::policy::switches::kNoSandbox);
qInfo() << "Sandboxing disabled by user.";
}
parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing);
+#if QT_CONFIG(opengl)
#if defined(Q_OS_WIN)
// This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
// an OpenGL Core Profile context. If the switch is not set, it would always try to create a
@@ -617,60 +660,58 @@ WebEngineContext::WebEngineContext()
if (isDesktopGLOrSoftware || isGLES2Context)
parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
-#endif
+#endif // defined(Q_OS_WIN)
+#endif // QT_CONFIG(opengl)
// Do not advertise a feature we have removed at compile time
parsedCommandLine->AppendSwitch(switches::kDisableSpeechAPI);
- std::string disableFeatures;
- std::string enableFeatures;
+ std::vector<std::string> disableFeatures;
+ std::vector<std::string> enableFeatures;
// Needed to allow navigations within pages that were set using setHtml(). One example is
// tst_QWebEnginePage::acceptNavigationRequest.
// This is deprecated behavior, and will be removed in a future Chromium version, as per
// upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422.
- appendToFeatureList(enableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
+ enableFeatures.push_back(features::kAllowContentInitiatedDataUrlNavigations.name);
- appendToFeatureList(enableFeatures, features::kTracingServiceInProcess.name);
+ enableFeatures.push_back(features::kNetworkServiceInProcess.name);
+ enableFeatures.push_back(features::kTracingServiceInProcess.name);
// The video-capture service is not functioning at this moment (since 69)
- appendToFeatureList(disableFeatures, features::kMojoVideoCapture.name);
+ disableFeatures.push_back(features::kMojoVideoCapture.name);
#if defined(Q_OS_LINUX)
// broken and crashy (even upstream):
- appendToFeatureList(disableFeatures, features::kFontSrcLocalMatching.name);
+ disableFeatures.push_back(features::kFontSrcLocalMatching.name);
#endif
// We don't support the skia renderer (enabled by default on Linux since 80)
- appendToFeatureList(disableFeatures, features::kUseSkiaRenderer.name);
+ disableFeatures.push_back(features::kUseSkiaRenderer.name);
- appendToFeatureList(disableFeatures, network::features::kDnsOverHttpsUpgrade.name);
+ disableFeatures.push_back(network::features::kDnsOverHttpsUpgrade.name);
// When enabled, event.movement is calculated in blink instead of in browser.
- appendToFeatureList(disableFeatures, features::kConsolidatedMovementXY.name);
+ disableFeatures.push_back(features::kConsolidatedMovementXY.name);
- // Explicitly tell Chromium about default-on features we do not support
- appendToFeatureList(disableFeatures, features::kBackgroundFetch.name);
- appendToFeatureList(disableFeatures, features::kSmsReceiver.name);
- appendToFeatureList(disableFeatures, features::kWebPayments.name);
- appendToFeatureList(disableFeatures, features::kWebUsb.name);
- appendToFeatureList(disableFeatures, media::kPictureInPicture.name);
+ // Avoid crashing when websites tries using this feature (since 83)
+ disableFeatures.push_back(features::kInstalledApp.name);
- // Breaks current colordialog tests.
- appendToFeatureList(disableFeatures, features::kFormControlsRefresh.name);
+ // Explicitly tell Chromium about default-on features we do not support
+ disableFeatures.push_back(features::kBackgroundFetch.name);
+ disableFeatures.push_back(features::kSmsReceiver.name);
+ disableFeatures.push_back(features::kWebPayments.name);
+ disableFeatures.push_back(features::kWebUsb.name);
+ disableFeatures.push_back(media::kPictureInPicture.name);
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
- appendToFeatureList(enableFeatures, features::kOverlayScrollbar.name);
+ enableFeatures.push_back(features::kOverlayScrollbar.name);
parsedCommandLine->AppendSwitch(switches::kEnableViewport);
parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, disableFeatures);
- appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, enableFeatures);
- base::FeatureList::InitializeInstance(
- parsedCommandLine->GetSwitchValueASCII(switches::kEnableFeatures),
- parsedCommandLine->GetSwitchValueASCII(switches::kDisableFeatures));
+ initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures);
GLContextHelper::initialize();
@@ -757,6 +798,7 @@ WebEngineContext::WebEngineContext()
registerMainThreadFactories();
content::ContentMainParams contentMainParams(m_mainDelegate.get());
+ contentMainParams.setup_signal_handlers = false;
#if defined(OS_WIN)
contentMainParams.sandbox_info = staticSandboxInterfaceInfo();
sandbox::SandboxInterfaceInfo sandbox_info = {0};
@@ -841,6 +883,16 @@ printing::PrintJobManager* WebEngineContext::getPrintJobManager()
}
#endif
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+WebRtcLogUploader *WebEngineContext::webRtcLogUploader()
+{
+ if (!m_webrtcLogUploader)
+ m_webrtcLogUploader = std::make_unique<WebRtcLogUploader>();
+ return m_webrtcLogUploader.get();
+}
+#endif
+
+
static QMutex s_spmMutex;
QAtomicPointer<gpu::SyncPointManager> WebEngineContext::s_syncPointManager;
@@ -884,4 +936,9 @@ base::CommandLine* WebEngineContext::commandLine() {
}
}
+bool WebEngineContext::closingDown()
+{
+ return m_closingDown;
+}
+
} // namespace
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index e2190f8a2..2e74a766c 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -86,6 +86,7 @@ struct SandboxInterfaceInfo;
#endif
QT_FORWARD_DECLARE_CLASS(QObject)
+class WebRtcLogUploader;
namespace QtWebEngineCore {
@@ -107,7 +108,8 @@ public:
static WebEngineContext *current();
static void destroyContextPostRoutine();
static ProxyAuthentication qProxyNetworkAuthentication(QString host, int port);
-
+ static void flushMessages();
+ static bool closingDown();
ProfileAdapter *createDefaultProfileAdapter();
ProfileAdapter *defaultProfileAdapter();
@@ -115,6 +117,9 @@ public:
#if QT_CONFIG(webengine_printing_and_pdf)
printing::PrintJobManager* getPrintJobManager();
#endif
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ WebRtcLogUploader *webRtcLogUploader();
+#endif
void destroyProfileAdapter();
void addProfileAdapter(ProfileAdapter *profileAdapter);
void removeProfileAdapter(ProfileAdapter *profileAdapter);
@@ -152,8 +157,12 @@ private:
#if QT_CONFIG(webengine_printing_and_pdf)
std::unique_ptr<printing::PrintJobManager> m_printJobManager;
#endif
+#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
+ std::unique_ptr<WebRtcLogUploader> m_webrtcLogUploader;
+#endif
static scoped_refptr<QtWebEngineCore::WebEngineContext> m_handle;
static bool m_destroyed;
+ static bool m_closingDown;
static QAtomicPointer<gpu::SyncPointManager> s_syncPointManager;
};
diff --git a/src/core/web_engine_context_threads.cpp b/src/core/web_engine_context_threads.cpp
index 5f9e345f7..5aa4c3e1e 100644
--- a/src/core/web_engine_context_threads.cpp
+++ b/src/core/web_engine_context_threads.cpp
@@ -84,7 +84,7 @@ struct GpuThreadControllerQt : content::GpuThreadController
if (s_gpuProcessDestroyed)
return;
- s_gpuProcess = std::make_unique<content::GpuProcess>(base::ThreadPriority::DISPLAY);
+ 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));
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index fa9e34268..3a6492273 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -45,9 +45,11 @@
#include "base/files/file_util.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "content/public/common/content_paths.h"
+#include "sandbox/policy/switches.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
-#include "services/service_manager/sandbox/switches.h"
+
#include "type_conversion.h"
#include <QByteArray>
@@ -75,7 +77,7 @@ QString fallbackDir() {
return directory;
}
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
static inline CFBundleRef frameworkBundle()
{
return CFBundleGetBundleWithIdentifier(CFSTR("org.qt-project.Qt.QtWebEngineCore"));
@@ -118,7 +120,7 @@ static QString getResourcesPath(CFBundleRef frameworkBundle)
}
#endif
-#if defined(OS_MACOSX)
+#if defined(OS_MAC)
static QString getMainApplicationResourcesPath()
{
QString resourcesPath;
@@ -162,7 +164,7 @@ QString subProcessPath()
// Only search in QTWEBENGINEPROCESS_PATH if set
candidatePaths << fromEnv;
} else {
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
candidatePaths << getPath(frameworkBundle())
% QStringLiteral("/Helpers/" QTWEBENGINEPROCESS_NAME ".app/Contents/MacOS/" QTWEBENGINEPROCESS_NAME);
#else
@@ -184,7 +186,7 @@ QString subProcessPath()
#if defined(OS_WIN)
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
- if (!parsedCommandLine->HasSwitch(service_manager::switches::kNoSandbox)) {
+ if (!parsedCommandLine->HasSwitch(sandbox::policy::switches::kNoSandbox)) {
if (WebEngineLibraryInfo::isUNCPath(processPath) || WebEngineLibraryInfo::isRemoteDrivePath(processPath))
qCritical("Can not launch QtWebEngineProcess from network path if sandbox is enabled: %s.", processPath.toUtf8().constData());
}
@@ -200,7 +202,7 @@ QString localesPath()
{
static bool initialized = false;
static QString potentialLocalesPath =
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
getResourcesPath(frameworkBundle()) % QLatin1String("/qtwebengine_locales");
#else
QLibraryInfo::location(QLibraryInfo::TranslationsPath) % QDir::separator() % QLatin1String("qtwebengine_locales");
@@ -236,7 +238,7 @@ QString dictionariesPath()
candidatePaths << fromEnv;
} else {
// First try to find dictionaries near the application.
-#ifdef OS_MACOSX
+#ifdef OS_MAC
QString resourcesDictionariesPath = getMainApplicationResourcesPath()
% QDir::separator() % QLatin1String("qtwebengine_dictionaries");
candidatePaths << resourcesDictionariesPath;
@@ -246,7 +248,7 @@ QString dictionariesPath()
candidatePaths << applicationDictionariesPath;
// Then try to find dictionaries near the installed library.
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
QString frameworkDictionariesPath = getResourcesPath(frameworkBundle())
% QLatin1String("/qtwebengine_dictionaries");
candidatePaths << frameworkDictionariesPath;
@@ -273,8 +275,10 @@ QString resourcesDataPath()
{
static bool initialized = false;
static QString potentialResourcesPath =
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
getResourcesPath(frameworkBundle());
+#elif defined(OS_MAC)
+ QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/Resources");
#else
QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/resources");
#endif
@@ -347,27 +351,32 @@ base::string16 WebEngineLibraryInfo::getApplicationName()
return toString16(qApp->applicationName());
}
-std::string WebEngineLibraryInfo::getApplicationLocale()
+std::string WebEngineLibraryInfo::getResolvedLocale()
{
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
- if (!parsedCommandLine->HasSwitch(switches::kLang)) {
+ if (parsedCommandLine->HasSwitch(switches::kLang)) {
+ return parsedCommandLine->GetSwitchValueASCII(switches::kLang);
+ } else {
const QString &locale = QLocale().bcp47Name();
-
- // QLocale::bcp47Name returns "en" for American English locale. Chromium requires the "US" suffix
- // to clarify the dialect and ignores the shorter version.
- if (locale == "en")
- return "en-US";
-
- return locale.toStdString();
+ std::string resolvedLocale;
+ if (l10n_util::CheckAndResolveLocale(locale.toStdString(), &resolvedLocale))
+ return resolvedLocale;
}
+ return "en-US";
+}
- return parsedCommandLine->GetSwitchValueASCII(switches::kLang);
+std::string WebEngineLibraryInfo::getApplicationLocale()
+{
+ base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ return parsedCommandLine->HasSwitch(switches::kLang)
+ ? parsedCommandLine->GetSwitchValueASCII(switches::kLang)
+ : QLocale().bcp47Name().toStdString();
}
#if defined(OS_WIN)
bool WebEngineLibraryInfo::isRemoteDrivePath(const QString &path)
{
- WCHAR wDriveLetter[3];
+ WCHAR wDriveLetter[4] = { 0 };
swprintf(wDriveLetter, L"%S", path.mid(0, 3).toStdString().c_str());
return GetDriveType(wDriveLetter) == DRIVE_REMOTE;
}
diff --git a/src/core/web_engine_library_info.h b/src/core/web_engine_library_info.h
index 4d23d8921..e7dc195f6 100644
--- a/src/core/web_engine_library_info.h
+++ b/src/core/web_engine_library_info.h
@@ -57,6 +57,7 @@ public:
static base::FilePath getPath(int key);
// Called by localized_error in our custom chrome layer
static base::string16 getApplicationName();
+ static std::string getResolvedLocale();
static std::string getApplicationLocale();
#if defined(OS_WIN)
static bool isRemoteDrivePath(const QString &path);
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 957fe2b7d..4115d10d7 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -49,9 +49,9 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/web_preferences.h"
#include "media/base/media_switches.h"
#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h"
+#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/event_switches.h"
@@ -116,7 +116,7 @@ WebEngineSettings::~WebEngineSettings()
settings->parentSettings = nullptr;
}
-void WebEngineSettings::overrideWebPreferences(content::WebContents *webContents, content::WebPreferences *prefs)
+void WebEngineSettings::overrideWebPreferences(content::WebContents *webContents, blink::web_pref::WebPreferences *prefs)
{
// Apply our settings on top of those.
applySettingsToWebPreferences(prefs);
@@ -124,7 +124,7 @@ void WebEngineSettings::overrideWebPreferences(content::WebContents *webContents
// as the host process already overides some of the default WebPreferences values
// before we get here (e.g. number_of_cpu_cores).
if (webPreferences.isNull())
- webPreferences.reset(new content::WebPreferences(*prefs));
+ webPreferences.reset(new blink::web_pref::WebPreferences(*prefs));
if (webContents
&& applySettingsToRendererPreferences(webContents->GetMutableRendererPrefs())) {
@@ -347,7 +347,7 @@ void WebEngineSettings::doApply()
m_adapter->webContents()->SyncRendererPrefs();
}
-void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *prefs)
+void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPreferences *prefs)
{
// Override for now
prefs->touch_event_feature_detection_enabled = isTouchEventsAPIEnabled();
@@ -385,20 +385,20 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p
prefs->hide_scrollbars = !testAttribute(ShowScrollBars);
if (isAttributeExplicitlySet(PlaybackRequiresUserGesture)) {
prefs->autoplay_policy = testAttribute(PlaybackRequiresUserGesture)
- ? content::AutoplayPolicy::kUserGestureRequired
- : content::AutoplayPolicy::kNoUserGestureRequired;
+ ? blink::web_pref::AutoplayPolicy::kUserGestureRequired
+ : blink::web_pref::AutoplayPolicy::kNoUserGestureRequired;
}
prefs->dom_paste_enabled = testAttribute(JavascriptCanPaste);
prefs->dns_prefetching_enabled = testAttribute(DnsPrefetchEnabled);
// Fonts settings.
- prefs->standard_font_family_map[content::kCommonScript] = toString16(fontFamily(StandardFont));
- prefs->fixed_font_family_map[content::kCommonScript] = toString16(fontFamily(FixedFont));
- prefs->serif_font_family_map[content::kCommonScript] = toString16(fontFamily(SerifFont));
- prefs->sans_serif_font_family_map[content::kCommonScript] = toString16(fontFamily(SansSerifFont));
- prefs->cursive_font_family_map[content::kCommonScript] = toString16(fontFamily(CursiveFont));
- prefs->fantasy_font_family_map[content::kCommonScript] = toString16(fontFamily(FantasyFont));
- prefs->pictograph_font_family_map[content::kCommonScript] = toString16(fontFamily(PictographFont));
+ prefs->standard_font_family_map[blink::web_pref::kCommonScript] = toString16(fontFamily(StandardFont));
+ prefs->fixed_font_family_map[blink::web_pref::kCommonScript] = toString16(fontFamily(FixedFont));
+ prefs->serif_font_family_map[blink::web_pref::kCommonScript] = toString16(fontFamily(SerifFont));
+ prefs->sans_serif_font_family_map[blink::web_pref::kCommonScript] = toString16(fontFamily(SansSerifFont));
+ prefs->cursive_font_family_map[blink::web_pref::kCommonScript] = toString16(fontFamily(CursiveFont));
+ prefs->fantasy_font_family_map[blink::web_pref::kCommonScript] = toString16(fontFamily(FantasyFont));
+ prefs->pictograph_font_family_map[blink::web_pref::kCommonScript] = toString16(fontFamily(PictographFont));
prefs->default_font_size = fontSize(DefaultFontSize);
prefs->default_fixed_font_size = fontSize(DefaultFixedFontSize);
prefs->minimum_font_size = fontSize(MinimumFontSize);
@@ -407,23 +407,16 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p
// Set the theme colors. Based on chrome_content_browser_client.cc:
const ui::NativeTheme *webTheme = ui::NativeTheme::GetInstanceForWeb();
- // WebPreferences::preferred_color_scheme was deleted in Chromium 80, but it
- // will make a comeback in Chromium 82...
- //
- // See also: https://chromium-review.googlesource.com/c/chromium/src/+/2079192
- //
- // if (webTheme) {
- // switch (webTheme->GetPreferredColorScheme()) {
- // case ui::NativeTheme::PreferredColorScheme::kDark:
- // prefs->preferred_color_scheme = blink::PreferredColorScheme::kDark;
- // break;
- // case ui::NativeTheme::PreferredColorScheme::kLight:
- // prefs->preferred_color_scheme = blink::PreferredColorScheme::kLight;
- // break;
- // case ui::NativeTheme::PreferredColorScheme::kNoPreference:
- // prefs->preferred_color_scheme = blink::PreferredColorScheme::kNoPreference;
- // }
- // }
+ if (webTheme) {
+ switch (webTheme->GetPreferredColorScheme()) {
+ case ui::NativeTheme::PreferredColorScheme::kDark:
+ prefs->preferred_color_scheme = blink::PreferredColorScheme::kDark;
+ break;
+ case ui::NativeTheme::PreferredColorScheme::kLight:
+ prefs->preferred_color_scheme = blink::PreferredColorScheme::kLight;
+ break;
+ }
+ }
// Apply native CaptionStyle parameters.
base::Optional<ui::CaptionStyle> style;
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index 95eea669f..d97ff5767 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -61,12 +61,15 @@
namespace content {
class WebContents;
-struct WebPreferences;
}
+
namespace blink {
namespace mojom {
class RendererPreferences;
}
+namespace web_pref {
+struct WebPreferences;
+}
}
namespace QtWebEngineCore {
@@ -142,7 +145,7 @@ public:
void setParentSettings(WebEngineSettings *parentSettings);
- void overrideWebPreferences(content::WebContents *webContents, content::WebPreferences *prefs);
+ void overrideWebPreferences(content::WebContents *webContents, blink::web_pref::WebPreferences *prefs);
void setAttribute(Attribute, bool on);
bool testAttribute(Attribute) const;
@@ -172,7 +175,7 @@ public:
private:
void doApply();
- void applySettingsToWebPreferences(content::WebPreferences *);
+ void applySettingsToWebPreferences(blink::web_pref::WebPreferences *);
bool applySettingsToRendererPreferences(blink::mojom::RendererPreferences *);
void setWebContentsAdapter(WebContentsAdapter *adapter) { m_adapter = adapter; }
@@ -181,7 +184,7 @@ private:
QHash<FontFamily, QString> m_fontFamilies;
QHash<FontSize, int> m_fontSizes;
QString m_defaultEncoding;
- QScopedPointer<content::WebPreferences> webPreferences;
+ QScopedPointer<blink::web_pref::WebPreferences> webPreferences;
QTimer m_batchTimer;
WebEngineSettings *parentSettings;
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 798ee9633..b6ca70294 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -1280,6 +1280,29 @@ static unsigned mouseButtonsModifiersForEvent(const T* event)
return ret;
}
+static WebInputEvent::Modifiers lockKeyModifiers(const quint32 nativeModifiers)
+{
+ unsigned result = 0;
+ if (keyboardDriver() == KeyboardDriver::Xkb) {
+ if (nativeModifiers & 0x42) /* Caps_Lock */
+ result |= WebInputEvent::kCapsLockOn;
+ if (nativeModifiers & 0x4d) /* Num_Lock */
+ result |= WebInputEvent::kNumLockOn;
+ } else if (keyboardDriver() == KeyboardDriver::Windows) {
+ if (nativeModifiers & 0x100) /* CapsLock */
+ result |= WebInputEvent::kCapsLockOn;
+ if (nativeModifiers & 0x200) /* NumLock */
+ result |= WebInputEvent::kNumLockOn;
+ if (nativeModifiers & 0x400) /* ScrollLock */
+ result |= WebInputEvent::kScrollLockOn;
+ } else if (keyboardDriver() == KeyboardDriver::Cocoa) {
+ if (nativeModifiers & 0x10000) /* NSEventModifierFlagCapsLock */
+ result |= WebInputEvent::kCapsLockOn;
+ }
+
+ return static_cast<WebInputEvent::Modifiers>(result);
+}
+
// If only a modifier key is pressed, Qt only reports the key code.
// But Chromium also expects the modifier being set.
static inline WebInputEvent::Modifiers modifierForKeyCode(int key)
@@ -1328,13 +1351,14 @@ static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* even
if (keyEvent->isAutoRepeat())
result |= WebInputEvent::kIsAutoRepeat;
result |= modifierForKeyCode(qtKeyForKeyEvent(keyEvent));
+ result |= lockKeyModifiers(keyEvent->nativeModifiers());
break;
}
default:
break;
}
- return (WebInputEvent::Modifiers)result;
+ return static_cast<WebInputEvent::Modifiers>(result);
}
static inline Qt::KeyboardModifiers keyboardModifiersForModifier(unsigned int modifier)
@@ -1382,36 +1406,36 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event)
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::TabletPress:
- return WebInputEvent::kMouseDown;
+ return WebInputEvent::Type::kMouseDown;
case QEvent::MouseButtonRelease:
case QEvent::TabletRelease:
- return WebInputEvent::kMouseUp;
+ return WebInputEvent::Type::kMouseUp;
case QEvent::Enter:
- return WebInputEvent::kMouseEnter;
+ return WebInputEvent::Type::kMouseEnter;
case QEvent::Leave:
- return WebInputEvent::kMouseLeave;
+ return WebInputEvent::Type::kMouseLeave;
case QEvent::MouseMove:
case QEvent::TabletMove:
- return WebInputEvent::kMouseMove;
+ return WebInputEvent::Type::kMouseMove;
case QEvent::Wheel:
- return WebInputEvent::kMouseWheel;
+ return WebInputEvent::Type::kMouseWheel;
case QEvent::KeyPress:
- return WebInputEvent::kRawKeyDown;
+ return WebInputEvent::Type::kRawKeyDown;
case QEvent::KeyRelease:
- return WebInputEvent::kKeyUp;
+ return WebInputEvent::Type::kKeyUp;
case QEvent::HoverMove:
- return WebInputEvent::kMouseMove;
+ return WebInputEvent::Type::kMouseMove;
case QEvent::TouchBegin:
- return WebInputEvent::kTouchStart;
+ return WebInputEvent::Type::kTouchStart;
case QEvent::TouchUpdate:
- return WebInputEvent::kTouchMove;
+ return WebInputEvent::Type::kTouchMove;
case QEvent::TouchEnd:
- return WebInputEvent::kTouchEnd;
+ return WebInputEvent::Type::kTouchEnd;
case QEvent::TouchCancel:
- return WebInputEvent::kTouchCancel;
+ return WebInputEvent::Type::kTouchCancel;
default:
Q_ASSERT(false);
- return WebInputEvent::kMouseMove;
+ return WebInputEvent::Type::kMouseMove;
}
}
@@ -1488,7 +1512,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev)
WebMouseEvent webKitEvent;
webKitEvent.SetTimeStamp(base::TimeTicks::Now());
- webKitEvent.SetType(WebInputEvent::kMouseLeave);
+ webKitEvent.SetType(WebInputEvent::Type::kMouseLeave);
return webKitEvent;
}
@@ -1508,20 +1532,26 @@ WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev)
Qt::NativeGestureType gestureType = ev->gestureType();
switch (gestureType) {
case Qt::ZoomNativeGesture:
- webKitEvent.SetType(WebInputEvent::kGesturePinchUpdate);
+ webKitEvent.SetType(WebInputEvent::Type::kGesturePinchUpdate);
webKitEvent.data.pinch_update.scale = static_cast<float>(ev->value() + 1.0);
break;
case Qt::SmartZoomNativeGesture:
- webKitEvent.SetType(WebInputEvent::kGestureDoubleTap);
+ webKitEvent.SetType(WebInputEvent::Type::kGestureDoubleTap);
webKitEvent.data.tap.tap_count = 1;
break;
case Qt::BeginNativeGesture:
+ webKitEvent.SetType(WebInputEvent::Type::kGesturePinchBegin);
+ webKitEvent.SetNeedsWheelEvent(true);
+ break;
case Qt::EndNativeGesture:
+ webKitEvent.SetType(WebInputEvent::Type::kGesturePinchEnd);
+ webKitEvent.SetNeedsWheelEvent(true);
+ break;
case Qt::RotateNativeGesture:
case Qt::PanNativeGesture:
case Qt::SwipeNativeGesture:
// Not implemented by Chromium for now.
- webKitEvent.SetType(blink::WebInputEvent::kUndefined);
+ webKitEvent.SetType(blink::WebInputEvent::Type::kUndefined);
break;
}
@@ -1557,7 +1587,7 @@ blink::WebMouseWheelEvent::Phase toBlinkPhase(QWheelEvent *ev)
#endif
return blink::WebMouseWheelEvent::kPhaseNone;
case Qt::ScrollBegin:
- return ev->angleDelta().isNull() ? blink::WebMouseWheelEvent::kPhaseMayBegin : blink::WebMouseWheelEvent::kPhaseBegan;
+ return blink::WebMouseWheelEvent::kPhaseBegan;
case Qt::ScrollUpdate:
return blink::WebMouseWheelEvent::kPhaseChanged;
case Qt::ScrollEnd:
@@ -1637,7 +1667,7 @@ static QPointF toQt(gfx::PointF p)
void WebEventFactory::sendUnhandledWheelEvent(const blink::WebGestureEvent &event,
RenderWidgetHostViewQtDelegate *delegate)
{
- Q_ASSERT(event.GetType() == blink::WebInputEvent::kGestureScrollUpdate);
+ Q_ASSERT(event.GetType() == blink::WebInputEvent::Type::kGestureScrollUpdate);
QWheelEvent ev(toQt(event.PositionInWidget()),
toQt(event.PositionInScreen()),
diff --git a/src/pdf/config/common.pri b/src/pdf/config/common.pri
index dd5bfa293..ec65b7bff 100644
--- a/src/pdf/config/common.pri
+++ b/src/pdf/config/common.pri
@@ -1,6 +1,50 @@
include($$QTWEBENGINE_OUT_ROOT/src/pdf/qtpdf-config.pri)
QT_FOR_CONFIG += pdf-private
+gn_args += use_nss_certs=false
+
+qtConfig(webengine-qt-png) {
+ gn_args += pdfium_use_qt_libpng=true
+ gn_args += "pdfium_qt_libpng_includes=\"$$system_path($$QMAKE_INCDIR_LIBPNG)\""
+}
+
+qtConfig(webengine-qt-jpeg) {
+ gn_args += use_qt_libjpeg=true
+ gn_args += "qt_libjpeg_includes=\"$$system_path($$QMAKE_INCDIR_LIBJPEG)\""
+}
+
+qtConfig(webengine-qt-harfbuzz) {
+ gn_args += use_qt_harfbuzz=true
+ gn_args += "qt_harfbuzz_includes=\"$$system_path($$QMAKE_INCDIR_HARFBUZZ)\""
+}
+
+qtConfig(webengine-qt-freetype) {
+ gn_args += use_qt_freetype=true
+ gn_args += "qt_freetype_includes=\"$$system_path($$QMAKE_INCDIR_FREETYPE)\""
+}
+
+qtConfig(webengine-qt-zlib) {
+ win32 {
+ CONFIG(debug, debug|release) {
+ qtzlib = Qt5Cored.lib
+ } else {
+ qtzlib = Qt5Core.lib
+ }
+
+ } else { qtzlib = libQt5Core.a
+ }
+ gn_args += use_qt_zlib = true
+ gn_args += "qt_zlib_includes=\["\
+ "\"$$system_path($$[QT_INSTALL_HEADERS])\"," \
+ "\"$$system_path($$[QT_INSTALL_HEADERS]/QtCore)\"," \
+ "\"$$system_path($$[QT_INSTALL_HEADERS]/QtZlib)\"\]"
+ gn_args += "qt_zlib=\"$$system_path($$[QT_INSTALL_LIBS]/$$qtzlib)\""
+}
+
+linux:!qtConfig(webengine-ozone-x11) {
+ gn_args += use_xkbcommon=false
+}
+
qtConfig(pdf-v8) {
gn_args += pdf_enable_v8=true
} else {
@@ -36,3 +80,9 @@ qtConfig(pdf-xfa-tiff) {
} else {
gn_args += pdf_enable_xfa_tiff=false
}
+qtConfig(pdf-bitcode) {
+ gn_args += enable_ios_bitcode=true
+}
+qtConfig(pdf-static-runtime) {
+ gn_args += qt_uses_static_runtime=true
+}
diff --git a/src/pdf/config/ios.pri b/src/pdf/config/ios.pri
index 1dcbeffde..c930c3fe3 100644
--- a/src/pdf/config/ios.pri
+++ b/src/pdf/config/ios.pri
@@ -17,7 +17,7 @@ enable_message_center=false \
enable_nacl=false \
enable_remoting=false \
enable_reporting=false \
-enable_resource_whitelist_generation=false \
+enable_resource_allowlist_generation=false \
enable_swiftshader=false \
enable_web_speech=false \
has_native_accessibility=false \
@@ -37,6 +37,7 @@ clang_base_path=\"$${clang_dir}\" \
ios_enable_code_signing=false \
target_os=\"ios\" \
ios_deployment_target=\"$${QMAKE_IOS_DEPLOYMENT_TARGET}\" \
+mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION_MAJOR_MINOR}\" \
enable_ios_bitcode=true \
use_jumbo_build=false
diff --git a/src/pdf/configure.json b/src/pdf/configure.json
index ddc0e99dc..b1f872982 100644
--- a/src/pdf/configure.json
+++ b/src/pdf/configure.json
@@ -2,7 +2,7 @@
"module": "pdf",
"depends" : [ "buildtools-private" ],
"testDir": "../../config.tests",
- "condition": "features.build-qtpdf && features.webengine-qtpdf-support",
+ "condition": "module.gui && features.webengine-qtpdf-support && features.build-qtpdf",
"libraries": {
},
"tests": {
@@ -44,7 +44,19 @@
"purpose": "Enables XFA-TIFF support.",
"condition": "features.pdf-xfa",
"output": ["privateFeature" ]
- }
+ },
+ "pdf-bitcode": {
+ "label": "Bitcode support",
+ "purpose": "Enables bitcode",
+ "condition": "config.ios",
+ "output": ["privateFeature"]
+ },
+ "pdf-static-runtime": {
+ "label": "Use static runtime",
+ "purpose": "Enables static runtime",
+ "condition": "config.static && config.static_runtime",
+ "output": ["privateFeature"]
+ }
},
"report": [
],
@@ -57,7 +69,9 @@
"pdf-xfa-bmp",
"pdf-xfa-gif",
"pdf-xfa-png",
- "pdf-xfa-tiff"
+ "pdf-xfa-tiff",
+ "pdf-bitcode",
+ "pdf-static-runtime"
]
}
]
diff --git a/src/pdf/gn_run.pro b/src/pdf/gn_run.pro
index 70ee582a9..0e559472a 100644
--- a/src/pdf/gn_run.pro
+++ b/src/pdf/gn_run.pro
@@ -27,39 +27,60 @@ build_pass|!debug_and_release {
gn_binary = gn
runninja.target = run_ninja
+ QMAKE_EXTRA_TARGETS += runninja
# fixme: refine args
gn_args = $$gnPdfArgs()
- # fixme: qtwebengine_target
- gn_args += "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtPdf\""
-
# fixme:
!qtConfig(webengine-system-gn) {
gn_binary = $$system_quote($$system_path($$gnPath()))
}
- gn_args = $$system_quote($$gn_args)
gn_src_root = $$system_quote($$system_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir()))
- gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$getConfigDir()))
gn_python = "--script-executable=$$pythonPathForSystem()"
- gn_run = $$gn_binary gen $$gn_build_root $$gn_python --args=$$gn_args --root=$$gn_src_root
-
- message("Running: $$gn_run ")
- !system($$gn_run) {
- error("GN run error!")
- }
ninjaflags = $$(NINJAFLAGS)
isEmpty(ninjaflags):!silent: ninjaflags = "-v"
- runninja.commands = $$NINJA $$ninjaflags -C $$gn_build_root QtPdf
- QMAKE_EXTRA_TARGETS += runninja
+ enableThreads = $$(GN_MORE_THREADS)
+ isEmpty(enableThreads):macos {
+ gn_threads = "--threads=1"
+ }
build_pass:build_all: default_target.target = all
else: default_target.target = first
default_target.depends = runninja
QMAKE_EXTRA_TARGETS += default_target
+
+ isUniversal(){
+ for(arch, QT_ARCHS) {
+ # fixme: qtwebengine_target
+ gn_target = "qtwebengine_target=\"$$system_path($$OUT_PWD/$$arch/$$getConfigDir()):QtPdf\""
+ gn_args_per_arch = $$system_quote($$gn_args $$gn_target target_cpu=\"$$gnArch($$arch)\")
+ gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$arch/$$getConfigDir()))
+ gn_run = $$gn_binary gen $$gn_build_root $$gn_python $$gn_threads --args=$$gn_args_per_arch --root=$$gn_src_root
+ message("Running for $$arch: $$gn_run")
+ !system($$gn_run) {
+ error("GN run error for $$arch!")
+ }
+ runninja_$${arch}.target = run_ninja_$${arch}
+ runninja_$${arch}.commands = $$NINJA $$ninjaflags -C $$gn_build_root QtPdf
+ QMAKE_EXTRA_TARGETS += runninja_$${arch}
+ runninja.depends += runninja_$${arch}
+ }
+ } else {
+ gn_args+= "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtPdf\""
+ gn_args = $$system_quote($$gn_args)
+ gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$getConfigDir()))
+ gn_run = $$gn_binary gen $$gn_build_root $$gn_python $$gn_threads --args=$$gn_args --root=$$gn_src_root
+ message("Running: $$gn_run")
+ !system($$gn_run) {
+ error("GN run error!")
+ }
+ runninja.commands = $$NINJA $$ninjaflags -C $$gn_build_root QtPdf
+ }
+
}
!build_pass:debug_and_release {
diff --git a/src/pdf/pdf.pro b/src/pdf/pdf.pro
index 9f98c32b0..fedcc9bde 100644
--- a/src/pdf/pdf.pro
+++ b/src/pdf/pdf.pro
@@ -3,13 +3,22 @@ QT_FOR_CONFIG += buildtools-private
TEMPLATE = subdirs
pdfcore.file = pdfcore.pro
pdfcore_generator.file = pdfcore_generator.pro
+
+pdfcore_lipo.file = pdfcore_lipo.pro
+pdfcore_lipo.depends = gn_run
+
gn_run.file = gn_run.pro
pdfcore_prl_generator.file = pdfcore_prl_generator.pro
gn_run.depends = pdfcore_generator
pdfcore_prl_generator.depends = gn_run
-pdfcore.depends = pdfcore_prl_generator
quick.depends = pdfcore
+isUniversal() {
+ pdfcore.depends += pdfcore_lipo
+} else {
+ pdfcore.depends += pdfcore_prl_generator
+}
+
!qtConfig(webengine-qtpdf-support):qtConfig(build-qtpdf)::!build_pass {
!qtwebengine_makeCheckPdfError() {
errorbuild.commands = @echo $$shell_quote("QtPdf will not be built. $${skipBuildReason}")
@@ -24,8 +33,13 @@ quick.depends = pdfcore
SUBDIRS += \
pdfcore_generator \
gn_run \
- pdfcore_prl_generator \
pdfcore \
quick
+
+ isUniversal() {
+ SUBDIRS += pdfcore_lipo
+ } else {
+ SUBDIRS += pdfcore_prl_generator
+ }
}
diff --git a/src/pdf/pdfcore.pro b/src/pdf/pdfcore.pro
index 2dfe39dc0..c2626a48a 100644
--- a/src/pdf/pdfcore.pro
+++ b/src/pdf/pdfcore.pro
@@ -27,11 +27,15 @@ msvc {
QMAKE_CXXFLAGS_WARN_ON += -wd"4100"
}
-include($${QTWEBENGINE_ROOT}/src/buildtools/config/linking.pri)
+isUniversal() {
+ include($${QTWEBENGINE_ROOT}/src/buildtools/config/lipo_linking.pri)
+} else {
+ include($${QTWEBENGINE_ROOT}/src/buildtools/config/linking.pri)
+}
# install static dependencies and handle prl files for static builds
-static:!isEmpty(NINJA_ARCHIVES) {
+static:!isEmpty(NINJA_ARCHIVES):!isUniversal() {
static_dep_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}_static_dep.pri
!include($${static_dep_pri}) {
error("Could not find the prl information.")
@@ -77,4 +81,11 @@ HEADERS += \
api/qpdfselection.h \
api/qpdfselection_p.h \
+
+qtConfig(webengine-qt-freetype): QMAKE_USE += freetype
+qtConfig(webengine-qt-png): QMAKE_USE += libpng
+qtConfig(webengine-qt-harfbuzz): QMAKE_USE += harfbuzz
+qtConfig(webengine-qt-jpeg): QMAKE_USE += libjpeg
+qtConfig(webengine-qt-zlib){} #qtzlib is a part of QtCore
+
load(qt_module)
diff --git a/src/pdf/pdfcore_generator.pro b/src/pdf/pdfcore_generator.pro
index e5c7258b7..0930256ca 100644
--- a/src/pdf/pdfcore_generator.pro
+++ b/src/pdf/pdfcore_generator.pro
@@ -5,7 +5,13 @@ TEMPLATE = lib
CONFIG = gn_generator $$CONFIG
CONFIG -=static # note we still do static when linking
GN_SRC_DIR = $$PWD
-GN_FILE = $$OUT_PWD/$$getConfigDir()/BUILD.gn
+isUniversal() {
+ for(arch, QT_ARCHS) {
+ GN_FILES += $$OUT_PWD/$$arch/$$getConfigDir()/BUILD.gn
+ }
+} else {
+ GN_FILES = $$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/qtpdf.gni
diff --git a/src/pdf/pdfcore_lipo.pro b/src/pdf/pdfcore_lipo.pro
new file mode 100644
index 000000000..6caf2ac75
--- /dev/null
+++ b/src/pdf/pdfcore_lipo.pro
@@ -0,0 +1,5 @@
+TEMPLATE = aux
+
+TARGET= QtPdf
+include($${QTWEBENGINE_ROOT}/src/buildtools/config/lipo.pri)
+
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index e4ec363ce..c07ec90c4 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -424,6 +424,8 @@ QRectF QPdfDocumentPrivate::getCharBox(FPDF_TEXTPAGE textPage, double pageHeight
QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF position)
{
const QPdfMutexLocker lock;
+
+ TextPosition result;
FPDF_PAGE pdfPage = FPDF_LoadPage(doc, page);
double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
@@ -440,10 +442,14 @@ QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF
++hitIndex;
}
qCDebug(qLcDoc) << "on page" << page << "@" << position << "got char position" << charPos << "index" << hitIndex;
- return { charPos, charBox.height(), hitIndex };
+ result = { charPos, charBox.height(), hitIndex };
}
}
- return {};
+
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
+ return result;
}
/*!
@@ -789,6 +795,9 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
CharacterHitTolerance, CharacterHitTolerance);
int endIndex = FPDFText_GetCharIndexAtPos(textPage, end.x(), pageHeight - end.y(),
CharacterHitTolerance, CharacterHitTolerance);
+
+ QPdfSelection result;
+
if (startIndex >= 0 && endIndex != startIndex) {
if (startIndex > endIndex)
qSwap(startIndex, endIndex);
@@ -815,11 +824,15 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
bounds << QPolygonF(rect);
}
qCDebug(qLcDoc) << page << start << "->" << end << "found" << startIndex << "->" << endIndex << text;
- return QPdfSelection(text, bounds, hull, startIndex, endIndex);
+ result = QPdfSelection(text, bounds, hull, startIndex, endIndex);
+ } else {
+ qCDebug(qLcDoc) << page << start << "->" << end << "nothing found";
}
- qCDebug(qLcDoc) << page << start << "->" << end << "nothing found";
- return QPdfSelection();
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
+ return result;
}
/*!
@@ -860,6 +873,10 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma
hull = QRectF(d->getCharPosition(textPage, pageHeight, startIndex), QSizeF());
qCDebug(qLcDoc) << "on page" << page << "at index" << startIndex << "maxLength" << maxLength
<< "got" << text.length() << "chars," << rectCount << "rects within" << hull;
+
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
return QPdfSelection(text, bounds, hull, startIndex, startIndex + text.length());
}
@@ -890,6 +907,10 @@ QPdfSelection QPdfDocument::getAllText(int page)
bounds << QPolygonF(rect);
}
qCDebug(qLcDoc) << "on page" << page << "got" << count << "chars," << rectCount << "rects within" << hull;
+
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
return QPdfSelection(text, bounds, hull, 0, count);
}
diff --git a/src/pdf/quick/qquickpdfdocument.cpp b/src/pdf/quick/qquickpdfdocument.cpp
index ab5910523..79b23ca84 100644
--- a/src/pdf/quick/qquickpdfdocument.cpp
+++ b/src/pdf/quick/qquickpdfdocument.cpp
@@ -94,7 +94,7 @@ void QQuickPdfDocument::setSource(QUrl source)
if (source.scheme() == QLatin1String("qrc"))
m_doc.load(QLatin1Char(':') + source.path());
else
- m_doc.load(source.path());
+ m_doc.load(source.toLocalFile());
}
/*!
diff --git a/src/pdf/quick/qquickpdfsearchmodel.cpp b/src/pdf/quick/qquickpdfsearchmodel.cpp
index 1f62fbad0..b40b9f924 100644
--- a/src/pdf/quick/qquickpdfsearchmodel.cpp
+++ b/src/pdf/quick/qquickpdfsearchmodel.cpp
@@ -39,7 +39,7 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(qLcS, "qt.pdf.search")
+Q_LOGGING_CATEGORY(qLcSearch, "qt.pdf.search")
/*!
\qmltype PdfSearchModel
@@ -282,7 +282,7 @@ void QQuickPdfSearchModel::setCurrentResult(int currentResult)
currentResult = 0;
}
}
- qCDebug(qLcS) << "currentResult was" << m_currentResult
+ qCDebug(qLcSearch) << "currentResult was" << m_currentResult
<< "requested" << currentResultWas << "on page" << currentPageWas
<< "->" << currentResult << "on page" << m_currentPage;
diff --git a/src/pdfwidgets/configure.json b/src/pdfwidgets/configure.json
index b33f08555..bef08ef72 100644
--- a/src/pdfwidgets/configure.json
+++ b/src/pdfwidgets/configure.json
@@ -13,7 +13,7 @@
"pdf-widgets": {
"label": "Support Qt PDF Widgets",
"purpose": "Provides Qt PDF Widgets support.",
- "condition": "module.widgets",
+ "condition": "features.widgets",
"output": [ "privateFeature" ]
}
},
diff --git a/src/pdfwidgets/qpdfview.cpp b/src/pdfwidgets/qpdfview.cpp
index 35e368633..32d0826af 100644
--- a/src/pdfwidgets/qpdfview.cpp
+++ b/src/pdfwidgets/qpdfview.cpp
@@ -461,9 +461,9 @@ void QPdfView::paintEvent(QPaintEvent *event)
const auto pageIt = d->m_pageCache.constFind(page);
if (pageIt != d->m_pageCache.cend()) {
const QImage &img = pageIt.value();
- painter.drawImage(pageGeometry.topLeft(), img);
+ painter.drawImage(pageGeometry, img);
} else {
- d->m_pageRenderer->requestPage(page, pageGeometry.size());
+ d->m_pageRenderer->requestPage(page, pageGeometry.size() * devicePixelRatioF());
}
}
}
diff --git a/src/plugins/qwebengineview/qwebengineview.pro b/src/plugins/qwebengineview/qwebengineview.pro
index c18b6fe94..6c82cdb4c 100644
--- a/src/plugins/qwebengineview/qwebengineview.pro
+++ b/src/plugins/qwebengineview/qwebengineview.pro
@@ -3,7 +3,6 @@ QT += designer webenginewidgets
PLUGIN_CLASS_NAME = QWebEngineViewPlugin
PLUGIN_TYPE = designer
-CONFIG += tool_plugin
load(qt_plugin)
SOURCES += qwebengineview_plugin.cpp
diff --git a/src/process/process.pro b/src/process/process.pro
index a28267ee9..149bce526 100644
--- a/src/process/process.pro
+++ b/src/process/process.pro
@@ -37,9 +37,9 @@ win32 {
support_win.cpp
msvc: QMAKE_LFLAGS += /MANIFESTINPUT:$$PWD/process.exe.manifest
- VERSION = $${QT_VERSION}.0
+ VERSION = $${MODULE_VERSION}.0
} else {
- VERSION = $${QT_VERSION}
+ VERSION = $${MODULE_VERSION}
}
TEMPLATE = app
diff --git a/src/process/support_win.cpp b/src/process/support_win.cpp
index 4fe69b7a9..b415dc2a5 100644
--- a/src/process/support_win.cpp
+++ b/src/process/support_win.cpp
@@ -47,6 +47,7 @@
#ifndef NDEBUG
#include "../3rdparty/chromium/base/command_line.h"
+#include "../3rdparty/chromium/base/logging.h"
#endif
class User32DLL {
diff --git a/src/src.pro b/src/src.pro
index 6f8bc2fe4..c99904309 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -29,7 +29,7 @@ qtConfig(build-qtwebengine-core):qtConfig(webengine-core-support) {
SUBDIRS += buildtools core process
- qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile {
+ qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile:!isUniversal() {
SUBDIRS += qwebengine_convert_dict
qwebengine_convert_dict.subdir = tools/qwebengine_convert_dict
qwebengine_convert_dict.depends = core
diff --git a/src/tools/qwebengine_convert_dict/main.cpp b/src/tools/qwebengine_convert_dict/main.cpp
index 37b6e0171..cfabbcdf7 100644
--- a/src/tools/qwebengine_convert_dict/main.cpp
+++ b/src/tools/qwebengine_convert_dict/main.cpp
@@ -126,7 +126,7 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
return true;
}
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
QString frameworkIcuDataPath()
{
return QLibraryInfo::location(QLibraryInfo::LibrariesPath) +
@@ -164,7 +164,7 @@ int main(int argc, char *argv[])
icuDataDir = icuPossibleEnvDataDir;
icuDataDirFound = true;
}
-#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
// In a macOS Qt framework build, the resources are inside the QtWebEngineCore framework
// Resources directory, rather than in the Qt install location.
else if (QFileInfo::exists(frameworkIcuDataPath())) {
diff --git a/src/webengine/api/qquickwebengineloadrequest.cpp b/src/webengine/api/qquickwebengineloadrequest.cpp
index 5ad99ea2e..db7399dc0 100644
--- a/src/webengine/api/qquickwebengineloadrequest.cpp
+++ b/src/webengine/api/qquickwebengineloadrequest.cpp
@@ -97,10 +97,13 @@ QUrl QQuickWebEngineLoadRequest::url() const
This enumeration represents the load status of a web page load request:
- \value WebEngineLoadRequest.LoadStartedStatus Page is currently loading.
- \value WebEngineLoadRequest.LoadSucceededStatus
+ \value WebEngineView.LoadStartedStatus Page is currently loading.
+ \value WebEngineView.LoadStoppedStatus
+ Loading the page was stopped by the stop() method or by the loader
+ code or network stack in Chromium.
+ \value WebEngineView.LoadSucceededStatus
Page has been loaded with success.
- \value WebEngineLoadRequest.LoadFailedStatus Page could not be loaded.
+ \value WebEngineView.LoadFailedStatus Page could not be loaded.
\sa WebEngineView::loadingChanged
*/
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 834bb6a05..a5a0b4ccb 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -837,6 +837,7 @@ bool QQuickWebEngineProfile::isSpellCheckEnabled() const
/*!
\property QQuickWebEngineProfile::useForGlobalCertificateVerification
\since 5.13
+ \obsolete
This property holds whether this profile is used for downloading and
caching during global certificate verification when using the online
@@ -850,13 +851,17 @@ bool QQuickWebEngineProfile::isSpellCheckEnabled() const
By default, no profile has this property enabled.
- Currently, only affects Linux/NSS installations, where having a profile with
- this role enables OCSP.
+ Originally only affected Linux/NSS installations, where having a profile with
+ this role enabled OCSP.
+
+ Since 5.15.3 no longer does anything, and certificate verification is now
+ done using AIO on the requesting profile.
*/
/*!
\qmlproperty bool WebEngineProfile::useForGlobalCertificateVerification
\since QtWebEngine 1.9
+ \obsolete
This property holds whether this profile is used for downloading and
caching during global certificate verification when using the online
@@ -870,8 +875,11 @@ bool QQuickWebEngineProfile::isSpellCheckEnabled() const
By default, no profile has this property enabled.
- Currently, only affects Linux/NSS installations, where having a profile with
- this role enables OCSP.
+ Originally only affected Linux/NSS installations, where having a profile with
+ this role enabled OCSP.
+
+ Since 5.15.3 no longer does anything, and certificate verification is now
+ done using AIO on the requesting profile.
*/
void QQuickWebEngineProfile::setUseForGlobalCertificateVerification(bool enable)
diff --git a/src/webengine/api/qquickwebenginetouchhandleprovider.cpp b/src/webengine/api/qquickwebenginetouchhandleprovider.cpp
index 80f4727b6..d6d6116dd 100644
--- a/src/webengine/api/qquickwebenginetouchhandleprovider.cpp
+++ b/src/webengine/api/qquickwebenginetouchhandleprovider.cpp
@@ -67,7 +67,7 @@ void QQuickWebEngineTouchHandleProvider::init(const QMap<int, QImage> &images)
return;
}
- m_touchHandleMap.unite(images);
+ m_touchHandleMap = images;
}
QImage QQuickWebEngineTouchHandleProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 7b875bf55..50e0711af 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -220,12 +220,14 @@ RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHo
const bool hasWindowCapability = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows);
RenderWidgetHostViewQtDelegateQuick *quickDelegate = new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ true);
if (hasWindowCapability) {
- RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow = new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate);
+ RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow =
+ new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate, q->window());
wrapperWindow->setVirtualParent(q);
quickDelegate->setParentItem(wrapperWindow->contentItem());
return wrapperWindow;
}
quickDelegate->setParentItem(q);
+ quickDelegate->show();
return quickDelegate;
}
@@ -235,7 +237,6 @@ void QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu
m_contextMenuData = data;
- QQuickWebEngineContextMenuRequest *request = new QQuickWebEngineContextMenuRequest(data);
QQmlEngine *engine = qmlEngine(q);
// TODO: this is a workaround for QTBUG-65044
@@ -243,6 +244,7 @@ void QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu
return;
// mark the object for gc by creating temporary jsvalue
+ QQuickWebEngineContextMenuRequest *request = new QQuickWebEngineContextMenuRequest(data);
engine->newQObject(request);
Q_EMIT q->contextMenuRequested(request);
@@ -432,6 +434,12 @@ void QQuickWebEngineViewPrivate::selectionChanged()
updateEditActions();
}
+void QQuickWebEngineViewPrivate::zoomUpdateIsNeeded()
+{
+ Q_Q(QQuickWebEngineView);
+ q->setZoomFactor(m_zoomFactor);
+}
+
void QQuickWebEngineViewPrivate::recentlyAudibleChanged(bool recentlyAudible)
{
Q_Q(QQuickWebEngineView);
@@ -872,6 +880,11 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
d->q_ptr = this;
this->setActiveFocusOnTab(true);
this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsDrops);
+
+ connect(action(WebAction::Back), &QQuickWebEngineAction::enabledChanged,
+ this, &QQuickWebEngineView::canGoBackChanged);
+ connect(action(WebAction::Forward), &QQuickWebEngineAction::enabledChanged,
+ this, &QQuickWebEngineView::canGoForwardChanged);
}
QQuickWebEngineView::~QQuickWebEngineView()
@@ -901,10 +914,8 @@ void QQuickWebEngineViewPrivate::initializationFinished()
emit q->backgroundColorChanged();
}
- if (!qFuzzyCompare(adapter->currentZoomFactor(), m_zoomFactor)) {
- adapter->setZoomFactor(m_zoomFactor);
- emit q->zoomFactorChanged(m_zoomFactor);
- }
+ // apply if it was set before first ever navigation already
+ q->setZoomFactor(m_zoomFactor);
#if QT_CONFIG(webengine_webchannel)
if (m_webChannel)
@@ -984,11 +995,14 @@ void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegateQui
if (oldWidget) {
oldWidget->setParentItem(nullptr);
#if QT_CONFIG(accessibility)
- QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(QAccessible::queryAccessibleInterface(oldWidget)));
+ if (!QtWebEngineCore::closingDown())
+ QAccessible::deleteAccessibleInterface(
+ QAccessible::uniqueId(QAccessible::queryAccessibleInterface(oldWidget)));
#endif
}
if (newWidget) {
+ Q_ASSERT(!QtWebEngineCore::closingDown());
#if QT_CONFIG(accessibility)
QAccessible::registerAccessibleInterface(new QtWebEngineCore::RenderWidgetHostViewQtDelegateQuickAccessible(newWidget, q));
#endif
@@ -1139,9 +1153,11 @@ void QQuickWebEngineView::stop()
void QQuickWebEngineView::setZoomFactor(qreal arg)
{
Q_D(QQuickWebEngineView);
- if (d->adapter->isInitialized() && !qFuzzyCompare(d->m_zoomFactor, d->adapter->currentZoomFactor())) {
+ if (d->adapter->isInitialized() && !qFuzzyCompare(arg, zoomFactor())) {
d->adapter->setZoomFactor(arg);
- emit zoomFactorChanged(arg);
+ // MEMO: should reset if factor was not applied due to being invalid
+ d->m_zoomFactor = zoomFactor();
+ emit zoomFactorChanged(d->m_zoomFactor);
} else {
d->m_zoomFactor = arg;
}
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index ab84b2600..3155bce37 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -116,8 +116,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(bool loading READ isLoading NOTIFY loadingChanged FINAL)
Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged FINAL)
Q_PROPERTY(QString title READ title NOTIFY titleChanged FINAL)
- Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY urlChanged FINAL)
- Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY urlChanged FINAL)
+ Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY canGoBackChanged FINAL)
+ Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY canGoForwardChanged FINAL)
Q_PROPERTY(bool isFullScreen READ isFullScreen NOTIFY isFullScreenChanged REVISION 1 FINAL)
Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged REVISION 1 FINAL)
Q_PROPERTY(QQuickWebEngineProfile *profile READ profile WRITE setProfile NOTIFY profileChanged FINAL REVISION 1)
@@ -581,6 +581,8 @@ Q_SIGNALS:
Q_REVISION(10) void recommendedStateChanged(LifecycleState state);
Q_REVISION(10) void findTextFinished(const QWebEngineFindTextResult &result);
Q_REVISION(11) void renderProcessPidChanged(qint64 pid);
+ Q_REVISION(11) void canGoBackChanged();
+ Q_REVISION(11) void canGoForwardChanged();
#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 68d65410a..a03f009f9 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -109,6 +109,7 @@ public:
void loadProgressChanged(int progress) override;
void didUpdateTargetURL(const QUrl&) override;
void selectionChanged() override;
+ void zoomUpdateIsNeeded() override;
void recentlyAudibleChanged(bool recentlyAudible) override;
void renderProcessPidChanged(qint64 pid) override;
QRectF viewportRect() const override;
@@ -116,7 +117,7 @@ public:
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override;
void loadVisuallyCommitted() override;
- void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) override;
+ void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) override;
void focusContainer() override;
void unhandledKeyEvent(QKeyEvent *event) override;
QSharedPointer<QtWebEngineCore::WebContentsAdapter>
diff --git a/src/webengine/api/qtwebengineglobal.cpp b/src/webengine/api/qtwebengineglobal.cpp
index 4346832c9..47b729ebc 100644
--- a/src/webengine/api/qtwebengineglobal.cpp
+++ b/src/webengine/api/qtwebengineglobal.cpp
@@ -72,8 +72,7 @@ namespace QtWebEngine {
*/
void initialize()
{
- QCoreApplication *app = QCoreApplication::instance();
- if (app) {
+ if (!QCoreApplication::startingUp()) {
qWarning("QtWebEngine::initialize() called with QCoreApplication object already created and should be call before. "\
"This is depreciated and may fail in the future.");
QtWebEngineCore::initialize();
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index 1c30f9858..9908d46a8 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -89,7 +89,7 @@
\l{https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md}{overview}
that is part of the documentation in the \l {Chromium Project} upstream source tree.
- This version of \QWE is based on Chromium version 80.0.3987, with additional security
+ This version of \QWE is based on Chromium version 87.0.4280, with additional security
fixes from newer versions.
\section2 Qt WebEngine Process
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index dac010058..9f75beb85 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -65,7 +65,7 @@
\li \l Python 2.7.5 or later. Python 3 is not supported.
\li Bison, Flex
\li GPerf
- \li Node.js for a full featured Dev Tools.
+ \li Node.js version 8 or later (version 12 or later is recommended)
\endlist
\section2 Windows
@@ -73,10 +73,10 @@
On Windows, the following additional tools are required:
\list
- \li Visual Studio 2017 version 15.8 or later
+ \li Visual Studio 2017 version 15.8 or later, or clang-cl version 8 or later
\li Active Template Library (ATL), usually included in the Visual Studio
installation
- \li Windows 10 SDK version 10.0.18362 or later
+ \li Windows 10 SDK version 10.0.19041 or later
\endlist
\QWE can only be built on 64-bit Windows, with a x64-bit toolchain.
@@ -126,6 +126,10 @@
\note \QWE cannot be built for the 32-bit mode of \macos (using the
\c macx-clang-32 \c mkspec).
+ \note Universal debug or debug-and-release builds of \QWE on \macos are not supported in Qt 5
+ due to memory constraints of the build toolchain. Use the configure options \c -force-debug-info
+ and \c -separate-debug-info for a build that can be used with a debugger.
+
\section1 Using Earlier Qt Versions to Build \QWE
Building \QWE with earlier Qt versions (down to the last LTS
@@ -221,13 +225,11 @@
or VoiceOver on \macos.
\endlist
- Due to some limitations, the Linux QPA plugin almost always reports that accessibility should
- be activated. On big HTML pages, this can cause a significant slowdown in rendering speed.
+ On some old Linux configurations, accessibility can cause a significant slowdown
+ on large HTML pages.
- Because of that, from Qt 5.9 onwards, \QWE accessibility support is disabled by default
- on Linux.
- It can be re-enabled by setting the \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
- variable to a non-empty value.
+ Because of that, \QWE accessibility support can be disabled on Linux, by setting the
+ \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment variable to 0.
\section1 Popups in Fullscreen Applications on Windows
Because of a limitation in the Windows compositor, applications that show a fullscreen web
diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc
index 0cd8441cf..0a78d65d5 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -1156,8 +1156,6 @@
Also if the audio is paused, this signal is emitted with an approximate \b{two-second
delay}, from the moment the audio is paused.
- This signal is also emitted for Flash plugin audio.
-
If a web page contains two videos that are started in sequence, this signal
gets emitted only once, for the first video to generate sound. After both
videos are stopped, the signal is emitted upon the last sound generated.
@@ -1233,8 +1231,6 @@
\a wasRecentlyAudible, is changed, due to audio being played or stopped.
\note The signal is also emitted when calling the setAudioMuted method.
- Also if the audio is paused, this signal is emitted with an approximate \b{2 second
- delay}, from the moment the audio is paused.
*/
/*!
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 6a5bef16d..e729f7532 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -41,13 +41,16 @@
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
+
#include <QGuiApplication>
-#include <QQuickPaintedItem>
#include <QQuickWindow>
-#include <QSurfaceFormat>
#include <QVariant>
#include <QWindow>
-#include <QtQuick/private/qquickwindow_p.h>
+
+#if defined(Q_OS_MACOS) && QT_CONFIG(opengl)
+#include <QOpenGLContext>
+#include <QSurfaceFormat>
+#endif
namespace QtWebEngineCore {
@@ -88,14 +91,13 @@ RenderWidgetHostViewQtDelegateQuick::~RenderWidgetHostViewQtDelegateQuick()
QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, this);
}
-void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
+void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &screenRect)
{
+ //note this is called when there is no windowing system
+ //otherwsie see RenderWidgetHostViewQtDelegateQuickWindow
Q_ASSERT(m_isPopup && parentItem());
- QRectF rect(parentItem()->mapRectFromScene(r));
- setX(rect.x());
- setY(rect.y());
- setWidth(rect.width());
- setHeight(rect.height());
+ setPosition(screenRect.topLeft());
+ setSize(screenRect.size());
setVisible(true);
}
@@ -168,22 +170,11 @@ QSGTexture *RenderWidgetHostViewQtDelegateQuick::createTextureFromImage(const QI
return QQuickItem::window()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
}
-QSGLayer *RenderWidgetHostViewQtDelegateQuick::createLayer()
-{
- QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
- return renderContext->sceneGraphContext()->createLayer(renderContext);
-}
-
QSGImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode()
{
return QQuickItem::window()->createImageNode();
}
-QSGRectangleNode *RenderWidgetHostViewQtDelegateQuick::createRectangleNode()
-{
- return QQuickItem::window()->createRectangleNode();
-}
-
void RenderWidgetHostViewQtDelegateQuick::update()
{
QQuickItem::update();
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 f70de50d7..86ee5fedd 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -72,9 +72,7 @@ public:
bool isVisible() const override;
QWindow* window() const override;
QSGTexture *createTextureFromImage(const QImage &) override;
- QSGLayer *createLayer() override;
QSGImageNode *createImageNode() override;
- QSGRectangleNode *createRectangleNode() override;
void update() override;
void updateCursor(const QCursor &) override;
void resize(int width, int height) override;
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 1de4d8835..e16ebd9ab 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -44,9 +44,19 @@
namespace QtWebEngineCore {
-RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate)
- : m_realDelegate(realDelegate)
- , m_virtualParent(nullptr)
+static inline QPoint getOffset(QQuickItem *item)
+{
+ // get parent window (scene) offset
+ QPointF offset = item->mapFromScene(QPoint(0, 0));
+ offset = item->mapToGlobal(offset);
+ // get local offset
+ offset -= item->mapToScene(QPoint(0, 0));
+ return offset.toPoint();
+}
+
+RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(
+ RenderWidgetHostViewQtDelegateQuick *realDelegate, QWindow *parent)
+ : QQuickWindow(parent), m_realDelegate(realDelegate), m_virtualParent(nullptr)
{
setFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
}
@@ -61,30 +71,12 @@ void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *vir
m_virtualParent = virtualParent;
}
-static inline QRectF mapRectToGlobal(const QQuickItem *item, const QRectF &rect)
-{
- const QPointF p1 = item->mapToGlobal(rect.topLeft());
- const QPointF p2 = item->mapToGlobal(rect.bottomRight());
- return QRectF(p1, p2).normalized();
-}
-
-static inline QRectF mapRectFromGlobal(const QQuickItem *item, const QRectF &rect)
-{
- const QPointF p1 = item->mapFromGlobal(rect.topLeft());
- const QPointF p2 = item->mapFromGlobal(rect.bottomRight());
- return QRectF(p1, p2).normalized();
-}
-
-void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &screenRect)
+void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &rect)
{
- QRectF popupRect(screenRect);
- popupRect = mapRectFromGlobal(m_virtualParent, popupRect);
- popupRect = m_virtualParent->mapRectToScene(popupRect);
- popupRect = mapRectToGlobal(m_virtualParent, popupRect);
-
- m_realDelegate->initAsPopup(QRect(QPoint(0, 0), popupRect.size().toSize()));
- popupRect.setSize(screenRect.size());
- setGeometry(popupRect.toAlignedRect());
+ m_realDelegate->setSize(rect.size());
+ QRect geometry(rect);
+ geometry.moveTo(rect.topLeft() - getOffset(m_virtualParent));
+ setGeometry(geometry);
raise();
show();
}
@@ -126,21 +118,11 @@ QSGTexture *RenderWidgetHostViewQtDelegateQuickWindow::createTextureFromImage(co
return m_realDelegate->createTextureFromImage(image);
}
-QSGLayer *RenderWidgetHostViewQtDelegateQuickWindow::createLayer()
-{
- return m_realDelegate->createLayer();
-}
-
QSGImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createImageNode()
{
return m_realDelegate->createImageNode();
}
-QSGRectangleNode *RenderWidgetHostViewQtDelegateQuickWindow::createRectangleNode()
-{
- return m_realDelegate->createRectangleNode();
-}
-
void RenderWidgetHostViewQtDelegateQuickWindow::update()
{
QQuickWindow::update();
@@ -160,12 +142,7 @@ void RenderWidgetHostViewQtDelegateQuickWindow::resize(int width, int height)
void RenderWidgetHostViewQtDelegateQuickWindow::move(const QPoint &screenPos)
{
- QRectF popupRect(screenPos, size());
- popupRect = mapRectFromGlobal(m_virtualParent, popupRect);
- popupRect = m_virtualParent->mapRectToScene(popupRect);
- popupRect = mapRectToGlobal(m_virtualParent, popupRect);
-
- QQuickWindow::setPosition(popupRect.topLeft().toPoint());
+ QQuickWindow::setPosition(screenPos - getOffset(m_virtualParent));
}
} // namespace QtWebEngineCore
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index bebbfa439..555e56484 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -52,7 +52,8 @@ namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public RenderWidgetHostViewQtDelegate {
public:
- RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate);
+ RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate,
+ QWindow *parent);
~RenderWidgetHostViewQtDelegateQuickWindow();
void initAsPopup(const QRect&) override;
@@ -67,9 +68,7 @@ public:
bool isVisible() const override;
QWindow* window() const override;
QSGTexture *createTextureFromImage(const QImage &) override;
- QSGLayer *createLayer() override;
QSGImageNode *createImageNode() override;
- QSGRectangleNode *createRectangleNode() override;
void update() override;
void updateCursor(const QCursor &) override;
void resize(int width, int height) override;
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index 7366dbf59..d44b9e4e9 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -465,7 +465,7 @@ QWebEngineDownloadItem::DownloadState QWebEngineDownloadItem::state() const
}
/*!
- Returns the the total amount of data to download in bytes.
+ Returns the total amount of data to download in bytes.
\c -1 means the size is unknown.
*/
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 6fb3c5c43..3c16ede56 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -247,6 +247,12 @@ void QWebEnginePagePrivate::selectionChanged()
});
}
+void QWebEnginePagePrivate::zoomUpdateIsNeeded()
+{
+ Q_Q(QWebEnginePage);
+ q->setZoomFactor(defaultZoomFactor);
+}
+
void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible)
{
Q_Q(QWebEnginePage);
@@ -289,22 +295,13 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE
Q_UNUSED(errorCode);
Q_UNUSED(errorDescription);
- if (isErrorPage) {
- Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled));
- QTimer::singleShot(0, q, [q](){
- emit q->loadFinished(false);
- });
+ if (isErrorPage)
return;
- }
isLoading = false;
- // Delay notifying failure until the error-page is done loading.
- // Error-pages are not loaded on failures due to abort.
- if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) {
- QTimer::singleShot(0, q, [q, success](){
- emit q->loadFinished(success);
- });
- }
+ QTimer::singleShot(0, q, [q, success](){
+ emit q->loadFinished(success);
+ });
}
void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool success)
@@ -337,8 +334,13 @@ QWebEnginePagePrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebC
Q_UNUSED(targetUrl);
QWebEnginePage *newPage = q->createWindow(toWindowType(disposition));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (!newPage)
return nullptr;
+#else
+ if (!newPage)
+ return adapter;
+#endif
if (!newWebContents->webContents())
return newPage->d_func()->adapter; // Reuse existing adapter
@@ -477,6 +479,10 @@ void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserControlle
QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), dialog, SLOT(deleteLater()));
QColorDialog::connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater()));
+#if defined(Q_OS_MACOS)
+ dialog->setOption(QColorDialog::DontUseNativeDialog);
+#endif
+
dialog->open();
#else
Q_UNUSED(controller);
@@ -911,8 +917,6 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
the audio is played or stopped.
\note The signal is also emitted when calling the setAudioMuted() method.
- Also, if the audio is paused, this signal is emitted with an approximate \b{two-second
- delay}, from the moment the audio is paused.
*/
/*!
@@ -2148,8 +2152,12 @@ void QWebEnginePage::setZoomFactor(qreal factor)
{
Q_D(QWebEnginePage);
d->defaultZoomFactor = factor;
- if (d->adapter->isInitialized())
+
+ if (d->adapter->isInitialized()) {
d->adapter->setZoomFactor(factor);
+ // MEMO: should reset if factor was not applied due to being invalid
+ d->defaultZoomFactor = zoomFactor();
+ }
}
void QWebEnginePage::runJavaScript(const QString &scriptSource)
@@ -2214,7 +2222,7 @@ QWebEnginePage *QWebEnginePage::createWindow(WebWindowType type)
if (newView)
return newView->page();
}
- return 0;
+ return nullptr;
}
/*!
@@ -2522,6 +2530,10 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+ \note This function rasterizes the result when rendering onto \a printer. Please consider raising
+ the default resolution of \a printer to at least 300 DPI or using printToPdf() to produce
+ PDF file output more effectively.
+
\since 5.8
*/
void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 3ddf4b3d6..65252f8d8 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -100,6 +100,7 @@ public:
void loadProgressChanged(int progress) override;
void didUpdateTargetURL(const QUrl&) override;
void selectionChanged() override;
+ void zoomUpdateIsNeeded() override;
void recentlyAudibleChanged(bool recentlyAudible) override;
void renderProcessPidChanged(qint64 pid) override;
QRectF viewportRect() const override;
@@ -107,7 +108,7 @@ public:
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
void loadCommitted() override { }
void loadVisuallyCommitted() override { }
- void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) override;
+ void loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) override;
void focusContainer() override;
void unhandledKeyEvent(QKeyEvent *event) override;
QSharedPointer<QtWebEngineCore::WebContentsAdapter>
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 4c49be709..b25055d79 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -228,6 +228,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
itemPrivate->downloadState = info.accepted ? QWebEngineDownloadItem::DownloadInProgress
: QWebEngineDownloadItem::DownloadRequested;
itemPrivate->startTime = info.startTime;
+ itemPrivate->totalBytes = info.totalBytes;
itemPrivate->downloadDirectory = QFileInfo(info.path).path();
itemPrivate->downloadFileName = QFileInfo(info.path).fileName();
itemPrivate->suggestedFileName = info.suggestedFileName;
@@ -830,6 +831,8 @@ void QWebEngineProfile::removeAllUrlSchemeHandlers()
/*!
\since 5.13
+ \obsolete
+
Sets if this profile is to be used for downloading and caching when needed
during certificate verification, for instance for OCSP, CRLs, and AIA.
@@ -838,11 +841,14 @@ void QWebEngineProfile::removeAllUrlSchemeHandlers()
needlessly re-downloading. If you set the option on a second profile,
it will be disabled on the profile it is currently set.
- Currently only affects Linux/NSS installations where it enables OCSP.
-
As long as one profile has \a enabled set to \c true, all other profiles
will be able to use it for their certificate verification.
+ Originally only affected Linux/NSS installations where it enabled OCSP.
+
+ Since 5.15.3, no longer does anything. Certificate verification is done
+ using AIO on the requesting profile.
+
\sa isUsedForGlobalCertificateVerification(), httpCacheType()
*/
void QWebEngineProfile::setUseForGlobalCertificateVerification(bool enabled)
@@ -854,6 +860,8 @@ void QWebEngineProfile::setUseForGlobalCertificateVerification(bool enabled)
/*!
\since 5.13
+ \obsolete
+
Returns \c true if this profile is currently being used for global
certificate verification.
*/
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index b06d99478..46a4887f2 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -62,7 +62,15 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage
if (oldPage) {
oldPage->setVisible(false);
- oldPage->disconnect(q);
+ QObject::disconnect(oldPage, &QWebEnginePage::titleChanged, q, &QWebEngineView::titleChanged);
+ QObject::disconnect(oldPage, &QWebEnginePage::urlChanged, q, &QWebEngineView::urlChanged);
+ QObject::disconnect(oldPage, &QWebEnginePage::iconUrlChanged, q, &QWebEngineView::iconUrlChanged);
+ QObject::disconnect(oldPage, &QWebEnginePage::iconChanged, q, &QWebEngineView::iconChanged);
+ QObject::disconnect(oldPage, &QWebEnginePage::loadStarted, q, &QWebEngineView::loadStarted);
+ QObject::disconnect(oldPage, &QWebEnginePage::loadProgress, q, &QWebEngineView::loadProgress);
+ QObject::disconnect(oldPage, &QWebEnginePage::loadFinished, q, &QWebEngineView::loadFinished);
+ QObject::disconnect(oldPage, &QWebEnginePage::selectionChanged, q, &QWebEngineView::selectionChanged);
+ QObject::disconnect(oldPage, &QWebEnginePage::renderProcessTerminated, q, &QWebEngineView::renderProcessTerminated);
}
if (newPage) {
@@ -108,11 +116,14 @@ void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQ
q->layout()->removeWidget(oldWidget);
oldWidget->hide();
#if QT_CONFIG(accessibility)
- QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(QAccessible::queryAccessibleInterface(oldWidget)));
+ if (!QtWebEngineCore::closingDown())
+ QAccessible::deleteAccessibleInterface(
+ QAccessible::uniqueId(QAccessible::queryAccessibleInterface(oldWidget)));
#endif
}
if (newWidget) {
+ Q_ASSERT(!QtWebEngineCore::closingDown());
#if QT_CONFIG(accessibility)
// An earlier QAccessible::queryAccessibleInterface() call may have already registered a default
// QAccessibleInterface for newWidget: remove it first to avoid assert in QAccessibleCache::insert().
diff --git a/src/webenginewidgets/configure.json b/src/webenginewidgets/configure.json
index a27faf78d..8aa41abce 100644
--- a/src/webenginewidgets/configure.json
+++ b/src/webenginewidgets/configure.json
@@ -13,7 +13,7 @@
"webengine-widgets": {
"label": "Support Qt WebEngine Widgets",
"purpose": "Provides WebEngine Widgets support.",
- "condition": "module.widgets",
+ "condition": "features.widgets",
"output": [ "privateFeature" ]
}
},
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 789d9794e..d88e8c48c 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -381,6 +381,12 @@
used as part of the user interface, and not to display external data, for example, when
displaying a list of results.
+ \note This function is not called for fragment navigation on the same page. Such navigation,
+ for example, happens by clicking a link to a '#fragment' within the page. It does not trigger
+ a load to a different document, even though it changes page's url and adds history entry.
+ It only serves as a shortcut to scroll within the page. Hence, no delegation of this navigation
+ type is expected to happen.
+
\note The loading process is started and the loadStarted() signal is emitted
\e before the request is accepted or rejected. Therefore, a loadFinished()
signal that returns \c false is to be expected even after delegating the
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index b83da9440..b7000b30d 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -106,13 +106,11 @@
Enables support for the HTML 5 local storage feature. Enabled by default.
\value LocalContentCanAccessRemoteUrls
Allows locally loaded documents to ignore cross-origin rules so that they can access
- remote resources that would normally be blocked, because all remote resources are
- considered cross-origin for a local file. Remote access that would not be blocked by
+ remote resources that would normally be blocked, since remote resources are
+ considered cross-origin for a local document. Remote access that would not be blocked by
cross-origin rules is still possible when this setting is disabled (default).
- Note that disabling this setting does not stop XMLHttpRequests or media elements in
- local files from accessing remote content. Basically, it only stops some HTML
- subresources, such as scripts, and therefore disabling this setting is not a safety
- mechanism.
+ Note that disabling this setting does not prevent media elements in local files from
+ accessing remote content. Disabled by default.
\value XSSAuditingEnabled
Obsolete and has no effect.
\value SpatialNavigationEnabled
@@ -123,7 +121,8 @@
trying to reach towards the right and which element they probably want.
Disabled by default.
\value LocalContentCanAccessFileUrls
- Allows locally loaded documents to access other local URLs. Enabled by default.
+ Allows locally loaded documents to access other local URLs. Disabling this makes QtWebEngine
+ behave more like Chrome and Firefox does by default. Enabled by default.
\value HyperlinkAuditingEnabled
Enables support for the \c ping attribute for hyperlinks. Disabled by default.
\value ScrollAnimatorEnabled
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 1dfcc4c5a..a559c15d0 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -50,7 +50,6 @@
#include <QSGAbstractRenderer>
#include <QSGNode>
#include <QWindow>
-#include <QtQuick/private/qquickwindow_p.h>
namespace QtWebEngineCore {
@@ -271,6 +270,10 @@ void RenderWidgetHostViewQtDelegateWidget::show()
// want to show anything else than popups as top-level.
if (parent() || m_isPopup) {
QQuickWidget::show();
+
+ QWebEngineView *view = static_cast<QWebEngineView *>(parent());
+ if (view && view->isWindow())
+ update();
}
}
@@ -296,22 +299,11 @@ QSGTexture *RenderWidgetHostViewQtDelegateWidget::createTextureFromImage(const Q
return quickWindow()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
}
-QSGLayer *RenderWidgetHostViewQtDelegateWidget::createLayer()
-{
- QSGRenderContext *renderContext = QQuickWindowPrivate::get(quickWindow())->context;
- return renderContext->sceneGraphContext()->createLayer(renderContext);
-}
-
QSGImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode()
{
return quickWindow()->createImageNode();
}
-QSGRectangleNode *RenderWidgetHostViewQtDelegateWidget::createRectangleNode()
-{
- return quickWindow()->createRectangleNode();
-}
-
void RenderWidgetHostViewQtDelegateWidget::update()
{
m_rootItem->update();
@@ -460,6 +452,26 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
break;
}
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ // Don't forward mouse events synthesized by the system, which are caused by genuine touch
+ // events. Chromium would then process for e.g. a mouse click handler twice, once due to the
+ // system synthesized mouse event, and another time due to a touch-to-gesture-to-mouse
+ // transformation done by Chromium.
+ // Only allow them for popup type, since QWidgetWindow will ignore them for Qt::Popup flag,
+ // which is expected to get input through synthesized mouse events (either by system or Qt)
+ if (!m_isPopup && static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem) {
+ Q_ASSERT(!windowFlags().testFlag(Qt::Popup));
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
if (event->type() == QEvent::MouseButtonDblClick) {
// QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event.
// QtQuick is different by sending both the Press and DblClick events for the second press
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 034fdd65c..fd8654d95 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -80,9 +80,7 @@ public:
bool isVisible() const override;
QWindow* window() const override;
QSGTexture *createTextureFromImage(const QImage &) override;
- QSGLayer *createLayer() override;
QSGImageNode *createImageNode() override;
- QSGRectangleNode *createRectangleNode() override;
void update() override;
void updateCursor(const QCursor &) override;
void resize(int width, int height) override;
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index 5290d5373..bcaebc5f5 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -249,22 +249,27 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QWebEngineCookieStore *client = m_profile->cookieStore();
QAtomicInt accessTested = 0;
- client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return true; });
+ QList<QPair<QUrl, QUrl>> resourceFirstParty;
+ client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &request) {
+ resourceFirstParty.append(qMakePair(request.origin, request.firstPartyUrl));
+ ++accessTested;
+ return true;
+ });
HttpServer httpServer;
-
- if (!httpServer.start())
- QSKIP("Failed to start http server");
+ httpServer.setHostDomain(QString("sub.test.localhost"));
+ QVERIFY(httpServer.start());
QByteArray cookieRequestHeader;
connect(&httpServer, &HttpServer::newRequest, [&cookieRequestHeader](HttpReqRep *rr) {
- if (rr->requestPath().size() <= 1) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == "/test.html") {
cookieRequestHeader = rr->requestHeader(QByteArrayLiteral("Cookie"));
if (cookieRequestHeader.isEmpty())
rr->setResponseHeader(QByteArrayLiteral("Set-Cookie"), QByteArrayLiteral("Test=test"));
+ rr->setResponseBody("<head><link rel='icon' type='image/png' href='resources/Fav.png'/>"
+ "<title>Page with a favicon and an icon</title></head>"
+ "<body><img src='resources/Img.ico'></body>");
rr->sendResponse();
- } else {
- rr->sendResponse(404);
}
});
@@ -273,12 +278,13 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
QSignalSpy serverSpy(&httpServer, SIGNAL(newRequest(HttpReqRep *)));
- page.load(httpServer.url());
+ QUrl firstPartyUrl = httpServer.url("/test.html");
+ page.load(firstPartyUrl);
QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QTRY_COMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 3);
+ QTRY_COMPARE(accessTested.loadAcquire(), 4);
QVERIFY(cookieRequestHeader.isEmpty());
page.triggerAction(QWebEnginePage::Reload);
@@ -286,12 +292,16 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QVERIFY(!cookieRequestHeader.isEmpty());
QTRY_COMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 5);
+ QTRY_COMPARE(accessTested.loadAcquire(), 7);
client->deleteAllCookies();
QTRY_COMPARE(cookieRemovedSpy.count(), 1);
- client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return false; });
+ client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &request) {
+ resourceFirstParty.append(qMakePair(request.origin, request.firstPartyUrl));
+ ++accessTested;
+ return false;
+ });
page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
@@ -299,8 +309,7 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
// Test cookies are NOT added:
QTest::qWait(100);
QCOMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 8);
-
+ QTRY_COMPARE(accessTested.loadAcquire(), 11);
page.triggerAction(QWebEnginePage::Reload);
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
@@ -308,8 +317,13 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QCOMPARE(cookieAddedSpy.count(), 1);
// Wait for last GET /favicon.ico
- QTRY_COMPARE(serverSpy.count(), 8);
+ QTRY_COMPARE(serverSpy.count(), 12);
(void) httpServer.stop();
+
+ QCOMPARE(resourceFirstParty.size(), accessTested.loadAcquire());
+ for (auto &&p : qAsConst(resourceFirstParty))
+ QVERIFY2(p.second == firstPartyUrl,
+ qPrintable(QString("Resource [%1] has wrong firstPartyUrl: %2").arg(p.first.toString(), p.second.toString())));
}
void tst_QWebEngineCookieStore::html5featureFilter()
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html
index 360ad65ef..84bf55036 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html
@@ -1,5 +1,6 @@
<html>
+<head><link rel="icon" href="data:,"></head>
<body>
-<a>This is test content</a>
+<a>Simple test page without favicon (meaning no separate request from http server)</a>
</body>
</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content2.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content2.html
new file mode 100644
index 000000000..84bf55036
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content2.html
@@ -0,0 +1,6 @@
+<html>
+<head><link rel="icon" href="data:,"></head>
+<body>
+<a>Simple test page without favicon (meaning no separate request from http server)</a>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html
new file mode 100644
index 000000000..84bf55036
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html
@@ -0,0 +1,6 @@
+<html>
+<head><link rel="icon" href="data:,"></head>
+<body>
+<a>Simple test page without favicon (meaning no separate request from http server)</a>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 20e191a4f..32a618de3 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -70,12 +70,16 @@ private Q_SLOTS:
void requestInterceptorByResourceType();
void firstPartyUrlHttp_data();
void firstPartyUrlHttp();
- void passRefererHeader_data();
- void passRefererHeader();
+ void customHeaders_data();
+ void customHeaders();
void initiator_data();
void initiator();
void jsServiceWorker_data();
void jsServiceWorker();
+ void replaceInterceptor_data();
+ void replaceInterceptor();
+ void replaceOnIntercept();
+ void multipleRedirects();
};
tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor()
@@ -116,36 +120,43 @@ struct RequestInfo {
int resourceType;
};
-static const QByteArray kHttpHeaderReferrerValue = QByteArrayLiteral("http://somereferrer.com/");
-static const QByteArray kHttpHeaderRefererName = QByteArrayLiteral("referer");
static const QUrl kRedirectUrl = QUrl("qrc:///resources/content.html");
+Q_LOGGING_CATEGORY(lc, "qt.webengine.tests")
+
class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
public:
QList<RequestInfo> requestInfos;
bool shouldRedirect = false;
+ QUrl redirectUrl;
QMap<QUrl, QSet<QUrl>> requestInitiatorUrls;
QMap<QByteArray, QByteArray> headers;
+ std::function<bool (QWebEngineUrlRequestInfo &)> onIntercept;
void interceptRequest(QWebEngineUrlRequestInfo &info) override
{
QCOMPARE(QThread::currentThread() == QCoreApplication::instance()->thread(), !property("deprecated").toBool());
+ qCDebug(lc) << this << "Type:" << info.resourceType() << info.requestMethod() << "Navigation:" << info.navigationType()
+ << info.requestUrl() << "Initiator:" << info.initiator();
// Since 63 we also intercept some unrelated blob requests..
if (info.requestUrl().scheme() == QLatin1String("blob"))
return;
+ if (onIntercept && !onIntercept(info))
+ return;
+
bool block = info.requestMethod() != QByteArrayLiteral("GET");
- bool redirect = shouldRedirect && info.requestUrl() != kRedirectUrl;
+ bool redirect = shouldRedirect && info.requestUrl() != redirectUrl;
+
+ // set additional headers if any required by test
+ for (auto it = headers.begin(); it != headers.end(); ++it) info.setHttpHeader(it.key(), it.value());
if (block) {
info.block(true);
} else if (redirect) {
- info.redirect(kRedirectUrl);
- } else {
- // set additional headers if any required by test
- for (auto it = headers.begin(); it != headers.end(); ++it) info.setHttpHeader(it.key(), it.value());
+ info.redirect(redirectUrl);
}
requestInitiatorUrls[info.requestUrl()].insert(info.initiator());
@@ -195,8 +206,31 @@ public:
return false;
}
- TestRequestInterceptor(bool redirect)
- : shouldRedirect(redirect)
+ TestRequestInterceptor(bool redirect = false, const QUrl &url = kRedirectUrl)
+ : shouldRedirect(redirect), redirectUrl(url)
+ {
+ }
+};
+
+class TestMultipleRedirectsInterceptor : public QWebEngineUrlRequestInterceptor {
+public:
+ QList<RequestInfo> requestInfos;
+ QMap<QUrl, QUrl> redirectPairs;
+ int redirectCount = 0;
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ QVERIFY(QThread::currentThread() == QCoreApplication::instance()->thread());
+ qCDebug(lc) << this << "Type:" << info.resourceType() << info.requestMethod() << "Navigation:" << info.navigationType()
+ << info.requestUrl() << "Initiator:" << info.initiator();
+ auto redirectUrl = redirectPairs.constFind(info.requestUrl());
+ if (redirectUrl != redirectPairs.constEnd()) {
+ info.redirect(redirectUrl.value());
+ requestInfos.append(info);
+ redirectCount++;
+ }
+ }
+
+ TestMultipleRedirectsInterceptor()
{
}
};
@@ -578,12 +612,6 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
QList<RequestInfo> infos;
- // SubFrame
- QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame));
- infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
- foreach (auto info, infos)
- QCOMPARE(info.firstPartyUrl, firstPartyUrl);
-
// Stylesheet
QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet));
infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet);
@@ -627,43 +655,69 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
QCOMPARE(info.firstPartyUrl, firstPartyUrl);
}
-void tst_QWebEngineUrlRequestInterceptor::passRefererHeader_data()
+void tst_QWebEngineUrlRequestInterceptor::customHeaders_data()
{
interceptRequest_data();
}
-void tst_QWebEngineUrlRequestInterceptor::passRefererHeader()
+void tst_QWebEngineUrlRequestInterceptor::customHeaders()
{
QFETCH(InterceptorSetter, setter);
// Create HTTP Server to parse the request.
HttpServer httpServer;
-
- if (!httpServer.start())
- QSKIP("Failed to start http server");
-
- bool succeeded = false;
- connect(&httpServer, &HttpServer::newRequest, [&succeeded](HttpReqRep *rr) {
- const QByteArray headerValue = rr->requestHeader(kHttpHeaderRefererName);
- QCOMPARE(headerValue, kHttpHeaderReferrerValue);
- succeeded = headerValue == kHttpHeaderReferrerValue;
- rr->sendResponse();
- });
+ httpServer.setResourceDirs({ TESTS_SOURCE_DIR "qwebengineurlrequestinterceptor/resources" });
+ QVERIFY(httpServer.start());
QWebEngineProfile profile;
TestRequestInterceptor interceptor(false);
- interceptor.headers.insert(kHttpHeaderRefererName, kHttpHeaderReferrerValue);
(profile.*setter)(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
- QWebEngineHttpRequest httpRequest;
- QUrl requestUrl = httpServer.url();
- httpRequest.setUrl(requestUrl);
- page.load(httpRequest);
+ interceptor.headers = {
+ { "referer", "http://somereferrer.com/" },
+ { "from", "user@example.com" },
+ { "user-agent", "mozilla/5.0 (x11; linux x86_64; rv:12.0) gecko/20100101 firefox/12.0" },
+ };
+
+ QMap<QByteArray, QByteArray> actual, expected;
+ connect(&httpServer, &HttpServer::newRequest, [&] (HttpReqRep *rr) {
+ for (auto it = expected.begin(); it != expected.end(); ++it) {
+ auto headerValue = rr->requestHeader(it.key());
+ actual[it.key()] = headerValue;
+ QCOMPARE(headerValue, it.value());
+ }
+ });
+
+ auto dumpHeaders = [&] () {
+ QString s; QDebug d(&s);
+ for (auto it = expected.begin(); it != expected.end(); ++it)
+ d << "\n\tHeader:" << it.key() << "| actual:" << actual[it.key()] << "expected:" << it.value();
+ return s;
+ };
+
+ expected = interceptor.headers;
+ page.load(httpServer.url("/content.html"));
QVERIFY(spy.wait());
+ QVERIFY2(actual == expected, qPrintable(dumpHeaders()));
+
+ // test that custom headers are also applied on redirect
+ interceptor.shouldRedirect = true;
+ interceptor.redirectUrl = httpServer.url("/content2.html");
+ interceptor.headers = {
+ { "referer", "http://somereferrer2.com/" },
+ { "from", "user2@example.com" },
+ { "user-agent", "mozilla/5.0 (compatible; googlebot/2.1; +http://www.google.com/bot.html)" },
+ };
+
+ actual.clear();
+ expected = interceptor.headers;
+ page.triggerAction(QWebEnginePage::Reload);
+ QVERIFY(spy.wait());
+ QVERIFY2(actual == expected, qPrintable(dumpHeaders()));
+
(void) httpServer.stop();
- QVERIFY(succeeded);
}
void tst_QWebEngineUrlRequestInterceptor::initiator_data()
@@ -687,12 +741,6 @@ void tst_QWebEngineUrlRequestInterceptor::initiator()
QList<RequestInfo> infos;
- // SubFrame
- QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame));
- infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
- foreach (auto info, infos)
- QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
-
// Stylesheet
QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet));
infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet);
@@ -760,7 +808,7 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
QTRY_COMPARE(page->messages.count(), 1);
QCOMPARE(page->levels.at(0), QWebEnginePage::InfoMessageLevel);
- QUrl firstPartyUrl = QUrl(server.url().toString(QUrl::RemovePort));
+ QUrl firstPartyUrl = QUrl(server.url().toString() + "sw.js");
QList<RequestInfo> infos;
// Service Worker
QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker));
@@ -771,5 +819,148 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
QVERIFY(server.stop());
}
+void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor_data()
+{
+ QTest::addColumn<bool>("firstInterceptIsInPage");
+ QTest::addColumn<bool>("keepInterceptionPoint");
+ QTest::newRow("page") << true << true;
+ QTest::newRow("page-profile") << true << false;
+ QTest::newRow("profile") << false << true;
+ QTest::newRow("profile-page") << false << false;
+}
+
+void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor()
+{
+ QFETCH(bool, firstInterceptIsInPage);
+ QFETCH(bool, keepInterceptionPoint);
+
+ HttpServer server;
+ server.setResourceDirs({ ":/resources" });
+ QVERIFY(server.start());
+
+ QWebEngineProfile profile;
+ profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ QWebEnginePage page(&profile);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+ bool fetchFinished = false;
+
+ auto setInterceptor = [&] (QWebEngineUrlRequestInterceptor *interceptor, bool interceptInPage) {
+ interceptInPage ? page.setUrlRequestInterceptor(interceptor) : profile.setUrlRequestInterceptor(interceptor);
+ };
+
+ std::vector<TestRequestInterceptor> interceptors(3);
+ std::vector<int> requestsOnReplace;
+ setInterceptor(&interceptors.front(), firstInterceptIsInPage);
+
+ auto sc = connect(&page, &QWebEnginePage::loadFinished, [&] () {
+ auto currentInterceptorIndex = requestsOnReplace.size();
+ requestsOnReplace.push_back(interceptors[currentInterceptorIndex].requestInfos.size());
+
+ bool isFirstReinstall = currentInterceptorIndex == 0;
+ bool interceptInPage = keepInterceptionPoint ? firstInterceptIsInPage : (isFirstReinstall ^ firstInterceptIsInPage);
+ setInterceptor(&interceptors[++currentInterceptorIndex], interceptInPage);
+ if (!keepInterceptionPoint)
+ setInterceptor(nullptr, !interceptInPage);
+
+ if (isFirstReinstall) {
+ page.triggerAction(QWebEnginePage::Reload);
+ } else {
+ page.runJavaScript("fetch('http://nonexistent.invalid').catch(() => {})", [&, interceptInPage] (const QVariant &) {
+ requestsOnReplace.push_back(interceptors.back().requestInfos.size());
+ setInterceptor(nullptr, interceptInPage);
+ fetchFinished = true;
+ });
+ }
+ });
+
+ page.setUrl(server.url("/favicon.html"));
+ QTRY_COMPARE(spy.count(), 2);
+ QTRY_VERIFY(fetchFinished);
+
+ QString s; QDebug d(&s);
+ for (auto i = 0u; i < interceptors.size(); ++i) {
+ auto &&interceptor = interceptors[i];
+ auto &&requests = interceptor.requestInfos;
+ d << "\nInterceptor [" << i << "] with" << requestsOnReplace[i] << "requests on replace and" << requests.size() << "in the end:";
+ for (int j = 0; j < requests.size(); ++j) {
+ auto &&r = requests[j];
+ d << "\n\t" << j << "| url:" << r.requestUrl << "firstPartyUrl:" << r.firstPartyUrl;
+ }
+ QVERIFY2(!requests.isEmpty(), qPrintable(s));
+ QVERIFY2(requests.size() == requestsOnReplace[i], qPrintable(s));
+ }
+}
+
+void tst_QWebEngineUrlRequestInterceptor::replaceOnIntercept()
+{
+ HttpServer server;
+ server.setResourceDirs({ ":/resources" });
+ QVERIFY(server.start());
+
+ QWebEngineProfile profile;
+ profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ QWebEnginePage page(&profile);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ struct Interceptor : QWebEngineUrlRequestInterceptor {
+ Interceptor(const std::function<void ()> &a) : action(a) { }
+ void interceptRequest(QWebEngineUrlRequestInfo &) override { action(); }
+ std::function<void ()> action;
+ int interceptRequestReceived = 0;
+ };
+
+ TestRequestInterceptor profileInterceptor, pageInterceptor1, pageInterceptor2;
+ page.setUrlRequestInterceptor(&pageInterceptor1);
+ profile.setUrlRequestInterceptor(&profileInterceptor);
+ profileInterceptor.onIntercept = [&] (QWebEngineUrlRequestInfo &) {
+ page.setUrlRequestInterceptor(&pageInterceptor2);
+ return true;
+ };
+
+ page.setUrl(server.url("/favicon.html"));
+ QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(profileInterceptor.requestInfos.size(), 2);
+
+ // if interceptor for page was replaced on intercept call in profile then, since request first
+ // comes to profile, forward to page's interceptor should land to second one
+ QCOMPARE(pageInterceptor1.requestInfos.size(), 0);
+ QCOMPARE(profileInterceptor.requestInfos.size(), pageInterceptor2.requestInfos.size());
+
+ page.setUrlRequestInterceptor(&pageInterceptor1);
+ bool fetchFinished = false;
+ page.runJavaScript("fetch('http://nonexistent.invalid').catch(() => {})", [&] (const QVariant &) {
+ page.setUrlRequestInterceptor(&pageInterceptor2);
+ fetchFinished = true;
+ });
+
+ QTRY_VERIFY(fetchFinished);
+ QCOMPARE(profileInterceptor.requestInfos.size(), 3);
+ QCOMPARE(pageInterceptor1.requestInfos.size(), 0);
+ QCOMPARE(profileInterceptor.requestInfos.size(), pageInterceptor2.requestInfos.size());
+}
+
+void tst_QWebEngineUrlRequestInterceptor::multipleRedirects()
+{
+ HttpServer server;
+ server.setResourceDirs({ ":/resources" });
+ QVERIFY(server.start());
+
+ TestMultipleRedirectsInterceptor multiInterceptor;
+ multiInterceptor.redirectPairs.insert(QUrl(server.url("/content.html")), QUrl(server.url("/content2.html")));
+ multiInterceptor.redirectPairs.insert(QUrl(server.url("/content2.html")), QUrl(server.url("/content3.html")));
+
+ QWebEngineProfile profile;
+ profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ profile.setUrlRequestInterceptor(&multiInterceptor);
+ QWebEnginePage page(&profile);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setUrl(server.url("/content.html"));
+
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE(multiInterceptor.redirectCount, 2);
+ QTRY_COMPARE(multiInterceptor.requestInfos.size(), 2);
+}
+
QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor)
#include "tst_qwebengineurlrequestinterceptor.moc"
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
index 6a34635f7..df9c81a7b 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
@@ -1,6 +1,8 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>resources/content.html</file>
+ <file>resources/content2.html</file>
+ <file>resources/content3.html</file>
<file>resources/favicon.html</file>
<file>resources/firstparty.html</file>
<file>resources/fontawesome.woff</file>
diff --git a/tests/auto/quick/dialogs/testhandler.cpp b/tests/auto/quick/dialogs/testhandler.cpp
index bdd63a547..78a944cc6 100644
--- a/tests/auto/quick/dialogs/testhandler.cpp
+++ b/tests/auto/quick/dialogs/testhandler.cpp
@@ -30,7 +30,7 @@
TestHandler::TestHandler(QObject *parent) : QObject(parent)
{
- setObjectName(QStringLiteral("TestListner"));
+ setObjectName(QStringLiteral("TestListener"));
}
QObject* TestHandler::request() const
diff --git a/tests/auto/quick/dialogs/tst_dialogs.cpp b/tests/auto/quick/dialogs/tst_dialogs.cpp
index 8e802a836..4df296bcd 100644
--- a/tests/auto/quick/dialogs/tst_dialogs.cpp
+++ b/tests/auto/quick/dialogs/tst_dialogs.cpp
@@ -29,22 +29,23 @@
#include "testhandler.h"
#include "server.h"
#include "util.h"
+
#include <QtWebEngine/private/qquickwebenginedialogrequests_p.h>
#include <QtWebEngine/private/qquickwebenginecontextmenurequest_p.h>
#include <QQuickWebEngineProfile>
+
+#include <QNetworkProxy>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
-#include <QTest>
#include <QSignalSpy>
-#include <QNetworkProxy>
-
+#include <QTest>
-class tst_Dialogs : public QObject {
+class tst_Dialogs : public QObject
+{
Q_OBJECT
public:
tst_Dialogs(){}
-
private slots:
void initTestCase();
void init();
@@ -57,11 +58,11 @@ private slots:
void authenticationDialogRequested();
private:
- void createDialog(const QLatin1String& dialog, bool &ok);
+ void createDialog(const QLatin1String &dialog, bool &ok);
private:
QScopedPointer<QQmlApplicationEngine> m_engine;
- QQuickWindow *m_widnow;
- TestHandler *m_listner;
+ QQuickWindow *m_window;
+ TestHandler *m_listener;
};
void tst_Dialogs::initTestCase()
@@ -70,10 +71,10 @@ void tst_Dialogs::initTestCase()
qmlRegisterType<TestHandler>("io.qt.tester", 1, 0, "TestHandler");
m_engine.reset(new QQmlApplicationEngine());
m_engine->load(QUrl(QStringLiteral("qrc:/WebView.qml")));
- m_widnow = qobject_cast<QQuickWindow*>(m_engine->rootObjects().first());
- Q_ASSERT(m_widnow);
- m_listner = m_widnow->findChild<TestHandler*>(QStringLiteral("TestListner"));
- Q_ASSERT(m_listner);
+ m_window = qobject_cast<QQuickWindow*>(m_engine->rootObjects().first());
+ Q_ASSERT(m_window);
+ m_listener = m_window->findChild<TestHandler*>(QStringLiteral("TestListener"));
+ Q_ASSERT(m_listener);
QNetworkProxy proxy;
proxy.setType(QNetworkProxy::HttpProxy);
@@ -84,29 +85,29 @@ void tst_Dialogs::initTestCase()
void tst_Dialogs::init()
{
- m_listner->setRequest(nullptr);
- m_listner->setReady(false);
+ m_listener->setRequest(nullptr);
+ m_listener->setReady(false);
}
-void tst_Dialogs::createDialog(const QLatin1String& dialog, bool &ok)
+void tst_Dialogs::createDialog(const QLatin1String &dialog, bool &ok)
{
QString trigger = QStringLiteral("document.getElementById('buttonOne').onclick = function() {document.getElementById('%1').click()}");
- QSignalSpy dialogSpy(m_listner, &TestHandler::requestChanged);
- m_listner->runJavaScript(trigger.arg(dialog));
- QTRY_VERIFY(m_listner->ready());
- QTest::mouseClick(m_widnow, Qt::LeftButton);
+ QSignalSpy dialogSpy(m_listener, &TestHandler::requestChanged);
+ m_listener->runJavaScript(trigger.arg(dialog));
+ QTRY_VERIFY(m_listener->ready());
+ QTest::mouseClick(m_window, Qt::LeftButton);
QTRY_COMPARE(dialogSpy.count(), 1);
ok = true;
}
void tst_Dialogs::colorDialogRequested()
{
- m_listner->load(QUrl("qrc:/index.html"));
- QTRY_VERIFY(m_listner->ready());
+ m_listener->load(QUrl("qrc:/index.html"));
+ QTRY_VERIFY(m_listener->ready());
bool ok = false;
createDialog(QLatin1String("colorpicker"), ok);
if (ok) {
- auto dialog = qobject_cast<QQuickWebEngineColorDialogRequest*>(m_listner->request());
+ auto *dialog = qobject_cast<QQuickWebEngineColorDialogRequest*>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
dialog->dialogReject();
QVERIFY2(dialog->isAccepted(), "Dialog is not accepted");
@@ -116,23 +117,23 @@ void tst_Dialogs::colorDialogRequested()
void tst_Dialogs::contextMenuRequested()
{
- m_listner->load(QUrl("qrc:/index.html"));
- QTRY_COMPARE_WITH_TIMEOUT(m_listner->ready(), true, 20000);
- QSignalSpy dialogSpy(m_listner, &TestHandler::requestChanged);
- QTest::mouseClick(m_widnow, Qt::RightButton);
+ m_listener->load(QUrl("qrc:/index.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(m_listener->ready(), true, 20000);
+ QSignalSpy dialogSpy(m_listener, &TestHandler::requestChanged);
+ QTest::mouseClick(m_window, Qt::RightButton);
QTRY_COMPARE(dialogSpy.count(), 1);
- auto dialog = qobject_cast<QQuickWebEngineContextMenuRequest*>(m_listner->request());
+ auto dialog = qobject_cast<QQuickWebEngineContextMenuRequest*>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
}
void tst_Dialogs::fileDialogRequested()
{
- m_listner->load(QUrl("qrc:/index.html"));
- QTRY_VERIFY(m_listner->ready());
+ m_listener->load(QUrl("qrc:/index.html"));
+ QTRY_VERIFY(m_listener->ready());
bool ok = false;
createDialog(QLatin1String("filepicker"), ok);
if (ok) {
- auto dialog = qobject_cast<QQuickWebEngineFileDialogRequest*>(m_listner->request());
+ auto dialog = qobject_cast<QQuickWebEngineFileDialogRequest*>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
dialog->dialogReject();
QVERIFY2(dialog->isAccepted(), "Dialog is not accepted");
@@ -173,11 +174,11 @@ void tst_Dialogs::authenticationDialogRequested()
server.run();
QTRY_VERIFY2(server.isListening(), "Could not setup authentication server");
- QSignalSpy dialogSpy(m_listner, &TestHandler::requestChanged);
- m_listner->load(url);
+ QSignalSpy dialogSpy(m_listener, &TestHandler::requestChanged);
+ m_listener->load(url);
QTRY_COMPARE(dialogSpy.count(), 1);
- auto dialog = qobject_cast<QQuickWebEngineAuthenticationDialogRequest*>(m_listner->request());
+ auto *dialog = qobject_cast<QQuickWebEngineAuthenticationDialogRequest*>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
dialog->dialogReject();
QVERIFY2(dialog->isAccepted(), "Dialog is not accepted");
@@ -214,20 +215,20 @@ void tst_Dialogs::javaScriptDialogRequested()
QFETCH(QString, message);
QFETCH(QString, defaultText);
- m_listner->load(QUrl("qrc:/index.html"));
- QTRY_VERIFY(m_listner->ready());
+ m_listener->load(QUrl("qrc:/index.html"));
+ QTRY_VERIFY(m_listener->ready());
- QSignalSpy dialogSpy(m_listner, &TestHandler::requestChanged);
- m_listner->runJavaScript(script);
+ QSignalSpy dialogSpy(m_listener, &TestHandler::requestChanged);
+ m_listener->runJavaScript(script);
QTRY_COMPARE(dialogSpy.count(), 1);
- auto dialog = qobject_cast<QQuickWebEngineJavaScriptDialogRequest*>(m_listner->request());
+ auto *dialog = qobject_cast<QQuickWebEngineJavaScriptDialogRequest*>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
dialog->dialogReject();
QVERIFY2(dialog->isAccepted(), "Dialog is not accepted");
QCOMPARE(dialog->type(), type);
QCOMPARE(dialog->message(), message);
QCOMPARE(dialog->defaultText(), defaultText);
- QTRY_VERIFY(m_listner->ready()); // make sure javascript executes no longer
+ QTRY_VERIFY(m_listener->ready()); // make sure javascript executes no longer
}
static QByteArrayList params;
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index dad962576..950c7375a 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -687,7 +687,9 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.backgroundColor --> QColor"
<< "QQuickWebEngineView.backgroundColorChanged() --> void"
<< "QQuickWebEngineView.canGoBack --> bool"
+ << "QQuickWebEngineView.canGoBackChanged() --> void"
<< "QQuickWebEngineView.canGoForward --> bool"
+ << "QQuickWebEngineView.canGoForwardChanged() --> void"
<< "QQuickWebEngineView.certificateError(QQuickWebEngineCertificateError*) --> void"
<< "QQuickWebEngineView.colorDialogRequested(QQuickWebEngineColorDialogRequest*) --> void"
<< "QQuickWebEngineView.contentsSize --> QSizeF"
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
index 46bc65923..55be5b644 100644
--- a/tests/auto/quick/qmltests/BLACKLIST
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -1,2 +1,5 @@
-[WebEngineViewSource::test_viewSourceURL]
+[NewViewRequest::test_loadNewViewRequest]
+macos
+
+[CertificateError::test_fatalError]
*
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index 6db076ae8..9033f2441 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -85,12 +85,14 @@ WebEngineView {
function getElementCenter(element) {
var center;
- runJavaScript("(function() {" +
+ testCase.tryVerify(function() {
+ runJavaScript("(function() {" +
" var elem = document.getElementById('" + element + "');" +
" var rect = elem.getBoundingClientRect();" +
" return { 'x': (rect.left + rect.right) / 2, 'y': (rect.top + rect.bottom) / 2 };" +
"})();", function(result) { center = result } );
- testCase.tryVerify(function() { return center !== undefined; });
+ return center !== undefined;
+ });
return center;
}
@@ -102,7 +104,6 @@ WebEngineView {
}
TestResult { id: testResult }
- TestCase { id: testCase }
onLoadingChanged: {
loadStatus = loadRequest.status
diff --git a/tests/auto/quick/qmltests/data/test2.html b/tests/auto/quick/qmltests/data/test2.html
index 629c2a063..7a02bf1f2 100644
--- a/tests/auto/quick/qmltests/data/test2.html
+++ b/tests/auto/quick/qmltests/data/test2.html
@@ -1,6 +1,6 @@
<html>
<head><title>Test page with huge link area</title></head>
<body>
-<a title="A title" href="test1.html"><img width=200 height=200></a>
+<a id="link" title="A title" href="test1.html"><img width=200 height=200></a>
</body>
</html>
diff --git a/tests/auto/quick/qmltests/data/test4.html b/tests/auto/quick/qmltests/data/test4.html
index c9b395ee5..cf5708994 100644
--- a/tests/auto/quick/qmltests/data/test4.html
+++ b/tests/auto/quick/qmltests/data/test4.html
@@ -24,6 +24,7 @@
}
</script>
<div id="content">
+ <p><a id='anchor' href='#anchor'>anchor</a>
<p>bla00
<p>bla01
<p>bla02
diff --git a/tests/auto/quick/qmltests/data/tst_action.qml b/tests/auto/quick/qmltests/data/tst_action.qml
index 852d4145a..91f260e0e 100644
--- a/tests/auto/quick/qmltests/data/tst_action.qml
+++ b/tests/auto/quick/qmltests/data/tst_action.qml
@@ -41,7 +41,7 @@ TestWebEngineView {
}
TestCase {
- id: actionTests
+ id: testCase
name: "WebEngineAction"
when: windowShown
@@ -116,8 +116,8 @@ TestWebEngineView {
var stopAction = webEngineView.action(WebEngineView.Stop);
verify(stopAction);
- var triggerSpy = createTemporaryObject(signalSpy, actionTests, {target: selectAction, signalName: "triggered"});
- var stopTriggerSpy = createTemporaryObject(signalSpy, actionTests, {target: stopAction, signalName: "triggered"});
+ var triggerSpy = createTemporaryObject(signalSpy, testCase, {target: selectAction, signalName: "triggered"});
+ var stopTriggerSpy = createTemporaryObject(signalSpy, testCase, {target: stopAction, signalName: "triggered"});
verify(selectAction.enabled);
selectAction.trigger();
@@ -148,7 +148,7 @@ TestWebEngineView {
compare(enabledSpy.count, 0);
selectAllAction.trigger();
compare(triggerSpy.count, 0);
- compare(getTextSelection(), "");
+ compare(webEngineView.getTextSelection(), "");
// Focus content by focusing window from JavaScript. Edit actions should be enabled and functional.
webView.runJavaScript("window.focus();");
@@ -157,6 +157,7 @@ TestWebEngineView {
selectAllAction.trigger();
compare(triggerSpy.count, 1);
tryVerify(function() { return webView.getTextSelection() === "foo bar" });
+ webView.destroy();
}
function test_editActionsWithInitialFocus() {
@@ -180,6 +181,7 @@ TestWebEngineView {
selectAllAction.trigger();
compare(triggerSpy.count, 1);
tryVerify(function() { return webView.getTextSelection() === "foo bar" });
+ webView.destroy();
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
index c360a1da2..83a2dc8c9 100644
--- a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
+++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
@@ -55,6 +55,7 @@ Item {
}
TestCase {
+ id: testCase
name: "ActiveFocusOnPress"
when:windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_audioMuted.qml b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
index c626d07a0..d0d9e35c3 100644
--- a/tests/auto/quick/qmltests/data/tst_audioMuted.qml
+++ b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
@@ -42,7 +42,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "WebEngineViewAudioMuted"
function test_audioMuted() {
diff --git a/tests/auto/quick/qmltests/data/tst_contextMenu.qml b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
index 99450a159..8493ba1c7 100644
--- a/tests/auto/quick/qmltests/data/tst_contextMenu.qml
+++ b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
@@ -65,12 +65,12 @@ TestWebEngineView {
}
function destroyContextMenu() {
- contextMenuTest.keyPress(Qt.Key_Escape);
+ testCase.keyPress(Qt.Key_Escape);
return getContextMenus().length == 0;
}
TestCase {
- id: contextMenuTest
+ id: testCase
name: "WebEngineViewContextMenu"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index 1b1750dd8..0674be491 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -80,11 +80,21 @@ TestWebEngineView {
Connections {
id: downloadItemConnections
ignoreUnknownSignals: true
- onStateChanged: downloadState.push(target.state)
- onInterruptReasonChanged: downloadInterruptReason = target.interruptReason
- onDownloadDirectoryChanged: downloadDirectoryChanged++
- onDownloadFileNameChanged: downloadFileNameChanged++
- onPathChanged: downloadPathChanged++
+ function onStateChanged() {
+ downloadState.push(target.state);
+ }
+ function onInterruptReasonChanged() {
+ downloadInterruptReason = target.interruptReason;
+ }
+ function onDownloadDirectoryChanged() {
+ downloadDirectoryChanged++;
+ }
+ function onDownloadFileNameChanged() {
+ downloadFileNameChanged++;
+ }
+ function onPathChanged() {
+ downloadPathChanged++;
+ }
}
WebEngineProfile {
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index c02a1348e..0b4a8d459 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -56,7 +56,7 @@ TestWebEngineView {
// If this starts to fail then either clear was not called before findText
// or unexpected callback was triggered from some search.
// On c++ side callback id can be checked to verify
- testcase.verify(!findCallbackCalled(), 'Unexpected callback call or uncleared state before findText call!')
+ testCase.verify(!findCallbackCalled(), 'Unexpected callback call or uncleared state before findText call!')
webEngineView.matchCount = matchCount
findFailed = matchCount == 0
@@ -64,7 +64,7 @@ TestWebEngineView {
TestCase {
- id: testcase
+ id: testCase
name: "WebViewFindText"
function getBodyInnerHTML() {
diff --git a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
index 93410a727..b2b7374f6 100644
--- a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
+++ b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
@@ -65,6 +65,7 @@ Item {
}
TestCase {
+ id: testCase
name: "WebEngineViewFocusOnNavigation"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
index 2536f319b..136863c4c 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
@@ -36,6 +36,7 @@ TestWebEngineView {
height: 480
TestCase {
+ id: testCase
name: "WebEngineViewKeyboardEvents"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_loadHtml.qml b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
index ed1de41fd..6ed9a4317 100644
--- a/tests/auto/quick/qmltests/data/tst_loadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
@@ -42,6 +42,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: "WebEngineViewLoadHtml"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 872c46641..08987e4c3 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -52,6 +52,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: "WebEngineViewLoadUrl"
when: windowShown
@@ -298,20 +299,19 @@ TestWebEngineView {
compare(loadRequestArray[0].status, WebEngineView.LoadStartedStatus);
compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
- // In-page navigation.
- webEngineView.url = Qt.resolvedUrl("test4.html#content");
- // In-page navigation doesn't trigger load succeeded, wait for load progress instead.
- tryCompare(webEngineView, "loadProgress", 100);
- compare(loadRequestArray.length, 3);
- compare(loadRequestArray[2].status, WebEngineView.LoadStartedStatus);
+ // In-page navigation shouldn't trigger load
+ let anchorUrl = Qt.resolvedUrl("test4.html#anchor");
+ let c = webEngineView.getElementCenter('anchor')
+ mouseClick(webEngineView, c.x, c.y)
+ tryCompare(webEngineView, 'url', anchorUrl)
// Load after in-page navigation.
webEngineView.url = Qt.resolvedUrl("test4.html");
verify(webEngineView.waitForLoadSucceeded());
compare(webEngineView.loadProgress, 100);
- compare(loadRequestArray.length, 5);
- compare(loadRequestArray[3].status, WebEngineView.LoadStartedStatus);
- compare(loadRequestArray[4].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray.length, 4);
+ compare(loadRequestArray[2].status, WebEngineView.LoadStartedStatus);
+ compare(loadRequestArray[3].status, WebEngineView.LoadSucceededStatus);
webEngineView.clear();
}
diff --git a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
index 6ed232589..47be2f47d 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
@@ -26,7 +26,8 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.15
+import QtQuick.Controls 2.15
import QtTest 1.0
import QtWebEngine 1.2
@@ -59,11 +60,25 @@ TestWebEngineView {
}
}
+ Button {
+ id: backButton
+ text: "Back"
+ enabled: webEngineView.canGoBack
+ onClicked: webEngineView.goBack()
+ }
+
+ Button {
+ id: forwardButton
+ text: "Forward"
+ enabled: webEngineView.canGoForward
+ onClicked: webEngineView.goForward()
+ }
+
TestCase {
name: "WebEngineViewNavigationHistory"
function test_navigationHistory() {
- compare(webEngineView.loadProgress, 0)
+ webEngineView.navigationHistory.clear()
webEngineView.url = Qt.resolvedUrl("test1.html")
verify(webEngineView.waitForLoadSucceeded())
@@ -142,5 +157,34 @@ TestWebEngineView {
compare(backItemsList.count, 0)
compare(forwardItemsList.count, 0)
}
+
+ function test_navigationButtons() {
+ webEngineView.navigationHistory.clear()
+
+ webEngineView.url = Qt.resolvedUrl("test1.html")
+ verify(webEngineView.waitForLoadSucceeded())
+ compare(backButton.enabled, false)
+ compare(forwardButton.enabled, false)
+
+ webEngineView.url = Qt.resolvedUrl("test2.html")
+ verify(webEngineView.waitForLoadSucceeded())
+ compare(backButton.enabled, true)
+ compare(forwardButton.enabled, false)
+
+ webEngineView.url = Qt.resolvedUrl("test3.html")
+ verify(webEngineView.waitForLoadSucceeded())
+ compare(backButton.enabled, true)
+ compare(forwardButton.enabled, false)
+
+ backButton.clicked()
+ verify(webEngineView.waitForLoadSucceeded())
+ compare(backButton.enabled, true)
+ compare(forwardButton.enabled, true)
+
+ webEngineView.url = Qt.resolvedUrl("test1.html")
+ verify(webEngineView.waitForLoadSucceeded())
+ compare(backButton.enabled, true)
+ compare(forwardButton.enabled, false)
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
index 96128574e..a24b8f0d4 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
@@ -79,6 +79,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: "WebEngineViewNavigationRequested"
when: windowShown
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index 80389e9f8..891b140e2 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -38,6 +38,13 @@ TestWebEngineView {
property var newViewRequest: null
property var dialog: null
property string viewType: ""
+ property var loadRequestArray: []
+
+ onLoadingChanged: {
+ loadRequestArray.push({
+ "status": loadRequest.status,
+ });
+ }
SignalSpy {
id: newViewRequestedSpy
@@ -70,7 +77,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "NewViewRequest"
when: windowShown
@@ -81,6 +88,7 @@ TestWebEngineView {
newViewRequestedSpy.clear();
newViewRequest = null;
viewType = "";
+ loadRequestArray = [];
}
function cleanup() {
@@ -150,7 +158,7 @@ TestWebEngineView {
" <button id='popupButton' onclick='popup()'>Pop Up!</button>" +
"</body></html>");
verify(webEngineView.waitForLoadSucceeded());
- verifyElementHasFocus("popupButton");
+ webEngineView.verifyElementHasFocus("popupButton");
keyPress(Qt.Key_Enter);
tryCompare(newViewRequestedSpy, "count", 1);
compare(newViewRequest.requestedUrl, url);
@@ -163,6 +171,23 @@ TestWebEngineView {
}
newViewRequestedSpy.clear();
}
+
+ loadRequestArray = [];
+ compare(loadRequestArray.length, 0);
+ webEngineView.url = Qt.resolvedUrl("test2.html");
+ verify(webEngineView.waitForLoadSucceeded());
+ var center = webEngineView.getElementCenter("link");
+ mouseClick(webEngineView, center.x, center.y, Qt.LeftButton, Qt.ControlModifier);
+ tryCompare(newViewRequestedSpy, "count", 1);
+ compare(newViewRequest.requestedUrl, Qt.resolvedUrl("test1.html"));
+ compare(newViewRequest.destination, WebEngineView.NewViewInBackgroundTab);
+ verify(newViewRequest.userInitiated);
+ if (viewType === "" || viewType === "null") {
+ compare(loadRequestArray[0].status, WebEngineView.LoadStartedStatus);
+ compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray.length, 2);
+ }
+ newViewRequestedSpy.clear();
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_settings.qml b/tests/auto/quick/qmltests/data/tst_settings.qml
index 2ff4f9c3c..b286a1dae 100644
--- a/tests/auto/quick/qmltests/data/tst_settings.qml
+++ b/tests/auto/quick/qmltests/data/tst_settings.qml
@@ -36,6 +36,7 @@ TestWebEngineView {
height: 300
TestCase {
+ id: testCase
name: "WebEngineViewSettings"
function test_javascriptEnabled() {
@@ -75,7 +76,7 @@ TestWebEngineView {
}
function test_settingsAffectCurrentViewOnly() {
- var webEngineView2 = Qt.createQmlObject('TestWebEngineView {width: 400; height: 300;}', webEngineView);
+ var webEngineView2 = Qt.createQmlObject('TestWebEngineView {width: 400; height: 300;}', testCase);
webEngineView.settings.javascriptEnabled = true;
webEngineView2.settings.javascriptEnabled = true;
diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
index 69aa76b77..5e163fc64 100644
--- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
+++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
@@ -46,6 +46,7 @@ Item {
focus: true
}
TestCase {
+ id: testCase
name: "WebEngineViewUnhandledKeyEventPropagation"
when: false
diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml
index 4966a052a..22c340c2b 100644
--- a/tests/auto/quick/qmltests/data/tst_viewSource.qml
+++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml
@@ -94,36 +94,6 @@ TestWebEngineView {
compare(webEngineView.url, "view-source:" + Qt.resolvedUrl("test1.html"));
}
- function test_viewSourceURL_data() {
- var testLocalUrl = "view-source:" + Qt.resolvedUrl("test1.html");
- var testLocalUrlWithoutScheme = "view-source:" + Qt.resolvedUrl("test1.html").substring(7);
-
- return [
- { tag: "view-source:", userInputUrl: "view-source:", loadSucceed: true, url: "view-source:", title: "view-source:" },
- { tag: "view-source:about:blank", userInputUrl: "view-source:about:blank", loadSucceed: true, url: "view-source:about:blank", title: "view-source:about:blank" },
- { tag: testLocalUrl, userInputUrl: testLocalUrl, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
- { tag: testLocalUrlWithoutScheme, userInputUrl: testLocalUrlWithoutScheme, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
- { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
- { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
- ];
- }
-
- function test_viewSourceURL(row) {
- WebEngine.settings.errorPageEnabled = true
- webEngineView.url = row.userInputUrl;
-
- if (row.loadSucceed) {
- tryCompare(webEngineView, "loadStatus", WebEngineView.LoadSucceededStatus);
- } else {
- tryCompare(webEngineView, "loadStatus", WebEngineView.LoadFailedStatus, 15000);
- }
- tryVerify(function() { return titleChangedSpy.count == 1; });
-
- compare(webEngineView.url, row.url);
- tryCompare(webEngineView, "title", row.title);
- verify(!webEngineView.action(WebEngineView.ViewSource).enabled);
- }
-
function test_viewSourceCredentials() {
var url = "http://user:passwd@httpbin.org/basic-auth/user/passwd";
diff --git a/tests/auto/quick/qmltests2/data/tst_favicon.qml b/tests/auto/quick/qmltests2/data/tst_favicon.qml
index 3f522d91a..ea5d20f17 100644
--- a/tests/auto/quick/qmltests2/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests2/data/tst_favicon.qml
@@ -59,16 +59,16 @@ TestWebEngineView {
function getFaviconPixel(faviconImage) {
var grabImage = Qt.createQmlObject("
import QtQuick 2.5\n
- Image { }", test)
+ Image { }", testCase)
var faviconCanvas = Qt.createQmlObject("
import QtQuick 2.5\n
- Canvas { }", test)
+ Canvas { }", testCase)
- test.tryVerify(function() { return faviconImage.status == Image.Ready });
+ testCase.tryVerify(function() { return faviconImage.status == Image.Ready });
faviconImage.grabToImage(function(result) {
grabImage.source = result.url
});
- test.tryVerify(function() { return grabImage.status == Image.Ready });
+ testCase.tryVerify(function() { return grabImage.status == Image.Ready });
faviconCanvas.width = faviconImage.width;
faviconCanvas.height = faviconImage.height;
@@ -97,7 +97,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "WebEngineFavicon"
when: windowShown
@@ -315,7 +315,7 @@ TestWebEngineView {
function test_faviconProvider(row) {
var faviconImage = Qt.createQmlObject("
import QtQuick 2.5\n
- Image { sourceSize: Qt.size(width, height) }", test)
+ Image { sourceSize: Qt.size(width, height) }", testCase)
compare(iconChangedSpy.count, 0)
@@ -338,7 +338,7 @@ TestWebEngineView {
function test_dynamicFavicon() {
var faviconImage = Qt.createQmlObject("
import QtQuick 2.5\n
- Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", test)
+ Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", testCase)
faviconImage.source = Qt.binding(function() { return webEngineView.icon; });
var colors = [
diff --git a/tests/auto/quick/qmltests2/data/tst_faviconDownload.qml b/tests/auto/quick/qmltests2/data/tst_faviconDownload.qml
index 9aa32279c..7d9c39814 100644
--- a/tests/auto/quick/qmltests2/data/tst_faviconDownload.qml
+++ b/tests/auto/quick/qmltests2/data/tst_faviconDownload.qml
@@ -47,7 +47,7 @@ TestWebEngineView {
}
TestCase {
- id: test
+ id: testCase
name: "WebEngineFaviconDownload"
function init() {
diff --git a/tests/auto/quick/qmltests2/data/tst_filePicker.qml b/tests/auto/quick/qmltests2/data/tst_filePicker.qml
index ab30d9e82..5b963c7bf 100644
--- a/tests/auto/quick/qmltests2/data/tst_filePicker.qml
+++ b/tests/auto/quick/qmltests2/data/tst_filePicker.qml
@@ -58,6 +58,7 @@ TestWebEngineView {
onTitleChanged: { titleChanges.push(webEngineView.title) }
TestCase {
+ id: testCase
name: "WebEngineViewSingleFileUpload"
when: windowShown
@@ -156,6 +157,16 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("directoryupload.html")
verify(webEngineView.waitForLoadSucceeded())
+ webEngineView.runJavaScript(
+ "let relativePathCount = 0;" +
+ "document.getElementById('upfile').addEventListener('change', function(event) {" +
+ " let files = event.target.files;" +
+ " for (let i = 0; i < files.length; i++) {" +
+ " if (files[i].webkitRelativePath != '')" +
+ " relativePathCount++;" +
+ " }" +
+ "}, false);")
+
FilePickerParams.selectFiles = true
FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("../data"))
@@ -163,6 +174,11 @@ TestWebEngineView {
tryCompare(FilePickerParams, "filePickerOpened", true)
// Check that the title is a file list (eg. "test1.html,test2.html")
tryVerify(function() { return webEngineView.title.match("^([^,]+,)+[^,]+$"); })
+
+ var relativePathCount = 0;
+ runJavaScript("relativePathCount", function(result) { relativePathCount = result; });
+ // The number of files in data directory may vary
+ tryVerify(function() { return relativePathCount > 0; });
}
function test_reject() {
@@ -226,15 +242,15 @@ TestWebEngineView {
{ tag: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", input: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", expected: "test.txt"},
{ tag: "file://applib/products/a-b/abc_1/t.est/test.txt", input: "file://applib/products/a-b/abc_1/t.est/test.txt", expected: "test.txt"},
{ tag: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", input: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", expected: "test.txt"},
- { tag: "file:C:/test.txt", input: "file:C:/test.txt", expected: "test.tx"},
- { tag: "file:/C:/test.txt", input: "file:/C:/test.txt", expected: "test.tx"},
+ { tag: "file:C:/test.txt", input: "file:C:/test.txt", expected: "test.txt"},
+ { tag: "file:/C:/test.txt", input: "file:/C:/test.txt", expected: "test.txt"},
{ tag: "file://C:/test.txt", input: "file://C:/test.txt", expected: "Failed to Upload"},
{ tag: "file:///C:test.txt", input: "file:///C:test.txt", expected: "Failed to Upload"},
{ tag: "file:///C:/test.txt", input: "file:///C:/test.txt", expected: "test.txt"},
{ tag: "file:///C:\\test.txt", input: "file:///C:\\test.txt", expected: "test.txt"},
{ tag: "file:\\//C:/test.txt", input: "file:\\//C:/test.txt", expected: "test.txt"},
{ tag: "file:\\\\/C:\\test.txt", input: "file:\\\\/C:\\test.txt", expected: "test.txt"},
- { tag: "\\\\?\\C:/test.txt", input: "\\\\?\\C:/test.txt", expected: "test.tx"},
+ { tag: "\\\\?\\C:/test.txt", input: "\\\\?\\C:/test.txt", expected: "test.txt"},
];
}
diff --git a/tests/auto/quick/qmltests2/data/tst_inputMethod.qml b/tests/auto/quick/qmltests2/data/tst_inputMethod.qml
index 0bf9f7eb0..00f85cb71 100644
--- a/tests/auto/quick/qmltests2/data/tst_inputMethod.qml
+++ b/tests/auto/quick/qmltests2/data/tst_inputMethod.qml
@@ -40,6 +40,7 @@ TestWebEngineView {
testSupport: WebEngineTestSupport { }
TestCase {
+ id: testCase
name: "WebEngineViewInputMethod"
when: windowShown
diff --git a/tests/auto/quick/qmltests2/data/tst_javaScriptDialogs.qml b/tests/auto/quick/qmltests2/data/tst_javaScriptDialogs.qml
index 658071005..a521ea0d6 100644
--- a/tests/auto/quick/qmltests2/data/tst_javaScriptDialogs.qml
+++ b/tests/auto/quick/qmltests2/data/tst_javaScriptDialogs.qml
@@ -112,6 +112,13 @@ TestWebEngineView {
simulateUserGesture()
webEngineView.triggerWebAction(WebEngineView.RequestClose);
verify(webEngineView.waitForWindowCloseRequested());
+
+ // Navigate away from page with onbeforeunload handler,
+ // otherwise it would trigger an extra dialog request when
+ // navigating in the subsequent test.
+ webEngineView.url = Qt.resolvedUrl("about:blank");
+ verify(webEngineView.waitForLoadSucceeded());
+ compare(JSDialogParams.dialogCount, 2)
}
function test_rejectClose() {
@@ -123,6 +130,14 @@ TestWebEngineView {
simulateUserGesture()
webEngineView.triggerWebAction(WebEngineView.RequestClose);
verify(webEngineView.testSupport.waitForWindowCloseRejected());
+
+ // Navigate away from page with onbeforeunload handler,
+ // otherwise it would trigger an extra dialog request when
+ // navigating in the subsequent test.
+ JSDialogParams.shouldAcceptDialog = true;
+ webEngineView.url = Qt.resolvedUrl("about:blank");
+ verify(webEngineView.waitForLoadSucceeded());
+ compare(JSDialogParams.dialogCount, 2)
}
function test_prompt() {
diff --git a/tests/auto/quick/qmltests2/data/tst_loadFail.qml b/tests/auto/quick/qmltests2/data/tst_loadFail.qml
index db412f252..298f5b0fe 100644
--- a/tests/auto/quick/qmltests2/data/tst_loadFail.qml
+++ b/tests/auto/quick/qmltests2/data/tst_loadFail.qml
@@ -119,21 +119,22 @@ TestWebEngineView {
verify(!loadRequest.isErrorPage)
// Loading of the unavailableUrl must fail
- loadRequest = loadRequestArray[1]
+ loadRequest = loadRequestArray[3]
compare(loadRequest.status, WebEngineView.LoadFailedStatus)
compare(loadRequest.errorDomain, WebEngineView.InternalErrorDomain)
compare(loadRequest.url, unavailableUrl)
verify(!loadRequest.isErrorPage)
+ // error page load is done inside main load through test support
// Start to load error page
- loadRequest = loadRequestArray[2]
+ loadRequest = loadRequestArray[1]
compare(loadRequest.status, WebEngineView.LoadStartedStatus)
compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain)
compare(loadRequest.url, "chrome-error://chromewebdata/")
verify(loadRequest.isErrorPage)
// Loading of the error page must be successful
- loadRequest = loadRequestArray[3]
+ loadRequest = loadRequestArray[2]
compare(loadRequest.status, WebEngineView.LoadSucceededStatus)
compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain)
compare(loadRequest.url, "chrome-error://chromewebdata/")
diff --git a/tests/auto/quick/qmltests2/data/tst_mouseClick.qml b/tests/auto/quick/qmltests2/data/tst_mouseClick.qml
index eaa012f86..6c314d44c 100644
--- a/tests/auto/quick/qmltests2/data/tst_mouseClick.qml
+++ b/tests/auto/quick/qmltests2/data/tst_mouseClick.qml
@@ -65,6 +65,7 @@ TestWebEngineView {
TestCase {
+ id: testCase
name: "WebEngineViewMouseClick"
when: windowShown
diff --git a/tests/auto/quick/qmltests2/data/tst_viewSoure.qml b/tests/auto/quick/qmltests2/data/tst_viewSoure.qml
new file mode 100644
index 000000000..28f7e8344
--- /dev/null
+++ b/tests/auto/quick/qmltests2/data/tst_viewSoure.qml
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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.4
+import QtWebEngine.testsupport 1.0
+import "../../qmltests/data" 1.0
+
+TestWebEngineView {
+ id: webEngineView
+ width: 200
+ height: 400
+
+ property var viewRequest: null
+ property var loadRequestArray: []
+
+ testSupport: WebEngineTestSupport {
+ errorPage.onLoadingChanged: {
+ loadRequestArray.push({
+ "status": loadRequest.status,
+ "url": loadRequest.url
+ })
+ }
+ }
+
+ onLoadingChanged: {
+ loadRequestArray.push({
+ "status": loadRequest.status,
+ "url": loadRequest.url
+ });
+ }
+
+ SignalSpy {
+ id: newViewRequestedSpy
+ target: webEngineView
+ signalName: "newViewRequested"
+ }
+
+ SignalSpy {
+ id: titleChangedSpy
+ target: webEngineView
+ signalName: "titleChanged"
+ }
+
+ onNewViewRequested: {
+ viewRequest = {
+ "destination": request.destination,
+ "userInitiated": request.userInitiated
+ };
+
+ request.openIn(webEngineView);
+ }
+
+ TestCase {
+ id: testCase
+ name: "WebEngineViewSource"
+
+ function init() {
+ webEngineView.loadStatus = null;
+ webEngineView.url = Qt.resolvedUrl("test1.html");
+ tryCompare(webEngineView, "loadStatus", WebEngineView.LoadSucceededStatus);
+ webEngineView.loadStatus = null;
+
+ newViewRequestedSpy.clear();
+ titleChangedSpy.clear();
+ viewRequest = null;
+ }
+
+ function test_viewSourceURL_data() {
+ var testLocalUrl = "view-source:" + Qt.resolvedUrl("test1.html");
+ var testLocalUrlWithoutScheme = "view-source:" + Qt.resolvedUrl("test1.html").substring(7);
+
+ return [
+ { tag: "view-source:", userInputUrl: "view-source:", loadSucceed: true, url: "view-source:", title: "view-source:" },
+ { tag: "view-source:about:blank", userInputUrl: "view-source:about:blank", loadSucceed: true, url: "view-source:about:blank", title: "view-source:about:blank" },
+ { tag: testLocalUrl, userInputUrl: testLocalUrl, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
+ { tag: testLocalUrlWithoutScheme, userInputUrl: testLocalUrlWithoutScheme, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
+ { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
+ { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
+ ];
+ }
+
+ function test_viewSourceURL(row) {
+ loadRequestArray = [];
+ WebEngine.settings.errorPageEnabled = true
+ webEngineView.url = row.userInputUrl;
+
+
+ if (row.loadSucceed) {
+ tryVerify(function() { return loadRequestArray.length == 2 });
+ compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus);
+ } else {
+ tryVerify(function() { return loadRequestArray.length == 4 }, 90000);
+ // error page load is done inside main load through test support
+ compare(loadRequestArray[2].status, WebEngineView.LoadSucceededStatus);
+ compare(loadRequestArray[2].url, "chrome-error://chromewebdata/")
+ compare(loadRequestArray[3].status, WebEngineView.LoadFailedStatus);
+ }
+ tryVerify(function() { return titleChangedSpy.count == 1; });
+
+ compare(webEngineView.url, row.url);
+ tryCompare(webEngineView, "title", row.title);
+ if (row.loadSucceed) {
+ verify(!webEngineView.action(WebEngineView.ViewSource).enabled);
+ } else {
+ verify(webEngineView.action(WebEngineView.ViewSource).enabled);
+ }
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qmltests2/qmltests2.pro b/tests/auto/quick/qmltests2/qmltests2.pro
index 4c7a8dc72..98e33972b 100644
--- a/tests/auto/quick/qmltests2/qmltests2.pro
+++ b/tests/auto/quick/qmltests2/qmltests2.pro
@@ -33,6 +33,7 @@ OTHER_FILES += \
$$PWD/data/tst_linkHovered.qml \
$$PWD/data/tst_loadFail.qml \
$$PWD/data/tst_mouseClick.qml \
+ $$PWD/data/tst_viewSource.qml \
$$PWD/data/icons/favicon.png \
$$PWD/data/icons/gray128.png \
$$PWD/data/icons/gray16.png \
diff --git a/tests/auto/quick/qmltests_ssl/BLACKLIST b/tests/auto/quick/qmltests_ssl/BLACKLIST
new file mode 100644
index 000000000..d60926525
--- /dev/null
+++ b/tests/auto/quick/qmltests_ssl/BLACKLIST
@@ -0,0 +1,2 @@
+[CertificateError::test_error]
+macos
diff --git a/tests/auto/quick/qmltests_ssl/data/tst_certificateError.qml b/tests/auto/quick/qmltests_ssl/data/tst_certificateError.qml
index 4c252e210..48ba601ac 100644
--- a/tests/auto/quick/qmltests_ssl/data/tst_certificateError.qml
+++ b/tests/auto/quick/qmltests_ssl/data/tst_certificateError.qml
@@ -45,6 +45,7 @@ TestWebEngineView {
}
TestCase {
+ id: testCase
name: 'CertificateError'
when: windowShown
@@ -55,6 +56,7 @@ TestWebEngineView {
request.sendResponse()
})
view.settings.errorPageEnabled = false
+ view.profile.useForGlobalCertificateVerification = true
}
function init() {
diff --git a/tests/auto/quick/qquickwebengineprofile/tst_qquickwebengineprofile.cpp b/tests/auto/quick/qquickwebengineprofile/tst_qquickwebengineprofile.cpp
deleted file mode 100644
index db7c2ad6e..000000000
--- a/tests/auto/quick/qquickwebengineprofile/tst_qquickwebengineprofile.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** 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 <QtQml/QQmlEngine>
-#include <QtTest/QtTest>
-#include <QtWebEngine/QQuickWebEngineProfile>
-
-class tst_QQuickWebEngineProfile : public QObject {
- Q_OBJECT
-public:
- tst_QQuickWebEngineProfile();
-
- // TODO: Many tests missings
- void usedForGlobalCertificateVerification();
-
-private Q_SLOTS:
- void init();
- void cleanup();
-};
-
-tst_QQuickWebEngineProfile::tst_QQuickWebEngineProfile()
-{
- QtWebEngine::initialize();
- QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true);
-}
-
-
-void tst_QQuickWebEngineProfile::init()
-{
-}
-
-void tst_QQuickWebEngineProfile::cleanup()
-{
-}
-
-void tst_QQuickWebEngineProfile::usedForGlobalCertificateVerification()
-{
- QQuickWebEngineProfile *profile1 = new QQuickWebEngineProfile();
- QQuickWebEngineProfile *profile2 = new QQuickWebEngineProfile();
- QVERIFY(!profile1->isUsedForGlobalVerification());
- QVERIFY(!profile2->isUsedForGlobalVerification());
-
-
-}
-
-
-QTEST_MAIN(tst_QQuickWebEngineProfile)
-#include "tst_qquickwebengineprofile.moc"
diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
new file mode 100644
index 000000000..d4a35a76a
--- /dev/null
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -0,0 +1,2 @@
+[javascriptClipboard]
+ubuntu-20.04
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 5ee30f165..c3796062b 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -791,20 +791,44 @@ void tst_QQuickWebEngineView::inputMethodHints()
void tst_QQuickWebEngineView::setZoomFactor()
{
QQuickWebEngineView *view = webEngineView();
+ m_window->show();
+ view->setSize(QSizeF(320, 240));
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 1.0));
+ QCOMPARE(view->zoomFactor(), 1.0);
view->setZoomFactor(2.5);
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
- view->setUrl(urlFromTestPath("html/basic_page.html"));
+ const QUrl url1 = urlFromTestPath("html/basic_page.html"), url2 = urlFromTestPath("html/basic_page2.html");
+
+ view->setUrl(url1);
QVERIFY(waitForLoadSucceeded(view));
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
view->setZoomFactor(0.1);
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
view->setZoomFactor(5.5);
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
+
+ QScopedPointer<QQuickWebEngineView> view2(newWebEngineView());
+ view2->setSize(QSizeF(320, 240));
+ view2->setParentItem(m_window->contentItem());
+
+ // try loading different url and check new values after load
+ for (auto &&p : {
+ qMakePair(view, 2.5), // navigating away to different url should keep zoom
+ qMakePair(view2.get(), 1.0), // same url navigation in diffent page shouldn't be affected
+ }) {
+ auto &&view = p.first; auto zoomFactor = p.second;
+ view->setUrl(url2);
+ QVERIFY(waitForLoadSucceeded(view));
+ QCOMPARE(view->zoomFactor(), zoomFactor);
+ }
+
+ // should have no influence on first page
+ view2->setZoomFactor(3.5);
+ for (auto &&p : { qMakePair(view, 2.5), qMakePair(view2.get(), 3.5), })
+ QCOMPARE(p.first->zoomFactor(), p.second);
}
void tst_QQuickWebEngineView::printToPdf()
@@ -1003,7 +1027,11 @@ void tst_QQuickWebEngineView::changeLocale()
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
+#else
+ errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
+#endif
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
QLocale::setDefault(QLocale("en"));
@@ -1013,7 +1041,11 @@ void tst_QQuickWebEngineView::changeLocale()
QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").isNull());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
errorLines = evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
+#else
+ errorLines = evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
+#endif
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached"));
// Reset error page
@@ -1026,7 +1058,11 @@ void tst_QQuickWebEngineView::changeLocale()
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
+#else
+ errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
+#endif
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
}
@@ -1173,6 +1209,9 @@ void tst_QQuickWebEngineView::focusChild_data()
void tst_QQuickWebEngineView::focusChild()
{
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 1)
+ QSKIP("Requires newer base Qt");
+#endif
auto traverseToWebDocumentAccessibleInterface = [](QAccessibleInterface *iface) -> QAccessibleInterface * {
QFETCH(QVector<QAccessible::Role>, ancestorRoles);
for (int i = 0; i < ancestorRoles.size(); ++i) {
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 41ea5c4c1..f02652ba1 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -20,5 +20,7 @@ qtConfig(webengine-testsupport) {
qtConfig(ssl): SUBDIRS += qmltests_ssl
+lessThan(QT_MAJOR_VERSION, 6):lessThan(QT_MINOR_VERSION, 14): SUBDIRS -= qmltests qmltests2 qmltests_ssl
+
# QTBUG-66055
boot2qt: SUBDIRS -= inspectorserver qquickwebengineview qmltests qmltests2
diff --git a/tests/auto/shared/data/loadprogress/page1.html b/tests/auto/shared/data/loadprogress/page1.html
index 5cd479ab6..9b11ce887 100644
--- a/tests/auto/shared/data/loadprogress/page1.html
+++ b/tests/auto/shared/data/loadprogress/page1.html
@@ -3,6 +3,6 @@
<title>page1</title>
</head>
<body>
- <h1>page1</h1>
+ <div><a href="page2.html#anchor">page2</a></div>
</body>
</html>
diff --git a/tests/auto/shared/data/loadprogress/page2.html b/tests/auto/shared/data/loadprogress/page2.html
index e3031f56a..223817c8c 100644
--- a/tests/auto/shared/data/loadprogress/page2.html
+++ b/tests/auto/shared/data/loadprogress/page2.html
@@ -9,6 +9,7 @@
}
</style>
<body>
+ <div><a href="#anchor">page2</a></div>
<div class="fardown" id="anchor">page2 anchor</div>
</body>
</html>
diff --git a/tests/auto/shared/data/loadprogress/page5.html b/tests/auto/shared/data/loadprogress/page5.html
new file mode 100644
index 000000000..47709ff08
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page5.html
@@ -0,0 +1,20 @@
+<html>
+ <head>
+ <title>page5</title>
+ </head>
+ <script>
+ addEventListener('DOMContentLoaded', (event) => {
+ document.getElementById('anchorLink').click();
+ });
+ </script>
+ <style>
+ .fardown {
+ position: absolute;
+ top: 2500px;
+ }
+ </style>
+ <body>
+ <div><a id="anchorLink" href="#anchor">go to the anchor</a></div>
+ <div class="fardown" id="anchor">here is the anchor</div>
+ </body>
+</html>
diff --git a/tests/auto/shared/data/loadprogress/page6.html b/tests/auto/shared/data/loadprogress/page6.html
new file mode 100644
index 000000000..98042701a
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page6.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title>page6</title>
+ </head>
+ <script>
+ addEventListener('DOMContentLoaded', (event) => {
+ document.getElementById('anchorLink').click();
+ });
+ </script>
+ <body>
+ <div><a id="anchorLink" href="page2.html#anchor">go to another page</a></div>
+ </body>
+</html>
diff --git a/tests/auto/shared/data/loadprogress/page7.html b/tests/auto/shared/data/loadprogress/page7.html
new file mode 100644
index 000000000..42538c5de
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page7.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title>page6</title>
+ </head>
+ <script>
+ setTimeout(function(){
+ document.getElementById('anchorLink').click();
+ },500);
+ </script>
+ <body>
+ <div><a id="anchorLink" href="page2.html#anchor">go to another page</a></div>
+ </body>
+</html>
diff --git a/tests/auto/shared/data/loadprogress/page8.html b/tests/auto/shared/data/loadprogress/page8.html
new file mode 100644
index 000000000..8ebdddf97
--- /dev/null
+++ b/tests/auto/shared/data/loadprogress/page8.html
@@ -0,0 +1,20 @@
+<html>
+ <head>
+ <title>Page with js navigation in the end of document to anchor within the page</title>
+ </head>
+ <style>
+ .fardown {
+ position: absolute;
+ top: 2500px;
+ }
+ </style>
+ <body>
+ <div><a id="anchorLink" href="#anchor">go to the anchor</a></div>
+ <div class="fardown" id="anchor">here is the anchor</div>
+ <script>
+ addEventListener('load', (event) => {
+ window.location.replace(document.getElementById('anchorLink').href)
+ })
+ </script>
+ </body>
+</html>
diff --git a/tests/auto/shared/httpserver.cpp b/tests/auto/shared/httpserver.cpp
index 67f491fac..69e8cb6cc 100644
--- a/tests/auto/shared/httpserver.cpp
+++ b/tests/auto/shared/httpserver.cpp
@@ -54,6 +54,7 @@ bool HttpServer::start()
{
m_error = false;
m_expectingError = false;
+ m_ignoreNewConnection = false;
if (!m_tcpServer->listen()) {
qCWarning(gHttpServerLog).noquote() << m_tcpServer->errorString();
@@ -84,6 +85,9 @@ QUrl HttpServer::url(const QString &path) const
void HttpServer::handleNewConnection()
{
+ if (m_ignoreNewConnection)
+ return;
+
auto rr = new HttpReqRep(m_tcpServer->nextPendingConnection(), this);
connect(rr, &HttpReqRep::requestReceived, [this, rr]() {
Q_EMIT newRequest(rr);
@@ -122,5 +126,9 @@ void HttpServer::handleNewConnection()
<< error;
m_error = true;
});
- connect(rr, &HttpReqRep::closed, rr, &QObject::deleteLater);
+
+ if (!m_tcpServer->isListening()) {
+ m_ignoreNewConnection = true;
+ connect(rr, &HttpReqRep::closed, rr, &QObject::deleteLater);
+ }
}
diff --git a/tests/auto/shared/httpserver.h b/tests/auto/shared/httpserver.h
index 9764852de..3ec69f8ed 100644
--- a/tests/auto/shared/httpserver.h
+++ b/tests/auto/shared/httpserver.h
@@ -78,6 +78,8 @@ public:
Q_INVOKABLE void setResourceDirs(const QStringList &dirs) { m_dirs = dirs; }
+ Q_INVOKABLE void setHostDomain(const QString &host) { m_url.setHost(host); }
+
Q_SIGNALS:
// Emitted after a HTTP request has been successfully parsed.
void newRequest(HttpReqRep *reqRep);
@@ -90,6 +92,7 @@ private:
QUrl m_url;
QStringList m_dirs;
bool m_error = false;
+ bool m_ignoreNewConnection = false;
bool m_expectingError = false;
};
diff --git a/tests/auto/shared/resources/cert.pem b/tests/auto/shared/resources/cert.pem
index 3aaaf289c..a201ed08e 100644
--- a/tests/auto/shared/resources/cert.pem
+++ b/tests/auto/shared/resources/cert.pem
@@ -1,64 +1,41 @@
-----BEGIN CERTIFICATE-----
-MIIEpDCCAoygAwIBAgIUO90aty9AMjvBvzfUhr1WwdBrKkMwDQYJKoZIhvcNAQEL
-BQAwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
-DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEyMDAGA1UEAwwpQmFkU1NM
-IEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTkwODI2MTQ0
-NDIxWhcNMTkwODI3MTQ0NDIxWjBjMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs
-aWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEPMA0GA1UECgwGQmFkU1NM
-MRYwFAYDVQQDDA0qLmJhZHNzbC50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAkybT/L4zJCqefpd+eYT6aQ0PtobQfFgP+n+z5wWoUxIAJnjb5ZW4
-7IJxka/2/ggzJOfrUBur54LkTfFQ+yX85eKYCuH0GLz+Rve50LDn0ya6qSgmEhDG
-0bend2tMZY+Nl3B+5Ane1vua8hdJjv3ZO3e5UgpQwysL54eYyhEWWlbFWF11LhEd
-MYp953UGLqoV4Mlw+Li8TmFwdKQx6icgBTuloXLzk9aUU+b6NbXdadNXkmzg09IC
-sb8pnMXiF2P9Xm5rK0IoiRkSHxVnU12nQXh65Ns/2Dj5DcbHmVdvallfr4wnLeFP
-UotysZnvFmE7FLMSr/eQfkTG+Jlb7ZhoGwIDAQABozQwMjAJBgNVHRMEAjAAMCUG
-A1UdEQQeMByCDSouYmFkc3NsLnRlc3SCC2JhZHNzbC50ZXN0MA0GCSqGSIb3DQEB
-CwUAA4ICAQA7Yc+QQzqSK15ibmaYrkqq+cumggsWLCprW8jvzhpWBt9IjToP5nsy
-sKinYPoZR8jvZ1YVotcts7uQT7DkqeWkB+l+88c7gQdgujvBo6v9/g+jrXFKgsJD
-IBmkho8hpd63Slqv2Yp4bYT20O5EvR9CQvwSkwTs+ylBNEs1Q+AbekxmBjuYUxHn
-9xL4/GZ6ufoNv676iCoXo4mnDrCD8e8MRiZoU9Lq4G41HGiLWV0tM/M6BdVJYGzl
-FcBg0ZKnQT9OCWEPRe3zyRS6a+MivPAzxS8z/kYaRN+C7H68Mib3xPDsEETz1MnO
-uzGAPHAAgtYWYJi+CaaNWkgAv4n+UIQa0oyqPn4z5hLcsO+nMBws2Sg0mkQLilBX
-N1ciCdVMi7sHKuLa7GVksq/RQrXnZcQhoYQRrZAaAHKbxyo/M2pNqmDiFJppdH7a
-6Rj2vYf6ig/FXAzDGsDvf/tsGCxgJTFzGly+GsWVe40vyjfWHxWWDU/eGjfGO05k
-Xzjm+kYGJnH2hfiIlX1Jeu/jjIodiSy31F0hvuKlJu8PfaQ7oo5neRzwRO6Wq9rR
-7DMsQN6OtXGnnA+ogC0korA+aXev6wzbwYUhzMf1YTzEjrFNIXeIHsQSzq6lPcIE
-JOly5wjyO/eNF7mpHyDX8brY6Hn+bgyDeKAmsUvhOCEXgaPpKlP4gQ==
+MIIDezCCAmOgAwIBAgIUFZEIIzeR7lEA10rb14w7MfhP87MwDQYJKoZIhvcNAQEL
+BQAwWjELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVy
+bGluMRUwEwYDVQQKDAxUaGVRdENvbXBhbnkxEjAQBgNVBAsMCXdlYmVuZ2luZTAe
+Fw0yMTA1MTAyMTM1MTJaFw0yMjA1MTAyMTM1MTJaMGAxCzAJBgNVBAYTAkRFMQ8w
+DQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEVMBMGA1UECgwMVGhlUXRD
+b21wYW55MRgwFgYDVQQDDA93ZWJlbmdpbmUucXQuaW8wggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCoDKAU8bkgstvcbnUPQ4g3gqmbm3c6HWcHJOe+LWQz
+P6wIEF0JK6C3g2cqQHqSIa0wSysSbX/GDwGR9ul63e/f6MCJ1GmO8IhKrLdn0PVy
+AIUzjqGKhv8C8tmmohOICCxTh8nhq64gqEWmUgasgoy/aAryFqgEYGhFQPVEz6Kv
+CMSvpM1dNC3YCn467Gznc0s+EA6C6al/PNFHz9SZuF6f4bkyEf5dPPOt6IKXPZXo
+Dv148mPLW5Dw0nv19445YENGLNENbDGyc13bgaOSm9xpPBp+IrpV2p65v5dO2IHl
+E9qXaicKPRNANydppx5yX/OZRawgU2Q0lYNx3f+8R3I5AgMBAAGjMzAxMBoGA1Ud
+EQQTMBGCD3dlYmVuZ2luZS5xdC5pbzATBgNVHSUEDDAKBggrBgEFBQcDATANBgkq
+hkiG9w0BAQsFAAOCAQEAjThKpP0sBv1vEmaqBc1wTu//7RHmFcoStTt3scADzb2C
+9gjOVC4NzxBneLkv01444Z1p/Iiu/ZZ+VKu7aJElJgnBWEisYwJ09t3cdZRA0UY7
+XRvTVAqV0OlsB1Jn0afE+aTLGjWo+jSYzua0O+NK74e23p9jkdSmXxH9w0FB/oyM
+FGIOFnnfP0+QR4ZVvAGk2H60tBHQKmCM6b87TiD4GQIfOghCQWH+qJYSuyGu4hkE
+uis+n1KHHhed3GIJOHpm7gt1C9qtjcp1nOpv0ycQjfc9CGvr02BcQjhMeO65hX0A
+TvCgKN9/XMFv5jwwjjPCL12GBhwnN2k9hM/tEYpe2A==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIGeTCCBGGgAwIBAgIUbVL7tFc7sgPIYnt+REVc0wiHdBcwDQYJKoZIhvcNAQEL
-BQAwdzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
-DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEqMCgGA1UEAwwhQmFkU1NM
-IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE5MDgyNjE0NDQyMFoXDTI5
-MDgyMzE0NDQyMFowfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx
-FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEyMDAGA1UE
-AwwpQmFkU1NMIEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgoU4q43DJEUyoAOeK31uyEgLn
-s5CCd6XFmGp6wln0yupwmYRaDiCoSJ1qpmjYt+gIHpDAFS2ZzR4TbZORFirjY0cQ
-6+IWwpBEQR0hOluWN99CqjdCxfuZwiTvTV3FQv1IJZ13g23Uh2xRbnrzC2muDHzT
-4ZNM3aayvziMGY6n33aksEc6WMZb3p/Qn2OepeC7EzZiy4tXKPf9OaOPbae5aJWZ
-bOzzydFLkV4UqZb5FfySt8toIivPeIlRCiPodWLb2y5DYUXyWBk1dpbIcVa/LusV
-vsBELeJ+BFDRH1NHtwOrhOkZHKMr3SQ1YRlNDEeHUVmQkori397j9JjpPzScQJ6r
-d/W4mGyzgRmguIy9IpKMbxX5/1A6c6l5q0HqMgPv84GWxlhav4xwsOf90iT2vLPZ
-yllVCgCsCfvLEyVFhER18HAo8mTkQqKL7ZO96xXHgugA7dFN/C3BdC9kYP/GbAwd
-J0R6qKrfSiyyk1VbjWfFdFH/G/bT9H0nrjMj5tCT4q/zDCb5HkBp3BOoyUKb9yyt
-a1Cht/Iu3f1SlQzsrDBt9iMMCjXoNNAJcV7ZZ6HCxcWwfAwxgylQgq8UG60shxhn
-CBPhcA8JM+mk2nghTU2pxwY/KpAd0H4/a79b0DE97dCOnNHzyP3tqP8RenG549B0
-gsNO60aG01k6P9jFuQIDAQABo4H0MIHxMB0GA1UdDgQWBBQgvWmDuYqQ6xX7y8xc
-cgky1FO7jzCBtAYDVR0jBIGsMIGpgBTUGo+svIaoSMF/shILSbeiQ1zAQKF7pHkw
-dzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNh
-biBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEqMCgGA1UEAwwhQmFkU1NMIFJv
-b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ghR1qCPxzkfCSCwMFHm98245f0pk0zAM
-BgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAnGr6
-t1+KNGZV9hmAE3SyMzHRpgwtqIG4kl94A7Pz3CbA8+q7u7DW8l1GdaNx2J2wo+R5
-rJi02V5e7TNa7ZS5S9WGYHZ2y6QOjXuT28VMAPX+3HAgxk3RMxocpLpkPp8hhD/9
-S5KxA6AQDUN6av8E3xeuuWYWmTvAXNHK5ABXDFxxTp902ozNnZaSk2DxAUqcsOD4
-ago0IhRdkFGe1Q7F8gOxtlUL5owNL4uhRP8BbwOja2Gopn2+kA9CNqdwPI4Ipjlr
-yo61oCqzy3RAXOUct8WAvybacADmJODAxDq9O5fAZuYZScjjj1ASowmbyDH/Wb9z
-+WfiKKH4BfgOIukzK3I1M9wiSDefIodCFfEVXbdNudZj8f9Gw4RrZwkUuxDLeRWG
-ReDtzAWq7G0Diw3uX40S4jaj3MeS6oHp2Nrj/VyjSRiYTeN/pnA9N0M5VuCYYvXD
-f50rrigjQfOgb4TmnyJAjXWVkXW7Fa+ooLsbvlfr8wP8f31y1cgWPHTVIv6Kmug7
-Bg88k3x5gLTXmutDjseORonhGMRdAxHgJVf5aKfzdRpwXZTDZJXhsAz9OdlOhNZd
-UrYo680QugA0V3H5D8Egbr2AUUSMDkn133COjeOIDknFxX3qDqeTzqLZCAEBIoKn
-Adpix0jvG1Ys4Ayq6K2wQFdGFjtl6LsiGC7pWWU=
+MIIDOzCCAiMCFDwWg4NZxCplj3qyBxAUTi1wmj4jMA0GCSqGSIb3DQEBCwUAMFox
+CzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEV
+MBMGA1UECgwMVGhlUXRDb21wYW55MRIwEAYDVQQLDAl3ZWJlbmdpbmUwHhcNMjEw
+NTEwMjEzMTE4WhcNMjIwNTEwMjEzMTE4WjBaMQswCQYDVQQGEwJERTEPMA0GA1UE
+CAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFTATBgNVBAoMDFRoZVF0Q29tcGFu
+eTESMBAGA1UECwwJd2ViZW5naW5lMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAuc/8xVrfSzOsI6kYul+o1QIPBh1I86eQm1PhTBDMAAPHuzyPaEMgBkn2
+XAUmvkynGpNioaJDU2ndV2fBHvsoeQCdNNmjFTe1rKYjrN6U2X5KoYSzN93TOYzK
+aR38fEFx+w4qV76nnxSjYtGNe9z74GrfWFMdDQ0NJKzvaO4gaZ+OOg0OzWy4MJQ0
+aINo3UV55Y7Nt92AxFweiuHucKu+rjf3BX7n0Af/Tcs2c84f0R3HA7euReSibVvX
+f33eHLRKwu2bvDjXiUzOdkxBn9GTo6Q09LyY6wDG0ZdWnyCKj3NBQKBVrq+bs3Q0
+ATsWhj/PvYlZhhZh4EOlqYOhCpwv4wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCC
+pLSFGJcG0zhHW+2A6ogmpn2tA8gKUZx7f0J1nwgPEoAXQqWQv/299ZtmWfMKHUkk
+ygG4u80C87wWPH42XWXo/KDrP9iYzoqAvtqbRuPG9PAxefQ/JUSnuhikA51g9+Mu
+IDKKKSI+y/JW9u0Qo77fp/5n2DaFn5B+pBYvn/xLfaEa9bRdJMTEMsElGbPBzMZd
+I/7X6B78X6Ow5TuRKSeZA7E1AZ/+e5A4Hj65bLAugoSKz3zaS0dV26LwAo18c2zP
+TqtwHyIVj4QCoI6Z694q9KH4Pkml3fz8VSkk+MvZMWapvUhHu/DneTgqGbp9POYg
+nx6oWME6idhnvN6DljxB
-----END CERTIFICATE-----
diff --git a/tests/auto/shared/resources/key.pem b/tests/auto/shared/resources/key.pem
index 89922679a..9bf87aee3 100644
--- a/tests/auto/shared/resources/key.pem
+++ b/tests/auto/shared/resources/key.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAkybT/L4zJCqefpd+eYT6aQ0PtobQfFgP+n+z5wWoUxIAJnjb
-5ZW47IJxka/2/ggzJOfrUBur54LkTfFQ+yX85eKYCuH0GLz+Rve50LDn0ya6qSgm
-EhDG0bend2tMZY+Nl3B+5Ane1vua8hdJjv3ZO3e5UgpQwysL54eYyhEWWlbFWF11
-LhEdMYp953UGLqoV4Mlw+Li8TmFwdKQx6icgBTuloXLzk9aUU+b6NbXdadNXkmzg
-09ICsb8pnMXiF2P9Xm5rK0IoiRkSHxVnU12nQXh65Ns/2Dj5DcbHmVdvallfr4wn
-LeFPUotysZnvFmE7FLMSr/eQfkTG+Jlb7ZhoGwIDAQABAoIBADRXy3BL98UVo+tD
-2ClBtBFKJBy5N9ADQyvH4SZ8TLO/423L7+xqpaz7eYppHWKfaBHorTuBnFRtquhO
-vo+Xo63iPFMirMFf+NMlq2MgilYBoMQrE9+5N//BZECGWlaGCcekrH5RRIMUXLlg
-rzm98lfE7pbQNIo39bQV97NpAJqBWPuoIvCrbRCysGoA5j7ptZ/EhSlC00eA7ybD
-CeYHmh8NrsapKOTGb5u1v3paV8X/mH6vKmsVs7n6LC0opBxzM8eAHEAQ6h8rmz9H
-y99FWDYha3lOS4SLkTnuRnNHOMLJajPq3Isu+BgzLWuRGnKZ3rmuUFwPNkCZTvsV
-dTdBE4ECgYEAw6jBEil0e8Pc9sGqnz93e8qrYE9wSPso4q3BNJgTbN48kon6mqh7
-gQVgEP/75Th5YrJUrY9Pd/8H9uoMOxbDXgOXG/xNnhC0L+7aM8nhKlxCLndY1e56
-/YymYYH4+D9ZD2u526mK/nmCg2QGOkCVYYp7NXe/mA0g34drKjefmj8CgYEAwIhq
-rZhlfAvQThSOqQA9zA7NXPDh4KzIjr8htVu5YvVcv5W2uhsni9DXFaloPnhuLdJ7
-MnPF2WqzQ9YqFrGn/9/OTqeE23f60ed04qLGM4BApb45y5Kw6sCPnWu7dMYfny9i
-XeZA2A+ODmqVkrU+ZNVzqzS1krYyUP3exd1voyUCgYEAqPRARH6np3gqhqoVvA4C
-D1OjSTdPrrWzSIriG5h2rbv6ck/Tp1l1zKPnoMZrrjRmHWQA2x61cNk4926DwUKW
-0cgn5HKqU6P49Ks8oRvi48FnJNjKTXHxoqChy/GAHF4Xecl8ZMKy06v5l5v4BLVg
-SSpb2n/dYl9z05IMaBhAKeECgYBKB2n1S6ah1q0GiLL92mDoiDyAYwKG8AjBkk40
-vIsAuNUruTYkQvKmuOsqohO6CXZb2hWSpZ9KZNN+3ucaCL9PDE/4QEM+W9iuQu/X
-gLzy6npxAD6avtGVweq2ncjbMp7QB1ksP69pJDn74xGV8miGPuiVyNOUEMgyChtR
-Oz6EnQKBgEth0w80CBg6b3NKuASoc/vC08njZQvWpe5xrzY2DL8epVKb1qf6+8SE
-eX34cIcSaonEZ2g67MAeIG6jtmPwxWk4EYAsO1u4XiyziABkoNyLKVH4hZg61BsV
-jL7R5UrUvBbhKLFOwkcB4Kwdwu7COB/UKa5XJBTMbuw1UTyxlUeI
+MIIEpQIBAAKCAQEAqAygFPG5ILLb3G51D0OIN4Kpm5t3Oh1nByTnvi1kMz+sCBBd
+CSugt4NnKkB6kiGtMEsrEm1/xg8Bkfbpet3v3+jAidRpjvCISqy3Z9D1cgCFM46h
+iob/AvLZpqITiAgsU4fJ4auuIKhFplIGrIKMv2gK8haoBGBoRUD1RM+irwjEr6TN
+XTQt2Ap+Ouxs53NLPhAOgumpfzzRR8/Umbhen+G5MhH+XTzzreiClz2V6A79ePJj
+y1uQ8NJ79feOOWBDRizRDWwxsnNd24GjkpvcaTwafiK6Vdqeub+XTtiB5RPal2on
+Cj0TQDcnaacecl/zmUWsIFNkNJWDcd3/vEdyOQIDAQABAoIBAQCW93icOCdim6tu
+FIDu7HEjxSsPUpPCToWu4lWaAHcinxGx0NlzkpD4K4DzcSdrvfszBmQ0UtBVokd7
+1IAdU+HZmePWLk+CDM2zoAPHrO3Cs3r2PS0cIHhZMsearcG0E/uWMseHB08PoXuo
+lcnPEhzVGueyYe4guGcTx+5PGeUBLf+fJcEc3rIQnT2LYulM2aqBZSQM3jRUaPYs
+F0awDpCNwajW/Bt2VB14Pr+H5MJ+WSznFCqW7SolBkqDGfKckXPSHgX6xZ0y7VCI
+MM8vwlVI4mPkaHvSQMSI8vS4Qh+SGQCSs/AuuNLjjPoz1YotV3Ih4YbLj6BjFP2g
+CrqzT6VNAoGBANOHmsqE0nRkLzonTDrMdla5b0TjTxwtNM5DjLgJa6UBBqPe+1Lv
+JFoBP9bIfYDRWZOZrxXItfMmM43nK/ST6Xqgx1IpHUCLKVr2pA9RXrP+m4oawfgn
+frW212fHibeOYiLy+DaQXQ0VRFxsc/VbwKVyVlMEcNg3N93x2E67M7vjAoGBAMtg
+7wDa+5gjwuyNr7LKkp5VDTmtKQhoDtg4sw6MSQSMF6fJT9Z4kGTZ23+G85/LsM/k
+iXbceabGJ0CQJvGn6oW4dI2Ut2c2nCNVbQCxJ6Nyn/yW7bRLShMnwXvbGAVxVUax
+5ohJPZGJ8ar2CP76A0bkvm2Nwylq2gp6Y8h7+iwzAoGBAKizwfQ6sk45iKDsrpNG
+dir8gY2DbJigRTksDpLIkJ1skAspz295YpiV3oBCLjYKwVJCg6zwAo0FrqBB+oB5
+ZwByMgWI3NeZJUZy5q2Ay/Lp4MroRELR3PC3/lu6fE90szgEZ4m84TmJ+Jdtt527
+q41H/yj+pbELePb95vIDw2LZAoGBAJBZ+MmupCzUFSI5Xp+UUIS48W4ijaE92mt1
+swF8aMcleBTLOjOL11D9oGHfs0OUG6czGq6WxnGs62dT6ZBUEo1e4rsq9xH3HNOn
+anq3Qt8sGIn7xjPVzHnUGeyDEYWrb0+CLZJGCcEnG7SwdKolYfYLnW281Oysvp35
+SKGf/W0pAoGAa2+sZmhb1mpGAf6Bi4z+uym/6qOJmG6CnrBSM9e/r8nujwFVkCYF
+3iz48qx3GbuliO6za8aM1drX2u8KWp1uP5KzwYvtW5SfpQ1eusFblHEYQQNRcKLT
+j/wZBXnU961eMKkkTe2XsPirO8rVhVmxuFLqT/aEPffcragQFFIGOEQ=
-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index 84382d6f1..0c235382a 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -160,6 +160,9 @@ void tst_Accessibility::focusChild_data()
void tst_Accessibility::focusChild()
{
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 1)
+ QSKIP("Requires newer base Qt");
+#endif
auto traverseToWebDocumentAccessibleInterface = [](QAccessibleInterface *iface) -> QAccessibleInterface * {
QFETCH(QVector<QAccessible::Role>, ancestorRoles);
for (int i = 0; i < ancestorRoles.size(); ++i) {
diff --git a/tests/auto/widgets/certificateerror/BLACKLIST b/tests/auto/widgets/certificateerror/BLACKLIST
new file mode 100644
index 000000000..a8fd16bf3
--- /dev/null
+++ b/tests/auto/widgets/certificateerror/BLACKLIST
@@ -0,0 +1,2 @@
+[fatalError]
+*
diff --git a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
index c5b761818..7a55e306d 100644
--- a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
+++ b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
@@ -30,6 +30,7 @@
#include <QWebEngineCertificateError>
#include <QWebEnginePage>
+#include <QWebEngineProfile>
#include <QWebEngineSettings>
#include <QtTest/QtTest>
@@ -99,8 +100,8 @@ void tst_CertificateError::handleError()
QVERIFY(page.error->isOverridable());
auto chain = page.error->certificateChain();
QCOMPARE(chain.size(), 2);
- QCOMPARE(chain[0].serialNumber(), "3b:dd:1a:b7:2f:40:32:3b:c1:bf:37:d4:86:bd:56:c1:d0:6b:2a:43");
- QCOMPARE(chain[1].serialNumber(), "6d:52:fb:b4:57:3b:b2:03:c8:62:7b:7e:44:45:5c:d3:08:87:74:17");
+ QCOMPARE(chain[0].serialNumber(), "15:91:08:23:37:91:ee:51:00:d7:4a:db:d7:8c:3b:31:f8:4f:f3:b3");
+ QCOMPARE(chain[1].serialNumber(), "3c:16:83:83:59:c4:2a:65:8f:7a:b2:07:10:14:4e:2d:70:9a:3e:23");
if (deferError) {
QVERIFY(page.error->deferred());
@@ -124,6 +125,7 @@ void tst_CertificateError::handleError()
void tst_CertificateError::fatalError()
{
PageWithCertificateErrorHandler page(false, false);
+ page.profile()->setUseForGlobalCertificateVerification();
page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
diff --git a/tests/auto/widgets/loadsignals/BLACKLIST b/tests/auto/widgets/loadsignals/BLACKLIST
deleted file mode 100644
index 570666a83..000000000
--- a/tests/auto/widgets/loadsignals/BLACKLIST
+++ /dev/null
@@ -1,14 +0,0 @@
-[secondLoadForError_WhenErrorPageEnabled:ErrorPageEnabled]
-*
-
-# QTBUG-65223
-[loadStartedAndFinishedCount:WithAnchorClickedFromJS]
-*
-
-# QTBUG-66869 (https://codereview.qt-project.org/#/c/222112/ is only a workaround)
-[loadAfterInPageNavigation_qtbug66869]
-*
-
-# QTBUG-66661
-[fileDownloadDoesNotTriggerLoadSignals_qtbug66661]
-*
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
index 32bf53931..8462f0559 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
@@ -36,6 +36,43 @@
#include "qwebenginesettings.h"
#include "qwebengineview.h"
+enum { LoadStarted, LoadSucceeded, LoadFailed };
+static const QList<int> SignalsOrderOnce({ LoadStarted, LoadSucceeded});
+static const QList<int> SignalsOrderTwice({ LoadStarted, LoadSucceeded, LoadStarted, LoadSucceeded });
+static const QList<int> SignalsOrderOnceFailure({ LoadStarted, LoadFailed });
+static const QList<int> SignalsOrderTwiceWithFailure({ LoadStarted, LoadSucceeded, LoadStarted, LoadFailed });
+
+class TestPage : public QWebEnginePage
+{
+public:
+ QSet<QUrl> blacklist;
+ int navigationRequestCount = 0;
+ QList<int> signalsOrder;
+ QList<int> loadProgress;
+
+ explicit TestPage(QObject *parent = nullptr) : TestPage(nullptr, parent) { }
+ TestPage(QWebEngineProfile *profile, QObject *parent = nullptr) : QWebEnginePage(profile, parent) {
+ connect(this, &QWebEnginePage::loadStarted, [this] () { signalsOrder.append(LoadStarted); });
+ connect(this, &QWebEnginePage::loadProgress, [this] (int p) { loadProgress.append(p); });
+ connect(this, &QWebEnginePage::loadFinished, [this] (bool r) { signalsOrder.append(r ? LoadSucceeded : LoadFailed); });
+ }
+
+ void reset()
+ {
+ blacklist.clear();
+ navigationRequestCount = 0;
+ signalsOrder.clear();
+ loadProgress.clear();
+ }
+
+protected:
+ bool acceptNavigationRequest(const QUrl &url, NavigationType, bool) override
+ {
+ ++navigationRequestCount;
+ return !blacklist.contains(url);
+ }
+};
+
class tst_LoadSignals : public QObject
{
Q_OBJECT
@@ -48,32 +85,59 @@ private Q_SLOTS:
void monotonicity();
void loadStartedAndFinishedCount_data();
void loadStartedAndFinishedCount();
- void secondLoadForError_WhenErrorPageEnabled_data();
- void secondLoadForError_WhenErrorPageEnabled();
+ void loadStartedAndFinishedCountClick_data();
+ void loadStartedAndFinishedCountClick();
+ void rejectNavigationRequest_data();
+ void rejectNavigationRequest();
void loadAfterInPageNavigation_qtbug66869();
- void fileDownloadDoesNotTriggerLoadSignals_qtbug66661();
+ void fileDownload();
+ void numberOfStartedAndFinishedSignalsIsSame_data();
+ void numberOfStartedAndFinishedSignalsIsSame();
+ void loadFinishedAfterNotFoundError_data();
+ void loadFinishedAfterNotFoundError();
+ void errorPageTriggered_data();
+ void errorPageTriggered();
private:
+ void clickLink(QPoint linkPos);
+
QWebEngineProfile profile;
- QWebEnginePage page{&profile};
+ TestPage page{&profile};
QWebEngineView view;
QSignalSpy loadStartedSpy{&page, &QWebEnginePage::loadStarted};
- QSignalSpy loadProgressSpy{&page, &QWebEnginePage::loadProgress};
QSignalSpy loadFinishedSpy{&page, &QWebEnginePage::loadFinished};
+ void resetSpies() {
+ loadStartedSpy.clear();
+ loadFinishedSpy.clear();
+ }
};
void tst_LoadSignals::initTestCase()
{
view.setPage(&page);
- view.resize(1024,768);
+ view.resize(640, 480);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
}
void tst_LoadSignals::init()
{
- loadStartedSpy.clear();
- loadProgressSpy.clear();
- loadFinishedSpy.clear();
+ // Reset content
+ if (!view.url().isEmpty()) {
+ loadFinishedSpy.clear();
+ view.load(QUrl("about:blank"));
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ }
+ resetSpies();
+ page.reset();
+}
+
+void tst_LoadSignals::clickLink(QPoint linkPos)
+{
+ // Simulate left-clicking on link.
+ QTRY_VERIFY(view.focusProxy());
+ QWidget *renderWidget = view.focusProxy();
+ QTest::mouseClick(renderWidget, Qt::LeftButton, {}, linkPos);
}
/**
@@ -82,27 +146,124 @@ void tst_LoadSignals::init()
void tst_LoadSignals::loadStartedAndFinishedCount_data()
{
QTest::addColumn<QUrl>("url");
- QTest::addColumn<int>("expectedLoadCount");
- QTest::newRow("Normal") << QUrl("qrc:///resources/page1.html") << 1;
- QTest::newRow("WithAnchor") << QUrl("qrc:///resources/page2.html#anchor") << 1;
-
- // In this case, we get an unexpected additional loadStarted, but no corresponding
- // loadFinished, so expectedLoadCount=2 would also not work. See also QTBUG-65223
- QTest::newRow("WithAnchorClickedFromJS") << QUrl("qrc:///resources/page3.html") << 1;
+ QTest::addColumn<QList<int>>("expectedSignals");
+ QTest::newRow("Simple") << QUrl("qrc:///resources/page1.html") << SignalsOrderOnce;
+ QTest::newRow("SimpleWithAnchor") << QUrl("qrc:///resources/page2.html#anchor") << SignalsOrderOnce;
+ QTest::newRow("SamePageImmediate") << QUrl("qrc:///resources/page5.html") << SignalsOrderOnce;
+ QTest::newRow("SamePageDeferred") << QUrl("qrc:///resources/page3.html") << SignalsOrderOnce;
+ QTest::newRow("OtherPageImmediate") << QUrl("qrc:///resources/page6.html") << SignalsOrderOnce;
+ QTest::newRow("OtherPageDeferred") << QUrl("qrc:///resources/page7.html") << SignalsOrderTwice;
+ QTest::newRow("SamePageImmediateJS") << QUrl("qrc:///resources/page8.html") << SignalsOrderOnce;
}
void tst_LoadSignals::loadStartedAndFinishedCount()
{
QFETCH(QUrl, url);
- QFETCH(int, expectedLoadCount);
+ QFETCH(QList<int>, expectedSignals);
view.load(url);
+
+ int expectedLoadCount = expectedSignals.size() / 2;
+ QTRY_COMPARE(loadStartedSpy.size(), expectedLoadCount);
QTRY_COMPARE(loadFinishedSpy.size(), expectedLoadCount);
+
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != expectedLoadCount || loadFinishedSpy.size() != expectedLoadCount, 1000, 100);
+
+ // No further signals should have occurred within this time and expected number of signals is preserved
+ QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
+ QCOMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.signalsOrder, expectedSignals);
+}
+
+/**
+ * Load a URL, then simulate a click to load a different URL.
+ */
+void tst_LoadSignals::loadStartedAndFinishedCountClick_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<int>("numberOfSignals");
+ QTest::newRow("SamePage") << QUrl("qrc:///resources/page2.html") << 0; // in-page navigation to anchor shouldn't emit anything
+ QTest::newRow("OtherPage") << QUrl("qrc:///resources/page1.html") << 1;
+}
+
+void tst_LoadSignals::loadStartedAndFinishedCountClick()
+{
+ QFETCH(QUrl, url);
+ QFETCH(int, numberOfSignals);
+
+ view.load(url);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QVERIFY(loadFinishedSpy[0][0].toBool());
+ resetSpies();
- // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs)
- QTRY_LOOP_IMPL((loadStartedSpy.size() != expectedLoadCount)
- || (loadFinishedSpy.size() != expectedLoadCount), 10000, 100);
+ clickLink(QPoint(10, 10));
+ if (numberOfSignals > 0) {
+ QTRY_COMPARE(loadStartedSpy.size(), numberOfSignals);
+ QTRY_COMPARE(loadFinishedSpy.size(), numberOfSignals);
+ QVERIFY(loadFinishedSpy[0][0].toBool());
+ }
+
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != numberOfSignals || loadFinishedSpy.size() != numberOfSignals, 1000, 100);
+
+ // No further loadStarted should have occurred within this time
+ QCOMPARE(loadStartedSpy.size(), numberOfSignals);
+ QCOMPARE(loadFinishedSpy.size(), numberOfSignals);
+ QCOMPARE(page.signalsOrder, numberOfSignals > 0 ? SignalsOrderTwice : SignalsOrderOnce);
+}
+
+void tst_LoadSignals::rejectNavigationRequest_data()
+{
+ QTest::addColumn<QUrl>("initialUrl");
+ QTest::addColumn<QUrl>("rejectedUrl");
+ QTest::addColumn<int>("expectedNavigations");
+ QTest::addColumn<QList<int>>("expectedSignals");
+ QTest::newRow("Simple")
+ << QUrl("qrc:///resources/page1.html")
+ << QUrl("qrc:///resources/page1.html")
+ << 1 << SignalsOrderOnceFailure;
+ QTest::newRow("SamePageImmediate")
+ << QUrl("qrc:///resources/page5.html")
+ << QUrl("qrc:///resources/page5.html#anchor")
+ << 1 << SignalsOrderOnce;
+ QTest::newRow("SamePageDeferred")
+ << QUrl("qrc:///resources/page3.html")
+ << QUrl("qrc:///resources/page3.html#anchor")
+ << 1 << SignalsOrderOnce;
+ QTest::newRow("OtherPageImmediate")
+ << QUrl("qrc:///resources/page6.html")
+ << QUrl("qrc:///resources/page2.html#anchor")
+ << 2 << SignalsOrderOnceFailure;
+ QTest::newRow("OtherPageDeferred")
+ << QUrl("qrc:///resources/page7.html")
+ << QUrl("qrc:///resources/page2.html#anchor")
+ << 2 << SignalsOrderTwiceWithFailure;
+}
+
+/**
+ * Returning false from acceptNavigationRequest means that the load
+ * fails, not that the load never starts.
+ *
+ * See QTBUG-75185.
+ */
+void tst_LoadSignals::rejectNavigationRequest()
+{
+ QFETCH(QUrl, initialUrl);
+ QFETCH(QUrl, rejectedUrl);
+ QFETCH(int, expectedNavigations);
+ QFETCH(QList<int>, expectedSignals);
+
+ page.blacklist.insert(rejectedUrl);
+ page.load(initialUrl);
+ QTRY_COMPARE(page.navigationRequestCount, expectedNavigations);
+ int expectedLoadCount = expectedSignals.size() / 2;
+ QTRY_COMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.signalsOrder, expectedSignals);
+
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != expectedLoadCount || loadFinishedSpy.size() != expectedLoadCount, 1000, 100);
// No further loadStarted should have occurred within this time
QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
@@ -125,53 +286,19 @@ void tst_LoadSignals::monotonicity()
QTRY_COMPARE(loadFinishedSpy.size(), 1);
QVERIFY(loadFinishedSpy[0][0].toBool());
+ QVERIFY(page.loadProgress.size() >= 3);
// first loadProgress should have 0% progress
- QCOMPARE(loadProgressSpy.takeFirst()[0].toInt(), 0);
+ QCOMPARE(page.loadProgress.first(), 0);
// every loadProgress should have more progress than the one before
- int progress = 0;
- for (const auto &item : loadProgressSpy) {
- QVERIFY(progress < item[0].toInt());
- progress = item[0].toInt();
+ int progress = -1;
+ for (int p : page.loadProgress) {
+ QVERIFY(progress < p);
+ progress = p;
}
// last loadProgress should have 100% progress
- QCOMPARE(loadProgressSpy.last()[0].toInt(), 100);
-}
-
-/**
- * Test that we get a second loadStarted and loadFinished signal
- * for error-pages (unless error-pages are disabled)
- */
-void tst_LoadSignals::secondLoadForError_WhenErrorPageEnabled_data()
-{
- QTest::addColumn<bool>("enabled");
- // in this case, we get no second loadStarted and loadFinished, although we had
- // agreed on making the navigation to an error page an individual load
- QTest::newRow("ErrorPageEnabled") << true;
- QTest::newRow("ErrorPageDisabled") << false;
-}
-
-void tst_LoadSignals::secondLoadForError_WhenErrorPageEnabled()
-{
- QFETCH(bool, enabled);
- view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, enabled);
- int expectedLoadCount = (enabled ? 2 : 1);
-
- // RFC 2606 guarantees that this will never become a valid domain
- view.load(QUrl("http://nonexistent.invalid"));
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), expectedLoadCount, 10000);
- QVERIFY(!loadFinishedSpy[0][0].toBool());
- if (enabled)
- QVERIFY(loadFinishedSpy[1][0].toBool());
-
- // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs)
- QTRY_LOOP_IMPL((loadStartedSpy.size() != expectedLoadCount)
- || (loadFinishedSpy.size() != expectedLoadCount), 10000, 100);
-
- // No further loadStarted should have occurred within this time
- QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
- QCOMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.loadProgress.last(), 100);
}
/**
@@ -185,27 +312,17 @@ void tst_LoadSignals::loadAfterInPageNavigation_qtbug66869()
QVERIFY(loadFinishedSpy[0][0].toBool());
// page3 does an in-page navigation after 500ms
- QTest::qWait(2000);
- loadFinishedSpy.clear();
- loadProgressSpy.clear();
- loadStartedSpy.clear();
+ QTRY_COMPARE(view.url(), QUrl("qrc:///resources/page3.html#anchor"));
// second load
view.load(QUrl("qrc:///resources/page1.html"));
- QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 2);
QVERIFY(loadFinishedSpy[0][0].toBool());
// loadStarted and loadFinished should have been signalled
- QCOMPARE(loadStartedSpy.size(), 1);
-
- // reminder that we still need to solve the core issue
- QFAIL("https://codereview.qt-project.org/#/c/222112/ only hides the symptom, the core issue still needs to be solved");
+ QCOMPARE(loadStartedSpy.size(), 2);
}
-/**
- * Test that file-downloads don't trigger loadStarted or loadFinished signals.
- * See QTBUG-66661
- */
-void tst_LoadSignals::fileDownloadDoesNotTriggerLoadSignals_qtbug66661()
+void tst_LoadSignals::fileDownload()
{
view.load(QUrl("qrc:///resources/page4.html"));
QTRY_COMPARE(loadFinishedSpy.size(), 1);
@@ -227,20 +344,156 @@ void tst_LoadSignals::fileDownloadDoesNotTriggerLoadSignals_qtbug66661()
});
// trigger the download link that becomes focused on page4
- QTest::qWait(1000);
QTest::sendKeyEvent(QTest::Press, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
QTest::sendKeyEvent(QTest::Release, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
- // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs)
- QTRY_LOOP_IMPL((loadStartedSpy.size() != 1)
- || (loadFinishedSpy.size() != 1), 10000, 100);
-
// Download must have occurred
QTRY_COMPARE(downloadState, QWebEngineDownloadItem::DownloadCompleted);
+ QTRY_COMPARE(loadFinishedSpy.size() + loadStartedSpy.size(), 4);
- // No further loadStarted should have occurred within this time
- QCOMPARE(loadStartedSpy.size(), 1);
- QCOMPARE(loadFinishedSpy.size(), 1);
+ // verify no more signals is emitted by waiting for another loadStarted or loadFinished
+ QTRY_LOOP_IMPL(loadStartedSpy.size() != 2 || loadFinishedSpy.size() != 2, 1000, 100);
+
+ QCOMPARE(page.signalsOrder, SignalsOrderTwiceWithFailure);
+}
+
+void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame_data()
+{
+ QTest::addColumn<bool>("imageFromServer");
+ QTest::addColumn<QString>("imageResourceUrl");
+ // triggers these calls in delegate internally:
+ // just two ordered triples DidStartNavigation/DidFinishNavigation/DidFinishLoad
+ QTest::newRow("no_image_resource") << false << "";
+ // out of order: DidStartNavigation/DidFinishNavigation/DidStartNavigation/DidFailLoad/DidFinishNavigation/DidFinishLoad
+ QTest::newRow("with_invalid_image") << false << "https://non.existent.locahost/image.png";
+ // out of order: DidStartNavigation/DidFinishNavigation/DidStartNavigation/DidFinishLoad/DidFinishNavigation/DidFinishLoad
+ QTest::newRow("with_server_image") << true << "";
+}
+
+void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame()
+{
+ QFETCH(bool, imageFromServer);
+ QFETCH(QString, imageResourceUrl);
+
+ HttpServer server;
+ server.setResourceDirs({ TESTS_SOURCE_DIR "/qwebengineprofile/resources" });
+ QVERIFY(server.start());
+
+ QUrl serverImage = server.url("/hedgehog.png");
+ QString imageUrl(!imageFromServer && imageResourceUrl.isEmpty()
+ ? "" : (imageFromServer ? serverImage.toEncoded() : imageResourceUrl));
+
+ auto html = "<html><head><link rel='icon' href='data:,'></head><body>"
+ "%1" "<form method='GET' name='hiddenform' action='qrc:///resources/page1.html' />"
+ "<script language='javascript'>document.forms[0].submit();</script>"
+ "</body></html>";
+ view.page()->setHtml(QString(html).arg(imageUrl.isEmpty() ? "" : "<img src='" + imageUrl + "'>"));
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+
+ resetSpies();
+ QTRY_LOOP_IMPL(loadStartedSpy.size() || loadFinishedSpy.size(), 1000, 100);
+ QCOMPARE(page.signalsOrder, SignalsOrderOnce);
+}
+
+void tst_LoadSignals::loadFinishedAfterNotFoundError_data()
+{
+ QTest::addColumn<bool>("rfcInvalid");
+ QTest::addColumn<bool>("withServer");
+ QTest::addRow("rfc_invalid") << true << false;
+ QTest::addRow("non_existent") << false << false;
+ QTest::addRow("server_404") << false << true;
+}
+
+void tst_LoadSignals::loadFinishedAfterNotFoundError()
+{
+ QFETCH(bool, withServer);
+ QFETCH(bool, rfcInvalid);
+
+ QScopedPointer<HttpServer> server;
+ if (withServer) {
+ server.reset(new HttpServer);
+ QVERIFY(server->start());
+ }
+ view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ auto url = server
+ ? server->url("/not-found-page.html")
+ : QUrl(rfcInvalid ? "http://some.invalid" : "http://non.existent/url");
+ view.load(url);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);
+ QVERIFY(!loadFinishedSpy.at(0).at(0).toBool());
+ QCOMPARE(toPlainTextSync(view.page()), QString());
+ QCOMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadStartedSpy.count(), 1);
+ QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
+ page.loadProgress.clear();
+
+ view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
+ url = server
+ ? server->url("/another-missing-one.html")
+ : QUrl(rfcInvalid ? "http://some.other.invalid" : "http://another.non.existent/url");
+ view.load(url);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 2, 20000);
+ QVERIFY(!loadFinishedSpy.at(1).at(0).toBool());
+ QCOMPARE(loadStartedSpy.count(), 2);
+
+ QEXPECT_FAIL("", "No more loads (like separate load for error pages) are expected", Continue);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 3, 1000);
+ QCOMPARE(loadStartedSpy.count(), 2);
+ QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
+}
+
+void tst_LoadSignals::errorPageTriggered_data()
+{
+ QTest::addColumn<QString>("urlPath");
+ QTest::addColumn<bool>("loadSucceed");
+ QTest::addColumn<bool>("triggersErrorPage");
+ QTest::newRow("/content/200") << QStringLiteral("/content/200") << true << false;
+ QTest::newRow("/empty/200") << QStringLiteral("/content/200") << true << false;
+ QTest::newRow("/content/404") << QStringLiteral("/content/404") << false << false;
+ QTest::newRow("/empty/404") << QStringLiteral("/empty/404") << false << true;
+}
+
+void tst_LoadSignals::errorPageTriggered()
+{
+ HttpServer server;
+ connect(&server, &HttpServer::newRequest, [] (HttpReqRep *rr) {
+ QList<QByteArray> parts = rr->requestPath().split('/');
+ if (parts.length() != 3) {
+ // For example, /favicon.ico
+ rr->sendResponse(404);
+ return;
+ }
+ bool isDocumentEmpty = (parts[1] == "empty");
+ int httpStatusCode = parts[2].toInt();
+
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+ if (!isDocumentEmpty) {
+ rr->setResponseBody(QByteArrayLiteral("<html></html>"));
+ }
+ rr->sendResponse(httpStatusCode);
+ });
+ QVERIFY(server.start());
+
+ QFETCH(QString, urlPath);
+ QFETCH(bool, loadSucceed);
+ QFETCH(bool, triggersErrorPage);
+
+ view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
+ view.load(server.url(urlPath));
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QCOMPARE(loadFinishedSpy[0][0].toBool(), loadSucceed);
+ if (triggersErrorPage)
+ QVERIFY(toPlainTextSync(view.page()).contains("HTTP ERROR 404"));
+ else
+ QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ loadFinishedSpy.clear();
+
+ view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ view.load(server.url(urlPath));
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QCOMPARE(loadFinishedSpy[0][0].toBool(), loadSucceed);
+ QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ loadFinishedSpy.clear();
}
QTEST_MAIN(tst_LoadSignals)
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.qrc b/tests/auto/widgets/loadsignals/tst_loadsignals.qrc
index 21c517154..b4ee36676 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.qrc
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.qrc
@@ -4,6 +4,10 @@
<file alias="page2.html">../../shared/data/loadprogress/page2.html</file>
<file alias="page3.html">../../shared/data/loadprogress/page3.html</file>
<file alias="page4.html">../../shared/data/loadprogress/page4.html</file>
+ <file alias="page5.html">../../shared/data/loadprogress/page5.html</file>
+ <file alias="page6.html">../../shared/data/loadprogress/page6.html</file>
+ <file alias="page7.html">../../shared/data/loadprogress/page7.html</file>
+ <file alias="page8.html">../../shared/data/loadprogress/page8.html</file>
<file alias="downloadable.tar.gz">../../shared/data/loadprogress/downloadable.tar.gz</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/origins/origins.pro b/tests/auto/widgets/origins/origins.pro
index 7498354de..8b2fca2e4 100644
--- a/tests/auto/widgets/origins/origins.pro
+++ b/tests/auto/widgets/origins/origins.pro
@@ -1,4 +1,5 @@
include(../tests.pri)
+include(../../shared/http.pri)
CONFIG += c++14
qtConfig(webengine-webchannel):qtHaveModule(websockets) {
QT += websockets
diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp
index c24fbede4..e7d71d7fe 100644
--- a/tests/auto/widgets/origins/tst_origins.cpp
+++ b/tests/auto/widgets/origins/tst_origins.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "../util.h"
+#include "httpserver.h"
#include <QtCore/qfile.h>
#include <QtTest/QtTest>
@@ -215,6 +216,8 @@ private Q_SLOTS:
void jsUrlOrigin();
void subdirWithAccess();
void subdirWithoutAccess();
+ void fileAccessRemoteUrl_data();
+ void fileAccessRemoteUrl();
void mixedSchemes();
void mixedSchemesWithCsp();
void mixedXHR_data();
@@ -497,6 +500,31 @@ void tst_Origins::subdirWithoutAccess()
QCOMPARE(eval(QSL("msg[1]")), QVariant(QSL("world")));
}
+void tst_Origins::fileAccessRemoteUrl_data()
+{
+ QTest::addColumn<bool>("EnableAccess");
+ QTest::addRow("enabled") << true;
+ QTest::addRow("disabled") << false;
+}
+
+void tst_Origins::fileAccessRemoteUrl()
+{
+ QFETCH(bool, EnableAccess);
+
+ HttpServer server;
+ server.setResourceDirs({ THIS_DIR "resources" });
+ QVERIFY(server.start());
+
+ ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessRemoteUrls, EnableAccess);
+ if (!EnableAccess)
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("blocked by CORS policy")));
+
+ QVERIFY(verifyLoad(QSL("file:" THIS_DIR "resources/mixedXHR.html")));
+
+ eval("sendXHR('" + server.url("/mixedXHR.txt").toString() + "')");
+ QTRY_COMPARE(eval("result"), (EnableAccess ? QString("ok") : QString("error")));
+}
+
// Load the main page over one scheme with an iframe over another scheme.
//
// For file and qrc schemes, the iframe should load but it should not be
@@ -629,7 +657,7 @@ void tst_Origins::mixedXHR_data()
<< QVariant(QString("ok"));
QTest::newRow("file->cors") << QString("file:" THIS_DIR "resources/mixedXHR.html")
<< QString("sendXHR('cors:/resources/mixedXHR.txt')")
- << QVariant(QString("ok"));
+ << QVariant(QString("error"));
QTest::newRow("qrc->file") << QString("qrc:/resources/mixedXHR.html")
<< QString("sendXHR('file:" THIS_DIR "resources/mixedXHR.txt')")
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index ac38e2ed2..74082ab8c 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -84,6 +84,8 @@ private Q_SLOTS:
#endif
void downloadToDirectoryWithFileName_data();
void downloadToDirectoryWithFileName();
+ void downloadDataUrls_data();
+ void downloadDataUrls();
private:
void saveLink(QPoint linkPos);
@@ -302,7 +304,7 @@ void tst_QWebEngineDownloadItem::downloadLink_data()
/* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain")
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("")
- /* fileHasReferer */ << false // crbug.com/455987
+ /* fileHasReferer */ << true
/* fileAction */ << FileIsDownloaded;
// ... same with the content disposition header save for the download type.
@@ -326,7 +328,7 @@ void tst_QWebEngineDownloadItem::downloadLink_data()
/* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain")
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("attachment")
- /* fileHasReferer */ << false // crbug.com/455987
+ /* fileHasReferer */ << true
/* fileAction */ << FileIsDownloaded;
// The file's extension has no effect.
@@ -453,7 +455,7 @@ void tst_QWebEngineDownloadItem::downloadLink()
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested);
QCOMPARE(item->isFinished(), false);
- QCOMPARE(item->totalBytes(), -1);
+ QCOMPARE(item->totalBytes(), fileContents.size());
QCOMPARE(item->receivedBytes(), 0);
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition));
@@ -566,7 +568,7 @@ void tst_QWebEngineDownloadItem::downloadTwoLinks()
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested);
QCOMPARE(item->isFinished(), false);
- QCOMPARE(item->totalBytes(), -1);
+ QCOMPARE(item->totalBytes(), 5); // strlen("fileN")
QCOMPARE(item->receivedBytes(), 0);
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
@@ -1392,5 +1394,50 @@ void tst_QWebEngineDownloadItem::downloadToDirectoryWithFileName()
QCOMPARE(downloadedSuggestedFileName, fileName);
}
+void tst_QWebEngineDownloadItem::downloadDataUrls_data()
+{
+ QTest::addColumn<QByteArray>("htmlData");
+ QTest::addColumn<QString>("expectedFileName");
+ QTest::newRow("data url without slash") << QByteArrayLiteral("<html><head><meta charset=\"utf-8\"></head><body><a href=\"data:application/gzip;base64,dGVzdA==\">data URL without slash</a><br/></body></html>") << QStringLiteral("qwe_download.gz") ;
+ QTest::newRow("data url with slash") << QByteArrayLiteral("<html><head><meta charset=\"utf-8\"></head><body><a href=\"data:application/gzip;base64,dGVzcnI/dGVzdA==\">data URL with filename</a><br/></body></html>") << QStringLiteral("qwe_download.gz") ;
+ QTest::newRow("data url with download tag") << QByteArrayLiteral("<html><head><meta charset=\"utf-8\"></head><body><a href=\"data:application/gzip;base64,dGVzdA/IHRlc3Q=\" download=\"filename.gz\">data URL with filename</a><br/></body></html>") << QStringLiteral("filename.gz") ;
+
+}
+
+void tst_QWebEngineDownloadItem::downloadDataUrls()
+{
+ QFETCH(QByteArray, htmlData);
+ QFETCH(QString, expectedFileName);
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == "/") {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+ rr->setResponseBody(htmlData);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ int downloadRequestCount = 0;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested);
+ QCOMPARE(item->downloadFileName(), expectedFileName);
+ downloadRequestCount++;
+ });
+
+ QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+ m_view->load(m_server->url());
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+
+ // Trigger download
+ simulateUserAction(QPoint(10, 10), UserAction::ClickLink);
+ QTRY_COMPARE(downloadRequestCount, 1);
+}
+
QTEST_MAIN(tst_QWebEngineDownloadItem)
#include "tst_qwebenginedownloaditem.moc"
diff --git a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
index bdb486793..72a45379b 100644
--- a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
+++ b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
@@ -320,7 +320,8 @@ void tst_QWebEngineHistory::serialize_2()
hist->forward();
QTRY_COMPARE(loadFinishedSpy->count(), 5);
hist->forward();
- QTRY_COMPARE(loadFinishedSpy->count(), 6);
+ // In-page navigation, the last url was the page5.html
+ QTRY_COMPARE(loadFinishedSpy->count(), 5);
QTRY_COMPARE(hist->currentItemIndex(), initialCurrentIndex);
}
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 02b297d5a..d1425bfd6 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -4,9 +4,4 @@ osx
[mouseMovementProperties]
windows
macos # Can't move cursor (QTBUG-76312)
-
-[devTools]
-msvc-2019
-
-[setLifecycleStateWithDevTools]
-msvc-2019
+sles-15.4 # QTBUG-111297
diff --git a/tests/auto/widgets/qwebenginepage/resources/redirect.html b/tests/auto/widgets/qwebenginepage/resources/redirect.html
new file mode 100644
index 000000000..db06d73a7
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/redirect.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<script>
+function doRedirect() { location.replace('qrc:///resources/content.html') }
+document.addEventListener("DOMContentLoaded", doRedirect)
+</script>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 040114258..78d0a9862 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -73,6 +73,13 @@ static void removeRecursive(const QString& dirname)
QDir().rmdir(dirname);
}
+struct TestBasePage : QWebEnginePage
+{
+ explicit TestBasePage(QWebEngineProfile *profile, QObject *parent = nullptr) : QWebEnginePage(profile, parent) { }
+ explicit TestBasePage(QObject *parent = nullptr) : QWebEnginePage(parent) { }
+ QSignalSpy loadSpy { this, &QWebEnginePage::loadFinished };
+};
+
class tst_QWebEnginePage : public QObject
{
Q_OBJECT
@@ -174,7 +181,6 @@ private Q_SLOTS:
void setUrlUsingStateObject();
void setUrlThenLoads_data();
void setUrlThenLoads();
- void loadFinishedAfterNotFoundError();
void loadInSignalHandlers_data();
void loadInSignalHandlers();
void loadFromQrc();
@@ -520,7 +526,7 @@ void tst_QWebEnginePage::consoleOutput()
class TestPage : public QWebEnginePage {
Q_OBJECT
public:
- TestPage(QObject* parent = 0) : QWebEnginePage(parent)
+ TestPage(QObject *parent = nullptr) : QWebEnginePage(parent)
{
connect(this, SIGNAL(geometryChangeRequested(QRect)), this, SLOT(slotGeometryChangeRequested(QRect)));
}
@@ -597,6 +603,39 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
<< QWebEnginePage::NavigationTypeReload
<< QWebEnginePage::NavigationTypeTyped
<< QWebEnginePage::NavigationTypeRedirect;
+
+ // client side redirect
+ page.load(QUrl("qrc:///resources/redirect.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 7, 20000);
+ QTRY_COMPARE(page.navigations.count(), 8);
+ expectedList += { QWebEnginePage::NavigationTypeTyped, QWebEnginePage::NavigationTypeRedirect };
+
+ // server side redirect
+ HttpServer server;
+ server.setResourceDirs({ ":/resources" });
+ connect(&server, &HttpServer::newRequest, &server, [&] (HttpReqRep *r) {
+ if (r->requestMethod() == "GET") {
+ if (r->requestPath() == "/redirect1.html") {
+ r->setResponseHeader("Location", server.url("/redirect2.html").toEncoded());
+ r->setResponseBody("<html><body>Redirect1</body></html>");
+ r->sendResponse(307); // Internal server redirect
+ } else if (r->requestPath() == "/redirect2.html") {
+ r->setResponseHeader("Location", server.url("/content.html").toEncoded());
+ r->setResponseBody("<html><body>Redirect2</body></html>");
+ r->sendResponse(301); // Moved permanently
+ }
+ }
+ });
+ QVERIFY(server.start());
+ page.load(QUrl(server.url("/redirect1.html")));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 8, 20000);
+ QTRY_COMPARE(page.navigations.count(), 11);
+ expectedList += {
+ QWebEnginePage::NavigationTypeTyped,
+ QWebEnginePage::NavigationTypeRedirect,
+ QWebEnginePage::NavigationTypeRedirect
+ };
+
QVERIFY(expectedList.count() == page.navigations.count());
for (int i = 0; i < expectedList.count(); ++i) {
QCOMPARE(page.navigations[i].type, expectedList[i]);
@@ -1713,12 +1752,15 @@ void tst_QWebEnginePage::savePage()
void tst_QWebEnginePage::openWindowDefaultSize()
{
TestPage page;
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated()));
QWebEngineView view;
page.setView(&view);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
+ page.setUrl(QUrl("about:blank"));
view.show();
+ QTRY_COMPARE(spyFinished.count(), 1);
- page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
// Open a default window.
page.runJavaScript("window.open()");
QTRY_COMPARE(windowCreatedSpy.count(), 1);
@@ -2820,20 +2862,6 @@ void tst_QWebEnginePage::setUrlThenLoads()
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad2));
}
-void tst_QWebEnginePage::loadFinishedAfterNotFoundError()
-{
- QWebEnginePage page;
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
-
- page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
- page.setUrl(QUrl("http://non.existent/url"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
-
- page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
- page.setUrl(QUrl("http://another.non.existent/url"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
-}
-
class URLSetter : public QObject {
Q_OBJECT
@@ -2915,11 +2943,7 @@ void tst_QWebEnginePage::loadInSignalHandlers()
URLSetter setter(m_page, signal, type, urlForSetter);
QSignalSpy spy(&setter, &URLSetter::finished);
m_page->load(url);
- // every loadStarted() call should have also loadFinished()
- if (signal == URLSetter::LoadStarted)
- QTRY_COMPARE(spy.count(), 2);
- else
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.count(), 1);
QCOMPARE(m_page->url(), urlForSetter);
}
@@ -3021,25 +3045,42 @@ void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
void tst_QWebEnginePage::setZoomFactor()
{
- QWebEnginePage page;
+ TestBasePage page, page2;
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 1.0));
+ QCOMPARE(page.zoomFactor(), 1.0);
page.setZoomFactor(2.5);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
-
- const QUrl urlToLoad("qrc:/resources/test1.html");
-
- QSignalSpy finishedSpy(&page, SIGNAL(loadFinished(bool)));
- page.load(urlToLoad);
- QTRY_COMPARE(finishedSpy.count(), 1);
- QVERIFY(finishedSpy.at(0).first().toBool());
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
-
- page.setZoomFactor(5.5);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ const QUrl url1("qrc:/resources/test1.html"), url2(QUrl("qrc:/resources/test2.html"));
+
+ page.load(url1);
+ QTRY_COMPARE(page.loadSpy.count(), 1);
+ QVERIFY(page.loadSpy.at(0).first().toBool());
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ page.setZoomFactor(5.5); // max accepted zoom: kMaximumPageZoomFactor = 5.0
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ page.setZoomFactor(0.1); // min accepted zoom: kMinimumPageZoomFactor = 0.25
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ // try loading different url and check new values after load
+ page.loadSpy.clear();
+ for (auto &&p : {
+ qMakePair(&page, 2.5), // navigating away to different url should keep zoom
+ qMakePair(&page2, 1.0), // same url navigation in diffent page shouldn't be affected
+ }) {
+ auto &&page = *p.first; auto zoomFactor = p.second;
+ page.load(url2);
+ QTRY_COMPARE(page.loadSpy.count(), 1);
+ QVERIFY(page.loadSpy.last().first().toBool());
+ QCOMPARE(page.zoomFactor(), zoomFactor);
+ }
- page.setZoomFactor(0.1);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ // should have no influence on first page
+ page2.setZoomFactor(3.5);
+ for (auto &&p : { qMakePair(&page, 2.5), qMakePair(&page2, 3.5), })
+ QCOMPARE(p.first->zoomFactor(), p.second);
}
void tst_QWebEnginePage::mouseButtonTranslation()
@@ -3349,7 +3390,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage1);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 90000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(&inspectedPage2);
@@ -3361,7 +3402,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage2);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 90000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(nullptr);
@@ -3458,7 +3499,11 @@ void tst_QWebEnginePage::openLinkInNewPage_data()
// the disposition and performing the navigation request normally.
QTest::newRow("BlockPopup") << Decision::ReturnNull << Cause::TargetBlank << Effect::Blocked;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ QTest::newRow("IgnoreIntent") << Decision::ReturnNull << Cause::MiddleClick << Effect::Blocked;
+#else
QTest::newRow("IgnoreIntent") << Decision::ReturnNull << Cause::MiddleClick << Effect::LoadInSelf;
+#endif
QTest::newRow("OverridePopup") << Decision::ReturnSelf << Cause::TargetBlank << Effect::LoadInSelf;
QTest::newRow("OverrideIntent") << Decision::ReturnSelf << Cause::MiddleClick << Effect::LoadInSelf;
QTest::newRow("AcceptPopup") << Decision::ReturnOther << Cause::TargetBlank << Effect::LoadInOther;
@@ -3535,7 +3580,10 @@ void tst_QWebEnginePage::openLinkInNewPage()
switch (effect) {
case Effect::Blocked:
- // Nothing to test
+ // Test nothing new loaded
+ QTest::qWait(500);
+ QCOMPARE(page1.spy.count(), 0);
+ QCOMPARE(page2.spy.count(), 0);
break;
case Effect::LoadInSelf:
QTRY_COMPARE(page1.spy.count(), 1);
@@ -4028,16 +4076,16 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
// Ensure pages are initialized
inspectedPage.load(QStringLiteral("about:blank"));
devToolsPage.load(QStringLiteral("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(inspectedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(inspectedSpy.count(), 1, 90000);
QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// Open DevTools with Frozen inspectedPage
inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
inspectedPage.setDevToolsPage(&devToolsPage);
QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
inspectedPage.setDevToolsPage(nullptr);
@@ -4045,7 +4093,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
inspectedPage.setDevToolsPage(&devToolsPage);
QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
QTRY_COMPARE(inspectedSpy.count(), 1);
QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
@@ -4055,7 +4103,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
devToolsPage.setInspectedPage(&inspectedPage);
QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
devToolsPage.setInspectedPage(nullptr);
@@ -4063,8 +4111,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
devToolsPage.setInspectedPage(&inspectedPage);
QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 2);
- QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(false));
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// keep DevTools open
@@ -4664,7 +4711,10 @@ void tst_QWebEnginePage::audioMuted()
void tst_QWebEnginePage::closeContents()
{
TestPage page;
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QSignalSpy windowCreatedSpy(&page, &TestPage::windowCreated);
+ page.setUrl(QUrl("about:blank"));
+ QTRY_COMPARE(spyFinished.count(), 1);
page.runJavaScript("var dialog = window.open('', '', 'width=100, height=100');");
QTRY_COMPARE(windowCreatedSpy.count(), 1);
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index 013a307de..3480341e8 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -14,6 +14,7 @@
<file>resources/user.css</file>
<file>resources/image.png</file>
<file>resources/pasteimage.html</file>
+ <file>resources/redirect.html</file>
<file>resources/reload.html</file>
<file>resources/style.css</file>
<file>resources/test1.html</file>
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index f4c0484eb..1b0f95064 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -514,7 +514,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerStreaming()
view.setPage(new QWebEnginePage(&profile, &view));
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
view.load(QUrl(QStringLiteral("stream://whatever")));
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QByteArray result;
result.append(1000, 'c');
QCOMPARE(toPlainTextSync(view.page()), QString::fromLatin1(result));
@@ -575,7 +575,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders()
QWebEnginePage page(&profile);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl(QStringLiteral("myscheme://whatever")));
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
}
void tst_QWebEngineProfile::urlSchemeHandlerInstallation()
@@ -707,7 +707,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerXhrStatus()
profile.installUrlSchemeHandler("aviancarrier", &handler);
page.setWebChannel(&channel);
page.load(QUrl("aviancarrier:/"));
- QTRY_VERIFY(host.isReady());
+ QTRY_VERIFY_WITH_TIMEOUT(host.isReady(), 30000);
host.load(QUrl("aviancarrier:/ok"));
host.load(QUrl("aviancarrier:/redirect"));
host.load(QUrl("aviancarrier:/fail"));
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index 32384aec2..a690d516e 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -40,6 +40,8 @@ static bool verifyOrder(QStringList orderList)
"Deferred"
};
+ if (orderList.size() != 5)
+ return false;
if (orderList.at(4) == "load (timeout)") {
if (orderList.at(3) != "Deferred")
return false;
diff --git a/tests/auto/widgets/qwebenginesettings/BLACKLIST b/tests/auto/widgets/qwebenginesettings/BLACKLIST
new file mode 100644
index 000000000..d4a35a76a
--- /dev/null
+++ b/tests/auto/widgets/qwebenginesettings/BLACKLIST
@@ -0,0 +1,2 @@
+[javascriptClipboard]
+ubuntu-20.04
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index 266f08886..592b47c01 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -1,8 +1,14 @@
[microFocusCoordinates]
osx
-[textSelectionOutOfInputField]
+[visibilityState3]
+windows
+
+[horizontalScrollbarTest]
+osx
+
+[mixLangLocale:eu_ES]
*
-[visibilityState3]
+[navigateOnDrop:file]
windows
diff --git a/tests/auto/widgets/qwebengineview/resources/dummy.html b/tests/auto/widgets/qwebengineview/resources/dummy.html
new file mode 100644
index 000000000..9075f27c3
--- /dev/null
+++ b/tests/auto/widgets/qwebengineview/resources/dummy.html
@@ -0,0 +1,6 @@
+<html><head>
+<title>Dummy simple page without real content</title>
+<link rel='icon' href='resources/image2.png'/>
+</head><body>
+<a>This is test content</a>
+</body></html>
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 5e16361c5..b56053fd2 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -25,7 +25,6 @@
#include <private/qinputmethod_p.h>
#include <qpainter.h>
#include <qpagelayout.h>
-#include <qpa/qplatforminputcontext.h>
#include <qwebengineview.h>
#include <qwebenginepage.h>
#include <qwebenginesettings.h>
@@ -39,9 +38,11 @@
#include <QLineEdit>
#include <QHBoxLayout>
#include <QMenu>
+#include <QMimeData>
#include <QQuickItem>
#include <QQuickWidget>
#include <QtWebEngineCore/qwebenginehttprequest.h>
+#include <QScopeGuard>
#include <QTcpServer>
#include <QTcpSocket>
#include <QStyle>
@@ -60,44 +61,6 @@ do { \
QCOMPARE((__expr), __expected); \
} while (0)
-static QTouchDevice* s_touchDevice = nullptr;
-
-static QPoint elementCenter(QWebEnginePage *page, const QString &id)
-{
- const QString jsCode(
- "(function(){"
- " var elem = document.getElementById('" + id + "');"
- " var rect = elem.getBoundingClientRect();"
- " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
- "})()");
- QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList();
-
- if (rectList.count() != 2) {
- qWarning("elementCenter failed.");
- return QPoint();
- }
-
- return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
-}
-
-static QRect elementGeometry(QWebEnginePage *page, const QString &id)
-{
- const QString jsCode(
- "(function() {"
- " var elem = document.getElementById('" + id + "');"
- " var rect = elem.getBoundingClientRect();"
- " return [rect.left, rect.top, rect.right, rect.bottom];"
- "})()");
- QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList();
-
- if (coords.count() != 4) {
- qWarning("elementGeometry faield.");
- return QRect();
- }
-
- return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt());
-}
-
QT_BEGIN_NAMESPACE
namespace QTest {
int Q_TESTLIB_EXPORT defaultMouseDelay();
@@ -162,14 +125,13 @@ private Q_SLOTS:
void doNotBreakLayout();
void changeLocale();
+ void mixLangLocale_data();
+ void mixLangLocale();
void inputMethodsTextFormat_data();
void inputMethodsTextFormat();
void keyboardEvents();
void keyboardFocusAfterPopup();
void mouseClick();
- void touchTap();
- void touchTapAndHold();
- void touchTapAndHoldCancelled();
void postData();
void inputFieldOverridesShortcuts();
@@ -202,6 +164,7 @@ private Q_SLOTS:
void jsKeyboardEvent_data();
void jsKeyboardEvent();
void deletePage();
+ void autoDeleteOnExternalPageDelete();
void closeOpenerTab();
void switchPage();
void setPageDeletesImplicitPage();
@@ -210,13 +173,15 @@ private Q_SLOTS:
void setPagePreservesExplicitPage();
void setViewPreservesExplicitPage();
void closeDiscardsPage();
+ void loadAfterRendererCrashed();
+ void navigateOnDrop_data();
+ void navigateOnDrop();
};
// This will be called before the first test function is executed.
// It is only called once.
void tst_QWebEngineView::initTestCase()
{
- s_touchDevice = QTest::createTouchDevice();
}
// This will be called after the last test function is executed.
@@ -1213,7 +1178,11 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
+#else
+ errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
+#endif
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
QLocale::setDefault(QLocale("en"));
@@ -1223,7 +1192,11 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewEN.page()).isEmpty());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
+#else
+ errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
+#endif
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached"));
// Reset error page
@@ -1236,10 +1209,57 @@ void tst_QWebEngineView::changeLocale()
QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
+#else
+ errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
+#endif
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
}
+void tst_QWebEngineView::mixLangLocale_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QByteArray>("formattedNumber");
+ QTest::newRow("en_DK") << "en-DK" << QByteArray("1.234.567.890");
+ QTest::newRow("de") << "de" << QByteArray("1.234.567.890");
+ QTest::newRow("de_CH") << "de-CH" << QByteArray("1’234’567’890");
+ QTest::newRow("eu_ES") << "eu-ES" << QByteArray("1.234.567.890");
+ QTest::newRow("hu_HU") << "hu-HU" << QByteArray("1\xC2\xA0""234\xC2\xA0""567\xC2\xA0""890"); // no-break spaces
+}
+
+void tst_QWebEngineView::mixLangLocale()
+{
+ QFETCH(QString, locale);
+ QFETCH(QByteArray, formattedNumber);
+
+ QLocale::setDefault(locale);
+
+ QWebEngineView view;
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+
+ bool terminated = false;
+ auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; });
+
+ view.load(QUrl("qrc:///resources/dummy.html"));
+ QTRY_VERIFY(terminated || loadSpy.count() == 1);
+
+ QVERIFY2(!terminated,
+ qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count())));
+ QVERIFY(loadSpy.first().first().toBool());
+
+ QString content = toPlainTextSync(view.page());
+ QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content));
+
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "navigator.language").toString(), QLocale().bcp47Name());
+
+ if (locale == "eu-ES")
+ QEXPECT_FAIL("", "Basque number formatting is somehow dependent on environment", Continue);
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "Number(1234567890).toLocaleString()").toByteArray(), formattedNumber);
+
+ QLocale::setDefault(QLocale("en"));
+}
+
void tst_QWebEngineView::inputMethodsTextFormat_data()
{
QTest::addColumn<QString>("string");
@@ -1283,6 +1303,7 @@ void tst_QWebEngineView::inputMethodsTextFormat()
evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()");
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QFETCH(QString, string);
QFETCH(int, start);
@@ -1520,172 +1541,6 @@ void tst_QWebEngineView::mouseClick()
QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty());
}
-void tst_QWebEngineView::touchTap()
-{
-#if defined(Q_OS_MACOS)
- QSKIP("Synthetic touch events are not supported on macOS");
-#endif
-
- QWebEngineView view;
- view.show();
- view.resize(200, 200);
- QVERIFY(QTest::qWaitForWindowExposed(&view));
-
- QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished);
-
- view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
- view.setHtml("<html><body>"
- "<p id='text' style='width: 150px;'>The Qt Company</p>"
- "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
- "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
- "</body></html>");
- QVERIFY(loadFinishedSpy.wait());
- QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
-
- auto singleTap = [](QWidget* target, const QPoint& tapCoords) -> void {
- QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
- QTest::touchEvent(target, s_touchDevice).stationary(1);
- QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target);
- };
-
- // Single tap on text doesn't trigger a selection
- singleTap(view.focusProxy(), elementCenter(view.page(), "text"));
- QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
- QTRY_VERIFY(!view.hasSelection());
-
- // Single tap inside the input field focuses it without selecting the text
- singleTap(view.focusProxy(), elementCenter(view.page(), "input"));
- QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
- QTRY_VERIFY(!view.hasSelection());
-
- // Single tap on the div clears the input field focus
- singleTap(view.focusProxy(), elementCenter(view.page(), "notext"));
- QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
-
- // Double tap on text still doesn't trigger a selection
- singleTap(view.focusProxy(), elementCenter(view.page(), "text"));
- singleTap(view.focusProxy(), elementCenter(view.page(), "text"));
- QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
- QTRY_VERIFY(!view.hasSelection());
-
- // Double tap inside the input field focuses it and selects the word under it
- singleTap(view.focusProxy(), elementCenter(view.page(), "input"));
- singleTap(view.focusProxy(), elementCenter(view.page(), "input"));
- QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
- QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2"));
-
- // Double tap outside the input field behaves like a single tap: clears its focus and selection
- singleTap(view.focusProxy(), elementCenter(view.page(), "notext"));
- singleTap(view.focusProxy(), elementCenter(view.page(), "notext"));
- QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
- QTRY_VERIFY(!view.hasSelection());
-}
-
-void tst_QWebEngineView::touchTapAndHold()
-{
-#if defined(Q_OS_MACOS)
- QSKIP("Synthetic touch events are not supported on macOS");
-#endif
-
- QWebEngineView view;
- view.show();
- view.resize(200, 200);
- QVERIFY(QTest::qWaitForWindowExposed(&view));
-
- QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished);
-
- view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
- view.setHtml("<html><body>"
- "<p id='text' style='width: 150px;'>The Qt Company</p>"
- "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
- "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
- "</body></html>");
- QVERIFY(loadFinishedSpy.wait());
- QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
-
- auto tapAndHold = [](QWidget* target, const QPoint& tapCoords) -> void {
- QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
- QTest::touchEvent(target, s_touchDevice).stationary(1);
- QTest::qWait(1000);
- QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target);
- };
-
- // Tap-and-hold on text selects the word under it
- tapAndHold(view.focusProxy(), elementCenter(view.page(), "text"));
- QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
- QTRY_COMPARE(view.selectedText(), QStringLiteral("Company"));
-
- // Tap-and-hold inside the input field focuses it and selects the word under it
- tapAndHold(view.focusProxy(), elementCenter(view.page(), "input"));
- QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
- QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2"));
-
- // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently
- // and other non-desktop platforms like Android may not even support context menus at all
-#if defined(Q_OS_WIN)
- // Tap-and-hold clears the text selection and shows the page's context menu
- QVERIFY(QApplication::activePopupWidget() == nullptr);
- tapAndHold(view.focusProxy(), elementCenter(view.page(), "notext"));
- QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
- QTRY_VERIFY(!view.hasSelection());
- QTRY_VERIFY(QApplication::activePopupWidget() != nullptr);
-
- QApplication::activePopupWidget()->close();
- QVERIFY(QApplication::activePopupWidget() == nullptr);
-#endif
-}
-
-void tst_QWebEngineView::touchTapAndHoldCancelled()
-{
-#if defined(Q_OS_MACOS)
- QSKIP("Synthetic touch events are not supported on macOS");
-#endif
-
- QWebEngineView view;
- view.show();
- view.resize(200, 200);
- QVERIFY(QTest::qWaitForWindowExposed(&view));
-
- QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished);
-
- view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
- view.setHtml("<html><body>"
- "<p id='text' style='width: 150px;'>The Qt Company</p>"
- "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
- "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
- "</body></html>");
- QVERIFY(loadFinishedSpy.wait());
- QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
-
- auto cancelledTapAndHold = [](QWidget* target, const QPoint& tapCoords) -> void {
- QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
- QTest::touchEvent(target, s_touchDevice).stationary(1);
- QTest::qWait(1000);
- QWindowSystemInterface::handleTouchCancelEvent(target->windowHandle(), s_touchDevice);
- };
-
- // A cancelled tap-and-hold should cancel text selection, but currently doesn't
- cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "text"));
- QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on text", Continue);
- QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100);
-
- // A cancelled tap-and-hold should cancel input field focusing and selection, but currently doesn't
- cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "input"));
- QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on input field", Continue);
- QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty(), 100);
- QEXPECT_FAIL("", "Incorrect Chromium focus behavior when cancelling tap-and-hold on input field", Continue);
- QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100);
-
- // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently
- // and other non-desktop platforms like Android may not even support context menus at all
-#if defined(Q_OS_WIN)
- // A cancelled tap-and-hold cancels the context menu
- QVERIFY(QApplication::activePopupWidget() == nullptr);
- cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "notext"));
- QVERIFY(QApplication::activePopupWidget() == nullptr);
-#endif
-}
-
void tst_QWebEngineView::postData()
{
QMap<QString, QString> postData;
@@ -1709,7 +1564,11 @@ void tst_QWebEngineView::postData()
QStringList lines = QString::fromLocal8Bit(rawData).split("\r\n");
// examine request
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
QStringList request = lines[0].split(" ", Qt::SkipEmptyParts);
+#else
+ QStringList request = lines[0].split(" ", QString::SkipEmptyParts);
+#endif
bool requestOk = request.length() > 2
&& request[2].toUpper().startsWith("HTTP/")
&& request[0].toUpper() == "POST"
@@ -2051,6 +1910,7 @@ void tst_QWebEngineView::inputContextQueryInput()
" <input type='text' id='input1' value='' size='50'/>"
"</body></html>");
QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QCOMPARE(testContext.infos.count(), 0);
// Set focus on an input field.
@@ -2202,6 +2062,7 @@ void tst_QWebEngineView::inputMethods()
" <input type='text' id='input1' style='font-family: serif' value='' maxlength='20' size='50'/>"
"</body></html>");
QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QPoint textInputCenter = elementCenter(view.page(), "input1");
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
@@ -2299,6 +2160,7 @@ void tst_QWebEngineView::textSelectionInInputField()
" <input type='text' id='input1' value='QtWebEngine' size='50'/>"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
// Tests for Selection when the Editor is NOT in Composition mode
@@ -2372,6 +2234,7 @@ void tst_QWebEngineView::textSelectionInInputField()
void tst_QWebEngineView::textSelectionOutOfInputField()
{
QWebEngineView view;
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
view.resize(640, 480);
view.show();
@@ -2381,6 +2244,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
" This is a text"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QCOMPARE(selectionChangedSpy.count(), 0);
QVERIFY(!view.hasSelection());
@@ -2429,6 +2293,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
" <input type='text' id='input1' value='QtWebEngine' size='50'/>"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QCOMPARE(selectionChangedSpy.count(), 0);
QVERIFY(!view.hasSelection());
@@ -2508,6 +2373,7 @@ void tst_QWebEngineView::emptyInputMethodEvent()
" <input type='text' id='input1' value='QtWebEngine'/>"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
QTRY_COMPARE(selectionChangedSpy.count(), 1);
@@ -2556,6 +2422,7 @@ void tst_QWebEngineView::imeComposition()
" <input type='text' id='input1' value='QtWebEngine inputMethod'/>"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
QTRY_COMPARE(selectionChangedSpy.count(), 1);
@@ -2773,6 +2640,7 @@ void tst_QWebEngineView::newlineInTextarea()
" <textarea rows='5' cols='1' id='input1'></textarea>"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
@@ -2897,6 +2765,7 @@ void tst_QWebEngineView::imeJSInputEvents()
" <pre id='log'></pre>"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
evaluateJavaScriptSync(view.page(), "document.getElementById('input').focus()");
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
@@ -3019,6 +2888,7 @@ void tst_QWebEngineView::imeCompositionQueryEvent()
" <input type='text' id='input1' />"
"</body></html>");
QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()");
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
@@ -3260,46 +3130,50 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::newRow("accessibility") << QUrl("chrome://accessibility") << true;
QTest::newRow("appcache-internals") << QUrl("chrome://appcache-internals") << true;
QTest::newRow("apps") << QUrl("chrome://apps") << false;
+ QTest::newRow("autofill-internals") << QUrl("chrome://autofill-internals") << false;
QTest::newRow("blob-internals") << QUrl("chrome://blob-internals") << true;
QTest::newRow("bluetooth-internals") << QUrl("chrome://bluetooth-internals") << false;
QTest::newRow("bookmarks") << QUrl("chrome://bookmarks") << false;
- QTest::newRow("cache") << QUrl("chrome://cache") << false;
- QTest::newRow("chrome") << QUrl("chrome://chrome") << false;
QTest::newRow("chrome-urls") << QUrl("chrome://chrome-urls") << false;
QTest::newRow("components") << QUrl("chrome://components") << false;
+ QTest::newRow("conversion-internals") << QUrl("chrome://conversion-internals") << true;
QTest::newRow("crashes") << QUrl("chrome://crashes") << false;
QTest::newRow("credits") << QUrl("chrome://credits") << false;
QTest::newRow("device-log") << QUrl("chrome://device-log") << false;
QTest::newRow("devices") << QUrl("chrome://devices") << false;
QTest::newRow("dino") << QUrl("chrome://dino") << false; // It works but this is an error page
- QTest::newRow("dns") << QUrl("chrome://dns") << false;
+ QTest::newRow("discards") << QUrl("chrome://discards") << false;
+ QTest::newRow("download-internals") << QUrl("chrome://download-internals") << false;
QTest::newRow("downloads") << QUrl("chrome://downloads") << false;
QTest::newRow("extensions") << QUrl("chrome://extensions") << false;
QTest::newRow("flags") << QUrl("chrome://flags") << false;
- QTest::newRow("flash") << QUrl("chrome://flash") << false;
QTest::newRow("gcm-internals") << QUrl("chrome://gcm-internals") << false;
QTest::newRow("gpu") << QUrl("chrome://gpu") << true;
QTest::newRow("help") << QUrl("chrome://help") << false;
QTest::newRow("histograms") << QUrl("chrome://histograms") << true;
+ QTest::newRow("history") << QUrl("chrome://history") << false;
QTest::newRow("indexeddb-internals") << QUrl("chrome://indexeddb-internals") << true;
QTest::newRow("inspect") << QUrl("chrome://inspect") << false;
+ QTest::newRow("interstitials") << QUrl("chrome://interstitials") << false;
+ QTest::newRow("interventions-internals") << QUrl("chrome://interventions-internals") << false;
QTest::newRow("invalidations") << QUrl("chrome://invalidations") << false;
QTest::newRow("linux-proxy-config") << QUrl("chrome://linux-proxy-config") << false;
QTest::newRow("local-state") << QUrl("chrome://local-state") << false;
+ QTest::newRow("management") << QUrl("chrome://management") << false;
+ QTest::newRow("media-engagement") << QUrl("chrome://media-engagement") << false;
QTest::newRow("media-internals") << QUrl("chrome://media-internals") << true;
QTest::newRow("net-export") << QUrl("chrome://net-export") << false;
- QTest::newRow("net-internals") << QUrl("chrome://net-internals") << false;
+ QTest::newRow("net-internals") << QUrl("chrome://net-internals") << true;
QTest::newRow("network-error") << QUrl("chrome://network-error") << false;
QTest::newRow("network-errors") << QUrl("chrome://network-errors") << true;
- QTest::newRow("newtab") << QUrl("chrome://newtab") << false;
QTest::newRow("ntp-tiles-internals") << QUrl("chrome://ntp-tiles-internals") << false;
QTest::newRow("omnibox") << QUrl("chrome://omnibox") << false;
QTest::newRow("password-manager-internals") << QUrl("chrome://password-manager-internals") << false;
QTest::newRow("policy") << QUrl("chrome://policy") << false;
QTest::newRow("predictors") << QUrl("chrome://predictors") << false;
+ QTest::newRow("prefs-internals") << QUrl("chrome://prefs-internals") << false;
QTest::newRow("print") << QUrl("chrome://print") << false;
QTest::newRow("process-internals") << QUrl("chrome://process-internals") << true;
- QTest::newRow("profiler") << QUrl("chrome://profiler") << false;
QTest::newRow("quota-internals") << QUrl("chrome://quota-internals") << true;
QTest::newRow("safe-browsing") << QUrl("chrome://safe-browsing") << false;
#ifdef Q_OS_LINUX
@@ -3316,14 +3190,14 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::newRow("sync-internals") << QUrl("chrome://sync-internals") << false;
QTest::newRow("system") << QUrl("chrome://system") << false;
QTest::newRow("terms") << QUrl("chrome://terms") << false;
- QTest::newRow("thumbnails") << QUrl("chrome://thumbnails") << false;
- QTest::newRow("tracing") << QUrl("chrome://tracing") << false;
+ QTest::newRow("tracing") << QUrl("chrome://tracing") << true;
QTest::newRow("translate-internals") << QUrl("chrome://translate-internals") << false;
+ QTest::newRow("ukm") << QUrl("chrome://ukm") << true;
QTest::newRow("usb-internals") << QUrl("chrome://usb-internals") << false;
- QTest::newRow("user-actions") << QUrl("chrome://user-actions") << false;
+ QTest::newRow("user-actions") << QUrl("chrome://user-actions") << true;
QTest::newRow("version") << QUrl("chrome://version") << false;
QTest::newRow("webrtc-internals") << QUrl("chrome://webrtc-internals") << true;
- QTest::newRow("webrtc-logs") << QUrl("chrome://webrtc-logs") << false;
+ QTest::newRow("webrtc-logs") << QUrl("chrome://webrtc-logs") << true;
}
void tst_QWebEngineView::webUIURLs()
@@ -3440,6 +3314,26 @@ void tst_QWebEngineView::deletePage()
QTRY_VERIFY(spy.count());
}
+void tst_QWebEngineView::autoDeleteOnExternalPageDelete()
+{
+ QPointer<QWebEngineView> view = new QWebEngineView;
+ QPointer<QWebEnginePage> page = new QWebEnginePage;
+ auto sg = qScopeGuard([&] () { delete view; delete page; });
+
+ QSignalSpy spy(page, &QWebEnginePage::loadFinished);
+ view->setPage(page);
+ view->show();
+ view->resize(320, 240);
+ page->load(QUrl("about:blank"));
+ QTRY_VERIFY(spy.count());
+ QVERIFY(page->parent() != view);
+
+ auto sc = QObject::connect(page, &QWebEnginePage::destroyed, view, &QWebEngineView::deleteLater);
+ QTimer::singleShot(0, page, &QObject::deleteLater);
+ QTRY_VERIFY(!page);
+ QTRY_VERIFY(!view);
+}
+
class TestView : public QWebEngineView {
Q_OBJECT
public:
@@ -3569,5 +3463,58 @@ void tst_QWebEngineView::closeDiscardsPage()
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
}
+
+void tst_QWebEngineView::loadAfterRendererCrashed()
+{
+ QWebEngineView view;
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ bool terminated = false;
+ connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; });
+ view.load(QUrl("chrome://crash"));
+ QTRY_VERIFY_WITH_TIMEOUT(terminated, 30000);
+
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ view.load(QUrl("qrc:///resources/dummy.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVERIFY(loadSpy.first().first().toBool());
+}
+
+void tst_QWebEngineView::navigateOnDrop_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::newRow("file") << QUrl::fromLocalFile(QDir(TESTS_SOURCE_DIR).absoluteFilePath("qwebengineview/resources/dummy.html"));
+ QTest::newRow("qrc") << QUrl("qrc:///resources/dummy.html");
+}
+
+void tst_QWebEngineView::navigateOnDrop()
+{
+ QFETCH(QUrl, url);
+ struct WebEngineView : QWebEngineView {
+ QWebEngineView* createWindow(QWebEnginePage::WebWindowType /* type */) override { return this; }
+ } view;
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ QMimeData mimeData;
+ mimeData.setUrls({ url });
+
+ auto sendEvents = [&] () {
+ QDragEnterEvent dee(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(&view, &dee);
+ QDropEvent de(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(&view, &de);
+ };
+
+ sendEvents();
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVERIFY(loadSpy.first().first().toBool());
+ QCOMPARE(view.url(), url);
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
index a09be0399..a0e81e242 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc
@@ -6,5 +6,6 @@
<file>resources/scrolltest_page.html</file>
<file>resources/keyboardEvents.html</file>
<file>resources/image2.png</file>
+ <file>resources/dummy.html</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/touchinput/BLACKLIST b/tests/auto/widgets/touchinput/BLACKLIST
new file mode 100644
index 000000000..d9e06df8c
--- /dev/null
+++ b/tests/auto/widgets/touchinput/BLACKLIST
@@ -0,0 +1,2 @@
+[touchTap]
+sles-15.4 # QTBUG-106334
diff --git a/tests/auto/quick/qquickwebengineprofile/qquickwebengineprofile.pro b/tests/auto/widgets/touchinput/touchinput.pro
index e99c7f493..d91c0074b 100644
--- a/tests/auto/quick/qquickwebengineprofile/qquickwebengineprofile.pro
+++ b/tests/auto/widgets/touchinput/touchinput.pro
@@ -1 +1,2 @@
include(../tests.pri)
+QT *= gui-private
diff --git a/tests/auto/widgets/touchinput/tst_touchinput.cpp b/tests/auto/widgets/touchinput/tst_touchinput.cpp
new file mode 100644
index 000000000..3c7d8ccbb
--- /dev/null
+++ b/tests/auto/widgets/touchinput/tst_touchinput.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 "../util.h"
+
+#include <QtGui/qpa/qwindowsysteminterface.h>
+#include <QSignalSpy>
+#include <QTest>
+#include <QTouchDevice>
+#include <QWebEngineSettings>
+#include <QWebEngineView>
+
+static QTouchDevice* s_touchDevice = nullptr;
+
+class TouchInputTest : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase();
+ void init();
+ void cleanup();
+
+private Q_SLOTS:
+ void touchTap();
+ void touchTapAndHold();
+ void touchTapAndHoldCancelled();
+ void scrolling();
+ void pinchZoom_data();
+ void pinchZoom();
+ void complexSequence();
+
+private:
+ QWebEngineView view;
+ QSignalSpy loadSpy { &view, &QWebEngineView::loadFinished };
+ QPoint notextCenter, textCenter, inputCenter;
+
+ QString activeElement() { return evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(); }
+
+ void gestureScroll(bool down) {
+ auto target = view.focusProxy();
+ QPoint p(target->width() / 2, target->height() / 4 * (down ? 3 : 1));
+
+ QTest::touchEvent(target, s_touchDevice).press(42, p, target);
+
+ QSignalSpy spy(view.page(), &QWebEnginePage::scrollPositionChanged);
+ for (int i = 0; i < 3; ++i) {
+ down ? p -= QPoint(5, 15) : p += QPoint(5, 15);
+ QTest::qWait(100); // too fast and events are recognized as fling gesture
+ QTest::touchEvent(target, s_touchDevice).move(42, p, target);
+ spy.wait();
+ }
+
+ QTest::touchEvent(target, s_touchDevice).release(42, p, target);
+ }
+
+ void gesturePinch(bool zoomIn, bool tapOneByOne = false) {
+ auto target = view.focusProxy();
+ QPoint p(target->width() / 2, target->height() / 2);
+ auto t1 = p - QPoint(zoomIn ? 50 : 150, 10), t2 = p + QPoint(zoomIn ? 50 : 150, 10);
+
+ if (tapOneByOne) {
+ QTest::touchEvent(target, s_touchDevice).press(42, t1, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(42).press(24, t2, target);
+ } else {
+ QTest::touchEvent(target, s_touchDevice).press(42, t1, target).press(24, t2, target);
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ if (zoomIn) {
+ t1 -= QPoint(25, 5);
+ t2 += QPoint(25, 5);
+ } else {
+ t1 += QPoint(35, 5);
+ t2 -= QPoint(35, 5);
+ }
+ QTest::qWait(100); // too fast and events are recognized as fling gesture
+ QTest::touchEvent(target, s_touchDevice).move(24, t1, target).move(42, t2, target);
+ }
+
+ if (tapOneByOne) {
+ QTest::touchEvent(target, s_touchDevice).stationary(42).release(24, t2, target);
+ QTest::touchEvent(target, s_touchDevice).release(42, t1, target);
+ } else {
+ QTest::touchEvent(target, s_touchDevice).release(42, t1, target).release(24, t2, target);
+ }
+ }
+
+ int getScrollPosition(int *position = nullptr) {
+ int p = evaluateJavaScriptSync(view.page(), "window.scrollY").toInt();
+ return position ? (*position = p) : p;
+ }
+
+ int pageScrollPosition() {
+ // this one is updated later in page in asynchronous way
+ return qRound(view.page()->scrollPosition().y());
+ }
+
+ double getScaleFactor(double *scale = nullptr) {
+ double s = evaluateJavaScriptSync(view.page(), "window.visualViewport.scale").toDouble();
+ return scale ? (*scale = s) : s;
+ }
+};
+
+void TouchInputTest::initTestCase()
+{
+ s_touchDevice = QTest::createTouchDevice();
+
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
+
+ view.show(); view.resize(480, 320);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ view.setHtml("<html><head><style>.rect { min-width: 240px; min-height: 120px; }</style></head><body>"
+ "<p id='text' style='width: 150px;'>The Qt Company</p>"
+ "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
+ "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
+ "<table style='width: 100%; padding: 15px; text-align: center;'>"
+ "<tr><td>BEFORE</td><td><div class='rect' style='background-color: #00f;'></div></td><td>AFTER</td></tr>"
+ "<tr><td>BEFORE</td><td><div class='rect' style='background-color: #0f0;'></div></td><td>AFTER</td></tr>"
+ "<tr><td>BEFORE</td><td><div class='rect' style='background-color: #f00;'></div></td><td>AFTER</td></tr></table>"
+ "</body></html>");
+ QVERIFY(loadSpy.wait() && loadSpy.first().first().toBool());
+
+ notextCenter = elementCenter(view.page(), "notext");
+ textCenter = elementCenter(view.page(), "text");
+ inputCenter = elementCenter(view.page(), "input");
+}
+
+void TouchInputTest::init()
+{
+ QCOMPARE(activeElement(), QString());
+}
+
+void TouchInputTest::cleanup()
+{
+ evaluateJavaScriptSync(view.page(), "if (document.activeElement) document.activeElement.blur()");
+ evaluateJavaScriptSync(view.page(), "window.scrollTo(0, 0)");
+ QTRY_COMPARE(getScrollPosition(), 0);
+ QTRY_COMPARE(pageScrollPosition(), 0);
+}
+
+void TouchInputTest::touchTap()
+{
+ auto singleTap = [target = view.focusProxy()] (const QPoint& tapCoords) -> void {
+ QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(1);
+ QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target);
+ };
+
+ // Single tap on text doesn't trigger a selection
+ singleTap(textCenter);
+ QTRY_COMPARE(activeElement(), QString());
+ QTRY_VERIFY(!view.hasSelection());
+
+ // Single tap inside the input field focuses it without selecting the text
+ singleTap(inputCenter);
+ QTRY_COMPARE(activeElement(), QStringLiteral("input"));
+ QTRY_VERIFY(!view.hasSelection());
+
+ // Single tap on the div clears the input field focus
+ singleTap(notextCenter);
+ QTRY_COMPARE(activeElement(), QString());
+
+ // Double tap on text still doesn't trigger a selection
+ singleTap(textCenter);
+ singleTap(textCenter);
+ QTRY_COMPARE(activeElement(), QString());
+ QTRY_VERIFY(!view.hasSelection());
+
+ // Double tap inside the input field focuses it and selects the word under it
+ singleTap(inputCenter);
+ singleTap(inputCenter);
+ QTRY_COMPARE(activeElement(), QStringLiteral("input"));
+ QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2"));
+
+ // Double tap outside the input field behaves like a single tap: clears its focus and selection
+ singleTap(notextCenter);
+ singleTap(notextCenter);
+ QTRY_COMPARE(activeElement(), QString());
+ QTRY_VERIFY(!view.hasSelection());
+}
+
+void TouchInputTest::touchTapAndHold()
+{
+ auto tapAndHold = [target = view.focusProxy()] (const QPoint& tapCoords) -> void {
+ QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(1);
+ QTest::qWait(1000);
+ QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target);
+ };
+
+ // Tap-and-hold on text selects the word under it
+ tapAndHold(textCenter);
+ QTRY_COMPARE(activeElement(), QString());
+ QTRY_COMPARE(view.selectedText(), QStringLiteral("Company"));
+
+ // Tap-and-hold inside the input field focuses it and selects the word under it
+ tapAndHold(inputCenter);
+ QTRY_COMPARE(activeElement(), QStringLiteral("input"));
+ QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2"));
+
+ // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently
+ // and other non-desktop platforms like Android may not even support context menus at all
+#if defined(Q_OS_WIN)
+ // Tap-and-hold clears the text selection and shows the page's context menu
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+ tapAndHold(notextCenter);
+ QTRY_COMPARE(activeElement(), QString());
+ QTRY_VERIFY(!view.hasSelection());
+ QTRY_VERIFY(QApplication::activePopupWidget() != nullptr);
+
+ QApplication::activePopupWidget()->close();
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+#endif
+}
+
+void TouchInputTest::touchTapAndHoldCancelled()
+{
+ auto cancelledTapAndHold = [target = view.focusProxy()] (const QPoint& tapCoords) -> void {
+ QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(1);
+ QTest::qWait(1000);
+ QWindowSystemInterface::handleTouchCancelEvent(target->windowHandle(), s_touchDevice);
+ };
+
+ // A cancelled tap-and-hold should cancel text selection, but currently doesn't
+ cancelledTapAndHold(textCenter);
+ QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on text", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100);
+
+ // A cancelled tap-and-hold should cancel input field focusing and selection, but currently doesn't
+ cancelledTapAndHold(inputCenter);
+ QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on input field", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty(), 100);
+ QEXPECT_FAIL("", "Incorrect Chromium focus behavior when cancelling tap-and-hold on input field", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100);
+
+ // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently
+ // and other non-desktop platforms like Android may not even support context menus at all
+#if defined(Q_OS_WIN)
+ // A cancelled tap-and-hold cancels the context menu
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+ cancelledTapAndHold(notextCenter);
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+#endif
+}
+
+void TouchInputTest::scrolling()
+{
+ int p = getScrollPosition();
+ QCOMPARE(p, 0);
+
+ // scroll a bit down...
+ for (int i = 0; i < 3; ++i) {
+ gestureScroll(/* down = */true);
+ int positionBefore = p;
+ QTRY_VERIFY2(getScrollPosition(&p) > positionBefore, qPrintable(QString("i: %1, position: %2 -> %3").arg(i).arg(positionBefore).arg(p)));
+ }
+
+ // ... and then scroll page again but in opposite direction
+ for (int i = 0; i < 3; ++i) {
+ gestureScroll(/* down = */false);
+ int positionBefore = p;
+ QTRY_VERIFY2(getScrollPosition(&p) < positionBefore, qPrintable(QString("i: %1, position: %2 -> %3").arg(i).arg(positionBefore).arg(p)));
+ }
+
+ QTRY_COMPARE(getScrollPosition(), 0);
+}
+
+void TouchInputTest::pinchZoom_data()
+{
+ QTest::addColumn<bool>("tapOneByOne");
+ QTest::addRow("sequential") << true;
+ QTest::addRow("simultaneous") << false;
+}
+
+void TouchInputTest::pinchZoom()
+{
+ QFETCH(bool, tapOneByOne);
+ double scale = getScaleFactor();
+ QCOMPARE(scale, 1.0);
+
+ for (int i = 0; i < 3; ++i) {
+ gesturePinch(/* zoomIn = */true, tapOneByOne);
+ QTRY_VERIFY2(getScaleFactor(&scale) > 1.5, qPrintable(QString("i: %1, scale: %2").arg(i).arg(scale)));
+ gesturePinch(/* zoomIn = */false, tapOneByOne);
+ QTRY_COMPARE(getScaleFactor(&scale), 1.0);
+ }
+}
+
+void TouchInputTest::complexSequence()
+{
+ auto t = view.focusProxy();
+ QPoint pc(view.width() / 2, view.height() / 2), p1 = pc - QPoint(50, 25), p2 = pc + QPoint(50, 25);
+
+ for (int i = 0; i < 4; ++i) {
+ QTest::touchEvent(t, s_touchDevice).press(42, p1, t); QTest::qWait(50);
+ QTest::touchEvent(t, s_touchDevice).stationary(42).press(24, p2, t); QTest::qWait(50);
+ QTest::touchEvent(t, s_touchDevice).release(42, p1, t).release(24, p2, t);
+
+ // for additional variablity add zooming in on even steps and zooming out on odd steps
+ // MEMO scroll position will always be 0 while viewport scale factor > 1.0, so do zoom in after scroll
+ bool zoomIn = i % 2 == 0;
+
+ if (!zoomIn) {
+ gesturePinch(false);
+ QTRY_COMPARE(getScaleFactor(), 1.0);
+ }
+
+ int p = getScrollPosition(), positionBefore = p;
+ gestureScroll(true);
+ QTRY_VERIFY2_WITH_TIMEOUT(getScrollPosition(&p) > positionBefore, qPrintable(QString("i: %1, position: %2 -> %3").arg(i).arg(positionBefore).arg(p)), 1000);
+
+ if (zoomIn) {
+ double s = getScaleFactor(), scaleBefore = s;
+ gesturePinch(true);
+ QTRY_VERIFY2(getScaleFactor(&s) > scaleBefore, qPrintable(QString("i: %1, scale: %2").arg(i).arg(s)));
+ }
+ }
+}
+
+QTEST_MAIN(TouchInputTest)
+#include "tst_touchinput.moc"
diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h
index af0b9bf6f..461baf9ac 100644
--- a/tests/auto/widgets/util.h
+++ b/tests/auto/widgets/util.h
@@ -184,6 +184,43 @@ static inline bool loadSync(QWebEngineView *view, const QUrl &url, bool ok = tru
return loadSync(view->page(), url, ok);
}
+static inline QPoint elementCenter(QWebEnginePage *page, const QString &id)
+{
+ const QString jsCode(
+ "(function(){"
+ " var elem = document.getElementById('" + id + "');"
+ " var rect = elem.getBoundingClientRect();"
+ " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
+ "})()");
+ QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList();
+
+ if (rectList.count() != 2) {
+ qWarning("elementCenter failed.");
+ return QPoint();
+ }
+
+ return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
+}
+
+static inline QRect elementGeometry(QWebEnginePage *page, const QString &id)
+{
+ const QString jsCode(
+ "(function() {"
+ " var elem = document.getElementById('" + id + "');"
+ " var rect = elem.getBoundingClientRect();"
+ " return [rect.left, rect.top, rect.right, rect.bottom];"
+ "})()");
+ QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList();
+
+ if (coords.count() != 4) {
+ qWarning("elementGeometry faield.");
+ return QRect();
+ }
+
+ return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt());
+}
+
+
#define W_QSKIP(a, b) QSKIP(a)
#define W_QTEST_MAIN(TestObject, params) \
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 6d65eecb5..d35f875c1 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -1,3 +1,5 @@
+load(functions)
+
include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
QT_FOR_CONFIG += webenginecore webenginecore-private
@@ -22,6 +24,9 @@ SUBDIRS += \
qwebenginesettings \
qwebengineview
+# Synthetic touch events are not supported on macOS
+!macos: SUBDIRS += touchinput
+
qtConfig(accessibility) {
SUBDIRS += accessibility
}
@@ -34,7 +39,7 @@ qtConfig(ssl) {
SUBDIRS += certificateerror
}
-qtConfig(webengine-spellchecker):!cross_compile {
+qtConfig(webengine-spellchecker):!cross_compile:!isUniversal() {
!qtConfig(webengine-native-spellchecker) {
SUBDIRS += spellchecking
} else {
diff --git a/tools/scripts/git_submodule.py b/tools/scripts/git_submodule.py
index edaed1ed2..43a652b11 100644
--- a/tools/scripts/git_submodule.py
+++ b/tools/scripts/git_submodule.py
@@ -47,6 +47,7 @@ class DEPSParser:
def __init__(self):
self.global_scope = {
'Var': lambda var_name: '{%s}' % var_name,
+ 'Str': str,
'deps_os': {},
}
self.local_scope = {}
@@ -229,8 +230,8 @@ class Submodule:
# supermodule.
if self.topmost_supermodule_path_prefix:
if not os.path.isdir(self.path):
- print '-- skipping ' + self.path + ' as dir has been stripped. --'
- return
+ print '-- creating ' + self.path + ' as dir is missing. --'
+ os.makedirs(self.path)
os.chdir(self.topmost_supermodule_path_prefix)
if os.path.isdir(self.path):
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 57906378a..b2c1276af 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -66,39 +66,40 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('buildtools/third_party/libc++')
or file_path.startswith('buildtools/third_party/libc++abi')
or file_path.startswith('buildtools/third_party/libunwind')
- or (file_path.startswith('chrome/') and
- not file_path.startswith('chrome/VERSION') and
- not file_path.startswith('chrome/app/resources/') and
- not file_path.startswith('chrome/app/theme/') and
- not file_path.startswith('chrome/browser/chrome_notification_types.h') and
- not file_path.startswith('chrome/browser/accessibility/') and
- not file_path.startswith('chrome/browser/custom_handlers/') and
- not file_path.startswith('chrome/browser/devtools/') and
- not file_path.startswith('chrome/browser/extensions/api/') and
- not file_path.startswith('chrome/browser/media/webrtc/') and
- not file_path.startswith('chrome/browser/net/') and
- not file_path.startswith('chrome/browser/prefs/') and
- not file_path.startswith('chrome/browser/printing/') and
- not file_path.startswith('chrome/browser/renderer_host/') and
- not file_path.startswith('chrome/browser/spellchecker') and
- not file_path.startswith('chrome/browser/tab_contents/') and
- not file_path.startswith('chrome/browser/ui/webui/') and
- not (file_path.startswith('chrome/browser/resources/') and
- not '/chromeos/' in file_path and
- not '/settings/' in file_path and
- not '/mediarouter/' in file_path) and
- not (file_path.startswith('chrome/common/') and not file_path.startswith('chrome/common/extensions/docs')) and
- not file_path.startswith('chrome/renderer/') and
- not file_path.startswith('chrome/tools/convert_dict/') and
- not file_path.endswith('.grd') and
- not file_path.endswith('.grdp') and
- not file_path.endswith('chrome_version.rc.version'))
+ or (file_path.startswith('chrome/')
+ and not file_path.startswith('chrome/VERSION')
+ and not file_path.startswith('chrome/app/resources/')
+ and not file_path.startswith('chrome/app/theme/')
+ and not file_path.startswith('chrome/browser/chrome_notification_types.h')
+ and not file_path.startswith('chrome/browser/accessibility/')
+ and not file_path.startswith('chrome/browser/custom_handlers/')
+ and not file_path.startswith('chrome/browser/devtools/')
+ and not file_path.startswith('chrome/browser/extensions/api/')
+ and not file_path.startswith('chrome/browser/media/webrtc/')
+ and not file_path.startswith('chrome/browser/net/')
+ and not file_path.startswith('chrome/browser/prefs/')
+ and not file_path.startswith('chrome/browser/printing/')
+ and not file_path.startswith('chrome/browser/renderer_host/')
+ and not file_path.startswith('chrome/browser/spellchecker')
+ and not file_path.startswith('chrome/browser/tab_contents/')
+ and not file_path.startswith('chrome/browser/ui/webui/')
+ and not (file_path.startswith('chrome/browser/resources/')
+ and not '/chromeos/' in file_path
+ and not '/settings/' in file_path
+ and not '/mediarouter/' in file_path)
+ and not (file_path.startswith('chrome/common/')
+ and not file_path.startswith('chrome/common/extensions/docs'))
+ and not file_path.startswith('chrome/renderer/')
+ and not file_path.startswith('chrome/tools/convert_dict/')
+ and not file_path.endswith('.grd')
+ and not file_path.endswith('.grdp')
+ and not file_path.endswith('chrome_version.rc.version'))
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/') and (
- file_path.startswith('components/chrome_apps/')
+ 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/')
@@ -107,37 +108,40 @@ def isInChromiumBlacklist(file_path):
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/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/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
- not file_path.endswith('.grd'))
+ or (file_path.startswith('content/shell')
+ and not file_path.startswith('content/shell/common')
+ and not file_path.endswith('.grd'))
or file_path.startswith('courgette')
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_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/')
+ 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/') and (
- file_path.startswith('third_party/WebKit/LayoutTests')
+ or (file_path.startswith('third_party/')
+ and (file_path.startswith('third_party/WebKit/LayoutTests')
or file_path.startswith('third_party/accessibility')
or file_path.startswith('third_party/afl')
or file_path.startswith('third_party/android_')
or file_path.startswith('third_party/angle/third_party/deqp')
or file_path.startswith('third_party/angle/third_party/glmark2')
+ or file_path.startswith('third_party/angle/third_party/VK-GL-CTS')
or file_path.startswith('third_party/angle/third_party/vulkan-validation-layers')
or file_path.startswith('third_party/apache-')
or file_path.startswith('third_party/arcode-android-sdk')
@@ -147,14 +151,16 @@ def isInChromiumBlacklist(file_path):
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/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'))
+ 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/beautifulsoup4')
+ and not file_path.startswith('third_party/catapult/third_party/html5lib-python')
+ and not file_path.startswith('third_party/catapult/third_party/polymer')
+ and not file_path.startswith('third_party/catapult/third_party/six')
+ 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')
@@ -178,8 +184,6 @@ def isInChromiumBlacklist(file_path):
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/openh264/src/res')
@@ -201,52 +205,55 @@ def isInChromiumBlacklist(file_path):
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('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 (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 '/fuzzers/' in file_path
- or '/fuzzing/' in file_path
+ or '/android/java/' in file_path
+ or ('/fuzz' in file_path
+ and ('/fuzz/' in file_path
+ or '/fuzzer/' in file_path
+ or '/fuzzers/' 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('test_hook.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 'core/mojo/test/' in file_path and
- not file_path.startswith('extensions/browser/') and
- (not file_path.startswith('base/test/') or
- file_path.startswith('base/test/android/') or
- file_path.startswith('base/test/data/')
- file_path.startswith('base/test/ios/') or
- file_path.startswith('base/test/launcher/') or
- file_path.startswith('base/test/library_loader/') or
- file_path.startswith('base/test/metrics/')))
+ 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('test_hook.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 'core/mojo/test/' in file_path
+ and not file_path.startswith('extensions/browser/')
+ and
+ (not file_path.startswith('base/test/')
+ or file_path.startswith('base/test/android/')
+ or file_path.startswith('base/test/data/')
+ or file_path.startswith('base/test/ios/')
+ or file_path.startswith('base/test/launcher/')
+ or file_path.startswith('base/test/library_loader/')
+ or file_path.startswith('base/test/metrics/')
+ )
+ )
))):
return True
return False
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index 32c8be74c..dd5470f88 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -38,8 +38,8 @@ import json
import urllib2
import git_submodule as GitSubmodule
-chromium_version = '83.0.4103.122'
-chromium_branch = '4103'
+chromium_version = '87.0.4280.144'
+chromium_branch = '4280'
ninja_version = 'v1.8.2'
json_url = 'http://omahaproxy.appspot.com/all.json'
@@ -89,8 +89,6 @@ def readSubmodules():
submodule_dict[sub.path] = sub
extradeps_dirs = parser.get_recursedeps()
- # Add buildtools submodules
- extradeps_dirs.append('buildtools')
for extradeps_dir in extradeps_dirs:
if extradeps_dir.startswith('src/'):