mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-07 01:08:52 +00:00
Show translated firmware release notes when provided
Send the users locale to the daemon so that it can be used to prefer the localized update text over the default en_US version. $ LANG=fr_FR.UTF8 fwupdmgr get-details test.cab ... └─ACME Plan 9: Nouvelle version: 0.0.5 Licence: Propriétaire Urgence: Faible Fournisseur: ACME Ltd. Description: Cette version stable corrige des bugs. I decided to send the locale to the daemon rather than change the `Description` to return GVariant to `a{ss}` as we also probably want to support things like localized summary and URLs too in the future.
This commit is contained in:
parent
3c8339c9eb
commit
70f9124545
@ -34,6 +34,9 @@
|
|||||||
#include "fwupd-request-private.h"
|
#include "fwupd-request-private.h"
|
||||||
#include "fwupd-security-attr-private.h"
|
#include "fwupd-security-attr-private.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
fwupd_client_fixup_dbus_error(GError *error);
|
||||||
|
|
||||||
typedef GObject *(*FwupdClientObjectNewFunc)(void);
|
typedef GObject *(*FwupdClientObjectNewFunc)(void);
|
||||||
|
|
||||||
#define FWUPD_CLIENT_DBUS_PROXY_TIMEOUT 180000 /* ms */
|
#define FWUPD_CLIENT_DBUS_PROXY_TIMEOUT 180000 /* ms */
|
||||||
@ -66,6 +69,7 @@ typedef struct {
|
|||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
GProxyResolver *proxy_resolver;
|
GProxyResolver *proxy_resolver;
|
||||||
gchar *user_agent;
|
gchar *user_agent;
|
||||||
|
GHashTable *hints; /* str:str */
|
||||||
#ifdef SOUP_SESSION_COMPAT
|
#ifdef SOUP_SESSION_COMPAT
|
||||||
GObject *soup_session;
|
GObject *soup_session;
|
||||||
GModule *soup_module; /* we leak this */
|
GModule *soup_module; /* we leak this */
|
||||||
@ -594,12 +598,40 @@ fwupd_client_curl_new(FwupdClient *self, GError **error)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
fwupd_client_set_hints_cb(GObject *source, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GTask) task = G_TASK(user_data);
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(GVariant) val = NULL;
|
||||||
|
|
||||||
|
val = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error);
|
||||||
|
if (val == NULL) {
|
||||||
|
/* new libfwupd and old daemon, just swallow the error */
|
||||||
|
if (g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) {
|
||||||
|
g_debug("ignoring %s", error->message);
|
||||||
|
g_task_return_boolean(task, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fwupd_client_fixup_dbus_error(error);
|
||||||
|
g_task_return_error(task, g_steal_pointer(&error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
g_task_return_boolean(task, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fwupd_client_connect_get_proxy_cb(GObject *source, GAsyncResult *res, gpointer user_data)
|
fwupd_client_connect_get_proxy_cb(GObject *source, GAsyncResult *res, gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = G_TASK(user_data);
|
g_autoptr(GTask) task = G_TASK(user_data);
|
||||||
|
GVariantBuilder builder;
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
FwupdClient *self = g_task_get_source_object(task);
|
FwupdClient *self = g_task_get_source_object(task);
|
||||||
FwupdClientPrivate *priv = GET_PRIVATE(self);
|
FwupdClientPrivate *priv = GET_PRIVATE(self);
|
||||||
|
GCancellable *cancellable = g_task_get_cancellable(task);
|
||||||
g_autoptr(GDBusProxy) proxy = NULL;
|
g_autoptr(GDBusProxy) proxy = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(GVariant) val = NULL;
|
g_autoptr(GVariant) val = NULL;
|
||||||
@ -653,8 +685,21 @@ fwupd_client_connect_get_proxy_cb(GObject *source, GAsyncResult *res, gpointer u
|
|||||||
if (val7 != NULL)
|
if (val7 != NULL)
|
||||||
fwupd_client_set_host_security_id(self, g_variant_get_string(val7, NULL));
|
fwupd_client_set_host_security_id(self, g_variant_get_string(val7, NULL));
|
||||||
|
|
||||||
/* success */
|
/* build client hints */
|
||||||
g_task_return_boolean(task, TRUE);
|
g_variant_builder_init(&builder, G_VARIANT_TYPE_DICTIONARY);
|
||||||
|
g_hash_table_iter_init(&iter, priv->hints);
|
||||||
|
while (g_hash_table_iter_next(&iter, &key, &value))
|
||||||
|
g_variant_builder_add(&builder, "{ss}", (const gchar *)key, (const gchar *)value);
|
||||||
|
|
||||||
|
/* only supported on fwupd >= 1.7.1 */
|
||||||
|
g_dbus_proxy_call(priv->proxy,
|
||||||
|
"SetHints",
|
||||||
|
g_variant_new("(a{ss})", &builder),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
FWUPD_CLIENT_DBUS_PROXY_TIMEOUT,
|
||||||
|
cancellable,
|
||||||
|
fwupd_client_set_hints_cb,
|
||||||
|
g_steal_pointer(&task));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4794,6 +4839,27 @@ fwupd_client_upload_bytes_finish(FwupdClient *self, GAsyncResult *res, GError **
|
|||||||
return g_task_propagate_pointer(G_TASK(res), error);
|
return g_task_propagate_pointer(G_TASK(res), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fwupd_client_add_hint:
|
||||||
|
* @self: a #FwupdClient
|
||||||
|
* @key: the key, e.g. `locale`
|
||||||
|
* @value: (nullable): the value @key should be set
|
||||||
|
*
|
||||||
|
* Sets optional hints from the client that may affect the list of devices.
|
||||||
|
*
|
||||||
|
* Since: 1.7.1
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
fwupd_client_add_hint(FwupdClient *self, const gchar *key, const gchar *value)
|
||||||
|
{
|
||||||
|
FwupdClientPrivate *priv = GET_PRIVATE(self);
|
||||||
|
|
||||||
|
g_return_if_fail(FWUPD_IS_CLIENT(self));
|
||||||
|
g_return_if_fail(key != NULL);
|
||||||
|
|
||||||
|
g_hash_table_insert(priv->hints, g_strdup(key), g_strdup(value));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SOUP_SESSION_COMPAT
|
#ifdef SOUP_SESSION_COMPAT
|
||||||
/* this is bad; we dlopen libsoup-2.4.so.1 and get the gtype manually
|
/* this is bad; we dlopen libsoup-2.4.so.1 and get the gtype manually
|
||||||
* to avoid deps on both libcurl and libsoup whilst preserving ABI */
|
* to avoid deps on both libcurl and libsoup whilst preserving ABI */
|
||||||
@ -5177,6 +5243,10 @@ fwupd_client_init(FwupdClient *self)
|
|||||||
priv->idle_sources =
|
priv->idle_sources =
|
||||||
g_ptr_array_new_with_free_func((GDestroyNotify)fwupd_client_context_helper_free);
|
g_ptr_array_new_with_free_func((GDestroyNotify)fwupd_client_context_helper_free);
|
||||||
priv->proxy_resolver = g_proxy_resolver_get_default();
|
priv->proxy_resolver = g_proxy_resolver_get_default();
|
||||||
|
priv->hints = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
|
||||||
|
/* we get this one for free */
|
||||||
|
fwupd_client_add_hint(self, "locale", g_getenv("LANG"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -5191,6 +5261,7 @@ fwupd_client_finalize(GObject *object)
|
|||||||
g_free(priv->host_product);
|
g_free(priv->host_product);
|
||||||
g_free(priv->host_machine_id);
|
g_free(priv->host_machine_id);
|
||||||
g_free(priv->host_security_id);
|
g_free(priv->host_security_id);
|
||||||
|
g_hash_table_unref(priv->hints);
|
||||||
g_mutex_clear(&priv->idle_mutex);
|
g_mutex_clear(&priv->idle_mutex);
|
||||||
if (priv->idle_id != 0)
|
if (priv->idle_id != 0)
|
||||||
g_source_remove(priv->idle_id);
|
g_source_remove(priv->idle_id);
|
||||||
|
@ -478,5 +478,7 @@ fwupd_client_upload_bytes_finish(FwupdClient *self,
|
|||||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
gboolean
|
gboolean
|
||||||
fwupd_client_ensure_networking(FwupdClient *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
fwupd_client_ensure_networking(FwupdClient *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
void
|
||||||
|
fwupd_client_add_hint(FwupdClient *self, const gchar *key, const gchar *value);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -709,3 +709,9 @@ LIBFWUPD_1.7.0 {
|
|||||||
fwupd_security_attr_has_guid;
|
fwupd_security_attr_has_guid;
|
||||||
local: *;
|
local: *;
|
||||||
} LIBFWUPD_1.6.2;
|
} LIBFWUPD_1.6.2;
|
||||||
|
|
||||||
|
LIBFWUPD_1.7.1 {
|
||||||
|
global:
|
||||||
|
fwupd_client_add_hint;
|
||||||
|
local: *;
|
||||||
|
} LIBFWUPD_1.7.0;
|
||||||
|
@ -15,6 +15,7 @@ struct _FuEngineRequest {
|
|||||||
FuEngineRequestKind kind;
|
FuEngineRequestKind kind;
|
||||||
FwupdFeatureFlags feature_flags;
|
FwupdFeatureFlags feature_flags;
|
||||||
FwupdDeviceFlags device_flags;
|
FwupdDeviceFlags device_flags;
|
||||||
|
gchar *locale;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(FuEngineRequest, fu_engine_request, G_TYPE_OBJECT)
|
G_DEFINE_TYPE(FuEngineRequest, fu_engine_request, G_TYPE_OBJECT)
|
||||||
@ -26,6 +27,13 @@ fu_engine_request_get_feature_flags(FuEngineRequest *self)
|
|||||||
return self->feature_flags;
|
return self->feature_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gchar *
|
||||||
|
fu_engine_request_get_locale(FuEngineRequest *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(FU_IS_ENGINE_REQUEST(self), NULL);
|
||||||
|
return self->locale;
|
||||||
|
}
|
||||||
|
|
||||||
FuEngineRequestKind
|
FuEngineRequestKind
|
||||||
fu_engine_request_get_kind(FuEngineRequest *self)
|
fu_engine_request_get_kind(FuEngineRequest *self)
|
||||||
{
|
{
|
||||||
@ -40,6 +48,17 @@ fu_engine_request_set_feature_flags(FuEngineRequest *self, FwupdFeatureFlags fea
|
|||||||
self->feature_flags = feature_flags;
|
self->feature_flags = feature_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fu_engine_request_set_locale(FuEngineRequest *self, const gchar *locale)
|
||||||
|
{
|
||||||
|
g_return_if_fail(FU_IS_ENGINE_REQUEST(self));
|
||||||
|
self->locale = g_strdup(locale);
|
||||||
|
|
||||||
|
/* remove the UTF8 suffix as it is not present in the XML */
|
||||||
|
if (self->locale != NULL)
|
||||||
|
g_strdelimit(self->locale, ".", '\0');
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
fu_engine_request_has_feature_flag(FuEngineRequest *self, FwupdFeatureFlags feature_flag)
|
fu_engine_request_has_feature_flag(FuEngineRequest *self, FwupdFeatureFlags feature_flag)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,10 @@ FwupdFeatureFlags
|
|||||||
fu_engine_request_get_feature_flags(FuEngineRequest *self);
|
fu_engine_request_get_feature_flags(FuEngineRequest *self);
|
||||||
void
|
void
|
||||||
fu_engine_request_set_feature_flags(FuEngineRequest *self, FwupdFeatureFlags feature_flags);
|
fu_engine_request_set_feature_flags(FuEngineRequest *self, FwupdFeatureFlags feature_flags);
|
||||||
|
const gchar *
|
||||||
|
fu_engine_request_get_locale(FuEngineRequest *self);
|
||||||
|
void
|
||||||
|
fu_engine_request_set_locale(FuEngineRequest *self, const gchar *locale);
|
||||||
gboolean
|
gboolean
|
||||||
fu_engine_request_has_feature_flag(FuEngineRequest *self, FwupdFeatureFlags feature_flag);
|
fu_engine_request_has_feature_flag(FuEngineRequest *self, FwupdFeatureFlags feature_flag);
|
||||||
FwupdDeviceFlags
|
FwupdDeviceFlags
|
||||||
|
@ -452,6 +452,25 @@ fu_engine_set_release_from_artifact(FuEngine *self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
fu_engine_request_get_localized_xpath(FuEngineRequest *request, const gchar *element)
|
||||||
|
{
|
||||||
|
GString *xpath = g_string_new(element);
|
||||||
|
const gchar *locale = NULL;
|
||||||
|
|
||||||
|
/* optional; not set in tests */
|
||||||
|
if (request != NULL)
|
||||||
|
locale = fu_engine_request_get_locale(request);
|
||||||
|
|
||||||
|
/* prefer the users locale if set */
|
||||||
|
if (locale != NULL) {
|
||||||
|
g_autofree gchar *xpath_locale = NULL;
|
||||||
|
xpath_locale = g_strdup_printf("%s[@xml:lang='%s']|", element, locale);
|
||||||
|
g_string_prepend(xpath, xpath_locale);
|
||||||
|
}
|
||||||
|
return g_string_free(xpath, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_engine_set_release_from_appstream(FuEngine *self,
|
fu_engine_set_release_from_appstream(FuEngine *self,
|
||||||
FuEngineRequest *request,
|
FuEngineRequest *request,
|
||||||
@ -465,6 +484,7 @@ fu_engine_set_release_from_appstream(FuEngine *self,
|
|||||||
const gchar *tmp;
|
const gchar *tmp;
|
||||||
const gchar *remote_id;
|
const gchar *remote_id;
|
||||||
guint64 tmp64;
|
guint64 tmp64;
|
||||||
|
g_autofree gchar *description_xpath = NULL;
|
||||||
g_autofree gchar *version_rel = NULL;
|
g_autofree gchar *version_rel = NULL;
|
||||||
g_autoptr(GPtrArray) cats = NULL;
|
g_autoptr(GPtrArray) cats = NULL;
|
||||||
g_autoptr(GPtrArray) issues = NULL;
|
g_autoptr(GPtrArray) issues = NULL;
|
||||||
@ -516,7 +536,8 @@ fu_engine_set_release_from_appstream(FuEngine *self,
|
|||||||
if (!fu_engine_set_release_from_artifact(self, rel, remote, artifact, error))
|
if (!fu_engine_set_release_from_artifact(self, rel, remote, artifact, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
description = xb_node_query_first(release, "description", NULL);
|
description_xpath = fu_engine_request_get_localized_xpath(request, "description");
|
||||||
|
description = xb_node_query_first(release, description_xpath, NULL);
|
||||||
if (description != NULL) {
|
if (description != NULL) {
|
||||||
g_autofree gchar *xml = NULL;
|
g_autofree gchar *xml = NULL;
|
||||||
g_autoptr(GString) str = NULL;
|
g_autoptr(GString) str = NULL;
|
||||||
@ -4209,6 +4230,7 @@ fu_engine_get_result_from_component(FuEngine *self,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FwupdReleaseFlags release_flags = FWUPD_RELEASE_FLAG_NONE;
|
FwupdReleaseFlags release_flags = FWUPD_RELEASE_FLAG_NONE;
|
||||||
|
g_autofree gchar *description_xpath = NULL;
|
||||||
g_autoptr(FuInstallTask) task = NULL;
|
g_autoptr(FuInstallTask) task = NULL;
|
||||||
g_autoptr(FuDevice) dev = NULL;
|
g_autoptr(FuDevice) dev = NULL;
|
||||||
g_autoptr(FwupdRelease) rel = NULL;
|
g_autoptr(FwupdRelease) rel = NULL;
|
||||||
@ -4300,7 +4322,8 @@ fu_engine_get_result_from_component(FuEngine *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create a result with all the metadata in */
|
/* create a result with all the metadata in */
|
||||||
description = xb_node_query_first(component, "description", NULL);
|
description_xpath = fu_engine_request_get_localized_xpath(request, "description");
|
||||||
|
description = xb_node_query_first(component, description_xpath, NULL);
|
||||||
if (description != NULL) {
|
if (description != NULL) {
|
||||||
g_autofree gchar *xml = NULL;
|
g_autofree gchar *xml = NULL;
|
||||||
xml = xb_node_export(description, XB_NODE_EXPORT_FLAG_ONLY_CHILDREN, NULL);
|
xml = xb_node_export(description, XB_NODE_EXPORT_FLAG_ONLY_CHILDREN, NULL);
|
||||||
|
@ -58,13 +58,18 @@ typedef enum {
|
|||||||
FU_MAIN_MACHINE_KIND_CONTAINER,
|
FU_MAIN_MACHINE_KIND_CONTAINER,
|
||||||
} FuMainMachineKind;
|
} FuMainMachineKind;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FwupdFeatureFlags feature_flags;
|
||||||
|
GHashTable *hints; /* str:str */
|
||||||
|
} FuSenderItem;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GDBusConnection *connection;
|
GDBusConnection *connection;
|
||||||
GDBusNodeInfo *introspection_daemon;
|
GDBusNodeInfo *introspection_daemon;
|
||||||
GDBusProxy *proxy_uid;
|
GDBusProxy *proxy_uid;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
GFileMonitor *argv0_monitor;
|
GFileMonitor *argv0_monitor;
|
||||||
GHashTable *sender_features; /* sender:FwupdFeatureFlags */
|
GHashTable *sender_items; /* sender:FuSenderItem */
|
||||||
#if GLIB_CHECK_VERSION(2, 63, 3)
|
#if GLIB_CHECK_VERSION(2, 63, 3)
|
||||||
GMemoryMonitor *memory_monitor;
|
GMemoryMonitor *memory_monitor;
|
||||||
#endif
|
#endif
|
||||||
@ -235,7 +240,7 @@ fu_main_engine_percentage_changed_cb(FuEngine *engine, guint percentage, FuMainP
|
|||||||
static FuEngineRequest *
|
static FuEngineRequest *
|
||||||
fu_main_create_request(FuMainPrivate *priv, const gchar *sender, GError **error)
|
fu_main_create_request(FuMainPrivate *priv, const gchar *sender, GError **error)
|
||||||
{
|
{
|
||||||
FwupdFeatureFlags *feature_flags;
|
FuSenderItem *sender_item;
|
||||||
FwupdDeviceFlags device_flags = FWUPD_DEVICE_FLAG_NONE;
|
FwupdDeviceFlags device_flags = FWUPD_DEVICE_FLAG_NONE;
|
||||||
uid_t calling_uid = 0;
|
uid_t calling_uid = 0;
|
||||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||||
@ -243,10 +248,14 @@ fu_main_create_request(FuMainPrivate *priv, const gchar *sender, GError **error)
|
|||||||
|
|
||||||
g_return_val_if_fail(sender != NULL, NULL);
|
g_return_val_if_fail(sender != NULL, NULL);
|
||||||
|
|
||||||
/* did the client set the list of supported feature */
|
/* did the client set the list of supported features or any hints */
|
||||||
feature_flags = g_hash_table_lookup(priv->sender_features, sender);
|
sender_item = g_hash_table_lookup(priv->sender_items, sender);
|
||||||
if (feature_flags != NULL)
|
if (sender_item != NULL) {
|
||||||
fu_engine_request_set_feature_flags(request, *feature_flags);
|
const gchar *locale = g_hash_table_lookup(sender_item->hints, "locale");
|
||||||
|
if (locale != NULL)
|
||||||
|
fu_engine_request_set_locale(request, locale);
|
||||||
|
fu_engine_request_set_feature_flags(request, sender_item->feature_flags);
|
||||||
|
}
|
||||||
|
|
||||||
/* are we root and therefore trusted? */
|
/* are we root and therefore trusted? */
|
||||||
value = g_dbus_proxy_call_sync(priv->proxy_uid,
|
value = g_dbus_proxy_call_sync(priv->proxy_uid,
|
||||||
@ -906,6 +915,19 @@ fu_main_install_with_helper(FuMainAuthHelper *helper_ref, GError **error)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FuSenderItem *
|
||||||
|
fu_main_ensure_sender_item(FuMainPrivate *priv, const gchar *sender)
|
||||||
|
{
|
||||||
|
FuSenderItem *sender_item;
|
||||||
|
sender_item = g_hash_table_lookup(priv->sender_items, sender);
|
||||||
|
if (sender_item == NULL) {
|
||||||
|
sender_item = g_new0(FuSenderItem, 1);
|
||||||
|
sender_item->hints = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
g_hash_table_insert(priv->sender_items, g_strdup(sender), sender_item);
|
||||||
|
}
|
||||||
|
return sender_item;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_main_device_id_valid(const gchar *device_id, GError **error)
|
fu_main_device_id_valid(const gchar *device_id, GError **error)
|
||||||
{
|
{
|
||||||
@ -1510,23 +1532,37 @@ fu_main_daemon_method_call(GDBusConnection *connection,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (g_strcmp0(method_name, "SetFeatureFlags") == 0) {
|
if (g_strcmp0(method_name, "SetFeatureFlags") == 0) {
|
||||||
FwupdFeatureFlags feature_flags;
|
FuSenderItem *sender_item;
|
||||||
guint64 feature_flags_u64 = 0;
|
guint64 feature_flags_u64 = 0;
|
||||||
|
|
||||||
g_variant_get(parameters, "(t)", &feature_flags_u64);
|
g_variant_get(parameters, "(t)", &feature_flags_u64);
|
||||||
g_debug("Called %s(%" G_GUINT64_FORMAT ")", method_name, feature_flags_u64);
|
g_debug("Called %s(%" G_GUINT64_FORMAT ")", method_name, feature_flags_u64);
|
||||||
|
|
||||||
/* old flags for the same sender will be automatically destroyed */
|
/* old flags for the same sender will be automatically destroyed */
|
||||||
feature_flags = feature_flags_u64;
|
sender_item = fu_main_ensure_sender_item(priv, sender);
|
||||||
g_hash_table_insert(priv->sender_features,
|
sender_item->feature_flags = feature_flags_u64;
|
||||||
g_strdup(sender),
|
|
||||||
#if GLIB_CHECK_VERSION(2, 67, 4)
|
|
||||||
g_memdup2(&feature_flags, sizeof(feature_flags)));
|
|
||||||
#else
|
|
||||||
g_memdup(&feature_flags, sizeof(feature_flags)));
|
|
||||||
#endif
|
|
||||||
g_dbus_method_invocation_return_value(invocation, NULL);
|
g_dbus_method_invocation_return_value(invocation, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (g_strcmp0(method_name, "SetHints") == 0) {
|
||||||
|
FuSenderItem *sender_item;
|
||||||
|
const gchar *prop_key;
|
||||||
|
const gchar *prop_value;
|
||||||
|
g_autoptr(GVariantIter) iter = NULL;
|
||||||
|
|
||||||
|
g_variant_get(parameters, "(a{ss})", &iter);
|
||||||
|
g_debug("Called %s()", method_name);
|
||||||
|
sender_item = fu_main_ensure_sender_item(priv, sender);
|
||||||
|
while (g_variant_iter_next(iter, "{&s&s}", &prop_key, &prop_value)) {
|
||||||
|
g_debug("got hint %s=%s", prop_key, prop_value);
|
||||||
|
g_hash_table_insert(sender_item->hints,
|
||||||
|
g_strdup(prop_key),
|
||||||
|
g_strdup(prop_value));
|
||||||
|
}
|
||||||
|
g_dbus_method_invocation_return_value(invocation, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_strcmp0(method_name, "Install") == 0) {
|
if (g_strcmp0(method_name, "Install") == 0) {
|
||||||
GVariant *prop_value;
|
GVariant *prop_value;
|
||||||
const gchar *device_id = NULL;
|
const gchar *device_id = NULL;
|
||||||
@ -1845,7 +1881,7 @@ fu_main_is_container(void)
|
|||||||
static void
|
static void
|
||||||
fu_main_private_free(FuMainPrivate *priv)
|
fu_main_private_free(FuMainPrivate *priv)
|
||||||
{
|
{
|
||||||
g_hash_table_unref(priv->sender_features);
|
g_hash_table_unref(priv->sender_items);
|
||||||
if (priv->loop != NULL)
|
if (priv->loop != NULL)
|
||||||
g_main_loop_unref(priv->loop);
|
g_main_loop_unref(priv->loop);
|
||||||
if (priv->owner_id > 0)
|
if (priv->owner_id > 0)
|
||||||
@ -1878,6 +1914,13 @@ fu_main_private_free(FuMainPrivate *priv)
|
|||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(FuMainPrivate, fu_main_private_free)
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(FuMainPrivate, fu_main_private_free)
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_main_sender_item_free(FuSenderItem *sender_item)
|
||||||
|
{
|
||||||
|
g_hash_table_unref(sender_item->hints);
|
||||||
|
g_free(sender_item);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -1926,7 +1969,10 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* create new objects */
|
/* create new objects */
|
||||||
priv = g_new0(FuMainPrivate, 1);
|
priv = g_new0(FuMainPrivate, 1);
|
||||||
priv->sender_features = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
priv->sender_items = g_hash_table_new_full(g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
(GDestroyNotify)fu_main_sender_item_free);
|
||||||
priv->loop = g_main_loop_new(NULL, FALSE);
|
priv->loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
|
||||||
/* load engine */
|
/* load engine */
|
||||||
|
@ -307,6 +307,25 @@
|
|||||||
</arg>
|
</arg>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<!--***********************************************************-->
|
||||||
|
<method name='SetHints'>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>
|
||||||
|
Sets optional hints from the client that may affect the list of devices.
|
||||||
|
A typical hint might be <doc:tt>locale</doc:tt> and unknown hints should be ignored.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
<arg type='a{ss}' name='hints' direction='in'>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>
|
||||||
|
<doc:para>An array of string key values.</doc:para>
|
||||||
|
</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
<!--***********************************************************-->
|
<!--***********************************************************-->
|
||||||
<method name='Install'>
|
<method name='Install'>
|
||||||
<doc:doc>
|
<doc:doc>
|
||||||
|
Loading…
Reference in New Issue
Block a user