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.
This commit is contained in:
LinXuan Jiang
2017-08-25 20:25:09 +08:00
committed by Alexander Larsson
parent 52bd146561
commit 4fc222ac3b

View File

@@ -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;