[epiphany/wip/tingping/profile-migration: 1/6] Store web extension settings in a keyfile



commit 40d213f02e33c7815d99c3a3f8d9148798f96b1b
Author: Patrick Griffis <pgriffis igalia com>
Date:   Mon Dec 17 09:08:07 2018 -0500

    Store web extension settings in a keyfile
    
    This will be required when the sandbox is enabled as
    they will not have access to DConf.

 embed/web-extension/ephy-uri-tester.c    |   6 +-
 embed/web-extension/ephy-web-extension.c |   6 +-
 lib/ephy-settings.c                      | 102 +++++++++++++++++++++++++++++++
 lib/ephy-settings.h                      |  19 +++---
 4 files changed, 119 insertions(+), 14 deletions(-)
---
diff --git a/embed/web-extension/ephy-uri-tester.c b/embed/web-extension/ephy-uri-tester.c
index 5158dcb3a..76ea56f60 100644
--- a/embed/web-extension/ephy-uri-tester.c
+++ b/embed/web-extension/ephy-uri-tester.c
@@ -634,7 +634,7 @@ ephy_uri_tester_begin_loading_adblock_filters (EphyUriTester  *tester,
 {
   char **filters;
 
-  filters = g_settings_get_strv (EPHY_SETTINGS_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
+  filters = g_settings_get_strv (EPHY_SETTINGS_WEB_EXTENSION_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
   tester->adblock_filters_to_load = g_strv_length (filters);
   for (guint i = 0; filters[i]; i++) {
     GFile *filter_file;
@@ -852,7 +852,7 @@ ephy_uri_tester_load (EphyUriTester *tester)
 
   g_assert (EPHY_IS_URI_TESTER (tester));
 
-  if (!g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
+  if (!g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
     tester->adblock_loaded = TRUE;
 
   if (tester->adblock_loaded)
@@ -871,6 +871,6 @@ ephy_uri_tester_load (EphyUriTester *tester)
                     G_CALLBACK (ephy_uri_tester_enable_adblock_changed_cb), tester);
   /* GSettings never emits the changed signal until after we read the setting
    * the first time after connecting the handler... work around this.*/
-  trash = g_settings_get_strv (EPHY_SETTINGS_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
+  trash = g_settings_get_strv (EPHY_SETTINGS_WEB_EXTENSION_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
   g_strfreev (trash);
 }
diff --git a/embed/web-extension/ephy-web-extension.c b/embed/web-extension/ephy-web-extension.c
index 4e11b600f..bebbebcef 100644
--- a/embed/web-extension/ephy-web-extension.c
+++ b/embed/web-extension/ephy-web-extension.c
@@ -103,7 +103,7 @@ should_use_adblocker (const char *request_uri,
                       const char *page_uri,
                       const char *redirected_request_uri)
 {
-  if (!g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
+  if (!g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
     return FALSE;
 
   /* Always load the main resource... */
@@ -150,7 +150,7 @@ web_page_send_request (WebKitWebPage     *web_page,
   page_uri = webkit_web_page_get_uri (web_page);
   redirected_response_uri = redirected_response ? webkit_uri_response_get_uri (redirected_response) : NULL;
 
-  if (g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
+  if (g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
     SoupMessageHeaders *headers = webkit_uri_request_get_http_headers (request);
     if (headers) {
       /* Do Not Track header. '1' means 'opt-out'. See:
@@ -275,7 +275,7 @@ web_page_form_controls_associated (WebKitWebPage    *web_page,
                                           G_TYPE_STRING, 2,
                                           G_TYPE_UINT64, G_TYPE_BOOLEAN);
   remember_passwords = !extension->is_private_profile &&
-                       g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
+                       g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, 
EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
   js_result = jsc_value_object_invoke_method (js_ephy,
                                               "formControlsAssociated",
                                               G_TYPE_UINT64, webkit_web_page_get_id (web_page),
diff --git a/lib/ephy-settings.c b/lib/ephy-settings.c
index 8c415a607..36dd41f0f 100644
--- a/lib/ephy-settings.c
+++ b/lib/ephy-settings.c
@@ -28,6 +28,9 @@
 #include <glib.h>
 #include <gio/gio.h>
 
+#define G_SETTINGS_ENABLE_BACKEND
+#include <gio/gsettingsbackend.h>
+
 static GHashTable *settings = NULL;
 
 static void
@@ -98,4 +101,103 @@ ephy_settings_get (const char *schema)
   return gsettings;
 }
 
+static void
+on_settings_changed (GSettings *settings,
+                     char      *key,
+                     gpointer   user_data)
+{
+  g_autoptr(GVariant) value = g_settings_get_user_value (settings, key);
+  if (value != NULL)
+    g_settings_set_value (user_data, key, value);
+  else
+    g_settings_reset (user_data, key);
+}
+
+static void
+sync_settings (GSettings *original,
+               GSettings *new)
+{
+  g_autoptr(GSettingsSchema) schema = NULL;
+  g_auto(GStrv) keys = NULL;
 
+  g_object_get (original, "settings-schema", &schema, NULL);
+  keys = g_settings_schema_list_keys (schema);
+
+  for (size_t i = 0; keys[i]; ++i) {
+    const char *key = keys[i];
+    g_autoptr(GVariant) value = g_settings_get_user_value (original, key);
+    if (value != NULL)
+      g_settings_set_value (new, key, value);
+  }
+
+  g_signal_connect_object (original, "changed", G_CALLBACK (on_settings_changed), new, 0);
+}
+
+static char *
+get_relocatable_path (const char *schema)
+{
+  for (size_t i = 0; i < G_N_ELEMENTS (ephy_prefs_relocatable_schemas); i++) {
+    if (g_strcmp0 (ephy_prefs_relocatable_schemas[i].schema, schema) == 0)
+      return g_build_path ("/", "/org/gnome/epiphany/", ephy_prefs_relocatable_schemas[i].path, NULL);
+  }
+  return NULL;
+}
+
+/**
+ * ephy_settings_get_for_web_extension:
+ *
+ * Equivilent to ephy_settings_get() except it ensures that the
+ * settings backend is always keyfile based instead of using DConf.
+ *
+ * It is also assumed this will only be used as read-only.
+ *
+ * Returns: (transfer none): #GSettings
+ */
+GSettings *
+ephy_settings_get_for_web_extension (const char *schema)
+{
+  GSettings *gsettings = NULL;
+  g_autofree char *key_name = NULL;
+
+  ephy_settings_init ();
+
+  // Web apps can't work with the sandbox anyway
+  const char *web_app_name = strstr (ephy_dot_dir (), EPHY_WEB_APP_PREFIX);
+  if (web_app_name != NULL)
+    return ephy_settings_get (schema);
+
+  key_name = g_strdup_printf ("keyfile-%s", schema);
+  gsettings = g_hash_table_lookup (settings, key_name);
+
+  if (gsettings == NULL) {
+    g_autoptr(GSettingsBackend) backend = NULL;
+    gsettings = ephy_settings_get (schema);
+    g_assert (gsettings != NULL);
+
+    // GLib inside Flatpak will default to this backend in the future
+    // so we don't need to do anything extra
+    g_object_get (gsettings, "backend", &backend, NULL);
+    // G_IS_KEYFILE_SETTINGS_BACKEND () is private API
+    if (!g_strcmp0 (g_type_name (G_TYPE_FROM_INSTANCE (backend)), "GKeyfileSettingsBackend")) {
+      g_hash_table_insert (settings, g_steal_pointer (&key_name), g_object_ref (gsettings));
+      return gsettings;
+    }
+
+    g_autofree char *keyfile_path = g_build_filename (ephy_dot_dir (), "web-extension-settings.ini", NULL);
+    backend = g_keyfile_settings_backend_new (keyfile_path, "/", "/");
+
+    GSettings *web_gsettings;
+    g_autofree char *path = get_relocatable_path (schema);
+    if (path != NULL)
+      web_gsettings = g_settings_new_with_backend_and_path (schema, backend, path);
+    else
+      web_gsettings = g_settings_new_with_backend (schema, backend);
+
+    sync_settings (gsettings, web_gsettings);
+    g_hash_table_insert (settings, g_steal_pointer (&key_name), web_gsettings);
+
+    return web_gsettings;
+  }
+
+  return gsettings;
+}
diff --git a/lib/ephy-settings.h b/lib/ephy-settings.h
index 48ed7fcc2..5c95f70d2 100644
--- a/lib/ephy-settings.h
+++ b/lib/ephy-settings.h
@@ -27,16 +27,19 @@
 
 G_BEGIN_DECLS
 
-#define EPHY_SETTINGS_MAIN      ephy_settings_get (EPHY_PREFS_SCHEMA)
-#define EPHY_SETTINGS_UI        ephy_settings_get (EPHY_PREFS_UI_SCHEMA)
-#define EPHY_SETTINGS_WEB       ephy_settings_get (EPHY_PREFS_WEB_SCHEMA)
-#define EPHY_SETTINGS_LOCKDOWN  ephy_settings_get (EPHY_PREFS_LOCKDOWN_SCHEMA)
-#define EPHY_SETTINGS_STATE     ephy_settings_get (EPHY_PREFS_STATE_SCHEMA)
-#define EPHY_SETTINGS_SYNC      ephy_settings_get (EPHY_PREFS_SYNC_SCHEMA)
-#define EPHY_SETTINGS_WEB_APP   ephy_settings_get (EPHY_PREFS_WEB_APP_SCHEMA)
-#define EPHY_SETTINGS_READER    ephy_settings_get (EPHY_PREFS_READER_SCHEMA)
+#define EPHY_SETTINGS_MAIN               ephy_settings_get (EPHY_PREFS_SCHEMA)
+#define EPHY_SETTINGS_UI                 ephy_settings_get (EPHY_PREFS_UI_SCHEMA)
+#define EPHY_SETTINGS_WEB                ephy_settings_get (EPHY_PREFS_WEB_SCHEMA)
+#define EPHY_SETTINGS_LOCKDOWN           ephy_settings_get (EPHY_PREFS_LOCKDOWN_SCHEMA)
+#define EPHY_SETTINGS_STATE              ephy_settings_get (EPHY_PREFS_STATE_SCHEMA)
+#define EPHY_SETTINGS_SYNC               ephy_settings_get (EPHY_PREFS_SYNC_SCHEMA)
+#define EPHY_SETTINGS_WEB_APP            ephy_settings_get (EPHY_PREFS_WEB_APP_SCHEMA)
+#define EPHY_SETTINGS_READER             ephy_settings_get (EPHY_PREFS_READER_SCHEMA)
+#define EPHY_SETTINGS_WEB_EXTENSION_MAIN ephy_settings_get_for_web_extension (EPHY_PREFS_SCHEMA)
+#define EPHY_SETTINGS_WEB_EXTENSION_WEB  ephy_settings_get_for_web_extension (EPHY_PREFS_WEB_SCHEMA)
 
 GSettings *ephy_settings_get (const char *schema);
+GSettings *ephy_settings_get_for_web_extension (const char *schema);
 
 void ephy_settings_shutdown (void);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]