diff --git a/src/fu-device-list.c b/src/fu-device-list.c new file mode 100644 index 000000000..4fc6ddb71 --- /dev/null +++ b/src/fu-device-list.c @@ -0,0 +1,272 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2017 Richard Hughes + * + * Licensed under the GNU Lesser General Public License Version 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include + +#include "fu-device-list.h" + +#include "fwupd-error.h" + +/** + * SECTION:fu-device-list + * @short_description: a list of devices + * + * This list of devices provides a way to find a device using either the + * device-id or a GUID. + * + * See also: #FuDevice + */ + +static void fu_device_list_finalize (GObject *obj); + +struct _FuDeviceList +{ + GObject parent_instance; + GPtrArray *devices; /* of FuDeviceItem */ +}; + +/* although this seems a waste of time, there are great plans for this... */ +typedef struct { + FuDevice *device; +} FuDeviceItem; + +G_DEFINE_TYPE (FuDeviceList, fu_device_list, G_TYPE_OBJECT) + +/** + * fu_device_list_get_all: + * @self: A #FuDeviceList + * + * Returns all the devices that have been added to the device list. + * + * Returns: (transfer container) (element-type FuDevice): the devices + * + * Since: 1.0.2 + **/ +GPtrArray * +fu_device_list_get_all (FuDeviceList *self) +{ + GPtrArray *devices; + g_return_val_if_fail (FU_IS_DEVICE_LIST (self), NULL); + devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + for (guint i = 0; i < self->devices->len; i++) { + FuDeviceItem *item = g_ptr_array_index (self->devices, i); + g_ptr_array_add (devices, g_object_ref (item->device)); + } + return devices; +} + +/** + * fu_device_list_remove: + * @self: A #FuDeviceList + * @device: A #FuDevice + * + * Removes a specific device from the list if it exists. + * + * Since: 1.0.2 + **/ +void +fu_device_list_remove (FuDeviceList *self, FuDevice *device) +{ + g_return_if_fail (FU_IS_DEVICE_LIST (self)); + g_return_if_fail (FU_IS_DEVICE (device)); + + for (guint i = 0; i < self->devices->len; i++) { + FuDeviceItem *item = g_ptr_array_index (self->devices, i); + if (item->device == device) { + g_ptr_array_remove (self->devices, item); + return; + } + } +} + +/** + * fu_device_list_add: + * @self: A #FuDeviceList + * @device: A #FuDevice + * @error: A #GError, or %NULL + * + * Adds a specific device to the device list. + * + * Returns: (transfer none): a device, or %NULL if not found + * + * Since: 1.0.2 + **/ +void +fu_device_list_add (FuDeviceList *self, FuDevice *device) +{ + FuDeviceItem *item; + + g_return_if_fail (FU_IS_DEVICE_LIST (self)); + g_return_if_fail (FU_IS_DEVICE (device)); + + /* FIXME: verify the device does not already exist */ + + /* add helper */ + item = g_new0 (FuDeviceItem, 1); + item->device = g_object_ref (device); + g_ptr_array_add (self->devices, item); +} + +/** + * fu_device_list_find_by_guid: + * @self: A #FuDeviceList + * @guid: A device GUID + * @error: A #GError, or %NULL + * + * Finds a specific device that has the matching GUID. + * + * Returns: (transfer none): a device, or %NULL if not found + * + * Since: 1.0.2 + **/ +FuDevice * +fu_device_list_find_by_guid (FuDeviceList *self, const gchar *guid, GError **error) +{ + g_return_val_if_fail (FU_IS_DEVICE_LIST (self), NULL); + g_return_val_if_fail (guid != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + for (guint i = 0; i < self->devices->len; i++) { + FuDeviceItem *item = g_ptr_array_index (self->devices, i); + if (fu_device_has_guid (item->device, guid)) + return item->device; + } + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_FOUND, + "GUID %s was not found", + guid); + return NULL; +} + +/** + * fu_device_list_find_by_id: + * @self: A #FuDeviceList + * @device_id: A device ID, typically a SHA1 hash + * @error: A #GError, or %NULL + * + * Finds a specific device using the ID string. This function also supports + * using abbreviated hashes. + * + * Returns: (transfer none): a device, or %NULL if not found + * + * Since: 1.0.2 + **/ +FuDevice * +fu_device_list_find_by_id (FuDeviceList *self, const gchar *device_id, GError **error) +{ + FuDeviceItem *item = NULL; + gboolean multiple_matches = FALSE; + gsize device_id_len; + + g_return_val_if_fail (FU_IS_DEVICE_LIST (self), NULL); + g_return_val_if_fail (device_id != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + /* support abbreviated hashes */ + device_id_len = strlen (device_id); + for (gsize i = 0; i < self->devices->len; i++) { + FuDeviceItem *item_tmp = g_ptr_array_index (self->devices, i); + const gchar *ids[] = { + fu_device_get_id (item_tmp->device), + fu_device_get_equivalent_id (item_tmp->device), + NULL }; + for (guint j = 0; ids[j] != NULL; j++) { + if (strncmp (ids[j], device_id, device_id_len) == 0) { + if (item != NULL) + multiple_matches = TRUE; + item = item_tmp; + } + } + } + + /* nothing at all matched */ + if (item == NULL) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_FOUND, + "device ID %s was not found", + device_id); + return NULL; + } + + /* multiple things matched */ + if (multiple_matches) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "device ID %s was not unique", + device_id); + return NULL; + } + + /* something found */ + return item->device; +} + +static void +fu_device_list_item_free (FuDeviceItem *item) +{ + g_object_unref (item->device); + g_free (item); +} + +static void +fu_device_list_class_init (FuDeviceListClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = fu_device_list_finalize; +} + +static void +fu_device_list_init (FuDeviceList *self) +{ + self->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_device_list_item_free); +} + +static void +fu_device_list_finalize (GObject *obj) +{ + FuDeviceList *self = FU_DEVICE_LIST (obj); + + g_ptr_array_unref (self->devices); + + G_OBJECT_CLASS (fu_device_list_parent_class)->finalize (obj); +} + +/** + * fu_device_list_new: + * + * Creates a new device list. + * + * Returns: (transfer full): a #FuDeviceList + * + * Since: 1.0.2 + **/ +FuDeviceList * +fu_device_list_new (void) +{ + FuDeviceList *self; + self = g_object_new (FU_TYPE_DEVICE_LIST, NULL); + return FU_DEVICE_LIST (self); +} diff --git a/src/fu-device-list.h b/src/fu-device-list.h new file mode 100644 index 000000000..a578e085e --- /dev/null +++ b/src/fu-device-list.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2017 Richard Hughes + * + * Licensed under the GNU Lesser General Public License Version 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __FU_DEVICE_LIST_H +#define __FU_DEVICE_LIST_H + +G_BEGIN_DECLS + +#include + +#include "fu-device.h" + +#define FU_TYPE_DEVICE_LIST (fu_device_list_get_type ()) +G_DECLARE_FINAL_TYPE (FuDeviceList, fu_device_list, FU, DEVICE_LIST, GObject) + +FuDeviceList *fu_device_list_new (void); +void fu_device_list_add (FuDeviceList *self, + FuDevice *device); +void fu_device_list_remove (FuDeviceList *self, + FuDevice *device); +GPtrArray *fu_device_list_get_all (FuDeviceList *self); +FuDevice *fu_device_list_find_by_id (FuDeviceList *self, + const gchar *device_id, + GError **error); +FuDevice *fu_device_list_find_by_guid (FuDeviceList *self, + const gchar *guid, + GError **error); + +G_END_DECLS + +#endif /* __FU_DEVICE_LIST_H */ + diff --git a/src/fu-engine.c b/src/fu-engine.c index 3fab25fe3..b432c343a 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -37,6 +37,7 @@ #include "fu-common.h" #include "fu-config.h" #include "fu-debug.h" +#include "fu-device-list.h" #include "fu-device-private.h" #include "fu-engine.h" #include "fu-hwids.h" @@ -62,7 +63,7 @@ struct _FuEngine GObject parent_instance; GUsbContext *usb_ctx; FuConfig *config; - GPtrArray *devices; /* of FuDeviceItem */ + FuDeviceList *device_list; FwupdStatus status; guint percentage; FuPending *pending; @@ -92,10 +93,6 @@ static guint signals[SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE (FuEngine, fu_engine, G_TYPE_OBJECT) -typedef struct { - FuDevice *device; -} FuDeviceItem; - static void fu_engine_emit_changed (FuEngine *self) { @@ -172,76 +169,6 @@ fu_engine_set_percentage (FuEngine *self, guint percentage) g_signal_emit (self, signals[SIGNAL_PERCENTAGE_CHANGED], 0, percentage); } -static void -fu_engine_item_free (FuDeviceItem *item) -{ - g_object_unref (item->device); - g_free (item); -} - -static FuDeviceItem * -fu_engine_get_item_by_id (FuEngine *self, const gchar *device_id, GError **error) -{ - FuDeviceItem *item = NULL; - gboolean multiple_matches = FALSE; - gsize device_id_len; - - g_return_val_if_fail (device_id != NULL, NULL); - - /* support abbreviated hashes */ - device_id_len = strlen (device_id); - for (gsize i = 0; i < self->devices->len; i++) { - FuDeviceItem *item_tmp = g_ptr_array_index (self->devices, i); - const gchar *ids[] = { - fu_device_get_id (item_tmp->device), - fu_device_get_equivalent_id (item_tmp->device), - NULL }; - for (guint j = 0; ids[j] != NULL; j++) { - if (ids[j] == NULL) - continue; - if (strncmp (ids[j], device_id, device_id_len) == 0) { - if (item != NULL) - multiple_matches = TRUE; - item = item_tmp; - } - } - } - - /* nothing at all matched */ - if (item == NULL) { - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_FOUND, - "device ID %s was not found", - device_id); - return NULL; - } - - /* multiple things matched */ - if (multiple_matches) { - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "device ID %s was not unique", - device_id); - return NULL; - } - - /* something found */ - return item; -} - -static FuDeviceItem * -fu_engine_get_item_by_guid (FuEngine *self, const gchar *guid) -{ - for (guint i = 0; i < self->devices->len; i++) { - FuDeviceItem *item = g_ptr_array_index (self->devices, i); - if (fu_device_has_guid (item->device, guid)) - return item; - } - return NULL; -} - static void fu_engine_set_release_from_appstream (FuEngine *self, FwupdRelease *rel, @@ -439,7 +366,7 @@ fu_engine_get_release_trust_flags (AsRelease *release, gboolean fu_engine_unlock (FuEngine *self, const gchar *device_id, GError **error) { - FuDeviceItem *item; + FuDevice *device; FuPlugin *plugin; g_return_val_if_fail (FU_IS_ENGINE (self), FALSE); @@ -447,25 +374,23 @@ fu_engine_unlock (FuEngine *self, const gchar *device_id, GError **error) g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* check the device exists */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return FALSE; /* get the plugin */ plugin = fu_plugin_list_find_by_name (self->plugin_list, - fu_device_get_plugin (item->device), + fu_device_get_plugin (device), error); if (plugin == NULL) return FALSE; /* run the correct plugin that added this */ - if (!fu_plugin_runner_unlock (plugin, - item->device, - error)) + if (!fu_plugin_runner_unlock (plugin, device, error)) return FALSE; /* make the UI update */ - fu_engine_emit_device_changed (self, item->device); + fu_engine_emit_device_changed (self, device); fu_engine_emit_changed (self); return TRUE; } @@ -595,7 +520,7 @@ fu_engine_modify_remote (FuEngine *self, gboolean fu_engine_verify_update (FuEngine *self, const gchar *device_id, GError **error) { - FuDeviceItem *item; + FuDevice *device; FuPlugin *plugin; GPtrArray *checksums; const gchar *fn = "/var/lib/fwupd/verify.xml"; @@ -608,26 +533,25 @@ fu_engine_verify_update (FuEngine *self, const gchar *device_id, GError **error) g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* check the devices still exists */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return FALSE; /* get the plugin */ plugin = fu_plugin_list_find_by_name (self->plugin_list, - fu_device_get_plugin (item->device), + fu_device_get_plugin (device), error); if (plugin == NULL) return FALSE; /* get the checksum */ - checksums = fu_device_get_checksums (item->device); + checksums = fu_device_get_checksums (device); if (checksums->len == 0) { - if (!fu_plugin_runner_verify (plugin, - item->device, + if (!fu_plugin_runner_verify (plugin, device, FU_PLUGIN_VERIFY_FLAG_NONE, error)) return FALSE; - fu_engine_emit_device_changed (self, item->device); + fu_engine_emit_device_changed (self, device); } /* we got nothing */ @@ -645,7 +569,7 @@ fu_engine_verify_update (FuEngine *self, const gchar *device_id, GError **error) return FALSE; /* add to store */ - app = fu_engine_verify_update_device_to_app (item->device); + app = fu_engine_verify_update_device_to_app (device); as_store_remove_app_by_id (store, as_app_get_id (app)); as_store_add_app (store, app); @@ -690,7 +614,7 @@ fu_engine_verify (FuEngine *self, const gchar *device_id, GError **error) AsApp *app; AsChecksum *csum; AsRelease *release; - FuDeviceItem *item = NULL; + FuDevice *device = NULL; FuPlugin *plugin; GPtrArray *checksums; const gchar *hash = NULL; @@ -702,19 +626,19 @@ fu_engine_verify (FuEngine *self, const gchar *device_id, GError **error) g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* check the id exists */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return FALSE; /* get the plugin */ plugin = fu_plugin_list_find_by_name (self->plugin_list, - fu_device_get_plugin (item->device), + fu_device_get_plugin (device), error); if (plugin == NULL) return FALSE; /* set the device firmware hash */ - if (!fu_plugin_runner_verify (plugin, item->device, + if (!fu_plugin_runner_verify (plugin, device, FU_PLUGIN_VERIFY_FLAG_NONE, error)) return FALSE; @@ -722,7 +646,7 @@ fu_engine_verify (FuEngine *self, const gchar *device_id, GError **error) store = fu_engine_load_verify_store (error); if (store == NULL) return FALSE; - app = fu_engine_store_get_app_by_guids (store, item->device); + app = fu_engine_store_get_app_by_guids (store, device); if (app == NULL) { g_set_error_literal (error, FWUPD_ERROR, @@ -732,11 +656,11 @@ fu_engine_verify (FuEngine *self, const gchar *device_id, GError **error) } /* find version in metadata */ - version = fu_device_get_version (item->device); + version = fu_device_get_version (device); release = as_app_get_release (app, version); if (release == NULL) { /* try again with the system metadata */ - app = fu_engine_store_get_app_by_guids (self->store, item->device); + app = fu_engine_store_get_app_by_guids (self->store, device); if (app == NULL) { g_set_error_literal (error, FWUPD_ERROR, @@ -765,7 +689,7 @@ fu_engine_verify (FuEngine *self, const gchar *device_id, GError **error) } /* get the matching checksum */ - checksums = fu_device_get_checksums (item->device); + checksums = fu_device_get_checksums (device); if (checksums->len == 0) { g_set_error (error, FWUPD_ERROR, @@ -1023,14 +947,17 @@ fu_engine_get_guids_from_store (AsStore *store) return g_string_free (str, FALSE); } -static FuDeviceItem * +static FuDevice * fu_engine_get_item_by_wildcard (FuEngine *self, AsStore *store, GError **error) { g_autofree gchar *guids = NULL; - for (guint i = 0; i < self->devices->len; i++) { - FuDeviceItem *item_tmp = g_ptr_array_index (self->devices, i); - if (fu_engine_store_get_app_by_guids (store, item_tmp->device) != NULL) - return item_tmp; + g_autoptr(GPtrArray) devices = NULL; + + devices = fu_device_list_get_all (self->device_list); + for (guint i = 0; i < devices->len; i++) { + FuDevice *device_tmp = g_ptr_array_index (devices, i); + if (fu_engine_store_get_app_by_guids (store, device_tmp) != NULL) + return device_tmp; } guids = fu_engine_get_guids_from_store (store); g_set_error (error, @@ -1065,7 +992,7 @@ fu_engine_install (FuEngine *self, AsApp *app; AsChecksum *csum_tmp; AsRelease *rel; - FuDeviceItem *item; + FuDevice *device; FuPlugin *plugin; GBytes *blob_fw; GPtrArray *plugins; @@ -1084,18 +1011,18 @@ fu_engine_install (FuEngine *self, /* wildcard */ if (g_strcmp0 (device_id, FWUPD_DEVICE_ID_ANY) == 0) { - item = fu_engine_get_item_by_wildcard (self, store, error); - if (item == NULL) + device = fu_engine_get_item_by_wildcard (self, store, error); + if (device == NULL) return FALSE; } else { /* find the specific device */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return FALSE; } /* check the device is not locked */ - if (fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_LOCKED)) { + if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_LOCKED)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, @@ -1105,19 +1032,19 @@ fu_engine_install (FuEngine *self, } /* no update abilities */ - if (!fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_UPDATABLE)) { + if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Device %s does not currently allow updates", - device_id); + fu_device_get_id (device)); return FALSE; } /* called with online update, test if device is supposed to allow this */ if ((flags & FWUPD_INSTALL_FLAG_OFFLINE) == 0 && - fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_ONLY_OFFLINE)) { + fu_device_has_flag (device, FWUPD_DEVICE_FLAG_ONLY_OFFLINE)) { g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, @@ -1127,7 +1054,7 @@ fu_engine_install (FuEngine *self, } /* find from guid */ - app = fu_engine_store_get_app_by_guids (store, item->device); + app = fu_engine_store_get_app_by_guids (store, device); if (app == NULL) { g_autofree gchar *guid = NULL; guid = fu_engine_get_guids_from_store (store); @@ -1135,12 +1062,12 @@ fu_engine_install (FuEngine *self, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Firmware is not for this hw: required %s got %s", - fu_device_get_guid_default (item->device), guid); + fu_device_get_guid_default (device), guid); return FALSE; } /* not in bootloader mode */ - if (fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER)) { + if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER)) { const gchar *caption = NULL; AsScreenshot *ss = _as_app_get_screenshot_default (app); if (ss != NULL) @@ -1150,13 +1077,13 @@ fu_engine_install (FuEngine *self, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Device %s needs to manually be put in update mode: %s", - fu_device_get_name (item->device), caption); + fu_device_get_name (device), caption); } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Device %s needs to manually be put in update mode", - fu_device_get_name (item->device)); + fu_device_get_name (device)); } return FALSE; } @@ -1168,7 +1095,7 @@ fu_engine_install (FuEngine *self, fu_engine_vendor_fixup_provide_value (app); /* check we can install it */ - if (!fu_engine_check_requirements (self, app, item->device, error)) + if (!fu_engine_check_requirements (self, app, device, error)) return FALSE; /* parse the DriverVer */ @@ -1225,10 +1152,10 @@ fu_engine_install (FuEngine *self, } version = as_release_get_version (rel); - fu_device_set_version_new (item->device, version); + fu_device_set_version_new (device, version); /* compare to the lowest supported version, if it exists */ - tmp = fu_device_get_version_lowest (item->device); + tmp = fu_device_get_version_lowest (device); if (tmp != NULL && as_utils_vercmp (tmp, version) > 0) { g_set_error (error, FWUPD_ERROR, @@ -1240,13 +1167,13 @@ fu_engine_install (FuEngine *self, /* get the plugin */ plugin = fu_plugin_list_find_by_name (self->plugin_list, - fu_device_get_plugin (item->device), + fu_device_get_plugin (device), error); if (plugin == NULL) return FALSE; /* compare the versions of what we have installed */ - tmp = fu_device_get_version (item->device); + tmp = fu_device_get_version (device); if (tmp == NULL) { g_set_error (error, FWUPD_ERROR, @@ -1278,28 +1205,28 @@ fu_engine_install (FuEngine *self, plugins = fu_plugin_list_get_all (self->plugin_list); for (guint j = 0; j < plugins->len; j++) { FuPlugin *plugin_tmp = g_ptr_array_index (plugins, j); - if (!fu_plugin_runner_update_prepare (plugin_tmp, item->device, error)) + if (!fu_plugin_runner_update_prepare (plugin_tmp, device, error)) return FALSE; } - /* save the chosen device ID in case the item goes away */ - device_id_orig = g_strdup (fu_device_get_id (item->device)); + /* save the chosen device ID in case the device goes away */ + device_id_orig = g_strdup (fu_device_get_id (device)); /* do the update */ - if (!fu_plugin_runner_update_detach (plugin, item->device, error)) + if (!fu_plugin_runner_update_detach (plugin, device, error)) return FALSE; - item = fu_engine_get_item_by_id (self, device_id_orig, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id_orig, error); + if (device == NULL) return FALSE; if (!fu_plugin_runner_update (plugin, - item->device, + device, blob_cab, blob_fw2, flags, error)) { g_autoptr(GError) error_attach = NULL; if (!fu_plugin_runner_update_attach (plugin, - item->device, + device, &error_attach)) { g_warning ("failed to attach device after failed update: %s", error_attach->message); @@ -1308,7 +1235,7 @@ fu_engine_install (FuEngine *self, FuPlugin *plugin_tmp = g_ptr_array_index (plugins, j); g_autoptr(GError) error_local = NULL; if (!fu_plugin_runner_update_cleanup (plugin_tmp, - item->device, + device, &error_local)) { g_warning ("failed to update-cleanup " "after failed update: %s", @@ -1317,24 +1244,24 @@ fu_engine_install (FuEngine *self, } return FALSE; } - item = fu_engine_get_item_by_id (self, device_id_orig, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id_orig, error); + if (device == NULL) return FALSE; - if (!fu_plugin_runner_update_attach (plugin, item->device, error)) + if (!fu_plugin_runner_update_attach (plugin, device, error)) return FALSE; /* get the new version number */ - item = fu_engine_get_item_by_id (self, device_id_orig, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id_orig, error); + if (device == NULL) return FALSE; - if (!fu_plugin_runner_update_reload (plugin, item->device, error)) + if (!fu_plugin_runner_update_reload (plugin, device, error)) return FALSE; /* signal to all the plugins the update has happened */ for (guint j = 0; j < plugins->len; j++) { FuPlugin *plugin_tmp = g_ptr_array_index (plugins, j); g_autoptr(GError) error_local = NULL; - if (!fu_plugin_runner_update_cleanup (plugin_tmp, item->device, &error_local)) { + if (!fu_plugin_runner_update_cleanup (plugin_tmp, device, &error_local)) { g_warning ("failed to update-cleanup: %s", error_local->message); } @@ -1342,38 +1269,25 @@ fu_engine_install (FuEngine *self, /* make the UI update */ fu_engine_set_status (self, FWUPD_STATUS_IDLE); - fu_device_set_modified (item->device, (guint64) g_get_real_time () / G_USEC_PER_SEC); - fu_engine_emit_device_changed (self, item->device); + fu_device_set_modified (device, (guint64) g_get_real_time () / G_USEC_PER_SEC); + fu_engine_emit_device_changed (self, device); fu_engine_emit_changed (self); return TRUE; } -static FuDeviceItem * -fu_engine_add_item (FuEngine *self, FuDevice *device, FuPlugin *plugin) -{ - FuDeviceItem *item; - - /* add helper */ - item = g_new0 (FuDeviceItem, 1); - item->device = g_object_ref (device); - g_ptr_array_add (self->devices, item); - - return item; -} - -static FuDeviceItem * +static FuDevice * fu_engine_get_item_by_id_fallback_pending (FuEngine *self, const gchar *id, GError **error) { FuDevice *dev; FuPlugin *plugin; - FuDeviceItem *item = NULL; + FuDevice *device = NULL; FwupdUpdateState update_state; const gchar *tmp; g_autoptr(GPtrArray) devices = NULL; /* not a wildcard */ if (g_strcmp0 (id, FWUPD_DEVICE_ID_ANY) != 0) - return fu_engine_get_item_by_id (self, id, error); + return fu_device_list_find_by_id (self->device_list, id, error); /* allow '*' for any */ devices = fu_pending_get_devices (self->pending, error); @@ -1387,29 +1301,29 @@ fu_engine_get_item_by_id_fallback_pending (FuEngine *self, const gchar *id, GErr if (update_state == FWUPD_UPDATE_STATE_PENDING) continue; - /* if the device is not still connected, fake a FuDeviceItem */ - item = fu_engine_get_item_by_id (self, fu_device_get_id (dev), NULL); - if (item == NULL) { + /* if the device is not still connected, fake a FuDevice */ + device = fu_device_list_find_by_id (self->device_list, fu_device_get_id (dev), NULL); + if (device == NULL) { tmp = fu_device_get_plugin (dev); plugin = fu_plugin_list_find_by_name (self->plugin_list, tmp, error); if (plugin == NULL) return NULL; - item = fu_engine_add_item (self, dev, plugin); + fu_device_list_add (self->device_list, dev); - /* FIXME: just a boolean on FuDeviceItem? */ + /* FIXME: just a boolean on FuDevice? */ fu_device_set_metadata (dev, "FakeDevice", "TRUE"); } break; } /* no device found */ - if (item == NULL) { + if (device == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no suitable devices found"); } - return item; + return device; } /** @@ -1433,7 +1347,7 @@ fu_engine_get_action_id_for_device (FuEngine *self, { AsApp *app; AsRelease *release; - FuDeviceItem *item; + FuDevice *device; FwupdTrustFlags trust_flags = FWUPD_TRUST_FLAG_NONE; const gchar *version; const gchar *version_release; @@ -1448,18 +1362,18 @@ fu_engine_get_action_id_for_device (FuEngine *self, /* wildcard */ if (g_strcmp0 (device_id, FWUPD_DEVICE_ID_ANY) == 0) { - item = fu_engine_get_item_by_wildcard (self, store, error); - if (item == NULL) + device = fu_engine_get_item_by_wildcard (self, store, error); + if (device == NULL) return NULL; } else { /* find the specific device */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return NULL; } /* get device */ - version = fu_device_get_version (item->device); + version = fu_device_get_version (device); if (version == NULL) { g_set_error (error, FWUPD_ERROR, @@ -1470,7 +1384,7 @@ fu_engine_get_action_id_for_device (FuEngine *self, } /* match the GUIDs in the XML */ - app = fu_engine_store_get_app_by_guids (store, item->device); + app = fu_engine_store_get_app_by_guids (store, device); if (app == NULL) { g_autofree gchar *guid = NULL; guid = fu_engine_get_guids_from_store (store); @@ -1478,7 +1392,7 @@ fu_engine_get_action_id_for_device (FuEngine *self, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "firmware is not for this hw: required %s got %s", - fu_device_get_guid_default (item->device), guid); + fu_device_get_guid_default (device), guid); return NULL; } @@ -1495,8 +1409,8 @@ fu_engine_get_action_id_for_device (FuEngine *self, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "%s [%s] has no firmware update metadata", - fu_device_get_id (item->device), - fu_device_get_name (item->device)); + fu_device_get_id (device), + fu_device_get_name (device)); return NULL; } @@ -1534,7 +1448,7 @@ fu_engine_get_action_id_for_device (FuEngine *self, is_trusted = (trust_flags & FWUPD_TRUST_FLAG_PAYLOAD) > 0; /* relax authentication checks for removable devices */ - if (!fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_INTERNAL)) { + if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_INTERNAL)) { if (is_downgrade) return "org.freedesktop.fwupd.downgrade-hotplug"; if (is_trusted) @@ -1651,6 +1565,7 @@ fu_engine_load_metadata_store (FuEngine *self, GError **error) GPtrArray *remotes; g_autofree gchar *guids_str = NULL; g_autoptr(GError) error_local = NULL; + g_autoptr(GPtrArray) devices = NULL; /* clear existing store */ as_store_remove_all (self->store); @@ -1721,10 +1636,11 @@ fu_engine_load_metadata_store (FuEngine *self, GError **error) } /* are any devices now supported? */ - for (guint i = 0; i < self->devices->len; i++) { - FuDeviceItem *item = g_ptr_array_index (self->devices, i); - if (fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_SUPPORTED)) - fu_engine_emit_device_changed (self, item->device); + devices = fu_device_list_get_all (self->device_list); + for (guint i = 0; i < devices->len; i++) { + FuDevice *device = g_ptr_array_index (devices, i); + if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_SUPPORTED)) + fu_engine_emit_device_changed (self, device); } return TRUE; @@ -1948,7 +1864,7 @@ fu_engine_get_result_from_app (FuEngine *self, AsApp *app, GError **error) provides = as_app_get_provides (app); for (guint i = 0; i < provides->len; i++) { AsProvide *prov = AS_PROVIDE (g_ptr_array_index (provides, i)); - FuDeviceItem *item; + FuDevice *device; const gchar *guid; /* not firmware */ @@ -1959,11 +1875,11 @@ fu_engine_get_result_from_app (FuEngine *self, AsApp *app, GError **error) guid = as_provide_get_value (prov); if (guid == NULL) continue; - item = fu_engine_get_item_by_guid (self, guid); - if (item != NULL) { - fwupd_device_set_name (dev, fu_device_get_name (item->device)); - fwupd_device_set_flags (dev, fu_device_get_flags (item->device)); - fwupd_device_set_id (dev, fu_device_get_id (item->device)); + device = fu_device_list_find_by_guid (self->device_list, guid, NULL); + if (device != NULL) { + fwupd_device_set_name (dev, fu_device_get_name (device)); + fwupd_device_set_flags (dev, fu_device_get_flags (device)); + fwupd_device_set_id (dev, fu_device_get_id (device)); } /* add GUID */ @@ -2083,12 +1999,7 @@ fu_engine_get_devices (FuEngine *self, GError **error) g_return_val_if_fail (FU_IS_ENGINE (self), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - for (guint i = 0; i < self->devices->len; i++) { - FuDeviceItem *item; - item = g_ptr_array_index (self->devices, i); - g_ptr_array_add (devices, g_object_ref (item->device)); - } + devices = fu_device_list_get_all (self->device_list); if (devices->len == 0) { g_set_error_literal (error, FWUPD_ERROR, @@ -2215,7 +2126,7 @@ fu_engine_get_releases_for_device (FuEngine *self, FuDevice *device, GError **er GPtrArray * fu_engine_get_releases (FuEngine *self, const gchar *device_id, GError **error) { - FuDeviceItem *item; + FuDevice *device; g_autoptr(GPtrArray) releases = NULL; g_return_val_if_fail (FU_IS_ENGINE (self), NULL); @@ -2223,12 +2134,12 @@ fu_engine_get_releases (FuEngine *self, const gchar *device_id, GError **error) g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* find the device */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return NULL; /* get all the releases for the device */ - releases = fu_engine_get_releases_for_device (self, item->device, error); + releases = fu_engine_get_releases_for_device (self, device, error); if (releases == NULL) return NULL; if (releases->len == 0) { @@ -2255,7 +2166,7 @@ fu_engine_get_releases (FuEngine *self, const gchar *device_id, GError **error) GPtrArray * fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error) { - FuDeviceItem *item; + FuDevice *device; g_autoptr(GPtrArray) releases = NULL; g_autoptr(GPtrArray) releases_tmp = NULL; g_autoptr(GString) error_str = g_string_new (NULL); @@ -2265,12 +2176,12 @@ fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* find the device */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return NULL; /* get all the releases for the device */ - releases_tmp = fu_engine_get_releases_for_device (self, item->device, error); + releases_tmp = fu_engine_get_releases_for_device (self, device, error); if (releases_tmp == NULL) return NULL; releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); @@ -2280,13 +2191,13 @@ fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error /* only include older firmware */ vercmp = as_utils_vercmp (fwupd_release_get_version (rel_tmp), - fu_device_get_version (item->device)); + fu_device_get_version (device)); if (vercmp == 0) { g_string_append_printf (error_str, "%s=same, ", fwupd_release_get_version (rel_tmp)); g_debug ("ignoring %s as the same as %s", fwupd_release_get_version (rel_tmp), - fu_device_get_version (item->device)); + fu_device_get_version (device)); continue; } if (vercmp > 0) { @@ -2294,19 +2205,19 @@ fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error fwupd_release_get_version (rel_tmp)); g_debug ("ignoring %s as newer than %s", fwupd_release_get_version (rel_tmp), - fu_device_get_version (item->device)); + fu_device_get_version (device)); continue; } /* don't show releases we are not allowed to dowgrade to */ - if (fu_device_get_version_lowest (item->device) != NULL) { + if (fu_device_get_version_lowest (device) != NULL) { if (as_utils_vercmp (fwupd_release_get_version (rel_tmp), - fu_device_get_version_lowest (item->device)) <= 0) { + fu_device_get_version_lowest (device)) <= 0) { g_string_append_printf (error_str, "%s=lowest, ", fwupd_release_get_version (rel_tmp)); g_debug ("ignoring %s as older than lowest %s", fwupd_release_get_version (rel_tmp), - fu_device_get_version_lowest (item->device)); + fu_device_get_version_lowest (device)); continue; } } @@ -2320,14 +2231,14 @@ fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No downgrades for device, current is %s: %s", - fu_device_get_version (item->device), + fu_device_get_version (device), error_str->str); } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No downgrades for device, current is %s", - fu_device_get_version (item->device)); + fu_device_get_version (device)); } return NULL; } @@ -2348,7 +2259,7 @@ fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error GPtrArray * fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error) { - FuDeviceItem *item; + FuDevice *device; g_autoptr(GPtrArray) releases = NULL; g_autoptr(GPtrArray) releases_tmp = NULL; g_autoptr(GString) error_str = g_string_new (NULL); @@ -2358,12 +2269,12 @@ fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error) g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* find the device */ - item = fu_engine_get_item_by_id (self, device_id, error); - if (item == NULL) + device = fu_device_list_find_by_id (self->device_list, device_id, error); + if (device == NULL) return NULL; /* get all the releases for the device */ - releases_tmp = fu_engine_get_releases_for_device (self, item->device, error); + releases_tmp = fu_engine_get_releases_for_device (self, device, error); if (releases_tmp == NULL) return NULL; releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); @@ -2373,13 +2284,13 @@ fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error) /* only include older firmware */ vercmp = as_utils_vercmp (fwupd_release_get_version (rel_tmp), - fu_device_get_version (item->device)); + fu_device_get_version (device)); if (vercmp == 0) { g_string_append_printf (error_str, "%s=same, ", fwupd_release_get_version (rel_tmp)); g_debug ("ignoring %s as the same as %s", fwupd_release_get_version (rel_tmp), - fu_device_get_version (item->device)); + fu_device_get_version (device)); continue; } if (vercmp < 0) { @@ -2387,7 +2298,7 @@ fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error) fwupd_release_get_version (rel_tmp)); g_debug ("ignoring %s as older than %s", fwupd_release_get_version (rel_tmp), - fu_device_get_version (item->device)); + fu_device_get_version (device)); continue; } g_ptr_array_add (releases, g_object_ref (rel_tmp)); @@ -2400,14 +2311,14 @@ fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error) FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No upgrades for device, current is %s: %s", - fu_device_get_version (item->device), + fu_device_get_version (device), error_str->str); } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No upgrades for device, current is %s", - fu_device_get_version (item->device)); + fu_device_get_version (device)); } return NULL; } @@ -2428,7 +2339,7 @@ fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error) gboolean fu_engine_clear_results (FuEngine *self, const gchar *device_id, GError **error) { - FuDeviceItem *item; + FuDevice *device; FuPlugin *plugin; g_return_val_if_fail (FU_IS_ENGINE (self), FALSE); @@ -2436,19 +2347,19 @@ fu_engine_clear_results (FuEngine *self, const gchar *device_id, GError **error) g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* find the device */ - item = fu_engine_get_item_by_id_fallback_pending (self, device_id, error); - if (item == NULL) + device = fu_engine_get_item_by_id_fallback_pending (self, device_id, error); + if (device == NULL) return FALSE; /* get the plugin */ plugin = fu_plugin_list_find_by_name (self->plugin_list, - fu_device_get_plugin (item->device), + fu_device_get_plugin (device), error); if (plugin == NULL) return FALSE; /* call into the plugin */ - return fu_plugin_runner_clear_results (plugin, item->device, error); + return fu_plugin_runner_clear_results (plugin, device, error); } /** @@ -2464,7 +2375,7 @@ fu_engine_clear_results (FuEngine *self, const gchar *device_id, GError **error) FwupdDevice * fu_engine_get_results (FuEngine *self, const gchar *device_id, GError **error) { - FuDeviceItem *item; + FuDevice *device; FuPlugin *plugin; g_return_val_if_fail (FU_IS_ENGINE (self), NULL); @@ -2472,22 +2383,22 @@ fu_engine_get_results (FuEngine *self, const gchar *device_id, GError **error) g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* find the device */ - item = fu_engine_get_item_by_id_fallback_pending (self, device_id, error); - if (item == NULL) + device = fu_engine_get_item_by_id_fallback_pending (self, device_id, error); + if (device == NULL) return NULL; /* get the plugin */ plugin = fu_plugin_list_find_by_name (self->plugin_list, - fu_device_get_plugin (item->device), + fu_device_get_plugin (device), error); if (plugin == NULL) return FALSE; /* call into the plugin */ - if (!fu_plugin_runner_get_results (plugin, item->device, error)) + if (!fu_plugin_runner_get_results (plugin, device, error)) return NULL; - return g_object_ref (item->device); + return g_object_ref (device); } static void @@ -2612,7 +2523,13 @@ fu_engine_plugin_device_added_cb (FuPlugin *plugin, gpointer user_data) { FuEngine *self = (FuEngine *) user_data; - FuDeviceItem *item; + fu_engine_add_device (self, device); +} + +void +fu_engine_add_device (FuEngine *self, FuDevice *device) +{ + FuDevice *device_tmp; GPtrArray *blacklisted_devices; GPtrArray *device_guids; @@ -2625,6 +2542,16 @@ fu_engine_plugin_device_added_cb (FuPlugin *plugin, return; } + /* does this device already exist? */ + device_tmp = fu_device_list_find_by_id (self->device_list, + fu_device_get_id (device), NULL); + if (device_tmp != NULL) { + g_warning ("already added %s by %s", + fu_device_get_id (device_tmp), + fu_device_get_plugin (device_tmp)); + return; + } + /* is this GUID blacklisted */ blacklisted_devices = fu_config_get_blacklist_devices (self->config); for (guint i = 0; i < blacklisted_devices->len; i++) { @@ -2634,42 +2561,18 @@ fu_engine_plugin_device_added_cb (FuPlugin *plugin, if (g_strcmp0 (blacklisted_guid, device_guid) == 0) { g_debug ("%s is blacklisted [%s], ignoring from %s", fu_device_get_id (device), device_guid, - fu_plugin_get_name (plugin)); + fu_device_get_plugin (device)); return; } } } - /* remove any fake device */ - item = fu_engine_get_item_by_id (self, fu_device_get_id (device), NULL); - if (item != NULL) { - if (g_strcmp0 (fu_device_get_plugin (item->device), - fu_plugin_get_name (plugin)) == 0) { - g_warning ("already added %s by %s", - fu_device_get_id (item->device), - fu_device_get_plugin (item->device)); - } else { - g_debug ("already added %s by %s, ignoring device from %s", - fu_device_get_id (item->device), - fu_device_get_plugin (item->device), - fu_plugin_get_name (plugin)); - } - return; - } - - /* success */ - fu_engine_add_device (self, plugin, device); -} - -void -fu_engine_add_device (FuEngine *self, FuPlugin *plugin, FuDevice *device) -{ /* notify all plugins about this new device */ if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_REGISTERED)) fu_engine_plugin_device_register (self, device); /* create new device */ - fu_engine_add_item (self, device, plugin); + fu_device_list_add (self->device_list, device); /* match the metadata at this point so clients can tell if the * device is worthy */ @@ -2687,19 +2590,21 @@ fu_engine_plugin_device_removed_cb (FuPlugin *plugin, gpointer user_data) { FuEngine *self = (FuEngine *) user_data; - FuDeviceItem *item; + FuDevice *device_tmp; FuPlugin *plugin_old; g_autoptr(GError) error = NULL; - item = fu_engine_get_item_by_id (self, fu_device_get_id (device), &error); - if (item == NULL) { + device_tmp = fu_device_list_find_by_id (self->device_list, + fu_device_get_id (device), + &error); + if (device_tmp == NULL) { g_debug ("%s", error->message); return; } /* get the plugin */ plugin_old = fu_plugin_list_find_by_name (self->plugin_list, - fu_device_get_plugin (item->device), + fu_device_get_plugin (device), &error); if (plugin_old == NULL) { g_debug ("%s", error->message); @@ -2715,8 +2620,8 @@ fu_engine_plugin_device_removed_cb (FuPlugin *plugin, } /* make the UI update */ + fu_device_list_remove (self->device_list, device); fu_engine_emit_device_removed (self, device); - g_ptr_array_remove (self->devices, item); fu_engine_emit_changed (self); } @@ -3024,7 +2929,7 @@ fu_engine_init (FuEngine *self) self->percentage = 0; self->status = FWUPD_STATUS_IDLE; self->config = fu_config_new (); - self->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_engine_item_free); + self->device_list = fu_device_list_new (); self->smbios = fu_smbios_new (); self->hwids = fu_hwids_new (); self->quirks = fu_quirks_new (); @@ -3053,7 +2958,7 @@ fu_engine_finalize (GObject *obj) g_object_unref (self->plugin_list); g_object_unref (self->profile); g_object_unref (self->store); - g_ptr_array_unref (self->devices); + g_object_unref (self->device_list); g_ptr_array_unref (self->supported_guids); G_OBJECT_CLASS (fu_engine_parent_class)->finalize (obj); diff --git a/src/fu-engine.h b/src/fu-engine.h index 8751ab1a8..cf957c5f1 100644 --- a/src/fu-engine.h +++ b/src/fu-engine.h @@ -103,7 +103,6 @@ GPtrArray *fu_engine_get_details (FuEngine *self, /* for the self tests */ void fu_engine_add_device (FuEngine *self, - FuPlugin *plugin, FuDevice *device); void fu_engine_add_plugin (FuEngine *self, FuPlugin *plugin); diff --git a/src/fu-self-test.c b/src/fu-self-test.c index 48a00b8a4..053898d02 100644 --- a/src/fu-self-test.c +++ b/src/fu-self-test.c @@ -30,6 +30,7 @@ #include #include "fu-config.h" +#include "fu-device-list.h" #include "fu-device-private.h" #include "fu-engine.h" #include "fu-quirks.h" @@ -69,12 +70,12 @@ fu_engine_partial_hash_func (void) fu_device_set_id (device1, "device1"); fu_device_set_plugin (device1, "test"); fu_device_add_guid (device1, "12345678-1234-1234-1234-123456789012"); - fu_engine_add_device (engine, plugin, device1); + fu_engine_add_device (engine, device1); fu_device_set_id (device2, "device21"); fu_device_set_plugin (device2, "test"); fu_device_set_equivalent_id (device2, "b92f5b7560b84ca005a79f5a15de3c003ce494cf"); fu_device_add_guid (device2, "12345678-1234-1234-1234-123456789012"); - fu_engine_add_device (engine, plugin, device2); + fu_engine_add_device (engine, device2); /* match nothing */ ret = fu_engine_unlock (engine, "deadbeef", &error_none); @@ -145,7 +146,7 @@ fu_engine_require_hwid_func (void) fu_device_set_id (device, "test_device"); fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); - fu_engine_add_device (engine, plugin, device); + fu_engine_add_device (engine, device); /* install it */ ret = fu_engine_install (engine, fu_device_get_id (device), @@ -271,7 +272,7 @@ fu_engine_func (void) fu_device_set_name (device, "Test Device"); fu_device_add_guid (device, "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); - fu_engine_add_device (engine, plugin, device); + fu_engine_add_device (engine, device); devices = fu_engine_get_devices (engine, &error); g_assert_no_error (error); g_assert (devices != NULL); @@ -306,6 +307,65 @@ fu_engine_func (void) g_assert_cmpstr (fwupd_release_get_version (rel), ==, "1.2.2"); } +static void +fu_device_list_func (void) +{ + g_autoptr(FuDeviceList) device_list = fu_device_list_new (); + g_autoptr(FuDevice) device1 = fu_device_new (); + g_autoptr(FuDevice) device2 = fu_device_new (); + g_autoptr(GPtrArray) devices = NULL; + g_autoptr(GPtrArray) devices2 = NULL; + g_autoptr(GError) error = NULL; + FuDevice *device; + + /* add both */ + fu_device_set_id (device1, "device1"); + fu_device_add_guid (device1, "foobar"); + fu_device_list_add (device_list, device1); + fu_device_set_id (device2, "device2"); + fu_device_add_guid (device2, "baz"); + fu_device_list_add (device_list, device2); + + /* get all */ + devices = fu_device_list_get_all (device_list); + g_assert_cmpint (devices->len, ==, 2); + device = g_ptr_array_index (devices, 0); + g_assert_cmpstr (fu_device_get_id (device), ==, + "99249eb1bd9ef0b6e192b271a8cb6a3090cfec7a"); + + /* find by ID */ + device = fu_device_list_find_by_id (device_list, + "99249eb1bd9ef0b6e192b271a8cb6a3090cfec7a", + &error); + g_assert_no_error (error); + g_assert (device != NULL); + g_assert_cmpstr (fu_device_get_id (device), ==, + "99249eb1bd9ef0b6e192b271a8cb6a3090cfec7a"); + + /* find by GUID */ + device = fu_device_list_find_by_guid (device_list, + "579a3b1c-d1db-5bdc-b6b9-e2c1b28d5b8a", + &error); + g_assert_no_error (error); + g_assert (device != NULL); + g_assert_cmpstr (fu_device_get_id (device), ==, + "1a8d0d9a96ad3e67ba76cf3033623625dc6d6882"); + + /* find by missing GUID */ + device = fu_device_list_find_by_guid (device_list, "notfound", &error); + g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND); + g_assert (device == NULL); + + /* remove device */ + fu_device_list_remove (device_list, device1); + devices2 = fu_device_list_get_all (device_list); + g_assert_cmpint (devices2->len, ==, 1); + device = g_ptr_array_index (devices2, 0); + g_assert_cmpstr (fu_device_get_id (device), ==, + "1a8d0d9a96ad3e67ba76cf3033623625dc6d6882"); +} + + static void fu_device_metadata_func (void) { @@ -1156,6 +1216,7 @@ main (int argc, char **argv) g_test_add_func ("/fwupd/device-locker{success}", fu_device_locker_func); g_test_add_func ("/fwupd/device-locker{fail}", fu_device_locker_fail_func); g_test_add_func ("/fwupd/device{metadata}", fu_device_metadata_func); + g_test_add_func ("/fwupd/device-list", fu_device_list_func); g_test_add_func ("/fwupd/engine", fu_engine_func); g_test_add_func ("/fwupd/engine{require-hwid}", fu_engine_require_hwid_func); g_test_add_func ("/fwupd/engine{partial-hash}", fu_engine_partial_hash_func); diff --git a/src/meson.build b/src/meson.build index f8bdb54bb..86dfb0e26 100644 --- a/src/meson.build +++ b/src/meson.build @@ -128,6 +128,7 @@ executable( 'fu-hwids.c', 'fu-debug.c', 'fu-device.c', + 'fu-device-list.c', 'fu-device-locker.c', 'fu-keyring.c', 'fu-pending.c', @@ -189,6 +190,7 @@ if get_option('enable-tests') 'fu-keyring.c', 'fu-hwids.c', 'fu-device.c', + 'fu-device-list.c', 'fu-device-locker.c', 'fu-pending.c', 'fu-keyring.c',