From 4fc222ac3b78f0f38871b0f87f35825764b41cfa Mon Sep 17 00:00:00 2001 From: LinXuan Jiang Date: Fri, 25 Aug 2017 20:25:09 +0800 Subject: [PATCH] Get language list from AccountsService's dbus (#973) * Get language list from AccountsService's dbus Fixes issue #950 When xa.languages is not set in repo config, system installs will get language list from AccountsService's dbus. --- common/flatpak-dir.c | 165 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 747bdc44..2a73817f 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -9696,6 +9696,154 @@ flatpak_dir_find_local_related (FlatpakDir *self, return g_steal_pointer (&related); } +static GDBusProxy * +get_accounts_dbus_proxy (void) +{ + GDBusConnection *conn = NULL; + GDBusProxy *proxy = NULL; + + const char *accounts_bus_name = "org.freedesktop.Accounts"; + const char *accounts_object_path = "/org/freedesktop/Accounts"; + const char *accounts_interface_name = accounts_bus_name; + + conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + accounts_bus_name, + accounts_object_path, + accounts_interface_name, + NULL, + NULL); + g_object_unref (conn); + + return proxy; +} + +static char ** +get_locale_subpaths_from_accounts_dbus (GDBusProxy *proxy) +{ + const char *accounts_bus_name = "org.freedesktop.Accounts"; + const char *accounts_interface_name = "org.freedesktop.Accounts.User"; + char **object_path; + GList *langs = NULL; + GList *l = NULL; + GString *langs_cache = g_string_new(NULL); + GPtrArray *subpaths = g_ptr_array_new (); + gboolean use_full_language = FALSE; + int i; + + GVariant *ret; + ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), + "ListCachedUsers", + g_variant_new ("()"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL); + if (ret != NULL) + { + g_variant_get (ret, + "(^ao)", + &object_path); + g_variant_unref (ret); + } + + if (object_path != NULL) + { + for (i = 0; object_path[i] != NULL; i++) + { + GDBusProxy *accounts_proxy = NULL; + GVariant *value = NULL; + gsize size; + char *lang; + + accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + accounts_bus_name, + object_path[i], + accounts_interface_name, + NULL, + NULL); + + value = g_dbus_proxy_get_cached_property (accounts_proxy, "Language"); + if (value != NULL) + { + size = g_variant_get_size (value); + lang = g_strdup (g_variant_get_string (value, &size)); + langs = g_list_append (langs, lang); + + g_variant_unref (value); + g_object_unref (accounts_proxy); + } + } + } + + l = langs; + while (l != NULL) + { + g_autofree char *dir = g_strconcat ("/", l->data, NULL); + char *c; + + c = strchr (dir, '@'); + if (c != NULL) + *c = 0; + c = strchr (dir, '_'); + if (c != NULL) + *c = 0; + c = strchr (dir, '.'); + if (c != NULL) + *c = 0; + + if (strcmp (dir, "/C") == 0) + continue; + + /* handle language == "" */ + if (strcmp (dir, "/") == 0) + { + use_full_language = TRUE; + break; + } + + /* filter duplicate language */ + if (g_strrstr (langs_cache->str, dir) == NULL) + { + g_string_append (langs_cache, dir); + g_string_append_c (langs_cache, ':'); + g_ptr_array_add (subpaths, g_steal_pointer (&dir)); + } + + l = l->next; + } + + if (langs == NULL) + { + return NULL; + } + + l = langs; + while (l != NULL) + { + if (l->data != NULL) + g_free (l->data); + l = l->next; + } + g_list_free (langs); + + g_string_free(langs_cache, TRUE); + + g_ptr_array_add (subpaths, NULL); + + if (use_full_language) + { + g_ptr_array_free (subpaths, TRUE); + return NULL; + } + else + return (char **)g_ptr_array_free (subpaths, FALSE); +} + char ** flatpak_dir_get_locale_subpaths (FlatpakDir *self) { @@ -9710,7 +9858,22 @@ flatpak_dir_get_locale_subpaths (FlatpakDir *self) if (flatpak_dir_is_user (self)) subpaths = flatpak_get_current_locale_subpaths (); else - subpaths = g_new0 (char *, 1); + { + /* If proxy is not NULL, it means that AccountService exists + * and gets the list of languages from AccountService. */ + GDBusProxy *proxy = get_accounts_dbus_proxy (); + if (proxy != NULL) + { + subpaths = get_locale_subpaths_from_accounts_dbus (proxy); + g_object_unref (proxy); + + /* If subpaths is NULL, it means using all languages */ + if (subpaths == NULL) + subpaths = g_new0 (char *, 1); + } + else /* proxy is NULL, falling back to all languages */ + subpaths = g_new0 (char *, 1); + } } return subpaths;