From b7381c715dfbf2c89b6face4b7f10e889cfd8e17 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Thu, 28 Nov 2019 12:06:13 +0100 Subject: [PATCH] Use the new WebKit user messages API instead of DBus It simplifies the code a lot and it's also a lot more efficient. --- embed/ephy-embed-shell.c | 396 +-------------- embed/ephy-web-process-extension-proxy.c | 354 ------------- embed/ephy-web-process-extension-proxy.h | 58 --- embed/ephy-web-view.c | 173 +++++-- embed/ephy-web-view.h | 3 - embed/meson.build | 1 - .../ephy-web-process-extension-main.c | 9 +- .../ephy-web-process-extension.c | 477 +++++++++--------- .../ephy-web-process-extension.h | 1 - .../resources/js/ephy.js | 9 +- lib/ephy-dbus-names.h | 29 -- lib/ephy-dbus-util.c | 40 -- lib/ephy-dbus-util.h | 29 -- lib/meson.build | 1 - meson.build | 2 +- 15 files changed, 407 insertions(+), 1175 deletions(-) delete mode 100644 embed/ephy-web-process-extension-proxy.c delete mode 100644 embed/ephy-web-process-extension-proxy.h delete mode 100644 lib/ephy-dbus-names.h delete mode 100644 lib/ephy-dbus-util.c delete mode 100644 lib/ephy-dbus-util.h diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c index 74e12a80d..3ee48ed65 100644 --- a/embed/ephy-embed-shell.c +++ b/embed/ephy-embed-shell.c @@ -23,7 +23,6 @@ #include "ephy-embed-shell.h" #include "ephy-about-handler.h" -#include "ephy-dbus-util.h" #include "ephy-debug.h" #include "ephy-downloads-manager.h" #include "ephy-embed-container.h" @@ -43,7 +42,6 @@ #include "ephy-uri-helpers.h" #include "ephy-view-source-handler.h" #include "ephy-web-app-utils.h" -#include "ephy-web-process-extension-proxy.h" #include #include @@ -66,8 +64,6 @@ typedef struct { EphyAboutHandler *about_handler; EphyViewSourceHandler *source_handler; char *guid; - GDBusServer *dbus_server; - GList *web_process_extensions; EphyFiltersManager *filters_manager; EphySearchEngineManager *search_engine_manager; GCancellable *cancellable; @@ -76,7 +72,6 @@ typedef struct { enum { RESTORED_WINDOW, WEB_VIEW_CREATED, - PAGE_CREATED, ALLOW_TLS_CERTIFICATE, ALLOW_UNSAFE_BROWSING, PASSWORD_FORM_FOCUSED, @@ -135,15 +130,6 @@ ephy_embed_shell_get_view_for_page_id (EphyEmbedShell *self, return NULL; } -static EphyWebProcessExtensionProxy * -ephy_embed_shell_get_extension_proxy_for_page_id (EphyEmbedShell *self, - guint64 page_id, - const char *origin) -{ - EphyWebView *view = ephy_embed_shell_get_view_for_page_id (self, page_id, origin); - return view ? ephy_web_view_get_web_process_extension_proxy (view) : NULL; -} - static GList * tabs_catalog_get_tabs_info (EphyTabsCatalog *catalog) { @@ -196,11 +182,6 @@ ephy_embed_shell_dispose (GObject *object) g_clear_object (&priv->cancellable); } - if (priv->web_process_extensions) { - g_list_free_full (priv->web_process_extensions, g_object_unref); - priv->web_process_extensions = NULL; - } - g_clear_object (&priv->encodings); g_clear_object (&priv->page_setup); g_clear_object (&priv->print_settings); @@ -213,7 +194,6 @@ ephy_embed_shell_dispose (GObject *object) g_clear_object (&priv->permissions_manager); g_clear_object (&priv->web_context); g_clear_pointer (&priv->guid, g_free); - g_clear_object (&priv->dbus_server); g_clear_object (&priv->filters_manager); g_clear_object (&priv->search_engine_manager); @@ -246,18 +226,22 @@ history_service_query_urls_cb (EphyHistoryService *service, { EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); GList *l; + GVariantBuilder builder; if (!success) return; - for (l = priv->web_process_extensions; l; l = g_list_next (l)) { - EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data; + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); + for (l = urls; l; l = g_list_next (l)) { + EphyHistoryURL *url = (EphyHistoryURL *)l->data; - ephy_web_process_extension_proxy_history_set_urls (web_process_extension, urls); + g_variant_builder_add (&builder, "(ss)", url->url, url->title); + ephy_embed_shell_schedule_thumbnail_update (shell, (EphyHistoryURL *)l->data); } - for (l = urls; l; l = g_list_next (l)) - ephy_embed_shell_schedule_thumbnail_update (shell, (EphyHistoryURL *)l->data); + webkit_web_context_send_message_to_all_extensions (priv->web_context, + webkit_user_message_new ("History.SetURLs", + g_variant_builder_end (&builder))); } static void @@ -340,46 +324,6 @@ web_process_extension_about_apps_message_received_cb (WebKitUserContentManager * ephy_web_application_delete (app_id); } -typedef struct { - EphyEmbedShell *shell; - char *origin; - gint32 promise_id; - guint64 page_id; - guint64 frame_id; -} PasswordManagerData; - -static void -password_manager_data_free (PasswordManagerData *data) -{ - g_object_unref (data->shell); - g_free (data->origin); - g_free (data); -} - -static void -password_manager_query_finished_cb (GList *records, - PasswordManagerData *data) -{ - EphyWebProcessExtensionProxy *proxy; - EphyPasswordRecord *record; - const char *username = NULL; - const char *password = NULL; - - record = records && records->data ? EPHY_PASSWORD_RECORD (records->data) : NULL; - if (record) { - username = ephy_password_record_get_username (record); - password = ephy_password_record_get_password (record); - } - - proxy = ephy_embed_shell_get_extension_proxy_for_page_id (data->shell, - data->page_id, - data->origin); - if (proxy) - ephy_web_process_extension_proxy_password_query_response (proxy, username, password, data->promise_id, data->frame_id); - - password_manager_data_free (data); -} - static char * property_to_string_or_null (JSCValue *value, const char *name) @@ -390,14 +334,6 @@ property_to_string_or_null (JSCValue *value, return jsc_value_to_string (prop); } -static int -property_to_int32 (JSCValue *value, - const char *name) -{ - g_autoptr (JSCValue) prop = jsc_value_object_get_property (value, name); - return jsc_value_to_int32 (prop); -} - static int property_to_uint64 (JSCValue *value, const char *name) @@ -406,51 +342,6 @@ property_to_uint64 (JSCValue *value, return (guint64)jsc_value_to_double (prop); } -static void -web_process_extension_password_manager_query_received_cb (WebKitUserContentManager *manager, - WebKitJavascriptResult *message, - EphyEmbedShell *shell) -{ - EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - JSCValue *value = webkit_javascript_result_get_js_value (message); - g_autofree char *origin = property_to_string_or_null (value, "origin"); - g_autofree char *target_origin = property_to_string_or_null (value, "targetOrigin"); - g_autofree char *username = property_to_string_or_null (value, "username"); - g_autofree char *username_field = property_to_string_or_null (value, "usernameField"); - g_autofree char *password_field = property_to_string_or_null (value, "passwordField"); - gint32 promise_id = property_to_int32 (value, "promiseID"); - guint64 page_id = property_to_uint64 (value, "pageID"); - guint64 frame_id = property_to_uint64 (value, "frameID"); - PasswordManagerData *data; - - if (!origin || !target_origin || !password_field) - return; - - /* Don't include username_field in queries unless we actually have a username - * to go along with it, or the query will fail because we don't save - * username_field without a corresponding username. - */ - if (!username && username_field) - g_clear_pointer (&username_field, g_free); - - data = g_new (PasswordManagerData, 1); - data->shell = g_object_ref (shell); - data->promise_id = promise_id; - data->page_id = page_id; - data->frame_id = frame_id; - data->origin = g_strdup (origin); - - ephy_password_manager_query (priv->password_manager, - NULL, - origin, - target_origin, - username, - username_field, - password_field, - (EphyPasswordManagerQueryCallback)password_manager_query_finished_cb, - data); -} - typedef struct { EphyPasswordManager *password_manager; EphyPermissionsManager *permissions_manager; @@ -577,30 +468,6 @@ web_process_extension_password_manager_request_save_received_cb (WebKitUserConte web_process_extension_password_manager_save_real (shell, value, TRUE); } -static void -web_process_extension_password_manager_query_usernames_received_cb (WebKitUserContentManager *manager, - WebKitJavascriptResult *message, - EphyEmbedShell *shell) -{ - EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - JSCValue *value = webkit_javascript_result_get_js_value (message); - g_autofree char *origin = property_to_string_or_null (value, "origin"); - gint32 promise_id = property_to_int32 (value, "promiseID"); - guint64 page_id = property_to_uint64 (value, "pageID"); - guint64 frame_id = property_to_uint64 (value, "frameID"); - GList *usernames; - EphyWebProcessExtensionProxy *proxy; - - if (!origin) - return; - - usernames = ephy_password_manager_get_usernames_for_origin (priv->password_manager, origin); - - proxy = ephy_embed_shell_get_extension_proxy_for_page_id (shell, page_id, origin); - if (proxy) - ephy_web_process_extension_proxy_password_query_usernames_response (proxy, usernames, promise_id, frame_id); -} - static void history_service_url_title_changed_cb (EphyHistoryService *service, const char *url, @@ -608,13 +475,10 @@ history_service_url_title_changed_cb (EphyHistoryService *service, EphyEmbedShell *shell) { EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - GList *l; - for (l = priv->web_process_extensions; l; l = g_list_next (l)) { - EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data; - - ephy_web_process_extension_proxy_history_set_url_title (web_process_extension, url, title); - } + webkit_web_context_send_message_to_all_extensions (priv->web_context, + webkit_user_message_new ("History.SetURLTitle", + g_variant_new ("(ss)", url, title))); } static void @@ -623,13 +487,10 @@ history_service_url_deleted_cb (EphyHistoryService *service, EphyEmbedShell *shell) { EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - GList *l; - - for (l = priv->web_process_extensions; l; l = g_list_next (l)) { - EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data; - ephy_web_process_extension_proxy_history_delete_url (web_process_extension, url->url); - } + webkit_web_context_send_message_to_all_extensions (priv->web_context, + webkit_user_message_new ("History.DeleteURL", + g_variant_new ("s", url))); } static void @@ -638,16 +499,12 @@ history_service_host_deleted_cb (EphyHistoryService *service, EphyEmbedShell *shell) { EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - GList *l; g_autoptr (SoupURI) deleted_uri = NULL; deleted_uri = soup_uri_new (deleted_url); - - for (l = priv->web_process_extensions; l; l = g_list_next (l)) { - EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data; - - ephy_web_process_extension_proxy_history_delete_host (web_process_extension, soup_uri_get_host (deleted_uri)); - } + webkit_web_context_send_message_to_all_extensions (priv->web_context, + webkit_user_message_new ("History.DeleteHost", + g_variant_new ("s", soup_uri_get_host (deleted_uri)))); } static void @@ -655,60 +512,10 @@ history_service_cleared_cb (EphyHistoryService *service, EphyEmbedShell *shell) { EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - GList *l; - - for (l = priv->web_process_extensions; l; l = g_list_next (l)) { - EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data; - - ephy_web_process_extension_proxy_history_clear (web_process_extension); - } -} - -typedef struct { - EphyWebProcessExtensionProxy *extension; - char *url; - char *path; -} DelayedThumbnailUpdateData; - -static DelayedThumbnailUpdateData * -delayed_thumbnail_update_data_new (EphyWebProcessExtensionProxy *extension, - const char *url, - const char *path) -{ - DelayedThumbnailUpdateData *data = g_new (DelayedThumbnailUpdateData, 1); - data->extension = extension; - data->url = g_strdup (url); - data->path = g_strdup (path); - g_object_add_weak_pointer (G_OBJECT (extension), (gpointer *)&data->extension); - return data; -} - -static void -delayed_thumbnail_update_data_free (DelayedThumbnailUpdateData *data) -{ - if (data->extension) - g_object_remove_weak_pointer (G_OBJECT (data->extension), (gpointer *)&data->extension); - g_free (data->url); - g_free (data->path); - g_free (data); -} - -static gboolean -delayed_thumbnail_update_cb (DelayedThumbnailUpdateData *data) -{ - if (!data->extension) { - delayed_thumbnail_update_data_free (data); - return G_SOURCE_REMOVE; - } - - if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data->extension), "initialized"))) { - ephy_web_process_extension_proxy_history_set_url_thumbnail (data->extension, data->url, data->path); - delayed_thumbnail_update_data_free (data); - return G_SOURCE_REMOVE; - } - /* Web process extension is not initialized yet, try again later.... */ - return G_SOURCE_CONTINUE; + webkit_web_context_send_message_to_all_extensions (priv->web_context, + webkit_user_message_new ("History.Clear", + NULL)); } void @@ -717,17 +524,10 @@ ephy_embed_shell_set_thumbnail_path (EphyEmbedShell *shell, const char *path) { EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - GList *l; - for (l = priv->web_process_extensions; l; l = g_list_next (l)) { - EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data; - if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (web_process_extension), "initialized"))) { - ephy_web_process_extension_proxy_history_set_url_thumbnail (web_process_extension, url, path); - } else { - DelayedThumbnailUpdateData *data = delayed_thumbnail_update_data_new (web_process_extension, url, path); - g_timeout_add (50, (GSourceFunc)delayed_thumbnail_update_cb, data); - } - } + webkit_web_context_send_message_to_all_extensions (priv->web_context, + webkit_user_message_new ("History.SetURLThumbnail", + g_variant_new ("(ss)", url, path))); } static void @@ -913,7 +713,6 @@ initialize_web_process_extensions (WebKitWebContext *web_context, EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); g_autoptr (GVariant) user_data = NULL; gboolean private_profile; - const char *address; #if DEVELOPER_MODE webkit_web_context_set_web_extensions_directory (web_context, BUILD_ROOT "/embed/web-process-extension"); @@ -921,12 +720,9 @@ initialize_web_process_extensions (WebKitWebContext *web_context, webkit_web_context_set_web_extensions_directory (web_context, EPHY_WEB_PROCESS_EXTENSIONS_DIR); #endif - address = priv->dbus_server ? g_dbus_server_get_client_address (priv->dbus_server) : NULL; - private_profile = priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE || priv->mode == EPHY_EMBED_SHELL_MODE_INCOGNITO || priv->mode == EPHY_EMBED_SHELL_MODE_AUTOMATION; - user_data = g_variant_new ("(smsmsbb)", + user_data = g_variant_new ("(smsbb)", priv->guid, - address, ephy_profile_dir_is_default () ? NULL : ephy_profile_dir (), g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS), private_profile); @@ -948,93 +744,6 @@ initialize_notification_permissions (WebKitWebContext *web_context, webkit_web_context_initialize_notification_permissions (web_context, permitted_origins, denied_origins); } -static void -web_process_extension_page_created (EphyWebProcessExtensionProxy *extension, - guint64 page_id, - EphyEmbedShell *shell) -{ - g_object_set_data (G_OBJECT (extension), "initialized", GINT_TO_POINTER (TRUE)); - g_signal_emit (shell, signals[PAGE_CREATED], 0, page_id, extension); -} - -static void -web_process_extension_connection_closed (EphyWebProcessExtensionProxy *extension, - EphyEmbedShell *shell) -{ - EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - - priv->web_process_extensions = g_list_remove (priv->web_process_extensions, extension); - g_object_unref (extension); -} - -static gboolean -new_connection_cb (GDBusServer *server, - GDBusConnection *connection, - EphyEmbedShell *shell) -{ - EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - g_autoptr (EphyWebProcessExtensionProxy) extension = NULL; - - extension = ephy_web_process_extension_proxy_new (connection); - - g_signal_connect_object (extension, "page-created", - G_CALLBACK (web_process_extension_page_created), shell, 0); - g_signal_connect_object (extension, "connection-closed", - G_CALLBACK (web_process_extension_connection_closed), shell, 0); - - priv->web_process_extensions = g_list_prepend (priv->web_process_extensions, g_steal_pointer (&extension)); - - return TRUE; -} - -static gboolean -authorize_authenticated_peer_cb (GDBusAuthObserver *observer, - GIOStream *stream, - GCredentials *credentials, - EphyEmbedShell *shell) -{ - return ephy_dbus_peer_is_authorized (credentials); -} - -static void -ephy_embed_shell_setup_web_process_extensions_server (EphyEmbedShell *shell) -{ - EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); - g_autoptr (GDBusAuthObserver) observer = NULL; - g_autofree char *address = NULL; - g_autoptr (GError) error = NULL; - - /* Due to the bubblewrap sandbox, we cannot use any abstract sockets here. - * This means that unix:tmpdir= or unix:abstract= addresses will not work. - * Using unix:dir= guarantees that abstract sockets won't be used. - */ - address = g_strdup_printf ("unix:dir=%s", ephy_file_tmp_dir ()); - - observer = g_dbus_auth_observer_new (); - - g_signal_connect_object (observer, "authorize-authenticated-peer", - G_CALLBACK (authorize_authenticated_peer_cb), shell, 0); - - /* Why sync? - * - * (a) The server must be started before web process extensions try to connect. - * (b) Gio actually has no async version. Don't know why. - */ - priv->dbus_server = g_dbus_server_new_sync (address, - G_DBUS_SERVER_FLAGS_NONE, - priv->guid, - observer, - NULL, - &error); - - if (error) - g_error ("Failed to start embed shell D-Bus server on %s: %s", address, error->message); - - g_signal_connect_object (priv->dbus_server, "new-connection", - G_CALLBACK (new_connection_cb), shell, 0); - g_dbus_server_start (priv->dbus_server); -} - static void ephy_embed_shell_create_web_context (EphyEmbedShell *shell) { @@ -1095,16 +804,12 @@ remember_passwords_setting_changed_cb (GSettings *settings, { EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell); gboolean should_remember_passwords; - GList *l; should_remember_passwords = g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS); - for (l = priv->web_process_extensions; l; l = g_list_next (l)) { - EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data; - - ephy_web_process_extension_proxy_set_should_remember_passwords (web_process_extension, - should_remember_passwords); - } + webkit_web_context_send_message_to_all_extensions (priv->web_context, + webkit_user_message_new ("PasswordManager.SetShouldRememberPasswords", + g_variant_new ("b", should_remember_passwords))); } static void @@ -1121,8 +826,6 @@ ephy_embed_shell_startup (GApplication *application) ephy_embed_shell_create_web_context (shell); - ephy_embed_shell_setup_web_process_extensions_server (shell); - webkit_web_context_set_process_model (priv->web_context, WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES); webkit_web_context_set_sandbox_enabled (priv->web_context, TRUE); @@ -1204,14 +907,8 @@ ephy_embed_shell_startup (GApplication *application) static void ephy_embed_shell_shutdown (GApplication *application) { - EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (EPHY_EMBED_SHELL (application)); - G_APPLICATION_CLASS (ephy_embed_shell_parent_class)->shutdown (application); - if (priv->dbus_server) - g_dbus_server_stop (priv->dbus_server); - - g_object_unref (ephy_embed_prefs_get_settings ()); ephy_embed_utils_shutdown (); } @@ -1339,23 +1036,6 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass) G_TYPE_NONE, 1, EPHY_TYPE_WEB_VIEW); - /** - * EphyEmbedShell::page-created: - * @shell: the #EphyEmbedShell - * @page_id: the identifier of the web page created - * @web_process_extension: the #EphyWebProcessExtensionProxy - * - * Emitted when a web page is created in the web process. - */ - signals[PAGE_CREATED] = - g_signal_new ("page-created", - EPHY_TYPE_EMBED_SHELL, - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, - G_TYPE_UINT64, - EPHY_TYPE_WEB_PROCESS_EXTENSION_PROXY); - /** * EphyEmbedShell::allow-tls-certificate: * @shell: the #EphyEmbedShell @@ -1658,20 +1338,6 @@ ephy_embed_shell_register_ucm_handler (EphyEmbedShell *shell, G_CALLBACK (web_process_extension_about_apps_message_received_cb), shell, 0); - webkit_user_content_manager_register_script_message_handler_in_world (ucm, - "passwordManagerQuery", - priv->guid); - g_signal_connect_object (ucm, "script-message-received::passwordManagerQuery", - G_CALLBACK (web_process_extension_password_manager_query_received_cb), - shell, 0); - - webkit_user_content_manager_register_script_message_handler_in_world (ucm, - "passwordManagerQueryUsernames", - priv->guid); - g_signal_connect_object (ucm, "script-message-received::passwordManagerQueryUsernames", - G_CALLBACK (web_process_extension_password_manager_query_usernames_received_cb), - shell, 0); - webkit_user_content_manager_register_script_message_handler_in_world (ucm, "passwordManagerSave", priv->guid); @@ -1724,13 +1390,7 @@ ephy_embed_shell_unregister_ucm_handler (EphyEmbedShell *shell, "passwordFormFocused", priv->guid); webkit_user_content_manager_unregister_script_message_handler (ucm, "aboutApps"); - webkit_user_content_manager_unregister_script_message_handler_in_world (ucm, - "passwordManagerQuery", - priv->guid); webkit_user_content_manager_unregister_script_message_handler_in_world (ucm, "passwordManagerSave", priv->guid); - webkit_user_content_manager_unregister_script_message_handler_in_world (ucm, - "passwordManagerQueryUsernames", - priv->guid); } diff --git a/embed/ephy-web-process-extension-proxy.c b/embed/ephy-web-process-extension-proxy.c deleted file mode 100644 index 278e8020b..000000000 --- a/embed/ephy-web-process-extension-proxy.c +++ /dev/null @@ -1,354 +0,0 @@ -/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * Copyright © 2014 Igalia S.L. - * - * This file is part of Epiphany. - * - * Epiphany is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Epiphany is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Epiphany. If not, see . - */ - -#include -#include "ephy-web-process-extension-proxy.h" - -#include "ephy-dbus-names.h" -#include "ephy-history-service.h" - -struct _EphyWebProcessExtensionProxy { - GObject parent_instance; - - GCancellable *cancellable; - GDBusProxy *proxy; - GDBusConnection *connection; - - guint page_created_signal_id; -}; - -enum { - PAGE_CREATED, - CONNECTION_CLOSED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE (EphyWebProcessExtensionProxy, ephy_web_process_extension_proxy, G_TYPE_OBJECT) - -static void -ephy_web_process_extension_proxy_dispose (GObject *object) -{ - EphyWebProcessExtensionProxy *web_process_extension = EPHY_WEB_PROCESS_EXTENSION_PROXY (object); - - if (web_process_extension->page_created_signal_id > 0) { - g_dbus_connection_signal_unsubscribe (web_process_extension->connection, - web_process_extension->page_created_signal_id); - web_process_extension->page_created_signal_id = 0; - } - - if (web_process_extension->cancellable) { - g_cancellable_cancel (web_process_extension->cancellable); - g_clear_object (&web_process_extension->cancellable); - } - - g_clear_object (&web_process_extension->proxy); - g_clear_object (&web_process_extension->connection); - - G_OBJECT_CLASS (ephy_web_process_extension_proxy_parent_class)->dispose (object); -} - -static void -ephy_web_process_extension_proxy_init (EphyWebProcessExtensionProxy *web_process_extension) -{ -} - -static void -ephy_web_process_extension_proxy_class_init (EphyWebProcessExtensionProxyClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = ephy_web_process_extension_proxy_dispose; - - signals[PAGE_CREATED] = - g_signal_new ("page-created", - EPHY_TYPE_WEB_PROCESS_EXTENSION_PROXY, - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_UINT64); - - signals[CONNECTION_CLOSED] = - g_signal_new ("connection-closed", - EPHY_TYPE_WEB_PROCESS_EXTENSION_PROXY, - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); -} - -static void -web_process_extension_page_created (GDBusConnection *connection, - const char *sender_name, - const char *object_path, - const char *interface_name, - const char *signal_name, - GVariant *parameters, - EphyWebProcessExtensionProxy *web_process_extension) -{ - guint64 page_id; - g_variant_get (parameters, "(t)", &page_id); - g_signal_emit (web_process_extension, signals[PAGE_CREATED], 0, page_id); -} - -static void -web_process_extension_proxy_created_cb (GDBusProxy *proxy, - GAsyncResult *result, - EphyWebProcessExtensionProxy *web_process_extension) -{ - g_autoptr (GError) error = NULL; - - web_process_extension->proxy = g_dbus_proxy_new_finish (result, &error); - if (!web_process_extension->proxy) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("Error creating web process extension proxy: %s", error->message); - - /* Attempt to trigger connection_closed_cb, which will emit the - * connection-closed signal, ensuring that EphyEmbedShell will - * remove us from its extensions list. - */ - g_dbus_connection_close (web_process_extension->connection, - web_process_extension->cancellable, - NULL /* GAsyncReadyCallback */, - NULL); - g_object_unref (web_process_extension); - return; - } - - web_process_extension->page_created_signal_id = - g_dbus_connection_signal_subscribe (web_process_extension->connection, - NULL, - EPHY_WEB_PROCESS_EXTENSION_INTERFACE, - "PageCreated", - EPHY_WEB_PROCESS_EXTENSION_OBJECT_PATH, - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - (GDBusSignalCallback)web_process_extension_page_created, - web_process_extension, - NULL); - g_object_unref (web_process_extension); -} - -static void -connection_closed_cb (GDBusConnection *connection, - gboolean remote_peer_vanished, - GError *error, - EphyWebProcessExtensionProxy *web_process_extension) -{ - if (error && !remote_peer_vanished) - g_warning ("Unexpectedly lost connection to web process extension: %s", error->message); - - g_signal_emit (web_process_extension, signals[CONNECTION_CLOSED], 0); -} - -EphyWebProcessExtensionProxy * -ephy_web_process_extension_proxy_new (GDBusConnection *connection) -{ - EphyWebProcessExtensionProxy *web_process_extension; - - g_assert (G_IS_DBUS_CONNECTION (connection)); - - web_process_extension = g_object_new (EPHY_TYPE_WEB_PROCESS_EXTENSION_PROXY, NULL); - - g_signal_connect (connection, "closed", - G_CALLBACK (connection_closed_cb), web_process_extension); - - web_process_extension->cancellable = g_cancellable_new (); - web_process_extension->connection = g_object_ref (connection); - - g_dbus_proxy_new (connection, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - NULL, - NULL, - EPHY_WEB_PROCESS_EXTENSION_OBJECT_PATH, - EPHY_WEB_PROCESS_EXTENSION_INTERFACE, - web_process_extension->cancellable, - (GAsyncReadyCallback)web_process_extension_proxy_created_cb, - g_object_ref (web_process_extension)); - - return web_process_extension; -} - -void -ephy_web_process_extension_proxy_history_set_urls (EphyWebProcessExtensionProxy *web_process_extension, - GList *urls) -{ - GList *l; - GVariantBuilder builder; - - if (!web_process_extension->proxy) - return; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); - for (l = urls; l; l = g_list_next (l)) { - EphyHistoryURL *url = (EphyHistoryURL *)l->data; - - g_variant_builder_add (&builder, "(ss)", url->url, url->title); - } - - g_dbus_proxy_call (web_process_extension->proxy, - "HistorySetURLs", - g_variant_new ("(@a(ss))", g_variant_builder_end (&builder)), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_history_set_url_thumbnail (EphyWebProcessExtensionProxy *web_process_extension, - const char *url, - const char *path) -{ - if (!web_process_extension->proxy) - return; - - g_dbus_proxy_call (web_process_extension->proxy, - "HistorySetURLThumbnail", - g_variant_new ("(ss)", url, path), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_history_set_url_title (EphyWebProcessExtensionProxy *web_process_extension, - const char *url, - const char *title) -{ - if (!web_process_extension->proxy) - return; - - g_dbus_proxy_call (web_process_extension->proxy, - "HistorySetURLTitle", - g_variant_new ("(ss)", url, title), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_history_delete_url (EphyWebProcessExtensionProxy *web_process_extension, - const char *url) -{ - if (!web_process_extension->proxy) - return; - - g_dbus_proxy_call (web_process_extension->proxy, - "HistoryDeleteURL", - g_variant_new ("(s)", url), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_history_delete_host (EphyWebProcessExtensionProxy *web_process_extension, - const char *host) -{ - if (!web_process_extension->proxy) - return; - - g_dbus_proxy_call (web_process_extension->proxy, - "HistoryDeleteHost", - g_variant_new ("(s)", host), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_history_clear (EphyWebProcessExtensionProxy *web_process_extension) -{ - if (!web_process_extension->proxy) - return; - - g_dbus_proxy_call (web_process_extension->proxy, - "HistoryClear", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_password_query_usernames_response (EphyWebProcessExtensionProxy *web_process_extension, - GList *users, - gint32 promise_id, - guint64 frame_id) -{ - GList *l; - g_auto (GVariantBuilder) builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_STRING_ARRAY); - - if (!web_process_extension->proxy) - return; - - for (l = users; l != NULL; l = l->next) - g_variant_builder_add (&builder, "s", l->data); - - g_dbus_proxy_call (web_process_extension->proxy, - "PasswordQueryUsernamesResponse", - g_variant_new ("(asit)", &builder, promise_id, frame_id), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_password_query_response (EphyWebProcessExtensionProxy *web_process_extension, - const char *username, - const char *password, - gint32 promise_id, - guint64 frame_id) -{ - if (!web_process_extension->proxy) - return; - - g_dbus_proxy_call (web_process_extension->proxy, - "PasswordQueryResponse", - g_variant_new ("(ssit)", username ? : "", password ? : "", promise_id, frame_id), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} - -void -ephy_web_process_extension_proxy_set_should_remember_passwords (EphyWebProcessExtensionProxy *web_process_extension, - gboolean should_remember_passwords) -{ - if (!web_process_extension->proxy) - return; - - g_dbus_proxy_call (web_process_extension->proxy, - "SetShouldRememberPasswords", - g_variant_new ("(b)", should_remember_passwords), - G_DBUS_CALL_FLAGS_NONE, - -1, - web_process_extension->cancellable, - NULL, NULL); -} diff --git a/embed/ephy-web-process-extension-proxy.h b/embed/ephy-web-process-extension-proxy.h deleted file mode 100644 index bd03dc023..000000000 --- a/embed/ephy-web-process-extension-proxy.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * Copyright © 2014 Igalia S.L. - * - * This file is part of Epiphany. - * - * Epiphany is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Epiphany is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Epiphany. If not, see . - */ - -#pragma once - -#include - -G_BEGIN_DECLS - -#define EPHY_TYPE_WEB_PROCESS_EXTENSION_PROXY (ephy_web_process_extension_proxy_get_type ()) - -G_DECLARE_FINAL_TYPE (EphyWebProcessExtensionProxy, ephy_web_process_extension_proxy, EPHY, WEB_PROCESS_EXTENSION_PROXY, GObject) - -EphyWebProcessExtensionProxy *ephy_web_process_extension_proxy_new (GDBusConnection *connection); -void ephy_web_process_extension_proxy_history_set_urls (EphyWebProcessExtensionProxy *web_process_extension, - GList *urls); -void ephy_web_process_extension_proxy_history_set_url_thumbnail (EphyWebProcessExtensionProxy *web_process_extension, - const char *url, - const char *path); -void ephy_web_process_extension_proxy_history_set_url_title (EphyWebProcessExtensionProxy *web_process_extension, - const char *url, - const char *title); -void ephy_web_process_extension_proxy_history_delete_url (EphyWebProcessExtensionProxy *web_process_extension, - const char *url); -void ephy_web_process_extension_proxy_history_delete_host (EphyWebProcessExtensionProxy *web_process_extension, - const char *host); -void ephy_web_process_extension_proxy_history_clear (EphyWebProcessExtensionProxy *web_process_extension); -void ephy_web_process_extension_proxy_password_query_usernames_response (EphyWebProcessExtensionProxy *web_process_extension, - GList *users, - gint32 promise_id, - guint64 frame_id); -void ephy_web_process_extension_proxy_password_query_response (EphyWebProcessExtensionProxy *web_process_extension, - const char *username, - const char *password, - gint32 promise_id, - guint64 frame_id); - -void ephy_web_process_extension_proxy_set_should_remember_passwords (EphyWebProcessExtensionProxy *web_process_extension, - gboolean should_remember_passwords); - -G_END_DECLS diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c index 1c5676183..bc2096543 100644 --- a/embed/ephy-web-view.c +++ b/embed/ephy-web-view.c @@ -128,9 +128,6 @@ struct _EphyWebView { char *tls_error_failing_uri; EphyWebViewErrorPage error_page; - - /* Web Process Extension */ - EphyWebProcessExtensionProxy *web_process_extension; }; typedef struct { @@ -899,22 +896,6 @@ allow_unsafe_browsing_cb (EphyEmbedShell *shell, ephy_web_view_load_url (view, ephy_web_view_get_address (view)); } -static void -page_created_cb (EphyEmbedShell *shell, - guint64 page_id, - EphyWebProcessExtensionProxy *web_process_extension, - EphyWebView *view) -{ - if (webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)) != page_id) - return; - - if (view->web_process_extension) - g_object_remove_weak_pointer (G_OBJECT (view->web_process_extension), (gpointer *)&view->web_process_extension); - - view->web_process_extension = web_process_extension; - g_object_add_weak_pointer (G_OBJECT (view->web_process_extension), (gpointer *)&view->web_process_extension); -} - static void ephy_web_view_dispose (GObject *object) { @@ -924,11 +905,6 @@ ephy_web_view_dispose (GObject *object) ephy_embed_prefs_unregister_ucm (ucm); ephy_embed_shell_unregister_ucm_handler (ephy_embed_shell_get_default (), ucm); - if (view->web_process_extension) { - g_object_remove_weak_pointer (G_OBJECT (view->web_process_extension), (gpointer *)&view->web_process_extension); - view->web_process_extension = NULL; - } - untrack_info_bar (&view->geolocation_info_bar); untrack_info_bar (&view->notification_info_bar); untrack_info_bar (&view->microphone_info_bar); @@ -2958,6 +2934,143 @@ authenticate_cb (WebKitWebView *web_view, return FALSE; } +typedef struct { + WebKitWebView *web_view; + char *origin; + WebKitUserMessage *message; +} PasswordManagerData; + +static void +password_manager_data_free (PasswordManagerData *data) +{ + g_object_unref (data->web_view); + g_object_unref (data->message); + g_free (data); +} + +static void +password_manager_query_finished_cb (GList *records, + PasswordManagerData *data) +{ + EphyPasswordRecord *record; + const char *origin; + const char *username = NULL; + const char *password = NULL; + g_autofree char *real_origin = NULL; + + record = records && records->data ? EPHY_PASSWORD_RECORD (records->data) : NULL; + if (record) { + username = ephy_password_record_get_username (record); + password = ephy_password_record_get_password (record); + } + + g_variant_get (webkit_user_message_get_parameters (data->message), "(&s@sm@sm@s@s)", &origin, NULL, NULL, NULL, NULL); + real_origin = ephy_uri_to_security_origin (webkit_web_view_get_uri (data->web_view)); + if (g_strcmp0 (real_origin, origin) != 0) { + g_debug ("Extension's origin '%s' doesn't match real origin '%s'", origin, real_origin); + password_manager_data_free (data); + return; + } + + webkit_user_message_send_reply (data->message, + webkit_user_message_new ("PasswordManager.QueryPasswordResponse", + g_variant_new ("(msms)", username, password))); + password_manager_data_free (data); +} + +static gboolean +password_manager_handle_query_usernames_message (WebKitWebView *web_view, + WebKitUserMessage *message) +{ + GVariant *parameters; + const char *origin; + EphyPasswordManager *password_manager; + GList *usernames, *l; + GVariantBuilder builder; + g_autofree char *real_origin = NULL; + + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return FALSE; + + g_variant_get (parameters, "&s", &origin); + real_origin = ephy_uri_to_security_origin (webkit_web_view_get_uri (web_view)); + if (g_strcmp0 (real_origin, origin) != 0) { + g_debug ("Extension's origin '%s' doesn't match real origin '%s'", origin, real_origin); + return FALSE; + } + + password_manager = ephy_embed_shell_get_password_manager (ephy_embed_shell_get_default ()); + usernames = ephy_password_manager_get_usernames_for_origin (password_manager, origin); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); + for (l = usernames; l != NULL; l = g_list_next (l)) + g_variant_builder_add (&builder, "s", l->data); + + webkit_user_message_send_reply (message, webkit_user_message_new ("PasswordManager.QueryUsernamesResponse", + g_variant_builder_end (&builder))); + return TRUE; +} + +static gboolean +password_manager_handle_query_password_message (WebKitWebView *web_view, + WebKitUserMessage *message) +{ + GVariant *parameters; + const char *origin; + const char *target_origin; + const char *username; + const char *username_field; + const char *password_field; + EphyPasswordManager *password_manager; + PasswordManagerData *data; + + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return FALSE; + + g_variant_get (parameters, "(&s&sm&sm&s&s)", &origin, &target_origin, &username, &username_field, &password_field); + + /* Don't include username_field in queries unless we actually have a username + * to go along with it, or the query will fail because we don't save + * username_field without a corresponding username. + */ + if (!username && username_field) + username_field = NULL; + + data = g_new (PasswordManagerData, 1); + data->web_view = g_object_ref (web_view); + data->message = g_object_ref (message); + + password_manager = ephy_embed_shell_get_password_manager (ephy_embed_shell_get_default ()); + ephy_password_manager_query (password_manager, + NULL, + origin, + target_origin, + username, + username_field, + password_field, + (EphyPasswordManagerQueryCallback)password_manager_query_finished_cb, + data); + return TRUE; +} + +static gboolean +user_message_received_cb (WebKitWebView *web_view, + WebKitUserMessage *message) +{ + const char *name; + + name = webkit_user_message_get_name (message); + if (g_strcmp0 (name, "PasswordManager.QueryUsernames") == 0) + return password_manager_handle_query_usernames_message (web_view, message); + + if (g_strcmp0 (name, "PasswordManager.QueryPassword") == 0) + return password_manager_handle_query_password_message (web_view, message); + + return FALSE; +} + static void ephy_web_view_init (EphyWebView *web_view) { @@ -3042,9 +3155,9 @@ ephy_web_view_init (EphyWebView *web_view) G_CALLBACK (authenticate_cb), NULL); - g_signal_connect_object (shell, "page-created", - G_CALLBACK (page_created_cb), - web_view, 0); + g_signal_connect (web_view, "user-message-received", + G_CALLBACK (user_message_received_cb), + NULL); g_signal_connect_object (shell, "password-form-focused", G_CALLBACK (password_form_focused_cb), @@ -4028,12 +4141,6 @@ ephy_web_view_get_reader_mode_state (EphyWebView *view) return view->reader_active; } -EphyWebProcessExtensionProxy * -ephy_web_view_get_web_process_extension_proxy (EphyWebView *view) -{ - return view->web_process_extension; -} - gboolean ephy_web_view_is_in_auth_dialog (EphyWebView *view) { diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h index acb032738..3d66760be 100644 --- a/embed/ephy-web-view.h +++ b/embed/ephy-web-view.h @@ -26,7 +26,6 @@ #include "ephy-embed-shell.h" #include "ephy-history-types.h" #include "ephy-security-levels.h" -#include "ephy-web-process-extension-proxy.h" G_BEGIN_DECLS @@ -166,8 +165,6 @@ gboolean ephy_web_view_get_reader_mode_state (EphyWebView gboolean ephy_web_view_is_in_auth_dialog (EphyWebView *view); -EphyWebProcessExtensionProxy *ephy_web_view_get_web_process_extension_proxy (EphyWebView *view); - void ephy_web_view_show_auth_form_save_request (EphyWebView *web_view, const char *origin, const char *username, diff --git a/embed/meson.build b/embed/meson.build index 05a064090..47a38c499 100644 --- a/embed/meson.build +++ b/embed/meson.build @@ -28,7 +28,6 @@ libephyembed_sources = [ 'ephy-find-toolbar.c', 'ephy-view-source-handler.c', 'ephy-web-view.c', - 'ephy-web-process-extension-proxy.c', enums ] diff --git a/embed/web-process-extension/ephy-web-process-extension-main.c b/embed/web-process-extension/ephy-web-process-extension-main.c index 76fb294cc..3a155a13c 100644 --- a/embed/web-process-extension/ephy-web-process-extension-main.c +++ b/embed/web-process-extension/ephy-web-process-extension-main.c @@ -36,18 +36,12 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten GVariant *user_data) { const char *guid; - const char *server_address; const char *profile_dir; gboolean private_profile; gboolean should_remember_passwords; g_autoptr (GError) error = NULL; - g_variant_get (user_data, "(&sm&sm&sbb)", &guid, &server_address, &profile_dir, &should_remember_passwords, &private_profile); - - if (!server_address) { - g_warning ("UI process did not start D-Bus server, giving up."); - return; - } + g_variant_get (user_data, "(&sm&sbb)", &guid, &profile_dir, &should_remember_passwords, &private_profile); if (!ephy_file_helpers_init (profile_dir, 0, &error)) g_warning ("Failed to initialize file helpers: %s", error->message); @@ -62,7 +56,6 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten ephy_web_process_extension_initialize (extension, webkit_extension, guid, - server_address, should_remember_passwords, private_profile); } diff --git a/embed/web-process-extension/ephy-web-process-extension.c b/embed/web-process-extension/ephy-web-process-extension.c index e0b0adc49..d779aa7af 100644 --- a/embed/web-process-extension/ephy-web-process-extension.c +++ b/embed/web-process-extension/ephy-web-process-extension.c @@ -21,8 +21,6 @@ #include "config.h" #include "ephy-web-process-extension.h" -#include "ephy-dbus-names.h" -#include "ephy-dbus-util.h" #include "ephy-debug.h" #include "ephy-file-helpers.h" #include "ephy-permissions-manager.h" @@ -47,9 +45,6 @@ struct _EphyWebProcessExtension { WebKitWebExtension *extension; gboolean initialized; - GDBusConnection *dbus_connection; - GArray *page_created_signals_pending; - EphyWebOverviewModel *overview_model; EphyPermissionsManager *permissions_manager; @@ -61,47 +56,6 @@ struct _EphyWebProcessExtension { GHashTable *frames_map; }; -static const char introspection_xml[] = - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; - G_DEFINE_TYPE (EphyWebProcessExtension, ephy_web_process_extension, G_TYPE_OBJECT) static gboolean @@ -273,67 +227,15 @@ web_page_context_menu (WebKitWebPage *web_page, return TRUE; } -static void -ephy_web_process_extension_emit_page_created (EphyWebProcessExtension *extension, - guint64 page_id) -{ - g_autoptr (GError) error = NULL; - - g_dbus_connection_emit_signal (extension->dbus_connection, - NULL, - EPHY_WEB_PROCESS_EXTENSION_OBJECT_PATH, - EPHY_WEB_PROCESS_EXTENSION_INTERFACE, - "PageCreated", - g_variant_new ("(t)", page_id), - &error); - if (error) - g_warning ("Error emitting signal PageCreated: %s\n", error->message); -} - -static void -ephy_web_process_extension_emit_page_created_signals_pending (EphyWebProcessExtension *extension) -{ - guint i; - - if (!extension->page_created_signals_pending) - return; - - for (i = 0; i < extension->page_created_signals_pending->len; i++) { - guint64 page_id; - - page_id = g_array_index (extension->page_created_signals_pending, guint64, i); - ephy_web_process_extension_emit_page_created (extension, page_id); - } - - g_array_free (extension->page_created_signals_pending, TRUE); - extension->page_created_signals_pending = NULL; -} - -static void -ephy_web_process_extension_queue_page_created_signal_emission (EphyWebProcessExtension *extension, - guint64 page_id) -{ - if (!extension->page_created_signals_pending) - extension->page_created_signals_pending = g_array_new (FALSE, FALSE, sizeof (guint64)); - extension->page_created_signals_pending = g_array_append_val (extension->page_created_signals_pending, page_id); -} - static void ephy_web_process_extension_page_created_cb (EphyWebProcessExtension *extension, WebKitWebPage *web_page) { - guint64 page_id; g_autoptr (JSCContext) js_context = NULL; /* Enforce the creation of the script world global context in the main frame */ js_context = webkit_frame_get_js_context_for_script_world (webkit_web_page_get_main_frame (web_page), extension->script_world); - page_id = webkit_web_page_get_id (web_page); - if (extension->dbus_connection) - ephy_web_process_extension_emit_page_created (extension, page_id); - else - ephy_web_process_extension_queue_page_created_signal_emission (extension, page_id); - g_signal_connect (web_page, "send-request", G_CALLBACK (web_page_send_request), extension); @@ -348,48 +250,26 @@ ephy_web_process_extension_page_created_cb (EphyWebProcessExtension *extension, extension); } -static JSCValue * -get_password_manager (EphyWebProcessExtension *self, - guint64 frame_id) -{ - WebKitFrame *frame; - g_autoptr (JSCContext) js_context = NULL; - g_autoptr (JSCValue) js_ephy = NULL; - - frame = g_hash_table_lookup (self->frames_map, GINT_TO_POINTER (frame_id)); - if (!frame) - return NULL; - - js_context = webkit_frame_get_js_context_for_script_world (frame, self->script_world); - js_ephy = jsc_context_get_value (js_context, "Ephy"); - - return jsc_value_object_get_property (js_ephy, "passwordManager"); -} - static void -handle_method_call (GDBusConnection *connection, - const char *sender, - const char *object_path, - const char *interface_name, - const char *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) +ephy_web_process_extension_user_message_received_cb (EphyWebProcessExtension *extension, + WebKitUserMessage *message) { - EphyWebProcessExtension *extension = EPHY_WEB_PROCESS_EXTENSION (user_data); + const char *name = webkit_user_message_get_name (message); - if (g_strcmp0 (interface_name, EPHY_WEB_PROCESS_EXTENSION_INTERFACE) != 0) - return; - - if (g_strcmp0 (method_name, "HistorySetURLs") == 0) { + if (g_strcmp0 (name, "History.SetURLs") == 0) { if (extension->overview_model) { + GVariant *parameters; GVariantIter iter; - g_autoptr (GVariant) array = NULL; const char *url; const char *title; GList *items = NULL; + g_autoptr (GVariant) array = NULL; + + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return; - g_variant_get (parameters, "(@a(ss))", &array); + g_variant_get (parameters, "@a(ss)", &array); g_variant_iter_init (&iter, array); while (g_variant_iter_loop (&iter, "(&s&s)", &url, &title)) @@ -397,85 +277,87 @@ handle_method_call (GDBusConnection *connection, ephy_web_overview_model_set_urls (extension->overview_model, g_list_reverse (items)); } - g_dbus_method_invocation_return_value (invocation, NULL); - } else if (g_strcmp0 (method_name, "HistorySetURLThumbnail") == 0) { + } else if (g_strcmp0 (name, "History.SetURLThumbnail") == 0) { if (extension->overview_model) { + GVariant *parameters; const char *url; const char *path; + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return; + g_variant_get (parameters, "(&s&s)", &url, &path); ephy_web_overview_model_set_url_thumbnail (extension->overview_model, url, path, TRUE); } - g_dbus_method_invocation_return_value (invocation, NULL); - } else if (g_strcmp0 (method_name, "HistorySetURLTitle") == 0) { + } else if (g_strcmp0 (name, "History.SetURLTitle") == 0) { if (extension->overview_model) { + GVariant *parameters; const char *url; const char *title; + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return; + g_variant_get (parameters, "(&s&s)", &url, &title); ephy_web_overview_model_set_url_title (extension->overview_model, url, title); } - g_dbus_method_invocation_return_value (invocation, NULL); - } else if (g_strcmp0 (method_name, "HistoryDeleteURL") == 0) { + } else if (g_strcmp0 (name, "History.DeleteURL") == 0) { if (extension->overview_model) { + GVariant *parameters; const char *url; - g_variant_get (parameters, "(&s)", &url); + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return; + + g_variant_get (parameters, "&s", &url); ephy_web_overview_model_delete_url (extension->overview_model, url); } - g_dbus_method_invocation_return_value (invocation, NULL); - } else if (g_strcmp0 (method_name, "HistoryDeleteHost") == 0) { + } else if (g_strcmp0 (name, "History.DeleteHost") == 0) { if (extension->overview_model) { + GVariant *parameters; const char *host; - g_variant_get (parameters, "(&s)", &host); + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return; + + g_variant_get (parameters, "&s", &host); ephy_web_overview_model_delete_host (extension->overview_model, host); } - g_dbus_method_invocation_return_value (invocation, NULL); - } else if (g_strcmp0 (method_name, "HistoryClear") == 0) { + } else if (g_strcmp0 (name, "History.Clear") == 0) { if (extension->overview_model) ephy_web_overview_model_clear (extension->overview_model); - g_dbus_method_invocation_return_value (invocation, NULL); - } else if (g_strcmp0 (method_name, "PasswordQueryUsernamesResponse") == 0) { - g_autofree const char **users; - g_autoptr (JSCValue) ret = NULL; - g_autoptr (JSCValue) password_manager = NULL; - gint32 promise_id; - guint64 frame_id; - - users = g_variant_get_strv (g_variant_get_child_value (parameters, 0), NULL); - g_variant_get_child (parameters, 1, "i", &promise_id); - g_variant_get_child (parameters, 2, "t", &frame_id); - - password_manager = get_password_manager (extension, frame_id); - if (password_manager != NULL) - ret = jsc_value_object_invoke_method (password_manager, "_onQueryUsernamesResponse", - G_TYPE_STRV, users, G_TYPE_INT, promise_id, G_TYPE_NONE); - } else if (g_strcmp0 (method_name, "PasswordQueryResponse") == 0) { - const char *username; - const char *password; - gint32 promise_id; - guint64 frame_id; - g_autoptr (JSCValue) ret = NULL; - g_autoptr (JSCValue) password_manager = NULL; - - g_variant_get (parameters, "(&s&sit)", &username, &password, &promise_id, &frame_id); - password_manager = get_password_manager (extension, frame_id); - if (password_manager != NULL) - ret = jsc_value_object_invoke_method (password_manager, "_onQueryResponse", - G_TYPE_STRING, username, - G_TYPE_STRING, password, - G_TYPE_INT, promise_id, G_TYPE_NONE); - } else if (g_strcmp0 (method_name, "SetShouldRememberPasswords") == 0) { - g_variant_get (parameters, "(b)", &extension->should_remember_passwords); + } else if (g_strcmp0 (name, "PasswordManager.SetShouldRememberPasswords") == 0) { + GVariant *parameters; + + parameters = webkit_user_message_get_parameters (message); + if (!parameters) + return; + + g_variant_get (parameters, "b", &extension->should_remember_passwords); } } -static const GDBusInterfaceVTable interface_vtable = { - handle_method_call, - NULL, - NULL -}; +static JSCValue * +get_password_manager (EphyWebProcessExtension *self, + guint64 frame_id) +{ + WebKitFrame *frame; + g_autoptr (JSCContext) js_context = NULL; + g_autoptr (JSCValue) js_ephy = NULL; + + frame = g_hash_table_lookup (self->frames_map, GINT_TO_POINTER (frame_id)); + if (!frame) + return NULL; + + js_context = webkit_frame_get_js_context_for_script_world (frame, self->script_world); + js_ephy = jsc_context_get_value (js_context, "Ephy"); + + return jsc_value_object_get_property (js_ephy, "passwordManager"); +} static void drop_frame_weak_ref (gpointer key, @@ -493,13 +375,7 @@ ephy_web_process_extension_dispose (GObject *object) g_clear_object (&extension->overview_model); g_clear_object (&extension->permissions_manager); - if (extension->page_created_signals_pending) { - g_array_free (extension->page_created_signals_pending, TRUE); - extension->page_created_signals_pending = NULL; - } - g_clear_object (&extension->script_world); - g_clear_object (&extension->dbus_connection); g_clear_object (&extension->extension); if (extension->frames_map) { @@ -537,47 +413,6 @@ ephy_web_process_extension_get (void) return EPHY_WEB_PROCESS_EXTENSION (g_once (&once_init, ephy_web_process_extension_create_instance, NULL)); } -static void -dbus_connection_created_cb (GObject *source_object, - GAsyncResult *result, - EphyWebProcessExtension *extension) -{ - static GDBusNodeInfo *introspection_data = NULL; - g_autoptr (GDBusConnection) connection = NULL; - guint registration_id; - g_autoptr (GError) error = NULL; - - if (!introspection_data) - introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); - - connection = g_dbus_connection_new_for_address_finish (result, &error); - if (error) - g_error ("Failed to connect to UI process: %s", error->message); - - registration_id = - g_dbus_connection_register_object (connection, - EPHY_WEB_PROCESS_EXTENSION_OBJECT_PATH, - introspection_data->interfaces[0], - &interface_vtable, - extension, - NULL, - &error); - if (!registration_id) - g_error ("Failed to register web process extension object: %s\n", error->message); - - extension->dbus_connection = g_steal_pointer (&connection); - ephy_web_process_extension_emit_page_created_signals_pending (extension); -} - -static gboolean -authorize_authenticated_peer_cb (GDBusAuthObserver *observer, - GIOStream *stream, - GCredentials *credentials, - EphyWebProcessExtension *extension) -{ - return ephy_dbus_peer_is_authorized (credentials); -} - static void js_log (const char *message) { @@ -604,6 +439,153 @@ js_auto_fill (JSCValue *js_element, webkit_dom_element_html_input_element_set_editing_value (element, value); } +typedef struct { + EphyWebProcessExtension *extension; + guint64 promise_id; + guint64 frame_id; +} PasswordManagerQueryData; + +static void +web_view_query_usernames_ready_cb (WebKitWebPage *web_page, + GAsyncResult *result, + PasswordManagerQueryData *data) +{ + WebKitUserMessage *reply; + GVariant *parameters; + const char **usernames; + g_autoptr (JSCValue) password_manager = NULL; + g_autoptr (GError) error = NULL; + + reply = webkit_web_page_send_message_to_view_finish (web_page, result, &error); + if (error) { + g_warning ("Error getting usernames from WebView: %s\n", error->message); + g_free (data); + return; + } + + parameters = webkit_user_message_get_parameters (reply); + if (!parameters) { + g_free (data); + return; + } + + usernames = g_variant_get_strv (parameters, NULL); + password_manager = get_password_manager (data->extension, data->frame_id); + if (password_manager) { + g_autoptr (JSCValue) ret = NULL; + + ret = jsc_value_object_invoke_method (password_manager, "_onQueryUsernamesResponse", + G_TYPE_STRV, usernames, + G_TYPE_UINT64, data->promise_id, + G_TYPE_NONE); + } + + g_free (usernames); + g_free (data); +} + +static void +js_query_usernames (const char *origin, + guint64 promise_id, + guint64 page_id, + guint64 frame_id, + EphyWebProcessExtension *extension) +{ + WebKitWebPage *web_page; + WebKitUserMessage *message; + PasswordManagerQueryData *data; + + if (!origin) + return; + + web_page = webkit_web_extension_get_page (extension->extension, page_id); + if (!web_page) + return; + + data = g_new0 (PasswordManagerQueryData, 1); + data->extension = extension; + data->promise_id = promise_id; + data->frame_id = frame_id; + message = webkit_user_message_new ("PasswordManager.QueryUsernames", + g_variant_new ("s", origin)); + webkit_web_page_send_message_to_view (web_page, message, NULL, + (GAsyncReadyCallback)web_view_query_usernames_ready_cb, + data); +} + +static void +web_view_query_password_ready_cb (WebKitWebPage *web_page, + GAsyncResult *result, + PasswordManagerQueryData *data) +{ + WebKitUserMessage *reply; + GVariant *parameters; + const char *username; + const char *password; + g_autoptr (JSCValue) password_manager = NULL; + g_autoptr (GError) error = NULL; + + reply = webkit_web_page_send_message_to_view_finish (web_page, result, &error); + if (error) { + g_warning ("Error getting password from WebView: %s\n", error->message); + g_free (data); + return; + } + + parameters = webkit_user_message_get_parameters (reply); + if (!parameters) { + g_free (data); + return; + } + + g_variant_get (parameters, "(m&sm&s)", &username, &password); + password_manager = get_password_manager (data->extension, data->frame_id); + if (password_manager) { + g_autoptr (JSCValue) ret = NULL; + + ret = jsc_value_object_invoke_method (password_manager, "_onQueryResponse", + G_TYPE_STRING, username, + G_TYPE_STRING, password, + G_TYPE_UINT64, data->promise_id, + G_TYPE_NONE); + } + + g_free (data); +} + +static void +js_query_password (const char *origin, + const char *target_origin, + const char *username, + const char *username_field, + const char *password_field, + guint64 promise_id, + guint64 page_id, + guint64 frame_id, + EphyWebProcessExtension *extension) +{ + WebKitWebPage *web_page; + WebKitUserMessage *message; + PasswordManagerQueryData *data; + + if (!origin || !target_origin || !password_field) + return; + + web_page = webkit_web_extension_get_page (extension->extension, page_id); + if (!web_page) + return; + + data = g_new0 (PasswordManagerQueryData, 1); + data->extension = extension; + data->promise_id = promise_id; + data->frame_id = frame_id; + message = webkit_user_message_new ("PasswordManager.QueryPassword", + g_variant_new ("(ssmsmss)", origin, target_origin, username, username_field, password_field)); + webkit_web_page_send_message_to_view (web_page, message, NULL, + (GAsyncReadyCallback)web_view_query_password_ready_cb, + data); +} + static gboolean js_is_web_application (void) { @@ -726,6 +708,28 @@ window_object_cleared_cb (WebKitScriptWorld *world, JSC_TYPE_VALUE, G_TYPE_STRING); jsc_value_object_set_property (js_ephy, "autoFill", js_function); g_clear_object (&js_function); + + js_function = jsc_value_new_function (js_context, + "queryUsernames", + G_CALLBACK (js_query_usernames), + extension, NULL, + G_TYPE_NONE, 4, + G_TYPE_STRING, G_TYPE_UINT64, + G_TYPE_UINT64, G_TYPE_UINT64); + jsc_value_object_set_property (js_ephy, "queryUsernames", js_function); + g_clear_object (&js_function); + + js_function = jsc_value_new_function (js_context, + "queryPassword", + G_CALLBACK (js_query_password), + extension, NULL, + G_TYPE_NONE, 8, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_UINT64, + G_TYPE_UINT64, G_TYPE_UINT64); + jsc_value_object_set_property (js_ephy, "queryPassword", js_function); + g_clear_object (&js_function); } js_function = jsc_value_new_function (js_context, @@ -756,12 +760,9 @@ void ephy_web_process_extension_initialize (EphyWebProcessExtension *extension, WebKitWebExtension *wk_extension, const char *guid, - const char *server_address, gboolean should_remember_passwords, gboolean is_private_profile) { - g_autoptr (GDBusAuthObserver) observer = NULL; - g_assert (EPHY_IS_WEB_PROCESS_EXTENSION (extension)); if (extension->initialized) @@ -782,21 +783,13 @@ ephy_web_process_extension_initialize (EphyWebProcessExtension *extension, extension->permissions_manager = ephy_permissions_manager_new (); + g_signal_connect_swapped (extension->extension, "user-message-received", + G_CALLBACK (ephy_web_process_extension_user_message_received_cb), + extension); g_signal_connect_swapped (extension->extension, "page-created", G_CALLBACK (ephy_web_process_extension_page_created_cb), extension); - observer = g_dbus_auth_observer_new (); - g_signal_connect (observer, "authorize-authenticated-peer", - G_CALLBACK (authorize_authenticated_peer_cb), extension); - - g_dbus_connection_new_for_address (server_address, - G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, - observer, - NULL, - (GAsyncReadyCallback)dbus_connection_created_cb, - extension); - extension->frames_map = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); } diff --git a/embed/web-process-extension/ephy-web-process-extension.h b/embed/web-process-extension/ephy-web-process-extension.h index f11b5e0e8..45467dcf2 100644 --- a/embed/web-process-extension/ephy-web-process-extension.h +++ b/embed/web-process-extension/ephy-web-process-extension.h @@ -33,7 +33,6 @@ EphyWebProcessExtension *ephy_web_process_extension_get (void); void ephy_web_process_extension_initialize (EphyWebProcessExtension *extension, WebKitWebExtension *wk_extension, const char *guid, - const char *server_address, gboolean should_remember_passwords, gboolean is_private_profile); diff --git a/embed/web-process-extension/resources/js/ephy.js b/embed/web-process-extension/resources/js/ephy.js index 9759b882e..aecddbc18 100644 --- a/embed/web-process-extension/resources/js/ephy.js +++ b/embed/web-process-extension/resources/js/ephy.js @@ -345,10 +345,7 @@ Ephy.PasswordManager = class PasswordManager { return new Promise((resolver, reject) => { let promiseID = this._promiseCounter++; - window.webkit.messageHandlers.passwordManagerQuery.postMessage({ - origin, targetOrigin, username, usernameField, passwordField, promiseID, - pageID: this._pageID, frameID: this._frameID - }); + Ephy.queryPassword(origin, targetOrigin, username, usernameField, passwordField, promiseID, this._pageID, this._frameID); this._pendingPromises.push({promiseID, resolver}); }); } @@ -381,9 +378,7 @@ Ephy.PasswordManager = class PasswordManager { return new Promise((resolver, reject) => { let promiseID = this._promiseCounter++; - window.webkit.messageHandlers.passwordManagerQueryUsernames.postMessage({ - origin, promiseID, pageID: this._pageID, frameID: this._frameID - }); + Ephy.queryUsernames(origin, promiseID, this._pageID, this._frameID); this._pendingPromises.push({promiseID, resolver}); }); } diff --git a/lib/ephy-dbus-names.h b/lib/ephy-dbus-names.h deleted file mode 100644 index 80b357517..000000000 --- a/lib/ephy-dbus-names.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * Copyright © 2014 Igalia S.L. - * - * This file is part of Epiphany. - * - * Epiphany is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Epiphany is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Epiphany. If not, see . - */ - -#pragma once - -G_BEGIN_DECLS - -#define EPHY_WEB_PROCESS_EXTENSION_SERVICE_NAME "org.gnome.Epiphany.WebProcessExtension" -#define EPHY_WEB_PROCESS_EXTENSION_OBJECT_PATH "/org/gnome/Epiphany/WebProcessExtension" -#define EPHY_WEB_PROCESS_EXTENSION_INTERFACE "org.gnome.Epiphany.WebProcessExtension" - -G_END_DECLS diff --git a/lib/ephy-dbus-util.c b/lib/ephy-dbus-util.c deleted file mode 100644 index 117001b24..000000000 --- a/lib/ephy-dbus-util.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * Copyright © 2016 Igalia S.L. - * - * This file is part of Epiphany. - * - * Epiphany is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Epiphany is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Epiphany. If not, see . - */ - -#include "ephy-dbus-util.h" - -gboolean -ephy_dbus_peer_is_authorized (GCredentials *peer_credentials) -{ - static GCredentials *own_credentials = NULL; - GError *error = NULL; - - if (!own_credentials) - own_credentials = g_credentials_new (); - - if (peer_credentials && g_credentials_is_same_user (peer_credentials, own_credentials, &error)) - return TRUE; - - if (error) { - g_warning ("Failed to authorize web extension connection: %s", error->message); - g_error_free (error); - } - return FALSE; -} diff --git a/lib/ephy-dbus-util.h b/lib/ephy-dbus-util.h deleted file mode 100644 index 2eef0f802..000000000 --- a/lib/ephy-dbus-util.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * Copyright © 2016 Igalia S.L. - * - * This file is part of Epiphany. - * - * Epiphany is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Epiphany is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Epiphany. If not, see . - */ - -#pragma once - -#include - -G_BEGIN_DECLS - -gboolean ephy_dbus_peer_is_authorized (GCredentials *peer_credentials); - -G_END_DECLS diff --git a/lib/meson.build b/lib/meson.build index cb309d166..a9f651a7a 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -14,7 +14,6 @@ libephymisc_sources = [ 'contrib/gnome-languages.c', 'contrib/gvdb/gvdb-builder.c', 'contrib/gvdb/gvdb-reader.c', - 'ephy-dbus-util.c', 'ephy-debug.c', 'ephy-dnd.c', 'ephy-favicon-helpers.c', diff --git a/meson.build b/meson.build index 0644c1a02..f48d2e821 100644 --- a/meson.build +++ b/meson.build @@ -76,7 +76,7 @@ config_h = declare_dependency( glib_requirement = '>= 2.61.2' gtk_requirement = '>= 3.24.0' nettle_requirement = '>= 3.4' -webkitgtk_requirement = '>= 2.26.0' +webkitgtk_requirement = '>= 2.27.3' cairo_dep = dependency('cairo', version: '>= 1.2') gcr_dep = dependency('gcr-3', version: '>= 3.5.5') -- GitLab