Return the device properties when calling GetDevices()

This allows us to discover a version number, and other things.
This commit is contained in:
Richard Hughes 2015-03-02 22:44:48 +00:00
parent 74cc217f9d
commit 1ffde6cd72
8 changed files with 142 additions and 65 deletions

View File

@ -21,6 +21,8 @@ AM_CPPFLAGS = \
bin_PROGRAMS = fwupdmgr bin_PROGRAMS = fwupdmgr
fwupdmgr_SOURCES = \ fwupdmgr_SOURCES = \
fu-device.c \
fu-device.h \
fu-util.c fu-util.c
fwupdmgr_LDADD = \ fwupdmgr_LDADD = \

View File

@ -29,4 +29,7 @@
#define FU_ERROR 1 #define FU_ERROR 1
#define FU_ERROR_INTERNAL 0 #define FU_ERROR_INTERNAL 0
#define FU_DEVICE_KEY_VERSION "Version"
#define FU_DEVICE_KEY_PROVIDER "Provider"
#endif /* __FU_COMMON_H */ #endif /* __FU_COMMON_H */

View File

@ -40,6 +40,7 @@ static void fu_device_finalize (GObject *object);
struct _FuDevicePrivate struct _FuDevicePrivate
{ {
gchar *id; gchar *id;
GHashTable *metadata;
}; };
enum { enum {
@ -76,6 +77,75 @@ fu_device_set_id (FuDevice *device, const gchar *id)
device->priv->id = g_strdup (id); device->priv->id = g_strdup (id);
} }
/**
* fu_device_get_metadata:
**/
const gchar *
fu_device_get_metadata (FuDevice *device, const gchar *key)
{
g_return_val_if_fail (FU_IS_DEVICE (device), NULL);
g_return_val_if_fail (key != NULL, NULL);
return g_hash_table_lookup (device->priv->metadata, key);
}
/**
* fu_device_get_id:
**/
void
fu_device_set_metadata (FuDevice *device, const gchar *key, const gchar *value)
{
g_return_if_fail (FU_IS_DEVICE (device));
g_return_if_fail (key != NULL);
g_return_if_fail (value != NULL);
g_hash_table_insert (device->priv->metadata, g_strdup (key), g_strdup (value));
}
/**
* fu_device_to_variant:
**/
GVariant *
fu_device_to_variant (FuDevice *device)
{
GList *l;
GVariantBuilder builder;
const gchar *key;
const gchar *value;
_cleanup_list_free_ GList *keys = NULL;
/* create an array with all the metadata in */
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
keys = g_hash_table_get_keys (device->priv->metadata);
for (l = keys; l != NULL; l = l->next) {
key = l->data;
value = g_hash_table_lookup (device->priv->metadata, key);
g_variant_builder_add (&builder, "{sv}",
key, g_variant_new_string (value));
}
return g_variant_new ("{sa{sv}}", device->priv->id, &builder);
}
/**
* fu_device_set_metadata_from_iter:
**/
void
fu_device_set_metadata_from_iter (FuDevice *device, GVariantIter *iter)
{
GVariant *variant;
const gchar *key;
const gchar *type;
while (g_variant_iter_next (iter, "{&sv}", &key, &variant)) {
type = g_variant_get_type_string (variant);
if (g_strcmp0 (type, "s") == 0) {
fu_device_set_metadata (device, key,
g_variant_get_string (variant, NULL));
} else {
fu_device_set_metadata (device, key, "???");
}
g_variant_unref (variant);
}
}
/** /**
* fu_device_get_property: * fu_device_get_property:
**/ **/
@ -145,6 +215,8 @@ static void
fu_device_init (FuDevice *device) fu_device_init (FuDevice *device)
{ {
device->priv = FU_DEVICE_GET_PRIVATE (device); device->priv = FU_DEVICE_GET_PRIVATE (device);
device->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
} }
/** /**
@ -157,6 +229,7 @@ fu_device_finalize (GObject *object)
FuDevicePrivate *priv = device->priv; FuDevicePrivate *priv = device->priv;
g_free (priv->id); g_free (priv->id);
g_hash_table_unref (priv->metadata);
G_OBJECT_CLASS (fu_device_parent_class)->finalize (object); G_OBJECT_CLASS (fu_device_parent_class)->finalize (object);
} }

View File

@ -53,9 +53,17 @@ GType fu_device_get_type (void);
FuDevice *fu_device_new (void); FuDevice *fu_device_new (void);
/* accessors */ /* accessors */
GVariant *fu_device_to_variant (FuDevice *device);
const gchar *fu_device_get_id (FuDevice *device); const gchar *fu_device_get_id (FuDevice *device);
void fu_device_set_id (FuDevice *device, void fu_device_set_id (FuDevice *device,
const gchar *id); const gchar *id);
const gchar *fu_device_get_metadata (FuDevice *device,
const gchar *key);
void fu_device_set_metadata (FuDevice *device,
const gchar *key,
const gchar *value);
void fu_device_set_metadata_from_iter (FuDevice *device,
GVariantIter *iter);
G_END_DECLS G_END_DECLS

