[gnome-software/wip/hughsie/fwupd: 14/21] Support getting firmware updates from fwupd
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/fwupd: 14/21] Support getting firmware updates from fwupd
- Date: Wed, 11 Mar 2015 19:50:13 +0000 (UTC)
commit fb84f2818500d976902d246a24d1915125abe88c
Author: Richard Hughes <richard hughsie com>
Date: Thu Mar 5 14:57:47 2015 +0000
Support getting firmware updates from fwupd
src/gs-update-list.c | 9 +-
src/plugins/Makefile.am | 6 +
src/plugins/gs-plugin-fwupd.c | 249 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 262 insertions(+), 2 deletions(-)
---
diff --git a/src/gs-update-list.c b/src/gs-update-list.c
index 733ba78..ba05632 100644
--- a/src/gs-update-list.c
+++ b/src/gs-update-list.c
@@ -65,6 +65,8 @@ is_addon_id_kind (GsApp *app)
return FALSE;
if (id_kind == AS_ID_KIND_WEB_APP)
return FALSE;
+ if (id_kind == AS_ID_KIND_FIRMWARE)
+ return FALSE;
return TRUE;
}
@@ -117,12 +119,15 @@ get_app_sort_key (GsApp *app)
/* sort desktop files, then addons */
switch (gs_app_get_id_kind (app)) {
- case AS_ID_KIND_DESKTOP:
+ case AS_ID_KIND_FIRMWARE:
g_string_append (key, "1:");
break;
- default:
+ case AS_ID_KIND_DESKTOP:
g_string_append (key, "2:");
break;
+ default:
+ g_string_append (key, "3:");
+ break;
}
/* sort by install date */
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index de60263..7608898 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -38,6 +38,7 @@ plugin_LTLIBRARIES = \
libgs_plugin_epiphany.la \
libgs_plugin_icons.la \
libgs_plugin_systemd-updates.la \
+ libgs_plugin_fwupd.la \
libgs_plugin_packagekit-refine.la \
libgs_plugin_packagekit-refresh.la \
libgs_plugin_packagekit-offline.la \
@@ -148,6 +149,11 @@ libgs_plugin_systemd_updates_la_LIBADD = $(GS_PLUGIN_LIBS) $(PACKAGEKIT_LIBS)
libgs_plugin_systemd_updates_la_LDFLAGS = -module -avoid-version
libgs_plugin_systemd_updates_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+libgs_plugin_fwupd_la_SOURCES = gs-plugin-fwupd.c
+libgs_plugin_fwupd_la_LIBADD = $(GS_PLUGIN_LIBS) $(PACKAGEKIT_LIBS)
+libgs_plugin_fwupd_la_LDFLAGS = -module -avoid-version
+libgs_plugin_fwupd_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
libgs_plugin_packagekit_history_la_SOURCES = gs-plugin-packagekit-history.c
libgs_plugin_packagekit_history_la_LIBADD = $(GS_PLUGIN_LIBS)
libgs_plugin_packagekit_history_la_LDFLAGS = -module -avoid-version
diff --git a/src/plugins/gs-plugin-fwupd.c b/src/plugins/gs-plugin-fwupd.c
new file mode 100644
index 0000000..00a6cd7
--- /dev/null
+++ b/src/plugins/gs-plugin-fwupd.c
@@ -0,0 +1,249 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include <gio/gio.h>
+
+#include "gs-cleanup.h"
+
+#include <appstream-glib.h>
+#include <gs-plugin.h>
+
+#define FWUPD_DBUS_PATH "/"
+#define FWUPD_DBUS_SERVICE "org.freedesktop.fwupd"
+#define FWUPD_DBUS_INTERFACE "org.freedesktop.fwupd"
+
+struct GsPluginPrivate {
+ gsize done_init;
+ GDBusProxy *proxy;
+ AsStore *store;
+};
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+ return "fwupd";
+}
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+ plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+ plugin->priv->store = as_store_new ();
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+ g_object_unref (plugin->priv->store);
+ if (plugin->priv->proxy != NULL)
+ g_object_unref (plugin->priv->proxy);
+}
+
+/**
+ * gs_plugin_startup:
+ */
+static gboolean
+gs_plugin_startup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+ _cleanup_object_unref_ GDBusConnection *conn = NULL;
+ conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
+ if (conn == NULL)
+ return FALSE;
+ plugin->priv->proxy = g_dbus_proxy_new_sync (conn,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ FWUPD_DBUS_SERVICE,
+ FWUPD_DBUS_PATH,
+ FWUPD_DBUS_INTERFACE,
+ NULL,
+ error);
+ if (plugin->priv->proxy == NULL)
+ return FALSE;
+
+ /* this is hugely wasteful */
+ if (!as_store_load (plugin->priv->store,
+ AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM,
+ cancellable, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * gs_plugin_fwupd_add_device:
+ */
+static gboolean
+gs_plugin_fwupd_add_device (GsPlugin *plugin,
+ const gchar *guid,
+ const gchar *version,
+ GList **list,
+ GError **error)
+{
+ AsApp *item;
+ AsRelease *rel;
+ GPtrArray *releases;
+ const gchar *tmp;
+ guint i;
+ _cleanup_free_ gchar *update_version = NULL;
+ _cleanup_object_unref_ GsApp *app = NULL;
+ _cleanup_string_free_ GString *update_desc = NULL;
+
+ /* find the device */
+ item = as_store_get_app_by_id (plugin->priv->store, guid);
+ if (item == NULL) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "device id %s not found in metadata",
+ guid);
+ return FALSE;
+ }
+
+ /* are any releases newer than what we have here */
+ g_debug ("device id %s found in metadata", guid);
+ update_desc = g_string_new ("");
+ releases = as_app_get_releases (item);
+ for (i = 0; i < releases->len; i++) {
+ _cleanup_free_ gchar *md = NULL;
+
+ /* check if actually newer */
+ rel = g_ptr_array_index (releases, i);
+ if (as_utils_vercmp (as_release_get_version (rel), version) <= 0)
+ continue;
+
+ /* get the update text, if it exists */
+ if (update_version == NULL)
+ update_version = g_strdup (as_release_get_version (rel));
+ tmp = as_release_get_description (rel, NULL);
+ if (tmp == NULL)
+ continue;
+ md = as_markup_convert (tmp, -1,
+ AS_MARKUP_CONVERT_FORMAT_MARKDOWN,
+ NULL);
+ if (md != NULL)
+ g_string_append_printf (update_desc, "%s\n", md);
+ }
+
+ /* no updates for this hardware */
+ if (update_version == NULL) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no updates available");
+ return FALSE;
+ }
+
+ /* remove trailing newline */
+ if (update_desc->len > 0)
+ g_string_truncate (update_desc, update_desc->len - 1);
+
+ /* actually addd the application */
+ app = gs_app_new (guid);
+ gs_app_set_management_plugin (app, "fwupd");
+ gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
+ gs_app_set_update_details (app, update_desc->str);
+ gs_app_set_update_version (app, update_version);
+// gs_app_add_source_id (app, package_ids[i]);
+ gs_app_add_source (app, as_app_get_name (item, NULL));
+ gs_app_set_kind (app, GS_APP_KIND_SYSTEM);
+ gs_plugin_add_app (list, app);
+ return TRUE;
+}
+
+/**
+ * gs_plugin_add_updates:
+ */
+gboolean
+gs_plugin_add_updates (GsPlugin *plugin,
+ GList **list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *id;
+ gboolean ret;
+ GVariantIter *iter_device;
+ _cleanup_variant_iter_free_ GVariantIter *iter = NULL;
+ _cleanup_variant_unref_ GVariant *val = NULL;
+
+ /* watch the file in case it comes or goes */
+ if (g_once_init_enter (&plugin->priv->done_init)) {
+ ret = gs_plugin_startup (plugin, cancellable, error);
+ g_once_init_leave (&plugin->priv->done_init, TRUE);
+ if (!ret)
+ return FALSE;
+ }
+
+ val = g_dbus_proxy_call_sync (plugin->priv->proxy,
+ "GetDevices",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ error);
+ if (val == NULL)
+ return FALSE;
+
+ /* parse */
+ g_variant_get (val, "(a{sa{sv}})", &iter);
+ while (g_variant_iter_next (iter, "{&sa{sv}}", &id, &iter_device)) {
+ GVariant *variant;
+ const gchar *key;
+ _cleanup_free_ gchar *guid = NULL;
+ _cleanup_free_ gchar *version = NULL;
+
+ while (g_variant_iter_next (iter_device, "{&sv}", &key, &variant)) {
+ g_debug ("%s has key %s", id, key);
+ if (g_strcmp0 (key, "Guid") == 0) {
+ guid = g_variant_dup_string (variant, NULL);
+ } else if (g_strcmp0 (key, "Version") == 0) {
+ version = g_variant_dup_string (variant, NULL);
+ }
+ g_variant_unref (variant);
+ }
+
+ /* we got all we needed */
+ if (guid != NULL && version != NULL) {
+ _cleanup_error_free_ GError *error_local = NULL;
+ if (!gs_plugin_fwupd_add_device (plugin,
+ guid,
+ version,
+ list,
+ &error_local)) {
+ g_debug ("cannot add device %s: %s",
+ id, error_local->message);
+ }
+ }
+
+ g_variant_iter_free (iter_device);
+ }
+
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]