[gnome-software/wip/hughsie/fwupd: 3/3] fwupd: Add support for the update action



commit 980035dd91f7ec0d9e75ad103ead5579342a0730
Author: Richard Hughes <richard hughsie com>
Date:   Tue Jun 30 14:05:11 2020 +0100

    fwupd: Add support for the update action
    
    Some future dock hardware needs the user to manually restart it after the update
    has completed. This patch adds the update-action functionality and shows a
    dialog box just like the existing detach-action one.

 plugins/fwupd/gs-plugin-fwupd.c | 29 +++++++++++++++++++
 src/gs-page.c                   | 62 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)
---
diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c
index 9f5886c3..2c50796b 100644
--- a/plugins/fwupd/gs-plugin-fwupd.c
+++ b/plugins/fwupd/gs-plugin-fwupd.c
@@ -226,6 +226,7 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
 #if FWUPD_CHECK_VERSION(1,4,5)
        /* send our implemented feature set */
        if (!fwupd_client_set_feature_flags (priv->client,
+                                            FWUPD_FEATURE_FLAG_UPDATE_ACTION |
                                             FWUPD_FEATURE_FLAG_DETACH_ACTION,
                                             cancellable, error)) {
                g_prefix_error (error, "Failed to set front-end features: ");
@@ -778,6 +779,7 @@ gs_plugin_fwupd_install (GsPlugin *plugin,
        GFile *local_file;
        g_autofree gchar *filename = NULL;
        gboolean downloaded_to_cache = FALSE;
+       g_autoptr(FwupdDevice) dev = NULL;
 
        /* not set */
        local_file = gs_app_get_local_file (app);
@@ -829,6 +831,33 @@ gs_plugin_fwupd_install (GsPlugin *plugin,
                        return FALSE;
        }
 
+       /* does the device have an update message */
+       dev = fwupd_client_get_device_by_id (priv->client, device_id,
+                                            cancellable, NULL);
+       if (dev != NULL) {
+               if (fwupd_device_get_update_message (dev) != NULL) {
+                       g_autoptr(AsScreenshot) ss = as_screenshot_new ();
+
+#if FWUPD_CHECK_VERSION(1,4,5)
+                       /* image is optional */
+                       if (fwupd_device_get_update_image (dev) != NULL) {
+                               g_autoptr(AsImage) im = as_image_new ();
+                               as_image_set_kind (im, AS_IMAGE_KIND_SOURCE);
+                               as_image_set_url (im, fwupd_device_get_update_image (dev));
+                               as_screenshot_add_image (ss, im);
+                       }
+#endif
+
+                       /* caption is required */
+                       as_screenshot_set_kind (ss, AS_SCREENSHOT_KIND_DEFAULT);
+                       as_screenshot_set_caption (ss, NULL, fwupd_device_get_update_message (dev));
+                       gs_app_set_action_screenshot (app, ss);
+
+                       /* require the dialog */
+                       gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_USER_ACTION);
+               }
+       }
+
        /* success */
        return TRUE;
 }
diff --git a/src/gs-page.c b/src/gs-page.c
index be83273f..c9d91bcd 100644
--- a/src/gs-page.c
+++ b/src/gs-page.c
@@ -59,6 +59,58 @@ gs_page_helper_free (GsPageHelper *helper)
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GsPageHelper, gs_page_helper_free);
 
+static void
+gs_page_update_app_response_close_cb (GtkDialog *dialog, gint response, gpointer user_data)
+{
+       gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+gs_page_show_update_message (GsPageHelper *helper, AsScreenshot *ss)
+{
+       GsPagePrivate *priv = gs_page_get_instance_private (helper->page);
+       GPtrArray *images;
+       GtkWidget *dialog;
+       g_autofree gchar *escaped = NULL;
+
+       dialog = gtk_message_dialog_new (gs_shell_get_window (priv->shell),
+                                        GTK_DIALOG_MODAL |
+                                        GTK_DIALOG_USE_HEADER_BAR,
+                                        GTK_MESSAGE_INFO,
+                                        GTK_BUTTONS_OK,
+                                        "%s", gs_app_get_name (helper->app));
+       escaped = g_markup_escape_text (as_screenshot_get_caption (ss, NULL), -1);
+       gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
+                                                   "%s", escaped);
+
+       /* image is optional */
+       images = as_screenshot_get_images (ss);
+       if (images->len) {
+               GtkWidget *content_area;
+               GtkWidget *ssimg;
+               g_autoptr(SoupSession) soup_session = NULL;
+
+               /* load screenshot */
+               soup_session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT,
+                                                             gs_user_agent (), NULL);
+               ssimg = gs_screenshot_image_new (soup_session);
+               gs_screenshot_image_set_screenshot (GS_SCREENSHOT_IMAGE (ssimg), ss);
+               gs_screenshot_image_set_size (GS_SCREENSHOT_IMAGE (ssimg), 400, 225);
+               gs_screenshot_image_load_async (GS_SCREENSHOT_IMAGE (ssimg),
+                                               helper->cancellable);
+               gtk_widget_set_margin_start (ssimg, 24);
+               gtk_widget_set_margin_end (ssimg, 24);
+               content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+               gtk_container_add (GTK_CONTAINER (content_area), ssimg);
+               gtk_container_child_set (GTK_CONTAINER (content_area), ssimg, "pack-type", GTK_PACK_END, 
NULL);
+       }
+
+       /* handle this async */
+       g_signal_connect (dialog, "response",
+                         G_CALLBACK (gs_page_update_app_response_close_cb), helper);
+       gs_shell_modal_dialog_present (priv->shell, GTK_DIALOG (dialog));
+}
+
 static void
 gs_page_app_installed_cb (GObject *source,
                           GAsyncResult *res,
@@ -94,6 +146,16 @@ gs_page_app_installed_cb (GObject *source,
                gs_utils_reboot_notify (list);
        }
 
+       /* tell the user what they have to do */
+       if (gs_app_get_kind (helper->app) == AS_APP_KIND_FIRMWARE &&
+           gs_app_has_quirk (helper->app, GS_APP_QUIRK_NEEDS_USER_ACTION)) {
+               AsScreenshot *ss = gs_app_get_action_screenshot (helper->app);
+               if (ss != NULL) {
+                       if (as_screenshot_get_caption (ss, NULL) != NULL)
+                               gs_page_show_update_message (helper, ss);
+               }
+       }
+
        /* only show this if the window is not active */
        if (gs_app_is_installed (helper->app) &&
            helper->action == GS_PLUGIN_ACTION_INSTALL &&


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]