diff --git a/src/fu-engine.c b/src/fu-engine.c index 56273b6df..e6563ff3d 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -5052,19 +5052,24 @@ static gint fu_engine_sort_releases_cb(gconstpointer a, gconstpointer b, gpointer user_data) { FuDevice *device = FU_DEVICE(user_data); - FwupdRelease *rel_a = FWUPD_RELEASE(*((FwupdRelease **)a)); - FwupdRelease *rel_b = FWUPD_RELEASE(*((FwupdRelease **)b)); + FuRelease *rel_a = FU_RELEASE(*((FuRelease **)a)); + FuRelease *rel_b = FU_RELEASE(*((FuRelease **)b)); gint rc; /* first by branch */ - rc = g_strcmp0(fwupd_release_get_branch(rel_b), fwupd_release_get_branch(rel_a)); + rc = g_strcmp0(fu_release_get_branch(rel_b), fu_release_get_branch(rel_a)); if (rc != 0) return rc; /* then by version */ - return fu_version_compare(fwupd_release_get_version(rel_b), - fwupd_release_get_version(rel_a), - fu_device_get_version_format(device)); + rc = fu_version_compare(fu_release_get_version(rel_b), + fu_release_get_version(rel_a), + fu_device_get_version_format(device)); + if (rc != 0) + return rc; + + /* then by priority */ + return fu_release_compare(rel_a, rel_b); } static gboolean diff --git a/src/fu-release.c b/src/fu-release.c index 30788b6f0..af83db2ff 100644 --- a/src/fu-release.c +++ b/src/fu-release.c @@ -33,6 +33,7 @@ struct _FuRelease { gboolean is_downgrade; GPtrArray *soft_reqs; /* nullable, element-type XbNode */ GPtrArray *hard_reqs; /* nullable, element-type XbNode */ + guint64 priority; }; G_DEFINE_TYPE(FuRelease, fu_release, FWUPD_TYPE_RELEASE) @@ -618,6 +619,13 @@ fu_release_check_requirements(FuRelease *self, return TRUE; } +void +fu_release_set_priority(FuRelease *self, guint64 priority) +{ + g_return_if_fail(FU_IS_RELEASE(self)); + self->priority = priority; +} + /** * fu_release_load: * @self: a #FuRelease @@ -689,6 +697,9 @@ fu_release_load(FuRelease *self, tmp = xb_node_query_text(component, "developer_name", NULL); if (tmp != NULL) fwupd_release_set_vendor(FWUPD_RELEASE(self), tmp); + tmp64 = xb_node_get_attr_as_uint(component, "priority"); + if (tmp64 != G_MAXUINT64) + fu_release_set_priority(self, tmp64); /* use default release */ if (rel_optional == NULL) { @@ -1014,7 +1025,7 @@ fu_release_get_action_id(FuRelease *self) * @release1: first task to compare. * @release2: second task to compare. * - * Compares two install tasks. + * Compares two releases. * * Returns: 1, 0 or -1 if @release1 is greater, equal, or less than @release2, respectively. **/ @@ -1023,10 +1034,18 @@ fu_release_compare(FuRelease *release1, FuRelease *release2) { FuDevice *device1 = fu_release_get_device(release1); FuDevice *device2 = fu_release_get_device(release2); + + /* device order, lower is better */ if (fu_device_get_order(device1) < fu_device_get_order(device2)) return -1; if (fu_device_get_order(device1) > fu_device_get_order(device2)) return 1; + + /* release priority, higher is better */ + if (release1->priority > release2->priority) + return -1; + if (release1->priority < release2->priority) + return 1; return 0; } diff --git a/src/fu-release.h b/src/fu-release.h index 9233d9fbe..910381e2a 100644 --- a/src/fu-release.h +++ b/src/fu-release.h @@ -23,6 +23,7 @@ fu_release_new(void); #define fu_release_add_flag(r, v) fwupd_release_add_flag(FWUPD_RELEASE(r), v) #define fu_release_add_tag(r, v) fwupd_release_add_tag(FWUPD_RELEASE(r), v) #define fu_release_add_metadata(r, v) fwupd_release_add_metadata(FWUPD_RELEASE(r), v) +#define fu_release_set_branch(r, v) fwupd_release_set_branch(FWUPD_RELEASE(r), v) FuDevice * fu_release_get_device(FuRelease *self); @@ -58,3 +59,5 @@ const gchar * fu_release_get_action_id(FuRelease *self); gint fu_release_compare(FuRelease *release1, FuRelease *release2); +void +fu_release_set_priority(FuRelease *self, guint64 priority); diff --git a/src/fu-self-test.c b/src/fu-self-test.c index e4c1b8a4b..916e59d67 100644 --- a/src/fu-self-test.c +++ b/src/fu-self-test.c @@ -4096,7 +4096,6 @@ fu_spawn_timeout_func(void) static void fu_release_compare_func(gconstpointer user_data) { - FuDevice *device_tmp; g_autoptr(GPtrArray) releases = g_ptr_array_new(); g_autoptr(FuDevice) device1 = fu_device_new(NULL); g_autoptr(FuDevice) device2 = fu_device_new(NULL); @@ -4105,25 +4104,31 @@ fu_release_compare_func(gconstpointer user_data) g_autoptr(FuRelease) release2 = fu_release_new(); g_autoptr(FuRelease) release3 = fu_release_new(); - fu_device_set_order(device1, 99); + fu_device_set_order(device1, 33); fu_release_set_device(release1, device1); - g_ptr_array_add(releases, release1); + fu_release_set_priority(release1, 0); + fu_release_set_branch(release1, "1"); + fu_device_set_order(device2, 11); fu_release_set_device(release2, device2); - g_ptr_array_add(releases, release2); - fu_device_set_order(device3, 33); + fu_release_set_priority(release2, 0); + fu_release_set_branch(release2, "2"); + + fu_device_set_order(device3, 11); fu_release_set_device(release3, device3); + fu_release_set_priority(release3, 99); + fu_release_set_branch(release3, "3"); + + g_ptr_array_add(releases, release1); + g_ptr_array_add(releases, release2); g_ptr_array_add(releases, release3); /* order the install tasks */ g_ptr_array_sort(releases, fu_release_compare_func_cb); g_assert_cmpint(releases->len, ==, 3); - device_tmp = fu_release_get_device(g_ptr_array_index(releases, 0)); - g_assert_cmpint(fu_device_get_order(device_tmp), ==, 11); - device_tmp = fu_release_get_device(g_ptr_array_index(releases, 1)); - g_assert_cmpint(fu_device_get_order(device_tmp), ==, 33); - device_tmp = fu_release_get_device(g_ptr_array_index(releases, 2)); - g_assert_cmpint(fu_device_get_order(device_tmp), ==, 99); + g_assert_cmpstr(fu_release_get_branch(g_ptr_array_index(releases, 0)), ==, "3"); + g_assert_cmpstr(fu_release_get_branch(g_ptr_array_index(releases, 1)), ==, "2"); + g_assert_cmpstr(fu_release_get_branch(g_ptr_array_index(releases, 2)), ==, "1"); } static void