View File

@ -50,21 +50,23 @@ typedef struct {
} FuDeviceItem; } FuDeviceItem;
/** /**
* fu_main_get_device_list_as_strv: * fu_device_to_variants:
**/ **/
static gchar ** static GVariant *
fu_main_get_device_list_as_strv (FuMainPrivate *priv) fu_device_to_variants (FuMainPrivate *priv)
{ {
gchar **val; GVariantBuilder builder;
guint i; guint i;
FuDevice *dev_tmp;
val = g_new0 (gchar *, priv->devices->len + 1); g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
for (i = 0; i < priv->devices->len; i++) { for (i = 0; i < priv->devices->len; i++) {
dev_tmp = g_ptr_array_index (priv->devices, i); GVariant *tmp;
val[i] = g_strdup (fu_device_get_id (dev_tmp)); FuDeviceItem *item;
item = g_ptr_array_index (priv->devices, i);
tmp = fu_device_to_variant (item->device);
g_variant_builder_add_value (&builder, tmp);
} }
return val; return g_variant_new ("(a{sa{sv}})", &builder);
} }
/** /**
@ -163,8 +165,9 @@ fu_main_check_authorization_cb (GObject *source, GAsyncResult *res, gpointer use
/* run the correct provider that added this */ /* run the correct provider that added this */
if (!fu_provider_update (item->provider, if (!fu_provider_update (item->provider,
item->device, item->device,
helper->fd,
helper->flags, helper->flags,
helper->fd, &error)) { &error)) {
g_dbus_method_invocation_return_gerror (helper->invocation, g_dbus_method_invocation_return_gerror (helper->invocation,
error); error);
fu_main_helper_free (helper); fu_main_helper_free (helper);
@ -192,8 +195,7 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
if (g_strcmp0 (method_name, "GetDevices") == 0) { if (g_strcmp0 (method_name, "GetDevices") == 0) {
_cleanup_strv_free_ gchar **devices = NULL; _cleanup_strv_free_ gchar **devices = NULL;
g_debug ("Called %s()", method_name); g_debug ("Called %s()", method_name);
devices = fu_main_get_device_list_as_strv (priv); val = fu_device_to_variants (priv);
val = g_variant_new ("(^as)", devices);
g_dbus_method_invocation_return_value (invocation, val); g_dbus_method_invocation_return_value (invocation, val);
return; return;
} }
@ -234,6 +236,7 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
if (g_strcmp0 (prop_key, "offline") == 0 && if (g_strcmp0 (prop_key, "offline") == 0 &&
g_variant_get_boolean (prop_value) == TRUE) g_variant_get_boolean (prop_value) == TRUE)
flags |= FU_PROVIDER_UPDATE_FLAG_OFFLINE; flags |= FU_PROVIDER_UPDATE_FLAG_OFFLINE;
g_variant_unref (prop_value);
} }
/* get the fd */ /* get the fd */

