diff --git a/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp b/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp index 7e14b2c366..333f7e58b3 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp +++ b/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp @@ -186,7 +186,11 @@ initialize_web_extensions (WebKitWebContext *context) const gchar *local_path = gst_wpe_get_devenv_extension_path (); const gchar *path = g_file_test (local_path, G_FILE_TEST_IS_DIR) ? local_path : G_STRINGIFY (WPE_EXTENSION_INSTALL_DIR); GST_INFO ("Loading WebExtension from %s", path); +#if USE_WPE2 + webkit_web_context_set_web_process_extensions_directory (context, path); +#else webkit_web_context_set_web_extensions_directory (context, path); +#endif } static void @@ -356,10 +360,14 @@ WPEView* WPEContextThread::createWPEView(GstWpeVideoSrc* src, GstGLContext* cont WPEView* view = nullptr; dispatch([&]() mutable { if (!glib.web_context) { +#if USE_WPE2 + glib.web_context = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr)); +#else auto *manager = webkit_website_data_manager_new(NULL); glib.web_context = webkit_web_context_new_with_website_data_manager(manager); g_object_unref(manager); +#endif } view = new WPEView(glib.web_context, src, context, display, width, height); }); @@ -434,7 +442,11 @@ WPEView::WPEView(WebKitWebContext* web_context, GstWpeVideoSrc* src, GstGLContex if (parent && GST_IS_WPE_SRC (parent)) { audio.init_ext_sigid = g_signal_connect (web_context, +#if USE_WPE2 + "initialize-web-process-extensions", +#else "initialize-web-extensions", +#endif G_CALLBACK (initialize_web_extensions), NULL); audio.extension_msg_sigid = g_signal_connect (web_context, @@ -726,22 +738,32 @@ void WPEView::loadUri(const gchar* uri) static void s_runJavascriptFinished(GObject* object, GAsyncResult* result, gpointer user_data) { - WebKitJavascriptResult* js_result; - GError* error = NULL; + GError *error = NULL; +#if USE_WPE2 + g_autoptr(JSCValue) js_result = webkit_web_view_evaluate_javascript_finish( +#else + g_autoptr(WebKitJavascriptResult) js_result = webkit_web_view_run_javascript_finish( +#endif + WEBKIT_WEB_VIEW(object), result, &error); - js_result = webkit_web_view_run_javascript_finish(WEBKIT_WEB_VIEW(object), result, &error); - if (!js_result) { + // TODO: Pass result back to signal call site using a GstPromise? + (void) js_result; + + if (error) { GST_WARNING("Error running javascript: %s", error->message); g_error_free(error); - return; } - webkit_javascript_result_unref(js_result); } void WPEView::runJavascript(const char* script) { s_view->dispatch([&]() { +#if USE_WPE2 + webkit_web_view_evaluate_javascript(webkit.view, script, -1, nullptr, nullptr, nullptr, + s_runJavascriptFinished, nullptr); +#else webkit_web_view_run_javascript(webkit.view, script, nullptr, s_runJavascriptFinished, nullptr); +#endif }); } diff --git a/subprojects/gst-plugins-bad/ext/wpe/meson.build b/subprojects/gst-plugins-bad/ext/wpe/meson.build index b8f3f34dd3..811d7579c1 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/meson.build +++ b/subprojects/gst-plugins-bad/ext/wpe/meson.build @@ -6,16 +6,47 @@ if not wpe_feat.allowed() subdir_done() endif -wpe_dep = dependency('wpe-webkit-1.1', version : '>= 2.28', required : false) -if not wpe_dep.found() - wpe_dep = dependency('wpe-webkit-1.0', version : '>= 2.28', required : wpe_feat) +# Version checks copied from Cog, licensed under MIT. +# https://github.com/Igalia/cog. The difference is that for the 2.0 API we +# require version 2.40.1, the first one without strict Application ID +# requirement for the WebProcess sandbox. +wpe_target_api_version_required = { + '2.0': '>=2.40.1', + '1.1': '>=2.33.1', + '1.0': '>=2.28.0', +} + +wpe_target_api = get_option('wpe_api') +if wpe_target_api == 'auto' + foreach try_api : ['2.0', '1.1', '1.0'] + wpewebkit_dep = dependency('wpe-webkit-' + try_api, + version: wpe_target_api_version_required[try_api], + required: false) + if wpewebkit_dep.found() + wpe_target_api = try_api + break + endif + endforeach +else + wpewebkit_dep = dependency('wpe-webkit-' + wpe_target_api, + version: wpe_target_api_version_required[wpe_target_api]) endif +if wpe_target_api == 'auto' or not wpewebkit_dep.found() + subdir_done() +endif + +use_wpe2 = 0 +if wpe_target_api == '2.0' + use_wpe2 = 1 +endif +gst_wpe_c_args = ['-DUSE_WPE2=@0@'.format(use_wpe2)] + wpe_fdo_dep = dependency('wpebackend-fdo-1.0', version : '>= 1.8', required : wpe_feat) egl_dep = dependency('egl', required : wpe_feat) xkbcommon_dep = dependency('xkbcommon', version : '>= 0.8', required : wpe_feat) wl_server_dep = dependency('wayland-server', required : wpe_feat) -if not (wpe_dep.found() and wpe_fdo_dep.found() and egl_dep.found() and xkbcommon_dep.found()) +if not (wpe_fdo_dep.found() and egl_dep.found() and xkbcommon_dep.found()) subdir_done() endif @@ -26,10 +57,10 @@ wpe_extension_install_dir = get_option('prefix') / get_option('libdir') / meson. building_wpe = true gstwpe = library('gstwpe', ['WPEThreadedView.cpp', 'gstwpe.cpp', 'gstwpevideosrc.cpp', 'gstwpesrcbin.cpp'], - dependencies : [egl_dep, wpe_dep, wpe_fdo_dep, gstallocators_dep, gstaudio_dep, gstvideo_dep, + dependencies : [egl_dep, wpewebkit_dep, wpe_fdo_dep, gstallocators_dep, gstaudio_dep, gstvideo_dep, gstbase_dep, gstgl_dep, xkbcommon_dep, wl_server_dep, giounix_dep], cpp_args : gst_plugins_bad_args + ['-DHAVE_CONFIG_H=1', - '-DWPE_EXTENSION_INSTALL_DIR=' + wpe_extension_install_dir], + '-DWPE_EXTENSION_INSTALL_DIR=' + wpe_extension_install_dir] + gst_wpe_c_args, include_directories : [configinc], install : true, install_dir : plugins_install_dir) diff --git a/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.c b/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.c index 845e95f87f..6bba314f97 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.c +++ b/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.c @@ -28,17 +28,24 @@ #include #include #include -#include GST_DEBUG_CATEGORY_STATIC (wpe_extension_debug); #define GST_CAT_DEFAULT wpe_extension_debug -G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension * - extension); +#if USE_WPE2 +#define WebKitWebExtension WebKitWebProcessExtension +#define extension_initialize webkit_web_process_extension_initialize +#define extension_send_message_to_context webkit_web_process_extension_send_message_to_context +#else +#define extension_initialize webkit_web_extension_initialize +#define extension_send_message_to_context webkit_web_extension_send_message_to_context +#endif + +G_MODULE_EXPORT void extension_initialize (WebKitWebExtension * extension); static WebKitWebExtension *global_extension = NULL; - +#if !USE_WPE2 static void console_message_cb (WebKitWebPage * page, WebKitConsoleMessage * console_message, gpointer data) @@ -49,17 +56,21 @@ console_message_cb (WebKitWebPage * page, NULL); g_free (message); } +#endif static void web_page_created_callback (WebKitWebExtension * extension, WebKitWebPage * web_page, gpointer data) { + // WebKitConsoleMessage is deprecated in wpe1 and has no replacement in wpe2. +#if !USE_WPE2 g_signal_connect (web_page, "console-message-sent", G_CALLBACK (console_message_cb), NULL); +#endif } void -webkit_web_extension_initialize (WebKitWebExtension * extension) +extension_initialize (WebKitWebExtension * extension) { g_return_if_fail (!global_extension); @@ -84,6 +95,6 @@ void gst_wpe_extension_send_message (WebKitUserMessage * msg, GCancellable * cancellable, GAsyncReadyCallback cb, gpointer udata) { - webkit_web_extension_send_message_to_context (global_extension, msg, - cancellable, cb, udata); + extension_send_message_to_context (global_extension, msg, cancellable, cb, + udata); } diff --git a/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.h b/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.h index 3cd62cd295..3f5bedbdef 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.h +++ b/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/gstwpeextension.h @@ -15,7 +15,11 @@ #pragma once +#if USE_WPE2 +#include +#else #include +#endif #include #include #include diff --git a/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/meson.build b/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/meson.build index e1ef972330..232ce05573 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/meson.build +++ b/subprojects/gst-plugins-bad/ext/wpe/wpe-extension/meson.build @@ -1,7 +1,7 @@ library('gstwpeextension', ['gstwpeextension.c', 'gstwpeaudiosink.c', 'gstwpebusmsgforwarder.c'], - dependencies : [wpe_dep, gst_dep, gstbase_dep, giounix_dep], - c_args : ['-DHAVE_CONFIG_H=1'], + dependencies : [wpewebkit_dep, gst_dep, gstbase_dep, giounix_dep], + c_args : ['-DHAVE_CONFIG_H=1'] + gst_wpe_c_args, include_directories : [configinc], install : true, install_dir : wpe_extension_install_dir) diff --git a/subprojects/gst-plugins-bad/meson_options.txt b/subprojects/gst-plugins-bad/meson_options.txt index 86266be3f9..16c594b07f 100644 --- a/subprojects/gst-plugins-bad/meson_options.txt +++ b/subprojects/gst-plugins-bad/meson_options.txt @@ -185,6 +185,14 @@ option('x265', type : 'feature', value : 'auto', description : 'HEVC/H.265 video option('zbar', type : 'feature', value : 'auto', description : 'Barcode image scanner plugin using zbar library') option('zxing', type : 'feature', value : 'auto', description : 'Barcode image scanner plugin using zxing-cpp library') option('wpe', type : 'feature', value : 'auto', description : 'WPE Web browser plugin') +option( + 'wpe_api', + type: 'combo', + value: 'auto', + choices: ['auto', '1.0', '1.1', '2.0'], + description: 'WPE WebKit API to target (1.0 = soup2, 1.1/2.0 = soup3)' +) + option('magicleap', type : 'feature', value : 'auto', description : 'Magic Leap platform support') option('v4l2codecs', type : 'feature', value : 'auto', description : 'Video4Linux Stateless CODECs support') option('isac', type : 'feature', value : 'auto', description : 'iSAC plugin')