[gnome-software/wip/hughsie/fwupd] Support triggering firmware upgrades
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/fwupd] Support triggering firmware upgrades
- Date: Wed, 11 Mar 2015 14:07:02 +0000 (UTC)
commit 967f7b693ace183075bc532bf8f9ceef2a94adeb
Author: Richard Hughes <richard hughsie com>
Date: Thu Mar 5 21:05:54 2015 +0000
Support triggering firmware upgrades
src/gs-plugin-loader.c | 5 ++
src/gs-plugin-loader.h | 1 +
src/gs-plugin.h | 4 ++
src/gs-shell-updates.c | 37 ++++++++++++++++-
src/gs-update-list.c | 17 +++++++
src/gs-update-list.h | 1 +
src/plugins/gs-plugin-fwupd.c | 93 +++++++++++++++++++++++++++++++++++++++-
7 files changed, 154 insertions(+), 4 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 5900fab..044ef2f 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -2718,6 +2718,11 @@ gs_plugin_loader_app_action_async (GsPluginLoader *plugin_loader,
state->state_success = AS_APP_STATE_UNKNOWN;
state->state_failure = AS_APP_STATE_UNKNOWN;
break;
+ case GS_PLUGIN_LOADER_ACTION_UPGRADE:
+ state->function_name = "gs_plugin_app_upgrade";
+ state->state_success = AS_APP_STATE_UNKNOWN;
+ state->state_failure = AS_APP_STATE_UNKNOWN;
+ break;
default:
g_assert_not_reached ();
break;
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 1146e81..579d6d6 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -67,6 +67,7 @@ typedef enum {
GS_PLUGIN_LOADER_ACTION_INSTALL,
GS_PLUGIN_LOADER_ACTION_REMOVE,
GS_PLUGIN_LOADER_ACTION_SET_RATING,
+ GS_PLUGIN_LOADER_ACTION_UPGRADE,
GS_PLUGIN_LOADER_ACTION_LAST
} GsPluginLoaderAction;
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 94c5268..751d01a 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -247,6 +247,10 @@ gboolean gs_plugin_app_set_rating (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error);
+gboolean gs_plugin_app_upgrade (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error);
gboolean gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
diff --git a/src/gs-shell-updates.c b/src/gs-shell-updates.c
index 51407b1..314dee6 100644
--- a/src/gs-shell-updates.c
+++ b/src/gs-shell-updates.c
@@ -839,11 +839,46 @@ gs_offline_updates_cancel (void)
g_warning ("failed to cancel the offline update: %s", error->message);
}
+/**
+ * gs_shell_updates_upgrade_cb:
+ **/
+static void
+gs_shell_updates_upgrade_cb (GsPluginLoader *plugin_loader,
+ GAsyncResult *res,
+ GsShellUpdates *shell_updates)
+{
+ _cleanup_error_free_ GError *error = NULL;
+
+ /* get the results */
+ if (!gs_plugin_loader_app_action_finish (plugin_loader, res, &error))
+ g_warning ("Failed to upgrade: %s", error->message);
+}
+
static void
gs_shell_updates_button_update_all_cb (GtkButton *button,
- GsShellUpdates *updates)
+ GsShellUpdates *shell_updates)
{
+ GsApp *app;
+ GsShellUpdatesPrivate *priv = shell_updates->priv;
+ guint i;
_cleanup_error_free_ GError *error = NULL;
+ _cleanup_ptrarray_unref_ GPtrArray *apps = NULL;
+
+ /* any firmware updates? */
+ apps = gs_update_list_get_apps (GS_UPDATE_LIST (priv->list_box_updates));
+ for (i = 0; i < apps->len; i++) {
+ app = g_ptr_array_index (apps, i);
+ if (gs_app_get_id_kind (app) != AS_ID_KIND_FIRMWARE)
+ continue;
+ gs_plugin_loader_app_action_async (priv->plugin_loader,
+ app,
+ GS_PLUGIN_LOADER_ACTION_UPGRADE,
+ priv->cancellable,
+ (GAsyncReadyCallback) gs_shell_updates_upgrade_cb,
+ shell_updates);
+ }
+
+ /* normal packages */
if (!pk_offline_trigger (PK_OFFLINE_ACTION_REBOOT, NULL, &error)) {
g_warning ("failed to trigger an offline update: %s", error->message);
return;
diff --git a/src/gs-update-list.c b/src/gs-update-list.c
index ba05632..a900bce 100644
--- a/src/gs-update-list.c
+++ b/src/gs-update-list.c
@@ -56,6 +56,23 @@ gs_update_list_add_app (GsUpdateList *update_list,
gtk_widget_show (app_row);
}
+GPtrArray *
+gs_update_list_get_apps (GsUpdateList *update_list)
+{
+ GList *l;
+ GPtrArray *apps;
+ GsAppRow *app_row;
+ _cleanup_list_free_ GList *children = NULL;
+
+ apps = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ children = gtk_container_get_children (GTK_CONTAINER (update_list));
+ for (l = children; l != NULL; l = l->next) {
+ app_row = GS_APP_ROW (l->data);
+ g_ptr_array_add (apps, g_object_ref (gs_app_row_get_app (app_row)));
+ }
+ return apps;
+}
+
static gboolean
is_addon_id_kind (GsApp *app)
{
diff --git a/src/gs-update-list.h b/src/gs-update-list.h
index ff2611b..aa954aa 100644
--- a/src/gs-update-list.h
+++ b/src/gs-update-list.h
@@ -53,6 +53,7 @@ GType gs_update_list_get_type (void);
GtkWidget *gs_update_list_new (void);
void gs_update_list_add_app (GsUpdateList *update_list,
GsApp *app);
+GPtrArray *gs_update_list_get_apps (GsUpdateList *update_list);
G_END_DECLS
diff --git a/src/plugins/gs-plugin-fwupd.c b/src/plugins/gs-plugin-fwupd.c
index 543ad13..462b382 100644
--- a/src/plugins/gs-plugin-fwupd.c
+++ b/src/plugins/gs-plugin-fwupd.c
@@ -20,14 +20,17 @@
*/
#include <config.h>
+
+#include <appstream-glib.h>
+#include <fcntl.h>
#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
#include <libsoup/soup.h>
-#include "gs-cleanup.h"
-
-#include <appstream-glib.h>
#include <gs-plugin.h>
+#include "gs-cleanup.h"
+
#define FWUPD_DBUS_PATH "/"
#define FWUPD_DBUS_SERVICE "org.freedesktop.fwupd"
#define FWUPD_DBUS_INTERFACE "org.freedesktop.fwupd"
@@ -178,6 +181,7 @@ gs_plugin_fwupd_add_required_location (GsPlugin *plugin, const gchar *location)
*/
static gboolean
gs_plugin_fwupd_add_device (GsPlugin *plugin,
+ const gchar *device_id,
const gchar *guid,
const gchar *version,
GList **list,
@@ -277,6 +281,7 @@ gs_plugin_fwupd_add_device (GsPlugin *plugin,
gs_app_add_source_id (app, filename_cache);
gs_app_add_source (app, as_app_get_name (item, NULL));
gs_app_set_kind (app, GS_APP_KIND_SYSTEM);
+ gs_app_set_metadata (app, "fwupd::DeviceID", device_id);
gs_plugin_add_app (list, app);
return TRUE;
}
@@ -336,6 +341,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
if (guid != NULL && version != NULL) {
_cleanup_error_free_ GError *error_local = NULL;
if (!gs_plugin_fwupd_add_device (plugin,
+ id,
guid,
version,
list,
@@ -408,3 +414,84 @@ gs_plugin_refresh (GsPlugin *plugin,
return TRUE;
}
+
+/**
+ * gs_plugin_app_upgrade:
+ */
+gboolean
+gs_plugin_app_upgrade (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GVariant *body;
+ GVariantBuilder builder;
+ const gchar *device_id;
+ const gchar *filename;
+ gint fd;
+ gint retval;
+ _cleanup_object_unref_ GDBusConnection *conn = NULL;
+ _cleanup_object_unref_ GDBusMessage *message = NULL;
+ _cleanup_object_unref_ GDBusMessage *request = NULL;
+ _cleanup_object_unref_ GUnixFDList *fd_list = NULL;
+
+ conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
+ if (conn == NULL)
+ return FALSE;
+
+ /* set options */
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (&builder, "{sv}",
+ "reason", g_variant_new_string ("system-update"));
+ filename = gs_app_get_source_id_default (app);
+ g_variant_builder_add (&builder, "{sv}",
+ "filename", g_variant_new_string (filename));
+ g_variant_builder_add (&builder, "{sv}",
+ "offline", g_variant_new_boolean (TRUE));
+
+ /* open file */
+ fd = open (filename, O_RDONLY);
+ if (fd < 0) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "failed to open %s",
+ filename);
+ return FALSE;
+ }
+
+ /* set out of band file descriptor */
+ fd_list = g_unix_fd_list_new ();
+ retval = g_unix_fd_list_append (fd_list, fd, NULL);
+ g_assert (retval != -1);
+ request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
+ FWUPD_DBUS_PATH,
+ FWUPD_DBUS_INTERFACE,
+ "Update");
+ g_dbus_message_set_unix_fd_list (request, fd_list);
+
+ /* g_unix_fd_list_append did a dup() already */
+ close (fd);
+
+ /* send message */
+ device_id = gs_app_get_metadata_item (app, "fwupd::DeviceID");
+ body = g_variant_new ("(sha{sv})", device_id, fd > -1 ? 0 : -1, &builder);
+ g_dbus_message_set_body (request, body);
+ message = g_dbus_connection_send_message_with_reply_sync (conn,
+ request,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ error);
+ if (message == NULL) {
+ g_dbus_error_strip_remote_error (*error);
+ return FALSE;
+ }
+ if (g_dbus_message_to_gerror (message, error)) {
+ g_dbus_error_strip_remote_error (*error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]