View File

@ -31,40 +31,8 @@
static void fu_provider_uefi_finalize (GObject *object); static void fu_provider_uefi_finalize (GObject *object);
#define FU_PROVIDER_UEFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FU_TYPE_PROVIDER_UEFI, FuProviderUefiPrivate))
/**
* FuProviderUefiPrivate:
**/
struct _FuProviderUefiPrivate
{
GPtrArray *array_devices;
};
G_DEFINE_TYPE (FuProviderUefi, fu_provider_uefi, FU_TYPE_PROVIDER) G_DEFINE_TYPE (FuProviderUefi, fu_provider_uefi, FU_TYPE_PROVIDER)
/**
* fu_provider_uefi_get_by_id:
**/
static FuDevice *
fu_provider_uefi_get_by_id (FuProviderUefi *provider_uefi,
const gchar *device_id)
{
FuProviderUefiPrivate *priv = provider_uefi->priv;
FuDevice *device = NULL;
FuDevice *device_tmp;
guint i;
for (i = 0; i < priv->array_devices->len; i++) {
device_tmp = g_ptr_array_index (priv->array_devices, i);
if (g_strcmp0 (fu_device_get_id (device_tmp), device_id) == 0) {
device = g_object_ref (device_tmp);
break;
}
}
return device;
}
/** /**
* fu_provider_uefi_update: * fu_provider_uefi_update:
**/ **/
@ -75,8 +43,6 @@ fu_provider_uefi_update (FuProvider *provider,
FuProviderFlags flags, FuProviderFlags flags,
GError **error) GError **error)
{ {
// FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (provider);
/* this only makes sense offline */ /* this only makes sense offline */
if ((flags & FU_PROVIDER_UPDATE_FLAG_OFFLINE) == 0) { if ((flags & FU_PROVIDER_UPDATE_FLAG_OFFLINE) == 0) {
g_set_error_literal (error, g_set_error_literal (error,
@ -97,13 +63,14 @@ fu_provider_uefi_update (FuProvider *provider,
static gboolean static gboolean
fu_provider_uefi_coldplug (FuProvider *provider, GError **error) fu_provider_uefi_coldplug (FuProvider *provider, GError **error)
{ {
// FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (provider);
_cleanup_object_unref_ FuDevice *dev = NULL; _cleanup_object_unref_ FuDevice *dev = NULL;
//FIXME //FIXME
g_debug ("Adding fake UEFI device"); g_debug ("Adding fake UEFI device");
dev = fu_device_new (); dev = fu_device_new ();
fu_device_set_id (dev, "UEFI-819b858e-c52c-402f-80e1-5b311b6c1959-dev1"); fu_device_set_id (dev, "UEFI-819b858e-c52c-402f-80e1-5b311b6c1959-dev1");
fu_device_set_metadata (dev, FU_DEVICE_KEY_PROVIDER, "UEFI");
fu_device_set_metadata (dev, FU_DEVICE_KEY_VERSION, "12345");
fu_provider_emit_added (provider, dev); fu_provider_emit_added (provider, dev);
return TRUE; return TRUE;
} }
@ -120,8 +87,6 @@ fu_provider_uefi_class_init (FuProviderUefiClass *klass)
provider_class->coldplug = fu_provider_uefi_coldplug; provider_class->coldplug = fu_provider_uefi_coldplug;
provider_class->update = fu_provider_uefi_update; provider_class->update = fu_provider_uefi_update;
object_class->finalize = fu_provider_uefi_finalize; object_class->finalize = fu_provider_uefi_finalize;
g_type_class_add_private (klass, sizeof (FuProviderUefiPrivate));
} }
/** /**
@ -130,8 +95,6 @@ fu_provider_uefi_class_init (FuProviderUefiClass *klass)
static void static void
fu_provider_uefi_init (FuProviderUefi *provider_uefi) fu_provider_uefi_init (FuProviderUefi *provider_uefi)
{ {
provider_uefi->priv = FU_PROVIDER_UEFI_GET_PRIVATE (provider_uefi);
provider_uefi->priv->array_devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
} }
/** /**
@ -140,11 +103,6 @@ fu_provider_uefi_init (FuProviderUefi *provider_uefi)
static void static void
fu_provider_uefi_finalize (GObject *object) fu_provider_uefi_finalize (GObject *object)
{ {
FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (object);
FuProviderUefiPrivate *priv = provider_uefi->priv;
g_ptr_array_unref (priv->array_devices);
G_OBJECT_CLASS (fu_provider_uefi_parent_class)->finalize (object); G_OBJECT_CLASS (fu_provider_uefi_parent_class)->finalize (object);
} }

View File

@ -194,11 +194,14 @@ fu_util_run (FuUtilPrivate *priv, const gchar *command, gchar **values, GError *
static gboolean static gboolean
fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error) fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
{ {
GVariantIter *iter_device;
FuDevice *dev;
gchar *id;
_cleanup_ptrarray_unref_ GPtrArray *devices = NULL;
_cleanup_object_unref_ GDBusConnection *conn = NULL; _cleanup_object_unref_ GDBusConnection *conn = NULL;
_cleanup_object_unref_ GDBusProxy *proxy = NULL; _cleanup_object_unref_ GDBusProxy *proxy = NULL;
_cleanup_variant_iter_free_ GVariantIter *iter = NULL;
_cleanup_variant_unref_ GVariant *val = NULL; _cleanup_variant_unref_ GVariant *val = NULL;
const gchar **ids = NULL;
guint i;
conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
if (conn == NULL) if (conn == NULL)
@ -222,12 +225,39 @@ fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
error); error);
if (val == NULL) if (val == NULL)
return FALSE; return FALSE;
g_variant_get (val, "(^a&s)", &ids);
g_assert (ids != NULL); /* parse */
if (ids[0] == NULL) g_variant_get (val, "(a{sa{sv}})", &iter);
devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
while (g_variant_iter_next (iter, "{&sa{sv}}", &id, &iter_device)) {
dev = fu_device_new ();
fu_device_set_id (dev, id);
fu_device_set_metadata_from_iter (dev, iter_device);
g_ptr_array_add (devices, dev);
g_variant_iter_free (iter_device);
}
/* print */
if (devices->len == 0) {
g_print ("No hardware detected with firmware update capaility\n"); g_print ("No hardware detected with firmware update capaility\n");
for (i = 0; ids[i] != NULL; i++) } else {
g_print ("%i: %s\n", i, ids[i]); guint i;
guint j;
const gchar *value;
const gchar *keys[] = {
FU_DEVICE_KEY_PROVIDER,
FU_DEVICE_KEY_VERSION,
NULL };
for (i = 0; i < devices->len; i++) {
dev = g_ptr_array_index (devices, i);
g_print ("Device: %s\n", fu_device_get_id (dev));
for (j = 0; keys[j] != NULL; j++) {
value = fu_device_get_metadata (dev, keys[j]);
if (value != NULL)
g_print (" %s:\t%s\n", keys[j], value);
}
}
}
return TRUE; return TRUE;
} }

View File

@ -31,10 +31,10 @@
</doc:para> </doc:para>
</doc:description> </doc:description>
</doc:doc> </doc:doc>
<arg type='as' name='ids' direction='out'> <arg type='a{sa{sv}}' name='devices' direction='out'>
<doc:doc> <doc:doc>
<doc:summary> <doc:summary>
<doc:para>An array of IDs.</doc:para> <doc:para>An array of devices, with any properties set on each.</doc:para>
</doc:summary> </doc:summary>
</doc:doc> </doc:doc>
</arg> </arg>